From 03aeed615d63e83dd9227c2b40400561079a3bb8 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Thu, 26 Mar 2009 20:03:41 +0100 Subject: [PATCH] RAWNAT: add the rawpost tables for IPv4/IPv6 --- extensions/Kbuild | 1 + extensions/compat_rawpost.h | 87 +++++++++++++++++++++++++++ extensions/ip6table_rawpost.c | 105 +++++++++++++++++++++++++++++++++ extensions/iptable_rawpost.c | 107 ++++++++++++++++++++++++++++++++++ mconfig | 1 + 5 files changed, 301 insertions(+) create mode 100644 extensions/compat_rawpost.h create mode 100644 extensions/ip6table_rawpost.c create mode 100644 extensions/iptable_rawpost.c diff --git a/extensions/Kbuild b/extensions/Kbuild index b6de614..559a3b9 100644 --- a/extensions/Kbuild +++ b/extensions/Kbuild @@ -11,6 +11,7 @@ obj-${build_DHCPMAC} += xt_DHCPMAC.o obj-${build_ECHO} += xt_ECHO.o obj-${build_IPMARK} += xt_IPMARK.o obj-${build_LOGMARK} += xt_LOGMARK.o +obj-${build_RAWNAT} += iptable_rawpost.o ip6table_rawpost.o obj-${build_SYSRQ} += xt_SYSRQ.o obj-${build_STEAL} += xt_STEAL.o obj-${build_TARPIT} += xt_TARPIT.o diff --git a/extensions/compat_rawpost.h b/extensions/compat_rawpost.h new file mode 100644 index 0000000..11c575f --- /dev/null +++ b/extensions/compat_rawpost.h @@ -0,0 +1,87 @@ +#ifndef XTA_COMPAT_RAWPOST_H +#define XTA_COMPAT_RAWPOST_H 1 + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) +typedef struct sk_buff sk_buff_t; +#else +typedef struct sk_buff *sk_buff_t; +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 21) +#define XT_TARGET_INIT(__name, __size) \ +{ \ + .target.u.user = { \ + .target_size = XT_ALIGN(__size), \ + .name = __name, \ + }, \ +} + +#define IPT_ENTRY_INIT(__size) \ +{ \ + .target_offset = sizeof(struct ipt_entry), \ + .next_offset = (__size), \ +} + +#define IPT_STANDARD_INIT(__verdict) \ +{ \ + .entry = IPT_ENTRY_INIT(sizeof(struct ipt_standard)), \ + .target = XT_TARGET_INIT(IPT_STANDARD_TARGET, \ + sizeof(struct xt_standard_target)), \ + .target.verdict = -(__verdict) - 1, \ +} + +#define IPT_ERROR_INIT \ +{ \ + .entry = IPT_ENTRY_INIT(sizeof(struct ipt_error)), \ + .target = XT_TARGET_INIT(IPT_ERROR_TARGET, \ + sizeof(struct ipt_error_target)), \ + .target.errorname = "ERROR", \ +} + +#define IP6T_ENTRY_INIT(__size) \ +{ \ + .target_offset = sizeof(struct ip6t_entry), \ + .next_offset = (__size), \ +} + +#define IP6T_STANDARD_INIT(__verdict) \ +{ \ + .entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_standard)), \ + .target = XT_TARGET_INIT(IP6T_STANDARD_TARGET, \ + sizeof(struct ip6t_standard_target)), \ + .target.verdict = -(__verdict) - 1, \ +} + +#define IP6T_ERROR_INIT \ +{ \ + .entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_error)), \ + .target = XT_TARGET_INIT(IP6T_ERROR_TARGET, \ + sizeof(struct ip6t_error_target)), \ + .target.errorname = "ERROR", \ +} + +#endif /* 2.6.21 */ + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 20) +# include +/* Standard entry */ +struct ip6t_standard +{ + struct ip6t_entry entry; + struct ip6t_standard_target target; +}; + +struct ip6t_error_target +{ + struct ip6t_entry_target target; + char errorname[IP6T_FUNCTION_MAXNAMELEN]; +}; + +struct ip6t_error +{ + struct ip6t_entry entry; + struct ip6t_error_target target; +}; +#endif /* 2.6.20 */ + +#endif /* XTA_COMPAT_RAWPOST_H */ diff --git a/extensions/ip6table_rawpost.c b/extensions/ip6table_rawpost.c new file mode 100644 index 0000000..b76a8ba --- /dev/null +++ b/extensions/ip6table_rawpost.c @@ -0,0 +1,105 @@ +/* + * rawpost table for ip6_tables + * written by Jan Engelhardt , 2008 - 2009 + * placed in the Public Domain + */ +#include +#include +#include +#include "compat_xtables.h" +#include "compat_rawpost.h" + +enum { + RAWPOST_VALID_HOOKS = 1 << NF_INET_POST_ROUTING, +}; + +static struct { + struct ip6t_replace repl; + struct ip6t_standard entries[1]; + struct ip6t_error term; +} rawpost6_initial __initdata = { + .repl = { + .name = "rawpost", + .valid_hooks = RAWPOST_VALID_HOOKS, + .num_entries = 2, + .size = sizeof(struct ip6t_standard) + + sizeof(struct ip6t_error), + .hook_entry = { + [NF_INET_POST_ROUTING] = 0, + }, + .underflow = { + [NF_INET_POST_ROUTING] = 0, + }, + }, + .entries = { + IP6T_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */ + }, + .term = IP6T_ERROR_INIT, /* ERROR */ +}; + +static struct xt_table *rawpost6_ptable; + +static struct xt_table rawpost6_itable = { + .name = "rawpost", + .af = NFPROTO_IPV6, + .valid_hooks = RAWPOST_VALID_HOOKS, + .me = THIS_MODULE, +}; + +static unsigned int rawpost6_hook_fn(unsigned int hook, sk_buff_t *skb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) + return ip6t_do_table(skb, hook, in, out, rawpost6_ptable); +#else + return ip6t_do_table(skb, hook, in, out, rawpost6_ptable, NULL); +#endif +} + +static struct nf_hook_ops rawpost6_hook_ops __read_mostly = { + .hook = rawpost6_hook_fn, + .pf = NFPROTO_IPV6, + .hooknum = NF_INET_POST_ROUTING, + .priority = NF_IP6_PRI_LAST, + .owner = THIS_MODULE, +}; + +static int __init rawpost6_table_init(void) +{ + int ret; + + rwlock_init(&rawpost6_itable.lock); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) + rawpost6_ptable = ip6t_register_table(&init_net, &rawpost6_itable, + &rawpost6_initial.repl); + if (IS_ERR(rawpost6_ptable)) + return PTR_ERR(rawpost6_ptable); +#else + ret = ip6t_register_table(&rawpost6_itable, &rawpost6_initial.repl); + if (ret < 0) + return ret; + rawpost6_ptable = &rawpost6_itable; +#endif + + ret = nf_register_hook(&rawpost6_hook_ops); + if (ret < 0) + goto out; + + return ret; + + out: + ip6t_unregister_table(rawpost6_ptable); + return ret; +} + +static void __exit rawpost6_table_exit(void) +{ + nf_unregister_hook(&rawpost6_hook_ops); + ip6t_unregister_table(rawpost6_ptable); +} + +module_init(rawpost6_table_init); +module_exit(rawpost6_table_exit); +MODULE_AUTHOR("Jan Engelhardt "); +MODULE_LICENSE("GPL"); diff --git a/extensions/iptable_rawpost.c b/extensions/iptable_rawpost.c new file mode 100644 index 0000000..bbb930c --- /dev/null +++ b/extensions/iptable_rawpost.c @@ -0,0 +1,107 @@ +/* + * rawpost table for ip_tables + * written by Jan Engelhardt , 2008 - 2009 + * placed in the Public Domain + */ +#include +#include +#include +#include +#include "compat_xtables.h" +#include "compat_rawpost.h" + +enum { + RAWPOST_VALID_HOOKS = 1 << NF_INET_POST_ROUTING, +}; + +static struct { + struct ipt_replace repl; + struct ipt_standard entries[1]; + struct ipt_error term; +} rawpost4_initial __initdata = { + .repl = { + .name = "rawpost", + .valid_hooks = RAWPOST_VALID_HOOKS, + .num_entries = 2, + .size = sizeof(struct ipt_standard) + + sizeof(struct ipt_error), + .hook_entry = { + [NF_INET_POST_ROUTING] = 0, + }, + .underflow = { + [NF_INET_POST_ROUTING] = 0, + }, + }, + .entries = { + IPT_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */ + }, + .term = IPT_ERROR_INIT, /* ERROR */ +}; + +static struct xt_table *rawpost4_ptable; + +static struct xt_table rawpost4_itable = { + .name = "rawpost", + .af = NFPROTO_IPV4, + .valid_hooks = RAWPOST_VALID_HOOKS, + .me = THIS_MODULE, +}; + +static unsigned int rawpost4_hook_fn(unsigned int hook, sk_buff_t *skb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) + return ipt_do_table(skb, hook, in, out, rawpost4_ptable); +#else + return ipt_do_table(skb, hook, in, out, rawpost4_ptable, NULL); +#endif +} + +static struct nf_hook_ops rawpost4_hook_ops __read_mostly = { + .hook = rawpost4_hook_fn, + .pf = NFPROTO_IPV4, + .hooknum = NF_INET_POST_ROUTING, + .priority = NF_IP_PRI_LAST, + .owner = THIS_MODULE, +}; + +static int __init rawpost4_table_init(void) +{ + int ret; + + rwlock_init(&rawpost4_itable.lock); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) + rawpost4_ptable = ipt_register_table(&init_net, &rawpost4_itable, + &rawpost4_initial.repl); + if (IS_ERR(rawpost4_ptable)) + return PTR_ERR(rawpost4_ptable); +#else + ret = ipt_register_table(&rawpost4_itable, &rawpost4_initial.repl); + if (ret < 0) + return ret; + rawpost4_ptable = &rawpost4_itable; +#endif + + ret = nf_register_hook(&rawpost4_hook_ops); + if (ret < 0) + goto out; + + return ret; + + out: + ipt_unregister_table(rawpost4_ptable); + return ret; +} + +static void __exit rawpost4_table_exit(void) +{ + nf_unregister_hook(&rawpost4_hook_ops); + ipt_unregister_table(rawpost4_ptable); +} + +module_init(rawpost4_table_init); +module_exit(rawpost4_table_exit); +MODULE_DESCRIPTION("Xtables: rawpost table for use with RAWNAT"); +MODULE_AUTHOR("Jan Engelhardt "); +MODULE_LICENSE("GPL"); diff --git a/mconfig b/mconfig index ac7e135..dfa46c4 100644 --- a/mconfig +++ b/mconfig @@ -6,6 +6,7 @@ build_DHCPMAC=m build_ECHO= build_IPMARK=m build_LOGMARK=m +build_RAWNAT=m build_STEAL=m build_SYSRQ=m build_TARPIT=m