⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 100-netfilter_layer7_2.17.patch

📁 Linux Home Server 是专门为家庭和SOHO/SMB 设计的高性价比的ISCSI 存储服务器, 具有如下的特色: 强大的iscsi 存储服务器软件; 混合iscsi 和NAS 服务;
💻 PATCH
📖 第 1 页 / 共 4 页
字号:
+				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';+	}++	/* Can be here, but unallocated, if numpackets is increased near+	the beginning of a connection */+	if(master_conntrack->layer7.app_data == NULL){+		spin_unlock_bh(&l7_lock);+		return (info->invert); /* unmatched */+	}++	if(!skb->cb[0]){+		int newbytes;+		newbytes = add_data(master_conntrack, app_data, appdatalen);++		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. */+	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);+	/* If the regexp failed to compile, don't bother running it */+	} else if(comppattern && +		  regexec(comppattern, master_conntrack->layer7.app_data)){+		DPRINTK("layer7: matched %s\n", info->protocol);+		pattern_result = 1;+	} else pattern_result = 0;++	if(pattern_result == 1) {+		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");+			spin_unlock_bh(&l7_lock);+			return (pattern_result ^ info->invert);+		}+		strcpy(master_conntrack->layer7.app_proto, info->protocol);+	} else if(pattern_result > 1) { /* cleanup from "unset" */+		pattern_result = 1;+	}++	/* mark the packet seen */+	skb->cb[0] = 1;++	spin_unlock_bh(&l7_lock);+	return (pattern_result ^ info->invert);+}++static int check(const char *tablename,+		 const void *inf,+		 const struct xt_match *match,+		 void *matchinfo,+		 unsigned int hook_mask)++{+	// 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;+}++static void+destroy(const struct xt_match *match, void *matchinfo)+{+	nf_ct_l3proto_module_put(match->family);+}++static struct xt_match xt_layer7_match[] = {+{+	.name		= "layer7",+	.family		= AF_INET,+	.checkentry	= check,+	.match		= match,+	.destroy	= destroy,+	.matchsize	= sizeof(struct xt_layer7_info),+	.me		= THIS_MODULE+}+};++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 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");+		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");+		maxdatalen = 65536;+	}+	return xt_register_matches(xt_layer7_match,+				   ARRAY_SIZE(xt_layer7_match));+}++static void __exit xt_layer7_fini(void)+{+	layer7_cleanup_proc();+	xt_unregister_matches(xt_layer7_match, ARRAY_SIZE(xt_layer7_match));+}++module_init(xt_layer7_init);+module_exit(xt_layer7_fini);Index: linux-2.6.21.7/net/netfilter/regexp/regexp.c===================================================================--- /dev/null+++ linux-2.6.21.7/net/netfilter/regexp/regexp.c@@ -0,0 +1,1197 @@+/*+ * regcomp and regexec -- regsub and regerror are elsewhere+ * @(#)regexp.c	1.3 of 18 April 87+ *+ *	Copyright (c) 1986 by University of Toronto.+ *	Written by Henry Spencer.  Not derived from licensed software.+ *+ *	Permission is granted to anyone to use this software for any+ *	purpose on any computer system, and to redistribute it freely,+ *	subject to the following restrictions:+ *+ *	1. The author is not responsible for the consequences of use of+ *		this software, no matter how awful, even if they arise+ *		from defects in it.+ *+ *	2. The origin of this software must not be misrepresented, either+ *		by explicit claim or by omission.+ *+ *	3. Altered versions must be plainly marked as such, and must not+ *		be misrepresented as being the original software.+ *+ * Beware that some of this code is subtly aware of the way operator+ * precedence is structured in regular expressions.  Serious changes in+ * regular-expression syntax might require a total rethink.+ *+ * This code was modified by Ethan Sommer to work within the kernel+ * (it now uses kmalloc etc..)+ *+ * Modified slightly by Matthew Strait to use more modern C.+ */++#include "regexp.h"+#include "regmagic.h"++/* added by ethan and matt.  Lets it work in both kernel and user space.+(So iptables can use it, for instance.)  Yea, it goes both ways... */+#if __KERNEL__+  #define malloc(foo) kmalloc(foo,GFP_ATOMIC)+#else+  #define printk(format,args...) printf(format,##args)+#endif++void regerror(char * s)+{+        printk("<3>Regexp: %s\n", s);+        /* NOTREACHED */+}++/*+ * The "internal use only" fields in regexp.h are present to pass info from+ * compile to execute that permits the execute phase to run lots faster on+ * simple cases.  They are:+ *+ * regstart	char that must begin a match; '\0' if none obvious+ * reganch	is the match anchored (at beginning-of-line only)?+ * regmust	string (pointer into program) that match must include, or NULL+ * regmlen	length of regmust string+ *+ * Regstart and reganch permit very fast decisions on suitable starting points+ * for a match, cutting down the work a lot.  Regmust permits fast rejection+ * of lines that cannot possibly match.  The regmust tests are costly enough+ * that regcomp() supplies a regmust only if the r.e. contains something+ * potentially expensive (at present, the only such thing detected is * or ++ * at the start of the r.e., which can involve a lot of backup).  Regmlen is+ * supplied because the test in regexec() needs it and regcomp() is computing+ * it anyway.+ */++/*+ * Structure for regexp "program".  This is essentially a linear encoding+ * of a nondeterministic finite-state machine (aka syntax charts or+ * "railroad normal form" in parsing technology).  Each node is an opcode+ * plus a "next" pointer, possibly plus an operand.  "Next" pointers of+ * all nodes except BRANCH implement concatenation; a "next" pointer with+ * a BRANCH on both ends of it is connecting two alternatives.  (Here we+ * have one of the subtle syntax dependencies:  an individual BRANCH (as+ * opposed to a collection of them) is never concatenated with anything+ * because of operator precedence.)  The operand of some types of node is+ * a literal string; for others, it is a node leading into a sub-FSM.  In+ * particular, the operand of a BRANCH node is the first node of the branch.+ * (NB this is *not* a tree structure:  the tail of the branch connects+ * to the thing following the set of BRANCHes.)  The opcodes are:+ */++/* definition	number	opnd?	meaning */+#define	END	0	/* no	End of program. */+#define	BOL	1	/* no	Match "" at beginning of line. */+#define	EOL	2	/* no	Match "" at end of line. */+#define	ANY	3	/* no	Match any one character. */+#define	ANYOF	4	/* str	Match any character in this string. */+#define	ANYBUT	5	/* str	Match any character not in this string. */+#define	BRANCH	6	/* node	Match this alternative, or the next... */+#define	BACK	7	/* no	Match "", "next" ptr points backward. */+#define	EXACTLY	8	/* str	Match this string. */+#define	NOTHING	9	/* no	Match empty string. */+#define	STAR	10	/* node	Match this (simple) thing 0 or more times. */+#define	PLUS	11	/* node	Match this (simple) thing 1 or more times. */+#define	OPEN	20	/* no	Mark this point in input as start of #n. */+			/*	OPEN+1 is number 1, etc. */+#define	CLOSE	30	/* no	Analogous to OPEN. */++/*+ * Opcode notes:+ *+ * BRANCH	The set of branches constituting a single choice are hooked+ *		together with their "next" pointers, since precedence prevents+ *		anything being concatenated to any individual branch.  The+ *		"next" pointer of the last BRANCH in a choice points to the+ *		thing following the whole choice.  This is also where the+ *		final "next" pointer of each individual branch points; each+ *		branch starts with the operand node of a BRANCH node.+ *+ * BACK		Normal "next" pointers all implicitly point forward; BACK+ *		exists to make loop structures possible.+ *+ * STAR,PLUS	'?', and complex '*' and '+', are implemented as circular+ *		BRANCH structures using BACK.  Simple cases (one character+ *		per match) are implemented with STAR and PLUS for speed+ *		and to minimize recursive plunges.+ *+ * OPEN,CLOSE	...are numbered at compile time.+ */++/*+ * A node is one char of opcode followed by two chars of "next" pointer.+ * "Next" pointers are stored as two 8-bit pieces, high order first.  The+ * value is a positive offset from the opcode of the node containing it.+ * An operand, if any, simply follows the node.  (Note that much of the+ * code generation knows about this implicit relationship.)+ *+ * Using two bytes for the "next" pointer is vast overkill for most things,+ * but allows patterns to get big without disasters.+ */+#define	OP(p)	(*(p))+#define	NEXT(p)	(((*((p)+1)&0377)<<8) + (*((p)+2)&0377))+#define	OPERAND(p)	((p) + 3)++/*+ * See regmagic.h for one further detail of program structure.+ */+++/*+ * Utility definitions.+ */+#ifndef CHARBITS+#define	UCHARAT(p)	((int)*(unsigned char *)(p))+#else+#define	UCHARAT(p)	((int)*(p)&CHARBITS)+#endif++#define	FAIL(m)	{ regerror(m); return(NULL); }+#define	ISMULT(c)	((c) == '*' || (c) == '+' || (c) == '?')+#define	META	"^$.[()|?+*\\"++/*+ * Flags to be passed up and down.+ */+#define	HASWIDTH	01	/* Known never to match null string. */+#define	SIMPLE		02	/* Simple enough to be STAR/PLUS operand. */+#define	SPSTART		04	/* Starts with * or +. */+#define	WORST		0	/* Worst case. */++/*+ * Global work variables for regcomp().+ */+struct match_globals {+char *reginput;		/* String-input pointer. */+char *regbol;		/* Beginning of input, for ^ check. */+char **regstartp;	/* Pointer to startp array. */+char **regendp;		/* Ditto for endp. */+char *regparse;		/* Input-scan pointer. */+int regnpar;		/* () count. */+char regdummy;+char *regcode;		/* Code-emit pointer; &regdummy = don't. */+long regsize;		/* Code size. */+};++/*+ * Forward declarations for regcomp()'s friends.+ */+#ifndef STATIC+#define	STATIC	static+#endif+STATIC char *reg(struct match_globals *g, int paren,int *flagp);+STATIC char *regbranch(struct match_globals *g, int *flagp);+STATIC char *regpiece(struct match_globals *g, int *flagp);+STATIC char *regatom(struct match_globals *g, int *flagp);+STATIC char *regnode(struct match_globals *g, char op);+STATIC char *regnext(struct match_globals *g, char *p);+STATIC void regc(struct match_globals *g, char b);+STATIC void reginsert(struct match_globals *g, char op, char *opnd);+STATIC void regtail(struct match_globals *g, char *p, char *val);+STATIC void regoptail(struct match_globals *g, char *p, char *val);+++__kernel_size_t my_strcspn(const char *s1,const char *s2)+{+        char *scan1;+        char *scan2;+        int count;++        count = 0;+        for (scan1 = (char *)s1; *scan1 != '\0'; scan1++) {+                for (scan2 = (char *)s2; *scan2 != '\0';)       /* ++ moved down. */+                        if (*scan1 == *scan2++)+                                return(count);+                count++;+        }+        return(count);+}++/*+ - regcomp - compile a regular expression into internal code+ *+ * We can't allocate space until we know how big the compiled form will be,+ * but we can't compile it (and thus know how big it is) until we've got a+ * place to put the code.  So we cheat:  we compile it twice, once with code+ * generation turned off and size counting turned on, and once "for real".+ * This also means that we don't allocate space until we are sure that the+ * thing really will compile successfully, and we never have to move the+ * code and thus invalidate pointers into it.  (Note that it has to be in+ * one piece because free() must be able to free it all.)+ *+ * Beware that the optimization-preparation code in here knows about some+ * of the structure of the compiled regexp.+ */+regexp *+regcomp(char *exp,int *patternsize)+{+	register regexp *r;+	register char *scan;+	register char *longest;+	register int len;+	int flags;+	struct match_globals g;+	+	/* commented out by ethan+	   extern char *malloc();+	*/++	if (exp == NULL)+		FAIL("NULL argument");++	/* First pass: determine size, legality. */+	g.regparse = exp;+	g.regnpar = 1;+	g.regsize = 0L;+	g.regcode = &g.regdummy;+	regc(&g, MAGIC);+	if (reg(&g, 0, &flags) == NULL)+		return(NULL);++	/* Small enough for pointer-storage convention? */+	if (g.regsize >= 32767L)		/* Probably could be 65535L. */+		FAIL("regexp too big");++	/* Allocate space. */+	*patternsize=sizeof(regexp) + (unsigned)g.regsize;+	r = (regexp *)malloc(sizeof(regexp) + (unsigned)g.regsize);+	if (r == NULL)+		FAIL("out of space");++	/* Second pass: emit code. */+	g.regparse = exp;+	g.regnpar = 1;+	g.regcode = r->program;+	regc(&g, MAGIC);+	if (reg(&g, 0, &flags) == NULL)+		return(NULL);++	/* Dig out information for optimizations. */+	r->regstart = '\0';	/* Worst-case defaults. */+	r->reganch = 0;+	r->regmust = NULL;+	r->regmlen = 0;+	scan = r->program+1;			/* First BRANCH. */+	if (OP(regnext(&g, scan)) == END) {		/* Only one top-level choice. */+		scan = OPERAND(scan);++		/* Starting-point info. */+		if (OP(scan) == EXACTLY)+			r->regstart = *OPERAND(scan);+		else if (OP(scan) == BOL)+			r->reganch++;++		/*+		 * If there's something expensive in the r.e., find the+		 * longest literal string that must appear and make it the+		 * regmust.  Resolve ties in favor of later strings, since+		 * the regstart check works with the beginning of the r.e.+		 * and avoiding duplication strengthens checking.  Not a+		 * strong reason, but sufficient in the absence of others.+		 */+		if (flags&SPSTART) {+			longest = NULL;+			len = 0;+			for (; scan != NULL; scan = regnext(&g, scan))+				if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {+					longest = OPERAND(scan);+					len = strlen(OPERAND(scan));+				}+			r->regmust = longest;+			r->regmlen = len;+		}+	}++	return(r);+}++/*+ - reg - regular expression, i.e. main body or parenthesized thing+ *+ * Caller must absorb opening parenthesis.+ *+ * Combining parenthesis handling with the base level of regular expression+ * is a trifle forced, but the need to tie the tails of the branches to what+ * follows makes it hard to avoid.+ */+static char *+reg(struct match_globals *g, int paren, int *flagp /* Parenthesized? */ )+{+	register char *ret;+	register char *br;+	register char *ender;+	register int parno = 0; /* 0 makes gcc happy */+	int flags;++	*flagp = HASWIDTH;	/* Tentatively. */++	/* Make an OPEN node, if parenthesized. */+	if (paren) {+		if (g->regnpar >= NSUBEXP)+			FAIL("too many ()");+		parno = g->regnpar;+		g->regnpar++;+		ret = regnode(g, OPEN+parno);+	} else+		ret = NULL;++	/* Pick up the branches, linking them together. */+	br = regbranch(g, &flags);+	if (br == NULL)+		return(NULL);+	if (ret != NULL)+		regtail(g, ret, br);	/* OPEN -> first. */+	else+		ret = br;+	if (!(flags&HASWIDTH))+		*flagp &= ~HASWIDTH;+	*flagp |= flags&SPSTART;+	while (*g->regparse == '|') {+		g->regparse++;+		br = regbranch(g, &flags);+		if (br == NULL)+			return(NULL);+		regtail(g, ret, br);	/* BRANCH -> BRANCH. */+		if (!(flags&HASWIDTH))+			*flagp &= ~HASWIDTH;+		*flagp |= flags&SPSTART;+	}++	/* Make a closing node, and hook it on the end. */+	ender = regnode(g, (paren) ? CLOSE+parno : END);	+	regtail(g, ret, ender);++	/* Hook the tails of the branches to the closing node. */+	for (br = ret; br != NULL; br = regnext(g, br))+		regoptail(g, br, ender);++	/* Check for proper termination. */+	if (paren && *g->regparse++ != ')') {+		FAIL("unmatched ()");+	} else if (!paren && *g->regparse != '\0') {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -