diff options
Diffstat (limited to 'target/linux')
20 files changed, 3164 insertions, 2844 deletions
| diff --git a/target/linux/generic-2.4/patches/602-netfilter_layer7_2.1nbd.patch b/target/linux/generic-2.4/patches/602-netfilter_layer7_2.17_with_pktmatch.patch index 301a3a79f..cfbca5331 100644 --- a/target/linux/generic-2.4/patches/602-netfilter_layer7_2.1nbd.patch +++ b/target/linux/generic-2.4/patches/602-netfilter_layer7_2.17_with_pktmatch.patch @@ -69,9 +69,9 @@ Index: linux-2.4.35.4/include/linux/netfilter_ipv4/ipt_layer7.h  +  +struct ipt_layer7_info {  +    char protocol[MAX_PROTOCOL_LEN]; -+    char invert:1;  +    char pattern[MAX_PATTERN_LEN]; -+    char pkt; ++    u_int8_t invert; ++    u_int8_t pkt;  +};  +  +#endif /* _IPT_LAYER7_H */ diff --git a/target/linux/generic-2.6/config-2.6.22 b/target/linux/generic-2.6/config-2.6.22 index f18508eb1..c91d1e338 100644 --- a/target/linux/generic-2.6/config-2.6.22 +++ b/target/linux/generic-2.6/config-2.6.22 @@ -558,8 +558,6 @@ CONFIG_IP_NF_MATCH_ECN=m  CONFIG_IP_NF_MATCH_HASHLIMIT=m  CONFIG_IP_NF_MATCH_IPP2P=m  CONFIG_IP_NF_MATCH_IPRANGE=m -CONFIG_IP_NF_MATCH_LAYER7=m -# CONFIG_IP_NF_MATCH_LAYER7_DEBUG is not set  CONFIG_IP_NF_MATCH_OWNER=m  CONFIG_IP_NF_MATCH_RECENT=m  CONFIG_IP_NF_MATCH_SET=m @@ -745,6 +743,8 @@ CONFIG_NETFILTER_XT_MATCH_PORTSCAN=m  CONFIG_NETFILTER_XT_MATCH_REALM=m  CONFIG_NETFILTER_XT_MATCH_SCTP=m  CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_LAYER7=m +# CONFIG_NETFILTER_XT_MATCH_LAYER7_DEBUG is not set  # CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set  CONFIG_NETFILTER_XT_MATCH_STRING=m  CONFIG_NETFILTER_XT_MATCH_TCPMSS=m diff --git a/target/linux/generic-2.6/config-default b/target/linux/generic-2.6/config-default index d814b01b7..cbef53671 100644 --- a/target/linux/generic-2.6/config-default +++ b/target/linux/generic-2.6/config-default @@ -533,8 +533,6 @@ CONFIG_IP_NF_MATCH_ECN=m  CONFIG_IP_NF_MATCH_HASHLIMIT=m  CONFIG_IP_NF_MATCH_IPP2P=m  CONFIG_IP_NF_MATCH_IPRANGE=m -CONFIG_IP_NF_MATCH_LAYER7=m -# CONFIG_IP_NF_MATCH_LAYER7_DEBUG is not set  CONFIG_IP_NF_MATCH_OWNER=m  CONFIG_IP_NF_MATCH_RECENT=m  CONFIG_IP_NF_MATCH_SET=m @@ -713,6 +711,8 @@ CONFIG_NETFILTER_XT_MATCH_PORTSCAN=m  CONFIG_NETFILTER_XT_MATCH_REALM=m  CONFIG_NETFILTER_XT_MATCH_SCTP=m  CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_LAYER7=m +# CONFIG_NETFILTER_XT_MATCH_LAYER7_DEBUG is not set  # CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set  CONFIG_NETFILTER_XT_MATCH_STRING=m  CONFIG_NETFILTER_XT_MATCH_TCPMSS=y diff --git a/target/linux/generic-2.6/patches-2.6.22/100-netfilter_layer7_2.9.patch b/target/linux/generic-2.6/patches-2.6.22/100-netfilter_layer7_2.17.patch index 0b16a3031..bfac6801a 100644 --- a/target/linux/generic-2.6/patches-2.6.22/100-netfilter_layer7_2.9.patch +++ b/target/linux/generic-2.6/patches-2.6.22/100-netfilter_layer7_2.17.patch @@ -1,80 +1,58 @@ -Index: linux-2.6.22-rc6/include/linux/netfilter_ipv4/ipt_layer7.h +Index: linux-2.6.22.18/net/netfilter/Kconfig  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc6/include/linux/netfilter_ipv4/ipt_layer7.h	2007-07-02 03:43:29.440242750 +0200 -@@ -0,0 +1,26 @@ -+/* -+  By Matthew Strait <quadong@users.sf.net>, Dec 2003. -+  http://l7-filter.sf.net -+ -+  This program is free software; you can redistribute it and/or -+  modify it under the terms of the GNU General Public License -+  as published by the Free Software Foundation; either version -+  2 of the License, or (at your option) any later version. -+  http://www.gnu.org/licenses/gpl.txt -+*/ -+ -+#ifndef _IPT_LAYER7_H -+#define _IPT_LAYER7_H -+ -+#define MAX_PATTERN_LEN 8192 -+#define MAX_PROTOCOL_LEN 256 +--- linux-2.6.22.18.orig/net/netfilter/Kconfig ++++ linux-2.6.22.18/net/netfilter/Kconfig +@@ -603,6 +603,27 @@ config NETFILTER_XT_MATCH_STATE +  + 	  To compile it as a module, choose M here.  If unsure, say N. +  ++config NETFILTER_XT_MATCH_LAYER7 ++	tristate '"layer7" match support' ++	depends on NETFILTER_XTABLES ++	depends on EXPERIMENTAL && (IP_NF_CONNTRACK || NF_CONNTRACK) ++       depends on NF_CT_ACCT ++	help ++	  Say Y if you want to be able to classify connections (and their ++	  packets) based on regular expression matching of their application ++	  layer data.   This is one way to classify applications such as ++	  peer-to-peer filesharing systems that do not always use the same ++	  port.  + -+typedef char *(*proc_ipt_search) (char *, char, char *); ++	  To compile it as a module, choose M here.  If unsure, say N.  + -+struct ipt_layer7_info { -+    char protocol[MAX_PROTOCOL_LEN]; -+    char invert:1; -+    char pattern[MAX_PATTERN_LEN]; -+}; ++config NETFILTER_XT_MATCH_LAYER7_DEBUG ++        bool 'Layer 7 debugging output' ++        depends on NETFILTER_XT_MATCH_LAYER7 ++        help ++          Say Y to get lots of debugging output.  + -+#endif /* _IPT_LAYER7_H */ -Index: linux-2.6.22-rc6/net/netfilter/nf_conntrack_core.c -=================================================================== ---- linux-2.6.22-rc6.orig/net/netfilter/nf_conntrack_core.c	2007-07-02 02:16:21.833537750 +0200 -+++ linux-2.6.22-rc6/net/netfilter/nf_conntrack_core.c	2007-07-02 02:16:23.497641750 +0200 -@@ -330,6 +330,13 @@ - 	 * too. */ - 	nf_ct_remove_expectations(ct); -  -+	#if defined(CONFIG_IP_NF_MATCH_LAYER7) || defined(CONFIG_IP_NF_MATCH_LAYER7_MODULE) -+	if(ct->layer7.app_proto) -+		kfree(ct->layer7.app_proto); -+	if(ct->layer7.app_data) -+		kfree(ct->layer7.app_data); -+	#endif  + - 	/* We overload first tuple to link into unconfirmed list. */ - 	if (!nf_ct_is_confirmed(ct)) { - 		BUG_ON(list_empty(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list)); -Index: linux-2.6.22-rc6/net/netfilter/nf_conntrack_standalone.c + config NETFILTER_XT_MATCH_STATISTIC + 	tristate '"statistic" match support' + 	depends on NETFILTER_XTABLES +Index: linux-2.6.22.18/net/netfilter/Makefile  =================================================================== ---- linux-2.6.22-rc6.orig/net/netfilter/nf_conntrack_standalone.c	2007-07-02 02:16:21.845538500 +0200 -+++ linux-2.6.22-rc6/net/netfilter/nf_conntrack_standalone.c	2007-07-02 02:16:23.521643250 +0200 -@@ -184,6 +184,12 @@ - 		return -ENOSPC; - #endif -  -+#if defined(CONFIG_IP_NF_MATCH_LAYER7) || defined(CONFIG_IP_NF_MATCH_LAYER7_MODULE) -+	if(conntrack->layer7.app_proto) -+		if (seq_printf(s, "l7proto=%s ",conntrack->layer7.app_proto)) -+			return 1; -+#endif -+ - 	if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use))) - 		return -ENOSPC; - 	 -Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c +--- linux-2.6.22.18.orig/net/netfilter/Makefile ++++ linux-2.6.22.18/net/netfilter/Makefile +@@ -68,6 +68,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) + + obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o + obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o + obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o ++obj-$(CONFIG_NETFILTER_XT_MATCH_LAYER7) += xt_layer7.o + obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o + obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o + obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o +Index: linux-2.6.22.18/net/netfilter/xt_layer7.c  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c	2007-07-02 03:43:44.341174000 +0200 -@@ -0,0 +1,583 @@ +--- /dev/null ++++ linux-2.6.22.18/net/netfilter/xt_layer7.c +@@ -0,0 +1,634 @@  +/*  +  Kernel module to match application layer (OSI layer 7) data in connections.  +  +  http://l7-filter.sf.net  + -+  By Matthew Strait and Ethan Sommer, 2003-2006. ++  (C) 2003, 2004, 2005, 2006, 2007 Matthew Strait and Ethan Sommer.  +  +  This program is free software; you can redistribute it and/or  +  modify it under the terms of the GNU General Public License @@ -82,37 +60,37 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  +  2 of the License, or (at your option) any later version.  +  http://www.gnu.org/licenses/gpl.txt  + -+  Based on ipt_string.c (C) 2000 Emmanuel Roger <winfield@freegates.be> -+  and cls_layer7.c (C) 2003 Matthew Strait, Ethan Sommer, Justin Levandoski -+ -+  Jan Engelhardt, 2007-03-11: Arrange to compile with nf_conntrack ++  Based on ipt_string.c (C) 2000 Emmanuel Roger <winfield@freegates.be>, ++  xt_helper.c (C) 2002 Harald Welte and cls_layer7.c (C) 2003 Matthew Strait, ++  Ethan Sommer, Justin Levandoski.  +*/  + -+#include <linux/module.h> -+#include <linux/skbuff.h> -+#include <linux/proc_fs.h> -+#include <linux/ctype.h> ++#include <linux/spinlock.h> ++#include <linux/version.h>  +#include <net/ip.h>  +#include <net/tcp.h> ++#include <linux/module.h> ++#include <linux/skbuff.h> ++#include <linux/netfilter.h>  +#include <net/netfilter/nf_conntrack.h> -+#include <net/netfilter/nf_nat_rule.h> -+#include <linux/spinlock.h> ++#include <net/netfilter/nf_conntrack_core.h> ++#include <linux/netfilter/x_tables.h> ++#include <linux/netfilter/xt_layer7.h> ++#include <linux/ctype.h> ++#include <linux/proc_fs.h>  +  +#include "regexp/regexp.c"  + -+#include <linux/netfilter_ipv4/ipt_layer7.h> -+#include <linux/netfilter_ipv4/ip_tables.h> -+ -+MODULE_AUTHOR("Matthew Strait <quadong@users.sf.net>, Ethan Sommer <sommere@users.sf.net>");  +MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Matthew Strait <quadong@users.sf.net>, Ethan Sommer <sommere@users.sf.net>");  +MODULE_DESCRIPTION("iptables application layer match module"); -+MODULE_VERSION("2.0"); ++MODULE_ALIAS("ipt_layer7"); ++MODULE_VERSION("2.17");  +  +static int maxdatalen = 2048; // this is the default  +module_param(maxdatalen, int, 0444);  +MODULE_PARM_DESC(maxdatalen, "maximum bytes of data looked at by l7-filter"); -+ -+#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG ++#ifdef CONFIG_NETFILTER_XT_MATCH_LAYER7_DEBUG  +	#define DPRINTK(format,args...) printk(format,##args)  +#else  +	#define DPRINTK(format,args...) @@ -131,23 +109,7 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  +	struct pattern_cache * next;  +} * first_pattern_cache = NULL;  + -+/* I'm new to locking.  Here are my assumptions: -+ -+- No one will write to /proc/net/layer7_numpackets over and over very fast; -+  if they did, nothing awful would happen. -+ -+- This code will never be processing the same packet twice at the same time, -+  because iptables rules are traversed in order. -+ -+- It doesn't matter if two packets from different connections are in here at -+  the same time, because they don't share any data. -+ -+- It _does_ matter if two packets from the same connection (or one from a -+  master and one from its child) are here at the same time.  In this case, -+  we have to protect the conntracks and the list of compiled patterns. -+*/ -+DEFINE_RWLOCK(ct_lock); -+DEFINE_SPINLOCK(list_lock); ++DEFINE_SPINLOCK(l7_lock);  +  +#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG  +/* Converts an unfriendly string into a friendly one by @@ -159,7 +121,8 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  +  +	if(!f) {  +		if (net_ratelimit()) -+			printk(KERN_ERR "layer7: out of memory in friendly_print, bailing.\n"); ++			printk(KERN_ERR "layer7: out of memory in " ++					"friendly_print, bailing.\n");  +		return NULL;  +	}  + @@ -176,14 +139,14 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  +{  +	switch (i) {  +		case 0 ... 9: -+			return (char)(i + '0'); ++			return (i + '0');  +			break;  +		case 10 ... 15: -+			return (char)(i - 10 + 'a'); ++			return (i - 10 + 'a');  +			break;  +		default:  +			if (net_ratelimit()) -+				printk("Problem in dec2hex\n"); ++				printk("layer7: Problem in dec2hex\n");  +			return '\0';  +	}  +} @@ -195,7 +158,8 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  +  +	if(!g) {  +	       if (net_ratelimit()) -+			printk(KERN_ERR "layer7: out of memory in hex_print, bailing.\n"); ++			printk(KERN_ERR "layer7: out of memory in hex_print, " ++					"bailing.\n");  +	       return NULL;  +	}  + @@ -212,7 +176,8 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  +  +/* Use instead of regcomp.  As we expect to be seeing the same regexps over and  +over again, it make sense to cache the results. */ -+static regexp * compile_and_cache(char * regex_string, char * protocol) ++static regexp * compile_and_cache(const char * regex_string,  ++                                  const char * protocol)  +{  +	struct pattern_cache * node               = first_pattern_cache;  +	struct pattern_cache * last_pattern_cache = first_pattern_cache; @@ -234,7 +199,8 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  +  +	if(!tmp) {  +		if (net_ratelimit()) -+			printk(KERN_ERR "layer7: out of memory in compile_and_cache, bailing.\n"); ++			printk(KERN_ERR "layer7: out of memory in " ++					"compile_and_cache, bailing.\n");  +		return NULL;  +	}  + @@ -244,7 +210,8 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  +  +	if(!tmp->regex_string || !tmp->pattern) {  +		if (net_ratelimit()) -+			printk(KERN_ERR "layer7: out of memory in compile_and_cache, bailing.\n"); ++			printk(KERN_ERR "layer7: out of memory in " ++					"compile_and_cache, bailing.\n");  +		kfree(tmp->regex_string);  +		kfree(tmp->pattern);  +		kfree(tmp); @@ -262,10 +229,12 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  +	/* copy the string and compile the regex */  +	len = strlen(regex_string);  +	DPRINTK("About to compile this: \"%s\"\n", regex_string); -+	node->pattern = regcomp(regex_string, &len); ++	node->pattern = regcomp((char *)regex_string, &len);  +	if ( !node->pattern ) {  +		if (net_ratelimit()) -+			printk(KERN_ERR "layer7: Error compiling regexp \"%s\" (%s)\n", regex_string, protocol); ++			printk(KERN_ERR "layer7: Error compiling regexp " ++					"\"%s\" (%s)\n",  ++					regex_string, protocol);  +		/* pattern is now cached as NULL, so we won't try again. */  +	}  + @@ -305,25 +274,30 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  +		return ip_hl + 8; /* ICMP header is 8 bytes */  +	} else {  +		if (net_ratelimit()) -+			printk(KERN_ERR "layer7: tried to handle unknown protocol!\n"); ++			printk(KERN_ERR "layer7: tried to handle unknown " ++					"protocol!\n");  +		return ip_hl + 8; /* something reasonable */  +	}  +}  +  +/* handles whether there's a match when we aren't appending data anymore */ -+static int match_no_append(struct nf_conn * conntrack, struct nf_conn * master_conntrack, -+			enum ip_conntrack_info ctinfo, enum ip_conntrack_info master_ctinfo, -+			struct ipt_layer7_info * info) ++static int match_no_append(struct nf_conn * conntrack,  ++                           struct nf_conn * master_conntrack,  ++                           enum ip_conntrack_info ctinfo, ++                           enum ip_conntrack_info master_ctinfo, ++                           const struct xt_layer7_info * info)  +{  +	/* If we're in here, throw the app data away */ -+	write_lock(&ct_lock);  +	if(master_conntrack->layer7.app_data != NULL) {  +  +	#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG  +		if(!master_conntrack->layer7.app_proto) { -+			char * f = friendly_print(master_conntrack->layer7.app_data); -+			char * g = hex_print(master_conntrack->layer7.app_data); -+			DPRINTK("\nl7-filter gave up after %d bytes (%d packets):\n%s\n", ++			char * f =  ++			  friendly_print(master_conntrack->layer7.app_data); ++			char * g =  ++			  hex_print(master_conntrack->layer7.app_data); ++			DPRINTK("\nl7-filter gave up after %d bytes " ++				"(%d packets):\n%s\n",  +				strlen(f), TOTAL_PACKETS, f);  +			kfree(f);  +			DPRINTK("In hex: %s\n", g); @@ -334,53 +308,54 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  +		kfree(master_conntrack->layer7.app_data);  +		master_conntrack->layer7.app_data = NULL; /* don't free again */  +	} -+	write_unlock(&ct_lock);  +  +	if(master_conntrack->layer7.app_proto){ -+		/* Here child connections set their .app_proto (for /proc/net/ip_conntrack) */ -+		write_lock(&ct_lock); ++		/* Here child connections set their .app_proto (for /proc) */  +		if(!conntrack->layer7.app_proto) { -+			conntrack->layer7.app_proto = kmalloc(strlen(master_conntrack->layer7.app_proto)+1, GFP_ATOMIC); ++			conntrack->layer7.app_proto =  ++			  kmalloc(strlen(master_conntrack->layer7.app_proto)+1,  ++			    GFP_ATOMIC);  +			if(!conntrack->layer7.app_proto){  +				if (net_ratelimit()) -+					printk(KERN_ERR "layer7: out of memory in match_no_append, bailing.\n"); -+				write_unlock(&ct_lock); ++					printk(KERN_ERR "layer7: out of memory " ++							"in match_no_append, " ++							"bailing.\n");  +				return 1;  +			} -+			strcpy(conntrack->layer7.app_proto, master_conntrack->layer7.app_proto); ++			strcpy(conntrack->layer7.app_proto,  ++				master_conntrack->layer7.app_proto);  +		} -+		write_unlock(&ct_lock);  + -+		return (!strcmp(master_conntrack->layer7.app_proto, info->protocol)); ++		return (!strcmp(master_conntrack->layer7.app_proto,  ++				info->protocol));  +	}  +	else {  +		/* If not classified, set to "unknown" to distinguish from  +		connections that are still being tested. */ -+		write_lock(&ct_lock); -+		master_conntrack->layer7.app_proto = kmalloc(strlen("unknown")+1, GFP_ATOMIC); ++		master_conntrack->layer7.app_proto =  ++			kmalloc(strlen("unknown")+1, GFP_ATOMIC);  +		if(!master_conntrack->layer7.app_proto){  +			if (net_ratelimit()) -+				printk(KERN_ERR "layer7: out of memory in match_no_append, bailing.\n"); -+			write_unlock(&ct_lock); ++				printk(KERN_ERR "layer7: out of memory in " ++						"match_no_append, bailing.\n");  +			return 1;  +		}  +		strcpy(master_conntrack->layer7.app_proto, "unknown"); -+		write_unlock(&ct_lock);  +		return 0;  +	}  +}  +  +/* add the new app data to the conntrack.  Return number of bytes added. */  +static int add_data(struct nf_conn * master_conntrack, -+			char * app_data, int appdatalen) ++                    char * app_data, int appdatalen)  +{  +	int length = 0, i;  +	int oldlength = master_conntrack->layer7.app_data_len;  + -+	// This is a fix for a race condition by Deti Fliegl. However, I'm not -+	// clear on whether the race condition exists or whether this really -+	// fixes it.  I might just be being dense... Anyway, if it's not really -+	// a fix, all it does is waste a very small amount of time. ++	/* This is a fix for a race condition by Deti Fliegl. However, I'm not  ++	   clear on whether the race condition exists or whether this really  ++	   fixes it.  I might just be being dense... Anyway, if it's not really  ++	   a fix, all it does is waste a very small amount of time. */  +	if(!master_conntrack->layer7.app_data) return 0;  +  +	/* Strip nulls. Make everything lower case (our regex lib doesn't @@ -388,9 +363,10 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  +	for(i = 0; i < maxdatalen-oldlength-1 &&  +		   i < appdatalen; i++) {  +		if(app_data[i] != '\0') { ++			/* the kernel version of tolower mungs 'upper ascii' */  +			master_conntrack->layer7.app_data[length+oldlength] = -+				/* the kernel version of tolower mungs 'upper ascii' */ -+				isascii(app_data[i])? tolower(app_data[i]) : app_data[i]; ++				isascii(app_data[i])?  ++					tolower(app_data[i]) : app_data[i];  +			length++;  +		}  +	} @@ -401,33 +377,109 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  +	return length;  +}  + -+/* Returns true on match and false otherwise.  */ -+static int match(const struct sk_buff *skbin, -+	const struct net_device *in, const struct net_device *out, -+	const struct xt_match *match, const void *matchinfo, -+	int offset, unsigned int protoff, int *hotdrop) ++/* taken from drivers/video/modedb.c */ ++static int my_atoi(const char *s) ++{ ++	int val = 0; ++ ++	for (;; s++) { ++		switch (*s) { ++			case '0'...'9': ++			val = 10*val+(*s-'0'); ++			break; ++		default: ++			return val; ++		} ++	} ++} ++ ++/* write out num_packets to userland. */ ++static int layer7_read_proc(char* page, char ** start, off_t off, int count, ++                            int* eof, void * data) ++{ ++	if(num_packets > 99 && net_ratelimit()) ++		printk(KERN_ERR "layer7: NOT REACHED. num_packets too big\n"); ++ ++	page[0] = num_packets/10 + '0'; ++	page[1] = num_packets%10 + '0'; ++	page[2] = '\n'; ++	page[3] = '\0'; ++ ++	*eof=1; ++ ++	return 3; ++} ++ ++/* Read in num_packets from userland */ ++static int layer7_write_proc(struct file* file, const char* buffer, ++                             unsigned long count, void *data) ++{ ++	char * foo = kmalloc(count, GFP_ATOMIC); ++ ++	if(!foo){ ++		if (net_ratelimit()) ++			printk(KERN_ERR "layer7: out of memory, bailing. " ++					"num_packets unchanged.\n"); ++		return count; ++	} ++ ++	if(copy_from_user(foo, buffer, count)) { ++		return -EFAULT; ++	} ++ ++ ++	num_packets = my_atoi(foo); ++	kfree (foo); ++ ++	/* This has an arbitrary limit to make the math easier. I'm lazy. ++	But anyway, 99 is a LOT! If you want more, you're doing it wrong! */ ++	if(num_packets > 99) { ++		printk(KERN_WARNING "layer7: num_packets can't be > 99.\n"); ++		num_packets = 99; ++	} else if(num_packets < 1) { ++		printk(KERN_WARNING "layer7: num_packets can't be < 1.\n"); ++		num_packets = 1; ++	} ++ ++	return count; ++} ++ ++static int ++match(const struct sk_buff *skbin, ++      const struct net_device *in, ++      const struct net_device *out, ++      const struct xt_match *match, ++      const void *matchinfo, ++      int offset, ++      unsigned int protoff, ++      int *hotdrop)  +{  +	/* sidestep const without getting a compiler warning... */ -+	struct sk_buff * skb = (struct sk_buff *)skbin; ++	struct sk_buff * skb = (struct sk_buff *)skbin;   + -+	struct ipt_layer7_info * info = (struct ipt_layer7_info *)matchinfo; ++	const struct xt_layer7_info * info = matchinfo;  +	enum ip_conntrack_info master_ctinfo, ctinfo; -+	struct nf_conn *master_conntrack; -+	struct nf_conn *conntrack; ++	struct nf_conn *master_conntrack, *conntrack;  +	unsigned char * app_data;  +	unsigned int pattern_result, appdatalen;  +	regexp * comppattern;  + ++	/* Be paranoid/incompetent - lock the entire match function. */ ++	spin_lock_bh(&l7_lock); ++  +	if(!can_handle(skb)){  +		DPRINTK("layer7: This is some protocol I can't handle.\n"); ++		spin_unlock_bh(&l7_lock);  +		return info->invert;  +	}  +  +	/* Treat parent & all its children together as one connection, except  +	for the purpose of setting conntrack->layer7.app_proto in the actual  +	connection. This makes /proc/net/ip_conntrack more satisfying. */ -+	if(((conntrack = nf_ct_get((struct sk_buff *)skb, &ctinfo)) == NULL) || -+	   ((master_conntrack = nf_ct_get((struct sk_buff *)skb, &master_ctinfo)) == NULL)) { ++	if(!(conntrack = nf_ct_get(skb, &ctinfo)) || ++	   !(master_conntrack=nf_ct_get(skb,&master_ctinfo))){ ++		DPRINTK("layer7: couldn't get conntrack.\n"); ++		spin_unlock_bh(&l7_lock);  +		return info->invert;  +	}  + @@ -439,95 +491,100 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  +	if(TOTAL_PACKETS > num_packets ||  +	   master_conntrack->layer7.app_proto) {  + -+		pattern_result = match_no_append(conntrack, master_conntrack, ctinfo, master_ctinfo, info); ++		pattern_result = match_no_append(conntrack, master_conntrack,  ++						 ctinfo, master_ctinfo, info);  + -+		/* skb->cb[0] == seen. Don't do things twice if there are multiple l7 -+		rules. I'm not sure that using cb for this purpose is correct, even though -+		it says "put your private variables there". But it doesn't look like it -+		is being used for anything else in the skbs that make it here. */ -+		skb->cb[0] = 1; /* marking it seen here is probably irrelevant, but consistant */ ++		/* skb->cb[0] == seen. Don't do things twice if there are  ++		multiple l7 rules. I'm not sure that using cb for this purpose  ++		is correct, even though it says "put your private variables  ++		there". But it doesn't look like it is being used for anything ++		else in the skbs that make it here. */ ++		skb->cb[0] = 1; /* marking it seen here's probably irrelevant */  + ++		spin_unlock_bh(&l7_lock);  +		return (pattern_result ^ info->invert);  +	}  +  +	if(skb_is_nonlinear(skb)){  +		if(skb_linearize(skb) != 0){  +			if (net_ratelimit()) -+				printk(KERN_ERR "layer7: failed to linearize packet, bailing.\n"); ++				printk(KERN_ERR "layer7: failed to linearize " ++						"packet, bailing.\n"); ++			spin_unlock_bh(&l7_lock);  +			return info->invert;  +		}  +	}  +  +	/* now that the skb is linearized, it's safe to set these. */  +	app_data = skb->data + app_data_offset(skb); -+	appdatalen = skb->tail - app_data; ++	appdatalen = skb_tail_pointer(skb) - app_data;  + -+	spin_lock_bh(&list_lock);  +	/* the return value gets checked later, when we're ready to use it */  +	comppattern = compile_and_cache(info->pattern, info->protocol); -+	spin_unlock_bh(&list_lock);  +  +	/* On the first packet of a connection, allocate space for app data */ -+	write_lock(&ct_lock); -+	if(TOTAL_PACKETS == 1 && !skb->cb[0] && !master_conntrack->layer7.app_data) { -+		master_conntrack->layer7.app_data = kmalloc(maxdatalen, GFP_ATOMIC); ++	if(TOTAL_PACKETS == 1 && !skb->cb[0] &&  ++	   !master_conntrack->layer7.app_data){ ++		master_conntrack->layer7.app_data =  ++			kmalloc(maxdatalen, GFP_ATOMIC);  +		if(!master_conntrack->layer7.app_data){  +			if (net_ratelimit()) -+				printk(KERN_ERR "layer7: out of memory in match, bailing.\n"); -+			write_unlock(&ct_lock); ++				printk(KERN_ERR "layer7: out of memory in " ++						"match, bailing.\n"); ++			spin_unlock_bh(&l7_lock);  +			return info->invert;  +		}  +  +		master_conntrack->layer7.app_data[0] = '\0';  +	} -+	write_unlock(&ct_lock);  +  +	/* Can be here, but unallocated, if numpackets is increased near  +	the beginning of a connection */ -+	if(master_conntrack->layer7.app_data == NULL) ++	if(master_conntrack->layer7.app_data == NULL){ ++		spin_unlock_bh(&l7_lock);  +		return (info->invert); /* unmatched */ ++	}  +  +	if(!skb->cb[0]){  +		int newbytes; -+		write_lock(&ct_lock);  +		newbytes = add_data(master_conntrack, app_data, appdatalen); -+		write_unlock(&ct_lock);  +  +		if(newbytes == 0) { /* didn't add any data */  +			skb->cb[0] = 1;  +			/* Didn't match before, not going to match now */ ++			spin_unlock_bh(&l7_lock);  +			return info->invert;  +		}  +	}  +  +	/* If looking for "unknown", then never match.  "Unknown" means that  +	we've given up; we're still trying with these packets. */ -+	read_lock(&ct_lock);  +	if(!strcmp(info->protocol, "unknown")) {  +		pattern_result = 0;  +	/* If looking for "unset", then always match. "Unset" means that we  +	haven't yet classified the connection. */  +	} else if(!strcmp(info->protocol, "unset")) {  +		pattern_result = 2; -+		DPRINTK("layer7: matched unset: not yet classified (%d/%d packets)\n", TOTAL_PACKETS, num_packets); ++		DPRINTK("layer7: matched unset: not yet classified " ++			"(%d/%d packets)\n", TOTAL_PACKETS, num_packets);  +	/* If the regexp failed to compile, don't bother running it */ -+	} else if(comppattern && regexec(comppattern, master_conntrack->layer7.app_data)) { ++	} else if(comppattern &&  ++		  regexec(comppattern, master_conntrack->layer7.app_data)){  +		DPRINTK("layer7: matched %s\n", info->protocol);  +		pattern_result = 1;  +	} else pattern_result = 0; -+	read_unlock(&ct_lock);  +  +	if(pattern_result == 1) { -+		write_lock(&ct_lock); -+		master_conntrack->layer7.app_proto = kmalloc(strlen(info->protocol)+1, GFP_ATOMIC); ++		master_conntrack->layer7.app_proto =  ++			kmalloc(strlen(info->protocol)+1, GFP_ATOMIC);  +		if(!master_conntrack->layer7.app_proto){  +			if (net_ratelimit()) -+				printk(KERN_ERR "layer7: out of memory in match, bailing.\n"); -+			write_unlock(&ct_lock); ++				printk(KERN_ERR "layer7: out of memory in " ++						"match, bailing.\n"); ++			spin_unlock_bh(&l7_lock);  +			return (pattern_result ^ info->invert);  +		}  +		strcpy(master_conntrack->layer7.app_proto, info->protocol); -+		write_unlock(&ct_lock);  +	} else if(pattern_result > 1) { /* cleanup from "unset" */  +		pattern_result = 1;  +	} @@ -535,169 +592,99 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  +	/* mark the packet seen */  +	skb->cb[0] = 1;  + ++	spin_unlock_bh(&l7_lock);  +	return (pattern_result ^ info->invert);  +}  + -+static struct xt_match layer7_match = { -+	.name = "layer7", -+	.match = &match, -+	.matchsize  = sizeof(struct ipt_layer7_info), -+	.family = AF_INET, -+	.me = THIS_MODULE -+}; ++static int check(const char *tablename, ++		 const void *inf, ++		 const struct xt_match *match, ++		 void *matchinfo, ++		 unsigned int hook_mask)  + -+/* taken from drivers/video/modedb.c */ -+static int my_atoi(const char *s)  +{ -+	int val = 0; -+ -+	for (;; s++) { -+		switch (*s) { -+			case '0'...'9': -+			val = 10*val+(*s-'0'); -+			break; -+		default: -+			return val; -+		} -+	} ++	// load nf_conntrack_ipv4 ++        if (nf_ct_l3proto_try_module_get(match->family) < 0) { ++                printk(KERN_WARNING "can't load conntrack support for " ++                                    "proto=%d\n", match->family); ++                return false; ++        } ++	return true;  +}  + -+/* write out num_packets to userland. */ -+static int layer7_read_proc(char* page, char ** start, off_t off, int count, -+		     int* eof, void * data) ++static void ++destroy(const struct xt_match *match, void *matchinfo)  +{ -+	if(num_packets > 99 && net_ratelimit()) -+		printk(KERN_ERR "layer7: NOT REACHED. num_packets too big\n"); -+ -+	page[0] = num_packets/10 + '0'; -+	page[1] = num_packets%10 + '0'; -+	page[2] = '\n'; -+	page[3] = '\0'; -+ -+	*eof=1; -+ -+	return 3; ++	nf_ct_l3proto_module_put(match->family);  +}  + -+/* Read in num_packets from userland */ -+static int layer7_write_proc(struct file* file, const char* buffer, -+		      unsigned long count, void *data) ++static struct xt_match xt_layer7_match[] = {  +{ -+	char * foo = kmalloc(count, GFP_ATOMIC); -+ -+	if(!foo){ -+		if (net_ratelimit()) -+			printk(KERN_ERR "layer7: out of memory, bailing. num_packets unchanged.\n"); -+		return count; -+	} -+ -+	if(copy_from_user(foo, buffer, count)) { -+		return -EFAULT; -+	} -+ -+ -+	num_packets = my_atoi(foo); -+	kfree (foo); -+ -+	/* This has an arbitrary limit to make the math easier. I'm lazy. -+	But anyway, 99 is a LOT! If you want more, you're doing it wrong! */ -+	if(num_packets > 99) { -+		printk(KERN_WARNING "layer7: num_packets can't be > 99.\n"); -+		num_packets = 99; -+	} else if(num_packets < 1) { -+		printk(KERN_WARNING "layer7: num_packets can't be < 1.\n"); -+		num_packets = 1; -+	} ++	.name		= "layer7", ++	.family		= AF_INET, ++	.checkentry	= check, ++	.match		= match, ++	.destroy	= destroy, ++	.matchsize	= sizeof(struct xt_layer7_info), ++	.me		= THIS_MODULE ++} ++};  + -+	return count; ++static void layer7_cleanup_proc(void) ++{ ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23) ++	remove_proc_entry("layer7_numpackets", proc_net); ++#else ++	remove_proc_entry("layer7_numpackets", init_net.proc_net); ++#endif  +}  +  +/* register the proc file */  +static void layer7_init_proc(void)  +{  +	struct proc_dir_entry* entry; ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)  +	entry = create_proc_entry("layer7_numpackets", 0644, proc_net); ++#else ++	entry = create_proc_entry("layer7_numpackets", 0644, init_net.proc_net); ++#endif  +	entry->read_proc = layer7_read_proc;  +	entry->write_proc = layer7_write_proc;  +}  + -+static void layer7_cleanup_proc(void) -+{ -+	remove_proc_entry("layer7_numpackets", proc_net); -+} -+ -+static int __init ipt_layer7_init(void) ++static int __init xt_layer7_init(void)  +{  +	need_conntrack();  +  +	layer7_init_proc();  +	if(maxdatalen < 1) { -+		printk(KERN_WARNING "layer7: maxdatalen can't be < 1, using 1\n"); ++		printk(KERN_WARNING "layer7: maxdatalen can't be < 1, " ++			"using 1\n");  +		maxdatalen = 1;  +	}  +	/* This is not a hard limit.  It's just here to prevent people from  +	bringing their slow machines to a grinding halt. */  +	else if(maxdatalen > 65536) { -+		printk(KERN_WARNING "layer7: maxdatalen can't be > 65536, using 65536\n"); ++		printk(KERN_WARNING "layer7: maxdatalen can't be > 65536, " ++			"using 65536\n");  +		maxdatalen = 65536;  +	} -+	return xt_register_match(&layer7_match); ++	return xt_register_matches(xt_layer7_match, ++				   ARRAY_SIZE(xt_layer7_match));  +}  + -+static void __exit ipt_layer7_fini(void) ++static void __exit xt_layer7_fini(void)  +{  +	layer7_cleanup_proc(); -+	xt_unregister_match(&layer7_match); ++	xt_unregister_matches(xt_layer7_match, ARRAY_SIZE(xt_layer7_match));  +}  + -+module_init(ipt_layer7_init); -+module_exit(ipt_layer7_fini); -Index: linux-2.6.22-rc6/net/ipv4/netfilter/Kconfig -=================================================================== ---- linux-2.6.22-rc6.orig/net/ipv4/netfilter/Kconfig	2007-07-02 02:16:21.857539250 +0200 -+++ linux-2.6.22-rc6/net/ipv4/netfilter/Kconfig	2007-07-02 03:43:29.324235500 +0200 -@@ -63,6 +63,24 @@ -  - 	  To compile it as a module, choose M here.  If unsure, say N. -  -+config IP_NF_MATCH_LAYER7 -+	tristate "Layer 7 match support (EXPERIMENTAL)" -+	depends on IP_NF_IPTABLES && NF_CT_ACCT && NF_CONNTRACK && EXPERIMENTAL -+	help -+	  Say Y if you want to be able to classify connections (and their -+	  packets) based on regular expression matching of their application -+	  layer data.   This is one way to classify applications such as -+	  peer-to-peer filesharing systems that do not always use the same -+	  port. -+ -+	  To compile it as a module, choose M here.  If unsure, say N. -+ -+config IP_NF_MATCH_LAYER7_DEBUG -+	bool "Layer 7 debugging output" -+	depends on IP_NF_MATCH_LAYER7 -+	help -+	  Say Y to get lots of debugging output. -+ - config IP_NF_MATCH_TOS - 	tristate "TOS match support" - 	depends on IP_NF_IPTABLES -Index: linux-2.6.22-rc6/net/ipv4/netfilter/Makefile ++module_init(xt_layer7_init); ++module_exit(xt_layer7_fini); +Index: linux-2.6.22.18/net/netfilter/regexp/regexp.c  =================================================================== ---- linux-2.6.22-rc6.orig/net/ipv4/netfilter/Makefile	2007-07-02 02:16:21.865539750 +0200 -+++ linux-2.6.22-rc6/net/ipv4/netfilter/Makefile	2007-07-02 03:43:29.336236250 +0200 -@@ -50,6 +50,8 @@ - obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o - obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o -  -+obj-$(CONFIG_IP_NF_MATCH_LAYER7) += ipt_layer7.o -+ - # targets - obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o - obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o -Index: linux-2.6.22-rc6/net/ipv4/netfilter/regexp/regexp.c -=================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc6/net/ipv4/netfilter/regexp/regexp.c	2007-07-02 02:35:33.797531000 +0200 +--- /dev/null ++++ linux-2.6.22.18/net/netfilter/regexp/regexp.c  @@ -0,0 +1,1197 @@  +/*  + * regcomp and regexec -- regsub and regerror are elsewhere @@ -935,7 +922,7 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/regexp/regexp.c  +	register int len;  +	int flags;  +	struct match_globals g; -+ ++	  +	/* commented out by ethan  +	   extern char *malloc();  +	*/ @@ -1062,7 +1049,7 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/regexp/regexp.c  +	}  +  +	/* Make a closing node, and hook it on the end. */ -+	ender = regnode(g, (paren) ? CLOSE+parno : END); ++	ender = regnode(g, (paren) ? CLOSE+parno : END);	  +	regtail(g, ret, ender);  +  +	/* Hook the tails of the branches to the closing node. */ @@ -1896,10 +1883,10 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/regexp/regexp.c  +#endif  +  + -Index: linux-2.6.22-rc6/net/ipv4/netfilter/regexp/regexp.h +Index: linux-2.6.22.18/net/netfilter/regexp/regexp.h  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc6/net/ipv4/netfilter/regexp/regexp.h	2007-07-02 02:16:23.677653000 +0200 +--- /dev/null ++++ linux-2.6.22.18/net/netfilter/regexp/regexp.h  @@ -0,0 +1,41 @@  +/*  + * Definitions etc. for regexp(3) routines. @@ -1942,20 +1929,20 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/regexp/regexp.h  +void regerror(char *s);  +  +#endif -Index: linux-2.6.22-rc6/net/ipv4/netfilter/regexp/regmagic.h +Index: linux-2.6.22.18/net/netfilter/regexp/regmagic.h  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc6/net/ipv4/netfilter/regexp/regmagic.h	2007-07-02 02:16:23.701654500 +0200 +--- /dev/null ++++ linux-2.6.22.18/net/netfilter/regexp/regmagic.h  @@ -0,0 +1,5 @@  +/*  + * The first byte of the regexp internal "program" is actually this magic  + * number; the start node begins in the second byte.  + */  +#define	MAGIC	0234 -Index: linux-2.6.22-rc6/net/ipv4/netfilter/regexp/regsub.c +Index: linux-2.6.22.18/net/netfilter/regexp/regsub.c  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc6/net/ipv4/netfilter/regexp/regsub.c	2007-07-02 02:35:46.074298250 +0200 +--- /dev/null ++++ linux-2.6.22.18/net/netfilter/regexp/regsub.c  @@ -0,0 +1,95 @@  +/*  + * regsub @@ -2013,7 +2000,7 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/regexp/regsub.c  +	register char c;  +	register int no;  +	register int len; -+ ++	  +	/* Not necessary and gcc doesn't like it -MLS */  +	/*extern char *strncpy();*/  + @@ -2052,15 +2039,53 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/regexp/regsub.c  +	}  +	*dst++ = '\0';  +} -Index: linux-2.6.22-rc6/include/net/netfilter/nf_conntrack.h +Index: linux-2.6.22.18/net/netfilter/nf_conntrack_core.c +=================================================================== +--- linux-2.6.22.18.orig/net/netfilter/nf_conntrack_core.c ++++ linux-2.6.22.18/net/netfilter/nf_conntrack_core.c +@@ -330,6 +330,14 @@ destroy_conntrack(struct nf_conntrack *n + 	 * too. */ + 	nf_ct_remove_expectations(ct); +  ++	#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE) ++	if(ct->layer7.app_proto) ++		kfree(ct->layer7.app_proto); ++	if(ct->layer7.app_data) ++	kfree(ct->layer7.app_data); ++	#endif ++ ++ + 	/* We overload first tuple to link into unconfirmed list. */ + 	if (!nf_ct_is_confirmed(ct)) { + 		BUG_ON(list_empty(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list)); +Index: linux-2.6.22.18/net/netfilter/nf_conntrack_standalone.c  =================================================================== ---- linux-2.6.22-rc6.orig/include/net/netfilter/nf_conntrack.h	2007-07-02 02:16:21.825537250 +0200 -+++ linux-2.6.22-rc6/include/net/netfilter/nf_conntrack.h	2007-07-02 02:16:23.749657500 +0200 -@@ -128,6 +128,21 @@ +--- linux-2.6.22.18.orig/net/netfilter/nf_conntrack_standalone.c ++++ linux-2.6.22.18/net/netfilter/nf_conntrack_standalone.c +@@ -184,7 +184,12 @@ static int ct_seq_show(struct seq_file * + 		return -ENOSPC; + #endif +  +-	if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use))) ++#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE) ++	if(conntrack->layer7.app_proto) ++		if(seq_printf(s, "l7proto=%s ", conntrack->layer7.app_proto)) ++			return -ENOSPC; ++#endif ++	if (seq_printf(s, "asdfuse=%u\n", atomic_read(&conntrack->ct_general.use))) + 		return -ENOSPC; + 	 + 	return 0; +Index: linux-2.6.22.18/include/net/netfilter/nf_conntrack.h +=================================================================== +--- linux-2.6.22.18.orig/include/net/netfilter/nf_conntrack.h ++++ linux-2.6.22.18/include/net/netfilter/nf_conntrack.h +@@ -128,6 +128,22 @@ struct nf_conn   	u_int32_t secmark;   #endif -+#if defined(CONFIG_IP_NF_MATCH_LAYER7) || defined(CONFIG_IP_NF_MATCH_LAYER7_MODULE) ++#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || \ ++    defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE)  +	struct {  +		/*  +		 * e.g. "http". NULL before decision. "unknown" after decision @@ -2078,3 +2103,21 @@ Index: linux-2.6.22-rc6/include/net/netfilter/nf_conntrack.h   	/* Storage reserved for other modules: */   	union nf_conntrack_proto proto; +Index: linux-2.6.22.18/include/linux/netfilter/xt_layer7.h +=================================================================== +--- /dev/null ++++ linux-2.6.22.18/include/linux/netfilter/xt_layer7.h +@@ -0,0 +1,13 @@ ++#ifndef _XT_LAYER7_H ++#define _XT_LAYER7_H ++ ++#define MAX_PATTERN_LEN 8192 ++#define MAX_PROTOCOL_LEN 256 ++ ++struct xt_layer7_info { ++    char protocol[MAX_PROTOCOL_LEN]; ++    char pattern[MAX_PATTERN_LEN]; ++    u_int8_t invert; ++}; ++ ++#endif /* _XT_LAYER7_H */ diff --git a/target/linux/generic-2.6/patches-2.6.22/101-netfilter_layer7_pktmatch.patch b/target/linux/generic-2.6/patches-2.6.22/101-netfilter_layer7_pktmatch.patch index 5ac30a7c2..8f2456ffe 100644 --- a/target/linux/generic-2.6/patches-2.6.22/101-netfilter_layer7_pktmatch.patch +++ b/target/linux/generic-2.6/patches-2.6.22/101-netfilter_layer7_pktmatch.patch @@ -1,36 +1,37 @@ -Index: linux-2.6.22-rc6/include/linux/netfilter_ipv4/ipt_layer7.h +Index: linux-2.6.22.18/include/linux/netfilter/xt_layer7.h  =================================================================== ---- linux-2.6.22-rc6.orig/include/linux/netfilter_ipv4/ipt_layer7.h	2007-07-02 03:23:28.597194750 +0200 -+++ linux-2.6.22-rc6/include/linux/netfilter_ipv4/ipt_layer7.h	2007-07-02 03:23:44.730203000 +0200 -@@ -21,6 +21,7 @@ +--- linux-2.6.22.18.orig/include/linux/netfilter/xt_layer7.h ++++ linux-2.6.22.18/include/linux/netfilter/xt_layer7.h +@@ -8,6 +8,7 @@ struct xt_layer7_info {       char protocol[MAX_PROTOCOL_LEN]; -     char invert:1;       char pattern[MAX_PATTERN_LEN]; -+    char pkt; +     u_int8_t invert; ++    u_int8_t pkt;   }; - #endif /* _IPT_LAYER7_H */ -Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c + #endif /* _XT_LAYER7_H */ +Index: linux-2.6.22.18/net/netfilter/xt_layer7.c  =================================================================== ---- linux-2.6.22-rc6.orig/net/ipv4/netfilter/ipt_layer7.c	2007-07-02 03:23:28.609195500 +0200 -+++ linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c	2007-07-02 03:23:54.234797000 +0200 -@@ -300,33 +300,34 @@ +--- linux-2.6.22.18.orig/net/netfilter/xt_layer7.c ++++ linux-2.6.22.18/net/netfilter/xt_layer7.c +@@ -297,34 +297,36 @@ static int match_no_append(struct nf_con   }   /* add the new app data to the conntrack.  Return number of bytes added. */  -static int add_data(struct nf_conn * master_conntrack, --			char * app_data, int appdatalen) +-                    char * app_data, int appdatalen)  +static int add_datastr(char *target, int offset, char *app_data, int len)   {   	int length = 0, i;  -	int oldlength = master_conntrack->layer7.app_data_len;  - --	// This is a fix for a race condition by Deti Fliegl. However, I'm not --	// clear on whether the race condition exists or whether this really --	// fixes it.  I might just be being dense... Anyway, if it's not really --	// a fix, all it does is waste a very small amount of time. +-	/* This is a fix for a race condition by Deti Fliegl. However, I'm not  +-	   clear on whether the race condition exists or whether this really  +-	   fixes it.  I might just be being dense... Anyway, if it's not really  +-	   a fix, all it does is waste a very small amount of time. */  -	if(!master_conntrack->layer7.app_data) return 0; -+	if(!target) return 0; ++	 ++	if (!target) return 0;   	/* Strip nulls. Make everything lower case (our regex lib doesn't   	do case insensitivity).  Add it to the end of the current data. */ @@ -38,15 +39,16 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  -		   i < appdatalen; i++) {  +	for(i = 0; i < maxdatalen-offset-1 && i < len; i++) {   		if(app_data[i] != '\0') { + 			/* the kernel version of tolower mungs 'upper ascii' */  -			master_conntrack->layer7.app_data[length+oldlength] =  +			target[length+offset] = - 				/* the kernel version of tolower mungs 'upper ascii' */ - 				isascii(app_data[i])? tolower(app_data[i]) : app_data[i]; + 				isascii(app_data[i])?  + 					tolower(app_data[i]) : app_data[i];   			length++;   		}   	}  +	target[length+offset] = '\0'; -+ ++	  +	return length;  +} @@ -54,7 +56,7 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  -	master_conntrack->layer7.app_data_len = length + oldlength;  +/* add the new app data to the conntrack.  Return number of bytes added. */  +static int add_data(struct nf_conn * master_conntrack, -+			char * app_data, int appdatalen) ++                    char * app_data, int appdatalen)  +{  +	int length; @@ -63,29 +65,29 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c   	return length;   } -@@ -343,7 +344,7 @@ +@@ -411,7 +413,7 @@ match(const struct sk_buff *skbin, + 	const struct xt_layer7_info * info = matchinfo;   	enum ip_conntrack_info master_ctinfo, ctinfo; - 	struct nf_conn *master_conntrack; - 	struct nf_conn *conntrack; + 	struct nf_conn *master_conntrack, *conntrack;  -	unsigned char * app_data;  +	unsigned char *app_data, *tmp_data;   	unsigned int pattern_result, appdatalen;   	regexp * comppattern; -@@ -365,8 +366,8 @@ +@@ -439,8 +441,8 @@ match(const struct sk_buff *skbin,   		master_conntrack = master_ct(master_conntrack);   	/* if we've classified it or seen too many packets */  -	if(TOTAL_PACKETS > num_packets ||  -	   master_conntrack->layer7.app_proto) {  +	if(!info->pkt && (TOTAL_PACKETS > num_packets || -+		master_conntrack->layer7.app_proto)) { -  - 		pattern_result = match_no_append(conntrack, master_conntrack, ctinfo, master_ctinfo, info); ++	   master_conntrack->layer7.app_proto)) { -@@ -396,6 +397,23 @@ + 		pattern_result = match_no_append(conntrack, master_conntrack,  + 						 ctinfo, master_ctinfo, info); +@@ -473,6 +475,25 @@ match(const struct sk_buff *skbin, + 	/* the return value gets checked later, when we're ready to use it */   	comppattern = compile_and_cache(info->pattern, info->protocol); - 	spin_unlock_bh(&list_lock);  +	if (info->pkt) {  +		tmp_data = kmalloc(maxdatalen, GFP_ATOMIC); @@ -98,12 +100,14 @@ Index: linux-2.6.22-rc6/net/ipv4/netfilter/ipt_layer7.c  +		tmp_data[0] = '\0';  +		add_datastr(tmp_data, 0, app_data, appdatalen);  +		pattern_result = ((comppattern && regexec(comppattern, tmp_data)) ? 1 : 0); ++  +		kfree(tmp_data);  +		tmp_data = NULL; ++		spin_unlock_bh(&l7_lock);  +  +		return (pattern_result ^ info->invert);  +	}  +   	/* On the first packet of a connection, allocate space for app data */ - 	write_lock(&ct_lock); - 	if(TOTAL_PACKETS == 1 && !skb->cb[0] && !master_conntrack->layer7.app_data) { + 	if(TOTAL_PACKETS == 1 && !skb->cb[0] &&  + 	   !master_conntrack->layer7.app_data){ diff --git a/target/linux/generic-2.6/patches-2.6.22/110-ipp2p_0.8.1rc1.patch b/target/linux/generic-2.6/patches-2.6.22/110-ipp2p_0.8.1rc1.patch index 6963ac098..9a4cb63cd 100644 --- a/target/linux/generic-2.6/patches-2.6.22/110-ipp2p_0.8.1rc1.patch +++ b/target/linux/generic-2.6/patches-2.6.22/110-ipp2p_0.8.1rc1.patch @@ -1,6 +1,7 @@ -diff -urN linux-2.6.21.1.old/include/linux/netfilter_ipv4/ipt_ipp2p.h linux-2.6.21.1.dev/include/linux/netfilter_ipv4/ipt_ipp2p.h ---- linux-2.6.21.1.old/include/linux/netfilter_ipv4/ipt_ipp2p.h	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/include/linux/netfilter_ipv4/ipt_ipp2p.h	2007-05-26 20:21:54.586864296 +0200 +Index: linux-2.6.22.18/include/linux/netfilter_ipv4/ipt_ipp2p.h +=================================================================== +--- /dev/null ++++ linux-2.6.22.18/include/linux/netfilter_ipv4/ipt_ipp2p.h  @@ -0,0 +1,31 @@  +#ifndef __IPT_IPP2P_H  +#define __IPT_IPP2P_H @@ -33,9 +34,10 @@ diff -urN linux-2.6.21.1.old/include/linux/netfilter_ipv4/ipt_ipp2p.h linux-2.6.  +#define IPP2P_MUTE		(1 << 14)  +#define IPP2P_WASTE		(1 << 15)  +#define IPP2P_XDCC		(1 << 16) -diff -urN linux-2.6.21.1.old/net/ipv4/netfilter/ipt_ipp2p.c linux-2.6.21.1.dev/net/ipv4/netfilter/ipt_ipp2p.c ---- linux-2.6.21.1.old/net/ipv4/netfilter/ipt_ipp2p.c	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/net/ipv4/netfilter/ipt_ipp2p.c	2007-05-26 20:21:54.587864144 +0200 +Index: linux-2.6.22.18/net/ipv4/netfilter/ipt_ipp2p.c +=================================================================== +--- /dev/null ++++ linux-2.6.22.18/net/ipv4/netfilter/ipt_ipp2p.c  @@ -0,0 +1,882 @@  +#if defined(MODVERSIONS)  +#include <linux/modversions.h> @@ -919,12 +921,13 @@ diff -urN linux-2.6.21.1.old/net/ipv4/netfilter/ipt_ipp2p.c linux-2.6.21.1.dev/n  +module_exit(fini);  +  + -diff -urN linux-2.6.21.1.old/net/ipv4/netfilter/Kconfig linux-2.6.21.1.dev/net/ipv4/netfilter/Kconfig ---- linux-2.6.21.1.old/net/ipv4/netfilter/Kconfig	2007-05-26 20:17:47.626407992 +0200 -+++ linux-2.6.21.1.dev/net/ipv4/netfilter/Kconfig	2007-05-26 20:21:54.587864144 +0200 -@@ -81,6 +81,12 @@ - 	help - 	  Say Y to get lots of debugging output. +Index: linux-2.6.22.18/net/ipv4/netfilter/Kconfig +=================================================================== +--- linux-2.6.22.18.orig/net/ipv4/netfilter/Kconfig ++++ linux-2.6.22.18/net/ipv4/netfilter/Kconfig +@@ -63,6 +63,12 @@ config IP_NF_MATCH_IPRANGE +  + 	  To compile it as a module, choose M here.  If unsure, say N.  +config IP_NF_MATCH_IPP2P  +	tristate "IPP2P" @@ -935,15 +938,15 @@ diff -urN linux-2.6.21.1.old/net/ipv4/netfilter/Kconfig linux-2.6.21.1.dev/net/i   config IP_NF_MATCH_TOS   	tristate "TOS match support"   	depends on IP_NF_IPTABLES -diff -urN linux-2.6.21.1.old/net/ipv4/netfilter/Makefile linux-2.6.21.1.dev/net/ipv4/netfilter/Makefile ---- linux-2.6.21.1.old/net/ipv4/netfilter/Makefile	2007-05-26 20:17:47.638406168 +0200 -+++ linux-2.6.21.1.dev/net/ipv4/netfilter/Makefile	2007-05-26 20:21:54.588863992 +0200 -@@ -49,7 +49,7 @@ +Index: linux-2.6.22.18/net/ipv4/netfilter/Makefile +=================================================================== +--- linux-2.6.22.18.orig/net/ipv4/netfilter/Makefile ++++ linux-2.6.22.18/net/ipv4/netfilter/Makefile +@@ -49,6 +49,7 @@ obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn   obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o   obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o   obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o --  +obj-$(CONFIG_IP_NF_MATCH_IPP2P) += ipt_ipp2p.o - obj-$(CONFIG_IP_NF_MATCH_LAYER7) += ipt_layer7.o   # targets + obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o diff --git a/target/linux/generic-2.6/patches-2.6.22/170-netfilter_chaostables.patch b/target/linux/generic-2.6/patches-2.6.22/170-netfilter_chaostables_0.8.patch index 2bc678e96..e2a288d92 100644 --- a/target/linux/generic-2.6/patches-2.6.22/170-netfilter_chaostables.patch +++ b/target/linux/generic-2.6/patches-2.6.22/170-netfilter_chaostables_0.8.patch @@ -1,15 +1,17 @@ -diff -urN linux-2.6.21.1.old/include/linux/netfilter/oot_conntrack.h linux-2.6.21.1.dev/include/linux/netfilter/oot_conntrack.h ---- linux-2.6.21.1.old/include/linux/netfilter/oot_conntrack.h	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/include/linux/netfilter/oot_conntrack.h	2007-05-26 20:40:10.922195992 +0200 +Index: linux-2.6.22.18/include/linux/netfilter/oot_conntrack.h +=================================================================== +--- /dev/null ++++ linux-2.6.22.18/include/linux/netfilter/oot_conntrack.h  @@ -0,0 +1,5 @@  +#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)  +#	include <linux/netfilter_ipv4/ip_conntrack.h>  +#else /* linux-2.6.20+ */  +#	include <net/netfilter/nf_nat_rule.h>  +#endif -diff -urN linux-2.6.21.1.old/include/linux/netfilter/oot_trans.h linux-2.6.21.1.dev/include/linux/netfilter/oot_trans.h ---- linux-2.6.21.1.old/include/linux/netfilter/oot_trans.h	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/include/linux/netfilter/oot_trans.h	2007-05-26 20:40:10.940193256 +0200 +Index: linux-2.6.22.18/include/linux/netfilter/oot_trans.h +=================================================================== +--- /dev/null ++++ linux-2.6.22.18/include/linux/netfilter/oot_trans.h  @@ -0,0 +1,14 @@  +/* Out of tree workarounds */  +#include <linux/version.h> @@ -25,39 +27,42 @@ diff -urN linux-2.6.21.1.old/include/linux/netfilter/oot_trans.h linux-2.6.21.1.  +#	define tcp_v4_check(tcph, tcph_sz, s, d, csp) \  +		tcp_v4_check((tcph_sz), (s), (d), (csp))  +#endif -diff -urN linux-2.6.21.1.old/include/linux/netfilter/xt_CHAOS.h linux-2.6.21.1.dev/include/linux/netfilter/xt_CHAOS.h ---- linux-2.6.21.1.old/include/linux/netfilter/xt_CHAOS.h	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/include/linux/netfilter/xt_CHAOS.h	2007-05-26 20:40:10.940193256 +0200 +Index: linux-2.6.22.18/include/linux/netfilter/xt_CHAOS.h +=================================================================== +--- /dev/null ++++ linux-2.6.22.18/include/linux/netfilter/xt_CHAOS.h  @@ -0,0 +1,14 @@ -+#ifndef _LINUX_XT_CHAOS_H -+#define _LINUX_XT_CHAOS_H 1 ++#ifndef _LINUX_NETFILTER_XT_CHAOS_H ++#define _LINUX_NETFILTER_XT_CHAOS_H 1  + -+enum xt_chaos_variant { ++enum xt_chaos_target_variant {  +	XTCHAOS_NORMAL,  +	XTCHAOS_TARPIT,  +	XTCHAOS_DELUDE,  +};  + -+struct xt_chaos_info { -+	enum xt_chaos_variant variant; ++struct xt_chaos_target_info { ++	uint8_t variant;  +};  + -+#endif /* _LINUX_XT_CHAOS_H */ -diff -urN linux-2.6.21.1.old/include/linux/netfilter/xt_portscan.h linux-2.6.21.1.dev/include/linux/netfilter/xt_portscan.h ---- linux-2.6.21.1.old/include/linux/netfilter/xt_portscan.h	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/include/linux/netfilter/xt_portscan.h	2007-05-26 20:40:10.940193256 +0200 ++#endif /* _LINUX_NETFILTER_XT_CHAOS_H */ +Index: linux-2.6.22.18/include/linux/netfilter/xt_portscan.h +=================================================================== +--- /dev/null ++++ linux-2.6.22.18/include/linux/netfilter/xt_portscan.h  @@ -0,0 +1,8 @@ -+#ifndef _LINUX_XT_PORTSCAN_H -+#define _LINUX_XT_PORTSCAN_H 1 ++#ifndef _LINUX_NETFILTER_XT_PORTSCAN_H ++#define _LINUX_NETFILTER_XT_PORTSCAN_H 1  + -+struct xt_portscan_info { -+	unsigned int match_stealth, match_syn, match_cn, match_gr; ++struct xt_portscan_match_info { ++	uint8_t match_stealth, match_syn, match_cn, match_gr;  +};  + -+#endif /* _LINUX_XT_PORTSCAN_H */ -diff -urN linux-2.6.21.1.old/net/netfilter/find_match.c linux-2.6.21.1.dev/net/netfilter/find_match.c ---- linux-2.6.21.1.old/net/netfilter/find_match.c	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/net/netfilter/find_match.c	2007-05-26 20:40:10.970188696 +0200 ++#endif /* _LINUX_NETFILTER_XT_PORTSCAN_H */ +Index: linux-2.6.22.18/net/netfilter/find_match.c +=================================================================== +--- /dev/null ++++ linux-2.6.22.18/net/netfilter/find_match.c  @@ -0,0 +1,39 @@  +/*  +    xt_request_find_match @@ -90,7 +95,7 @@ diff -urN linux-2.6.21.1.old/net/netfilter/find_match.c linux-2.6.21.1.dev/net/n  +  +	match = try_then_request_module(xt_find_match(af, name, revision),  +		"%st_%s", xt_prefix[af], name); -+	if(IS_ERR(match) || match == NULL) ++	if (IS_ERR(match) || match == NULL)  +		return NULL;  +  +	return match; @@ -98,10 +103,11 @@ diff -urN linux-2.6.21.1.old/net/netfilter/find_match.c linux-2.6.21.1.dev/net/n  +  +/* In case it goes into mainline, let this out-of-tree package compile */  +#define xt_request_find_match xt_request_find_match_lo -diff -urN linux-2.6.21.1.old/net/netfilter/Kconfig linux-2.6.21.1.dev/net/netfilter/Kconfig ---- linux-2.6.21.1.old/net/netfilter/Kconfig	2007-04-27 23:49:26.000000000 +0200 -+++ linux-2.6.21.1.dev/net/netfilter/Kconfig	2007-05-26 20:40:11.003183680 +0200 -@@ -255,6 +255,14 @@ +Index: linux-2.6.22.18/net/netfilter/Kconfig +=================================================================== +--- linux-2.6.22.18.orig/net/netfilter/Kconfig ++++ linux-2.6.22.18/net/netfilter/Kconfig +@@ -255,6 +255,14 @@ config NETFILTER_XTABLES   # alphabetically ordered list of targets @@ -116,7 +122,7 @@ diff -urN linux-2.6.21.1.old/net/netfilter/Kconfig linux-2.6.21.1.dev/net/netfil   config NETFILTER_XT_TARGET_CLASSIFY   	tristate '"CLASSIFY" target support'   	depends on NETFILTER_XTABLES -@@ -282,6 +290,14 @@ +@@ -282,6 +290,14 @@ config NETFILTER_XT_TARGET_CONNMARK   	  <file:Documentation/kbuild/modules.txt>.  The module will be called   	  ipt_CONNMARK.ko.  If unsure, say `N'. @@ -131,7 +137,7 @@ diff -urN linux-2.6.21.1.old/net/netfilter/Kconfig linux-2.6.21.1.dev/net/netfil   config NETFILTER_XT_TARGET_DSCP   	tristate '"DSCP" target support'   	depends on NETFILTER_XTABLES -@@ -526,6 +542,14 @@ +@@ -526,6 +542,14 @@ config NETFILTER_XT_MATCH_POLICY   	  To compile it as a module, choose M here.  If unsure, say N. @@ -146,40 +152,38 @@ diff -urN linux-2.6.21.1.old/net/netfilter/Kconfig linux-2.6.21.1.dev/net/netfil   config NETFILTER_XT_MATCH_MULTIPORT   	tristate "Multiple port match support"   	depends on NETFILTER_XTABLES -diff -urN linux-2.6.21.1.old/net/netfilter/Makefile linux-2.6.21.1.dev/net/netfilter/Makefile ---- linux-2.6.21.1.old/net/netfilter/Makefile	2007-04-27 23:49:26.000000000 +0200 -+++ linux-2.6.21.1.dev/net/netfilter/Makefile	2007-05-26 20:40:11.003183680 +0200 -@@ -37,8 +37,10 @@ - obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o -  - # targets +Index: linux-2.6.22.18/net/netfilter/Makefile +=================================================================== +--- linux-2.6.22.18.orig/net/netfilter/Makefile ++++ linux-2.6.22.18/net/netfilter/Makefile +@@ -47,6 +47,8 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK + obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o + obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o + obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o  +obj-$(CONFIG_NETFILTER_XT_TARGET_CHAOS) += xt_CHAOS.o - obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o - obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o  +obj-$(CONFIG_NETFILTER_XT_TARGET_DELUDE) += xt_DELUDE.o - obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o - obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o - obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o -@@ -63,6 +65,7 @@ - obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o - obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o - obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o +  + # matches + obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o +@@ -74,3 +76,4 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_STRING)  + obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o + obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o + obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o  +obj-$(CONFIG_NETFILTER_XT_MATCH_PORTSCAN) += xt_portscan.o - obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o - obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o - obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o -diff -urN linux-2.6.21.1.old/net/netfilter/xt_CHAOS.c linux-2.6.21.1.dev/net/netfilter/xt_CHAOS.c ---- linux-2.6.21.1.old/net/netfilter/xt_CHAOS.c	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/net/netfilter/xt_CHAOS.c	2007-05-26 20:40:11.004183528 +0200 -@@ -0,0 +1,204 @@ +Index: linux-2.6.22.18/net/netfilter/xt_CHAOS.c +=================================================================== +--- /dev/null ++++ linux-2.6.22.18/net/netfilter/xt_CHAOS.c +@@ -0,0 +1,200 @@  +/* -+	CHAOS target for netfilter -+ -+	Copyright © Jan Engelhardt <jengelh [at] gmx de>, 2006 - 2007 -+	This program is free software; you can redistribute it and/or modify -+	it under the terms of the GNU General Public License version 2 as -+	published by the Free Software Foundation. -+*/ ++ *	CHAOS target for netfilter ++ *	Copyright © CC Computer Consultants GmbH, 2006 - 2007 ++ *	Contact: Jan Engelhardt <jengelh@computergmbh.de> ++ * ++ *	This program is free software; you can redistribute it and/or modify ++ *	it under the terms of the GNU General Public License; either version ++ *	2 or 3 as published by the Free Software Foundation. ++ */  +#include <linux/icmp.h>  +#include <linux/in.h>  +#include <linux/ip.h> @@ -190,9 +194,17 @@ diff -urN linux-2.6.21.1.old/net/netfilter/xt_CHAOS.c linux-2.6.21.1.dev/net/net  +#include <linux/netfilter/xt_tcpudp.h>  +#include <linux/netfilter_ipv4/ipt_REJECT.h>  +#include <net/ip.h> -+#include <linux/netfilter/xt_CHAOS.h> -+#include "find_match.c" -+#include <linux/netfilter/oot_trans.h> ++#if defined(_LOCAL) ++#	include "xt_CHAOS.h" ++#	include "find_match.c" ++#elif defined(CONFIG_NETFILTER_XT_TARGET_CHAOS) || \ ++    defined(CONFIG_NETFILTER_XT_TARGET_CHAOS_MODULE) ++#	include <linux/netfilter/xt_CHAOS.h> ++#	include "find_match.c" ++#else ++#	include "xt_CHAOS.h" ++#	include "find_match.c" ++#endif  +#define PFX KBUILD_MODNAME ": "  +  +/* Module parameters */ @@ -218,110 +230,97 @@ diff -urN linux-2.6.21.1.old/net/netfilter/xt_CHAOS.c linux-2.6.21.1.dev/net/net  +};  +  +/* CHAOS functions */ -+static void xt_chaos_total(const struct xt_chaos_info *info, ++static void xt_chaos_total(const struct xt_chaos_target_info *info,  +    struct sk_buff **pskb, const struct net_device *in,  +    const struct net_device *out, unsigned int hooknum)  +{ -+	const int protoff = ip_hdrlen(*pskb); -+	const int offset  = ntohs(ip_hdr(*pskb)->frag_off) & IP_OFFSET; ++	const struct iphdr *iph = ip_hdr(*pskb); ++	const int protoff       = 4 * iph->ihl; ++	const int offset        = ntohs(iph->frag_off) & IP_OFFSET;  +	const struct xt_target *destiny;  +	int hotdrop = 0, ret;  +  +	ret = xm_tcp->match(*pskb, in, out, xm_tcp, &tcp_params,  +	                    offset, protoff, &hotdrop); -+	if(!ret || hotdrop || (unsigned int)net_random() > delude_percentage) ++	if (!ret || hotdrop || (unsigned int)net_random() > delude_percentage)  +		return;  +  +	destiny = (info->variant == XTCHAOS_TARPIT) ? xt_tarpit : xt_delude; -+#ifdef HAVE_TARGUSERINFO -+	destiny->target(pskb, in, out, hooknum, destiny, NULL, NULL); -+#else  +	destiny->target(pskb, in, out, hooknum, destiny, NULL); -+#endif  +	return;  +}  + -+static unsigned int xt_chaos_target(struct sk_buff **pskb, ++static unsigned int chaos_tg(struct sk_buff **pskb,  +    const struct net_device *in, const struct net_device *out, -+    unsigned int hooknum, const struct xt_target *target, const void *targinfo -+#ifdef HAVE_TARGUSERINFO -+    , -+    void *userinfo -+#endif -+    ) ++    unsigned int hooknum, const struct xt_target *target, const void *targinfo)  +{ -+	/* Equivalent to: ++	/* ++	 * Equivalent to:  +	 * -A chaos -m statistic --mode random --probability \  +	 *         $reject_percentage -j REJECT --reject-with host-unreach;  +	 * -A chaos -p tcp -m statistic --mode random --probability \  +	 *         $delude_percentage -j DELUDE;  +	 * -A chaos -j DROP;  +	 */ -+	const struct xt_chaos_info *info = targinfo; ++	const struct xt_chaos_target_info *info = targinfo; ++	const struct iphdr *iph = ip_hdr(*pskb);  + -+	if((unsigned int)net_random() <= reject_percentage) -+#ifdef HAVE_TARGUSERINFO -+		return xt_reject->target(pskb, in, out, hooknum, target, -+		       &reject_params, userinfo); -+#else ++	if ((unsigned int)net_random() <= reject_percentage)  +		return xt_reject->target(pskb, in, out, hooknum, target,  +		       &reject_params); -+#endif  +  +	/* TARPIT/DELUDE may not be called from the OUTPUT chain */ -+	if(ip_hdr(*pskb)->protocol == IPPROTO_TCP && -+	  info->variant != XTCHAOS_NORMAL && hooknum != NF_IP_LOCAL_OUT) ++	if (iph->protocol == IPPROTO_TCP && ++	    info->variant != XTCHAOS_NORMAL && hooknum != NF_IP_LOCAL_OUT)  +		xt_chaos_total(info, pskb, in, out, hooknum);  +  +	return NF_DROP;  +}  + -+static int xt_chaos_checkentry(const char *tablename, const void *entry, -+    const struct xt_target *target, void *targinfo, -+#ifdef HAVE_TARGINFOSIZE -+    unsigned int targinfosize, -+#endif -+    unsigned int hook_mask) ++static int chaos_tg_check(const char *tablename, const void *entry, ++    const struct xt_target *target, void *targinfo, unsigned int hook_mask)  +{ -+	const struct xt_chaos_info *info = targinfo; -+	if(info->variant == XTCHAOS_DELUDE && !have_delude) { ++	const struct xt_chaos_target_info *info = targinfo; ++ ++	if (info->variant == XTCHAOS_DELUDE && !have_delude) {  +		printk(KERN_WARNING PFX "Error: Cannot use --delude when "  +		       "DELUDE module not available\n"); -+		return 0; ++		return false;  +	} -+	if(info->variant == XTCHAOS_TARPIT && !have_tarpit) { ++	if (info->variant == XTCHAOS_TARPIT && !have_tarpit) {  +		printk(KERN_WARNING PFX "Error: Cannot use --tarpit when "  +		       "TARPIT module not available\n"); -+		return 0; ++		return false;  +	} -+	return 1; ++ ++	return true;  +}  + -+static struct xt_target xt_chaos_info = { ++static struct xt_target chaos_tg_reg = {  +	.name       = "CHAOS", -+	.target     = xt_chaos_target, -+	.checkentry = xt_chaos_checkentry, ++	.family     = AF_INET,  +	.table      = "filter", -+	.targetsize = sizeof(struct xt_chaos_info),  +	.hooks      = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) |  +	              (1 << NF_IP_LOCAL_OUT), -+	.family     = AF_INET, ++	.checkentry = chaos_tg_check, ++	.target     = chaos_tg, ++	.targetsize = sizeof(struct xt_chaos_target_info),  +	.me         = THIS_MODULE,  +};  + -+static int __init xt_chaos_init(void) ++static int __init chaos_tg_init(void)  +{  +	int ret = -EINVAL;  +  +	xm_tcp = xt_request_find_match(AF_INET, "tcp", 0); -+	if(xm_tcp == NULL) { ++	if (xm_tcp == NULL) {  +		printk(KERN_WARNING PFX "Error: Could not find or load "  +		       "\"tcp\" match\n");  +		return -EINVAL;  +	}  +  +	xt_reject = xt_request_find_target(AF_INET, "REJECT", 0); -+	if(xt_reject == NULL) { ++	if (xt_reject == NULL) {  +		printk(KERN_WARNING PFX "Error: Could not find or load "  +		       "\"REJECT\" target\n");  +		goto out2; @@ -329,17 +328,17 @@ diff -urN linux-2.6.21.1.old/net/netfilter/xt_CHAOS.c linux-2.6.21.1.dev/net/net  +  +	xt_tarpit   = xt_request_find_target(AF_INET, "TARPIT", 0);  +	have_tarpit = xt_tarpit != NULL; -+	if(!have_tarpit) ++	if (!have_tarpit)  +		printk(KERN_WARNING PFX "Warning: Could not find or load "  +		       "\"TARPIT\" target\n");  +  +	xt_delude   = xt_request_find_target(AF_INET, "DELUDE", 0);  +	have_delude = xt_delude != NULL; -+	if(!have_delude) ++	if (!have_delude)  +		printk(KERN_WARNING PFX "Warning: Could not find or load "  +		       "\"DELUDE\" target\n");  + -+	if((ret = xt_register_target(&xt_chaos_info)) != 0) { ++	if ((ret = xt_register_target(&chaos_tg_reg)) != 0) {  +		printk(KERN_WARNING PFX "xt_register_target returned "  +		       "error %d\n", ret);  +		goto out3; @@ -348,9 +347,9 @@ diff -urN linux-2.6.21.1.old/net/netfilter/xt_CHAOS.c linux-2.6.21.1.dev/net/net  +	return 0;  +  + out3: -+ 	if(have_delude) ++ 	if (have_delude)  + 		module_put(xt_delude->me); -+	if(have_tarpit) ++	if (have_tarpit)  +		module_put(xt_tarpit->me);  +	module_put(xt_reject->me);  + out2: @@ -358,131 +357,67 @@ diff -urN linux-2.6.21.1.old/net/netfilter/xt_CHAOS.c linux-2.6.21.1.dev/net/net  +	return ret;  +}  + -+static void __exit xt_chaos_exit(void) ++static void __exit chaos_tg_exit(void)  +{ -+	xt_unregister_target(&xt_chaos_info); ++	xt_unregister_target(&chaos_tg_reg);  +	module_put(xm_tcp->me);  +	module_put(xt_reject->me); -+	if(have_delude) ++	if (have_delude)  +		module_put(xt_delude->me); -+	if(have_tarpit) ++	if (have_tarpit)  +		module_put(xt_tarpit->me);  +	return;  +}  + -+module_init(xt_chaos_init); -+module_exit(xt_chaos_exit); -+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>"); -+MODULE_DESCRIPTION("netfilter CHAOS target"); ++module_init(chaos_tg_init); ++module_exit(chaos_tg_exit); ++MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); ++MODULE_DESCRIPTION("netfilter \"CHAOS\" target");  +MODULE_LICENSE("GPL");  +MODULE_ALIAS("ipt_CHAOS"); -diff -urN linux-2.6.21.1.old/net/netfilter/xt_DELUDE.c linux-2.6.21.1.dev/net/netfilter/xt_DELUDE.c ---- linux-2.6.21.1.old/net/netfilter/xt_DELUDE.c	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/net/netfilter/xt_DELUDE.c	2007-05-26 20:40:11.004183528 +0200 -@@ -0,0 +1,288 @@ +Index: linux-2.6.22.18/net/netfilter/xt_DELUDE.c +=================================================================== +--- /dev/null ++++ linux-2.6.22.18/net/netfilter/xt_DELUDE.c +@@ -0,0 +1,197 @@  +/* -+	DELUDE target -+	Copyright © Jan Engelhardt <jengelh [at] gmx de>, 2007 -+ -+	Based upon linux-2.6.18.5/net/ipv4/netfilter/ipt_REJECT.c: -+	(C) 1999-2001 Paul `Rusty' Russell -+	(C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> -+ -+	xt_DELUDE acts like REJECT, but does reply with SYN-ACK on SYN. -+ -+	This program is free software; you can redistribute it and/or modify -+	it under the terms of the GNU General Public License version 2 as -+	published by the Free Software Foundation. -+*/ ++ *	DELUDE target ++ *	Copyright © CC Computer Consultants GmbH, 2007 ++ *	Contact: Jan Engelhardt <jengelh@computergmbh.de> ++ * ++ *	Based upon linux-2.6.18.5/net/ipv4/netfilter/ipt_REJECT.c: ++ *	(C) 1999-2001 Paul `Rusty' Russell ++ *	(C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> ++ * ++ *	xt_DELUDE acts like REJECT, but does reply with SYN-ACK on SYN. ++ * ++ *	This program is free software; you can redistribute it and/or modify ++ *	it under the terms of the GNU General Public License version 2 as ++ *	published by the Free Software Foundation. ++ */  +#include <linux/module.h>  +#include <linux/skbuff.h>  +#include <linux/ip.h> -+#include <linux/random.h>  +#include <linux/tcp.h> -+#include <linux/udp.h> -+#include <linux/icmp.h> -+#include <net/icmp.h> -+#include <net/ip.h> -+#include <net/tcp.h> -+#include <net/route.h> -+#include <net/dst.h> -+#include <linux/netfilter_ipv4/ip_tables.h> ++#include <linux/netfilter/x_tables.h>  +#ifdef CONFIG_BRIDGE_NETFILTER  +#	include <linux/netfilter_bridge.h>  +#endif -+#include <linux/netfilter/oot_trans.h> ++#include <net/tcp.h>  +#define PFX KBUILD_MODNAME ": "  + -+static inline struct rtable *route_reverse(struct sk_buff *skb, -+					   struct tcphdr *tcph, int hook) -+{ -+	struct iphdr *iph = ip_hdr(skb); -+	struct dst_entry *odst; -+	struct flowi fl = {}; -+	struct rtable *rt; -+ -+	/* We don't require ip forwarding to be enabled to be able to -+	 * send a RST reply for bridged traffic. */ -+	if (hook != NF_IP_FORWARD -+#ifdef CONFIG_BRIDGE_NETFILTER -+	    || (skb->nf_bridge && skb->nf_bridge->mask & BRNF_BRIDGED) -+#endif -+	   ) { -+		fl.nl_u.ip4_u.daddr = iph->saddr; -+		if (hook == NF_IP_LOCAL_IN) -+			fl.nl_u.ip4_u.saddr = iph->daddr; -+		fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); -+ -+		if (ip_route_output_key(&rt, &fl) != 0) -+			return NULL; -+	} else { -+		/* non-local src, find valid iif to satisfy -+		 * rp-filter when calling ip_route_input. */ -+		fl.nl_u.ip4_u.daddr = iph->daddr; -+		if (ip_route_output_key(&rt, &fl) != 0) -+			return NULL; -+ -+		odst = skb->dst; -+		if (ip_route_input(skb, iph->saddr, iph->daddr, -+		                   RT_TOS(iph->tos), rt->u.dst.dev) != 0) { -+			dst_release(&rt->u.dst); -+			return NULL; -+		} -+		dst_release(&rt->u.dst); -+		rt = (struct rtable *)skb->dst; -+		skb->dst = odst; -+ -+		fl.nl_u.ip4_u.daddr = iph->saddr; -+		fl.nl_u.ip4_u.saddr = iph->daddr; -+		fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); -+	} -+ -+	if (rt->u.dst.error) { -+		dst_release(&rt->u.dst); -+		return NULL; -+	} -+ -+	fl.proto = IPPROTO_TCP; -+	fl.fl_ip_sport = tcph->dest; -+	fl.fl_ip_dport = tcph->source; -+ -+	xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0); -+ -+	return rt; -+} -+ -+static void send_reset(struct sk_buff *oldskb, int hook) ++static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)  +{ -+	struct sk_buff *nskb; -+	struct iphdr *iph = ip_hdr(oldskb);  +	struct tcphdr _otcph, *oth, *tcph; -+	__be16 tmp_port; -+	__be32 tmp_addr; -+	int needs_ack;  +	unsigned int addr_type; ++	struct sk_buff *nskb; ++	u_int16_t tmp_port; ++	u_int32_t tmp_addr; ++	struct iphdr *niph; ++	bool needs_ack;  +  +	/* IP header checks: fragment. */ -+	if (iph->frag_off & htons(IP_OFFSET)) ++	if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET))  +		return;  +  +	oth = skb_header_pointer(oldskb, ip_hdrlen(oldskb), @@ -508,78 +443,75 @@ diff -urN linux-2.6.21.1.old/net/netfilter/xt_DELUDE.c linux-2.6.21.1.dev/net/ne  +  +	/* This packet will not be the same as the other: clear nf fields */  +	nf_reset(nskb); -+	nskb->nfmark = 0; ++	nskb->mark = 0;  +	skb_init_secmark(nskb);  +  +	skb_shinfo(nskb)->gso_size = 0;  +	skb_shinfo(nskb)->gso_segs = 0;  +	skb_shinfo(nskb)->gso_type = 0;  + -+	tcph = tcp_hdr(nskb); ++	tcph = (struct tcphdr *)(skb_network_header(nskb) + ip_hdrlen(nskb));  +  +	/* Swap source and dest */ -+	tmp_addr = ip_hdr(nskb)->saddr; -+	ip_hdr(nskb)->saddr = ip_hdr(nskb)->daddr; -+	ip_hdr(nskb)->daddr = tmp_addr; -+	tmp_port = tcph->source; ++	niph         = ip_hdr(nskb); ++	tmp_addr     = niph->saddr; ++	niph->saddr  = niph->daddr; ++	niph->daddr  = tmp_addr; ++	tmp_port     = tcph->source;  +	tcph->source = tcph->dest; -+	tcph->dest = tmp_port; ++	tcph->dest   = tmp_port;  +  +	/* Truncate to length (no data) */ -+	tcph->doff = sizeof(struct tcphdr)/4; ++	tcph->doff    = sizeof(struct tcphdr) / 4;  +	skb_trim(nskb, ip_hdrlen(nskb) + sizeof(struct tcphdr)); -+	ip_hdr(nskb)->tot_len = htons(nskb->len); ++	niph->tot_len = htons(nskb->len);  + -+	if(oth->syn && !oth->ack && !oth->rst && !oth->fin) { ++	if (oth->syn && !oth->ack && !oth->rst && !oth->fin) {  +		/* DELUDE essential part */  +		tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin +  +		                oldskb->len - ip_hdrlen(oldskb) -  +		                (oth->doff << 2)); -+		tcph->seq     = htonl(secure_tcp_sequence_number( -+		                ip_hdr(nskb)->saddr, ip_hdr(nskb)->daddr, -+			        tcph->source, tcph->dest)); -+		tcph->ack     = 1; ++		tcph->seq     = false; ++		tcph->ack     = true;  +	} else { -+		if(!tcph->ack) { -+			needs_ack = 1; -+			tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin -+					      + oldskb->len - ip_hdrlen(oldskb) -+					      - (oth->doff<<2)); -+			tcph->seq = 0; ++		if (!tcph->ack) { ++			needs_ack     = true; ++			tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + ++			                oth->fin + oldskb->len - ++			                ip_hdrlen(oldskb) - (oth->doff<<2)); ++			tcph->seq     = false;  +		} else { -+			needs_ack = 0; -+			tcph->seq = oth->ack_seq; -+			tcph->ack_seq = 0; ++			needs_ack     = false; ++			tcph->seq     = oth->ack_seq; ++			tcph->ack_seq = false;  +		}  +  +		/* Reset flags */  +		((u_int8_t *)tcph)[13] = 0; -+		tcph->rst = 1; ++		tcph->rst = true;  +		tcph->ack = needs_ack;  +	}  + -+ -+	tcph->window = 0; ++	tcph->window  = 0;  +	tcph->urg_ptr = 0;  +  +	/* Adjust TCP checksum */  +	tcph->check = 0; -+	tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr), -+				   ip_hdr(nskb)->saddr, -+				   ip_hdr(nskb)->daddr, -+				   csum_partial((char *)tcph, -+						sizeof(struct tcphdr), 0)); ++	tcph->check = tcp_v4_check(sizeof(struct tcphdr), niph->saddr, ++	              niph->daddr, csum_partial((char *)tcph, ++	              sizeof(struct tcphdr), 0));  +  +	/* Set DF, id = 0 */ -+	ip_hdr(nskb)->frag_off = htons(IP_DF); -+	ip_hdr(nskb)->id = 0; ++	niph->frag_off = htons(IP_DF); ++	niph->id       = 0;  +  +	addr_type = RTN_UNSPEC; -+	if (hook != NF_IP_FORWARD  +#ifdef CONFIG_BRIDGE_NETFILTER -+	    || (nskb->nf_bridge && nskb->nf_bridge->mask & BRNF_BRIDGED) ++	if (hook != NF_IP_FORWARD || (nskb->nf_bridge != NULL && ++	    nskb->nf_bridge->mask & BRNF_BRIDGED)) ++#else ++	if (hook != NF_IP_FORWARD)  +#endif -+	   )  +		addr_type = RTN_LOCAL;  +  +	if (ip_route_me_harder(&nskb, addr_type)) @@ -588,12 +520,11 @@ diff -urN linux-2.6.21.1.old/net/netfilter/xt_DELUDE.c linux-2.6.21.1.dev/net/ne  +	nskb->ip_summed = CHECKSUM_NONE;  +  +	/* Adjust IP TTL */ -+	ip_hdr(nskb)->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); ++	niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);  +  +	/* Adjust IP checksum */ -+	ip_hdr(nskb)->check = 0; -+	ip_hdr(nskb)->check = ip_fast_csum((unsigned char *)ip_hdr(nskb), -+					   ip_hdr(nskb)->ihl); ++	niph->check = 0; ++	niph->check = ip_fast_csum(skb_network_header(nskb), niph->ihl);  +  +	/* "Never happens" */  +	if (nskb->len > dst_mtu(nskb->dst)) @@ -609,77 +540,57 @@ diff -urN linux-2.6.21.1.old/net/netfilter/xt_DELUDE.c linux-2.6.21.1.dev/net/ne  +	kfree_skb(nskb);  +}  + -+static unsigned int xt_delude_target(struct sk_buff **pskb, ++static unsigned int delude_tg(struct sk_buff **pskb,  +    const struct net_device *in, const struct net_device *out, -+    unsigned int hooknum, const struct xt_target *target, const void *targinfo -+#ifdef HAVE_TARGUSERINFO -+    , -+    void *userinfo -+#endif -+    ) ++    unsigned int hooknum, const struct xt_target *target, const void *targinfo)  +{  +	/* WARNING: This code causes reentry within iptables.  +	   This means that the iptables jump stack is now crap.  We  +	   must return an absolute verdict. --RR */ -+	send_reset(*pskb, hooknum); ++	delude_send_reset(*pskb, hooknum);  +	return NF_DROP;  +}  + -+static int xt_delude_check(const char *tablename, const void *e_void, -+    const struct xt_target *target, void *targinfo, -+#ifdef HAVE_TARGINFOSIZE -+    unsigned int targinfosize, -+#endif -+    unsigned int hook_mask) -+{ -+	if(hook_mask & ~((1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD))) { -+		printk(KERN_WARNING PFX "DELUDE may not be used in chains " -+		       "other than INPUT and FORWARD\n"); -+		return 0; -+	} -+	return 1; -+} -+ -+static struct xt_target xt_delude_info = { ++static struct xt_target delude_tg_reg = {  +	.name       = "DELUDE", -+	.target     = xt_delude_target, -+	.checkentry = xt_delude_check, ++	.family     = AF_INET,  +	.table      = "filter", -+	.hooks      = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | -+	              (1 << NF_IP_LOCAL_OUT), ++	.hooks      = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD), ++	.target     = delude_tg,  +	.proto      = IPPROTO_TCP, -+	.family     = AF_INET,  +	.me         = THIS_MODULE,  +};  + -+static int __init xt_delude_init(void) ++static int __init delude_tg_init(void)  +{ -+	return xt_register_target(&xt_delude_info); ++	return xt_register_target(&delude_tg_reg);  +}  + -+static void __exit xt_delude_exit(void) ++static void __exit delude_tg_exit(void)  +{ -+	xt_unregister_target(&xt_delude_info); ++	xt_unregister_target(&delude_tg_reg);  +}  + -+module_init(xt_delude_init); -+module_exit(xt_delude_exit); -+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>"); -+MODULE_DESCRIPTION("netfilter DELUDE target"); ++module_init(delude_tg_init); ++module_exit(delude_tg_exit); ++MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); ++MODULE_DESCRIPTION("netfilter \"DELUDE\" target");  +MODULE_LICENSE("GPL");  +MODULE_ALIAS("ipt_DELUDE"); -diff -urN linux-2.6.21.1.old/net/netfilter/xt_portscan.c linux-2.6.21.1.dev/net/netfilter/xt_portscan.c ---- linux-2.6.21.1.old/net/netfilter/xt_portscan.c	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/net/netfilter/xt_portscan.c	2007-05-26 20:40:11.004183528 +0200 -@@ -0,0 +1,272 @@ +Index: linux-2.6.22.18/net/netfilter/xt_portscan.c +=================================================================== +--- /dev/null ++++ linux-2.6.22.18/net/netfilter/xt_portscan.c +@@ -0,0 +1,269 @@  +/* -+	portscan match for netfilter -+ -+	Written by Jan Engelhardt, 2006 - 2007 -+	This program is free software; you can redistribute it and/or modify -+	it under the terms of the GNU General Public License version 2 as -+	published by the Free Software Foundation. -+*/ ++ *	portscan match for netfilter ++ *	Copyright © CC Computer Consultants GmbH, 2006 - 2007 ++ *	Contact: Jan Engelhardt <jengelh@computergmbh.de> ++ * ++ *	This program is free software; you can redistribute it and/or modify ++ *	it under the terms of the GNU General Public License; either version ++ *	2 or 3 as published by the Free Software Foundation. ++ */  +#include <linux/in.h>  +#include <linux/ip.h>  +#include <linux/module.h> @@ -691,9 +602,15 @@ diff -urN linux-2.6.21.1.old/net/netfilter/xt_portscan.c linux-2.6.21.1.dev/net/  +#include <linux/version.h>  +#include <linux/netfilter/x_tables.h>  +#include <linux/netfilter/xt_tcpudp.h> -+#include <linux/netfilter/oot_conntrack.h> -+#include <linux/netfilter/xt_portscan.h> -+#include <linux/netfilter/oot_trans.h> ++#include <net/netfilter/nf_nat_rule.h> ++#if defined(_LOCAL) ++#	include "xt_portscan.h" ++#elif defined(CONFIG_NETFILTER_XT_MATCH_PORTSCAN) || \ ++    defined(CONFIG_NETFILTER_XT_MATCH_PORTSCAN_MODULE) ++#	include <linux/netfilter/xt_portscan.h> ++#else ++#	include "xt_portscan.h" ++#endif  +#define PFX KBUILD_MODNAME ": "  +  +enum { @@ -740,55 +657,55 @@ diff -urN linux-2.6.21.1.old/net/netfilter/xt_portscan.c linux-2.6.21.1.dev/net/  +MODULE_PARM_DESC(mark_valid,    "connmark value for Valid state");  +  +/* TCP flag functions */ -+static inline int tflg_ack4(const struct tcphdr *th) ++static inline bool tflg_ack4(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_ACK;  +}  + -+static inline int tflg_ack6(const struct tcphdr *th) ++static inline bool tflg_ack6(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL6) == TCP_FLAG_ACK;  +}  + -+static inline int tflg_fin(const struct tcphdr *th) ++static inline bool tflg_fin(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_FIN;  +}  + -+static inline int tflg_rst(const struct tcphdr *th) ++static inline bool tflg_rst(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_RST;  +}  + -+static inline int tflg_rstack(const struct tcphdr *th) ++static inline bool tflg_rstack(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) ==  +	       (TCP_FLAG_ACK | TCP_FLAG_RST);  +}  + -+static inline int tflg_syn(const struct tcphdr *th) ++static inline bool tflg_syn(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_SYN;  +}  + -+static inline int tflg_synack(const struct tcphdr *th) ++static inline bool tflg_synack(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) ==  +	       (TCP_FLAG_SYN | TCP_FLAG_ACK);  +}  +  +/* portscan functions */ -+static inline int xt_portscan_stealth(const struct tcphdr *th) ++static inline bool portscan_mt_stealth(const struct tcphdr *th)  +{  +	/*  +	 * "Connection refused" replies to our own probes must not be matched.  +	 */ -+	if(tflg_rstack(th)) -+		return 0; ++	if (tflg_rstack(th)) ++		return false;  + -+	if(tflg_rst(th) && printk_ratelimit()) { ++	if (tflg_rst(th) && printk_ratelimit()) {  +		printk(KERN_WARNING PFX "Warning: Pure RST received\n"); -+		return 0; ++		return false;  +	}  +  +	/* @@ -800,42 +717,43 @@ diff -urN linux-2.6.21.1.old/net/netfilter/xt_portscan.c linux-2.6.21.1.dev/net/  +	return !tflg_syn(th);  +}  + -+static inline int xt_portscan_full(int mark, enum ip_conntrack_info ctstate, -+    int loopback, const struct tcphdr *tcph, int payload_len) ++static inline unsigned int portscan_mt_full(int mark, ++    enum ip_conntrack_info ctstate, bool loopback, const struct tcphdr *tcph, ++    unsigned int payload_len)  +{ -+	if(mark == mark_estab2) { ++	if (mark == mark_estab2) {  +		/*  +		 * -m connmark --mark $ESTAB2  +		 */ -+		if(tflg_ack4(tcph) && payload_len == 0) ++		if (tflg_ack4(tcph) && payload_len == 0)  +			return mark; /* keep mark */ -+		else if(tflg_rst(tcph) || tflg_fin(tcph)) ++		else if (tflg_rst(tcph) || tflg_fin(tcph))  +			return mark_grscan;  +		else  +			return mark_valid; -+	} else if(mark == mark_estab1) { ++	} else if (mark == mark_estab1) {  +		/*  +		 * -m connmark --mark $ESTAB1  +		 */ -+		if(tflg_rst(tcph) || tflg_fin(tcph)) ++		if (tflg_rst(tcph) || tflg_fin(tcph))  +			return mark_cnscan; -+		else if(!loopback && tflg_ack4(tcph) && payload_len == 0) ++		else if (!loopback && tflg_ack4(tcph) && payload_len == 0)  +			return mark_estab2;  +		else  +			return mark_valid; -+	} else if(mark == mark_synrcv) { ++	} else if (mark == mark_synrcv) {  +		/*  +		 * -m connmark --mark $SYN  +		 */ -+		if(loopback && tflg_synack(tcph)) ++		if (loopback && tflg_synack(tcph))  +			return mark; /* keep mark */ -+		else if(loopback && tflg_rstack(tcph)) ++		else if (loopback && tflg_rstack(tcph))  +			return mark_closed; -+		else if(tflg_ack6(tcph)) ++		else if (tflg_ack6(tcph))  +			return mark_estab1;  +		else  +			return mark_synscan; -+	} else if(ctstate == IP_CT_NEW && tflg_syn(tcph)) { ++	} else if (ctstate == IP_CT_NEW && tflg_syn(tcph)) {  +		/*  +		 * -p tcp --syn --ctstate NEW  +		 */ @@ -844,30 +762,30 @@ diff -urN linux-2.6.21.1.old/net/netfilter/xt_portscan.c linux-2.6.21.1.dev/net/  +	return mark;  +}  + -+static int xt_portscan_match(const struct sk_buff *skb, ++static int portscan_mt(const struct sk_buff *skb,  +    const struct net_device *in, const struct net_device *out,  +    const struct xt_match *match, const void *matchinfo, int offset,  +    unsigned int protoff, int *hotdrop)  +{ -+	const struct xt_portscan_info *info = matchinfo; ++	const struct xt_portscan_match_info *info = matchinfo;  +	enum ip_conntrack_info ctstate; -+	struct nf_conn *ctdata;  +	const struct tcphdr *tcph; ++	struct nf_conn *ctdata;  +	struct tcphdr tcph_buf;  +  +	tcph = skb_header_pointer(skb, protoff, sizeof(tcph_buf), &tcph_buf); -+	if(tcph == NULL) -+		return 0; ++	if (tcph == NULL) ++		return false;  +  +	/* Check for invalid packets: -m conntrack --ctstate INVALID */ -+	if((ctdata = nf_ct_get(skb, &ctstate)) == NULL) { -+		if(info->match_stealth) -+			return xt_portscan_stealth(tcph); ++	if ((ctdata = nf_ct_get(skb, &ctstate)) == NULL) { ++		if (info->match_stealth) ++			return portscan_mt_stealth(tcph);  +		/*  +		 * If @ctdata is NULL, we cannot match the other scan  +		 * types, return.  +		 */ -+		return 0; ++		return false;  +	}  +  +	/* @@ -875,17 +793,17 @@ diff -urN linux-2.6.21.1.old/net/netfilter/xt_portscan.c linux-2.6.21.1.dev/net/  +	 * simulate must not be run through again. And for speedup, do not call  +	 * it either when the connection is already VALID.  +	 */ -+	if((ctdata->mark & connmark_mask) == mark_valid || -+	  (skb->nfmark & packet_mask) != mark_seen) -+	{ ++	if ((ctdata->mark & connmark_mask) == mark_valid || ++	     (skb->mark & packet_mask) != mark_seen) {  +		unsigned int n; -+		n = xt_portscan_full(ctdata->mark & connmark_mask, ctstate, ++ ++		n = portscan_mt_full(ctdata->mark & connmark_mask, ctstate,  +		    in == &loopback_dev, tcph,  +		    skb->len - protoff - 4 * tcph->doff);  +  +		ctdata->mark = (ctdata->mark & ~connmark_mask) | n; -+		((struct sk_buff *)skb)->nfmark = -+			(skb->nfmark & ~packet_mask) | mark_seen; ++		((struct sk_buff *)skb)->mark = ++			(skb->mark & ~packet_mask) ^ mark_seen;  +	}  +  +	return (info->match_syn && ctdata->mark == mark_synscan) || @@ -893,61 +811,51 @@ diff -urN linux-2.6.21.1.old/net/netfilter/xt_portscan.c linux-2.6.21.1.dev/net/  +	       (info->match_gr && ctdata->mark == mark_grscan);  +}  + -+static int xt_portscan_checkentry(const char *tablename, const void *entry, -+    const struct xt_match *match, void *matchinfo, -+#ifdef HAVE_MATCHINFOSIZE -+    unsigned int matchinfosize, -+#endif -+    unsigned int hook_mask) ++static int portscan_mt_check(const char *tablename, const void *entry, ++    const struct xt_match *match, void *matchinfo, unsigned int hook_mask)  +{ -+	const struct xt_portscan_info *info = matchinfo; -+#ifdef HAVE_MATCHINFOSIZE -+	if(matchinfosize != XT_ALIGN(sizeof(struct xt_portscan_info))) { -+		printk(KERN_WARNING PFX "matchinfosize %u != %Zu\n", -+		       matchinfosize, -+		       XT_ALIGN(sizeof(struct xt_portscan_info))); -+		return 0; -+	} -+#endif -+	if((info->match_stealth & ~1) || (info->match_syn & ~1) || -+	  (info->match_cn & ~1) || (info->match_gr & ~1)) { ++	const struct xt_portscan_match_info *info = matchinfo; ++ ++	if ((info->match_stealth & ~1) || (info->match_syn & ~1) || ++	    (info->match_cn & ~1) || (info->match_gr & ~1)) {  +		printk(KERN_WARNING PFX "Invalid flags\n"); -+		return 0; ++		return false;  +	} -+	return 1; ++	return true;  +}  + -+static struct xt_match xt_portscan = { ++static struct xt_match portscan_mt_reg __read_mostly = {  +	.name       = "portscan", -+	.match      = xt_portscan_match, -+	.checkentry = xt_portscan_checkentry, -+	.matchsize  = sizeof(struct xt_portscan_info), -+	.proto      = IPPROTO_TCP,  +	.family     = AF_INET, ++	.match      = portscan_mt, ++	.checkentry = portscan_mt_check, ++	.matchsize  = sizeof(struct xt_portscan_match_info), ++	.proto      = IPPROTO_TCP,  +	.me         = THIS_MODULE,  +};  + -+static int __init xt_portscan_init(void) ++static int __init portscan_mt_init(void)  +{ -+	return xt_register_match(&xt_portscan); ++	return xt_register_match(&portscan_mt_reg);  +}  + -+static void __exit xt_portscan_exit(void) ++static void __exit portscan_mt_exit(void)  +{ -+	xt_unregister_match(&xt_portscan); ++	xt_unregister_match(&portscan_mt_reg);  +	return;  +}  + -+module_init(xt_portscan_init); -+module_exit(xt_portscan_exit); -+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>"); -+MODULE_DESCRIPTION("netfilter portscan match module"); ++module_init(portscan_mt_init); ++module_exit(portscan_mt_exit); ++MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); ++MODULE_DESCRIPTION("netfilter \"portscan\" match");  +MODULE_LICENSE("GPL");  +MODULE_ALIAS("ipt_portscan"); -diff -urN linux-2.6.22-rc3.old/drivers/char/random.c linux-2.6.22-rc3.dev/drivers/char/random.c ---- linux-2.6.22-rc3.old/drivers/char/random.c	2007-05-26 03:55:14.000000000 +0100 -+++ linux-2.6.22-rc3.dev/drivers/char/random.c	2007-05-29 11:21:53.000000000 +0100 -@@ -1557,6 +1557,8 @@ +Index: linux-2.6.22.18/drivers/char/random.c +=================================================================== +--- linux-2.6.22.18.orig/drivers/char/random.c ++++ linux-2.6.22.18/drivers/char/random.c +@@ -1564,6 +1564,8 @@ __u32 secure_tcp_sequence_number(__be32    	return seq;   } diff --git a/target/linux/generic-2.6/patches-2.6.22/171-netfilter_tarpit.patch b/target/linux/generic-2.6/patches-2.6.22/171-netfilter_tarpit.patch index 52c89d80f..2e5b9e813 100644 --- a/target/linux/generic-2.6/patches-2.6.22/171-netfilter_tarpit.patch +++ b/target/linux/generic-2.6/patches-2.6.22/171-netfilter_tarpit.patch @@ -1,7 +1,7 @@ -Index: linux-2.6.22.4/net/netfilter/Kconfig +Index: linux-2.6.22.18/net/netfilter/Kconfig  =================================================================== ---- linux-2.6.22.4.orig/net/netfilter/Kconfig -+++ linux-2.6.22.4/net/netfilter/Kconfig +--- linux-2.6.22.18.orig/net/netfilter/Kconfig ++++ linux-2.6.22.18/net/netfilter/Kconfig  @@ -379,6 +379,23 @@ config NETFILTER_XT_TARGET_CONNSECMARK   	  To compile it as a module, choose M here.  If unsure, say N. @@ -26,22 +26,22 @@ Index: linux-2.6.22.4/net/netfilter/Kconfig   config NETFILTER_XT_TARGET_TCPMSS   	tristate '"TCPMSS" target support'   	depends on NETFILTER_XTABLES && (IPV6 || IPV6=n) -Index: linux-2.6.22.4/net/netfilter/Makefile +Index: linux-2.6.22.18/net/netfilter/Makefile  =================================================================== ---- linux-2.6.22.4.orig/net/netfilter/Makefile -+++ linux-2.6.22.4/net/netfilter/Makefile -@@ -47,6 +47,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE +--- linux-2.6.22.18.orig/net/netfilter/Makefile ++++ linux-2.6.22.18/net/netfilter/Makefile +@@ -45,6 +45,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE   obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o   obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o   obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o  +obj-$(CONFIG_NETFILTER_XT_TARGET_TARPIT) += xt_TARPIT.o   obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o   obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o -  -Index: linux-2.6.22.4/net/netfilter/xt_TARPIT.c + obj-$(CONFIG_NETFILTER_XT_TARGET_CHAOS) += xt_CHAOS.o +Index: linux-2.6.22.18/net/netfilter/xt_TARPIT.c  ===================================================================  --- /dev/null -+++ linux-2.6.22.4/net/netfilter/xt_TARPIT.c ++++ linux-2.6.22.18/net/netfilter/xt_TARPIT.c  @@ -0,0 +1,280 @@  +/*  + * Kernel module to capture and hold incoming TCP connections using @@ -284,7 +284,7 @@ Index: linux-2.6.22.4/net/netfilter/xt_TARPIT.c  +	return NF_DROP;  +}  + -+static bool xt_tarpit_check(const char *tablename, const void *entry, ++static int xt_tarpit_check(const char *tablename, const void *entry,  +                            const struct xt_target *target, void *targinfo,  +                            unsigned int hook_mask)  +{ diff --git a/target/linux/generic-2.6/patches-2.6.23/101-netfilter_layer7_pktmatch.patch b/target/linux/generic-2.6/patches-2.6.23/101-netfilter_layer7_pktmatch.patch new file mode 100644 index 000000000..257454313 --- /dev/null +++ b/target/linux/generic-2.6/patches-2.6.23/101-netfilter_layer7_pktmatch.patch @@ -0,0 +1,113 @@ +Index: linux-2.6.23.16/include/linux/netfilter/xt_layer7.h +=================================================================== +--- linux-2.6.23.16.orig/include/linux/netfilter/xt_layer7.h ++++ linux-2.6.23.16/include/linux/netfilter/xt_layer7.h +@@ -8,6 +8,7 @@ struct xt_layer7_info { +     char protocol[MAX_PROTOCOL_LEN]; +     char pattern[MAX_PATTERN_LEN]; +     u_int8_t invert; ++    u_int8_t pkt; + }; +  + #endif /* _XT_LAYER7_H */ +Index: linux-2.6.23.16/net/netfilter/xt_layer7.c +=================================================================== +--- linux-2.6.23.16.orig/net/netfilter/xt_layer7.c ++++ linux-2.6.23.16/net/netfilter/xt_layer7.c +@@ -297,34 +297,36 @@ static int match_no_append(struct nf_con + } +  + /* add the new app data to the conntrack.  Return number of bytes added. */ +-static int add_data(struct nf_conn * master_conntrack, +-                    char * app_data, int appdatalen) ++static int add_datastr(char *target, int offset, char *app_data, int len) + { + 	int length = 0, i; +-	int oldlength = master_conntrack->layer7.app_data_len; +- +-	/* This is a fix for a race condition by Deti Fliegl. However, I'm not  +-	   clear on whether the race condition exists or whether this really  +-	   fixes it.  I might just be being dense... Anyway, if it's not really  +-	   a fix, all it does is waste a very small amount of time. */ +-	if(!master_conntrack->layer7.app_data) return 0; ++	 ++	if (!target) return 0; +  + 	/* Strip nulls. Make everything lower case (our regex lib doesn't + 	do case insensitivity).  Add it to the end of the current data. */ +-	for(i = 0; i < maxdatalen-oldlength-1 && +-		   i < appdatalen; i++) { ++	for(i = 0; i < maxdatalen-offset-1 && i < len; i++) { + 		if(app_data[i] != '\0') { + 			/* the kernel version of tolower mungs 'upper ascii' */ +-			master_conntrack->layer7.app_data[length+oldlength] = ++			target[length+offset] = + 				isascii(app_data[i])?  + 					tolower(app_data[i]) : app_data[i]; + 			length++; + 		} + 	} ++	target[length+offset] = '\0'; ++	 ++	return length; ++} +  +-	master_conntrack->layer7.app_data[length+oldlength] = '\0'; +-	master_conntrack->layer7.app_data_len = length + oldlength; ++/* add the new app data to the conntrack.  Return number of bytes added. */ ++static int add_data(struct nf_conn * master_conntrack, ++                    char * app_data, int appdatalen) ++{ ++	int length; +  ++	length = add_datastr(master_conntrack->layer7.app_data, master_conntrack->layer7.app_data_len, app_data, appdatalen); ++	master_conntrack->layer7.app_data_len += length; + 	return length; + } +  +@@ -411,7 +413,7 @@ match(const struct sk_buff *skbin, + 	const struct xt_layer7_info * info = matchinfo; + 	enum ip_conntrack_info master_ctinfo, ctinfo; + 	struct nf_conn *master_conntrack, *conntrack; +-	unsigned char * app_data; ++	unsigned char *app_data, *tmp_data; + 	unsigned int pattern_result, appdatalen; + 	regexp * comppattern; +  +@@ -439,8 +441,8 @@ match(const struct sk_buff *skbin, + 		master_conntrack = master_ct(master_conntrack); +  + 	/* if we've classified it or seen too many packets */ +-	if(TOTAL_PACKETS > num_packets || +-	   master_conntrack->layer7.app_proto) { ++	if(!info->pkt && (TOTAL_PACKETS > num_packets || ++	   master_conntrack->layer7.app_proto)) { +  + 		pattern_result = match_no_append(conntrack, master_conntrack,  + 						 ctinfo, master_ctinfo, info); +@@ -473,6 +475,25 @@ match(const struct sk_buff *skbin, + 	/* the return value gets checked later, when we're ready to use it */ + 	comppattern = compile_and_cache(info->pattern, info->protocol); +  ++	if (info->pkt) { ++		tmp_data = kmalloc(maxdatalen, GFP_ATOMIC); ++		if(!tmp_data){ ++			if (net_ratelimit()) ++				printk(KERN_ERR "layer7: out of memory in match, bailing.\n"); ++			return info->invert; ++		} ++ ++		tmp_data[0] = '\0'; ++		add_datastr(tmp_data, 0, app_data, appdatalen); ++		pattern_result = ((comppattern && regexec(comppattern, tmp_data)) ? 1 : 0); ++ ++		kfree(tmp_data); ++		tmp_data = NULL; ++		spin_unlock_bh(&l7_lock); ++ ++		return (pattern_result ^ info->invert); ++	} ++ + 	/* On the first packet of a connection, allocate space for app data */ + 	if(TOTAL_PACKETS == 1 && !skb->cb[0] &&  + 	   !master_conntrack->layer7.app_data){ diff --git a/target/linux/generic-2.6/patches-2.6.23/170-netfilter_chaostables.patch b/target/linux/generic-2.6/patches-2.6.23/170-netfilter_chaostables_0.8.patch index cfc009233..ad9e0597b 100644 --- a/target/linux/generic-2.6/patches-2.6.23/170-netfilter_chaostables.patch +++ b/target/linux/generic-2.6/patches-2.6.23/170-netfilter_chaostables_0.8.patch @@ -1,17 +1,17 @@ -Index: linux-2.6.23/include/linux/netfilter/oot_conntrack.h +Index: linux-2.6.23.16/include/linux/netfilter/oot_conntrack.h  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23/include/linux/netfilter/oot_conntrack.h	2007-10-10 13:52:59.000000000 +0800 +--- /dev/null ++++ linux-2.6.23.16/include/linux/netfilter/oot_conntrack.h  @@ -0,0 +1,5 @@  +#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)  +#	include <linux/netfilter_ipv4/ip_conntrack.h>  +#else /* linux-2.6.20+ */  +#	include <net/netfilter/nf_nat_rule.h>  +#endif -Index: linux-2.6.23/include/linux/netfilter/oot_trans.h +Index: linux-2.6.23.16/include/linux/netfilter/oot_trans.h  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23/include/linux/netfilter/oot_trans.h	2007-10-10 13:52:59.000000000 +0800 +--- /dev/null ++++ linux-2.6.23.16/include/linux/netfilter/oot_trans.h  @@ -0,0 +1,14 @@  +/* Out of tree workarounds */  +#include <linux/version.h> @@ -27,42 +27,42 @@ Index: linux-2.6.23/include/linux/netfilter/oot_trans.h  +#	define tcp_v4_check(tcph, tcph_sz, s, d, csp) \  +		tcp_v4_check((tcph_sz), (s), (d), (csp))  +#endif -Index: linux-2.6.23/include/linux/netfilter/xt_CHAOS.h +Index: linux-2.6.23.16/include/linux/netfilter/xt_CHAOS.h  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23/include/linux/netfilter/xt_CHAOS.h	2007-10-10 13:52:59.000000000 +0800 +--- /dev/null ++++ linux-2.6.23.16/include/linux/netfilter/xt_CHAOS.h  @@ -0,0 +1,14 @@ -+#ifndef _LINUX_XT_CHAOS_H -+#define _LINUX_XT_CHAOS_H 1 ++#ifndef _LINUX_NETFILTER_XT_CHAOS_H ++#define _LINUX_NETFILTER_XT_CHAOS_H 1  + -+enum xt_chaos_variant { ++enum xt_chaos_target_variant {  +	XTCHAOS_NORMAL,  +	XTCHAOS_TARPIT,  +	XTCHAOS_DELUDE,  +};  + -+struct xt_chaos_info { -+	enum xt_chaos_variant variant; ++struct xt_chaos_target_info { ++	uint8_t variant;  +};  + -+#endif /* _LINUX_XT_CHAOS_H */ -Index: linux-2.6.23/include/linux/netfilter/xt_portscan.h ++#endif /* _LINUX_NETFILTER_XT_CHAOS_H */ +Index: linux-2.6.23.16/include/linux/netfilter/xt_portscan.h  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23/include/linux/netfilter/xt_portscan.h	2007-10-10 13:52:59.000000000 +0800 +--- /dev/null ++++ linux-2.6.23.16/include/linux/netfilter/xt_portscan.h  @@ -0,0 +1,8 @@ -+#ifndef _LINUX_XT_PORTSCAN_H -+#define _LINUX_XT_PORTSCAN_H 1 ++#ifndef _LINUX_NETFILTER_XT_PORTSCAN_H ++#define _LINUX_NETFILTER_XT_PORTSCAN_H 1  + -+struct xt_portscan_info { -+	unsigned int match_stealth, match_syn, match_cn, match_gr; ++struct xt_portscan_match_info { ++	uint8_t match_stealth, match_syn, match_cn, match_gr;  +};  + -+#endif /* _LINUX_XT_PORTSCAN_H */ -Index: linux-2.6.23/net/netfilter/find_match.c ++#endif /* _LINUX_NETFILTER_XT_PORTSCAN_H */ +Index: linux-2.6.23.16/net/netfilter/find_match.c  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23/net/netfilter/find_match.c	2007-10-10 13:52:59.000000000 +0800 +--- /dev/null ++++ linux-2.6.23.16/net/netfilter/find_match.c  @@ -0,0 +1,39 @@  +/*  +    xt_request_find_match @@ -95,7 +95,7 @@ Index: linux-2.6.23/net/netfilter/find_match.c  +  +	match = try_then_request_module(xt_find_match(af, name, revision),  +		"%st_%s", xt_prefix[af], name); -+	if(IS_ERR(match) || match == NULL) ++	if (IS_ERR(match) || match == NULL)  +		return NULL;  +  +	return match; @@ -103,11 +103,11 @@ Index: linux-2.6.23/net/netfilter/find_match.c  +  +/* In case it goes into mainline, let this out-of-tree package compile */  +#define xt_request_find_match xt_request_find_match_lo -Index: linux-2.6.23/net/netfilter/Kconfig +Index: linux-2.6.23.16/net/netfilter/Kconfig  =================================================================== ---- linux-2.6.23.orig/net/netfilter/Kconfig	2007-10-10 04:31:38.000000000 +0800 -+++ linux-2.6.23/net/netfilter/Kconfig	2007-10-10 13:53:04.000000000 +0800 -@@ -265,6 +265,14 @@ +--- linux-2.6.23.16.orig/net/netfilter/Kconfig ++++ linux-2.6.23.16/net/netfilter/Kconfig +@@ -265,6 +265,14 @@ config NETFILTER_XTABLES   # alphabetically ordered list of targets @@ -122,7 +122,7 @@ Index: linux-2.6.23/net/netfilter/Kconfig   config NETFILTER_XT_TARGET_CLASSIFY   	tristate '"CLASSIFY" target support'   	depends on NETFILTER_XTABLES -@@ -292,6 +300,14 @@ +@@ -292,6 +300,14 @@ config NETFILTER_XT_TARGET_CONNMARK   	  <file:Documentation/kbuild/modules.txt>.  The module will be called   	  ipt_CONNMARK.ko.  If unsure, say `N'. @@ -137,7 +137,7 @@ Index: linux-2.6.23/net/netfilter/Kconfig   config NETFILTER_XT_TARGET_DSCP   	tristate '"DSCP" target support'   	depends on NETFILTER_XTABLES -@@ -556,6 +572,14 @@ +@@ -556,6 +572,14 @@ config NETFILTER_XT_MATCH_POLICY   	  To compile it as a module, choose M here.  If unsure, say N. @@ -152,42 +152,38 @@ Index: linux-2.6.23/net/netfilter/Kconfig   config NETFILTER_XT_MATCH_MULTIPORT   	tristate "Multiple port match support"   	depends on NETFILTER_XTABLES -Index: linux-2.6.23/net/netfilter/Makefile +Index: linux-2.6.23.16/net/netfilter/Makefile  =================================================================== ---- linux-2.6.23.orig/net/netfilter/Makefile	2007-10-10 04:31:38.000000000 +0800 -+++ linux-2.6.23/net/netfilter/Makefile	2007-10-10 13:52:59.000000000 +0800 -@@ -38,8 +38,10 @@ - obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o -  - # targets +--- linux-2.6.23.16.orig/net/netfilter/Makefile ++++ linux-2.6.23.16/net/netfilter/Makefile +@@ -49,6 +49,8 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE)  + obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o + obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o + obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o  +obj-$(CONFIG_NETFILTER_XT_TARGET_CHAOS) += xt_CHAOS.o - obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o - obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o  +obj-$(CONFIG_NETFILTER_XT_TARGET_DELUDE) += xt_DELUDE.o - obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o - obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o - obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o -@@ -66,6 +68,7 @@ - obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o - obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o - obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o +  + # matches + obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o +@@ -78,3 +80,4 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS)  + obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o + obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o + obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o  +obj-$(CONFIG_NETFILTER_XT_MATCH_PORTSCAN) += xt_portscan.o - obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o - obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o - obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o -Index: linux-2.6.23/net/netfilter/xt_CHAOS.c +Index: linux-2.6.23.16/net/netfilter/xt_CHAOS.c  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23/net/netfilter/xt_CHAOS.c	2007-10-10 13:52:59.000000000 +0800 -@@ -0,0 +1,205 @@ +--- /dev/null ++++ linux-2.6.23.16/net/netfilter/xt_CHAOS.c +@@ -0,0 +1,200 @@  +/* -+	CHAOS target for netfilter -+ -+	Copyright © Jan Engelhardt <jengelh [at] gmx de>, 2006 - 2007 -+	This program is free software; you can redistribute it and/or modify -+	it under the terms of the GNU General Public License version 2 as -+	published by the Free Software Foundation. -+*/ ++ *	CHAOS target for netfilter ++ *	Copyright © CC Computer Consultants GmbH, 2006 - 2007 ++ *	Contact: Jan Engelhardt <jengelh@computergmbh.de> ++ * ++ *	This program is free software; you can redistribute it and/or modify ++ *	it under the terms of the GNU General Public License; either version ++ *	2 or 3 as published by the Free Software Foundation. ++ */  +#include <linux/icmp.h>  +#include <linux/in.h>  +#include <linux/ip.h> @@ -198,9 +194,17 @@ Index: linux-2.6.23/net/netfilter/xt_CHAOS.c  +#include <linux/netfilter/xt_tcpudp.h>  +#include <linux/netfilter_ipv4/ipt_REJECT.h>  +#include <net/ip.h> -+#include <linux/netfilter/xt_CHAOS.h> -+#include "find_match.c" -+#include <linux/netfilter/oot_trans.h> ++#if defined(_LOCAL) ++#	include "xt_CHAOS.h" ++#	include "find_match.c" ++#elif defined(CONFIG_NETFILTER_XT_TARGET_CHAOS) || \ ++    defined(CONFIG_NETFILTER_XT_TARGET_CHAOS_MODULE) ++#	include <linux/netfilter/xt_CHAOS.h> ++#	include "find_match.c" ++#else ++#	include "xt_CHAOS.h" ++#	include "find_match.c" ++#endif  +#define PFX KBUILD_MODNAME ": "  +  +/* Module parameters */ @@ -226,111 +230,97 @@ Index: linux-2.6.23/net/netfilter/xt_CHAOS.c  +};  +  +/* CHAOS functions */ -+static void xt_chaos_total(const struct xt_chaos_info *info, ++static void xt_chaos_total(const struct xt_chaos_target_info *info,  +    struct sk_buff **pskb, const struct net_device *in,  +    const struct net_device *out, unsigned int hooknum)  +{ -+	const int protoff = ip_hdrlen(*pskb); -+	const int offset  = ntohs(ip_hdr(*pskb)->frag_off) & IP_OFFSET; ++	const struct iphdr *iph = ip_hdr(*pskb); ++	const int protoff       = 4 * iph->ihl; ++	const int offset        = ntohs(iph->frag_off) & IP_OFFSET;  +	const struct xt_target *destiny; -+	bool hotdrop = false; -+	int ret; ++	bool hotdrop = false, ret;  +  +	ret = xm_tcp->match(*pskb, in, out, xm_tcp, &tcp_params,  +	                    offset, protoff, &hotdrop); -+	if(!ret || hotdrop || (unsigned int)net_random() > delude_percentage) ++	if (!ret || hotdrop || (unsigned int)net_random() > delude_percentage)  +		return;  +  +	destiny = (info->variant == XTCHAOS_TARPIT) ? xt_tarpit : xt_delude; -+#ifdef HAVE_TARGUSERINFO -+	destiny->target(pskb, in, out, hooknum, destiny, NULL, NULL); -+#else  +	destiny->target(pskb, in, out, hooknum, destiny, NULL); -+#endif  +	return;  +}  + -+static unsigned int xt_chaos_target(struct sk_buff **pskb, ++static unsigned int chaos_tg(struct sk_buff **pskb,  +    const struct net_device *in, const struct net_device *out, -+    unsigned int hooknum, const struct xt_target *target, const void *targinfo -+#ifdef HAVE_TARGUSERINFO -+    , -+    void *userinfo -+#endif -+    ) ++    unsigned int hooknum, const struct xt_target *target, const void *targinfo)  +{ -+	/* Equivalent to: ++	/* ++	 * Equivalent to:  +	 * -A chaos -m statistic --mode random --probability \  +	 *         $reject_percentage -j REJECT --reject-with host-unreach;  +	 * -A chaos -p tcp -m statistic --mode random --probability \  +	 *         $delude_percentage -j DELUDE;  +	 * -A chaos -j DROP;  +	 */ -+	const struct xt_chaos_info *info = targinfo; ++	const struct xt_chaos_target_info *info = targinfo; ++	const struct iphdr *iph = ip_hdr(*pskb);  + -+	if((unsigned int)net_random() <= reject_percentage) -+#ifdef HAVE_TARGUSERINFO -+		return xt_reject->target(pskb, in, out, hooknum, target, -+		       &reject_params, userinfo); -+#else ++	if ((unsigned int)net_random() <= reject_percentage)  +		return xt_reject->target(pskb, in, out, hooknum, target,  +		       &reject_params); -+#endif  +  +	/* TARPIT/DELUDE may not be called from the OUTPUT chain */ -+	if(ip_hdr(*pskb)->protocol == IPPROTO_TCP && -+	  info->variant != XTCHAOS_NORMAL && hooknum != NF_IP_LOCAL_OUT) ++	if (iph->protocol == IPPROTO_TCP && ++	    info->variant != XTCHAOS_NORMAL && hooknum != NF_IP_LOCAL_OUT)  +		xt_chaos_total(info, pskb, in, out, hooknum);  +  +	return NF_DROP;  +}  + -+static bool xt_chaos_checkentry(const char *tablename, const void *entry, -+    const struct xt_target *target, void *targinfo, -+#ifdef HAVE_TARGINFOSIZE -+    unsigned int targinfosize, -+#endif -+    unsigned int hook_mask) ++static bool chaos_tg_check(const char *tablename, const void *entry, ++    const struct xt_target *target, void *targinfo, unsigned int hook_mask)  +{ -+	const struct xt_chaos_info *info = targinfo; -+	if(info->variant == XTCHAOS_DELUDE && !have_delude) { ++	const struct xt_chaos_target_info *info = targinfo; ++ ++	if (info->variant == XTCHAOS_DELUDE && !have_delude) {  +		printk(KERN_WARNING PFX "Error: Cannot use --delude when "  +		       "DELUDE module not available\n");  +		return false;  +	} -+	if(info->variant == XTCHAOS_TARPIT && !have_tarpit) { ++	if (info->variant == XTCHAOS_TARPIT && !have_tarpit) {  +		printk(KERN_WARNING PFX "Error: Cannot use --tarpit when "  +		       "TARPIT module not available\n");  +		return false;  +	} ++  +	return true;  +}  + -+static struct xt_target xt_chaos_info = { ++static struct xt_target chaos_tg_reg = {  +	.name       = "CHAOS", -+	.target     = xt_chaos_target, -+	.checkentry = xt_chaos_checkentry, ++	.family     = AF_INET,  +	.table      = "filter", -+	.targetsize = sizeof(struct xt_chaos_info),  +	.hooks      = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) |  +	              (1 << NF_IP_LOCAL_OUT), -+	.family     = AF_INET, ++	.checkentry = chaos_tg_check, ++	.target     = chaos_tg, ++	.targetsize = sizeof(struct xt_chaos_target_info),  +	.me         = THIS_MODULE,  +};  + -+static int __init xt_chaos_init(void) ++static int __init chaos_tg_init(void)  +{  +	int ret = -EINVAL;  +  +	xm_tcp = xt_request_find_match(AF_INET, "tcp", 0); -+	if(xm_tcp == NULL) { ++	if (xm_tcp == NULL) {  +		printk(KERN_WARNING PFX "Error: Could not find or load "  +		       "\"tcp\" match\n");  +		return -EINVAL;  +	}  +  +	xt_reject = xt_request_find_target(AF_INET, "REJECT", 0); -+	if(xt_reject == NULL) { ++	if (xt_reject == NULL) {  +		printk(KERN_WARNING PFX "Error: Could not find or load "  +		       "\"REJECT\" target\n");  +		goto out2; @@ -338,17 +328,17 @@ Index: linux-2.6.23/net/netfilter/xt_CHAOS.c  +  +	xt_tarpit   = xt_request_find_target(AF_INET, "TARPIT", 0);  +	have_tarpit = xt_tarpit != NULL; -+	if(!have_tarpit) ++	if (!have_tarpit)  +		printk(KERN_WARNING PFX "Warning: Could not find or load "  +		       "\"TARPIT\" target\n");  +  +	xt_delude   = xt_request_find_target(AF_INET, "DELUDE", 0);  +	have_delude = xt_delude != NULL; -+	if(!have_delude) ++	if (!have_delude)  +		printk(KERN_WARNING PFX "Warning: Could not find or load "  +		       "\"DELUDE\" target\n");  + -+	if((ret = xt_register_target(&xt_chaos_info)) != 0) { ++	if ((ret = xt_register_target(&chaos_tg_reg)) != 0) {  +		printk(KERN_WARNING PFX "xt_register_target returned "  +		       "error %d\n", ret);  +		goto out3; @@ -357,9 +347,9 @@ Index: linux-2.6.23/net/netfilter/xt_CHAOS.c  +	return 0;  +  + out3: -+ 	if(have_delude) ++ 	if (have_delude)  + 		module_put(xt_delude->me); -+	if(have_tarpit) ++	if (have_tarpit)  +		module_put(xt_tarpit->me);  +	module_put(xt_reject->me);  + out2: @@ -367,132 +357,67 @@ Index: linux-2.6.23/net/netfilter/xt_CHAOS.c  +	return ret;  +}  + -+static void __exit xt_chaos_exit(void) ++static void __exit chaos_tg_exit(void)  +{ -+	xt_unregister_target(&xt_chaos_info); ++	xt_unregister_target(&chaos_tg_reg);  +	module_put(xm_tcp->me);  +	module_put(xt_reject->me); -+	if(have_delude) ++	if (have_delude)  +		module_put(xt_delude->me); -+	if(have_tarpit) ++	if (have_tarpit)  +		module_put(xt_tarpit->me);  +	return;  +}  + -+module_init(xt_chaos_init); -+module_exit(xt_chaos_exit); -+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>"); -+MODULE_DESCRIPTION("netfilter CHAOS target"); ++module_init(chaos_tg_init); ++module_exit(chaos_tg_exit); ++MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); ++MODULE_DESCRIPTION("netfilter \"CHAOS\" target");  +MODULE_LICENSE("GPL");  +MODULE_ALIAS("ipt_CHAOS"); -Index: linux-2.6.23/net/netfilter/xt_DELUDE.c +Index: linux-2.6.23.16/net/netfilter/xt_DELUDE.c  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23/net/netfilter/xt_DELUDE.c	2007-10-10 13:52:59.000000000 +0800 -@@ -0,0 +1,288 @@ +--- /dev/null ++++ linux-2.6.23.16/net/netfilter/xt_DELUDE.c +@@ -0,0 +1,197 @@  +/* -+	DELUDE target -+	Copyright © Jan Engelhardt <jengelh [at] gmx de>, 2007 -+ -+	Based upon linux-2.6.18.5/net/ipv4/netfilter/ipt_REJECT.c: -+	(C) 1999-2001 Paul `Rusty' Russell -+	(C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> -+ -+	xt_DELUDE acts like REJECT, but does reply with SYN-ACK on SYN. -+ -+	This program is free software; you can redistribute it and/or modify -+	it under the terms of the GNU General Public License version 2 as -+	published by the Free Software Foundation. -+*/ ++ *	DELUDE target ++ *	Copyright © CC Computer Consultants GmbH, 2007 ++ *	Contact: Jan Engelhardt <jengelh@computergmbh.de> ++ * ++ *	Based upon linux-2.6.18.5/net/ipv4/netfilter/ipt_REJECT.c: ++ *	(C) 1999-2001 Paul `Rusty' Russell ++ *	(C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> ++ * ++ *	xt_DELUDE acts like REJECT, but does reply with SYN-ACK on SYN. ++ * ++ *	This program is free software; you can redistribute it and/or modify ++ *	it under the terms of the GNU General Public License version 2 as ++ *	published by the Free Software Foundation. ++ */  +#include <linux/module.h>  +#include <linux/skbuff.h>  +#include <linux/ip.h> -+#include <linux/random.h>  +#include <linux/tcp.h> -+#include <linux/udp.h> -+#include <linux/icmp.h> -+#include <net/icmp.h> -+#include <net/ip.h> -+#include <net/tcp.h> -+#include <net/route.h> -+#include <net/dst.h> -+#include <linux/netfilter_ipv4/ip_tables.h> ++#include <linux/netfilter/x_tables.h>  +#ifdef CONFIG_BRIDGE_NETFILTER  +#	include <linux/netfilter_bridge.h>  +#endif -+#include <linux/netfilter/oot_trans.h> ++#include <net/tcp.h>  +#define PFX KBUILD_MODNAME ": "  + -+static inline struct rtable *route_reverse(struct sk_buff *skb, -+					   struct tcphdr *tcph, int hook) ++static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)  +{ -+	struct iphdr *iph = ip_hdr(skb); -+	struct dst_entry *odst; -+	struct flowi fl = {}; -+	struct rtable *rt; -+ -+	/* We don't require ip forwarding to be enabled to be able to -+	 * send a RST reply for bridged traffic. */ -+	if (hook != NF_IP_FORWARD -+#ifdef CONFIG_BRIDGE_NETFILTER -+	    || (skb->nf_bridge && skb->nf_bridge->mask & BRNF_BRIDGED) -+#endif -+	   ) { -+		fl.nl_u.ip4_u.daddr = iph->saddr; -+		if (hook == NF_IP_LOCAL_IN) -+			fl.nl_u.ip4_u.saddr = iph->daddr; -+		fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); -+ -+		if (ip_route_output_key(&rt, &fl) != 0) -+			return NULL; -+	} else { -+		/* non-local src, find valid iif to satisfy -+		 * rp-filter when calling ip_route_input. */ -+		fl.nl_u.ip4_u.daddr = iph->daddr; -+		if (ip_route_output_key(&rt, &fl) != 0) -+			return NULL; -+ -+		odst = skb->dst; -+		if (ip_route_input(skb, iph->saddr, iph->daddr, -+		                   RT_TOS(iph->tos), rt->u.dst.dev) != 0) { -+			dst_release(&rt->u.dst); -+			return NULL; -+		} -+		dst_release(&rt->u.dst); -+		rt = (struct rtable *)skb->dst; -+		skb->dst = odst; -+ -+		fl.nl_u.ip4_u.daddr = iph->saddr; -+		fl.nl_u.ip4_u.saddr = iph->daddr; -+		fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); -+	} -+ -+	if (rt->u.dst.error) { -+		dst_release(&rt->u.dst); -+		return NULL; -+	} -+ -+	fl.proto = IPPROTO_TCP; -+	fl.fl_ip_sport = tcph->dest; -+	fl.fl_ip_dport = tcph->source; -+ -+	xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0); -+ -+	return rt; -+} -+ -+static void send_reset(struct sk_buff *oldskb, int hook) -+{ -+	struct sk_buff *nskb; -+	struct iphdr *iph = ip_hdr(oldskb);  +	struct tcphdr _otcph, *oth, *tcph; -+	__be16 tmp_port; -+	__be32 tmp_addr; -+	int needs_ack;  +	unsigned int addr_type; ++	struct sk_buff *nskb; ++	u_int16_t tmp_port; ++	u_int32_t tmp_addr; ++	struct iphdr *niph; ++	bool needs_ack;  +  +	/* IP header checks: fragment. */ -+	if (iph->frag_off & htons(IP_OFFSET)) ++	if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET))  +		return;  +  +	oth = skb_header_pointer(oldskb, ip_hdrlen(oldskb), @@ -518,78 +443,75 @@ Index: linux-2.6.23/net/netfilter/xt_DELUDE.c  +  +	/* This packet will not be the same as the other: clear nf fields */  +	nf_reset(nskb); -+	nskb->nfmark = 0; ++	nskb->mark = 0;  +	skb_init_secmark(nskb);  +  +	skb_shinfo(nskb)->gso_size = 0;  +	skb_shinfo(nskb)->gso_segs = 0;  +	skb_shinfo(nskb)->gso_type = 0;  + -+	tcph = tcp_hdr(nskb); ++	tcph = (struct tcphdr *)(skb_network_header(nskb) + ip_hdrlen(nskb));  +  +	/* Swap source and dest */ -+	tmp_addr = ip_hdr(nskb)->saddr; -+	ip_hdr(nskb)->saddr = ip_hdr(nskb)->daddr; -+	ip_hdr(nskb)->daddr = tmp_addr; -+	tmp_port = tcph->source; ++	niph         = ip_hdr(nskb); ++	tmp_addr     = niph->saddr; ++	niph->saddr  = niph->daddr; ++	niph->daddr  = tmp_addr; ++	tmp_port     = tcph->source;  +	tcph->source = tcph->dest; -+	tcph->dest = tmp_port; ++	tcph->dest   = tmp_port;  +  +	/* Truncate to length (no data) */ -+	tcph->doff = sizeof(struct tcphdr)/4; ++	tcph->doff    = sizeof(struct tcphdr) / 4;  +	skb_trim(nskb, ip_hdrlen(nskb) + sizeof(struct tcphdr)); -+	ip_hdr(nskb)->tot_len = htons(nskb->len); ++	niph->tot_len = htons(nskb->len);  + -+	if(oth->syn && !oth->ack && !oth->rst && !oth->fin) { ++	if (oth->syn && !oth->ack && !oth->rst && !oth->fin) {  +		/* DELUDE essential part */  +		tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin +  +		                oldskb->len - ip_hdrlen(oldskb) -  +		                (oth->doff << 2)); -+		tcph->seq     = htonl(secure_tcp_sequence_number( -+		                ip_hdr(nskb)->saddr, ip_hdr(nskb)->daddr, -+			        tcph->source, tcph->dest)); -+		tcph->ack     = 1; ++		tcph->seq     = false; ++		tcph->ack     = true;  +	} else { -+		if(!tcph->ack) { -+			needs_ack = 1; -+			tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin -+					      + oldskb->len - ip_hdrlen(oldskb) -+					      - (oth->doff<<2)); -+			tcph->seq = 0; ++		if (!tcph->ack) { ++			needs_ack     = true; ++			tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + ++			                oth->fin + oldskb->len - ++			                ip_hdrlen(oldskb) - (oth->doff<<2)); ++			tcph->seq     = false;  +		} else { -+			needs_ack = 0; -+			tcph->seq = oth->ack_seq; -+			tcph->ack_seq = 0; ++			needs_ack     = false; ++			tcph->seq     = oth->ack_seq; ++			tcph->ack_seq = false;  +		}  +  +		/* Reset flags */  +		((u_int8_t *)tcph)[13] = 0; -+		tcph->rst = 1; ++		tcph->rst = true;  +		tcph->ack = needs_ack;  +	}  + -+ -+	tcph->window = 0; ++	tcph->window  = 0;  +	tcph->urg_ptr = 0;  +  +	/* Adjust TCP checksum */  +	tcph->check = 0; -+	tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr), -+				   ip_hdr(nskb)->saddr, -+				   ip_hdr(nskb)->daddr, -+				   csum_partial((char *)tcph, -+						sizeof(struct tcphdr), 0)); ++	tcph->check = tcp_v4_check(sizeof(struct tcphdr), niph->saddr, ++	              niph->daddr, csum_partial((char *)tcph, ++	              sizeof(struct tcphdr), 0));  +  +	/* Set DF, id = 0 */ -+	ip_hdr(nskb)->frag_off = htons(IP_DF); -+	ip_hdr(nskb)->id = 0; ++	niph->frag_off = htons(IP_DF); ++	niph->id       = 0;  +  +	addr_type = RTN_UNSPEC; -+	if (hook != NF_IP_FORWARD  +#ifdef CONFIG_BRIDGE_NETFILTER -+	    || (nskb->nf_bridge && nskb->nf_bridge->mask & BRNF_BRIDGED) ++	if (hook != NF_IP_FORWARD || (nskb->nf_bridge != NULL && ++	    nskb->nf_bridge->mask & BRNF_BRIDGED)) ++#else ++	if (hook != NF_IP_FORWARD)  +#endif -+	   )  +		addr_type = RTN_LOCAL;  +  +	if (ip_route_me_harder(&nskb, addr_type)) @@ -598,12 +520,11 @@ Index: linux-2.6.23/net/netfilter/xt_DELUDE.c  +	nskb->ip_summed = CHECKSUM_NONE;  +  +	/* Adjust IP TTL */ -+	ip_hdr(nskb)->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); ++	niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);  +  +	/* Adjust IP checksum */ -+	ip_hdr(nskb)->check = 0; -+	ip_hdr(nskb)->check = ip_fast_csum((unsigned char *)ip_hdr(nskb), -+					   ip_hdr(nskb)->ihl); ++	niph->check = 0; ++	niph->check = ip_fast_csum(skb_network_header(nskb), niph->ihl);  +  +	/* "Never happens" */  +	if (nskb->len > dst_mtu(nskb->dst)) @@ -619,78 +540,57 @@ Index: linux-2.6.23/net/netfilter/xt_DELUDE.c  +	kfree_skb(nskb);  +}  + -+static unsigned int xt_delude_target(struct sk_buff **pskb, ++static unsigned int delude_tg(struct sk_buff **pskb,  +    const struct net_device *in, const struct net_device *out, -+    unsigned int hooknum, const struct xt_target *target, const void *targinfo -+#ifdef HAVE_TARGUSERINFO -+    , -+    void *userinfo -+#endif -+    ) ++    unsigned int hooknum, const struct xt_target *target, const void *targinfo)  +{  +	/* WARNING: This code causes reentry within iptables.  +	   This means that the iptables jump stack is now crap.  We  +	   must return an absolute verdict. --RR */ -+	send_reset(*pskb, hooknum); ++	delude_send_reset(*pskb, hooknum);  +	return NF_DROP;  +}  + -+static bool xt_delude_check(const char *tablename, const void *e_void, -+    const struct xt_target *target, void *targinfo, -+#ifdef HAVE_TARGINFOSIZE -+    unsigned int targinfosize, -+#endif -+    unsigned int hook_mask) -+{ -+	if(hook_mask & ~((1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD))) { -+		printk(KERN_WARNING PFX "DELUDE may not be used in chains " -+		       "other than INPUT and FORWARD\n"); -+		return false; -+	} -+	return true; -+} -+ -+static struct xt_target xt_delude_info = { ++static struct xt_target delude_tg_reg = {  +	.name       = "DELUDE", -+	.target     = xt_delude_target, -+	.checkentry = xt_delude_check, ++	.family     = AF_INET,  +	.table      = "filter", -+	.hooks      = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | -+	              (1 << NF_IP_LOCAL_OUT), ++	.hooks      = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD), ++	.target     = delude_tg,  +	.proto      = IPPROTO_TCP, -+	.family     = AF_INET,  +	.me         = THIS_MODULE,  +};  + -+static int __init xt_delude_init(void) ++static int __init delude_tg_init(void)  +{ -+	return xt_register_target(&xt_delude_info); ++	return xt_register_target(&delude_tg_reg);  +}  + -+static void __exit xt_delude_exit(void) ++static void __exit delude_tg_exit(void)  +{ -+	xt_unregister_target(&xt_delude_info); ++	xt_unregister_target(&delude_tg_reg);  +}  + -+module_init(xt_delude_init); -+module_exit(xt_delude_exit); -+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>"); -+MODULE_DESCRIPTION("netfilter DELUDE target"); ++module_init(delude_tg_init); ++module_exit(delude_tg_exit); ++MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); ++MODULE_DESCRIPTION("netfilter \"DELUDE\" target");  +MODULE_LICENSE("GPL");  +MODULE_ALIAS("ipt_DELUDE"); -Index: linux-2.6.23/net/netfilter/xt_portscan.c +Index: linux-2.6.23.16/net/netfilter/xt_portscan.c  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23/net/netfilter/xt_portscan.c	2007-10-10 13:52:59.000000000 +0800 -@@ -0,0 +1,272 @@ +--- /dev/null ++++ linux-2.6.23.16/net/netfilter/xt_portscan.c +@@ -0,0 +1,269 @@  +/* -+	portscan match for netfilter -+ -+	Written by Jan Engelhardt, 2006 - 2007 -+	This program is free software; you can redistribute it and/or modify -+	it under the terms of the GNU General Public License version 2 as -+	published by the Free Software Foundation. -+*/ ++ *	portscan match for netfilter ++ *	Copyright © CC Computer Consultants GmbH, 2006 - 2007 ++ *	Contact: Jan Engelhardt <jengelh@computergmbh.de> ++ * ++ *	This program is free software; you can redistribute it and/or modify ++ *	it under the terms of the GNU General Public License; either version ++ *	2 or 3 as published by the Free Software Foundation. ++ */  +#include <linux/in.h>  +#include <linux/ip.h>  +#include <linux/module.h> @@ -702,9 +602,15 @@ Index: linux-2.6.23/net/netfilter/xt_portscan.c  +#include <linux/version.h>  +#include <linux/netfilter/x_tables.h>  +#include <linux/netfilter/xt_tcpudp.h> -+#include <linux/netfilter/oot_conntrack.h> -+#include <linux/netfilter/xt_portscan.h> -+#include <linux/netfilter/oot_trans.h> ++#include <net/netfilter/nf_nat_rule.h> ++#if defined(_LOCAL) ++#	include "xt_portscan.h" ++#elif defined(CONFIG_NETFILTER_XT_MATCH_PORTSCAN) || \ ++    defined(CONFIG_NETFILTER_XT_MATCH_PORTSCAN_MODULE) ++#	include <linux/netfilter/xt_portscan.h> ++#else ++#	include "xt_portscan.h" ++#endif  +#define PFX KBUILD_MODNAME ": "  +  +enum { @@ -751,55 +657,55 @@ Index: linux-2.6.23/net/netfilter/xt_portscan.c  +MODULE_PARM_DESC(mark_valid,    "connmark value for Valid state");  +  +/* TCP flag functions */ -+static inline int tflg_ack4(const struct tcphdr *th) ++static inline bool tflg_ack4(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_ACK;  +}  + -+static inline int tflg_ack6(const struct tcphdr *th) ++static inline bool tflg_ack6(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL6) == TCP_FLAG_ACK;  +}  + -+static inline int tflg_fin(const struct tcphdr *th) ++static inline bool tflg_fin(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_FIN;  +}  + -+static inline int tflg_rst(const struct tcphdr *th) ++static inline bool tflg_rst(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_RST;  +}  + -+static inline int tflg_rstack(const struct tcphdr *th) ++static inline bool tflg_rstack(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) ==  +	       (TCP_FLAG_ACK | TCP_FLAG_RST);  +}  + -+static inline int tflg_syn(const struct tcphdr *th) ++static inline bool tflg_syn(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_SYN;  +}  + -+static inline int tflg_synack(const struct tcphdr *th) ++static inline bool tflg_synack(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) ==  +	       (TCP_FLAG_SYN | TCP_FLAG_ACK);  +}  +  +/* portscan functions */ -+static inline int xt_portscan_stealth(const struct tcphdr *th) ++static inline bool portscan_mt_stealth(const struct tcphdr *th)  +{  +	/*  +	 * "Connection refused" replies to our own probes must not be matched.  +	 */ -+	if(tflg_rstack(th)) -+		return 0; ++	if (tflg_rstack(th)) ++		return false;  + -+	if(tflg_rst(th) && printk_ratelimit()) { ++	if (tflg_rst(th) && printk_ratelimit()) {  +		printk(KERN_WARNING PFX "Warning: Pure RST received\n"); -+		return 0; ++		return false;  +	}  +  +	/* @@ -811,42 +717,43 @@ Index: linux-2.6.23/net/netfilter/xt_portscan.c  +	return !tflg_syn(th);  +}  + -+static inline int xt_portscan_full(int mark, enum ip_conntrack_info ctstate, -+    int loopback, const struct tcphdr *tcph, int payload_len) ++static inline unsigned int portscan_mt_full(int mark, ++    enum ip_conntrack_info ctstate, bool loopback, const struct tcphdr *tcph, ++    unsigned int payload_len)  +{ -+	if(mark == mark_estab2) { ++	if (mark == mark_estab2) {  +		/*  +		 * -m connmark --mark $ESTAB2  +		 */ -+		if(tflg_ack4(tcph) && payload_len == 0) ++		if (tflg_ack4(tcph) && payload_len == 0)  +			return mark; /* keep mark */ -+		else if(tflg_rst(tcph) || tflg_fin(tcph)) ++		else if (tflg_rst(tcph) || tflg_fin(tcph))  +			return mark_grscan;  +		else  +			return mark_valid; -+	} else if(mark == mark_estab1) { ++	} else if (mark == mark_estab1) {  +		/*  +		 * -m connmark --mark $ESTAB1  +		 */ -+		if(tflg_rst(tcph) || tflg_fin(tcph)) ++		if (tflg_rst(tcph) || tflg_fin(tcph))  +			return mark_cnscan; -+		else if(!loopback && tflg_ack4(tcph) && payload_len == 0) ++		else if (!loopback && tflg_ack4(tcph) && payload_len == 0)  +			return mark_estab2;  +		else  +			return mark_valid; -+	} else if(mark == mark_synrcv) { ++	} else if (mark == mark_synrcv) {  +		/*  +		 * -m connmark --mark $SYN  +		 */ -+		if(loopback && tflg_synack(tcph)) ++		if (loopback && tflg_synack(tcph))  +			return mark; /* keep mark */ -+		else if(loopback && tflg_rstack(tcph)) ++		else if (loopback && tflg_rstack(tcph))  +			return mark_closed; -+		else if(tflg_ack6(tcph)) ++		else if (tflg_ack6(tcph))  +			return mark_estab1;  +		else  +			return mark_synscan; -+	} else if(ctstate == IP_CT_NEW && tflg_syn(tcph)) { ++	} else if (ctstate == IP_CT_NEW && tflg_syn(tcph)) {  +		/*  +		 * -p tcp --syn --ctstate NEW  +		 */ @@ -855,25 +762,25 @@ Index: linux-2.6.23/net/netfilter/xt_portscan.c  +	return mark;  +}  + -+static bool xt_portscan_match(const struct sk_buff *skb, ++static bool portscan_mt(const struct sk_buff *skb,  +    const struct net_device *in, const struct net_device *out,  +    const struct xt_match *match, const void *matchinfo, int offset,  +    unsigned int protoff, bool *hotdrop)  +{ -+	const struct xt_portscan_info *info = matchinfo; ++	const struct xt_portscan_match_info *info = matchinfo;  +	enum ip_conntrack_info ctstate; -+	struct nf_conn *ctdata;  +	const struct tcphdr *tcph; ++	struct nf_conn *ctdata;  +	struct tcphdr tcph_buf;  +  +	tcph = skb_header_pointer(skb, protoff, sizeof(tcph_buf), &tcph_buf); -+	if(tcph == NULL) ++	if (tcph == NULL)  +		return false;  +  +	/* Check for invalid packets: -m conntrack --ctstate INVALID */ -+	if((ctdata = nf_ct_get(skb, &ctstate)) == NULL) { -+		if(info->match_stealth) -+			return xt_portscan_stealth(tcph); ++	if ((ctdata = nf_ct_get(skb, &ctstate)) == NULL) { ++		if (info->match_stealth) ++			return portscan_mt_stealth(tcph);  +		/*  +		 * If @ctdata is NULL, we cannot match the other scan  +		 * types, return. @@ -886,17 +793,17 @@ Index: linux-2.6.23/net/netfilter/xt_portscan.c  +	 * simulate must not be run through again. And for speedup, do not call  +	 * it either when the connection is already VALID.  +	 */ -+	if((ctdata->mark & connmark_mask) == mark_valid || -+	  (skb->nfmark & packet_mask) != mark_seen) -+	{ ++	if ((ctdata->mark & connmark_mask) == mark_valid || ++	     (skb->mark & packet_mask) != mark_seen) {  +		unsigned int n; -+		n = xt_portscan_full(ctdata->mark & connmark_mask, ctstate, ++ ++		n = portscan_mt_full(ctdata->mark & connmark_mask, ctstate,  +		    in == &loopback_dev, tcph,  +		    skb->len - protoff - 4 * tcph->doff);  +  +		ctdata->mark = (ctdata->mark & ~connmark_mask) | n; -+		((struct sk_buff *)skb)->nfmark = -+			(skb->nfmark & ~packet_mask) | mark_seen; ++		((struct sk_buff *)skb)->mark = ++			(skb->mark & ~packet_mask) ^ mark_seen;  +	}  +  +	return (info->match_syn && ctdata->mark == mark_synscan) || @@ -904,62 +811,51 @@ Index: linux-2.6.23/net/netfilter/xt_portscan.c  +	       (info->match_gr && ctdata->mark == mark_grscan);  +}  + -+static bool xt_portscan_checkentry(const char *tablename, const void *entry, -+    const struct xt_match *match, void *matchinfo, -+#ifdef HAVE_MATCHINFOSIZE -+    unsigned int matchinfosize, -+#endif -+    unsigned int hook_mask) ++static bool portscan_mt_check(const char *tablename, const void *entry, ++    const struct xt_match *match, void *matchinfo, unsigned int hook_mask)  +{ -+	const struct xt_portscan_info *info = matchinfo; -+#ifdef HAVE_MATCHINFOSIZE -+	if(matchinfosize != XT_ALIGN(sizeof(struct xt_portscan_info))) { -+		printk(KERN_WARNING PFX "matchinfosize %u != %Zu\n", -+		       matchinfosize, -+		       XT_ALIGN(sizeof(struct xt_portscan_info))); -+		return false; -+	} -+#endif -+	if((info->match_stealth & ~1) || (info->match_syn & ~1) || -+	  (info->match_cn & ~1) || (info->match_gr & ~1)) { ++	const struct xt_portscan_match_info *info = matchinfo; ++ ++	if ((info->match_stealth & ~1) || (info->match_syn & ~1) || ++	    (info->match_cn & ~1) || (info->match_gr & ~1)) {  +		printk(KERN_WARNING PFX "Invalid flags\n");  +		return false;  +	}  +	return true;  +}  + -+static struct xt_match xt_portscan = { ++static struct xt_match portscan_mt_reg __read_mostly = {  +	.name       = "portscan", -+	.match      = xt_portscan_match, -+	.checkentry = xt_portscan_checkentry, -+	.matchsize  = sizeof(struct xt_portscan_info), -+	.proto      = IPPROTO_TCP,  +	.family     = AF_INET, ++	.match      = portscan_mt, ++	.checkentry = portscan_mt_check, ++	.matchsize  = sizeof(struct xt_portscan_match_info), ++	.proto      = IPPROTO_TCP,  +	.me         = THIS_MODULE,  +};  + -+static int __init xt_portscan_init(void) ++static int __init portscan_mt_init(void)  +{ -+	return xt_register_match(&xt_portscan); ++	return xt_register_match(&portscan_mt_reg);  +}  + -+static void __exit xt_portscan_exit(void) ++static void __exit portscan_mt_exit(void)  +{ -+	xt_unregister_match(&xt_portscan); ++	xt_unregister_match(&portscan_mt_reg);  +	return;  +}  + -+module_init(xt_portscan_init); -+module_exit(xt_portscan_exit); -+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>"); -+MODULE_DESCRIPTION("netfilter portscan match module"); ++module_init(portscan_mt_init); ++module_exit(portscan_mt_exit); ++MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); ++MODULE_DESCRIPTION("netfilter \"portscan\" match");  +MODULE_LICENSE("GPL");  +MODULE_ALIAS("ipt_portscan"); -Index: linux-2.6.23/drivers/char/random.c +Index: linux-2.6.23.16/drivers/char/random.c  =================================================================== ---- linux-2.6.23.orig/drivers/char/random.c	2007-10-10 04:31:38.000000000 +0800 -+++ linux-2.6.23/drivers/char/random.c	2007-10-10 13:52:59.000000000 +0800 -@@ -1564,6 +1564,8 @@ +--- linux-2.6.23.16.orig/drivers/char/random.c ++++ linux-2.6.23.16/drivers/char/random.c +@@ -1564,6 +1564,8 @@ __u32 secure_tcp_sequence_number(__be32    	return seq;   } diff --git a/target/linux/generic-2.6/patches-2.6.23/171-netfilter_tarpit.patch b/target/linux/generic-2.6/patches-2.6.23/171-netfilter_tarpit.patch index 058dda5c2..073951a15 100644 --- a/target/linux/generic-2.6/patches-2.6.23/171-netfilter_tarpit.patch +++ b/target/linux/generic-2.6/patches-2.6.23/171-netfilter_tarpit.patch @@ -1,7 +1,7 @@ -Index: linux-2.6.23/net/netfilter/Kconfig +Index: linux-2.6.23.16/net/netfilter/Kconfig  =================================================================== ---- linux-2.6.23.orig/net/netfilter/Kconfig -+++ linux-2.6.23/net/netfilter/Kconfig +--- linux-2.6.23.16.orig/net/netfilter/Kconfig ++++ linux-2.6.23.16/net/netfilter/Kconfig  @@ -401,6 +401,23 @@ config NETFILTER_XT_TARGET_CONNSECMARK   	  To compile it as a module, choose M here.  If unsure, say N. @@ -26,22 +26,22 @@ Index: linux-2.6.23/net/netfilter/Kconfig   config NETFILTER_XT_TARGET_TCPMSS   	tristate '"TCPMSS" target support'   	depends on NETFILTER_XTABLES && (IPV6 || IPV6=n) -Index: linux-2.6.23/net/netfilter/Makefile +Index: linux-2.6.23.16/net/netfilter/Makefile  =================================================================== ---- linux-2.6.23.orig/net/netfilter/Makefile -+++ linux-2.6.23/net/netfilter/Makefile -@@ -49,6 +49,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG)  +--- linux-2.6.23.16.orig/net/netfilter/Makefile ++++ linux-2.6.23.16/net/netfilter/Makefile +@@ -47,6 +47,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG)    obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o   obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o   obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o  +obj-$(CONFIG_NETFILTER_XT_TARGET_TARPIT) += xt_TARPIT.o   obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o   obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o -  -Index: linux-2.6.23/net/netfilter/xt_TARPIT.c + obj-$(CONFIG_NETFILTER_XT_TARGET_CHAOS) += xt_CHAOS.o +Index: linux-2.6.23.16/net/netfilter/xt_TARPIT.c  ===================================================================  --- /dev/null -+++ linux-2.6.23/net/netfilter/xt_TARPIT.c ++++ linux-2.6.23.16/net/netfilter/xt_TARPIT.c  @@ -0,0 +1,280 @@  +/*  + * Kernel module to capture and hold incoming TCP connections using diff --git a/target/linux/generic-2.6/patches-2.6.24/101-netfilter_layer7_pktmatch.patch b/target/linux/generic-2.6/patches-2.6.24/101-netfilter_layer7_pktmatch.patch new file mode 100644 index 000000000..9605e4fa6 --- /dev/null +++ b/target/linux/generic-2.6/patches-2.6.24/101-netfilter_layer7_pktmatch.patch @@ -0,0 +1,113 @@ +Index: linux-2.6.24/include/linux/netfilter/xt_layer7.h +=================================================================== +--- linux-2.6.24.orig/include/linux/netfilter/xt_layer7.h ++++ linux-2.6.24/include/linux/netfilter/xt_layer7.h +@@ -8,6 +8,7 @@ struct xt_layer7_info { +     char protocol[MAX_PROTOCOL_LEN]; +     char pattern[MAX_PATTERN_LEN]; +     u_int8_t invert; ++    u_int8_t pkt; + }; +  + #endif /* _XT_LAYER7_H */ +Index: linux-2.6.24/net/netfilter/xt_layer7.c +=================================================================== +--- linux-2.6.24.orig/net/netfilter/xt_layer7.c ++++ linux-2.6.24/net/netfilter/xt_layer7.c +@@ -297,34 +297,36 @@ static int match_no_append(struct nf_con + } +  + /* add the new app data to the conntrack.  Return number of bytes added. */ +-static int add_data(struct nf_conn * master_conntrack, +-                    char * app_data, int appdatalen) ++static int add_datastr(char *target, int offset, char *app_data, int len) + { + 	int length = 0, i; +-	int oldlength = master_conntrack->layer7.app_data_len; +- +-	/* This is a fix for a race condition by Deti Fliegl. However, I'm not  +-	   clear on whether the race condition exists or whether this really  +-	   fixes it.  I might just be being dense... Anyway, if it's not really  +-	   a fix, all it does is waste a very small amount of time. */ +-	if(!master_conntrack->layer7.app_data) return 0; ++	 ++	if (!target) return 0; +  + 	/* Strip nulls. Make everything lower case (our regex lib doesn't + 	do case insensitivity).  Add it to the end of the current data. */ +-	for(i = 0; i < maxdatalen-oldlength-1 && +-		   i < appdatalen; i++) { ++	for(i = 0; i < maxdatalen-offset-1 && i < len; i++) { + 		if(app_data[i] != '\0') { + 			/* the kernel version of tolower mungs 'upper ascii' */ +-			master_conntrack->layer7.app_data[length+oldlength] = ++			target[length+offset] = + 				isascii(app_data[i])?  + 					tolower(app_data[i]) : app_data[i]; + 			length++; + 		} + 	} ++	target[length+offset] = '\0'; ++	 ++	return length; ++} +  +-	master_conntrack->layer7.app_data[length+oldlength] = '\0'; +-	master_conntrack->layer7.app_data_len = length + oldlength; ++/* add the new app data to the conntrack.  Return number of bytes added. */ ++static int add_data(struct nf_conn * master_conntrack, ++                    char * app_data, int appdatalen) ++{ ++	int length; +  ++	length = add_datastr(master_conntrack->layer7.app_data, master_conntrack->layer7.app_data_len, app_data, appdatalen); ++	master_conntrack->layer7.app_data_len += length; + 	return length; + } +  +@@ -411,7 +413,7 @@ match(const struct sk_buff *skbin, + 	const struct xt_layer7_info * info = matchinfo; + 	enum ip_conntrack_info master_ctinfo, ctinfo; + 	struct nf_conn *master_conntrack, *conntrack; +-	unsigned char * app_data; ++	unsigned char *app_data, *tmp_data; + 	unsigned int pattern_result, appdatalen; + 	regexp * comppattern; +  +@@ -439,8 +441,8 @@ match(const struct sk_buff *skbin, + 		master_conntrack = master_ct(master_conntrack); +  + 	/* if we've classified it or seen too many packets */ +-	if(TOTAL_PACKETS > num_packets || +-	   master_conntrack->layer7.app_proto) { ++	if(!info->pkt && (TOTAL_PACKETS > num_packets || ++	   master_conntrack->layer7.app_proto)) { +  + 		pattern_result = match_no_append(conntrack, master_conntrack,  + 						 ctinfo, master_ctinfo, info); +@@ -473,6 +475,25 @@ match(const struct sk_buff *skbin, + 	/* the return value gets checked later, when we're ready to use it */ + 	comppattern = compile_and_cache(info->pattern, info->protocol); +  ++	if (info->pkt) { ++		tmp_data = kmalloc(maxdatalen, GFP_ATOMIC); ++		if(!tmp_data){ ++			if (net_ratelimit()) ++				printk(KERN_ERR "layer7: out of memory in match, bailing.\n"); ++			return info->invert; ++		} ++ ++		tmp_data[0] = '\0'; ++		add_datastr(tmp_data, 0, app_data, appdatalen); ++		pattern_result = ((comppattern && regexec(comppattern, tmp_data)) ? 1 : 0); ++ ++		kfree(tmp_data); ++		tmp_data = NULL; ++		spin_unlock_bh(&l7_lock); ++ ++		return (pattern_result ^ info->invert); ++	} ++ + 	/* On the first packet of a connection, allocate space for app data */ + 	if(TOTAL_PACKETS == 1 && !skb->cb[0] &&  + 	   !master_conntrack->layer7.app_data){ diff --git a/target/linux/generic-2.6/patches-2.6.24/170-netfilter_chaostables.patch b/target/linux/generic-2.6/patches-2.6.24/170-netfilter_chaostables_0.8.patch index b55aeb1eb..38b50004e 100644 --- a/target/linux/generic-2.6/patches-2.6.24/170-netfilter_chaostables.patch +++ b/target/linux/generic-2.6/patches-2.6.24/170-netfilter_chaostables_0.8.patch @@ -1,17 +1,17 @@ -Index: linux-2.6.23/include/linux/netfilter/oot_conntrack.h +Index: linux-2.6.24/include/linux/netfilter/oot_conntrack.h  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23/include/linux/netfilter/oot_conntrack.h	2007-10-10 13:52:59.000000000 +0800 +--- /dev/null ++++ linux-2.6.24/include/linux/netfilter/oot_conntrack.h  @@ -0,0 +1,5 @@  +#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)  +#	include <linux/netfilter_ipv4/ip_conntrack.h>  +#else /* linux-2.6.20+ */  +#	include <net/netfilter/nf_nat_rule.h>  +#endif -Index: linux-2.6.23/include/linux/netfilter/oot_trans.h +Index: linux-2.6.24/include/linux/netfilter/oot_trans.h  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23/include/linux/netfilter/oot_trans.h	2007-10-10 13:52:59.000000000 +0800 +--- /dev/null ++++ linux-2.6.24/include/linux/netfilter/oot_trans.h  @@ -0,0 +1,14 @@  +/* Out of tree workarounds */  +#include <linux/version.h> @@ -27,42 +27,42 @@ Index: linux-2.6.23/include/linux/netfilter/oot_trans.h  +#	define tcp_v4_check(tcph, tcph_sz, s, d, csp) \  +		tcp_v4_check((tcph_sz), (s), (d), (csp))  +#endif -Index: linux-2.6.23/include/linux/netfilter/xt_CHAOS.h +Index: linux-2.6.24/include/linux/netfilter/xt_CHAOS.h  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23/include/linux/netfilter/xt_CHAOS.h	2007-10-10 13:52:59.000000000 +0800 +--- /dev/null ++++ linux-2.6.24/include/linux/netfilter/xt_CHAOS.h  @@ -0,0 +1,14 @@ -+#ifndef _LINUX_XT_CHAOS_H -+#define _LINUX_XT_CHAOS_H 1 ++#ifndef _LINUX_NETFILTER_XT_CHAOS_H ++#define _LINUX_NETFILTER_XT_CHAOS_H 1  + -+enum xt_chaos_variant { ++enum xt_chaos_target_variant {  +	XTCHAOS_NORMAL,  +	XTCHAOS_TARPIT,  +	XTCHAOS_DELUDE,  +};  + -+struct xt_chaos_info { -+	enum xt_chaos_variant variant; ++struct xt_chaos_target_info { ++	uint8_t variant;  +};  + -+#endif /* _LINUX_XT_CHAOS_H */ -Index: linux-2.6.23/include/linux/netfilter/xt_portscan.h ++#endif /* _LINUX_NETFILTER_XT_CHAOS_H */ +Index: linux-2.6.24/include/linux/netfilter/xt_portscan.h  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23/include/linux/netfilter/xt_portscan.h	2007-10-10 13:52:59.000000000 +0800 +--- /dev/null ++++ linux-2.6.24/include/linux/netfilter/xt_portscan.h  @@ -0,0 +1,8 @@ -+#ifndef _LINUX_XT_PORTSCAN_H -+#define _LINUX_XT_PORTSCAN_H 1 ++#ifndef _LINUX_NETFILTER_XT_PORTSCAN_H ++#define _LINUX_NETFILTER_XT_PORTSCAN_H 1  + -+struct xt_portscan_info { -+	unsigned int match_stealth, match_syn, match_cn, match_gr; ++struct xt_portscan_match_info { ++	uint8_t match_stealth, match_syn, match_cn, match_gr;  +};  + -+#endif /* _LINUX_XT_PORTSCAN_H */ -Index: linux-2.6.23/net/netfilter/find_match.c ++#endif /* _LINUX_NETFILTER_XT_PORTSCAN_H */ +Index: linux-2.6.24/net/netfilter/find_match.c  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23/net/netfilter/find_match.c	2007-10-10 13:52:59.000000000 +0800 +--- /dev/null ++++ linux-2.6.24/net/netfilter/find_match.c  @@ -0,0 +1,39 @@  +/*  +    xt_request_find_match @@ -95,7 +95,7 @@ Index: linux-2.6.23/net/netfilter/find_match.c  +  +	match = try_then_request_module(xt_find_match(af, name, revision),  +		"%st_%s", xt_prefix[af], name); -+	if(IS_ERR(match) || match == NULL) ++	if (IS_ERR(match) || match == NULL)  +		return NULL;  +  +	return match; @@ -103,11 +103,11 @@ Index: linux-2.6.23/net/netfilter/find_match.c  +  +/* In case it goes into mainline, let this out-of-tree package compile */  +#define xt_request_find_match xt_request_find_match_lo -Index: linux-2.6.23/net/netfilter/Kconfig +Index: linux-2.6.24/net/netfilter/Kconfig  =================================================================== ---- linux-2.6.23.orig/net/netfilter/Kconfig	2007-10-10 04:31:38.000000000 +0800 -+++ linux-2.6.23/net/netfilter/Kconfig	2007-10-10 13:53:04.000000000 +0800 -@@ -265,6 +265,14 @@ +--- linux-2.6.24.orig/net/netfilter/Kconfig ++++ linux-2.6.24/net/netfilter/Kconfig +@@ -265,6 +265,14 @@ config NETFILTER_XTABLES   # alphabetically ordered list of targets @@ -122,7 +122,7 @@ Index: linux-2.6.23/net/netfilter/Kconfig   config NETFILTER_XT_TARGET_CLASSIFY   	tristate '"CLASSIFY" target support'   	depends on NETFILTER_XTABLES -@@ -292,6 +300,14 @@ +@@ -292,6 +300,14 @@ config NETFILTER_XT_TARGET_CONNMARK   	  <file:Documentation/kbuild/modules.txt>.  The module will be called   	  ipt_CONNMARK.ko.  If unsure, say `N'. @@ -137,7 +137,7 @@ Index: linux-2.6.23/net/netfilter/Kconfig   config NETFILTER_XT_TARGET_DSCP   	tristate '"DSCP" target support'   	depends on NETFILTER_XTABLES -@@ -556,6 +572,14 @@ +@@ -556,6 +572,14 @@ config NETFILTER_XT_MATCH_POLICY   	  To compile it as a module, choose M here.  If unsure, say N. @@ -152,11 +152,11 @@ Index: linux-2.6.23/net/netfilter/Kconfig   config NETFILTER_XT_MATCH_MULTIPORT   	tristate "Multiple port match support"   	depends on NETFILTER_XTABLES -Index: linux-2.6.23/net/netfilter/Makefile +Index: linux-2.6.24/net/netfilter/Makefile  =================================================================== ---- linux-2.6.23.orig/net/netfilter/Makefile	2007-10-10 04:31:38.000000000 +0800 -+++ linux-2.6.23/net/netfilter/Makefile	2007-10-10 13:52:59.000000000 +0800 -@@ -49,6 +49,8 @@ +--- linux-2.6.24.orig/net/netfilter/Makefile ++++ linux-2.6.24/net/netfilter/Makefile +@@ -49,6 +49,8 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK   obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o   obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o   obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o @@ -165,24 +165,25 @@ Index: linux-2.6.23/net/netfilter/Makefile   # matches   obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o -@@ -79,3 +81,4 @@ +@@ -79,3 +81,4 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_STRING)    obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o   obj-$(CONFIG_NETFILTER_XT_MATCH_TIME) += xt_time.o   obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o  +obj-$(CONFIG_NETFILTER_XT_MATCH_PORTSCAN) += xt_portscan.o -Index: linux-2.6.23/net/netfilter/xt_CHAOS.c +Index: linux-2.6.24/net/netfilter/xt_CHAOS.c  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23/net/netfilter/xt_CHAOS.c	2007-10-10 13:52:59.000000000 +0800 -@@ -0,0 +1,205 @@ +--- /dev/null ++++ linux-2.6.24/net/netfilter/xt_CHAOS.c +@@ -0,0 +1,200 @@  +/* -+	CHAOS target for netfilter -+ -+	Copyright © Jan Engelhardt <jengelh [at] gmx de>, 2006 - 2007 -+	This program is free software; you can redistribute it and/or modify -+	it under the terms of the GNU General Public License version 2 as -+	published by the Free Software Foundation. -+*/ ++ *	CHAOS target for netfilter ++ *	Copyright © CC Computer Consultants GmbH, 2006 - 2007 ++ *	Contact: Jan Engelhardt <jengelh@computergmbh.de> ++ * ++ *	This program is free software; you can redistribute it and/or modify ++ *	it under the terms of the GNU General Public License; either version ++ *	2 or 3 as published by the Free Software Foundation. ++ */  +#include <linux/icmp.h>  +#include <linux/in.h>  +#include <linux/ip.h> @@ -193,9 +194,17 @@ Index: linux-2.6.23/net/netfilter/xt_CHAOS.c  +#include <linux/netfilter/xt_tcpudp.h>  +#include <linux/netfilter_ipv4/ipt_REJECT.h>  +#include <net/ip.h> -+#include <linux/netfilter/xt_CHAOS.h> -+#include "find_match.c" -+#include <linux/netfilter/oot_trans.h> ++#if defined(_LOCAL) ++#	include "xt_CHAOS.h" ++#	include "find_match.c" ++#elif defined(CONFIG_NETFILTER_XT_TARGET_CHAOS) || \ ++    defined(CONFIG_NETFILTER_XT_TARGET_CHAOS_MODULE) ++#	include <linux/netfilter/xt_CHAOS.h> ++#	include "find_match.c" ++#else ++#	include "xt_CHAOS.h" ++#	include "find_match.c" ++#endif  +#define PFX KBUILD_MODNAME ": "  +  +/* Module parameters */ @@ -221,111 +230,97 @@ Index: linux-2.6.23/net/netfilter/xt_CHAOS.c  +};  +  +/* CHAOS functions */ -+static void xt_chaos_total(const struct xt_chaos_info *info, ++static void xt_chaos_total(const struct xt_chaos_target_info *info,  +    struct sk_buff *skb, const struct net_device *in,  +    const struct net_device *out, unsigned int hooknum)  +{ -+	const int protoff = ip_hdrlen(skb); -+	const int offset  = ntohs(ip_hdr(skb)->frag_off) & IP_OFFSET; ++	const struct iphdr *iph = ip_hdr(skb); ++	const int protoff       = 4 * iph->ihl; ++	const int offset        = ntohs(iph->frag_off) & IP_OFFSET;  +	const struct xt_target *destiny; -+	bool hotdrop = false; -+	int ret; ++	bool hotdrop = false, ret;  +  +	ret = xm_tcp->match(skb, in, out, xm_tcp, &tcp_params,  +	                    offset, protoff, &hotdrop); -+	if(!ret || hotdrop || (unsigned int)net_random() > delude_percentage) ++	if (!ret || hotdrop || (unsigned int)net_random() > delude_percentage)  +		return;  +  +	destiny = (info->variant == XTCHAOS_TARPIT) ? xt_tarpit : xt_delude; -+#ifdef HAVE_TARGUSERINFO -+	destiny->target(skb, in, out, hooknum, destiny, NULL, NULL); -+#else  +	destiny->target(skb, in, out, hooknum, destiny, NULL); -+#endif  +	return;  +}  + -+static unsigned int xt_chaos_target(struct sk_buff *skb, ++static unsigned int chaos_tg(struct sk_buff *skb,  +    const struct net_device *in, const struct net_device *out, -+    unsigned int hooknum, const struct xt_target *target, const void *targinfo -+#ifdef HAVE_TARGUSERINFO -+    , -+    void *userinfo -+#endif -+    ) ++    unsigned int hooknum, const struct xt_target *target, const void *targinfo)  +{ -+	/* Equivalent to: ++	/* ++	 * Equivalent to:  +	 * -A chaos -m statistic --mode random --probability \  +	 *         $reject_percentage -j REJECT --reject-with host-unreach;  +	 * -A chaos -p tcp -m statistic --mode random --probability \  +	 *         $delude_percentage -j DELUDE;  +	 * -A chaos -j DROP;  +	 */ -+	const struct xt_chaos_info *info = targinfo; ++	const struct xt_chaos_target_info *info = targinfo; ++	const struct iphdr *iph = ip_hdr(skb);  + -+	if((unsigned int)net_random() <= reject_percentage) -+#ifdef HAVE_TARGUSERINFO -+		return xt_reject->target(skb, in, out, hooknum, target, -+		       &reject_params, userinfo); -+#else ++	if ((unsigned int)net_random() <= reject_percentage)  +		return xt_reject->target(skb, in, out, hooknum, target,  +		       &reject_params); -+#endif  +  +	/* TARPIT/DELUDE may not be called from the OUTPUT chain */ -+	if(ip_hdr(skb)->protocol == IPPROTO_TCP && -+	  info->variant != XTCHAOS_NORMAL && hooknum != NF_IP_LOCAL_OUT) ++	if (iph->protocol == IPPROTO_TCP && ++	    info->variant != XTCHAOS_NORMAL && hooknum != NF_IP_LOCAL_OUT)  +		xt_chaos_total(info, skb, in, out, hooknum);  +  +	return NF_DROP;  +}  + -+static bool xt_chaos_checkentry(const char *tablename, const void *entry, -+    const struct xt_target *target, void *targinfo, -+#ifdef HAVE_TARGINFOSIZE -+    unsigned int targinfosize, -+#endif -+    unsigned int hook_mask) ++static bool chaos_tg_check(const char *tablename, const void *entry, ++    const struct xt_target *target, void *targinfo, unsigned int hook_mask)  +{ -+	const struct xt_chaos_info *info = targinfo; -+	if(info->variant == XTCHAOS_DELUDE && !have_delude) { ++	const struct xt_chaos_target_info *info = targinfo; ++ ++	if (info->variant == XTCHAOS_DELUDE && !have_delude) {  +		printk(KERN_WARNING PFX "Error: Cannot use --delude when "  +		       "DELUDE module not available\n");  +		return false;  +	} -+	if(info->variant == XTCHAOS_TARPIT && !have_tarpit) { ++	if (info->variant == XTCHAOS_TARPIT && !have_tarpit) {  +		printk(KERN_WARNING PFX "Error: Cannot use --tarpit when "  +		       "TARPIT module not available\n");  +		return false;  +	} ++  +	return true;  +}  + -+static struct xt_target xt_chaos_info = { ++static struct xt_target chaos_tg_reg = {  +	.name       = "CHAOS", -+	.target     = xt_chaos_target, -+	.checkentry = xt_chaos_checkentry, ++	.family     = AF_INET,  +	.table      = "filter", -+	.targetsize = sizeof(struct xt_chaos_info),  +	.hooks      = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) |  +	              (1 << NF_IP_LOCAL_OUT), -+	.family     = AF_INET, ++	.checkentry = chaos_tg_check, ++	.target     = chaos_tg, ++	.targetsize = sizeof(struct xt_chaos_target_info),  +	.me         = THIS_MODULE,  +};  + -+static int __init xt_chaos_init(void) ++static int __init chaos_tg_init(void)  +{  +	int ret = -EINVAL;  +  +	xm_tcp = xt_request_find_match(AF_INET, "tcp", 0); -+	if(xm_tcp == NULL) { ++	if (xm_tcp == NULL) {  +		printk(KERN_WARNING PFX "Error: Could not find or load "  +		       "\"tcp\" match\n");  +		return -EINVAL;  +	}  +  +	xt_reject = xt_request_find_target(AF_INET, "REJECT", 0); -+	if(xt_reject == NULL) { ++	if (xt_reject == NULL) {  +		printk(KERN_WARNING PFX "Error: Could not find or load "  +		       "\"REJECT\" target\n");  +		goto out2; @@ -333,17 +328,17 @@ Index: linux-2.6.23/net/netfilter/xt_CHAOS.c  +  +	xt_tarpit   = xt_request_find_target(AF_INET, "TARPIT", 0);  +	have_tarpit = xt_tarpit != NULL; -+	if(!have_tarpit) ++	if (!have_tarpit)  +		printk(KERN_WARNING PFX "Warning: Could not find or load "  +		       "\"TARPIT\" target\n");  +  +	xt_delude   = xt_request_find_target(AF_INET, "DELUDE", 0);  +	have_delude = xt_delude != NULL; -+	if(!have_delude) ++	if (!have_delude)  +		printk(KERN_WARNING PFX "Warning: Could not find or load "  +		       "\"DELUDE\" target\n");  + -+	if((ret = xt_register_target(&xt_chaos_info)) != 0) { ++	if ((ret = xt_register_target(&chaos_tg_reg)) != 0) {  +		printk(KERN_WARNING PFX "xt_register_target returned "  +		       "error %d\n", ret);  +		goto out3; @@ -352,9 +347,9 @@ Index: linux-2.6.23/net/netfilter/xt_CHAOS.c  +	return 0;  +  + out3: -+ 	if(have_delude) ++ 	if (have_delude)  + 		module_put(xt_delude->me); -+	if(have_tarpit) ++	if (have_tarpit)  +		module_put(xt_tarpit->me);  +	module_put(xt_reject->me);  + out2: @@ -362,132 +357,67 @@ Index: linux-2.6.23/net/netfilter/xt_CHAOS.c  +	return ret;  +}  + -+static void __exit xt_chaos_exit(void) ++static void __exit chaos_tg_exit(void)  +{ -+	xt_unregister_target(&xt_chaos_info); ++	xt_unregister_target(&chaos_tg_reg);  +	module_put(xm_tcp->me);  +	module_put(xt_reject->me); -+	if(have_delude) ++	if (have_delude)  +		module_put(xt_delude->me); -+	if(have_tarpit) ++	if (have_tarpit)  +		module_put(xt_tarpit->me);  +	return;  +}  + -+module_init(xt_chaos_init); -+module_exit(xt_chaos_exit); -+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>"); -+MODULE_DESCRIPTION("netfilter CHAOS target"); ++module_init(chaos_tg_init); ++module_exit(chaos_tg_exit); ++MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); ++MODULE_DESCRIPTION("netfilter \"CHAOS\" target");  +MODULE_LICENSE("GPL");  +MODULE_ALIAS("ipt_CHAOS"); -Index: linux-2.6.23/net/netfilter/xt_DELUDE.c +Index: linux-2.6.24/net/netfilter/xt_DELUDE.c  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23/net/netfilter/xt_DELUDE.c	2007-10-10 13:52:59.000000000 +0800 -@@ -0,0 +1,288 @@ +--- /dev/null ++++ linux-2.6.24/net/netfilter/xt_DELUDE.c +@@ -0,0 +1,197 @@  +/* -+	DELUDE target -+	Copyright © Jan Engelhardt <jengelh [at] gmx de>, 2007 -+ -+	Based upon linux-2.6.18.5/net/ipv4/netfilter/ipt_REJECT.c: -+	(C) 1999-2001 Paul `Rusty' Russell -+	(C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> -+ -+	xt_DELUDE acts like REJECT, but does reply with SYN-ACK on SYN. -+ -+	This program is free software; you can redistribute it and/or modify -+	it under the terms of the GNU General Public License version 2 as -+	published by the Free Software Foundation. -+*/ ++ *	DELUDE target ++ *	Copyright © CC Computer Consultants GmbH, 2007 ++ *	Contact: Jan Engelhardt <jengelh@computergmbh.de> ++ * ++ *	Based upon linux-2.6.18.5/net/ipv4/netfilter/ipt_REJECT.c: ++ *	(C) 1999-2001 Paul `Rusty' Russell ++ *	(C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> ++ * ++ *	xt_DELUDE acts like REJECT, but does reply with SYN-ACK on SYN. ++ * ++ *	This program is free software; you can redistribute it and/or modify ++ *	it under the terms of the GNU General Public License version 2 as ++ *	published by the Free Software Foundation. ++ */  +#include <linux/module.h>  +#include <linux/skbuff.h>  +#include <linux/ip.h> -+#include <linux/random.h>  +#include <linux/tcp.h> -+#include <linux/udp.h> -+#include <linux/icmp.h> -+#include <net/icmp.h> -+#include <net/ip.h> -+#include <net/tcp.h> -+#include <net/route.h> -+#include <net/dst.h> -+#include <linux/netfilter_ipv4/ip_tables.h> ++#include <linux/netfilter/x_tables.h>  +#ifdef CONFIG_BRIDGE_NETFILTER  +#	include <linux/netfilter_bridge.h>  +#endif -+#include <linux/netfilter/oot_trans.h> ++#include <net/tcp.h>  +#define PFX KBUILD_MODNAME ": "  + -+static inline struct rtable *route_reverse(struct sk_buff *skb, -+					   struct tcphdr *tcph, int hook) ++static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)  +{ -+	struct iphdr *iph = ip_hdr(skb); -+	struct dst_entry *odst; -+	struct flowi fl = {}; -+	struct rtable *rt; -+ -+	/* We don't require ip forwarding to be enabled to be able to -+	 * send a RST reply for bridged traffic. */ -+	if (hook != NF_IP_FORWARD -+#ifdef CONFIG_BRIDGE_NETFILTER -+	    || (skb->nf_bridge && skb->nf_bridge->mask & BRNF_BRIDGED) -+#endif -+	   ) { -+		fl.nl_u.ip4_u.daddr = iph->saddr; -+		if (hook == NF_IP_LOCAL_IN) -+			fl.nl_u.ip4_u.saddr = iph->daddr; -+		fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); -+ -+		if (ip_route_output_key(&rt, &fl) != 0) -+			return NULL; -+	} else { -+		/* non-local src, find valid iif to satisfy -+		 * rp-filter when calling ip_route_input. */ -+		fl.nl_u.ip4_u.daddr = iph->daddr; -+		if (ip_route_output_key(&rt, &fl) != 0) -+			return NULL; -+ -+		odst = skb->dst; -+		if (ip_route_input(skb, iph->saddr, iph->daddr, -+		                   RT_TOS(iph->tos), rt->u.dst.dev) != 0) { -+			dst_release(&rt->u.dst); -+			return NULL; -+		} -+		dst_release(&rt->u.dst); -+		rt = (struct rtable *)skb->dst; -+		skb->dst = odst; -+ -+		fl.nl_u.ip4_u.daddr = iph->saddr; -+		fl.nl_u.ip4_u.saddr = iph->daddr; -+		fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); -+	} -+ -+	if (rt->u.dst.error) { -+		dst_release(&rt->u.dst); -+		return NULL; -+	} -+ -+	fl.proto = IPPROTO_TCP; -+	fl.fl_ip_sport = tcph->dest; -+	fl.fl_ip_dport = tcph->source; -+ -+	xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0); -+ -+	return rt; -+} -+ -+static void send_reset(struct sk_buff *oldskb, int hook) -+{ -+	struct sk_buff *nskb; -+	struct iphdr *iph = ip_hdr(oldskb);  +	struct tcphdr _otcph, *oth, *tcph; -+	__be16 tmp_port; -+	__be32 tmp_addr; -+	int needs_ack;  +	unsigned int addr_type; ++	struct sk_buff *nskb; ++	u_int16_t tmp_port; ++	u_int32_t tmp_addr; ++	struct iphdr *niph; ++	bool needs_ack;  +  +	/* IP header checks: fragment. */ -+	if (iph->frag_off & htons(IP_OFFSET)) ++	if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET))  +		return;  +  +	oth = skb_header_pointer(oldskb, ip_hdrlen(oldskb), @@ -513,78 +443,75 @@ Index: linux-2.6.23/net/netfilter/xt_DELUDE.c  +  +	/* This packet will not be the same as the other: clear nf fields */  +	nf_reset(nskb); -+	nskb->nfmark = 0; ++	nskb->mark = 0;  +	skb_init_secmark(nskb);  +  +	skb_shinfo(nskb)->gso_size = 0;  +	skb_shinfo(nskb)->gso_segs = 0;  +	skb_shinfo(nskb)->gso_type = 0;  + -+	tcph = tcp_hdr(nskb); ++	tcph = (struct tcphdr *)(skb_network_header(nskb) + ip_hdrlen(nskb));  +  +	/* Swap source and dest */ -+	tmp_addr = ip_hdr(nskb)->saddr; -+	ip_hdr(nskb)->saddr = ip_hdr(nskb)->daddr; -+	ip_hdr(nskb)->daddr = tmp_addr; -+	tmp_port = tcph->source; ++	niph         = ip_hdr(nskb); ++	tmp_addr     = niph->saddr; ++	niph->saddr  = niph->daddr; ++	niph->daddr  = tmp_addr; ++	tmp_port     = tcph->source;  +	tcph->source = tcph->dest; -+	tcph->dest = tmp_port; ++	tcph->dest   = tmp_port;  +  +	/* Truncate to length (no data) */ -+	tcph->doff = sizeof(struct tcphdr)/4; ++	tcph->doff    = sizeof(struct tcphdr) / 4;  +	skb_trim(nskb, ip_hdrlen(nskb) + sizeof(struct tcphdr)); -+	ip_hdr(nskb)->tot_len = htons(nskb->len); ++	niph->tot_len = htons(nskb->len);  + -+	if(oth->syn && !oth->ack && !oth->rst && !oth->fin) { ++	if (oth->syn && !oth->ack && !oth->rst && !oth->fin) {  +		/* DELUDE essential part */  +		tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin +  +		                oldskb->len - ip_hdrlen(oldskb) -  +		                (oth->doff << 2)); -+		tcph->seq     = htonl(secure_tcp_sequence_number( -+		                ip_hdr(nskb)->saddr, ip_hdr(nskb)->daddr, -+			        tcph->source, tcph->dest)); -+		tcph->ack     = 1; ++		tcph->seq     = false; ++		tcph->ack     = true;  +	} else { -+		if(!tcph->ack) { -+			needs_ack = 1; -+			tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin -+					      + oldskb->len - ip_hdrlen(oldskb) -+					      - (oth->doff<<2)); -+			tcph->seq = 0; ++		if (!tcph->ack) { ++			needs_ack     = true; ++			tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + ++			                oth->fin + oldskb->len - ++			                ip_hdrlen(oldskb) - (oth->doff<<2)); ++			tcph->seq     = false;  +		} else { -+			needs_ack = 0; -+			tcph->seq = oth->ack_seq; -+			tcph->ack_seq = 0; ++			needs_ack     = false; ++			tcph->seq     = oth->ack_seq; ++			tcph->ack_seq = false;  +		}  +  +		/* Reset flags */  +		((u_int8_t *)tcph)[13] = 0; -+		tcph->rst = 1; ++		tcph->rst = true;  +		tcph->ack = needs_ack;  +	}  + -+ -+	tcph->window = 0; ++	tcph->window  = 0;  +	tcph->urg_ptr = 0;  +  +	/* Adjust TCP checksum */  +	tcph->check = 0; -+	tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr), -+				   ip_hdr(nskb)->saddr, -+				   ip_hdr(nskb)->daddr, -+				   csum_partial((char *)tcph, -+						sizeof(struct tcphdr), 0)); ++	tcph->check = tcp_v4_check(sizeof(struct tcphdr), niph->saddr, ++	              niph->daddr, csum_partial((char *)tcph, ++	              sizeof(struct tcphdr), 0));  +  +	/* Set DF, id = 0 */ -+	ip_hdr(nskb)->frag_off = htons(IP_DF); -+	ip_hdr(nskb)->id = 0; ++	niph->frag_off = htons(IP_DF); ++	niph->id       = 0;  +  +	addr_type = RTN_UNSPEC; -+	if (hook != NF_IP_FORWARD  +#ifdef CONFIG_BRIDGE_NETFILTER -+	    || (nskb->nf_bridge && nskb->nf_bridge->mask & BRNF_BRIDGED) ++	if (hook != NF_IP_FORWARD || (nskb->nf_bridge != NULL && ++	    nskb->nf_bridge->mask & BRNF_BRIDGED)) ++#else ++	if (hook != NF_IP_FORWARD)  +#endif -+	   )  +		addr_type = RTN_LOCAL;  +  +	if (ip_route_me_harder(nskb, addr_type)) @@ -593,12 +520,11 @@ Index: linux-2.6.23/net/netfilter/xt_DELUDE.c  +	nskb->ip_summed = CHECKSUM_NONE;  +  +	/* Adjust IP TTL */ -+	ip_hdr(nskb)->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); ++	niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);  +  +	/* Adjust IP checksum */ -+	ip_hdr(nskb)->check = 0; -+	ip_hdr(nskb)->check = ip_fast_csum((unsigned char *)ip_hdr(nskb), -+					   ip_hdr(nskb)->ihl); ++	niph->check = 0; ++	niph->check = ip_fast_csum(skb_network_header(nskb), niph->ihl);  +  +	/* "Never happens" */  +	if (nskb->len > dst_mtu(nskb->dst)) @@ -614,78 +540,57 @@ Index: linux-2.6.23/net/netfilter/xt_DELUDE.c  +	kfree_skb(nskb);  +}  + -+static unsigned int xt_delude_target(struct sk_buff *skb, ++static unsigned int delude_tg(struct sk_buff *skb,  +    const struct net_device *in, const struct net_device *out, -+    unsigned int hooknum, const struct xt_target *target, const void *targinfo -+#ifdef HAVE_TARGUSERINFO -+    , -+    void *userinfo -+#endif -+    ) ++    unsigned int hooknum, const struct xt_target *target, const void *targinfo)  +{  +	/* WARNING: This code causes reentry within iptables.  +	   This means that the iptables jump stack is now crap.  We  +	   must return an absolute verdict. --RR */ -+	send_reset(skb, hooknum); ++	delude_send_reset(skb, hooknum);  +	return NF_DROP;  +}  + -+static bool xt_delude_check(const char *tablename, const void *e_void, -+    const struct xt_target *target, void *targinfo, -+#ifdef HAVE_TARGINFOSIZE -+    unsigned int targinfosize, -+#endif -+    unsigned int hook_mask) -+{ -+	if(hook_mask & ~((1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD))) { -+		printk(KERN_WARNING PFX "DELUDE may not be used in chains " -+		       "other than INPUT and FORWARD\n"); -+		return false; -+	} -+	return true; -+} -+ -+static struct xt_target xt_delude_info = { ++static struct xt_target delude_tg_reg = {  +	.name       = "DELUDE", -+	.target     = xt_delude_target, -+	.checkentry = xt_delude_check, ++	.family     = AF_INET,  +	.table      = "filter", -+	.hooks      = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | -+	              (1 << NF_IP_LOCAL_OUT), ++	.hooks      = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD), ++	.target     = delude_tg,  +	.proto      = IPPROTO_TCP, -+	.family     = AF_INET,  +	.me         = THIS_MODULE,  +};  + -+static int __init xt_delude_init(void) ++static int __init delude_tg_init(void)  +{ -+	return xt_register_target(&xt_delude_info); ++	return xt_register_target(&delude_tg_reg);  +}  + -+static void __exit xt_delude_exit(void) ++static void __exit delude_tg_exit(void)  +{ -+	xt_unregister_target(&xt_delude_info); ++	xt_unregister_target(&delude_tg_reg);  +}  + -+module_init(xt_delude_init); -+module_exit(xt_delude_exit); -+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>"); -+MODULE_DESCRIPTION("netfilter DELUDE target"); ++module_init(delude_tg_init); ++module_exit(delude_tg_exit); ++MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); ++MODULE_DESCRIPTION("netfilter \"DELUDE\" target");  +MODULE_LICENSE("GPL");  +MODULE_ALIAS("ipt_DELUDE"); -Index: linux-2.6.23/net/netfilter/xt_portscan.c +Index: linux-2.6.24/net/netfilter/xt_portscan.c  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23/net/netfilter/xt_portscan.c	2007-10-10 13:52:59.000000000 +0800 -@@ -0,0 +1,272 @@ +--- /dev/null ++++ linux-2.6.24/net/netfilter/xt_portscan.c +@@ -0,0 +1,269 @@  +/* -+	portscan match for netfilter -+ -+	Written by Jan Engelhardt, 2006 - 2007 -+	This program is free software; you can redistribute it and/or modify -+	it under the terms of the GNU General Public License version 2 as -+	published by the Free Software Foundation. -+*/ ++ *	portscan match for netfilter ++ *	Copyright © CC Computer Consultants GmbH, 2006 - 2007 ++ *	Contact: Jan Engelhardt <jengelh@computergmbh.de> ++ * ++ *	This program is free software; you can redistribute it and/or modify ++ *	it under the terms of the GNU General Public License; either version ++ *	2 or 3 as published by the Free Software Foundation. ++ */  +#include <linux/in.h>  +#include <linux/ip.h>  +#include <linux/module.h> @@ -697,9 +602,15 @@ Index: linux-2.6.23/net/netfilter/xt_portscan.c  +#include <linux/version.h>  +#include <linux/netfilter/x_tables.h>  +#include <linux/netfilter/xt_tcpudp.h> -+#include <linux/netfilter/oot_conntrack.h> -+#include <linux/netfilter/xt_portscan.h> -+#include <linux/netfilter/oot_trans.h> ++#include <net/netfilter/nf_nat_rule.h> ++#if defined(_LOCAL) ++#	include "xt_portscan.h" ++#elif defined(CONFIG_NETFILTER_XT_MATCH_PORTSCAN) || \ ++    defined(CONFIG_NETFILTER_XT_MATCH_PORTSCAN_MODULE) ++#	include <linux/netfilter/xt_portscan.h> ++#else ++#	include "xt_portscan.h" ++#endif  +#define PFX KBUILD_MODNAME ": "  +  +enum { @@ -746,55 +657,55 @@ Index: linux-2.6.23/net/netfilter/xt_portscan.c  +MODULE_PARM_DESC(mark_valid,    "connmark value for Valid state");  +  +/* TCP flag functions */ -+static inline int tflg_ack4(const struct tcphdr *th) ++static inline bool tflg_ack4(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_ACK;  +}  + -+static inline int tflg_ack6(const struct tcphdr *th) ++static inline bool tflg_ack6(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL6) == TCP_FLAG_ACK;  +}  + -+static inline int tflg_fin(const struct tcphdr *th) ++static inline bool tflg_fin(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_FIN;  +}  + -+static inline int tflg_rst(const struct tcphdr *th) ++static inline bool tflg_rst(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_RST;  +}  + -+static inline int tflg_rstack(const struct tcphdr *th) ++static inline bool tflg_rstack(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) ==  +	       (TCP_FLAG_ACK | TCP_FLAG_RST);  +}  + -+static inline int tflg_syn(const struct tcphdr *th) ++static inline bool tflg_syn(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_SYN;  +}  + -+static inline int tflg_synack(const struct tcphdr *th) ++static inline bool tflg_synack(const struct tcphdr *th)  +{  +	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) ==  +	       (TCP_FLAG_SYN | TCP_FLAG_ACK);  +}  +  +/* portscan functions */ -+static inline int xt_portscan_stealth(const struct tcphdr *th) ++static inline bool portscan_mt_stealth(const struct tcphdr *th)  +{  +	/*  +	 * "Connection refused" replies to our own probes must not be matched.  +	 */ -+	if(tflg_rstack(th)) -+		return 0; ++	if (tflg_rstack(th)) ++		return false;  + -+	if(tflg_rst(th) && printk_ratelimit()) { ++	if (tflg_rst(th) && printk_ratelimit()) {  +		printk(KERN_WARNING PFX "Warning: Pure RST received\n"); -+		return 0; ++		return false;  +	}  +  +	/* @@ -806,42 +717,43 @@ Index: linux-2.6.23/net/netfilter/xt_portscan.c  +	return !tflg_syn(th);  +}  + -+static inline int xt_portscan_full(int mark, enum ip_conntrack_info ctstate, -+    int loopback, const struct tcphdr *tcph, int payload_len) ++static inline unsigned int portscan_mt_full(int mark, ++    enum ip_conntrack_info ctstate, bool loopback, const struct tcphdr *tcph, ++    unsigned int payload_len)  +{ -+	if(mark == mark_estab2) { ++	if (mark == mark_estab2) {  +		/*  +		 * -m connmark --mark $ESTAB2  +		 */ -+		if(tflg_ack4(tcph) && payload_len == 0) ++		if (tflg_ack4(tcph) && payload_len == 0)  +			return mark; /* keep mark */ -+		else if(tflg_rst(tcph) || tflg_fin(tcph)) ++		else if (tflg_rst(tcph) || tflg_fin(tcph))  +			return mark_grscan;  +		else  +			return mark_valid; -+	} else if(mark == mark_estab1) { ++	} else if (mark == mark_estab1) {  +		/*  +		 * -m connmark --mark $ESTAB1  +		 */ -+		if(tflg_rst(tcph) || tflg_fin(tcph)) ++		if (tflg_rst(tcph) || tflg_fin(tcph))  +			return mark_cnscan; -+		else if(!loopback && tflg_ack4(tcph) && payload_len == 0) ++		else if (!loopback && tflg_ack4(tcph) && payload_len == 0)  +			return mark_estab2;  +		else  +			return mark_valid; -+	} else if(mark == mark_synrcv) { ++	} else if (mark == mark_synrcv) {  +		/*  +		 * -m connmark --mark $SYN  +		 */ -+		if(loopback && tflg_synack(tcph)) ++		if (loopback && tflg_synack(tcph))  +			return mark; /* keep mark */ -+		else if(loopback && tflg_rstack(tcph)) ++		else if (loopback && tflg_rstack(tcph))  +			return mark_closed; -+		else if(tflg_ack6(tcph)) ++		else if (tflg_ack6(tcph))  +			return mark_estab1;  +		else  +			return mark_synscan; -+	} else if(ctstate == IP_CT_NEW && tflg_syn(tcph)) { ++	} else if (ctstate == IP_CT_NEW && tflg_syn(tcph)) {  +		/*  +		 * -p tcp --syn --ctstate NEW  +		 */ @@ -850,25 +762,25 @@ Index: linux-2.6.23/net/netfilter/xt_portscan.c  +	return mark;  +}  + -+static bool xt_portscan_match(const struct sk_buff *skb, ++static bool portscan_mt(const struct sk_buff *skb,  +    const struct net_device *in, const struct net_device *out,  +    const struct xt_match *match, const void *matchinfo, int offset,  +    unsigned int protoff, bool *hotdrop)  +{ -+	const struct xt_portscan_info *info = matchinfo; ++	const struct xt_portscan_match_info *info = matchinfo;  +	enum ip_conntrack_info ctstate; -+	struct nf_conn *ctdata;  +	const struct tcphdr *tcph; ++	struct nf_conn *ctdata;  +	struct tcphdr tcph_buf;  +  +	tcph = skb_header_pointer(skb, protoff, sizeof(tcph_buf), &tcph_buf); -+	if(tcph == NULL) ++	if (tcph == NULL)  +		return false;  +  +	/* Check for invalid packets: -m conntrack --ctstate INVALID */ -+	if((ctdata = nf_ct_get(skb, &ctstate)) == NULL) { -+		if(info->match_stealth) -+			return xt_portscan_stealth(tcph); ++	if ((ctdata = nf_ct_get(skb, &ctstate)) == NULL) { ++		if (info->match_stealth) ++			return portscan_mt_stealth(tcph);  +		/*  +		 * If @ctdata is NULL, we cannot match the other scan  +		 * types, return. @@ -881,17 +793,17 @@ Index: linux-2.6.23/net/netfilter/xt_portscan.c  +	 * simulate must not be run through again. And for speedup, do not call  +	 * it either when the connection is already VALID.  +	 */ -+	if((ctdata->mark & connmark_mask) == mark_valid || -+	  (skb->nfmark & packet_mask) != mark_seen) -+	{ ++	if ((ctdata->mark & connmark_mask) == mark_valid || ++	     (skb->mark & packet_mask) != mark_seen) {  +		unsigned int n; -+		n = xt_portscan_full(ctdata->mark & connmark_mask, ctstate, -+		    (in->flags && IFF_LOOPBACK) == IFF_LOOPBACK, tcph, ++ ++		n = portscan_mt_full(ctdata->mark & connmark_mask, ctstate, ++		    (in->flags & IFF_LOOPBACK) == IFF_LOOPBACK, tcph,  +		    skb->len - protoff - 4 * tcph->doff);  +  +		ctdata->mark = (ctdata->mark & ~connmark_mask) | n; -+		((struct sk_buff *)skb)->nfmark = -+			(skb->nfmark & ~packet_mask) | mark_seen; ++		((struct sk_buff *)skb)->mark = ++			(skb->mark & ~packet_mask) ^ mark_seen;  +	}  +  +	return (info->match_syn && ctdata->mark == mark_synscan) || @@ -899,62 +811,51 @@ Index: linux-2.6.23/net/netfilter/xt_portscan.c  +	       (info->match_gr && ctdata->mark == mark_grscan);  +}  + -+static bool xt_portscan_checkentry(const char *tablename, const void *entry, -+    const struct xt_match *match, void *matchinfo, -+#ifdef HAVE_MATCHINFOSIZE -+    unsigned int matchinfosize, -+#endif -+    unsigned int hook_mask) ++static bool portscan_mt_check(const char *tablename, const void *entry, ++    const struct xt_match *match, void *matchinfo, unsigned int hook_mask)  +{ -+	const struct xt_portscan_info *info = matchinfo; -+#ifdef HAVE_MATCHINFOSIZE -+	if(matchinfosize != XT_ALIGN(sizeof(struct xt_portscan_info))) { -+		printk(KERN_WARNING PFX "matchinfosize %u != %Zu\n", -+		       matchinfosize, -+		       XT_ALIGN(sizeof(struct xt_portscan_info))); -+		return false; -+	} -+#endif -+	if((info->match_stealth & ~1) || (info->match_syn & ~1) || -+	  (info->match_cn & ~1) || (info->match_gr & ~1)) { ++	const struct xt_portscan_match_info *info = matchinfo; ++ ++	if ((info->match_stealth & ~1) || (info->match_syn & ~1) || ++	    (info->match_cn & ~1) || (info->match_gr & ~1)) {  +		printk(KERN_WARNING PFX "Invalid flags\n");  +		return false;  +	}  +	return true;  +}  + -+static struct xt_match xt_portscan = { ++static struct xt_match portscan_mt_reg __read_mostly = {  +	.name       = "portscan", -+	.match      = xt_portscan_match, -+	.checkentry = xt_portscan_checkentry, -+	.matchsize  = sizeof(struct xt_portscan_info), -+	.proto      = IPPROTO_TCP,  +	.family     = AF_INET, ++	.match      = portscan_mt, ++	.checkentry = portscan_mt_check, ++	.matchsize  = sizeof(struct xt_portscan_match_info), ++	.proto      = IPPROTO_TCP,  +	.me         = THIS_MODULE,  +};  + -+static int __init xt_portscan_init(void) ++static int __init portscan_mt_init(void)  +{ -+	return xt_register_match(&xt_portscan); ++	return xt_register_match(&portscan_mt_reg);  +}  + -+static void __exit xt_portscan_exit(void) ++static void __exit portscan_mt_exit(void)  +{ -+	xt_unregister_match(&xt_portscan); ++	xt_unregister_match(&portscan_mt_reg);  +	return;  +}  + -+module_init(xt_portscan_init); -+module_exit(xt_portscan_exit); -+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>"); -+MODULE_DESCRIPTION("netfilter portscan match module"); ++module_init(portscan_mt_init); ++module_exit(portscan_mt_exit); ++MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); ++MODULE_DESCRIPTION("netfilter \"portscan\" match");  +MODULE_LICENSE("GPL");  +MODULE_ALIAS("ipt_portscan"); -Index: linux-2.6.23/drivers/char/random.c +Index: linux-2.6.24/drivers/char/random.c  =================================================================== ---- linux-2.6.23.orig/drivers/char/random.c	2007-10-10 04:31:38.000000000 +0800 -+++ linux-2.6.23/drivers/char/random.c	2007-10-10 13:52:59.000000000 +0800 -@@ -1564,6 +1564,8 @@ +--- linux-2.6.24.orig/drivers/char/random.c ++++ linux-2.6.24/drivers/char/random.c +@@ -1564,6 +1564,8 @@ __u32 secure_tcp_sequence_number(__be32    	return seq;   } diff --git a/target/linux/generic-2.6/patches/100-netfilter_layer7_2.9.patch b/target/linux/generic-2.6/patches/100-netfilter_layer7_2.17.patch index 437f883e8..52908b307 100644 --- a/target/linux/generic-2.6/patches/100-netfilter_layer7_2.9.patch +++ b/target/linux/generic-2.6/patches/100-netfilter_layer7_2.17.patch @@ -1,80 +1,58 @@ -Index: linux-2.6.21.5/include/linux/netfilter_ipv4/ipt_layer7.h +Index: linux-2.6.21.7/net/netfilter/Kconfig  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.21.5/include/linux/netfilter_ipv4/ipt_layer7.h	2007-07-02 00:43:58.271086750 +0200 -@@ -0,0 +1,26 @@ -+/* -+  By Matthew Strait <quadong@users.sf.net>, Dec 2003. -+  http://l7-filter.sf.net -+ -+  This program is free software; you can redistribute it and/or -+  modify it under the terms of the GNU General Public License -+  as published by the Free Software Foundation; either version -+  2 of the License, or (at your option) any later version. -+  http://www.gnu.org/licenses/gpl.txt -+*/ -+ -+#ifndef _IPT_LAYER7_H -+#define _IPT_LAYER7_H -+ -+#define MAX_PATTERN_LEN 8192 -+#define MAX_PROTOCOL_LEN 256 +--- linux-2.6.21.7.orig/net/netfilter/Kconfig ++++ linux-2.6.21.7/net/netfilter/Kconfig +@@ -640,6 +640,27 @@ config NETFILTER_XT_MATCH_STATE +  + 	  To compile it as a module, choose M here.  If unsure, say N. +  ++config NETFILTER_XT_MATCH_LAYER7 ++	tristate '"layer7" match support' ++	depends on NETFILTER_XTABLES ++	depends on EXPERIMENTAL && (IP_NF_CONNTRACK || NF_CONNTRACK) ++       depends on NF_CT_ACCT ++	help ++	  Say Y if you want to be able to classify connections (and their ++	  packets) based on regular expression matching of their application ++	  layer data.   This is one way to classify applications such as ++	  peer-to-peer filesharing systems that do not always use the same ++	  port.  + -+typedef char *(*proc_ipt_search) (char *, char, char *); ++	  To compile it as a module, choose M here.  If unsure, say N.  + -+struct ipt_layer7_info { -+    char protocol[MAX_PROTOCOL_LEN]; -+    char invert:1; -+    char pattern[MAX_PATTERN_LEN]; -+}; ++config NETFILTER_XT_MATCH_LAYER7_DEBUG ++        bool 'Layer 7 debugging output' ++        depends on NETFILTER_XT_MATCH_LAYER7 ++        help ++          Say Y to get lots of debugging output.  + -+#endif /* _IPT_LAYER7_H */ -Index: linux-2.6.21.5/net/ipv4/netfilter/ip_conntrack_core.c -=================================================================== ---- linux-2.6.21.5.orig/net/ipv4/netfilter/ip_conntrack_core.c	2007-07-02 00:37:53.432285750 +0200 -+++ linux-2.6.21.5/net/ipv4/netfilter/ip_conntrack_core.c	2007-07-02 00:37:55.496414750 +0200 -@@ -332,6 +332,13 @@ - 	 * too. */ - 	ip_ct_remove_expectations(ct); -  -+	#if defined(CONFIG_IP_NF_MATCH_LAYER7) || defined(CONFIG_IP_NF_MATCH_LAYER7_MODULE) -+	if(ct->layer7.app_proto) -+		kfree(ct->layer7.app_proto); -+	if(ct->layer7.app_data) -+		kfree(ct->layer7.app_data); -+	#endif  + - 	/* We overload first tuple to link into unconfirmed list. */ - 	if (!is_confirmed(ct)) { - 		BUG_ON(list_empty(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list)); -Index: linux-2.6.21.5/net/ipv4/netfilter/ip_conntrack_standalone.c + config NETFILTER_XT_MATCH_STATISTIC + 	tristate '"statistic" match support' + 	depends on NETFILTER_XTABLES +Index: linux-2.6.21.7/net/netfilter/Makefile  =================================================================== ---- linux-2.6.21.5.orig/net/ipv4/netfilter/ip_conntrack_standalone.c	2007-07-02 00:37:53.440286250 +0200 -+++ linux-2.6.21.5/net/ipv4/netfilter/ip_conntrack_standalone.c	2007-07-02 00:37:55.544417750 +0200 -@@ -188,6 +188,12 @@ - 		return -ENOSPC; - #endif -  -+#if defined(CONFIG_IP_NF_MATCH_LAYER7) || defined(CONFIG_IP_NF_MATCH_LAYER7_MODULE) -+	if(conntrack->layer7.app_proto) -+		if (seq_printf(s, "l7proto=%s ",conntrack->layer7.app_proto)) -+			return 1; -+#endif -+ - 	if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use))) - 		return -ENOSPC; -  -Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c +--- linux-2.6.21.7.orig/net/netfilter/Makefile ++++ linux-2.6.21.7/net/netfilter/Makefile +@@ -68,6 +68,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) + + obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o + obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o + obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o ++obj-$(CONFIG_NETFILTER_XT_MATCH_LAYER7) += xt_layer7.o + obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o + obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o + obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o +Index: linux-2.6.21.7/net/netfilter/xt_layer7.c  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c	2007-07-02 01:27:54.195821750 +0200 -@@ -0,0 +1,583 @@ +--- /dev/null ++++ linux-2.6.21.7/net/netfilter/xt_layer7.c +@@ -0,0 +1,634 @@  +/*  +  Kernel module to match application layer (OSI layer 7) data in connections.  +  +  http://l7-filter.sf.net  + -+  By Matthew Strait and Ethan Sommer, 2003-2006. ++  (C) 2003, 2004, 2005, 2006, 2007 Matthew Strait and Ethan Sommer.  +  +  This program is free software; you can redistribute it and/or  +  modify it under the terms of the GNU General Public License @@ -82,37 +60,37 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +  2 of the License, or (at your option) any later version.  +  http://www.gnu.org/licenses/gpl.txt  + -+  Based on ipt_string.c (C) 2000 Emmanuel Roger <winfield@freegates.be> -+  and cls_layer7.c (C) 2003 Matthew Strait, Ethan Sommer, Justin Levandoski -+ -+  Jan Engelhardt, 2007-03-11: Arrange to compile with nf_conntrack ++  Based on ipt_string.c (C) 2000 Emmanuel Roger <winfield@freegates.be>, ++  xt_helper.c (C) 2002 Harald Welte and cls_layer7.c (C) 2003 Matthew Strait, ++  Ethan Sommer, Justin Levandoski.  +*/  + -+#include <linux/module.h> -+#include <linux/skbuff.h> -+#include <linux/proc_fs.h> -+#include <linux/ctype.h> ++#include <linux/spinlock.h> ++#include <linux/version.h>  +#include <net/ip.h>  +#include <net/tcp.h> ++#include <linux/module.h> ++#include <linux/skbuff.h> ++#include <linux/netfilter.h>  +#include <net/netfilter/nf_conntrack.h> -+#include <net/netfilter/nf_nat_rule.h> -+#include <linux/spinlock.h> ++#include <net/netfilter/nf_conntrack_core.h> ++#include <linux/netfilter/x_tables.h> ++#include <linux/netfilter/xt_layer7.h> ++#include <linux/ctype.h> ++#include <linux/proc_fs.h>  +  +#include "regexp/regexp.c"  + -+#include <linux/netfilter_ipv4/ipt_layer7.h> -+#include <linux/netfilter_ipv4/ip_tables.h> -+ -+MODULE_AUTHOR("Matthew Strait <quadong@users.sf.net>, Ethan Sommer <sommere@users.sf.net>");  +MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Matthew Strait <quadong@users.sf.net>, Ethan Sommer <sommere@users.sf.net>");  +MODULE_DESCRIPTION("iptables application layer match module"); -+MODULE_VERSION("2.0"); ++MODULE_ALIAS("ipt_layer7"); ++MODULE_VERSION("2.17");  +  +static int maxdatalen = 2048; // this is the default  +module_param(maxdatalen, int, 0444);  +MODULE_PARM_DESC(maxdatalen, "maximum bytes of data looked at by l7-filter"); -+ -+#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG ++#ifdef CONFIG_NETFILTER_XT_MATCH_LAYER7_DEBUG  +	#define DPRINTK(format,args...) printk(format,##args)  +#else  +	#define DPRINTK(format,args...) @@ -131,23 +109,7 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +	struct pattern_cache * next;  +} * first_pattern_cache = NULL;  + -+/* I'm new to locking.  Here are my assumptions: -+ -+- No one will write to /proc/net/layer7_numpackets over and over very fast; -+  if they did, nothing awful would happen. -+ -+- This code will never be processing the same packet twice at the same time, -+  because iptables rules are traversed in order. -+ -+- It doesn't matter if two packets from different connections are in here at -+  the same time, because they don't share any data. -+ -+- It _does_ matter if two packets from the same connection (or one from a -+  master and one from its child) are here at the same time.  In this case, -+  we have to protect the conntracks and the list of compiled patterns. -+*/ -+DEFINE_RWLOCK(ct_lock); -+DEFINE_SPINLOCK(list_lock); ++DEFINE_SPINLOCK(l7_lock);  +  +#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG  +/* Converts an unfriendly string into a friendly one by @@ -159,7 +121,8 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +  +	if(!f) {  +		if (net_ratelimit()) -+			printk(KERN_ERR "layer7: out of memory in friendly_print, bailing.\n"); ++			printk(KERN_ERR "layer7: out of memory in " ++					"friendly_print, bailing.\n");  +		return NULL;  +	}  + @@ -176,14 +139,14 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +{  +	switch (i) {  +		case 0 ... 9: -+			return (char)(i + '0'); ++			return (i + '0');  +			break;  +		case 10 ... 15: -+			return (char)(i - 10 + 'a'); ++			return (i - 10 + 'a');  +			break;  +		default:  +			if (net_ratelimit()) -+				printk("Problem in dec2hex\n"); ++				printk("layer7: Problem in dec2hex\n");  +			return '\0';  +	}  +} @@ -195,7 +158,8 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +  +	if(!g) {  +	       if (net_ratelimit()) -+			printk(KERN_ERR "layer7: out of memory in hex_print, bailing.\n"); ++			printk(KERN_ERR "layer7: out of memory in hex_print, " ++					"bailing.\n");  +	       return NULL;  +	}  + @@ -212,7 +176,8 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +  +/* Use instead of regcomp.  As we expect to be seeing the same regexps over and  +over again, it make sense to cache the results. */ -+static regexp * compile_and_cache(char * regex_string, char * protocol) ++static regexp * compile_and_cache(const char * regex_string,  ++                                  const char * protocol)  +{  +	struct pattern_cache * node               = first_pattern_cache;  +	struct pattern_cache * last_pattern_cache = first_pattern_cache; @@ -234,7 +199,8 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +  +	if(!tmp) {  +		if (net_ratelimit()) -+			printk(KERN_ERR "layer7: out of memory in compile_and_cache, bailing.\n"); ++			printk(KERN_ERR "layer7: out of memory in " ++					"compile_and_cache, bailing.\n");  +		return NULL;  +	}  + @@ -244,7 +210,8 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +  +	if(!tmp->regex_string || !tmp->pattern) {  +		if (net_ratelimit()) -+			printk(KERN_ERR "layer7: out of memory in compile_and_cache, bailing.\n"); ++			printk(KERN_ERR "layer7: out of memory in " ++					"compile_and_cache, bailing.\n");  +		kfree(tmp->regex_string);  +		kfree(tmp->pattern);  +		kfree(tmp); @@ -262,10 +229,12 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +	/* copy the string and compile the regex */  +	len = strlen(regex_string);  +	DPRINTK("About to compile this: \"%s\"\n", regex_string); -+	node->pattern = regcomp(regex_string, &len); ++	node->pattern = regcomp((char *)regex_string, &len);  +	if ( !node->pattern ) {  +		if (net_ratelimit()) -+			printk(KERN_ERR "layer7: Error compiling regexp \"%s\" (%s)\n", regex_string, protocol); ++			printk(KERN_ERR "layer7: Error compiling regexp " ++					"\"%s\" (%s)\n",  ++					regex_string, protocol);  +		/* pattern is now cached as NULL, so we won't try again. */  +	}  + @@ -275,11 +244,11 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +  +static int can_handle(const struct sk_buff *skb)  +{ -+	if(!skb->nh.iph) /* not IP */ ++	if(!ip_hdr(skb)) /* not IP */  +		return 0; -+	if(skb->nh.iph->protocol != IPPROTO_TCP && -+	   skb->nh.iph->protocol != IPPROTO_UDP && -+	   skb->nh.iph->protocol != IPPROTO_ICMP) ++	if(ip_hdr(skb)->protocol != IPPROTO_TCP && ++	   ip_hdr(skb)->protocol != IPPROTO_UDP && ++	   ip_hdr(skb)->protocol != IPPROTO_ICMP)  +		return 0;  +	return 1;  +} @@ -287,11 +256,11 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +/* Returns offset the into the skb->data that the application data starts */  +static int app_data_offset(const struct sk_buff *skb)  +{ -+	/* In case we are ported somewhere (ebtables?) where skb->nh.iph ++	/* In case we are ported somewhere (ebtables?) where ip_hdr(skb)  +	isn't set, this can be gotten from 4*(skb->data[0] & 0x0f) as well. */ -+	int ip_hl = 4*skb->nh.iph->ihl; ++	int ip_hl = 4*ip_hdr(skb)->ihl;  + -+	if( skb->nh.iph->protocol == IPPROTO_TCP ) { ++	if( ip_hdr(skb)->protocol == IPPROTO_TCP ) {  +		/* 12 == offset into TCP header for the header length field.  +		Can't get this with skb->h.th->doff because the tcphdr  +		struct doesn't get set when routing (this is confirmed to be @@ -299,31 +268,36 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +		int tcp_hl = 4*(skb->data[ip_hl + 12] >> 4);  +  +		return ip_hl + tcp_hl; -+	} else if( skb->nh.iph->protocol == IPPROTO_UDP  ) { ++	} else if( ip_hdr(skb)->protocol == IPPROTO_UDP  ) {  +		return ip_hl + 8; /* UDP header is always 8 bytes */ -+	} else if( skb->nh.iph->protocol == IPPROTO_ICMP ) { ++	} else if( ip_hdr(skb)->protocol == IPPROTO_ICMP ) {  +		return ip_hl + 8; /* ICMP header is 8 bytes */  +	} else {  +		if (net_ratelimit()) -+			printk(KERN_ERR "layer7: tried to handle unknown protocol!\n"); ++			printk(KERN_ERR "layer7: tried to handle unknown " ++					"protocol!\n");  +		return ip_hl + 8; /* something reasonable */  +	}  +}  +  +/* handles whether there's a match when we aren't appending data anymore */ -+static int match_no_append(struct ip_conntrack * conntrack, struct ip_conntrack * master_conntrack, -+			enum ip_conntrack_info ctinfo, enum ip_conntrack_info master_ctinfo, -+			struct ipt_layer7_info * info) ++static int match_no_append(struct nf_conn * conntrack,  ++                           struct nf_conn * master_conntrack,  ++                           enum ip_conntrack_info ctinfo, ++                           enum ip_conntrack_info master_ctinfo, ++                           const struct xt_layer7_info * info)  +{  +	/* If we're in here, throw the app data away */ -+	write_lock(&ct_lock);  +	if(master_conntrack->layer7.app_data != NULL) {  +  +	#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG  +		if(!master_conntrack->layer7.app_proto) { -+			char * f = friendly_print(master_conntrack->layer7.app_data); -+			char * g = hex_print(master_conntrack->layer7.app_data); -+			DPRINTK("\nl7-filter gave up after %d bytes (%d packets):\n%s\n", ++			char * f =  ++			  friendly_print(master_conntrack->layer7.app_data); ++			char * g =  ++			  hex_print(master_conntrack->layer7.app_data); ++			DPRINTK("\nl7-filter gave up after %d bytes " ++				"(%d packets):\n%s\n",  +				strlen(f), TOTAL_PACKETS, f);  +			kfree(f);  +			DPRINTK("In hex: %s\n", g); @@ -334,53 +308,54 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +		kfree(master_conntrack->layer7.app_data);  +		master_conntrack->layer7.app_data = NULL; /* don't free again */  +	} -+	write_unlock(&ct_lock);  +  +	if(master_conntrack->layer7.app_proto){ -+		/* Here child connections set their .app_proto (for /proc/net/ip_conntrack) */ -+		write_lock(&ct_lock); ++		/* Here child connections set their .app_proto (for /proc) */  +		if(!conntrack->layer7.app_proto) { -+			conntrack->layer7.app_proto = kmalloc(strlen(master_conntrack->layer7.app_proto)+1, GFP_ATOMIC); ++			conntrack->layer7.app_proto =  ++			  kmalloc(strlen(master_conntrack->layer7.app_proto)+1,  ++			    GFP_ATOMIC);  +			if(!conntrack->layer7.app_proto){  +				if (net_ratelimit()) -+					printk(KERN_ERR "layer7: out of memory in match_no_append, bailing.\n"); -+				write_unlock(&ct_lock); ++					printk(KERN_ERR "layer7: out of memory " ++							"in match_no_append, " ++							"bailing.\n");  +				return 1;  +			} -+			strcpy(conntrack->layer7.app_proto, master_conntrack->layer7.app_proto); ++			strcpy(conntrack->layer7.app_proto,  ++				master_conntrack->layer7.app_proto);  +		} -+		write_unlock(&ct_lock);  + -+		return (!strcmp(master_conntrack->layer7.app_proto, info->protocol)); ++		return (!strcmp(master_conntrack->layer7.app_proto,  ++				info->protocol));  +	}  +	else {  +		/* If not classified, set to "unknown" to distinguish from  +		connections that are still being tested. */ -+		write_lock(&ct_lock); -+		master_conntrack->layer7.app_proto = kmalloc(strlen("unknown")+1, GFP_ATOMIC); ++		master_conntrack->layer7.app_proto =  ++			kmalloc(strlen("unknown")+1, GFP_ATOMIC);  +		if(!master_conntrack->layer7.app_proto){  +			if (net_ratelimit()) -+				printk(KERN_ERR "layer7: out of memory in match_no_append, bailing.\n"); -+			write_unlock(&ct_lock); ++				printk(KERN_ERR "layer7: out of memory in " ++						"match_no_append, bailing.\n");  +			return 1;  +		}  +		strcpy(master_conntrack->layer7.app_proto, "unknown"); -+		write_unlock(&ct_lock);  +		return 0;  +	}  +}  +  +/* add the new app data to the conntrack.  Return number of bytes added. */ -+static int add_data(struct ip_conntrack * master_conntrack, -+			char * app_data, int appdatalen) ++static int add_data(struct nf_conn * master_conntrack, ++                    char * app_data, int appdatalen)  +{  +	int length = 0, i;  +	int oldlength = master_conntrack->layer7.app_data_len;  + -+	// This is a fix for a race condition by Deti Fliegl. However, I'm not  -+	// clear on whether the race condition exists or whether this really  -+	// fixes it.  I might just be being dense... Anyway, if it's not really  -+	// a fix, all it does is waste a very small amount of time. ++	/* This is a fix for a race condition by Deti Fliegl. However, I'm not  ++	   clear on whether the race condition exists or whether this really  ++	   fixes it.  I might just be being dense... Anyway, if it's not really  ++	   a fix, all it does is waste a very small amount of time. */  +	if(!master_conntrack->layer7.app_data) return 0;  +  +	/* Strip nulls. Make everything lower case (our regex lib doesn't @@ -388,9 +363,10 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +	for(i = 0; i < maxdatalen-oldlength-1 &&  +		   i < appdatalen; i++) {  +		if(app_data[i] != '\0') { ++			/* the kernel version of tolower mungs 'upper ascii' */  +			master_conntrack->layer7.app_data[length+oldlength] = -+				/* the kernel version of tolower mungs 'upper ascii' */ -+				isascii(app_data[i])? tolower(app_data[i]) : app_data[i]; ++				isascii(app_data[i])?  ++					tolower(app_data[i]) : app_data[i];  +			length++;  +		}  +	} @@ -401,33 +377,109 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +	return length;  +}  + -+/* Returns true on match and false otherwise.  */ -+static int match(const struct sk_buff *skbin, -+	const struct net_device *in, const struct net_device *out, -+	const struct xt_match *match, const void *matchinfo, -+	int offset, unsigned int protoff, int *hotdrop) ++/* taken from drivers/video/modedb.c */ ++static int my_atoi(const char *s) ++{ ++	int val = 0; ++ ++	for (;; s++) { ++		switch (*s) { ++			case '0'...'9': ++			val = 10*val+(*s-'0'); ++			break; ++		default: ++			return val; ++		} ++	} ++} ++ ++/* write out num_packets to userland. */ ++static int layer7_read_proc(char* page, char ** start, off_t off, int count, ++                            int* eof, void * data) ++{ ++	if(num_packets > 99 && net_ratelimit()) ++		printk(KERN_ERR "layer7: NOT REACHED. num_packets too big\n"); ++ ++	page[0] = num_packets/10 + '0'; ++	page[1] = num_packets%10 + '0'; ++	page[2] = '\n'; ++	page[3] = '\0'; ++ ++	*eof=1; ++ ++	return 3; ++} ++ ++/* Read in num_packets from userland */ ++static int layer7_write_proc(struct file* file, const char* buffer, ++                             unsigned long count, void *data) ++{ ++	char * foo = kmalloc(count, GFP_ATOMIC); ++ ++	if(!foo){ ++		if (net_ratelimit()) ++			printk(KERN_ERR "layer7: out of memory, bailing. " ++					"num_packets unchanged.\n"); ++		return count; ++	} ++ ++	if(copy_from_user(foo, buffer, count)) { ++		return -EFAULT; ++	} ++ ++ ++	num_packets = my_atoi(foo); ++	kfree (foo); ++ ++	/* This has an arbitrary limit to make the math easier. I'm lazy. ++	But anyway, 99 is a LOT! If you want more, you're doing it wrong! */ ++	if(num_packets > 99) { ++		printk(KERN_WARNING "layer7: num_packets can't be > 99.\n"); ++		num_packets = 99; ++	} else if(num_packets < 1) { ++		printk(KERN_WARNING "layer7: num_packets can't be < 1.\n"); ++		num_packets = 1; ++	} ++ ++	return count; ++} ++ ++static int ++match(const struct sk_buff *skbin, ++      const struct net_device *in, ++      const struct net_device *out, ++      const struct xt_match *match, ++      const void *matchinfo, ++      int offset, ++      unsigned int protoff, ++      int *hotdrop)  +{  +	/* sidestep const without getting a compiler warning... */  +	struct sk_buff * skb = (struct sk_buff *)skbin;   + -+	struct ipt_layer7_info * info = (struct ipt_layer7_info *)matchinfo; ++	const struct xt_layer7_info * info = matchinfo;  +	enum ip_conntrack_info master_ctinfo, ctinfo; -+	struct nf_conn *master_conntrack; -+	struct ip_conntrack *conntrack; ++	struct nf_conn *master_conntrack, *conntrack;  +	unsigned char * app_data;  +	unsigned int pattern_result, appdatalen;  +	regexp * comppattern;  + ++	/* Be paranoid/incompetent - lock the entire match function. */ ++	spin_lock_bh(&l7_lock); ++  +	if(!can_handle(skb)){  +		DPRINTK("layer7: This is some protocol I can't handle.\n"); ++		spin_unlock_bh(&l7_lock);  +		return info->invert;  +	}  +  +	/* Treat parent & all its children together as one connection, except  +	for the purpose of setting conntrack->layer7.app_proto in the actual  +	connection. This makes /proc/net/ip_conntrack more satisfying. */ -+	if(((conntrack = ip_conntrack_get((struct sk_buff *)skb, &ctinfo)) == NULL) || -+	   ((master_conntrack = ip_conntrack_get((struct sk_buff *)skb, &master_ctinfo)) == NULL)) { ++	if(!(conntrack = nf_ct_get(skb, &ctinfo)) || ++	   !(master_conntrack=nf_ct_get(skb,&master_ctinfo))){ ++		DPRINTK("layer7: couldn't get conntrack.\n"); ++		spin_unlock_bh(&l7_lock);  +		return info->invert;  +	}  + @@ -439,95 +491,100 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +	if(TOTAL_PACKETS > num_packets ||  +	   master_conntrack->layer7.app_proto) {  + -+		pattern_result = match_no_append(conntrack, master_conntrack, ctinfo, master_ctinfo, info); ++		pattern_result = match_no_append(conntrack, master_conntrack,  ++						 ctinfo, master_ctinfo, info);  + -+		/* skb->cb[0] == seen. Don't do things twice if there are multiple l7 -+		rules. I'm not sure that using cb for this purpose is correct, even though -+		it says "put your private variables there". But it doesn't look like it -+		is being used for anything else in the skbs that make it here. */ -+		skb->cb[0] = 1; /* marking it seen here is probably irrelevant, but consistant */ ++		/* skb->cb[0] == seen. Don't do things twice if there are  ++		multiple l7 rules. I'm not sure that using cb for this purpose  ++		is correct, even though it says "put your private variables  ++		there". But it doesn't look like it is being used for anything ++		else in the skbs that make it here. */ ++		skb->cb[0] = 1; /* marking it seen here's probably irrelevant */  + ++		spin_unlock_bh(&l7_lock);  +		return (pattern_result ^ info->invert);  +	}  +  +	if(skb_is_nonlinear(skb)){  +		if(skb_linearize(skb) != 0){  +			if (net_ratelimit()) -+				printk(KERN_ERR "layer7: failed to linearize packet, bailing.\n"); ++				printk(KERN_ERR "layer7: failed to linearize " ++						"packet, bailing.\n"); ++			spin_unlock_bh(&l7_lock);  +			return info->invert;  +		}  +	}  +  +	/* now that the skb is linearized, it's safe to set these. */  +	app_data = skb->data + app_data_offset(skb); -+	appdatalen = skb->tail - app_data; ++	appdatalen = skb_tail_pointer(skb) - app_data;  + -+	spin_lock_bh(&list_lock);  +	/* the return value gets checked later, when we're ready to use it */  +	comppattern = compile_and_cache(info->pattern, info->protocol); -+	spin_unlock_bh(&list_lock);  +  +	/* On the first packet of a connection, allocate space for app data */ -+	write_lock(&ct_lock); -+	if(TOTAL_PACKETS == 1 && !skb->cb[0] && !master_conntrack->layer7.app_data) { -+		master_conntrack->layer7.app_data = kmalloc(maxdatalen, GFP_ATOMIC); ++	if(TOTAL_PACKETS == 1 && !skb->cb[0] &&  ++	   !master_conntrack->layer7.app_data){ ++		master_conntrack->layer7.app_data =  ++			kmalloc(maxdatalen, GFP_ATOMIC);  +		if(!master_conntrack->layer7.app_data){  +			if (net_ratelimit()) -+				printk(KERN_ERR "layer7: out of memory in match, bailing.\n"); -+			write_unlock(&ct_lock); ++				printk(KERN_ERR "layer7: out of memory in " ++						"match, bailing.\n"); ++			spin_unlock_bh(&l7_lock);  +			return info->invert;  +		}  +  +		master_conntrack->layer7.app_data[0] = '\0';  +	} -+	write_unlock(&ct_lock);  +  +	/* Can be here, but unallocated, if numpackets is increased near  +	the beginning of a connection */ -+	if(master_conntrack->layer7.app_data == NULL) ++	if(master_conntrack->layer7.app_data == NULL){ ++		spin_unlock_bh(&l7_lock);  +		return (info->invert); /* unmatched */ ++	}  +  +	if(!skb->cb[0]){  +		int newbytes; -+		write_lock(&ct_lock);  +		newbytes = add_data(master_conntrack, app_data, appdatalen); -+		write_unlock(&ct_lock);  +  +		if(newbytes == 0) { /* didn't add any data */  +			skb->cb[0] = 1;  +			/* Didn't match before, not going to match now */ ++			spin_unlock_bh(&l7_lock);  +			return info->invert;  +		}  +	}  +  +	/* If looking for "unknown", then never match.  "Unknown" means that  +	we've given up; we're still trying with these packets. */ -+	read_lock(&ct_lock);  +	if(!strcmp(info->protocol, "unknown")) {  +		pattern_result = 0;  +	/* If looking for "unset", then always match. "Unset" means that we  +	haven't yet classified the connection. */  +	} else if(!strcmp(info->protocol, "unset")) {  +		pattern_result = 2; -+		DPRINTK("layer7: matched unset: not yet classified (%d/%d packets)\n", TOTAL_PACKETS, num_packets); ++		DPRINTK("layer7: matched unset: not yet classified " ++			"(%d/%d packets)\n", TOTAL_PACKETS, num_packets);  +	/* If the regexp failed to compile, don't bother running it */ -+	} else if(comppattern && regexec(comppattern, master_conntrack->layer7.app_data)) { ++	} else if(comppattern &&  ++		  regexec(comppattern, master_conntrack->layer7.app_data)){  +		DPRINTK("layer7: matched %s\n", info->protocol);  +		pattern_result = 1;  +	} else pattern_result = 0; -+	read_unlock(&ct_lock);  +  +	if(pattern_result == 1) { -+		write_lock(&ct_lock); -+		master_conntrack->layer7.app_proto = kmalloc(strlen(info->protocol)+1, GFP_ATOMIC); ++		master_conntrack->layer7.app_proto =  ++			kmalloc(strlen(info->protocol)+1, GFP_ATOMIC);  +		if(!master_conntrack->layer7.app_proto){  +			if (net_ratelimit()) -+				printk(KERN_ERR "layer7: out of memory in match, bailing.\n"); -+			write_unlock(&ct_lock); ++				printk(KERN_ERR "layer7: out of memory in " ++						"match, bailing.\n"); ++			spin_unlock_bh(&l7_lock);  +			return (pattern_result ^ info->invert);  +		}  +		strcpy(master_conntrack->layer7.app_proto, info->protocol); -+		write_unlock(&ct_lock);  +	} else if(pattern_result > 1) { /* cleanup from "unset" */  +		pattern_result = 1;  +	} @@ -535,169 +592,99 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +	/* mark the packet seen */  +	skb->cb[0] = 1;  + ++	spin_unlock_bh(&l7_lock);  +	return (pattern_result ^ info->invert);  +}  + -+static struct xt_match layer7_match = { -+	.name = "layer7", -+	.match = &match, -+	.matchsize  = sizeof(struct ipt_layer7_info), -+	.family = AF_INET, -+	.me = THIS_MODULE -+}; ++static int check(const char *tablename, ++		 const void *inf, ++		 const struct xt_match *match, ++		 void *matchinfo, ++		 unsigned int hook_mask)  + -+/* taken from drivers/video/modedb.c */ -+static int my_atoi(const char *s)  +{ -+	int val = 0; -+ -+	for (;; s++) { -+		switch (*s) { -+			case '0'...'9': -+			val = 10*val+(*s-'0'); -+			break; -+		default: -+			return val; -+		} -+	} ++	// load nf_conntrack_ipv4 ++        if (nf_ct_l3proto_try_module_get(match->family) < 0) { ++                printk(KERN_WARNING "can't load conntrack support for " ++                                    "proto=%d\n", match->family); ++                return false; ++        } ++	return true;  +}  + -+/* write out num_packets to userland. */ -+static int layer7_read_proc(char* page, char ** start, off_t off, int count, -+		     int* eof, void * data) ++static void ++destroy(const struct xt_match *match, void *matchinfo)  +{ -+	if(num_packets > 99 && net_ratelimit()) -+		printk(KERN_ERR "layer7: NOT REACHED. num_packets too big\n"); -+ -+	page[0] = num_packets/10 + '0'; -+	page[1] = num_packets%10 + '0'; -+	page[2] = '\n'; -+	page[3] = '\0'; -+ -+	*eof=1; -+ -+	return 3; ++	nf_ct_l3proto_module_put(match->family);  +}  + -+/* Read in num_packets from userland */ -+static int layer7_write_proc(struct file* file, const char* buffer, -+		      unsigned long count, void *data) ++static struct xt_match xt_layer7_match[] = {  +{ -+	char * foo = kmalloc(count, GFP_ATOMIC); -+ -+	if(!foo){ -+		if (net_ratelimit()) -+			printk(KERN_ERR "layer7: out of memory, bailing. num_packets unchanged.\n"); -+		return count; -+	} -+ -+	if(copy_from_user(foo, buffer, count)) { -+		return -EFAULT; -+	} -+ -+ -+	num_packets = my_atoi(foo); -+	kfree (foo); -+ -+	/* This has an arbitrary limit to make the math easier. I'm lazy. -+	But anyway, 99 is a LOT! If you want more, you're doing it wrong! */ -+	if(num_packets > 99) { -+		printk(KERN_WARNING "layer7: num_packets can't be > 99.\n"); -+		num_packets = 99; -+	} else if(num_packets < 1) { -+		printk(KERN_WARNING "layer7: num_packets can't be < 1.\n"); -+		num_packets = 1; -+	} ++	.name		= "layer7", ++	.family		= AF_INET, ++	.checkentry	= check, ++	.match		= match, ++	.destroy	= destroy, ++	.matchsize	= sizeof(struct xt_layer7_info), ++	.me		= THIS_MODULE ++} ++};  + -+	return count; ++static void layer7_cleanup_proc(void) ++{ ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23) ++	remove_proc_entry("layer7_numpackets", proc_net); ++#else ++	remove_proc_entry("layer7_numpackets", init_net.proc_net); ++#endif  +}  +  +/* register the proc file */  +static void layer7_init_proc(void)  +{  +	struct proc_dir_entry* entry; ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)  +	entry = create_proc_entry("layer7_numpackets", 0644, proc_net); ++#else ++	entry = create_proc_entry("layer7_numpackets", 0644, init_net.proc_net); ++#endif  +	entry->read_proc = layer7_read_proc;  +	entry->write_proc = layer7_write_proc;  +}  + -+static void layer7_cleanup_proc(void) -+{ -+	remove_proc_entry("layer7_numpackets", proc_net); -+} -+ -+static int __init ipt_layer7_init(void) ++static int __init xt_layer7_init(void)  +{  +	need_conntrack();  +  +	layer7_init_proc();  +	if(maxdatalen < 1) { -+		printk(KERN_WARNING "layer7: maxdatalen can't be < 1, using 1\n"); ++		printk(KERN_WARNING "layer7: maxdatalen can't be < 1, " ++			"using 1\n");  +		maxdatalen = 1;  +	}  +	/* This is not a hard limit.  It's just here to prevent people from  +	bringing their slow machines to a grinding halt. */  +	else if(maxdatalen > 65536) { -+		printk(KERN_WARNING "layer7: maxdatalen can't be > 65536, using 65536\n"); ++		printk(KERN_WARNING "layer7: maxdatalen can't be > 65536, " ++			"using 65536\n");  +		maxdatalen = 65536;  +	} -+	return xt_register_match(&layer7_match); ++	return xt_register_matches(xt_layer7_match, ++				   ARRAY_SIZE(xt_layer7_match));  +}  + -+static void __exit ipt_layer7_fini(void) ++static void __exit xt_layer7_fini(void)  +{  +	layer7_cleanup_proc(); -+	xt_unregister_match(&layer7_match); ++	xt_unregister_matches(xt_layer7_match, ARRAY_SIZE(xt_layer7_match));  +}  + -+module_init(ipt_layer7_init); -+module_exit(ipt_layer7_fini); -Index: linux-2.6.21.5/net/ipv4/netfilter/Kconfig -=================================================================== ---- linux-2.6.21.5.orig/net/ipv4/netfilter/Kconfig	2007-07-02 00:37:53.456287250 +0200 -+++ linux-2.6.21.5/net/ipv4/netfilter/Kconfig	2007-07-02 01:21:17.231013000 +0200 -@@ -245,6 +245,24 @@ -  - 	  To compile it as a module, choose M here.  If unsure, say N. -  -+config IP_NF_MATCH_LAYER7 -+	tristate "Layer 7 match support (EXPERIMENTAL)" -+	depends on IP_NF_IPTABLES && NF_CT_ACCT && NF_CONNTRACK && EXPERIMENTAL -+	help -+	  Say Y if you want to be able to classify connections (and their -+	  packets) based on regular expression matching of their application -+	  layer data.   This is one way to classify applications such as -+	  peer-to-peer filesharing systems that do not always use the same -+	  port. -+ -+	  To compile it as a module, choose M here.  If unsure, say N. -+ -+config IP_NF_MATCH_LAYER7_DEBUG -+	bool "Layer 7 debugging output" -+	depends on IP_NF_MATCH_LAYER7 -+	help -+	  Say Y to get lots of debugging output. -+ - config IP_NF_MATCH_TOS - 	tristate "TOS match support" - 	depends on IP_NF_IPTABLES -Index: linux-2.6.21.5/net/ipv4/netfilter/Makefile ++module_init(xt_layer7_init); ++module_exit(xt_layer7_fini); +Index: linux-2.6.21.7/net/netfilter/regexp/regexp.c  =================================================================== ---- linux-2.6.21.5.orig/net/ipv4/netfilter/Makefile	2007-07-02 00:37:53.464287750 +0200 -+++ linux-2.6.21.5/net/ipv4/netfilter/Makefile	2007-07-02 00:43:58.191081750 +0200 -@@ -92,6 +92,8 @@ - obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o - obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o -  -+obj-$(CONFIG_IP_NF_MATCH_LAYER7) += ipt_layer7.o -+ - # targets - obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o - obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o -Index: linux-2.6.21.5/net/ipv4/netfilter/regexp/regexp.c -=================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.21.5/net/ipv4/netfilter/regexp/regexp.c	2007-07-02 00:37:55.648424250 +0200 +--- /dev/null ++++ linux-2.6.21.7/net/netfilter/regexp/regexp.c  @@ -0,0 +1,1197 @@  +/*  + * regcomp and regexec -- regsub and regerror are elsewhere @@ -1896,10 +1883,10 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/regexp/regexp.c  +#endif  +  + -Index: linux-2.6.21.5/net/ipv4/netfilter/regexp/regexp.h +Index: linux-2.6.21.7/net/netfilter/regexp/regexp.h  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.21.5/net/ipv4/netfilter/regexp/regexp.h	2007-07-02 00:37:55.700427500 +0200 +--- /dev/null ++++ linux-2.6.21.7/net/netfilter/regexp/regexp.h  @@ -0,0 +1,41 @@  +/*  + * Definitions etc. for regexp(3) routines. @@ -1942,20 +1929,20 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/regexp/regexp.h  +void regerror(char *s);  +  +#endif -Index: linux-2.6.21.5/net/ipv4/netfilter/regexp/regmagic.h +Index: linux-2.6.21.7/net/netfilter/regexp/regmagic.h  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.21.5/net/ipv4/netfilter/regexp/regmagic.h	2007-07-02 00:37:55.724429000 +0200 +--- /dev/null ++++ linux-2.6.21.7/net/netfilter/regexp/regmagic.h  @@ -0,0 +1,5 @@  +/*  + * The first byte of the regexp internal "program" is actually this magic  + * number; the start node begins in the second byte.  + */  +#define	MAGIC	0234 -Index: linux-2.6.21.5/net/ipv4/netfilter/regexp/regsub.c +Index: linux-2.6.21.7/net/netfilter/regexp/regsub.c  =================================================================== ---- /dev/null	1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.21.5/net/ipv4/netfilter/regexp/regsub.c	2007-07-02 00:37:55.752430750 +0200 +--- /dev/null ++++ linux-2.6.21.7/net/netfilter/regexp/regsub.c  @@ -0,0 +1,95 @@  +/*  + * regsub @@ -2052,15 +2039,53 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/regexp/regsub.c  +	}  +	*dst++ = '\0';  +} -Index: linux-2.6.21.5/include/net/netfilter/nf_conntrack.h +Index: linux-2.6.21.7/net/netfilter/nf_conntrack_core.c +=================================================================== +--- linux-2.6.21.7.orig/net/netfilter/nf_conntrack_core.c ++++ linux-2.6.21.7/net/netfilter/nf_conntrack_core.c +@@ -352,6 +352,14 @@ destroy_conntrack(struct nf_conntrack *n + 	 * too. */ + 	nf_ct_remove_expectations(ct); +  ++	#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE) ++	if(ct->layer7.app_proto) ++		kfree(ct->layer7.app_proto); ++	if(ct->layer7.app_data) ++	kfree(ct->layer7.app_data); ++	#endif ++ ++ + 	/* We overload first tuple to link into unconfirmed list. */ + 	if (!nf_ct_is_confirmed(ct)) { + 		BUG_ON(list_empty(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list)); +Index: linux-2.6.21.7/net/netfilter/nf_conntrack_standalone.c +=================================================================== +--- linux-2.6.21.7.orig/net/netfilter/nf_conntrack_standalone.c ++++ linux-2.6.21.7/net/netfilter/nf_conntrack_standalone.c +@@ -195,7 +195,12 @@ static int ct_seq_show(struct seq_file * + 		return -ENOSPC; + #endif +  +-	if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use))) ++#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE) ++	if(conntrack->layer7.app_proto) ++		if(seq_printf(s, "l7proto=%s ", conntrack->layer7.app_proto)) ++			return -ENOSPC; ++#endif ++	if (seq_printf(s, "asdfuse=%u\n", atomic_read(&conntrack->ct_general.use))) + 		return -ENOSPC; + 	 + 	return 0; +Index: linux-2.6.21.7/include/net/netfilter/nf_conntrack.h  =================================================================== ---- linux-2.6.21.5.orig/include/net/netfilter/nf_conntrack.h	2007-07-02 00:49:22.815369500 +0200 -+++ linux-2.6.21.5/include/net/netfilter/nf_conntrack.h	2007-07-02 00:56:21.413530250 +0200 -@@ -128,6 +128,21 @@ +--- linux-2.6.21.7.orig/include/net/netfilter/nf_conntrack.h ++++ linux-2.6.21.7/include/net/netfilter/nf_conntrack.h +@@ -128,6 +128,22 @@ struct nf_conn   	u_int32_t secmark;   #endif -+#if defined(CONFIG_IP_NF_MATCH_LAYER7) || defined(CONFIG_IP_NF_MATCH_LAYER7_MODULE) ++#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || \ ++    defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE)  +	struct {  +		/*  +		 * e.g. "http". NULL before decision. "unknown" after decision @@ -2078,3 +2103,21 @@ Index: linux-2.6.21.5/include/net/netfilter/nf_conntrack.h   	/* Storage reserved for other modules: */   	union nf_conntrack_proto proto; +Index: linux-2.6.21.7/include/linux/netfilter/xt_layer7.h +=================================================================== +--- /dev/null ++++ linux-2.6.21.7/include/linux/netfilter/xt_layer7.h +@@ -0,0 +1,13 @@ ++#ifndef _XT_LAYER7_H ++#define _XT_LAYER7_H ++ ++#define MAX_PATTERN_LEN 8192 ++#define MAX_PROTOCOL_LEN 256 ++ ++struct xt_layer7_info { ++    char protocol[MAX_PROTOCOL_LEN]; ++    char pattern[MAX_PATTERN_LEN]; ++    u_int8_t invert; ++}; ++ ++#endif /* _XT_LAYER7_H */ diff --git a/target/linux/generic-2.6/patches/101-netfilter_layer7_pktmatch.patch b/target/linux/generic-2.6/patches/101-netfilter_layer7_pktmatch.patch index 966353ad2..cabffacc1 100644 --- a/target/linux/generic-2.6/patches/101-netfilter_layer7_pktmatch.patch +++ b/target/linux/generic-2.6/patches/101-netfilter_layer7_pktmatch.patch @@ -1,37 +1,37 @@ -Index: linux-2.6.21.5/include/linux/netfilter_ipv4/ipt_layer7.h +Index: linux-2.6.21.7/include/linux/netfilter/xt_layer7.h  =================================================================== ---- linux-2.6.21.5.orig/include/linux/netfilter_ipv4/ipt_layer7.h	2007-07-02 00:43:58.271086750 +0200 -+++ linux-2.6.21.5/include/linux/netfilter_ipv4/ipt_layer7.h	2007-07-02 01:36:08.914739750 +0200 -@@ -21,6 +21,7 @@ +--- linux-2.6.21.7.orig/include/linux/netfilter/xt_layer7.h ++++ linux-2.6.21.7/include/linux/netfilter/xt_layer7.h +@@ -8,6 +8,7 @@ struct xt_layer7_info {       char protocol[MAX_PROTOCOL_LEN]; -     char invert:1;       char pattern[MAX_PATTERN_LEN]; -+    char pkt; +     u_int8_t invert; ++    u_int8_t pkt;   }; - #endif /* _IPT_LAYER7_H */ -Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c + #endif /* _XT_LAYER7_H */ +Index: linux-2.6.21.7/net/netfilter/xt_layer7.c  =================================================================== ---- linux-2.6.21.5.orig/net/ipv4/netfilter/ipt_layer7.c	2007-07-02 01:27:54.195821750 +0200 -+++ linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c	2007-07-02 01:37:01.990056750 +0200 -@@ -299,33 +299,34 @@ - 	} +--- linux-2.6.21.7.orig/net/netfilter/xt_layer7.c ++++ linux-2.6.21.7/net/netfilter/xt_layer7.c +@@ -297,34 +297,36 @@ static int match_no_append(struct nf_con   } --/* add the new app data to the conntrack.  Return number of bytes added. */ --static int add_data(struct ip_conntrack * master_conntrack, --			char * app_data, int appdatalen) + /* add the new app data to the conntrack.  Return number of bytes added. */ +-static int add_data(struct nf_conn * master_conntrack, +-                    char * app_data, int appdatalen)  +static int add_datastr(char *target, int offset, char *app_data, int len)   {   	int length = 0, i;  -	int oldlength = master_conntrack->layer7.app_data_len;  - --	// This is a fix for a race condition by Deti Fliegl. However, I'm not  --	// clear on whether the race condition exists or whether this really  --	// fixes it.  I might just be being dense... Anyway, if it's not really  --	// a fix, all it does is waste a very small amount of time. +-	/* This is a fix for a race condition by Deti Fliegl. However, I'm not  +-	   clear on whether the race condition exists or whether this really  +-	   fixes it.  I might just be being dense... Anyway, if it's not really  +-	   a fix, all it does is waste a very small amount of time. */  -	if(!master_conntrack->layer7.app_data) return 0; -+	if(!target) return 0; ++	 ++	if (!target) return 0;   	/* Strip nulls. Make everything lower case (our regex lib doesn't   	do case insensitivity).  Add it to the end of the current data. */ @@ -39,54 +39,55 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  -		   i < appdatalen; i++) {  +	for(i = 0; i < maxdatalen-offset-1 && i < len; i++) {   		if(app_data[i] != '\0') { + 			/* the kernel version of tolower mungs 'upper ascii' */  -			master_conntrack->layer7.app_data[length+oldlength] =  +			target[length+offset] = - 				/* the kernel version of tolower mungs 'upper ascii' */ - 				isascii(app_data[i])? tolower(app_data[i]) : app_data[i]; + 				isascii(app_data[i])?  + 					tolower(app_data[i]) : app_data[i];   			length++;   		}   	}  +	target[length+offset] = '\0'; ++	 ++	return length; ++}  -	master_conntrack->layer7.app_data[length+oldlength] = '\0';  -	master_conntrack->layer7.app_data_len = length + oldlength; -+	return length; -+} -+  +/* add the new app data to the conntrack.  Return number of bytes added. */ -+static int add_data(struct ip_conntrack * master_conntrack, -+			char * app_data, int appdatalen) ++static int add_data(struct nf_conn * master_conntrack, ++                    char * app_data, int appdatalen)  +{  +	int length; -+ +   +	length = add_datastr(master_conntrack->layer7.app_data, master_conntrack->layer7.app_data_len, app_data, appdatalen);  +	master_conntrack->layer7.app_data_len += length; -    	return length;   } -@@ -343,7 +344,7 @@ +  +@@ -411,7 +413,7 @@ match(const struct sk_buff *skbin, + 	const struct xt_layer7_info * info = matchinfo;   	enum ip_conntrack_info master_ctinfo, ctinfo; - 	struct nf_conn *master_conntrack; - 	struct ip_conntrack *conntrack; + 	struct nf_conn *master_conntrack, *conntrack;  -	unsigned char * app_data;  +	unsigned char *app_data, *tmp_data;   	unsigned int pattern_result, appdatalen;   	regexp * comppattern; -@@ -365,8 +366,8 @@ +@@ -439,8 +441,8 @@ match(const struct sk_buff *skbin,   		master_conntrack = master_ct(master_conntrack);   	/* if we've classified it or seen too many packets */  -	if(TOTAL_PACKETS > num_packets ||  -	   master_conntrack->layer7.app_proto) {  +	if(!info->pkt && (TOTAL_PACKETS > num_packets || -+		master_conntrack->layer7.app_proto)) { -  - 		pattern_result = match_no_append(conntrack, master_conntrack, ctinfo, master_ctinfo, info); ++	   master_conntrack->layer7.app_proto)) { -@@ -396,6 +397,23 @@ + 		pattern_result = match_no_append(conntrack, master_conntrack,  + 						 ctinfo, master_ctinfo, info); +@@ -473,6 +475,25 @@ match(const struct sk_buff *skbin, + 	/* the return value gets checked later, when we're ready to use it */   	comppattern = compile_and_cache(info->pattern, info->protocol); - 	spin_unlock_bh(&list_lock);  +	if (info->pkt) {  +		tmp_data = kmalloc(maxdatalen, GFP_ATOMIC); @@ -99,12 +100,14 @@ Index: linux-2.6.21.5/net/ipv4/netfilter/ipt_layer7.c  +		tmp_data[0] = '\0';  +		add_datastr(tmp_data, 0, app_data, appdatalen);  +		pattern_result = ((comppattern && regexec(comppattern, tmp_data)) ? 1 : 0); ++  +		kfree(tmp_data);  +		tmp_data = NULL; ++		spin_unlock_bh(&l7_lock);  +  +		return (pattern_result ^ info->invert);  +	}  +   	/* On the first packet of a connection, allocate space for app data */ - 	write_lock(&ct_lock); - 	if(TOTAL_PACKETS == 1 && !skb->cb[0] && !master_conntrack->layer7.app_data) { + 	if(TOTAL_PACKETS == 1 && !skb->cb[0] &&  + 	   !master_conntrack->layer7.app_data){ diff --git a/target/linux/generic-2.6/patches/110-ipp2p_0.8.1rc1.patch b/target/linux/generic-2.6/patches/110-ipp2p_0.8.1rc1.patch index 509c5eb16..5f202ca99 100644 --- a/target/linux/generic-2.6/patches/110-ipp2p_0.8.1rc1.patch +++ b/target/linux/generic-2.6/patches/110-ipp2p_0.8.1rc1.patch @@ -1,6 +1,7 @@ -diff -urN linux-2.6.21.1.old/include/linux/netfilter_ipv4/ipt_ipp2p.h linux-2.6.21.1.dev/include/linux/netfilter_ipv4/ipt_ipp2p.h ---- linux-2.6.21.1.old/include/linux/netfilter_ipv4/ipt_ipp2p.h	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/include/linux/netfilter_ipv4/ipt_ipp2p.h	2007-05-26 20:21:54.586864296 +0200 +Index: linux-2.6.21.7/include/linux/netfilter_ipv4/ipt_ipp2p.h +=================================================================== +--- /dev/null ++++ linux-2.6.21.7/include/linux/netfilter_ipv4/ipt_ipp2p.h  @@ -0,0 +1,31 @@  +#ifndef __IPT_IPP2P_H  +#define __IPT_IPP2P_H @@ -33,9 +34,10 @@ diff -urN linux-2.6.21.1.old/include/linux/netfilter_ipv4/ipt_ipp2p.h linux-2.6.  +#define IPP2P_MUTE		(1 << 14)  +#define IPP2P_WASTE		(1 << 15)  +#define IPP2P_XDCC		(1 << 16) -diff -urN linux-2.6.21.1.old/net/ipv4/netfilter/ipt_ipp2p.c linux-2.6.21.1.dev/net/ipv4/netfilter/ipt_ipp2p.c ---- linux-2.6.21.1.old/net/ipv4/netfilter/ipt_ipp2p.c	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/net/ipv4/netfilter/ipt_ipp2p.c	2007-05-26 20:21:54.587864144 +0200 +Index: linux-2.6.21.7/net/ipv4/netfilter/ipt_ipp2p.c +=================================================================== +--- /dev/null ++++ linux-2.6.21.7/net/ipv4/netfilter/ipt_ipp2p.c  @@ -0,0 +1,882 @@  +#if defined(MODVERSIONS)  +#include <linux/modversions.h> @@ -782,7 +784,7 @@ diff -urN linux-2.6.21.1.old/net/ipv4/netfilter/ipt_ipp2p.c linux-2.6.21.1.dev/n  +{  +    const struct ipt_p2p_info *info = matchinfo;  +    unsigned char  *haystack; -+    struct iphdr *ip = skb->nh.iph; ++    struct iphdr *ip = ip_hdr(skb);  +    int p2p_result = 0, i = 0;  +//    int head_len;  +    int hlen = ntohs(ip->tot_len)-(ip->ihl*4);	/*hlen = packet-data length*/ @@ -919,12 +921,13 @@ diff -urN linux-2.6.21.1.old/net/ipv4/netfilter/ipt_ipp2p.c linux-2.6.21.1.dev/n  +module_exit(fini);  +  + -diff -urN linux-2.6.21.1.old/net/ipv4/netfilter/Kconfig linux-2.6.21.1.dev/net/ipv4/netfilter/Kconfig ---- linux-2.6.21.1.old/net/ipv4/netfilter/Kconfig	2007-05-26 20:17:47.626407992 +0200 -+++ linux-2.6.21.1.dev/net/ipv4/netfilter/Kconfig	2007-05-26 20:21:54.587864144 +0200 -@@ -263,6 +263,12 @@ - 	help - 	  Say Y to get lots of debugging output. +Index: linux-2.6.21.7/net/ipv4/netfilter/Kconfig +=================================================================== +--- linux-2.6.21.7.orig/net/ipv4/netfilter/Kconfig ++++ linux-2.6.21.7/net/ipv4/netfilter/Kconfig +@@ -245,6 +245,12 @@ config IP_NF_MATCH_IPRANGE +  + 	  To compile it as a module, choose M here.  If unsure, say N.  +config IP_NF_MATCH_IPP2P  +	tristate "IPP2P" @@ -935,15 +938,15 @@ diff -urN linux-2.6.21.1.old/net/ipv4/netfilter/Kconfig linux-2.6.21.1.dev/net/i   config IP_NF_MATCH_TOS   	tristate "TOS match support"   	depends on IP_NF_IPTABLES -diff -urN linux-2.6.21.1.old/net/ipv4/netfilter/Makefile linux-2.6.21.1.dev/net/ipv4/netfilter/Makefile ---- linux-2.6.21.1.old/net/ipv4/netfilter/Makefile	2007-05-26 20:17:47.638406168 +0200 -+++ linux-2.6.21.1.dev/net/ipv4/netfilter/Makefile	2007-05-26 20:21:54.588863992 +0200 -@@ -91,7 +91,7 @@ +Index: linux-2.6.21.7/net/ipv4/netfilter/Makefile +=================================================================== +--- linux-2.6.21.7.orig/net/ipv4/netfilter/Makefile ++++ linux-2.6.21.7/net/ipv4/netfilter/Makefile +@@ -91,6 +91,7 @@ obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn   obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o   obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o   obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o --  +obj-$(CONFIG_IP_NF_MATCH_IPP2P) += ipt_ipp2p.o - obj-$(CONFIG_IP_NF_MATCH_LAYER7) += ipt_layer7.o   # targets + obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o diff --git a/target/linux/generic-2.6/patches/170-netfilter_chaostables.patch b/target/linux/generic-2.6/patches/170-netfilter_chaostables.patch deleted file mode 100644 index 2c24975f5..000000000 --- a/target/linux/generic-2.6/patches/170-netfilter_chaostables.patch +++ /dev/null @@ -1,946 +0,0 @@ -diff -urN linux-2.6.21.1.old/include/linux/netfilter/oot_conntrack.h linux-2.6.21.1.dev/include/linux/netfilter/oot_conntrack.h ---- linux-2.6.21.1.old/include/linux/netfilter/oot_conntrack.h	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/include/linux/netfilter/oot_conntrack.h	2007-05-26 20:40:10.922195992 +0200 -@@ -0,0 +1,5 @@ -+#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) -+#	include <linux/netfilter_ipv4/ip_conntrack.h> -+#else /* linux-2.6.20+ */ -+#	include <net/netfilter/nf_nat_rule.h> -+#endif -diff -urN linux-2.6.21.1.old/include/linux/netfilter/oot_trans.h linux-2.6.21.1.dev/include/linux/netfilter/oot_trans.h ---- linux-2.6.21.1.old/include/linux/netfilter/oot_trans.h	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/include/linux/netfilter/oot_trans.h	2007-05-26 20:40:10.940193256 +0200 -@@ -0,0 +1,14 @@ -+/* Out of tree workarounds */ -+#include <linux/version.h> -+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) -+#	define HAVE_MATCHINFOSIZE 1 -+#	define HAVE_TARGUSERINFO 1 -+#	define HAVE_TARGINFOSIZE 1 -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) -+#	define nfmark mark -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21) -+#	define tcp_v4_check(tcph, tcph_sz, s, d, csp) \ -+		tcp_v4_check((tcph_sz), (s), (d), (csp)) -+#endif -diff -urN linux-2.6.21.1.old/include/linux/netfilter/xt_CHAOS.h linux-2.6.21.1.dev/include/linux/netfilter/xt_CHAOS.h ---- linux-2.6.21.1.old/include/linux/netfilter/xt_CHAOS.h	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/include/linux/netfilter/xt_CHAOS.h	2007-05-26 20:40:10.940193256 +0200 -@@ -0,0 +1,14 @@ -+#ifndef _LINUX_XT_CHAOS_H -+#define _LINUX_XT_CHAOS_H 1 -+ -+enum xt_chaos_variant { -+	XTCHAOS_NORMAL, -+	XTCHAOS_TARPIT, -+	XTCHAOS_DELUDE, -+}; -+ -+struct xt_chaos_info { -+	enum xt_chaos_variant variant; -+}; -+ -+#endif /* _LINUX_XT_CHAOS_H */ -diff -urN linux-2.6.21.1.old/include/linux/netfilter/xt_portscan.h linux-2.6.21.1.dev/include/linux/netfilter/xt_portscan.h ---- linux-2.6.21.1.old/include/linux/netfilter/xt_portscan.h	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/include/linux/netfilter/xt_portscan.h	2007-05-26 20:40:10.940193256 +0200 -@@ -0,0 +1,8 @@ -+#ifndef _LINUX_XT_PORTSCAN_H -+#define _LINUX_XT_PORTSCAN_H 1 -+ -+struct xt_portscan_info { -+	unsigned int match_stealth, match_syn, match_cn, match_gr; -+}; -+ -+#endif /* _LINUX_XT_PORTSCAN_H */ -diff -urN linux-2.6.21.1.old/net/netfilter/find_match.c linux-2.6.21.1.dev/net/netfilter/find_match.c ---- linux-2.6.21.1.old/net/netfilter/find_match.c	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/net/netfilter/find_match.c	2007-05-26 20:40:10.970188696 +0200 -@@ -0,0 +1,39 @@ -+/* -+    xt_request_find_match -+    by Jan Engelhardt <jengelh [at] gmx de>, 2006 - 2007 -+ -+    Based upon linux-2.6.18.5/net/netfilter/x_tables.c: -+    Copyright (C) 2006-2006 Harald Welte <laforge@netfilter.org> -+    This program is free software; you can redistribute it and/or modify -+    it under the terms of the GNU General Public License version 2 as -+    published by the Free Software Foundation. -+*/ -+#include <linux/err.h> -+#include <linux/netfilter_arp.h> -+#include <linux/socket.h> -+#include <linux/netfilter/x_tables.h> -+ -+/* -+ * Yeah this code is sub-optimal, but the function is missing in -+ * mainline so far. -jengelh -+ */ -+static struct xt_match *xt_request_find_match_lo(int af, const char *name, -+    u8 revision) -+{ -+	static const char *const xt_prefix[] = { -+		[AF_INET]  = "ip", -+		[AF_INET6] = "ip6", -+		[NF_ARP]   = "arp", -+	}; -+	struct xt_match *match; -+ -+	match = try_then_request_module(xt_find_match(af, name, revision), -+		"%st_%s", xt_prefix[af], name); -+	if(IS_ERR(match) || match == NULL) -+		return NULL; -+ -+	return match; -+} -+ -+/* In case it goes into mainline, let this out-of-tree package compile */ -+#define xt_request_find_match xt_request_find_match_lo -diff -urN linux-2.6.21.1.old/net/netfilter/Kconfig linux-2.6.21.1.dev/net/netfilter/Kconfig ---- linux-2.6.21.1.old/net/netfilter/Kconfig	2007-04-27 23:49:26.000000000 +0200 -+++ linux-2.6.21.1.dev/net/netfilter/Kconfig	2007-05-26 20:40:11.003183680 +0200 -@@ -287,6 +287,14 @@ -  - # alphabetically ordered list of targets -  -+config NETFILTER_XT_TARGET_CHAOS -+	tristate '"CHAOS" target support' -+	depends on NETFILTER_XTABLES -+	help -+	  This option adds a `CHAOS' target. -+ -+	  To compile it as a module, choose M here.  If unsure, say N. -+ - config NETFILTER_XT_TARGET_CLASSIFY - 	tristate '"CLASSIFY" target support' - 	depends on NETFILTER_XTABLES -@@ -315,6 +323,14 @@ - 	  <file:Documentation/modules.txt>.  The module will be called - 	  ipt_CONNMARK.o.  If unsure, say `N'. -  -+config NETFILTER_XT_TARGET_DELUDE -+	tristate '"DELUDE" target support' -+	depends on NETFILTER_XTABLES -+	help -+	  This option adds a `DELUDE' target. -+ -+	  To compile it as a module, choose M here.  If unsure, say N. -+ - config NETFILTER_XT_TARGET_DSCP - 	tristate '"DSCP" target support' - 	depends on NETFILTER_XTABLES -@@ -563,6 +579,14 @@ -  - 	  To compile it as a module, choose M here.  If unsure, say N. -  -+config NETFILTER_XT_MATCH_PORTSCAN -+	tristate '"portscan" match support' -+	depends on NETFILTER_XTABLES -+	help -+	  This option adds a 'portscan' match support. -+ -+	  To compile it as a module, choose M here.  If unsure, say N. -+ - config NETFILTER_XT_MATCH_MULTIPORT - 	tristate "Multiple port match support" - 	depends on NETFILTER_XTABLES -diff -urN linux-2.6.21.1.old/net/netfilter/Makefile linux-2.6.21.1.dev/net/netfilter/Makefile ---- linux-2.6.21.1.old/net/netfilter/Makefile	2007-04-27 23:49:26.000000000 +0200 -+++ linux-2.6.21.1.dev/net/netfilter/Makefile	2007-05-26 20:40:11.003183680 +0200 -@@ -37,8 +37,10 @@ - obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o -  - # targets -+obj-$(CONFIG_NETFILTER_XT_TARGET_CHAOS) += xt_CHAOS.o - obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o - obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o -+obj-$(CONFIG_NETFILTER_XT_TARGET_DELUDE) += xt_DELUDE.o - obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o - obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o - obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o -@@ -63,6 +65,7 @@ - obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o - obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o - obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o -+obj-$(CONFIG_NETFILTER_XT_MATCH_PORTSCAN) += xt_portscan.o - obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o - obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o - obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o -diff -urN linux-2.6.21.1.old/net/netfilter/xt_CHAOS.c linux-2.6.21.1.dev/net/netfilter/xt_CHAOS.c ---- linux-2.6.21.1.old/net/netfilter/xt_CHAOS.c	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/net/netfilter/xt_CHAOS.c	2007-05-26 20:40:11.004183528 +0200 -@@ -0,0 +1,204 @@ -+/* -+	CHAOS target for netfilter -+ -+	Copyright © Jan Engelhardt <jengelh [at] gmx de>, 2006 - 2007 -+	This program is free software; you can redistribute it and/or modify -+	it under the terms of the GNU General Public License version 2 as -+	published by the Free Software Foundation. -+*/ -+#include <linux/icmp.h> -+#include <linux/in.h> -+#include <linux/ip.h> -+#include <linux/module.h> -+#include <linux/skbuff.h> -+#include <linux/stat.h> -+#include <linux/netfilter/x_tables.h> -+#include <linux/netfilter/xt_tcpudp.h> -+#include <linux/netfilter_ipv4/ipt_REJECT.h> -+#include <net/ip.h> -+#include <linux/netfilter/xt_CHAOS.h> -+#include "find_match.c" -+#include <linux/netfilter/oot_trans.h> -+#define PFX KBUILD_MODNAME ": " -+ -+/* Module parameters */ -+static unsigned int reject_percentage = ~0U * .01; -+static unsigned int delude_percentage = ~0U * .0101; -+module_param(reject_percentage, uint, S_IRUGO | S_IWUSR); -+module_param(delude_percentage, uint, S_IRUGO | S_IWUSR); -+ -+/* References to other matches/targets */ -+static struct xt_match *xm_tcp; -+static struct xt_target *xt_delude, *xt_reject, *xt_tarpit; -+ -+static int have_delude, have_tarpit; -+ -+/* Static data for other matches/targets */ -+static const struct ipt_reject_info reject_params = { -+	.with = ICMP_HOST_UNREACH, -+}; -+ -+static const struct xt_tcp tcp_params = { -+	.spts = {0, ~0}, -+	.dpts = {0, ~0}, -+}; -+ -+/* CHAOS functions */ -+static void xt_chaos_total(const struct xt_chaos_info *info, -+    struct sk_buff **pskb, const struct net_device *in, -+    const struct net_device *out, unsigned int hooknum) -+{ -+	const int protoff = 4 * (*pskb)->nh.iph->ihl; -+	const int offset  = ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET; -+	const struct xt_target *destiny; -+	int hotdrop = 0, ret; -+ -+	ret = xm_tcp->match(*pskb, in, out, xm_tcp, &tcp_params, -+	                    offset, protoff, &hotdrop); -+	if(!ret || hotdrop || (unsigned int)net_random() > delude_percentage) -+		return; -+ -+	destiny = (info->variant == XTCHAOS_TARPIT) ? xt_tarpit : xt_delude; -+#ifdef HAVE_TARGUSERINFO -+	destiny->target(pskb, in, out, hooknum, destiny, NULL, NULL); -+#else -+	destiny->target(pskb, in, out, hooknum, destiny, NULL); -+#endif -+	return; -+} -+ -+static unsigned int xt_chaos_target(struct sk_buff **pskb, -+    const struct net_device *in, const struct net_device *out, -+    unsigned int hooknum, const struct xt_target *target, const void *targinfo -+#ifdef HAVE_TARGUSERINFO -+    , -+    void *userinfo -+#endif -+    ) -+{ -+	/* Equivalent to: -+	 * -A chaos -m statistic --mode random --probability \ -+	 *         $reject_percentage -j REJECT --reject-with host-unreach; -+	 * -A chaos -p tcp -m statistic --mode random --probability \ -+	 *         $delude_percentage -j DELUDE; -+	 * -A chaos -j DROP; -+	 */ -+	const struct xt_chaos_info *info = targinfo; -+ -+	if((unsigned int)net_random() <= reject_percentage) -+#ifdef HAVE_TARGUSERINFO -+		return xt_reject->target(pskb, in, out, hooknum, target, -+		       &reject_params, userinfo); -+#else -+		return xt_reject->target(pskb, in, out, hooknum, target, -+		       &reject_params); -+#endif -+ -+	/* TARPIT/DELUDE may not be called from the OUTPUT chain */ -+	if((*pskb)->nh.iph->protocol == IPPROTO_TCP && -+	  info->variant != XTCHAOS_NORMAL && hooknum != NF_IP_LOCAL_OUT) -+		xt_chaos_total(info, pskb, in, out, hooknum); -+ -+	return NF_DROP; -+} -+ -+static int xt_chaos_checkentry(const char *tablename, const void *entry, -+    const struct xt_target *target, void *targinfo, -+#ifdef HAVE_TARGINFOSIZE -+    unsigned int targinfosize, -+#endif -+    unsigned int hook_mask) -+{ -+	const struct xt_chaos_info *info = targinfo; -+	if(info->variant == XTCHAOS_DELUDE && !have_delude) { -+		printk(KERN_WARNING PFX "Error: Cannot use --delude when " -+		       "DELUDE module not available\n"); -+		return 0; -+	} -+	if(info->variant == XTCHAOS_TARPIT && !have_tarpit) { -+		printk(KERN_WARNING PFX "Error: Cannot use --tarpit when " -+		       "TARPIT module not available\n"); -+		return 0; -+	} -+	return 1; -+} -+ -+static struct xt_target xt_chaos_info = { -+	.name       = "CHAOS", -+	.target     = xt_chaos_target, -+	.checkentry = xt_chaos_checkentry, -+	.table      = "filter", -+	.targetsize = sizeof(struct xt_chaos_info), -+	.hooks      = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | -+	              (1 << NF_IP_LOCAL_OUT), -+	.family     = AF_INET, -+	.me         = THIS_MODULE, -+}; -+ -+static int __init xt_chaos_init(void) -+{ -+	int ret = -EINVAL; -+ -+	xm_tcp = xt_request_find_match(AF_INET, "tcp", 0); -+	if(xm_tcp == NULL) { -+		printk(KERN_WARNING PFX "Error: Could not find or load " -+		       "\"tcp\" match\n"); -+		return -EINVAL; -+	} -+ -+	xt_reject = xt_request_find_target(AF_INET, "REJECT", 0); -+	if(xt_reject == NULL) { -+		printk(KERN_WARNING PFX "Error: Could not find or load " -+		       "\"REJECT\" target\n"); -+		goto out2; -+	} -+ -+	xt_tarpit   = xt_request_find_target(AF_INET, "TARPIT", 0); -+	have_tarpit = xt_tarpit != NULL; -+	if(!have_tarpit) -+		printk(KERN_WARNING PFX "Warning: Could not find or load " -+		       "\"TARPIT\" target\n"); -+ -+	xt_delude   = xt_request_find_target(AF_INET, "DELUDE", 0); -+	have_delude = xt_delude != NULL; -+	if(!have_delude) -+		printk(KERN_WARNING PFX "Warning: Could not find or load " -+		       "\"DELUDE\" target\n"); -+ -+	if((ret = xt_register_target(&xt_chaos_info)) != 0) { -+		printk(KERN_WARNING PFX "xt_register_target returned " -+		       "error %d\n", ret); -+		goto out3; -+	} -+ -+	return 0; -+ -+ out3: -+ 	if(have_delude) -+ 		module_put(xt_delude->me); -+	if(have_tarpit) -+		module_put(xt_tarpit->me); -+	module_put(xt_reject->me); -+ out2: -+	module_put(xm_tcp->me); -+	return ret; -+} -+ -+static void __exit xt_chaos_exit(void) -+{ -+	xt_unregister_target(&xt_chaos_info); -+	module_put(xm_tcp->me); -+	module_put(xt_reject->me); -+	if(have_delude) -+		module_put(xt_delude->me); -+	if(have_tarpit) -+		module_put(xt_tarpit->me); -+	return; -+} -+ -+module_init(xt_chaos_init); -+module_exit(xt_chaos_exit); -+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>"); -+MODULE_DESCRIPTION("netfilter CHAOS target"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("ipt_CHAOS"); -diff -urN linux-2.6.21.1.old/net/netfilter/xt_DELUDE.c linux-2.6.21.1.dev/net/netfilter/xt_DELUDE.c ---- linux-2.6.21.1.old/net/netfilter/xt_DELUDE.c	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/net/netfilter/xt_DELUDE.c	2007-05-26 20:40:11.004183528 +0200 -@@ -0,0 +1,288 @@ -+/* -+	DELUDE target -+	Copyright © Jan Engelhardt <jengelh [at] gmx de>, 2007 -+ -+	Based upon linux-2.6.18.5/net/ipv4/netfilter/ipt_REJECT.c: -+	(C) 1999-2001 Paul `Rusty' Russell -+	(C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> -+ -+	xt_DELUDE acts like REJECT, but does reply with SYN-ACK on SYN. -+ -+	This program is free software; you can redistribute it and/or modify -+	it under the terms of the GNU General Public License version 2 as -+	published by the Free Software Foundation. -+*/ -+#include <linux/module.h> -+#include <linux/skbuff.h> -+#include <linux/ip.h> -+#include <linux/random.h> -+#include <linux/tcp.h> -+#include <linux/udp.h> -+#include <linux/icmp.h> -+#include <net/icmp.h> -+#include <net/ip.h> -+#include <net/tcp.h> -+#include <net/route.h> -+#include <net/dst.h> -+#include <linux/netfilter_ipv4/ip_tables.h> -+#ifdef CONFIG_BRIDGE_NETFILTER -+#	include <linux/netfilter_bridge.h> -+#endif -+#include <linux/netfilter/oot_trans.h> -+#define PFX KBUILD_MODNAME ": " -+ -+static inline struct rtable *route_reverse(struct sk_buff *skb, -+					   struct tcphdr *tcph, int hook) -+{ -+	struct iphdr *iph = skb->nh.iph; -+	struct dst_entry *odst; -+	struct flowi fl = {}; -+	struct rtable *rt; -+ -+	/* We don't require ip forwarding to be enabled to be able to -+	 * send a RST reply for bridged traffic. */ -+	if (hook != NF_IP_FORWARD -+#ifdef CONFIG_BRIDGE_NETFILTER -+	    || (skb->nf_bridge && skb->nf_bridge->mask & BRNF_BRIDGED) -+#endif -+	   ) { -+		fl.nl_u.ip4_u.daddr = iph->saddr; -+		if (hook == NF_IP_LOCAL_IN) -+			fl.nl_u.ip4_u.saddr = iph->daddr; -+		fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); -+ -+		if (ip_route_output_key(&rt, &fl) != 0) -+			return NULL; -+	} else { -+		/* non-local src, find valid iif to satisfy -+		 * rp-filter when calling ip_route_input. */ -+		fl.nl_u.ip4_u.daddr = iph->daddr; -+		if (ip_route_output_key(&rt, &fl) != 0) -+			return NULL; -+ -+		odst = skb->dst; -+		if (ip_route_input(skb, iph->saddr, iph->daddr, -+		                   RT_TOS(iph->tos), rt->u.dst.dev) != 0) { -+			dst_release(&rt->u.dst); -+			return NULL; -+		} -+		dst_release(&rt->u.dst); -+		rt = (struct rtable *)skb->dst; -+		skb->dst = odst; -+ -+		fl.nl_u.ip4_u.daddr = iph->saddr; -+		fl.nl_u.ip4_u.saddr = iph->daddr; -+		fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); -+	} -+ -+	if (rt->u.dst.error) { -+		dst_release(&rt->u.dst); -+		return NULL; -+	} -+ -+	fl.proto = IPPROTO_TCP; -+	fl.fl_ip_sport = tcph->dest; -+	fl.fl_ip_dport = tcph->source; -+ -+	xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0); -+ -+	return rt; -+} -+ -+static void send_reset(struct sk_buff *oldskb, int hook) -+{ -+	struct sk_buff *nskb; -+	struct iphdr *iph = oldskb->nh.iph; -+	struct tcphdr _otcph, *oth, *tcph; -+	__be16 tmp_port; -+	__be32 tmp_addr; -+	int needs_ack; -+	unsigned int addr_type; -+ -+	/* IP header checks: fragment. */ -+	if (oldskb->nh.iph->frag_off & htons(IP_OFFSET)) -+		return; -+ -+	oth = skb_header_pointer(oldskb, oldskb->nh.iph->ihl * 4, -+				 sizeof(_otcph), &_otcph); -+	if (oth == NULL) -+		return; -+ -+	/* No RST for RST. */ -+	if (oth->rst) -+		return; -+ -+	/* Check checksum */ -+	if (nf_ip_checksum(oldskb, hook, iph->ihl * 4, IPPROTO_TCP)) -+		return; -+ -+	/* We need a linear, writeable skb.  We also need to expand -+	   headroom in case hh_len of incoming interface < hh_len of -+	   outgoing interface */ -+	nskb = skb_copy_expand(oldskb, LL_MAX_HEADER, skb_tailroom(oldskb), -+			       GFP_ATOMIC); -+	if (!nskb) -+		return; -+ -+	/* This packet will not be the same as the other: clear nf fields */ -+	nf_reset(nskb); -+	nskb->nfmark = 0; -+	skb_init_secmark(nskb); -+ -+	skb_shinfo(nskb)->gso_size = 0; -+	skb_shinfo(nskb)->gso_segs = 0; -+	skb_shinfo(nskb)->gso_type = 0; -+ -+	tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl); -+ -+	/* Swap source and dest */ -+	tmp_addr = nskb->nh.iph->saddr; -+	nskb->nh.iph->saddr = nskb->nh.iph->daddr; -+	nskb->nh.iph->daddr = tmp_addr; -+	tmp_port = tcph->source; -+	tcph->source = tcph->dest; -+	tcph->dest = tmp_port; -+ -+	/* Truncate to length (no data) */ -+	tcph->doff = sizeof(struct tcphdr)/4; -+	skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr)); -+	nskb->nh.iph->tot_len = htons(nskb->len); -+ -+	if(oth->syn && !oth->ack && !oth->rst && !oth->fin) { -+		/* DELUDE essential part */ -+		tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin + -+		                oldskb->len - oldskb->nh.iph->ihl * 4 - -+		                (oth->doff << 2)); -+		tcph->seq     = htonl(secure_tcp_sequence_number( -+		                nskb->nh.iph->saddr, nskb->nh.iph->daddr, -+			        tcph->source, tcph->dest)); -+		tcph->ack     = 1; -+	} else { -+		if(!tcph->ack) { -+			needs_ack = 1; -+			tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin -+					      + oldskb->len - oldskb->nh.iph->ihl*4 -+					      - (oth->doff<<2)); -+			tcph->seq = 0; -+		} else { -+			needs_ack = 0; -+			tcph->seq = oth->ack_seq; -+			tcph->ack_seq = 0; -+		} -+ -+		/* Reset flags */ -+		((u_int8_t *)tcph)[13] = 0; -+		tcph->rst = 1; -+		tcph->ack = needs_ack; -+	} -+ -+ -+	tcph->window = 0; -+	tcph->urg_ptr = 0; -+ -+	/* Adjust TCP checksum */ -+	tcph->check = 0; -+	tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr), -+				   nskb->nh.iph->saddr, -+				   nskb->nh.iph->daddr, -+				   csum_partial((char *)tcph, -+						sizeof(struct tcphdr), 0)); -+ -+	/* Set DF, id = 0 */ -+	nskb->nh.iph->frag_off = htons(IP_DF); -+	nskb->nh.iph->id = 0; -+ -+	addr_type = RTN_UNSPEC; -+	if (hook != NF_IP_FORWARD -+#ifdef CONFIG_BRIDGE_NETFILTER -+	    || (nskb->nf_bridge && nskb->nf_bridge->mask & BRNF_BRIDGED) -+#endif -+	   ) -+		addr_type = RTN_LOCAL; -+ -+	if (ip_route_me_harder(&nskb, addr_type)) -+		goto free_nskb; -+ -+	nskb->ip_summed = CHECKSUM_NONE; -+ -+	/* Adjust IP TTL */ -+	nskb->nh.iph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); -+ -+	/* Adjust IP checksum */ -+	nskb->nh.iph->check = 0; -+	nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph, -+					   nskb->nh.iph->ihl); -+ -+	/* "Never happens" */ -+	if (nskb->len > dst_mtu(nskb->dst)) -+		goto free_nskb; -+ -+	nf_ct_attach(nskb, oldskb); -+ -+	NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev, -+		dst_output); -+	return; -+ -+ free_nskb: -+	kfree_skb(nskb); -+} -+ -+static unsigned int xt_delude_target(struct sk_buff **pskb, -+    const struct net_device *in, const struct net_device *out, -+    unsigned int hooknum, const struct xt_target *target, const void *targinfo -+#ifdef HAVE_TARGUSERINFO -+    , -+    void *userinfo -+#endif -+    ) -+{ -+	/* WARNING: This code causes reentry within iptables. -+	   This means that the iptables jump stack is now crap.  We -+	   must return an absolute verdict. --RR */ -+	send_reset(*pskb, hooknum); -+	return NF_DROP; -+} -+ -+static int xt_delude_check(const char *tablename, const void *e_void, -+    const struct xt_target *target, void *targinfo, -+#ifdef HAVE_TARGINFOSIZE -+    unsigned int targinfosize, -+#endif -+    unsigned int hook_mask) -+{ -+	if(hook_mask & ~((1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD))) { -+		printk(KERN_WARNING PFX "DELUDE may not be used in chains " -+		       "other than INPUT and FORWARD\n"); -+		return 0; -+	} -+	return 1; -+} -+ -+static struct xt_target xt_delude_info = { -+	.name       = "DELUDE", -+	.target     = xt_delude_target, -+	.checkentry = xt_delude_check, -+	.table      = "filter", -+	.hooks      = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | -+	              (1 << NF_IP_LOCAL_OUT), -+	.proto      = IPPROTO_TCP, -+	.family     = AF_INET, -+	.me         = THIS_MODULE, -+}; -+ -+static int __init xt_delude_init(void) -+{ -+	return xt_register_target(&xt_delude_info); -+} -+ -+static void __exit xt_delude_exit(void) -+{ -+	xt_unregister_target(&xt_delude_info); -+} -+ -+module_init(xt_delude_init); -+module_exit(xt_delude_exit); -+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>"); -+MODULE_DESCRIPTION("netfilter DELUDE target"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("ipt_DELUDE"); -diff -urN linux-2.6.21.1.old/net/netfilter/xt_portscan.c linux-2.6.21.1.dev/net/netfilter/xt_portscan.c ---- linux-2.6.21.1.old/net/netfilter/xt_portscan.c	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.21.1.dev/net/netfilter/xt_portscan.c	2007-05-26 20:40:11.004183528 +0200 -@@ -0,0 +1,272 @@ -+/* -+	portscan match for netfilter -+ -+	Written by Jan Engelhardt, 2006 - 2007 -+	This program is free software; you can redistribute it and/or modify -+	it under the terms of the GNU General Public License version 2 as -+	published by the Free Software Foundation. -+*/ -+#include <linux/in.h> -+#include <linux/ip.h> -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/skbuff.h> -+#include <linux/stat.h> -+#include <linux/tcp.h> -+#include <linux/types.h> -+#include <linux/version.h> -+#include <linux/netfilter/x_tables.h> -+#include <linux/netfilter/xt_tcpudp.h> -+#include <linux/netfilter/oot_conntrack.h> -+#include <linux/netfilter/xt_portscan.h> -+#include <linux/netfilter/oot_trans.h> -+#define PFX KBUILD_MODNAME ": " -+ -+enum { -+	TCP_FLAGS_ALL3 = TCP_FLAG_FIN | TCP_FLAG_RST | TCP_FLAG_SYN, -+	TCP_FLAGS_ALL4 = TCP_FLAGS_ALL3 | TCP_FLAG_ACK, -+	TCP_FLAGS_ALL6 = TCP_FLAGS_ALL4 | TCP_FLAG_PSH | TCP_FLAG_URG, -+}; -+ -+/* Module parameters */ -+static unsigned int -+	connmark_mask = ~0, -+	packet_mask   = ~0, -+	mark_seen     = 0x9, -+	mark_synrcv   = 0x1, -+	mark_closed   = 0x2, -+	mark_synscan  = 0x3, -+	mark_estab1   = 0x4, -+	mark_estab2   = 0x5, -+	mark_cnscan   = 0x6, -+	mark_grscan   = 0x7, -+	mark_valid    = 0x8; -+ -+module_param(connmark_mask, uint, S_IRUGO | S_IWUSR); -+module_param(packet_mask,   uint, S_IRUGO | S_IWUSR); -+module_param(mark_seen,     uint, S_IRUGO | S_IWUSR); -+module_param(mark_synrcv,   uint, S_IRUGO | S_IWUSR); -+module_param(mark_closed,   uint, S_IRUGO | S_IWUSR); -+module_param(mark_synscan,  uint, S_IRUGO | S_IWUSR); -+module_param(mark_estab1,   uint, S_IRUGO | S_IWUSR); -+module_param(mark_estab2,   uint, S_IRUGO | S_IWUSR); -+module_param(mark_cnscan,   uint, S_IRUGO | S_IWUSR); -+module_param(mark_grscan,   uint, S_IRUGO | S_IWUSR); -+module_param(mark_valid,    uint, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(connmark_mask, "only set specified bits in connection mark"); -+MODULE_PARM_DESC(packet_mask,   "only set specified bits in packet mark"); -+MODULE_PARM_DESC(mark_seen,     "nfmark value for packet-seen state"); -+MODULE_PARM_DESC(mark_synrcv,   "connmark value for SYN Received state"); -+MODULE_PARM_DESC(mark_closed,   "connmark value for closed state"); -+MODULE_PARM_DESC(mark_synscan,  "connmark value for SYN Scan state"); -+MODULE_PARM_DESC(mark_estab1,   "connmark value for Established-1 state"); -+MODULE_PARM_DESC(mark_estab2,   "connmark value for Established-2 state"); -+MODULE_PARM_DESC(mark_cnscan,   "connmark value for Connect Scan state"); -+MODULE_PARM_DESC(mark_grscan,   "connmark value for Grab Scan state"); -+MODULE_PARM_DESC(mark_valid,    "connmark value for Valid state"); -+ -+/* TCP flag functions */ -+static inline int tflg_ack4(const struct tcphdr *th) -+{ -+	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_ACK; -+} -+ -+static inline int tflg_ack6(const struct tcphdr *th) -+{ -+	return (tcp_flag_word(th) & TCP_FLAGS_ALL6) == TCP_FLAG_ACK; -+} -+ -+static inline int tflg_fin(const struct tcphdr *th) -+{ -+	return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_FIN; -+} -+ -+static inline int tflg_rst(const struct tcphdr *th) -+{ -+	return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_RST; -+} -+ -+static inline int tflg_rstack(const struct tcphdr *th) -+{ -+	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == -+	       (TCP_FLAG_ACK | TCP_FLAG_RST); -+} -+ -+static inline int tflg_syn(const struct tcphdr *th) -+{ -+	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_SYN; -+} -+ -+static inline int tflg_synack(const struct tcphdr *th) -+{ -+	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == -+	       (TCP_FLAG_SYN | TCP_FLAG_ACK); -+} -+ -+/* portscan functions */ -+static inline int xt_portscan_stealth(const struct tcphdr *th) -+{ -+	/* -+	 * "Connection refused" replies to our own probes must not be matched. -+	 */ -+	if(tflg_rstack(th)) -+		return 0; -+ -+	if(tflg_rst(th) && printk_ratelimit()) { -+		printk(KERN_WARNING PFX "Warning: Pure RST received\n"); -+		return 0; -+	} -+ -+	/* -+	 * -p tcp ! --syn -m conntrack --ctstate INVALID: Looking for non-start -+	 * packets that are not associated with any connection -- this will -+	 * match most scan types (NULL, XMAS, FIN) and ridiculous flag -+	 * combinations (SYN-RST, SYN-FIN, SYN-FIN-RST, FIN-RST, etc.). -+	 */ -+	return !tflg_syn(th); -+} -+ -+static inline int xt_portscan_full(int mark, enum ip_conntrack_info ctstate, -+    int loopback, const struct tcphdr *tcph, int payload_len) -+{ -+	if(mark == mark_estab2) { -+		/* -+		 * -m connmark --mark $ESTAB2 -+		 */ -+		if(tflg_ack4(tcph) && payload_len == 0) -+			return mark; /* keep mark */ -+		else if(tflg_rst(tcph) || tflg_fin(tcph)) -+			return mark_grscan; -+		else -+			return mark_valid; -+	} else if(mark == mark_estab1) { -+		/* -+		 * -m connmark --mark $ESTAB1 -+		 */ -+		if(tflg_rst(tcph) || tflg_fin(tcph)) -+			return mark_cnscan; -+		else if(!loopback && tflg_ack4(tcph) && payload_len == 0) -+			return mark_estab2; -+		else -+			return mark_valid; -+	} else if(mark == mark_synrcv) { -+		/* -+		 * -m connmark --mark $SYN -+		 */ -+		if(loopback && tflg_synack(tcph)) -+			return mark; /* keep mark */ -+		else if(loopback && tflg_rstack(tcph)) -+			return mark_closed; -+		else if(tflg_ack6(tcph)) -+			return mark_estab1; -+		else -+			return mark_synscan; -+	} else if(ctstate == IP_CT_NEW && tflg_syn(tcph)) { -+		/* -+		 * -p tcp --syn --ctstate NEW -+		 */ -+		return mark_synrcv; -+	} -+	return mark; -+} -+ -+static int xt_portscan_match(const struct sk_buff *skb, -+    const struct net_device *in, const struct net_device *out, -+    const struct xt_match *match, const void *matchinfo, int offset, -+    unsigned int protoff, int *hotdrop) -+{ -+	const struct xt_portscan_info *info = matchinfo; -+	enum ip_conntrack_info ctstate; -+	struct ip_conntrack *ctdata; -+	const struct tcphdr *tcph; -+	struct tcphdr tcph_buf; -+ -+	tcph = skb_header_pointer(skb, protoff, sizeof(tcph_buf), &tcph_buf); -+	if(tcph == NULL) -+		return 0; -+ -+	/* Check for invalid packets: -m conntrack --ctstate INVALID */ -+	if((ctdata = ip_conntrack_get(skb, &ctstate)) == NULL) { -+		if(info->match_stealth) -+			return xt_portscan_stealth(tcph); -+		/* -+		 * If @ctdata is NULL, we cannot match the other scan -+		 * types, return. -+		 */ -+		return 0; -+	} -+ -+	/* -+	 * If -m portscan was previously applied to this packet, the rules we -+	 * simulate must not be run through again. And for speedup, do not call -+	 * it either when the connection is already VALID. -+	 */ -+	if((ctdata->mark & connmark_mask) == mark_valid || -+	  (skb->nfmark & packet_mask) != mark_seen) -+	{ -+		unsigned int n; -+		n = xt_portscan_full(ctdata->mark & connmark_mask, ctstate, -+		    in == &loopback_dev, tcph, -+		    skb->len - protoff - 4 * tcph->doff); -+ -+		ctdata->mark = (ctdata->mark & ~connmark_mask) | n; -+		((struct sk_buff *)skb)->nfmark = -+			(skb->nfmark & ~packet_mask) | mark_seen; -+	} -+ -+	return (info->match_syn && ctdata->mark == mark_synscan) || -+	       (info->match_cn && ctdata->mark == mark_cnscan) || -+	       (info->match_gr && ctdata->mark == mark_grscan); -+} -+ -+static int xt_portscan_checkentry(const char *tablename, const void *entry, -+    const struct xt_match *match, void *matchinfo, -+#ifdef HAVE_MATCHINFOSIZE -+    unsigned int matchinfosize, -+#endif -+    unsigned int hook_mask) -+{ -+	const struct xt_portscan_info *info = matchinfo; -+#ifdef HAVE_MATCHINFOSIZE -+	if(matchinfosize != XT_ALIGN(sizeof(struct xt_portscan_info))) { -+		printk(KERN_WARNING PFX "matchinfosize %u != %Zu\n", -+		       matchinfosize, -+		       XT_ALIGN(sizeof(struct xt_portscan_info))); -+		return 0; -+	} -+#endif -+	if((info->match_stealth & ~1) || (info->match_syn & ~1) || -+	  (info->match_cn & ~1) || (info->match_gr & ~1)) { -+		printk(KERN_WARNING PFX "Invalid flags\n"); -+		return 0; -+	} -+	return 1; -+} -+ -+static struct xt_match xt_portscan = { -+	.name       = "portscan", -+	.match      = xt_portscan_match, -+	.checkentry = xt_portscan_checkentry, -+	.matchsize  = sizeof(struct xt_portscan_info), -+	.proto      = IPPROTO_TCP, -+	.family     = AF_INET, -+	.me         = THIS_MODULE, -+}; -+ -+static int __init xt_portscan_init(void) -+{ -+	return xt_register_match(&xt_portscan); -+} -+ -+static void __exit xt_portscan_exit(void) -+{ -+	xt_unregister_match(&xt_portscan); -+	return; -+} -+ -+module_init(xt_portscan_init); -+module_exit(xt_portscan_exit); -+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>"); -+MODULE_DESCRIPTION("netfilter portscan match module"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("ipt_portscan"); diff --git a/target/linux/generic-2.6/patches/170-netfilter_chaostables_0.8.patch b/target/linux/generic-2.6/patches/170-netfilter_chaostables_0.8.patch new file mode 100644 index 000000000..063bcf1e6 --- /dev/null +++ b/target/linux/generic-2.6/patches/170-netfilter_chaostables_0.8.patch @@ -0,0 +1,853 @@ +Index: linux-2.6.21.7/include/linux/netfilter/oot_conntrack.h +=================================================================== +--- /dev/null ++++ linux-2.6.21.7/include/linux/netfilter/oot_conntrack.h +@@ -0,0 +1,5 @@ ++#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) ++#	include <linux/netfilter_ipv4/ip_conntrack.h> ++#else /* linux-2.6.20+ */ ++#	include <net/netfilter/nf_nat_rule.h> ++#endif +Index: linux-2.6.21.7/include/linux/netfilter/oot_trans.h +=================================================================== +--- /dev/null ++++ linux-2.6.21.7/include/linux/netfilter/oot_trans.h +@@ -0,0 +1,14 @@ ++/* Out of tree workarounds */ ++#include <linux/version.h> ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) ++#	define HAVE_MATCHINFOSIZE 1 ++#	define HAVE_TARGUSERINFO 1 ++#	define HAVE_TARGINFOSIZE 1 ++#endif ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) ++#	define nfmark mark ++#endif ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21) ++#	define tcp_v4_check(tcph, tcph_sz, s, d, csp) \ ++		tcp_v4_check((tcph_sz), (s), (d), (csp)) ++#endif +Index: linux-2.6.21.7/include/linux/netfilter/xt_CHAOS.h +=================================================================== +--- /dev/null ++++ linux-2.6.21.7/include/linux/netfilter/xt_CHAOS.h +@@ -0,0 +1,14 @@ ++#ifndef _LINUX_NETFILTER_XT_CHAOS_H ++#define _LINUX_NETFILTER_XT_CHAOS_H 1 ++ ++enum xt_chaos_target_variant { ++	XTCHAOS_NORMAL, ++	XTCHAOS_TARPIT, ++	XTCHAOS_DELUDE, ++}; ++ ++struct xt_chaos_target_info { ++	uint8_t variant; ++}; ++ ++#endif /* _LINUX_NETFILTER_XT_CHAOS_H */ +Index: linux-2.6.21.7/include/linux/netfilter/xt_portscan.h +=================================================================== +--- /dev/null ++++ linux-2.6.21.7/include/linux/netfilter/xt_portscan.h +@@ -0,0 +1,8 @@ ++#ifndef _LINUX_NETFILTER_XT_PORTSCAN_H ++#define _LINUX_NETFILTER_XT_PORTSCAN_H 1 ++ ++struct xt_portscan_match_info { ++	uint8_t match_stealth, match_syn, match_cn, match_gr; ++}; ++ ++#endif /* _LINUX_NETFILTER_XT_PORTSCAN_H */ +Index: linux-2.6.21.7/net/netfilter/find_match.c +=================================================================== +--- /dev/null ++++ linux-2.6.21.7/net/netfilter/find_match.c +@@ -0,0 +1,39 @@ ++/* ++    xt_request_find_match ++    by Jan Engelhardt <jengelh [at] gmx de>, 2006 - 2007 ++ ++    Based upon linux-2.6.18.5/net/netfilter/x_tables.c: ++    Copyright (C) 2006-2006 Harald Welte <laforge@netfilter.org> ++    This program is free software; you can redistribute it and/or modify ++    it under the terms of the GNU General Public License version 2 as ++    published by the Free Software Foundation. ++*/ ++#include <linux/err.h> ++#include <linux/netfilter_arp.h> ++#include <linux/socket.h> ++#include <linux/netfilter/x_tables.h> ++ ++/* ++ * Yeah this code is sub-optimal, but the function is missing in ++ * mainline so far. -jengelh ++ */ ++static struct xt_match *xt_request_find_match_lo(int af, const char *name, ++    u8 revision) ++{ ++	static const char *const xt_prefix[] = { ++		[AF_INET]  = "ip", ++		[AF_INET6] = "ip6", ++		[NF_ARP]   = "arp", ++	}; ++	struct xt_match *match; ++ ++	match = try_then_request_module(xt_find_match(af, name, revision), ++		"%st_%s", xt_prefix[af], name); ++	if (IS_ERR(match) || match == NULL) ++		return NULL; ++ ++	return match; ++} ++ ++/* In case it goes into mainline, let this out-of-tree package compile */ ++#define xt_request_find_match xt_request_find_match_lo +Index: linux-2.6.21.7/net/netfilter/Kconfig +=================================================================== +--- linux-2.6.21.7.orig/net/netfilter/Kconfig ++++ linux-2.6.21.7/net/netfilter/Kconfig +@@ -287,6 +287,14 @@ config NETFILTER_XTABLES +  + # alphabetically ordered list of targets +  ++config NETFILTER_XT_TARGET_CHAOS ++	tristate '"CHAOS" target support' ++	depends on NETFILTER_XTABLES ++	help ++	  This option adds a `CHAOS' target. ++ ++	  To compile it as a module, choose M here.  If unsure, say N. ++ + config NETFILTER_XT_TARGET_CLASSIFY + 	tristate '"CLASSIFY" target support' + 	depends on NETFILTER_XTABLES +@@ -315,6 +323,14 @@ config NETFILTER_XT_TARGET_CONNMARK + 	  <file:Documentation/modules.txt>.  The module will be called + 	  ipt_CONNMARK.o.  If unsure, say `N'. +  ++config NETFILTER_XT_TARGET_DELUDE ++	tristate '"DELUDE" target support' ++	depends on NETFILTER_XTABLES ++	help ++	  This option adds a `DELUDE' target. ++ ++	  To compile it as a module, choose M here.  If unsure, say N. ++ + config NETFILTER_XT_TARGET_DSCP + 	tristate '"DSCP" target support' + 	depends on NETFILTER_XTABLES +@@ -563,6 +579,14 @@ config NETFILTER_XT_MATCH_POLICY +  + 	  To compile it as a module, choose M here.  If unsure, say N. +  ++config NETFILTER_XT_MATCH_PORTSCAN ++	tristate '"portscan" match support' ++	depends on NETFILTER_XTABLES ++	help ++	  This option adds a 'portscan' match support. ++ ++	  To compile it as a module, choose M here.  If unsure, say N. ++ + config NETFILTER_XT_MATCH_MULTIPORT + 	tristate "Multiple port match support" + 	depends on NETFILTER_XTABLES +Index: linux-2.6.21.7/net/netfilter/Makefile +=================================================================== +--- linux-2.6.21.7.orig/net/netfilter/Makefile ++++ linux-2.6.21.7/net/netfilter/Makefile +@@ -47,6 +47,8 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK + obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o + obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o + obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o ++obj-$(CONFIG_NETFILTER_XT_TARGET_CHAOS) += xt_CHAOS.o ++obj-$(CONFIG_NETFILTER_XT_TARGET_DELUDE) += xt_DELUDE.o +  + # matches + obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o +@@ -74,3 +76,4 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_STRING)  + obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o + obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o + obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o ++obj-$(CONFIG_NETFILTER_XT_MATCH_PORTSCAN) += xt_portscan.o +Index: linux-2.6.21.7/net/netfilter/xt_CHAOS.c +=================================================================== +--- /dev/null ++++ linux-2.6.21.7/net/netfilter/xt_CHAOS.c +@@ -0,0 +1,200 @@ ++/* ++ *	CHAOS target for netfilter ++ *	Copyright © CC Computer Consultants GmbH, 2006 - 2007 ++ *	Contact: Jan Engelhardt <jengelh@computergmbh.de> ++ * ++ *	This program is free software; you can redistribute it and/or modify ++ *	it under the terms of the GNU General Public License; either version ++ *	2 or 3 as published by the Free Software Foundation. ++ */ ++#include <linux/icmp.h> ++#include <linux/in.h> ++#include <linux/ip.h> ++#include <linux/module.h> ++#include <linux/skbuff.h> ++#include <linux/stat.h> ++#include <linux/netfilter/x_tables.h> ++#include <linux/netfilter/xt_tcpudp.h> ++#include <linux/netfilter_ipv4/ipt_REJECT.h> ++#include <net/ip.h> ++#if defined(_LOCAL) ++#	include "xt_CHAOS.h" ++#	include "find_match.c" ++#elif defined(CONFIG_NETFILTER_XT_TARGET_CHAOS) || \ ++    defined(CONFIG_NETFILTER_XT_TARGET_CHAOS_MODULE) ++#	include <linux/netfilter/xt_CHAOS.h> ++#	include "find_match.c" ++#else ++#	include "xt_CHAOS.h" ++#	include "find_match.c" ++#endif ++#define PFX KBUILD_MODNAME ": " ++ ++/* Module parameters */ ++static unsigned int reject_percentage = ~0U * .01; ++static unsigned int delude_percentage = ~0U * .0101; ++module_param(reject_percentage, uint, S_IRUGO | S_IWUSR); ++module_param(delude_percentage, uint, S_IRUGO | S_IWUSR); ++ ++/* References to other matches/targets */ ++static struct xt_match *xm_tcp; ++static struct xt_target *xt_delude, *xt_reject, *xt_tarpit; ++ ++static int have_delude, have_tarpit; ++ ++/* Static data for other matches/targets */ ++static const struct ipt_reject_info reject_params = { ++	.with = ICMP_HOST_UNREACH, ++}; ++ ++static const struct xt_tcp tcp_params = { ++	.spts = {0, ~0}, ++	.dpts = {0, ~0}, ++}; ++ ++/* CHAOS functions */ ++static void xt_chaos_total(const struct xt_chaos_target_info *info, ++    struct sk_buff **pskb, const struct net_device *in, ++    const struct net_device *out, unsigned int hooknum) ++{ ++	const struct iphdr *iph = ip_hdr(*pskb); ++	const int protoff       = 4 * iph->ihl; ++	const int offset        = ntohs(iph->frag_off) & IP_OFFSET; ++	const struct xt_target *destiny; ++	int hotdrop = 0, ret; ++ ++	ret = xm_tcp->match(*pskb, in, out, xm_tcp, &tcp_params, ++	                    offset, protoff, &hotdrop); ++	if (!ret || hotdrop || (unsigned int)net_random() > delude_percentage) ++		return; ++ ++	destiny = (info->variant == XTCHAOS_TARPIT) ? xt_tarpit : xt_delude; ++	destiny->target(pskb, in, out, hooknum, destiny, NULL); ++	return; ++} ++ ++static unsigned int chaos_tg(struct sk_buff **pskb, ++    const struct net_device *in, const struct net_device *out, ++    unsigned int hooknum, const struct xt_target *target, const void *targinfo) ++{ ++	/* ++	 * Equivalent to: ++	 * -A chaos -m statistic --mode random --probability \ ++	 *         $reject_percentage -j REJECT --reject-with host-unreach; ++	 * -A chaos -p tcp -m statistic --mode random --probability \ ++	 *         $delude_percentage -j DELUDE; ++	 * -A chaos -j DROP; ++	 */ ++	const struct xt_chaos_target_info *info = targinfo; ++	const struct iphdr *iph = ip_hdr(*pskb); ++ ++	if ((unsigned int)net_random() <= reject_percentage) ++		return xt_reject->target(pskb, in, out, hooknum, target, ++		       &reject_params); ++ ++	/* TARPIT/DELUDE may not be called from the OUTPUT chain */ ++	if (iph->protocol == IPPROTO_TCP && ++	    info->variant != XTCHAOS_NORMAL && hooknum != NF_IP_LOCAL_OUT) ++		xt_chaos_total(info, pskb, in, out, hooknum); ++ ++	return NF_DROP; ++} ++ ++static int chaos_tg_check(const char *tablename, const void *entry, ++    const struct xt_target *target, void *targinfo, unsigned int hook_mask) ++{ ++	const struct xt_chaos_target_info *info = targinfo; ++ ++	if (info->variant == XTCHAOS_DELUDE && !have_delude) { ++		printk(KERN_WARNING PFX "Error: Cannot use --delude when " ++		       "DELUDE module not available\n"); ++		return false; ++	} ++	if (info->variant == XTCHAOS_TARPIT && !have_tarpit) { ++		printk(KERN_WARNING PFX "Error: Cannot use --tarpit when " ++		       "TARPIT module not available\n"); ++		return false; ++	} ++ ++	return true; ++} ++ ++static struct xt_target chaos_tg_reg = { ++	.name       = "CHAOS", ++	.family     = AF_INET, ++	.table      = "filter", ++	.hooks      = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | ++	              (1 << NF_IP_LOCAL_OUT), ++	.checkentry = chaos_tg_check, ++	.target     = chaos_tg, ++	.targetsize = sizeof(struct xt_chaos_target_info), ++	.me         = THIS_MODULE, ++}; ++ ++static int __init chaos_tg_init(void) ++{ ++	int ret = -EINVAL; ++ ++	xm_tcp = xt_request_find_match(AF_INET, "tcp", 0); ++	if (xm_tcp == NULL) { ++		printk(KERN_WARNING PFX "Error: Could not find or load " ++		       "\"tcp\" match\n"); ++		return -EINVAL; ++	} ++ ++	xt_reject = xt_request_find_target(AF_INET, "REJECT", 0); ++	if (xt_reject == NULL) { ++		printk(KERN_WARNING PFX "Error: Could not find or load " ++		       "\"REJECT\" target\n"); ++		goto out2; ++	} ++ ++	xt_tarpit   = xt_request_find_target(AF_INET, "TARPIT", 0); ++	have_tarpit = xt_tarpit != NULL; ++	if (!have_tarpit) ++		printk(KERN_WARNING PFX "Warning: Could not find or load " ++		       "\"TARPIT\" target\n"); ++ ++	xt_delude   = xt_request_find_target(AF_INET, "DELUDE", 0); ++	have_delude = xt_delude != NULL; ++	if (!have_delude) ++		printk(KERN_WARNING PFX "Warning: Could not find or load " ++		       "\"DELUDE\" target\n"); ++ ++	if ((ret = xt_register_target(&chaos_tg_reg)) != 0) { ++		printk(KERN_WARNING PFX "xt_register_target returned " ++		       "error %d\n", ret); ++		goto out3; ++	} ++ ++	return 0; ++ ++ out3: ++ 	if (have_delude) ++ 		module_put(xt_delude->me); ++	if (have_tarpit) ++		module_put(xt_tarpit->me); ++	module_put(xt_reject->me); ++ out2: ++	module_put(xm_tcp->me); ++	return ret; ++} ++ ++static void __exit chaos_tg_exit(void) ++{ ++	xt_unregister_target(&chaos_tg_reg); ++	module_put(xm_tcp->me); ++	module_put(xt_reject->me); ++	if (have_delude) ++		module_put(xt_delude->me); ++	if (have_tarpit) ++		module_put(xt_tarpit->me); ++	return; ++} ++ ++module_init(chaos_tg_init); ++module_exit(chaos_tg_exit); ++MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); ++MODULE_DESCRIPTION("netfilter \"CHAOS\" target"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("ipt_CHAOS"); +Index: linux-2.6.21.7/net/netfilter/xt_DELUDE.c +=================================================================== +--- /dev/null ++++ linux-2.6.21.7/net/netfilter/xt_DELUDE.c +@@ -0,0 +1,197 @@ ++/* ++ *	DELUDE target ++ *	Copyright © CC Computer Consultants GmbH, 2007 ++ *	Contact: Jan Engelhardt <jengelh@computergmbh.de> ++ * ++ *	Based upon linux-2.6.18.5/net/ipv4/netfilter/ipt_REJECT.c: ++ *	(C) 1999-2001 Paul `Rusty' Russell ++ *	(C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> ++ * ++ *	xt_DELUDE acts like REJECT, but does reply with SYN-ACK on SYN. ++ * ++ *	This program is free software; you can redistribute it and/or modify ++ *	it under the terms of the GNU General Public License version 2 as ++ *	published by the Free Software Foundation. ++ */ ++#include <linux/module.h> ++#include <linux/skbuff.h> ++#include <linux/ip.h> ++#include <linux/tcp.h> ++#include <linux/netfilter/x_tables.h> ++#ifdef CONFIG_BRIDGE_NETFILTER ++#	include <linux/netfilter_bridge.h> ++#endif ++#include <net/tcp.h> ++#define PFX KBUILD_MODNAME ": " ++ ++static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook) ++{ ++	struct tcphdr _otcph, *oth, *tcph; ++	unsigned int addr_type; ++	struct sk_buff *nskb; ++	u_int16_t tmp_port; ++	u_int32_t tmp_addr; ++	struct iphdr *niph; ++	bool needs_ack; ++ ++	/* IP header checks: fragment. */ ++	if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET)) ++		return; ++ ++	oth = skb_header_pointer(oldskb, ip_hdrlen(oldskb), ++				 sizeof(_otcph), &_otcph); ++	if (oth == NULL) ++		return; ++ ++	/* No RST for RST. */ ++	if (oth->rst) ++		return; ++ ++	/* Check checksum */ ++	if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP)) ++		return; ++ ++	/* We need a linear, writeable skb.  We also need to expand ++	   headroom in case hh_len of incoming interface < hh_len of ++	   outgoing interface */ ++	nskb = skb_copy_expand(oldskb, LL_MAX_HEADER, skb_tailroom(oldskb), ++			       GFP_ATOMIC); ++	if (!nskb) ++		return; ++ ++	/* This packet will not be the same as the other: clear nf fields */ ++	nf_reset(nskb); ++	nskb->mark = 0; ++	skb_init_secmark(nskb); ++ ++	skb_shinfo(nskb)->gso_size = 0; ++	skb_shinfo(nskb)->gso_segs = 0; ++	skb_shinfo(nskb)->gso_type = 0; ++ ++	tcph = (struct tcphdr *)(skb_network_header(nskb) + ip_hdrlen(nskb)); ++ ++	/* Swap source and dest */ ++	niph         = ip_hdr(nskb); ++	tmp_addr     = niph->saddr; ++	niph->saddr  = niph->daddr; ++	niph->daddr  = tmp_addr; ++	tmp_port     = tcph->source; ++	tcph->source = tcph->dest; ++	tcph->dest   = tmp_port; ++ ++	/* Truncate to length (no data) */ ++	tcph->doff    = sizeof(struct tcphdr) / 4; ++	skb_trim(nskb, ip_hdrlen(nskb) + sizeof(struct tcphdr)); ++	niph->tot_len = htons(nskb->len); ++ ++	if (oth->syn && !oth->ack && !oth->rst && !oth->fin) { ++		/* DELUDE essential part */ ++		tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin + ++		                oldskb->len - ip_hdrlen(oldskb) - ++		                (oth->doff << 2)); ++		tcph->seq     = false; ++		tcph->ack     = true; ++	} else { ++		if (!tcph->ack) { ++			needs_ack     = true; ++			tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + ++			                oth->fin + oldskb->len - ++			                ip_hdrlen(oldskb) - (oth->doff<<2)); ++			tcph->seq     = false; ++		} else { ++			needs_ack     = false; ++			tcph->seq     = oth->ack_seq; ++			tcph->ack_seq = false; ++		} ++ ++		/* Reset flags */ ++		((u_int8_t *)tcph)[13] = 0; ++		tcph->rst = true; ++		tcph->ack = needs_ack; ++	} ++ ++	tcph->window  = 0; ++	tcph->urg_ptr = 0; ++ ++	/* Adjust TCP checksum */ ++	tcph->check = 0; ++	tcph->check = tcp_v4_check(sizeof(struct tcphdr), niph->saddr, ++	              niph->daddr, csum_partial((char *)tcph, ++	              sizeof(struct tcphdr), 0)); ++ ++	/* Set DF, id = 0 */ ++	niph->frag_off = htons(IP_DF); ++	niph->id       = 0; ++ ++	addr_type = RTN_UNSPEC; ++#ifdef CONFIG_BRIDGE_NETFILTER ++	if (hook != NF_IP_FORWARD || (nskb->nf_bridge != NULL && ++	    nskb->nf_bridge->mask & BRNF_BRIDGED)) ++#else ++	if (hook != NF_IP_FORWARD) ++#endif ++		addr_type = RTN_LOCAL; ++ ++	if (ip_route_me_harder(&nskb, addr_type)) ++		goto free_nskb; ++ ++	nskb->ip_summed = CHECKSUM_NONE; ++ ++	/* Adjust IP TTL */ ++	niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); ++ ++	/* Adjust IP checksum */ ++	niph->check = 0; ++	niph->check = ip_fast_csum(skb_network_header(nskb), niph->ihl); ++ ++	/* "Never happens" */ ++	if (nskb->len > dst_mtu(nskb->dst)) ++		goto free_nskb; ++ ++	nf_ct_attach(nskb, oldskb); ++ ++	NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev, ++		dst_output); ++	return; ++ ++ free_nskb: ++	kfree_skb(nskb); ++} ++ ++static unsigned int delude_tg(struct sk_buff **pskb, ++    const struct net_device *in, const struct net_device *out, ++    unsigned int hooknum, const struct xt_target *target, const void *targinfo) ++{ ++	/* WARNING: This code causes reentry within iptables. ++	   This means that the iptables jump stack is now crap.  We ++	   must return an absolute verdict. --RR */ ++	delude_send_reset(*pskb, hooknum); ++	return NF_DROP; ++} ++ ++static struct xt_target delude_tg_reg = { ++	.name       = "DELUDE", ++	.family     = AF_INET, ++	.table      = "filter", ++	.hooks      = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD), ++	.target     = delude_tg, ++	.proto      = IPPROTO_TCP, ++	.me         = THIS_MODULE, ++}; ++ ++static int __init delude_tg_init(void) ++{ ++	return xt_register_target(&delude_tg_reg); ++} ++ ++static void __exit delude_tg_exit(void) ++{ ++	xt_unregister_target(&delude_tg_reg); ++} ++ ++module_init(delude_tg_init); ++module_exit(delude_tg_exit); ++MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); ++MODULE_DESCRIPTION("netfilter \"DELUDE\" target"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("ipt_DELUDE"); +Index: linux-2.6.21.7/net/netfilter/xt_portscan.c +=================================================================== +--- /dev/null ++++ linux-2.6.21.7/net/netfilter/xt_portscan.c +@@ -0,0 +1,269 @@ ++/* ++ *	portscan match for netfilter ++ *	Copyright © CC Computer Consultants GmbH, 2006 - 2007 ++ *	Contact: Jan Engelhardt <jengelh@computergmbh.de> ++ * ++ *	This program is free software; you can redistribute it and/or modify ++ *	it under the terms of the GNU General Public License; either version ++ *	2 or 3 as published by the Free Software Foundation. ++ */ ++#include <linux/in.h> ++#include <linux/ip.h> ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/skbuff.h> ++#include <linux/stat.h> ++#include <linux/tcp.h> ++#include <linux/types.h> ++#include <linux/version.h> ++#include <linux/netfilter/x_tables.h> ++#include <linux/netfilter/xt_tcpudp.h> ++#include <net/netfilter/nf_nat_rule.h> ++#if defined(_LOCAL) ++#	include "xt_portscan.h" ++#elif defined(CONFIG_NETFILTER_XT_MATCH_PORTSCAN) || \ ++    defined(CONFIG_NETFILTER_XT_MATCH_PORTSCAN_MODULE) ++#	include <linux/netfilter/xt_portscan.h> ++#else ++#	include "xt_portscan.h" ++#endif ++#define PFX KBUILD_MODNAME ": " ++ ++enum { ++	TCP_FLAGS_ALL3 = TCP_FLAG_FIN | TCP_FLAG_RST | TCP_FLAG_SYN, ++	TCP_FLAGS_ALL4 = TCP_FLAGS_ALL3 | TCP_FLAG_ACK, ++	TCP_FLAGS_ALL6 = TCP_FLAGS_ALL4 | TCP_FLAG_PSH | TCP_FLAG_URG, ++}; ++ ++/* Module parameters */ ++static unsigned int ++	connmark_mask = ~0, ++	packet_mask   = ~0, ++	mark_seen     = 0x9, ++	mark_synrcv   = 0x1, ++	mark_closed   = 0x2, ++	mark_synscan  = 0x3, ++	mark_estab1   = 0x4, ++	mark_estab2   = 0x5, ++	mark_cnscan   = 0x6, ++	mark_grscan   = 0x7, ++	mark_valid    = 0x8; ++ ++module_param(connmark_mask, uint, S_IRUGO | S_IWUSR); ++module_param(packet_mask,   uint, S_IRUGO | S_IWUSR); ++module_param(mark_seen,     uint, S_IRUGO | S_IWUSR); ++module_param(mark_synrcv,   uint, S_IRUGO | S_IWUSR); ++module_param(mark_closed,   uint, S_IRUGO | S_IWUSR); ++module_param(mark_synscan,  uint, S_IRUGO | S_IWUSR); ++module_param(mark_estab1,   uint, S_IRUGO | S_IWUSR); ++module_param(mark_estab2,   uint, S_IRUGO | S_IWUSR); ++module_param(mark_cnscan,   uint, S_IRUGO | S_IWUSR); ++module_param(mark_grscan,   uint, S_IRUGO | S_IWUSR); ++module_param(mark_valid,    uint, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(connmark_mask, "only set specified bits in connection mark"); ++MODULE_PARM_DESC(packet_mask,   "only set specified bits in packet mark"); ++MODULE_PARM_DESC(mark_seen,     "nfmark value for packet-seen state"); ++MODULE_PARM_DESC(mark_synrcv,   "connmark value for SYN Received state"); ++MODULE_PARM_DESC(mark_closed,   "connmark value for closed state"); ++MODULE_PARM_DESC(mark_synscan,  "connmark value for SYN Scan state"); ++MODULE_PARM_DESC(mark_estab1,   "connmark value for Established-1 state"); ++MODULE_PARM_DESC(mark_estab2,   "connmark value for Established-2 state"); ++MODULE_PARM_DESC(mark_cnscan,   "connmark value for Connect Scan state"); ++MODULE_PARM_DESC(mark_grscan,   "connmark value for Grab Scan state"); ++MODULE_PARM_DESC(mark_valid,    "connmark value for Valid state"); ++ ++/* TCP flag functions */ ++static inline bool tflg_ack4(const struct tcphdr *th) ++{ ++	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_ACK; ++} ++ ++static inline bool tflg_ack6(const struct tcphdr *th) ++{ ++	return (tcp_flag_word(th) & TCP_FLAGS_ALL6) == TCP_FLAG_ACK; ++} ++ ++static inline bool tflg_fin(const struct tcphdr *th) ++{ ++	return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_FIN; ++} ++ ++static inline bool tflg_rst(const struct tcphdr *th) ++{ ++	return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_RST; ++} ++ ++static inline bool tflg_rstack(const struct tcphdr *th) ++{ ++	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == ++	       (TCP_FLAG_ACK | TCP_FLAG_RST); ++} ++ ++static inline bool tflg_syn(const struct tcphdr *th) ++{ ++	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_SYN; ++} ++ ++static inline bool tflg_synack(const struct tcphdr *th) ++{ ++	return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == ++	       (TCP_FLAG_SYN | TCP_FLAG_ACK); ++} ++ ++/* portscan functions */ ++static inline bool portscan_mt_stealth(const struct tcphdr *th) ++{ ++	/* ++	 * "Connection refused" replies to our own probes must not be matched. ++	 */ ++	if (tflg_rstack(th)) ++		return false; ++ ++	if (tflg_rst(th) && printk_ratelimit()) { ++		printk(KERN_WARNING PFX "Warning: Pure RST received\n"); ++		return false; ++	} ++ ++	/* ++	 * -p tcp ! --syn -m conntrack --ctstate INVALID: Looking for non-start ++	 * packets that are not associated with any connection -- this will ++	 * match most scan types (NULL, XMAS, FIN) and ridiculous flag ++	 * combinations (SYN-RST, SYN-FIN, SYN-FIN-RST, FIN-RST, etc.). ++	 */ ++	return !tflg_syn(th); ++} ++ ++static inline unsigned int portscan_mt_full(int mark, ++    enum ip_conntrack_info ctstate, bool loopback, const struct tcphdr *tcph, ++    unsigned int payload_len) ++{ ++	if (mark == mark_estab2) { ++		/* ++		 * -m connmark --mark $ESTAB2 ++		 */ ++		if (tflg_ack4(tcph) && payload_len == 0) ++			return mark; /* keep mark */ ++		else if (tflg_rst(tcph) || tflg_fin(tcph)) ++			return mark_grscan; ++		else ++			return mark_valid; ++	} else if (mark == mark_estab1) { ++		/* ++		 * -m connmark --mark $ESTAB1 ++		 */ ++		if (tflg_rst(tcph) || tflg_fin(tcph)) ++			return mark_cnscan; ++		else if (!loopback && tflg_ack4(tcph) && payload_len == 0) ++			return mark_estab2; ++		else ++			return mark_valid; ++	} else if (mark == mark_synrcv) { ++		/* ++		 * -m connmark --mark $SYN ++		 */ ++		if (loopback && tflg_synack(tcph)) ++			return mark; /* keep mark */ ++		else if (loopback && tflg_rstack(tcph)) ++			return mark_closed; ++		else if (tflg_ack6(tcph)) ++			return mark_estab1; ++		else ++			return mark_synscan; ++	} else if (ctstate == IP_CT_NEW && tflg_syn(tcph)) { ++		/* ++		 * -p tcp --syn --ctstate NEW ++		 */ ++		return mark_synrcv; ++	} ++	return mark; ++} ++ ++static int portscan_mt(const struct sk_buff *skb, ++    const struct net_device *in, const struct net_device *out, ++    const struct xt_match *match, const void *matchinfo, int offset, ++    unsigned int protoff, int *hotdrop) ++{ ++	const struct xt_portscan_match_info *info = matchinfo; ++	enum ip_conntrack_info ctstate; ++	const struct tcphdr *tcph; ++	struct nf_conn *ctdata; ++	struct tcphdr tcph_buf; ++ ++	tcph = skb_header_pointer(skb, protoff, sizeof(tcph_buf), &tcph_buf); ++	if (tcph == NULL) ++		return false; ++ ++	/* Check for invalid packets: -m conntrack --ctstate INVALID */ ++	if ((ctdata = nf_ct_get(skb, &ctstate)) == NULL) { ++		if (info->match_stealth) ++			return portscan_mt_stealth(tcph); ++		/* ++		 * If @ctdata is NULL, we cannot match the other scan ++		 * types, return. ++		 */ ++		return false; ++	} ++ ++	/* ++	 * If -m portscan was previously applied to this packet, the rules we ++	 * simulate must not be run through again. And for speedup, do not call ++	 * it either when the connection is already VALID. ++	 */ ++	if ((ctdata->mark & connmark_mask) == mark_valid || ++	     (skb->mark & packet_mask) != mark_seen) { ++		unsigned int n; ++ ++		n = portscan_mt_full(ctdata->mark & connmark_mask, ctstate, ++		    in == &loopback_dev, tcph, ++		    skb->len - protoff - 4 * tcph->doff); ++ ++		ctdata->mark = (ctdata->mark & ~connmark_mask) | n; ++		((struct sk_buff *)skb)->mark = ++			(skb->mark & ~packet_mask) ^ mark_seen; ++	} ++ ++	return (info->match_syn && ctdata->mark == mark_synscan) || ++	       (info->match_cn && ctdata->mark == mark_cnscan) || ++	       (info->match_gr && ctdata->mark == mark_grscan); ++} ++ ++static int portscan_mt_check(const char *tablename, const void *entry, ++    const struct xt_match *match, void *matchinfo, unsigned int hook_mask) ++{ ++	const struct xt_portscan_match_info *info = matchinfo; ++ ++	if ((info->match_stealth & ~1) || (info->match_syn & ~1) || ++	    (info->match_cn & ~1) || (info->match_gr & ~1)) { ++		printk(KERN_WARNING PFX "Invalid flags\n"); ++		return false; ++	} ++	return true; ++} ++ ++static struct xt_match portscan_mt_reg __read_mostly = { ++	.name       = "portscan", ++	.family     = AF_INET, ++	.match      = portscan_mt, ++	.checkentry = portscan_mt_check, ++	.matchsize  = sizeof(struct xt_portscan_match_info), ++	.proto      = IPPROTO_TCP, ++	.me         = THIS_MODULE, ++}; ++ ++static int __init portscan_mt_init(void) ++{ ++	return xt_register_match(&portscan_mt_reg); ++} ++ ++static void __exit portscan_mt_exit(void) ++{ ++	xt_unregister_match(&portscan_mt_reg); ++	return; ++} ++ ++module_init(portscan_mt_init); ++module_exit(portscan_mt_exit); ++MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); ++MODULE_DESCRIPTION("netfilter \"portscan\" match"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("ipt_portscan"); diff --git a/target/linux/generic-2.6/patches/171-netfilter_tarpit.patch b/target/linux/generic-2.6/patches/171-netfilter_tarpit.patch new file mode 100644 index 000000000..a686bd3d6 --- /dev/null +++ b/target/linux/generic-2.6/patches/171-netfilter_tarpit.patch @@ -0,0 +1,325 @@ +Index: linux-2.6.21.7/net/netfilter/Kconfig +=================================================================== +--- linux-2.6.21.7.orig/net/netfilter/Kconfig ++++ linux-2.6.21.7/net/netfilter/Kconfig +@@ -414,6 +414,23 @@ config NETFILTER_XT_TARGET_CONNSECMARK +  + 	  To compile it as a module, choose M here.  If unsure, say N. +  ++config NETFILTER_XT_TARGET_TARPIT ++	tristate '"TARPIT" target support' ++	depends on NETFILTER_XTABLES ++	---help--- ++	  Adds a TARPIT target to iptables, which captures and holds ++	  incoming TCP connections using no local per-connection resources. ++	  Connections are accepted, but immediately switched to the persist ++	  state (0 byte window), in which the remote side stops sending data ++	  and asks to continue every 60-240 seconds. Attempts to close the ++	  connection are ignored, forcing the remote side to time out the ++	  connection in 12-24 minutes. ++ ++	  This offers similar functionality to LaBrea ++	  <http://www.hackbusters.net/LaBrea/>, but does not require dedicated ++	  hardware or IPs. Any TCP port that you would normally DROP or REJECT ++	  can instead become a tarpit. ++ + config NETFILTER_XT_TARGET_TCPMSS + 	tristate '"TCPMSS" target support' + 	depends on NETFILTER_XTABLES && (IPV6 || IPV6=n) +Index: linux-2.6.21.7/net/netfilter/Makefile +=================================================================== +--- linux-2.6.21.7.orig/net/netfilter/Makefile ++++ linux-2.6.21.7/net/netfilter/Makefile +@@ -45,6 +45,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE + obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o + obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o + obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o ++obj-$(CONFIG_NETFILTER_XT_TARGET_TARPIT) += xt_TARPIT.o + obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o + obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o + obj-$(CONFIG_NETFILTER_XT_TARGET_CHAOS) += xt_CHAOS.o +Index: linux-2.6.21.7/net/netfilter/xt_TARPIT.c +=================================================================== +--- /dev/null ++++ linux-2.6.21.7/net/netfilter/xt_TARPIT.c +@@ -0,0 +1,280 @@ ++/* ++ * Kernel module to capture and hold incoming TCP connections using ++ * no local per-connection resources. ++ * ++ * Based on ipt_REJECT.c and offering functionality similar to ++ * LaBrea <http://www.hackbusters.net/LaBrea/>. ++ * ++ * Copyright (c) 2002 Aaron Hopkins <tools@die.net> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ * Goal: ++ * - Allow incoming TCP connections to be established. ++ * - Passing data should result in the connection being switched to the ++ *   persist state (0 byte window), in which the remote side stops sending ++ *   data and asks to continue every 60 seconds. ++ * - Attempts to shut down the connection should be ignored completely, so ++ *   the remote side ends up having to time it out. ++ * ++ * This means: ++ * - Reply to TCP SYN,!ACK,!RST,!FIN with SYN-ACK, window 5 bytes ++ * - Reply to TCP SYN,ACK,!RST,!FIN with RST to prevent spoofing ++ * - Reply to TCP !SYN,!RST,!FIN with ACK, window 0 bytes, rate-limited ++ */ ++ ++#include <linux/version.h> ++#include <linux/module.h> ++#include <linux/skbuff.h> ++#include <linux/ip.h> ++#include <net/ip.h> ++#include <net/tcp.h> ++#include <net/icmp.h> ++struct in_device; ++#include <net/route.h> ++#include <linux/random.h> ++#include <linux/netfilter_ipv4/ip_tables.h> ++ ++#if 0 ++#define DEBUGP printk ++#else ++#define DEBUGP(format, args...) ++#endif ++ ++/* Stolen from ip_finish_output2 */ ++static int ip_direct_send(struct sk_buff *skb) ++{ ++	struct dst_entry *dst = skb->dst; ++ ++        if (dst->hh != NULL) ++		return neigh_hh_output(dst->hh, skb); ++	else if (dst->neighbour != NULL) ++		return dst->neighbour->output(skb); ++ ++	if (net_ratelimit()) ++		printk(KERN_DEBUG "TARPIT ip_direct_send: no header cache and no neighbor!\n"); ++ ++	kfree_skb(skb); ++	return -EINVAL; ++} ++ ++ ++/* Send reply */ ++static void tarpit_tcp(const struct sk_buff *oskb, struct rtable *ort, ++                       unsigned int local) ++{ ++	struct sk_buff *nskb; ++	struct rtable *nrt; ++	struct tcphdr *otcph, *ntcph; ++	struct flowi fl = {}; ++	unsigned int otcplen; ++	u_int16_t tmp; ++ ++	const struct iphdr *oiph = ip_hdr(oskb); ++	struct iphdr *niph; ++ ++	/* A truncated TCP header is not going to be useful */ ++	if (oskb->len < ip_hdrlen(oskb) + sizeof(struct tcphdr)) ++		return; ++ ++	otcph   = (void *)oiph + ip_hdrlen(oskb); ++	otcplen = oskb->len - ip_hdrlen(oskb); ++ ++	/* No replies for RST or FIN */ ++	if (otcph->rst || otcph->fin) ++		return; ++ ++	/* No reply to !SYN,!ACK.  Rate-limit replies to !SYN,ACKs */ ++	if (!otcph->syn && (!otcph->ack || !xrlim_allow(&ort->u.dst, 1*HZ))) ++		return; ++ ++	/* Check checksum. */ ++	if (tcp_v4_check(otcplen, oiph->saddr, oiph->daddr, ++	    csum_partial((char *)otcph, otcplen, 0)) != 0) ++		return; ++ ++	/* ++	 * Copy skb (even if skb is about to be dropped, we cannot just ++	 * clone it because there may be other things, such as tcpdump, ++	 * interested in it) ++	 */ ++	nskb = skb_copy(oskb, GFP_ATOMIC); ++	if (nskb == NULL) ++		return; ++ ++	niph = ip_hdr(nskb); ++ ++	/* This packet will not be the same as the other: clear nf fields */ ++	nf_conntrack_put(nskb->nfct); ++	nskb->nfct = NULL; ++#ifdef CONFIG_NETFILTER_DEBUG ++	nskb->nf_debug = 0; ++#endif ++ ++	ntcph = (void *)niph + ip_hdrlen(nskb); ++ ++	/* Truncate to length (no data) */ ++	ntcph->doff = sizeof(struct tcphdr)/4; ++	skb_trim(nskb, ip_hdrlen(nskb) + sizeof(struct tcphdr)); ++	niph->tot_len = htons(nskb->len); ++ ++	/* Swap source and dest */ ++	niph->daddr = xchg(&niph->saddr, niph->daddr); ++	tmp = ntcph->source; ++	ntcph->source = ntcph->dest; ++	ntcph->dest = tmp; ++ ++	/* Use supplied sequence number or make a new one */ ++	ntcph->seq = otcph->ack ? otcph->ack_seq ++		: htonl(secure_tcp_sequence_number(niph->saddr, ++						   niph->daddr, ++						   ntcph->source, ++						   ntcph->dest)); ++ ++	/* Our SYN-ACKs must have a >0 window */ ++	ntcph->window = (otcph->syn && !otcph->ack) ? htons(5) : 0; ++ ++	ntcph->urg_ptr = 0; ++ ++	/* Reset flags */ ++	((u_int8_t *)ntcph)[13] = 0; ++ ++	if (otcph->syn && otcph->ack) { ++		ntcph->rst = 1; ++		ntcph->ack_seq = 0; ++	} else { ++		ntcph->syn = otcph->syn; ++		ntcph->ack = 1; ++		ntcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn); ++	} ++ ++	/* Adjust TCP checksum */ ++	ntcph->check = 0; ++	ntcph->check = tcp_v4_check(sizeof(struct tcphdr), ++				   niph->saddr, ++				   niph->daddr, ++				   csum_partial((char *)ntcph, ++						sizeof(struct tcphdr), 0)); ++ ++	fl.nl_u.ip4_u.daddr = niph->daddr; ++	fl.nl_u.ip4_u.saddr = local ? niph->saddr : 0; ++	fl.nl_u.ip4_u.tos = RT_TOS(niph->tos) | RTO_CONN; ++	fl.oif = 0; ++ ++	if (ip_route_output_key(&nrt, &fl)) ++		goto free_nskb; ++ ++	dst_release(nskb->dst); ++	nskb->dst = &nrt->u.dst; ++ ++	/* Adjust IP TTL */ ++	niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); ++ ++	/* Set DF, id = 0 */ ++	niph->frag_off = htons(IP_DF); ++	niph->id = 0; ++ ++	/* Adjust IP checksum */ ++	niph->check = 0; ++	niph->check = ip_fast_csum((unsigned char *)niph, niph->ihl); ++ ++	/* "Never happens" */ ++	if (nskb->len > dst_mtu(nskb->dst)) ++		goto free_nskb; ++ ++	ip_direct_send(nskb); ++	return; ++ ++ free_nskb: ++	kfree_skb(nskb); ++} ++ ++static unsigned int xt_tarpit_target(struct sk_buff **pskb, ++                                     const struct net_device *in, ++                                     const struct net_device *out, ++                                     unsigned int hooknum, ++                                     const struct xt_target *target, ++                                     const void *targinfo) ++{ ++	const struct sk_buff *skb = *pskb; ++	const struct iphdr *iph   = ip_hdr(skb); ++	struct rtable *rt         = (void *)skb->dst; ++ ++	/* Do we have an input route cache entry? */ ++	if (rt == NULL) ++		return NF_DROP; ++ ++	/* No replies to physical multicast/broadcast */ ++	if (skb->pkt_type != PACKET_HOST && skb->pkt_type != PACKET_OTHERHOST) ++		return NF_DROP; ++ ++	/* Now check at the protocol level */ ++	if (rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) ++		return NF_DROP; ++ ++	/* ++	 * Our naive response construction does not deal with IP ++	 * options, and probably should not try. ++	 */ ++	if (iph->ihl * 4 != sizeof(struct iphdr)) ++		return NF_DROP; ++ ++	/* We are not interested in fragments */ ++	if (iph->frag_off & htons(IP_OFFSET)) ++		return NF_DROP; ++ ++	tarpit_tcp(skb, rt, hooknum == NF_IP_LOCAL_IN); ++	return NF_DROP; ++} ++ ++static int xt_tarpit_check(const char *tablename, const void *entry, ++                            const struct xt_target *target, void *targinfo, ++                            unsigned int hook_mask) ++{ ++	bool invalid; ++ ++	if (strcmp(tablename, "raw") == 0 && hook_mask == NF_IP_PRE_ROUTING) ++		return true; ++	if (strcmp(tablename, "filter") != 0) ++		return false; ++	invalid = hook_mask & ~((1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD)); ++	return !invalid; ++} ++ ++static struct xt_target xt_tarpit_reg = { ++	.name       = "TARPIT", ++	.family     = AF_INET, ++	.proto      = IPPROTO_TCP, ++	.target     = xt_tarpit_target, ++	.checkentry = xt_tarpit_check, ++	.me         = THIS_MODULE, ++}; ++ ++static int __init xt_tarpit_init(void) ++{ ++	return xt_register_target(&xt_tarpit_reg); ++} ++ ++static void __exit xt_tarpit_exit(void) ++{ ++	xt_unregister_target(&xt_tarpit_reg); ++} ++ ++module_init(xt_tarpit_init); ++module_exit(xt_tarpit_exit); ++MODULE_DESCRIPTION("netfilter xt_TARPIT target module"); ++MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("ipt_TARPIT"); diff --git a/target/linux/generic-2.6/patches/999-backport_ip_hdr_and_friends.patch b/target/linux/generic-2.6/patches/999-backport_ip_hdr_and_friends.patch new file mode 100644 index 000000000..bb8f4f334 --- /dev/null +++ b/target/linux/generic-2.6/patches/999-backport_ip_hdr_and_friends.patch @@ -0,0 +1,58 @@ +Index: linux-2.6.21.7/include/linux/ip.h +=================================================================== +--- linux-2.6.21.7.orig/include/linux/ip.h ++++ linux-2.6.21.7/include/linux/ip.h +@@ -104,6 +104,16 @@ struct iphdr { + 	/*The options start here. */ + }; +  ++#ifdef __KERNEL__ ++#include <linux/skbuff.h> ++ ++static inline struct iphdr *ip_hdr(const struct sk_buff *skb) ++{ ++	return (struct iphdr *)skb_network_header(skb); ++} ++ ++#endif ++ + struct ip_auth_hdr { + 	__u8  nexthdr; + 	__u8  hdrlen;		/* This one is measured in 32 bit units! */ +Index: linux-2.6.21.7/include/linux/skbuff.h +=================================================================== +--- linux-2.6.21.7.orig/include/linux/skbuff.h ++++ linux-2.6.21.7/include/linux/skbuff.h +@@ -966,6 +966,16 @@ static inline void skb_reserve(struct sk + 	skb->tail += len; + } +  ++static inline unsigned char *skb_network_header(const struct sk_buff *skb) ++{ ++	return skb->nh.raw; ++} ++ ++static inline unsigned char *skb_tail_pointer(const struct sk_buff *skb) ++{ ++	return skb->tail; ++} ++ + /* +  * CPUs often take a performance hit when accessing unaligned memory +  * locations. The actual performance hit varies, it can be small if the +Index: linux-2.6.21.7/include/net/ip.h +=================================================================== +--- linux-2.6.21.7.orig/include/net/ip.h ++++ linux-2.6.21.7/include/net/ip.h +@@ -43,6 +43,11 @@ struct inet_skb_parm + #define IPSKB_REROUTED		16 + }; +  ++static inline unsigned int ip_hdrlen(const struct sk_buff *skb) ++{ ++	return ip_hdr(skb)->ihl * 4; ++} ++ + struct ipcm_cookie + { + 	__be32			addr; | 
