]> git.pld-linux.org Git - packages/kernel.git/blob - 2.6.5-rc1-patch-o-matic-ng-extra-20040316.patch
- CSZ scheduler removed from kernel tree.
[packages/kernel.git] / 2.6.5-rc1-patch-o-matic-ng-extra-20040316.patch
1 diff -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 */
138 diff -Nur --exclude '*.orig' linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.5-rc1/include/linux/netfilter_ipv4/ip_conntrack.h
139 --- linux-2.6.5-rc1.org/include/linux/netfilter_ipv4/ip_conntrack.h     2004-03-16 12:00:23.000000000 +0000
140 +++ linux-2.6.5-rc1/include/linux/netfilter_ipv4/ip_conntrack.h 2004-03-16 12:04:49.000000000 +0000
141 @@ -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 */
152 diff -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 */
224 diff -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*/
253 diff -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*/
270 diff -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 */
283 diff -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
298 diff -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*/
320 diff -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 */
376 diff -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 */
415 diff -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 */
440 diff -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 */
533 diff -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)
544 diff -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)
556 diff -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  
621 diff -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
624 @@ -41,6 +49,8 @@
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
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
674 diff -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 +
1186 diff -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 +
1693 diff -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;
1706 diff -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  
1770 diff -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);
1892 diff -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);
1977 diff -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);
2098 diff -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);
2170 diff -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);
2255 diff -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,
2437 diff -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);
2617 diff -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 +
3049 diff -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
3052 @@ -0,0 +1,220 @@
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 +
3091 +int smp_num_cpus = 1;
3092 +
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);
3273 diff -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);
3284 diff -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 3.763683 seconds and 3 git commands to generate.