]> git.pld-linux.org Git - packages/kernel.git/blame - 2.6.5-rc1-patch-o-matic-ng-extra-20040316.patch
- moving config-* fixed.
[packages/kernel.git] / 2.6.5-rc1-patch-o-matic-ng-extra-20040316.patch
CommitLineData
5283140c 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
5283140c 141@@ -206,6 +209,10 @@
142 } nat;
143 #endif /* CONFIG_IP_NF_NAT_NEEDED */
144
145+#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
146+ unsigned long mark;
147+#endif
148+
149 };
150
151 /* get master conntrack via master expectation */
152diff -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
153--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ip_conntrack_rpc.h 1970-01-01 00:00:00.000000000 +0000
154+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ip_conntrack_rpc.h 2004-03-16 12:04:46.000000000 +0000
155@@ -0,0 +1,68 @@
156+/* RPC extension for IP connection tracking, Version 2.2
157+ * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
158+ * - original rpc tracking module
159+ * - "recent" connection handling for kernel 2.3+ netfilter
160+ *
161+ * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
162+ * - upgraded conntrack modules to oldnat api - kernel 2.4.0+
163+ *
164+ * (C) 2002 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
165+ * - upgraded conntrack modules to newnat api - kernel 2.4.20+
166+ * - extended matching to support filtering on procedures
167+ *
168+ * ip_conntrack_rpc.h,v 2.2 2003/01/12 18:30:00
169+ *
170+ * This program is free software; you can redistribute it and/or
171+ * modify it under the terms of the GNU General Public License
172+ * as published by the Free Software Foundation; either version
173+ * 2 of the License, or (at your option) any later version.
174+ **
175+ */
176+
177+#include <asm/param.h>
178+#include <linux/sched.h>
179+#include <linux/timer.h>
180+#include <linux/stddef.h>
181+#include <linux/list.h>
182+
183+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
184+
185+#ifndef _IP_CONNTRACK_RPC_H
186+#define _IP_CONNTRACK_RPC_H
187+
188+#define RPC_PORT 111
189+
190+
191+/* Datum in RPC packets are encoded in XDR */
192+#define IXDR_GET_INT32(buf) ((u_int32_t) ntohl((uint32_t)*buf))
193+
194+/* Fast timeout, to deny DoS atacks */
195+#define EXP (60 * HZ)
196+
197+/* Normal timeouts */
198+#define EXPIRES (180 * HZ)
199+
200+/* For future conections RPC, using client's cache bindings
201+ * I'll use ip_conntrack_lock to lock these lists */
202+
203+/* This identifies each request and stores protocol */
204+struct request_p {
205+ struct list_head list;
206+
207+ u_int32_t xid;
208+ u_int32_t ip;
209+ u_int16_t port;
210+
211+ /* Protocol */
212+ u_int16_t proto;
213+
214+ struct timer_list timeout;
215+};
216+
217+static inline int request_p_cmp(const struct request_p *p, u_int32_t xid,
218+ u_int32_t ip, u_int32_t port) {
219+ return (p->xid == xid && p->ip == ip && p->port);
220+
221+}
222+
223+#endif /* _IP_CONNTRACK_RPC_H */
5283140c 224diff -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
225--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_CONNMARK.h 1970-01-01 00:00:00.000000000 +0000
226+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_CONNMARK.h 2004-03-16 12:04:09.000000000 +0000
227@@ -0,0 +1,25 @@
228+#ifndef _IPT_CONNMARK_H_target
229+#define _IPT_CONNMARK_H_target
230+
231+/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
232+ * by Henrik Nordstrom <hno@marasystems.com>
233+ *
234+ * This program is free software; you can redistribute it and/or modify
235+ * it under the terms of the GNU General Public License as published by
236+ * the Free Software Foundation; either version 2 of the License, or
237+ * (at your option) any later version.
238+ */
239+
240+enum {
241+ IPT_CONNMARK_SET = 0,
242+ IPT_CONNMARK_SAVE,
243+ IPT_CONNMARK_RESTORE
244+};
245+
246+struct ipt_connmark_target_info {
247+ unsigned long mark;
248+ unsigned long mask;
249+ u_int8_t mode;
250+};
251+
252+#endif /*_IPT_CONNMARK_H_target*/
253diff -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
254--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_IPMARK.h 1970-01-01 00:00:00.000000000 +0000
255+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_IPMARK.h 2004-03-16 12:04:10.000000000 +0000
256@@ -0,0 +1,13 @@
257+#ifndef _IPT_IPMARK_H_target
258+#define _IPT_IPMARK_H_target
259+
260+struct ipt_ipmark_target_info {
261+ unsigned long andmask;
262+ unsigned long ormask;
263+ unsigned int addr;
264+};
265+
266+#define IPT_IPMARK_SRC 0
267+#define IPT_IPMARK_DST 1
268+
269+#endif /*_IPT_IPMARK_H_target*/
270diff -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
271--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_XOR.h 1970-01-01 00:00:00.000000000 +0000
272+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_XOR.h 2004-03-16 12:04:18.000000000 +0000
273@@ -0,0 +1,9 @@
274+#ifndef _IPT_XOR_H
275+#define _IPT_XOR_H
276+
277+struct ipt_XOR_info {
278+ char key[30];
279+ u_int8_t block_size;
280+};
281+
282+#endif /* _IPT_XOR_H */
283diff -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
284--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_addrtype.h 1970-01-01 00:00:00.000000000 +0000
285+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_addrtype.h 2004-03-16 12:04:20.000000000 +0000
286@@ -0,0 +1,11 @@
287+#ifndef _IPT_ADDRTYPE_H
288+#define _IPT_ADDRTYPE_H
289+
290+struct ipt_addrtype_info {
291+ u_int16_t source; /* source-type mask */
292+ u_int16_t dest; /* dest-type mask */
293+ int invert_source;
294+ int invert_dest;
295+};
296+
297+#endif
298diff -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
299--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_connmark.h 1970-01-01 00:00:00.000000000 +0000
300+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_connmark.h 2004-03-16 12:04:09.000000000 +0000
301@@ -0,0 +1,18 @@
302+#ifndef _IPT_CONNMARK_H
303+#define _IPT_CONNMARK_H
304+
305+/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
306+ * by Henrik Nordstrom <hno@marasystems.com>
307+ *
308+ * This program is free software; you can redistribute it and/or modify
309+ * it under the terms of the GNU General Public License as published by
310+ * the Free Software Foundation; either version 2 of the License, or
311+ * (at your option) any later version.
312+ */
313+
314+struct ipt_connmark_info {
315+ unsigned long mark, mask;
316+ u_int8_t invert;
317+};
318+
319+#endif /*_IPT_CONNMARK_H*/
320diff -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
321--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_policy.h 1970-01-01 00:00:00.000000000 +0000
322+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_policy.h 2004-03-16 12:04:45.000000000 +0000
323@@ -0,0 +1,52 @@
324+#ifndef _IPT_POLICY_H
325+#define _IPT_POLICY_H
326+
327+#define POLICY_MAX_ELEM 4
328+
329+enum ipt_policy_flags
330+{
331+ POLICY_MATCH_IN = 0x1,
332+ POLICY_MATCH_OUT = 0x2,
333+ POLICY_MATCH_NONE = 0x4,
334+ POLICY_MATCH_STRICT = 0x8,
335+};
336+
337+enum ipt_policy_modes
338+{
339+ POLICY_MODE_TRANSPORT,
340+ POLICY_MODE_TUNNEL
341+};
342+
343+struct ipt_policy_spec
344+{
345+ u_int8_t saddr:1,
346+ daddr:1,
347+ proto:1,
348+ mode:1,
349+ spi:1,
350+ reqid:1;
351+};
352+
353+struct ipt_policy_elem
354+{
355+ u_int32_t saddr;
356+ u_int32_t smask;
357+ u_int32_t daddr;
358+ u_int32_t dmask;
359+ u_int32_t spi;
360+ u_int32_t reqid;
361+ u_int8_t proto;
362+ u_int8_t mode;
363+
364+ struct ipt_policy_spec match;
365+ struct ipt_policy_spec invert;
366+};
367+
368+struct ipt_policy_info
369+{
370+ struct ipt_policy_elem pol[POLICY_MAX_ELEM];
371+ u_int16_t flags;
372+ u_int16_t len;
373+};
374+
375+#endif /* _IPT_POLICY_H */
376diff -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
377--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_rpc.h 1970-01-01 00:00:00.000000000 +0000
378+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_rpc.h 2004-03-16 12:04:46.000000000 +0000
379@@ -0,0 +1,35 @@
380+/* RPC extension for IP netfilter matching, Version 2.2
381+ * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
382+ * - original rpc tracking module
383+ * - "recent" connection handling for kernel 2.3+ netfilter
384+ *
385+ * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
386+ * - upgraded conntrack modules to oldnat api - kernel 2.4.0+
387+ *
388+ * (C) 2002 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
389+ * - upgraded conntrack modules to newnat api - kernel 2.4.20+
390+ * - extended matching to support filtering on procedures
391+ *
392+ * ipt_rpc.h.c,v 2.2 2003/01/12 18:30:00
393+ *
394+ * This program is free software; you can redistribute it and/or
395+ * modify it under the terms of the GNU General Public License
396+ * as published by the Free Software Foundation; either version
397+ * 2 of the License, or (at your option) any later version.
398+ **
399+ */
400+
401+#ifndef _IPT_RPC_H
402+#define _IPT_RPC_H
403+
404+struct ipt_rpc_data;
405+
406+struct ipt_rpc_info {
407+ int inverse;
408+ int strict;
409+ const char c_procs[1408];
410+ int i_procs;
411+ struct ipt_rpc_data *data;
412+};
413+
414+#endif /* _IPT_RPC_H */
415diff -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
416--- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ipt_string.h 1970-01-01 00:00:00.000000000 +0000
417+++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ipt_string.h 2004-03-16 12:06:26.000000000 +0000
418@@ -0,0 +1,21 @@
419+#ifndef _IPT_STRING_H
420+#define _IPT_STRING_H
421+
422+/* *** PERFORMANCE TWEAK ***
423+ * Packet size and search string threshold,
424+ * above which sublinear searches is used. */
425+#define IPT_STRING_HAYSTACK_THRESH 100
426+#define IPT_STRING_NEEDLE_THRESH 20
427+
428+#define BM_MAX_NLEN 256
429+#define BM_MAX_HLEN 1024
430+
431+typedef char *(*proc_ipt_search) (char *, char *, int, int);
432+
433+struct ipt_string_info {
434+ char string[BM_MAX_NLEN];
435+ u_int16_t invert;
436+ u_int16_t len;
437+};
438+
439+#endif /* _IPT_STRING_H */
5283140c 440diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_mime.h linux-2.6.5-rc1/include/linux/netfilter_mime.h
441--- linux-2.6.5-rc1.org/include/linux/netfilter_mime.h 1970-01-01 00:00:00.000000000 +0000
442+++ linux-2.6.5-rc1/include/linux/netfilter_mime.h 2004-03-16 12:04:49.000000000 +0000
443@@ -0,0 +1,89 @@
444+/*
445+ * MIME functions for netfilter modules. This file provides implementations
446+ * for basic MIME parsing. MIME headers are used in many protocols, such as
447+ * HTTP, RTSP, SIP, etc.
448+ *
449+ * gcc will warn for defined but unused functions, so we only include the
450+ * functions requested. The following macros are used:
451+ * NF_NEED_MIME_NEXTLINE nf_mime_nextline()
452+ */
453+#ifndef _NETFILTER_MIME_H
454+#define _NETFILTER_MIME_H
455+
456+/* Only include these functions for kernel code. */
457+#ifdef __KERNEL__
458+
459+#include <linux/ctype.h>
460+
461+/*
462+ * Given a buffer and length, advance to the next line and mark the current
463+ * line. If the current line is empty, *plinelen will be set to zero. If
464+ * not, it will be set to the actual line length (including CRLF).
465+ *
466+ * 'line' in this context means logical line (includes LWS continuations).
467+ * Returns 1 on success, 0 on failure.
468+ */
469+#ifdef NF_NEED_MIME_NEXTLINE
470+static int
471+nf_mime_nextline(char* p, uint len, uint* poff, uint* plineoff, uint* plinelen)
472+{
473+ uint off = *poff;
474+ uint physlen = 0;
475+ int is_first_line = 1;
476+
477+ if (off >= len)
478+ {
479+ return 0;
480+ }
481+
482+ do
483+ {
484+ while (p[off] != '\n')
485+ {
486+ if (len-off <= 1)
487+ {
488+ return 0;
489+ }
490+
491+ physlen++;
492+ off++;
493+ }
494+
495+ /* if we saw a crlf, physlen needs adjusted */
496+ if (physlen > 0 && p[off] == '\n' && p[off-1] == '\r')
497+ {
498+ physlen--;
499+ }
500+
501+ /* advance past the newline */
502+ off++;
503+
504+ /* check for an empty line */
505+ if (physlen == 0)
506+ {
507+ break;
508+ }
509+
510+ /* check for colon on the first physical line */
511+ if (is_first_line)
512+ {
513+ is_first_line = 0;
514+ if (memchr(p+(*poff), ':', physlen) == NULL)
515+ {
516+ return 0;
517+ }
518+ }
519+ }
520+ while (p[off] == ' ' || p[off] == '\t');
521+
522+ *plineoff = *poff;
523+ *plinelen = (physlen == 0) ? 0 : (off - *poff);
524+ *poff = off;
525+
526+ return 1;
527+}
528+#endif /* NF_NEED_MIME_NEXTLINE */
529+
530+#endif /* __KERNEL__ */
531+
532+#endif /* _NETFILTER_MIME_H */
533diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/net/tcp.h linux-2.6.5-rc1/include/net/tcp.h
534--- linux-2.6.5-rc1.org/include/net/tcp.h 2004-03-16 05:45:33.000000000 +0000
535+++ linux-2.6.5-rc1/include/net/tcp.h 2004-03-16 12:04:38.000000000 +0000
536@@ -162,6 +162,7 @@
537 extern void tcp_bucket_unlock(struct sock *sk);
538 extern int tcp_port_rover;
539 extern struct sock *tcp_v4_lookup_listener(u32 addr, unsigned short hnum, int dif);
540+extern struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 hnum, int dif);
541
542 /* These are AF independent. */
543 static __inline__ int tcp_bhashfn(__u16 lport)
544diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/net/udp.h linux-2.6.5-rc1/include/net/udp.h
545--- linux-2.6.5-rc1.org/include/net/udp.h 2004-03-16 05:47:17.000000000 +0000
546+++ linux-2.6.5-rc1/include/net/udp.h 2004-03-16 12:04:38.000000000 +0000
547@@ -74,6 +74,8 @@
548 extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg);
549 extern int udp_disconnect(struct sock *sk, int flags);
550
551+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
552+
553 DECLARE_SNMP_STAT(struct udp_mib, udp_statistics);
554 #define UDP_INC_STATS(field) SNMP_INC_STATS(udp_statistics, field)
555 #define UDP_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_statistics, field)
556diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/Kconfig linux-2.6.5-rc1/net/ipv4/netfilter/Kconfig
557--- linux-2.6.5-rc1.org/net/ipv4/netfilter/Kconfig 2004-03-16 12:00:23.000000000 +0000
558+++ linux-2.6.5-rc1/net/ipv4/netfilter/Kconfig 2004-03-16 12:06:26.000000000 +0000
559@@ -672,5 +672,61 @@
560 depends on IP_NF_IPTABLES
561 help
562
563+config IP_NF_CONNTRACK_MARK
564+ bool 'Connection mark tracking support'
565+config IP_NF_TARGET_CONNMARK
566+ tristate 'CONNMARK target support'
567+ depends on IP_NF_MANGLE
568+config IP_NF_MATCH_CONNMARK
569+ tristate ' Connection mark match support'
570+ depends on IP_NF_IPTABLES
571+ help
572+
573+config IP_NF_TARGET_IPMARK
574+ tristate 'IPMARK target support'
575+ depends on IP_NF_MANGLE
576+ help
577+
578+config IP_NF_TARGET_XOR
579+ tristate 'XOR target support'
580+ depends on IP_NF_MANGLE
581+ help
582+
583+config IP_NF_MATCH_ADDRTYPE
584+ tristate 'address type match support'
585+ depends on IP_NF_IPTABLES
586+ help
587+
588+config IP_NF_MATCH_POLICY
589+ tristate "IPsec policy match support"
590+ depends on IP_NF_IPTABLES && XFRM
591+ help
592+ Policy matching allows you to match packets based on the
593+ IPsec policy that was used during decapsulation/will
594+ be used during encapsulation.
595+
596+ To compile it as a module, choose M here. If unsure, say N.
597+ help
598+
599+config IP_NF_MATCH_RPC
600+ tristate 'RPC match support'
601+ depends on IP_NF_CONNTRACK && IP_NF_IPTABLES
602+ help
603+
604+config IP_NF_NAT_RTSP
605+ tristate
606+ depends on IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
607+ default IP_NF_NAT if IP_NF_RTSP=y
608+ default m if IP_NF_RTSP=m
609+config IP_NF_RTSP
610+ tristate ' RTSP protocol support'
611+ depends on IP_NF_CONNTRACK
612+ help
613+
614+config IP_NF_MATCH_STRING
615+ tristate 'String match support'
616+ depends on IP_NF_IPTABLES
617+ help
618+
619 endmenu
620
621diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/netfilter/Makefile linux-2.6.5-rc1/net/ipv4/netfilter/Makefile
622--- linux-2.6.5-rc1.org/net/ipv4/netfilter/Makefile 2004-03-16 12:00:23.000000000 +0000
623+++ linux-2.6.5-rc1/net/ipv4/netfilter/Makefile 2004-03-16 12:06:26.000000000 +0000
2fea659f 624@@ -41,6 +49,8 @@
5283140c 625 obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
626
627 # matches
628+obj-$(CONFIG_IP_NF_MATCH_RPC) += ip_conntrack_rpc_tcp.o ip_conntrack_rpc_udp.o ipt_rpc.o
5283140c 629+
630 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
631 obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
632 obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o
633@@ -48,6 +59,7 @@
634 obj-$(CONFIG_IP_NF_MATCH_DSTLIMIT) += ipt_dstlimit.o
635 obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
636 obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
637+obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o
638 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
639
640 obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
641@@ -78,12 +90,15 @@
642
643 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
644 obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
645+obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o
646 obj-$(CONFIG_IP_NF_MATCH_CONNLIMIT) += ipt_connlimit.o
647 obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
648 obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
649+obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
650 obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
651
652 obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
653+obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o
654
655 # targets
656 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
657@@ -91,6 +106,7 @@
658 obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
659 obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o
660 obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o
661+obj-$(CONFIG_IP_NF_TARGET_IPMARK) += ipt_IPMARK.o
662 obj-$(CONFIG_IP_NF_TARGET_IMQ) += ipt_IMQ.o
663 obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
664 obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
665@@ -99,6 +115,8 @@
666 obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
667 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
668 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
669+obj-$(CONFIG_IP_NF_TARGET_XOR) += ipt_XOR.o
670+obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK.o
671 obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
672 obj-$(CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP) += ipt_IPV4OPTSSTRIP.o
673 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
674diff -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
675--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_rpc_tcp.c 1970-01-01 00:00:00.000000000 +0000
676+++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_rpc_tcp.c 2004-03-16 12:04:46.000000000 +0000
677@@ -0,0 +1,508 @@
678+/* RPC extension for IP (TCP) connection tracking, Version 2.2
679+ * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
680+ * - original rpc tracking module
681+ * - "recent" connection handling for kernel 2.3+ netfilter
682+ *
683+ * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
684+ * - upgraded conntrack modules to oldnat api - kernel 2.4.0+
685+ *
686+ * (C) 2002,2003 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
687+ * - upgraded conntrack modules to newnat api - kernel 2.4.20+
688+ * - extended matching to support filtering on procedures
689+ *
690+ * ip_conntrack_rpc_tpc.c,v 2.2 2003/01/12 18:30:00
691+ *
692+ * This program is free software; you can redistribute it and/or
693+ * modify it under the terms of the GNU General Public License
694+ * as published by the Free Software Foundation; either version
695+ * 2 of the License, or (at your option) any later version.
696+ **
697+ * Module load syntax:
698+ * insmod ip_conntrack_rpc_tcp.o ports=port1,port2,...port<MAX_PORTS>
699+ *
700+ * Please give the ports of all RPC servers you wish to connect to.
701+ * If you don't specify ports, the default will be port 111.
702+ **
703+ * Note to all:
704+ *
705+ * RPCs should not be exposed to the internet - ask the Pentagon;
706+ *
707+ * "The unidentified crackers pleaded guilty in July to charges
708+ * of juvenile delinquency stemming from a string of Pentagon
709+ * network intrusions in February.
710+ *
711+ * The youths, going by the names TooShort and Makaveli, used
712+ * a common server security hole to break in, according to
713+ * Dane Jasper, owner of the California Internet service
714+ * provider, Sonic. They used the hole, known as the 'statd'
715+ * exploit, to attempt more than 800 break-ins, Jasper said."
716+ *
717+ * From: Wired News; "Pentagon Kids Kicked Off Grid" - Nov 6, 1998
718+ * URL: http://www.wired.com/news/politics/0,1283,16098,00.html
719+ **
720+ */
721+
722+#include <linux/module.h>
723+#include <linux/netfilter.h>
724+#include <linux/ip.h>
725+#include <net/checksum.h>
726+#include <net/tcp.h>
727+
728+#include <asm/param.h>
729+#include <linux/sched.h>
730+#include <linux/timer.h>
731+#include <linux/stddef.h>
732+#include <linux/list.h>
733+
734+#include <linux/netfilter_ipv4/lockhelp.h>
735+#include <linux/netfilter_ipv4/ip_tables.h>
736+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
737+#include <linux/netfilter_ipv4/ip_conntrack_rpc.h>
738+
739+#define MAX_PORTS 8
740+static int ports[MAX_PORTS];
741+static int ports_n_c = 0;
742+
743+#ifdef MODULE_PARM
744+MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
745+MODULE_PARM_DESC(ports, "port numbers (TCP/UDP) of RPC portmapper servers");
746+#endif
747+
748+MODULE_AUTHOR("Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>");
749+MODULE_DESCRIPTION("RPC TCP connection tracking module");
750+MODULE_LICENSE("GPL");
751+
752+#if 0
753+#define DEBUGP(format, args...) printk(KERN_DEBUG "ip_conntrack_rpc_tcp: " \
754+ format, ## args)
755+#else
756+#define DEBUGP(format, args...)
757+#endif
758+
759+DECLARE_RWLOCK(ipct_rpc_tcp_lock);
760+#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ipct_rpc_tcp_lock)
761+#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ipct_rpc_tcp_lock)
762+#include <linux/netfilter_ipv4/listhelp.h>
763+
764+/* For future conections RPC, using client's cache bindings
765+ * I'll use ip_conntrack_lock to lock these lists */
766+
767+LIST_HEAD(request_p_list_tcp);
768+
769+
770+static void delete_request_p(unsigned long request_p_ul)
771+{
772+ struct request_p *p = (void *)request_p_ul;
773+
774+ WRITE_LOCK(&ipct_rpc_tcp_lock);
775+ LIST_DELETE(&request_p_list_tcp, p);
776+ WRITE_UNLOCK(&ipct_rpc_tcp_lock);
777+ kfree(p);
778+ return;
779+}
780+
781+
782+static void req_cl(struct request_p * r)
783+{
784+ WRITE_LOCK(&ipct_rpc_tcp_lock);
785+ del_timer(&r->timeout);
786+ LIST_DELETE(&request_p_list_tcp, r);
787+ WRITE_UNLOCK(&ipct_rpc_tcp_lock);
788+ kfree(r);
789+ return;
790+}
791+
792+
793+static void clean_request(struct list_head *list)
794+{
795+ struct list_head *first = list->prev;
796+ struct list_head *temp = list->next;
797+ struct list_head *aux;
798+
799+ if (list_empty(list))
800+ return;
801+
802+ while (first != temp) {
803+ aux = temp->next;
804+ req_cl((struct request_p *)temp);
805+ temp = aux;
806+ }
807+ req_cl((struct request_p *)temp);
808+ return;
809+}
810+
811+
812+static void alloc_request_p(u_int32_t xid, u_int16_t proto, u_int32_t ip,
813+ u_int16_t port)
814+{
815+ struct request_p *req_p;
816+
817+ /* Verifies if entry already exists */
818+ WRITE_LOCK(&ipct_rpc_tcp_lock);
819+ req_p = LIST_FIND(&request_p_list_tcp, request_p_cmp,
820+ struct request_p *, xid, ip, port);
821+
822+ if (req_p) {
823+ /* Refresh timeout */
824+ if (del_timer(&req_p->timeout)) {
825+ req_p->timeout.expires = jiffies + EXP;
826+ add_timer(&req_p->timeout);
827+ }
828+ WRITE_UNLOCK(&ipct_rpc_tcp_lock);
829+ return;
830+
831+ }
832+ WRITE_UNLOCK(&ipct_rpc_tcp_lock);
833+
834+ /* Allocate new request_p */
835+ req_p = (struct request_p *) kmalloc(sizeof(struct request_p), GFP_ATOMIC);
836+ if (!req_p) {
837+ DEBUGP("can't allocate request_p\n");
838+ return;
839+ }
840+ *req_p = ((struct request_p) {{ NULL, NULL }, xid, ip, port, proto,
841+ { { NULL, NULL }, jiffies + EXP, (unsigned long)req_p,
842+ NULL }});
843+
844+ /* Initialize timer */
845+ init_timer(&req_p->timeout);
846+ req_p->timeout.function = delete_request_p;
847+ add_timer(&req_p->timeout);
848+
849+ /* Put in list */
850+ WRITE_LOCK(&ipct_rpc_tcp_lock);
851+ list_prepend(&request_p_list_tcp, req_p);
852+ WRITE_UNLOCK(&ipct_rpc_tcp_lock);
853+ return;
854+
855+}
856+
857+
858+static int check_rpc_packet(const u_int32_t *data,
859+ int dir, struct ip_conntrack *ct,
860+ struct list_head request_p_list)
861+{
862+ struct request_p *req_p;
863+ u_int32_t xid;
864+ struct ip_conntrack_expect expect, *exp = &expect;
865+
866+ /* Translstion's buffer for XDR */
867+ u_int16_t port_buf;
868+
869+
870+ /* Get XID */
871+ xid = *data;
872+
873+ /* This does sanity checking on RPC payloads,
874+ * and permits only the RPC "get port" (3)
875+ * in authorised procedures in client
876+ * communications with the portmapper.
877+ */
878+
879+ /* perform direction dependant RPC work */
880+ if (dir == IP_CT_DIR_ORIGINAL) {
881+
882+ data += 5;
883+
884+ /* Get RPC requestor */
885+ if (IXDR_GET_INT32(data) != 3) {
886+ DEBUGP("RPC packet contains an invalid (non \"get\") requestor. [skip]\n");
887+ return NF_ACCEPT;
888+ }
889+ DEBUGP("RPC packet contains a \"get\" requestor. [cont]\n");
890+
891+ data++;
892+
893+ /* Jump Credentials and Verfifier */
894+ data += IXDR_GET_INT32(data) + 2;
895+ data += IXDR_GET_INT32(data) + 2;
896+
897+ /* Get RPC procedure */
898+ DEBUGP("RPC packet contains procedure request [%u]. [cont]\n",
899+ (unsigned int)IXDR_GET_INT32(data));
900+
901+ /* Get RPC protocol and store against client parameters */
902+ data = data + 2;
903+ alloc_request_p(xid, IXDR_GET_INT32(data), ct->tuplehash[dir].tuple.src.ip,
904+ ct->tuplehash[dir].tuple.src.u.all);
905+
906+ DEBUGP("allocated RPC req_p for xid=%u proto=%u %u.%u.%u.%u:%u\n",
907+ xid, IXDR_GET_INT32(data),
908+ NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
909+ ntohs(ct->tuplehash[dir].tuple.src.u.all));
910+
911+ DEBUGP("allocated RPC request for protocol %u. [done]\n",
912+ (unsigned int)IXDR_GET_INT32(data));
913+
914+ } else {
915+
916+ /* Check for returning packet's stored counterpart */
917+ req_p = LIST_FIND(&request_p_list_tcp, request_p_cmp,
918+ struct request_p *, xid,
919+ ct->tuplehash[!dir].tuple.src.ip,
920+ ct->tuplehash[!dir].tuple.src.u.all);
921+
922+ /* Drop unexpected packets */
923+ if (!req_p) {
924+ DEBUGP("packet is not expected. [skip]\n");
925+ return NF_ACCEPT;
926+ }
927+
928+ /* Verifies if packet is really an RPC reply packet */
929+ data = data++;
930+ if (IXDR_GET_INT32(data) != 1) {
931+ DEBUGP("packet is not a valid RPC reply. [skip]\n");
932+ return NF_ACCEPT;
933+ }
934+
935+ /* Is status accept? */
936+ data++;
937+ if (IXDR_GET_INT32(data)) {
938+ DEBUGP("packet is not an RPC accept. [skip]\n");
939+ return NF_ACCEPT;
940+ }
941+
942+ /* Get Verifier length. Jump verifier */
943+ data++;
944+ data = data + IXDR_GET_INT32(data) + 2;
945+
946+ /* Is accpet status "success"? */
947+ if (IXDR_GET_INT32(data)) {
948+ DEBUGP("packet is not an RPC accept status of success. [skip]\n");
949+ return NF_ACCEPT;
950+ }
951+
952+ /* Get server port number */
953+ data++;
954+ port_buf = (u_int16_t) IXDR_GET_INT32(data);
955+
956+ /* If a packet has made it this far then it deserves an
957+ * expectation ... if port == 0, then this service is
958+ * not going to be registered.
959+ */
960+ if (port_buf) {
961+ DEBUGP("port found: %u\n", port_buf);
962+
963+ memset(&expect, 0, sizeof(expect));
964+
965+ /* Watch out, Radioactive-Man! */
966+ exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
967+ exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
968+ exp->mask.src.ip = 0xffffffff;
969+ exp->mask.dst.ip = 0xffffffff;
970+
971+ switch (req_p->proto) {
972+ case IPPROTO_UDP:
973+ exp->tuple.src.u.udp.port = 0;
974+ exp->tuple.dst.u.udp.port = htons(port_buf);
975+ exp->tuple.dst.protonum = IPPROTO_UDP;
976+ exp->mask.src.u.udp.port = 0;
977+ exp->mask.dst.u.udp.port = htons(0xffff);
978+ exp->mask.dst.protonum = 0xffff;
979+ break;
980+
981+ case IPPROTO_TCP:
982+ exp->tuple.src.u.tcp.port = 0;
983+ exp->tuple.dst.u.tcp.port = htons(port_buf);
984+ exp->tuple.dst.protonum = IPPROTO_TCP;
985+ exp->mask.src.u.tcp.port = 0;
986+ exp->mask.dst.u.tcp.port = htons(0xffff);
987+ exp->mask.dst.protonum = 0xffff;
988+ break;
989+ }
990+ exp->expectfn = NULL;
991+
992+ ip_conntrack_expect_related(ct, &expect);
993+
994+ DEBUGP("expect related ip %u.%u.%u.%u:0-%u.%u.%u.%u:%u proto=%u\n",
995+ NIPQUAD(exp->tuple.src.ip),
996+ NIPQUAD(exp->tuple.dst.ip),
997+ port_buf, req_p->proto);
998+
999+ DEBUGP("expect related mask %u.%u.%u.%u:0-%u.%u.%u.%u:65535 proto=%u\n",
1000+ NIPQUAD(exp->mask.src.ip),
1001+ NIPQUAD(exp->mask.dst.ip),
1002+ exp->mask.dst.protonum);
1003+
1004+ }
1005+
1006+ req_cl(req_p);
1007+
1008+ DEBUGP("packet evaluated. [expect]\n");
1009+ return NF_ACCEPT;
1010+ }
1011+
1012+ return NF_ACCEPT;
1013+
1014+}
1015+
1016+
1017+/* RPC TCP helper */
1018+static int help(const struct iphdr *iph, size_t len,
1019+ struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
1020+{
1021+ struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
1022+ const u_int32_t *data = (const u_int32_t *)tcph + tcph->doff;
1023+ size_t tcplen = len - iph->ihl * 4;
1024+
1025+ int dir = CTINFO2DIR(ctinfo);
1026+ int crp_ret;
1027+
1028+
1029+ DEBUGP("new packet to evaluate ..\n");
1030+
1031+ /* This works for packets like handshake packets, ignore */
1032+ if (len == ((tcph->doff + iph->ihl) * 4)) {
1033+ DEBUGP("packet has no data (may still be handshaking). [skip]\n");
1034+ return NF_ACCEPT;
1035+ }
1036+
1037+ /* Until there's been traffic both ways, don't look in packets. */
1038+ if (ctinfo != IP_CT_ESTABLISHED
1039+ && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
1040+ DEBUGP("connection tracking state is; ctinfo=%u ..\n", ctinfo);
1041+ DEBUGP("[note: failure to get past this error may indicate asymmetric routing]\n");
1042+ DEBUGP("packet is not yet part of a two way stream. [skip]\n");
1043+ return NF_ACCEPT;
1044+ }
1045+
1046+ /* Not whole TCP header? */
1047+ if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4) {
1048+ DEBUGP("TCP header length is; tcplen=%u ..\n", (unsigned) tcplen);
1049+ DEBUGP("packet does not contain a complete TCP header. [skip]\n");
1050+ return NF_ACCEPT;
1051+ }
1052+
1053+ /* FIXME: Source route IP option packets --RR */
1054+ if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
1055+ csum_partial((char *) tcph, tcplen, 0))) {
1056+ DEBUGP("csum; %p %u %u.%u.%u.%u %u.%u.%u.%u\n",
1057+ tcph, tcplen, NIPQUAD(iph->saddr),
1058+ NIPQUAD(iph->daddr));
1059+ DEBUGP("[note: failure to get past this error may indicate source routing]\n");
1060+ DEBUGP("packet contains a bad checksum. [skip]\n");
1061+ return NF_ACCEPT;
1062+ }
1063+
1064+ /* perform direction dependant protocol work */
1065+ if (dir == IP_CT_DIR_ORIGINAL) {
1066+
1067+ DEBUGP("packet is from the initiator. [cont]\n");
1068+
1069+ /* Tests if packet len is ok */
1070+ if ((tcplen - (tcph->doff * 4)) != 60) {
1071+ DEBUGP("packet length is not correct. [skip]\n");
1072+ return NF_ACCEPT;
1073+ }
1074+
1075+ } else {
1076+
1077+ DEBUGP("packet is from the receiver. [cont]\n");
1078+
1079+ /* Tests if packet len is ok */
1080+ if ((tcplen - (tcph->doff * 4)) != 32) {
1081+ DEBUGP("packet length is not correct. [skip]\n");
1082+ return NF_ACCEPT;
1083+ }
1084+ }
1085+
1086+ /* Get to the data */
1087+ data++;
1088+
1089+ /* Check the RPC data */
1090+ crp_ret = check_rpc_packet(data, dir, ct, request_p_list_tcp);
1091+
1092+ return crp_ret;
1093+
1094+}
1095+
1096+
1097+static struct ip_conntrack_helper rpc_helpers[MAX_PORTS];
1098+
1099+static void fini(void);
1100+
1101+
1102+static int __init init(void)
1103+{
1104+ int port, ret;
1105+ static char name[10];
1106+
1107+
1108+ /* If no port given, default to standard RPC port */
1109+ if (ports[0] == 0)
1110+ ports[0] = RPC_PORT;
1111+
1112+ for (port = 0; (port < MAX_PORTS) && ports[port]; port++) {
1113+ memset(&rpc_helpers[port], 0, sizeof(struct ip_conntrack_helper));
1114+
1115+ if (ports[port] == RPC_PORT)
1116+ sprintf(name, "rpc");
1117+ else
1118+ sprintf(name, "rpc-%d", port);
1119+
1120+ rpc_helpers[port].name = name;
1121+ rpc_helpers[port].me = THIS_MODULE;
1122+ rpc_helpers[port].max_expected = 1;
1123+ rpc_helpers[port].flags = IP_CT_HELPER_F_REUSE_EXPECT;
1124+ rpc_helpers[port].timeout = 0;
1125+
1126+ rpc_helpers[port].tuple.dst.protonum = IPPROTO_TCP;
1127+ rpc_helpers[port].mask.dst.protonum = 0xffff;
1128+
1129+ /* RPC can come from ports 0:65535 to ports[port] (111) */
1130+ rpc_helpers[port].tuple.src.u.udp.port = htons(ports[port]);
1131+ rpc_helpers[port].mask.src.u.udp.port = htons(0xffff);
1132+ rpc_helpers[port].mask.dst.u.udp.port = htons(0x0);
1133+
1134+ rpc_helpers[port].help = help;
1135+
1136+ DEBUGP("registering helper for port #%d: %d/TCP\n", port, ports[port]);
1137+ DEBUGP("helper match ip %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
1138+ NIPQUAD(rpc_helpers[port].tuple.dst.ip),
1139+ ntohs(rpc_helpers[port].tuple.dst.u.tcp.port),
1140+ NIPQUAD(rpc_helpers[port].tuple.src.ip),
1141+ ntohs(rpc_helpers[port].tuple.src.u.tcp.port));
1142+ DEBUGP("helper match mask %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
1143+ NIPQUAD(rpc_helpers[port].mask.dst.ip),
1144+ ntohs(rpc_helpers[port].mask.dst.u.tcp.port),
1145+ NIPQUAD(rpc_helpers[port].mask.src.ip),
1146+ ntohs(rpc_helpers[port].mask.src.u.tcp.port));
1147+
1148+ ret = ip_conntrack_helper_register(&rpc_helpers[port]);
1149+
1150+ if (ret) {
1151+ printk("ERROR registering port %d\n",
1152+ ports[port]);
1153+ fini();
1154+ return -EBUSY;
1155+ }
1156+ ports_n_c++;
1157+ }
1158+ return 0;
1159+}
1160+
1161+
1162+/* This function is intentionally _NOT_ defined as __exit, because
1163+ * it is needed by the init function */
1164+static void fini(void)
1165+{
1166+ int port;
1167+
1168+ DEBUGP("cleaning request list\n");
1169+ clean_request(&request_p_list_tcp);
1170+
1171+ for (port = 0; (port < ports_n_c) && ports[port]; port++) {
1172+ DEBUGP("unregistering port %d\n", ports[port]);
1173+ ip_conntrack_helper_unregister(&rpc_helpers[port]);
1174+ }
1175+}
1176+
1177+
1178+module_init(init);
1179+module_exit(fini);
1180+
1181+struct module *ip_conntrack_rpc_tcp = THIS_MODULE;
1182+EXPORT_SYMBOL(request_p_list_tcp);
1183+EXPORT_SYMBOL(ip_conntrack_rpc_tcp);
1184+EXPORT_SYMBOL(ipct_rpc_tcp_lock);
1185+
1186diff -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
1187--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_rpc_udp.c 1970-01-01 00:00:00.000000000 +0000
1188+++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_rpc_udp.c 2004-03-16 12:04:46.000000000 +0000
1189@@ -0,0 +1,503 @@
1190+/* RPC extension for IP (UDP) connection tracking, Version 2.2
1191+ * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
1192+ * - original rpc tracking module
1193+ * - "recent" connection handling for kernel 2.3+ netfilter
1194+ *
1195+ * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
1196+ * - upgraded conntrack modules to oldnat api - kernel 2.4.0+
1197+ *
1198+ * (C) 2002,2003 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
1199+ * - upgraded conntrack modules to newnat api - kernel 2.4.20+
1200+ * - extended matching to support filtering on procedures
1201+ *
1202+ * ip_conntrack_rpc_udp.c,v 2.2 2003/01/12 18:30:00
1203+ *
1204+ * This program is free software; you can redistribute it and/or
1205+ * modify it under the terms of the GNU General Public License
1206+ * as published by the Free Software Foundation; either version
1207+ * 2 of the License, or (at your option) any later version.
1208+ **
1209+ * Module load syntax:
1210+ * insmod ip_conntrack_rpc_udp.o ports=port1,port2,...port<MAX_PORTS>
1211+ *
1212+ * Please give the ports of all RPC servers you wish to connect to.
1213+ * If you don't specify ports, the default will be port 111.
1214+ **
1215+ * Note to all:
1216+ *
1217+ * RPCs should not be exposed to the internet - ask the Pentagon;
1218+ *
1219+ * "The unidentified crackers pleaded guilty in July to charges
1220+ * of juvenile delinquency stemming from a string of Pentagon
1221+ * network intrusions in February.
1222+ *
1223+ * The youths, going by the names TooShort and Makaveli, used
1224+ * a common server security hole to break in, according to
1225+ * Dane Jasper, owner of the California Internet service
1226+ * provider, Sonic. They used the hole, known as the 'statd'
1227+ * exploit, to attempt more than 800 break-ins, Jasper said."
1228+ *
1229+ * From: Wired News; "Pentagon Kids Kicked Off Grid" - Nov 6, 1998
1230+ * URL: http://www.wired.com/news/politics/0,1283,16098,00.html
1231+ **
1232+ */
1233+
1234+#include <linux/module.h>
1235+#include <linux/netfilter.h>
1236+#include <linux/ip.h>
1237+#include <net/checksum.h>
1238+#include <net/udp.h>
1239+
1240+#include <asm/param.h>
1241+#include <linux/sched.h>
1242+#include <linux/timer.h>
1243+#include <linux/stddef.h>
1244+#include <linux/list.h>
1245+
1246+#include <linux/netfilter_ipv4/lockhelp.h>
1247+#include <linux/netfilter_ipv4/ip_tables.h>
1248+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
1249+#include <linux/netfilter_ipv4/ip_conntrack_rpc.h>
1250+
1251+#define MAX_PORTS 8
1252+static int ports[MAX_PORTS];
1253+static int ports_n_c = 0;
1254+
1255+#ifdef MODULE_PARM
1256+MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
1257+MODULE_PARM_DESC(ports, "port numbers (TCP/UDP) of RPC portmapper servers");
1258+#endif
1259+
1260+MODULE_AUTHOR("Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>");
1261+MODULE_DESCRIPTION("RPC UDP connection tracking module");
1262+MODULE_LICENSE("GPL");
1263+
1264+#if 0
1265+#define DEBUGP(format, args...) printk(KERN_DEBUG "ip_conntrack_rpc_udp: " \
1266+ format, ## args)
1267+#else
1268+#define DEBUGP(format, args...)
1269+#endif
1270+
1271+DECLARE_RWLOCK(ipct_rpc_udp_lock);
1272+#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ipct_rpc_udp_lock)
1273+#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ipct_rpc_udp_lock)
1274+#include <linux/netfilter_ipv4/listhelp.h>
1275+
1276+/* For future conections RPC, using client's cache bindings
1277+ * I'll use ip_conntrack_lock to lock these lists */
1278+
1279+LIST_HEAD(request_p_list_udp);
1280+
1281+
1282+static void delete_request_p(unsigned long request_p_ul)
1283+{
1284+ struct request_p *p = (void *)request_p_ul;
1285+
1286+ WRITE_LOCK(&ipct_rpc_udp_lock);
1287+ LIST_DELETE(&request_p_list_udp, p);
1288+ WRITE_UNLOCK(&ipct_rpc_udp_lock);
1289+ kfree(p);
1290+ return;
1291+}
1292+
1293+
1294+static void req_cl(struct request_p * r)
1295+{
1296+ WRITE_LOCK(&ipct_rpc_udp_lock);
1297+ del_timer(&r->timeout);
1298+ LIST_DELETE(&request_p_list_udp, r);
1299+ WRITE_UNLOCK(&ipct_rpc_udp_lock);
1300+ kfree(r);
1301+ return;
1302+}
1303+
1304+
1305+static void clean_request(struct list_head *list)
1306+{
1307+ struct list_head *first = list->prev;
1308+ struct list_head *temp = list->next;
1309+ struct list_head *aux;
1310+
1311+ if (list_empty(list))
1312+ return;
1313+
1314+ while (first != temp) {
1315+ aux = temp->next;
1316+ req_cl((struct request_p *)temp);
1317+ temp = aux;
1318+ }
1319+ req_cl((struct request_p *)temp);
1320+ return;
1321+}
1322+
1323+
1324+static void alloc_request_p(u_int32_t xid, u_int16_t proto, u_int32_t ip,
1325+ u_int16_t port)
1326+{
1327+ struct request_p *req_p;
1328+
1329+ /* Verifies if entry already exists */
1330+ WRITE_LOCK(&ipct_rpc_udp_lock);
1331+ req_p = LIST_FIND(&request_p_list_udp, request_p_cmp,
1332+ struct request_p *, xid, ip, port);
1333+
1334+ if (req_p) {
1335+ /* Refresh timeout */
1336+ if (del_timer(&req_p->timeout)) {
1337+ req_p->timeout.expires = jiffies + EXP;
1338+ add_timer(&req_p->timeout);
1339+ }
1340+ WRITE_UNLOCK(&ipct_rpc_udp_lock);
1341+ return;
1342+
1343+ }
1344+ WRITE_UNLOCK(&ipct_rpc_udp_lock);
1345+
1346+ /* Allocate new request_p */
1347+ req_p = (struct request_p *) kmalloc(sizeof(struct request_p), GFP_ATOMIC);
1348+ if (!req_p) {
1349+ DEBUGP("can't allocate request_p\n");
1350+ return;
1351+ }
1352+ *req_p = ((struct request_p) {{ NULL, NULL }, xid, ip, port, proto,
1353+ { { NULL, NULL }, jiffies + EXP, (unsigned long)req_p,
1354+ NULL }});
1355+
1356+ /* Initialize timer */
1357+ init_timer(&req_p->timeout);
1358+ req_p->timeout.function = delete_request_p;
1359+ add_timer(&req_p->timeout);
1360+
1361+ /* Put in list */
1362+ WRITE_LOCK(&ipct_rpc_udp_lock);
1363+ list_prepend(&request_p_list_udp, req_p);
1364+ WRITE_UNLOCK(&ipct_rpc_udp_lock);
1365+ return;
1366+
1367+}
1368+
1369+
1370+static int check_rpc_packet(const u_int32_t *data,
1371+ int dir, struct ip_conntrack *ct,
1372+ struct list_head request_p_list)
1373+{
1374+ struct request_p *req_p;
1375+ u_int32_t xid;
1376+ struct ip_conntrack_expect expect, *exp = &expect;
1377+
1378+ /* Translstion's buffer for XDR */
1379+ u_int16_t port_buf;
1380+
1381+
1382+ /* Get XID */
1383+ xid = *data;
1384+
1385+ /* This does sanity checking on RPC payloads,
1386+ * and permits only the RPC "get port" (3)
1387+ * in authorised procedures in client
1388+ * communications with the portmapper.
1389+ */
1390+
1391+ /* perform direction dependant RPC work */
1392+ if (dir == IP_CT_DIR_ORIGINAL) {
1393+
1394+ data += 5;
1395+
1396+ /* Get RPC requestor */
1397+ if (IXDR_GET_INT32(data) != 3) {
1398+ DEBUGP("RPC packet contains an invalid (non \"get\") requestor. [skip]\n");
1399+ return NF_ACCEPT;
1400+ }
1401+ DEBUGP("RPC packet contains a \"get\" requestor. [cont]\n");
1402+
1403+ data++;
1404+
1405+ /* Jump Credentials and Verfifier */
1406+ data = data + IXDR_GET_INT32(data) + 2;
1407+ data = data + IXDR_GET_INT32(data) + 2;
1408+
1409+ /* Get RPC procedure */
1410+ DEBUGP("RPC packet contains procedure request [%u]. [cont]\n",
1411+ (unsigned int)IXDR_GET_INT32(data));
1412+
1413+ /* Get RPC protocol and store against client parameters */
1414+ data = data + 2;
1415+ alloc_request_p(xid, IXDR_GET_INT32(data), ct->tuplehash[dir].tuple.src.ip,
1416+ ct->tuplehash[dir].tuple.src.u.all);
1417+
1418+ DEBUGP("allocated RPC req_p for xid=%u proto=%u %u.%u.%u.%u:%u\n",
1419+ xid, IXDR_GET_INT32(data),
1420+ NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
1421+ ntohs(ct->tuplehash[dir].tuple.src.u.all));
1422+
1423+ DEBUGP("allocated RPC request for protocol %u. [done]\n",
1424+ (unsigned int)IXDR_GET_INT32(data));
1425+
1426+ } else {
1427+
1428+ /* Check for returning packet's stored counterpart */
1429+ req_p = LIST_FIND(&request_p_list_udp, request_p_cmp,
1430+ struct request_p *, xid,
1431+ ct->tuplehash[!dir].tuple.src.ip,
1432+ ct->tuplehash[!dir].tuple.src.u.all);
1433+
1434+ /* Drop unexpected packets */
1435+ if (!req_p) {
1436+ DEBUGP("packet is not expected. [skip]\n");
1437+ return NF_ACCEPT;
1438+ }
1439+
1440+ /* Verifies if packet is really an RPC reply packet */
1441+ data = data++;
1442+ if (IXDR_GET_INT32(data) != 1) {
1443+ DEBUGP("packet is not a valid RPC reply. [skip]\n");
1444+ return NF_ACCEPT;
1445+ }
1446+
1447+ /* Is status accept? */
1448+ data++;
1449+ if (IXDR_GET_INT32(data)) {
1450+ DEBUGP("packet is not an RPC accept. [skip]\n");
1451+ return NF_ACCEPT;
1452+ }
1453+
1454+ /* Get Verifier length. Jump verifier */
1455+ data++;
1456+ data = data + IXDR_GET_INT32(data) + 2;
1457+
1458+ /* Is accpet status "success"? */
1459+ if (IXDR_GET_INT32(data)) {
1460+ DEBUGP("packet is not an RPC accept status of success. [skip]\n");
1461+ return NF_ACCEPT;
1462+ }
1463+
1464+ /* Get server port number */
1465+ data++;
1466+ port_buf = (u_int16_t) IXDR_GET_INT32(data);
1467+
1468+ /* If a packet has made it this far then it deserves an
1469+ * expectation ... if port == 0, then this service is
1470+ * not going to be registered.
1471+ */
1472+ if (port_buf) {
1473+ DEBUGP("port found: %u\n", port_buf);
1474+
1475+ memset(&expect, 0, sizeof(expect));
1476+
1477+ /* Watch out, Radioactive-Man! */
1478+ exp->tuple.src.ip = ct->tuplehash[!dir].tuple.src.ip;
1479+ exp->tuple.dst.ip = ct->tuplehash[!dir].tuple.dst.ip;
1480+ exp->mask.src.ip = 0xffffffff;
1481+ exp->mask.dst.ip = 0xffffffff;
1482+
1483+ switch (req_p->proto) {
1484+ case IPPROTO_UDP:
1485+ exp->tuple.src.u.udp.port = 0;
1486+ exp->tuple.dst.u.udp.port = htons(port_buf);
1487+ exp->tuple.dst.protonum = IPPROTO_UDP;
1488+ exp->mask.src.u.udp.port = 0;
1489+ exp->mask.dst.u.udp.port = htons(0xffff);
1490+ exp->mask.dst.protonum = 0xffff;
1491+ break;
1492+
1493+ case IPPROTO_TCP:
1494+ exp->tuple.src.u.tcp.port = 0;
1495+ exp->tuple.dst.u.tcp.port = htons(port_buf);
1496+ exp->tuple.dst.protonum = IPPROTO_TCP;
1497+ exp->mask.src.u.tcp.port = 0;
1498+ exp->mask.dst.u.tcp.port = htons(0xffff);
1499+ exp->mask.dst.protonum = 0xffff;
1500+ break;
1501+ }
1502+ exp->expectfn = NULL;
1503+
1504+ ip_conntrack_expect_related(ct, &expect);
1505+
1506+ DEBUGP("expect related ip %u.%u.%u.%u:0-%u.%u.%u.%u:%u proto=%u\n",
1507+ NIPQUAD(exp->tuple.src.ip),
1508+ NIPQUAD(exp->tuple.dst.ip),
1509+ port_buf, req_p->proto);
1510+
1511+ DEBUGP("expect related mask %u.%u.%u.%u:0-%u.%u.%u.%u:65535 proto=%u\n",
1512+ NIPQUAD(exp->mask.src.ip),
1513+ NIPQUAD(exp->mask.dst.ip),
1514+ exp->mask.dst.protonum);
1515+
1516+ }
1517+
1518+ req_cl(req_p);
1519+
1520+ DEBUGP("packet evaluated. [expect]\n");
1521+ return NF_ACCEPT;
1522+ }
1523+
1524+ return NF_ACCEPT;
1525+
1526+}
1527+
1528+
1529+/* RPC UDP helper */
1530+static int help(const struct iphdr *iph, size_t len,
1531+ struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
1532+{
1533+ struct udphdr *udph = (void *) iph + iph->ihl * 4;
1534+ const u_int32_t *data = (const u_int32_t *)udph + 2;
1535+ size_t udplen = len - iph->ihl * 4;
1536+ int dir = CTINFO2DIR(ctinfo);
1537+ int crp_ret;
1538+
1539+ /* Checksum */
1540+ const u_int16_t *chsm = (const u_int16_t *)udph + 3;
1541+
1542+
1543+ DEBUGP("new packet to evaluate ..\n");
1544+
1545+ /* Not whole UDP header? */
1546+ if (udplen < sizeof(struct udphdr)) {
1547+ DEBUGP("UDP header length is; udplen=%u ..\n", (unsigned) udplen);
1548+ DEBUGP("packet does not contain a complete UDP header. [skip]\n");
1549+ return NF_ACCEPT;
1550+ }
1551+
1552+ /* FIXME: Source route IP option packets --RR */
1553+ if (*chsm) {
1554+ if (csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP,
1555+ csum_partial((char *)udph, udplen, 0))) {
1556+ DEBUGP("[note: failure to get past this error may indicate source routing]\n");
1557+ DEBUGP("packet contains a bad checksum. [skip]\n");
1558+ return NF_ACCEPT;
1559+ }
1560+ }
1561+
1562+ /* perform direction dependant protocol work */
1563+ if (dir == IP_CT_DIR_ORIGINAL) {
1564+
1565+ DEBUGP("packet is from the initiator. [cont]\n");
1566+
1567+ /* Tests if packet len is ok */
1568+ if ((udplen - sizeof(struct udphdr)) != 56) {
1569+ DEBUGP("packet length is not correct. [skip]\n");
1570+ return NF_ACCEPT;
1571+ }
1572+
1573+ } else {
1574+
1575+ DEBUGP("packet is from the receiver. [cont]\n");
1576+
1577+ /* Until there's been traffic both ways, don't look in packets. */
1578+ if (ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
1579+ DEBUGP("connection tracking state is; ctinfo=%u ..\n", ctinfo);
1580+ DEBUGP("[note: failure to get past this error may indicate asymmetric routing]\n");
1581+ DEBUGP("packet is not yet part of a two way stream. [skip]\n");
1582+ return NF_ACCEPT;
1583+ }
1584+
1585+ /* Tests if packet len is ok */
1586+ if ((udplen - sizeof(struct udphdr)) != 28) {
1587+ DEBUGP("packet length is not correct. [skip]\n");
1588+ return NF_ACCEPT;
1589+ }
1590+
1591+ }
1592+
1593+ /* Get to the data */
1594+ /* udp *data == *correct */
1595+
1596+ /* Check the RPC data */
1597+ crp_ret = check_rpc_packet(data, dir, ct, request_p_list_udp);
1598+
1599+ return crp_ret;
1600+
1601+}
1602+
1603+
1604+static struct ip_conntrack_helper rpc_helpers[MAX_PORTS];
1605+
1606+static void fini(void);
1607+
1608+
1609+static int __init init(void)
1610+{
1611+ int port, ret;
1612+ static char name[10];
1613+
1614+
1615+ /* If no port given, default to standard RPC port */
1616+ if (ports[0] == 0)
1617+ ports[0] = RPC_PORT;
1618+
1619+ for (port = 0; (port < MAX_PORTS) && ports[port]; port++) {
1620+ memset(&rpc_helpers[port], 0, sizeof(struct ip_conntrack_helper));
1621+
1622+ if (ports[port] == RPC_PORT)
1623+ sprintf(name, "rpc");
1624+ else
1625+ sprintf(name, "rpc-%d", port);
1626+
1627+ rpc_helpers[port].name = name;
1628+ rpc_helpers[port].me = THIS_MODULE;
1629+ rpc_helpers[port].max_expected = 1;
1630+ rpc_helpers[port].flags = IP_CT_HELPER_F_REUSE_EXPECT;
1631+ rpc_helpers[port].timeout = 0;
1632+
1633+ rpc_helpers[port].tuple.dst.protonum = IPPROTO_UDP;
1634+ rpc_helpers[port].mask.dst.protonum = 0xffff;
1635+
1636+ /* RPC can come from ports 0:65535 to ports[port] (111) */
1637+ rpc_helpers[port].tuple.src.u.udp.port = htons(ports[port]);
1638+ rpc_helpers[port].mask.src.u.udp.port = htons(0xffff);
1639+ rpc_helpers[port].mask.dst.u.udp.port = htons(0x0);
1640+
1641+ rpc_helpers[port].help = help;
1642+
1643+ DEBUGP("registering helper for port #%d: %d/UDP\n", port, ports[port]);
1644+ DEBUGP("helper match ip %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
1645+ NIPQUAD(rpc_helpers[port].tuple.dst.ip),
1646+ ntohs(rpc_helpers[port].tuple.dst.u.udp.port),
1647+ NIPQUAD(rpc_helpers[port].tuple.src.ip),
1648+ ntohs(rpc_helpers[port].tuple.src.u.udp.port));
1649+ DEBUGP("helper match mask %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
1650+ NIPQUAD(rpc_helpers[port].mask.dst.ip),
1651+ ntohs(rpc_helpers[port].mask.dst.u.udp.port),
1652+ NIPQUAD(rpc_helpers[port].mask.src.ip),
1653+ ntohs(rpc_helpers[port].mask.src.u.udp.port));
1654+
1655+ ret = ip_conntrack_helper_register(&rpc_helpers[port]);
1656+
1657+ if (ret) {
1658+ printk("ERROR registering port %d\n",
1659+ ports[port]);
1660+ fini();
1661+ return -EBUSY;
1662+ }
1663+ ports_n_c++;
1664+ }
1665+ return 0;
1666+}
1667+
1668+
1669+/* This function is intentionally _NOT_ defined as __exit, because
1670+ * it is needed by the init function */
1671+static void fini(void)
1672+{
1673+ int port;
1674+
1675+ DEBUGP("cleaning request list\n");
1676+ clean_request(&request_p_list_udp);
1677+
1678+ for (port = 0; (port < ports_n_c) && ports[port]; port++) {
1679+ DEBUGP("unregistering port %d\n", ports[port]);
1680+ ip_conntrack_helper_unregister(&rpc_helpers[port]);
1681+ }
1682+}
1683+
1684+
1685+module_init(init);
1686+module_exit(fini);
1687+
1688+struct module *ip_conntrack_rpc_udp = THIS_MODULE;
1689+EXPORT_SYMBOL(request_p_list_udp);
1690+EXPORT_SYMBOL(ip_conntrack_rpc_udp);
1691+EXPORT_SYMBOL(ipct_rpc_udp_lock);
1692+
5283140c 1693diff -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
1694--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-03-16 12:00:23.000000000 +0000
1695+++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-03-16 12:04:09.000000000 +0000
1696@@ -110,6 +110,9 @@
1697 len += sprintf(buffer + len, "[ASSURED] ");
1698 len += sprintf(buffer + len, "use=%u ",
1699 atomic_read(&conntrack->ct_general.use));
1700+#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
1701+ len += sprintf(buffer + len, "mark=%ld ", conntrack->mark);
1702+#endif
1703 len += sprintf(buffer + len, "\n");
1704
1705 return len;
5283140c 1706diff -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
1707--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ip_tables.c 2004-03-16 05:45:50.000000000 +0000
1708+++ linux-2.6.5-rc1/net/ipv4/netfilter/ip_tables.c 2004-03-16 12:04:36.000000000 +0000
1709@@ -8,6 +8,10 @@
1710 * it under the terms of the GNU General Public License version 2 as
1711 * published by the Free Software Foundation.
1712 *
1713+ * 6 Mar 2002 Robert Olsson <robban@robtex.com>
1714+ * 17 Apr 2003 Chris Wilson <chris@netservers.co.uk>
1715+ * - mark_source_chains speedup for complex chains
1716+ *
1717 * 19 Jan 2002 Harald Welte <laforge@gnumonks.org>
1718 * - increase module usage count as soon as we have rules inside
1719 * a table
1720@@ -498,6 +502,9 @@
1721 {
1722 unsigned int hook;
1723
1724+ /* keep track of where we have been: */
1725+ unsigned char *been = vmalloc(newinfo->size);
1726+
1727 /* No recursion; use packet counter to save back ptrs (reset
1728 to 0 as we leave), and comefrom to save source hook bitmask */
1729 for (hook = 0; hook < NF_IP_NUMHOOKS; hook++) {
1730@@ -510,6 +517,7 @@
1731
1732 /* Set initial back pointer. */
1733 e->counters.pcnt = pos;
1734+ memset(been, 0, newinfo->size);
1735
1736 for (;;) {
1737 struct ipt_standard_target *t
1738@@ -518,6 +526,7 @@
1739 if (e->comefrom & (1 << NF_IP_NUMHOOKS)) {
1740 printk("iptables: loop hook %u pos %u %08X.\n",
1741 hook, pos, e->comefrom);
1742+ vfree(been);
1743 return 0;
1744 }
1745 e->comefrom
1746@@ -565,10 +574,14 @@
1747 } else {
1748 int newpos = t->verdict;
1749
1750- if (strcmp(t->target.u.user.name,
1751+ if ( (pos < 0 || pos >= newinfo->size
1752+ || !been[pos])
1753+ && strcmp(t->target.u.user.name,
1754 IPT_STANDARD_TARGET) == 0
1755 && newpos >= 0) {
1756 /* This a jump; chase it. */
1757+ if (pos >= 0 && pos < newinfo->size)
1758+ been[pos]++;
1759 duprintf("Jump rule %u -> %u\n",
1760 pos, newpos);
1761 } else {
1762@@ -584,6 +597,7 @@
1763 next:
1764 duprintf("Finished chain %u\n", hook);
1765 }
1766+ vfree(been);
1767 return 1;
1768 }
1769
1770diff -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
1771--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_CONNMARK.c 1970-01-01 00:00:00.000000000 +0000
1772+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_CONNMARK.c 2004-03-16 12:04:09.000000000 +0000
1773@@ -0,0 +1,118 @@
1774+/* This kernel module is used to modify the connection mark values, or
1775+ * to optionally restore the skb nfmark from the connection mark
1776+ *
1777+ * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
1778+ * by Henrik Nordstrom <hno@marasystems.com>
1779+ *
1780+ * This program is free software; you can redistribute it and/or modify
1781+ * it under the terms of the GNU General Public License as published by
1782+ * the Free Software Foundation; either version 2 of the License, or
1783+ * (at your option) any later version.
1784+ *
1785+ * This program is distributed in the hope that it will be useful,
1786+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1787+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1788+ * GNU General Public License for more details.
1789+ *
1790+ * You should have received a copy of the GNU General Public License
1791+ * along with this program; if not, write to the Free Software
1792+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1793+ */
1794+#include <linux/module.h>
1795+#include <linux/skbuff.h>
1796+#include <linux/ip.h>
1797+#include <net/checksum.h>
1798+
1799+MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
1800+MODULE_DESCRIPTION("IP tables CONNMARK matching module");
1801+MODULE_LICENSE("GPL");
1802+
1803+#include <linux/netfilter_ipv4/ip_tables.h>
1804+#include <linux/netfilter_ipv4/ipt_CONNMARK.h>
1805+#include <linux/netfilter_ipv4/ip_conntrack.h>
1806+
1807+static unsigned int
1808+target(struct sk_buff **pskb,
1809+ const struct net_device *in,
1810+ const struct net_device *out,
1811+ unsigned int hooknum,
1812+ const void *targinfo,
1813+ void *userinfo)
1814+{
1815+ const struct ipt_connmark_target_info *markinfo = targinfo;
1816+ unsigned long diff;
1817+ unsigned long nfmark;
1818+ unsigned long newmark;
1819+
1820+ enum ip_conntrack_info ctinfo;
1821+ struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo);
1822+ if (ct) {
1823+ switch(markinfo->mode) {
1824+ case IPT_CONNMARK_SET:
1825+ newmark = (ct->mark & ~markinfo->mask) | markinfo->mark;
1826+ if (newmark != ct->mark)
1827+ ct->mark = newmark;
1828+ break;
1829+ case IPT_CONNMARK_SAVE:
1830+ newmark = (ct->mark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask);
1831+ if (ct->mark != newmark)
1832+ ct->mark = newmark;
1833+ break;
1834+ case IPT_CONNMARK_RESTORE:
1835+ nfmark = (*pskb)->nfmark;
1836+ diff = (ct->mark ^ nfmark & markinfo->mask);
1837+ if (diff != 0) {
1838+ (*pskb)->nfmark = nfmark ^ diff;
1839+ (*pskb)->nfcache |= NFC_ALTERED;
1840+ }
1841+ break;
1842+ }
1843+ }
1844+
1845+ return IPT_CONTINUE;
1846+}
1847+
1848+static int
1849+checkentry(const char *tablename,
1850+ const struct ipt_entry *e,
1851+ void *targinfo,
1852+ unsigned int targinfosize,
1853+ unsigned int hook_mask)
1854+{
1855+ struct ipt_connmark_target_info *matchinfo = targinfo;
1856+ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_connmark_target_info))) {
1857+ printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n",
1858+ targinfosize,
1859+ IPT_ALIGN(sizeof(struct ipt_connmark_target_info)));
1860+ return 0;
1861+ }
1862+
1863+ if (matchinfo->mode == IPT_CONNMARK_RESTORE) {
1864+ if (strcmp(tablename, "mangle") != 0) {
1865+ printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1866+ return 0;
1867+ }
1868+ }
1869+
1870+ return 1;
1871+}
1872+
1873+static struct ipt_target ipt_connmark_reg = {
1874+ .name = "CONNMARK",
1875+ .target = &target,
1876+ .checkentry = &checkentry,
1877+ .me = THIS_MODULE
1878+};
1879+
1880+static int __init init(void)
1881+{
1882+ return ipt_register_target(&ipt_connmark_reg);
1883+}
1884+
1885+static void __exit fini(void)
1886+{
1887+ ipt_unregister_target(&ipt_connmark_reg);
1888+}
1889+
1890+module_init(init);
1891+module_exit(fini);
1892diff -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
1893--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_IPMARK.c 1970-01-01 00:00:00.000000000 +0000
1894+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_IPMARK.c 2004-03-16 12:04:10.000000000 +0000
1895@@ -0,0 +1,81 @@
1896+/* This is a module which is used for setting the NFMARK field of an skb. */
1897+#include <linux/module.h>
1898+#include <linux/skbuff.h>
1899+#include <linux/ip.h>
1900+#include <net/checksum.h>
1901+
1902+#include <linux/netfilter_ipv4/ip_tables.h>
1903+#include <linux/netfilter_ipv4/ipt_IPMARK.h>
1904+
1905+MODULE_AUTHOR("Grzegorz Janoszka <Grzegorz.Janoszka@pro.onet.pl>");
1906+MODULE_DESCRIPTION("IP tables IPMARK: mark based on ip address");
1907+MODULE_LICENSE("GPL");
1908+
1909+static unsigned int
1910+target(struct sk_buff **pskb,
1911+ const struct net_device *in,
1912+ const struct net_device *out,
1913+ unsigned int hooknum,
1914+ const void *targinfo,
1915+ void *userinfo)
1916+{
1917+ const struct ipt_ipmark_target_info *ipmarkinfo = targinfo;
1918+ struct iphdr *iph = (*pskb)->nh.iph;
1919+ unsigned long mark;
1920+
1921+ if (ipmarkinfo->addr == IPT_IPMARK_SRC)
1922+ mark = (unsigned long) ntohl(iph->saddr);
1923+ else
1924+ mark = (unsigned long) ntohl(iph->daddr);
1925+
1926+ mark &= ipmarkinfo->andmask;
1927+ mark |= ipmarkinfo->ormask;
1928+
1929+ if ((*pskb)->nfmark != mark) {
1930+ (*pskb)->nfmark = mark;
1931+ (*pskb)->nfcache |= NFC_ALTERED;
1932+ }
1933+ return IPT_CONTINUE;
1934+}
1935+
1936+static int
1937+checkentry(const char *tablename,
1938+ const struct ipt_entry *e,
1939+ void *targinfo,
1940+ unsigned int targinfosize,
1941+ unsigned int hook_mask)
1942+{
1943+ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ipmark_target_info))) {
1944+ printk(KERN_WARNING "IPMARK: targinfosize %u != %Zu\n",
1945+ targinfosize,
1946+ IPT_ALIGN(sizeof(struct ipt_ipmark_target_info)));
1947+ return 0;
1948+ }
1949+
1950+ if (strcmp(tablename, "mangle") != 0) {
1951+ printk(KERN_WARNING "IPMARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1952+ return 0;
1953+ }
1954+
1955+ return 1;
1956+}
1957+
1958+static struct ipt_target ipt_ipmark_reg = {
1959+ .name = "IPMARK",
1960+ .target = target,
1961+ .checkentry = checkentry,
1962+ .me = THIS_MODULE
1963+};
1964+
1965+static int __init init(void)
1966+{
1967+ return ipt_register_target(&ipt_ipmark_reg);
1968+}
1969+
1970+static void __exit fini(void)
1971+{
1972+ ipt_unregister_target(&ipt_ipmark_reg);
1973+}
1974+
1975+module_init(init);
1976+module_exit(fini);
1977diff -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
1978--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_XOR.c 1970-01-01 00:00:00.000000000 +0000
1979+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_XOR.c 2004-03-16 12:04:18.000000000 +0000
1980@@ -0,0 +1,117 @@
1981+/* XOR target for IP tables
1982+ * (C) 2000 by Tim Vandermeersch <Tim.Vandermeersch@pandora.be>
1983+ * Based on ipt_TTL.c
1984+ *
1985+ * Version 1.0
1986+ *
1987+ * This software is distributed under the terms of GNU GPL
1988+ */
1989+
1990+#include <linux/module.h>
1991+#include <linux/skbuff.h>
1992+#include <linux/ip.h>
1993+#include <linux/tcp.h>
1994+#include <linux/udp.h>
1995+
1996+#include <linux/netfilter_ipv4/ip_tables.h>
1997+#include <linux/netfilter_ipv4/ipt_XOR.h>
1998+
1999+MODULE_AUTHOR("Tim Vandermeersch <Tim.Vandermeersch@pandora.be>");
2000+MODULE_DESCRIPTION("IP tables XOR module");
2001+MODULE_LICENSE("GPL");
2002+
2003+static unsigned int
2004+ipt_xor_target(struct sk_buff **pskb,
2005+ const struct net_device *in, const struct net_device *out,
2006+ unsigned int hooknum, const void *targinfo, void *userinfo)
2007+{
2008+ struct ipt_XOR_info *info = (void *) targinfo;
2009+ struct iphdr *iph;
2010+ struct tcphdr *tcph;
2011+ struct udphdr *udph;
2012+ int i, j, k;
2013+
2014+ if (!skb_ip_make_writable(pskb, (*pskb)->len))
2015+ return NF_DROP;
2016+
2017+ iph = (*pskb)->nh.iph;
2018+
2019+ if (iph->protocol == IPPROTO_TCP) {
2020+ tcph = (struct tcphdr *) ((*pskb)->data + iph->ihl*4);
2021+ for (i=0, j=0; i<(ntohs(iph->tot_len) - iph->ihl*4 - tcph->doff*4); ) {
2022+ for (k=0; k<=info->block_size; k++) {
2023+ (char) (*pskb)->data[ iph->ihl*4 + tcph->doff*4 + i ] ^=
2024+ info->key[j];
2025+ i++;
2026+ }
2027+ j++;
2028+ if (info->key[j] == 0x00)
2029+ j = 0;
2030+ }
2031+ } else if (iph->protocol == IPPROTO_UDP) {
2032+ udph = (struct udphdr *) ((*pskb)->data + iph->ihl*4);
2033+ for (i=0, j=0; i<(ntohs(udph->len)-8); ) {
2034+ for (k=0; k<=info->block_size; k++) {
2035+ (char) (*pskb)->data[ iph->ihl*4 + sizeof(struct udphdr) + i ] ^=
2036+ info->key[j];
2037+ i++;
2038+ }
2039+ j++;
2040+ if (info->key[j] == 0x00)
2041+ j = 0;
2042+ }
2043+ }
2044+
2045+ return IPT_CONTINUE;
2046+}
2047+
2048+static int ipt_xor_checkentry(const char *tablename, const struct ipt_entry *e,
2049+ void *targinfo, unsigned int targinfosize,
2050+ unsigned int hook_mask)
2051+{
2052+ struct ipt_XOR_info *info = targinfo;
2053+
2054+ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_XOR_info))) {
2055+ printk(KERN_WARNING "XOR: targinfosize %u != %Zu\n",
2056+ targinfosize, IPT_ALIGN(sizeof(struct ipt_XOR_info)));
2057+ return 0;
2058+ }
2059+
2060+ if (strcmp(tablename, "mangle")) {
2061+ printk(KERN_WARNING "XOR: can only be called from"
2062+ "\"mangle\" table, not \"%s\"\n", tablename);
2063+ return 0;
2064+ }
2065+
2066+ if (!strcmp(info->key, "")) {
2067+ printk(KERN_WARNING "XOR: You must specify a key");
2068+ return 0;
2069+ }
2070+
2071+ if (info->block_size == 0) {
2072+ printk(KERN_WARNING "XOR: You must specify a block-size");
2073+ return 0;
2074+ }
2075+
2076+ return 1;
2077+}
2078+
2079+static struct ipt_target ipt_XOR = {
2080+ .name = "XOR",
2081+ .target = ipt_xor_target,
2082+ .checkentry = ipt_xor_checkentry,
2083+ .me = THIS_MODULE,
2084+};
2085+
2086+static int __init init(void)
2087+{
2088+ return ipt_register_target(&ipt_XOR);
2089+}
2090+
2091+static void __exit fini(void)
2092+{
2093+ ipt_unregister_target(&ipt_XOR);
2094+}
2095+
2096+module_init(init);
2097+module_exit(fini);
2098diff -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
2099--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_addrtype.c 1970-01-01 00:00:00.000000000 +0000
2100+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_addrtype.c 2004-03-16 12:04:20.000000000 +0000
2101@@ -0,0 +1,68 @@
2102+/*
2103+ * iptables module to match inet_addr_type() of an ip.
2104+ */
2105+
2106+#include <linux/module.h>
2107+#include <linux/skbuff.h>
2108+#include <linux/netdevice.h>
2109+#include <net/route.h>
2110+
2111+#include <linux/netfilter_ipv4/ipt_addrtype.h>
2112+#include <linux/netfilter_ipv4/ip_tables.h>
2113+
2114+MODULE_LICENSE("GPL");
2115+
2116+static inline int match_type(u_int32_t addr, u_int16_t mask)
2117+{
2118+ return !!(mask & (1 << inet_addr_type(addr)));
2119+}
2120+
2121+static int match(const struct sk_buff *skb, const struct net_device *in,
2122+ const struct net_device *out, const void *matchinfo,
2123+ int offset, int *hotdrop)
2124+{
2125+ const struct ipt_addrtype_info *info = matchinfo;
2126+ const struct iphdr *iph = skb->nh.iph;
2127+ int ret = 1;
2128+
2129+ if (info->source)
2130+ ret &= match_type(iph->saddr, info->source)^info->invert_source;
2131+ if (info->dest)
2132+ ret &= match_type(iph->daddr, info->dest)^info->invert_dest;
2133+
2134+ return ret;
2135+}
2136+
2137+static int checkentry(const char *tablename, const struct ipt_ip *ip,
2138+ void *matchinfo, unsigned int matchsize,
2139+ unsigned int hook_mask)
2140+{
2141+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_addrtype_info))) {
2142+ printk(KERN_ERR "ipt_addrtype: invalid size (%u != %u)\n.",
2143+ matchsize, IPT_ALIGN(sizeof(struct ipt_addrtype_info)));
2144+ return 0;
2145+ }
2146+
2147+ return 1;
2148+}
2149+
2150+static struct ipt_match addrtype_match = {
2151+ .name = "addrtype",
2152+ .match = match,
2153+ .checkentry = checkentry,
2154+ .me = THIS_MODULE
2155+};
2156+
2157+static int __init init(void)
2158+{
2159+ return ipt_register_match(&addrtype_match);
2160+}
2161+
2162+static void __exit fini(void)
2163+{
2164+ ipt_unregister_match(&addrtype_match);
2165+
2166+}
2167+
2168+module_init(init);
2169+module_exit(fini);
2170diff -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
2171--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_connmark.c 1970-01-01 00:00:00.000000000 +0000
2172+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_connmark.c 2004-03-16 12:04:09.000000000 +0000
2173@@ -0,0 +1,81 @@
2174+/* This kernel module matches connection mark values set by the
2175+ * CONNMARK target
2176+ *
2177+ * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
2178+ * by Henrik Nordstrom <hno@marasystems.com>
2179+ *
2180+ * This program is free software; you can redistribute it and/or modify
2181+ * it under the terms of the GNU General Public License as published by
2182+ * the Free Software Foundation; either version 2 of the License, or
2183+ * (at your option) any later version.
2184+ *
2185+ * This program is distributed in the hope that it will be useful,
2186+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2187+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2188+ * GNU General Public License for more details.
2189+ *
2190+ * You should have received a copy of the GNU General Public License
2191+ * along with this program; if not, write to the Free Software
2192+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2193+ */
2194+
2195+#include <linux/module.h>
2196+#include <linux/skbuff.h>
2197+
2198+MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
2199+MODULE_DESCRIPTION("IP tables connmark match module");
2200+MODULE_LICENSE("GPL");
2201+
2202+#include <linux/netfilter_ipv4/ip_tables.h>
2203+#include <linux/netfilter_ipv4/ipt_connmark.h>
2204+#include <linux/netfilter_ipv4/ip_conntrack.h>
2205+
2206+static int
2207+match(const struct sk_buff *skb,
2208+ const struct net_device *in,
2209+ const struct net_device *out,
2210+ const void *matchinfo,
2211+ int offset,
2212+ int *hotdrop)
2213+{
2214+ const struct ipt_connmark_info *info = matchinfo;
2215+ enum ip_conntrack_info ctinfo;
2216+ struct ip_conntrack *ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
2217+ if (!ct)
2218+ return 0;
2219+
2220+ return ((ct->mark & info->mask) == info->mark) ^ info->invert;
2221+}
2222+
2223+static int
2224+checkentry(const char *tablename,
2225+ const struct ipt_ip *ip,
2226+ void *matchinfo,
2227+ unsigned int matchsize,
2228+ unsigned int hook_mask)
2229+{
2230+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_connmark_info)))
2231+ return 0;
2232+
2233+ return 1;
2234+}
2235+
2236+static struct ipt_match connmark_match = {
2237+ .name = "connmark",
2238+ .match = &match,
2239+ .checkentry = &checkentry,
2240+ .me = THIS_MODULE
2241+};
2242+
2243+static int __init init(void)
2244+{
2245+ return ipt_register_match(&connmark_match);
2246+}
2247+
2248+static void __exit fini(void)
2249+{
2250+ ipt_unregister_match(&connmark_match);
2251+}
2252+
2253+module_init(init);
2254+module_exit(fini);
2255diff -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
2256--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_owner.c 2004-03-16 05:47:19.000000000 +0000
2257+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_owner.c 2004-03-16 12:04:38.000000000 +0000
2258@@ -6,12 +6,19 @@
2259 * This program is free software; you can redistribute it and/or modify
2260 * it under the terms of the GNU General Public License version 2 as
2261 * published by the Free Software Foundation.
2262+ *
2263+ * 03/26/2003 Patrick McHardy <kaber@trash.net> : LOCAL_IN support
2264 */
2265
2266 #include <linux/module.h>
2267 #include <linux/skbuff.h>
2268 #include <linux/file.h>
2269+#include <linux/ip.h>
2270+#include <linux/tcp.h>
2271+#include <linux/udp.h>
2272 #include <net/sock.h>
2273+#include <net/tcp.h>
2274+#include <net/udp.h>
2275
2276 #include <linux/netfilter_ipv4/ipt_owner.h>
2277 #include <linux/netfilter_ipv4/ip_tables.h>
2278@@ -21,7 +28,7 @@
2279 MODULE_DESCRIPTION("iptables owner match");
2280
2281 static int
2282-match_comm(const struct sk_buff *skb, const char *comm)
2283+match_comm(const struct sock *sk, const char *comm)
2284 {
2285 struct task_struct *g, *p;
2286 struct files_struct *files;
2287@@ -38,7 +45,7 @@
2288 spin_lock(&files->file_lock);
2289 for (i=0; i < files->max_fds; i++) {
2290 if (fcheck_files(files, i) ==
2291- skb->sk->sk_socket->file) {
2292+ sk->sk_socket->file) {
2293 spin_unlock(&files->file_lock);
2294 task_unlock(p);
2295 read_unlock(&tasklist_lock);
2296@@ -54,7 +61,7 @@
2297 }
2298
2299 static int
2300-match_pid(const struct sk_buff *skb, pid_t pid)
2301+match_pid(const struct sock *sk, pid_t pid)
2302 {
2303 struct task_struct *p;
2304 struct files_struct *files;
2305@@ -70,7 +77,7 @@
2306 spin_lock(&files->file_lock);
2307 for (i=0; i < files->max_fds; i++) {
2308 if (fcheck_files(files, i) ==
2309- skb->sk->sk_socket->file) {
2310+ sk->sk_socket->file) {
2311 spin_unlock(&files->file_lock);
2312 task_unlock(p);
2313 read_unlock(&tasklist_lock);
2314@@ -86,10 +93,10 @@
2315 }
2316
2317 static int
2318-match_sid(const struct sk_buff *skb, pid_t sid)
2319+match_sid(const struct sock *sk, pid_t sid)
2320 {
2321 struct task_struct *g, *p;
2322- struct file *file = skb->sk->sk_socket->file;
2323+ struct file *file = sk->sk_socket->file;
2324 int i, found=0;
2325
2326 read_lock(&tasklist_lock);
2327@@ -129,41 +136,71 @@
2328 int *hotdrop)
2329 {
2330 const struct ipt_owner_info *info = matchinfo;
2331+ struct iphdr *iph = skb->nh.iph;
2332+ struct sock *sk = NULL;
2333+ int ret = 0;
2334+
2335+ if (out) {
2336+ sk = skb->sk;
2337+ } else {
2338+ if (iph->protocol == IPPROTO_TCP) {
2339+ struct tcphdr *tcph =
2340+ (struct tcphdr *)((u_int32_t *)iph + iph->ihl);
2341+ sk = tcp_v4_lookup(iph->saddr, tcph->source,
2342+ iph->daddr, tcph->dest,
2343+ skb->dev->ifindex);
2344+ if (sk && sk->sk_state == TCP_TIME_WAIT) {
2345+ tcp_tw_put((struct tcp_tw_bucket *)sk);
2346+ return ret;
2347+ }
2348+ } else if (iph->protocol == IPPROTO_UDP) {
2349+ struct udphdr *udph =
2350+ (struct udphdr *)((u_int32_t *)iph + iph->ihl);
2351+ sk = udp_v4_lookup(iph->saddr, udph->source, iph->daddr,
2352+ udph->dest, skb->dev->ifindex);
2353+ }
2354+ }
2355
2356- if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
2357- return 0;
2358+ if (!sk || !sk->sk_socket || !sk->sk_socket->file)
2359+ goto out;
2360
2361 if(info->match & IPT_OWNER_UID) {
2362- if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
2363+ if ((sk->sk_socket->file->f_uid != info->uid) ^
2364 !!(info->invert & IPT_OWNER_UID))
2365- return 0;
2366+ goto out;
2367 }
2368
2369 if(info->match & IPT_OWNER_GID) {
2370- if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
2371+ if ((sk->sk_socket->file->f_gid != info->gid) ^
2372 !!(info->invert & IPT_OWNER_GID))
2373- return 0;
2374+ goto out;
2375 }
2376
2377 if(info->match & IPT_OWNER_PID) {
2378- if (!match_pid(skb, info->pid) ^
2379+ if (!match_pid(sk, info->pid) ^
2380 !!(info->invert & IPT_OWNER_PID))
2381- return 0;
2382+ goto out;
2383 }
2384
2385 if(info->match & IPT_OWNER_SID) {
2386- if (!match_sid(skb, info->sid) ^
2387+ if (!match_sid(sk, info->sid) ^
2388 !!(info->invert & IPT_OWNER_SID))
2389- return 0;
2390+ goto out;
2391 }
2392
2393 if(info->match & IPT_OWNER_COMM) {
2394- if (!match_comm(skb, info->comm) ^
2395+ if (!match_comm(sk, info->comm) ^
2396 !!(info->invert & IPT_OWNER_COMM))
2397- return 0;
2398+ goto out;
2399 }
2400
2401- return 1;
2402+ ret = 1;
2403+
2404+out:
2405+ if (in && sk)
2406+ sock_put(sk);
2407+
2408+ return ret;
2409 }
2410
2411 static int
2412@@ -173,11 +210,19 @@
2413 unsigned int matchsize,
2414 unsigned int hook_mask)
2415 {
2416- if (hook_mask
2417- & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING))) {
2418- printk("ipt_owner: only valid for LOCAL_OUT or POST_ROUTING.\n");
2419- return 0;
2420- }
2421+ if (hook_mask
2422+ & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING) |
2423+ (1 << NF_IP_LOCAL_IN))) {
2424+ printk("ipt_owner: only valid for LOCAL_IN, LOCAL_OUT "
2425+ "or POST_ROUTING.\n");
2426+ return 0;
2427+ }
2428+
2429+ if ((hook_mask & (1 << NF_IP_LOCAL_IN))
2430+ && ip->proto != IPPROTO_TCP && ip->proto != IPPROTO_UDP) {
2431+ printk("ipt_owner: only TCP or UDP can be used in LOCAL_IN\n");
2432+ return 0;
2433+ }
2434
2435 if (matchsize != IPT_ALIGN(sizeof(struct ipt_owner_info))) {
2436 printk("Matchsize %u != %Zu\n", matchsize,
2437diff -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
2438--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_policy.c 1970-01-01 00:00:00.000000000 +0000
2439+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_policy.c 2004-03-16 12:04:45.000000000 +0000
2440@@ -0,0 +1,176 @@
2441+/* IP tables module for matching IPsec policy
2442+ *
2443+ * Copyright (c) 2004 Patrick McHardy, <kaber@trash.net>
2444+ *
2445+ * This program is free software; you can redistribute it and/or modify
2446+ * it under the terms of the GNU General Public License version 2 as
2447+ * published by the Free Software Foundation.
2448+ */
2449+
2450+#include <linux/kernel.h>
2451+#include <linux/config.h>
2452+#include <linux/module.h>
2453+#include <linux/skbuff.h>
2454+#include <linux/init.h>
2455+#include <net/xfrm.h>
2456+
2457+#include <linux/netfilter_ipv4.h>
2458+#include <linux/netfilter_ipv4/ipt_policy.h>
2459+#include <linux/netfilter_ipv4/ip_tables.h>
2460+
2461+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
2462+MODULE_DESCRIPTION("IPtables IPsec policy matching module");
2463+MODULE_LICENSE("GPL");
2464+
2465+
2466+static inline int
2467+match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e)
2468+{
2469+#define MISMATCH(x,y) (e->match.x && ((e->x != (y)) ^ e->invert.x))
2470+
2471+ if (MISMATCH(saddr, x->props.saddr.a4 & e->smask) ||
2472+ MISMATCH(daddr, x->id.daddr.a4 & e->dmask) ||
2473+ MISMATCH(proto, x->id.proto) ||
2474+ MISMATCH(mode, x->props.mode) ||
2475+ MISMATCH(spi, x->id.spi) ||
2476+ MISMATCH(reqid, x->props.reqid))
2477+ return 0;
2478+ return 1;
2479+}
2480+
2481+static int
2482+match_policy_in(const struct sk_buff *skb, const struct ipt_policy_info *info)
2483+{
2484+ const struct ipt_policy_elem *e;
2485+ struct sec_path *sp = skb->sp;
2486+ int strict = info->flags & POLICY_MATCH_STRICT;
2487+ int i, pos;
2488+
2489+ if (sp == NULL)
2490+ return -1;
2491+ if (strict && info->len != sp->len)
2492+ return 0;
2493+
2494+ for (i = sp->len - 1; i >= 0; i--) {
2495+ pos = strict ? i - sp->len + 1 : 0;
2496+ if (pos >= info->len)
2497+ return 0;
2498+ e = &info->pol[pos];
2499+
2500+ if (match_xfrm_state(sp->x[i].xvec, e)) {
2501+ if (!strict)
2502+ return 1;
2503+ } else if (strict)
2504+ return 0;
2505+ }
2506+
2507+ return strict ? 1 : 0;
2508+}
2509+
2510+static int
2511+match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info)
2512+{
2513+ const struct ipt_policy_elem *e;
2514+ struct dst_entry *dst = skb->dst;
2515+ int strict = info->flags & POLICY_MATCH_STRICT;
2516+ int i, pos;
2517+
2518+ if (dst->xfrm == NULL)
2519+ return -1;
2520+
2521+ for (i = 0; dst && dst->xfrm; dst = dst->child, i++) {
2522+ pos = strict ? i : 0;
2523+ if (pos >= info->len)
2524+ return 0;
2525+ e = &info->pol[pos];
2526+
2527+ if (match_xfrm_state(dst->xfrm, e)) {
2528+ if (!strict)
2529+ return 1;
2530+ } else if (strict)
2531+ return 0;
2532+ }
2533+
2534+ return strict ? 1 : 0;
2535+}
2536+
2537+static int match(const struct sk_buff *skb,
2538+ const struct net_device *in,
2539+ const struct net_device *out,
2540+ const void *matchinfo, int offset, int *hotdrop)
2541+{
2542+ const struct ipt_policy_info *info = matchinfo;
2543+ int ret;
2544+
2545+ if (info->flags & POLICY_MATCH_IN)
2546+ ret = match_policy_in(skb, info);
2547+ else
2548+ ret = match_policy_out(skb, info);
2549+
2550+ if (ret < 0) {
2551+ if (info->flags & POLICY_MATCH_NONE)
2552+ ret = 1;
2553+ else
2554+ ret = 0;
2555+ } else if (info->flags & POLICY_MATCH_NONE)
2556+ ret = 0;
2557+
2558+ return ret;
2559+}
2560+
2561+static int checkentry(const char *tablename, const struct ipt_ip *ip,
2562+ void *matchinfo, unsigned int matchsize,
2563+ unsigned int hook_mask)
2564+{
2565+ struct ipt_policy_info *info = matchinfo;
2566+
2567+ if (matchsize != IPT_ALIGN(sizeof(*info))) {
2568+ printk(KERN_ERR "ipt_policy: matchsize %u != %u\n",
2569+ matchsize, IPT_ALIGN(sizeof(*info)));
2570+ return 0;
2571+ }
2572+ if (!(info->flags & (POLICY_MATCH_IN|POLICY_MATCH_OUT))) {
2573+ printk(KERN_ERR "ipt_policy: neither incoming nor "
2574+ "outgoing policy selected\n");
2575+ return 0;
2576+ }
2577+ if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
2578+ && info->flags & POLICY_MATCH_OUT) {
2579+ printk(KERN_ERR "ipt_policy: output policy not valid in "
2580+ "PRE_ROUTING and INPUT\n");
2581+ return 0;
2582+ }
2583+ if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
2584+ && info->flags & POLICY_MATCH_IN) {
2585+ printk(KERN_ERR "ipt_policy: input policy not valid in "
2586+ "POST_ROUTING and OUTPUT\n");
2587+ return 0;
2588+ }
2589+ if (info->len > POLICY_MAX_ELEM) {
2590+ printk(KERN_ERR "ipt_policy: too many policy elements\n");
2591+ return 0;
2592+ }
2593+
2594+ return 1;
2595+}
2596+
2597+static struct ipt_match policy_match =
2598+{
2599+ .name = "policy",
2600+ .match = match,
2601+ .checkentry = checkentry,
2602+ .me = THIS_MODULE,
2603+};
2604+
2605+static int __init init(void)
2606+{
2607+ return ipt_register_match(&policy_match);
2608+}
2609+
2610+static void __exit fini(void)
2611+{
2612+ ipt_unregister_match(&policy_match);
2613+}
2614+
2615+module_init(init);
2616+module_exit(fini);
2617diff -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
2618--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_rpc.c 1970-01-01 00:00:00.000000000 +0000
2619+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_rpc.c 2004-03-16 12:04:46.000000000 +0000
2620@@ -0,0 +1,428 @@
2621+/* RPC extension for IP connection matching, Version 2.2
2622+ * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
2623+ * - original rpc tracking module
2624+ * - "recent" connection handling for kernel 2.3+ netfilter
2625+ *
2626+ * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
2627+ * - upgraded conntrack modules to oldnat api - kernel 2.4.0+
2628+ *
2629+ * (C) 2002,2003 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
2630+ * - upgraded conntrack modules to newnat api - kernel 2.4.20+
2631+ * - extended matching to support filtering on procedures
2632+ *
2633+ * ipt_rpc.c,v 2.2 2003/01/12 18:30:00
2634+ *
2635+ * This program is free software; you can redistribute it and/or
2636+ * modify it under the terms of the GNU General Public License
2637+ * as published by the Free Software Foundation; either version
2638+ * 2 of the License, or (at your option) any later version.
2639+ **
2640+ * Module load syntax:
2641+ * insmod ipt_rpc.o ports=port1,port2,...port<MAX_PORTS>
2642+ *
2643+ * Please give the ports of all RPC servers you wish to connect to.
2644+ * If you don't specify ports, the default will be port 111.
2645+ **
2646+ * Note to all:
2647+ *
2648+ * RPCs should not be exposed to the internet - ask the Pentagon;
2649+ *
2650+ * "The unidentified crackers pleaded guilty in July to charges
2651+ * of juvenile delinquency stemming from a string of Pentagon
2652+ * network intrusions in February.
2653+ *
2654+ * The youths, going by the names TooShort and Makaveli, used
2655+ * a common server security hole to break in, according to
2656+ * Dane Jasper, owner of the California Internet service
2657+ * provider, Sonic. They used the hole, known as the 'statd'
2658+ * exploit, to attempt more than 800 break-ins, Jasper said."
2659+ *
2660+ * From: Wired News; "Pentagon Kids Kicked Off Grid" - Nov 6, 1998
2661+ * URL: http://www.wired.com/news/politics/0,1283,16098,00.html
2662+ **
2663+ */
2664+
2665+#include <linux/module.h>
2666+#include <linux/skbuff.h>
2667+#include <linux/list.h>
2668+#include <linux/udp.h>
2669+#include <linux/tcp.h>
2670+#include <linux/netfilter_ipv4/ip_conntrack.h>
2671+#include <linux/netfilter_ipv4/ip_tables.h>
2672+#include <linux/netfilter_ipv4/ip_conntrack_rpc.h>
2673+#include <linux/netfilter_ipv4/lockhelp.h>
2674+#include <linux/netfilter_ipv4/ipt_rpc.h>
2675+
2676+#define MAX_PORTS 8
2677+static int ports[MAX_PORTS];
2678+static int ports_n_c = 0;
2679+
2680+#ifdef MODULE_PARM
2681+MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
2682+MODULE_PARM_DESC(ports, "port numbers (TCP/UDP) of RPC portmapper servers");
2683+#endif
2684+
2685+MODULE_AUTHOR("Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>");
2686+MODULE_DESCRIPTION("RPC connection matching module");
2687+MODULE_LICENSE("GPL");
2688+
2689+#if 0
2690+#define DEBUGP(format, args...) printk(KERN_DEBUG "ipt_rpc: " \
2691+ format, ## args)
2692+#else
2693+#define DEBUGP(format, args...)
2694+#endif
2695+
2696+EXPORT_NO_SYMBOLS;
2697+
2698+/* vars from ip_conntrack_rpc_tcp */
2699+extern struct list_head request_p_list_tcp;
2700+extern struct module *ip_conntrack_rpc_tcp;
2701+
2702+/* vars from ip_conntrack_rpc_udp */
2703+extern struct list_head request_p_list_udp;
2704+extern struct module *ip_conntrack_rpc_udp;
2705+
2706+DECLARE_RWLOCK_EXTERN(ipct_rpc_tcp_lock);
2707+DECLARE_RWLOCK_EXTERN(ipct_rpc_udp_lock);
2708+
2709+#define ASSERT_READ_LOCK(x) \
2710+do { \
2711+ if (x == &request_p_list_udp) \
2712+ MUST_BE_READ_LOCKED(&ipct_rpc_udp_lock); \
2713+ else if (x == &request_p_list_tcp) \
2714+ MUST_BE_READ_LOCKED(&ipct_rpc_tcp_lock); \
2715+} while (0)
2716+
2717+#define ASSERT_WRITE_LOCK(x) \
2718+do { \
2719+ if (x == &request_p_list_udp) \
2720+ MUST_BE_WRITE_LOCKED(&ipct_rpc_udp_lock); \
2721+ else if (x == &request_p_list_tcp) \
2722+ MUST_BE_WRITE_LOCKED(&ipct_rpc_tcp_lock); \
2723+} while (0)
2724+
2725+#include <linux/netfilter_ipv4/listhelp.h>
2726+
2727+const int IPT_RPC_CHAR_LEN = 11;
2728+
2729+
2730+static int k_atoi(char *string)
2731+{
2732+ unsigned int result = 0;
2733+ int maxoctet = IPT_RPC_CHAR_LEN;
2734+
2735+ for ( ; *string != 0 && maxoctet != 0; maxoctet--, string++) {
2736+ if (*string < 0)
2737+ return(0);
2738+ if (*string == 0)
2739+ break;
2740+ if (*string < 48 || *string > 57) {
2741+ return(0);
2742+ }
2743+ result = result * 10 + ( *string - 48 );
2744+ }
2745+ return(result);
2746+}
2747+
2748+
2749+static int match_rpcs(char *c_procs, int i_procs, int proc)
2750+{
2751+ int proc_ctr;
2752+ char *proc_ptr;
2753+ unsigned int proc_num;
2754+
2755+ DEBUGP("entered match_rpcs [%i] [%i] ..\n", i_procs, proc);
2756+
2757+ if (i_procs == -1)
2758+ return 1;
2759+
2760+ for (proc_ctr=0; proc_ctr <= i_procs; proc_ctr++) {
2761+
2762+ proc_ptr = c_procs;
2763+ proc_ptr += proc_ctr * IPT_RPC_CHAR_LEN;
2764+ proc_num = k_atoi(proc_ptr);
2765+
2766+ if (proc_num == proc)
2767+ return 1;
2768+ }
2769+
2770+ return 0;
2771+}
2772+
2773+
2774+static int check_rpc_packet(const u_int32_t *data, const void *matchinfo,
2775+ int *hotdrop, int dir, struct ip_conntrack *ct,
2776+ int offset, struct list_head request_p_list)
2777+{
2778+ const struct ipt_rpc_info *rpcinfo = matchinfo;
2779+ struct request_p *req_p;
2780+ u_int32_t xid;
2781+
2782+
2783+ /* Get XID */
2784+ xid = *data;
2785+
2786+ /* This does sanity checking on RPC payloads,
2787+ * and permits only the RPC "get port" (3)
2788+ * in authorised procedures in client
2789+ * communications with the portmapper.
2790+ */
2791+
2792+ data += 5;
2793+
2794+ /* Get RPC requestor */
2795+ if (IXDR_GET_INT32(data) != 3) {
2796+ DEBUGP("RPC packet contains an invalid (non \"get\") requestor. [skip]\n");
2797+ if(rpcinfo->strict == 1)
2798+ *hotdrop = 1;
2799+ return 0;
2800+ }
2801+ DEBUGP("RPC packet contains a \"get\" requestor. [cont]\n");
2802+
2803+ data++;
2804+
2805+ /* Jump Credentials and Verfifier */
2806+ data = data + IXDR_GET_INT32(data) + 2;
2807+ data = data + IXDR_GET_INT32(data) + 2;
2808+
2809+ /* Get RPC procedure */
2810+ if (match_rpcs((char *)&rpcinfo->c_procs,
2811+ rpcinfo->i_procs, IXDR_GET_INT32(data)) == 0) {
2812+ DEBUGP("RPC packet contains illegal procedure request [%u]. [drop]\n",
2813+ (unsigned int)IXDR_GET_INT32(data));
2814+
2815+ /* If the RPC conntrack half entry already exists .. */
2816+
2817+ switch (ct->tuplehash[0].tuple.dst.protonum) {
2818+ case IPPROTO_UDP:
2819+ WRITE_LOCK(&ipct_rpc_udp_lock);
2820+ case IPPROTO_TCP:
2821+ WRITE_LOCK(&ipct_rpc_tcp_lock);
2822+ }
2823+ req_p = LIST_FIND(&request_p_list, request_p_cmp,
2824+ struct request_p *, xid,
2825+ ct->tuplehash[dir].tuple.src.ip,
2826+ ct->tuplehash[dir].tuple.src.u.all);
2827+
2828+ if (req_p) {
2829+ DEBUGP("found req_p for xid=%u proto=%u %u.%u.%u.%u:%u\n",
2830+ xid, ct->tuplehash[dir].tuple.dst.protonum,
2831+ NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
2832+ ntohs(ct->tuplehash[dir].tuple.src.u.all));
2833+
2834+ /* .. remove it */
2835+ if (del_timer(&req_p->timeout))
2836+ req_p->timeout.expires = 0;
2837+
2838+ LIST_DELETE(&request_p_list, req_p);
2839+ DEBUGP("RPC req_p removed. [done]\n");
2840+
2841+ } else {
2842+ DEBUGP("no req_p found for xid=%u proto=%u %u.%u.%u.%u:%u\n",
2843+ xid, ct->tuplehash[dir].tuple.dst.protonum,
2844+ NIPQUAD(ct->tuplehash[dir].tuple.src.ip),
2845+ ntohs(ct->tuplehash[dir].tuple.src.u.all));
2846+
2847+ }
2848+ switch (ct->tuplehash[0].tuple.dst.protonum) {
2849+ case IPPROTO_UDP:
2850+ WRITE_UNLOCK(&ipct_rpc_udp_lock);
2851+ case IPPROTO_TCP:
2852+ WRITE_UNLOCK(&ipct_rpc_tcp_lock);
2853+ }
2854+
2855+ if(rpcinfo->strict == 1)
2856+ *hotdrop = 1;
2857+ return 0;
2858+ }
2859+
2860+ DEBUGP("RPC packet contains authorised procedure request [%u]. [match]\n",
2861+ (unsigned int)IXDR_GET_INT32(data));
2862+ return (1 && (!offset));
2863+}
2864+
2865+
2866+static int match(const struct sk_buff *skb, const struct net_device *in,
2867+ const struct net_device *out, const void *matchinfo,
2868+ int offset, const void *hdr, u_int16_t datalen, int *hotdrop)
2869+{
2870+ struct ip_conntrack *ct;
2871+ enum ip_conntrack_info ctinfo;
2872+ const u_int32_t *data;
2873+ enum ip_conntrack_dir dir;
2874+ const struct tcphdr *tcp;
2875+ const struct ipt_rpc_info *rpcinfo = matchinfo;
2876+ int port, portsok;
2877+ int tval;
2878+
2879+
2880+ DEBUGP("new packet to evaluate ..\n");
2881+
2882+ ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
2883+ if (!ct) {
2884+ DEBUGP("no ct available [skip]\n");
2885+ return 0;
2886+ }
2887+
2888+ DEBUGP("ct detected. [cont]\n");
2889+ dir = CTINFO2DIR(ctinfo);
2890+
2891+ /* we only want the client to server packets for matching */
2892+ if (dir != IP_CT_DIR_ORIGINAL)
2893+ return 0;
2894+
2895+ /* This does sanity checking on UDP or TCP packets,
2896+ * like their respective modules.
2897+ */
2898+
2899+ switch (ct->tuplehash[0].tuple.dst.protonum) {
2900+
2901+ case IPPROTO_UDP:
2902+ DEBUGP("PROTO_UDP [cont]\n");
2903+ if (offset == 0 && datalen < sizeof(struct udphdr)) {
2904+ DEBUGP("packet does not contain a complete header. [drop]\n");
2905+ return 0;
2906+ }
2907+
2908+ for (port=0,portsok=0; port <= ports_n_c; port++) {
2909+ if (ntohs(ct->tuplehash[dir].tuple.dst.u.all) == ports[port]) {
2910+ portsok++;
2911+ break;
2912+ }
2913+ }
2914+ if (portsok == 0) {
2915+ DEBUGP("packet is not destined for a portmapper [%u]. [skip]\n",
2916+ ntohs(ct->tuplehash[dir].tuple.dst.u.all));
2917+ return 0;
2918+ }
2919+
2920+ if ((datalen - sizeof(struct udphdr)) != 56) {
2921+ DEBUGP("packet length is not correct for RPC content. [skip]\n");
2922+ if (rpcinfo->strict == 1)
2923+ *hotdrop = 1;
2924+ return 0;
2925+ }
2926+ DEBUGP("packet length is correct. [cont]\n");
2927+
2928+ /* Get to the data */
2929+ data = (const u_int32_t *)hdr + 2;
2930+
2931+ /* Check the RPC data */
2932+ tval = check_rpc_packet(data, matchinfo, hotdrop,
2933+ dir, ct, offset,
2934+ request_p_list_udp);
2935+
2936+ return tval;
2937+
2938+
2939+ case IPPROTO_TCP:
2940+ DEBUGP("PROTO_TCP [cont]\n");
2941+ if (offset == 0 && datalen < sizeof(struct tcphdr)) {
2942+ DEBUGP("packet does not contain a complete header. [drop]\n");
2943+ return 0;
2944+ }
2945+
2946+ for (port=0,portsok=0; port <= ports_n_c; port++) {
2947+ if (ntohs(ct->tuplehash[dir].tuple.dst.u.all) == ports[port]) {
2948+ portsok++;
2949+ break;
2950+ }
2951+ }
2952+ if (portsok == 0) {
2953+ DEBUGP("packet is not destined for a portmapper [%u]. [skip]\n",
2954+ ntohs(ct->tuplehash[dir].tuple.dst.u.all));
2955+ return 0;
2956+ }
2957+
2958+ tcp = hdr;
2959+ if (datalen == (tcp->doff * 4)) {
2960+ DEBUGP("packet does not contain any data. [match]\n");
2961+ return (1 && (!offset));
2962+ }
2963+
2964+ /* Tests if packet len is ok */
2965+ if ((datalen - (tcp->doff * 4)) != 60) {
2966+ DEBUGP("packet length is not correct for RPC content. [skip]\n");
2967+ if(rpcinfo->strict == 1)
2968+ *hotdrop = 1;
2969+ return 0;
2970+ }
2971+ DEBUGP("packet length is correct. [cont]\n");
2972+
2973+ /* Get to the data */
2974+ data = (const u_int32_t *)tcp + tcp->doff + 1;
2975+
2976+ /* Check the RPC data */
2977+ tval = check_rpc_packet(data, matchinfo, hotdrop,
2978+ dir, ct, offset,
2979+ request_p_list_tcp);
2980+
2981+ return tval;
2982+
2983+ }
2984+
2985+ DEBUGP("transport protocol=%u, is not supported [skip]\n",
2986+ ct->tuplehash[0].tuple.dst.protonum);
2987+ return 0;
2988+}
2989+
2990+
2991+static int checkentry(const char *tablename, const struct ipt_ip *ip, void *matchinfo,
2992+ unsigned int matchsize, unsigned int hook_mask)
2993+{
2994+ if (hook_mask
2995+ & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_FORWARD) | (1 << NF_IP_POST_ROUTING)
2996+ | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_LOCAL_OUT))) {
2997+ printk("ipt_rpc: only valid for PRE_ROUTING, FORWARD, POST_ROUTING, LOCAL_IN and/or LOCAL_OUT targets.\n");
2998+ return 0;
2999+ }
3000+
3001+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_rpc_info)))
3002+ return 0;
3003+
3004+ return 1;
3005+}
3006+
3007+
3008+static struct ipt_match rpc_match = { { NULL, NULL }, "rpc",
3009+ &match, &checkentry, NULL,
3010+ THIS_MODULE };
3011+
3012+
3013+static int __init init(void)
3014+{
3015+ int port;
3016+
3017+ DEBUGP("incrementing usage counts\n");
3018+ __MOD_INC_USE_COUNT(ip_conntrack_rpc_udp);
3019+ __MOD_INC_USE_COUNT(ip_conntrack_rpc_tcp);
3020+
3021+ /* If no port given, default to standard RPC port */
3022+ if (ports[0] == 0)
3023+ ports[0] = RPC_PORT;
3024+
3025+ DEBUGP("registering match [%s] for;\n", rpc_match.name);
3026+ for (port = 0; (port < MAX_PORTS) && ports[port]; port++) {
3027+ DEBUGP(" port %i (UDP|TCP);\n", ports[port]);
3028+ ports_n_c++;
3029+ }
3030+
3031+ return ipt_register_match(&rpc_match);
3032+}
3033+
3034+
3035+static void fini(void)
3036+{
3037+ DEBUGP("unregistering match\n");
3038+ ipt_unregister_match(&rpc_match);
3039+
3040+ DEBUGP("decrementing usage counts\n");
3041+ __MOD_DEC_USE_COUNT(ip_conntrack_rpc_tcp);
3042+ __MOD_DEC_USE_COUNT(ip_conntrack_rpc_udp);
3043+}
3044+
3045+
3046+module_init(init);
3047+module_exit(fini);
3048+
3049diff -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
3050--- linux-2.6.5-rc1.org/net/ipv4/netfilter/ipt_string.c 1970-01-01 00:00:00.000000000 +0000
3051+++ linux-2.6.5-rc1/net/ipv4/netfilter/ipt_string.c 2004-03-16 12:06:26.000000000 +0000
fcbdbef7 3052@@ -0,0 +1,220 @@
5283140c 3053+/* Kernel module to match a string into a packet.
3054+ *
3055+ * Copyright (C) 2000 Emmanuel Roger <winfield@freegates.be>
3056+ *
3057+ * ChangeLog
3058+ * 19.02.2002: Gianni Tedesco <gianni@ecsc.co.uk>
3059+ * Fixed SMP re-entrancy problem using per-cpu data areas
3060+ * for the skip/shift tables.
3061+ * 02.05.2001: Gianni Tedesco <gianni@ecsc.co.uk>
3062+ * Fixed kernel panic, due to overrunning boyer moore string
3063+ * tables. Also slightly tweaked heuristic for deciding what
3064+ * search algo to use.
3065+ * 27.01.2001: Gianni Tedesco <gianni@ecsc.co.uk>
3066+ * Implemented Boyer Moore Sublinear search algorithm
3067+ * alongside the existing linear search based on memcmp().
3068+ * Also a quick check to decide which method to use on a per
3069+ * packet basis.
3070+ */
3071+
3072+#include <linux/smp.h>
3073+#include <linux/module.h>
3074+#include <linux/skbuff.h>
3075+#include <linux/file.h>
3076+#include <net/sock.h>
3077+
3078+#include <linux/netfilter_ipv4/ip_tables.h>
3079+#include <linux/netfilter_ipv4/ipt_string.h>
3080+
3081+MODULE_LICENSE("GPL");
3082+
3083+struct string_per_cpu {
3084+ int *skip;
3085+ int *shift;
3086+ int *len;
3087+};
3088+
3089+struct string_per_cpu *bm_string_data=NULL;
3090+
fcbdbef7 3091+int smp_num_cpus = 1;
3092+
5283140c 3093+/* Boyer Moore Sublinear string search - VERY FAST */
3094+char *search_sublinear (char *needle, char *haystack, int needle_len, int haystack_len)
3095+{
3096+ int M1, right_end, sk, sh;
3097+ int ended, j, i;
3098+
3099+ int *skip, *shift, *len;
3100+
3101+ /* use data suitable for this CPU */
3102+ shift=bm_string_data[smp_processor_id()].shift;
3103+ skip=bm_string_data[smp_processor_id()].skip;
3104+ len=bm_string_data[smp_processor_id()].len;
3105+
3106+ /* Setup skip/shift tables */
3107+ M1 = right_end = needle_len-1;
3108+ for (i = 0; i < BM_MAX_HLEN; i++) skip[i] = needle_len;
3109+ for (i = 0; needle[i]; i++) skip[needle[i]] = M1 - i;
3110+
3111+ for (i = 1; i < needle_len; i++) {
3112+ for (j = 0; j < needle_len && needle[M1 - j] == needle[M1 - i - j]; j++);
3113+ len[i] = j;
3114+ }
3115+
3116+ shift[0] = 1;
3117+ for (i = 1; i < needle_len; i++) shift[i] = needle_len;
3118+ for (i = M1; i > 0; i--) shift[len[i]] = i;
3119+ ended = 0;
3120+
3121+ for (i = 0; i < needle_len; i++) {
3122+ if (len[i] == M1 - i) ended = i;
3123+ if (ended) shift[i] = ended;
3124+ }
3125+
3126+ /* Do the search*/
3127+ while (right_end < haystack_len)
3128+ {
3129+ for (i = 0; i < needle_len && haystack[right_end - i] == needle[M1 - i]; i++);
3130+ if (i == needle_len) {
3131+ return haystack+(right_end - M1);
3132+ }
3133+
3134+ sk = skip[haystack[right_end - i]];
3135+ sh = shift[i];
3136+ right_end = max(right_end - i + sk, right_end + sh);
3137+ }
3138+
3139+ return NULL;
3140+}
3141+
3142+/* Linear string search based on memcmp() */
3143+char *search_linear (char *needle, char *haystack, int needle_len, int haystack_len)
3144+{
3145+ char *k = haystack + (haystack_len-needle_len);
3146+ char *t = haystack;
3147+
3148+ while ( t <= k ) {
3149+ if (memcmp(t, needle, needle_len) == 0)
3150+ return t;
3151+ t++;
3152+ }
3153+
3154+ return NULL;
3155+}
3156+
3157+
3158+static int
3159+match(const struct sk_buff *skb,
3160+ const struct net_device *in,
3161+ const struct net_device *out,
3162+ const void *matchinfo,
3163+ int offset,
3164+ const void *hdr,
3165+ u_int16_t datalen,
3166+ int *hotdrop)
3167+{
3168+ const struct ipt_string_info *info = matchinfo;
3169+ struct iphdr *ip = skb->nh.iph;
3170+ int hlen, nlen;
3171+ char *needle, *haystack;
3172+ proc_ipt_search search=search_linear;
3173+
3174+ if ( !ip ) return 0;
3175+
3176+ /* get lenghts, and validate them */
3177+ nlen=info->len;
3178+ hlen=ntohs(ip->tot_len)-(ip->ihl*4);
3179+ if ( nlen > hlen ) return 0;
3180+
3181+ needle=(char *)&info->string;
3182+ haystack=(char *)ip+(ip->ihl*4);
3183+
3184+ /* The sublinear search comes in to its own
3185+ * on the larger packets */
3186+ if ( (hlen>IPT_STRING_HAYSTACK_THRESH) &&
3187+ (nlen>IPT_STRING_NEEDLE_THRESH) ) {
3188+ if ( hlen < BM_MAX_HLEN ) {
3189+ search=search_sublinear;
3190+ }else{
3191+ if (net_ratelimit())
3192+ printk(KERN_INFO "ipt_string: Packet too big "
3193+ "to attempt sublinear string search "
3194+ "(%d bytes)\n", hlen );
3195+ }
3196+ }
3197+
3198+ return ((search(needle, haystack, nlen, hlen)!=NULL) ^ info->invert);
3199+}
3200+
3201+static int
3202+checkentry(const char *tablename,
3203+ const struct ipt_ip *ip,
3204+ void *matchinfo,
3205+ unsigned int matchsize,
3206+ unsigned int hook_mask)
3207+{
3208+
3209+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_string_info)))
3210+ return 0;
3211+
3212+ return 1;
3213+}
3214+
3215+void string_freeup_data(void)
3216+{
3217+ int c;
3218+
3219+ if ( bm_string_data ) {
3220+ for(c=0; c<smp_num_cpus; c++) {
3221+ if ( bm_string_data[c].shift ) kfree(bm_string_data[c].shift);
3222+ if ( bm_string_data[c].skip ) kfree(bm_string_data[c].skip);
3223+ if ( bm_string_data[c].len ) kfree(bm_string_data[c].len);
3224+ }
3225+ kfree(bm_string_data);
3226+ }
3227+}
3228+
3229+static struct ipt_match string_match
3230+= { { NULL, NULL }, "string", &match, &checkentry, NULL, THIS_MODULE };
3231+
3232+static int __init init(void)
3233+{
3234+ int c;
3235+ size_t tlen;
3236+ size_t alen;
3237+
3238+ tlen=sizeof(struct string_per_cpu)*smp_num_cpus;
3239+ alen=sizeof(int)*BM_MAX_HLEN;
3240+
3241+ /* allocate array of structures */
3242+ if ( !(bm_string_data=kmalloc(tlen,GFP_KERNEL)) ) {
3243+ return 0;
3244+ }
3245+
3246+ memset(bm_string_data, 0, tlen);
3247+
3248+ /* allocate our skip/shift tables */
3249+ for(c=0; c<smp_num_cpus; c++) {
3250+ if ( !(bm_string_data[c].shift=kmalloc(alen, GFP_KERNEL)) )
3251+ goto alloc_fail;
3252+ if ( !(bm_string_data[c].skip=kmalloc(alen, GFP_KERNEL)) )
3253+ goto alloc_fail;
3254+ if ( !(bm_string_data[c].len=kmalloc(alen, GFP_KERNEL)) )
3255+ goto alloc_fail;
3256+ }
3257+
3258+ return ipt_register_match(&string_match);
3259+
3260+alloc_fail:
3261+ string_freeup_data();
3262+ return 0;
3263+}
3264+
3265+static void __exit fini(void)
3266+{
3267+ ipt_unregister_match(&string_match);
3268+ string_freeup_data();
3269+}
3270+
3271+module_init(init);
3272+module_exit(fini);
3273diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/tcp_ipv4.c linux-2.6.5-rc1/net/ipv4/tcp_ipv4.c
3274--- linux-2.6.5-rc1.org/net/ipv4/tcp_ipv4.c 2004-03-16 05:45:58.000000000 +0000
3275+++ linux-2.6.5-rc1/net/ipv4/tcp_ipv4.c 2004-03-16 12:04:38.000000000 +0000
3276@@ -2667,6 +2667,7 @@
3277 EXPORT_SYMBOL(tcp_v4_connect);
3278 EXPORT_SYMBOL(tcp_v4_do_rcv);
3279 EXPORT_SYMBOL(tcp_v4_lookup_listener);
3280+EXPORT_SYMBOL(tcp_v4_lookup);
3281 EXPORT_SYMBOL(tcp_v4_rebuild_header);
3282 EXPORT_SYMBOL(tcp_v4_remember_stamp);
3283 EXPORT_SYMBOL(tcp_v4_send_check);
3284diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/net/ipv4/udp.c linux-2.6.5-rc1/net/ipv4/udp.c
3285--- linux-2.6.5-rc1.org/net/ipv4/udp.c 2004-03-16 05:45:49.000000000 +0000
3286+++ linux-2.6.5-rc1/net/ipv4/udp.c 2004-03-16 12:04:38.000000000 +0000
3287@@ -1543,6 +1543,7 @@
3288 EXPORT_SYMBOL(udp_port_rover);
3289 EXPORT_SYMBOL(udp_prot);
3290 EXPORT_SYMBOL(udp_sendmsg);
3291+EXPORT_SYMBOL(udp_v4_lookup);
3292
3293 #ifdef CONFIG_PROC_FS
3294 EXPORT_SYMBOL(udp_proc_register);
This page took 0.428486 seconds and 4 git commands to generate.