]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/netfilter_layer7_2.22_kernel3.0.patch
snort: Update urls for rules download (2.9.7.0) in 'ids.cgi'
[ipfire-2.x.git] / src / patches / netfilter_layer7_2.22_kernel3.0.patch
CommitLineData
71fe6ae5
AF
1diff -Naur linux-3.0.24.org/include/linux/netfilter/xt_layer7.h linux-3.0.24/include/linux/netfilter/xt_layer7.h
2--- linux-3.0.24.org/include/linux/netfilter/xt_layer7.h 1970-01-01 01:00:00.000000000 +0100
3+++ linux-3.0.24/include/linux/netfilter/xt_layer7.h 2012-03-15 20:08:48.976050501 +0100
4@@ -0,0 +1,13 @@
5+#ifndef _XT_LAYER7_H
6+#define _XT_LAYER7_H
7+
8+#define MAX_PATTERN_LEN 8192
9+#define MAX_PROTOCOL_LEN 256
10+
11+struct xt_layer7_info {
12+ char protocol[MAX_PROTOCOL_LEN];
13+ char pattern[MAX_PATTERN_LEN];
14+ u_int8_t invert;
15+};
16+
17+#endif /* _XT_LAYER7_H */
18diff -Naur linux-3.0.24.org/include/net/netfilter/nf_conntrack.h linux-3.0.24/include/net/netfilter/nf_conntrack.h
19--- linux-3.0.24.org/include/net/netfilter/nf_conntrack.h 2012-03-12 18:58:19.000000000 +0100
20+++ linux-3.0.24/include/net/netfilter/nf_conntrack.h 2012-03-15 20:11:43.806042495 +0100
21@@ -134,6 +134,22 @@
22 struct net *ct_net;
23 #endif
24
25+#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || \
26+ defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE)
27+ struct {
28+ /*
29+ * e.g. "http". NULL before decision. "unknown" after decision
30+ * if no match.
31+ */
32+ char *app_proto;
33+ /*
34+ * application layer data so far. NULL after match decision.
35+ */
36+ char *app_data;
37+ unsigned int app_data_len;
38+ } layer7;
39+#endif
40+
41 /* Storage reserved for other modules, must be the last member */
42 union nf_conntrack_proto proto;
43 };
44diff -Naur linux-3.0.24.org/net/netfilter/Kconfig linux-3.0.24/net/netfilter/Kconfig
45--- linux-3.0.24.org/net/netfilter/Kconfig 2012-03-12 18:58:19.000000000 +0100
46+++ linux-3.0.24/net/netfilter/Kconfig 2012-03-15 20:46:12.046043918 +0100
47@@ -1020,6 +1020,26 @@
48
49 To compile it as a module, choose M here. If unsure, say N.
50
51+config NETFILTER_XT_MATCH_LAYER7
52+ tristate '"layer7" match support'
53+ depends on NETFILTER_XTABLES
54+ depends on EXPERIMENTAL && (IP_NF_CONNTRACK || NF_CONNTRACK)
55+ help
56+ Say Y if you want to be able to classify connections (and their
57+ packets) based on regular expression matching of their application
58+ layer data. This is one way to classify applications such as
59+ peer-to-peer filesharing systems that do not always use the same
60+ port.
61+
62+ To compile it as a module, choose M here. If unsure, say N.
63+
64+config NETFILTER_XT_MATCH_LAYER7_DEBUG
65+ bool 'Layer 7 debugging output'
66+ depends on NETFILTER_XT_MATCH_LAYER7
67+ help
68+ Say Y to get lots of debugging output.
69+
70+
71 config NETFILTER_XT_MATCH_STATISTIC
72 tristate '"statistic" match support'
73 depends on NETFILTER_ADVANCED
74diff -Naur linux-3.0.24.org/net/netfilter/Makefile linux-3.0.24/net/netfilter/Makefile
75--- linux-3.0.24.org/net/netfilter/Makefile 2012-03-12 18:58:19.000000000 +0100
76+++ linux-3.0.24/net/netfilter/Makefile 2012-03-15 20:08:49.016044445 +0100
77@@ -102,6 +102,7 @@
78 obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
79 obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
80 obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
81+obj-$(CONFIG_NETFILTER_XT_MATCH_LAYER7) += xt_layer7.o
82 obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
83 obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
84 obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
85diff -Naur linux-3.0.24.org/net/netfilter/nf_conntrack_core.c linux-3.0.24/net/netfilter/nf_conntrack_core.c
86--- linux-3.0.24.org/net/netfilter/nf_conntrack_core.c 2012-03-12 18:58:19.000000000 +0100
87+++ linux-3.0.24/net/netfilter/nf_conntrack_core.c 2012-03-15 20:08:49.026044761 +0100
88@@ -213,6 +213,14 @@
89 * too. */
90 nf_ct_remove_expectations(ct);
91
92+ #if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE)
93+ if(ct->layer7.app_proto)
94+ kfree(ct->layer7.app_proto);
95+ if(ct->layer7.app_data)
96+ kfree(ct->layer7.app_data);
97+ #endif
98+
99+
100 /* We overload first tuple to link into unconfirmed list. */
101 if (!nf_ct_is_confirmed(ct)) {
102 BUG_ON(hlist_nulls_unhashed(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode));
103diff -Naur linux-3.0.24.org/net/netfilter/nf_conntrack_standalone.c linux-3.0.24/net/netfilter/nf_conntrack_standalone.c
104--- linux-3.0.24.org/net/netfilter/nf_conntrack_standalone.c 2012-03-12 18:58:19.000000000 +0100
105+++ linux-3.0.24/net/netfilter/nf_conntrack_standalone.c 2012-03-15 20:08:49.036047262 +0100
106@@ -239,6 +239,12 @@
107 if (ct_show_delta_time(s, ct))
108 goto release;
109
110+#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE)
111+ if(ct->layer7.app_proto &&
112+ seq_printf(s, "l7proto=%s ", ct->layer7.app_proto))
113+ return -ENOSPC;
114+#endif
115+
116 if (seq_printf(s, "use=%u\n", atomic_read(&ct->ct_general.use)))
117 goto release;
118
119diff -Naur linux-3.0.24.org/net/netfilter/regexp/regexp.c linux-3.0.24/net/netfilter/regexp/regexp.c
120--- linux-3.0.24.org/net/netfilter/regexp/regexp.c 1970-01-01 01:00:00.000000000 +0100
121+++ linux-3.0.24/net/netfilter/regexp/regexp.c 2012-03-15 20:08:49.066043520 +0100
122@@ -0,0 +1,1197 @@
123+/*
124+ * regcomp and regexec -- regsub and regerror are elsewhere
125+ * @(#)regexp.c 1.3 of 18 April 87
126+ *
127+ * Copyright (c) 1986 by University of Toronto.
128+ * Written by Henry Spencer. Not derived from licensed software.
129+ *
130+ * Permission is granted to anyone to use this software for any
131+ * purpose on any computer system, and to redistribute it freely,
132+ * subject to the following restrictions:
133+ *
134+ * 1. The author is not responsible for the consequences of use of
135+ * this software, no matter how awful, even if they arise
136+ * from defects in it.
137+ *
138+ * 2. The origin of this software must not be misrepresented, either
139+ * by explicit claim or by omission.
140+ *
141+ * 3. Altered versions must be plainly marked as such, and must not
142+ * be misrepresented as being the original software.
143+ *
144+ * Beware that some of this code is subtly aware of the way operator
145+ * precedence is structured in regular expressions. Serious changes in
146+ * regular-expression syntax might require a total rethink.
147+ *
148+ * This code was modified by Ethan Sommer to work within the kernel
149+ * (it now uses kmalloc etc..)
150+ *
151+ * Modified slightly by Matthew Strait to use more modern C.
152+ */
153+
154+#include "regexp.h"
155+#include "regmagic.h"
156+
157+/* added by ethan and matt. Lets it work in both kernel and user space.
158+(So iptables can use it, for instance.) Yea, it goes both ways... */
159+#if __KERNEL__
160+ #define malloc(foo) kmalloc(foo,GFP_ATOMIC)
161+#else
162+ #define printk(format,args...) printf(format,##args)
163+#endif
164+
165+void regerror(char * s)
166+{
167+ printk("<3>Regexp: %s\n", s);
168+ /* NOTREACHED */
169+}
170+
171+/*
172+ * The "internal use only" fields in regexp.h are present to pass info from
173+ * compile to execute that permits the execute phase to run lots faster on
174+ * simple cases. They are:
175+ *
176+ * regstart char that must begin a match; '\0' if none obvious
177+ * reganch is the match anchored (at beginning-of-line only)?
178+ * regmust string (pointer into program) that match must include, or NULL
179+ * regmlen length of regmust string
180+ *
181+ * Regstart and reganch permit very fast decisions on suitable starting points
182+ * for a match, cutting down the work a lot. Regmust permits fast rejection
183+ * of lines that cannot possibly match. The regmust tests are costly enough
184+ * that regcomp() supplies a regmust only if the r.e. contains something
185+ * potentially expensive (at present, the only such thing detected is * or +
186+ * at the start of the r.e., which can involve a lot of backup). Regmlen is
187+ * supplied because the test in regexec() needs it and regcomp() is computing
188+ * it anyway.
189+ */
190+
191+/*
192+ * Structure for regexp "program". This is essentially a linear encoding
193+ * of a nondeterministic finite-state machine (aka syntax charts or
194+ * "railroad normal form" in parsing technology). Each node is an opcode
195+ * plus a "next" pointer, possibly plus an operand. "Next" pointers of
196+ * all nodes except BRANCH implement concatenation; a "next" pointer with
197+ * a BRANCH on both ends of it is connecting two alternatives. (Here we
198+ * have one of the subtle syntax dependencies: an individual BRANCH (as
199+ * opposed to a collection of them) is never concatenated with anything
200+ * because of operator precedence.) The operand of some types of node is
201+ * a literal string; for others, it is a node leading into a sub-FSM. In
202+ * particular, the operand of a BRANCH node is the first node of the branch.
203+ * (NB this is *not* a tree structure: the tail of the branch connects
204+ * to the thing following the set of BRANCHes.) The opcodes are:
205+ */
206+
207+/* definition number opnd? meaning */
208+#define END 0 /* no End of program. */
209+#define BOL 1 /* no Match "" at beginning of line. */
210+#define EOL 2 /* no Match "" at end of line. */
211+#define ANY 3 /* no Match any one character. */
212+#define ANYOF 4 /* str Match any character in this string. */
213+#define ANYBUT 5 /* str Match any character not in this string. */
214+#define BRANCH 6 /* node Match this alternative, or the next... */
215+#define BACK 7 /* no Match "", "next" ptr points backward. */
216+#define EXACTLY 8 /* str Match this string. */
217+#define NOTHING 9 /* no Match empty string. */
218+#define STAR 10 /* node Match this (simple) thing 0 or more times. */
219+#define PLUS 11 /* node Match this (simple) thing 1 or more times. */
220+#define OPEN 20 /* no Mark this point in input as start of #n. */
221+ /* OPEN+1 is number 1, etc. */
222+#define CLOSE 30 /* no Analogous to OPEN. */
223+
224+/*
225+ * Opcode notes:
226+ *
227+ * BRANCH The set of branches constituting a single choice are hooked
228+ * together with their "next" pointers, since precedence prevents
229+ * anything being concatenated to any individual branch. The
230+ * "next" pointer of the last BRANCH in a choice points to the
231+ * thing following the whole choice. This is also where the
232+ * final "next" pointer of each individual branch points; each
233+ * branch starts with the operand node of a BRANCH node.
234+ *
235+ * BACK Normal "next" pointers all implicitly point forward; BACK
236+ * exists to make loop structures possible.
237+ *
238+ * STAR,PLUS '?', and complex '*' and '+', are implemented as circular
239+ * BRANCH structures using BACK. Simple cases (one character
240+ * per match) are implemented with STAR and PLUS for speed
241+ * and to minimize recursive plunges.
242+ *
243+ * OPEN,CLOSE ...are numbered at compile time.
244+ */
245+
246+/*
247+ * A node is one char of opcode followed by two chars of "next" pointer.
248+ * "Next" pointers are stored as two 8-bit pieces, high order first. The
249+ * value is a positive offset from the opcode of the node containing it.
250+ * An operand, if any, simply follows the node. (Note that much of the
251+ * code generation knows about this implicit relationship.)
252+ *
253+ * Using two bytes for the "next" pointer is vast overkill for most things,
254+ * but allows patterns to get big without disasters.
255+ */
256+#define OP(p) (*(p))
257+#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
258+#define OPERAND(p) ((p) + 3)
259+
260+/*
261+ * See regmagic.h for one further detail of program structure.
262+ */
263+
264+
265+/*
266+ * Utility definitions.
267+ */
268+#ifndef CHARBITS
269+#define UCHARAT(p) ((int)*(unsigned char *)(p))
270+#else
271+#define UCHARAT(p) ((int)*(p)&CHARBITS)
272+#endif
273+
274+#define FAIL(m) { regerror(m); return(NULL); }
275+#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?')
276+#define META "^$.[()|?+*\\"
277+
278+/*
279+ * Flags to be passed up and down.
280+ */
281+#define HASWIDTH 01 /* Known never to match null string. */
282+#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */
283+#define SPSTART 04 /* Starts with * or +. */
284+#define WORST 0 /* Worst case. */
285+
286+/*
287+ * Global work variables for regcomp().
288+ */
289+struct match_globals {
290+char *reginput; /* String-input pointer. */
291+char *regbol; /* Beginning of input, for ^ check. */
292+char **regstartp; /* Pointer to startp array. */
293+char **regendp; /* Ditto for endp. */
294+char *regparse; /* Input-scan pointer. */
295+int regnpar; /* () count. */
296+char regdummy;
297+char *regcode; /* Code-emit pointer; &regdummy = don't. */
298+long regsize; /* Code size. */
299+};
300+
301+/*
302+ * Forward declarations for regcomp()'s friends.
303+ */
304+#ifndef STATIC
305+#define STATIC static
306+#endif
307+STATIC char *reg(struct match_globals *g, int paren,int *flagp);
308+STATIC char *regbranch(struct match_globals *g, int *flagp);
309+STATIC char *regpiece(struct match_globals *g, int *flagp);
310+STATIC char *regatom(struct match_globals *g, int *flagp);
311+STATIC char *regnode(struct match_globals *g, char op);
312+STATIC char *regnext(struct match_globals *g, char *p);
313+STATIC void regc(struct match_globals *g, char b);
314+STATIC void reginsert(struct match_globals *g, char op, char *opnd);
315+STATIC void regtail(struct match_globals *g, char *p, char *val);
316+STATIC void regoptail(struct match_globals *g, char *p, char *val);
317+
318+
319+__kernel_size_t my_strcspn(const char *s1,const char *s2)
320+{
321+ char *scan1;
322+ char *scan2;
323+ int count;
324+
325+ count = 0;
326+ for (scan1 = (char *)s1; *scan1 != '\0'; scan1++) {
327+ for (scan2 = (char *)s2; *scan2 != '\0';) /* ++ moved down. */
328+ if (*scan1 == *scan2++)
329+ return(count);
330+ count++;
331+ }
332+ return(count);
333+}
334+
335+/*
336+ - regcomp - compile a regular expression into internal code
337+ *
338+ * We can't allocate space until we know how big the compiled form will be,
339+ * but we can't compile it (and thus know how big it is) until we've got a
340+ * place to put the code. So we cheat: we compile it twice, once with code
341+ * generation turned off and size counting turned on, and once "for real".
342+ * This also means that we don't allocate space until we are sure that the
343+ * thing really will compile successfully, and we never have to move the
344+ * code and thus invalidate pointers into it. (Note that it has to be in
345+ * one piece because free() must be able to free it all.)
346+ *
347+ * Beware that the optimization-preparation code in here knows about some
348+ * of the structure of the compiled regexp.
349+ */
350+regexp *
351+regcomp(char *exp,int *patternsize)
352+{
353+ register regexp *r;
354+ register char *scan;
355+ register char *longest;
356+ register int len;
357+ int flags;
358+ struct match_globals g;
359+
360+ /* commented out by ethan
361+ extern char *malloc();
362+ */
363+
364+ if (exp == NULL)
365+ FAIL("NULL argument");
366+
367+ /* First pass: determine size, legality. */
368+ g.regparse = exp;
369+ g.regnpar = 1;
370+ g.regsize = 0L;
371+ g.regcode = &g.regdummy;
372+ regc(&g, MAGIC);
373+ if (reg(&g, 0, &flags) == NULL)
374+ return(NULL);
375+
376+ /* Small enough for pointer-storage convention? */
377+ if (g.regsize >= 32767L) /* Probably could be 65535L. */
378+ FAIL("regexp too big");
379+
380+ /* Allocate space. */
381+ *patternsize=sizeof(regexp) + (unsigned)g.regsize;
382+ r = (regexp *)malloc(sizeof(regexp) + (unsigned)g.regsize);
383+ if (r == NULL)
384+ FAIL("out of space");
385+
386+ /* Second pass: emit code. */
387+ g.regparse = exp;
388+ g.regnpar = 1;
389+ g.regcode = r->program;
390+ regc(&g, MAGIC);
391+ if (reg(&g, 0, &flags) == NULL)
392+ return(NULL);
393+
394+ /* Dig out information for optimizations. */
395+ r->regstart = '\0'; /* Worst-case defaults. */
396+ r->reganch = 0;
397+ r->regmust = NULL;
398+ r->regmlen = 0;
399+ scan = r->program+1; /* First BRANCH. */
400+ if (OP(regnext(&g, scan)) == END) { /* Only one top-level choice. */
401+ scan = OPERAND(scan);
402+
403+ /* Starting-point info. */
404+ if (OP(scan) == EXACTLY)
405+ r->regstart = *OPERAND(scan);
406+ else if (OP(scan) == BOL)
407+ r->reganch++;
408+
409+ /*
410+ * If there's something expensive in the r.e., find the
411+ * longest literal string that must appear and make it the
412+ * regmust. Resolve ties in favor of later strings, since
413+ * the regstart check works with the beginning of the r.e.
414+ * and avoiding duplication strengthens checking. Not a
415+ * strong reason, but sufficient in the absence of others.
416+ */
417+ if (flags&SPSTART) {
418+ longest = NULL;
419+ len = 0;
420+ for (; scan != NULL; scan = regnext(&g, scan))
421+ if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
422+ longest = OPERAND(scan);
423+ len = strlen(OPERAND(scan));
424+ }
425+ r->regmust = longest;
426+ r->regmlen = len;
427+ }
428+ }
429+
430+ return(r);
431+}
432+
433+/*
434+ - reg - regular expression, i.e. main body or parenthesized thing
435+ *
436+ * Caller must absorb opening parenthesis.
437+ *
438+ * Combining parenthesis handling with the base level of regular expression
439+ * is a trifle forced, but the need to tie the tails of the branches to what
440+ * follows makes it hard to avoid.
441+ */
442+static char *
443+reg(struct match_globals *g, int paren, int *flagp /* Parenthesized? */ )
444+{
445+ register char *ret;
446+ register char *br;
447+ register char *ender;
448+ register int parno = 0; /* 0 makes gcc happy */
449+ int flags;
450+
451+ *flagp = HASWIDTH; /* Tentatively. */
452+
453+ /* Make an OPEN node, if parenthesized. */
454+ if (paren) {
455+ if (g->regnpar >= NSUBEXP)
456+ FAIL("too many ()");
457+ parno = g->regnpar;
458+ g->regnpar++;
459+ ret = regnode(g, OPEN+parno);
460+ } else
461+ ret = NULL;
462+
463+ /* Pick up the branches, linking them together. */
464+ br = regbranch(g, &flags);
465+ if (br == NULL)
466+ return(NULL);
467+ if (ret != NULL)
468+ regtail(g, ret, br); /* OPEN -> first. */
469+ else
470+ ret = br;
471+ if (!(flags&HASWIDTH))
472+ *flagp &= ~HASWIDTH;
473+ *flagp |= flags&SPSTART;
474+ while (*g->regparse == '|') {
475+ g->regparse++;
476+ br = regbranch(g, &flags);
477+ if (br == NULL)
478+ return(NULL);
479+ regtail(g, ret, br); /* BRANCH -> BRANCH. */
480+ if (!(flags&HASWIDTH))
481+ *flagp &= ~HASWIDTH;
482+ *flagp |= flags&SPSTART;
483+ }
484+
485+ /* Make a closing node, and hook it on the end. */
486+ ender = regnode(g, (paren) ? CLOSE+parno : END);
487+ regtail(g, ret, ender);
488+
489+ /* Hook the tails of the branches to the closing node. */
490+ for (br = ret; br != NULL; br = regnext(g, br))
491+ regoptail(g, br, ender);
492+
493+ /* Check for proper termination. */
494+ if (paren && *g->regparse++ != ')') {
495+ FAIL("unmatched ()");
496+ } else if (!paren && *g->regparse != '\0') {
497+ if (*g->regparse == ')') {
498+ FAIL("unmatched ()");
499+ } else
500+ FAIL("junk on end"); /* "Can't happen". */
501+ /* NOTREACHED */
502+ }
503+
504+ return(ret);
505+}
506+
507+/*
508+ - regbranch - one alternative of an | operator
509+ *
510+ * Implements the concatenation operator.
511+ */
512+static char *
513+regbranch(struct match_globals *g, int *flagp)
514+{
515+ register char *ret;
516+ register char *chain;
517+ register char *latest;
518+ int flags;
519+
520+ *flagp = WORST; /* Tentatively. */
521+
522+ ret = regnode(g, BRANCH);
523+ chain = NULL;
524+ while (*g->regparse != '\0' && *g->regparse != '|' && *g->regparse != ')') {
525+ latest = regpiece(g, &flags);
526+ if (latest == NULL)
527+ return(NULL);
528+ *flagp |= flags&HASWIDTH;
529+ if (chain == NULL) /* First piece. */
530+ *flagp |= flags&SPSTART;
531+ else
532+ regtail(g, chain, latest);
533+ chain = latest;
534+ }
535+ if (chain == NULL) /* Loop ran zero times. */
536+ (void) regnode(g, NOTHING);
537+
538+ return(ret);
539+}
540+
541+/*
542+ - regpiece - something followed by possible [*+?]
543+ *
544+ * Note that the branching code sequences used for ? and the general cases
545+ * of * and + are somewhat optimized: they use the same NOTHING node as
546+ * both the endmarker for their branch list and the body of the last branch.
547+ * It might seem that this node could be dispensed with entirely, but the
548+ * endmarker role is not redundant.
549+ */
550+static char *
551+regpiece(struct match_globals *g, int *flagp)
552+{
553+ register char *ret;
554+ register char op;
555+ register char *next;
556+ int flags;
557+
558+ ret = regatom(g, &flags);
559+ if (ret == NULL)
560+ return(NULL);
561+
562+ op = *g->regparse;
563+ if (!ISMULT(op)) {
564+ *flagp = flags;
565+ return(ret);
566+ }
567+
568+ if (!(flags&HASWIDTH) && op != '?')
569+ FAIL("*+ operand could be empty");
570+ *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
571+
572+ if (op == '*' && (flags&SIMPLE))
573+ reginsert(g, STAR, ret);
574+ else if (op == '*') {
575+ /* Emit x* as (x&|), where & means "self". */
576+ reginsert(g, BRANCH, ret); /* Either x */
577+ regoptail(g, ret, regnode(g, BACK)); /* and loop */
578+ regoptail(g, ret, ret); /* back */
579+ regtail(g, ret, regnode(g, BRANCH)); /* or */
580+ regtail(g, ret, regnode(g, NOTHING)); /* null. */
581+ } else if (op == '+' && (flags&SIMPLE))
582+ reginsert(g, PLUS, ret);
583+ else if (op == '+') {
584+ /* Emit x+ as x(&|), where & means "self". */
585+ next = regnode(g, BRANCH); /* Either */
586+ regtail(g, ret, next);
587+ regtail(g, regnode(g, BACK), ret); /* loop back */
588+ regtail(g, next, regnode(g, BRANCH)); /* or */
589+ regtail(g, ret, regnode(g, NOTHING)); /* null. */
590+ } else if (op == '?') {
591+ /* Emit x? as (x|) */
592+ reginsert(g, BRANCH, ret); /* Either x */
593+ regtail(g, ret, regnode(g, BRANCH)); /* or */
594+ next = regnode(g, NOTHING); /* null. */
595+ regtail(g, ret, next);
596+ regoptail(g, ret, next);
597+ }
598+ g->regparse++;
599+ if (ISMULT(*g->regparse))
600+ FAIL("nested *?+");
601+
602+ return(ret);
603+}
604+
605+/*
606+ - regatom - the lowest level
607+ *
608+ * Optimization: gobbles an entire sequence of ordinary characters so that
609+ * it can turn them into a single node, which is smaller to store and
610+ * faster to run. Backslashed characters are exceptions, each becoming a
611+ * separate node; the code is simpler that way and it's not worth fixing.
612+ */
613+static char *
614+regatom(struct match_globals *g, int *flagp)
615+{
616+ register char *ret;
617+ int flags;
618+
619+ *flagp = WORST; /* Tentatively. */
620+
621+ switch (*g->regparse++) {
622+ case '^':
623+ ret = regnode(g, BOL);
624+ break;
625+ case '$':
626+ ret = regnode(g, EOL);
627+ break;
628+ case '.':
629+ ret = regnode(g, ANY);
630+ *flagp |= HASWIDTH|SIMPLE;
631+ break;
632+ case '[': {
633+ register int class;
634+ register int classend;
635+
636+ if (*g->regparse == '^') { /* Complement of range. */
637+ ret = regnode(g, ANYBUT);
638+ g->regparse++;
639+ } else
640+ ret = regnode(g, ANYOF);
641+ if (*g->regparse == ']' || *g->regparse == '-')
642+ regc(g, *g->regparse++);
643+ while (*g->regparse != '\0' && *g->regparse != ']') {
644+ if (*g->regparse == '-') {
645+ g->regparse++;
646+ if (*g->regparse == ']' || *g->regparse == '\0')
647+ regc(g, '-');
648+ else {
649+ class = UCHARAT(g->regparse-2)+1;
650+ classend = UCHARAT(g->regparse);
651+ if (class > classend+1)
652+ FAIL("invalid [] range");
653+ for (; class <= classend; class++)
654+ regc(g, class);
655+ g->regparse++;
656+ }
657+ } else
658+ regc(g, *g->regparse++);
659+ }
660+ regc(g, '\0');
661+ if (*g->regparse != ']')
662+ FAIL("unmatched []");
663+ g->regparse++;
664+ *flagp |= HASWIDTH|SIMPLE;
665+ }
666+ break;
667+ case '(':
668+ ret = reg(g, 1, &flags);
669+ if (ret == NULL)
670+ return(NULL);
671+ *flagp |= flags&(HASWIDTH|SPSTART);
672+ break;
673+ case '\0':
674+ case '|':
675+ case ')':
676+ FAIL("internal urp"); /* Supposed to be caught earlier. */
677+ break;
678+ case '?':
679+ case '+':
680+ case '*':
681+ FAIL("?+* follows nothing");
682+ break;
683+ case '\\':
684+ if (*g->regparse == '\0')
685+ FAIL("trailing \\");
686+ ret = regnode(g, EXACTLY);
687+ regc(g, *g->regparse++);
688+ regc(g, '\0');
689+ *flagp |= HASWIDTH|SIMPLE;
690+ break;
691+ default: {
692+ register int len;
693+ register char ender;
694+
695+ g->regparse--;
696+ len = my_strcspn((const char *)g->regparse, (const char *)META);
697+ if (len <= 0)
698+ FAIL("internal disaster");
699+ ender = *(g->regparse+len);
700+ if (len > 1 && ISMULT(ender))
701+ len--; /* Back off clear of ?+* operand. */
702+ *flagp |= HASWIDTH;
703+ if (len == 1)
704+ *flagp |= SIMPLE;
705+ ret = regnode(g, EXACTLY);
706+ while (len > 0) {
707+ regc(g, *g->regparse++);
708+ len--;
709+ }
710+ regc(g, '\0');
711+ }
712+ break;
713+ }
714+
715+ return(ret);
716+}
717+
718+/*
719+ - regnode - emit a node
720+ */
721+static char * /* Location. */
722+regnode(struct match_globals *g, char op)
723+{
724+ register char *ret;
725+ register char *ptr;
726+
727+ ret = g->regcode;
728+ if (ret == &g->regdummy) {
729+ g->regsize += 3;
730+ return(ret);
731+ }
732+
733+ ptr = ret;
734+ *ptr++ = op;
735+ *ptr++ = '\0'; /* Null "next" pointer. */
736+ *ptr++ = '\0';
737+ g->regcode = ptr;
738+
739+ return(ret);
740+}
741+
742+/*
743+ - regc - emit (if appropriate) a byte of code
744+ */
745+static void
746+regc(struct match_globals *g, char b)
747+{
748+ if (g->regcode != &g->regdummy)
749+ *g->regcode++ = b;
750+ else
751+ g->regsize++;
752+}
753+
754+/*
755+ - reginsert - insert an operator in front of already-emitted operand
756+ *
757+ * Means relocating the operand.
758+ */
759+static void
760+reginsert(struct match_globals *g, char op, char* opnd)
761+{
762+ register char *src;
763+ register char *dst;
764+ register char *place;
765+
766+ if (g->regcode == &g->regdummy) {
767+ g->regsize += 3;
768+ return;
769+ }
770+
771+ src = g->regcode;
772+ g->regcode += 3;
773+ dst = g->regcode;
774+ while (src > opnd)
775+ *--dst = *--src;
776+
777+ place = opnd; /* Op node, where operand used to be. */
778+ *place++ = op;
779+ *place++ = '\0';
780+ *place++ = '\0';
781+}
782+
783+/*
784+ - regtail - set the next-pointer at the end of a node chain
785+ */
786+static void
787+regtail(struct match_globals *g, char *p, char *val)
788+{
789+ register char *scan;
790+ register char *temp;
791+ register int offset;
792+
793+ if (p == &g->regdummy)
794+ return;
795+
796+ /* Find last node. */
797+ scan = p;
798+ for (;;) {
799+ temp = regnext(g, scan);
800+ if (temp == NULL)
801+ break;
802+ scan = temp;
803+ }
804+
805+ if (OP(scan) == BACK)
806+ offset = scan - val;
807+ else
808+ offset = val - scan;
809+ *(scan+1) = (offset>>8)&0377;
810+ *(scan+2) = offset&0377;
811+}
812+
813+/*
814+ - regoptail - regtail on operand of first argument; nop if operandless
815+ */
816+static void
817+regoptail(struct match_globals *g, char *p, char *val)
818+{
819+ /* "Operandless" and "op != BRANCH" are synonymous in practice. */
820+ if (p == NULL || p == &g->regdummy || OP(p) != BRANCH)
821+ return;
822+ regtail(g, OPERAND(p), val);
823+}
824+
825+/*
826+ * regexec and friends
827+ */
828+
829+
830+/*
831+ * Forwards.
832+ */
833+STATIC int regtry(struct match_globals *g, regexp *prog, char *string);
834+STATIC int regmatch(struct match_globals *g, char *prog);
835+STATIC int regrepeat(struct match_globals *g, char *p);
836+
837+#ifdef DEBUG
838+int regnarrate = 0;
839+void regdump();
840+STATIC char *regprop(char *op);
841+#endif
842+
843+/*
844+ - regexec - match a regexp against a string
845+ */
846+int
847+regexec(regexp *prog, char *string)
848+{
849+ register char *s;
850+ struct match_globals g;
851+
852+ /* Be paranoid... */
853+ if (prog == NULL || string == NULL) {
854+ printk("<3>Regexp: NULL parameter\n");
855+ return(0);
856+ }
857+
858+ /* Check validity of program. */
859+ if (UCHARAT(prog->program) != MAGIC) {
860+ printk("<3>Regexp: corrupted program\n");
861+ return(0);
862+ }
863+
864+ /* If there is a "must appear" string, look for it. */
865+ if (prog->regmust != NULL) {
866+ s = string;
867+ while ((s = strchr(s, prog->regmust[0])) != NULL) {
868+ if (strncmp(s, prog->regmust, prog->regmlen) == 0)
869+ break; /* Found it. */
870+ s++;
871+ }
872+ if (s == NULL) /* Not present. */
873+ return(0);
874+ }
875+
876+ /* Mark beginning of line for ^ . */
877+ g.regbol = string;
878+
879+ /* Simplest case: anchored match need be tried only once. */
880+ if (prog->reganch)
881+ return(regtry(&g, prog, string));
882+
883+ /* Messy cases: unanchored match. */
884+ s = string;
885+ if (prog->regstart != '\0')
886+ /* We know what char it must start with. */
887+ while ((s = strchr(s, prog->regstart)) != NULL) {
888+ if (regtry(&g, prog, s))
889+ return(1);
890+ s++;
891+ }
892+ else
893+ /* We don't -- general case. */
894+ do {
895+ if (regtry(&g, prog, s))
896+ return(1);
897+ } while (*s++ != '\0');
898+
899+ /* Failure. */
900+ return(0);
901+}
902+
903+/*
904+ - regtry - try match at specific point
905+ */
906+static int /* 0 failure, 1 success */
907+regtry(struct match_globals *g, regexp *prog, char *string)
908+{
909+ register int i;
910+ register char **sp;
911+ register char **ep;
912+
913+ g->reginput = string;
914+ g->regstartp = prog->startp;
915+ g->regendp = prog->endp;
916+
917+ sp = prog->startp;
918+ ep = prog->endp;
919+ for (i = NSUBEXP; i > 0; i--) {
920+ *sp++ = NULL;
921+ *ep++ = NULL;
922+ }
923+ if (regmatch(g, prog->program + 1)) {
924+ prog->startp[0] = string;
925+ prog->endp[0] = g->reginput;
926+ return(1);
927+ } else
928+ return(0);
929+}
930+
931+/*
932+ - regmatch - main matching routine
933+ *
934+ * Conceptually the strategy is simple: check to see whether the current
935+ * node matches, call self recursively to see whether the rest matches,
936+ * and then act accordingly. In practice we make some effort to avoid
937+ * recursion, in particular by going through "ordinary" nodes (that don't
938+ * need to know whether the rest of the match failed) by a loop instead of
939+ * by recursion.
940+ */
941+static int /* 0 failure, 1 success */
942+regmatch(struct match_globals *g, char *prog)
943+{
944+ register char *scan = prog; /* Current node. */
945+ char *next; /* Next node. */
946+
947+#ifdef DEBUG
948+ if (scan != NULL && regnarrate)
949+ fprintf(stderr, "%s(\n", regprop(scan));
950+#endif
951+ while (scan != NULL) {
952+#ifdef DEBUG
953+ if (regnarrate)
954+ fprintf(stderr, "%s...\n", regprop(scan));
955+#endif
956+ next = regnext(g, scan);
957+
958+ switch (OP(scan)) {
959+ case BOL:
960+ if (g->reginput != g->regbol)
961+ return(0);
962+ break;
963+ case EOL:
964+ if (*g->reginput != '\0')
965+ return(0);
966+ break;
967+ case ANY:
968+ if (*g->reginput == '\0')
969+ return(0);
970+ g->reginput++;
971+ break;
972+ case EXACTLY: {
973+ register int len;
974+ register char *opnd;
975+
976+ opnd = OPERAND(scan);
977+ /* Inline the first character, for speed. */
978+ if (*opnd != *g->reginput)
979+ return(0);
980+ len = strlen(opnd);
981+ if (len > 1 && strncmp(opnd, g->reginput, len) != 0)
982+ return(0);
983+ g->reginput += len;
984+ }
985+ break;
986+ case ANYOF:
987+ if (*g->reginput == '\0' || strchr(OPERAND(scan), *g->reginput) == NULL)
988+ return(0);
989+ g->reginput++;
990+ break;
991+ case ANYBUT:
992+ if (*g->reginput == '\0' || strchr(OPERAND(scan), *g->reginput) != NULL)
993+ return(0);
994+ g->reginput++;
995+ break;
996+ case NOTHING:
997+ case BACK:
998+ break;
999+ case OPEN+1:
1000+ case OPEN+2:
1001+ case OPEN+3:
1002+ case OPEN+4:
1003+ case OPEN+5:
1004+ case OPEN+6:
1005+ case OPEN+7:
1006+ case OPEN+8:
1007+ case OPEN+9: {
1008+ register int no;
1009+ register char *save;
1010+
1011+ no = OP(scan) - OPEN;
1012+ save = g->reginput;
1013+
1014+ if (regmatch(g, next)) {
1015+ /*
1016+ * Don't set startp if some later
1017+ * invocation of the same parentheses
1018+ * already has.
1019+ */
1020+ if (g->regstartp[no] == NULL)
1021+ g->regstartp[no] = save;
1022+ return(1);
1023+ } else
1024+ return(0);
1025+ }
1026+ break;
1027+ case CLOSE+1:
1028+ case CLOSE+2:
1029+ case CLOSE+3:
1030+ case CLOSE+4:
1031+ case CLOSE+5:
1032+ case CLOSE+6:
1033+ case CLOSE+7:
1034+ case CLOSE+8:
1035+ case CLOSE+9:
1036+ {
1037+ register int no;
1038+ register char *save;
1039+
1040+ no = OP(scan) - CLOSE;
1041+ save = g->reginput;
1042+
1043+ if (regmatch(g, next)) {
1044+ /*
1045+ * Don't set endp if some later
1046+ * invocation of the same parentheses
1047+ * already has.
1048+ */
1049+ if (g->regendp[no] == NULL)
1050+ g->regendp[no] = save;
1051+ return(1);
1052+ } else
1053+ return(0);
1054+ }
1055+ break;
1056+ case BRANCH: {
1057+ register char *save;
1058+
1059+ if (OP(next) != BRANCH) /* No choice. */
1060+ next = OPERAND(scan); /* Avoid recursion. */
1061+ else {
1062+ do {
1063+ save = g->reginput;
1064+ if (regmatch(g, OPERAND(scan)))
1065+ return(1);
1066+ g->reginput = save;
1067+ scan = regnext(g, scan);
1068+ } while (scan != NULL && OP(scan) == BRANCH);
1069+ return(0);
1070+ /* NOTREACHED */
1071+ }
1072+ }
1073+ break;
1074+ case STAR:
1075+ case PLUS: {
1076+ register char nextch;
1077+ register int no;
1078+ register char *save;
1079+ register int min;
1080+
1081+ /*
1082+ * Lookahead to avoid useless match attempts
1083+ * when we know what character comes next.
1084+ */
1085+ nextch = '\0';
1086+ if (OP(next) == EXACTLY)
1087+ nextch = *OPERAND(next);
1088+ min = (OP(scan) == STAR) ? 0 : 1;
1089+ save = g->reginput;
1090+ no = regrepeat(g, OPERAND(scan));
1091+ while (no >= min) {
1092+ /* If it could work, try it. */
1093+ if (nextch == '\0' || *g->reginput == nextch)
1094+ if (regmatch(g, next))
1095+ return(1);
1096+ /* Couldn't or didn't -- back up. */
1097+ no--;
1098+ g->reginput = save + no;
1099+ }
1100+ return(0);
1101+ }
1102+ break;
1103+ case END:
1104+ return(1); /* Success! */
1105+ break;
1106+ default:
1107+ printk("<3>Regexp: memory corruption\n");
1108+ return(0);
1109+ break;
1110+ }
1111+
1112+ scan = next;
1113+ }
1114+
1115+ /*
1116+ * We get here only if there's trouble -- normally "case END" is
1117+ * the terminating point.
1118+ */
1119+ printk("<3>Regexp: corrupted pointers\n");
1120+ return(0);
1121+}
1122+
1123+/*
1124+ - regrepeat - repeatedly match something simple, report how many
1125+ */
1126+static int
1127+regrepeat(struct match_globals *g, char *p)
1128+{
1129+ register int count = 0;
1130+ register char *scan;
1131+ register char *opnd;
1132+
1133+ scan = g->reginput;
1134+ opnd = OPERAND(p);
1135+ switch (OP(p)) {
1136+ case ANY:
1137+ count = strlen(scan);
1138+ scan += count;
1139+ break;
1140+ case EXACTLY:
1141+ while (*opnd == *scan) {
1142+ count++;
1143+ scan++;
1144+ }
1145+ break;
1146+ case ANYOF:
1147+ while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
1148+ count++;
1149+ scan++;
1150+ }
1151+ break;
1152+ case ANYBUT:
1153+ while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
1154+ count++;
1155+ scan++;
1156+ }
1157+ break;
1158+ default: /* Oh dear. Called inappropriately. */
1159+ printk("<3>Regexp: internal foulup\n");
1160+ count = 0; /* Best compromise. */
1161+ break;
1162+ }
1163+ g->reginput = scan;
1164+
1165+ return(count);
1166+}
1167+
1168+/*
1169+ - regnext - dig the "next" pointer out of a node
1170+ */
1171+static char*
1172+regnext(struct match_globals *g, char *p)
1173+{
1174+ register int offset;
1175+
1176+ if (p == &g->regdummy)
1177+ return(NULL);
1178+
1179+ offset = NEXT(p);
1180+ if (offset == 0)
1181+ return(NULL);
1182+
1183+ if (OP(p) == BACK)
1184+ return(p-offset);
1185+ else
1186+ return(p+offset);
1187+}
1188+
1189+#ifdef DEBUG
1190+
1191+STATIC char *regprop();
1192+
1193+/*
1194+ - regdump - dump a regexp onto stdout in vaguely comprehensible form
1195+ */
1196+void
1197+regdump(regexp *r)
1198+{
1199+ register char *s;
1200+ register char op = EXACTLY; /* Arbitrary non-END op. */
1201+ register char *next;
1202+ /* extern char *strchr(); */
1203+
1204+
1205+ s = r->program + 1;
1206+ while (op != END) { /* While that wasn't END last time... */
1207+ op = OP(s);
1208+ printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */
1209+ next = regnext(s);
1210+ if (next == NULL) /* Next ptr. */
1211+ printf("(0)");
1212+ else
1213+ printf("(%d)", (s-r->program)+(next-s));
1214+ s += 3;
1215+ if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
1216+ /* Literal string, where present. */
1217+ while (*s != '\0') {
1218+ putchar(*s);
1219+ s++;
1220+ }
1221+ s++;
1222+ }
1223+ putchar('\n');
1224+ }
1225+
1226+ /* Header fields of interest. */
1227+ if (r->regstart != '\0')
1228+ printf("start `%c' ", r->regstart);
1229+ if (r->reganch)
1230+ printf("anchored ");
1231+ if (r->regmust != NULL)
1232+ printf("must have \"%s\"", r->regmust);
1233+ printf("\n");
1234+}
1235+
1236+/*
1237+ - regprop - printable representation of opcode
1238+ */
1239+static char *
1240+regprop(char *op)
1241+{
1242+#define BUFLEN 50
1243+ register char *p;
1244+ static char buf[BUFLEN];
1245+
1246+ strcpy(buf, ":");
1247+
1248+ switch (OP(op)) {
1249+ case BOL:
1250+ p = "BOL";
1251+ break;
1252+ case EOL:
1253+ p = "EOL";
1254+ break;
1255+ case ANY:
1256+ p = "ANY";
1257+ break;
1258+ case ANYOF:
1259+ p = "ANYOF";
1260+ break;
1261+ case ANYBUT:
1262+ p = "ANYBUT";
1263+ break;
1264+ case BRANCH:
1265+ p = "BRANCH";
1266+ break;
1267+ case EXACTLY:
1268+ p = "EXACTLY";
1269+ break;
1270+ case NOTHING:
1271+ p = "NOTHING";
1272+ break;
1273+ case BACK:
1274+ p = "BACK";
1275+ break;
1276+ case END:
1277+ p = "END";
1278+ break;
1279+ case OPEN+1:
1280+ case OPEN+2:
1281+ case OPEN+3:
1282+ case OPEN+4:
1283+ case OPEN+5:
1284+ case OPEN+6:
1285+ case OPEN+7:
1286+ case OPEN+8:
1287+ case OPEN+9:
1288+ snprintf(buf+strlen(buf),BUFLEN-strlen(buf), "OPEN%d", OP(op)-OPEN);
1289+ p = NULL;
1290+ break;
1291+ case CLOSE+1:
1292+ case CLOSE+2:
1293+ case CLOSE+3:
1294+ case CLOSE+4:
1295+ case CLOSE+5:
1296+ case CLOSE+6:
1297+ case CLOSE+7:
1298+ case CLOSE+8:
1299+ case CLOSE+9:
1300+ snprintf(buf+strlen(buf),BUFLEN-strlen(buf), "CLOSE%d", OP(op)-CLOSE);
1301+ p = NULL;
1302+ break;
1303+ case STAR:
1304+ p = "STAR";
1305+ break;
1306+ case PLUS:
1307+ p = "PLUS";
1308+ break;
1309+ default:
1310+ printk("<3>Regexp: corrupted opcode\n");
1311+ break;
1312+ }
1313+ if (p != NULL)
1314+ strncat(buf, p, BUFLEN-strlen(buf));
1315+ return(buf);
1316+}
1317+#endif
1318+
1319+
1320diff -Naur linux-3.0.24.org/net/netfilter/regexp/regexp.h linux-3.0.24/net/netfilter/regexp/regexp.h
1321--- linux-3.0.24.org/net/netfilter/regexp/regexp.h 1970-01-01 01:00:00.000000000 +0100
1322+++ linux-3.0.24/net/netfilter/regexp/regexp.h 2012-03-15 20:08:49.066043520 +0100
1323@@ -0,0 +1,41 @@
1324+/*
1325+ * Definitions etc. for regexp(3) routines.
1326+ *
1327+ * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof],
1328+ * not the System V one.
1329+ */
1330+
1331+#ifndef REGEXP_H
1332+#define REGEXP_H
1333+
1334+
1335+/*
1336+http://www.opensource.apple.com/darwinsource/10.3/expect-1/expect/expect.h ,
1337+which contains a version of this library, says:
1338+
1339+ *
1340+ * NSUBEXP must be at least 10, and no greater than 117 or the parser
1341+ * will not work properly.
1342+ *
1343+
1344+However, it looks rather like this library is limited to 10. If you think
1345+otherwise, let us know.
1346+*/
1347+
1348+#define NSUBEXP 10
1349+typedef struct regexp {
1350+ char *startp[NSUBEXP];
1351+ char *endp[NSUBEXP];
1352+ char regstart; /* Internal use only. */
1353+ char reganch; /* Internal use only. */
1354+ char *regmust; /* Internal use only. */
1355+ int regmlen; /* Internal use only. */
1356+ char program[1]; /* Unwarranted chumminess with compiler. */
1357+} regexp;
1358+
1359+regexp * regcomp(char *exp, int *patternsize);
1360+int regexec(regexp *prog, char *string);
1361+void regsub(regexp *prog, char *source, char *dest);
1362+void regerror(char *s);
1363+
1364+#endif
1365diff -Naur linux-3.0.24.org/net/netfilter/regexp/regmagic.h linux-3.0.24/net/netfilter/regexp/regmagic.h
1366--- linux-3.0.24.org/net/netfilter/regexp/regmagic.h 1970-01-01 01:00:00.000000000 +0100
1367+++ linux-3.0.24/net/netfilter/regexp/regmagic.h 2012-03-15 20:08:49.066043520 +0100
1368@@ -0,0 +1,5 @@
1369+/*
1370+ * The first byte of the regexp internal "program" is actually this magic
1371+ * number; the start node begins in the second byte.
1372+ */
1373+#define MAGIC 0234
1374diff -Naur linux-3.0.24.org/net/netfilter/regexp/regsub.c linux-3.0.24/net/netfilter/regexp/regsub.c
1375--- linux-3.0.24.org/net/netfilter/regexp/regsub.c 1970-01-01 01:00:00.000000000 +0100
1376+++ linux-3.0.24/net/netfilter/regexp/regsub.c 2012-03-15 20:08:49.076047746 +0100
1377@@ -0,0 +1,95 @@
1378+/*
1379+ * regsub
1380+ * @(#)regsub.c 1.3 of 2 April 86
1381+ *
1382+ * Copyright (c) 1986 by University of Toronto.
1383+ * Written by Henry Spencer. Not derived from licensed software.
1384+ *
1385+ * Permission is granted to anyone to use this software for any
1386+ * purpose on any computer system, and to redistribute it freely,
1387+ * subject to the following restrictions:
1388+ *
1389+ * 1. The author is not responsible for the consequences of use of
1390+ * this software, no matter how awful, even if they arise
1391+ * from defects in it.
1392+ *
1393+ * 2. The origin of this software must not be misrepresented, either
1394+ * by explicit claim or by omission.
1395+ *
1396+ * 3. Altered versions must be plainly marked as such, and must not
1397+ * be misrepresented as being the original software.
1398+ *
1399+ *
1400+ * This code was modified by Ethan Sommer to work within the kernel
1401+ * (it now uses kmalloc etc..)
1402+ *
1403+ */
1404+#include "regexp.h"
1405+#include "regmagic.h"
1406+#include <linux/string.h>
1407+
1408+
1409+#ifndef CHARBITS
1410+#define UCHARAT(p) ((int)*(unsigned char *)(p))
1411+#else
1412+#define UCHARAT(p) ((int)*(p)&CHARBITS)
1413+#endif
1414+
1415+#if 0
1416+//void regerror(char * s)
1417+//{
1418+// printk("regexp(3): %s", s);
1419+// /* NOTREACHED */
1420+//}
1421+#endif
1422+
1423+/*
1424+ - regsub - perform substitutions after a regexp match
1425+ */
1426+void
1427+regsub(regexp * prog, char * source, char * dest)
1428+{
1429+ register char *src;
1430+ register char *dst;
1431+ register char c;
1432+ register int no;
1433+ register int len;
1434+
1435+ /* Not necessary and gcc doesn't like it -MLS */
1436+ /*extern char *strncpy();*/
1437+
1438+ if (prog == NULL || source == NULL || dest == NULL) {
1439+ regerror("NULL parm to regsub");
1440+ return;
1441+ }
1442+ if (UCHARAT(prog->program) != MAGIC) {
1443+ regerror("damaged regexp fed to regsub");
1444+ return;
1445+ }
1446+
1447+ src = source;
1448+ dst = dest;
1449+ while ((c = *src++) != '\0') {
1450+ if (c == '&')
1451+ no = 0;
1452+ else if (c == '\\' && '0' <= *src && *src <= '9')
1453+ no = *src++ - '0';
1454+ else
1455+ no = -1;
1456+
1457+ if (no < 0) { /* Ordinary character. */
1458+ if (c == '\\' && (*src == '\\' || *src == '&'))
1459+ c = *src++;
1460+ *dst++ = c;
1461+ } else if (prog->startp[no] != NULL && prog->endp[no] != NULL) {
1462+ len = prog->endp[no] - prog->startp[no];
1463+ (void) strncpy(dst, prog->startp[no], len);
1464+ dst += len;
1465+ if (len != 0 && *(dst-1) == '\0') { /* strncpy hit NUL. */
1466+ regerror("damaged match string");
1467+ return;
1468+ }
1469+ }
1470+ }
1471+ *dst++ = '\0';
1472+}
1473diff -Naur linux-3.0.24.org/net/netfilter/xt_layer7.c linux-3.0.24/net/netfilter/xt_layer7.c
1474--- linux-3.0.24.org/net/netfilter/xt_layer7.c 1970-01-01 01:00:00.000000000 +0100
1475+++ linux-3.0.24/net/netfilter/xt_layer7.c 2012-03-20 01:44:50.907527097 +0100
1476@@ -0,0 +1,684 @@
1477+/*
1478+ Kernel module to match application layer (OSI layer 7) data in connections.
1479+
1480+ http://l7-filter.sf.net
1481+
1482+ (C) 2003-2009 Matthew Strait and Ethan Sommer.
1483+
1484+ This program is free software; you can redistribute it and/or
1485+ modify it under the terms of the GNU General Public License
1486+ as published by the Free Software Foundation; either version
1487+ 2 of the License, or (at your option) any later version.
1488+ http://www.gnu.org/licenses/gpl.txt
1489+
1490+ Based on ipt_string.c (C) 2000 Emmanuel Roger <winfield@freegates.be>,
1491+ xt_helper.c (C) 2002 Harald Welte and cls_layer7.c (C) 2003 Matthew Strait,
1492+ Ethan Sommer, Justin Levandoski.
1493+*/
1494+
1495+#include <linux/spinlock.h>
1496+#include <linux/version.h>
1497+#include <net/ip.h>
1498+#include <net/tcp.h>
1499+#include <linux/module.h>
1500+#include <linux/skbuff.h>
1501+#include <linux/netfilter.h>
1502+#include <net/netfilter/nf_conntrack.h>
1503+#include <net/netfilter/nf_conntrack_core.h>
1504+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
1505+#include <net/netfilter/nf_conntrack_extend.h>
1506+#include <net/netfilter/nf_conntrack_acct.h>
1507+#endif
1508+#include <linux/netfilter/x_tables.h>
1509+#include <linux/netfilter/xt_layer7.h>
1510+#include <linux/ctype.h>
1511+#include <linux/proc_fs.h>
1512+
1513+#include "regexp/regexp.c"
1514+
1515+MODULE_LICENSE("GPL");
1516+MODULE_AUTHOR("Matthew Strait <quadong@users.sf.net>, Ethan Sommer <sommere@users.sf.net>");
1517+MODULE_DESCRIPTION("iptables application layer match module");
1518+MODULE_ALIAS("ipt_layer7");
1519+MODULE_VERSION("2.22ipfire");
1520+
1521+static int maxdatalen = 2048; // this is the default
1522+module_param(maxdatalen, int, 0444);
1523+MODULE_PARM_DESC(maxdatalen, "maximum bytes of data looked at by l7-filter");
1524+#ifdef CONFIG_NETFILTER_XT_MATCH_LAYER7_DEBUG
1525+ #define DPRINTK(format,args...) printk(format,##args)
1526+#else
1527+ #define DPRINTK(format,args...)
1528+#endif
1529+
1530+/* Number of packets whose data we look at.
1531+This can be modified through /proc/net/layer7_numpackets */
1532+static int num_packets = 10;
1533+
1534+static struct pattern_cache {
1535+ char * regex_string;
1536+ regexp * pattern;
1537+ struct pattern_cache * next;
1538+} * first_pattern_cache = NULL;
1539+
1540+DEFINE_SPINLOCK(l7_lock);
1541+
1542+static int total_acct_packets(struct nf_conn *ct)
1543+{
1544+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
1545+ BUG_ON(ct == NULL);
1546+ return (ct->counters[IP_CT_DIR_ORIGINAL].packets + ct->counters[IP_CT_DIR_REPLY].packets);
1547+#else
1548+ struct nf_conn_counter *acct;
1549+
1550+ BUG_ON(ct == NULL);
1551+ acct = nf_conn_acct_find(ct);
1552+ if (!acct)
1553+ return 0;
1554+ return (acct[IP_CT_DIR_ORIGINAL].packets + acct[IP_CT_DIR_REPLY].packets);
1555+#endif
1556+}
1557+
1558+#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
1559+/* Converts an unfriendly string into a friendly one by
1560+replacing unprintables with periods and all whitespace with " ". */
1561+static char * friendly_print(unsigned char * s)
1562+{
1563+ char * f = kmalloc(strlen(s) + 1, GFP_ATOMIC);
1564+ int i;
1565+
1566+ if(!f) {
1567+ if (net_ratelimit())
1568+ printk(KERN_ERR "layer7: out of memory in "
1569+ "friendly_print, bailing.\n");
1570+ return NULL;
1571+ }
1572+
1573+ for(i = 0; i < strlen(s); i++){
1574+ if(isprint(s[i]) && s[i] < 128) f[i] = s[i];
1575+ else if(isspace(s[i])) f[i] = ' ';
1576+ else f[i] = '.';
1577+ }
1578+ f[i] = '\0';
1579+ return f;
1580+}
1581+
1582+static char dec2hex(int i)
1583+{
1584+ switch (i) {
1585+ case 0 ... 9:
1586+ return (i + '0');
1587+ break;
1588+ case 10 ... 15:
1589+ return (i - 10 + 'a');
1590+ break;
1591+ default:
1592+ if (net_ratelimit())
1593+ printk("layer7: Problem in dec2hex\n");
1594+ return '\0';
1595+ }
1596+}
1597+
1598+static char * hex_print(unsigned char * s)
1599+{
1600+ char * g = kmalloc(strlen(s)*3 + 1, GFP_ATOMIC);
1601+ int i;
1602+
1603+ if(!g) {
1604+ if (net_ratelimit())
1605+ printk(KERN_ERR "layer7: out of memory in hex_print, "
1606+ "bailing.\n");
1607+ return NULL;
1608+ }
1609+
1610+ for(i = 0; i < strlen(s); i++) {
1611+ g[i*3 ] = dec2hex(s[i]/16);
1612+ g[i*3 + 1] = dec2hex(s[i]%16);
1613+ g[i*3 + 2] = ' ';
1614+ }
1615+ g[i*3] = '\0';
1616+
1617+ return g;
1618+}
1619+#endif // DEBUG
1620+
1621+/* Use instead of regcomp. As we expect to be seeing the same regexps over and
1622+over again, it make sense to cache the results. */
1623+static regexp * compile_and_cache(const char * regex_string,
1624+ const char * protocol)
1625+{
1626+ struct pattern_cache * node = first_pattern_cache;
1627+ struct pattern_cache * last_pattern_cache = first_pattern_cache;
1628+ struct pattern_cache * tmp;
1629+ unsigned int len;
1630+
1631+ while (node != NULL) {
1632+ if (!strcmp(node->regex_string, regex_string))
1633+ return node->pattern;
1634+
1635+ last_pattern_cache = node;/* points at the last non-NULL node */
1636+ node = node->next;
1637+ }
1638+
1639+ /* If we reach the end of the list, then we have not yet cached
1640+ the pattern for this regex. Let's do that now.
1641+ Be paranoid about running out of memory to avoid list corruption. */
1642+ tmp = kmalloc(sizeof(struct pattern_cache), GFP_ATOMIC);
1643+
1644+ if(!tmp) {
1645+ if (net_ratelimit())
1646+ printk(KERN_ERR "layer7: out of memory in "
1647+ "compile_and_cache, bailing.\n");
1648+ return NULL;
1649+ }
1650+
1651+ tmp->regex_string = kmalloc(strlen(regex_string) + 1, GFP_ATOMIC);
1652+ tmp->pattern = kmalloc(sizeof(struct regexp), GFP_ATOMIC);
1653+ tmp->next = NULL;
1654+
1655+ if(!tmp->regex_string || !tmp->pattern) {
1656+ if (net_ratelimit())
1657+ printk(KERN_ERR "layer7: out of memory in "
1658+ "compile_and_cache, bailing.\n");
1659+ kfree(tmp->regex_string);
1660+ kfree(tmp->pattern);
1661+ kfree(tmp);
1662+ return NULL;
1663+ }
1664+
1665+ /* Ok. The new node is all ready now. */
1666+ node = tmp;
1667+
1668+ if(first_pattern_cache == NULL) /* list is empty */
1669+ first_pattern_cache = node; /* make node the beginning */
1670+ else
1671+ last_pattern_cache->next = node; /* attach node to the end */
1672+
1673+ /* copy the string and compile the regex */
1674+ len = strlen(regex_string);
1675+ DPRINTK("layer7: about to compile this: \"%s\"\n", regex_string);
1676+ node->pattern = regcomp((char *)regex_string, &len);
1677+ if ( !node->pattern ) {
1678+ if (net_ratelimit())
1679+ printk(KERN_ERR "layer7: Error compiling regexp "
1680+ "\"%s\" (%s)\n",
1681+ regex_string, protocol);
1682+ /* pattern is now cached as NULL, so we won't try again. */
1683+ }
1684+
1685+ strcpy(node->regex_string, regex_string);
1686+ return node->pattern;
1687+}
1688+
1689+static int can_handle(const struct sk_buff *skb)
1690+{
1691+ if(!ip_hdr(skb)) /* not IP */
1692+ return 0;
1693+ if(ip_hdr(skb)->protocol != IPPROTO_TCP &&
1694+ ip_hdr(skb)->protocol != IPPROTO_UDP &&
1695+ ip_hdr(skb)->protocol != IPPROTO_ICMP)
1696+ return 0;
1697+ return 1;
1698+}
1699+
1700+/* Returns offset the into the skb->data that the application data starts */
1701+static int app_data_offset(const struct sk_buff *skb)
1702+{
1703+ /* In case we are ported somewhere (ebtables?) where ip_hdr(skb)
1704+ isn't set, this can be gotten from 4*(skb->data[0] & 0x0f) as well. */
1705+ int ip_hl = 4*ip_hdr(skb)->ihl;
1706+
1707+ if( ip_hdr(skb)->protocol == IPPROTO_TCP ) {
1708+ /* 12 == offset into TCP header for the header length field.
1709+ Can't get this with skb->h.th->doff because the tcphdr
1710+ struct doesn't get set when routing (this is confirmed to be
1711+ true in Netfilter as well as QoS.) */
1712+ int tcp_hl = 4*(skb->data[ip_hl + 12] >> 4);
1713+
1714+ return ip_hl + tcp_hl;
1715+ } else if( ip_hdr(skb)->protocol == IPPROTO_UDP ) {
1716+ return ip_hl + 8; /* UDP header is always 8 bytes */
1717+ } else if( ip_hdr(skb)->protocol == IPPROTO_ICMP ) {
1718+ return ip_hl + 8; /* ICMP header is 8 bytes */
1719+ } else {
1720+ if (net_ratelimit())
1721+ printk(KERN_ERR "layer7: tried to handle unknown "
1722+ "protocol!\n");
1723+ return ip_hl + 8; /* something reasonable */
1724+ }
1725+}
1726+
1727+/* handles whether there's a match when we aren't appending data anymore */
1728+static int match_no_append(struct nf_conn * conntrack,
1729+ struct nf_conn * master_conntrack,
1730+ enum ip_conntrack_info ctinfo,
1731+ enum ip_conntrack_info master_ctinfo,
1732+ const struct xt_layer7_info * info)
1733+{
1734+ /* If we're in here, throw the app data away */
1735+ if(master_conntrack->layer7.app_data != NULL) {
1736+
1737+ #ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
1738+ if(!master_conntrack->layer7.app_proto) {
1739+ char * f =
1740+ friendly_print(master_conntrack->layer7.app_data);
1741+ char * g =
1742+ hex_print(master_conntrack->layer7.app_data);
1743+ DPRINTK("\nl7-filter gave up after %d bytes "
1744+ "(%d packets):\n%s\n",
1745+ strlen(f), total_acct_packets(master_conntrack), f);
1746+ kfree(f);
1747+ DPRINTK("In hex: %s\n", g);
1748+ kfree(g);
1749+ }
1750+ #endif
1751+
1752+ kfree(master_conntrack->layer7.app_data);
1753+ master_conntrack->layer7.app_data = NULL; /* don't free again */
1754+ }
1755+
1756+ if(master_conntrack->layer7.app_proto){
1757+ /* Here child connections set their .app_proto (for /proc) */
1758+ if(!conntrack->layer7.app_proto) {
1759+ conntrack->layer7.app_proto =
1760+ kmalloc(strlen(master_conntrack->layer7.app_proto)+1,
1761+ GFP_ATOMIC);
1762+ if(!conntrack->layer7.app_proto){
1763+ if (net_ratelimit())
1764+ printk(KERN_ERR "layer7: out of memory "
1765+ "in match_no_append, "
1766+ "bailing.\n");
1767+ return 1;
1768+ }
1769+ strcpy(conntrack->layer7.app_proto,
1770+ master_conntrack->layer7.app_proto);
1771+ }
1772+
1773+ return (!strcmp(master_conntrack->layer7.app_proto,
1774+ info->protocol));
1775+ }
1776+ else {
1777+ /* If not classified, set to "unknown" to distinguish from
1778+ connections that are still being tested. */
1779+ master_conntrack->layer7.app_proto =
1780+ kmalloc(strlen("unknown")+1, GFP_ATOMIC);
1781+ if(!master_conntrack->layer7.app_proto){
1782+ if (net_ratelimit())
1783+ printk(KERN_ERR "layer7: out of memory in "
1784+ "match_no_append, bailing.\n");
1785+ return 1;
1786+ }
1787+ strcpy(master_conntrack->layer7.app_proto, "unknown");
1788+ return 0;
1789+ }
1790+}
1791+
1792+/* add the new app data to the conntrack. Return number of bytes added. */
1793+static int add_data(struct nf_conn * master_conntrack,
1794+ char * app_data, int appdatalen)
1795+{
1796+ int length = 0, i;
1797+ int oldlength = master_conntrack->layer7.app_data_len;
1798+
1799+ /* This is a fix for a race condition by Deti Fliegl. However, I'm not
1800+ clear on whether the race condition exists or whether this really
1801+ fixes it. I might just be being dense... Anyway, if it's not really
1802+ a fix, all it does is waste a very small amount of time. */
1803+ if(!master_conntrack->layer7.app_data) return 0;
1804+
1805+ /* Strip nulls. Make everything lower case (our regex lib doesn't
1806+ do case insensitivity). Add it to the end of the current data. */
1807+ for(i = 0; i < maxdatalen-oldlength-1 &&
1808+ i < appdatalen; i++) {
1809+ if(app_data[i] != '\0') {
1810+ /* the kernel version of tolower mungs 'upper ascii' */
1811+ master_conntrack->layer7.app_data[length+oldlength] =
1812+ isascii(app_data[i])?
1813+ tolower(app_data[i]) : app_data[i];
1814+ length++;
1815+ }
1816+ }
1817+
1818+ master_conntrack->layer7.app_data[length+oldlength] = '\0';
1819+ master_conntrack->layer7.app_data_len = length + oldlength;
1820+
1821+ return length;
1822+}
1823+
1824+/* taken from drivers/video/modedb.c */
1825+static int my_atoi(const char *s)
1826+{
1827+ int val = 0;
1828+
1829+ for (;; s++) {
1830+ switch (*s) {
1831+ case '0'...'9':
1832+ val = 10*val+(*s-'0');
1833+ break;
1834+ default:
1835+ return val;
1836+ }
1837+ }
1838+}
1839+
1840+/* write out num_packets to userland. */
1841+static int layer7_read_proc(char* page, char ** start, off_t off, int count,
1842+ int* eof, void * data)
1843+{
1844+ if(num_packets > 99 && net_ratelimit())
1845+ printk(KERN_ERR "layer7: NOT REACHED. num_packets too big\n");
1846+
1847+ page[0] = num_packets/10 + '0';
1848+ page[1] = num_packets%10 + '0';
1849+ page[2] = '\n';
1850+ page[3] = '\0';
1851+
1852+ *eof=1;
1853+
1854+ return 3;
1855+}
1856+
1857+/* Read in num_packets from userland */
1858+static int layer7_write_proc(struct file* file, const char* buffer,
1859+ unsigned long count, void *data)
1860+{
1861+ char * foo = kmalloc(count, GFP_ATOMIC);
1862+
1863+ if(!foo){
1864+ if (net_ratelimit())
1865+ printk(KERN_ERR "layer7: out of memory, bailing. "
1866+ "num_packets unchanged.\n");
1867+ return count;
1868+ }
1869+
1870+ if(copy_from_user(foo, buffer, count)) {
1871+ return -EFAULT;
1872+ }
1873+
1874+
1875+ num_packets = my_atoi(foo);
1876+ kfree (foo);
1877+
1878+ /* This has an arbitrary limit to make the math easier. I'm lazy.
1879+ But anyway, 99 is a LOT! If you want more, you're doing it wrong! */
1880+ if(num_packets > 99) {
1881+ printk(KERN_WARNING "layer7: num_packets can't be > 99.\n");
1882+ num_packets = 99;
1883+ } else if(num_packets < 1) {
1884+ printk(KERN_WARNING "layer7: num_packets can't be < 1.\n");
1885+ num_packets = 1;
1886+ }
1887+
1888+ return count;
1889+}
1890+
1891+static bool
1892+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
1893+match(const struct sk_buff *skbin, struct xt_action_param *par)
1894+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
1895+match(const struct sk_buff *skbin, const struct xt_match_param *par)
1896+#else
1897+match(const struct sk_buff *skbin,
1898+ const struct net_device *in,
1899+ const struct net_device *out,
1900+ const struct xt_match *match,
1901+ const void *matchinfo,
1902+ int offset,
1903+ unsigned int protoff,
1904+ bool *hotdrop)
1905+#endif
1906+{
1907+ /* sidestep const without getting a compiler warning... */
1908+ struct sk_buff * skb = (struct sk_buff *)skbin;
1909+
1910+ const struct xt_layer7_info * info =
1911+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
1912+ par->matchinfo;
1913+ #else
1914+ matchinfo;
1915+ #endif
1916+
1917+ enum ip_conntrack_info master_ctinfo, ctinfo;
1918+ struct nf_conn *master_conntrack, *conntrack;
1919+ unsigned char * app_data;
1920+ unsigned int pattern_result, appdatalen;
1921+ regexp * comppattern;
1922+
1923+ /* Be paranoid/incompetent - lock the entire match function. */
1924+ spin_lock_bh(&l7_lock);
1925+
1926+ if(!can_handle(skb)){
1927+ DPRINTK("layer7: This is some protocol I can't handle.\n");
1928+ spin_unlock_bh(&l7_lock);
1929+ return info->invert;
1930+ }
1931+
1932+ /* Treat parent & all its children together as one connection, except
1933+ for the purpose of setting conntrack->layer7.app_proto in the actual
1934+ connection. This makes /proc/net/ip_conntrack more satisfying. */
1935+ if(!(conntrack = nf_ct_get(skb, &ctinfo)) ||
1936+ !(master_conntrack=nf_ct_get(skb,&master_ctinfo))){
1937+ DPRINTK("layer7: couldn't get conntrack.\n");
1938+ spin_unlock_bh(&l7_lock);
1939+ return info->invert;
1940+ }
1941+
1942+ /* Try to get a master conntrack (and its master etc) for FTP, etc. */
1943+ while (master_ct(master_conntrack) != NULL)
1944+ master_conntrack = master_ct(master_conntrack);
1945+
1946+ /* if we've classified it or seen too many packets */
1947+ if(total_acct_packets(master_conntrack) > num_packets ||
1948+ master_conntrack->layer7.app_proto) {
1949+
1950+ pattern_result = match_no_append(conntrack, master_conntrack,
1951+ ctinfo, master_ctinfo, info);
1952+
1953+ /* skb->cb[0] == seen. Don't do things twice if there are
1954+ multiple l7 rules. I'm not sure that using cb for this purpose
1955+ is correct, even though it says "put your private variables
1956+ there". But it doesn't look like it is being used for anything
1957+ else in the skbs that make it here. */
1958+ skb->cb[0] = 1; /* marking it seen here's probably irrelevant */
1959+
1960+ spin_unlock_bh(&l7_lock);
1961+ return (pattern_result ^ info->invert);
1962+ }
1963+
1964+ if(skb_is_nonlinear(skb)){
1965+ if(skb_linearize(skb) != 0){
1966+ if (net_ratelimit())
1967+ printk(KERN_ERR "layer7: failed to linearize "
1968+ "packet, bailing.\n");
1969+ spin_unlock_bh(&l7_lock);
1970+ return info->invert;
1971+ }
1972+ }
1973+
1974+ /* now that the skb is linearized, it's safe to set these. */
1975+ app_data = skb->data + app_data_offset(skb);
1976+ appdatalen = skb_tail_pointer(skb) - app_data;
1977+
1978+ /* the return value gets checked later, when we're ready to use it */
1979+ comppattern = compile_and_cache(info->pattern, info->protocol);
1980+
1981+ /* On the first packet of a connection, allocate space for app data */
1982+ if(total_acct_packets(master_conntrack) == 1 && !skb->cb[0] &&
1983+ !master_conntrack->layer7.app_data){
1984+ master_conntrack->layer7.app_data =
1985+ kmalloc(maxdatalen, GFP_ATOMIC);
1986+ if(!master_conntrack->layer7.app_data){
1987+ if (net_ratelimit())
1988+ printk(KERN_ERR "layer7: out of memory in "
1989+ "match, bailing.\n");
1990+ spin_unlock_bh(&l7_lock);
1991+ return info->invert;
1992+ }
1993+
1994+ master_conntrack->layer7.app_data[0] = '\0';
1995+ }
1996+
1997+ /* Can be here, but unallocated, if numpackets is increased near
1998+ the beginning of a connection */
1999+ if(master_conntrack->layer7.app_data == NULL){
2000+ spin_unlock_bh(&l7_lock);
2001+ return info->invert; /* unmatched */
2002+ }
2003+
2004+ if(!skb->cb[0]){
2005+ int newbytes;
2006+ newbytes = add_data(master_conntrack, app_data, appdatalen);
2007+
2008+ if(newbytes == 0) { /* didn't add any data */
2009+ skb->cb[0] = 1;
2010+ /* Didn't match before, not going to match now */
2011+ spin_unlock_bh(&l7_lock);
2012+ return info->invert;
2013+ }
2014+ }
2015+
2016+ /* If looking for "unknown", then never match. "Unknown" means that
2017+ we've given up; we're still trying with these packets. */
2018+ if(!strcmp(info->protocol, "unknown")) {
2019+ pattern_result = 0;
2020+ /* If looking for "unset", then always match. "Unset" means that we
2021+ haven't yet classified the connection. */
2022+ } else if(!strcmp(info->protocol, "unset")) {
2023+ pattern_result = 2;
2024+ DPRINTK("layer7: matched unset: not yet classified "
2025+ "(%d/%d packets)\n",
2026+ total_acct_packets(master_conntrack), num_packets);
2027+ /* If the regexp failed to compile, don't bother running it */
2028+ } else if(comppattern &&
2029+ regexec(comppattern, master_conntrack->layer7.app_data)){
2030+ DPRINTK("layer7: matched %s\n", info->protocol);
2031+ pattern_result = 1;
2032+ } else pattern_result = 0;
2033+
2034+ if(pattern_result == 1) {
2035+ master_conntrack->layer7.app_proto =
2036+ kmalloc(strlen(info->protocol)+1, GFP_ATOMIC);
2037+ if(!master_conntrack->layer7.app_proto){
2038+ if (net_ratelimit())
2039+ printk(KERN_ERR "layer7: out of memory in "
2040+ "match, bailing.\n");
2041+ spin_unlock_bh(&l7_lock);
2042+ return (pattern_result ^ info->invert);
2043+ }
2044+ strcpy(master_conntrack->layer7.app_proto, info->protocol);
2045+ } else if(pattern_result > 1) { /* cleanup from "unset" */
2046+ pattern_result = 1;
2047+ }
2048+
2049+ /* mark the packet seen */
2050+ skb->cb[0] = 1;
2051+
2052+ spin_unlock_bh(&l7_lock);
2053+ return (pattern_result ^ info->invert);
2054+}
2055+
2056+// load nf_conntrack_ipv4
2057+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
2058+static int
2059+#else
2060+static bool
2061+#endif
2062+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
2063+check(const struct xt_mtchk_param *par)
2064+{
2065+ if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
2066+ printk(KERN_WARNING "can't load conntrack support for "
2067+ "proto=%d\n", par->match->family);
2068+#else
2069+check(const char *tablename, const void *inf,
2070+ const struct xt_match *match, void *matchinfo,
2071+ unsigned int hook_mask)
2072+{
2073+ if (nf_ct_l3proto_try_module_get(match->family) < 0) {
2074+ printk(KERN_WARNING "can't load conntrack support for "
2075+ "proto=%d\n", match->family);
2076+#endif
2077+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
2078+ return -EINVAL;
2079+ }
2080+ return 0;
2081+#else
2082+ return 0;
2083+ }
2084+ return 1;
2085+#endif
2086+}
2087+
2088+
2089+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
2090+ static void destroy(const struct xt_mtdtor_param *par)
2091+ {
2092+ nf_ct_l3proto_module_put(par->match->family);
2093+ }
2094+#else
2095+ static void destroy(const struct xt_match *match, void *matchinfo)
2096+ {
2097+ nf_ct_l3proto_module_put(match->family);
2098+ }
2099+#endif
2100+
2101+static struct xt_match xt_layer7_match[] __read_mostly = {
2102+{
2103+ .name = "layer7",
2104+ .family = AF_INET,
2105+ .checkentry = check,
2106+ .match = match,
2107+ .destroy = destroy,
2108+ .matchsize = sizeof(struct xt_layer7_info),
2109+ .me = THIS_MODULE
2110+}
2111+};
2112+
2113+static void layer7_cleanup_proc(void)
2114+{
2115+ remove_proc_entry("layer7_numpackets", init_net.proc_net);
2116+}
2117+
2118+/* register the proc file */
2119+static void layer7_init_proc(void)
2120+{
2121+ struct proc_dir_entry* entry;
2122+ entry = create_proc_entry("layer7_numpackets", 0644, init_net.proc_net);
2123+ entry->read_proc = layer7_read_proc;
2124+ entry->write_proc = layer7_write_proc;
2125+}
2126+
2127+static int __init xt_layer7_init(void)
2128+{
2129+ need_conntrack();
2130+
2131+ if (init_net.ct.sysctl_acct == 0) {
2132+ printk(KERN_WARNING "layer7: enabling nf_conntrack_acct\n");
2133+ init_net.ct.sysctl_acct = 1;
2134+ }
2135+
2136+ layer7_init_proc();
2137+ if(maxdatalen < 1) {
2138+ printk(KERN_WARNING "layer7: maxdatalen can't be < 1, "
2139+ "using 1\n");
2140+ maxdatalen = 1;
2141+ }
2142+ /* This is not a hard limit. It's just here to prevent people from
2143+ bringing their slow machines to a grinding halt. */
2144+ else if(maxdatalen > 65536) {
2145+ printk(KERN_WARNING "layer7: maxdatalen can't be > 65536, "
2146+ "using 65536\n");
2147+ maxdatalen = 65536;
2148+ }
2149+ return xt_register_matches(xt_layer7_match,
2150+ ARRAY_SIZE(xt_layer7_match));
2151+}
2152+
2153+static void __exit xt_layer7_fini(void)
2154+{
2155+ layer7_cleanup_proc();
2156+ xt_unregister_matches(xt_layer7_match, ARRAY_SIZE(xt_layer7_match));
2157+}
2158+
2159+module_init(xt_layer7_init);
2160+module_exit(xt_layer7_fini);