From 146aa6772bdd87b14a91ac0a50df80a79a0ab7f8 Mon Sep 17 00:00:00 2001 From: Thomas Jarosch Date: Tue, 13 Feb 2007 16:07:02 +0000 Subject: [PATCH] ipt_ACCOUNT: (tomj) fix for kernel >= 2.6.19, compat glue for older kernels, simplified iptables patching --- iptables.patch | 190 ---------------------------- iptables/extensions/.ACCOUNT-test | 3 + iptables/extensions/libipt_ACCOUNT.c | 174 +++++++++++++++++++++++++ linux-2.6/net/ipv4/netfilter/ipt_ACCOUNT.c | 37 ++++++- 4 files changed, 213 insertions(+), 191 deletions(-) delete mode 100644 iptables.patch create mode 100755 iptables/extensions/.ACCOUNT-test create mode 100644 iptables/extensions/libipt_ACCOUNT.c diff --git a/iptables.patch b/iptables.patch deleted file mode 100644 index 8eb594e..0000000 --- a/iptables.patch +++ /dev/null @@ -1,190 +0,0 @@ -diff -u -r -p --new-file iptables-1.3.6/extensions/libipt_ACCOUNT.c iptables.ACCOUNT/extensions/libipt_ACCOUNT.c ---- iptables-1.3.6/extensions/libipt_ACCOUNT.c 1970-01-01 01:00:00.000000000 +0100 -+++ iptables.ACCOUNT/extensions/libipt_ACCOUNT.c 2006-10-26 12:17:57.000000000 +0200 -@@ -0,0 +1,174 @@ -+/* Shared library add-on to iptables to add ACCOUNT(ing) support. -+ Author: Intra2net AG -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static struct option opts[] = { -+ { .name = "addr", .has_arg = 1, .flag = 0, .val = 'a' }, -+ { .name = "tname", .has_arg = 1, .flag = 0, .val = 't' }, -+ { .name = 0 } -+}; -+ -+/* Function which prints out usage message. */ -+static void help(void) -+{ -+ printf( -+"ACCOUNT v%s options:\n" -+" --%s ip/netmask\t\tBase network IP and netmask used for this table\n" -+" --%s name\t\t\tTable name for the userspace library\n", -+IPTABLES_VERSION, opts[0].name, opts[1].name); -+} -+ -+/* Initialize the target. */ -+static void -+init(struct ipt_entry_target *t, unsigned int *nfcache) -+{ -+ struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)t->data; -+ -+ accountinfo->table_nr = -1; -+ -+ /* Can't cache this */ -+ *nfcache |= NFC_UNKNOWN; -+} -+ -+#define IPT_ACCOUNT_OPT_ADDR 0x01 -+#define IPT_ACCOUNT_OPT_TABLE 0x02 -+ -+/* Function which parses command options; returns true if it -+ ate an option */ -+static int -+parse(int c, char **argv, int invert, unsigned int *flags, -+ const struct ipt_entry *entry, -+ struct ipt_entry_target **target) -+{ -+ struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)(*target)->data; -+ struct in_addr *addrs = NULL, mask; -+ unsigned int naddrs = 0; -+ -+ switch (c) { -+ case 'a': -+ if (*flags & IPT_ACCOUNT_OPT_ADDR) -+ exit_error(PARAMETER_PROBLEM, "Can't specify --%s twice", -+ opts[0].name); -+ -+ if (check_inverse(optarg, &invert, NULL, 0)) -+ exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --%s", -+ opts[0].name); -+ -+ //loginfo->level = parse_level(optarg); -+ parse_hostnetworkmask(optarg, &addrs, &mask, &naddrs); -+ -+ if (naddrs > 1) -+ exit_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed"); -+ -+ accountinfo->net_ip = addrs[0].s_addr; -+ accountinfo->net_mask = mask.s_addr; -+ -+ *flags |= IPT_ACCOUNT_OPT_ADDR; -+ break; -+ -+ case 't': -+ if (*flags & IPT_ACCOUNT_OPT_TABLE) -+ exit_error(PARAMETER_PROBLEM, -+ "Can't specify --%s twice", opts[1].name); -+ -+ if (check_inverse(optarg, &invert, NULL, 0)) -+ exit_error(PARAMETER_PROBLEM, -+ "Unexpected `!' after --%s", opts[1].name); -+ -+ if (strlen(optarg) > ACCOUNT_TABLE_NAME_LEN - 1) -+ exit_error(PARAMETER_PROBLEM, -+ "Maximum table name length %u for --%s", -+ ACCOUNT_TABLE_NAME_LEN - 1, opts[1].name); -+ -+ strcpy(accountinfo->table_name, optarg); -+ *flags |= IPT_ACCOUNT_OPT_TABLE; -+ break; -+ -+ default: -+ return 0; -+ } -+ return 1; -+} -+ -+/* Final check; nothing. */ -+static void final_check(unsigned int flags) -+{ -+ if (!(flags&IPT_ACCOUNT_OPT_ADDR) || !(flags&IPT_ACCOUNT_OPT_TABLE)) -+ exit_error(PARAMETER_PROBLEM, "ACCOUNT: needs --%s and --%s", -+ opts[0].name, opts[1].name); -+} -+ -+static void print_it(const struct ipt_ip *ip, -+ const struct ipt_entry_target *target, char do_prefix) -+{ -+ const struct ipt_acc_info *accountinfo -+ = (const struct ipt_acc_info *)target->data; -+ struct in_addr a; -+ -+ if (!do_prefix) -+ printf("ACCOUNT "); -+ -+ // Network information -+ if (do_prefix) -+ printf("--"); -+ printf("%s ", opts[0].name); -+ -+ a.s_addr = accountinfo->net_ip; -+ printf("%s", addr_to_dotted(&a)); -+ a.s_addr = accountinfo->net_mask; -+ printf("%s", mask_to_dotted(&a)); -+ -+ printf(" "); -+ if (do_prefix) -+ printf("--"); -+ -+ printf("%s %s", opts[1].name, accountinfo->table_name); -+} -+ -+/* Prints out the targinfo. */ -+static void -+print(const struct ipt_ip *ip, -+ const struct ipt_entry_target *target, -+ int numeric) -+{ -+ print_it (ip, target, 0); -+} -+ -+/* Saves the union ipt_targinfo in parsable form to stdout. */ -+static void -+save(const struct ipt_ip *ip, const struct ipt_entry_target *target) -+{ -+ print_it(ip, target, 1); -+} -+ -+static -+struct iptables_target account -+= { -+ .next = NULL, -+ .name = "ACCOUNT", -+ .version = IPTABLES_VERSION, -+ .size = IPT_ALIGN(sizeof(struct ipt_acc_info)), -+ .userspacesize = IPT_ALIGN(sizeof(struct ipt_acc_info)), -+ .help = &help, -+ .init = &init, -+ .parse = &parse, -+ .final_check = &final_check, -+ .print = &print, -+ .save = &save, -+ .extra_opts = opts -+}; -+ -+void _init(void) -+{ -+ register_target(&account); -+} -diff -u -r -p --new-file iptables-1.3.6/extensions/Makefile iptables.ACCOUNT/extensions/Makefile ---- iptables-1.3.6/extensions/Makefile 2006-09-28 18:40:32.000000000 +0200 -+++ iptables.ACCOUNT/extensions/Makefile 2007-02-09 11:31:24.000000000 +0100 -@@ -5,7 +5,7 @@ - # header files are present in the include/linux directory of this iptables - # package (HW) - # --PF_EXT_SLIB:=ah addrtype comment connlimit connmark conntrack dscp ecn esp hashlimit helper icmp iprange length limit mac mark multiport owner physdev pkttype policy realm rpc sctp standard state tcp tcpmss tos ttl udp unclean CLASSIFY CONNMARK DNAT DSCP ECN LOG MARK MASQUERADE MIRROR NETMAP NFQUEUE NOTRACK REDIRECT REJECT SAME SNAT TARPIT TCPMSS TOS TRACE TTL ULOG -+PF_EXT_SLIB:=ah addrtype comment connlimit connmark conntrack dscp ecn esp hashlimit helper icmp iprange length limit mac mark multiport owner physdev pkttype policy realm rpc sctp standard state tcp tcpmss tos ttl udp unclean ACCOUNT CLASSIFY CONNMARK DNAT DSCP ECN LOG MARK MASQUERADE MIRROR NETMAP NFQUEUE NOTRACK REDIRECT REJECT SAME SNAT TARPIT TCPMSS TOS TRACE TTL ULOG - PF6_EXT_SLIB:=connmark eui64 hl icmp6 length limit mac mark multiport owner physdev policy standard state tcp udp CONNMARK HL LOG NFQUEUE MARK TRACE - - ifeq ($(DO_SELINUX), 1) diff --git a/iptables/extensions/.ACCOUNT-test b/iptables/extensions/.ACCOUNT-test new file mode 100755 index 0000000..ab839f3 --- /dev/null +++ b/iptables/extensions/.ACCOUNT-test @@ -0,0 +1,3 @@ +#!/bin/sh +# True if ACCOUNT is applied. +[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_ACCOUNT.h ] && echo ACCOUNT diff --git a/iptables/extensions/libipt_ACCOUNT.c b/iptables/extensions/libipt_ACCOUNT.c new file mode 100644 index 0000000..084c31f --- /dev/null +++ b/iptables/extensions/libipt_ACCOUNT.c @@ -0,0 +1,174 @@ +/* Shared library add-on to iptables to add ACCOUNT(ing) support. + Author: Intra2net AG +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct option opts[] = { + { .name = "addr", .has_arg = 1, .flag = 0, .val = 'a' }, + { .name = "tname", .has_arg = 1, .flag = 0, .val = 't' }, + { .name = 0 } +}; + +/* Function which prints out usage message. */ +static void help(void) +{ + printf( +"ACCOUNT v%s options:\n" +" --%s ip/netmask\t\tBase network IP and netmask used for this table\n" +" --%s name\t\t\tTable name for the userspace library\n", +IPTABLES_VERSION, opts[0].name, opts[1].name); +} + +/* Initialize the target. */ +static void +init(struct ipt_entry_target *t, unsigned int *nfcache) +{ + struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)t->data; + + accountinfo->table_nr = -1; + + /* Can't cache this */ + *nfcache |= NFC_UNKNOWN; +} + +#define IPT_ACCOUNT_OPT_ADDR 0x01 +#define IPT_ACCOUNT_OPT_TABLE 0x02 + +/* Function which parses command options; returns true if it + ate an option */ +static int +parse(int c, char **argv, int invert, unsigned int *flags, + const struct ipt_entry *entry, + struct ipt_entry_target **target) +{ + struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)(*target)->data; + struct in_addr *addrs = NULL, mask; + unsigned int naddrs = 0; + + switch (c) { + case 'a': + if (*flags & IPT_ACCOUNT_OPT_ADDR) + exit_error(PARAMETER_PROBLEM, "Can't specify --%s twice", + opts[0].name); + + if (check_inverse(optarg, &invert, NULL, 0)) + exit_error(PARAMETER_PROBLEM, "Unexpected `!' after --%s", + opts[0].name); + + //loginfo->level = parse_level(optarg); + parse_hostnetworkmask(optarg, &addrs, &mask, &naddrs); + + if (naddrs > 1) + exit_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed"); + + accountinfo->net_ip = addrs[0].s_addr; + accountinfo->net_mask = mask.s_addr; + + *flags |= IPT_ACCOUNT_OPT_ADDR; + break; + + case 't': + if (*flags & IPT_ACCOUNT_OPT_TABLE) + exit_error(PARAMETER_PROBLEM, + "Can't specify --%s twice", opts[1].name); + + if (check_inverse(optarg, &invert, NULL, 0)) + exit_error(PARAMETER_PROBLEM, + "Unexpected `!' after --%s", opts[1].name); + + if (strlen(optarg) > ACCOUNT_TABLE_NAME_LEN - 1) + exit_error(PARAMETER_PROBLEM, + "Maximum table name length %u for --%s", + ACCOUNT_TABLE_NAME_LEN - 1, opts[1].name); + + strcpy(accountinfo->table_name, optarg); + *flags |= IPT_ACCOUNT_OPT_TABLE; + break; + + default: + return 0; + } + return 1; +} + +/* Final check; nothing. */ +static void final_check(unsigned int flags) +{ + if (!(flags&IPT_ACCOUNT_OPT_ADDR) || !(flags&IPT_ACCOUNT_OPT_TABLE)) + exit_error(PARAMETER_PROBLEM, "ACCOUNT: needs --%s and --%s", + opts[0].name, opts[1].name); +} + +static void print_it(const struct ipt_ip *ip, + const struct ipt_entry_target *target, char do_prefix) +{ + const struct ipt_acc_info *accountinfo + = (const struct ipt_acc_info *)target->data; + struct in_addr a; + + if (!do_prefix) + printf("ACCOUNT "); + + // Network information + if (do_prefix) + printf("--"); + printf("%s ", opts[0].name); + + a.s_addr = accountinfo->net_ip; + printf("%s", addr_to_dotted(&a)); + a.s_addr = accountinfo->net_mask; + printf("%s", mask_to_dotted(&a)); + + printf(" "); + if (do_prefix) + printf("--"); + + printf("%s %s", opts[1].name, accountinfo->table_name); +} + +/* Prints out the targinfo. */ +static void +print(const struct ipt_ip *ip, + const struct ipt_entry_target *target, + int numeric) +{ + print_it (ip, target, 0); +} + +/* Saves the union ipt_targinfo in parsable form to stdout. */ +static void +save(const struct ipt_ip *ip, const struct ipt_entry_target *target) +{ + print_it(ip, target, 1); +} + +static +struct iptables_target account += { + .next = NULL, + .name = "ACCOUNT", + .version = IPTABLES_VERSION, + .size = IPT_ALIGN(sizeof(struct ipt_acc_info)), + .userspacesize = IPT_ALIGN(sizeof(struct ipt_acc_info)), + .help = &help, + .init = &init, + .parse = &parse, + .final_check = &final_check, + .print = &print, + .save = &save, + .extra_opts = opts +}; + +void _init(void) +{ + register_target(&account); +} diff --git a/linux-2.6/net/ipv4/netfilter/ipt_ACCOUNT.c b/linux-2.6/net/ipv4/netfilter/ipt_ACCOUNT.c index 78f2bb3..3cd8a61 100644 --- a/linux-2.6/net/ipv4/netfilter/ipt_ACCOUNT.c +++ b/linux-2.6/net/ipv4/netfilter/ipt_ACCOUNT.c @@ -188,15 +188,31 @@ static int ipt_acc_table_insert(char *name, u_int32_t ip, u_int32_t netmask) } static int ipt_acc_checkentry(const char *tablename, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) const void *e, +#else + const struct ipt_entry *e, +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) const struct xt_target *target, +#endif void *targinfo, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) unsigned int targinfosize, +#endif unsigned int hook_mask) { struct ipt_acc_info *info = targinfo; int table_nr; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17) + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_acc_info))) { + DEBUGP("ACCOUNT: targinfosize %u != %u\n", + targinfosize, IPT_ALIGN(sizeof(struct ipt_acc_info))); + return 0; + } +#endif + spin_lock_bh(&ipt_acc_lock); table_nr = ipt_acc_table_insert(info->table_name, info->net_ip, info->net_mask); @@ -213,15 +229,26 @@ static int ipt_acc_checkentry(const char *tablename, return 1; } -static void ipt_acc_destroy(const struct xt_target *target, void *targinfo, unsigned int targinfosize) +static void ipt_acc_destroy( +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) + const struct xt_target *target, +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19) + void *targinfo) +#else + void *targinfo, + unsigned int targinfosize) +#endif { unsigned int i; struct ipt_acc_info *info = targinfo; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17) if (targinfosize != IPT_ALIGN(sizeof(struct ipt_acc_info))) { DEBUGP("ACCOUNT: targinfosize %u != %u\n", targinfosize, IPT_ALIGN(sizeof(struct ipt_acc_info))); } +#endif spin_lock_bh(&ipt_acc_lock); @@ -413,9 +440,15 @@ static unsigned int ipt_acc_target(struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, unsigned int hooknum, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) const struct xt_target *target, +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19) + const void *targinfo) +#else const void *targinfo, void *userinfo) +#endif { const struct ipt_acc_info *info = (const struct ipt_acc_info *)targinfo; @@ -1020,7 +1053,9 @@ static int ipt_acc_get_ctl(struct sock *sk, int cmd, void *user, int *len) static struct ipt_target ipt_acc_reg = { .name = "ACCOUNT", .target = ipt_acc_target, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) .targetsize = sizeof(struct ipt_acc_info), +#endif .checkentry = ipt_acc_checkentry, .destroy = ipt_acc_destroy, .me = THIS_MODULE -- 1.7.1