]> git.pld-linux.org Git - packages/kernel.git/blame - 2.6.5-rc1-patch-o-matic-ng-extra-20040316.patch
- ported from linux-2.4.25-atmdd.patch
[packages/kernel.git] / 2.6.5-rc1-patch-o-matic-ng-extra-20040316.patch
CommitLineData
4e23f685 1diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_helpers.h linux-2.6.5-rc1/include/linux/netfilter_helpers.h
2--- linux-2.6.5-rc1.org/include/linux/netfilter_helpers.h 1970-01-01 00:00:00.000000000 +0000
3+++ linux-2.6.5-rc1/include/linux/netfilter_helpers.h 2004-03-16 12:04:49.000000000 +0000
4@@ -0,0 +1,133 @@
5+/*
6+ * Helpers for netfiler modules. This file provides implementations for basic
7+ * functions such as strncasecmp(), etc.
8+ *
9+ * gcc will warn for defined but unused functions, so we only include the
10+ * functions requested. The following macros are used:
11+ * NF_NEED_STRNCASECMP nf_strncasecmp()
12+ * NF_NEED_STRTOU16 nf_strtou16()
13+ * NF_NEED_STRTOU32 nf_strtou32()
14+ */
15+#ifndef _NETFILTER_HELPERS_H
16+#define _NETFILTER_HELPERS_H
17+
18+/* Only include these functions for kernel code. */
19+#ifdef __KERNEL__
20+
21+#include <linux/ctype.h>
22+#define iseol(c) ( (c) == '\r' || (c) == '\n' )
23+
24+/*
25+ * The standard strncasecmp()
26+ */
27+#ifdef NF_NEED_STRNCASECMP
28+static int
29+nf_strncasecmp(const char* s1, const char* s2, u_int32_t len)
30+{
31+ if (s1 == NULL || s2 == NULL)
32+ {
33+ if (s1 == NULL && s2 == NULL)
34+ {
35+ return 0;
36+ }
37+ return (s1 == NULL) ? -1 : 1;
38+ }
39+ while (len > 0 && tolower(*s1) == tolower(*s2))
40+ {
41+ len--;
42+ s1++;
43+ s2++;
44+ }
45+ return ( (len == 0) ? 0 : (tolower(*s1) - tolower(*s2)) );
46+}
47+#endif /* NF_NEED_STRNCASECMP */
48+
49+/*
50+ * Parse a string containing a 16-bit unsigned integer.
51+ * Returns the number of chars used, or zero if no number is found.
52+ */
53+#ifdef NF_NEED_STRTOU16
54+static int
55+nf_strtou16(const char* pbuf, u_int16_t* pval)
56+{
57+ int n = 0;
58+
59+ *pval = 0;
60+ while (isdigit(pbuf[n]))
61+ {
62+ *pval = (*pval * 10) + (pbuf[n] - '0');
63+ n++;
64+ }
65+
66+ return n;
67+}
68+#endif /* NF_NEED_STRTOU16 */
69+
70+/*
71+ * Parse a string containing a 32-bit unsigned integer.
72+ * Returns the number of chars used, or zero if no number is found.
73+ */
74+#ifdef NF_NEED_STRTOU32
75+static int
76+nf_strtou32(const char* pbuf, u_int32_t* pval)
77+{
78+ int n = 0;
79+
80+ *pval = 0;
81+ while (pbuf[n] >= '0' && pbuf[n] <= '9')
82+ {
83+ *pval = (*pval * 10) + (pbuf[n] - '0');
84+ n++;
85+ }
86+
87+ return n;
88+}
89+#endif /* NF_NEED_STRTOU32 */
90+
91+/*
92+ * Given a buffer and length, advance to the next line and mark the current
93+ * line.
94+ */
95+#ifdef NF_NEED_NEXTLINE
96+static int
97+nf_nextline(char* p, uint len, uint* poff, uint* plineoff, uint* plinelen)
98+{
99+ uint off = *poff;
100+ uint physlen = 0;
101+
102+ if (off >= len)
103+ {
104+ return 0;
105+ }
106+
107+ while (p[off] != '\n')
108+ {
109+ if (len-off <= 1)
110+ {
111+ return 0;
112+ }
113+
114+ physlen++;
115+ off++;
116+ }
117+
118+ /* if we saw a crlf, physlen needs adjusted */
119+ if (physlen > 0 && p[off] == '\n' && p[off-1] == '\r')
120+ {
121+ physlen--;
122+ }
123+
124+ /* advance past the newline */
125+ off++;
126+
127+ *plineoff = *poff;
128+ *plinelen = physlen;
129+ *poff = off;
130+
131+ return 1;
132+}
133+#endif /* NF_NEED_NEXTLINE */
134+
135+#endif /* __KERNEL__ */
136+
137+#endif /* _NETFILTER_HELPERS_H */
138diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ip_conntrack.h
139--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ip_conntrack.h 2004-03-16 12:00:23.000000000 +0000
140+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ip_conntrack.h 2004-03-16 12:04:49.000000000 +0000
141@@ -64,6 +64,7 @@
142 };
143
144 /* Add protocol helper include file here */
145+#include <linux/netfilter_ipv4/ip_conntrack_rtsp.h>
146 #include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
147 #include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
148 #include <linux/netfilter_ipv4/ip_conntrack_irc.h>
149@@ -71,6 +72,8 @@
150 /* per expectation: application helper private data */
151 union ip_conntrack_expect_help {
152 /* insert conntrack helper private data (expect) here */
153+ struct ip_ct_rtsp_expect exp_rtsp_info;
154+ struct ip_ct_rtsp_master ct_rtsp_info;
155 struct ip_ct_amanda_expect exp_amanda_info;
156 struct ip_ct_ftp_expect exp_ftp_info;
157 struct ip_ct_irc_expect exp_irc_info;
158@@ -206,6 +209,10 @@
159 } nat;
160 #endif /* CONFIG_IP_NF_NAT_NEEDED */
161
162+#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
163+ unsigned long mark;
164+#endif
165+
166 };
167
168 /* get master conntrack via master expectation */
169diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ip_conntrack_rpc.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ip_conntrack_rpc.h
170--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ip_conntrack_rpc.h 1970-01-01 00:00:00.000000000 +0000
171+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ip_conntrack_rpc.h 2004-03-16 12:04:46.000000000 +0000
172@@ -0,0 +1,68 @@
173+/* RPC extension for IP connection tracking, Version 2.2
174+ * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
175+ * - original rpc tracking module
176+ * - "recent" connection handling for kernel 2.3+ netfilter
177+ *
178+ * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
179+ * - upgraded conntrack modules to oldnat api - kernel 2.4.0+
180+ *
181+ * (C) 2002 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
182+ * - upgraded conntrack modules to newnat api - kernel 2.4.20+
183+ * - extended matching to support filtering on procedures
184+ *
185+ * ip_conntrack_rpc.h,v 2.2 2003/01/12 18:30:00
186+ *
187+ * This program is free software; you can redistribute it and/or
188+ * modify it under the terms of the GNU General Public License
189+ * as published by the Free Software Foundation; either version
190+ * 2 of the License, or (at your option) any later version.
191+ **
192+ */
193+
194+#include <asm/param.h>
195+#include <linux/sched.h>
196+#include <linux/timer.h>
197+#include <linux/stddef.h>
198+#include <linux/list.h>
199+
200+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
201+
202+#ifndef _IP_CONNTRACK_RPC_H
203+#define _IP_CONNTRACK_RPC_H
204+
205+#define RPC_PORT 111
206+
207+
208+/* Datum in RPC packets are encoded in XDR */
209+#define IXDR_GET_INT32(buf) ((u_int32_t) ntohl((uint32_t)*buf))
210+
211+/* Fast timeout, to deny DoS atacks */
212+#define EXP (60 * HZ)
213+
214+/* Normal timeouts */
215+#define EXPIRES (180 * HZ)
216+
217+/* For future conections RPC, using client's cache bindings
218+ * I'll use ip_conntrack_lock to lock these lists */
219+
220+/* This identifies each request and stores protocol */
221+struct request_p {
222+ struct list_head list;
223+
224+ u_int32_t xid;
225+ u_int32_t ip;
226+ u_int16_t port;
227+
228+ /* Protocol */
229+ u_int16_t proto;
230+
231+ struct timer_list timeout;
232+};
233+
234+static inline int request_p_cmp(const struct request_p *p, u_int32_t xid,
235+ u_int32_t ip, u_int32_t port) {
236+ return (p->xid == xid && p->ip == ip && p->port);
237+
238+}
239+
240+#endif /* _IP_CONNTRACK_RPC_H */
241diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ip_conntrack_rtsp.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ip_conntrack_rtsp.h
242--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ip_conntrack_rtsp.h 1970-01-01 00:00:00.000000000 +0000
243+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ip_conntrack_rtsp.h 2004-03-16 12:04:49.000000000 +0000
244@@ -0,0 +1,68 @@
245+/*
246+ * RTSP extension for IP connection tracking.
247+ * (C) 2003 by Tom Marshall <tmarshall@real.com>
248+ * based on ip_conntrack_irc.h
249+ *
250+ * This program is free software; you can redistribute it and/or
251+ * modify it under the terms of the GNU General Public License
252+ * as published by the Free Software Foundation; either version
253+ * 2 of the License, or (at your option) any later version.
254+ */
255+#ifndef _IP_CONNTRACK_RTSP_H
256+#define _IP_CONNTRACK_RTSP_H
257+
258+/* #define IP_NF_RTSP_DEBUG */
259+#define IP_NF_RTSP_VERSION "0.01"
260+
261+/* port block types */
262+typedef enum {
263+ pb_single, /* client_port=x */
264+ pb_range, /* client_port=x-y */
265+ pb_discon /* client_port=x/y (rtspbis) */
266+} portblock_t;
267+
268+/* We record seq number and length of rtsp headers here, all in host order. */
269+
270+/*
271+ * This structure is per expected connection. It is a member of struct
272+ * ip_conntrack_expect. The TCP SEQ for the conntrack expect is stored
273+ * there and we are expected to only store the length of the data which
274+ * needs replaced. If a packet contains multiple RTSP messages, we create
275+ * one expected connection per message.
276+ *
277+ * We use these variables to mark the entire header block. This may seem
278+ * like overkill, but the nature of RTSP requires it. A header may appear
279+ * multiple times in a message. We must treat two Transport headers the
280+ * same as one Transport header with two entries.
281+ */
282+struct ip_ct_rtsp_expect
283+{
284+ u_int32_t len; /* length of header block */
285+ portblock_t pbtype; /* Type of port block that was requested */
286+ u_int16_t loport; /* Port that was requested, low or first */
287+ u_int16_t hiport; /* Port that was requested, high or second */
288+#if 0
289+ uint method; /* RTSP method */
290+ uint cseq; /* CSeq from request */
291+#endif
292+};
293+
294+/* This structure exists only once per master */
295+struct ip_ct_rtsp_master
296+{
297+ /* Empty (?) */
298+};
299+
300+
301+#ifdef __KERNEL__
302+
303+#include <linux/netfilter_ipv4/lockhelp.h>
304+
305+#define RTSP_PORT 554
306+
307+/* Protects rtsp part of conntracks */
308+DECLARE_LOCK_EXTERN(ip_rtsp_lock);
309+
310+#endif /* __KERNEL__ */
311+
312+#endif /* _IP_CONNTRACK_RTSP_H */
313diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_CONNMARK.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_CONNMARK.h
314--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_CONNMARK.h 1970-01-01 00:00:00.000000000 +0000
315+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_CONNMARK.h 2004-03-16 12:04:09.000000000 +0000
316@@ -0,0 +1,25 @@
317+#ifndef _IPT_CONNMARK_H_target
318+#define _IPT_CONNMARK_H_target
319+
320+/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
321+ * by Henrik Nordstrom <hno@marasystems.com>
322+ *
323+ * This program is free software; you can redistribute it and/or modify
324+ * it under the terms of the GNU General Public License as published by
325+ * the Free Software Foundation; either version 2 of the License, or
326+ * (at your option) any later version.
327+ */
328+
329+enum {
330+ IPT_CONNMARK_SET = 0,
331+ IPT_CONNMARK_SAVE,
332+ IPT_CONNMARK_RESTORE
333+};
334+
335+struct ipt_connmark_target_info {
336+ unsigned long mark;
337+ unsigned long mask;
338+ u_int8_t mode;
339+};
340+
341+#endif /*_IPT_CONNMARK_H_target*/
342diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_IPMARK.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_IPMARK.h
343--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_IPMARK.h 1970-01-01 00:00:00.000000000 +0000
344+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_IPMARK.h 2004-03-16 12:04:10.000000000 +0000
345@@ -0,0 +1,13 @@
346+#ifndef _IPT_IPMARK_H_target
347+#define _IPT_IPMARK_H_target
348+
349+struct ipt_ipmark_target_info {
350+ unsigned long andmask;
351+ unsigned long ormask;
352+ unsigned int addr;
353+};
354+
355+#define IPT_IPMARK_SRC 0
356+#define IPT_IPMARK_DST 1
357+
358+#endif /*_IPT_IPMARK_H_target*/
359diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_XOR.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_XOR.h
360--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_XOR.h 1970-01-01 00:00:00.000000000 +0000
361+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_XOR.h 2004-03-16 12:04:18.000000000 +0000
362@@ -0,0 +1,9 @@
363+#ifndef _IPT_XOR_H
364+#define _IPT_XOR_H
365+
366+struct ipt_XOR_info {
367+ char key[30];
368+ u_int8_t block_size;
369+};
370+
371+#endif /* _IPT_XOR_H */
372diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_addrtype.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_addrtype.h
373--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_addrtype.h 1970-01-01 00:00:00.000000000 +0000
374+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_addrtype.h 2004-03-16 12:04:20.000000000 +0000
375@@ -0,0 +1,11 @@
376+#ifndef _IPT_ADDRTYPE_H
377+#define _IPT_ADDRTYPE_H
378+
379+struct ipt_addrtype_info {
380+ u_int16_t source; /* source-type mask */
381+ u_int16_t dest; /* dest-type mask */
382+ int invert_source;
383+ int invert_dest;
384+};
385+
386+#endif
387diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_connmark.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_connmark.h
388--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_connmark.h 1970-01-01 00:00:00.000000000 +0000
389+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_connmark.h 2004-03-16 12:04:09.000000000 +0000
390@@ -0,0 +1,18 @@
391+#ifndef _IPT_CONNMARK_H
392+#define _IPT_CONNMARK_H
393+
394+/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
395+ * by Henrik Nordstrom <hno@marasystems.com>
396+ *
397+ * This program is free software; you can redistribute it and/or modify
398+ * it under the terms of the GNU General Public License as published by
399+ * the Free Software Foundation; either version 2 of the License, or
400+ * (at your option) any later version.
401+ */
402+
403+struct ipt_connmark_info {
404+ unsigned long mark, mask;
405+ u_int8_t invert;
406+};
407+
408+#endif /*_IPT_CONNMARK_H*/
409diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_policy.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_policy.h
410--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_policy.h 1970-01-01 00:00:00.000000000 +0000
411+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_policy.h 2004-03-16 12:04:45.000000000 +0000
412@@ -0,0 +1,52 @@
413+#ifndef _IPT_POLICY_H
414+#define _IPT_POLICY_H
415+
416+#define POLICY_MAX_ELEM 4
417+
418+enum ipt_policy_flags
419+{
420+ POLICY_MATCH_IN = 0x1,
421+ POLICY_MATCH_OUT = 0x2,
422+ POLICY_MATCH_NONE = 0x4,
423+ POLICY_MATCH_STRICT = 0x8,
424+};
425+
426+enum ipt_policy_modes
427+{
428+ POLICY_MODE_TRANSPORT,
429+ POLICY_MODE_TUNNEL
430+};
431+
432+struct ipt_policy_spec
433+{
434+ u_int8_t saddr:1,
435+ daddr:1,
436+ proto:1,
437+ mode:1,
438+ spi:1,
439+ reqid:1;
440+};
441+
442+struct ipt_policy_elem
443+{
444+ u_int32_t saddr;
445+ u_int32_t smask;
446+ u_int32_t daddr;
447+ u_int32_t dmask;
448+ u_int32_t spi;
449+ u_int32_t reqid;
450+ u_int8_t proto;
451+ u_int8_t mode;
452+
453+ struct ipt_policy_spec match;
454+ struct ipt_policy_spec invert;
455+};
456+
457+struct ipt_policy_info
458+{
459+ struct ipt_policy_elem pol[POLICY_MAX_ELEM];
460+ u_int16_t flags;
461+ u_int16_t len;
462+};
463+
464+#endif /* _IPT_POLICY_H */
465diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_rpc.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_rpc.h
466--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_rpc.h 1970-01-01 00:00:00.000000000 +0000
467+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_rpc.h 2004-03-16 12:04:46.000000000 +0000
468@@ -0,0 +1,35 @@
469+/* RPC extension for IP netfilter matching, Version 2.2
470+ * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
471+ * - original rpc tracking module
472+ * - "recent" connection handling for kernel 2.3+ netfilter
473+ *
474+ * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
475+ * - upgraded conntrack modules to oldnat api - kernel 2.4.0+
476+ *
477+ * (C) 2002 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
478+ * - upgraded conntrack modules to newnat api - kernel 2.4.20+
479+ * - extended matching to support filtering on procedures
480+ *
481+ * ipt_rpc.h.c,v 2.2 2003/01/12 18:30:00
482+ *
483+ * This program is free software; you can redistribute it and/or
484+ * modify it under the terms of the GNU General Public License
485+ * as published by the Free Software Foundation; either version
486+ * 2 of the License, or (at your option) any later version.
487+ **
488+ */
489+
490+#ifndef _IPT_RPC_H
491+#define _IPT_RPC_H
492+
493+struct ipt_rpc_data;
494+
495+struct ipt_rpc_info {
496+ int inverse;
497+ int strict;
498+ const char c_procs[1408];
499+ int i_procs;
500+ struct ipt_rpc_data *data;
501+};
502+
503+#endif /* _IPT_RPC_H */
504diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_string.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_string.h
505--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_string.h 1970-01-01 00:00:00.000000000 +0000
506+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_string.h 2004-03-16 12:06:26.000000000 +0000
507@@ -0,0 +1,21 @@
508+#ifndef _IPT_STRING_H
509+#define _IPT_STRING_H
510+
511+/* *** PERFORMANCE TWEAK ***
512+ * Packet size and search string threshold,
513+ * above which sublinear searches is used. */
514+#define IPT_STRING_HAYSTACK_THRESH 100
515+#define IPT_STRING_NEEDLE_THRESH 20
516+
517+#define BM_MAX_NLEN 256
518+#define BM_MAX_HLEN 1024
519+
520+typedef char *(*proc_ipt_search) (char *, char *, int, int);
521+
522+struct ipt_string_info {
523+ char string[BM_MAX_NLEN];
524+ u_int16_t invert;
525+ u_int16_t len;
526+};
527+
528+#endif /* _IPT_STRING_H */
529diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv6/ip6t_owner.h linux-2.6.5-rc1/include/linux/netfilter_ipv6/ip6t_owner.h
530--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv6/ip6t_owner.h 2004-03-16 05:46:45.000000000 +0000
531+++ linux-2.6.5-rc1/include/linux/netfilter_ipv6/ip6t_owner.h 2004-03-16 12:04:42.000000000 +0000
532@@ -6,12 +6,14 @@
533 #define IP6T_OWNER_GID 0x02
534 #define IP6T_OWNER_PID 0x04
535 #define IP6T_OWNER_SID 0x08
536+#define IP6T_OWNER_COMM 0x10
537
538 struct ip6t_owner_info {
539 uid_t uid;
540 gid_t gid;
541 pid_t pid;
542 pid_t sid;
543+ char comm[16];
544 u_int8_t match, invert; /* flags */
545 };
546
547diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_mime.h linux-2.6.5-rc1/include/linux/netfilter_mime.h
548--- linux-2.6.5-rc1.org/include/linux/netfilter_mime.h 1970-01-01 00:00:00.000000000 +0000
549+++ linux-2.6.5-rc1/include/linux/netfilter_mime.h 2004-03-16 12:04:49.000000000 +0000
550@@ -0,0 +1,89 @@
551+/*
552+ * MIME functions for netfilter modules. This file provides implementations
553+ * for basic MIME parsing. MIME headers are used in many protocols, such as
554+ * HTTP, RTSP, SIP, etc.
555+ *
556+ * gcc will warn for defined but unused functions, so we only include the
557+ * functions requested. The following macros are used:
558+ * NF_NEED_MIME_NEXTLINE nf_mime_nextline()
559+ */
560+#ifndef _NETFILTER_MIME_H
561+#define _NETFILTER_MIME_H
562+
563+/* Only include these functions for kernel code. */
564+#ifdef __KERNEL__
565+
566+#include <linux/ctype.h>
567+
568+/*
569+ * Given a buffer and length, advance to the next line and mark the current
570+ * line. If the current line is empty, *plinelen will be set to zero. If
571+ * not, it will be set to the actual line length (including CRLF).
572+ *
573+ * 'line' in this context means logical line (includes LWS continuations).
574+ * Returns 1 on success, 0 on failure.
575+ */
576+#ifdef NF_NEED_MIME_NEXTLINE
577+static int
578+nf_mime_nextline(char* p, uint len, uint* poff, uint* plineoff, uint* plinelen)
579+{
580+ uint off = *poff;
581+ uint physlen = 0;
582+ int is_first_line = 1;
583+
584+ if (off >= len)
585+ {
586+ return 0;
587+ }
588+
589+ do
590+ {
591+ while (p[off] != '\n')
592+ {
593+ if (len-off <= 1)
594+ {
595+ return 0;
596+ }
597+
598+ physlen++;
599+ off++;
600+ }
601+
602+ /* if we saw a crlf, physlen needs adjusted */
603+ if (physlen > 0 && p[off] == '\n' && p[off-1] == '\r')
604+ {
605+ physlen--;
606+ }
607+
608+ /* advance past the newline */
609+ off++;
610+
611+ /* check for an empty line */
612+ if (physlen == 0)
613+ {
614+ break;
615+ }
616+
617+ /* check for colon on the first physical line */
618+ if (is_first_line)
619+ {
620+ is_first_line = 0;
621+ if (memchr(p+(*poff), ':', physlen) == NULL)
622+ {
623+ return 0;
624+ }
625+ }
626+ }
627+ while (p[off] == ' ' || p[off] == '\t');
628+
629+ *plineoff = *poff;
630+ *plinelen = (physlen == 0) ? 0 : (off - *poff);
631+ *poff = off;
632+
633+ return 1;
634+}
635+#endif /* NF_NEED_MIME_NEXTLINE */
636+
637+#endif /* __KERNEL__ */
638+
639+#endif /* _NETFILTER_MIME_H */
640diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/net/tcp.h linux-2.6.5-rc1/include/net/tcp.h
641--- linux-2.6.5-rc1.org/include/net/tcp.h 2004-03-16 05:45:33.000000000 +0000
642+++ linux-2.6.5-rc1/include/net/tcp.h 2004-03-16 12:04:38.000000000 +0000
643@@ -162,6 +162,7 @@
644 extern void tcp_bucket_unlock(struct sock *sk);
645 extern int tcp_port_rover;
646 extern struct sock *tcp_v4_lookup_listener(u32 addr, unsigned short hnum, int dif);
647+extern struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 hnum, int dif);
648
649 /* These are AF independent. */
650 static __inline__ int tcp_bhashfn(__u16 lport)
651diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/net/udp.h linux-2.6.5-rc1/include/net/udp.h
652--- linux-2.6.5-rc1.org/include/net/udp.h 2004-03-16 05:47:17.000000000 +0000
653+++ linux-2.6.5-rc1/include/net/udp.h 2004-03-16 12:04:38.000000000 +0000
654@@ -74,6 +74,8 @@
655 extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg);
656 extern int udp_disconnect(struct sock *sk, int flags);
657
658+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
659+
660 DECLARE_SNMP_STAT(struct udp_mib, udp_statistics);
661 #define UDP_INC_STATS(field) SNMP_INC_STATS(udp_statistics, field)
662 #define UDP_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_statistics, field)
663diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/Kconfig linux-2.6.5-rc1/net/ipv4/netfilter/Kconfig
664--- linux-2.6.5-rc1.org/net/ipv4/netfilter/Kconfig 2004-03-16 12:00:23.000000000 +0000
665+++ linux-2.6.5-rc1/net/ipv4/netfilter/Kconfig 2004-03-16 12:06:26.000000000 +0000
666@@ -672,5 +672,61 @@
667 depends on IP_NF_IPTABLES
668 help
669
670+config IP_NF_CONNTRACK_MARK
671+ bool 'Connection mark tracking support'
672+config IP_NF_TARGET_CONNMARK
673+ tristate 'CONNMARK target support'
674+ depends on IP_NF_MANGLE
675+config IP_NF_MATCH_CONNMARK
676+ tristate ' Connection mark match support'
677+ depends on IP_NF_IPTABLES
678+ help
679+
680+config IP_NF_TARGET_IPMARK
681+ tristate 'IPMARK target support'
682+ depends on IP_NF_MANGLE
683+ help
684+
685+config IP_NF_TARGET_XOR
686+ tristate 'XOR target support'
687+ depends on IP_NF_MANGLE
688+ help
689+
690+config IP_NF_MATCH_ADDRTYPE
691+ tristate 'address type match support'
692+ depends on IP_NF_IPTABLES
693+ help
694+
695+config IP_NF_MATCH_POLICY
696+ tristate "IPsec policy match support"
697+ depends on IP_NF_IPTABLES && XFRM
698+ help
699+ Policy matching allows you to match packets based on the
700+ IPsec policy that was used during decapsulation/will
701+ be used during encapsulation.
702+
703+ To compile it as a module, choose M here. If unsure, say N.
704+ help
705+
706+config IP_NF_MATCH_RPC
707+ tristate 'RPC match support'
708+ depends on IP_NF_CONNTRACK && IP_NF_IPTABLES
709+ help
710+
711+config IP_NF_NAT_RTSP
712+ tristate
713+ depends on IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
714+ default IP_NF_NAT if IP_NF_RTSP=y
715+ default m if IP_NF_RTSP=m
716+config IP_NF_RTSP
717+ tristate ' RTSP protocol support'
718+ depends on IP_NF_CONNTRACK
719+ help
720+
721+config IP_NF_MATCH_STRING
722+ tristate 'String match support'
723+ depends on IP_NF_IPTABLES
724+ help
725+
726 endmenu
727
728diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/Makefile linux-2.6.5-rc1/net/ipv4/netfilter/Makefile
729--- linux-2.6.5-rc1.org/net/ipv4/netfilter/Makefile 2004-03-16 12:00:23.000000000 +0000
730+++ linux-2.6.5-rc1/net/ipv4/netfilter/Makefile 2004-03-16 12:06:26.000000000 +0000
731@@ -20,6 +20,14 @@
732 obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
733
734 # connection tracking helpers
735+
736+# rtsp protocol support
737+obj-$(CONFIG_IP_NF_RTSP) += ip_conntrack_rtsp.o
738+ifdef CONFIG_IP_NF_NAT_RTSP
739+ export-objs += ip_conntrack_rtsp.o
740+endif
741+obj-$(CONFIG_IP_NF_NAT_RTSP) += ip_nat_rtsp.o
742+
743 obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o
744 obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o
745 obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o
746@@ -41,6 +49,9 @@
747 obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
748
749 # matches
750+obj-$(CONFIG_IP_NF_MATCH_RPC) += ip_conntrack_rpc_tcp.o ip_conntrack_rpc_udp.o ipt_rpc.o
751+export-objs += ip_conntrack_rpc_tcp.o ip_conntrack_rpc_udp.o
752+
753 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
754 obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
755 obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o
756@@ -48,6 +59,7 @@
757 obj-$(CONFIG_IP_NF_MATCH_DSTLIMIT) += ipt_dstlimit.o
758 obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
759 obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
760+obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o
761 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
762
763 obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
764@@ -78,12 +90,15 @@
765
766 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
767 obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
768+obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o
769 obj-$(CONFIG_IP_NF_MATCH_CONNLIMIT) += ipt_connlimit.o
770 obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
771 obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
772+obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
773 obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
774
775 obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
776+obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o
777
778 # targets
779 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
780@@ -91,6 +106,7 @@
781 obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
782 obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o
783 obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o
784+obj-$(CONFIG_IP_NF_TARGET_IPMARK) += ipt_IPMARK.o
785 obj-$(CONFIG_IP_NF_TARGET_IMQ) += ipt_IMQ.o
786 obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
787 obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
788@@ -99,6 +115,8 @@
789 obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
790 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
791 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
792+obj-$(CONFIG_IP_NF_TARGET_XOR) += ipt_XOR.o
793+obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK.o
794 obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
795 obj-$(CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP) += ipt_IPV4OPTSSTRIP.o
796 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
797diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_rpc_tcp.c linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_rpc_tcp.c
798--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_rpc_tcp.c 1970-01-01 00:00:00.000000000 +0000
799+++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_rpc_tcp.c 2004-03-16 12:04:46.000000000 +0000
800@@ -0,0 +1,508 @@
801+/* RPC extension for IP (TCP) connection tracking, Version 2.2
802+ * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
803+ * - original rpc tracking module
804+ * - "recent" connection handling for kernel 2.3+ netfilter
805+ *
806+ * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
807+ * - upgraded conntrack modules to oldnat api - kernel 2.4.0+
808+ *
809+ * (C) 2002,2003 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
810+ * - upgraded conntrack modules to newnat api - kernel 2.4.20+
811+ * - extended matching to support filtering on procedures
812+ *
813+ * ip_conntrack_rpc_tpc.c,v 2.2 2003/01/12 18:30:00
814+ *
815+ * This program is free software; you can redistribute it and/or
816+ * modify it under the terms of the GNU General Public License
817+ * as published by the Free Software Foundation; either version
818+ * 2 of the License, or (at your option) any later version.
819+ **
820+ * Module load syntax:
821+ * insmod ip_conntrack_rpc_tcp.o ports=port1,port2,...port<MAX_PORTS>
822+ *
823+ * Please give the ports of all RPC servers you wish to connect to.
824+ * If you don't specify ports, the default will be port 111.
825+ **
826+ * Note to all:
827+ *
828+ * RPCs should not be exposed to the internet - ask the Pentagon;
829+ *
830+ * "The unidentified crackers pleaded guilty in July to charges
831+ * of juvenile delinquency stemming from a string of Pentagon
832+ * network intrusions in February.
833+ *
834+ * The youths, going by the names TooShort and Makaveli, used
835+ * a common server security hole to break in, according to
836+ * Dane Jasper, owner of the California Internet service
837+ * provider, Sonic. They used the hole, known as the 'statd'
838+ * exploit, to attempt more than 800 break-ins, Jasper said."
839+ *
840+ * From: Wired News; "Pentagon Kids Kicked Off Grid" - Nov 6, 1998
841+ * URL: http://www.wired.com/news/politics/0,1283,16098,00.html
842+ **
843+ */
844+
845+#include <linux/module.h>
846+#include <linux/netfilter.h>
847+#include <linux/ip.h>
848+#include <net/checksum.h>
849+#include <net/tcp.h>
850+
851+#include <asm/param.h>
852+#include <linux/sched.h>
853+#include <linux/timer.h>
854+#include <linux/stddef.h>
855+#include <linux/list.h>
856+
857+#include <linux/netfilter_ipv4/lockhelp.h>
858+#include <linux/netfilter_ipv4/ip_tables.h>
859+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
860+#include <linux/netfilter_ipv4/ip_conntrack_rpc.h>
861+
862+#define MAX_PORTS 8
863+static int ports[MAX_PORTS];
864+static int ports_n_c = 0;
865+
866+#ifdef MODULE_PARM
867+MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
868+MODULE_PARM_DESC(ports, "port numbers (TCP/UDP) of RPC portmapper servers");
869+#endif
870+
871+MODULE_AUTHOR("Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>");
872+MODULE_DESCRIPTION("RPC TCP connection tracking module");
873+MODULE_LICENSE("GPL");
874+
875+#if 0
876+#define DEBUGP(format, args...) printk(KERN_DEBUG "ip_conntrack_rpc_tcp: " \
877+ format, ## args)
878+#else
879+#define DEBUGP(format, args...)
880+#endif
881+
882+DECLARE_RWLOCK(ipct_rpc_tcp_lock);
883+#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ipct_rpc_tcp_lock)
884+#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ipct_rpc_tcp_lock)
885+#include <linux/netfilter_ipv4/listhelp.h>
886+
887+/* For future conections RPC, using client's cache bindings
888+ * I'll use ip_conntrack_lock to lock these lists */
889+
890+LIST_HEAD(request_p_list_tcp);
891+
892+
893+static void delete_request_p(unsigned long request_p_ul)
894+{
895+ struct request_p *p = (void *)request_p_ul;
896+
897+ WRITE_LOCK(&ipct_rpc_tcp_lock);
898+ LIST_DELETE(&request_p_list_tcp, p);
899+ WRITE_UNLOCK(&ipct_rpc_tcp_lock);
900+ kfree(p);
901+ return;
902+}
903+
904+
905+static void req_cl(struct request_p * r)
906+{
907+ WRITE_LOCK(&ipct_rpc_tcp_lock);
908+ del_timer(&r->timeout);
909+ LIST_DELETE(&request_p_list_tcp, r);
910+ WRITE_UNLOCK(&ipct_rpc_tcp_lock);
911+ kfree(r);
912+ return;
913+}
914+
915+
916+static void clean_request(struct list_head *list)
917+{
918+ struct list_head *first = list->prev;
919+ struct list_head *temp = list->next;
920+ struct list_head *aux;
921+
922+ if (list_empty(list))
923+ return;
924+
925+ while (first != temp) {
926+ aux = temp->next;
927+ req_cl((struct request_p *)temp);
928+ temp = aux;
929+ }
930+ req_cl((struct request_p *)temp);
931+ return;
932+}
933+
934+
935+static void alloc_request_p(u_int32_t xid, u_int16_t proto, u_int32_t ip,
936+ u_int16_t port)
937+{
938+ struct request_p *req_p;
939+
940+ /* Verifies if entry already exists */
941+ WRITE_LOCK(&ipct_rpc_tcp_lock);
942+ req_p = LIST_FIND(&request_p_list_tcp, request_p_cmp,
943+ struct request_p *, xid, ip, port);
944+
945+ if (req_p) {
946+ /* Refresh timeout */
947+ if (del_timer(&req_p->timeout)) {
948+ req_p->timeout.expires = jiffies + EXP;
949+ add_timer(&req_p->timeout);
950+ }
951+ WRITE_UNLOCK(&ipct_rpc_tcp_lock);
952+ return;
953+
954+ }
955+ WRITE_UNLOCK(&ipct_rpc_tcp_lock);
956+
957+ /* Allocate new request_p */
958+ req_p = (struct request_p *) kmalloc(sizeof(struct request_p), GFP_ATOMIC);
959+ if (!req_p) {
960+ DEBUGP("can't allocate request_p\n");
961+ return;
962+ }
963+ *req_p = ((struct request_p) {{ NULL, NULL }, xid, ip, port, proto,
964+ { { NULL, NULL }, jiffies + EXP, (unsigned long)req_p,
965+ NULL }});
966+
967+ /* Initialize timer */
968+ init_timer(&req_p->timeout);
969+ req_p->timeout.function = delete_request_p;
970+ add_timer(&req_p->timeout);
971+
972+ /* Put in list */
973+ WRITE_LOCK(&ipct_rpc_tcp_lock);
974+ list_prepend(&request_p_list_tcp, req_p);
975+ WRITE_UNLOCK(&ipct_rpc_tcp_lock);
976+ return;
977+
978+}
979+
980+
981+static int check_rpc_packet(const u_int32_t *data,
982+ int dir, struct ip_conntrack *ct,
983+ struct list_head request_p_list)
984+{
985+ struct request_p *req_p;
986+ u_int32_t xid;
987+ struct ip_conntrack_expect expect, *exp = &expect;
988+
989+ /* Translstion's buffer for XDR */
990+ u_int16_t port_buf;
991+
992+
993+ /* Get XID */
994+ xid = *data;
995+
996+ /* This does sanity checking on RPC payloads,
997+ * and permits only the RPC "get port" (3)
998+ * in authorised procedures in client
999+ * communications with the portmapper.
1000+ */
1001+
1002+ /* perform direction dependant RPC work */
1003+ if (dir == IP_CT_DIR_ORIGINAL) {
1004+
1005+ data += 5;
1006+
1007+ /* Get RPC requestor */
1008+ if (IXDR_GET_INT32(data) != 3) {
1009+ DEBUGP("RPC packet contains an invalid (non \"get\") requestor. [skip]\n");
1010+ return NF_ACCEPT;
1011+ }
1012+ DEBUGP("RPC packet contains a \"get\" requestor. [cont]\n");
1013+
1014+ data++;
1015+
1016+ /* Jump Credentials and Verfifier */
1017+ data += IXDR_GET_INT32(data) + 2;
1018+ data += IXDR_GET_INT32(data) + 2;
1019+
1020+ /* Get RPC procedure */
1021+ DEBUGP("RPC packet contains procedure request [%u]. [cont]\n",
1022+ (unsigned int)IXDR_GET_INT32(data));
1023+
1024+ /* Get RPC protocol and store against client parameters */
1025+ data = data + 2;
1026+ alloc_request_p(xid, IXDR_GET_INT32(data), ct->tuplehash[dir].tuple.src.ip,
1027+ ct->tuplehash[dir].tuple.src.u.all);
1028+
1029+ DEBUGP("allocated RPC req_p for xid=%u proto=%u %u.%u.%u.%u:%u\n",
1030+ xid, IXDR_GET_INT32(data),
1031+ NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
1032+ ntohs(ct->tuplehash[dir].tuple.src.u.all));
1033+
1034+ DEBUGP("allocated RPC request for protocol %u. [done]\n",
1035+ (unsigned int)IXDR_GET_INT32(data));
1036+
1037+ } else {
1038+
1039+ /* Check for returning packet's stored counterpart */
1040+ req_p = LIST_FIND(&request_p_list_tcp, request_p_cmp,
1041+ struct request_p *, xid,
1042+ ct->tuplehash[!dir].tuple.src.ip,
1043+ ct->tuplehash[!dir].tuple.src.u.all);
1044+
1045+ /* Drop unexpected packets */
1046+ if (!req_p) {
1047+ DEBUGP("packet is not expected. [skip]\n");
1048+ return NF_ACCEPT;
1049+ }
1050+
1051+ /* Verifies if packet is really an RPC reply packet */
1052+ data = data++;
1053+ if (IXDR_GET_INT32(data) != 1) {
1054+ DEBUGP("packet is not a valid RPC reply. [skip]\n");
1055+ return NF_ACCEPT;
1056+ }
1057+
1058+ /* Is status accept? */
1059+ data++;
1060+ if (IXDR_GET_INT32(data)) {
1061+ DEBUGP("packet is not an RPC accept. [skip]\n");
1062+ return NF_ACCEPT;
1063+ }
1064+
1065+ /* Get Verifier length. Jump verifier */
1066+ data++;
1067+ data = data + IXDR_GET_INT32(data) + 2;
1068+
1069+ /* Is accpet status "success"? */
1070+ if (IXDR_GET_INT32(data)) {
1071+ DEBUGP("packet is not an RPC accept status of success. [skip]\n");
1072+ return NF_ACCEPT;
1073+ }
1074+
1075+ /* Get server port number */
1076+ data++;
1077+ port_buf = (u_int16_t) IXDR_GET_INT32(data);
1078+
1079+ /* If a packet has made it this far then it deserves an
1080+ * expectation ... if port == 0, then this service is
1081+ * not going to be registered.
1082+ */
1083+ if (port_buf) {
1084+ DEBUGP("port found: %u\n", port_buf);
1085+
1086+ memset(&expect, 0, sizeof(expect));
1087+
1088+ /* Watch out, Radioactive-Man! */
1089+ exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
1090+ exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
1091+ exp->mask.src.ip = 0xffffffff;
1092+ exp->mask.dst.ip = 0xffffffff;
1093+
1094+ switch (req_p->proto) {
1095+ case IPPROTO_UDP:
1096+ exp->tuple.src.u.udp.port = 0;
1097+ exp->tuple.dst.u.udp.port = htons(port_buf);
1098+ exp->tuple.dst.protonum = IPPROTO_UDP;
1099+ exp->mask.src.u.udp.port = 0;
1100+ exp->mask.dst.u.udp.port = htons(0xffff);
1101+ exp->mask.dst.protonum = 0xffff;
1102+ break;
1103+
1104+ case IPPROTO_TCP:
1105+ exp->tuple.src.u.tcp.port = 0;
1106+ exp->tuple.dst.u.tcp.port = htons(port_buf);
1107+ exp->tuple.dst.protonum = IPPROTO_TCP;
1108+ exp->mask.src.u.tcp.port = 0;
1109+ exp->mask.dst.u.tcp.port = htons(0xffff);
1110+ exp->mask.dst.protonum = 0xffff;
1111+ break;
1112+ }
1113+ exp->expectfn = NULL;
1114+
1115+ ip_conntrack_expect_related(ct, &expect);
1116+
1117+ DEBUGP("expect related ip %u.%u.%u.%u:0-%u.%u.%u.%u:%u proto=%u\n",
1118+ NIPQUAD(exp->tuple.src.ip),
1119+ NIPQUAD(exp->tuple.dst.ip),
1120+ port_buf, req_p->proto);
1121+
1122+ DEBUGP("expect related mask %u.%u.%u.%u:0-%u.%u.%u.%u:65535 proto=%u\n",
1123+ NIPQUAD(exp->mask.src.ip),
1124+ NIPQUAD(exp->mask.dst.ip),
1125+ exp->mask.dst.protonum);
1126+
1127+ }
1128+
1129+ req_cl(req_p);
1130+
1131+ DEBUGP("packet evaluated. [expect]\n");
1132+ return NF_ACCEPT;
1133+ }
1134+
1135+ return NF_ACCEPT;
1136+
1137+}
1138+
1139+
1140+/* RPC TCP helper */
1141+static int help(const struct iphdr *iph, size_t len,
1142+ struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
1143+{
1144+ struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
1145+ const u_int32_t *data = (const u_int32_t *)tcph + tcph->doff;
1146+ size_t tcplen = len - iph->ihl * 4;
1147+
1148+ int dir = CTINFO2DIR(ctinfo);
1149+ int crp_ret;
1150+
1151+
1152+ DEBUGP("new packet to evaluate ..\n");
1153+
1154+ /* This works for packets like handshake packets, ignore */
1155+ if (len == ((tcph->doff + iph->ihl) * 4)) {
1156+ DEBUGP("packet has no data (may still be handshaking). [skip]\n");
1157+ return NF_ACCEPT;
1158+ }
1159+
1160+ /* Until there's been traffic both ways, don't look in packets. */
1161+ if (ctinfo != IP_CT_ESTABLISHED
1162+ && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
1163+ DEBUGP("connection tracking state is; ctinfo=%u ..\n", ctinfo);
1164+ DEBUGP("[note: failure to get past this error may indicate asymmetric routing]\n");
1165+ DEBUGP("packet is not yet part of a two way stream. [skip]\n");
1166+ return NF_ACCEPT;
1167+ }
1168+
1169+ /* Not whole TCP header? */
1170+ if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4) {
1171+ DEBUGP("TCP header length is; tcplen=%u ..\n", (unsigned) tcplen);
1172+ DEBUGP("packet does not contain a complete TCP header. [skip]\n");
1173+ return NF_ACCEPT;
1174+ }
1175+
1176+ /* FIXME: Source route IP option packets --RR */
1177+ if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
1178+ csum_partial((char *) tcph, tcplen, 0))) {
1179+ DEBUGP("csum; %p %u %u.%u.%u.%u %u.%u.%u.%u\n",
1180+ tcph, tcplen, NIPQUAD(iph->saddr),
1181+ NIPQUAD(iph->daddr));
1182+ DEBUGP("[note: failure to get past this error may indicate source routing]\n");
1183+ DEBUGP("packet contains a bad checksum. [skip]\n");
1184+ return NF_ACCEPT;
1185+ }
1186+
1187+ /* perform direction dependant protocol work */
1188+ if (dir == IP_CT_DIR_ORIGINAL) {
1189+
1190+ DEBUGP("packet is from the initiator. [cont]\n");
1191+
1192+ /* Tests if packet len is ok */
1193+ if ((tcplen - (tcph->doff * 4)) != 60) {
1194+ DEBUGP("packet length is not correct. [skip]\n");
1195+ return NF_ACCEPT;
1196+ }
1197+
1198+ } else {
1199+
1200+ DEBUGP("packet is from the receiver. [cont]\n");
1201+
1202+ /* Tests if packet len is ok */
1203+ if ((tcplen - (tcph->doff * 4)) != 32) {
1204+ DEBUGP("packet length is not correct. [skip]\n");
1205+ return NF_ACCEPT;
1206+ }
1207+ }
1208+
1209+ /* Get to the data */
1210+ data++;
1211+
1212+ /* Check the RPC data */
1213+ crp_ret = check_rpc_packet(data, dir, ct, request_p_list_tcp);
1214+
1215+ return crp_ret;
1216+
1217+}
1218+
1219+
1220+static struct ip_conntrack_helper rpc_helpers[MAX_PORTS];
1221+
1222+static void fini(void);
1223+
1224+
1225+static int __init init(void)
1226+{
1227+ int port, ret;
1228+ static char name[10];
1229+
1230+
1231+ /* If no port given, default to standard RPC port */
1232+ if (ports[0] == 0)
1233+ ports[0] = RPC_PORT;
1234+
1235+ for (port = 0; (port < MAX_PORTS) && ports[port]; port++) {
1236+ memset(&rpc_helpers[port], 0, sizeof(struct ip_conntrack_helper));
1237+
1238+ if (ports[port] == RPC_PORT)
1239+ sprintf(name, "rpc");
1240+ else
1241+ sprintf(name, "rpc-%d", port);
1242+
1243+ rpc_helpers[port].name = name;
1244+ rpc_helpers[port].me = THIS_MODULE;
1245+ rpc_helpers[port].max_expected = 1;
1246+ rpc_helpers[port].flags = IP_CT_HELPER_F_REUSE_EXPECT;
1247+ rpc_helpers[port].timeout = 0;
1248+
1249+ rpc_helpers[port].tuple.dst.protonum = IPPROTO_TCP;
1250+ rpc_helpers[port].mask.dst.protonum = 0xffff;
1251+
1252+ /* RPC can come from ports 0:65535 to ports[port] (111) */
1253+ rpc_helpers[port].tuple.src.u.udp.port = htons(ports[port]);
1254+ rpc_helpers[port].mask.src.u.udp.port = htons(0xffff);
1255+ rpc_helpers[port].mask.dst.u.udp.port = htons(0x0);
1256+
1257+ rpc_helpers[port].help = help;
1258+
1259+ DEBUGP("registering helper for port #%d: %d/TCP\n", port, ports[port]);
1260+ DEBUGP("helper match ip %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
1261+ NIPQUAD(rpc_helpers[port].tuple.dst.ip),
1262+ ntohs(rpc_helpers[port].tuple.dst.u.tcp.port),
1263+ NIPQUAD(rpc_helpers[port].tuple.src.ip),
1264+ ntohs(rpc_helpers[port].tuple.src.u.tcp.port));
1265+ DEBUGP("helper match mask %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
1266+ NIPQUAD(rpc_helpers[port].mask.dst.ip),
1267+ ntohs(rpc_helpers[port].mask.dst.u.tcp.port),
1268+ NIPQUAD(rpc_helpers[port].mask.src.ip),
1269+ ntohs(rpc_helpers[port].mask.src.u.tcp.port));
1270+
1271+ ret = ip_conntrack_helper_register(&rpc_helpers[port]);
1272+
1273+ if (ret) {
1274+ printk("ERROR registering port %d\n",
1275+ ports[port]);
1276+ fini();
1277+ return -EBUSY;
1278+ }
1279+ ports_n_c++;
1280+ }
1281+ return 0;
1282+}
1283+
1284+
1285+/* This function is intentionally _NOT_ defined as __exit, because
1286+ * it is needed by the init function */
1287+static void fini(void)
1288+{
1289+ int port;
1290+
1291+ DEBUGP("cleaning request list\n");
1292+ clean_request(&request_p_list_tcp);
1293+
1294+ for (port = 0; (port < ports_n_c) && ports[port]; port++) {
1295+ DEBUGP("unregistering port %d\n", ports[port]);
1296+ ip_conntrack_helper_unregister(&rpc_helpers[port]);
1297+ }
1298+}
1299+
1300+
1301+module_init(init);
1302+module_exit(fini);
1303+
1304+struct module *ip_conntrack_rpc_tcp = THIS_MODULE;
1305+EXPORT_SYMBOL(request_p_list_tcp);
1306+EXPORT_SYMBOL(ip_conntrack_rpc_tcp);
1307+EXPORT_SYMBOL(ipct_rpc_tcp_lock);
1308+
1309diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_rpc_udp.c linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_rpc_udp.c
1310--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_rpc_udp.c 1970-01-01 00:00:00.000000000 +0000
1311+++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_rpc_udp.c 2004-03-16 12:04:46.000000000 +0000
1312@@ -0,0 +1,503 @@
1313+/* RPC extension for IP (UDP) connection tracking, Version 2.2
1314+ * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
1315+ * - original rpc tracking module
1316+ * - "recent" connection handling for kernel 2.3+ netfilter
1317+ *
1318+ * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
1319+ * - upgraded conntrack modules to oldnat api - kernel 2.4.0+
1320+ *
1321+ * (C) 2002,2003 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
1322+ * - upgraded conntrack modules to newnat api - kernel 2.4.20+
1323+ * - extended matching to support filtering on procedures
1324+ *
1325+ * ip_conntrack_rpc_udp.c,v 2.2 2003/01/12 18:30:00
1326+ *
1327+ * This program is free software; you can redistribute it and/or
1328+ * modify it under the terms of the GNU General Public License
1329+ * as published by the Free Software Foundation; either version
1330+ * 2 of the License, or (at your option) any later version.
1331+ **
1332+ * Module load syntax:
1333+ * insmod ip_conntrack_rpc_udp.o ports=port1,port2,...port<MAX_PORTS>
1334+ *
1335+ * Please give the ports of all RPC servers you wish to connect to.
1336+ * If you don't specify ports, the default will be port 111.
1337+ **
1338+ * Note to all:
1339+ *
1340+ * RPCs should not be exposed to the internet - ask the Pentagon;
1341+ *
1342+ * "The unidentified crackers pleaded guilty in July to charges
1343+ * of juvenile delinquency stemming from a string of Pentagon
1344+ * network intrusions in February.
1345+ *
1346+ * The youths, going by the names TooShort and Makaveli, used
1347+ * a common server security hole to break in, according to
1348+ * Dane Jasper, owner of the California Internet service
1349+ * provider, Sonic. They used the hole, known as the 'statd'
1350+ * exploit, to attempt more than 800 break-ins, Jasper said."
1351+ *
1352+ * From: Wired News; "Pentagon Kids Kicked Off Grid" - Nov 6, 1998
1353+ * URL: http://www.wired.com/news/politics/0,1283,16098,00.html
1354+ **
1355+ */
1356+
1357+#include <linux/module.h>
1358+#include <linux/netfilter.h>
1359+#include <linux/ip.h>
1360+#include <net/checksum.h>
1361+#include <net/udp.h>
1362+
1363+#include <asm/param.h>
1364+#include <linux/sched.h>
1365+#include <linux/timer.h>
1366+#include <linux/stddef.h>
1367+#include <linux/list.h>
1368+
1369+#include <linux/netfilter_ipv4/lockhelp.h>
1370+#include <linux/netfilter_ipv4/ip_tables.h>
1371+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
1372+#include <linux/netfilter_ipv4/ip_conntrack_rpc.h>
1373+
1374+#define MAX_PORTS 8
1375+static int ports[MAX_PORTS];
1376+static int ports_n_c = 0;
1377+
1378+#ifdef MODULE_PARM
1379+MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
1380+MODULE_PARM_DESC(ports, "port numbers (TCP/UDP) of RPC portmapper servers");
1381+#endif
1382+
1383+MODULE_AUTHOR("Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>");
1384+MODULE_DESCRIPTION("RPC UDP connection tracking module");
1385+MODULE_LICENSE("GPL");
1386+
1387+#if 0
1388+#define DEBUGP(format, args...) printk(KERN_DEBUG "ip_conntrack_rpc_udp: " \
1389+ format, ## args)
1390+#else
1391+#define DEBUGP(format, args...)
1392+#endif
1393+
1394+DECLARE_RWLOCK(ipct_rpc_udp_lock);
1395+#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ipct_rpc_udp_lock)
1396+#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ipct_rpc_udp_lock)
1397+#include <linux/netfilter_ipv4/listhelp.h>
1398+
1399+/* For future conections RPC, using client's cache bindings
1400+ * I'll use ip_conntrack_lock to lock these lists */
1401+
1402+LIST_HEAD(request_p_list_udp);
1403+
1404+
1405+static void delete_request_p(unsigned long request_p_ul)
1406+{
1407+ struct request_p *p = (void *)request_p_ul;
1408+
1409+ WRITE_LOCK(&ipct_rpc_udp_lock);
1410+ LIST_DELETE(&request_p_list_udp, p);
1411+ WRITE_UNLOCK(&ipct_rpc_udp_lock);
1412+ kfree(p);
1413+ return;
1414+}
1415+
1416+
1417+static void req_cl(struct request_p * r)
1418+{
1419+ WRITE_LOCK(&ipct_rpc_udp_lock);
1420+ del_timer(&r->timeout);
1421+ LIST_DELETE(&request_p_list_udp, r);
1422+ WRITE_UNLOCK(&ipct_rpc_udp_lock);
1423+ kfree(r);
1424+ return;
1425+}
1426+
1427+
1428+static void clean_request(struct list_head *list)
1429+{
1430+ struct list_head *first = list->prev;
1431+ struct list_head *temp = list->next;
1432+ struct list_head *aux;
1433+
1434+ if (list_empty(list))
1435+ return;
1436+
1437+ while (first != temp) {
1438+ aux = temp->next;
1439+ req_cl((struct request_p *)temp);
1440+ temp = aux;
1441+ }
1442+ req_cl((struct request_p *)temp);
1443+ return;
1444+}
1445+
1446+
1447+static void alloc_request_p(u_int32_t xid, u_int16_t proto, u_int32_t ip,
1448+ u_int16_t port)
1449+{
1450+ struct request_p *req_p;
1451+
1452+ /* Verifies if entry already exists */
1453+ WRITE_LOCK(&ipct_rpc_udp_lock);
1454+ req_p = LIST_FIND(&request_p_list_udp, request_p_cmp,
1455+ struct request_p *, xid, ip, port);
1456+
1457+ if (req_p) {
1458+ /* Refresh timeout */
1459+ if (del_timer(&req_p->timeout)) {
1460+ req_p->timeout.expires = jiffies + EXP;
1461+ add_timer(&req_p->timeout);
1462+ }
1463+ WRITE_UNLOCK(&ipct_rpc_udp_lock);
1464+ return;
1465+
1466+ }
1467+ WRITE_UNLOCK(&ipct_rpc_udp_lock);
1468+
1469+ /* Allocate new request_p */
1470+ req_p = (struct request_p *) kmalloc(sizeof(struct request_p), GFP_ATOMIC);
1471+ if (!req_p) {
1472+ DEBUGP("can't allocate request_p\n");
1473+ return;
1474+ }
1475+ *req_p = ((struct request_p) {{ NULL, NULL }, xid, ip, port, proto,
1476+ { { NULL, NULL }, jiffies + EXP, (unsigned long)req_p,
1477+ NULL }});
1478+
1479+ /* Initialize timer */
1480+ init_timer(&req_p->timeout);
1481+ req_p->timeout.function = delete_request_p;
1482+ add_timer(&req_p->timeout);
1483+
1484+ /* Put in list */
1485+ WRITE_LOCK(&ipct_rpc_udp_lock);
1486+ list_prepend(&request_p_list_udp, req_p);
1487+ WRITE_UNLOCK(&ipct_rpc_udp_lock);
1488+ return;
1489+
1490+}
1491+
1492+
1493+static int check_rpc_packet(const u_int32_t *data,
1494+ int dir, struct ip_conntrack *ct,
1495+ struct list_head request_p_list)
1496+{
1497+ struct request_p *req_p;
1498+ u_int32_t xid;
1499+ struct ip_conntrack_expect expect, *exp = &expect;
1500+
1501+ /* Translstion's buffer for XDR */
1502+ u_int16_t port_buf;
1503+
1504+
1505+ /* Get XID */
1506+ xid = *data;
1507+
1508+ /* This does sanity checking on RPC payloads,
1509+ * and permits only the RPC "get port" (3)
1510+ * in authorised procedures in client
1511+ * communications with the portmapper.
1512+ */
1513+
1514+ /* perform direction dependant RPC work */
1515+ if (dir == IP_CT_DIR_ORIGINAL) {
1516+
1517+ data += 5;
1518+
1519+ /* Get RPC requestor */
1520+ if (IXDR_GET_INT32(data) != 3) {
1521+ DEBUGP("RPC packet contains an invalid (non \"get\") requestor. [skip]\n");
1522+ return NF_ACCEPT;
1523+ }
1524+ DEBUGP("RPC packet contains a \"get\" requestor. [cont]\n");
1525+
1526+ data++;
1527+
1528+ /* Jump Credentials and Verfifier */
1529+ data = data + IXDR_GET_INT32(data) + 2;
1530+ data = data + IXDR_GET_INT32(data) + 2;
1531+
1532+ /* Get RPC procedure */
1533+ DEBUGP("RPC packet contains procedure request [%u]. [cont]\n",
1534+ (unsigned int)IXDR_GET_INT32(data));
1535+
1536+ /* Get RPC protocol and store against client parameters */
1537+ data = data + 2;
1538+ alloc_request_p(xid, IXDR_GET_INT32(data), ct->tuplehash[dir].tuple.src.ip,
1539+ ct->tuplehash[dir].tuple.src.u.all);
1540+
1541+ DEBUGP("allocated RPC req_p for xid=%u proto=%u %u.%u.%u.%u:%u\n",
1542+ xid, IXDR_GET_INT32(data),
1543+ NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
1544+ ntohs(ct->tuplehash[dir].tuple.src.u.all));
1545+
1546+ DEBUGP("allocated RPC request for protocol %u. [done]\n",
1547+ (unsigned int)IXDR_GET_INT32(data));
1548+
1549+ } else {
1550+
1551+ /* Check for returning packet's stored counterpart */
1552+ req_p = LIST_FIND(&request_p_list_udp, request_p_cmp,
1553+ struct request_p *, xid,
1554+ ct->tuplehash[!dir].tuple.src.ip,
1555+ ct->tuplehash[!dir].tuple.src.u.all);
1556+
1557+ /* Drop unexpected packets */
1558+ if (!req_p) {
1559+ DEBUGP("packet is not expected. [skip]\n");
1560+ return NF_ACCEPT;
1561+ }
1562+
1563+ /* Verifies if packet is really an RPC reply packet */
1564+ data = data++;
1565+ if (IXDR_GET_INT32(data) != 1) {
1566+ DEBUGP("packet is not a valid RPC reply. [skip]\n");
1567+ return NF_ACCEPT;
1568+ }
1569+
1570+ /* Is status accept? */
1571+ data++;
1572+ if (IXDR_GET_INT32(data)) {
1573+ DEBUGP("packet is not an RPC accept. [skip]\n");
1574+ return NF_ACCEPT;
1575+ }
1576+
1577+ /* Get Verifier length. Jump verifier */
1578+ data++;
1579+ data = data + IXDR_GET_INT32(data) + 2;
1580+
1581+ /* Is accpet status "success"? */
1582+ if (IXDR_GET_INT32(data)) {
1583+ DEBUGP("packet is not an RPC accept status of success. [skip]\n");
1584+ return NF_ACCEPT;
1585+ }
1586+
1587+ /* Get server port number */
1588+ data++;
1589+ port_buf = (u_int16_t) IXDR_GET_INT32(data);
1590+
1591+ /* If a packet has made it this far then it deserves an
1592+ * expectation ... if port == 0, then this service is
1593+ * not going to be registered.
1594+ */
1595+ if (port_buf) {
1596+ DEBUGP("port found: %u\n", port_buf);
1597+
1598+ memset(&expect, 0, sizeof(expect));
1599+
1600+ /* Watch out, Radioactive-Man! */
1601+ exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
1602+ exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
1603+ exp->mask.src.ip = 0xffffffff;
1604+ exp->mask.dst.ip = 0xffffffff;
1605+
1606+ switch (req_p->proto) {
1607+ case IPPROTO_UDP:
1608+ exp->tuple.src.u.udp.port = 0;
1609+ exp->tuple.dst.u.udp.port = htons(port_buf);
1610+ exp->tuple.dst.protonum = IPPROTO_UDP;
1611+ exp->mask.src.u.udp.port = 0;
1612+ exp->mask.dst.u.udp.port = htons(0xffff);
1613+ exp->mask.dst.protonum = 0xffff;
1614+ break;
1615+
1616+ case IPPROTO_TCP:
1617+ exp->tuple.src.u.tcp.port = 0;
1618+ exp->tuple.dst.u.tcp.port = htons(port_buf);
1619+ exp->tuple.dst.protonum = IPPROTO_TCP;
1620+ exp->mask.src.u.tcp.port = 0;
1621+ exp->mask.dst.u.tcp.port = htons(0xffff);
1622+ exp->mask.dst.protonum = 0xffff;
1623+ break;
1624+ }
1625+ exp->expectfn = NULL;
1626+
1627+ ip_conntrack_expect_related(ct, &expect);
1628+
1629+ DEBUGP("expect related ip %u.%u.%u.%u:0-%u.%u.%u.%u:%u proto=%u\n",
1630+ NIPQUAD(exp->tuple.src.ip),
1631+ NIPQUAD(exp->tuple.dst.ip),
1632+ port_buf, req_p->proto);
1633+
1634+ DEBUGP("expect related mask %u.%u.%u.%u:0-%u.%u.%u.%u:65535 proto=%u\n",
1635+ NIPQUAD(exp->mask.src.ip),
1636+ NIPQUAD(exp->mask.dst.ip),
1637+ exp->mask.dst.protonum);
1638+
1639+ }
1640+
1641+ req_cl(req_p);
1642+
1643+ DEBUGP("packet evaluated. [expect]\n");
1644+ return NF_ACCEPT;
1645+ }
1646+
1647+ return NF_ACCEPT;
1648+
1649+}
1650+
1651+
1652+/* RPC UDP helper */
1653+static int help(const struct iphdr *iph, size_t len,
1654+ struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
1655+{
1656+ struct udphdr *udph = (void *) iph + iph->ihl * 4;
1657+ const u_int32_t *data = (const u_int32_t *)udph + 2;
1658+ size_t udplen = len - iph->ihl * 4;
1659+ int dir = CTINFO2DIR(ctinfo);
1660+ int crp_ret;
1661+
1662+ /* Checksum */
1663+ const u_int16_t *chsm = (const u_int16_t *)udph + 3;
1664+
1665+
1666+ DEBUGP("new packet to evaluate ..\n");
1667+
1668+ /* Not whole UDP header? */
1669+ if (udplen < sizeof(struct udphdr)) {
1670+ DEBUGP("UDP header length is; udplen=%u ..\n", (unsigned) udplen);
1671+ DEBUGP("packet does not contain a complete UDP header. [skip]\n");
1672+ return NF_ACCEPT;
1673+ }
1674+
1675+ /* FIXME: Source route IP option packets --RR */
1676+ if (*chsm) {
1677+ if (csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP,
1678+ csum_partial((char *)udph, udplen, 0))) {
1679+ DEBUGP("[note: failure to get past this error may indicate source routing]\n");
1680+ DEBUGP("packet contains a bad checksum. [skip]\n");
1681+ return NF_ACCEPT;
1682+ }
1683+ }
1684+
1685+ /* perform direction dependant protocol work */
1686+ if (dir == IP_CT_DIR_ORIGINAL) {
1687+
1688+ DEBUGP("packet is from the initiator. [cont]\n");
1689+
1690+ /* Tests if packet len is ok */
1691+ if ((udplen - sizeof(struct udphdr)) != 56) {
1692+ DEBUGP("packet length is not correct. [skip]\n");
1693+ return NF_ACCEPT;
1694+ }
1695+
1696+ } else {
1697+
1698+ DEBUGP("packet is from the receiver. [cont]\n");
1699+
1700+ /* Until there's been traffic both ways, don't look in packets. */
1701+ if (ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
1702+ DEBUGP("connection tracking state is; ctinfo=%u ..\n", ctinfo);
1703+ DEBUGP("[note: failure to get past this error may indicate asymmetric routing]\n");
1704+ DEBUGP("packet is not yet part of a two way stream. [skip]\n");
1705+ return NF_ACCEPT;
1706+ }
1707+
1708+ /* Tests if packet len is ok */
1709+ if ((udplen - sizeof(struct udphdr)) != 28) {
1710+ DEBUGP("packet length is not correct. [skip]\n");
1711+ return NF_ACCEPT;
1712+ }
1713+
1714+ }
1715+
1716+ /* Get to the data */
1717+ /* udp *data == *correct */
1718+
1719+ /* Check the RPC data */
1720+ crp_ret = check_rpc_packet(data, dir, ct, request_p_list_udp);
1721+
1722+ return crp_ret;
1723+
1724+}
1725+
1726+
1727+static struct ip_conntrack_helper rpc_helpers[MAX_PORTS];
1728+
1729+static void fini(void);
1730+
1731+
1732+static int __init init(void)
1733+{
1734+ int port, ret;
1735+ static char name[10];
1736+
1737+
1738+ /* If no port given, default to standard RPC port */
1739+ if (ports[0] == 0)
1740+ ports[0] = RPC_PORT;
1741+
1742+ for (port = 0; (port < MAX_PORTS) && ports[port]; port++) {
1743+ memset(&rpc_helpers[port], 0, sizeof(struct ip_conntrack_helper));
1744+
1745+ if (ports[port] == RPC_PORT)
1746+ sprintf(name, "rpc");
1747+ else
1748+ sprintf(name, "rpc-%d", port);
1749+
1750+ rpc_helpers[port].name = name;
1751+ rpc_helpers[port].me = THIS_MODULE;
1752+ rpc_helpers[port].max_expected = 1;
1753+ rpc_helpers[port].flags = IP_CT_HELPER_F_REUSE_EXPECT;
1754+ rpc_helpers[port].timeout = 0;
1755+
1756+ rpc_helpers[port].tuple.dst.protonum = IPPROTO_UDP;
1757+ rpc_helpers[port].mask.dst.protonum = 0xffff;
1758+
1759+ /* RPC can come from ports 0:65535 to ports[port] (111) */
1760+ rpc_helpers[port].tuple.src.u.udp.port = htons(ports[port]);
1761+ rpc_helpers[port].mask.src.u.udp.port = htons(0xffff);
1762+ rpc_helpers[port].mask.dst.u.udp.port = htons(0x0);
1763+
1764+ rpc_helpers[port].help = help;
1765+
1766+ DEBUGP("registering helper for port #%d: %d/UDP\n", port, ports[port]);
1767+ DEBUGP("helper match ip %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
1768+ NIPQUAD(rpc_helpers[port].tuple.dst.ip),
1769+ ntohs(rpc_helpers[port].tuple.dst.u.udp.port),
1770+ NIPQUAD(rpc_helpers[port].tuple.src.ip),
1771+ ntohs(rpc_helpers[port].tuple.src.u.udp.port));
1772+ DEBUGP("helper match mask %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
1773+ NIPQUAD(rpc_helpers[port].mask.dst.ip),
1774+ ntohs(rpc_helpers[port].mask.dst.u.udp.port),
1775+ NIPQUAD(rpc_helpers[port].mask.src.ip),
1776+ ntohs(rpc_helpers[port].mask.src.u.udp.port));
1777+
1778+ ret = ip_conntrack_helper_register(&rpc_helpers[port]);
1779+
1780+ if (ret) {
1781+ printk("ERROR registering port %d\n",
1782+ ports[port]);
1783+ fini();
1784+ return -EBUSY;
1785+ }
1786+ ports_n_c++;
1787+ }
1788+ return 0;
1789+}
1790+
1791+
1792+/* This function is intentionally _NOT_ defined as __exit, because
1793+ * it is needed by the init function */
1794+static void fini(void)
1795+{
1796+ int port;
1797+
1798+ DEBUGP("cleaning request list\n");
1799+ clean_request(&request_p_list_udp);
1800+
1801+ for (port = 0; (port < ports_n_c) && ports[port]; port++) {
1802+ DEBUGP("unregistering port %d\n", ports[port]);
1803+ ip_conntrack_helper_unregister(&rpc_helpers[port]);
1804+ }
1805+}
1806+
1807+
1808+module_init(init);
1809+module_exit(fini);
1810+
1811+struct module *ip_conntrack_rpc_udp = THIS_MODULE;
1812+EXPORT_SYMBOL(request_p_list_udp);
1813+EXPORT_SYMBOL(ip_conntrack_rpc_udp);
1814+EXPORT_SYMBOL(ipct_rpc_udp_lock);
1815+
1816diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_rtsp.c linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_rtsp.c
1817--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_rtsp.c 1970-01-01 00:00:00.000000000 +0000
1818+++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_rtsp.c 2004-03-16 12:04:49.000000000 +0000
1819@@ -0,0 +1,509 @@
1820+/*
1821+ * RTSP extension for IP connection tracking
1822+ * (C) 2003 by Tom Marshall <tmarshall@real.com>
1823+ * based on ip_conntrack_irc.c
1824+ *
1825+ * This program is free software; you can redistribute it and/or
1826+ * modify it under the terms of the GNU General Public License
1827+ * as published by the Free Software Foundation; either version
1828+ * 2 of the License, or (at your option) any later version.
1829+ *
1830+ * Module load syntax:
1831+ * insmod ip_conntrack_rtsp.o ports=port1,port2,...port<MAX_PORTS>
1832+ * max_outstanding=n setup_timeout=secs
1833+ *
1834+ * If no ports are specified, the default will be port 554.
1835+ *
1836+ * With max_outstanding you can define the maximum number of not yet
1837+ * answered SETUP requests per RTSP session (default 8).
1838+ * With setup_timeout you can specify how long the system waits for
1839+ * an expected data channel (default 300 seconds).
1840+ */
1841+
1842+#include <linux/config.h>
1843+#include <linux/module.h>
1844+#include <linux/netfilter.h>
1845+#include <linux/ip.h>
1846+#include <net/checksum.h>
1847+#include <net/tcp.h>
1848+
1849+#include <linux/netfilter_ipv4/lockhelp.h>
1850+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
1851+#include <linux/netfilter_ipv4/ip_conntrack_rtsp.h>
1852+
1853+#include <linux/ctype.h>
1854+#define NF_NEED_STRNCASECMP
1855+#define NF_NEED_STRTOU16
1856+#define NF_NEED_STRTOU32
1857+#define NF_NEED_NEXTLINE
1858+#include <linux/netfilter_helpers.h>
1859+#define NF_NEED_MIME_NEXTLINE
1860+#include <linux/netfilter_mime.h>
1861+
1862+#define MAX_SIMUL_SETUP 8 /* XXX: use max_outstanding */
1863+
1864+#define INFOP(args...) printk(KERN_INFO __FILE__ ":" __FUNCTION__ ":" args)
1865+#ifdef IP_NF_RTSP_DEBUG
1866+#define DEBUGP(args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__ ":" args)
1867+#else
1868+#define DEBUGP(args...)
1869+#endif
1870+
1871+#define MAX_PORTS 8
1872+static int ports[MAX_PORTS];
1873+static int num_ports = 0;
1874+static int max_outstanding = 8;
1875+static unsigned int setup_timeout = 300;
1876+
1877+MODULE_AUTHOR("Tom Marshall <tmarshall@real.com>");
1878+MODULE_DESCRIPTION("RTSP connection tracking module");
1879+MODULE_LICENSE("GPL");
1880+#ifdef MODULE_PARM
1881+MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
1882+MODULE_PARM_DESC(ports, "port numbers of RTSP servers");
1883+MODULE_PARM(max_outstanding, "i");
1884+MODULE_PARM_DESC(max_outstanding, "max number of outstanding SETUP requests per RTSP session");
1885+MODULE_PARM(setup_timeout, "i");
1886+MODULE_PARM_DESC(setup_timeout, "timeout on for unestablished data channels");
1887+#endif
1888+
1889+DECLARE_LOCK(ip_rtsp_lock);
1890+struct module* ip_conntrack_rtsp = THIS_MODULE;
1891+
1892+/*
1893+ * Max mappings we will allow for one RTSP connection (for RTP, the number
1894+ * of allocated ports is twice this value). Note that SMIL burns a lot of
1895+ * ports so keep this reasonably high. If this is too low, you will see a
1896+ * lot of "no free client map entries" messages.
1897+ */
1898+#define MAX_PORT_MAPS 16
1899+
1900+/*** default port list was here in the masq code: 554, 3030, 4040 ***/
1901+
1902+#define SKIP_WSPACE(ptr,len,off) while(off < len && isspace(*(ptr+off))) { off++; }
1903+
1904+/*
1905+ * Parse an RTSP packet.
1906+ *
1907+ * Returns zero if parsing failed.
1908+ *
1909+ * Parameters:
1910+ * IN ptcp tcp data pointer
1911+ * IN tcplen tcp data len
1912+ * IN/OUT ptcpoff points to current tcp offset
1913+ * OUT phdrsoff set to offset of rtsp headers
1914+ * OUT phdrslen set to length of rtsp headers
1915+ * OUT pcseqoff set to offset of CSeq header
1916+ * OUT pcseqlen set to length of CSeq header
1917+ */
1918+static int
1919+rtsp_parse_message(char* ptcp, uint tcplen, uint* ptcpoff,
1920+ uint* phdrsoff, uint* phdrslen,
1921+ uint* pcseqoff, uint* pcseqlen)
1922+{
1923+ uint entitylen = 0;
1924+ uint lineoff;
1925+ uint linelen;
1926+
1927+ if (!nf_nextline(ptcp, tcplen, ptcpoff, &lineoff, &linelen))
1928+ {
1929+ return 0;
1930+ }
1931+
1932+ *phdrsoff = *ptcpoff;
1933+ while (nf_mime_nextline(ptcp, tcplen, ptcpoff, &lineoff, &linelen))
1934+ {
1935+ if (linelen == 0)
1936+ {
1937+ if (entitylen > 0)
1938+ {
1939+ *ptcpoff += min(entitylen, tcplen - *ptcpoff);
1940+ }
1941+ break;
1942+ }
1943+ if (lineoff+linelen > tcplen)
1944+ {
1945+ INFOP("!! overrun !!\n");
1946+ break;
1947+ }
1948+
1949+ if (nf_strncasecmp(ptcp+lineoff, "CSeq:", 5) == 0)
1950+ {
1951+ *pcseqoff = lineoff;
1952+ *pcseqlen = linelen;
1953+ }
1954+ if (nf_strncasecmp(ptcp+lineoff, "Content-Length:", 15) == 0)
1955+ {
1956+ uint off = lineoff+15;
1957+ SKIP_WSPACE(ptcp+lineoff, linelen, off);
1958+ nf_strtou32(ptcp+off, &entitylen);
1959+ }
1960+ }
1961+ *phdrslen = (*ptcpoff) - (*phdrsoff);
1962+
1963+ return 1;
1964+}
1965+
1966+/*
1967+ * Find lo/hi client ports (if any) in transport header
1968+ * In:
1969+ * ptcp, tcplen = packet
1970+ * tranoff, tranlen = buffer to search
1971+ *
1972+ * Out:
1973+ * pport_lo, pport_hi = lo/hi ports (host endian)
1974+ *
1975+ * Returns nonzero if any client ports found
1976+ *
1977+ * Note: it is valid (and expected) for the client to request multiple
1978+ * transports, so we need to parse the entire line.
1979+ */
1980+static int
1981+rtsp_parse_transport(char* ptran, uint tranlen,
1982+ struct ip_ct_rtsp_expect* prtspexp)
1983+{
1984+ int rc = 0;
1985+ uint off = 0;
1986+
1987+ if (tranlen < 10 || !iseol(ptran[tranlen-1]) ||
1988+ nf_strncasecmp(ptran, "Transport:", 10) != 0)
1989+ {
1990+ INFOP("sanity check failed\n");
1991+ return 0;
1992+ }
1993+ DEBUGP("tran='%.*s'\n", (int)tranlen, ptran);
1994+ off += 10;
1995+ SKIP_WSPACE(ptran, tranlen, off);
1996+
1997+ /* Transport: tran;field;field=val,tran;field;field=val,... */
1998+ while (off < tranlen)
1999+ {
2000+ const char* pparamend;
2001+ uint nextparamoff;
2002+
2003+ pparamend = memchr(ptran+off, ',', tranlen-off);
2004+ pparamend = (pparamend == NULL) ? ptran+tranlen : pparamend+1;
2005+ nextparamoff = pparamend-ptran;
2006+
2007+ while (off < nextparamoff)
2008+ {
2009+ const char* pfieldend;
2010+ uint nextfieldoff;
2011+
2012+ pfieldend = memchr(ptran+off, ';', nextparamoff-off);
2013+ nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;
2014+
2015+ if (strncmp(ptran+off, "client_port=", 12) == 0)
2016+ {
2017+ u_int16_t port;
2018+ uint numlen;
2019+
2020+ off += 12;
2021+ numlen = nf_strtou16(ptran+off, &port);
2022+ off += numlen;
2023+ if (prtspexp->loport != 0 && prtspexp->loport != port)
2024+ {
2025+ DEBUGP("multiple ports found, port %hu ignored\n", port);
2026+ }
2027+ else
2028+ {
2029+ prtspexp->loport = prtspexp->hiport = port;
2030+ if (ptran[off] == '-')
2031+ {
2032+ off++;
2033+ numlen = nf_strtou16(ptran+off, &port);
2034+ off += numlen;
2035+ prtspexp->pbtype = pb_range;
2036+ prtspexp->hiport = port;
2037+
2038+ // If we have a range, assume rtp:
2039+ // loport must be even, hiport must be loport+1
2040+ if ((prtspexp->loport & 0x0001) != 0 ||
2041+ prtspexp->hiport != prtspexp->loport+1)
2042+ {
2043+ DEBUGP("incorrect range: %hu-%hu, correcting\n",
2044+ prtspexp->loport, prtspexp->hiport);
2045+ prtspexp->loport &= 0xfffe;
2046+ prtspexp->hiport = prtspexp->loport+1;
2047+ }
2048+ }
2049+ else if (ptran[off] == '/')
2050+ {
2051+ off++;
2052+ numlen = nf_strtou16(ptran+off, &port);
2053+ off += numlen;
2054+ prtspexp->pbtype = pb_discon;
2055+ prtspexp->hiport = port;
2056+ }
2057+ rc = 1;
2058+ }
2059+ }
2060+
2061+ /*
2062+ * Note we don't look for the destination parameter here.
2063+ * If we are using NAT, the NAT module will handle it. If not,
2064+ * and the client is sending packets elsewhere, the expectation
2065+ * will quietly time out.
2066+ */
2067+
2068+ off = nextfieldoff;
2069+ }
2070+
2071+ off = nextparamoff;
2072+ }
2073+
2074+ return rc;
2075+}
2076+
2077+/*** conntrack functions ***/
2078+
2079+/* outbound packet: client->server */
2080+static int
2081+help_out(const struct iphdr* iph, size_t pktlen,
2082+ struct ip_conntrack* ct, enum ip_conntrack_info ctinfo)
2083+{
2084+ int dir = CTINFO2DIR(ctinfo); /* = IP_CT_DIR_ORIGINAL */
2085+ struct tcphdr* tcph = (void*)iph + iph->ihl * 4;
2086+ uint tcplen = pktlen - iph->ihl * 4;
2087+ char* pdata = (char*)tcph + tcph->doff * 4;
2088+ uint datalen = tcplen - tcph->doff * 4;
2089+ uint dataoff = 0;
2090+
2091+ struct ip_conntrack_expect exp;
2092+
2093+ while (dataoff < datalen)
2094+ {
2095+ uint cmdoff = dataoff;
2096+ uint hdrsoff = 0;
2097+ uint hdrslen = 0;
2098+ uint cseqoff = 0;
2099+ uint cseqlen = 0;
2100+ uint lineoff = 0;
2101+ uint linelen = 0;
2102+ uint off;
2103+ int rc;
2104+
2105+ if (!rtsp_parse_message(pdata, datalen, &dataoff,
2106+ &hdrsoff, &hdrslen,
2107+ &cseqoff, &cseqlen))
2108+ {
2109+ break; /* not a valid message */
2110+ }
2111+
2112+ if (strncmp(pdata+cmdoff, "SETUP ", 6) != 0)
2113+ {
2114+ continue; /* not a SETUP message */
2115+ }
2116+ DEBUGP("found a setup message\n");
2117+
2118+ memset(&exp, 0, sizeof(exp));
2119+
2120+ off = 0;
2121+ while (nf_mime_nextline(pdata+hdrsoff, hdrslen, &off,
2122+ &lineoff, &linelen))
2123+ {
2124+ if (linelen == 0)
2125+ {
2126+ break;
2127+ }
2128+ if (off > hdrsoff+hdrslen)
2129+ {
2130+ INFOP("!! overrun !!");
2131+ break;
2132+ }
2133+
2134+ if (nf_strncasecmp(pdata+hdrsoff+lineoff, "Transport:", 10) == 0)
2135+ {
2136+ rtsp_parse_transport(pdata+hdrsoff+lineoff, linelen,
2137+ &exp.help.exp_rtsp_info);
2138+ }
2139+ }
2140+
2141+ if (exp.help.exp_rtsp_info.loport == 0)
2142+ {
2143+ DEBUGP("no udp transports found\n");
2144+ continue; /* no udp transports found */
2145+ }
2146+
2147+ DEBUGP("udp transport found, ports=(%d,%hu,%hu)\n",
2148+ (int)exp.help.exp_rtsp_info.pbtype,
2149+ exp.help.exp_rtsp_info.loport,
2150+ exp.help.exp_rtsp_info.hiport);
2151+
2152+ LOCK_BH(&ip_rtsp_lock);
2153+ exp.seq = ntohl(tcph->seq) + hdrsoff; /* mark all the headers */
2154+ exp.help.exp_rtsp_info.len = hdrslen;
2155+
2156+ exp.tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
2157+ exp.mask.src.ip = 0xffffffff;
2158+ exp.tuple.dst.ip = ct->tuplehash[dir].tuple.src.ip;
2159+ exp.mask.dst.ip = 0xffffffff;
2160+ exp.tuple.dst.u.udp.port = exp.help.exp_rtsp_info.loport;
2161+ exp.mask.dst.u.udp.port = (exp.help.exp_rtsp_info.pbtype == pb_range) ? 0xfffe : 0xffff;
2162+ exp.tuple.dst.protonum = IPPROTO_UDP;
2163+ exp.mask.dst.protonum = 0xffff;
2164+
2165+ DEBUGP("expect_related %u.%u.%u.%u:%u-%u.%u.%u.%u:%u\n",
2166+ NIPQUAD(exp.tuple.src.ip),
2167+ ntohs(exp.tuple.src.u.tcp.port),
2168+ NIPQUAD(exp.tuple.dst.ip),
2169+ ntohs(exp.tuple.dst.u.tcp.port));
2170+
2171+ /* pass the request off to the nat helper */
2172+ rc = ip_conntrack_expect_related(ct, &exp);
2173+ UNLOCK_BH(&ip_rtsp_lock);
2174+ if (rc == 0)
2175+ {
2176+ DEBUGP("ip_conntrack_expect_related succeeded\n");
2177+ }
2178+ else
2179+ {
2180+ INFOP("ip_conntrack_expect_related failed (%d)\n", rc);
2181+ }
2182+ }
2183+
2184+ return NF_ACCEPT;
2185+}
2186+
2187+/* inbound packet: server->client */
2188+static int
2189+help_in(const struct iphdr* iph, size_t pktlen,
2190+ struct ip_conntrack* ct, enum ip_conntrack_info ctinfo)
2191+{
2192+ return NF_ACCEPT;
2193+}
2194+
2195+static int
2196+help(const struct iphdr* iph, size_t pktlen,
2197+ struct ip_conntrack* ct, enum ip_conntrack_info ctinfo)
2198+{
2199+ /* tcplen not negative guarenteed by ip_conntrack_tcp.c */
2200+ struct tcphdr* tcph = (void*)iph + iph->ihl * 4;
2201+ u_int32_t tcplen = pktlen - iph->ihl * 4;
2202+
2203+ /* Until there's been traffic both ways, don't look in packets. */
2204+ if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY)
2205+ {
2206+ DEBUGP("conntrackinfo = %u\n", ctinfo);
2207+ return NF_ACCEPT;
2208+ }
2209+
2210+ /* Not whole TCP header? */
2211+ if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4)
2212+ {
2213+ DEBUGP("tcplen = %u\n", (unsigned)tcplen);
2214+ return NF_ACCEPT;
2215+ }
2216+
2217+ /* Checksum invalid? Ignore. */
2218+ /* FIXME: Source route IP option packets --RR */
2219+ if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
2220+ csum_partial((char*)tcph, tcplen, 0)))
2221+ {
2222+ DEBUGP("bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n",
2223+ tcph, tcplen, NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
2224+ return NF_ACCEPT;
2225+ }
2226+
2227+ switch (CTINFO2DIR(ctinfo))
2228+ {
2229+ case IP_CT_DIR_ORIGINAL:
2230+ help_out(iph, pktlen, ct, ctinfo);
2231+ break;
2232+ case IP_CT_DIR_REPLY:
2233+ help_in(iph, pktlen, ct, ctinfo);
2234+ break;
2235+ default:
2236+ /* oops */
2237+ }
2238+
2239+ return NF_ACCEPT;
2240+}
2241+
2242+static struct ip_conntrack_helper rtsp_helpers[MAX_PORTS];
2243+static char rtsp_names[MAX_PORTS][10];
2244+
2245+/* This function is intentionally _NOT_ defined as __exit */
2246+static void
2247+fini(void)
2248+{
2249+ int i;
2250+ for (i = 0; i < num_ports; i++)
2251+ {
2252+ DEBUGP("unregistering port %d\n", ports[i]);
2253+ ip_conntrack_helper_unregister(&rtsp_helpers[i]);
2254+ }
2255+}
2256+
2257+static int __init
2258+init(void)
2259+{
2260+ int i, ret;
2261+ struct ip_conntrack_helper *hlpr;
2262+ char *tmpname;
2263+
2264+ printk("ip_conntrack_rtsp v" IP_NF_RTSP_VERSION " loading\n");
2265+
2266+ if (max_outstanding < 1)
2267+ {
2268+ printk("ip_conntrack_rtsp: max_outstanding must be a positive integer\n");
2269+ return -EBUSY;
2270+ }
2271+ if (setup_timeout < 0)
2272+ {
2273+ printk("ip_conntrack_rtsp: setup_timeout must be a positive integer\n");
2274+ return -EBUSY;
2275+ }
2276+
2277+ /* If no port given, default to standard rtsp port */
2278+ if (ports[0] == 0)
2279+ {
2280+ ports[0] = RTSP_PORT;
2281+ }
2282+
2283+ for (i = 0; (i < MAX_PORTS) && ports[i]; i++)
2284+ {
2285+ hlpr = &rtsp_helpers[i];
2286+ memset(hlpr, 0, sizeof(struct ip_conntrack_helper));
2287+ hlpr->tuple.src.u.tcp.port = htons(ports[i]);
2288+ hlpr->tuple.dst.protonum = IPPROTO_TCP;
2289+ hlpr->mask.src.u.tcp.port = 0xFFFF;
2290+ hlpr->mask.dst.protonum = 0xFFFF;
2291+ hlpr->max_expected = max_outstanding;
2292+ hlpr->timeout = setup_timeout;
2293+ hlpr->flags = IP_CT_HELPER_F_REUSE_EXPECT;
2294+ hlpr->me = ip_conntrack_rtsp;
2295+ hlpr->help = help;
2296+
2297+ tmpname = &rtsp_names[i][0];
2298+ if (ports[i] == RTSP_PORT)
2299+ {
2300+ sprintf(tmpname, "rtsp");
2301+ }
2302+ else
2303+ {
2304+ sprintf(tmpname, "rtsp-%d", i);
2305+ }
2306+ hlpr->name = tmpname;
2307+
2308+ DEBUGP("port #%d: %d\n", i, ports[i]);
2309+
2310+ ret = ip_conntrack_helper_register(hlpr);
2311+
2312+ if (ret)
2313+ {
2314+ printk("ip_conntrack_rtsp: ERROR registering port %d\n", ports[i]);
2315+ fini();
2316+ return -EBUSY;
2317+ }
2318+ num_ports++;
2319+ }
2320+ return 0;
2321+}
2322+
2323+#ifdef CONFIG_IP_NF_NAT_NEEDED
2324+EXPORT_SYMBOL(ip_rtsp_lock);
2325+#endif
2326+
2327+module_init(init);
2328+module_exit(fini);
2329diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_standalone.c
2330--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-03-16 12:00:23.000000000 +0000
2331+++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-03-16 12:04:09.000000000 +0000
2332@@ -110,6 +110,9 @@
2333 len += sprintf(buffer + len, "[ASSURED] ");
2334 len += sprintf(buffer + len, "use=%u ",
2335 atomic_read(&conntrack->ct_general.use));
2336+#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
2337+ len += sprintf(buffer + len, "mark=%ld ", conntrack->mark);
2338+#endif
2339 len += sprintf(buffer + len, "\n");
2340
2341 return len;
2342diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_nat_rtsp.c linux-2.6.5-rc1/net/ipv4/netfilter/ip_nat_rtsp.c
2343--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_nat_rtsp.c 1970-01-01 00:00:00.000000000 +0000
2344+++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_nat_rtsp.c 2004-03-16 12:04:49.000000000 +0000
2345@@ -0,0 +1,625 @@
2346+/*
2347+ * RTSP extension for TCP NAT alteration
2348+ * (C) 2003 by Tom Marshall <tmarshall@real.com>
2349+ * based on ip_nat_irc.c
2350+ *
2351+ * This program is free software; you can redistribute it and/or
2352+ * modify it under the terms of the GNU General Public License
2353+ * as published by the Free Software Foundation; either version
2354+ * 2 of the License, or (at your option) any later version.
2355+ *
2356+ * Module load syntax:
2357+ * insmod ip_nat_rtsp.o ports=port1,port2,...port<MAX_PORTS>
2358+ * stunaddr=<address>
2359+ * destaction=[auto|strip|none]
2360+ *
2361+ * If no ports are specified, the default will be port 554 only.
2362+ *
2363+ * stunaddr specifies the address used to detect that a client is using STUN.
2364+ * If this address is seen in the destination parameter, it is assumed that
2365+ * the client has already punched a UDP hole in the firewall, so we don't
2366+ * mangle the client_port. If none is specified, it is autodetected. It
2367+ * only needs to be set if you have multiple levels of NAT. It should be
2368+ * set to the external address that the STUN clients detect. Note that in
2369+ * this case, it will not be possible for clients to use UDP with servers
2370+ * between the NATs.
2371+ *
2372+ * If no destaction is specified, auto is used.
2373+ * destaction=auto: strip destination parameter if it is not stunaddr.
2374+ * destaction=strip: always strip destination parameter (not recommended).
2375+ * destaction=none: do not touch destination parameter (not recommended).
2376+ */
2377+
2378+#include <linux/module.h>
2379+#include <linux/netfilter_ipv4.h>
2380+#include <linux/ip.h>
2381+#include <linux/tcp.h>
2382+#include <linux/kernel.h>
2383+#include <net/tcp.h>
2384+#include <linux/netfilter_ipv4/ip_nat.h>
2385+#include <linux/netfilter_ipv4/ip_nat_helper.h>
2386+#include <linux/netfilter_ipv4/ip_nat_rule.h>
2387+#include <linux/netfilter_ipv4/ip_conntrack_rtsp.h>
2388+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
2389+
2390+#include <linux/inet.h>
2391+#include <linux/ctype.h>
2392+#define NF_NEED_STRNCASECMP
2393+#define NF_NEED_STRTOU16
2394+#include <linux/netfilter_helpers.h>
2395+#define NF_NEED_MIME_NEXTLINE
2396+#include <linux/netfilter_mime.h>
2397+
2398+#define INFOP(args...) printk(KERN_INFO __FILE__ ":" __FUNCTION__ ":" args)
2399+#ifdef IP_NF_RTSP_DEBUG
2400+#define DEBUGP(args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__ ":" args);
2401+#else
2402+#define DEBUGP(args...)
2403+#endif
2404+
2405+#define MAX_PORTS 8
2406+#define DSTACT_AUTO 0
2407+#define DSTACT_STRIP 1
2408+#define DSTACT_NONE 2
2409+
2410+static int ports[MAX_PORTS];
2411+static char* stunaddr = NULL;
2412+static char* destaction = NULL;
2413+
2414+static int num_ports = 0;
2415+static u_int32_t extip = 0;
2416+static int dstact = 0;
2417+
2418+MODULE_AUTHOR("Tom Marshall <tmarshall@real.com>");
2419+MODULE_DESCRIPTION("RTSP network address translation module");
2420+MODULE_LICENSE("GPL");
2421+#ifdef MODULE_PARM
2422+MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
2423+MODULE_PARM_DESC(ports, "port numbers of RTSP servers");
2424+MODULE_PARM(stunaddr, "s");
2425+MODULE_PARM_DESC(stunaddr, "Address for detecting STUN");
2426+MODULE_PARM(destaction, "s");
2427+MODULE_PARM_DESC(destaction, "Action for destination parameter (auto/strip/none)");
2428+#endif
2429+
2430+/* protects rtsp part of conntracks */
2431+DECLARE_LOCK_EXTERN(ip_rtsp_lock);
2432+
2433+#define SKIP_WSPACE(ptr,len,off) while(off < len && isspace(*(ptr+off))) { off++; }
2434+
2435+/*** helper functions ***/
2436+
2437+static void
2438+get_skb_tcpdata(struct sk_buff* skb, char** pptcpdata, uint* ptcpdatalen)
2439+{
2440+ struct iphdr* iph = (struct iphdr*)skb->nh.iph;
2441+ struct tcphdr* tcph = (struct tcphdr*)((char*)iph + iph->ihl*4);
2442+
2443+ *pptcpdata = (char*)tcph + tcph->doff*4;
2444+ *ptcpdatalen = ((char*)skb->h.raw + skb->len) - *pptcpdata;
2445+}
2446+
2447+/*** nat functions ***/
2448+
2449+/*
2450+ * Mangle the "Transport:" header:
2451+ * - Replace all occurences of "client_port=<spec>"
2452+ * - Handle destination parameter
2453+ *
2454+ * In:
2455+ * ct, ctinfo = conntrack context
2456+ * pskb = packet
2457+ * tranoff = Transport header offset from TCP data
2458+ * tranlen = Transport header length (incl. CRLF)
2459+ * rport_lo = replacement low port (host endian)
2460+ * rport_hi = replacement high port (host endian)
2461+ *
2462+ * Returns packet size difference.
2463+ *
2464+ * Assumes that a complete transport header is present, ending with CR or LF
2465+ */
2466+static int
2467+rtsp_mangle_tran(struct ip_conntrack* ct, enum ip_conntrack_info ctinfo,
2468+ struct ip_conntrack_expect* exp,
2469+ struct sk_buff** pskb, uint tranoff, uint tranlen)
2470+{
2471+ char* ptcp;
2472+ uint tcplen;
2473+ char* ptran;
2474+ char rbuf1[16]; /* Replacement buffer (one port) */
2475+ uint rbuf1len; /* Replacement len (one port) */
2476+ char rbufa[16]; /* Replacement buffer (all ports) */
2477+ uint rbufalen; /* Replacement len (all ports) */
2478+ u_int32_t newip;
2479+ u_int16_t loport, hiport;
2480+ uint off = 0;
2481+ uint diff; /* Number of bytes we removed */
2482+
2483+ struct ip_ct_rtsp_expect* prtspexp = &exp->help.exp_rtsp_info;
2484+ struct ip_conntrack_tuple t;
2485+
2486+ char szextaddr[15+1];
2487+ uint extaddrlen;
2488+ int is_stun;
2489+
2490+ get_skb_tcpdata(*pskb, &ptcp, &tcplen);
2491+ ptran = ptcp+tranoff;
2492+
2493+ if (tranoff+tranlen > tcplen || tcplen-tranoff < tranlen ||
2494+ tranlen < 10 || !iseol(ptran[tranlen-1]) ||
2495+ nf_strncasecmp(ptran, "Transport:", 10) != 0)
2496+ {
2497+ INFOP("sanity check failed\n");
2498+ return 0;
2499+ }
2500+ off += 10;
2501+ SKIP_WSPACE(ptcp+tranoff, tranlen, off);
2502+
2503+ newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
2504+ t = exp->tuple;
2505+ t.dst.ip = newip;
2506+
2507+ extaddrlen = extip ? sprintf(szextaddr, "%u.%u.%u.%u", NIPQUAD(extip))
2508+ : sprintf(szextaddr, "%u.%u.%u.%u", NIPQUAD(newip));
2509+ DEBUGP("stunaddr=%s (%s)\n", szextaddr, (extip?"forced":"auto"));
2510+
2511+ rbuf1len = rbufalen = 0;
2512+ switch (prtspexp->pbtype)
2513+ {
2514+ case pb_single:
2515+ for (loport = prtspexp->loport; loport != 0; loport++) /* XXX: improper wrap? */
2516+ {
2517+ t.dst.u.udp.port = htons(loport);
2518+ if (ip_conntrack_change_expect(exp, &t) == 0)
2519+ {
2520+ DEBUGP("using port %hu\n", loport);
2521+ break;
2522+ }
2523+ }
2524+ if (loport != 0)
2525+ {
2526+ rbuf1len = sprintf(rbuf1, "%hu", loport);
2527+ rbufalen = sprintf(rbufa, "%hu", loport);
2528+ }
2529+ break;
2530+ case pb_range:
2531+ for (loport = prtspexp->loport; loport != 0; loport += 2) /* XXX: improper wrap? */
2532+ {
2533+ t.dst.u.udp.port = htons(loport);
2534+ if (ip_conntrack_change_expect(exp, &t) == 0)
2535+ {
2536+ hiport = loport + ~exp->mask.dst.u.udp.port;
2537+ DEBUGP("using ports %hu-%hu\n", loport, hiport);
2538+ break;
2539+ }
2540+ }
2541+ if (loport != 0)
2542+ {
2543+ rbuf1len = sprintf(rbuf1, "%hu", loport);
2544+ rbufalen = sprintf(rbufa, "%hu-%hu", loport, loport+1);
2545+ }
2546+ break;
2547+ case pb_discon:
2548+ for (loport = prtspexp->loport; loport != 0; loport++) /* XXX: improper wrap? */
2549+ {
2550+ t.dst.u.udp.port = htons(loport);
2551+ if (ip_conntrack_change_expect(exp, &t) == 0)
2552+ {
2553+ DEBUGP("using port %hu (1 of 2)\n", loport);
2554+ break;
2555+ }
2556+ }
2557+ for (hiport = prtspexp->hiport; hiport != 0; hiport++) /* XXX: improper wrap? */
2558+ {
2559+ t.dst.u.udp.port = htons(hiport);
2560+ if (ip_conntrack_change_expect(exp, &t) == 0)
2561+ {
2562+ DEBUGP("using port %hu (2 of 2)\n", hiport);
2563+ break;
2564+ }
2565+ }
2566+ if (loport != 0 && hiport != 0)
2567+ {
2568+ rbuf1len = sprintf(rbuf1, "%hu", loport);
2569+ if (hiport == loport+1)
2570+ {
2571+ rbufalen = sprintf(rbufa, "%hu-%hu", loport, hiport);
2572+ }
2573+ else
2574+ {
2575+ rbufalen = sprintf(rbufa, "%hu/%hu", loport, hiport);
2576+ }
2577+ }
2578+ break;
2579+ default:
2580+ /* oops */
2581+ }
2582+
2583+ if (rbuf1len == 0)
2584+ {
2585+ return 0; /* cannot get replacement port(s) */
2586+ }
2587+
2588+ /* Transport: tran;field;field=val,tran;field;field=val,... */
2589+ while (off < tranlen)
2590+ {
2591+ uint saveoff;
2592+ const char* pparamend;
2593+ uint nextparamoff;
2594+
2595+ pparamend = memchr(ptran+off, ',', tranlen-off);
2596+ pparamend = (pparamend == NULL) ? ptran+tranlen : pparamend+1;
2597+ nextparamoff = pparamend-ptcp;
2598+
2599+ /*
2600+ * We pass over each param twice. On the first pass, we look for a
2601+ * destination= field. It is handled by the security policy. If it
2602+ * is present, allowed, and equal to our external address, we assume
2603+ * that STUN is being used and we leave the client_port= field alone.
2604+ */
2605+ is_stun = 0;
2606+ saveoff = off;
2607+ while (off < nextparamoff)
2608+ {
2609+ const char* pfieldend;
2610+ uint nextfieldoff;
2611+
2612+ pfieldend = memchr(ptran+off, ';', nextparamoff-off);
2613+ nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;
2614+
2615+ if (dstact != DSTACT_NONE && strncmp(ptran+off, "destination=", 12) == 0)
2616+ {
2617+ if (strncmp(ptran+off+12, szextaddr, extaddrlen) == 0)
2618+ {
2619+ is_stun = 1;
2620+ }
2621+ if (dstact == DSTACT_STRIP || (dstact == DSTACT_AUTO && !is_stun))
2622+ {
2623+ diff = nextfieldoff-off;
2624+ if (!ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
2625+ off, diff, NULL, 0))
2626+ {
2627+ /* mangle failed, all we can do is bail */
2628+ return 0;
2629+ }
2630+ get_skb_tcpdata(*pskb, &ptcp, &tcplen);
2631+ ptran = ptcp+tranoff;
2632+ tranlen -= diff;
2633+ nextparamoff -= diff;
2634+ nextfieldoff -= diff;
2635+ }
2636+ }
2637+
2638+ off = nextfieldoff;
2639+ }
2640+ if (is_stun)
2641+ {
2642+ continue;
2643+ }
2644+ off = saveoff;
2645+ while (off < nextparamoff)
2646+ {
2647+ const char* pfieldend;
2648+ uint nextfieldoff;
2649+
2650+ pfieldend = memchr(ptran+off, ';', nextparamoff-off);
2651+ nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;
2652+
2653+ if (strncmp(ptran+off, "client_port=", 12) == 0)
2654+ {
2655+ u_int16_t port;
2656+ uint numlen;
2657+ uint origoff;
2658+ uint origlen;
2659+ char* rbuf = rbuf1;
2660+ uint rbuflen = rbuf1len;
2661+
2662+ off += 12;
2663+ origoff = (ptran-ptcp)+off;
2664+ origlen = 0;
2665+ numlen = nf_strtou16(ptran+off, &port);
2666+ off += numlen;
2667+ origlen += numlen;
2668+ if (port != prtspexp->loport)
2669+ {
2670+ DEBUGP("multiple ports found, port %hu ignored\n", port);
2671+ }
2672+ else
2673+ {
2674+ if (ptran[off] == '-' || ptran[off] == '/')
2675+ {
2676+ off++;
2677+ origlen++;
2678+ numlen = nf_strtou16(ptran+off, &port);
2679+ off += numlen;
2680+ origlen += numlen;
2681+ rbuf = rbufa;
2682+ rbuflen = rbufalen;
2683+ }
2684+
2685+ /*
2686+ * note we cannot just memcpy() if the sizes are the same.
2687+ * the mangle function does skb resizing, checks for a
2688+ * cloned skb, and updates the checksums.
2689+ *
2690+ * parameter 4 below is offset from start of tcp data.
2691+ */
2692+ diff = origlen-rbuflen;
2693+ if (!ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
2694+ origoff, origlen, rbuf, rbuflen))
2695+ {
2696+ /* mangle failed, all we can do is bail */
2697+ return 0;
2698+ }
2699+ get_skb_tcpdata(*pskb, &ptcp, &tcplen);
2700+ ptran = ptcp+tranoff;
2701+ tranlen -= diff;
2702+ nextparamoff -= diff;
2703+ nextfieldoff -= diff;
2704+ }
2705+ }
2706+
2707+ off = nextfieldoff;
2708+ }
2709+
2710+ off = nextparamoff;
2711+ }
2712+
2713+ return 1;
2714+}
2715+
2716+static unsigned int
2717+expected(struct sk_buff **pskb, uint hooknum, struct ip_conntrack* ct, struct ip_nat_info* info)
2718+{
2719+ struct ip_nat_multi_range mr;
2720+ u_int32_t newdstip, newsrcip, newip;
2721+
2722+ struct ip_conntrack *master = master_ct(ct);
2723+
2724+ IP_NF_ASSERT(info);
2725+ IP_NF_ASSERT(master);
2726+
2727+ IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
2728+
2729+ newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
2730+ newsrcip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
2731+ newip = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) ? newsrcip : newdstip;
2732+
2733+ DEBUGP("newsrcip=%u.%u.%u.%u, newdstip=%u.%u.%u.%u, newip=%u.%u.%u.%u\n",
2734+ NIPQUAD(newsrcip), NIPQUAD(newdstip), NIPQUAD(newip));
2735+
2736+ mr.rangesize = 1;
2737+ /* We don't want to manip the per-protocol, just the IPs. */
2738+ mr.range[0].flags = IP_NAT_RANGE_MAP_IPS;
2739+ mr.range[0].min_ip = mr.range[0].max_ip = newip;
2740+
2741+ return ip_nat_setup_info(ct, &mr, hooknum);
2742+}
2743+
2744+static uint
2745+help_out(struct ip_conntrack* ct, enum ip_conntrack_info ctinfo,
2746+ struct ip_conntrack_expect* exp, struct sk_buff** pskb)
2747+{
2748+ char* ptcp;
2749+ uint tcplen;
2750+ uint hdrsoff;
2751+ uint hdrslen;
2752+ uint lineoff;
2753+ uint linelen;
2754+ uint off;
2755+
2756+ struct iphdr* iph = (struct iphdr*)(*pskb)->nh.iph;
2757+ struct tcphdr* tcph = (struct tcphdr*)((void*)iph + iph->ihl*4);
2758+
2759+ struct ip_ct_rtsp_expect* prtspexp = &exp->help.exp_rtsp_info;
2760+
2761+ get_skb_tcpdata(*pskb, &ptcp, &tcplen);
2762+
2763+ hdrsoff = exp->seq - ntohl(tcph->seq);
2764+ hdrslen = prtspexp->len;
2765+ off = hdrsoff;
2766+
2767+ while (nf_mime_nextline(ptcp, hdrsoff+hdrslen, &off, &lineoff, &linelen))
2768+ {
2769+ if (linelen == 0)
2770+ {
2771+ break;
2772+ }
2773+ if (off > hdrsoff+hdrslen)
2774+ {
2775+ INFOP("!! overrun !!");
2776+ break;
2777+ }
2778+ DEBUGP("hdr: len=%u, %.*s", linelen, (int)linelen, ptcp+lineoff);
2779+
2780+ if (nf_strncasecmp(ptcp+lineoff, "Transport:", 10) == 0)
2781+ {
2782+ uint oldtcplen = tcplen;
2783+ if (!rtsp_mangle_tran(ct, ctinfo, exp, pskb, lineoff, linelen))
2784+ {
2785+ break;
2786+ }
2787+ get_skb_tcpdata(*pskb, &ptcp, &tcplen);
2788+ hdrslen -= (oldtcplen-tcplen);
2789+ off -= (oldtcplen-tcplen);
2790+ lineoff -= (oldtcplen-tcplen);
2791+ linelen -= (oldtcplen-tcplen);
2792+ DEBUGP("rep: len=%u, %.*s", linelen, (int)linelen, ptcp+lineoff);
2793+ }
2794+ }
2795+
2796+ return NF_ACCEPT;
2797+}
2798+
2799+static uint
2800+help_in(struct ip_conntrack* ct, enum ip_conntrack_info ctinfo,
2801+ struct ip_conntrack_expect* exp, struct sk_buff** pskb)
2802+{
2803+ /* XXX: unmangle */
2804+ return NF_ACCEPT;
2805+}
2806+
2807+static uint
2808+help(struct ip_conntrack* ct,
2809+ struct ip_conntrack_expect* exp,
2810+ struct ip_nat_info* info,
2811+ enum ip_conntrack_info ctinfo,
2812+ unsigned int hooknum,
2813+ struct sk_buff** pskb)
2814+{
2815+ struct iphdr* iph = (struct iphdr*)(*pskb)->nh.iph;
2816+ struct tcphdr* tcph = (struct tcphdr*)((char*)iph + iph->ihl * 4);
2817+ uint datalen;
2818+ int dir;
2819+ struct ip_ct_rtsp_expect* ct_rtsp_info;
2820+ int rc = NF_ACCEPT;
2821+
2822+ if (ct == NULL || exp == NULL || info == NULL || pskb == NULL)
2823+ {
2824+ DEBUGP("!! null ptr (%p,%p,%p,%p) !!\n", ct, exp, info, pskb);
2825+ return NF_ACCEPT;
2826+ }
2827+
2828+ ct_rtsp_info = &exp->help.exp_rtsp_info;
2829+
2830+ /*
2831+ * Only mangle things once: original direction in POST_ROUTING
2832+ * and reply direction on PRE_ROUTING.
2833+ */
2834+ dir = CTINFO2DIR(ctinfo);
2835+ if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL)
2836+ || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY)))
2837+ {
2838+ DEBUGP("Not touching dir %s at hook %s\n",
2839+ dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
2840+ hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
2841+ : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
2842+ : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???");
2843+ return NF_ACCEPT;
2844+ }
2845+ DEBUGP("got beyond not touching\n");
2846+
2847+ datalen = (*pskb)->len - iph->ihl * 4 - tcph->doff * 4;
2848+
2849+ LOCK_BH(&ip_rtsp_lock);
2850+ /* Ensure the packet contains all of the marked data */
2851+ if (!between(exp->seq + ct_rtsp_info->len,
2852+ ntohl(tcph->seq), ntohl(tcph->seq) + datalen))
2853+ {
2854+ /* Partial retransmission? Probably a hacker. */
2855+ if (net_ratelimit())
2856+ {
2857+ INFOP("partial packet %u/%u in %u/%u\n",
2858+ exp->seq, ct_rtsp_info->len, ntohl(tcph->seq), ntohl(tcph->seq) + datalen);
2859+ }
2860+ UNLOCK_BH(&ip_rtsp_lock);
2861+ return NF_DROP;
2862+ }
2863+
2864+ switch (dir)
2865+ {
2866+ case IP_CT_DIR_ORIGINAL:
2867+ rc = help_out(ct, ctinfo, exp, pskb);
2868+ break;
2869+ case IP_CT_DIR_REPLY:
2870+ rc = help_in(ct, ctinfo, exp, pskb);
2871+ break;
2872+ default:
2873+ /* oops */
2874+ }
2875+ UNLOCK_BH(&ip_rtsp_lock);
2876+
2877+ return rc;
2878+}
2879+
2880+static struct ip_nat_helper ip_nat_rtsp_helpers[MAX_PORTS];
2881+static char rtsp_names[MAX_PORTS][10];
2882+
2883+/* This function is intentionally _NOT_ defined as __exit */
2884+static void
2885+fini(void)
2886+{
2887+ int i;
2888+
2889+ for (i = 0; i < num_ports; i++)
2890+ {
2891+ DEBUGP("unregistering helper for port %d\n", ports[i]);
2892+ ip_nat_helper_unregister(&ip_nat_rtsp_helpers[i]);
2893+ }
2894+}
2895+
2896+static int __init
2897+init(void)
2898+{
2899+ int ret = 0;
2900+ int i;
2901+ struct ip_nat_helper* hlpr;
2902+ char* tmpname;
2903+
2904+ printk("ip_nat_rtsp v" IP_NF_RTSP_VERSION " loading\n");
2905+
2906+ if (ports[0] == 0)
2907+ {
2908+ ports[0] = RTSP_PORT;
2909+ }
2910+
2911+ for (i = 0; (i < MAX_PORTS) && ports[i] != 0; i++)
2912+ {
2913+ hlpr = &ip_nat_rtsp_helpers[i];
2914+ memset(hlpr, 0, sizeof(struct ip_nat_helper));
2915+
2916+ hlpr->tuple.dst.protonum = IPPROTO_TCP;
2917+ hlpr->tuple.src.u.tcp.port = htons(ports[i]);
2918+ hlpr->mask.src.u.tcp.port = 0xFFFF;
2919+ hlpr->mask.dst.protonum = 0xFFFF;
2920+ hlpr->help = help;
2921+ hlpr->flags = 0;
2922+ hlpr->me = THIS_MODULE;
2923+ hlpr->expect = expected;
2924+
2925+ tmpname = &rtsp_names[i][0];
2926+ if (ports[i] == RTSP_PORT)
2927+ {
2928+ sprintf(tmpname, "rtsp");
2929+ }
2930+ else
2931+ {
2932+ sprintf(tmpname, "rtsp-%d", i);
2933+ }
2934+ hlpr->name = tmpname;
2935+
2936+ DEBUGP("registering helper for port %d: name %s\n", ports[i], hlpr->name);
2937+ ret = ip_nat_helper_register(hlpr);
2938+
2939+ if (ret)
2940+ {
2941+ printk("ip_nat_rtsp: error registering helper for port %d\n", ports[i]);
2942+ fini();
2943+ return 1;
2944+ }
2945+ num_ports++;
2946+ }
2947+ if (stunaddr != NULL)
2948+ {
2949+ extip = in_aton(stunaddr);
2950+ }
2951+ if (destaction != NULL)
2952+ {
2953+ if (strcmp(destaction, "auto") == 0)
2954+ {
2955+ dstact = DSTACT_AUTO;
2956+ }
2957+ if (strcmp(destaction, "strip") == 0)
2958+ {
2959+ dstact = DSTACT_STRIP;
2960+ }
2961+ if (strcmp(destaction, "none") == 0)
2962+ {
2963+ dstact = DSTACT_NONE;
2964+ }
2965+ }
2966+ return ret;
2967+}
2968+
2969+module_init(init);
2970+module_exit(fini);
2971diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_tables.c linux-2.6.5-rc1/net/ipv4/netfilter/ip_tables.c
2972--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_tables.c 2004-03-16 05:45:50.000000000 +0000
2973+++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_tables.c 2004-03-16 12:04:36.000000000 +0000
2974@@ -8,6 +8,10 @@
2975 * it under the terms of the GNU General Public License version 2 as
2976 * published by the Free Software Foundation.
2977 *
2978+ * 6 Mar 2002 Robert Olsson <robban@robtex.com>
2979+ * 17 Apr 2003 Chris Wilson <chris@netservers.co.uk>
2980+ * - mark_source_chains speedup for complex chains
2981+ *
2982 * 19 Jan 2002 Harald Welte <laforge@gnumonks.org>
2983 * - increase module usage count as soon as we have rules inside
2984 * a table
2985@@ -498,6 +502,9 @@
2986 {
2987 unsigned int hook;
2988
2989+ /* keep track of where we have been: */
2990+ unsigned char *been = vmalloc(newinfo->size);
2991+
2992 /* No recursion; use packet counter to save back ptrs (reset
2993 to 0 as we leave), and comefrom to save source hook bitmask */
2994 for (hook = 0; hook < NF_IP_NUMHOOKS; hook++) {
2995@@ -510,6 +517,7 @@
2996
2997 /* Set initial back pointer. */
2998 e->counters.pcnt = pos;
2999+ memset(been, 0, newinfo->size);
3000
3001 for (;;) {
3002 struct ipt_standard_target *t
3003@@ -518,6 +526,7 @@
3004 if (e->comefrom & (1 << NF_IP_NUMHOOKS)) {
3005 printk("iptables: loop hook %u pos %u %08X.\n",
3006 hook, pos, e->comefrom);
3007+ vfree(been);
3008 return 0;
3009 }
3010 e->comefrom
3011@@ -565,10 +574,14 @@
3012 } else {
3013 int newpos = t->verdict;
3014
3015- if (strcmp(t->target.u.user.name,
3016+ if ( (pos < 0 || pos >= newinfo->size
3017+ || !been[pos])
3018+ && strcmp(t->target.u.user.name,
3019 IPT_STANDARD_TARGET) == 0
3020 && newpos >= 0) {
3021 /* This a jump; chase it. */
3022+ if (pos >= 0 && pos < newinfo->size)
3023+ been[pos]++;
3024 duprintf("Jump rule %u -> %u\n",
3025 pos, newpos);
3026 } else {
3027@@ -584,6 +597,7 @@
3028 next:
3029 duprintf("Finished chain %u\n", hook);
3030 }
3031+ vfree(been);
3032 return 1;
3033 }
3034
3035diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_CONNMARK.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_CONNMARK.c
3036--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_CONNMARK.c 1970-01-01 00:00:00.000000000 +0000
3037+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_CONNMARK.c 2004-03-16 12:04:09.000000000 +0000
3038@@ -0,0 +1,118 @@
3039+/* This kernel module is used to modify the connection mark values, or
3040+ * to optionally restore the skb nfmark from the connection mark
3041+ *
3042+ * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
3043+ * by Henrik Nordstrom <hno@marasystems.com>
3044+ *
3045+ * This program is free software; you can redistribute it and/or modify
3046+ * it under the terms of the GNU General Public License as published by
3047+ * the Free Software Foundation; either version 2 of the License, or
3048+ * (at your option) any later version.
3049+ *
3050+ * This program is distributed in the hope that it will be useful,
3051+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3052+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3053+ * GNU General Public License for more details.
3054+ *
3055+ * You should have received a copy of the GNU General Public License
3056+ * along with this program; if not, write to the Free Software
3057+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3058+ */
3059+#include <linux/module.h>
3060+#include <linux/skbuff.h>
3061+#include <linux/ip.h>
3062+#include <net/checksum.h>
3063+
3064+MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
3065+MODULE_DESCRIPTION("IP tables CONNMARK matching module");
3066+MODULE_LICENSE("GPL");
3067+
3068+#include <linux/netfilter_ipv4/ip_tables.h>
3069+#include <linux/netfilter_ipv4/ipt_CONNMARK.h>
3070+#include <linux/netfilter_ipv4/ip_conntrack.h>
3071+
3072+static unsigned int
3073+target(struct sk_buff **pskb,
3074+ const struct net_device *in,
3075+ const struct net_device *out,
3076+ unsigned int hooknum,
3077+ const void *targinfo,
3078+ void *userinfo)
3079+{
3080+ const struct ipt_connmark_target_info *markinfo = targinfo;
3081+ unsigned long diff;
3082+ unsigned long nfmark;
3083+ unsigned long newmark;
3084+
3085+ enum ip_conntrack_info ctinfo;
3086+ struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo);
3087+ if (ct) {
3088+ switch(markinfo->mode) {
3089+ case IPT_CONNMARK_SET:
3090+ newmark = (ct->mark & ~markinfo->mask) | markinfo->mark;
3091+ if (newmark != ct->mark)
3092+ ct->mark = newmark;
3093+ break;
3094+ case IPT_CONNMARK_SAVE:
3095+ newmark = (ct->mark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask);
3096+ if (ct->mark != newmark)
3097+ ct->mark = newmark;
3098+ break;
3099+ case IPT_CONNMARK_RESTORE:
3100+ nfmark = (*pskb)->nfmark;
3101+ diff = (ct->mark ^ nfmark & markinfo->mask);
3102+ if (diff != 0) {
3103+ (*pskb)->nfmark = nfmark ^ diff;
3104+ (*pskb)->nfcache |= NFC_ALTERED;
3105+ }
3106+ break;
3107+ }
3108+ }
3109+
3110+ return IPT_CONTINUE;
3111+}
3112+
3113+static int
3114+checkentry(const char *tablename,
3115+ const struct ipt_entry *e,
3116+ void *targinfo,
3117+ unsigned int targinfosize,
3118+ unsigned int hook_mask)
3119+{
3120+ struct ipt_connmark_target_info *matchinfo = targinfo;
3121+ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_connmark_target_info))) {
3122+ printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n",
3123+ targinfosize,
3124+ IPT_ALIGN(sizeof(struct ipt_connmark_target_info)));
3125+ return 0;
3126+ }
3127+
3128+ if (matchinfo->mode == IPT_CONNMARK_RESTORE) {
3129+ if (strcmp(tablename, "mangle") != 0) {
3130+ printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename);
3131+ return 0;
3132+ }
3133+ }
3134+
3135+ return 1;
3136+}
3137+
3138+static struct ipt_target ipt_connmark_reg = {
3139+ .name = "CONNMARK",
3140+ .target = &target,
3141+ .checkentry = &checkentry,
3142+ .me = THIS_MODULE
3143+};
3144+
3145+static int __init init(void)
3146+{
3147+ return ipt_register_target(&ipt_connmark_reg);
3148+}
3149+
3150+static void __exit fini(void)
3151+{
3152+ ipt_unregister_target(&ipt_connmark_reg);
3153+}
3154+
3155+module_init(init);
3156+module_exit(fini);
3157diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_IPMARK.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_IPMARK.c
3158--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_IPMARK.c 1970-01-01 00:00:00.000000000 +0000
3159+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_IPMARK.c 2004-03-16 12:04:10.000000000 +0000
3160@@ -0,0 +1,81 @@
3161+/* This is a module which is used for setting the NFMARK field of an skb. */
3162+#include <linux/module.h>
3163+#include <linux/skbuff.h>
3164+#include <linux/ip.h>
3165+#include <net/checksum.h>
3166+
3167+#include <linux/netfilter_ipv4/ip_tables.h>
3168+#include <linux/netfilter_ipv4/ipt_IPMARK.h>
3169+
3170+MODULE_AUTHOR("Grzegorz Janoszka <Grzegorz.Janoszka@pro.onet.pl>");
3171+MODULE_DESCRIPTION("IP tables IPMARK: mark based on ip address");
3172+MODULE_LICENSE("GPL");
3173+
3174+static unsigned int
3175+target(struct sk_buff **pskb,
3176+ const struct net_device *in,
3177+ const struct net_device *out,
3178+ unsigned int hooknum,
3179+ const void *targinfo,
3180+ void *userinfo)
3181+{
3182+ const struct ipt_ipmark_target_info *ipmarkinfo = targinfo;
3183+ struct iphdr *iph = (*pskb)->nh.iph;
3184+ unsigned long mark;
3185+
3186+ if (ipmarkinfo->addr == IPT_IPMARK_SRC)
3187+ mark = (unsigned long) ntohl(iph->saddr);
3188+ else
3189+ mark = (unsigned long) ntohl(iph->daddr);
3190+
3191+ mark &= ipmarkinfo->andmask;
3192+ mark |= ipmarkinfo->ormask;
3193+
3194+ if ((*pskb)->nfmark != mark) {
3195+ (*pskb)->nfmark = mark;
3196+ (*pskb)->nfcache |= NFC_ALTERED;
3197+ }
3198+ return IPT_CONTINUE;
3199+}
3200+
3201+static int
3202+checkentry(const char *tablename,
3203+ const struct ipt_entry *e,
3204+ void *targinfo,
3205+ unsigned int targinfosize,
3206+ unsigned int hook_mask)
3207+{
3208+ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ipmark_target_info))) {
3209+ printk(KERN_WARNING "IPMARK: targinfosize %u != %Zu\n",
3210+ targinfosize,
3211+ IPT_ALIGN(sizeof(struct ipt_ipmark_target_info)));
3212+ return 0;
3213+ }
3214+
3215+ if (strcmp(tablename, "mangle") != 0) {
3216+ printk(KERN_WARNING "IPMARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
3217+ return 0;
3218+ }
3219+
3220+ return 1;
3221+}
3222+
3223+static struct ipt_target ipt_ipmark_reg = {
3224+ .name = "IPMARK",
3225+ .target = target,
3226+ .checkentry = checkentry,
3227+ .me = THIS_MODULE
3228+};
3229+
3230+static int __init init(void)
3231+{
3232+ return ipt_register_target(&ipt_ipmark_reg);
3233+}
3234+
3235+static void __exit fini(void)
3236+{
3237+ ipt_unregister_target(&ipt_ipmark_reg);
3238+}
3239+
3240+module_init(init);
3241+module_exit(fini);
3242diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_XOR.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_XOR.c
3243--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_XOR.c 1970-01-01 00:00:00.000000000 +0000
3244+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_XOR.c 2004-03-16 12:04:18.000000000 +0000
3245@@ -0,0 +1,117 @@
3246+/* XOR target for IP tables
3247+ * (C) 2000 by Tim Vandermeersch <Tim.Vandermeersch@pandora.be>
3248+ * Based on ipt_TTL.c
3249+ *
3250+ * Version 1.0
3251+ *
3252+ * This software is distributed under the terms of GNU GPL
3253+ */
3254+
3255+#include <linux/module.h>
3256+#include <linux/skbuff.h>
3257+#include <linux/ip.h>
3258+#include <linux/tcp.h>
3259+#include <linux/udp.h>
3260+
3261+#include <linux/netfilter_ipv4/ip_tables.h>
3262+#include <linux/netfilter_ipv4/ipt_XOR.h>
3263+
3264+MODULE_AUTHOR("Tim Vandermeersch <Tim.Vandermeersch@pandora.be>");
3265+MODULE_DESCRIPTION("IP tables XOR module");
3266+MODULE_LICENSE("GPL");
3267+
3268+static unsigned int
3269+ipt_xor_target(struct sk_buff **pskb,
3270+ const struct net_device *in, const struct net_device *out,
3271+ unsigned int hooknum, const void *targinfo, void *userinfo)
3272+{
3273+ struct ipt_XOR_info *info = (void *) targinfo;
3274+ struct iphdr *iph;
3275+ struct tcphdr *tcph;
3276+ struct udphdr *udph;
3277+ int i, j, k;
3278+
3279+ if (!skb_ip_make_writable(pskb, (*pskb)->len))
3280+ return NF_DROP;
3281+
3282+ iph = (*pskb)->nh.iph;
3283+
3284+ if (iph->protocol == IPPROTO_TCP) {
3285+ tcph = (struct tcphdr *) ((*pskb)->data + iph->ihl*4);
3286+ for (i=0, j=0; i<(ntohs(iph->tot_len) - iph->ihl*4 - tcph->doff*4); ) {
3287+ for (k=0; k<=info->block_size; k++) {
3288+ (char) (*pskb)->data[ iph->ihl*4 + tcph->doff*4 + i ] ^=
3289+ info->key[j];
3290+ i++;
3291+ }
3292+ j++;
3293+ if (info->key[j] == 0x00)
3294+ j = 0;
3295+ }
3296+ } else if (iph->protocol == IPPROTO_UDP) {
3297+ udph = (struct udphdr *) ((*pskb)->data + iph->ihl*4);
3298+ for (i=0, j=0; i<(ntohs(udph->len)-8); ) {
3299+ for (k=0; k<=info->block_size; k++) {
3300+ (char) (*pskb)->data[ iph->ihl*4 + sizeof(struct udphdr) + i ] ^=
3301+ info->key[j];
3302+ i++;
3303+ }
3304+ j++;
3305+ if (info->key[j] == 0x00)
3306+ j = 0;
3307+ }
3308+ }
3309+
3310+ return IPT_CONTINUE;
3311+}
3312+
3313+static int ipt_xor_checkentry(const char *tablename, const struct ipt_entry *e,
3314+ void *targinfo, unsigned int targinfosize,
3315+ unsigned int hook_mask)
3316+{
3317+ struct ipt_XOR_info *info = targinfo;
3318+
3319+ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_XOR_info))) {
3320+ printk(KERN_WARNING "XOR: targinfosize %u != %Zu\n",
3321+ targinfosize, IPT_ALIGN(sizeof(struct ipt_XOR_info)));
3322+ return 0;
3323+ }
3324+
3325+ if (strcmp(tablename, "mangle")) {
3326+ printk(KERN_WARNING "XOR: can only be called from"
3327+ "\"mangle\" table, not \"%s\"\n", tablename);
3328+ return 0;
3329+ }
3330+
3331+ if (!strcmp(info->key, "")) {
3332+ printk(KERN_WARNING "XOR: You must specify a key");
3333+ return 0;
3334+ }
3335+
3336+ if (info->block_size == 0) {
3337+ printk(KERN_WARNING "XOR: You must specify a block-size");
3338+ return 0;
3339+ }
3340+
3341+ return 1;
3342+}
3343+
3344+static struct ipt_target ipt_XOR = {
3345+ .name = "XOR",
3346+ .target = ipt_xor_target,
3347+ .checkentry = ipt_xor_checkentry,
3348+ .me = THIS_MODULE,
3349+};
3350+
3351+static int __init init(void)
3352+{
3353+ return ipt_register_target(&ipt_XOR);
3354+}
3355+
3356+static void __exit fini(void)
3357+{
3358+ ipt_unregister_target(&ipt_XOR);
3359+}
3360+
3361+module_init(init);
3362+module_exit(fini);
3363diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_addrtype.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_addrtype.c
3364--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_addrtype.c 1970-01-01 00:00:00.000000000 +0000
3365+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_addrtype.c 2004-03-16 12:04:20.000000000 +0000
3366@@ -0,0 +1,68 @@
3367+/*
3368+ * iptables module to match inet_addr_type() of an ip.
3369+ */
3370+
3371+#include <linux/module.h>
3372+#include <linux/skbuff.h>
3373+#include <linux/netdevice.h>
3374+#include <net/route.h>
3375+
3376+#include <linux/netfilter_ipv4/ipt_addrtype.h>
3377+#include <linux/netfilter_ipv4/ip_tables.h>
3378+
3379+MODULE_LICENSE("GPL");
3380+
3381+static inline int match_type(u_int32_t addr, u_int16_t mask)
3382+{
3383+ return !!(mask & (1 << inet_addr_type(addr)));
3384+}
3385+
3386+static int match(const struct sk_buff *skb, const struct net_device *in,
3387+ const struct net_device *out, const void *matchinfo,
3388+ int offset, int *hotdrop)
3389+{
3390+ const struct ipt_addrtype_info *info = matchinfo;
3391+ const struct iphdr *iph = skb->nh.iph;
3392+ int ret = 1;
3393+
3394+ if (info->source)
3395+ ret &= match_type(iph->saddr, info->source)^info->invert_source;
3396+ if (info->dest)
3397+ ret &= match_type(iph->daddr, info->dest)^info->invert_dest;
3398+
3399+ return ret;
3400+}
3401+
3402+static int checkentry(const char *tablename, const struct ipt_ip *ip,
3403+ void *matchinfo, unsigned int matchsize,
3404+ unsigned int hook_mask)
3405+{
3406+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_addrtype_info))) {
3407+ printk(KERN_ERR "ipt_addrtype: invalid size (%u != %u)\n.",
3408+ matchsize, IPT_ALIGN(sizeof(struct ipt_addrtype_info)));
3409+ return 0;
3410+ }
3411+
3412+ return 1;
3413+}
3414+
3415+static struct ipt_match addrtype_match = {
3416+ .name = "addrtype",
3417+ .match = match,
3418+ .checkentry = checkentry,
3419+ .me = THIS_MODULE
3420+};
3421+
3422+static int __init init(void)
3423+{
3424+ return ipt_register_match(&addrtype_match);
3425+}
3426+
3427+static void __exit fini(void)
3428+{
3429+ ipt_unregister_match(&addrtype_match);
3430+
3431+}
3432+
3433+module_init(init);
3434+module_exit(fini);
3435diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_connmark.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_connmark.c
3436--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_connmark.c 1970-01-01 00:00:00.000000000 +0000
3437+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_connmark.c 2004-03-16 12:04:09.000000000 +0000
3438@@ -0,0 +1,81 @@
3439+/* This kernel module matches connection mark values set by the
3440+ * CONNMARK target
3441+ *
3442+ * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
3443+ * by Henrik Nordstrom <hno@marasystems.com>
3444+ *
3445+ * This program is free software; you can redistribute it and/or modify
3446+ * it under the terms of the GNU General Public License as published by
3447+ * the Free Software Foundation; either version 2 of the License, or
3448+ * (at your option) any later version.
3449+ *
3450+ * This program is distributed in the hope that it will be useful,
3451+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3452+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3453+ * GNU General Public License for more details.
3454+ *
3455+ * You should have received a copy of the GNU General Public License
3456+ * along with this program; if not, write to the Free Software
3457+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3458+ */
3459+
3460+#include <linux/module.h>
3461+#include <linux/skbuff.h>
3462+
3463+MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
3464+MODULE_DESCRIPTION("IP tables connmark match module");
3465+MODULE_LICENSE("GPL");
3466+
3467+#include <linux/netfilter_ipv4/ip_tables.h>
3468+#include <linux/netfilter_ipv4/ipt_connmark.h>
3469+#include <linux/netfilter_ipv4/ip_conntrack.h>
3470+
3471+static int
3472+match(const struct sk_buff *skb,
3473+ const struct net_device *in,
3474+ const struct net_device *out,
3475+ const void *matchinfo,
3476+ int offset,
3477+ int *hotdrop)
3478+{
3479+ const struct ipt_connmark_info *info = matchinfo;
3480+ enum ip_conntrack_info ctinfo;
3481+ struct ip_conntrack *ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
3482+ if (!ct)
3483+ return 0;
3484+
3485+ return ((ct->mark & info->mask) == info->mark) ^ info->invert;
3486+}
3487+
3488+static int
3489+checkentry(const char *tablename,
3490+ const struct ipt_ip *ip,
3491+ void *matchinfo,
3492+ unsigned int matchsize,
3493+ unsigned int hook_mask)
3494+{
3495+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_connmark_info)))
3496+ return 0;
3497+
3498+ return 1;
3499+}
3500+
3501+static struct ipt_match connmark_match = {
3502+ .name = "connmark",
3503+ .match = &match,
3504+ .checkentry = &checkentry,
3505+ .me = THIS_MODULE
3506+};
3507+
3508+static int __init init(void)
3509+{
3510+ return ipt_register_match(&connmark_match);
3511+}
3512+
3513+static void __exit fini(void)
3514+{
3515+ ipt_unregister_match(&connmark_match);
3516+}
3517+
3518+module_init(init);
3519+module_exit(fini);
3520diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_owner.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_owner.c
3521--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_owner.c 2004-03-16 05:47:19.000000000 +0000
3522+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_owner.c 2004-03-16 12:04:38.000000000 +0000
3523@@ -6,12 +6,19 @@
3524 * This program is free software; you can redistribute it and/or modify
3525 * it under the terms of the GNU General Public License version 2 as
3526 * published by the Free Software Foundation.
3527+ *
3528+ * 03/26/2003 Patrick McHardy <kaber@trash.net> : LOCAL_IN support
3529 */
3530
3531 #include <linux/module.h>
3532 #include <linux/skbuff.h>
3533 #include <linux/file.h>
3534+#include <linux/ip.h>
3535+#include <linux/tcp.h>
3536+#include <linux/udp.h>
3537 #include <net/sock.h>
3538+#include <net/tcp.h>
3539+#include <net/udp.h>
3540
3541 #include <linux/netfilter_ipv4/ipt_owner.h>
3542 #include <linux/netfilter_ipv4/ip_tables.h>
3543@@ -21,7 +28,7 @@
3544 MODULE_DESCRIPTION("iptables owner match");
3545
3546 static int
3547-match_comm(const struct sk_buff *skb, const char *comm)
3548+match_comm(const struct sock *sk, const char *comm)
3549 {
3550 struct task_struct *g, *p;
3551 struct files_struct *files;
3552@@ -38,7 +45,7 @@
3553 spin_lock(&files->file_lock);
3554 for (i=0; i < files->max_fds; i++) {
3555 if (fcheck_files(files, i) ==
3556- skb->sk->sk_socket->file) {
3557+ sk->sk_socket->file) {
3558 spin_unlock(&files->file_lock);
3559 task_unlock(p);
3560 read_unlock(&tasklist_lock);
3561@@ -54,7 +61,7 @@
3562 }
3563
3564 static int
3565-match_pid(const struct sk_buff *skb, pid_t pid)
3566+match_pid(const struct sock *sk, pid_t pid)
3567 {
3568 struct task_struct *p;
3569 struct files_struct *files;
3570@@ -70,7 +77,7 @@
3571 spin_lock(&files->file_lock);
3572 for (i=0; i < files->max_fds; i++) {
3573 if (fcheck_files(files, i) ==
3574- skb->sk->sk_socket->file) {
3575+ sk->sk_socket->file) {
3576 spin_unlock(&files->file_lock);
3577 task_unlock(p);
3578 read_unlock(&tasklist_lock);
3579@@ -86,10 +93,10 @@
3580 }
3581
3582 static int
3583-match_sid(const struct sk_buff *skb, pid_t sid)
3584+match_sid(const struct sock *sk, pid_t sid)
3585 {
3586 struct task_struct *g, *p;
3587- struct file *file = skb->sk->sk_socket->file;
3588+ struct file *file = sk->sk_socket->file;
3589 int i, found=0;
3590
3591 read_lock(&tasklist_lock);
3592@@ -129,41 +136,71 @@
3593 int *hotdrop)
3594 {
3595 const struct ipt_owner_info *info = matchinfo;
3596+ struct iphdr *iph = skb->nh.iph;
3597+ struct sock *sk = NULL;
3598+ int ret = 0;
3599+
3600+ if (out) {
3601+ sk = skb->sk;
3602+ } else {
3603+ if (iph->protocol == IPPROTO_TCP) {
3604+ struct tcphdr *tcph =
3605+ (struct tcphdr *)((u_int32_t *)iph + iph->ihl);
3606+ sk = tcp_v4_lookup(iph->saddr, tcph->source,
3607+ iph->daddr, tcph->dest,
3608+ skb->dev->ifindex);
3609+ if (sk && sk->sk_state == TCP_TIME_WAIT) {
3610+ tcp_tw_put((struct tcp_tw_bucket *)sk);
3611+ return ret;
3612+ }
3613+ } else if (iph->protocol == IPPROTO_UDP) {
3614+ struct udphdr *udph =
3615+ (struct udphdr *)((u_int32_t *)iph + iph->ihl);
3616+ sk = udp_v4_lookup(iph->saddr, udph->source, iph->daddr,
3617+ udph->dest, skb->dev->ifindex);
3618+ }
3619+ }
3620
3621- if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
3622- return 0;
3623+ if (!sk || !sk->sk_socket || !sk->sk_socket->file)
3624+ goto out;
3625
3626 if(info->match & IPT_OWNER_UID) {
3627- if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
3628+ if ((sk->sk_socket->file->f_uid != info->uid) ^
3629 !!(info->invert & IPT_OWNER_UID))
3630- return 0;
3631+ goto out;
3632 }
3633
3634 if(info->match & IPT_OWNER_GID) {
3635- if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
3636+ if ((sk->sk_socket->file->f_gid != info->gid) ^
3637 !!(info->invert & IPT_OWNER_GID))
3638- return 0;
3639+ goto out;
3640 }
3641
3642 if(info->match & IPT_OWNER_PID) {
3643- if (!match_pid(skb, info->pid) ^
3644+ if (!match_pid(sk, info->pid) ^
3645 !!(info->invert & IPT_OWNER_PID))
3646- return 0;
3647+ goto out;
3648 }
3649
3650 if(info->match & IPT_OWNER_SID) {
3651- if (!match_sid(skb, info->sid) ^
3652+ if (!match_sid(sk, info->sid) ^
3653 !!(info->invert & IPT_OWNER_SID))
3654- return 0;
3655+ goto out;
3656 }
3657
3658 if(info->match & IPT_OWNER_COMM) {
3659- if (!match_comm(skb, info->comm) ^
3660+ if (!match_comm(sk, info->comm) ^
3661 !!(info->invert & IPT_OWNER_COMM))
3662- return 0;
3663+ goto out;
3664 }
3665
3666- return 1;
3667+ ret = 1;
3668+
3669+out:
3670+ if (in && sk)
3671+ sock_put(sk);
3672+
3673+ return ret;
3674 }
3675
3676 static int
3677@@ -173,11 +210,19 @@
3678 unsigned int matchsize,
3679 unsigned int hook_mask)
3680 {
3681- if (hook_mask
3682- & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING))) {
3683- printk("ipt_owner: only valid for LOCAL_OUT or POST_ROUTING.\n");
3684- return 0;
3685- }
3686+ if (hook_mask
3687+ & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING) |
3688+ (1 << NF_IP_LOCAL_IN))) {
3689+ printk("ipt_owner: only valid for LOCAL_IN, LOCAL_OUT "
3690+ "or POST_ROUTING.\n");
3691+ return 0;
3692+ }
3693+
3694+ if ((hook_mask & (1 << NF_IP_LOCAL_IN))
3695+ && ip->proto != IPPROTO_TCP && ip->proto != IPPROTO_UDP) {
3696+ printk("ipt_owner: only TCP or UDP can be used in LOCAL_IN\n");
3697+ return 0;
3698+ }
3699
3700 if (matchsize != IPT_ALIGN(sizeof(struct ipt_owner_info))) {
3701 printk("Matchsize %u != %Zu\n", matchsize,
3702diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_policy.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_policy.c
3703--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_policy.c 1970-01-01 00:00:00.000000000 +0000
3704+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_policy.c 2004-03-16 12:04:45.000000000 +0000
3705@@ -0,0 +1,176 @@
3706+/* IP tables module for matching IPsec policy
3707+ *
3708+ * Copyright (c) 2004 Patrick McHardy, <kaber@trash.net>
3709+ *
3710+ * This program is free software; you can redistribute it and/or modify
3711+ * it under the terms of the GNU General Public License version 2 as
3712+ * published by the Free Software Foundation.
3713+ */
3714+
3715+#include <linux/kernel.h>
3716+#include <linux/config.h>
3717+#include <linux/module.h>
3718+#include <linux/skbuff.h>
3719+#include <linux/init.h>
3720+#include <net/xfrm.h>
3721+
3722+#include <linux/netfilter_ipv4.h>
3723+#include <linux/netfilter_ipv4/ipt_policy.h>
3724+#include <linux/netfilter_ipv4/ip_tables.h>
3725+
3726+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
3727+MODULE_DESCRIPTION("IPtables IPsec policy matching module");
3728+MODULE_LICENSE("GPL");
3729+
3730+
3731+static inline int
3732+match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e)
3733+{
3734+#define MISMATCH(x,y) (e->match.x && ((e->x != (y)) ^ e->invert.x))
3735+
3736+ if (MISMATCH(saddr, x->props.saddr.a4 & e->smask) ||
3737+ MISMATCH(daddr, x->id.daddr.a4 & e->dmask) ||
3738+ MISMATCH(proto, x->id.proto) ||
3739+ MISMATCH(mode, x->props.mode) ||
3740+ MISMATCH(spi, x->id.spi) ||
3741+ MISMATCH(reqid, x->props.reqid))
3742+ return 0;
3743+ return 1;
3744+}
3745+
3746+static int
3747+match_policy_in(const struct sk_buff *skb, const struct ipt_policy_info *info)
3748+{
3749+ const struct ipt_policy_elem *e;
3750+ struct sec_path *sp = skb->sp;
3751+ int strict = info->flags & POLICY_MATCH_STRICT;
3752+ int i, pos;
3753+
3754+ if (sp == NULL)
3755+ return -1;
3756+ if (strict && info->len != sp->len)
3757+ return 0;
3758+
3759+ for (i = sp->len - 1; i >= 0; i--) {
3760+ pos = strict ? i - sp->len + 1 : 0;
3761+ if (pos >= info->len)
3762+ return 0;
3763+ e = &info->pol[pos];
3764+
3765+ if (match_xfrm_state(sp->x[i].xvec, e)) {
3766+ if (!strict)
3767+ return 1;
3768+ } else if (strict)
3769+ return 0;
3770+ }
3771+
3772+ return strict ? 1 : 0;
3773+}
3774+
3775+static int
3776+match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info)
3777+{
3778+ const struct ipt_policy_elem *e;
3779+ struct dst_entry *dst = skb->dst;
3780+ int strict = info->flags & POLICY_MATCH_STRICT;
3781+ int i, pos;
3782+
3783+ if (dst->xfrm == NULL)
3784+ return -1;
3785+
3786+ for (i = 0; dst && dst->xfrm; dst = dst->child, i++) {
3787+ pos = strict ? i : 0;
3788+ if (pos >= info->len)
3789+ return 0;
3790+ e = &info->pol[pos];
3791+
3792+ if (match_xfrm_state(dst->xfrm, e)) {
3793+ if (!strict)
3794+ return 1;
3795+ } else if (strict)
3796+ return 0;
3797+ }
3798+
3799+ return strict ? 1 : 0;
3800+}
3801+
3802+static int match(const struct sk_buff *skb,
3803+ const struct net_device *in,
3804+ const struct net_device *out,
3805+ const void *matchinfo, int offset, int *hotdrop)
3806+{
3807+ const struct ipt_policy_info *info = matchinfo;
3808+ int ret;
3809+
3810+ if (info->flags & POLICY_MATCH_IN)
3811+ ret = match_policy_in(skb, info);
3812+ else
3813+ ret = match_policy_out(skb, info);
3814+
3815+ if (ret < 0) {
3816+ if (info->flags & POLICY_MATCH_NONE)
3817+ ret = 1;
3818+ else
3819+ ret = 0;
3820+ } else if (info->flags & POLICY_MATCH_NONE)
3821+ ret = 0;
3822+
3823+ return ret;
3824+}
3825+
3826+static int checkentry(const char *tablename, const struct ipt_ip *ip,
3827+ void *matchinfo, unsigned int matchsize,
3828+ unsigned int hook_mask)
3829+{
3830+ struct ipt_policy_info *info = matchinfo;
3831+
3832+ if (matchsize != IPT_ALIGN(sizeof(*info))) {
3833+ printk(KERN_ERR "ipt_policy: matchsize %u != %u\n",
3834+ matchsize, IPT_ALIGN(sizeof(*info)));
3835+ return 0;
3836+ }
3837+ if (!(info->flags & (POLICY_MATCH_IN|POLICY_MATCH_OUT))) {
3838+ printk(KERN_ERR "ipt_policy: neither incoming nor "
3839+ "outgoing policy selected\n");
3840+ return 0;
3841+ }
3842+ if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
3843+ && info->flags & POLICY_MATCH_OUT) {
3844+ printk(KERN_ERR "ipt_policy: output policy not valid in "
3845+ "PRE_ROUTING and INPUT\n");
3846+ return 0;
3847+ }
3848+ if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
3849+ && info->flags & POLICY_MATCH_IN) {
3850+ printk(KERN_ERR "ipt_policy: input policy not valid in "
3851+ "POST_ROUTING and OUTPUT\n");
3852+ return 0;
3853+ }
3854+ if (info->len > POLICY_MAX_ELEM) {
3855+ printk(KERN_ERR "ipt_policy: too many policy elements\n");
3856+ return 0;
3857+ }
3858+
3859+ return 1;
3860+}
3861+
3862+static struct ipt_match policy_match =
3863+{
3864+ .name = "policy",
3865+ .match = match,
3866+ .checkentry = checkentry,
3867+ .me = THIS_MODULE,
3868+};
3869+
3870+static int __init init(void)
3871+{
3872+ return ipt_register_match(&policy_match);
3873+}
3874+
3875+static void __exit fini(void)
3876+{
3877+ ipt_unregister_match(&policy_match);
3878+}
3879+
3880+module_init(init);
3881+module_exit(fini);
3882diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_rpc.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_rpc.c
3883--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_rpc.c 1970-01-01 00:00:00.000000000 +0000
3884+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_rpc.c 2004-03-16 12:04:46.000000000 +0000
3885@@ -0,0 +1,428 @@
3886+/* RPC extension for IP connection matching, Version 2.2
3887+ * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
3888+ * - original rpc tracking module
3889+ * - "recent" connection handling for kernel 2.3+ netfilter
3890+ *
3891+ * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
3892+ * - upgraded conntrack modules to oldnat api - kernel 2.4.0+
3893+ *
3894+ * (C) 2002,2003 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
3895+ * - upgraded conntrack modules to newnat api - kernel 2.4.20+
3896+ * - extended matching to support filtering on procedures
3897+ *
3898+ * ipt_rpc.c,v 2.2 2003/01/12 18:30:00
3899+ *
3900+ * This program is free software; you can redistribute it and/or
3901+ * modify it under the terms of the GNU General Public License
3902+ * as published by the Free Software Foundation; either version
3903+ * 2 of the License, or (at your option) any later version.
3904+ **
3905+ * Module load syntax:
3906+ * insmod ipt_rpc.o ports=port1,port2,...port<MAX_PORTS>
3907+ *
3908+ * Please give the ports of all RPC servers you wish to connect to.
3909+ * If you don't specify ports, the default will be port 111.
3910+ **
3911+ * Note to all:
3912+ *
3913+ * RPCs should not be exposed to the internet - ask the Pentagon;
3914+ *
3915+ * "The unidentified crackers pleaded guilty in July to charges
3916+ * of juvenile delinquency stemming from a string of Pentagon
3917+ * network intrusions in February.
3918+ *
3919+ * The youths, going by the names TooShort and Makaveli, used
3920+ * a common server security hole to break in, according to
3921+ * Dane Jasper, owner of the California Internet service
3922+ * provider, Sonic. They used the hole, known as the 'statd'
3923+ * exploit, to attempt more than 800 break-ins, Jasper said."
3924+ *
3925+ * From: Wired News; "Pentagon Kids Kicked Off Grid" - Nov 6, 1998
3926+ * URL: http://www.wired.com/news/politics/0,1283,16098,00.html
3927+ **
3928+ */
3929+
3930+#include <linux/module.h>
3931+#include <linux/skbuff.h>
3932+#include <linux/list.h>
3933+#include <linux/udp.h>
3934+#include <linux/tcp.h>
3935+#include <linux/netfilter_ipv4/ip_conntrack.h>
3936+#include <linux/netfilter_ipv4/ip_tables.h>
3937+#include <linux/netfilter_ipv4/ip_conntrack_rpc.h>
3938+#include <linux/netfilter_ipv4/lockhelp.h>
3939+#include <linux/netfilter_ipv4/ipt_rpc.h>
3940+
3941+#define MAX_PORTS 8
3942+static int ports[MAX_PORTS];
3943+static int ports_n_c = 0;
3944+
3945+#ifdef MODULE_PARM
3946+MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
3947+MODULE_PARM_DESC(ports, "port numbers (TCP/UDP) of RPC portmapper servers");
3948+#endif
3949+
3950+MODULE_AUTHOR("Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>");
3951+MODULE_DESCRIPTION("RPC connection matching module");
3952+MODULE_LICENSE("GPL");
3953+
3954+#if 0
3955+#define DEBUGP(format, args...) printk(KERN_DEBUG "ipt_rpc: " \
3956+ format, ## args)
3957+#else
3958+#define DEBUGP(format, args...)
3959+#endif
3960+
3961+EXPORT_NO_SYMBOLS;
3962+
3963+/* vars from ip_conntrack_rpc_tcp */
3964+extern struct list_head request_p_list_tcp;
3965+extern struct module *ip_conntrack_rpc_tcp;
3966+
3967+/* vars from ip_conntrack_rpc_udp */
3968+extern struct list_head request_p_list_udp;
3969+extern struct module *ip_conntrack_rpc_udp;
3970+
3971+DECLARE_RWLOCK_EXTERN(ipct_rpc_tcp_lock);
3972+DECLARE_RWLOCK_EXTERN(ipct_rpc_udp_lock);
3973+
3974+#define ASSERT_READ_LOCK(x) \
3975+do { \
3976+ if (x == &request_p_list_udp) \
3977+ MUST_BE_READ_LOCKED(&ipct_rpc_udp_lock); \
3978+ else if (x == &request_p_list_tcp) \
3979+ MUST_BE_READ_LOCKED(&ipct_rpc_tcp_lock); \
3980+} while (0)
3981+
3982+#define ASSERT_WRITE_LOCK(x) \
3983+do { \
3984+ if (x == &request_p_list_udp) \
3985+ MUST_BE_WRITE_LOCKED(&ipct_rpc_udp_lock); \
3986+ else if (x == &request_p_list_tcp) \
3987+ MUST_BE_WRITE_LOCKED(&ipct_rpc_tcp_lock); \
3988+} while (0)
3989+
3990+#include <linux/netfilter_ipv4/listhelp.h>
3991+
3992+const int IPT_RPC_CHAR_LEN = 11;
3993+
3994+
3995+static int k_atoi(char *string)
3996+{
3997+ unsigned int result = 0;
3998+ int maxoctet = IPT_RPC_CHAR_LEN;
3999+
4000+ for ( ; *string != 0 && maxoctet != 0; maxoctet--, string++) {
4001+ if (*string < 0)
4002+ return(0);
4003+ if (*string == 0)
4004+ break;
4005+ if (*string < 48 || *string > 57) {
4006+ return(0);
4007+ }
4008+ result = result * 10 + ( *string - 48 );
4009+ }
4010+ return(result);
4011+}
4012+
4013+
4014+static int match_rpcs(char *c_procs, int i_procs, int proc)
4015+{
4016+ int proc_ctr;
4017+ char *proc_ptr;
4018+ unsigned int proc_num;
4019+
4020+ DEBUGP("entered match_rpcs [%i] [%i] ..\n", i_procs, proc);
4021+
4022+ if (i_procs == -1)
4023+ return 1;
4024+
4025+ for (proc_ctr=0; proc_ctr <= i_procs; proc_ctr++) {
4026+
4027+ proc_ptr = c_procs;
4028+ proc_ptr += proc_ctr * IPT_RPC_CHAR_LEN;
4029+ proc_num = k_atoi(proc_ptr);
4030+
4031+ if (proc_num == proc)
4032+ return 1;
4033+ }
4034+
4035+ return 0;
4036+}
4037+
4038+
4039+static int check_rpc_packet(const u_int32_t *data, const void *matchinfo,
4040+ int *hotdrop, int dir, struct ip_conntrack *ct,
4041+ int offset, struct list_head request_p_list)
4042+{
4043+ const struct ipt_rpc_info *rpcinfo = matchinfo;
4044+ struct request_p *req_p;
4045+ u_int32_t xid;
4046+
4047+
4048+ /* Get XID */
4049+ xid = *data;
4050+
4051+ /* This does sanity checking on RPC payloads,
4052+ * and permits only the RPC "get port" (3)
4053+ * in authorised procedures in client
4054+ * communications with the portmapper.
4055+ */
4056+
4057+ data += 5;
4058+
4059+ /* Get RPC requestor */
4060+ if (IXDR_GET_INT32(data) != 3) {
4061+ DEBUGP("RPC packet contains an invalid (non \"get\") requestor. [skip]\n");
4062+ if(rpcinfo->strict == 1)
4063+ *hotdrop = 1;
4064+ return 0;
4065+ }
4066+ DEBUGP("RPC packet contains a \"get\" requestor. [cont]\n");
4067+
4068+ data++;
4069+
4070+ /* Jump Credentials and Verfifier */
4071+ data = data + IXDR_GET_INT32(data) + 2;
4072+ data = data + IXDR_GET_INT32(data) + 2;
4073+
4074+ /* Get RPC procedure */
4075+ if (match_rpcs((char *)&rpcinfo->c_procs,
4076+ rpcinfo->i_procs, IXDR_GET_INT32(data)) == 0) {
4077+ DEBUGP("RPC packet contains illegal procedure request [%u]. [drop]\n",
4078+ (unsigned int)IXDR_GET_INT32(data));
4079+
4080+ /* If the RPC conntrack half entry already exists .. */
4081+
4082+ switch (ct->tuplehash[0].tuple.dst.protonum) {
4083+ case IPPROTO_UDP:
4084+ WRITE_LOCK(&ipct_rpc_udp_lock);
4085+ case IPPROTO_TCP:
4086+ WRITE_LOCK(&ipct_rpc_tcp_lock);
4087+ }
4088+ req_p = LIST_FIND(&request_p_list, request_p_cmp,
4089+ struct request_p *, xid,
4090+ ct->tuplehash[dir].tuple.src.ip,
4091+ ct->tuplehash[dir].tuple.src.u.all);
4092+
4093+ if (req_p) {
4094+ DEBUGP("found req_p for xid=%u proto=%u %u.%u.%u.%u:%u\n",
4095+ xid, ct->tuplehash[dir].tuple.dst.protonum,
4096+ NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
4097+ ntohs(ct->tuplehash[dir].tuple.src.u.all));
4098+
4099+ /* .. remove it */
4100+ if (del_timer(&req_p->timeout))
4101+ req_p->timeout.expires = 0;
4102+
4103+ LIST_DELETE(&request_p_list, req_p);
4104+ DEBUGP("RPC req_p removed. [done]\n");
4105+
4106+ } else {
4107+ DEBUGP("no req_p found for xid=%u proto=%u %u.%u.%u.%u:%u\n",
4108+ xid, ct->tuplehash[dir].tuple.dst.protonum,
4109+ NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
4110+ ntohs(ct->tuplehash[dir].tuple.src.u.all));
4111+
4112+ }
4113+ switch (ct->tuplehash[0].tuple.dst.protonum) {
4114+ case IPPROTO_UDP:
4115+ WRITE_UNLOCK(&ipct_rpc_udp_lock);
4116+ case IPPROTO_TCP:
4117+ WRITE_UNLOCK(&ipct_rpc_tcp_lock);
4118+ }
4119+
4120+ if(rpcinfo->strict == 1)
4121+ *hotdrop = 1;
4122+ return 0;
4123+ }
4124+
4125+ DEBUGP("RPC packet contains authorised procedure request [%u]. [match]\n",
4126+ (unsigned int)IXDR_GET_INT32(data));
4127+ return (1 && (!offset));
4128+}
4129+
4130+
4131+static int match(const struct sk_buff *skb, const struct net_device *in,
4132+ const struct net_device *out, const void *matchinfo,
4133+ int offset, const void *hdr, u_int16_t datalen, int *hotdrop)
4134+{
4135+ struct ip_conntrack *ct;
4136+ enum ip_conntrack_info ctinfo;
4137+ const u_int32_t *data;
4138+ enum ip_conntrack_dir dir;
4139+ const struct tcphdr *tcp;
4140+ const struct ipt_rpc_info *rpcinfo = matchinfo;
4141+ int port, portsok;
4142+ int tval;
4143+
4144+
4145+ DEBUGP("new packet to evaluate ..\n");
4146+
4147+ ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
4148+ if (!ct) {
4149+ DEBUGP("no ct available [skip]\n");
4150+ return 0;
4151+ }
4152+
4153+ DEBUGP("ct detected. [cont]\n");
4154+ dir = CTINFO2DIR(ctinfo);
4155+
4156+ /* we only want the client to server packets for matching */
4157+ if (dir != IP_CT_DIR_ORIGINAL)
4158+ return 0;
4159+
4160+ /* This does sanity checking on UDP or TCP packets,
4161+ * like their respective modules.
4162+ */
4163+
4164+ switch (ct->tuplehash[0].tuple.dst.protonum) {
4165+
4166+ case IPPROTO_UDP:
4167+ DEBUGP("PROTO_UDP [cont]\n");
4168+ if (offset == 0 && datalen < sizeof(struct udphdr)) {
4169+ DEBUGP("packet does not contain a complete header. [drop]\n");
4170+ return 0;
4171+ }
4172+
4173+ for (port=0,portsok=0; port <= ports_n_c; port++) {
4174+ if (ntohs(ct->tuplehash[dir].tuple.dst.u.all) == ports[port]) {
4175+ portsok++;
4176+ break;
4177+ }
4178+ }
4179+ if (portsok == 0) {
4180+ DEBUGP("packet is not destined for a portmapper [%u]. [skip]\n",
4181+ ntohs(ct->tuplehash[dir].tuple.dst.u.all));
4182+ return 0;
4183+ }
4184+
4185+ if ((datalen - sizeof(struct udphdr)) != 56) {
4186+ DEBUGP("packet length is not correct for RPC content. [skip]\n");
4187+ if (rpcinfo->strict == 1)
4188+ *hotdrop = 1;
4189+ return 0;
4190+ }
4191+ DEBUGP("packet length is correct. [cont]\n");
4192+
4193+ /* Get to the data */
4194+ data = (const u_int32_t *)hdr + 2;
4195+
4196+ /* Check the RPC data */
4197+ tval = check_rpc_packet(data, matchinfo, hotdrop,
4198+ dir, ct, offset,
4199+ request_p_list_udp);
4200+
4201+ return tval;
4202+
4203+
4204+ case IPPROTO_TCP:
4205+ DEBUGP("PROTO_TCP [cont]\n");
4206+ if (offset == 0 && datalen < sizeof(struct tcphdr)) {
4207+ DEBUGP("packet does not contain a complete header. [drop]\n");
4208+ return 0;
4209+ }
4210+
4211+ for (port=0,portsok=0; port <= ports_n_c; port++) {
4212+ if (ntohs(ct->tuplehash[dir].tuple.dst.u.all) == ports[port]) {
4213+ portsok++;
4214+ break;
4215+ }
4216+ }
4217+ if (portsok == 0) {
4218+ DEBUGP("packet is not destined for a portmapper [%u]. [skip]\n",
4219+ ntohs(ct->tuplehash[dir].tuple.dst.u.all));
4220+ return 0;
4221+ }
4222+
4223+ tcp = hdr;
4224+ if (datalen == (tcp->doff * 4)) {
4225+ DEBUGP("packet does not contain any data. [match]\n");
4226+ return (1 && (!offset));
4227+ }
4228+
4229+ /* Tests if packet len is ok */
4230+ if ((datalen - (tcp->doff * 4)) != 60) {
4231+ DEBUGP("packet length is not correct for RPC content. [skip]\n");
4232+ if(rpcinfo->strict == 1)
4233+ *hotdrop = 1;
4234+ return 0;
4235+ }
4236+ DEBUGP("packet length is correct. [cont]\n");
4237+
4238+ /* Get to the data */
4239+ data = (const u_int32_t *)tcp + tcp->doff + 1;
4240+
4241+ /* Check the RPC data */
4242+ tval = check_rpc_packet(data, matchinfo, hotdrop,
4243+ dir, ct, offset,
4244+ request_p_list_tcp);
4245+
4246+ return tval;
4247+
4248+ }
4249+
4250+ DEBUGP("transport protocol=%u, is not supported [skip]\n",
4251+ ct->tuplehash[0].tuple.dst.protonum);
4252+ return 0;
4253+}
4254+
4255+
4256+static int checkentry(const char *tablename, const struct ipt_ip *ip, void *matchinfo,
4257+ unsigned int matchsize, unsigned int hook_mask)
4258+{
4259+ if (hook_mask
4260+ & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_FORWARD) | (1 << NF_IP_POST_ROUTING)
4261+ | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_LOCAL_OUT))) {
4262+ printk("ipt_rpc: only valid for PRE_ROUTING, FORWARD, POST_ROUTING, LOCAL_IN and/or LOCAL_OUT targets.\n");
4263+ return 0;
4264+ }
4265+
4266+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_rpc_info)))
4267+ return 0;
4268+
4269+ return 1;
4270+}
4271+
4272+
4273+static struct ipt_match rpc_match = { { NULL, NULL }, "rpc",
4274+ &match, &checkentry, NULL,
4275+ THIS_MODULE };
4276+
4277+
4278+static int __init init(void)
4279+{
4280+ int port;
4281+
4282+ DEBUGP("incrementing usage counts\n");
4283+ __MOD_INC_USE_COUNT(ip_conntrack_rpc_udp);
4284+ __MOD_INC_USE_COUNT(ip_conntrack_rpc_tcp);
4285+
4286+ /* If no port given, default to standard RPC port */
4287+ if (ports[0] == 0)
4288+ ports[0] = RPC_PORT;
4289+
4290+ DEBUGP("registering match [%s] for;\n", rpc_match.name);
4291+ for (port = 0; (port < MAX_PORTS) && ports[port]; port++) {
4292+ DEBUGP(" port %i (UDP|TCP);\n", ports[port]);
4293+ ports_n_c++;
4294+ }
4295+
4296+ return ipt_register_match(&rpc_match);
4297+}
4298+
4299+
4300+static void fini(void)
4301+{
4302+ DEBUGP("unregistering match\n");
4303+ ipt_unregister_match(&rpc_match);
4304+
4305+ DEBUGP("decrementing usage counts\n");
4306+ __MOD_DEC_USE_COUNT(ip_conntrack_rpc_tcp);
4307+ __MOD_DEC_USE_COUNT(ip_conntrack_rpc_udp);
4308+}
4309+
4310+
4311+module_init(init);
4312+module_exit(fini);
4313+
4314diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_string.c linux-2.6.5-rc1/net/ipv4/netfilter/ipt_string.c
4315--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_string.c 1970-01-01 00:00:00.000000000 +0000
4316+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_string.c 2004-03-16 12:06:26.000000000 +0000
4317@@ -0,0 +1,218 @@
4318+/* Kernel module to match a string into a packet.
4319+ *
4320+ * Copyright (C) 2000 Emmanuel Roger <winfield@freegates.be>
4321+ *
4322+ * ChangeLog
4323+ * 19.02.2002: Gianni Tedesco <gianni@ecsc.co.uk>
4324+ * Fixed SMP re-entrancy problem using per-cpu data areas
4325+ * for the skip/shift tables.
4326+ * 02.05.2001: Gianni Tedesco <gianni@ecsc.co.uk>
4327+ * Fixed kernel panic, due to overrunning boyer moore string
4328+ * tables. Also slightly tweaked heuristic for deciding what
4329+ * search algo to use.
4330+ * 27.01.2001: Gianni Tedesco <gianni@ecsc.co.uk>
4331+ * Implemented Boyer Moore Sublinear search algorithm
4332+ * alongside the existing linear search based on memcmp().
4333+ * Also a quick check to decide which method to use on a per
4334+ * packet basis.
4335+ */
4336+
4337+#include <linux/smp.h>
4338+#include <linux/module.h>
4339+#include <linux/skbuff.h>
4340+#include <linux/file.h>
4341+#include <net/sock.h>
4342+
4343+#include <linux/netfilter_ipv4/ip_tables.h>
4344+#include <linux/netfilter_ipv4/ipt_string.h>
4345+
4346+MODULE_LICENSE("GPL");
4347+
4348+struct string_per_cpu {
4349+ int *skip;
4350+ int *shift;
4351+ int *len;
4352+};
4353+
4354+struct string_per_cpu *bm_string_data=NULL;
4355+
4356+/* Boyer Moore Sublinear string search - VERY FAST */
4357+char *search_sublinear (char *needle, char *haystack, int needle_len, int haystack_len)
4358+{
4359+ int M1, right_end, sk, sh;
4360+ int ended, j, i;
4361+
4362+ int *skip, *shift, *len;
4363+
4364+ /* use data suitable for this CPU */
4365+ shift=bm_string_data[smp_processor_id()].shift;
4366+ skip=bm_string_data[smp_processor_id()].skip;
4367+ len=bm_string_data[smp_processor_id()].len;
4368+
4369+ /* Setup skip/shift tables */
4370+ M1 = right_end = needle_len-1;
4371+ for (i = 0; i < BM_MAX_HLEN; i++) skip[i] = needle_len;
4372+ for (i = 0; needle[i]; i++) skip[needle[i]] = M1 - i;
4373+
4374+ for (i = 1; i < needle_len; i++) {
4375+ for (j = 0; j < needle_len && needle[M1 - j] == needle[M1 - i - j]; j++);
4376+ len[i] = j;
4377+ }
4378+
4379+ shift[0] = 1;
4380+ for (i = 1; i < needle_len; i++) shift[i] = needle_len;
4381+ for (i = M1; i > 0; i--) shift[len[i]] = i;
4382+ ended = 0;
4383+
4384+ for (i = 0; i < needle_len; i++) {
4385+ if (len[i] == M1 - i) ended = i;
4386+ if (ended) shift[i] = ended;
4387+ }
4388+
4389+ /* Do the search*/
4390+ while (right_end < haystack_len)
4391+ {
4392+ for (i = 0; i < needle_len && haystack[right_end - i] == needle[M1 - i]; i++);
4393+ if (i == needle_len) {
4394+ return haystack+(right_end - M1);
4395+ }
4396+
4397+ sk = skip[haystack[right_end - i]];
4398+ sh = shift[i];
4399+ right_end = max(right_end - i + sk, right_end + sh);
4400+ }
4401+
4402+ return NULL;
4403+}
4404+
4405+/* Linear string search based on memcmp() */
4406+char *search_linear (char *needle, char *haystack, int needle_len, int haystack_len)
4407+{
4408+ char *k = haystack + (haystack_len-needle_len);
4409+ char *t = haystack;
4410+
4411+ while ( t <= k ) {
4412+ if (memcmp(t, needle, needle_len) == 0)
4413+ return t;
4414+ t++;
4415+ }
4416+
4417+ return NULL;
4418+}
4419+
4420+
4421+static int
4422+match(const struct sk_buff *skb,
4423+ const struct net_device *in,
4424+ const struct net_device *out,
4425+ const void *matchinfo,
4426+ int offset,
4427+ const void *hdr,
4428+ u_int16_t datalen,
4429+ int *hotdrop)
4430+{
4431+ const struct ipt_string_info *info = matchinfo;
4432+ struct iphdr *ip = skb->nh.iph;
4433+ int hlen, nlen;
4434+ char *needle, *haystack;
4435+ proc_ipt_search search=search_linear;
4436+
4437+ if ( !ip ) return 0;
4438+
4439+ /* get lenghts, and validate them */
4440+ nlen=info->len;
4441+ hlen=ntohs(ip->tot_len)-(ip->ihl*4);
4442+ if ( nlen > hlen ) return 0;
4443+
4444+ needle=(char *)&info->string;
4445+ haystack=(char *)ip+(ip->ihl*4);
4446+
4447+ /* The sublinear search comes in to its own
4448+ * on the larger packets */
4449+ if ( (hlen>IPT_STRING_HAYSTACK_THRESH) &&
4450+ (nlen>IPT_STRING_NEEDLE_THRESH) ) {
4451+ if ( hlen < BM_MAX_HLEN ) {
4452+ search=search_sublinear;
4453+ }else{
4454+ if (net_ratelimit())
4455+ printk(KERN_INFO "ipt_string: Packet too big "
4456+ "to attempt sublinear string search "
4457+ "(%d bytes)\n", hlen );
4458+ }
4459+ }
4460+
4461+ return ((search(needle, haystack, nlen, hlen)!=NULL) ^ info->invert);
4462+}
4463+
4464+static int
4465+checkentry(const char *tablename,
4466+ const struct ipt_ip *ip,
4467+ void *matchinfo,
4468+ unsigned int matchsize,
4469+ unsigned int hook_mask)
4470+{
4471+
4472+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_string_info)))
4473+ return 0;
4474+
4475+ return 1;
4476+}
4477+
4478+void string_freeup_data(void)
4479+{
4480+ int c;
4481+
4482+ if ( bm_string_data ) {
4483+ for(c=0; c<smp_num_cpus; c++) {
4484+ if ( bm_string_data[c].shift ) kfree(bm_string_data[c].shift);
4485+ if ( bm_string_data[c].skip ) kfree(bm_string_data[c].skip);
4486+ if ( bm_string_data[c].len ) kfree(bm_string_data[c].len);
4487+ }
4488+ kfree(bm_string_data);
4489+ }
4490+}
4491+
4492+static struct ipt_match string_match
4493+= { { NULL, NULL }, "string", &match, &checkentry, NULL, THIS_MODULE };
4494+
4495+static int __init init(void)
4496+{
4497+ int c;
4498+ size_t tlen;
4499+ size_t alen;
4500+
4501+ tlen=sizeof(struct string_per_cpu)*smp_num_cpus;
4502+ alen=sizeof(int)*BM_MAX_HLEN;
4503+
4504+ /* allocate array of structures */
4505+ if ( !(bm_string_data=kmalloc(tlen,GFP_KERNEL)) ) {
4506+ return 0;
4507+ }
4508+
4509+ memset(bm_string_data, 0, tlen);
4510+
4511+ /* allocate our skip/shift tables */
4512+ for(c=0; c<smp_num_cpus; c++) {
4513+ if ( !(bm_string_data[c].shift=kmalloc(alen, GFP_KERNEL)) )
4514+ goto alloc_fail;
4515+ if ( !(bm_string_data[c].skip=kmalloc(alen, GFP_KERNEL)) )
4516+ goto alloc_fail;
4517+ if ( !(bm_string_data[c].len=kmalloc(alen, GFP_KERNEL)) )
4518+ goto alloc_fail;
4519+ }
4520+
4521+ return ipt_register_match(&string_match);
4522+
4523+alloc_fail:
4524+ string_freeup_data();
4525+ return 0;
4526+}
4527+
4528+static void __exit fini(void)
4529+{
4530+ ipt_unregister_match(&string_match);
4531+ string_freeup_data();
4532+}
4533+
4534+module_init(init);
4535+module_exit(fini);
4536diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/tcp_ipv4.c linux-2.6.5-rc1/net/ipv4/tcp_ipv4.c
4537--- linux-2.6.5-rc1.org/net/ipv4/tcp_ipv4.c 2004-03-16 05:45:58.000000000 +0000
4538+++ linux-2.6.5-rc1/net/ipv4/tcp_ipv4.c 2004-03-16 12:04:38.000000000 +0000
4539@@ -2667,6 +2667,7 @@
4540 EXPORT_SYMBOL(tcp_v4_connect);
4541 EXPORT_SYMBOL(tcp_v4_do_rcv);
4542 EXPORT_SYMBOL(tcp_v4_lookup_listener);
4543+EXPORT_SYMBOL(tcp_v4_lookup);
4544 EXPORT_SYMBOL(tcp_v4_rebuild_header);
4545 EXPORT_SYMBOL(tcp_v4_remember_stamp);
4546 EXPORT_SYMBOL(tcp_v4_send_check);
4547diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/udp.c linux-2.6.5-rc1/net/ipv4/udp.c
4548--- linux-2.6.5-rc1.org/net/ipv4/udp.c 2004-03-16 05:45:49.000000000 +0000
4549+++ linux-2.6.5-rc1/net/ipv4/udp.c 2004-03-16 12:04:38.000000000 +0000
4550@@ -1543,6 +1543,7 @@
4551 EXPORT_SYMBOL(udp_port_rover);
4552 EXPORT_SYMBOL(udp_prot);
4553 EXPORT_SYMBOL(udp_sendmsg);
4554+EXPORT_SYMBOL(udp_v4_lookup);
4555
4556 #ifdef CONFIG_PROC_FS
4557 EXPORT_SYMBOL(udp_proc_register);
4558diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv6/netfilter/ip6t_owner.c linux-2.6.5-rc1/net/ipv6/netfilter/ip6t_owner.c
4559--- linux-2.6.5-rc1.org/net/ipv6/netfilter/ip6t_owner.c 2004-03-16 05:47:17.000000000 +0000
4560+++ linux-2.6.5-rc1/net/ipv6/netfilter/ip6t_owner.c 2004-03-16 12:04:42.000000000 +0000
4561@@ -21,6 +21,38 @@
4562 MODULE_LICENSE("GPL");
4563
4564 static int
4565+match_comm(const struct sk_buff *skb, const char *comm)
4566+{
4567+ struct task_struct *p;
4568+ struct files_struct *files;
4569+ int i;
4570+
4571+ read_lock(&tasklist_lock);
4572+ for_each_task(p) {
4573+ if(strncmp(p->comm, comm, sizeof(p->comm)))
4574+ continue;
4575+
4576+ task_lock(p);
4577+ files = p->files;
4578+ if(files) {
4579+ read_lock(&files->file_lock);
4580+ for (i=0; i < files->max_fds; i++) {
4581+ if (fcheck_files(files, i) == skb->sk->socket->file) {
4582+ read_unlock(&files->file_lock);
4583+ task_unlock(p);
4584+ read_unlock(&tasklist_lock);
4585+ return 1;
4586+ }
4587+ }
4588+ read_unlock(&files->file_lock);
4589+ }
4590+ task_unlock(p);
4591+ }
4592+ read_unlock(&tasklist_lock);
4593+ return 0;
4594+}
4595+
4596+static int
4597 match_pid(const struct sk_buff *skb, pid_t pid)
4598 {
4599 struct task_struct *p;
4600@@ -125,6 +157,12 @@
4601 return 0;
4602 }
4603
4604+ if(info->match & IP6T_OWNER_COMM) {
4605+ if (!match_comm(skb, info->comm) ^
4606+ !!(info->invert & IP6T_OWNER_COMM))
4607+ return 0;
4608+ }
4609+
4610 return 1;
4611 }
4612
This page took 1.146287 seconds and 4 git commands to generate.