Root/target/linux/generic/patches-2.6.32/100-netfilter_layer7_2.21.patch

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

Archive Download this file



interactive