]> git.pld-linux.org Git - packages/kernel.git/blob - 2.6.5-patch-o-matic-ng-base-20040322.patch
- obsolete
[packages/kernel.git] / 2.6.5-patch-o-matic-ng-base-20040322.patch
1 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter.h linux-2.6.5-rc2/include/linux/netfilter.h
2 --- linux-2.6.5-rc2.org/include/linux/netfilter.h       2004-03-20 00:11:18.000000000 +0000
3 +++ linux-2.6.5-rc2/include/linux/netfilter.h   2004-03-22 08:27:15.000000000 +0000
4 @@ -99,6 +99,24 @@
5  
6  extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
7  
8 +typedef void nf_logfn(unsigned int hooknum,
9 +                     const struct sk_buff *skb,
10 +                     const struct net_device *in,
11 +                     const struct net_device *out,
12 +                     const char *prefix);
13 +
14 +/* Function to register/unregister log function. */
15 +int nf_log_register(int pf, nf_logfn *logfn);
16 +void nf_log_unregister(int pf, nf_logfn *logfn);
17 +
18 +/* Calls the registered backend logging function */
19 +void nf_log_packet(int pf,
20 +                  unsigned int hooknum,
21 +                  const struct sk_buff *skb,
22 +                  const struct net_device *in,
23 +                  const struct net_device *out,
24 +                  const char *fmt, ...);
25 +                   
26  /* Activate hook; either okfn or kfree_skb called, unless a hook
27     returns NF_STOLEN (in which case, it's up to the hook to deal with
28     the consequences).
29 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ip_conntrack.h
30 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ip_conntrack.h     2004-03-20 00:11:50.000000000 +0000
31 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ip_conntrack.h 2004-03-22 08:29:50.000000000 +0000
32 @@ -251,6 +251,9 @@
33  /* Call me when a conntrack is destroyed. */
34  extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack);
35  
36 +/* Fake conntrack entry for untracked connections */
37 +extern struct ip_conntrack ip_conntrack_untracked;
38 +
39  /* Returns new sk_buff, or NULL */
40  struct sk_buff *
41  ip_ct_gather_frags(struct sk_buff *skb);
42 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ip_pool.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ip_pool.h
43 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ip_pool.h  1970-01-01 00:00:00.000000000 +0000
44 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ip_pool.h      2004-03-22 08:29:18.000000000 +0000
45 @@ -0,0 +1,64 @@
46 +#ifndef _IP_POOL_H
47 +#define _IP_POOL_H
48 +
49 +/***************************************************************************/
50 +/*  This program is free software; you can redistribute it and/or modify   */
51 +/*  it under the terms of the GNU General Public License as published by   */
52 +/*  the Free Software Foundation; either version 2 of the License, or     */
53 +/*  (at your option) any later version.                                           */
54 +/*                                                                        */
55 +/*  This program is distributed in the hope that it will be useful,       */
56 +/*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */
57 +/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         */
58 +/*  GNU General Public License for more details.                          */
59 +/*                                                                        */
60 +/*  You should have received a copy of the GNU General Public License     */
61 +/*  along with this program; if not, write to the Free Software                   */
62 +/*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/
63 +/***************************************************************************/
64 +
65 +/* A sockopt of such quality has hardly ever been seen before on the open
66 + * market!  This little beauty, hardly ever used: above 64, so it's
67 + * traditionally used for firewalling, not touched (even once!) by the
68 + * 2.0, 2.2 and 2.4 kernels!
69 + *
70 + * Comes with its own certificate of authenticity, valid anywhere in the
71 + * Free world!
72 + *
73 + * Rusty, 19.4.2000
74 + */
75 +#define SO_IP_POOL 81
76 +
77 +typedef int ip_pool_t;                 /* pool index */
78 +#define IP_POOL_NONE   ((ip_pool_t)-1)
79 +
80 +struct ip_pool_request {
81 +       int op;
82 +       ip_pool_t index;
83 +       u_int32_t addr;
84 +       u_int32_t addr2;
85 +};
86 +
87 +/* NOTE: I deliberately break the first cut ippool utility. Nobody uses it. */
88 +
89 +#define IP_POOL_BAD001         0x00000010
90 +
91 +#define IP_POOL_FLUSH          0x00000011      /* req.index, no arguments */
92 +#define IP_POOL_INIT           0x00000012      /* from addr to addr2 incl. */
93 +#define IP_POOL_DESTROY                0x00000013      /* req.index, no arguments */
94 +#define IP_POOL_ADD_ADDR       0x00000014      /* add addr to pool */
95 +#define IP_POOL_DEL_ADDR       0x00000015      /* del addr from pool */
96 +#define IP_POOL_HIGH_NR                0x00000016      /* result in req.index */
97 +#define IP_POOL_LOOKUP         0x00000017      /* result in addr and addr2 */
98 +#define IP_POOL_USAGE          0x00000018      /* result in addr */
99 +#define IP_POOL_TEST_ADDR      0x00000019      /* result (0/1) returned */
100 +
101 +#ifdef __KERNEL__
102 +
103 +/* NOTE: ip_pool_match() and ip_pool_mod() expect ADDR to be host byte order */
104 +extern int ip_pool_match(ip_pool_t pool, u_int32_t addr);
105 +extern int ip_pool_mod(ip_pool_t pool, u_int32_t addr, int isdel);
106 +
107 +#endif
108 +
109 +#endif /*_IP_POOL_H*/
110 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_TTL.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_TTL.h
111 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_TTL.h  1970-01-01 00:00:00.000000000 +0000
112 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_TTL.h      2004-03-22 08:28:11.000000000 +0000
113 @@ -0,0 +1,21 @@
114 +/* TTL modification module for IP tables
115 + * (C) 2000 by Harald Welte <laforge@gnumonks.org> */
116 +
117 +#ifndef _IPT_TTL_H
118 +#define _IPT_TTL_H
119 +
120 +enum {
121 +       IPT_TTL_SET = 0,
122 +       IPT_TTL_INC,
123 +       IPT_TTL_DEC
124 +};
125 +
126 +#define IPT_TTL_MAXMODE        IPT_TTL_DEC
127 +
128 +struct ipt_TTL_info {
129 +       u_int8_t        mode;
130 +       u_int8_t        ttl;
131 +};
132 +
133 +
134 +#endif
135 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_ULOG.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_ULOG.h
136 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_ULOG.h 2004-03-20 00:11:05.000000000 +0000
137 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_ULOG.h     2004-03-22 08:27:15.000000000 +0000
138 @@ -11,6 +11,9 @@
139  #define NETLINK_NFLOG  5
140  #endif
141  
142 +#define ULOG_DEFAULT_NLGROUP   1
143 +#define ULOG_DEFAULT_QTHRESHOLD        1
144 +
145  #define ULOG_MAC_LEN   80
146  #define ULOG_PREFIX_LEN        32
147  
148 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_connlimit.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_connlimit.h
149 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_connlimit.h    1970-01-01 00:00:00.000000000 +0000
150 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_connlimit.h        2004-03-22 08:28:18.000000000 +0000
151 @@ -0,0 +1,12 @@
152 +#ifndef _IPT_CONNLIMIT_H
153 +#define _IPT_CONNLIMIT_H
154 +
155 +struct ipt_connlimit_data;
156 +
157 +struct ipt_connlimit_info {
158 +       int limit;
159 +       int inverse;
160 +       u_int32_t mask;
161 +       struct ipt_connlimit_data *data;
162 +};
163 +#endif /* _IPT_CONNLIMIT_H */
164 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_conntrack.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_conntrack.h
165 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_conntrack.h    2004-03-20 00:11:34.000000000 +0000
166 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_conntrack.h        2004-03-22 08:29:50.000000000 +0000
167 @@ -10,6 +10,7 @@
168  
169  #define IPT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1))
170  #define IPT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2))
171 +#define IPT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3))
172  
173  /* flags, invflags: */
174  #define IPT_CONNTRACK_STATE    0x01
175 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_dstlimit.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_dstlimit.h
176 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_dstlimit.h     1970-01-01 00:00:00.000000000 +0000
177 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_dstlimit.h 2004-03-22 08:28:26.000000000 +0000
178 @@ -0,0 +1,39 @@
179 +#ifndef _IPT_DSTLIMIT_H
180 +#define _IPT_DSTLIMIT_H
181 +
182 +/* timings are in milliseconds. */
183 +#define IPT_DSTLIMIT_SCALE 10000
184 +/* 1/10,000 sec period => max of 10,000/sec.  Min rate is then 429490
185 +   seconds, or one every 59 hours. */
186 +
187 +/* details of this structure hidden by the implementation */
188 +struct ipt_dstlimit_htable;
189 +
190 +#define IPT_DSTLIMIT_HASH_DIP  0x0001
191 +#define IPT_DSTLIMIT_HASH_DPT  0x0002
192 +#define IPT_DSTLIMIT_HASH_SIP  0x0004
193 +
194 +struct dstlimit_cfg {
195 +       u_int32_t mode;   /* bitmask of IPT_DSTLIMIT_HASH_* */
196 +       u_int32_t avg;    /* Average secs between packets * scale */
197 +       u_int32_t burst;  /* Period multiplier for upper limit. */
198 +
199 +       /* user specified */
200 +       u_int32_t size;         /* how many buckets */
201 +       u_int32_t max;          /* max number of entries */
202 +       u_int32_t gc_interval;  /* gc interval */
203 +       u_int32_t expire;       /* when do entries expire? */
204 +};
205 +
206 +struct ipt_dstlimit_info {
207 +       char name [IFNAMSIZ];           /* name */
208 +       struct dstlimit_cfg cfg;
209 +       struct ipt_dstlimit_htable *hinfo;
210 +
211 +       /* Used internally by the kernel */
212 +       union {
213 +               void *ptr;
214 +               struct ipt_dstlimit_info *master;
215 +       } u;
216 +};
217 +#endif /*_IPT_DSTLIMIT_H*/
218 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_fuzzy.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_fuzzy.h
219 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_fuzzy.h        1970-01-01 00:00:00.000000000 +0000
220 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_fuzzy.h    2004-03-22 08:28:32.000000000 +0000
221 @@ -0,0 +1,21 @@
222 +#ifndef _IPT_FUZZY_H
223 +#define _IPT_FUZZY_H
224 +
225 +#include <linux/param.h>
226 +#include <linux/types.h>
227 +
228 +#define MAXFUZZYRATE 10000000
229 +#define MINFUZZYRATE 3
230 +
231 +struct ipt_fuzzy_info {
232 +       u_int32_t minimum_rate;
233 +       u_int32_t maximum_rate;
234 +       u_int32_t packets_total;
235 +       u_int32_t bytes_total;
236 +       u_int32_t previous_time;
237 +       u_int32_t present_time;
238 +       u_int32_t mean_rate;
239 +       u_int8_t acceptance_rate;
240 +};
241 +
242 +#endif /*_IPT_FUZZY_H*/
243 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_ipv4options.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_ipv4options.h
244 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_ipv4options.h  1970-01-01 00:00:00.000000000 +0000
245 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_ipv4options.h      2004-03-22 08:28:47.000000000 +0000
246 @@ -0,0 +1,21 @@
247 +#ifndef __ipt_ipv4options_h_included__
248 +#define __ipt_ipv4options_h_included__
249 +
250 +#define IPT_IPV4OPTION_MATCH_SSRR              0x01  /* For strict source routing */
251 +#define IPT_IPV4OPTION_MATCH_LSRR              0x02  /* For loose source routing */
252 +#define IPT_IPV4OPTION_DONT_MATCH_SRR          0x04  /* any source routing */
253 +#define IPT_IPV4OPTION_MATCH_RR                        0x08  /* For Record route */
254 +#define IPT_IPV4OPTION_DONT_MATCH_RR           0x10
255 +#define IPT_IPV4OPTION_MATCH_TIMESTAMP         0x20  /* For timestamp request */
256 +#define IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP    0x40
257 +#define IPT_IPV4OPTION_MATCH_ROUTER_ALERT      0x80  /* For router-alert */
258 +#define IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT 0x100
259 +#define IPT_IPV4OPTION_MATCH_ANY_OPT           0x200 /* match packet with any option */
260 +#define IPT_IPV4OPTION_DONT_MATCH_ANY_OPT      0x400 /* match packet with no option */
261 +
262 +struct ipt_ipv4options_info {
263 +       u_int16_t options;
264 +};
265 +
266 +
267 +#endif /* __ipt_ipv4options_h_included__ */
268 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_mport.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_mport.h
269 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_mport.h        1970-01-01 00:00:00.000000000 +0000
270 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_mport.h    2004-03-22 08:28:51.000000000 +0000
271 @@ -0,0 +1,24 @@
272 +#ifndef _IPT_MPORT_H
273 +#define _IPT_MPORT_H
274 +#include <linux/netfilter_ipv4/ip_tables.h>
275 +
276 +#define IPT_MPORT_SOURCE (1<<0)
277 +#define IPT_MPORT_DESTINATION (1<<1)
278 +#define IPT_MPORT_EITHER (IPT_MPORT_SOURCE|IPT_MPORT_DESTINATION)
279 +
280 +#define IPT_MULTI_PORTS        15
281 +
282 +/* Must fit inside union ipt_matchinfo: 32 bytes */
283 +/* every entry in ports[] except for the last one has one bit in pflags
284 + * associated with it. If this bit is set, the port is the first port of
285 + * a portrange, with the next entry being the last.
286 + * End of list is marked with pflags bit set and port=65535.
287 + * If 14 ports are used (last one does not have a pflag), the last port
288 + * is repeated to fill the last entry in ports[] */
289 +struct ipt_mport
290 +{
291 +       u_int8_t flags:2;                       /* Type of comparison */
292 +       u_int16_t pflags:14;                    /* Port flags */
293 +       u_int16_t ports[IPT_MULTI_PORTS];       /* Ports */
294 +};
295 +#endif /*_IPT_MPORT_H*/
296 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_nth.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_nth.h
297 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_nth.h  1970-01-01 00:00:00.000000000 +0000
298 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_nth.h      2004-03-22 08:29:02.000000000 +0000
299 @@ -0,0 +1,19 @@
300 +#ifndef _IPT_NTH_H
301 +#define _IPT_NTH_H
302 +
303 +#include <linux/param.h>
304 +#include <linux/types.h>
305 +
306 +#ifndef IPT_NTH_NUM_COUNTERS
307 +#define IPT_NTH_NUM_COUNTERS 16
308 +#endif
309 +
310 +struct ipt_nth_info {
311 +       u_int8_t every;
312 +       u_int8_t not;
313 +       u_int8_t startat;
314 +       u_int8_t counter;
315 +       u_int8_t packet;
316 +};
317 +
318 +#endif /*_IPT_NTH_H*/
319 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_osf.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_osf.h
320 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_osf.h  1970-01-01 00:00:00.000000000 +0000
321 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_osf.h      2004-03-22 08:29:11.000000000 +0000
322 @@ -0,0 +1,148 @@
323 +/*
324 + * ipt_osf.h
325 + *
326 + * Copyright (c) 2003 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
327 + *
328 + *
329 + * This program is free software; you can redistribute it and/or modify
330 + * it under the terms of the GNU General Public License as published by
331 + * the Free Software Foundation; either version 2 of the License, or
332 + * (at your option) any later version.
333 + *
334 + * This program is distributed in the hope that it will be useful,
335 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
336 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
337 + * GNU General Public License for more details.
338 + *
339 + * You should have received a copy of the GNU General Public License
340 + * along with this program; if not, write to the Free Software
341 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
342 + */
343 +
344 +#ifndef _IPT_OSF_H
345 +#define _IPT_OSF_H
346 +
347 +#define MAXGENRELEN            32
348 +#define MAXDETLEN              64
349 +
350 +#define IPT_OSF_GENRE          1
351 +#define        IPT_OSF_SMART           2
352 +#define IPT_OSF_LOG            4
353 +#define IPT_OSF_NETLINK                8
354 +
355 +#define IPT_OSF_LOGLEVEL_ALL   0
356 +#define IPT_OSF_LOGLEVEL_FIRST 1
357 +
358 +#include <linux/list.h>
359 +
360 +#ifndef __KERNEL__
361 +#include <netinet/ip.h>
362 +#include <netinet/tcp.h>
363 +
364 +struct list_head
365 +{
366 +       struct list_head *prev, *next;
367 +};
368 +#endif
369 +
370 +struct ipt_osf_info
371 +{
372 +       char                    genre[MAXGENRELEN];
373 +       int                     len;
374 +       unsigned long           flags;
375 +       int                     loglevel;
376 +       int                     invert; /* UNSUPPORTED */
377 +};
378 +
379 +struct osf_wc
380 +{
381 +       char                    wc;
382 +       unsigned long           val;
383 +};
384 +
385 +/* This struct represents IANA options
386 + * http://www.iana.org/assignments/tcp-parameters
387 + */
388 +struct osf_opt
389 +{
390 +       unsigned char           kind;
391 +       unsigned char           length;
392 +       struct osf_wc           wc;
393 +};
394 +
395 +struct osf_finger
396 +{
397 +       struct list_head        flist;
398 +       struct osf_wc           wss;
399 +       unsigned char           ttl;
400 +       unsigned char           df;
401 +       unsigned long           ss;
402 +       unsigned char           genre[MAXGENRELEN];
403 +       unsigned char           version[MAXGENRELEN], subtype[MAXGENRELEN];
404 +       
405 +       /* Not needed, but for consistency with original table from Michal Zalewski */
406 +       unsigned char           details[MAXDETLEN]; 
407 +
408 +       int                     opt_num;
409 +       struct osf_opt          opt[MAX_IPOPTLEN]; /* In case it is all NOP or EOL */
410 +
411 +};
412 +
413 +struct ipt_osf_nlmsg
414 +{
415 +       struct osf_finger       f;
416 +       struct iphdr            ip;
417 +       struct tcphdr           tcp;
418 +};
419 +
420 +#ifdef __KERNEL__
421 +
422 +/* Defines for IANA option kinds */
423 +
424 +#define OSFOPT_EOL             0       /* End of options */
425 +#define OSFOPT_NOP             1       /* NOP */
426 +#define OSFOPT_MSS             2       /* Maximum segment size */
427 +#define OSFOPT_WSO             3       /* Window scale option */
428 +#define OSFOPT_SACKP           4       /* SACK permitted */
429 +#define OSFOPT_SACK            5       /* SACK */
430 +#define OSFOPT_ECHO            6       
431 +#define OSFOPT_ECHOREPLY       7
432 +#define OSFOPT_TS              8       /* Timestamp option */
433 +#define OSFOPT_POCP            9       /* Partial Order Connection Permitted */
434 +#define OSFOPT_POSP            10      /* Partial Order Service Profile */
435 +/* Others are not used in current OSF */
436 +
437 +static struct osf_opt IANA_opts[] = 
438 +{
439 +       {0, 1,},
440 +       {1, 1,},
441 +       {2, 4,},
442 +       {3, 3,},
443 +       {4, 2,},
444 +       {5, 1 ,}, /* SACK length is not defined */
445 +       {6, 6,},
446 +       {7, 6,},
447 +       {8, 10,},
448 +       {9, 2,},
449 +       {10, 3,},
450 +       {11, 1,}, /* CC: Suppose 1 */
451 +       {12, 1,}, /* the same */
452 +       {13, 1,}, /* and here too */
453 +       {14, 3,},
454 +       {15, 1,}, /* TCP Alternate Checksum Data. Length is not defined */
455 +       {16, 1,},
456 +       {17, 1,},
457 +       {18, 3,},
458 +       {19, 18,},
459 +       {20, 1,},
460 +       {21, 1,},
461 +       {22, 1,},
462 +       {23, 1,},
463 +       {24, 1,},
464 +       {25, 1,},
465 +       {26, 1,},
466 +};
467 +
468 +#endif /* __KERNEL__ */
469 +
470 +#endif /* _IPT_OSF_H */
471 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_pool.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_pool.h
472 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_pool.h 1970-01-01 00:00:00.000000000 +0000
473 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_pool.h     2004-03-22 08:29:18.000000000 +0000
474 @@ -0,0 +1,25 @@
475 +#ifndef _IPT_POOL_H
476 +#define _IPT_POOL_H
477 +
478 +#include <linux/netfilter_ipv4/ip_pool.h>
479 +
480 +#define IPT_POOL_INV_SRC       0x00000001
481 +#define IPT_POOL_INV_DST       0x00000002
482 +#define IPT_POOL_DEL_SRC       0x00000004
483 +#define IPT_POOL_DEL_DST       0x00000008
484 +#define IPT_POOL_INV_MOD_SRC   0x00000010
485 +#define IPT_POOL_INV_MOD_DST   0x00000020
486 +#define IPT_POOL_MOD_SRC_ACCEPT        0x00000040
487 +#define IPT_POOL_MOD_DST_ACCEPT        0x00000080
488 +#define IPT_POOL_MOD_SRC_DROP  0x00000100
489 +#define IPT_POOL_MOD_DST_DROP  0x00000200
490 +
491 +/* match info */
492 +struct ipt_pool_info
493 +{
494 +       ip_pool_t src;
495 +       ip_pool_t dst;
496 +       unsigned flags;
497 +};
498 +
499 +#endif /*_IPT_POOL_H*/
500 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_psd.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_psd.h
501 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_psd.h  1970-01-01 00:00:00.000000000 +0000
502 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_psd.h      2004-03-22 08:29:30.000000000 +0000
503 @@ -0,0 +1,40 @@
504 +#ifndef _IPT_PSD_H
505 +#define _IPT_PSD_H
506 +
507 +#include <linux/param.h>
508 +#include <linux/types.h>
509 +
510 +/*
511 + * High port numbers have a lower weight to reduce the frequency of false
512 + * positives, such as from passive mode FTP transfers.
513 + */
514 +#define PORT_WEIGHT_PRIV               3
515 +#define PORT_WEIGHT_HIGH               1
516 +
517 +/*
518 + * Port scan detection thresholds: at least COUNT ports need to be scanned
519 + * from the same source, with no longer than DELAY ticks between ports.
520 + */
521 +#define SCAN_MIN_COUNT                 7
522 +#define SCAN_MAX_COUNT                 (SCAN_MIN_COUNT * PORT_WEIGHT_PRIV)
523 +#define SCAN_WEIGHT_THRESHOLD          SCAN_MAX_COUNT
524 +#define SCAN_DELAY_THRESHOLD           (HZ * 3)
525 +
526 +/*
527 + * Keep track of up to LIST_SIZE source addresses, using a hash table of
528 + * HASH_SIZE entries for faster lookups, but limiting hash collisions to
529 + * HASH_MAX source addresses per the same hash value.
530 + */
531 +#define LIST_SIZE                      0x100
532 +#define HASH_LOG                       9
533 +#define HASH_SIZE                      (1 << HASH_LOG)
534 +#define HASH_MAX                       0x10
535 +
536 +struct ipt_psd_info {
537 +       unsigned int weight_threshold;
538 +       unsigned int delay_threshold;
539 +       unsigned short lo_ports_weight;
540 +       unsigned short hi_ports_weight;
541 +};
542 +
543 +#endif /*_IPT_PSD_H*/
544 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_quota.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_quota.h
545 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_quota.h        1970-01-01 00:00:00.000000000 +0000
546 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_quota.h    2004-03-22 08:29:35.000000000 +0000
547 @@ -0,0 +1,11 @@
548 +#ifndef _IPT_QUOTA_H
549 +#define _IPT_QUOTA_H
550 +
551 +/* print debug info in both kernel/netfilter module & iptable library */
552 +//#define DEBUG_IPT_QUOTA
553 +
554 +struct ipt_quota_info {
555 +        u_int64_t quota;
556 +};
557 +
558 +#endif /*_IPT_QUOTA_H*/
559 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_random.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_random.h
560 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_random.h       1970-01-01 00:00:00.000000000 +0000
561 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_random.h   2004-03-22 08:29:43.000000000 +0000
562 @@ -0,0 +1,11 @@
563 +#ifndef _IPT_RAND_H
564 +#define _IPT_RAND_H
565 +
566 +#include <linux/param.h>
567 +#include <linux/types.h>
568 +
569 +struct ipt_rand_info {
570 +       u_int8_t average;
571 +};
572 +
573 +#endif /*_IPT_RAND_H*/
574 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_realm.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_realm.h
575 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_realm.h        1970-01-01 00:00:00.000000000 +0000
576 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_realm.h    2004-03-22 08:29:57.000000000 +0000
577 @@ -0,0 +1,9 @@
578 +#ifndef _IPT_REALM_H
579 +#define _IPT_REALM_H
580 +
581 +struct ipt_realm_info {
582 +       u_int32_t id;
583 +       u_int32_t mask;
584 +       u_int8_t invert;
585 +};
586 +#endif /*_IPT_REALM_H*/
587 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_sctp.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_sctp.h
588 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_sctp.h 1970-01-01 00:00:00.000000000 +0000
589 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_sctp.h     2004-03-22 08:30:03.000000000 +0000
590 @@ -0,0 +1,107 @@
591 +#ifndef _IPT_SCTP_H_
592 +#define _IPT_SCTP_H_
593 +
594 +#define IPT_SCTP_SRC_PORTS             0x01
595 +#define IPT_SCTP_DEST_PORTS            0x02
596 +#define IPT_SCTP_CHUNK_TYPES           0x04
597 +
598 +#define IPT_SCTP_VALID_FLAGS           0x07
599 +
600 +#define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0]))
601 +
602 +
603 +struct ipt_sctp_flag_info {
604 +       u_int8_t chunktype;
605 +       u_int8_t flag;
606 +       u_int8_t flag_mask;
607 +};
608 +
609 +#define IPT_NUM_SCTP_FLAGS     4
610 +
611 +struct ipt_sctp_info {
612 +       u_int16_t dpts[2];  /* Min, Max */
613 +       u_int16_t spts[2];  /* Min, Max */
614 +
615 +       u_int32_t chunkmap[256 / sizeof (u_int32_t)];  /* Bit mask of chunks to be matched according to RFC 2960 */
616 +
617 +#define SCTP_CHUNK_MATCH_ANY   0x01  /* Match if any of the chunk types are present */
618 +#define SCTP_CHUNK_MATCH_ALL   0x02  /* Match if all of the chunk types are present */
619 +#define SCTP_CHUNK_MATCH_ONLY  0x04  /* Match if these are the only chunk types present */
620 +
621 +       u_int32_t chunk_match_type;
622 +       struct ipt_sctp_flag_info flag_info[IPT_NUM_SCTP_FLAGS];
623 +       int flag_count;
624 +
625 +       u_int32_t flags;
626 +       u_int32_t invflags;
627 +};
628 +
629 +#define bytes(type) (sizeof(type) * 8)
630 +
631 +#define SCTP_CHUNKMAP_SET(chunkmap, type)              \
632 +       do {                                            \
633 +               chunkmap[type / bytes(u_int32_t)] |=    \
634 +                       1 << (type % bytes(u_int32_t)); \
635 +       } while (0)
636 +
637 +#define SCTP_CHUNKMAP_CLEAR(chunkmap, type)                    \
638 +       do {                                                    \
639 +               chunkmap[type / bytes(u_int32_t)] &=            \
640 +                       ~(1 << (type % bytes(u_int32_t)));      \
641 +       } while (0)
642 +
643 +#define SCTP_CHUNKMAP_IS_SET(chunkmap, type)                   \
644 +({                                                             \
645 +       (chunkmap[type / bytes (u_int32_t)] &                   \
646 +               (1 << (type % bytes (u_int32_t)))) ? 1: 0;      \
647 +})
648 +
649 +#define SCTP_CHUNKMAP_RESET(chunkmap)                          \
650 +       do {                                                    \
651 +               int i;                                          \
652 +               for (i = 0; i < ELEMCOUNT(chunkmap); i++)       \
653 +                       chunkmap[i] = 0;                        \
654 +       } while (0)
655 +
656 +#define SCTP_CHUNKMAP_SET_ALL(chunkmap)                        \
657 +       do {                                                    \
658 +               int i;                                          \
659 +               for (i = 0; i < ELEMCOUNT(chunkmap); i++)       \
660 +                       chunkmap[i] = ~0;                       \
661 +       } while (0)
662 +
663 +#define SCTP_CHUNKMAP_COPY(destmap, srcmap)                    \
664 +       do {                                                    \
665 +               int i;                                          \
666 +               for (i = 0; i < ELEMCOUNT(chunkmap); i++)       \
667 +                       destmap[i] = srcmap[i];                 \
668 +       } while (0)
669 +
670 +#define SCTP_CHUNKMAP_IS_CLEAR(chunkmap)               \
671 +({                                                     \
672 +       int i;                                          \
673 +       int flag = 1;                                   \
674 +       for (i = 0; i < ELEMCOUNT(chunkmap); i++) {     \
675 +               if (chunkmap[i]) {                      \
676 +                       flag = 0;                       \
677 +                       break;                          \
678 +               }                                       \
679 +       }                                               \
680 +        flag;                                          \
681 +})
682 +
683 +#define SCTP_CHUNKMAP_IS_ALL_SET(chunkmap)             \
684 +({                                                     \
685 +       int i;                                          \
686 +       int flag = 1;                                   \
687 +       for (i = 0; i < ELEMCOUNT(chunkmap); i++) {     \
688 +               if (chunkmap[i] != ~0) {                \
689 +                       flag = 0;                       \
690 +                               break;                  \
691 +               }                                       \
692 +       }                                               \
693 +        flag;                                          \
694 +})
695 +
696 +#endif /* _IPT_SCTP_H_ */
697 +
698 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_state.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_state.h
699 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_state.h        2004-03-20 00:11:41.000000000 +0000
700 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_state.h    2004-03-22 08:29:50.000000000 +0000
701 @@ -4,6 +4,8 @@
702  #define IPT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
703  #define IPT_STATE_INVALID (1 << 0)
704  
705 +#define IPT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1))
706 +
707  struct ipt_state_info
708  {
709         unsigned int statemask;
710 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_time.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_time.h
711 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_time.h 1970-01-01 00:00:00.000000000 +0000
712 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_time.h     2004-03-22 08:30:10.000000000 +0000
713 @@ -0,0 +1,13 @@
714 +#ifndef __ipt_time_h_included__
715 +#define __ipt_time_h_included__
716 +
717 +
718 +struct ipt_time_info {
719 +       u_int8_t  days_match;   /* 1 bit per day. -SMTWTFS                      */
720 +       u_int16_t time_start;   /* 0 < time_start < 23*60+59 = 1439             */
721 +       u_int16_t time_stop;    /* 0:0 < time_stat < 23:59                      */
722 +       u_int8_t  kerneltime;   /* ignore skb time (and use kerneltime) or not. */
723 +};
724 +
725 +
726 +#endif /* __ipt_time_h_included__ */
727 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_u32.h linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_u32.h
728 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4/ipt_u32.h  1970-01-01 00:00:00.000000000 +0000
729 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4/ipt_u32.h      2004-03-22 08:30:19.000000000 +0000
730 @@ -0,0 +1,40 @@
731 +#ifndef _IPT_U32_H
732 +#define _IPT_U32_H
733 +#include <linux/netfilter_ipv4/ip_tables.h>
734 +
735 +enum ipt_u32_ops
736 +{
737 +       IPT_U32_AND,
738 +       IPT_U32_LEFTSH,
739 +       IPT_U32_RIGHTSH,
740 +       IPT_U32_AT
741 +};
742 +
743 +struct ipt_u32_location_element
744 +{
745 +       u_int32_t number;
746 +       u_int8_t nextop;
747 +};
748 +struct ipt_u32_value_element
749 +{
750 +       u_int32_t min;
751 +       u_int32_t max;
752 +};
753 +/* *** any way to allow for an arbitrary number of elements?
754 +   for now I settle for a limit of 10 of each */
755 +#define U32MAXSIZE 10
756 +struct ipt_u32_test
757 +{
758 +       u_int8_t nnums;
759 +       struct ipt_u32_location_element location[U32MAXSIZE+1];
760 +       u_int8_t nvalues;
761 +       struct ipt_u32_value_element value[U32MAXSIZE+1];
762 +};
763 +
764 +struct ipt_u32
765 +{
766 +       u_int8_t ntests;
767 +       struct ipt_u32_test tests[U32MAXSIZE+1];
768 +};
769 +
770 +#endif /*_IPT_U32_H*/
771 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv4.h linux-2.6.5-rc2/include/linux/netfilter_ipv4.h
772 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv4.h  2004-03-20 00:11:41.000000000 +0000
773 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv4.h      2004-03-22 08:29:50.000000000 +0000
774 @@ -51,6 +51,8 @@
775  
776  enum nf_ip_hook_priorities {
777         NF_IP_PRI_FIRST = INT_MIN,
778 +       NF_IP_PRI_CONNTRACK_DEFRAG = -400,
779 +       NF_IP_PRI_RAW = -300,
780         NF_IP_PRI_SELINUX_FIRST = -225,
781         NF_IP_PRI_CONNTRACK = -200,
782         NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
783 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_HL.h linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_HL.h
784 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_HL.h  1970-01-01 00:00:00.000000000 +0000
785 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_HL.h      2004-03-22 08:27:23.000000000 +0000
786 @@ -0,0 +1,22 @@
787 +/* Hop Limit modification module for ip6tables
788 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
789 + * Based on HW's TTL module */
790 +
791 +#ifndef _IP6T_HL_H
792 +#define _IP6T_HL_H
793 +
794 +enum {
795 +       IP6T_HL_SET = 0,
796 +       IP6T_HL_INC,
797 +       IP6T_HL_DEC
798 +};
799 +
800 +#define IP6T_HL_MAXMODE        IP6T_HL_DEC
801 +
802 +struct ip6t_HL_info {
803 +       u_int8_t        mode;
804 +       u_int8_t        hop_limit;
805 +};
806 +
807 +
808 +#endif
809 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_REJECT.h linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_REJECT.h
810 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_REJECT.h      2004-03-20 00:11:00.000000000 +0000
811 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_REJECT.h  2004-03-22 08:28:02.000000000 +0000
812 @@ -2,15 +2,17 @@
813  #define _IP6T_REJECT_H
814  
815  enum ip6t_reject_with {
816 -       IP6T_ICMP_NET_UNREACHABLE,
817 -       IP6T_ICMP_HOST_UNREACHABLE,
818 -       IP6T_ICMP_PROT_UNREACHABLE,
819 -       IP6T_ICMP_PORT_UNREACHABLE,
820 -       IP6T_ICMP_ECHOREPLY
821 +       IP6T_ICMP6_NO_ROUTE,
822 +       IP6T_ICMP6_ADM_PROHIBITED,
823 +       IP6T_ICMP6_NOT_NEIGHBOUR,
824 +       IP6T_ICMP6_ADDR_UNREACH,
825 +       IP6T_ICMP6_PORT_UNREACH,
826 +       IP6T_ICMP6_ECHOREPLY,
827 +       IP6T_TCP_RESET
828  };
829  
830  struct ip6t_reject_info {
831         enum ip6t_reject_with with;      /* reject type */
832  };
833  
834 -#endif /*_IPT_REJECT_H*/
835 +#endif /*_IP6T_REJECT_H*/
836 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_fuzzy.h
837 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h       1970-01-01 00:00:00.000000000 +0000
838 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_fuzzy.h   2004-03-22 08:28:32.000000000 +0000
839 @@ -0,0 +1,21 @@
840 +#ifndef _IP6T_FUZZY_H
841 +#define _IP6T_FUZZY_H
842 +
843 +#include <linux/param.h>
844 +#include <linux/types.h>
845 +
846 +#define MAXFUZZYRATE 10000000
847 +#define MINFUZZYRATE 3
848 +
849 +struct ip6t_fuzzy_info {
850 +       u_int32_t minimum_rate;
851 +       u_int32_t maximum_rate;
852 +       u_int32_t packets_total;
853 +       u_int32_t bytes_total;
854 +       u_int32_t previous_time;
855 +       u_int32_t present_time;
856 +       u_int32_t mean_rate;
857 +       u_int8_t acceptance_rate;
858 +};
859 +
860 +#endif /*_IP6T_FUZZY_H*/
861 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_nth.h linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_nth.h
862 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_nth.h 1970-01-01 00:00:00.000000000 +0000
863 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_nth.h     2004-03-22 08:29:02.000000000 +0000
864 @@ -0,0 +1,19 @@
865 +#ifndef _IP6T_NTH_H
866 +#define _IP6T_NTH_H
867 +
868 +#include <linux/param.h>
869 +#include <linux/types.h>
870 +
871 +#ifndef IP6T_NTH_NUM_COUNTERS
872 +#define IP6T_NTH_NUM_COUNTERS 16
873 +#endif
874 +
875 +struct ip6t_nth_info {
876 +       u_int8_t every;
877 +       u_int8_t not;
878 +       u_int8_t startat;
879 +       u_int8_t counter;
880 +       u_int8_t packet;
881 +};
882 +
883 +#endif /*_IP6T_NTH_H*/
884 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_random.h linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_random.h
885 --- linux-2.6.5-rc2.org/include/linux/netfilter_ipv6/ip6t_random.h      1970-01-01 00:00:00.000000000 +0000
886 +++ linux-2.6.5-rc2/include/linux/netfilter_ipv6/ip6t_random.h  2004-03-22 08:29:43.000000000 +0000
887 @@ -0,0 +1,11 @@
888 +#ifndef _IP6T_RAND_H
889 +#define _IP6T_RAND_H
890 +
891 +#include <linux/param.h>
892 +#include <linux/types.h>
893 +
894 +struct ip6t_rand_info {
895 +       u_int8_t average;
896 +};
897 +
898 +#endif /*_IP6T_RAND_H*/
899 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/core/netfilter.c linux-2.6.5-rc2/net/core/netfilter.c
900 --- linux-2.6.5-rc2.org/net/core/netfilter.c    2004-03-20 00:11:08.000000000 +0000
901 +++ linux-2.6.5-rc2/net/core/netfilter.c        2004-03-22 08:27:15.000000000 +0000
902 @@ -8,8 +8,10 @@
903   *
904   * February 2000: Modified by James Morris to have 1 queue per protocol.
905   * 15-Mar-2000:   Added NF_REPEAT --RR.
906 + * 08-May-2003:          Internal logging interface added by Jozsef Kadlecsik.
907   */
908  #include <linux/config.h>
909 +#include <linux/kernel.h>
910  #include <linux/netfilter.h>
911  #include <net/protocol.h>
912  #include <linux/init.h>
913 @@ -741,6 +743,72 @@
914  EXPORT_SYMBOL(skb_ip_make_writable);
915  #endif /*CONFIG_INET*/
916  
917 +/* Internal logging interface, which relies on the real 
918 +   LOG target modules */
919 +
920 +#define NF_LOG_PREFIXLEN               128
921 +
922 +static nf_logfn *nf_logging[NPROTO]; /* = NULL */
923 +static int reported = 0;
924 +static spinlock_t nf_log_lock = SPIN_LOCK_UNLOCKED;
925 +
926 +int nf_log_register(int pf, nf_logfn *logfn)
927 +{
928 +       int ret = -EBUSY;
929 +
930 +       /* Any setup of logging members must be done before
931 +        * substituting pointer. */
932 +       smp_wmb();
933 +       spin_lock(&nf_log_lock);
934 +       if (!nf_logging[pf]) {
935 +               nf_logging[pf] = logfn;
936 +               ret = 0;
937 +       }
938 +       spin_unlock(&nf_log_lock);
939 +       return ret;
940 +}              
941 +
942 +void nf_log_unregister(int pf, nf_logfn *logfn)
943 +{
944 +       spin_lock(&nf_log_lock);
945 +       if (nf_logging[pf] == logfn)
946 +               nf_logging[pf] = NULL;
947 +       spin_unlock(&nf_log_lock);
948 +
949 +       /* Give time to concurrent readers. */
950 +       synchronize_net();
951 +}              
952 +
953 +void nf_log_packet(int pf,
954 +                  unsigned int hooknum,
955 +                  const struct sk_buff *skb,
956 +                  const struct net_device *in,
957 +                  const struct net_device *out,
958 +                  const char *fmt, ...)
959 +{
960 +       va_list args;
961 +       char prefix[NF_LOG_PREFIXLEN];
962 +       nf_logfn *logfn;
963 +       
964 +       rcu_read_lock();
965 +       logfn = nf_logging[pf];
966 +       if (logfn) {
967 +               va_start(args, fmt);
968 +               vsnprintf(prefix, sizeof(prefix), fmt, args);
969 +               va_end(args);
970 +               /* We must read logging before nf_logfn[pf] */
971 +               smp_read_barrier_depends();
972 +               logfn(hooknum, skb, in, out, prefix);
973 +       } else if (!reported) {
974 +               printk(KERN_WARNING "nf_log_packet: can\'t log yet, "
975 +                      "no backend logging module loaded in!\n");
976 +               reported++;
977 +       }
978 +       rcu_read_unlock();
979 +}
980 +EXPORT_SYMBOL(nf_log_register);
981 +EXPORT_SYMBOL(nf_log_unregister);
982 +EXPORT_SYMBOL(nf_log_packet);
983  
984  /* This does not belong here, but ipt_REJECT needs it if connection
985     tracking in use: without this, connection may not be in hash table,
986 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/Kconfig linux-2.6.5-rc2/net/ipv4/netfilter/Kconfig
987 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/Kconfig      2004-03-20 00:11:41.000000000 +0000
988 +++ linux-2.6.5-rc2/net/ipv4/netfilter/Kconfig  2004-03-22 08:30:19.000000000 +0000
989 @@ -579,5 +579,118 @@
990  
991           To compile it as a module, choose M here.  If unsure, say N.
992  
993 +config IP_NF_TARGET_IPV4OPTSSTRIP
994 +       tristate  'IPV4OPTSSTRIP target support'
995 +       depends on IP_NF_MANGLE
996 +         help
997 +
998 +config IP_NF_TARGET_TTL
999 +       tristate  'TTL target support'
1000 +       depends on IP_NF_MANGLE
1001 +         help
1002 +
1003 +config IP_NF_MATCH_CONNLIMIT
1004 +       tristate  'Connections/IP limit match support'
1005 +       depends on IP_NF_IPTABLES
1006 +         help
1007 +
1008 +config IP_NF_MATCH_DSTLIMIT
1009 +       tristate  'dstlimit match support'
1010 +       depends on IP_NF_IPTABLES
1011 +         help
1012 +
1013 +config IP_NF_MATCH_FUZZY
1014 +       tristate  'fuzzy match support'
1015 +       depends on IP_NF_IPTABLES
1016 +         help
1017 +
1018 +config IP_NF_MATCH_IPV4OPTIONS
1019 +       tristate  'IPV4OPTIONS match support'
1020 +       depends on IP_NF_IPTABLES
1021 +         help
1022 +
1023 +config IP_NF_MATCH_MPORT
1024 +       tristate  'Multiple port with ranges match support'
1025 +       depends on IP_NF_IPTABLES
1026 +         help
1027 +
1028 +config IP_NF_MATCH_NTH
1029 +       tristate  'Nth match support'
1030 +       depends on IP_NF_IPTABLES
1031 +         help
1032 +
1033 +config IP_NF_MATCH_OSF
1034 +       tristate  'OSF match support'
1035 +       depends on IP_NF_IPTABLES
1036 +         help
1037 +
1038 +config IP_POOL_STATISTICS
1039 +       bool  'enable statistics on pool usage'
1040 +       depends on IP_NF_POOL!=n
1041 +
1042 +config IP_NF_POOL
1043 +       tristate  'IP address pool support'
1044 +       depends on IP_NF_IPTABLES
1045 +         help
1046 +
1047 +config IP_NF_MATCH_PSD
1048 +       tristate  'psd match support'
1049 +       depends on IP_NF_IPTABLES
1050 +         help
1051 +
1052 +config IP_NF_MATCH_QUOTA
1053 +       tristate  'quota match support'
1054 +       depends on IP_NF_IPTABLES
1055 +         help
1056 +
1057 +config IP_NF_MATCH_RANDOM
1058 +       tristate  'random match support'
1059 +       depends on IP_NF_IPTABLES
1060 +         help
1061 +
1062 +config IP_NF_TARGET_NOTRACK
1063 +       tristate  'NOTRACK target support'
1064 +       depends on IP_NF_RAW
1065 +       help
1066 +         The NOTRACK target allows a select rule to specify
1067 +         which packets *not* to enter the conntrack/NAT
1068 +         subsystem with all the consequences (no ICMP error tracking,
1069 +         no protocol helpers for the selected packets).
1070 +       
1071 +         If you want to compile it as a module, say M here and read
1072 +         <file:Documentation/modules.txt>.  If unsure, say `N'.
1073 +
1074 +config IP_NF_RAW
1075 +       tristate  'raw table support (required for NOTRACK/TRACE)'
1076 +       depends on IP_NF_IPTABLES
1077 +       help
1078 +         This option adds a `raw' table to iptables. This table is the very
1079 +         first in the netfilter framework and hooks in at the PREROUTING
1080 +         and OUTPUT chains.
1081 +       
1082 +         If you want to compile it as a module, say M here and read
1083 +         <file:Documentation/modules.txt>.  If unsure, say `N'.
1084 +         help
1085 +
1086 +config IP_NF_MATCH_REALM
1087 +       tristate  'realm match support'
1088 +       depends on IP_NF_IPTABLES && NET_CLS_ROUTE
1089 +         help
1090 +
1091 +config IP_NF_MATCH_SCTP
1092 +       tristate  'SCTP protocol match support'
1093 +       depends on IP_NF_IPTABLES
1094 +         help
1095 +
1096 +config IP_NF_MATCH_TIME
1097 +       tristate  'TIME match support'
1098 +       depends on IP_NF_IPTABLES
1099 +         help
1100 +
1101 +config IP_NF_MATCH_U32
1102 +       tristate  'U32 match support'
1103 +       depends on IP_NF_IPTABLES
1104 +         help
1105 +
1106  endmenu
1107  
1108 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/Makefile linux-2.6.5-rc2/net/ipv4/netfilter/Makefile
1109 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/Makefile     2004-03-20 00:11:03.000000000 +0000
1110 +++ linux-2.6.5-rc2/net/ipv4/netfilter/Makefile 2004-03-22 08:30:19.000000000 +0000
1111 @@ -38,19 +38,44 @@
1112  obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
1113  obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
1114  obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
1115 +obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
1116  
1117  # matches
1118  obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
1119  obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
1120 +obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o
1121 +obj-$(CONFIG_IP_NF_MATCH_QUOTA) += ipt_quota.o
1122 +obj-$(CONFIG_IP_NF_MATCH_DSTLIMIT) += ipt_dstlimit.o
1123  obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
1124 +obj-$(CONFIG_IP_NF_POOL) += ipt_pool.o ipt_POOL.o ip_pool.o
1125  obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
1126  obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
1127  
1128  obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
1129  obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
1130 +
1131 +obj-$(CONFIG_IP_NF_MATCH_MPORT) += ipt_mport.o
1132 +
1133  obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
1134  obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
1135  
1136 +obj-$(CONFIG_IP_NF_MATCH_TIME) += ipt_time.o
1137 +
1138 +
1139 +obj-$(CONFIG_IP_NF_MATCH_RANDOM) += ipt_random.o
1140 +
1141 +obj-$(CONFIG_IP_NF_MATCH_PSD) += ipt_psd.o
1142 +
1143 +obj-$(CONFIG_IP_NF_MATCH_OSF) += ipt_osf.o
1144 +
1145 +
1146 +obj-$(CONFIG_IP_NF_MATCH_NTH) += ipt_nth.o
1147 +
1148 +obj-$(CONFIG_IP_NF_MATCH_IPV4OPTIONS) += ipt_ipv4options.o
1149 +
1150 +
1151 +obj-$(CONFIG_IP_NF_MATCH_FUZZY) += ipt_fuzzy.o
1152 +
1153  obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
1154  
1155  obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
1156 @@ -59,10 +84,15 @@
1157  
1158  obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o
1159  
1160 +obj-$(CONFIG_IP_NF_MATCH_U32) += ipt_u32.o
1161 +
1162 +
1163  obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
1164  obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
1165 +obj-$(CONFIG_IP_NF_MATCH_CONNLIMIT) += ipt_connlimit.o
1166  obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
1167  obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
1168 +obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
1169  
1170  obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
1171  
1172 @@ -79,8 +109,11 @@
1173  obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
1174  obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
1175  obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
1176 +obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
1177 +obj-$(CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP) += ipt_IPV4OPTSSTRIP.o
1178  obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
1179  obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
1180 +obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o
1181  
1182  # generic ARP tables
1183  obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
1184 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_conntrack_core.c linux-2.6.5-rc2/net/ipv4/netfilter/ip_conntrack_core.c
1185 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_conntrack_core.c  2004-03-20 00:11:00.000000000 +0000
1186 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ip_conntrack_core.c      2004-03-22 08:29:50.000000000 +0000
1187 @@ -67,6 +67,7 @@
1188  static atomic_t ip_conntrack_count = ATOMIC_INIT(0);
1189  struct list_head *ip_conntrack_hash;
1190  static kmem_cache_t *ip_conntrack_cachep;
1191 +struct ip_conntrack ip_conntrack_untracked;
1192  
1193  extern struct ip_conntrack_protocol ip_conntrack_generic_protocol;
1194  
1195 @@ -691,42 +692,50 @@
1196                              struct ip_conntrack_expect *, tuple);
1197         READ_UNLOCK(&ip_conntrack_expect_tuple_lock);
1198  
1199 -       /* If master is not in hash table yet (ie. packet hasn't left
1200 -          this machine yet), how can other end know about expected?
1201 -          Hence these are not the droids you are looking for (if
1202 -          master ct never got confirmed, we'd hold a reference to it
1203 -          and weird things would happen to future packets). */
1204 -       if (expected && !is_confirmed(expected->expectant))
1205 -               expected = NULL;
1206 -
1207 -       /* Look up the conntrack helper for master connections only */
1208 -       if (!expected)
1209 -               conntrack->helper = ip_ct_find_helper(&repl_tuple);
1210 -
1211 -       /* If the expectation is dying, then this is a loser. */
1212 -       if (expected
1213 -           && expected->expectant->helper->timeout
1214 -           && ! del_timer(&expected->timeout))
1215 -               expected = NULL;
1216 -
1217         if (expected) {
1218 -               DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
1219 -                       conntrack, expected);
1220 -               /* Welcome, Mr. Bond.  We've been expecting you... */
1221 -               IP_NF_ASSERT(master_ct(conntrack));
1222 -               __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
1223 -               conntrack->master = expected;
1224 -               expected->sibling = conntrack;
1225 -               LIST_DELETE(&ip_conntrack_expect_list, expected);
1226 -               expected->expectant->expecting--;
1227 -               nf_conntrack_get(&master_ct(conntrack)->infos[0]);
1228 -       }
1229 -       atomic_inc(&ip_conntrack_count);
1230 +               /* If master is not in hash table yet (ie. packet hasn't left
1231 +                  this machine yet), how can other end know about expected?
1232 +                  Hence these are not the droids you are looking for (if
1233 +                  master ct never got confirmed, we'd hold a reference to it
1234 +                  and weird things would happen to future packets). */
1235 +               if (!is_confirmed(expected->expectant)) {
1236 +                       
1237 +                       conntrack->helper = ip_ct_find_helper(&repl_tuple);
1238 +                       goto end;
1239 +               }
1240 +
1241 +               /* Expectation is dying... */
1242 +               if (expected->expectant->helper->timeout
1243 +                   && ! del_timer(&expected->timeout)) {
1244 +                       goto end;       
1245 +               }
1246 +
1247 +                DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
1248 +                       conntrack, expected);
1249 +                /* Welcome, Mr. Bond.  We've been expecting you... */
1250 +                IP_NF_ASSERT(master_ct(conntrack));
1251 +                __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
1252 +                conntrack->master = expected;
1253 +                expected->sibling = conntrack;
1254 +                LIST_DELETE(&ip_conntrack_expect_list, expected);
1255 +                expected->expectant->expecting--;
1256 +                nf_conntrack_get(&master_ct(conntrack)->infos[0]);
1257 +
1258 +               /* this is a braindead... --pablo */
1259 +               atomic_inc(&ip_conntrack_count);
1260 +               WRITE_UNLOCK(&ip_conntrack_lock);
1261 +
1262 +               if (expected->expectfn)
1263 +                       expected->expectfn(conntrack);
1264 +
1265 +               goto ret;
1266 +        } else 
1267 +                conntrack->helper = ip_ct_find_helper(&repl_tuple);
1268 +
1269 +end:   atomic_inc(&ip_conntrack_count);
1270         WRITE_UNLOCK(&ip_conntrack_lock);
1271  
1272 -       if (expected && expected->expectfn)
1273 -               expected->expectfn(conntrack);
1274 -       return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
1275 +ret:   return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
1276  }
1277  
1278  /* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
1279 @@ -794,6 +803,15 @@
1280         int set_reply;
1281         int ret;
1282  
1283 +       /* Never happen */
1284 +       if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) {
1285 +               if (net_ratelimit()) {
1286 +               printk(KERN_ERR "ip_conntrack_in: Frag of proto %u (hook=%u)\n",
1287 +                      (*pskb)->nh.iph->protocol, hooknum);
1288 +               }
1289 +               return NF_DROP;
1290 +       }
1291 +
1292         /* FIXME: Do this right please. --RR */
1293         (*pskb)->nfcache |= NFC_UNKNOWN;
1294  
1295 @@ -812,18 +830,10 @@
1296         }
1297  #endif
1298  
1299 -       /* Previously seen (loopback)?  Ignore.  Do this before
1300 -           fragment check. */
1301 +       /* Previously seen (loopback or untracked)?  Ignore. */
1302         if ((*pskb)->nfct)
1303                 return NF_ACCEPT;
1304  
1305 -       /* Gather fragments. */
1306 -       if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
1307 -               *pskb = ip_ct_gather_frags(*pskb);
1308 -               if (!*pskb)
1309 -                       return NF_STOLEN;
1310 -       }
1311 -
1312         proto = ip_ct_find_proto((*pskb)->nh.iph->protocol);
1313  
1314         /* It may be an icmp error... */
1315 @@ -1422,6 +1432,18 @@
1316  
1317         /* For use by ipt_REJECT */
1318         ip_ct_attach = ip_conntrack_attach;
1319 +
1320 +       /* Set up fake conntrack:
1321 +           - to never be deleted, not in any hashes */
1322 +       atomic_set(&ip_conntrack_untracked.ct_general.use, 1);
1323 +       /*  - and look it like as a confirmed connection */
1324 +       set_bit(IPS_CONFIRMED_BIT, &ip_conntrack_untracked.status);
1325 +       /*  - and prepare the ctinfo field for REJECT & NAT. */
1326 +       ip_conntrack_untracked.infos[IP_CT_NEW].master =
1327 +       ip_conntrack_untracked.infos[IP_CT_RELATED].master =
1328 +       ip_conntrack_untracked.infos[IP_CT_RELATED + IP_CT_IS_REPLY].master = 
1329 +                       &ip_conntrack_untracked.ct_general;
1330 +
1331         return ret;
1332  
1333  err_free_hash:
1334 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.6.5-rc2/net/ipv4/netfilter/ip_conntrack_standalone.c
1335 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_conntrack_standalone.c    2004-03-20 00:11:06.000000000 +0000
1336 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ip_conntrack_standalone.c        2004-03-22 08:29:50.000000000 +0000
1337 @@ -194,6 +194,26 @@
1338         return ip_conntrack_confirm(*pskb);
1339  }
1340  
1341 +static unsigned int ip_conntrack_defrag(unsigned int hooknum,
1342 +                                       struct sk_buff **pskb,
1343 +                                       const struct net_device *in,
1344 +                                       const struct net_device *out,
1345 +                                       int (*okfn)(struct sk_buff *))
1346 +{
1347 +       /* Previously seen (loopback)?  Ignore.  Do this before
1348 +           fragment check. */
1349 +       if ((*pskb)->nfct)
1350 +               return NF_ACCEPT;
1351 +
1352 +       /* Gather fragments. */
1353 +       if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
1354 +               *pskb = ip_ct_gather_frags(*pskb);
1355 +               if (!*pskb)
1356 +                       return NF_STOLEN;
1357 +       }
1358 +       return NF_ACCEPT;
1359 +}
1360 +
1361  static unsigned int ip_refrag(unsigned int hooknum,
1362                               struct sk_buff **pskb,
1363                               const struct net_device *in,
1364 @@ -236,6 +256,14 @@
1365  
1366  /* Connection tracking may drop packets, but never alters them, so
1367     make it the first hook. */
1368 +static struct nf_hook_ops ip_conntrack_defrag_ops = {
1369 +       .hook           = ip_conntrack_defrag,
1370 +       .owner          = THIS_MODULE,
1371 +       .pf             = PF_INET,
1372 +       .hooknum        = NF_IP_PRE_ROUTING,
1373 +       .priority       = NF_IP_PRI_CONNTRACK_DEFRAG,
1374 +};
1375 +
1376  static struct nf_hook_ops ip_conntrack_in_ops = {
1377         .hook           = ip_conntrack_in,
1378         .owner          = THIS_MODULE,
1379 @@ -244,6 +272,14 @@
1380         .priority       = NF_IP_PRI_CONNTRACK,
1381  };
1382  
1383 +static struct nf_hook_ops ip_conntrack_defrag_local_out_ops = {
1384 +       .hook           = ip_conntrack_defrag,
1385 +       .owner          = THIS_MODULE,
1386 +       .pf             = PF_INET,
1387 +       .hooknum        = NF_IP_LOCAL_OUT,
1388 +       .priority       = NF_IP_PRI_CONNTRACK_DEFRAG,
1389 +};
1390 +
1391  static struct nf_hook_ops ip_conntrack_local_out_ops = {
1392         .hook           = ip_conntrack_local,
1393         .owner          = THIS_MODULE,
1394 @@ -470,10 +506,20 @@
1395         if (!proc) goto cleanup_init;
1396         proc->owner = THIS_MODULE;
1397  
1398 +       ret = nf_register_hook(&ip_conntrack_defrag_ops);
1399 +       if (ret < 0) {
1400 +               printk("ip_conntrack: can't register pre-routing defrag hook.\n");
1401 +               goto cleanup_proc;
1402 +       }
1403 +       ret = nf_register_hook(&ip_conntrack_defrag_local_out_ops);
1404 +       if (ret < 0) {
1405 +               printk("ip_conntrack: can't register local_out defrag hook.\n");
1406 +               goto cleanup_defragops;
1407 +       }
1408         ret = nf_register_hook(&ip_conntrack_in_ops);
1409         if (ret < 0) {
1410                 printk("ip_conntrack: can't register pre-routing hook.\n");
1411 -               goto cleanup_proc;
1412 +               goto cleanup_defraglocalops;
1413         }
1414         ret = nf_register_hook(&ip_conntrack_local_out_ops);
1415         if (ret < 0) {
1416 @@ -511,6 +557,10 @@
1417         nf_unregister_hook(&ip_conntrack_local_out_ops);
1418   cleanup_inops:
1419         nf_unregister_hook(&ip_conntrack_in_ops);
1420 + cleanup_defraglocalops:
1421 +       nf_unregister_hook(&ip_conntrack_defrag_local_out_ops);
1422 + cleanup_defragops:
1423 +       nf_unregister_hook(&ip_conntrack_defrag_ops);
1424   cleanup_proc:
1425         proc_net_remove("ip_conntrack");
1426   cleanup_init:
1427 @@ -602,5 +652,6 @@
1428  EXPORT_SYMBOL(ip_conntrack_expect_list);
1429  EXPORT_SYMBOL(ip_conntrack_lock);
1430  EXPORT_SYMBOL(ip_conntrack_hash);
1431 +EXPORT_SYMBOL(ip_conntrack_untracked);
1432  EXPORT_SYMBOL_GPL(ip_conntrack_find_get);
1433  EXPORT_SYMBOL_GPL(ip_conntrack_put);
1434 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_nat_core.c linux-2.6.5-rc2/net/ipv4/netfilter/ip_nat_core.c
1435 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_nat_core.c        2004-03-20 00:11:02.000000000 +0000
1436 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ip_nat_core.c    2004-03-22 08:29:50.000000000 +0000
1437 @@ -1016,6 +1016,10 @@
1438         /* FIXME: Man, this is a hack.  <SIGH> */
1439         IP_NF_ASSERT(ip_conntrack_destroyed == NULL);
1440         ip_conntrack_destroyed = &ip_nat_cleanup_conntrack;
1441 +       
1442 +       /* Initialize fake conntrack so that NAT will skip it */
1443 +       ip_conntrack_untracked.nat.info.initialized |= 
1444 +               (1 << IP_NAT_MANIP_SRC) | (1 << IP_NAT_MANIP_DST);
1445  
1446         return 0;
1447  }
1448 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_pool.c linux-2.6.5-rc2/net/ipv4/netfilter/ip_pool.c
1449 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ip_pool.c    1970-01-01 00:00:00.000000000 +0000
1450 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ip_pool.c        2004-03-22 08:29:18.000000000 +0000
1451 @@ -0,0 +1,334 @@
1452 +/* Kernel module for IP pool management */
1453 +
1454 +#include <linux/module.h>
1455 +#include <linux/ip.h>
1456 +#include <linux/skbuff.h>
1457 +#include <linux/netfilter_ipv4/ip_tables.h>
1458 +#include <linux/netfilter_ipv4/ip_pool.h>
1459 +#include <linux/errno.h>
1460 +#include <asm/uaccess.h>
1461 +#include <asm/bitops.h>
1462 +#include <linux/interrupt.h>
1463 +#include <linux/spinlock.h>
1464 +
1465 +#if 0
1466 +#define DP printk
1467 +#else
1468 +#define DP(format, args...)
1469 +#endif
1470 +
1471 +MODULE_LICENSE("GPL");
1472 +
1473 +#define NR_POOL 16
1474 +static int nr_pool = NR_POOL;/* overwrite this when loading module */
1475 +
1476 +struct ip_pool {
1477 +       u_int32_t first_ip;     /* host byte order, included in range */
1478 +       u_int32_t last_ip;      /* host byte order, included in range */
1479 +       void *members;          /* the bitmap proper */
1480 +       int nr_use;             /* total nr. of tests through this */
1481 +       int nr_match;           /* total nr. of matches through this */
1482 +       rwlock_t lock;
1483 +};
1484 +
1485 +static struct ip_pool *POOL;
1486 +
1487 +static inline struct ip_pool *lookup(ip_pool_t index)
1488 +{
1489 +       if (index < 0 || index >= nr_pool) {
1490 +               DP("ip_pool:lookup: bad index %d\n", index);
1491 +               return 0;
1492 +       }
1493 +       return POOL+index;
1494 +}
1495 +
1496 +int ip_pool_match(ip_pool_t index, u_int32_t addr)
1497 +{
1498 +        struct ip_pool *pool = lookup(index);
1499 +       int res = 0;
1500 +
1501 +       if (!pool || !pool->members)
1502 +               return 0;
1503 +       read_lock_bh(&pool->lock);
1504 +       if (pool->members) {
1505 +               if (addr >= pool->first_ip && addr <= pool->last_ip) {
1506 +                       addr -= pool->first_ip;
1507 +                       if (test_bit(addr, pool->members)) {
1508 +                               res = 1;
1509 +#ifdef CONFIG_IP_POOL_STATISTICS
1510 +                               pool->nr_match++;
1511 +#endif
1512 +                       }
1513 +               }
1514 +#ifdef CONFIG_IP_POOL_STATISTICS
1515 +               pool->nr_use++;
1516 +#endif
1517 +       }
1518 +       read_unlock_bh(&pool->lock);
1519 +       return res;
1520 +}
1521 +EXPORT_SYMBOL(ip_pool_match);
1522 +
1523 +static int pool_change(ip_pool_t index, u_int32_t addr, int isdel)
1524 +{
1525 +       struct ip_pool *pool;
1526 +       int res = -1;
1527 +
1528 +       pool = lookup(index);
1529 +       if (    !pool || !pool->members
1530 +            || addr < pool->first_ip || addr > pool->last_ip)
1531 +               return -1;
1532 +       read_lock_bh(&pool->lock);
1533 +       if (pool->members && addr >= pool->first_ip && addr <= pool->last_ip) {
1534 +               addr -= pool->first_ip;
1535 +               res = isdel
1536 +                       ? (0 != test_and_clear_bit(addr, pool->members))
1537 +                       : (0 != test_and_set_bit(addr, pool->members));
1538 +       }
1539 +       read_unlock_bh(&pool->lock);
1540 +       return res;
1541 +}
1542 +
1543 +int ip_pool_mod(ip_pool_t index, u_int32_t addr, int isdel)
1544 +{
1545 +       int res = pool_change(index,addr,isdel);
1546 +
1547 +       if (!isdel) res = !res;
1548 +       return res;
1549 +}
1550 +EXPORT_SYMBOL(ip_pool_mod);
1551 +
1552 +static inline int bitmap_bytes(u_int32_t a, u_int32_t b)
1553 +{
1554 +       return 4*((((b-a+8)/8)+3)/4);
1555 +}
1556 +
1557 +static inline int poolbytes(ip_pool_t index)
1558 +{
1559 +       struct ip_pool *pool = lookup(index);
1560 +
1561 +       return pool ? bitmap_bytes(pool->first_ip, pool->last_ip) : 0;
1562 +}
1563 +
1564 +static int setpool(
1565 +       struct sock *sk,
1566 +       int optval,
1567 +       void *user,
1568 +       unsigned int len
1569 +) {
1570 +       struct ip_pool_request req;
1571 +
1572 +       DP("ip_pool:setpool: optval=%d, user=%p, len=%d\n", optval, user, len);
1573 +       if (!capable(CAP_NET_ADMIN))
1574 +               return -EPERM;
1575 +       if (optval != SO_IP_POOL)
1576 +               return -EBADF;
1577 +       if (len != sizeof(req))
1578 +               return -EINVAL;
1579 +       if (copy_from_user(&req, user, sizeof(req)) != 0)
1580 +               return -EFAULT;
1581 +       printk("obsolete op - upgrade your ippool(8) utility.\n");
1582 +       return -EINVAL;
1583 +}
1584 +
1585 +static int getpool(
1586 +       struct sock *sk,
1587 +       int optval,
1588 +       void *user,
1589 +       int *len
1590 +) {
1591 +       struct ip_pool_request req;
1592 +       struct ip_pool *pool;
1593 +       ip_pool_t i;
1594 +       int newbytes;
1595 +       void *newmembers;
1596 +       int res;
1597 +
1598 +       DP("ip_pool:getpool: optval=%d, user=%p\n", optval, user);
1599 +       if (!capable(CAP_NET_ADMIN))
1600 +               return -EINVAL;
1601 +       if (optval != SO_IP_POOL)
1602 +               return -EINVAL;
1603 +       if (*len != sizeof(req)) {
1604 +               return -EFAULT;
1605 +       }
1606 +       if (copy_from_user(&req, user, sizeof(req)) != 0)
1607 +               return -EFAULT;
1608 +       DP("ip_pool:getpool op=%d, index=%d\n", req.op, req.index);
1609 +       if (req.op < IP_POOL_BAD001) {
1610 +               printk("obsolete op - upgrade your ippool(8) utility.\n");
1611 +               return -EFAULT;
1612 +       }
1613 +       switch(req.op) {
1614 +       case IP_POOL_HIGH_NR:
1615 +               DP("ip_pool HIGH_NR\n");
1616 +               req.index = IP_POOL_NONE;
1617 +               for (i=0; i<nr_pool; i++)
1618 +                       if (POOL[i].members)
1619 +                               req.index = i;
1620 +               return copy_to_user(user, &req, sizeof(req));
1621 +       case IP_POOL_LOOKUP:
1622 +               DP("ip_pool LOOKUP\n");
1623 +               pool = lookup(req.index);
1624 +               if (!pool)
1625 +                       return -EINVAL;
1626 +               if (!pool->members)
1627 +                       return -EBADF;
1628 +               req.addr = htonl(pool->first_ip);
1629 +               req.addr2 = htonl(pool->last_ip);
1630 +               return copy_to_user(user, &req, sizeof(req));
1631 +       case IP_POOL_USAGE:
1632 +               DP("ip_pool USE\n");
1633 +               pool = lookup(req.index);
1634 +               if (!pool)
1635 +                       return -EINVAL;
1636 +               if (!pool->members)
1637 +                       return -EBADF;
1638 +               req.addr = pool->nr_use;
1639 +               req.addr2 = pool->nr_match;
1640 +               return copy_to_user(user, &req, sizeof(req));
1641 +       case IP_POOL_TEST_ADDR:
1642 +               DP("ip_pool TEST 0x%08x\n", req.addr);
1643 +               pool = lookup(req.index);
1644 +               if (!pool)
1645 +                       return -EINVAL;
1646 +               res = 0;
1647 +               read_lock_bh(&pool->lock);
1648 +               if (!pool->members) {
1649 +                       DP("ip_pool TEST_ADDR no members in pool\n");
1650 +                       res = -EBADF;
1651 +                       goto unlock_and_return_res;
1652 +               }
1653 +               req.addr = ntohl(req.addr);
1654 +               if (req.addr < pool->first_ip) {
1655 +                       DP("ip_pool TEST_ADDR address < pool bounds\n");
1656 +                       res = -ERANGE;
1657 +                       goto unlock_and_return_res;
1658 +               }
1659 +               if (req.addr > pool->last_ip) {
1660 +                       DP("ip_pool TEST_ADDR address > pool bounds\n");
1661 +                       res = -ERANGE;
1662 +                       goto unlock_and_return_res;
1663 +               }
1664 +               req.addr = (0 != test_bit((req.addr - pool->first_ip),
1665 +                                       pool->members));
1666 +               read_unlock_bh(&pool->lock);
1667 +               return copy_to_user(user, &req, sizeof(req));
1668 +       case IP_POOL_FLUSH:
1669 +               DP("ip_pool FLUSH not yet implemented.\n");
1670 +               return -EBUSY;
1671 +       case IP_POOL_DESTROY:
1672 +               DP("ip_pool DESTROY not yet implemented.\n");
1673 +               return -EBUSY;
1674 +       case IP_POOL_INIT:
1675 +               DP("ip_pool INIT 0x%08x-0x%08x\n", req.addr, req.addr2);
1676 +               pool = lookup(req.index);
1677 +               if (!pool)
1678 +                       return -EINVAL;
1679 +               req.addr = ntohl(req.addr);
1680 +               req.addr2 = ntohl(req.addr2);
1681 +               if (req.addr > req.addr2) {
1682 +                       DP("ip_pool INIT bad ip range\n");
1683 +                       return -EINVAL;
1684 +               }
1685 +               newbytes = bitmap_bytes(req.addr, req.addr2);
1686 +               newmembers = kmalloc(newbytes, GFP_KERNEL);
1687 +               if (!newmembers) {
1688 +                       DP("ip_pool INIT out of mem for %d bytes\n", newbytes);
1689 +                       return -ENOMEM;
1690 +               }
1691 +               memset(newmembers, 0, newbytes);
1692 +               write_lock_bh(&pool->lock);
1693 +               if (pool->members) {
1694 +                       DP("ip_pool INIT pool %d exists\n", req.index);
1695 +                       kfree(newmembers);
1696 +                       res = -EBUSY;
1697 +                       goto unlock_and_return_res;
1698 +               }
1699 +               pool->first_ip = req.addr;
1700 +               pool->last_ip = req.addr2;
1701 +               pool->nr_use = 0;
1702 +               pool->nr_match = 0;
1703 +               pool->members = newmembers;
1704 +               write_unlock_bh(&pool->lock);
1705 +               return 0;
1706 +       case IP_POOL_ADD_ADDR:
1707 +               DP("ip_pool ADD_ADDR 0x%08x\n", req.addr);
1708 +               req.addr = pool_change(req.index, ntohl(req.addr), 0);
1709 +               return copy_to_user(user, &req, sizeof(req));
1710 +       case IP_POOL_DEL_ADDR:
1711 +               DP("ip_pool DEL_ADDR 0x%08x\n", req.addr);
1712 +               req.addr = pool_change(req.index, ntohl(req.addr), 1);
1713 +               return copy_to_user(user, &req, sizeof(req));
1714 +       default:
1715 +               DP("ip_pool:getpool bad op %d\n", req.op);
1716 +               return -EINVAL;
1717 +       }
1718 +       return -EINVAL;
1719 +
1720 +unlock_and_return_res:
1721 +       if (pool)
1722 +               read_unlock_bh(&pool->lock);
1723 +       return res;
1724 +}
1725 +
1726 +static struct nf_sockopt_ops so_pool
1727 += { { NULL, NULL }, PF_INET,
1728 +    SO_IP_POOL, SO_IP_POOL+1, &setpool,
1729 +    SO_IP_POOL, SO_IP_POOL+1, &getpool,
1730 +    0, NULL };
1731 +
1732 +MODULE_PARM(nr_pool, "i");
1733 +
1734 +static int __init init(void)
1735 +{
1736 +       ip_pool_t i;
1737 +       int res;
1738 +
1739 +       if (nr_pool < 1) {
1740 +               printk("ip_pool module init: bad nr_pool %d\n", nr_pool);
1741 +               return -EINVAL;
1742 +       }
1743 +       POOL = kmalloc(nr_pool * sizeof(*POOL), GFP_KERNEL);
1744 +       if (!POOL) {
1745 +               printk("ip_pool module init: out of memory for nr_pool %d\n",
1746 +                       nr_pool);
1747 +               return -ENOMEM;
1748 +       }
1749 +       for (i=0; i<nr_pool; i++) {
1750 +               POOL[i].first_ip = 0;
1751 +               POOL[i].last_ip = 0;
1752 +               POOL[i].members = 0;
1753 +               POOL[i].nr_use = 0;
1754 +               POOL[i].nr_match = 0;
1755 +               POOL[i].lock = RW_LOCK_UNLOCKED;
1756 +       }
1757 +       res = nf_register_sockopt(&so_pool);
1758 +       DP("ip_pool:init %d pools, result %d\n", nr_pool, res);
1759 +       if (res != 0) {
1760 +               kfree(POOL);
1761 +               POOL = 0;
1762 +       }
1763 +       return res;
1764 +}
1765 +
1766 +static void __exit fini(void)
1767 +{
1768 +       ip_pool_t i;
1769 +
1770 +       DP("ip_pool:fini BYEBYE\n");
1771 +       nf_unregister_sockopt(&so_pool);
1772 +       for (i=0; i<nr_pool; i++) {
1773 +               if (POOL[i].members) {
1774 +                       kfree(POOL[i].members);
1775 +                       POOL[i].members = 0;
1776 +               }
1777 +       }
1778 +       kfree(POOL);
1779 +       POOL = 0;
1780 +       DP("ip_pool:fini these are the famous last words\n");
1781 +       return;
1782 +}
1783 +
1784 +module_init(init);
1785 +module_exit(fini);
1786 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c
1787 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c  1970-01-01 00:00:00.000000000 +0000
1788 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c      2004-03-22 08:27:30.000000000 +0000
1789 @@ -0,0 +1,89 @@
1790 +/**
1791 + * Strip all IP options in the IP packet header.
1792 + *
1793 + * (C) 2001 by Fabrice MARIE <fabrice@netfilter.org>
1794 + * This software is distributed under GNU GPL v2, 1991
1795 + */
1796 +
1797 +#include <linux/module.h>
1798 +#include <linux/skbuff.h>
1799 +#include <linux/ip.h>
1800 +#include <net/checksum.h>
1801 +
1802 +#include <linux/netfilter_ipv4/ip_tables.h>
1803 +
1804 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
1805 +MODULE_DESCRIPTION("Strip all options in IPv4 packets");
1806 +MODULE_LICENSE("GPL");
1807 +
1808 +static unsigned int
1809 +target(struct sk_buff **pskb,
1810 +       const struct net_device *in,
1811 +       const struct net_device *out,
1812 +       unsigned int hooknum,
1813 +       const void *targinfo,
1814 +       void *userinfo)
1815 +{
1816 +       struct iphdr *iph;
1817 +       struct sk_buff *skb;
1818 +       struct ip_options *opt;
1819 +       unsigned char *optiph;
1820 +       int l;
1821 +       
1822 +       if (!skb_ip_make_writable(pskb, (*pskb)->len))
1823 +               return NF_DROP;
1824
1825 +       skb = (*pskb);
1826 +       iph = (*pskb)->nh.iph;
1827 +       optiph = skb->nh.raw;
1828 +       l = ((struct ip_options *)(&(IPCB(skb)->opt)))->optlen;
1829 +
1830 +       /* if no options in packet then nothing to clear. */
1831 +       if (iph->ihl * 4 == sizeof(struct iphdr))
1832 +               return IPT_CONTINUE;
1833 +
1834 +       /* else clear all options */
1835 +       memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
1836 +       memset(optiph+sizeof(struct iphdr), IPOPT_NOOP, l);
1837 +       opt = &(IPCB(skb)->opt);
1838 +       opt->is_data = 0;
1839 +       opt->optlen = l;
1840 +
1841 +       skb->nfcache |= NFC_ALTERED;
1842 +
1843 +        return IPT_CONTINUE;
1844 +}
1845 +
1846 +static int
1847 +checkentry(const char *tablename,
1848 +          const struct ipt_entry *e,
1849 +           void *targinfo,
1850 +           unsigned int targinfosize,
1851 +           unsigned int hook_mask)
1852 +{
1853 +       if (strcmp(tablename, "mangle")) {
1854 +               printk(KERN_WARNING "IPV4OPTSSTRIP: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1855 +               return 0;
1856 +       }
1857 +       /* nothing else to check because no parameters */
1858 +       return 1;
1859 +}
1860 +
1861 +static struct ipt_target ipt_ipv4optsstrip_reg = { 
1862 +       .name = "IPV4OPTSSTRIP",
1863 +       .target = target,
1864 +       .checkentry = checkentry,
1865 +       .me = THIS_MODULE };
1866 +
1867 +static int __init init(void)
1868 +{
1869 +       return ipt_register_target(&ipt_ipv4optsstrip_reg);
1870 +}
1871 +
1872 +static void __exit fini(void)
1873 +{
1874 +       ipt_unregister_target(&ipt_ipv4optsstrip_reg);
1875 +}
1876 +
1877 +module_init(init);
1878 +module_exit(fini);
1879 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_LOG.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_LOG.c
1880 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_LOG.c    2004-03-20 00:11:42.000000000 +0000
1881 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_LOG.c        2004-03-22 08:27:15.000000000 +0000
1882 @@ -19,6 +19,7 @@
1883  #include <net/tcp.h>
1884  #include <net/route.h>
1885  
1886 +#include <linux/netfilter.h>
1887  #include <linux/netfilter_ipv4/ip_tables.h>
1888  #include <linux/netfilter_ipv4/ipt_LOG.h>
1889  
1890 @@ -26,6 +27,10 @@
1891  MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
1892  MODULE_DESCRIPTION("iptables syslog logging module");
1893  
1894 +static unsigned int nflog = 1;
1895 +MODULE_PARM(nflog, "i");
1896 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
1897
1898  #if 0
1899  #define DEBUGP printk
1900  #else
1901 @@ -324,28 +329,25 @@
1902         /* maxlen = 230+   91  + 230 + 252 = 803 */
1903  }
1904  
1905 -static unsigned int
1906 -ipt_log_target(struct sk_buff **pskb,
1907 +static void
1908 +ipt_log_packet(unsigned int hooknum,
1909 +              const struct sk_buff *skb,
1910                const struct net_device *in,
1911                const struct net_device *out,
1912 -              unsigned int hooknum,
1913 -              const void *targinfo,
1914 -              void *userinfo)
1915 +              const struct ipt_log_info *loginfo,
1916 +              const char *level_string,
1917 +              const char *prefix)
1918  {
1919 -       const struct ipt_log_info *loginfo = targinfo;
1920 -       char level_string[4] = "< >";
1921 -
1922 -       level_string[1] = '0' + (loginfo->level % 8);
1923         spin_lock_bh(&log_lock);
1924         printk(level_string);
1925         printk("%sIN=%s OUT=%s ",
1926 -              loginfo->prefix,
1927 +              prefix == NULL ? loginfo->prefix : prefix,
1928                in ? in->name : "",
1929                out ? out->name : "");
1930  #ifdef CONFIG_BRIDGE_NETFILTER
1931 -       if ((*pskb)->nf_bridge) {
1932 -               struct net_device *physindev = (*pskb)->nf_bridge->physindev;
1933 -               struct net_device *physoutdev = (*pskb)->nf_bridge->physoutdev;
1934 +       if (skb->nf_bridge) {
1935 +               struct net_device *physindev = skb->nf_bridge->physindev;
1936 +               struct net_device *physoutdev = skb->nf_bridge->physoutdev;
1937  
1938                 if (physindev && in != physindev)
1939                         printk("PHYSIN=%s ", physindev->name);
1940 @@ -357,25 +359,56 @@
1941         if (in && !out) {
1942                 /* MAC logging for input chain only. */
1943                 printk("MAC=");
1944 -               if ((*pskb)->dev && (*pskb)->dev->hard_header_len
1945 -                   && (*pskb)->mac.raw != (void*)(*pskb)->nh.iph) {
1946 +               if (skb->dev && skb->dev->hard_header_len
1947 +                   && skb->mac.raw != (void*)skb->nh.iph) {
1948                         int i;
1949 -                       unsigned char *p = (*pskb)->mac.raw;
1950 -                       for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++)
1951 +                       unsigned char *p = skb->mac.raw;
1952 +                       for (i = 0; i < skb->dev->hard_header_len; i++,p++)
1953                                 printk("%02x%c", *p,
1954 -                                      i==(*pskb)->dev->hard_header_len - 1
1955 +                                      i==skb->dev->hard_header_len - 1
1956                                        ? ' ':':');
1957                 } else
1958                         printk(" ");
1959         }
1960  
1961 -       dump_packet(loginfo, *pskb, 0);
1962 +       dump_packet(loginfo, skb, 0);
1963         printk("\n");
1964         spin_unlock_bh(&log_lock);
1965 +}
1966 +
1967 +static unsigned int
1968 +ipt_log_target(struct sk_buff **pskb,
1969 +              const struct net_device *in,
1970 +              const struct net_device *out,
1971 +              unsigned int hooknum,
1972 +              const void *targinfo,
1973 +              void *userinfo)
1974 +{
1975 +       const struct ipt_log_info *loginfo = targinfo;
1976 +       char level_string[4] = "< >";
1977 +
1978 +       level_string[1] = '0' + (loginfo->level % 8);
1979 +       ipt_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL);
1980  
1981         return IPT_CONTINUE;
1982  }
1983  
1984 +static void
1985 +ipt_logfn(unsigned int hooknum,
1986 +         const struct sk_buff *skb,
1987 +         const struct net_device *in,
1988 +         const struct net_device *out,
1989 +         const char *prefix)
1990 +{
1991 +       struct ipt_log_info loginfo = { 
1992 +               .level = 0, 
1993 +               .logflags = IPT_LOG_MASK, 
1994 +               .prefix = "" 
1995 +       };
1996 +
1997 +       ipt_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
1998 +}
1999 +
2000  static int ipt_log_checkentry(const char *tablename,
2001                               const struct ipt_entry *e,
2002                               void *targinfo,
2003 @@ -413,11 +446,18 @@
2004  
2005  static int __init init(void)
2006  {
2007 -       return ipt_register_target(&ipt_log_reg);
2008 +       if (ipt_register_target(&ipt_log_reg))
2009 +               return -EINVAL;
2010 +       if (nflog)
2011 +               nf_log_register(PF_INET, &ipt_logfn);
2012 +       
2013 +       return 0;
2014  }
2015  
2016  static void __exit fini(void)
2017  {
2018 +       if (nflog)
2019 +               nf_log_unregister(PF_INET, &ipt_logfn);
2020         ipt_unregister_target(&ipt_log_reg);
2021  }
2022  
2023 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_NOTRACK.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_NOTRACK.c
2024 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_NOTRACK.c        1970-01-01 00:00:00.000000000 +0000
2025 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_NOTRACK.c    2004-03-22 08:29:50.000000000 +0000
2026 @@ -0,0 +1,75 @@
2027 +/* This is a module which is used for setting up fake conntracks
2028 + * on packets so that they are not seen by the conntrack/NAT code.
2029 + */
2030 +#include <linux/module.h>
2031 +#include <linux/skbuff.h>
2032 +
2033 +#include <linux/netfilter_ipv4/ip_tables.h>
2034 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2035 +
2036 +static unsigned int
2037 +target(struct sk_buff **pskb,
2038 +       const struct net_device *in,
2039 +       const struct net_device *out,
2040 +       unsigned int hooknum,
2041 +       const void *targinfo,
2042 +       void *userinfo)
2043 +{
2044 +       /* Previously seen (loopback)? Ignore. */
2045 +       if ((*pskb)->nfct != NULL)
2046 +               return IPT_CONTINUE;
2047 +
2048 +       /* Attach fake conntrack entry. 
2049 +          If there is a real ct entry correspondig to this packet, 
2050 +          it'll hang aroun till timing out. We don't deal with it
2051 +          for performance reasons. JK */
2052 +       (*pskb)->nfct = &ip_conntrack_untracked.infos[IP_CT_NEW];
2053 +       nf_conntrack_get((*pskb)->nfct);
2054 +
2055 +       return IPT_CONTINUE;
2056 +}
2057 +
2058 +static int
2059 +checkentry(const char *tablename,
2060 +          const struct ipt_entry *e,
2061 +           void *targinfo,
2062 +           unsigned int targinfosize,
2063 +           unsigned int hook_mask)
2064 +{
2065 +       if (targinfosize != 0) {
2066 +               printk(KERN_WARNING "NOTRACK: targinfosize %u != 0\n",
2067 +                      targinfosize);
2068 +               return 0;
2069 +       }
2070 +
2071 +       if (strcmp(tablename, "raw") != 0) {
2072 +               printk(KERN_WARNING "NOTRACK: can only be called from \"raw\" table, not \"%s\"\n", tablename);
2073 +               return 0;
2074 +       }
2075 +
2076 +       return 1;
2077 +}
2078 +
2079 +static struct ipt_target ipt_notrack_reg = { 
2080 +       .name = "NOTRACK", 
2081 +       .target = target, 
2082 +       .checkentry = checkentry,
2083 +       .me = THIS_MODULE 
2084 +};
2085 +
2086 +static int __init init(void)
2087 +{
2088 +       if (ipt_register_target(&ipt_notrack_reg))
2089 +               return -EINVAL;
2090 +
2091 +       return 0;
2092 +}
2093 +
2094 +static void __exit fini(void)
2095 +{
2096 +       ipt_unregister_target(&ipt_notrack_reg);
2097 +}
2098 +
2099 +module_init(init);
2100 +module_exit(fini);
2101 +MODULE_LICENSE("GPL");
2102 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_POOL.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_POOL.c
2103 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_POOL.c   1970-01-01 00:00:00.000000000 +0000
2104 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_POOL.c       2004-03-22 08:29:18.000000000 +0000
2105 @@ -0,0 +1,116 @@
2106 +/* ipt_POOL.c - netfilter target to manipulate IP pools
2107 + *
2108 + * This target can be used almost everywhere. It acts on some specified
2109 + * IP pool, adding or deleting some IP address in the pool. The address
2110 + * can be either the source (--addsrc, --delsrc), or destination (--add/deldst)
2111 + * of the packet under inspection.
2112 + *
2113 + * The target normally returns IPT_CONTINUE.
2114 + */
2115 +
2116 +#include <linux/types.h>
2117 +#include <linux/ip.h>
2118 +#include <linux/timer.h>
2119 +#include <linux/module.h>
2120 +#include <linux/netfilter.h>
2121 +#include <linux/netdevice.h>
2122 +#include <linux/if.h>
2123 +#include <linux/inetdevice.h>
2124 +#include <net/protocol.h>
2125 +#include <net/checksum.h>
2126 +#include <linux/netfilter_ipv4.h>
2127 +#include <linux/netfilter_ipv4/ip_nat_rule.h>
2128 +#include <linux/netfilter_ipv4/ipt_pool.h>
2129 +
2130 +#if 0
2131 +#define DEBUGP printk
2132 +#else
2133 +#define DEBUGP(format, args...)
2134 +#endif
2135 +
2136 +/*** NOTE NOTE NOTE NOTE ***
2137 +**
2138 +** By sheer luck, I get away with using the "struct ipt_pool_info", as defined
2139 +** in <linux/netfilter_ipv4/ipt_pool.h>, both as the match and target info.
2140 +** Here, in the target implementation, ipt_pool_info.src, if not IP_POOL_NONE,
2141 +** is modified for the source IP address of the packet under inspection.
2142 +** The same way, the ipt_pool_info.dst pool is modified for the destination.
2143 +**
2144 +** The address is added to the pool normally. However, if IPT_POOL_DEL_dir
2145 +** flag is set in ipt_pool_info.flags, the address is deleted from the pool.
2146 +**
2147 +** If a modification was done to the pool, we possibly return ACCEPT or DROP,
2148 +** if the right IPT_POOL_MOD_dir_ACCEPT or _MOD_dir_DROP flags are set.
2149 +** The IPT_POOL_INV_MOD_dir flag inverts the sense of the check (i.e. the
2150 +** ACCEPT and DROP flags are evaluated when the pool was not modified.)
2151 +*/
2152 +
2153 +static int
2154 +do_check(const char *tablename,
2155 +              const struct ipt_entry *e,
2156 +              void *targinfo,
2157 +              unsigned int targinfosize,
2158 +              unsigned int hook_mask)
2159 +{
2160 +       const struct ipt_pool_info *ipi = targinfo;
2161 +
2162 +       if (targinfosize != IPT_ALIGN(sizeof(*ipi))) {
2163 +               DEBUGP("POOL_check: size %u.\n", targinfosize);
2164 +               return 0;
2165 +       }
2166 +       DEBUGP("ipt_POOL:do_check(%d,%d,%d)\n",ipi->src,ipi->dst,ipi->flags);
2167 +       return 1;
2168 +}
2169 +
2170 +static unsigned int
2171 +do_target(struct sk_buff **pskb,
2172 +               unsigned int hooknum,
2173 +               const struct net_device *in,
2174 +               const struct net_device *out,
2175 +               const void *targinfo,
2176 +               void *userinfo)
2177 +{
2178 +       const struct ipt_pool_info *ipi = targinfo;
2179 +       int modified;
2180 +       unsigned int verdict = IPT_CONTINUE;
2181 +
2182 +       if (ipi->src != IP_POOL_NONE) {
2183 +               modified = ip_pool_mod(ipi->src, ntohl((*pskb)->nh.iph->saddr),
2184 +                                       ipi->flags & IPT_POOL_DEL_SRC);
2185 +               if (!!modified ^ !!(ipi->flags & IPT_POOL_INV_MOD_SRC)) {
2186 +                       if (ipi->flags & IPT_POOL_MOD_SRC_ACCEPT)
2187 +                               verdict = NF_ACCEPT;
2188 +                       else if (ipi->flags & IPT_POOL_MOD_SRC_DROP)
2189 +                               verdict = NF_DROP;
2190 +               }
2191 +       }
2192 +       if (verdict == IPT_CONTINUE && ipi->dst != IP_POOL_NONE) {
2193 +               modified = ip_pool_mod(ipi->dst, ntohl((*pskb)->nh.iph->daddr),
2194 +                                       ipi->flags & IPT_POOL_DEL_DST);
2195 +               if (!!modified ^ !!(ipi->flags & IPT_POOL_INV_MOD_DST)) {
2196 +                       if (ipi->flags & IPT_POOL_MOD_DST_ACCEPT)
2197 +                               verdict = NF_ACCEPT;
2198 +                       else if (ipi->flags & IPT_POOL_MOD_DST_DROP)
2199 +                               verdict = NF_DROP;
2200 +               }
2201 +       }
2202 +       return verdict;
2203 +}
2204 +
2205 +static struct ipt_target pool_reg
2206 += { { NULL, NULL }, "POOL", do_target, do_check, NULL, THIS_MODULE };
2207 +
2208 +static int __init init(void)
2209 +{
2210 +       DEBUGP("init ipt_POOL\n");
2211 +       return ipt_register_target(&pool_reg);
2212 +}
2213 +
2214 +static void __exit fini(void)
2215 +{
2216 +       DEBUGP("fini ipt_POOL\n");
2217 +       ipt_unregister_target(&pool_reg);
2218 +}
2219 +
2220 +module_init(init);
2221 +module_exit(fini);
2222 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_TTL.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_TTL.c
2223 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_TTL.c    1970-01-01 00:00:00.000000000 +0000
2224 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_TTL.c        2004-03-22 08:28:11.000000000 +0000
2225 @@ -0,0 +1,120 @@
2226 +/* TTL modification target for IP tables
2227 + * (C) 2000 by Harald Welte <laforge@gnumonks.org>
2228 + *
2229 + * Version: $Revision$
2230 + *
2231 + * This software is distributed under the terms of GNU GPL
2232 + */
2233 +
2234 +#include <linux/module.h>
2235 +#include <linux/skbuff.h>
2236 +#include <linux/ip.h>
2237 +#include <net/checksum.h>
2238 +
2239 +#include <linux/netfilter_ipv4/ip_tables.h>
2240 +#include <linux/netfilter_ipv4/ipt_TTL.h>
2241 +
2242 +MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
2243 +MODULE_DESCRIPTION("IP tables TTL modification module");
2244 +MODULE_LICENSE("GPL");
2245 +
2246 +static unsigned int 
2247 +ipt_ttl_target(struct sk_buff **pskb, const struct net_device *in, 
2248 +               const struct net_device *out, unsigned int hooknum, 
2249 +               const void *targinfo, void *userinfo)
2250 +{
2251 +       struct iphdr *iph;
2252 +       const struct ipt_TTL_info *info = targinfo;
2253 +       u_int16_t diffs[2];
2254 +       int new_ttl;
2255 +
2256 +       if (!skb_ip_make_writable(pskb, (*pskb)->len))
2257 +               return NF_DROP;
2258 +
2259 +       iph = (*pskb)->nh.iph;
2260 +                        
2261 +       switch (info->mode) {
2262 +               case IPT_TTL_SET:
2263 +                       new_ttl = info->ttl;
2264 +                       break;
2265 +               case IPT_TTL_INC:
2266 +                       new_ttl = iph->ttl + info->ttl;
2267 +                       if (new_ttl > 255)
2268 +                               new_ttl = 255;
2269 +                       break;
2270 +               case IPT_TTL_DEC:
2271 +                       new_ttl = iph->ttl + info->ttl;
2272 +                       if (new_ttl < 0)
2273 +                               new_ttl = 0;
2274 +                       break;
2275 +               default:
2276 +                       new_ttl = iph->ttl;
2277 +                       break;
2278 +       }
2279 +
2280 +       if (new_ttl != iph->ttl) {
2281 +               diffs[0] = htons(((unsigned)iph->ttl) << 8) ^ 0xFFFF;
2282 +               iph->ttl = new_ttl;
2283 +               diffs[1] = htons(((unsigned)iph->ttl) << 8);
2284 +               iph->check = csum_fold(csum_partial((char *)diffs,
2285 +                                                   sizeof(diffs),
2286 +                                                   iph->check^0xFFFF));
2287 +                                                                                               (*pskb)->nfcache |= NFC_ALTERED;
2288 +       }
2289 +
2290 +       return IPT_CONTINUE;
2291 +}
2292 +
2293 +static int ipt_ttl_checkentry(const char *tablename,
2294 +               const struct ipt_entry *e,
2295 +               void *targinfo,
2296 +               unsigned int targinfosize,
2297 +               unsigned int hook_mask)
2298 +{
2299 +       struct ipt_TTL_info *info = targinfo;
2300 +
2301 +       if (targinfosize != IPT_ALIGN(sizeof(struct ipt_TTL_info))) {
2302 +               printk(KERN_WARNING "TTL: targinfosize %u != %Zu\n",
2303 +                               targinfosize,
2304 +                               IPT_ALIGN(sizeof(struct ipt_TTL_info)));
2305 +               return 0;       
2306 +       }       
2307 +
2308 +       if (strcmp(tablename, "mangle")) {
2309 +               printk(KERN_WARNING "TTL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
2310 +               return 0;
2311 +       }
2312 +
2313 +       if (info->mode > IPT_TTL_MAXMODE) {
2314 +               printk(KERN_WARNING "TTL: invalid or unknown Mode %u\n", 
2315 +                       info->mode);
2316 +               return 0;
2317 +       }
2318 +
2319 +       if ((info->mode != IPT_TTL_SET) && (info->ttl == 0)) {
2320 +               printk(KERN_WARNING "TTL: increment/decrement doesn't make sense with value 0\n");
2321 +               return 0;
2322 +       }
2323 +       
2324 +       return 1;
2325 +}
2326 +
2327 +static struct ipt_target ipt_TTL = { 
2328 +       .name = "TTL",
2329 +       .target = ipt_ttl_target, 
2330 +       .checkentry = ipt_ttl_checkentry, 
2331 +       .me = THIS_MODULE 
2332 +};
2333 +
2334 +static int __init init(void)
2335 +{
2336 +       return ipt_register_target(&ipt_TTL);
2337 +}
2338 +
2339 +static void __exit fini(void)
2340 +{
2341 +       ipt_unregister_target(&ipt_TTL);
2342 +}
2343 +
2344 +module_init(init);
2345 +module_exit(fini);
2346 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_ULOG.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_ULOG.c
2347 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_ULOG.c   2004-03-20 00:11:05.000000000 +0000
2348 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_ULOG.c       2004-03-22 08:27:15.000000000 +0000
2349 @@ -50,6 +50,7 @@
2350  #include <linux/netlink.h>
2351  #include <linux/netdevice.h>
2352  #include <linux/mm.h>
2353 +#include <linux/netfilter.h>
2354  #include <linux/netfilter_ipv4/ip_tables.h>
2355  #include <linux/netfilter_ipv4/ipt_ULOG.h>
2356  #include <linux/netfilter_ipv4/lockhelp.h>
2357 @@ -80,6 +81,10 @@
2358  MODULE_PARM(flushtimeout, "i");
2359  MODULE_PARM_DESC(flushtimeout, "buffer flush timeout");
2360  
2361 +static unsigned int nflog = 1;
2362 +MODULE_PARM(nflog, "i");
2363 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
2364 +
2365  /* global data structures */
2366  
2367  typedef struct {
2368 @@ -157,17 +162,17 @@
2369         return skb;
2370  }
2371  
2372 -static unsigned int ipt_ulog_target(struct sk_buff **pskb,
2373 -                                   const struct net_device *in,
2374 -                                   const struct net_device *out,
2375 -                                   unsigned int hooknum,
2376 -                                   const void *targinfo, void *userinfo)
2377 +static void ipt_ulog_packet(unsigned int hooknum,
2378 +                           const struct sk_buff *skb,
2379 +                           const struct net_device *in,
2380 +                           const struct net_device *out,
2381 +                           const struct ipt_ulog_info *loginfo,
2382 +                           const char *prefix)
2383  {
2384         ulog_buff_t *ub;
2385         ulog_packet_msg_t *pm;
2386         size_t size, copy_len;
2387         struct nlmsghdr *nlh;
2388 -       struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
2389  
2390         /* ffs == find first bit set, necessary because userspace
2391          * is already shifting groupnumber, but we need unshifted.
2392 @@ -176,8 +181,8 @@
2393  
2394         /* calculate the size of the skb needed */
2395         if ((loginfo->copy_range == 0) ||
2396 -           (loginfo->copy_range > (*pskb)->len)) {
2397 -               copy_len = (*pskb)->len;
2398 +           (loginfo->copy_range > skb->len)) {
2399 +               copy_len = skb->len;
2400         } else {
2401                 copy_len = loginfo->copy_range;
2402         }
2403 @@ -214,19 +219,21 @@
2404  
2405         /* copy hook, prefix, timestamp, payload, etc. */
2406         pm->data_len = copy_len;
2407 -       pm->timestamp_sec = (*pskb)->stamp.tv_sec;
2408 -       pm->timestamp_usec = (*pskb)->stamp.tv_usec;
2409 -       pm->mark = (*pskb)->nfmark;
2410 +       pm->timestamp_sec = skb->stamp.tv_sec;
2411 +       pm->timestamp_usec = skb->stamp.tv_usec;
2412 +       pm->mark = skb->nfmark;
2413         pm->hook = hooknum;
2414 -       if (loginfo->prefix[0] != '\0')
2415 +       if (prefix != NULL)
2416 +               strncpy(pm->prefix, prefix, sizeof(pm->prefix));
2417 +       else if (loginfo->prefix[0] != '\0')
2418                 strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix));
2419         else
2420                 *(pm->prefix) = '\0';
2421  
2422         if (in && in->hard_header_len > 0
2423 -           && (*pskb)->mac.raw != (void *) (*pskb)->nh.iph
2424 +           && skb->mac.raw != (void *) skb->nh.iph
2425             && in->hard_header_len <= ULOG_MAC_LEN) {
2426 -               memcpy(pm->mac, (*pskb)->mac.raw, in->hard_header_len);
2427 +               memcpy(pm->mac, skb->mac.raw, in->hard_header_len);
2428                 pm->mac_len = in->hard_header_len;
2429         } else
2430                 pm->mac_len = 0;
2431 @@ -241,8 +248,8 @@
2432         else
2433                 pm->outdev_name[0] = '\0';
2434  
2435 -       /* copy_len <= (*pskb)->len, so can't fail. */
2436 -       if (skb_copy_bits(*pskb, 0, pm->payload, copy_len) < 0)
2437 +       /* copy_len <= skb->len, so can't fail. */
2438 +       if (skb_copy_bits(skb, 0, pm->payload, copy_len) < 0)
2439                 BUG();
2440         
2441         /* check if we are building multi-part messages */
2442 @@ -266,8 +273,7 @@
2443  
2444         UNLOCK_BH(&ulog_lock);
2445  
2446 -       return IPT_CONTINUE;
2447 -
2448 +       return;
2449  
2450  nlmsg_failure:
2451         PRINTR("ipt_ULOG: error during NLMSG_PUT\n");
2452 @@ -276,8 +282,35 @@
2453         PRINTR("ipt_ULOG: Error building netlink message\n");
2454  
2455         UNLOCK_BH(&ulog_lock);
2456 +}
2457 +
2458 +static unsigned int ipt_ulog_target(struct sk_buff **pskb,
2459 +                                   const struct net_device *in,
2460 +                                   const struct net_device *out,
2461 +                                   unsigned int hooknum,
2462 +                                   const void *targinfo, void *userinfo)
2463 +{
2464 +       struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
2465  
2466 -       return IPT_CONTINUE;
2467 +       ipt_ulog_packet(hooknum, *pskb, in, out, loginfo, NULL);
2468
2469 +       return IPT_CONTINUE;
2470 +}
2471
2472 +static void ipt_logfn(unsigned int hooknum,
2473 +                     const struct sk_buff *skb,
2474 +                     const struct net_device *in,
2475 +                     const struct net_device *out,
2476 +                     const char *prefix)
2477 +{
2478 +       struct ipt_ulog_info loginfo = { 
2479 +               .nl_group = ULOG_DEFAULT_NLGROUP,
2480 +               .copy_range = 0,
2481 +               .qthreshold = ULOG_DEFAULT_QTHRESHOLD,
2482 +               .prefix = ""
2483 +       };
2484 +
2485 +       ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
2486  }
2487  
2488  static int ipt_ulog_checkentry(const char *tablename,
2489 @@ -341,7 +374,9 @@
2490                 sock_release(nflognl->sk_socket);
2491                 return -EINVAL;
2492         }
2493 -
2494 +       if (nflog)
2495 +               nf_log_register(PF_INET, &ipt_logfn);
2496 +       
2497         return 0;
2498  }
2499  
2500 @@ -352,6 +387,8 @@
2501  
2502         DEBUGP("ipt_ULOG: cleanup_module\n");
2503  
2504 +       if (nflog)
2505 +               nf_log_unregister(PF_INET, &ipt_logfn);
2506         ipt_unregister_target(&ipt_ulog_reg);
2507         sock_release(nflognl->sk_socket);
2508  
2509 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_connlimit.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_connlimit.c
2510 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_connlimit.c      1970-01-01 00:00:00.000000000 +0000
2511 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_connlimit.c  2004-03-22 08:28:18.000000000 +0000
2512 @@ -0,0 +1,230 @@
2513 +/*
2514 + * netfilter module to limit the number of parallel tcp
2515 + * connections per IP address.
2516 + *   (c) 2000 Gerd Knorr <kraxel@bytesex.org>
2517 + *   Nov 2002: Martin Bene <martin.bene@icomedias.com>:
2518 + *             only ignore TIME_WAIT or gone connections
2519 + *
2520 + * based on ...
2521 + *
2522 + * Kernel module to match connection tracking information.
2523 + * GPL (C) 1999  Rusty Russell (rusty@rustcorp.com.au).
2524 + */
2525 +#include <linux/module.h>
2526 +#include <linux/skbuff.h>
2527 +#include <linux/list.h>
2528 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2529 +#include <linux/netfilter_ipv4/ip_conntrack_core.h>
2530 +#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
2531 +#include <linux/netfilter_ipv4/ip_tables.h>
2532 +#include <linux/netfilter_ipv4/ipt_connlimit.h>
2533 +
2534 +#define DEBUG 0
2535 +
2536 +MODULE_LICENSE("GPL");
2537 +
2538 +/* we'll save the tuples of all connections we care about */
2539 +struct ipt_connlimit_conn
2540 +{
2541 +        struct list_head list;
2542 +       struct ip_conntrack_tuple tuple;
2543 +};
2544 +
2545 +struct ipt_connlimit_data {
2546 +       spinlock_t lock;
2547 +       struct list_head iphash[256];
2548 +};
2549 +
2550 +static int ipt_iphash(u_int32_t addr)
2551 +{
2552 +       int hash;
2553 +
2554 +       hash  =  addr        & 0xff;
2555 +       hash ^= (addr >>  8) & 0xff;
2556 +       hash ^= (addr >> 16) & 0xff;
2557 +       hash ^= (addr >> 24) & 0xff;
2558 +       return hash;
2559 +}
2560 +
2561 +static int count_them(struct ipt_connlimit_data *data,
2562 +                     u_int32_t addr, u_int32_t mask,
2563 +                     struct ip_conntrack *ct)
2564 +{
2565 +#if DEBUG
2566 +       const static char *tcp[] = { "none", "established", "syn_sent", "syn_recv",
2567 +                                    "fin_wait", "time_wait", "close", "close_wait",
2568 +                                    "last_ack", "listen" };
2569 +#endif
2570 +       int addit = 1, matches = 0;
2571 +       struct ip_conntrack_tuple tuple;
2572 +       struct ip_conntrack_tuple_hash *found;
2573 +       struct ipt_connlimit_conn *conn;
2574 +       struct list_head *hash,*lh;
2575 +
2576 +       spin_lock(&data->lock);
2577 +       tuple = ct->tuplehash[0].tuple;
2578 +       hash = &data->iphash[ipt_iphash(addr & mask)];
2579 +
2580 +       /* check the saved connections */
2581 +       for (lh = hash->next; lh != hash; lh = lh->next) {
2582 +               conn = list_entry(lh,struct ipt_connlimit_conn,list);
2583 +               found = ip_conntrack_find_get(&conn->tuple,ct);
2584 +               if (0 == memcmp(&conn->tuple,&tuple,sizeof(tuple)) &&
2585 +                   found != NULL &&
2586 +                   found->ctrack->proto.tcp.state != TCP_CONNTRACK_TIME_WAIT) {
2587 +                       /* Just to be sure we have it only once in the list.
2588 +                          We should'nt see tuples twice unless someone hooks this
2589 +                          into a table without "-p tcp --syn" */
2590 +                       addit = 0;
2591 +               }
2592 +#if DEBUG
2593 +               printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d %s\n",
2594 +                      ipt_iphash(addr & mask),
2595 +                      NIPQUAD(conn->tuple.src.ip), ntohs(conn->tuple.src.u.tcp.port),
2596 +                      NIPQUAD(conn->tuple.dst.ip), ntohs(conn->tuple.dst.u.tcp.port),
2597 +                      (NULL != found) ? tcp[found->ctrack->proto.tcp.state] : "gone");
2598 +#endif
2599 +               if (NULL == found) {
2600 +                       /* this one is gone */
2601 +                       lh = lh->prev;
2602 +                       list_del(lh->next);
2603 +                       kfree(conn);
2604 +                       continue;
2605 +               }
2606 +               if (found->ctrack->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT) {
2607 +                       /* we don't care about connections which are
2608 +                          closed already -> ditch it */
2609 +                       lh = lh->prev;
2610 +                       list_del(lh->next);
2611 +                       kfree(conn);
2612 +                       nf_conntrack_put(&found->ctrack->infos[0]);
2613 +                       continue;
2614 +               }
2615 +               if ((addr & mask) == (conn->tuple.src.ip & mask)) {
2616 +                       /* same source IP address -> be counted! */
2617 +                       matches++;
2618 +               }
2619 +               nf_conntrack_put(&found->ctrack->infos[0]);
2620 +       }
2621 +       if (addit) {
2622 +               /* save the new connection in our list */
2623 +#if DEBUG
2624 +               printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d new\n",
2625 +                      ipt_iphash(addr & mask),
2626 +                      NIPQUAD(tuple.src.ip), ntohs(tuple.src.u.tcp.port),
2627 +                      NIPQUAD(tuple.dst.ip), ntohs(tuple.dst.u.tcp.port));
2628 +#endif
2629 +               conn = kmalloc(sizeof(*conn),GFP_ATOMIC);
2630 +               if (NULL == conn)
2631 +                       return -1;
2632 +               memset(conn,0,sizeof(*conn));
2633 +               INIT_LIST_HEAD(&conn->list);
2634 +               conn->tuple = tuple;
2635 +               list_add(&conn->list,hash);
2636 +               matches++;
2637 +       }
2638 +       spin_unlock(&data->lock);
2639 +       return matches;
2640 +}
2641 +
2642 +static int
2643 +match(const struct sk_buff *skb,
2644 +      const struct net_device *in,
2645 +      const struct net_device *out,
2646 +      const void *matchinfo,
2647 +      int offset,
2648 +      int *hotdrop)
2649 +{
2650 +       const struct ipt_connlimit_info *info = matchinfo;
2651 +       int connections, match;
2652 +       struct ip_conntrack *ct;
2653 +       enum ip_conntrack_info ctinfo;
2654 +
2655 +       ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
2656 +       if (NULL == ct) {
2657 +               printk("ipt_connlimit: Oops: invalid ct state ?\n");
2658 +               *hotdrop = 1;
2659 +               return 0;
2660 +       }
2661 +       connections = count_them(info->data,skb->nh.iph->saddr,info->mask,ct);
2662 +       if (-1 == connections) {
2663 +               printk("ipt_connlimit: Hmm, kmalloc failed :-(\n");
2664 +               *hotdrop = 1; /* let's free some memory :-) */
2665 +               return 0;
2666 +       }
2667 +        match = (info->inverse) ? (connections <= info->limit) : (connections > info->limit);
2668 +#if DEBUG
2669 +       printk("ipt_connlimit: src=%u.%u.%u.%u mask=%u.%u.%u.%u "
2670 +              "connections=%d limit=%d match=%s\n",
2671 +              NIPQUAD(skb->nh.iph->saddr), NIPQUAD(info->mask),
2672 +              connections, info->limit, match ? "yes" : "no");
2673 +#endif
2674 +
2675 +       return match;
2676 +}
2677 +
2678 +static int check(const char *tablename,
2679 +                const struct ipt_ip *ip,
2680 +                void *matchinfo,
2681 +                unsigned int matchsize,
2682 +                unsigned int hook_mask)
2683 +{
2684 +       struct ipt_connlimit_info *info = matchinfo;
2685 +       int i;
2686 +
2687 +       /* verify size */
2688 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_connlimit_info)))
2689 +               return 0;
2690 +
2691 +       /* refuse anything but tcp */
2692 +       if (ip->proto != IPPROTO_TCP)
2693 +               return 0;
2694 +
2695 +       /* init private data */
2696 +       info->data = kmalloc(sizeof(struct ipt_connlimit_data),GFP_KERNEL);
2697 +       spin_lock_init(&(info->data->lock));
2698 +       for (i = 0; i < 256; i++)
2699 +               INIT_LIST_HEAD(&(info->data->iphash[i]));
2700 +       
2701 +       return 1;
2702 +}
2703 +
2704 +static void destroy(void *matchinfo, unsigned int matchinfosize)
2705 +{
2706 +       struct ipt_connlimit_info *info = matchinfo;
2707 +       struct ipt_connlimit_conn *conn;
2708 +       struct list_head *hash;
2709 +       int i;
2710 +
2711 +       /* cleanup */
2712 +       for (i = 0; i < 256; i++) {
2713 +               hash = &(info->data->iphash[i]);
2714 +               while (hash != hash->next) {
2715 +                       conn = list_entry(hash->next,struct ipt_connlimit_conn,list);
2716 +                       list_del(hash->next);
2717 +                       kfree(conn);
2718 +               }
2719 +       }
2720 +       kfree(info->data);
2721 +}
2722 +
2723 +static struct ipt_match connlimit_match = { 
2724 +       .name = "connlimit",
2725 +       .match = &match,
2726 +       .checkentry = &check,
2727 +       .destroy = &destroy,
2728 +       .me = THIS_MODULE
2729 +};
2730 +
2731 +static int __init init(void)
2732 +{
2733 +       return ipt_register_match(&connlimit_match);
2734 +}
2735 +
2736 +static void __exit fini(void)
2737 +{
2738 +       ipt_unregister_match(&connlimit_match);
2739 +}
2740 +
2741 +module_init(init);
2742 +module_exit(fini);
2743 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_conntrack.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_conntrack.c
2744 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_conntrack.c      2004-03-20 00:11:50.000000000 +0000
2745 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_conntrack.c  2004-03-22 08:29:50.000000000 +0000
2746 @@ -35,11 +35,13 @@
2747  
2748  #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
2749  
2750 -       if (ct)
2751 -               statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
2752 -       else
2753 -               statebit = IPT_CONNTRACK_STATE_INVALID;
2754 -
2755 +       if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
2756 +               statebit = IPT_CONNTRACK_STATE_UNTRACKED;
2757 +       else if (ct)
2758 +               statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
2759 +       else
2760 +               statebit = IPT_CONNTRACK_STATE_INVALID;
2761
2762         if(sinfo->flags & IPT_CONNTRACK_STATE) {
2763                 if (ct) {
2764                         if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip !=
2765 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_dstlimit.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_dstlimit.c
2766 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_dstlimit.c       1970-01-01 00:00:00.000000000 +0000
2767 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_dstlimit.c   2004-03-22 08:28:26.000000000 +0000
2768 @@ -0,0 +1,690 @@
2769 +/* iptables match extension to limit the number of packets per second
2770 + * seperately for each destination.
2771 + *
2772 + * (C) 2003 by Harald Welte <laforge@netfilter.org>
2773 + *
2774 + * $Id$
2775 + *
2776 + * Development of this code was funded by Astaro AG, http://www.astaro.com/
2777 + *
2778 + * based on ipt_limit.c by:
2779 + * Jérôme de Vivie     <devivie@info.enserb.u-bordeaux.fr>
2780 + * Hervé Eychenne      <eychenne@info.enserb.u-bordeaux.fr>
2781 + * Rusty Russell       <rusty@rustcorp.com.au>
2782 + *
2783 + * The general idea is to create a hash table for every dstip and have a
2784 + * seperate limit counter per tuple.  This way you can do something like 'limit
2785 + * the number of syn packets for each of my internal addresses.
2786 + *
2787 + * Ideally this would just be implemented as a general 'hash' match, which would
2788 + * allow us to attach any iptables target to it's hash buckets.  But this is
2789 + * not possible in the current iptables architecture.  As always, pkttables for
2790 + * 2.7.x will help ;)
2791 + */
2792 +#include <linux/module.h>
2793 +#include <linux/skbuff.h>
2794 +#include <linux/spinlock.h>
2795 +#include <linux/random.h>
2796 +#include <linux/jhash.h>
2797 +#include <linux/slab.h>
2798 +#include <linux/vmalloc.h>
2799 +#include <linux/tcp.h>
2800 +#include <linux/udp.h>
2801 +#include <linux/proc_fs.h>
2802 +#include <linux/seq_file.h>
2803 +
2804 +#define ASSERT_READ_LOCK(x) 
2805 +#define ASSERT_WRITE_LOCK(x) 
2806 +#include <linux/netfilter_ipv4/lockhelp.h>
2807 +#include <linux/netfilter_ipv4/listhelp.h>
2808 +
2809 +#include <linux/netfilter_ipv4/ip_tables.h>
2810 +#include <linux/netfilter_ipv4/ipt_dstlimit.h>
2811 +
2812 +/* FIXME: this is just for IP_NF_ASSERRT */
2813 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2814 +
2815 +#define MS2JIFFIES(x) ((x*HZ)/1000)
2816 +
2817 +MODULE_LICENSE("GPL");
2818 +MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
2819 +MODULE_DESCRIPTION("iptables match for limiting per destination");
2820 +
2821 +/* need to declare this at the top */
2822 +static struct proc_dir_entry *dstlimit_procdir;
2823 +static struct file_operations dl_file_ops;
2824 +
2825 +/* hash table crap */
2826 +
2827 +struct dsthash_dst {
2828 +       u_int32_t src_ip;
2829 +       u_int32_t dst_ip;
2830 +       u_int16_t port;
2831 +};
2832 +
2833 +struct dsthash_ent {
2834 +       /* static / read-only parts in the beginning */
2835 +       struct list_head list;
2836 +       struct dsthash_dst dst;
2837 +
2838 +       /* modified structure members in the end */
2839 +       unsigned long expires;          /* precalculated expiry time */
2840 +       struct {
2841 +               unsigned long prev;     /* last modification */
2842 +               u_int32_t credit;
2843 +               u_int32_t credit_cap, cost;
2844 +       } rateinfo;
2845 +};
2846 +
2847 +struct ipt_dstlimit_htable {
2848 +       struct list_head list;          /* global list of all htables */
2849 +       atomic_t use;
2850 +
2851 +       struct dstlimit_cfg cfg;        /* config */
2852 +
2853 +       /* used internally */
2854 +       spinlock_t lock;                /* lock for list_head */
2855 +       u_int32_t rnd;                  /* random seed for hash */
2856 +       struct timer_list timer;        /* timer for gc */
2857 +       atomic_t count;                 /* number entries in table */
2858 +
2859 +       /* seq_file stuff */
2860 +       struct proc_dir_entry *pde;
2861 +
2862 +       struct list_head hash[0];       /* hashtable itself */
2863 +};
2864 +
2865 +DECLARE_RWLOCK(dstlimit_lock);         /* protects htables list */
2866 +static LIST_HEAD(dstlimit_htables);
2867 +static kmem_cache_t *dstlimit_cachep;
2868 +
2869 +static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b)
2870 +{
2871 +       return (ent->dst.dst_ip == b->dst_ip 
2872 +               && ent->dst.port == b->port
2873 +               && ent->dst.src_ip == b->src_ip);
2874 +}
2875 +
2876 +static inline u_int32_t
2877 +hash_dst(const struct ipt_dstlimit_htable *ht, const struct dsthash_dst *dst)
2878 +{
2879 +       return (jhash_3words(dst->dst_ip, dst->port, 
2880 +                            dst->src_ip, ht->rnd) % ht->cfg.size);
2881 +}
2882 +
2883 +static inline struct dsthash_ent *
2884 +__dsthash_find(const struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
2885 +{
2886 +       struct dsthash_ent *ent;
2887 +       u_int32_t hash = hash_dst(ht, dst);
2888 +       MUST_BE_LOCKED(&ht->lock);
2889 +       ent = LIST_FIND(&ht->hash[hash], dst_cmp, struct dsthash_ent *, dst);
2890 +       return ent;
2891 +}
2892 +
2893 +/* allocate dsthash_ent, initialize dst, put in htable and lock it */
2894 +static struct dsthash_ent *
2895 +__dsthash_alloc_init(struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
2896 +{
2897 +       struct dsthash_ent *ent;
2898 +
2899 +       /* initialize hash with random val at the time we allocate
2900 +        * the first hashtable entry */
2901 +       if (!ht->rnd)
2902 +               get_random_bytes(&ht->rnd, 4);
2903 +
2904 +       if (ht->cfg.max &&
2905 +           atomic_read(&ht->count) >= ht->cfg.max) {
2906 +               /* FIXME: do something. question is what.. */
2907 +               if (net_ratelimit())
2908 +                       printk(KERN_WARNING 
2909 +                               "ipt_dstlimit: max count of %u reached\n", 
2910 +                               ht->cfg.max);
2911 +               return NULL;
2912 +       }
2913 +
2914 +       ent = kmem_cache_alloc(dstlimit_cachep, GFP_ATOMIC);
2915 +       if (!ent) {
2916 +               if (net_ratelimit())
2917 +                       printk(KERN_ERR 
2918 +                               "ipt_dstlimit: can't allocate dsthash_ent\n");
2919 +               return NULL;
2920 +       }
2921 +
2922 +       atomic_inc(&ht->count);
2923 +
2924 +       ent->dst.dst_ip = dst->dst_ip;
2925 +       ent->dst.port = dst->port;
2926 +       ent->dst.src_ip = dst->src_ip;
2927 +
2928 +       list_add(&ent->list, &ht->hash[hash_dst(ht, dst)]);
2929 +
2930 +       return ent;
2931 +}
2932 +
2933 +static inline void 
2934 +__dsthash_free(struct ipt_dstlimit_htable *ht, struct dsthash_ent *ent)
2935 +{
2936 +       MUST_BE_LOCKED(&ht->lock);
2937 +
2938 +       list_del(&ent->list);
2939 +       kmem_cache_free(dstlimit_cachep, ent);
2940 +       atomic_dec(&ht->count);
2941 +}
2942 +static void htable_gc(unsigned long htlong);
2943 +
2944 +static int htable_create(struct ipt_dstlimit_info *minfo)
2945 +{
2946 +       int i;
2947 +       unsigned int size;
2948 +       struct ipt_dstlimit_htable *hinfo;
2949 +
2950 +       if (minfo->cfg.size)
2951 +               size = minfo->cfg.size;
2952 +       else {
2953 +               size = (((num_physpages << PAGE_SHIFT) / 16384)
2954 +                        / sizeof(struct list_head));
2955 +               if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
2956 +                       size = 8192;
2957 +               if (size < 16)
2958 +                       size = 16;
2959 +       }
2960 +       /* FIXME: don't use vmalloc() here or anywhere else -HW */
2961 +       hinfo = vmalloc(sizeof(struct ipt_dstlimit_htable)
2962 +                       + (sizeof(struct list_head) * size));
2963 +       if (!hinfo) {
2964 +               printk(KERN_ERR "ipt_dstlimit: Unable to create hashtable\n");
2965 +               return -1;
2966 +       }
2967 +       minfo->hinfo = hinfo;
2968 +
2969 +       /* copy match config into hashtable config */
2970 +       memcpy(&hinfo->cfg, &minfo->cfg, sizeof(hinfo->cfg));
2971 +       hinfo->cfg.size = size;
2972 +       if (!hinfo->cfg.max)
2973 +               hinfo->cfg.max = 8 * hinfo->cfg.size;
2974 +       else if (hinfo->cfg.max < hinfo->cfg.size)
2975 +               hinfo->cfg.max = hinfo->cfg.size;
2976 +
2977 +       for (i = 0; i < hinfo->cfg.size; i++)
2978 +               INIT_LIST_HEAD(&hinfo->hash[i]);
2979 +
2980 +       atomic_set(&hinfo->count, 0);
2981 +       atomic_set(&hinfo->use, 1);
2982 +       hinfo->rnd = 0;
2983 +       hinfo->lock = SPIN_LOCK_UNLOCKED;
2984 +       hinfo->pde = create_proc_entry(minfo->name, 0, dstlimit_procdir);
2985 +       if (!hinfo->pde) {
2986 +               vfree(hinfo);
2987 +               return -1;
2988 +       }
2989 +       hinfo->pde->proc_fops = &dl_file_ops;
2990 +       hinfo->pde->data = hinfo;
2991 +
2992 +       init_timer(&hinfo->timer);
2993 +       hinfo->timer.expires = jiffies + MS2JIFFIES(hinfo->cfg.gc_interval);
2994 +       hinfo->timer.data = (unsigned long )hinfo;
2995 +       hinfo->timer.function = htable_gc;
2996 +       add_timer(&hinfo->timer);
2997 +
2998 +       WRITE_LOCK(&dstlimit_lock);
2999 +       list_add(&hinfo->list, &dstlimit_htables);
3000 +       WRITE_UNLOCK(&dstlimit_lock);
3001 +
3002 +       return 0;
3003 +}
3004 +
3005 +static int select_all(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
3006 +{
3007 +       return 1;
3008 +}
3009 +
3010 +static int select_gc(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
3011 +{
3012 +       return (jiffies >= he->expires);
3013 +}
3014 +
3015 +static void htable_selective_cleanup(struct ipt_dstlimit_htable *ht,
3016 +                               int (*select)(struct ipt_dstlimit_htable *ht, 
3017 +                                             struct dsthash_ent *he))
3018 +{
3019 +       int i;
3020 +
3021 +       IP_NF_ASSERT(ht->cfg.size && ht->cfg.max);
3022 +
3023 +       /* lock hash table and iterate over it */
3024 +       LOCK_BH(&ht->lock);
3025 +       for (i = 0; i < ht->cfg.size; i++) {
3026 +               struct dsthash_ent *dh, *n;
3027 +               list_for_each_entry_safe(dh, n, &ht->hash[i], list) {
3028 +                       if ((*select)(ht, dh))
3029 +                               __dsthash_free(ht, dh);
3030 +               }
3031 +       }
3032 +       UNLOCK_BH(&ht->lock);
3033 +}
3034 +
3035 +/* hash table garbage collector, run by timer */
3036 +static void htable_gc(unsigned long htlong)
3037 +{
3038 +       struct ipt_dstlimit_htable *ht = (struct ipt_dstlimit_htable *)htlong;
3039 +
3040 +       htable_selective_cleanup(ht, select_gc);
3041 +
3042 +       /* re-add the timer accordingly */
3043 +       ht->timer.expires = jiffies + MS2JIFFIES(ht->cfg.gc_interval);
3044 +       add_timer(&ht->timer);
3045 +}
3046 +
3047 +static void htable_destroy(struct ipt_dstlimit_htable *hinfo)
3048 +{
3049 +       /* remove timer, if it is pending */
3050 +       if (timer_pending(&hinfo->timer))
3051 +               del_timer(&hinfo->timer);
3052 +
3053 +       /* remove proc entry */
3054 +       remove_proc_entry(hinfo->pde->name, dstlimit_procdir);
3055 +
3056 +       htable_selective_cleanup(hinfo, select_all);
3057 +       vfree(hinfo);
3058 +}
3059 +
3060 +static struct ipt_dstlimit_htable *htable_find_get(char *name)
3061 +{
3062 +       struct ipt_dstlimit_htable *hinfo;
3063 +
3064 +       READ_LOCK(&dstlimit_lock);
3065 +       list_for_each_entry(hinfo, &dstlimit_htables, list) {
3066 +               if (!strcmp(name, hinfo->pde->name)) {
3067 +                       atomic_inc(&hinfo->use);
3068 +                       READ_UNLOCK(&dstlimit_lock);
3069 +                       return hinfo;
3070 +               }
3071 +       }
3072 +       READ_UNLOCK(&dstlimit_lock);
3073 +
3074 +       return NULL;
3075 +}
3076 +
3077 +static void htable_put(struct ipt_dstlimit_htable *hinfo)
3078 +{
3079 +       if (atomic_dec_and_test(&hinfo->use)) {
3080 +               WRITE_LOCK(&dstlimit_lock);
3081 +               list_del(&hinfo->list);
3082 +               WRITE_UNLOCK(&dstlimit_lock);
3083 +               htable_destroy(hinfo);
3084 +       }
3085 +}
3086 +
3087 +
3088 +/* The algorithm used is the Simple Token Bucket Filter (TBF)
3089 + * see net/sched/sch_tbf.c in the linux source tree
3090 + */
3091 +
3092 +/* Rusty: This is my (non-mathematically-inclined) understanding of
3093 +   this algorithm.  The `average rate' in jiffies becomes your initial
3094 +   amount of credit `credit' and the most credit you can ever have
3095 +   `credit_cap'.  The `peak rate' becomes the cost of passing the
3096 +   test, `cost'.
3097 +
3098 +   `prev' tracks the last packet hit: you gain one credit per jiffy.
3099 +   If you get credit balance more than this, the extra credit is
3100 +   discarded.  Every time the match passes, you lose `cost' credits;
3101 +   if you don't have that many, the test fails.
3102 +
3103 +   See Alexey's formal explanation in net/sched/sch_tbf.c.
3104 +
3105 +   To get the maximum range, we multiply by this factor (ie. you get N
3106 +   credits per jiffy).  We want to allow a rate as low as 1 per day
3107 +   (slowest userspace tool allows), which means
3108 +   CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32 ie.
3109 +*/
3110 +#define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24))
3111 +
3112 +/* Repeated shift and or gives us all 1s, final shift and add 1 gives
3113 + * us the power of 2 below the theoretical max, so GCC simply does a
3114 + * shift. */
3115 +#define _POW2_BELOW2(x) ((x)|((x)>>1))
3116 +#define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2))
3117 +#define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4))
3118 +#define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8))
3119 +#define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16))
3120 +#define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1)
3121 +
3122 +#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
3123 +
3124 +/* Precision saver. */
3125 +static inline u_int32_t
3126 +user2credits(u_int32_t user)
3127 +{
3128 +       /* If multiplying would overflow... */
3129 +       if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY))
3130 +               /* Divide first. */
3131 +               return (user / IPT_DSTLIMIT_SCALE) * HZ * CREDITS_PER_JIFFY;
3132 +
3133 +       return (user * HZ * CREDITS_PER_JIFFY) / IPT_DSTLIMIT_SCALE;
3134 +}
3135 +
3136 +static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
3137 +{
3138 +       dh->rateinfo.credit += (now - xchg(&dh->rateinfo.prev, now)) 
3139 +                                       * CREDITS_PER_JIFFY;
3140 +       if (dh->rateinfo.credit > dh->rateinfo.credit_cap)
3141 +               dh->rateinfo.credit = dh->rateinfo.credit_cap;
3142 +}
3143 +
3144 +static int
3145 +dstlimit_match(const struct sk_buff *skb,
3146 +               const struct net_device *in,
3147 +               const struct net_device *out,
3148 +               const void *matchinfo,
3149 +               int offset,
3150 +               int *hotdrop)
3151 +{
3152 +       struct ipt_dstlimit_info *r = 
3153 +               ((struct ipt_dstlimit_info *)matchinfo)->u.master;
3154 +       struct ipt_dstlimit_htable *hinfo = r->hinfo;
3155 +       unsigned long now = jiffies;
3156 +       struct dsthash_ent *dh;
3157 +       struct dsthash_dst dst;
3158 +
3159 +       memset(&dst, 0, sizeof(dst));
3160 +
3161 +       /* dest ip is always in hash */
3162 +       dst.dst_ip = skb->nh.iph->daddr;
3163 +
3164 +       /* source ip only if respective hashmode, otherwise set to
3165 +        * zero */
3166 +       if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_SIP)
3167 +               dst.src_ip = skb->nh.iph->saddr;
3168 +
3169 +       /* dest port only if respective mode */
3170 +       if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_DPT) {
3171 +               u16 ports[2];
3172 +
3173 +               /* Must not be a fragment. */
3174 +               if (offset)
3175 +                       return 0;
3176 +
3177 +               /* Must be big enough to read ports (both UDP and TCP have
3178 +                  them at the start). */
3179 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
3180 +                       /* We've been asked to examine this packet, and we
3181 +                          can't.  Hence, no choice but to drop. */
3182 +                       *hotdrop = 1;
3183 +                       return 0;
3184 +               }
3185 +
3186 +               switch (skb->nh.iph->protocol) {
3187 +                       struct tcphdr *th;
3188 +                       struct udphdr *uh;
3189 +               case IPPROTO_TCP:
3190 +                       th = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
3191 +                       dst.port = th->dest;
3192 +                       break;
3193 +               case IPPROTO_UDP:
3194 +                       uh = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
3195 +                       dst.port = uh->dest;
3196 +                       break;
3197 +               default:
3198 +                       break;
3199 +               }
3200 +       } 
3201 +
3202 +       LOCK_BH(&hinfo->lock);
3203 +       dh = __dsthash_find(hinfo, &dst);
3204 +       if (!dh) {
3205 +               dh = __dsthash_alloc_init(hinfo, &dst);
3206 +
3207 +               if (!dh) {
3208 +                       /* enomem... don't match == DROP */
3209 +                       if (net_ratelimit())
3210 +                               printk(KERN_ERR "%s: ENOMEM\n", __FUNCTION__);
3211 +                       UNLOCK_BH(&hinfo->lock);
3212 +                       return 0;
3213 +               }
3214 +
3215 +               dh->expires = jiffies + MS2JIFFIES(hinfo->cfg.expire);
3216 +
3217 +               dh->rateinfo.prev = jiffies;
3218 +               dh->rateinfo.credit = user2credits(hinfo->cfg.avg * 
3219 +                                                       hinfo->cfg.burst);
3220 +               dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg * 
3221 +                                                       hinfo->cfg.burst);
3222 +               dh->rateinfo.cost = user2credits(hinfo->cfg.avg);
3223 +
3224 +               UNLOCK_BH(&hinfo->lock);
3225 +               return 1;
3226 +       }
3227 +
3228 +       /* update expiration timeout */
3229 +       dh->expires = now + MS2JIFFIES(hinfo->cfg.expire);
3230 +
3231 +       rateinfo_recalc(dh, now);
3232 +       if (dh->rateinfo.credit >= dh->rateinfo.cost) {
3233 +               /* We're underlimit. */
3234 +               dh->rateinfo.credit -= dh->rateinfo.cost;
3235 +               UNLOCK_BH(&hinfo->lock);
3236 +               return 1;
3237 +       }
3238 +
3239 +               UNLOCK_BH(&hinfo->lock);
3240 +
3241 +       /* default case: we're overlimit, thus don't match */
3242 +       return 0;
3243 +}
3244 +
3245 +static int
3246 +dstlimit_checkentry(const char *tablename,
3247 +                    const struct ipt_ip *ip,
3248 +                    void *matchinfo,
3249 +                    unsigned int matchsize,
3250 +                    unsigned int hook_mask)
3251 +{
3252 +       struct ipt_dstlimit_info *r = matchinfo;
3253 +
3254 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_dstlimit_info)))
3255 +               return 0;
3256 +
3257 +       /* Check for overflow. */
3258 +       if (r->cfg.burst == 0
3259 +           || user2credits(r->cfg.avg * r->cfg.burst) < 
3260 +                                       user2credits(r->cfg.avg)) {
3261 +               printk(KERN_ERR "ipt_dstlimit: Overflow, try lower: %u/%u\n",
3262 +                      r->cfg.avg, r->cfg.burst);
3263 +               return 0;
3264 +       }
3265 +
3266 +       if (r->cfg.mode == 0 
3267 +           || r->cfg.mode > (IPT_DSTLIMIT_HASH_DPT
3268 +                         |IPT_DSTLIMIT_HASH_DIP
3269 +                         |IPT_DSTLIMIT_HASH_SIP))
3270 +               return 0;
3271 +
3272 +       if (!r->cfg.gc_interval)
3273 +               return 0;
3274 +       
3275 +       if (!r->cfg.expire)
3276 +               return 0;
3277 +
3278 +       r->hinfo = htable_find_get(r->name);
3279 +       if (!r->hinfo && (htable_create(r) != 0)) {
3280 +               return 0;
3281 +       }
3282 +
3283 +       /* Ugly hack: For SMP, we only want to use one set */
3284 +       r->u.master = r;
3285 +
3286 +       return 1;
3287 +}
3288 +
3289 +static void
3290 +dstlimit_destroy(void *matchinfo, unsigned int matchsize)
3291 +{
3292 +       struct ipt_dstlimit_info *r = (struct ipt_dstlimit_info *) matchinfo;
3293 +
3294 +       htable_put(r->hinfo);
3295 +}
3296 +
3297 +static struct ipt_match ipt_dstlimit = { 
3298 +       .list = { .prev = NULL, .next = NULL }, 
3299 +       .name = "dstlimit", 
3300 +       .match = dstlimit_match, 
3301 +       .checkentry = dstlimit_checkentry, 
3302 +       .destroy = dstlimit_destroy,
3303 +       .me = THIS_MODULE 
3304 +};
3305 +
3306 +/* PROC stuff */
3307 +
3308 +static void *dl_seq_start(struct seq_file *s, loff_t *pos)
3309 +{
3310 +       struct proc_dir_entry *pde = s->private;
3311 +       struct ipt_dstlimit_htable *htable = pde->data;
3312 +       unsigned int *bucket;
3313 +
3314 +       LOCK_BH(&htable->lock);
3315 +       if (*pos >= htable->cfg.size)
3316 +               return NULL;
3317 +
3318 +       bucket = kmalloc(sizeof(unsigned int), GFP_KERNEL);
3319 +       if (!bucket)
3320 +               return ERR_PTR(-ENOMEM);
3321 +
3322 +       *bucket = *pos;
3323 +       return bucket;
3324 +}
3325 +
3326 +static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
3327 +{
3328 +       struct proc_dir_entry *pde = s->private;
3329 +       struct ipt_dstlimit_htable *htable = pde->data;
3330 +       unsigned int *bucket = (unsigned int *)v;
3331 +
3332 +       *pos = ++(*bucket);
3333 +       if (*pos >= htable->cfg.size) {
3334 +               kfree(v);
3335 +               return NULL;
3336 +       }
3337 +       return bucket;
3338 +}
3339 +
3340 +static void dl_seq_stop(struct seq_file *s, void *v)
3341 +{
3342 +       struct proc_dir_entry *pde = s->private;
3343 +       struct ipt_dstlimit_htable *htable = pde->data;
3344 +       unsigned int *bucket = (unsigned int *)v;
3345 +
3346 +       kfree(bucket);
3347 +
3348 +       UNLOCK_BH(&htable->lock);
3349 +}
3350 +
3351 +static inline int dl_seq_real_show(struct dsthash_ent *ent, struct seq_file *s)
3352 +{
3353 +       /* recalculate to show accurate numbers */
3354 +       rateinfo_recalc(ent, jiffies);
3355 +
3356 +       return seq_printf(s, "%ld %u.%u.%u.%u->%u.%u.%u.%u:%u %u %u %u\n",
3357 +                       (ent->expires - jiffies)/HZ,
3358 +                       NIPQUAD(ent->dst.src_ip),
3359 +                       NIPQUAD(ent->dst.dst_ip), ntohs(ent->dst.port),
3360 +                       ent->rateinfo.credit, ent->rateinfo.credit_cap,
3361 +                       ent->rateinfo.cost);
3362 +}
3363 +
3364 +static int dl_seq_show(struct seq_file *s, void *v)
3365 +{
3366 +       struct proc_dir_entry *pde = s->private;
3367 +       struct ipt_dstlimit_htable *htable = pde->data;
3368 +       unsigned int *bucket = (unsigned int *)v;
3369 +
3370 +       if (LIST_FIND_W(&htable->hash[*bucket], dl_seq_real_show,
3371 +                     struct dsthash_ent *, s)) {
3372 +               /* buffer was filled and unable to print that tuple */
3373 +               return 1;
3374 +       }
3375 +       return 0;
3376 +}
3377 +
3378 +static struct seq_operations dl_seq_ops = {
3379 +       .start = dl_seq_start,
3380 +       .next  = dl_seq_next,
3381 +       .stop  = dl_seq_stop,
3382 +       .show  = dl_seq_show
3383 +};
3384 +
3385 +static int dl_proc_open(struct inode *inode, struct file *file)
3386 +{
3387 +       int ret = seq_open(file, &dl_seq_ops);
3388 +
3389 +       if (!ret) {
3390 +               struct seq_file *sf = file->private_data;
3391 +               sf->private = PDE(inode);
3392 +       }
3393 +       return ret;
3394 +}
3395 +
3396 +static struct file_operations dl_file_ops = {
3397 +       .owner   = THIS_MODULE,
3398 +       .open    = dl_proc_open,
3399 +       .read    = seq_read,
3400 +       .llseek  = seq_lseek,
3401 +       .release = seq_release
3402 +};
3403 +
3404 +static int init_or_fini(int fini)
3405 +{
3406 +       int ret = 0;
3407 +
3408 +       if (fini)
3409 +               goto cleanup;
3410 +
3411 +       if (ipt_register_match(&ipt_dstlimit)) {
3412 +               ret = -EINVAL;
3413 +               goto cleanup_nothing;
3414 +       }
3415 +
3416 +       /* FIXME: do we really want HWCACHE_ALIGN since our objects are
3417 +        * quite small ? */
3418 +       dstlimit_cachep = kmem_cache_create("ipt_dstlimit",
3419 +                                           sizeof(struct dsthash_ent), 0,
3420 +                                           SLAB_HWCACHE_ALIGN, NULL, NULL);
3421 +       if (!dstlimit_cachep) {
3422 +               printk(KERN_ERR "Unable to create ipt_dstlimit slab cache\n");
3423 +               ret = -ENOMEM;
3424 +               goto cleanup_unreg_match;
3425 +       }
3426 +
3427 +       dstlimit_procdir = proc_mkdir("ipt_dstlimit", proc_net);
3428 +       if (!dstlimit_procdir) {
3429 +               printk(KERN_ERR "Unable to create proc dir entry\n");
3430 +               ret = -ENOMEM;
3431 +               goto cleanup_free_slab;
3432 +       }
3433 +
3434 +       return ret;
3435 +
3436 +cleanup:
3437 +       remove_proc_entry("ipt_dstlimit", proc_net);
3438 +cleanup_free_slab:
3439 +       kmem_cache_destroy(dstlimit_cachep);
3440 +cleanup_unreg_match:
3441 +       ipt_unregister_match(&ipt_dstlimit);
3442 +cleanup_nothing:
3443 +       return ret;
3444 +       
3445 +}
3446 +
3447 +static int __init init(void)
3448 +{
3449 +       return init_or_fini(0);
3450 +}
3451 +
3452 +static void __exit fini(void)
3453 +{
3454 +       init_or_fini(1);
3455 +}
3456 +
3457 +module_init(init);
3458 +module_exit(fini);
3459 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_fuzzy.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_fuzzy.c
3460 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_fuzzy.c  1970-01-01 00:00:00.000000000 +0000
3461 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_fuzzy.c      2004-03-22 08:28:32.000000000 +0000
3462 @@ -0,0 +1,185 @@
3463 +/*
3464 + *  This module implements a simple TSK FLC 
3465 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
3466 + * to limit , in an adaptive and flexible way , the packet rate crossing 
3467 + * a given stream . It serves as an initial and very simple (but effective)
3468 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
3469 + *  As a matter of fact , Fuzzy Logic can help us to insert any "behavior"  
3470 + * into our code in a precise , adaptive and efficient manner. 
3471 + *  The goal is very similar to that of "limit" match , but using techniques of
3472 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
3473 + * avoiding over and undershoots - and stuff like that .
3474 + *
3475 + *
3476 + * 2002-08-10  Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
3477 + * 2002-08-17  : Changed to eliminate floating point operations .
3478 + * 2002-08-23  : Coding style changes .
3479 +*/
3480 +
3481 +#include <linux/module.h>
3482 +#include <linux/skbuff.h>
3483 +#include <linux/ip.h>
3484 +#include <linux/random.h>
3485 +#include <net/tcp.h>
3486 +#include <linux/spinlock.h>
3487 +#include <linux/netfilter_ipv4/ip_tables.h>
3488 +#include <linux/netfilter_ipv4/ipt_fuzzy.h>
3489 +
3490 +/*
3491 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
3492 + Expressed in percentage
3493 +*/
3494 +
3495 +#define PAR_LOW                1/100
3496 +#define PAR_HIGH       1
3497 +
3498 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED ;
3499 +
3500 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
3501 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
3502 +MODULE_LICENSE("GPL");
3503 +
3504 +static  u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
3505 +{
3506 +       if (tx >= maxi)
3507 +               return 100;
3508 +
3509 +       if (tx <= mini)
3510 +               return 0;
3511 +
3512 +       return ( (100*(tx-mini)) / (maxi-mini) );
3513 +}
3514 +
3515 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
3516 +{
3517 +       if (tx <= mini)
3518 +               return 100;
3519 +
3520 +       if (tx >= maxi)
3521 +               return 0;
3522 +
3523 +       return ( (100*( maxi - tx ))  / ( maxi - mini ) );
3524 +}
3525 +
3526 +static int
3527 +ipt_fuzzy_match(const struct sk_buff *pskb,
3528 +              const struct net_device *in,
3529 +              const struct net_device *out,
3530 +              const void *matchinfo,
3531 +              int offset,
3532 +              int *hotdrop)
3533 +{
3534 +       /* From userspace */
3535 +       
3536 +       struct ipt_fuzzy_info *info = (struct ipt_fuzzy_info *) matchinfo;
3537 +
3538 +       u_int8_t random_number;
3539 +       unsigned long amount;
3540 +       u_int8_t howhigh, howlow;
3541 +       
3542 +
3543 +       spin_lock_bh(&fuzzy_lock); /* Rise the lock */
3544 +
3545 +       info->bytes_total += pskb->len;
3546 +       info->packets_total++;
3547 +
3548 +       info->present_time = jiffies;
3549 +       
3550 +       if (info->present_time >= info->previous_time)
3551 +               amount = info->present_time - info->previous_time;
3552 +       else { 
3553 +               /* There was a transition : I choose to re-sample 
3554 +                  and keep the old acceptance rate...
3555 +               */
3556 +
3557 +               amount = 0;
3558 +               info->previous_time = info->present_time;
3559 +               info->bytes_total = info->packets_total = 0;
3560 +       };
3561 +       
3562 +       if (amount > HZ/10) /* More than 100 ms elapsed ... */
3563 +       {
3564 +
3565 +               info->mean_rate = (u_int32_t) ((HZ*info->packets_total)  \
3566 +                                       / amount );
3567 +
3568 +               info->previous_time = info->present_time;
3569 +               info->bytes_total = info->packets_total = 0;
3570 +
3571 +               howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
3572 +               howlow  = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
3573 +
3574 +               info->acceptance_rate = (u_int8_t) \
3575 +                          (howhigh*PAR_LOW + PAR_HIGH*howlow);
3576 +
3577 +               /* In fact , the above defuzzification would require a denominator
3578 +                  proportional to (howhigh+howlow) but , in this particular case ,
3579 +                  that expression is constant .
3580 +                  An imediate consequence is that it isn't necessary to call 
3581 +                  both mf_high and mf_low - but to keep things understandable ,
3582 +                  I did so .  */ 
3583 +
3584 +       }
3585 +       
3586 +       spin_unlock_bh(&fuzzy_lock); /* Release the lock */
3587 +
3588 +
3589 +       if ( info->acceptance_rate < 100 )
3590 +       {                
3591 +               get_random_bytes((void *)(&random_number), 1);
3592 +
3593 +               /*  If within the acceptance , it can pass => don't match */
3594 +               if (random_number <= (255 * info->acceptance_rate) / 100)
3595 +                       return 0;
3596 +               else
3597 +                       return 1; /* It can't pass ( It matches ) */
3598 +       } ;
3599 +
3600 +       return 0; /* acceptance_rate == 100 % => Everything passes ... */
3601 +       
3602 +}
3603 +
3604 +static int
3605 +ipt_fuzzy_checkentry(const char *tablename,
3606 +                  const struct ipt_ip *e,
3607 +                  void *matchinfo,
3608 +                  unsigned int matchsize,
3609 +                  unsigned int hook_mask)
3610 +{
3611 +       
3612 +       const struct ipt_fuzzy_info *info = matchinfo;
3613 +
3614 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_fuzzy_info))) {
3615 +               printk("ipt_fuzzy: matchsize %u != %u\n", matchsize,
3616 +                      IPT_ALIGN(sizeof(struct ipt_fuzzy_info)));
3617 +               return 0;
3618 +       }
3619 +
3620 +       if ((info->minimum_rate < MINFUZZYRATE ) || (info->maximum_rate > MAXFUZZYRATE)
3621 +           || (info->minimum_rate >= info->maximum_rate )) {
3622 +               printk("ipt_fuzzy: BAD limits , please verify !!!\n");
3623 +               return 0;
3624 +       }
3625 +
3626 +       return 1;
3627 +}
3628 +
3629 +static struct ipt_match ipt_fuzzy_reg = { 
3630 +       .name = "fuzzy",
3631 +       .match = ipt_fuzzy_match,
3632 +       .checkentry = ipt_fuzzy_checkentry,
3633 +       .me = THIS_MODULE
3634 +};
3635 +
3636 +static int __init init(void)
3637 +{
3638 +       return ipt_register_match(&ipt_fuzzy_reg);
3639 +}
3640 +
3641 +static void __exit fini(void)
3642 +{
3643 +       ipt_unregister_match(&ipt_fuzzy_reg);
3644 +}
3645 +
3646 +module_init(init);
3647 +module_exit(fini);
3648 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_helper.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_helper.c
3649 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_helper.c 2004-03-20 00:11:34.000000000 +0000
3650 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_helper.c     2004-03-22 08:27:11.000000000 +0000
3651 @@ -41,17 +41,17 @@
3652         struct ip_conntrack_expect *exp;
3653         struct ip_conntrack *ct;
3654         enum ip_conntrack_info ctinfo;
3655 -       int ret = 0;
3656 +       int ret = info->invert;
3657         
3658         ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
3659         if (!ct) {
3660                 DEBUGP("ipt_helper: Eek! invalid conntrack?\n");
3661 -               return 0;
3662 +               return ret;
3663         }
3664  
3665         if (!ct->master) {
3666                 DEBUGP("ipt_helper: conntrack %p has no master\n", ct);
3667 -               return 0;
3668 +               return ret;
3669         }
3670  
3671         exp = ct->master;
3672 @@ -71,8 +71,8 @@
3673         DEBUGP("master's name = %s , info->name = %s\n", 
3674                 exp->expectant->helper->name, info->name);
3675  
3676 -       ret = !strncmp(exp->expectant->helper->name, info->name, 
3677 -                      strlen(exp->expectant->helper->name)) ^ info->invert;
3678 +       ret ^= !strncmp(exp->expectant->helper->name, info->name, 
3679 +                       strlen(exp->expectant->helper->name));
3680  out_unlock:
3681         READ_UNLOCK(&ip_conntrack_lock);
3682         return ret;
3683 @@ -108,7 +108,6 @@
3684  
3685  static int __init init(void)
3686  {
3687 -       need_ip_conntrack();
3688         return ipt_register_match(&helper_match);
3689  }
3690  
3691 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_ipv4options.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_ipv4options.c
3692 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_ipv4options.c    1970-01-01 00:00:00.000000000 +0000
3693 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_ipv4options.c        2004-03-22 08:28:47.000000000 +0000
3694 @@ -0,0 +1,172 @@
3695 +/*
3696 +  This is a module which is used to match ipv4 options.
3697 +  This file is distributed under the terms of the GNU General Public
3698 +  License (GPL). Copies of the GPL can be obtained from:
3699 +  ftp://prep.ai.mit.edu/pub/gnu/GPL
3700 +
3701 +  11-mars-2001 Fabrice MARIE <fabrice@netfilter.org> : initial development.
3702 +  12-july-2001 Fabrice MARIE <fabrice@netfilter.org> : added router-alert otions matching. Fixed a bug with no-srr
3703 +  12-august-2001 Imran Patel <ipatel@crosswinds.net> : optimization of the match.
3704 +  18-november-2001 Fabrice MARIE <fabrice@netfilter.org> : added [!] 'any' option match.
3705 +  19-february-2004 Harald Welte <laforge@netfilter.org> : merge with 2.6.x
3706 +*/
3707 +
3708 +#include <linux/module.h>
3709 +#include <linux/skbuff.h>
3710 +#include <net/ip.h>
3711 +
3712 +#include <linux/netfilter_ipv4/ip_tables.h>
3713 +#include <linux/netfilter_ipv4/ipt_ipv4options.h>
3714 +
3715 +MODULE_LICENSE("GPL");
3716 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
3717 +
3718 +static int
3719 +match(const struct sk_buff *skb,
3720 +      const struct net_device *in,
3721 +      const struct net_device *out,
3722 +      const void *matchinfo,
3723 +      int offset,
3724 +      int *hotdrop)
3725 +{
3726 +       const struct ipt_ipv4options_info *info = matchinfo;   /* match info for rule */
3727 +       const struct iphdr *iph = skb->nh.iph;
3728 +       const struct ip_options *opt;
3729 +
3730 +       if (iph->ihl * 4 == sizeof(struct iphdr)) {
3731 +               /* No options, so we match only the "DONTs" and the "IGNOREs" */
3732 +
3733 +               if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) ||
3734 +                   ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3735 +                   ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
3736 +                   ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
3737 +                   ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
3738 +                    ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
3739 +                       return 0;
3740 +               return 1;
3741 +       }
3742 +       else {
3743 +               if ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)
3744 +                       /* there are options, and we don't need to care which one */
3745 +                       return 1;
3746 +               else {
3747 +                       if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
3748 +                               /* there are options but we don't want any ! */
3749 +                               return 0;
3750 +               }
3751 +       }
3752 +
3753 +       opt = &(IPCB(skb)->opt);
3754 +
3755 +       /* source routing */
3756 +       if ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) {
3757 +               if (!((opt->srr) & (opt->is_strictroute)))
3758 +                       return 0;
3759 +       }
3760 +       else if ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) {
3761 +               if (!((opt->srr) & (!opt->is_strictroute)))
3762 +                       return 0;
3763 +       }
3764 +       else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) {
3765 +               if (opt->srr)
3766 +                       return 0;
3767 +       }
3768 +       /* record route */
3769 +       if ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) {
3770 +               if (!opt->rr)
3771 +                       return 0;
3772 +       }
3773 +       else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) {
3774 +               if (opt->rr)
3775 +                       return 0;
3776 +       }
3777 +       /* timestamp */
3778 +       if ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) {
3779 +               if (!opt->ts)
3780 +                       return 0;
3781 +       }
3782 +       else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) {
3783 +               if (opt->ts)
3784 +                       return 0;
3785 +       }
3786 +       /* router-alert option  */
3787 +       if ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) {
3788 +               if (!opt->router_alert)
3789 +                       return 0;
3790 +       }
3791 +       else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) {
3792 +               if (opt->router_alert)
3793 +                       return 0;
3794 +       }
3795 +
3796 +       /* we match ! */
3797 +       return 1;
3798 +}
3799 +
3800 +static int
3801 +checkentry(const char *tablename,
3802 +          const struct ipt_ip *ip,
3803 +          void *matchinfo,
3804 +          unsigned int matchsize,
3805 +          unsigned int hook_mask)
3806 +{
3807 +       const struct ipt_ipv4options_info *info = matchinfo;   /* match info for rule */
3808 +       /* Check the size */
3809 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_ipv4options_info)))
3810 +               return 0;
3811 +       /* Now check the coherence of the data ... */
3812 +       if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) &&
3813 +           (((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) ||
3814 +            ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) ||
3815 +            ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) ||
3816 +            ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) ||
3817 +            ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)))
3818 +               return 0; /* opposites */
3819 +       if (((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) &&
3820 +           (((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
3821 +            ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3822 +            ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
3823 +            ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
3824 +            ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) ||
3825 +            ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)))
3826 +               return 0; /* opposites */
3827 +       if (((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) &&
3828 +           ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR))
3829 +               return 0; /* cannot match in the same time loose and strict source routing */
3830 +       if ((((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3831 +            ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR)) &&
3832 +           ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR))
3833 +               return 0; /* opposites */
3834 +       if (((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) &&
3835 +           ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR))
3836 +               return 0; /* opposites */
3837 +       if (((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) &&
3838 +           ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
3839 +               return 0; /* opposites */
3840 +       if (((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) &&
3841 +           ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
3842 +               return 0; /* opposites */
3843 +
3844 +       /* everything looks ok. */
3845 +       return 1;
3846 +}
3847 +
3848 +static struct ipt_match ipv4options_match = { 
3849 +       .name = "ipv4options",
3850 +       .match = match,
3851 +       .checkentry = checkentry,
3852 +       .me = THIS_MODULE
3853 +};
3854 +
3855 +static int __init init(void)
3856 +{
3857 +       return ipt_register_match(&ipv4options_match);
3858 +}
3859 +
3860 +static void __exit fini(void)
3861 +{
3862 +       ipt_unregister_match(&ipv4options_match);
3863 +}
3864 +
3865 +module_init(init);
3866 +module_exit(fini);
3867 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_mport.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_mport.c
3868 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_mport.c  1970-01-01 00:00:00.000000000 +0000
3869 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_mport.c      2004-03-22 08:28:51.000000000 +0000
3870 @@ -0,0 +1,116 @@
3871 +/* Kernel module to match one of a list of TCP/UDP ports: ports are in
3872 +   the same place so we can treat them as equal. */
3873 +#include <linux/module.h>
3874 +#include <linux/types.h>
3875 +#include <linux/udp.h>
3876 +#include <linux/skbuff.h>
3877 +
3878 +#include <linux/netfilter_ipv4/ipt_mport.h>
3879 +#include <linux/netfilter_ipv4/ip_tables.h>
3880 +
3881 +MODULE_LICENSE("GPL");
3882 +
3883 +#if 0
3884 +#define duprintf(format, args...) printk(format , ## args)
3885 +#else
3886 +#define duprintf(format, args...)
3887 +#endif
3888 +
3889 +/* Returns 1 if the port is matched by the test, 0 otherwise. */
3890 +static inline int
3891 +ports_match(const struct ipt_mport *minfo, u_int16_t src, u_int16_t dst)
3892 +{
3893 +       unsigned int i;
3894 +        unsigned int m;
3895 +        u_int16_t pflags = minfo->pflags;
3896 +       for (i=0, m=1; i<IPT_MULTI_PORTS; i++, m<<=1) {
3897 +                u_int16_t s, e;
3898 +
3899 +                if (pflags & m
3900 +                    && minfo->ports[i] == 65535)
3901 +                        return 0;
3902 +
3903 +                s = minfo->ports[i];
3904 +
3905 +                if (pflags & m) {
3906 +                        e = minfo->ports[++i];
3907 +                        m <<= 1;
3908 +                } else
3909 +                        e = s;
3910 +
3911 +                if (minfo->flags & IPT_MPORT_SOURCE
3912 +                    && src >= s && src <= e)
3913 +                        return 1;
3914 +
3915 +               if (minfo->flags & IPT_MPORT_DESTINATION
3916 +                   && dst >= s && dst <= e)
3917 +                       return 1;
3918 +       }
3919 +
3920 +       return 0;
3921 +}
3922 +
3923 +static int
3924 +match(const struct sk_buff *skb,
3925 +      const struct net_device *in,
3926 +      const struct net_device *out,
3927 +      const void *matchinfo,
3928 +      int offset,
3929 +      int *hotdrop)
3930 +{
3931 +       u16 ports[2];
3932 +       const struct ipt_mport *minfo = matchinfo;
3933 +
3934 +       if (offset)
3935 +               return 0;
3936 +
3937 +       /* Must be big enough to read ports (both UDP and TCP have
3938 +           them at the start). */
3939 +       if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
3940 +               /* We've been asked to examine this packet, and we
3941 +                  can't.  Hence, no choice but to drop. */
3942 +                       duprintf("ipt_multiport:"
3943 +                                " Dropping evil offset=0 tinygram.\n");
3944 +                       *hotdrop = 1;
3945 +                       return 0;
3946 +       }
3947 +
3948 +       return ports_match(minfo, ntohs(ports[0]), ntohs(ports[1]));
3949 +}
3950 +
3951 +/* Called when user tries to insert an entry of this type. */
3952 +static int
3953 +checkentry(const char *tablename,
3954 +          const struct ipt_ip *ip,
3955 +          void *matchinfo,
3956 +          unsigned int matchsize,
3957 +          unsigned int hook_mask)
3958 +{
3959 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_mport)))
3960 +               return 0;
3961 +
3962 +       /* Must specify proto == TCP/UDP, no unknown flags or bad count */
3963 +       return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
3964 +               && !(ip->invflags & IPT_INV_PROTO)
3965 +               && matchsize == IPT_ALIGN(sizeof(struct ipt_mport));
3966 +}
3967 +
3968 +static struct ipt_match mport_match = { 
3969 +       .name = "mport",
3970 +       .match = &match,
3971 +       .checkentry = &checkentry,
3972 +       .me = THIS_MODULE
3973 +};
3974 +
3975 +static int __init init(void)
3976 +{
3977 +       return ipt_register_match(&mport_match);
3978 +}
3979 +
3980 +static void __exit fini(void)
3981 +{
3982 +       ipt_unregister_match(&mport_match);
3983 +}
3984 +
3985 +module_init(init);
3986 +module_exit(fini);
3987 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_nth.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_nth.c
3988 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_nth.c    1970-01-01 00:00:00.000000000 +0000
3989 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_nth.c        2004-03-22 08:29:02.000000000 +0000
3990 @@ -0,0 +1,166 @@
3991 +/*
3992 +  This is a module which is used for match support for every Nth packet
3993 +  This file is distributed under the terms of the GNU General Public
3994 +  License (GPL). Copies of the GPL can be obtained from:
3995 +     ftp://prep.ai.mit.edu/pub/gnu/GPL
3996 +
3997 +  2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
3998 +  2001-09-20 Richard Wagner (rwagner@cloudnet.com)
3999 +        * added support for multiple counters
4000 +        * added support for matching on individual packets
4001 +          in the counter cycle
4002 +  2004-02-19 Harald Welte <laforge@netfilter.org>
4003 +       * port to 2.6.x
4004 +
4005 +*/
4006 +
4007 +#include <linux/module.h>
4008 +#include <linux/skbuff.h>
4009 +#include <linux/ip.h>
4010 +#include <net/tcp.h>
4011 +#include <linux/spinlock.h>
4012 +#include <linux/netfilter_ipv4/ip_tables.h>
4013 +#include <linux/netfilter_ipv4/ipt_nth.h>
4014 +
4015 +MODULE_LICENSE("GPL");
4016 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
4017 +
4018 +/*
4019 + * State information.
4020 + */
4021 +struct state {
4022 +       spinlock_t lock;
4023 +       u_int16_t number;
4024 +};
4025 +
4026 +static struct state states[IPT_NTH_NUM_COUNTERS];
4027 +
4028 +static int
4029 +ipt_nth_match(const struct sk_buff *pskb,
4030 +             const struct net_device *in,
4031 +             const struct net_device *out,
4032 +             const void *matchinfo,
4033 +             int offset,
4034 +             int *hotdrop)
4035 +{
4036 +       /* Parameters from userspace */
4037 +       const struct ipt_nth_info *info = matchinfo;
4038 +        unsigned counter = info->counter;
4039 +               if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS)) 
4040 +       {
4041 +                       printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
4042 +               return 0;
4043 +        };
4044 +
4045 +        spin_lock(&states[counter].lock);
4046 +
4047 +        /* Are we matching every nth packet?*/
4048 +        if (info->packet == 0xFF)
4049 +        {
4050 +               /* We're matching every nth packet and only every nth packet*/
4051 +               /* Do we match or invert match? */
4052 +               if (info->not == 0)
4053 +               {
4054 +                       if (states[counter].number == 0)
4055 +                       {
4056 +                               ++states[counter].number;
4057 +                               goto match;
4058 +                       }
4059 +                       if (states[counter].number >= info->every)
4060 +                               states[counter].number = 0; /* reset the counter */
4061 +                       else
4062 +                               ++states[counter].number;
4063 +                       goto dontmatch;
4064 +               }
4065 +               else
4066 +               {
4067 +                       if (states[counter].number == 0)
4068 +                       {
4069 +                               ++states[counter].number;
4070 +                               goto dontmatch;
4071 +                       }
4072 +                       if (states[counter].number >= info->every)
4073 +                               states[counter].number = 0;
4074 +                       else
4075 +                               ++states[counter].number;
4076 +                       goto match;
4077 +               }
4078 +        }
4079 +        else
4080 +        {
4081 +               /* We're using the --packet, so there must be a rule for every value */
4082 +               if (states[counter].number == info->packet)
4083 +               {
4084 +                       /* only increment the counter when a match happens */
4085 +                       if (states[counter].number >= info->every)
4086 +                               states[counter].number = 0; /* reset the counter */
4087 +                       else
4088 +                               ++states[counter].number;
4089 +                       goto match;
4090 +               }
4091 +               else
4092 +                       goto dontmatch;
4093 +       }
4094 +
4095 + dontmatch:
4096 +       /* don't match */
4097 +       spin_unlock(&states[counter].lock);
4098 +       return 0;
4099 +
4100 + match:
4101 +       spin_unlock(&states[counter].lock);
4102 +       return 1;
4103 +}
4104 +
4105 +static int
4106 +ipt_nth_checkentry(const char *tablename,
4107 +                  const struct ipt_ip *e,
4108 +                  void *matchinfo,
4109 +                  unsigned int matchsize,
4110 +                  unsigned int hook_mask)
4111 +{
4112 +       /* Parameters from userspace */
4113 +       const struct ipt_nth_info *info = matchinfo;
4114 +        unsigned counter = info->counter;
4115 +        if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS)) 
4116 +       {
4117 +               printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
4118 +                       return 0;
4119 +               };
4120 +
4121 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_nth_info))) {
4122 +               printk("nth: matchsize %u != %u\n", matchsize,
4123 +                      IPT_ALIGN(sizeof(struct ipt_nth_info)));
4124 +               return 0;
4125 +       }
4126 +
4127 +       states[counter].number = info->startat;
4128 +
4129 +       return 1;
4130 +}
4131 +
4132 +static struct ipt_match ipt_nth_reg = { 
4133 +       .name = "nth",
4134 +       .match = ipt_nth_match,
4135 +       .checkentry = ipt_nth_checkentry,
4136 +       .me = THIS_MODULE
4137 +};
4138 +
4139 +static int __init init(void)
4140 +{
4141 +       unsigned counter;
4142 +
4143 +       memset(&states, 0, sizeof(states));
4144 +        for (counter = 0; counter < IPT_NTH_NUM_COUNTERS; counter++) 
4145 +               spin_lock_init(&(states[counter].lock));
4146 +
4147 +       return ipt_register_match(&ipt_nth_reg);
4148 +}
4149 +
4150 +static void __exit fini(void)
4151 +{
4152 +       ipt_unregister_match(&ipt_nth_reg);
4153 +}
4154 +
4155 +module_init(init);
4156 +module_exit(fini);
4157 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_osf.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_osf.c
4158 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_osf.c    1970-01-01 00:00:00.000000000 +0000
4159 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_osf.c        2004-03-22 08:29:11.000000000 +0000
4160 @@ -0,0 +1,865 @@
4161 +/*
4162 + * ipt_osf.c
4163 + *
4164 + * Copyright (c) 2003 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
4165 + *
4166 + *
4167 + * This program is free software; you can redistribute it and/or modify
4168 + * it under the terms of the GNU General Public License as published by
4169 + * the Free Software Foundation; either version 2 of the License, or
4170 + * (at your option) any later version.
4171 + *
4172 + * This program is distributed in the hope that it will be useful,
4173 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4174 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4175 + * GNU General Public License for more details.
4176 + *
4177 + * You should have received a copy of the GNU General Public License
4178 + * along with this program; if not, write to the Free Software
4179 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4180 + */
4181 +
4182 +/*
4183 + * OS fingerprint matching module.
4184 + * It simply compares various parameters from SYN packet with
4185 + * some hardcoded ones.
4186 + *
4187 + * Original table was created by Michal Zalewski <lcamtuf@coredump.cx>
4188 + * for his p0f.
4189 + */
4190 +
4191 +#include <linux/config.h>
4192 +#include <linux/kernel.h>
4193 +#include <linux/types.h>
4194 +#include <linux/string.h>
4195 +#include <linux/smp.h>
4196 +#include <linux/module.h>
4197 +#include <linux/skbuff.h>
4198 +#include <linux/file.h>
4199 +#include <linux/ip.h>
4200 +#include <linux/proc_fs.h>
4201 +#include <linux/fs.h>
4202 +#include <linux/slab.h>
4203 +#include <linux/spinlock.h>
4204 +#include <linux/ctype.h>
4205 +#include <linux/list.h>
4206 +#include <linux/if.h>
4207 +
4208 +#include <net/sock.h>
4209 +#include <net/ip.h>
4210 +
4211 +#include <linux/netfilter_ipv4/ip_tables.h>
4212 +
4213 +#include <linux/netfilter_ipv4/ipt_osf.h>
4214 +
4215 +#define OSF_DEBUG
4216 +
4217 +#ifdef OSF_DEBUG
4218 +#define log(x...)              printk(KERN_INFO "ipt_osf: " x)
4219 +#define loga(x...)             printk(x)
4220 +#else
4221 +#define log(x...)              do {} while(0)
4222 +#define loga(x...)             do {} while(0)
4223 +#endif
4224 +
4225 +#define FMATCH_WRONG           0
4226 +#define FMATCH_OK              1
4227 +#define FMATCH_OPT_WRONG       2
4228 +
4229 +#define OPTDEL                 ','
4230 +#define OSFPDEL                ':'
4231 +#define MAXOPTSTRLEN           128
4232 +#define OSFFLUSH               "FLUSH"
4233 +
4234 +static rwlock_t osf_lock = RW_LOCK_UNLOCKED;
4235 +static spinlock_t ipt_osf_netlink_lock = SPIN_LOCK_UNLOCKED;
4236 +static struct list_head        finger_list;    
4237 +static int match(const struct sk_buff *, const struct net_device *, const struct net_device *,
4238 +                     const void *, int, 
4239 +                     const void *, u_int16_t, 
4240 +                     int *);
4241 +static int checkentry(const char *, const struct ipt_ip *, void *,
4242 +                          unsigned int, unsigned int);
4243 +
4244 +static unsigned long seq, ipt_osf_groups = 1;
4245 +static struct sock *nts;
4246 +
4247 +static struct ipt_match osf_match = 
4248 +{ 
4249 +       { NULL, NULL }, 
4250 +       "osf", 
4251 +       &match, 
4252 +       &checkentry, 
4253 +       NULL, 
4254 +       THIS_MODULE 
4255 +};
4256 +
4257 +static void ipt_osf_nlsend(struct osf_finger *f, const struct sk_buff *sk)
4258 +{
4259 +       unsigned int size;
4260 +       struct sk_buff *skb;
4261 +       struct ipt_osf_nlmsg *data;
4262 +       struct nlmsghdr *nlh;
4263 +
4264 +       size = NLMSG_SPACE(sizeof(struct ipt_osf_nlmsg));
4265 +
4266 +       skb = alloc_skb(size, GFP_ATOMIC);
4267 +       if (!skb)
4268 +       {
4269 +               log("skb_alloc() failed.\n");
4270 +               return;
4271 +       }
4272 +       
4273 +       nlh = NLMSG_PUT(skb, 0, seq++, NLMSG_DONE, size - sizeof(*nlh));
4274 +       
4275 +       data = (struct ipt_osf_nlmsg *)NLMSG_DATA(nlh);
4276 +
4277 +       memcpy(&data->f, f, sizeof(struct osf_finger));
4278 +       memcpy(&data->ip, sk->nh.iph, sizeof(struct iphdr));
4279 +       memcpy(&data->tcp, (struct tcphdr *)((u_int32_t *)sk->nh.iph + sk->nh.iph->ihl), sizeof(struct tcphdr));
4280 +
4281 +       NETLINK_CB(skb).dst_groups = ipt_osf_groups;
4282 +       netlink_broadcast(nts, skb, 0, ipt_osf_groups, GFP_ATOMIC);
4283 +
4284 +nlmsg_failure:
4285 +       return;
4286 +}
4287 +
4288 +static inline int smart_dec(const struct sk_buff *skb, unsigned long flags, unsigned char f_ttl)
4289 +{
4290 +       struct iphdr *ip = skb->nh.iph;
4291 +
4292 +       if (flags & IPT_OSF_SMART)
4293 +       {
4294 +               struct in_device *in_dev = in_dev_get(skb->dev);
4295 +
4296 +               for_ifa(in_dev)
4297 +               {
4298 +                       if (inet_ifa_match(ip->saddr, ifa))
4299 +                       {
4300 +                               in_dev_put(in_dev);
4301 +                               return (ip->ttl == f_ttl);
4302 +                       }
4303 +               }
4304 +               endfor_ifa(in_dev);
4305 +               
4306 +               in_dev_put(in_dev);
4307 +               return (ip->ttl <= f_ttl);
4308 +       }
4309 +       else
4310 +               return (ip->ttl == f_ttl);
4311 +}
4312 +
4313 +static int
4314 +match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out,
4315 +      const void *matchinfo, int offset,
4316 +      const void *hdr, u_int16_t datalen,
4317 +      int *hotdrop)
4318 +{
4319 +       struct ipt_osf_info *info = (struct ipt_osf_info *)matchinfo;
4320 +       struct iphdr *ip = skb->nh.iph;
4321 +       struct tcphdr *tcp;
4322 +       int fmatch = FMATCH_WRONG, fcount = 0;
4323 +       unsigned long totlen, optsize = 0, window;
4324 +       unsigned char df, *optp = NULL, *_optp = NULL;
4325 +       char check_WSS = 0;
4326 +       struct list_head *ent;
4327 +       struct osf_finger *f;
4328 +
4329 +       if (!ip || !info)
4330 +               return 0;
4331 +                               
4332 +       tcp = (struct tcphdr *)((u_int32_t *)ip + ip->ihl);
4333 +
4334 +       if (!tcp->syn)
4335 +               return 0;
4336 +       
4337 +       totlen = ntohs(ip->tot_len);
4338 +       df = ((ntohs(ip->frag_off) & IP_DF)?1:0);
4339 +       window = ntohs(tcp->window);
4340 +       
4341 +       if (tcp->doff*4 > sizeof(struct tcphdr))
4342 +       {
4343 +               _optp = optp = (char *)(tcp+1);
4344 +               optsize = tcp->doff*4 - sizeof(struct tcphdr);
4345 +       }
4346 +
4347 +       
4348 +       /* Actually we can create hash/table of all genres and search
4349 +        * only in appropriate part, but here is initial variant,
4350 +        * so will use slow path.
4351 +        */
4352 +       read_lock(&osf_lock);
4353 +       list_for_each(ent, &finger_list)
4354 +       {
4355 +               f = list_entry(ent, struct osf_finger, flist);
4356 +       
4357 +               if (!(info->flags & IPT_OSF_LOG) && strcmp(info->genre, f->genre)) 
4358 +                       continue;
4359 +
4360 +               optp = _optp;
4361 +               fmatch = FMATCH_WRONG;
4362 +
4363 +               if (totlen == f->ss && df == f->df && 
4364 +                       smart_dec(skb, info->flags, f->ttl))
4365 +               {
4366 +                       unsigned long foptsize;
4367 +                       int optnum;
4368 +                       unsigned short mss = 0;
4369 +
4370 +                       check_WSS = 0;
4371 +
4372 +                       switch (f->wss.wc)
4373 +                       {
4374 +                               case 0:   check_WSS = 0; break;
4375 +                               case 'S': check_WSS = 1; break;
4376 +                               case 'T': check_WSS = 2; break;
4377 +                               case '%': check_WSS = 3; break;
4378 +                               default: log("Wrong fingerprint wss.wc=%d, %s - %s\n", 
4379 +                                                        f->wss.wc, f->genre, f->details);
4380 +                                        check_WSS = 4;
4381 +                                        break;
4382 +                       }
4383 +                       if (check_WSS == 4)
4384 +                               continue;
4385 +
4386 +                       /* Check options */
4387 +
4388 +                       foptsize = 0;
4389 +                       for (optnum=0; optnum<f->opt_num; ++optnum)
4390 +                               foptsize += f->opt[optnum].length;
4391 +
4392 +                               
4393 +                       if (foptsize > MAX_IPOPTLEN || optsize > MAX_IPOPTLEN || optsize != foptsize)
4394 +                               continue;
4395 +
4396 +                       if (!optp)
4397 +                       {
4398 +                               fmatch = FMATCH_OK;
4399 +                               loga("\tYEP : matching without options.\n");
4400 +                               if ((info->flags & IPT_OSF_LOG) && 
4401 +                                       info->loglevel == IPT_OSF_LOGLEVEL_FIRST)
4402 +                                       break;
4403 +                               else
4404 +                                       continue;
4405 +                       }
4406 +                       
4407 +
4408 +                       for (optnum=0; optnum<f->opt_num; ++optnum)
4409 +                       {
4410 +                               if (f->opt[optnum].kind == (*optp)) 
4411 +                               {
4412 +                                       unsigned char len = f->opt[optnum].length;
4413 +                                       unsigned char *optend = optp + len;
4414 +                                       int loop_cont = 0;
4415 +
4416 +                                       fmatch = FMATCH_OK;
4417 +
4418 +
4419 +                                       switch (*optp)
4420 +                                       {
4421 +                                               case OSFOPT_MSS:
4422 +                                                       mss = ntohs(*(unsigned short *)(optp+2));
4423 +                                                       break;
4424 +                                               case OSFOPT_TS:
4425 +                                                       loop_cont = 1;
4426 +                                                       break;
4427 +                                       }
4428 +                                       
4429 +                                       if (loop_cont)
4430 +                                       {
4431 +                                               optp = optend;
4432 +                                               continue;
4433 +                                       }
4434 +                                       
4435 +                                       if (len != 1)
4436 +                                       {
4437 +                                               /* Skip kind and length fields*/
4438 +                                               optp += 2; 
4439 +
4440 +                                               if (f->opt[optnum].wc.val != 0)
4441 +                                               {
4442 +                                                       unsigned long tmp = 0;
4443 +                                                       
4444 +                                                       /* Hmmm... It looks a bit ugly. :) */
4445 +                                                       memcpy(&tmp, optp, 
4446 +                                                               (len > sizeof(unsigned long)?
4447 +                                                                       sizeof(unsigned long):len));
4448 +                                                       /* 2 + 2: optlen(2 bytes) + 
4449 +                                                        *      kind(1 byte) + length(1 byte) */
4450 +                                                       if (len == 4) 
4451 +                                                               tmp = ntohs(tmp);
4452 +                                                       else
4453 +                                                               tmp = ntohl(tmp);
4454 +
4455 +                                                       if (f->opt[optnum].wc.wc == '%')
4456 +                                                       {
4457 +                                                               if ((tmp % f->opt[optnum].wc.val) != 0)
4458 +                                                                       fmatch = FMATCH_OPT_WRONG;
4459 +                                                       }
4460 +                                                       else if (tmp != f->opt[optnum].wc.val)
4461 +                                                               fmatch = FMATCH_OPT_WRONG;
4462 +                                               }
4463 +                                       }
4464 +
4465 +                                       optp = optend;
4466 +                               }
4467 +                               else
4468 +                                       fmatch = FMATCH_OPT_WRONG;
4469 +
4470 +                               if (fmatch != FMATCH_OK)
4471 +                                       break;
4472 +                       }
4473 +
4474 +                       if (fmatch != FMATCH_OPT_WRONG)
4475 +                       {
4476 +                               fmatch = FMATCH_WRONG;
4477 +
4478 +                               switch (check_WSS)
4479 +                               {
4480 +                                       case 0:
4481 +                                               if (f->wss.val == 0 || window == f->wss.val)
4482 +                                                       fmatch = FMATCH_OK;
4483 +                                               break;
4484 +                                       case 1: /* MSS */
4485 +/* Lurked in OpenBSD */
4486 +#define SMART_MSS      1460
4487 +                                               if (window == f->wss.val*mss || 
4488 +                                                       window == f->wss.val*SMART_MSS)
4489 +                                                       fmatch = FMATCH_OK;
4490 +                                               break;
4491 +                                       case 2: /* MTU */
4492 +                                               if (window == f->wss.val*(mss+40) ||
4493 +                                                       window == f->wss.val*(SMART_MSS+40))
4494 +                                                       fmatch = FMATCH_OK;
4495 +                                               break;
4496 +                                       case 3: /* MOD */
4497 +                                               if ((window % f->wss.val) == 0)
4498 +                                                       fmatch = FMATCH_OK;
4499 +                                               break;
4500 +                               }
4501 +                       }
4502 +                                       
4503 +
4504 +                       if (fmatch == FMATCH_OK)
4505 +                       {
4506 +                               fcount++;
4507 +                               log("%s [%s:%s:%s] : %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u hops=%d\n", 
4508 +                                       f->genre, f->version,
4509 +                                       f->subtype, f->details,
4510 +                                       NIPQUAD(ip->saddr), ntohs(tcp->source),
4511 +                                       NIPQUAD(ip->daddr), ntohs(tcp->dest),
4512 +                                       f->ttl - ip->ttl);
4513 +                               if (info->flags & IPT_OSF_NETLINK)
4514 +                               {
4515 +                                       spin_lock_bh(&ipt_osf_netlink_lock);
4516 +                                       ipt_osf_nlsend(f, skb);
4517 +                                       spin_unlock_bh(&ipt_osf_netlink_lock);
4518 +                               }
4519 +                               if ((info->flags & IPT_OSF_LOG) && 
4520 +                                       info->loglevel == IPT_OSF_LOGLEVEL_FIRST)
4521 +                                       break;
4522 +                       }
4523 +               }
4524 +       }
4525 +       if (!fcount && (info->flags & (IPT_OSF_LOG | IPT_OSF_NETLINK)))
4526 +       {
4527 +               unsigned char opt[4 * 15 - sizeof(struct tcphdr)];
4528 +               unsigned int i, optsize;
4529 +               struct osf_finger fg;
4530 +
4531 +               memset(&fg, 0, sizeof(fg));
4532 +
4533 +               if ((info->flags & IPT_OSF_LOG))
4534 +                       log("Unknown: %lu:%d:%d:%lu:", window, ip->ttl, df, totlen);
4535 +               if (optp)
4536 +               {
4537 +                       optsize = tcp->doff * 4 - sizeof(struct tcphdr);
4538 +                       if (skb_copy_bits(skb, ip->ihl*4 + sizeof(struct tcphdr),
4539 +                                         opt, optsize) < 0)
4540 +                       {
4541 +                               if (info->flags & IPT_OSF_LOG)
4542 +                                       loga("TRUNCATED");
4543 +                               if (info->flags & IPT_OSF_NETLINK)
4544 +                                       strcpy(fg.details, "TRUNCATED");
4545 +                       }
4546 +                       else
4547 +                       {
4548 +                               for (i = 0; i < optsize; i++)
4549 +                               {
4550 +                                       if (info->flags & IPT_OSF_LOG)
4551 +                                               loga("%02X", opt[i]);
4552 +                               }
4553 +                               if (info->flags & IPT_OSF_NETLINK)
4554 +                                       memcpy(fg.details, opt, MAXDETLEN);
4555 +                       }
4556 +               }
4557 +               if ((info->flags & IPT_OSF_LOG))
4558 +                       loga(" %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n", 
4559 +                               NIPQUAD(ip->saddr), ntohs(tcp->source),
4560 +                               NIPQUAD(ip->daddr), ntohs(tcp->dest));
4561 +               
4562 +               if (info->flags & IPT_OSF_NETLINK)
4563 +               {
4564 +                       fg.wss.val      = window;
4565 +                       fg.ttl          = ip->ttl;
4566 +                       fg.df           = df;
4567 +                       fg.ss           = totlen;
4568 +                       strncpy(fg.genre, "Unknown", MAXGENRELEN);
4569 +
4570 +                       spin_lock_bh(&ipt_osf_netlink_lock);
4571 +                       ipt_osf_nlsend(&fg, skb);
4572 +                       spin_unlock_bh(&ipt_osf_netlink_lock);
4573 +               }
4574 +       }
4575 +
4576 +       read_unlock(&osf_lock);
4577 +
4578 +       return (fmatch == FMATCH_OK)?1:0;
4579 +}
4580 +
4581 +static int
4582 +checkentry(const char *tablename,
4583 +           const struct ipt_ip *ip,
4584 +           void *matchinfo,
4585 +           unsigned int matchsize,
4586 +           unsigned int hook_mask)
4587 +{
4588 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_osf_info)))
4589 +               return 0;
4590 +       if (ip->proto != IPPROTO_TCP)
4591 +              return 0;
4592 +
4593 +       return 1;
4594 +}
4595 +
4596 +static char * osf_strchr(char *ptr, char c)
4597 +{
4598 +       char *tmp;
4599 +
4600 +       tmp = strchr(ptr, c);
4601 +
4602 +       while (tmp && tmp+1 && isspace(*(tmp+1)))
4603 +               tmp++;
4604 +
4605 +       return tmp;
4606 +}
4607 +
4608 +static struct osf_finger * finger_alloc(void)
4609 +{
4610 +       struct osf_finger *f;
4611 +
4612 +       f = kmalloc(sizeof(struct osf_finger), GFP_KERNEL);
4613 +       if (f)
4614 +               memset(f, 0, sizeof(struct osf_finger));
4615 +       
4616 +       return f;
4617 +}
4618 +
4619 +static void finger_free(struct osf_finger *f)
4620 +{
4621 +       memset(f, 0, sizeof(struct osf_finger));
4622 +       kfree(f);
4623 +}
4624 +
4625 +
4626 +static void osf_parse_opt(struct osf_opt *opt, int *optnum, char *obuf, int olen)
4627 +{
4628 +       int i, op;
4629 +       char *ptr, wc;
4630 +       unsigned long val;
4631 +
4632 +       ptr = &obuf[0];
4633 +       i = 0;
4634 +       while (ptr != NULL && i < olen)
4635 +       {
4636 +               val = 0;
4637 +               op = 0;
4638 +               wc = 0;
4639 +               switch (obuf[i])
4640 +               {
4641 +                       case 'N': 
4642 +                               op = OSFOPT_NOP;
4643 +                               ptr = osf_strchr(&obuf[i], OPTDEL);
4644 +                               if (ptr)
4645 +                               {
4646 +                                       *ptr = '\0';
4647 +                                       ptr++;
4648 +                                       i += (int)(ptr-&obuf[i]);
4649 +
4650 +                               }
4651 +                               else
4652 +                                       i++;
4653 +                               break;
4654 +                       case 'S': 
4655 +                               op = OSFOPT_SACKP;
4656 +                               ptr = osf_strchr(&obuf[i], OPTDEL);
4657 +                               if (ptr)
4658 +                               {
4659 +                                       *ptr = '\0';
4660 +                                       ptr++;
4661 +                                       i += (int)(ptr-&obuf[i]);
4662 +
4663 +                               }
4664 +                               else
4665 +                                       i++;
4666 +                               break;
4667 +                       case 'T': 
4668 +                               op = OSFOPT_TS;
4669 +                               ptr = osf_strchr(&obuf[i], OPTDEL);
4670 +                               if (ptr)
4671 +                               {
4672 +                                       *ptr = '\0';
4673 +                                       ptr++;
4674 +                                       i += (int)(ptr-&obuf[i]);
4675 +
4676 +                               }
4677 +                               else
4678 +                                       i++;
4679 +                               break;
4680 +                       case 'W': 
4681 +                               op = OSFOPT_WSO;
4682 +                               ptr = osf_strchr(&obuf[i], OPTDEL);
4683 +                               if (ptr)
4684 +                               {
4685 +                                       switch (obuf[i+1])
4686 +                                       {
4687 +                                               case '%':       wc = '%'; break;
4688 +                                               case 'S':       wc = 'S'; break;
4689 +                                               case 'T':       wc = 'T'; break;
4690 +                                               default:        wc = 0; break;
4691 +                                       }
4692 +                                       
4693 +                                       *ptr = '\0';
4694 +                                       ptr++;
4695 +                                       if (wc)
4696 +                                               val = simple_strtoul(&obuf[i+2], NULL, 10);
4697 +                                       else
4698 +                                               val = simple_strtoul(&obuf[i+1], NULL, 10);
4699 +                                       i += (int)(ptr-&obuf[i]);
4700 +
4701 +                               }
4702 +                               else
4703 +                                       i++;
4704 +                               break;
4705 +                       case 'M': 
4706 +                               op = OSFOPT_MSS;
4707 +                               ptr = osf_strchr(&obuf[i], OPTDEL);
4708 +                               if (ptr)
4709 +                               {
4710 +                                       if (obuf[i+1] == '%')
4711 +                                               wc = '%';
4712 +                                       *ptr = '\0';
4713 +                                       ptr++;
4714 +                                       if (wc)
4715 +                                               val = simple_strtoul(&obuf[i+2], NULL, 10);
4716 +                                       else
4717 +                                               val = simple_strtoul(&obuf[i+1], NULL, 10);
4718 +                                       i += (int)(ptr-&obuf[i]);
4719 +
4720 +                               }
4721 +                               else
4722 +                                       i++;
4723 +                               break;
4724 +                       case 'E': 
4725 +                               op = OSFOPT_EOL;
4726 +                               ptr = osf_strchr(&obuf[i], OPTDEL);
4727 +                               if (ptr)
4728 +                               {
4729 +                                       *ptr = '\0';
4730 +                                       ptr++;
4731 +                                       i += (int)(ptr-&obuf[i]);
4732 +
4733 +                               }
4734 +                               else
4735 +                                       i++;
4736 +                               break;
4737 +                       default:
4738 +                               ptr = osf_strchr(&obuf[i], OPTDEL);
4739 +                               if (ptr)
4740 +                               {
4741 +                                       ptr++;
4742 +                                       i += (int)(ptr-&obuf[i]);
4743 +
4744 +                               }
4745 +                               else
4746 +                                       i++;
4747 +                               break;
4748 +               }
4749 +
4750 +               opt[*optnum].kind       = IANA_opts[op].kind;
4751 +               opt[*optnum].length     = IANA_opts[op].length;
4752 +               opt[*optnum].wc.wc      = wc;
4753 +               opt[*optnum].wc.val     = val;
4754 +
4755 +               (*optnum)++;
4756 +       }
4757 +}
4758 +
4759 +static int osf_proc_read(char *buf, char **start, off_t off, int count, int *eof, void *data)
4760 +{
4761 +       struct list_head *ent;
4762 +       struct osf_finger *f = NULL;
4763 +       int i;
4764 +       
4765 +       *eof = 1;
4766 +       count = 0;
4767 +
4768 +       read_lock_bh(&osf_lock);
4769 +       list_for_each(ent, &finger_list)
4770 +       {
4771 +               f = list_entry(ent, struct osf_finger, flist);
4772 +
4773 +               log("%s [%s]", f->genre, f->details);
4774 +               
4775 +               count += sprintf(buf+count, "%s - %s[%s] : %s", 
4776 +                                       f->genre, f->version,
4777 +                                       f->subtype, f->details);
4778 +               
4779 +               if (f->opt_num)
4780 +               {
4781 +                       loga(" OPT: ");
4782 +                       //count += sprintf(buf+count, " OPT: ");
4783 +                       for (i=0; i<f->opt_num; ++i)
4784 +                       {
4785 +                               //count += sprintf(buf+count, "%d.%c%lu; ", 
4786 +                               //      f->opt[i].kind, (f->opt[i].wc.wc)?f->opt[i].wc.wc:' ', f->opt[i].wc.val);
4787 +                               loga("%d.%c%lu; ", 
4788 +                                       f->opt[i].kind, (f->opt[i].wc.wc)?f->opt[i].wc.wc:' ', f->opt[i].wc.val);
4789 +                       }
4790 +               }
4791 +               loga("\n");
4792 +               count += sprintf(buf+count, "\n");
4793 +       }
4794 +       read_unlock_bh(&osf_lock);
4795 +
4796 +       return count;
4797 +}
4798 +
4799 +static int osf_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
4800 +{
4801 +       int cnt;
4802 +       unsigned long i;
4803 +       char obuf[MAXOPTSTRLEN];
4804 +       struct osf_finger *finger;
4805 +       struct list_head *ent, *n;
4806 +
4807 +       char *pbeg, *pend;
4808 +
4809 +       if (count == strlen(OSFFLUSH) && !strncmp(buffer, OSFFLUSH, strlen(OSFFLUSH)))
4810 +       {
4811 +               int i = 0;
4812 +               write_lock_bh(&osf_lock);
4813 +               list_for_each_safe(ent, n, &finger_list)
4814 +               {
4815 +                       i++;
4816 +                       finger = list_entry(ent, struct osf_finger, flist);
4817 +                       list_del(&finger->flist);
4818 +                       finger_free(finger);
4819 +               }
4820 +               write_unlock_bh(&osf_lock);
4821 +       
4822 +               log("Flushed %d entries.\n", i);
4823 +               
4824 +               return count;
4825 +       }
4826 +
4827 +       
4828 +       cnt = 0;
4829 +       for (i=0; i<count && buffer[i] != '\0'; ++i)
4830 +               if (buffer[i] == ':')
4831 +                       cnt++;
4832 +
4833 +       if (cnt != 8 || i != count)
4834 +       {
4835 +               log("Wrong input line cnt=%d[8], len=%lu[%lu]\n", 
4836 +                       cnt, i, count);
4837 +               return count;
4838 +       }
4839 +
4840 +       memset(obuf, 0, sizeof(obuf));
4841 +       
4842 +       finger = finger_alloc();
4843 +       if (!finger)
4844 +       {
4845 +               log("Failed to allocate new fingerprint entry.\n");
4846 +               return -ENOMEM;
4847 +       }
4848 +
4849 +       pbeg = (char *)buffer;
4850 +       pend = osf_strchr(pbeg, OSFPDEL);
4851 +       if (pend)
4852 +       {
4853 +               *pend = '\0';
4854 +               if (pbeg[0] == 'S')
4855 +               {
4856 +                       finger->wss.wc = 'S';
4857 +                       if (pbeg[1] == '%')
4858 +                               finger->wss.val = simple_strtoul(pbeg+2, NULL, 10);
4859 +                       else if (pbeg[1] == '*')
4860 +                               finger->wss.val = 0;
4861 +                       else 
4862 +                               finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
4863 +               }
4864 +               else if (pbeg[0] == 'T')
4865 +               {
4866 +                       finger->wss.wc = 'T';
4867 +                       if (pbeg[1] == '%')
4868 +                               finger->wss.val = simple_strtoul(pbeg+2, NULL, 10);
4869 +                       else if (pbeg[1] == '*')
4870 +                               finger->wss.val = 0;
4871 +                       else 
4872 +                               finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
4873 +               }
4874 +               else if (pbeg[0] == '%')
4875 +               {
4876 +                       finger->wss.wc = '%';
4877 +                       finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
4878 +               }
4879 +               else if (isdigit(pbeg[0]))
4880 +               {
4881 +                       finger->wss.wc = 0;
4882 +                       finger->wss.val = simple_strtoul(pbeg, NULL, 10);
4883 +               }
4884 +
4885 +               pbeg = pend+1;
4886 +       }
4887 +       pend = osf_strchr(pbeg, OSFPDEL);
4888 +       if (pend)
4889 +       {
4890 +               *pend = '\0';
4891 +               finger->ttl = simple_strtoul(pbeg, NULL, 10);
4892 +               pbeg = pend+1;
4893 +       }
4894 +       pend = osf_strchr(pbeg, OSFPDEL);
4895 +       if (pend)
4896 +       {
4897 +               *pend = '\0';
4898 +               finger->df = simple_strtoul(pbeg, NULL, 10);
4899 +               pbeg = pend+1;
4900 +       }
4901 +       pend = osf_strchr(pbeg, OSFPDEL);
4902 +       if (pend)
4903 +       {
4904 +               *pend = '\0';
4905 +               finger->ss = simple_strtoul(pbeg, NULL, 10);
4906 +               pbeg = pend+1;
4907 +       }
4908 +
4909 +       pend = osf_strchr(pbeg, OSFPDEL);
4910 +       if (pend)
4911 +       {
4912 +               *pend = '\0';
4913 +               cnt = snprintf(obuf, sizeof(obuf), "%s", pbeg);
4914 +               pbeg = pend+1;
4915 +       }
4916 +
4917 +       pend = osf_strchr(pbeg, OSFPDEL);
4918 +       if (pend)
4919 +       {
4920 +               *pend = '\0';
4921 +               if (pbeg[0] == '@' || pbeg[0] == '*')
4922 +                       cnt = snprintf(finger->genre, sizeof(finger->genre), "%s", pbeg+1);
4923 +               else
4924 +                       cnt = snprintf(finger->genre, sizeof(finger->genre), "%s", pbeg);
4925 +               pbeg = pend+1;
4926 +       }
4927 +       
4928 +       pend = osf_strchr(pbeg, OSFPDEL);
4929 +       if (pend)
4930 +       {
4931 +               *pend = '\0';
4932 +               cnt = snprintf(finger->version, sizeof(finger->version), "%s", pbeg);
4933 +               pbeg = pend+1;
4934 +       }
4935 +       
4936 +       pend = osf_strchr(pbeg, OSFPDEL);
4937 +       if (pend)
4938 +       {
4939 +               *pend = '\0';
4940 +               cnt = snprintf(finger->subtype, sizeof(finger->subtype), "%s", pbeg);
4941 +               pbeg = pend+1;
4942 +       }
4943 +
4944 +       cnt = snprintf(finger->details, 
4945 +                       ((count - (pbeg - buffer)+1) > MAXDETLEN)?MAXDETLEN:(count - (pbeg - buffer)+1), 
4946 +                       "%s", pbeg);
4947 +       
4948 +       log("%s - %s[%s] : %s\n", 
4949 +               finger->genre, finger->version,
4950 +               finger->subtype, finger->details);
4951 +       
4952 +       osf_parse_opt(finger->opt, &finger->opt_num, obuf, sizeof(obuf));
4953 +       
4954 +
4955 +       write_lock_bh(&osf_lock);
4956 +       list_add_tail(&finger->flist, &finger_list);
4957 +       write_unlock_bh(&osf_lock);
4958 +
4959 +       return count;
4960 +}
4961 +
4962 +static int __init osf_init(void)
4963 +{
4964 +       int err;
4965 +       struct proc_dir_entry *p;
4966 +
4967 +       log("Startng OS fingerprint matching module.\n");
4968 +
4969 +       INIT_LIST_HEAD(&finger_list);
4970 +       
4971 +       err = ipt_register_match(&osf_match);
4972 +       if (err)
4973 +       {
4974 +               log("Failed to register OS fingerprint matching module.\n");
4975 +               return -ENXIO;
4976 +       }
4977 +
4978 +       p = create_proc_entry("sys/net/ipv4/osf", S_IFREG | 0644, NULL);
4979 +       if (!p)
4980 +       {
4981 +               ipt_unregister_match(&osf_match);
4982 +               return -ENXIO;
4983 +       }
4984 +
4985 +       p->write_proc = osf_proc_write;
4986 +       p->read_proc  = osf_proc_read;
4987 +       
4988 +       nts = netlink_kernel_create(NETLINK_NFLOG, NULL);
4989 +       if (!nts)
4990 +       {
4991 +               log("netlink_kernel_create() failed\n");
4992 +               remove_proc_entry("sys/net/ipv4/osf", NULL);
4993 +               ipt_unregister_match(&osf_match);
4994 +               return -ENOMEM;
4995 +       }
4996 +
4997 +       return 0;
4998 +}
4999 +
5000 +static void __exit osf_fini(void)
5001 +{
5002 +       struct list_head *ent, *n;
5003 +       struct osf_finger *f;
5004 +       
5005 +       remove_proc_entry("sys/net/ipv4/osf", NULL);
5006 +       ipt_unregister_match(&osf_match);
5007 +//     if (nts && nts->socket)
5008 +//             sock_release(nts->socket);
5009 +
5010 +       list_for_each_safe(ent, n, &finger_list)
5011 +       {
5012 +               f = list_entry(ent, struct osf_finger, flist);
5013 +               list_del(&f->flist);
5014 +               finger_free(f);
5015 +       }
5016 +       
5017 +       log("OS fingerprint matching module finished.\n");
5018 +}
5019 +
5020 +module_init(osf_init);
5021 +module_exit(osf_fini);
5022 +
5023 +MODULE_LICENSE("GPL");
5024 +MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
5025 +MODULE_DESCRIPTION("Passive OS fingerprint matching.");
5026 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_pool.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_pool.c
5027 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_pool.c   1970-01-01 00:00:00.000000000 +0000
5028 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_pool.c       2004-03-22 08:29:18.000000000 +0000
5029 @@ -0,0 +1,71 @@
5030 +/* Kernel module to match an IP address pool. */
5031 +
5032 +#include <linux/module.h>
5033 +#include <linux/ip.h>
5034 +#include <linux/skbuff.h>
5035 +
5036 +#include <linux/netfilter_ipv4/ip_tables.h>
5037 +#include <linux/netfilter_ipv4/ip_pool.h>
5038 +#include <linux/netfilter_ipv4/ipt_pool.h>
5039 +
5040 +static inline int match_pool(
5041 +       ip_pool_t index,
5042 +       __u32 addr,
5043 +       int inv
5044 +) {
5045 +       if (ip_pool_match(index, ntohl(addr)))
5046 +               inv = !inv;
5047 +       return inv;
5048 +}
5049 +
5050 +static int match(
5051 +       const struct sk_buff *skb,
5052 +       const struct net_device *in,
5053 +       const struct net_device *out,
5054 +       const void *matchinfo,
5055 +       int offset,
5056 +       const void *hdr,
5057 +       u_int16_t datalen,
5058 +       int *hotdrop
5059 +) {
5060 +       const struct ipt_pool_info *info = matchinfo;
5061 +       const struct iphdr *iph = skb->nh.iph;
5062 +
5063 +       if (info->src != IP_POOL_NONE && !match_pool(info->src, iph->saddr,
5064 +                                               info->flags&IPT_POOL_INV_SRC))
5065 +               return 0;
5066 +
5067 +       if (info->dst != IP_POOL_NONE && !match_pool(info->dst, iph->daddr,
5068 +                                               info->flags&IPT_POOL_INV_DST))
5069 +               return 0;
5070 +
5071 +       return 1;
5072 +}
5073 +
5074 +static int checkentry(
5075 +       const char *tablename,
5076 +       const struct ipt_ip *ip,
5077 +       void *matchinfo,
5078 +       unsigned int matchsize,
5079 +       unsigned int hook_mask
5080 +) {
5081 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_pool_info)))
5082 +               return 0;
5083 +       return 1;
5084 +}
5085 +
5086 +static struct ipt_match pool_match
5087 += { { NULL, NULL }, "pool", &match, &checkentry, NULL, THIS_MODULE };
5088 +
5089 +static int __init init(void)
5090 +{
5091 +       return ipt_register_match(&pool_match);
5092 +}
5093 +
5094 +static void __exit fini(void)
5095 +{
5096 +       ipt_unregister_match(&pool_match);
5097 +}
5098 +
5099 +module_init(init);
5100 +module_exit(fini);
5101 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_psd.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_psd.c
5102 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_psd.c    1970-01-01 00:00:00.000000000 +0000
5103 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_psd.c        2004-03-22 08:29:30.000000000 +0000
5104 @@ -0,0 +1,361 @@
5105 +/*
5106 +  This is a module which is used for PSD (portscan detection)
5107 +  Derived from scanlogd v2.1 written by Solar Designer <solar@false.com>
5108 +  and LOG target module.
5109 +
5110 +  Copyright (C) 2000,2001 astaro AG
5111 +
5112 +  This file is distributed under the terms of the GNU General Public
5113 +  License (GPL). Copies of the GPL can be obtained from:
5114 +     ftp://prep.ai.mit.edu/pub/gnu/GPL
5115 +
5116 +  2000-05-04 Markus Hennig <hennig@astaro.de> : initial
5117 +  2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
5118 +  2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
5119 +  2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified
5120 +  2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
5121 +*/
5122 +
5123 +#include <linux/module.h>
5124 +#include <linux/skbuff.h>
5125 +#include <linux/ip.h>
5126 +#include <net/tcp.h>
5127 +#include <linux/spinlock.h>
5128 +#include <linux/netfilter_ipv4/ip_tables.h>
5129 +#include <linux/netfilter_ipv4/ipt_psd.h>
5130 +
5131 +#if 0
5132 +#define DEBUGP printk
5133 +#else
5134 +#define DEBUGP(format, args...)
5135 +#endif
5136 +
5137 +MODULE_LICENSE("GPL");
5138 +MODULE_AUTHOR("Dennis Koslowski <koslowski@astaro.com>");
5139 +
5140 +#define HF_DADDR_CHANGING   0x01
5141 +#define HF_SPORT_CHANGING   0x02
5142 +#define HF_TOS_CHANGING            0x04
5143 +#define HF_TTL_CHANGING            0x08
5144 +            
5145 +/*
5146 + * Information we keep per each target port
5147 + */
5148 +struct port {
5149 +       u_int16_t number;      /* port number */ 
5150 +       u_int8_t proto;        /* protocol number */
5151 +       u_int8_t and_flags;    /* tcp ANDed flags */
5152 +       u_int8_t or_flags;     /* tcp ORed flags */
5153 +};
5154 +
5155 +/*
5156 + * Information we keep per each source address.
5157 + */
5158 +struct host {
5159 +       struct host *next;              /* Next entry with the same hash */
5160 +       clock_t timestamp;              /* Last update time */
5161 +       struct in_addr src_addr;        /* Source address */
5162 +       struct in_addr dest_addr;       /* Destination address */
5163 +       unsigned short src_port;        /* Source port */
5164 +       int count;                      /* Number of ports in the list */
5165 +       int weight;                     /* Total weight of ports in the list */
5166 +       struct port ports[SCAN_MAX_COUNT - 1];  /* List of ports */
5167 +       unsigned char tos;              /* TOS */
5168 +       unsigned char ttl;              /* TTL */
5169 +       unsigned char flags;            /* HF_ flags bitmask */
5170 +};
5171 +
5172 +/*
5173 + * State information.
5174 + */
5175 +static struct {
5176 +       spinlock_t lock;
5177 +       struct host list[LIST_SIZE];    /* List of source addresses */
5178 +       struct host *hash[HASH_SIZE];   /* Hash: pointers into the list */
5179 +       int index;                      /* Oldest entry to be replaced */
5180 +} state;
5181 +
5182 +/*
5183 + * Convert an IP address into a hash table index.
5184 + */
5185 +static inline int hashfunc(struct in_addr addr)
5186 +{
5187 +       unsigned int value;
5188 +       int hash;
5189 +
5190 +       value = addr.s_addr;
5191 +       hash = 0;
5192 +       do {
5193 +               hash ^= value;
5194 +       } while ((value >>= HASH_LOG));
5195 +
5196 +       return hash & (HASH_SIZE - 1);
5197 +}
5198 +
5199 +static int
5200 +ipt_psd_match(const struct sk_buff *pskb,
5201 +             const struct net_device *in,
5202 +             const struct net_device *out,
5203 +             const void *matchinfo,
5204 +             int offset,
5205 +             const void *hdr,
5206 +             u_int16_t datalen,
5207 +             int *hotdrop)
5208 +{
5209 +       struct iphdr *ip_hdr;
5210 +       struct tcphdr *tcp_hdr;
5211 +       struct in_addr addr;
5212 +       u_int16_t src_port,dest_port;
5213 +       u_int8_t tcp_flags, proto;
5214 +       clock_t now;
5215 +       struct host *curr, *last, **head;
5216 +       int hash, index, count;
5217 +
5218 +       /* Parameters from userspace */
5219 +       const struct ipt_psd_info *psdinfo = matchinfo;
5220 +
5221 +       /* IP header */
5222 +       ip_hdr = pskb->nh.iph;
5223 +
5224 +       /* Sanity check */
5225 +       if (ntohs(ip_hdr->frag_off) & IP_OFFSET) {
5226 +               DEBUGP("PSD: sanity check failed\n");
5227 +               return 0;
5228 +       }
5229 +
5230 +       /* TCP or UDP ? */
5231 +       proto = ip_hdr->protocol;
5232 +
5233 +       if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
5234 +               DEBUGP("PSD: protocol not supported\n");
5235 +               return 0;
5236 +       }
5237 +
5238 +       /* Get the source address, source & destination ports, and TCP flags */
5239 +
5240 +       addr.s_addr = ip_hdr->saddr;
5241 +
5242 +       tcp_hdr = (struct tcphdr*)((u_int32_t *)ip_hdr + ip_hdr->ihl);
5243 +
5244 +       /* Yep, it´s dirty */
5245 +       src_port = tcp_hdr->source;
5246 +       dest_port = tcp_hdr->dest;
5247 +
5248 +       if (proto == IPPROTO_TCP) {
5249 +               tcp_flags = *((u_int8_t*)tcp_hdr + 13);
5250 +       }
5251 +       else {
5252 +               tcp_flags = 0x00;
5253 +       }
5254 +
5255 +       /* We're using IP address 0.0.0.0 for a special purpose here, so don't let
5256 +        * them spoof us. [DHCP needs this feature - HW] */
5257 +       if (!addr.s_addr) {
5258 +               DEBUGP("PSD: spoofed source address (0.0.0.0)\n");
5259 +               return 0;
5260 +       }
5261 +
5262 +       /* Use jiffies here not to depend on someone setting the time while we're
5263 +        * running; we need to be careful with possible return value overflows. */
5264 +       now = jiffies;
5265 +
5266 +       spin_lock(&state.lock);
5267 +
5268 +       /* Do we know this source address already? */
5269 +       count = 0;
5270 +       last = NULL;
5271 +       if ((curr = *(head = &state.hash[hash = hashfunc(addr)])))
5272 +               do {
5273 +                       if (curr->src_addr.s_addr == addr.s_addr) break;
5274 +                       count++;
5275 +                       if (curr->next) last = curr;
5276 +               } while ((curr = curr->next));
5277 +
5278 +       if (curr) {
5279 +
5280 +               /* We know this address, and the entry isn't too old. Update it. */
5281 +               if (now - curr->timestamp <= (psdinfo->delay_threshold*HZ)/100 &&
5282 +                   time_after_eq(now, curr->timestamp)) {
5283 +
5284 +                       /* Just update the appropriate list entry if we've seen this port already */
5285 +                       for (index = 0; index < curr->count; index++) {
5286 +                               if (curr->ports[index].number == dest_port) {
5287 +                                       curr->ports[index].proto = proto;
5288 +                                       curr->ports[index].and_flags &= tcp_flags;
5289 +                                       curr->ports[index].or_flags |= tcp_flags;
5290 +                                       goto out_no_match;
5291 +                               }
5292 +                       }
5293 +
5294 +                       /* TCP/ACK and/or TCP/RST to a new port? This could be an outgoing connection. */
5295 +                       if (proto == IPPROTO_TCP && (tcp_hdr->ack || tcp_hdr->rst))
5296 +                               goto out_no_match;
5297 +
5298 +                       /* Packet to a new port, and not TCP/ACK: update the timestamp */
5299 +                       curr->timestamp = now;
5300 +
5301 +                       /* Logged this scan already? Then drop the packet. */
5302 +                       if (curr->weight >= psdinfo->weight_threshold)
5303 +                               goto out_match;
5304 +
5305 +                       /* Specify if destination address, source port, TOS or TTL are not fixed */
5306 +                       if (curr->dest_addr.s_addr != ip_hdr->daddr)
5307 +                               curr->flags |= HF_DADDR_CHANGING;
5308 +                       if (curr->src_port != src_port)
5309 +                               curr->flags |= HF_SPORT_CHANGING;
5310 +                       if (curr->tos != ip_hdr->tos)
5311 +                               curr->flags |= HF_TOS_CHANGING;
5312 +                       if (curr->ttl != ip_hdr->ttl)
5313 +                               curr->flags |= HF_TTL_CHANGING;
5314 +
5315 +                       /* Update the total weight */
5316 +                       curr->weight += (ntohs(dest_port) < 1024) ?
5317 +                               psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
5318 +
5319 +                       /* Got enough destination ports to decide that this is a scan? */
5320 +                       /* Then log it and drop the packet. */
5321 +                       if (curr->weight >= psdinfo->weight_threshold)
5322 +                               goto out_match;
5323 +
5324 +                       /* Remember the new port */
5325 +                       if (curr->count < SCAN_MAX_COUNT) {
5326 +                               curr->ports[curr->count].number = dest_port;
5327 +                               curr->ports[curr->count].proto = proto;
5328 +                               curr->ports[curr->count].and_flags = tcp_flags;
5329 +                               curr->ports[curr->count].or_flags = tcp_flags;
5330 +                               curr->count++;
5331 +                       }
5332 +
5333 +                       goto out_no_match;
5334 +               }
5335 +
5336 +               /* We know this address, but the entry is outdated. Mark it unused, and
5337 +                * remove from the hash table. We'll allocate a new entry instead since
5338 +                * this one might get re-used too soon. */
5339 +               curr->src_addr.s_addr = 0;
5340 +               if (last)
5341 +                       last->next = last->next->next;
5342 +               else if (*head)
5343 +                       *head = (*head)->next;
5344 +               last = NULL;
5345 +       }
5346 +
5347 +       /* We don't need an ACK from a new source address */
5348 +       if (proto == IPPROTO_TCP && tcp_hdr->ack)
5349 +               goto out_no_match;
5350 +
5351 +       /* Got too many source addresses with the same hash value? Then remove the
5352 +        * oldest one from the hash table, so that they can't take too much of our
5353 +        * CPU time even with carefully chosen spoofed IP addresses. */
5354 +       if (count >= HASH_MAX && last) last->next = NULL;
5355 +
5356 +       /* We're going to re-use the oldest list entry, so remove it from the hash
5357 +        * table first (if it is really already in use, and isn't removed from the
5358 +        * hash table already because of the HASH_MAX check above). */
5359 +
5360 +       /* First, find it */
5361 +       if (state.list[state.index].src_addr.s_addr)
5362 +               head = &state.hash[hashfunc(state.list[state.index].src_addr)];
5363 +       else
5364 +               head = &last;
5365 +       last = NULL;
5366 +       if ((curr = *head))
5367 +       do {
5368 +               if (curr == &state.list[state.index]) break;
5369 +               last = curr;
5370 +       } while ((curr = curr->next));
5371 +
5372 +       /* Then, remove it */
5373 +       if (curr) {
5374 +               if (last)
5375 +                       last->next = last->next->next;
5376 +               else if (*head)
5377 +                       *head = (*head)->next;
5378 +       }
5379 +
5380 +       /* Get our list entry */
5381 +       curr = &state.list[state.index++];
5382 +       if (state.index >= LIST_SIZE) state.index = 0;
5383 +
5384 +       /* Link it into the hash table */
5385 +       head = &state.hash[hash];
5386 +       curr->next = *head;
5387 +       *head = curr;
5388 +
5389 +       /* And fill in the fields */
5390 +       curr->timestamp = now;
5391 +       curr->src_addr = addr;
5392 +       curr->dest_addr.s_addr = ip_hdr->daddr;
5393 +       curr->src_port = src_port;
5394 +       curr->count = 1;
5395 +       curr->weight = (ntohs(dest_port) < 1024) ?
5396 +               psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
5397 +       curr->ports[0].number = dest_port;
5398 +       curr->ports[0].proto = proto;
5399 +       curr->ports[0].and_flags = tcp_flags;
5400 +       curr->ports[0].or_flags = tcp_flags;
5401 +       curr->tos = ip_hdr->tos;
5402 +       curr->ttl = ip_hdr->ttl;
5403 +
5404 +out_no_match:
5405 +       spin_unlock(&state.lock);
5406 +       return 0;
5407 +
5408 +out_match:
5409 +       spin_unlock(&state.lock);
5410 +       return 1;
5411 +}
5412 +
5413 +static int ipt_psd_checkentry(const char *tablename,
5414 +                             const struct ipt_ip *e,
5415 +                             void *matchinfo,
5416 +                             unsigned int matchsize,
5417 +                             unsigned int hook_mask)
5418 +{
5419 +/*     const struct ipt_psd_info *psdinfo = targinfo;*/
5420 +
5421 +       /* we accept TCP only */
5422 +/*     if (e->ip.proto != IPPROTO_TCP) { */
5423 +/*             DEBUGP("PSD: specified protocol may be TCP only\n"); */
5424 +/*             return 0; */
5425 +/*     } */
5426 +
5427 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_psd_info))) {
5428 +               DEBUGP("PSD: matchsize %u != %u\n",
5429 +                      matchsize,
5430 +                      IPT_ALIGN(sizeof(struct ipt_psd_info)));
5431 +               return 0;
5432 +       }
5433 +
5434 +       return 1;
5435 +}
5436 +
5437 +static struct ipt_match ipt_psd_reg = { 
5438 +       {NULL, NULL},
5439 +       "psd",
5440 +       ipt_psd_match,
5441 +       ipt_psd_checkentry,
5442 +       NULL,
5443 +       THIS_MODULE };
5444 +
5445 +static int __init init(void)
5446 +{
5447 +       if (ipt_register_match(&ipt_psd_reg))
5448 +               return -EINVAL;
5449 +
5450 +       memset(&state, 0, sizeof(state));
5451 +
5452 +       spin_lock_init(&(state.lock));
5453 +
5454 +       printk("netfilter PSD loaded - (c) astaro AG\n");
5455 +       return 0;
5456 +}
5457 +
5458 +static void __exit fini(void)
5459 +{
5460 +       ipt_unregister_match(&ipt_psd_reg);
5461 +       printk("netfilter PSD unloaded - (c) astaro AG\n");
5462 +}
5463 +
5464 +module_init(init);
5465 +module_exit(fini);
5466 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_quota.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_quota.c
5467 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_quota.c  1970-01-01 00:00:00.000000000 +0000
5468 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_quota.c      2004-03-22 08:29:35.000000000 +0000
5469 @@ -0,0 +1,91 @@
5470 +/* 
5471 + * netfilter module to enforce network quotas
5472 + *
5473 + * Sam Johnston <samj@samj.net>
5474 + */
5475 +#include <linux/module.h>
5476 +#include <linux/skbuff.h>
5477 +#include <linux/spinlock.h>
5478 +#include <linux/interrupt.h>
5479 +
5480 +#include <linux/netfilter_ipv4/ip_tables.h>
5481 +#include <linux/netfilter_ipv4/ipt_quota.h>
5482 +
5483 +MODULE_LICENSE("GPL");
5484 +MODULE_AUTHOR("Sam Johnston <samj@samj.net>");
5485 +
5486 +static spinlock_t quota_lock = SPIN_LOCK_UNLOCKED;
5487 +
5488 +static int
5489 +match(const struct sk_buff *skb,
5490 +      const struct net_device *in,
5491 +      const struct net_device *out,
5492 +      const void *matchinfo,
5493 +      int offset, int *hotdrop)
5494 +{
5495 +        struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
5496 +       unsigned int datalen;
5497 +
5498 +       if (skb->len < sizeof(struct iphdr))
5499 +               return NF_ACCEPT;
5500 +       
5501 +       datalen = skb->len - skb->nh.iph->ihl*4;
5502 +
5503 +        spin_lock_bh(&quota_lock);
5504 +
5505 +        if (q->quota >= datalen) {
5506 +                /* we can afford this one */
5507 +                q->quota -= datalen;
5508 +                spin_unlock_bh(&quota_lock);
5509 +
5510 +#ifdef DEBUG_IPT_QUOTA
5511 +                printk("IPT Quota OK: %llu datlen %d \n", q->quota, datalen);
5512 +#endif
5513 +                return 1;
5514 +        }
5515 +
5516 +        /* so we do not allow even small packets from now on */
5517 +        q->quota = 0;
5518 +
5519 +#ifdef DEBUG_IPT_QUOTA
5520 +        printk("IPT Quota Failed: %llu datlen %d \n", q->quota, datalen);
5521 +#endif
5522 +
5523 +        spin_unlock_bh(&quota_lock);
5524 +        return 0;
5525 +}
5526 +
5527 +static int
5528 +checkentry(const char *tablename,
5529 +           const struct ipt_ip *ip,
5530 +           void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
5531 +{
5532 +        /* TODO: spinlocks? sanity checks? */
5533 +        if (matchsize != IPT_ALIGN(sizeof (struct ipt_quota_info)))
5534 +                return 0;
5535 +
5536 +        return 1;
5537 +}
5538 +
5539 +static struct ipt_match quota_match = {
5540 +       .name = "quota",
5541 +       .match = match,
5542 +       .checkentry = checkentry,
5543 +       .me = THIS_MODULE
5544 +};
5545 +
5546 +static int __init
5547 +init(void)
5548 +{
5549 +        return ipt_register_match(&quota_match);
5550 +}
5551 +
5552 +static void __exit
5553 +fini(void)
5554 +{
5555 +        ipt_unregister_match(&quota_match);
5556 +}
5557 +
5558 +module_init(init);
5559 +module_exit(fini);
5560 +
5561 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_random.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_random.c
5562 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_random.c 1970-01-01 00:00:00.000000000 +0000
5563 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_random.c     2004-03-22 08:29:43.000000000 +0000
5564 @@ -0,0 +1,96 @@
5565 +/*
5566 +  This is a module which is used for a "random" match support.
5567 +  This file is distributed under the terms of the GNU General Public
5568 +  License (GPL). Copies of the GPL can be obtained from:
5569 +     ftp://prep.ai.mit.edu/pub/gnu/GPL
5570 +
5571 +  2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
5572 +*/
5573 +
5574 +#include <linux/module.h>
5575 +#include <linux/skbuff.h>
5576 +#include <linux/ip.h>
5577 +#include <linux/random.h>
5578 +#include <net/tcp.h>
5579 +#include <linux/spinlock.h>
5580 +#include <linux/netfilter_ipv4/ip_tables.h>
5581 +#include <linux/netfilter_ipv4/ipt_random.h>
5582 +
5583 +MODULE_LICENSE("GPL");
5584 +
5585 +static int
5586 +ipt_rand_match(const struct sk_buff *pskb,
5587 +              const struct net_device *in,
5588 +              const struct net_device *out,
5589 +              const void *matchinfo,
5590 +              int offset,
5591 +              const void *hdr,
5592 +              u_int16_t datalen,
5593 +              int *hotdrop)
5594 +{
5595 +       /* Parameters from userspace */
5596 +       const struct ipt_rand_info *info = matchinfo;
5597 +       u_int8_t random_number;
5598 +
5599 +       /* get 1 random number from the kernel random number generation routine */
5600 +       get_random_bytes((void *)(&random_number), 1);
5601 +
5602 +       /* Do we match ? */
5603 +       if (random_number <= info->average)
5604 +               return 1;
5605 +       else
5606 +               return 0;
5607 +}
5608 +
5609 +static int
5610 +ipt_rand_checkentry(const char *tablename,
5611 +                  const struct ipt_ip *e,
5612 +                  void *matchinfo,
5613 +                  unsigned int matchsize,
5614 +                  unsigned int hook_mask)
5615 +{
5616 +       /* Parameters from userspace */
5617 +       const struct ipt_rand_info *info = matchinfo;
5618 +
5619 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_rand_info))) {
5620 +               printk("ipt_random: matchsize %u != %u\n", matchsize,
5621 +                      IPT_ALIGN(sizeof(struct ipt_rand_info)));
5622 +               return 0;
5623 +       }
5624 +
5625 +       /* must be  1 <= average % <= 99 */
5626 +       /* 1  x 2.55 = 2   */
5627 +       /* 99 x 2.55 = 252 */
5628 +       if ((info->average < 2) || (info->average > 252)) {
5629 +               printk("ipt_random:  invalid average %u\n", info->average);
5630 +               return 0;
5631 +       }
5632 +
5633 +       return 1;
5634 +}
5635 +
5636 +static struct ipt_match ipt_rand_reg = { 
5637 +       {NULL, NULL},
5638 +       "random",
5639 +       ipt_rand_match,
5640 +       ipt_rand_checkentry,
5641 +       NULL,
5642 +       THIS_MODULE };
5643 +
5644 +static int __init init(void)
5645 +{
5646 +       if (ipt_register_match(&ipt_rand_reg))
5647 +               return -EINVAL;
5648 +
5649 +       printk("ipt_random match loaded\n");
5650 +       return 0;
5651 +}
5652 +
5653 +static void __exit fini(void)
5654 +{
5655 +       ipt_unregister_match(&ipt_rand_reg);
5656 +       printk("ipt_random match unloaded\n");
5657 +}
5658 +
5659 +module_init(init);
5660 +module_exit(fini);
5661 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_realm.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_realm.c
5662 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_realm.c  1970-01-01 00:00:00.000000000 +0000
5663 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_realm.c      2004-03-22 08:29:57.000000000 +0000
5664 @@ -0,0 +1,78 @@
5665 +/* IP tables module for matching the routing realm
5666 + *
5667 + * $Id$
5668 + *
5669 + * (C) 2003 by Sampsa Ranta <sampsa@netsonic.fi>
5670 + *
5671 + * This program is free software; you can redistribute it and/or modify
5672 + * it under the terms of the GNU General Public License version 2 as
5673 + * published by the Free Software Foundation.
5674 + */
5675 +
5676 +#include <linux/module.h>
5677 +#include <linux/skbuff.h>
5678 +#include <linux/netdevice.h>
5679 +#include <net/route.h>
5680 +
5681 +#include <linux/netfilter_ipv4/ipt_realm.h>
5682 +#include <linux/netfilter_ipv4/ip_tables.h>
5683 +
5684 +MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>");
5685 +MODULE_LICENSE("GPL");
5686 +
5687 +static int
5688 +match(const struct sk_buff *skb,
5689 +      const struct net_device *in,
5690 +      const struct net_device *out,
5691 +      const void *matchinfo,
5692 +      int offset,
5693 +      int *hotdrop)
5694 +{
5695 +       const struct ipt_realm_info *info = matchinfo;
5696 +       struct dst_entry *dst = skb->dst;
5697 +    
5698 +       if (!dst)
5699 +               return 0;
5700 +
5701 +       return (info->id == (dst->tclassid & info->mask)) ^ info->invert;
5702 +}
5703 +
5704 +static int check(const char *tablename,
5705 +                 const struct ipt_ip *ip,
5706 +                 void *matchinfo,
5707 +                 unsigned int matchsize,
5708 +                 unsigned int hook_mask)
5709 +{
5710 +       if (hook_mask
5711 +           & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) |
5712 +               (1 << NF_IP_LOCAL_OUT)| (1 << NF_IP_LOCAL_IN))) {
5713 +               printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, "
5714 +                      "LOCAL_IN or FORWARD.\n");
5715 +               return 0;
5716 +       }
5717 +
5718 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info)))
5719 +               return 0;
5720 +
5721 +       return 1;
5722 +}
5723 +
5724 +static struct ipt_match realm_match = {
5725 +       .name = "realm",
5726 +       .match = match, 
5727 +       .checkentry = check,
5728 +       .me = THIS_MODULE
5729 +};
5730 +
5731 +static int __init init(void)
5732 +{
5733 +       return ipt_register_match(&realm_match);
5734 +}
5735 +
5736 +static void __exit fini(void)
5737 +{
5738 +       ipt_unregister_match(&realm_match);
5739 +}
5740 +
5741 +module_init(init);
5742 +module_exit(fini);
5743 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_sctp.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_sctp.c
5744 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_sctp.c   1970-01-01 00:00:00.000000000 +0000
5745 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_sctp.c       2004-03-22 08:30:03.000000000 +0000
5746 @@ -0,0 +1,199 @@
5747 +#include <linux/module.h>
5748 +#include <linux/skbuff.h>
5749 +#include <net/ip.h>
5750 +#include <linux/sctp.h>
5751 +
5752 +#include <linux/netfilter_ipv4/ip_tables.h>
5753 +#include <linux/netfilter_ipv4/ipt_sctp.h>
5754 +
5755 +#if 0
5756 +#define duprintf(format, args...) printk(format , ## args)
5757 +#else
5758 +#define duprintf(format, args...)
5759 +#endif
5760 +
5761 +#define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \
5762 +                                             || (!!((invflag) & (option)) ^ (cond)))
5763 +
5764 +static int
5765 +match_flags(const struct ipt_sctp_flag_info *flag_info,
5766 +           const int flag_count,
5767 +           u_int8_t chunktype,
5768 +           u_int8_t chunkflags)
5769 +{
5770 +       int i;
5771 +
5772 +       for (i = 0; i < flag_count; i++) {
5773 +               if (flag_info[i].chunktype == chunktype) {
5774 +                       return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag;
5775 +               }
5776 +       }
5777 +
5778 +       return 1;
5779 +}
5780 +
5781 +static int
5782 +match_packet(const struct sk_buff *skb,
5783 +            const u_int32_t *chunkmap,
5784 +            int chunk_match_type,
5785 +            const struct ipt_sctp_flag_info *flag_info,
5786 +            const int flag_count,
5787 +            int *hotdrop)
5788 +{
5789 +       int offset;
5790 +       u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
5791 +       sctp_chunkhdr_t sch;
5792 +
5793 +       int i = 0;
5794 +
5795 +       if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) {
5796 +               SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap);
5797 +       }
5798 +
5799 +       offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t);
5800 +       do {
5801 +               if (skb_copy_bits(skb, offset, &sch, sizeof(sch)) < 0) {
5802 +                       duprintf("Dropping invalid SCTP packet.\n");
5803 +                       *hotdrop = 1;
5804 +                       return 0;
5805 +               }
5806 +
5807 +               duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n", 
5808 +                               ++i, offset, sch.type, htons(sch.length), sch.flags);
5809 +
5810 +               offset += (htons(sch.length) + 3) & ~3;
5811 +
5812 +               duprintf("skb->len: %d\toffset: %d\n", skb->len, offset);
5813 +
5814 +               if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch.type)) {
5815 +                       switch (chunk_match_type) {
5816 +                       case SCTP_CHUNK_MATCH_ANY:
5817 +                               if (match_flags(flag_info, flag_count, 
5818 +                                       sch.type, sch.flags)) {
5819 +                                       return 1;
5820 +                               }
5821 +                               break;
5822 +
5823 +                       case SCTP_CHUNK_MATCH_ALL:
5824 +                               if (match_flags(flag_info, flag_count, 
5825 +                                       sch.type, sch.flags)) {
5826 +                                       SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch.type);
5827 +                               }
5828 +                               break;
5829 +
5830 +                       case SCTP_CHUNK_MATCH_ONLY:
5831 +                               if (!match_flags(flag_info, flag_count, 
5832 +                                       sch.type, sch.flags)) {
5833 +                                       return 0;
5834 +                               }
5835 +                               break;
5836 +                       }
5837 +               } else {
5838 +                       switch (chunk_match_type) {
5839 +                       case SCTP_CHUNK_MATCH_ONLY:
5840 +                               return 0;
5841 +                       }
5842 +               }
5843 +       } while (offset < skb->len);
5844 +
5845 +       switch (chunk_match_type) {
5846 +       case SCTP_CHUNK_MATCH_ALL:
5847 +               return SCTP_CHUNKMAP_IS_CLEAR(chunkmap);
5848 +       case SCTP_CHUNK_MATCH_ANY:
5849 +               return 0;
5850 +       case SCTP_CHUNK_MATCH_ONLY:
5851 +               return 1;
5852 +       }
5853 +
5854 +       /* This will never be reached, but required to stop compiler whine */
5855 +       return 0;
5856 +}
5857 +
5858 +static int
5859 +match(const struct sk_buff *skb,
5860 +      const struct net_device *in,
5861 +      const struct net_device *out,
5862 +      const void *matchinfo,
5863 +      int offset,
5864 +      int *hotdrop)
5865 +{
5866 +       const struct ipt_sctp_info *info;
5867 +       sctp_sctphdr_t sh;
5868 +
5869 +       info = (const struct ipt_sctp_info *)matchinfo;
5870 +
5871 +       if (offset) {
5872 +               duprintf("Dropping non-first fragment.. FIXME\n");
5873 +               return 0;
5874 +       }
5875 +       
5876 +       if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &sh, sizeof(sh)) < 0) {
5877 +               duprintf("Dropping evil TCP offset=0 tinygram.\n");
5878 +               *hotdrop = 1;
5879 +               return 0;
5880 +               }
5881 +       duprintf("spt: %d\tdpt: %d\n", ntohs(sh.source), ntohs(sh.dest));
5882 +
5883 +       return  SCCHECK(((ntohs(sh.source) >= info->spts[0]) 
5884 +                       && (ntohs(sh.source) <= info->spts[1])), 
5885 +                       IPT_SCTP_SRC_PORTS, info->flags, info->invflags)
5886 +               && SCCHECK(((ntohs(sh.dest) >= info->dpts[0]) 
5887 +                       && (ntohs(sh.dest) <= info->dpts[1])), 
5888 +                       IPT_SCTP_DEST_PORTS, info->flags, info->invflags)
5889 +               && SCCHECK(match_packet(skb, info->chunkmap, info->chunk_match_type,
5890 +                                       info->flag_info, info->flag_count, 
5891 +                                       hotdrop),
5892 +                          IPT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
5893 +}
5894 +
5895 +static int
5896 +checkentry(const char *tablename,
5897 +          const struct ipt_ip *ip,
5898 +          void *matchinfo,
5899 +          unsigned int matchsize,
5900 +          unsigned int hook_mask)
5901 +{
5902 +       const struct ipt_sctp_info *info;
5903 +
5904 +       info = (const struct ipt_sctp_info *)matchinfo;
5905 +
5906 +       return ip->proto == IPPROTO_SCTP
5907 +               && !(ip->invflags & IPT_INV_PROTO)
5908 +               && matchsize == IPT_ALIGN(sizeof(struct ipt_sctp_info))
5909 +               && !(info->flags & ~IPT_SCTP_VALID_FLAGS)
5910 +               && !(info->invflags & ~IPT_SCTP_VALID_FLAGS)
5911 +               && !(info->invflags & ~info->flags)
5912 +               && ((!(info->flags & IPT_SCTP_CHUNK_TYPES)) || 
5913 +                       (info->chunk_match_type &
5914 +                               (SCTP_CHUNK_MATCH_ALL 
5915 +                               | SCTP_CHUNK_MATCH_ANY
5916 +                               | SCTP_CHUNK_MATCH_ONLY)));
5917 +}
5918 +
5919 +static struct ipt_match sctp_match = 
5920 +{ 
5921 +       .list = { NULL, NULL},
5922 +       .name = "sctp",
5923 +       .match = &match,
5924 +       .checkentry = &checkentry,
5925 +       .destroy = NULL,
5926 +       .me = THIS_MODULE
5927 +};
5928 +
5929 +static int __init init(void)
5930 +{
5931 +       return ipt_register_match(&sctp_match);
5932 +}
5933 +
5934 +static void __exit fini(void)
5935 +{
5936 +       ipt_unregister_match(&sctp_match);
5937 +}
5938 +
5939 +module_init(init);
5940 +module_exit(fini);
5941 +
5942 +MODULE_LICENSE("GPL");
5943 +MODULE_AUTHOR("Kiran Kumar Immidi");
5944 +MODULE_DESCRIPTION("Match for SCTP protocol packets");
5945 +
5946 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_state.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_state.c
5947 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_state.c  2004-03-20 00:12:09.000000000 +0000
5948 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_state.c      2004-03-22 08:29:50.000000000 +0000
5949 @@ -30,7 +30,9 @@
5950         enum ip_conntrack_info ctinfo;
5951         unsigned int statebit;
5952  
5953 -       if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
5954 +       if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
5955 +               statebit = IPT_STATE_UNTRACKED;
5956 +       else if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
5957                 statebit = IPT_STATE_INVALID;
5958         else
5959                 statebit = IPT_STATE_BIT(ctinfo);
5960 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_time.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_time.c
5961 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_time.c   1970-01-01 00:00:00.000000000 +0000
5962 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_time.c       2004-03-22 08:30:10.000000000 +0000
5963 @@ -0,0 +1,185 @@
5964 +/*
5965 +  This is a module which is used for time matching
5966 +  It is using some modified code from dietlibc (localtime() function)
5967 +  that you can find at http://www.fefe.de/dietlibc/
5968 +  This file is distributed under the terms of the GNU General Public
5969 +  License (GPL). Copies of the GPL can be obtained from: ftp://prep.ai.mit.edu/pub/gnu/GPL
5970 +  2001-05-04 Fabrice MARIE <fabrice@netfilter.org> : initial development.
5971 +  2001-21-05 Fabrice MARIE <fabrice@netfilter.org> : bug fix in the match code,
5972 +     thanks to "Zeng Yu" <zengy@capitel.com.cn> for bug report.
5973 +  2001-26-09 Fabrice MARIE <fabrice@netfilter.org> : force the match to be in LOCAL_IN or PRE_ROUTING only.
5974 +  2001-30-11 Fabrice : added the possibility to use the match in FORWARD/OUTPUT with a little hack,
5975 +     added Nguyen Dang Phuoc Dong <dongnd@tlnet.com.vn> patch to support timezones.
5976 +*/
5977 +
5978 +#include <linux/module.h>
5979 +#include <linux/skbuff.h>
5980 +#include <linux/netfilter_ipv4/ip_tables.h>
5981 +#include <linux/netfilter_ipv4/ipt_time.h>
5982 +#include <linux/time.h>
5983 +
5984 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
5985 +MODULE_DESCRIPTION("Match arrival timestamp");
5986 +MODULE_LICENSE("GPL");
5987 +
5988 +struct tm
5989 +{
5990 +       int tm_sec;                   /* Seconds.     [0-60] (1 leap second) */
5991 +       int tm_min;                   /* Minutes.     [0-59] */
5992 +       int tm_hour;                  /* Hours.       [0-23] */
5993 +       int tm_mday;                  /* Day.         [1-31] */
5994 +       int tm_mon;                   /* Month.       [0-11] */
5995 +       int tm_year;                  /* Year - 1900.  */
5996 +       int tm_wday;                  /* Day of week. [0-6] */
5997 +       int tm_yday;                  /* Days in year.[0-365] */
5998 +       int tm_isdst;                 /* DST.         [-1/0/1]*/
5999 +
6000 +       long int tm_gmtoff;           /* we don't care, we count from GMT */
6001 +       const char *tm_zone;          /* we don't care, we count from GMT */
6002 +};
6003 +
6004 +void
6005 +localtime(const time_t *timepr, struct tm *r);
6006 +
6007 +static int
6008 +match(const struct sk_buff *skb,
6009 +      const struct net_device *in,
6010 +      const struct net_device *out,
6011 +      const void *matchinfo,
6012 +      int offset,
6013 +      const void *hdr,
6014 +      u_int16_t datalen,
6015 +      int *hotdrop)
6016 +{
6017 +       const struct ipt_time_info *info = matchinfo;   /* match info for rule */
6018 +       struct tm currenttime;                          /* time human readable */
6019 +       u_int8_t days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
6020 +       u_int16_t packet_time;
6021 +       struct timeval kerneltimeval;
6022 +       time_t packet_local_time;
6023 +
6024 +       /* if kerneltime=1, we don't read the skb->timestamp but kernel time instead */
6025 +       if (info->kerneltime)
6026 +       {
6027 +               do_gettimeofday(&kerneltimeval);
6028 +               packet_local_time = kerneltimeval.tv_sec;
6029 +       }
6030 +       else
6031 +               packet_local_time = skb->stamp.tv_sec;
6032 +
6033 +       /* Transform the timestamp of the packet, in a human readable form */
6034 +       localtime(&packet_local_time, &currenttime);
6035 +
6036 +       /* check if we match this timestamp, we start by the days... */
6037 +       if ((days_of_week[currenttime.tm_wday] & info->days_match) != days_of_week[currenttime.tm_wday])
6038 +               return 0; /* the day doesn't match */
6039 +
6040 +       /* ... check the time now */
6041 +       packet_time = (currenttime.tm_hour * 60) + currenttime.tm_min;
6042 +       if ((packet_time < info->time_start) || (packet_time > info->time_stop))
6043 +               return 0;
6044 +
6045 +       /* here we match ! */
6046 +       return 1;
6047 +}
6048 +
6049 +static int
6050 +checkentry(const char *tablename,
6051 +           const struct ipt_ip *ip,
6052 +           void *matchinfo,
6053 +           unsigned int matchsize,
6054 +           unsigned int hook_mask)
6055 +{
6056 +       struct ipt_time_info *info = matchinfo;   /* match info for rule */
6057 +
6058 +       /* First, check that we are in the correct hook */
6059 +       /* PRE_ROUTING, LOCAL_IN or FROWARD */
6060 +       if (hook_mask
6061 +            & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
6062 +       {
6063 +               printk("ipt_time: error, only valid for PRE_ROUTING, LOCAL_IN, FORWARD and OUTPUT)\n");
6064 +               return 0;
6065 +       }
6066 +       /* we use the kerneltime if we are in forward or output */
6067 +       info->kerneltime = 1;
6068 +       if (hook_mask & ~((1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT))) 
6069 +               /* if not, we use the skb time */
6070 +               info->kerneltime = 0;
6071 +
6072 +       /* Check the size */
6073 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_time_info)))
6074 +               return 0;
6075 +       /* Now check the coherence of the data ... */
6076 +       if ((info->time_start > 1439) ||        /* 23*60+59 = 1439*/
6077 +           (info->time_stop  > 1439))
6078 +       {
6079 +               printk(KERN_WARNING "ipt_time: invalid argument\n");
6080 +               return 0;
6081 +       }
6082 +
6083 +       return 1;
6084 +}
6085 +
6086 +static struct ipt_match time_match
6087 += { { NULL, NULL }, "time", &match, &checkentry, NULL, THIS_MODULE };
6088 +
6089 +static int __init init(void)
6090 +{
6091 +       printk("ipt_time loading\n");
6092 +       return ipt_register_match(&time_match);
6093 +}
6094 +
6095 +static void __exit fini(void)
6096 +{
6097 +       ipt_unregister_match(&time_match);
6098 +       printk("ipt_time unloaded\n");
6099 +}
6100 +
6101 +module_init(init);
6102 +module_exit(fini);
6103 +
6104 +
6105 +/* The part below is borowed and modified from dietlibc */
6106 +
6107 +/* seconds per day */
6108 +#define SPD 24*60*60
6109 +
6110 +void
6111 +localtime(const time_t *timepr, struct tm *r) {
6112 +       time_t i;
6113 +       time_t timep;
6114 +       extern struct timezone sys_tz;
6115 +       const unsigned int __spm[12] =
6116 +               { 0,
6117 +                 (31),
6118 +                 (31+28),
6119 +                 (31+28+31),
6120 +                 (31+28+31+30),
6121 +                 (31+28+31+30+31),
6122 +                 (31+28+31+30+31+30),
6123 +                 (31+28+31+30+31+30+31),
6124 +                 (31+28+31+30+31+30+31+31),
6125 +                 (31+28+31+30+31+30+31+31+30),
6126 +                 (31+28+31+30+31+30+31+31+30+31),
6127 +                 (31+28+31+30+31+30+31+31+30+31+30),
6128 +               };
6129 +       register time_t work;
6130 +
6131 +       timep = (*timepr) - (sys_tz.tz_minuteswest * 60);
6132 +       work=timep%(SPD);
6133 +       r->tm_sec=work%60; work/=60;
6134 +       r->tm_min=work%60; r->tm_hour=work/60;
6135 +       work=timep/(SPD);
6136 +       r->tm_wday=(4+work)%7;
6137 +       for (i=1970; ; ++i) {
6138 +               register time_t k= (!(i%4) && ((i%100) || !(i%400)))?366:365;
6139 +               if (work>k)
6140 +                       work-=k;
6141 +               else
6142 +                       break;
6143 +       }
6144 +       r->tm_year=i-1900;
6145 +       for (i=11; i && __spm[i]>work; --i) ;
6146 +       r->tm_mon=i;
6147 +       r->tm_mday=work-__spm[i]+1;
6148 +}
6149 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_u32.c linux-2.6.5-rc2/net/ipv4/netfilter/ipt_u32.c
6150 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/ipt_u32.c    1970-01-01 00:00:00.000000000 +0000
6151 +++ linux-2.6.5-rc2/net/ipv4/netfilter/ipt_u32.c        2004-03-22 08:30:19.000000000 +0000
6152 @@ -0,0 +1,211 @@
6153 +/* Kernel module to match u32 packet content. */
6154 +
6155 +/* 
6156 +U32 tests whether quantities of up to 4 bytes extracted from a packet 
6157 +have specified values.  The specification of what to extract is general 
6158 +enough to find data at given offsets from tcp headers or payloads.
6159 +
6160 + --u32 tests
6161 + The argument amounts to a program in a small language described below.
6162 + tests := location = value |  tests && location = value
6163 + value := range | value , range
6164 + range := number | number : number
6165 +  a single number, n, is interpreted the same as n:n
6166 +  n:m is interpreted as the range of numbers >=n and <=m
6167 + location := number | location operator number
6168 + operator := & | << | >> | @
6169 +
6170 + The operators &, <<, >>, && mean the same as in c.  The = is really a set
6171 + membership operator and the value syntax describes a set.  The @ operator
6172 + is what allows moving to the next header and is described further below.
6173 +
6174 + *** Until I can find out how to avoid it, there are some artificial limits
6175 + on the size of the tests:
6176 + - no more than 10 ='s (and 9 &&'s) in the u32 argument
6177 + - no more than 10 ranges (and 9 commas) per value
6178 + - no more than 10 numbers (and 9 operators) per location
6179 +
6180 + To describe the meaning of location, imagine the following machine that
6181 + interprets it.  There are three registers:
6182 +  A is of type char*, initially the address of the IP header
6183 +  B and C are unsigned 32 bit integers, initially zero
6184 +
6185 +  The instructions are:
6186 +   number      B = number;
6187 +               C = (*(A+B)<<24)+(*(A+B+1)<<16)+(*(A+B+2)<<8)+*(A+B+3)
6188 +   &number     C = C&number
6189 +   <<number    C = C<<number
6190 +   >>number    C = C>>number
6191 +   @number     A = A+C; then do the instruction number
6192 +  Any access of memory outside [skb->head,skb->end] causes the match to fail.
6193 +  Otherwise the result of the computation is the final value of C.
6194 +
6195 + Whitespace is allowed but not required in the tests.
6196 + However the characters that do occur there are likely to require
6197 + shell quoting, so it's a good idea to enclose the arguments in quotes.
6198 +
6199 +Example:
6200 + match IP packets with total length >= 256
6201 + The IP header contains a total length field in bytes 2-3.
6202 + --u32 "0&0xFFFF=0x100:0xFFFF" 
6203 + read bytes 0-3
6204 + AND that with FFFF (giving bytes 2-3),
6205 + and test whether that's in the range [0x100:0xFFFF]
6206 +
6207 +Example: (more realistic, hence more complicated)
6208 + match icmp packets with icmp type 0
6209 + First test that it's an icmp packet, true iff byte 9 (protocol) = 1
6210 + --u32 "6&0xFF=1 && ...
6211 + read bytes 6-9, use & to throw away bytes 6-8 and compare the result to 1
6212 + Next test that it's not a fragment.
6213 +  (If so it might be part of such a packet but we can't always tell.)
6214 +  n.b. This test is generally needed if you want to match anything
6215 +  beyond the IP header.
6216 + The last 6 bits of byte 6 and all of byte 7 are 0 iff this is a complete
6217 + packet (not a fragment).  Alternatively, you can allow first fragments
6218 + by only testing the last 5 bits of byte 6.
6219 + ... 4&0x3FFF=0 && ...
6220 + Last test: the first byte past the IP header (the type) is 0
6221 + This is where we have to use the @syntax.  The length of the IP header
6222 + (IHL) in 32 bit words is stored in the right half of byte 0 of the
6223 + IP header itself.
6224 + ... 0>>22&0x3C@0>>24=0"
6225 + The first 0 means read bytes 0-3,
6226 + >>22 means shift that 22 bits to the right.  Shifting 24 bits would give
6227 +   the first byte, so only 22 bits is four times that plus a few more bits.
6228 + &3C then eliminates the two extra bits on the right and the first four 
6229 + bits of the first byte.
6230 + For instance, if IHL=5 then the IP header is 20 (4 x 5) bytes long.
6231 + In this case bytes 0-1 are (in binary) xxxx0101 yyzzzzzz, 
6232 + >>22 gives the 10 bit value xxxx0101yy and &3C gives 010100.
6233 + @ means to use this number as a new offset into the packet, and read
6234 + four bytes starting from there.  This is the first 4 bytes of the icmp
6235 + payload, of which byte 0 is the icmp type.  Therefore we simply shift
6236 + the value 24 to the right to throw out all but the first byte and compare
6237 + the result with 0.
6238 +
6239 +Example: 
6240 + tcp payload bytes 8-12 is any of 1, 2, 5 or 8
6241 + First we test that the packet is a tcp packet (similar to icmp).
6242 + --u32 "6&0xFF=6 && ...
6243 + Next, test that it's not a fragment (same as above).
6244 + ... 0>>22&0x3C@12>>26&0x3C@8=1,2,5,8"
6245 + 0>>22&3C as above computes the number of bytes in the IP header.
6246 + @ makes this the new offset into the packet, which is the start of the
6247 + tcp header.  The length of the tcp header (again in 32 bit words) is
6248 + the left half of byte 12 of the tcp header.  The 12>>26&3C
6249 + computes this length in bytes (similar to the IP header before).
6250 + @ makes this the new offset, which is the start of the tcp payload.
6251 + Finally 8 reads bytes 8-12 of the payload and = checks whether the
6252 + result is any of 1, 2, 5 or 8
6253 +*/
6254 +
6255 +#include <linux/module.h>
6256 +#include <linux/skbuff.h>
6257 +
6258 +#include <linux/netfilter_ipv4/ipt_u32.h>
6259 +#include <linux/netfilter_ipv4/ip_tables.h>
6260 +
6261 +/* #include <asm-i386/timex.h> for timing */
6262 +
6263 +MODULE_AUTHOR("Don Cohen <don@isis.cs3-inc.com>");
6264 +MODULE_DESCRIPTION("IP tables u32 matching module");
6265 +MODULE_LICENSE("GPL");
6266 +
6267 +static int
6268 +match(const struct sk_buff *skb,
6269 +      const struct net_device *in,
6270 +      const struct net_device *out,
6271 +      const void *matchinfo,
6272 +      int offset,
6273 +      const void *hdr,
6274 +      u_int16_t datalen,
6275 +      int *hotdrop)
6276 +{
6277 +       const struct ipt_u32 *data = matchinfo;
6278 +       int testind, i;
6279 +       unsigned char* origbase = (char*)skb->nh.iph;
6280 +       unsigned char* base = origbase;
6281 +       unsigned char* head = skb->head;
6282 +       unsigned char* end = skb->end;
6283 +       int nnums, nvals;
6284 +       u_int32_t pos, val;
6285 +       /* unsigned long long cycles1, cycles2, cycles3, cycles4;
6286 +          cycles1 = get_cycles(); */
6287 +
6288 +       for (testind=0; testind < data->ntests; testind++) {
6289 +               base = origbase; /* reset for each test */
6290 +               pos = data->tests[testind].location[0].number;
6291 +               if (base+pos+3 > end || base+pos < head) 
6292 +                       return 0;
6293 +               val = (base[pos]<<24) + (base[pos+1]<<16) +
6294 +                       (base[pos+2]<<8) + base[pos+3];
6295 +               nnums = data->tests[testind].nnums;
6296 +               for (i=1; i < nnums; i++) {
6297 +                       u_int32_t number = data->tests[testind].location[i].number;
6298 +                       switch (data->tests[testind].location[i].nextop) {
6299 +                       case IPT_U32_AND: 
6300 +                               val = val & number; 
6301 +                               break;
6302 +                       case IPT_U32_LEFTSH: 
6303 +                               val = val << number;
6304 +                               break;
6305 +                       case IPT_U32_RIGHTSH: 
6306 +                               val = val >> number; 
6307 +                               break;
6308 +                       case IPT_U32_AT:
6309 +                               base = base + val;
6310 +                               pos = number;
6311 +                               if (base+pos+3 > end || base+pos < head) 
6312 +                                       return 0;
6313 +                               val = (base[pos]<<24) + (base[pos+1]<<16) +
6314 +                                       (base[pos+2]<<8) + base[pos+3];
6315 +                               break;
6316 +                       }
6317 +               }
6318 +               nvals = data->tests[testind].nvalues;
6319 +               for (i=0; i < nvals; i++) {
6320 +                       if ((data->tests[testind].value[i].min <= val) &&
6321 +                           (val <= data->tests[testind].value[i].max)) {
6322 +                               break;
6323 +                       }
6324 +               }
6325 +               if (i >= data->tests[testind].nvalues) {
6326 +                       /* cycles2 = get_cycles(); 
6327 +                          printk("failed %d in %d cycles\n", testind, 
6328 +                                 cycles2-cycles1); */
6329 +                       return 0;
6330 +               }
6331 +       }
6332 +       /* cycles2 = get_cycles();
6333 +          printk("succeeded in %d cycles\n", cycles2-cycles1); */
6334 +       return 1;
6335 +}
6336 +
6337 +static int
6338 +checkentry(const char *tablename,
6339 +           const struct ipt_ip *ip,
6340 +           void *matchinfo,
6341 +           unsigned int matchsize,
6342 +           unsigned int hook_mask)
6343 +{
6344 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_u32)))
6345 +               return 0;
6346 +       return 1;
6347 +}
6348 +
6349 +static struct ipt_match u32_match
6350 += { { NULL, NULL }, "u32", &match, &checkentry, NULL, THIS_MODULE };
6351 +
6352 +static int __init init(void)
6353 +{
6354 +       return ipt_register_match(&u32_match);
6355 +}
6356 +
6357 +static void __exit fini(void)
6358 +{
6359 +       ipt_unregister_match(&u32_match);
6360 +}
6361 +
6362 +module_init(init);
6363 +module_exit(fini);
6364 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv4/netfilter/iptable_raw.c linux-2.6.5-rc2/net/ipv4/netfilter/iptable_raw.c
6365 --- linux-2.6.5-rc2.org/net/ipv4/netfilter/iptable_raw.c        1970-01-01 00:00:00.000000000 +0000
6366 +++ linux-2.6.5-rc2/net/ipv4/netfilter/iptable_raw.c    2004-03-22 08:29:50.000000000 +0000
6367 @@ -0,0 +1,149 @@
6368 +/* 
6369 + * 'raw' table, which is the very first hooked in at PRE_ROUTING and LOCAL_OUT .
6370 + *
6371 + * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
6372 + */
6373 +#include <linux/module.h>
6374 +#include <linux/netfilter_ipv4/ip_tables.h>
6375 +
6376 +#define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
6377 +
6378 +/* Standard entry. */
6379 +struct ipt_standard
6380 +{
6381 +       struct ipt_entry entry;
6382 +       struct ipt_standard_target target;
6383 +};
6384 +
6385 +struct ipt_error_target
6386 +{
6387 +       struct ipt_entry_target target;
6388 +       char errorname[IPT_FUNCTION_MAXNAMELEN];
6389 +};
6390 +
6391 +struct ipt_error
6392 +{
6393 +       struct ipt_entry entry;
6394 +       struct ipt_error_target target;
6395 +};
6396 +
6397 +static struct
6398 +{
6399 +       struct ipt_replace repl;
6400 +       struct ipt_standard entries[2];
6401 +       struct ipt_error term;
6402 +} initial_table __initdata
6403 += { { "raw", RAW_VALID_HOOKS, 3,
6404 +      sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
6405 +      { [NF_IP_PRE_ROUTING] 0,
6406 +       [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
6407 +      { [NF_IP_PRE_ROUTING] 0,
6408 +       [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
6409 +      0, NULL, { } },
6410 +    {
6411 +           /* PRE_ROUTING */
6412 +           { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
6413 +               0,
6414 +               sizeof(struct ipt_entry),
6415 +               sizeof(struct ipt_standard),
6416 +               0, { 0, 0 }, { } },
6417 +             { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
6418 +               -NF_ACCEPT - 1 } },
6419 +           /* LOCAL_OUT */
6420 +           { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
6421 +               0,
6422 +               sizeof(struct ipt_entry),
6423 +               sizeof(struct ipt_standard),
6424 +               0, { 0, 0 }, { } },
6425 +             { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
6426 +               -NF_ACCEPT - 1 } }
6427 +    },
6428 +    /* ERROR */
6429 +    { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
6430 +       0,
6431 +       sizeof(struct ipt_entry),
6432 +       sizeof(struct ipt_error),
6433 +       0, { 0, 0 }, { } },
6434 +      { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } },
6435 +         { } },
6436 +       "ERROR"
6437 +      }
6438 +    }
6439 +};
6440 +
6441 +static struct ipt_table packet_raw = { 
6442 +       .name = "raw", 
6443 +       .table = &initial_table.repl,
6444 +       .valid_hooks =  RAW_VALID_HOOKS, 
6445 +       .lock = RW_LOCK_UNLOCKED, 
6446 +       .me = THIS_MODULE
6447 +};
6448 +
6449 +/* The work comes in here from netfilter.c. */
6450 +static unsigned int
6451 +ipt_hook(unsigned int hook,
6452 +        struct sk_buff **pskb,
6453 +        const struct net_device *in,
6454 +        const struct net_device *out,
6455 +        int (*okfn)(struct sk_buff *))
6456 +{
6457 +       return ipt_do_table(pskb, hook, in, out, &packet_raw, NULL);
6458 +}
6459 +
6460 +/* 'raw' is the very first table. */
6461 +static struct nf_hook_ops ipt_ops[] = {
6462 +       {
6463 +         .hook = ipt_hook, 
6464 +         .pf = PF_INET, 
6465 +         .hooknum = NF_IP_PRE_ROUTING, 
6466 +         .priority = NF_IP_PRI_RAW
6467 +       },
6468 +       {
6469 +         .hook = ipt_hook, 
6470 +         .pf = PF_INET, 
6471 +         .hooknum = NF_IP_LOCAL_OUT, 
6472 +         .priority = NF_IP_PRI_RAW
6473 +       },
6474 +};
6475 +
6476 +static int __init init(void)
6477 +{
6478 +       int ret;
6479 +
6480 +       /* Register table */
6481 +       ret = ipt_register_table(&packet_raw);
6482 +       if (ret < 0)
6483 +               return ret;
6484 +
6485 +       /* Register hooks */
6486 +       ret = nf_register_hook(&ipt_ops[0]);
6487 +       if (ret < 0)
6488 +               goto cleanup_table;
6489 +
6490 +       ret = nf_register_hook(&ipt_ops[1]);
6491 +       if (ret < 0)
6492 +               goto cleanup_hook0;
6493 +
6494 +       return ret;
6495 +
6496 + cleanup_hook0:
6497 +       nf_unregister_hook(&ipt_ops[0]);
6498 + cleanup_table:
6499 +       ipt_unregister_table(&packet_raw);
6500 +
6501 +       return ret;
6502 +}
6503 +
6504 +static void __exit fini(void)
6505 +{
6506 +       unsigned int i;
6507 +
6508 +       for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++)
6509 +               nf_unregister_hook(&ipt_ops[i]);
6510 +
6511 +       ipt_unregister_table(&packet_raw);
6512 +}
6513 +
6514 +module_init(init);
6515 +module_exit(fini);
6516 +MODULE_LICENSE("GPL");
6517 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/Kconfig linux-2.6.5-rc2/net/ipv6/netfilter/Kconfig
6518 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/Kconfig      2004-03-20 00:11:42.000000000 +0000
6519 +++ linux-2.6.5-rc2/net/ipv6/netfilter/Kconfig  2004-03-22 08:29:50.000000000 +0000
6520 @@ -218,5 +218,42 @@
6521           To compile it as a module, choose M here.  If unsure, say N.
6522  
6523  #dep_tristate '  LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES
6524 +config IP6_NF_TARGET_HL
6525 +       tristate  'HL target support'
6526 +       depends on IP6_NF_MANGLE
6527 +         help
6528 +
6529 +config IP6_NF_TARGET_REJECT
6530 +       tristate  'REJECT target support'
6531 +       depends on IP6_NF_FILTER
6532 +         help
6533 +
6534 +config IP6_NF_MATCH_FUZZY
6535 +       tristate  'Fuzzy match support'
6536 +       depends on IP6_NF_FILTER
6537 +         help
6538 +
6539 +config IP6_NF_MATCH_NTH
6540 +       tristate  'Nth match support'
6541 +       depends on IP6_NF_IPTABLES
6542 +         help
6543 +
6544 +config IP6_NF_MATCH_RANDOM
6545 +       tristate  'Random match support'
6546 +       depends on IP6_NF_IPTABLES
6547 +         help
6548 +
6549 +config IP6_NF_RAW
6550 +       tristate  'raw table support (required for TRACE)'
6551 +       depends on IP6_NF_IPTABLES
6552 +       help
6553 +         This option adds a `raw' table to ip6tables. This table is the very
6554 +         first in the netfilter framework and hooks in at the PREROUTING
6555 +         and OUTPUT chains.
6556 +       
6557 +         If you want to compile it as a module, say M here and read
6558 +         <file:Documentation/modules.txt>.  If unsure, say `N'.
6559 +         help
6560 +
6561  endmenu
6562  
6563 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/Makefile linux-2.6.5-rc2/net/ipv6/netfilter/Makefile
6564 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/Makefile     2004-03-20 00:11:32.000000000 +0000
6565 +++ linux-2.6.5-rc2/net/ipv6/netfilter/Makefile 2004-03-22 08:29:50.000000000 +0000
6566 @@ -8,6 +8,7 @@
6567  obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o
6568  obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
6569  obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o
6570 +obj-$(CONFIG_IP6_NF_MATCH_FUZZY) += ip6t_fuzzy.o
6571  obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
6572  obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
6573  obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
6574 @@ -19,6 +20,13 @@
6575  obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
6576  obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
6577  obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
6578 +obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
6579  obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
6580  obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
6581 +obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
6582 +
6583 +obj-$(CONFIG_IP6_NF_MATCH_RANDOM) += ip6t_random.o
6584 +
6585 +obj-$(CONFIG_IP6_NF_MATCH_NTH) += ip6t_nth.o
6586 +obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
6587  obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
6588 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_HL.c linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_HL.c
6589 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_HL.c    1970-01-01 00:00:00.000000000 +0000
6590 +++ linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_HL.c        2004-03-22 08:27:23.000000000 +0000
6591 @@ -0,0 +1,105 @@
6592 +/* 
6593 + * Hop Limit modification target for ip6tables
6594 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
6595 + * Based on HW's TTL module
6596 + *
6597 + * This software is distributed under the terms of GNU GPL
6598 + */
6599 +
6600 +#include <linux/module.h>
6601 +#include <linux/skbuff.h>
6602 +#include <linux/ip.h>
6603 +
6604 +#include <linux/netfilter_ipv6/ip6_tables.h>
6605 +#include <linux/netfilter_ipv6/ip6t_HL.h>
6606 +
6607 +MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
6608 +MODULE_DESCRIPTION("IP tables Hop Limit modification module");
6609 +MODULE_LICENSE("GPL");
6610 +
6611 +static unsigned int ip6t_hl_target(struct sk_buff **pskb, unsigned int hooknum,
6612 +               const struct net_device *in, const struct net_device *out,
6613 +               const void *targinfo, void *userinfo)
6614 +{
6615 +       struct ipv6hdr *ip6h = (*pskb)->nh.ipv6h;
6616 +       const struct ip6t_HL_info *info = targinfo;
6617 +       u_int16_t diffs[2];
6618 +       int new_hl;
6619 +                        
6620 +       switch (info->mode) {
6621 +               case IP6T_HL_SET:
6622 +                       new_hl = info->hop_limit;
6623 +                       break;
6624 +               case IP6T_HL_INC:
6625 +                       new_hl = ip6h->hop_limit + info->hop_limit;
6626 +                       if (new_hl > 255)
6627 +                               new_hl = 255;
6628 +                       break;
6629 +               case IP6T_HL_DEC:
6630 +                       new_hl = ip6h->hop_limit + info->hop_limit;
6631 +                       if (new_hl < 0)
6632 +                               new_hl = 0;
6633 +                       break;
6634 +               default:
6635 +                       new_hl = ip6h->hop_limit;
6636 +                       break;
6637 +       }
6638 +
6639 +       if (new_hl != ip6h->hop_limit) {
6640 +               diffs[0] = htons(((unsigned)ip6h->hop_limit) << 8) ^ 0xFFFF;
6641 +               ip6h->hop_limit = new_hl;
6642 +               diffs[1] = htons(((unsigned)ip6h->hop_limit) << 8);
6643 +       }
6644 +
6645 +       return IP6T_CONTINUE;
6646 +}
6647 +
6648 +static int ip6t_hl_checkentry(const char *tablename,
6649 +               const struct ip6t_entry *e,
6650 +               void *targinfo,
6651 +               unsigned int targinfosize,
6652 +               unsigned int hook_mask)
6653 +{
6654 +       struct ip6t_HL_info *info = targinfo;
6655 +
6656 +       if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_HL_info))) {
6657 +               printk(KERN_WARNING "HL: targinfosize %u != %Zu\n",
6658 +                               targinfosize,
6659 +                               IP6T_ALIGN(sizeof(struct ip6t_HL_info)));
6660 +               return 0;       
6661 +       }       
6662 +
6663 +       if (strcmp(tablename, "mangle")) {
6664 +               printk(KERN_WARNING "HL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
6665 +               return 0;
6666 +       }
6667 +
6668 +       if (info->mode > IP6T_HL_MAXMODE) {
6669 +               printk(KERN_WARNING "HL: invalid or unknown Mode %u\n", 
6670 +                       info->mode);
6671 +               return 0;
6672 +       }
6673 +
6674 +       if ((info->mode != IP6T_HL_SET) && (info->hop_limit == 0)) {
6675 +               printk(KERN_WARNING "HL: increment/decrement doesn't make sense with value 0\n");
6676 +               return 0;
6677 +       }
6678 +       
6679 +       return 1;
6680 +}
6681 +
6682 +static struct ip6t_target ip6t_HL = { { NULL, NULL }, "HL", 
6683 +       ip6t_hl_target, ip6t_hl_checkentry, NULL, THIS_MODULE };
6684 +
6685 +static int __init init(void)
6686 +{
6687 +       return ip6t_register_target(&ip6t_HL);
6688 +}
6689 +
6690 +static void __exit fini(void)
6691 +{
6692 +       ip6t_unregister_target(&ip6t_HL);
6693 +}
6694 +
6695 +module_init(init);
6696 +module_exit(fini);
6697 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_LOG.c linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_LOG.c
6698 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_LOG.c   2004-03-20 00:11:04.000000000 +0000
6699 +++ linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_LOG.c       2004-03-22 08:27:15.000000000 +0000
6700 @@ -18,12 +18,17 @@
6701  #include <net/udp.h>
6702  #include <net/tcp.h>
6703  #include <net/ipv6.h>
6704 +#include <linux/netfilter.h>
6705  #include <linux/netfilter_ipv6/ip6_tables.h>
6706  
6707  MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
6708  MODULE_DESCRIPTION("IP6 tables LOG target module");
6709  MODULE_LICENSE("GPL");
6710  
6711 +static unsigned int nflog = 1;
6712 +MODULE_PARM(nflog, "i");
6713 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
6714
6715  struct in_device;
6716  #include <net/route.h>
6717  #include <linux/netfilter_ipv6/ip6t_LOG.h>
6718 @@ -265,40 +270,38 @@
6719         }
6720  }
6721  
6722 -static unsigned int
6723 -ip6t_log_target(struct sk_buff **pskb,
6724 -               unsigned int hooknum,
6725 +static void
6726 +ip6t_log_packet(unsigned int hooknum,
6727 +               const struct sk_buff *skb,
6728                 const struct net_device *in,
6729                 const struct net_device *out,
6730 -               const void *targinfo,
6731 -               void *userinfo)
6732 +               const struct ip6t_log_info *loginfo,
6733 +               const char *level_string,
6734 +               const char *prefix)
6735  {
6736 -       struct ipv6hdr *ipv6h = (*pskb)->nh.ipv6h;
6737 -       const struct ip6t_log_info *loginfo = targinfo;
6738 -       char level_string[4] = "< >";
6739 +       struct ipv6hdr *ipv6h = skb->nh.ipv6h;
6740  
6741 -       level_string[1] = '0' + (loginfo->level % 8);
6742         spin_lock_bh(&log_lock);
6743         printk(level_string);
6744         printk("%sIN=%s OUT=%s ",
6745 -               loginfo->prefix,
6746 +               prefix == NULL ? loginfo->prefix : prefix,
6747                 in ? in->name : "",
6748                 out ? out->name : "");
6749         if (in && !out) {
6750                 /* MAC logging for input chain only. */
6751                 printk("MAC=");
6752 -               if ((*pskb)->dev && (*pskb)->dev->hard_header_len && (*pskb)->mac.raw != (void*)ipv6h) {
6753 -                       if ((*pskb)->dev->type != ARPHRD_SIT){
6754 +               if (skb->dev && skb->dev->hard_header_len && skb->mac.raw != (void*)ipv6h) {
6755 +                       if (skb->dev->type != ARPHRD_SIT){
6756                           int i;
6757 -                         unsigned char *p = (*pskb)->mac.raw;
6758 -                         for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++)
6759 +                         unsigned char *p = skb->mac.raw;
6760 +                         for (i = 0; i < skb->dev->hard_header_len; i++,p++)
6761                                 printk("%02x%c", *p,
6762 -                                       i==(*pskb)->dev->hard_header_len - 1
6763 +                                       i==skb->dev->hard_header_len - 1
6764                                         ? ' ':':');
6765                         } else {
6766                           int i;
6767 -                         unsigned char *p = (*pskb)->mac.raw;
6768 -                         if ( p - (ETH_ALEN*2+2) > (*pskb)->head ){
6769 +                         unsigned char *p = skb->mac.raw;
6770 +                         if ( p - (ETH_ALEN*2+2) > skb->head ){
6771                             p -= (ETH_ALEN+2);
6772                             for (i = 0; i < (ETH_ALEN); i++,p++)
6773                                 printk("%02x%s", *p,
6774 @@ -309,10 +312,10 @@
6775                                         i == ETH_ALEN-1 ? ' ' : ':');
6776                           }
6777                           
6778 -                         if (((*pskb)->dev->addr_len == 4) &&
6779 -                             (*pskb)->dev->hard_header_len > 20){
6780 +                         if ((skb->dev->addr_len == 4) &&
6781 +                             skb->dev->hard_header_len > 20){
6782                             printk("TUNNEL=");
6783 -                           p = (*pskb)->mac.raw + 12;
6784 +                           p = skb->mac.raw + 12;
6785                             for (i = 0; i < 4; i++,p++)
6786                                 printk("%3d%s", *p,
6787                                         i == 3 ? "->" : ".");
6788 @@ -328,10 +331,41 @@
6789         dump_packet(loginfo, ipv6h, 1);
6790         printk("\n");
6791         spin_unlock_bh(&log_lock);
6792 +}
6793 +
6794 +static unsigned int
6795 +ip6t_log_target(struct sk_buff **pskb,
6796 +               unsigned int hooknum,
6797 +               const struct net_device *in,
6798 +               const struct net_device *out,
6799 +               const void *targinfo,
6800 +               void *userinfo)
6801 +{
6802 +       const struct ip6t_log_info *loginfo = targinfo;
6803 +       char level_string[4] = "< >";
6804 +
6805 +       level_string[1] = '0' + (loginfo->level % 8);
6806 +       ip6t_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL);
6807  
6808         return IP6T_CONTINUE;
6809  }
6810  
6811 +static void
6812 +ip6t_logfn(unsigned int hooknum,
6813 +          const struct sk_buff *skb,
6814 +          const struct net_device *in,
6815 +          const struct net_device *out,
6816 +          const char *prefix)
6817 +{
6818 +       struct ip6t_log_info loginfo = {
6819 +               .level = 0,
6820 +               .logflags = IP6T_LOG_MASK,
6821 +               .prefix = ""
6822 +       };
6823 +
6824 +       ip6t_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
6825 +}
6826 +
6827  static int ip6t_log_checkentry(const char *tablename,
6828                                const struct ip6t_entry *e,
6829                                void *targinfo,
6830 @@ -360,20 +394,27 @@
6831         return 1;
6832  }
6833  
6834 -static struct ip6t_target ip6t_log_reg
6835 -= { { NULL, NULL }, "LOG", ip6t_log_target, ip6t_log_checkentry, NULL, 
6836 -    THIS_MODULE };
6837 +static struct ip6t_target ip6t_log_reg = {
6838 +       .name           = "LOG",
6839 +       .target         = ip6t_log_target, 
6840 +       .checkentry     = ip6t_log_checkentry, 
6841 +       .me             = THIS_MODULE,
6842 +};
6843  
6844  static int __init init(void)
6845  {
6846         if (ip6t_register_target(&ip6t_log_reg))
6847                 return -EINVAL;
6848 +       if (nflog)
6849 +               nf_log_register(PF_INET6, &ip6t_logfn);
6850  
6851         return 0;
6852  }
6853  
6854  static void __exit fini(void)
6855  {
6856 +       if (nflog)
6857 +               nf_log_unregister(PF_INET6, &ip6t_logfn);
6858         ip6t_unregister_target(&ip6t_log_reg);
6859  }
6860  
6861 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_REJECT.c linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_REJECT.c
6862 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_REJECT.c        1970-01-01 00:00:00.000000000 +0000
6863 +++ linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_REJECT.c    2004-03-22 08:28:02.000000000 +0000
6864 @@ -0,0 +1,274 @@
6865 +/*
6866 + * This is a module which is used for rejecting packets.
6867 + *     Added support for customized reject packets (Jozsef Kadlecsik).
6868 + * Sun 12 Nov 2000
6869 + *     Port to IPv6 / ip6tables (Harald Welte <laforge@gnumonks.org>)
6870 + */
6871 +#include <linux/config.h>
6872 +#include <linux/module.h>
6873 +#include <linux/skbuff.h>
6874 +#include <linux/icmpv6.h>
6875 +#include <net/tcp.h>
6876 +#include <linux/netfilter_ipv6/ip6_tables.h>
6877 +#include <linux/netfilter_ipv6/ip6t_REJECT.h>
6878 +
6879 +#if 1
6880 +#define DEBUGP printk
6881 +#else
6882 +#define DEBUGP(format, args...)
6883 +#endif
6884 +
6885 +#if 0
6886 +/* Send RST reply */
6887 +static void send_reset(struct sk_buff *oldskb)
6888 +{
6889 +       struct sk_buff *nskb;
6890 +       struct tcphdr *otcph, *tcph;
6891 +       struct rtable *rt;
6892 +       unsigned int otcplen;
6893 +       int needs_ack;
6894 +
6895 +       /* IP header checks: fragment, too short. */
6896 +       if (oldskb->nh.iph->frag_off & htons(IP_OFFSET)
6897 +           || oldskb->len < (oldskb->nh.iph->ihl<<2) + sizeof(struct tcphdr))
6898 +               return;
6899 +
6900 +       otcph = (struct tcphdr *)((u_int32_t*)oldskb->nh.iph + oldskb->nh.iph->ihl);
6901 +       otcplen = oldskb->len - oldskb->nh.iph->ihl*4;
6902 +
6903 +       /* No RST for RST. */
6904 +       if (otcph->rst)
6905 +               return;
6906 +
6907 +       /* Check checksum. */
6908 +       if (tcp_v4_check(otcph, otcplen, oldskb->nh.iph->saddr,
6909 +                        oldskb->nh.iph->daddr,
6910 +                        csum_partial((char *)otcph, otcplen, 0)) != 0)
6911 +               return;
6912 +
6913 +       /* Copy skb (even if skb is about to be dropped, we can't just
6914 +           clone it because there may be other things, such as tcpdump,
6915 +           interested in it) */
6916 +       nskb = skb_copy(oldskb, GFP_ATOMIC);
6917 +       if (!nskb)
6918 +               return;
6919 +
6920 +       /* This packet will not be the same as the other: clear nf fields */
6921 +       nf_conntrack_put(nskb->nfct);
6922 +       nskb->nfct = NULL;
6923 +       nskb->nfcache = 0;
6924 +#ifdef CONFIG_NETFILTER_DEBUG
6925 +       nskb->nf_debug = 0;
6926 +#endif
6927 +
6928 +       tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
6929 +
6930 +       nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
6931 +       tcph->source = xchg(&tcph->dest, tcph->source);
6932 +
6933 +       /* Truncate to length (no data) */
6934 +       tcph->doff = sizeof(struct tcphdr)/4;
6935 +       skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
6936 +       nskb->nh.iph->tot_len = htons(nskb->len);
6937 +
6938 +       if (tcph->ack) {
6939 +               needs_ack = 0;
6940 +               tcph->seq = otcph->ack_seq;
6941 +               tcph->ack_seq = 0;
6942 +       } else {
6943 +               needs_ack = 1;
6944 +               tcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn + otcph->fin
6945 +                                     + otcplen - (otcph->doff<<2));
6946 +               tcph->seq = 0;
6947 +       }
6948 +
6949 +       /* Reset flags */
6950 +       ((u_int8_t *)tcph)[13] = 0;
6951 +       tcph->rst = 1;
6952 +       tcph->ack = needs_ack;
6953 +
6954 +       tcph->window = 0;
6955 +       tcph->urg_ptr = 0;
6956 +
6957 +       /* Adjust TCP checksum */
6958 +       tcph->check = 0;
6959 +       tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
6960 +                                  nskb->nh.iph->saddr,
6961 +                                  nskb->nh.iph->daddr,
6962 +                                  csum_partial((char *)tcph,
6963 +                                               sizeof(struct tcphdr), 0));
6964 +
6965 +       /* Adjust IP TTL, DF */
6966 +       nskb->nh.iph->ttl = MAXTTL;
6967 +       /* Set DF, id = 0 */
6968 +       nskb->nh.iph->frag_off = htons(IP_DF);
6969 +       nskb->nh.iph->id = 0;
6970 +
6971 +       /* Adjust IP checksum */
6972 +       nskb->nh.iph->check = 0;
6973 +       nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph, 
6974 +                                          nskb->nh.iph->ihl);
6975 +
6976 +       /* Routing */
6977 +       if (ip_route_output(&rt, nskb->nh.iph->daddr, nskb->nh.iph->saddr,
6978 +                           RT_TOS(nskb->nh.iph->tos) | RTO_CONN,
6979 +                           0) != 0)
6980 +               goto free_nskb;
6981 +
6982 +       dst_release(nskb->dst);
6983 +       nskb->dst = &rt->u.dst;
6984 +
6985 +       /* "Never happens" */
6986 +       if (nskb->len > nskb->dst->pmtu)
6987 +               goto free_nskb;
6988 +
6989 +       NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
6990 +               ip_finish_output);
6991 +       return;
6992 +
6993 + free_nskb:
6994 +       kfree_skb(nskb);
6995 +}
6996 +#endif
6997 +
6998 +static unsigned int reject6_target(struct sk_buff **pskb,
6999 +                          unsigned int hooknum,
7000 +                          const struct net_device *in,
7001 +                          const struct net_device *out,
7002 +                          const void *targinfo,
7003 +                          void *userinfo)
7004 +{
7005 +       const struct ip6t_reject_info *reject = targinfo;
7006 +
7007 +       /* WARNING: This code causes reentry within ip6tables.
7008 +          This means that the ip6tables jump stack is now crap.  We
7009 +          must return an absolute verdict. --RR */
7010 +       DEBUGP("REJECTv6: calling icmpv6_send\n");
7011 +       switch (reject->with) {
7012 +       case IP6T_ICMP6_NO_ROUTE:
7013 +               icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, out);
7014 +               break;
7015 +       case IP6T_ICMP6_ADM_PROHIBITED:
7016 +               icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADM_PROHIBITED, 0, out);
7017 +               break;
7018 +       case IP6T_ICMP6_NOT_NEIGHBOUR:
7019 +               icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOT_NEIGHBOUR, 0, out);
7020 +               break;
7021 +       case IP6T_ICMP6_ADDR_UNREACH:
7022 +               icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, out);
7023 +               break;
7024 +       case IP6T_ICMP6_PORT_UNREACH:
7025 +               icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, out);
7026 +               break;
7027 +#if 0
7028 +       case IPT_ICMP_ECHOREPLY: {
7029 +               struct icmp6hdr *icmph  = (struct icmphdr *)
7030 +                       ((u_int32_t *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl);
7031 +               unsigned int datalen = (*pskb)->len - (*pskb)->nh.iph->ihl * 4;
7032 +
7033 +               /* Not non-head frags, or truncated */
7034 +               if (((ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET) == 0)
7035 +                   && datalen >= 4) {
7036 +                       /* Usually I don't like cut & pasting code,
7037 +                           but dammit, my party is starting in 45
7038 +                           mins! --RR */
7039 +                       struct icmp_bxm icmp_param;
7040 +
7041 +                       icmp_param.icmph=*icmph;
7042 +                       icmp_param.icmph.type=ICMP_ECHOREPLY;
7043 +                       icmp_param.data_ptr=(icmph+1);
7044 +                       icmp_param.data_len=datalen;
7045 +                       icmp_reply(&icmp_param, *pskb);
7046 +               }
7047 +       }
7048 +       break;
7049 +       case IPT_TCP_RESET:
7050 +               send_reset(*pskb);
7051 +               break;
7052 +#endif
7053 +       default:
7054 +               printk(KERN_WARNING "REJECTv6: case %u not handled yet\n", reject->with);
7055 +               break;
7056 +       }
7057 +
7058 +       return NF_DROP;
7059 +}
7060 +
7061 +static inline int find_ping_match(const struct ip6t_entry_match *m)
7062 +{
7063 +       const struct ip6t_icmp *icmpinfo = (const struct ip6t_icmp *)m->data;
7064 +
7065 +       if (strcmp(m->u.kernel.match->name, "icmp6") == 0
7066 +           && icmpinfo->type == ICMPV6_ECHO_REQUEST
7067 +           && !(icmpinfo->invflags & IP6T_ICMP_INV))
7068 +               return 1;
7069 +
7070 +       return 0;
7071 +}
7072 +
7073 +static int check(const char *tablename,
7074 +                const struct ip6t_entry *e,
7075 +                void *targinfo,
7076 +                unsigned int targinfosize,
7077 +                unsigned int hook_mask)
7078 +{
7079 +       const struct ip6t_reject_info *rejinfo = targinfo;
7080 +
7081 +       if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
7082 +               DEBUGP("REJECTv6: targinfosize %u != 0\n", targinfosize);
7083 +               return 0;
7084 +       }
7085 +
7086 +       /* Only allow these for packet filtering. */
7087 +       if (strcmp(tablename, "filter") != 0) {
7088 +               DEBUGP("REJECTv6: bad table `%s'.\n", tablename);
7089 +               return 0;
7090 +       }
7091 +       if ((hook_mask & ~((1 << NF_IP6_LOCAL_IN)
7092 +                          | (1 << NF_IP6_FORWARD)
7093 +                          | (1 << NF_IP6_LOCAL_OUT))) != 0) {
7094 +               DEBUGP("REJECTv6: bad hook mask %X\n", hook_mask);
7095 +               return 0;
7096 +       }
7097 +
7098 +       if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
7099 +               /* Must specify that it's an ICMP ping packet. */
7100 +               if (e->ipv6.proto != IPPROTO_ICMPV6
7101 +                   || (e->ipv6.invflags & IP6T_INV_PROTO)) {
7102 +                       DEBUGP("REJECTv6: ECHOREPLY illegal for non-icmp\n");
7103 +                       return 0;
7104 +               }
7105 +               /* Must contain ICMP match. */
7106 +               if (IP6T_MATCH_ITERATE(e, find_ping_match) == 0) {
7107 +                       DEBUGP("REJECTv6: ECHOREPLY illegal for non-ping\n");
7108 +                       return 0;
7109 +               }
7110 +       } else if (rejinfo->with == IP6T_TCP_RESET) {
7111 +               /* Must specify that it's a TCP packet */
7112 +               if (e->ipv6.proto != IPPROTO_TCP
7113 +                   || (e->ipv6.invflags & IP6T_INV_PROTO)) {
7114 +                       DEBUGP("REJECTv6: TCP_RESET illegal for non-tcp\n");
7115 +                       return 0;
7116 +               }
7117 +       }
7118 +
7119 +       return 1;
7120 +}
7121 +
7122 +static struct ip6t_target ip6t_reject_reg
7123 += { { NULL, NULL }, "REJECT", reject6_target, check, NULL, THIS_MODULE };
7124 +
7125 +static int __init init(void)
7126 +{
7127 +       if (ip6t_register_target(&ip6t_reject_reg))
7128 +               return -EINVAL;
7129 +       return 0;
7130 +}
7131 +
7132 +static void __exit fini(void)
7133 +{
7134 +       ip6t_unregister_target(&ip6t_reject_reg);
7135 +}
7136 +
7137 +module_init(init);
7138 +module_exit(fini);
7139 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_fuzzy.c linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_fuzzy.c
7140 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_fuzzy.c 1970-01-01 00:00:00.000000000 +0000
7141 +++ linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_fuzzy.c     2004-03-22 08:28:32.000000000 +0000
7142 @@ -0,0 +1,189 @@
7143 +/*
7144 + * This module implements a simple TSK FLC
7145 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
7146 + * to limit , in an adaptive and flexible way , the packet rate crossing
7147 + * a given stream . It serves as an initial and very simple (but effective)
7148 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
7149 + *  As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
7150 + * into our code in a precise , adaptive and efficient manner.
7151 + *  The goal is very similar to that of "limit" match , but using techniques of
7152 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
7153 + * avoiding over and undershoots - and stuff like that .
7154 + *
7155 + *
7156 + * 2002-08-10  Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
7157 + * 2002-08-17  : Changed to eliminate floating point operations .
7158 + * 2002-08-23  : Coding style changes .
7159 + * 2003-04-08  Maciej Soltysiak <solt@dns.toxicilms.tv> : IPv6 Port
7160 + */
7161 +
7162 +#include <linux/module.h>
7163 +#include <linux/skbuff.h>
7164 +#include <linux/ipv6.h>
7165 +#include <linux/random.h>
7166 +#include <net/tcp.h>
7167 +#include <linux/spinlock.h>
7168 +#include <linux/netfilter_ipv6/ip6_tables.h>
7169 +#include <linux/netfilter_ipv6/ip6t_fuzzy.h>
7170 +
7171 +/*
7172 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
7173 + Expressed in percentage
7174 +*/
7175 +
7176 +#define PAR_LOW                1/100
7177 +#define PAR_HIGH       1
7178 +
7179 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED;
7180 +
7181 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
7182 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
7183 +MODULE_LICENSE("GPL");
7184 +
7185 +static  u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
7186 +{
7187 +       if (tx >= maxi) return 100;
7188 +
7189 +       if (tx <= mini) return 0;
7190 +
7191 +       return ((100 * (tx-mini)) / (maxi-mini));
7192 +}
7193 +
7194 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
7195 +{
7196 +       if (tx <= mini) return 100;
7197 +
7198 +       if (tx >= maxi) return 0;
7199 +
7200 +       return ((100 * (maxi - tx)) / (maxi - mini));
7201 +
7202 +}
7203 +
7204 +static int
7205 +ip6t_fuzzy_match(const struct sk_buff *pskb,
7206 +              const struct net_device *in,
7207 +              const struct net_device *out,
7208 +              const void *matchinfo,
7209 +              int offset,
7210 +              const void *hdr,
7211 +              u_int16_t datalen,
7212 +              int *hotdrop)
7213 +{
7214 +       /* From userspace */
7215 +
7216 +       struct ip6t_fuzzy_info *info = (struct ip6t_fuzzy_info *) matchinfo;
7217 +
7218 +       u_int8_t random_number;
7219 +       unsigned long amount;
7220 +       u_int8_t howhigh, howlow;
7221 +
7222 +
7223 +       spin_lock_bh(&fuzzy_lock); /* Rise the lock */
7224 +
7225 +       info->bytes_total += pskb->len;
7226 +       info->packets_total++;
7227 +
7228 +       info->present_time = jiffies;
7229 +
7230 +       if (info->present_time >= info->previous_time)
7231 +               amount = info->present_time - info->previous_time;
7232 +       else {
7233 +               /* There was a transition : I choose to re-sample
7234 +                  and keep the old acceptance rate...
7235 +               */
7236 +
7237 +               amount = 0;
7238 +               info->previous_time = info->present_time;
7239 +               info->bytes_total = info->packets_total = 0;
7240 +            };
7241 +
7242 +       if ( amount > HZ/10) {/* More than 100 ms elapsed ... */
7243 +
7244 +               info->mean_rate = (u_int32_t) ((HZ * info->packets_total) \
7245 +                                       / amount);
7246 +
7247 +               info->previous_time = info->present_time;
7248 +               info->bytes_total = info->packets_total = 0;
7249 +
7250 +               howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
7251 +               howlow  = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
7252 +
7253 +               info->acceptance_rate = (u_int8_t) \
7254 +                               (howhigh * PAR_LOW + PAR_HIGH * howlow);
7255 +
7256 +       /* In fact, the above defuzzification would require a denominator
7257 +        * proportional to (howhigh+howlow) but, in this particular case,
7258 +        * that expression is constant.
7259 +        * An imediate consequence is that it is not necessary to call
7260 +        * both mf_high and mf_low - but to keep things understandable,
7261 +        * I did so.
7262 +        */
7263 +
7264 +       }
7265 +
7266 +       spin_unlock_bh(&fuzzy_lock); /* Release the lock */
7267 +
7268 +
7269 +       if (info->acceptance_rate < 100)
7270 +       {
7271 +               get_random_bytes((void *)(&random_number), 1);
7272 +
7273 +               /*  If within the acceptance , it can pass => don't match */
7274 +               if (random_number <= (255 * info->acceptance_rate) / 100)
7275 +                       return 0;
7276 +               else
7277 +                       return 1; /* It can't pass (It matches) */
7278 +       };
7279 +
7280 +       return 0; /* acceptance_rate == 100 % => Everything passes ... */
7281 +
7282 +}
7283 +
7284 +static int
7285 +ip6t_fuzzy_checkentry(const char *tablename,
7286 +                  const struct ip6t_ip6 *ip,
7287 +                  void *matchinfo,
7288 +                  unsigned int matchsize,
7289 +                  unsigned int hook_mask)
7290 +{
7291 +
7292 +       const struct ip6t_fuzzy_info *info = matchinfo;
7293 +
7294 +       if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info))) {
7295 +               printk("ip6t_fuzzy: matchsize %u != %u\n", matchsize,
7296 +                      IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info)));
7297 +               return 0;
7298 +       }
7299 +
7300 +       if ((info->minimum_rate < MINFUZZYRATE) || (info->maximum_rate > MAXFUZZYRATE)
7301 +        || (info->minimum_rate >= info->maximum_rate)) {
7302 +               printk("ip6t_fuzzy: BAD limits , please verify !!!\n");
7303 +               return 0;
7304 +       }
7305 +
7306 +       return 1;
7307 +}
7308 +
7309 +static struct ip6t_match ip6t_fuzzy_reg = {
7310 +       {NULL, NULL},
7311 +       "fuzzy",
7312 +       ip6t_fuzzy_match,
7313 +       ip6t_fuzzy_checkentry,
7314 +       NULL,
7315 +       THIS_MODULE };
7316 +
7317 +static int __init init(void)
7318 +{
7319 +       if (ip6t_register_match(&ip6t_fuzzy_reg))
7320 +               return -EINVAL;
7321 +
7322 +       return 0;
7323 +}
7324 +
7325 +static void __exit fini(void)
7326 +{
7327 +       ip6t_unregister_match(&ip6t_fuzzy_reg);
7328 +}
7329 +
7330 +module_init(init);
7331 +module_exit(fini);
7332 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_nth.c linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_nth.c
7333 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_nth.c   1970-01-01 00:00:00.000000000 +0000
7334 +++ linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_nth.c       2004-03-22 08:29:02.000000000 +0000
7335 @@ -0,0 +1,173 @@
7336 +/*
7337 +  This is a module which is used for match support for every Nth packet
7338 +  This file is distributed under the terms of the GNU General Public
7339 +  License (GPL). Copies of the GPL can be obtained from:
7340 +     ftp://prep.ai.mit.edu/pub/gnu/GPL
7341 +
7342 +  2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
7343 +  2001-09-20 Richard Wagner (rwagner@cloudnet.com)
7344 +        * added support for multiple counters
7345 +        * added support for matching on individual packets
7346 +          in the counter cycle
7347 +  2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
7348 +
7349 +*/
7350 +
7351 +#include <linux/module.h>
7352 +#include <linux/skbuff.h>
7353 +#include <linux/ip.h>
7354 +#include <net/tcp.h>
7355 +#include <linux/spinlock.h>
7356 +#include <linux/netfilter_ipv6/ip6_tables.h>
7357 +#include <linux/netfilter_ipv6/ip6t_nth.h>
7358 +
7359 +MODULE_LICENSE("GPL");
7360 +
7361 +/*
7362 + * State information.
7363 + */
7364 +struct state {
7365 +       spinlock_t lock;
7366 +       u_int16_t number;
7367 +};
7368 +
7369 +static struct state states[IP6T_NTH_NUM_COUNTERS];
7370 +
7371 +static int
7372 +ip6t_nth_match(const struct sk_buff *pskb,
7373 +             const struct net_device *in,
7374 +             const struct net_device *out,
7375 +             const void *matchinfo,
7376 +             int offset,
7377 +             const void *hdr,
7378 +             u_int16_t datalen,
7379 +             int *hotdrop)
7380 +{
7381 +       /* Parameters from userspace */
7382 +       const struct ip6t_nth_info *info = matchinfo;
7383 +        unsigned counter = info->counter;
7384 +               if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS)) 
7385 +       {
7386 +                       printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
7387 +               return 0;
7388 +        };
7389 +
7390 +        spin_lock(&states[counter].lock);
7391 +
7392 +        /* Are we matching every nth packet?*/
7393 +        if (info->packet == 0xFF)
7394 +        {
7395 +               /* We're matching every nth packet and only every nth packet*/
7396 +               /* Do we match or invert match? */
7397 +               if (info->not == 0)
7398 +               {
7399 +                       if (states[counter].number == 0)
7400 +                       {
7401 +                               ++states[counter].number;
7402 +                               goto match;
7403 +                       }
7404 +                       if (states[counter].number >= info->every)
7405 +                               states[counter].number = 0; /* reset the counter */
7406 +                       else
7407 +                               ++states[counter].number;
7408 +                       goto dontmatch;
7409 +               }
7410 +               else
7411 +               {
7412 +                       if (states[counter].number == 0)
7413 +                       {
7414 +                               ++states[counter].number;
7415 +                               goto dontmatch;
7416 +                       }
7417 +                       if (states[counter].number >= info->every)
7418 +                               states[counter].number = 0;
7419 +                       else
7420 +                               ++states[counter].number;
7421 +                       goto match;
7422 +               }
7423 +        }
7424 +        else
7425 +        {
7426 +               /* We're using the --packet, so there must be a rule for every value */
7427 +               if (states[counter].number == info->packet)
7428 +               {
7429 +                       /* only increment the counter when a match happens */
7430 +                       if (states[counter].number >= info->every)
7431 +                               states[counter].number = 0; /* reset the counter */
7432 +                       else
7433 +                               ++states[counter].number;
7434 +                       goto match;
7435 +               }
7436 +               else
7437 +                       goto dontmatch;
7438 +       }
7439 +
7440 + dontmatch:
7441 +       /* don't match */
7442 +       spin_unlock(&states[counter].lock);
7443 +       return 0;
7444 +
7445 + match:
7446 +       spin_unlock(&states[counter].lock);
7447 +       return 1;
7448 +}
7449 +
7450 +static int
7451 +ip6t_nth_checkentry(const char *tablename,
7452 +                  const struct ip6t_ip6 *e,
7453 +                  void *matchinfo,
7454 +                  unsigned int matchsize,
7455 +                  unsigned int hook_mask)
7456 +{
7457 +       /* Parameters from userspace */
7458 +       const struct ip6t_nth_info *info = matchinfo;
7459 +        unsigned counter = info->counter;
7460 +        if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS)) 
7461 +       {
7462 +               printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
7463 +                       return 0;
7464 +               };
7465 +
7466 +       if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_nth_info))) {
7467 +               printk("nth: matchsize %u != %u\n", matchsize,
7468 +                      IP6T_ALIGN(sizeof(struct ip6t_nth_info)));
7469 +               return 0;
7470 +       }
7471 +
7472 +       states[counter].number = info->startat;
7473 +
7474 +       return 1;
7475 +}
7476 +
7477 +static struct ip6t_match ip6t_nth_reg = { 
7478 +       {NULL, NULL},
7479 +       "nth",
7480 +       ip6t_nth_match,
7481 +       ip6t_nth_checkentry,
7482 +       NULL,
7483 +       THIS_MODULE };
7484 +
7485 +static int __init init(void)
7486 +{
7487 +       unsigned counter;
7488 +        memset(&states, 0, sizeof(states));
7489 +       if (ip6t_register_match(&ip6t_nth_reg))
7490 +               return -EINVAL;
7491 +
7492 +        for(counter = 0; counter < IP6T_NTH_NUM_COUNTERS; counter++) 
7493 +       {
7494 +               spin_lock_init(&(states[counter].lock));
7495 +        };
7496 +
7497 +       printk("ip6t_nth match loaded\n");
7498 +       return 0;
7499 +}
7500 +
7501 +static void __exit fini(void)
7502 +{
7503 +       ip6t_unregister_match(&ip6t_nth_reg);
7504 +       printk("ip6t_nth match unloaded\n");
7505 +}
7506 +
7507 +module_init(init);
7508 +module_exit(fini);
7509 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_random.c linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_random.c
7510 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6t_random.c        1970-01-01 00:00:00.000000000 +0000
7511 +++ linux-2.6.5-rc2/net/ipv6/netfilter/ip6t_random.c    2004-03-22 08:29:43.000000000 +0000
7512 @@ -0,0 +1,97 @@
7513 +/*
7514 +  This is a module which is used for a "random" match support.
7515 +  This file is distributed under the terms of the GNU General Public
7516 +  License (GPL). Copies of the GPL can be obtained from:
7517 +     ftp://prep.ai.mit.edu/pub/gnu/GPL
7518 +
7519 +  2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
7520 +  2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
7521 +*/
7522 +
7523 +#include <linux/module.h>
7524 +#include <linux/skbuff.h>
7525 +#include <linux/ip.h>
7526 +#include <linux/random.h>
7527 +#include <net/tcp.h>
7528 +#include <linux/spinlock.h>
7529 +#include <linux/netfilter_ipv6/ip6_tables.h>
7530 +#include <linux/netfilter_ipv6/ip6t_random.h>
7531 +
7532 +MODULE_LICENSE("GPL");
7533 +
7534 +static int
7535 +ip6t_rand_match(const struct sk_buff *pskb,
7536 +              const struct net_device *in,
7537 +              const struct net_device *out,
7538 +              const void *matchinfo,
7539 +              int offset,
7540 +              const void *hdr,
7541 +              u_int16_t datalen,
7542 +              int *hotdrop)
7543 +{
7544 +       /* Parameters from userspace */
7545 +       const struct ip6t_rand_info *info = matchinfo;
7546 +       u_int8_t random_number;
7547 +
7548 +       /* get 1 random number from the kernel random number generation routine */
7549 +       get_random_bytes((void *)(&random_number), 1);
7550 +
7551 +       /* Do we match ? */
7552 +       if (random_number <= info->average)
7553 +               return 1;
7554 +       else
7555 +               return 0;
7556 +}
7557 +
7558 +static int
7559 +ip6t_rand_checkentry(const char *tablename,
7560 +                  const struct ip6t_ip6 *e,
7561 +                  void *matchinfo,
7562 +                  unsigned int matchsize,
7563 +                  unsigned int hook_mask)
7564 +{
7565 +       /* Parameters from userspace */
7566 +       const struct ip6t_rand_info *info = matchinfo;
7567 +
7568 +       if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_rand_info))) {
7569 +               printk("ip6t_random: matchsize %u != %u\n", matchsize,
7570 +                      IP6T_ALIGN(sizeof(struct ip6t_rand_info)));
7571 +               return 0;
7572 +       }
7573 +
7574 +       /* must be  1 <= average % <= 99 */
7575 +       /* 1  x 2.55 = 2   */
7576 +       /* 99 x 2.55 = 252 */
7577 +       if ((info->average < 2) || (info->average > 252)) {
7578 +               printk("ip6t_random:  invalid average %u\n", info->average);
7579 +               return 0;
7580 +       }
7581 +
7582 +       return 1;
7583 +}
7584 +
7585 +static struct ip6t_match ip6t_rand_reg = { 
7586 +       {NULL, NULL},
7587 +       "random",
7588 +       ip6t_rand_match,
7589 +       ip6t_rand_checkentry,
7590 +       NULL,
7591 +       THIS_MODULE };
7592 +
7593 +static int __init init(void)
7594 +{
7595 +       if (ip6t_register_match(&ip6t_rand_reg))
7596 +               return -EINVAL;
7597 +
7598 +       printk("ip6t_random match loaded\n");
7599 +       return 0;
7600 +}
7601 +
7602 +static void __exit fini(void)
7603 +{
7604 +       ip6t_unregister_match(&ip6t_rand_reg);
7605 +       printk("ip6t_random match unloaded\n");
7606 +}
7607 +
7608 +module_init(init);
7609 +module_exit(fini);
7610 diff -Nur --exclude '*.orig' linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6table_raw.c linux-2.6.5-rc2/net/ipv6/netfilter/ip6table_raw.c
7611 --- linux-2.6.5-rc2.org/net/ipv6/netfilter/ip6table_raw.c       1970-01-01 00:00:00.000000000 +0000
7612 +++ linux-2.6.5-rc2/net/ipv6/netfilter/ip6table_raw.c   2004-03-22 08:29:50.000000000 +0000
7613 @@ -0,0 +1,154 @@
7614 +/*
7615 + * IPv6 raw table, a port of the IPv4 raw table to IPv6
7616 + *
7617 + * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
7618 + */
7619 +#include <linux/module.h>
7620 +#include <linux/netfilter_ipv6/ip6_tables.h>
7621 +
7622 +#define RAW_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT))
7623 +
7624 +#if 0
7625 +#define DEBUGP(x, args...)     printk(KERN_DEBUG x, ## args)
7626 +#else
7627 +#define DEBUGP(x, args...)
7628 +#endif
7629 +
7630 +/* Standard entry. */
7631 +struct ip6t_standard
7632 +{
7633 +       struct ip6t_entry entry;
7634 +       struct ip6t_standard_target target;
7635 +};
7636 +
7637 +struct ip6t_error_target
7638 +{
7639 +       struct ip6t_entry_target target;
7640 +       char errorname[IP6T_FUNCTION_MAXNAMELEN];
7641 +};
7642 +
7643 +struct ip6t_error
7644 +{
7645 +       struct ip6t_entry entry;
7646 +       struct ip6t_error_target target;
7647 +};
7648 +
7649 +static struct
7650 +{
7651 +       struct ip6t_replace repl;
7652 +       struct ip6t_standard entries[2];
7653 +       struct ip6t_error term;
7654 +} initial_table __initdata 
7655 += { { "raw", RAW_VALID_HOOKS, 3,
7656 +      sizeof(struct ip6t_standard) * 2 + sizeof(struct ip6t_error),
7657 +      { [NF_IP6_PRE_ROUTING]   0,
7658 +       [NF_IP6_LOCAL_OUT]      sizeof(struct ip6t_standard) },
7659 +      { [NF_IP6_PRE_ROUTING]   0,
7660 +       [NF_IP6_LOCAL_OUT]      sizeof(struct ip6t_standard) },
7661 +      0, NULL, { } },
7662 +    {
7663 +           /* PRE_ROUTING */
7664 +            { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
7665 +               0,
7666 +               sizeof(struct ip6t_entry),
7667 +               sizeof(struct ip6t_standard),
7668 +               0, { 0, 0 }, { } },
7669 +             { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
7670 +               -NF_ACCEPT - 1 } },
7671 +           /* LOCAL_OUT */
7672 +            { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
7673 +               0,
7674 +               sizeof(struct ip6t_entry),
7675 +               sizeof(struct ip6t_standard),
7676 +               0, { 0, 0 }, { } },
7677 +             { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
7678 +               -NF_ACCEPT - 1 } },
7679 +    },
7680 +    /* ERROR */
7681 +    { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
7682 +       0,
7683 +       sizeof(struct ip6t_entry),
7684 +       sizeof(struct ip6t_error),
7685 +       0, { 0, 0 }, { } },
7686 +      { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } },
7687 +         { } },
7688 +       "ERROR"
7689 +      }
7690 +    }
7691 +};
7692 +
7693 +static struct ip6t_table packet_raw = { 
7694 +       .name = "raw", 
7695 +       .table = &initial_table.repl,
7696 +       .valid_hooks = RAW_VALID_HOOKS, 
7697 +       .lock = RW_LOCK_UNLOCKED, 
7698 +       .me = THIS_MODULE
7699 +};
7700 +
7701 +/* The work comes in here from netfilter.c. */
7702 +static unsigned int
7703 +ip6t_hook(unsigned int hook,
7704 +        struct sk_buff **pskb,
7705 +        const struct net_device *in,
7706 +        const struct net_device *out,
7707 +        int (*okfn)(struct sk_buff *))
7708 +{
7709 +       return ip6t_do_table(pskb, hook, in, out, &packet_raw, NULL);
7710 +}
7711 +
7712 +static struct nf_hook_ops ip6t_ops[] = { 
7713 +       {
7714 +         .hook = ip6t_hook, 
7715 +         .pf = PF_INET6,
7716 +         .hooknum = NF_IP6_PRE_ROUTING,
7717 +         .priority = NF_IP6_PRI_FIRST
7718 +       },
7719 +       {
7720 +         .hook = ip6t_hook, 
7721 +         .pf = PF_INET6, 
7722 +         .hooknum = NF_IP6_LOCAL_OUT,
7723 +         .priority = NF_IP6_PRI_FIRST
7724 +       },
7725 +};
7726 +
7727 +static int __init init(void)
7728 +{
7729 +       int ret;
7730 +
7731 +       /* Register table */
7732 +       ret = ip6t_register_table(&packet_raw);
7733 +       if (ret < 0)
7734 +               return ret;
7735 +
7736 +       /* Register hooks */
7737 +       ret = nf_register_hook(&ip6t_ops[0]);
7738 +       if (ret < 0)
7739 +               goto cleanup_table;
7740 +
7741 +       ret = nf_register_hook(&ip6t_ops[1]);
7742 +       if (ret < 0)
7743 +               goto cleanup_hook0;
7744 +
7745 +       return ret;
7746 +
7747 + cleanup_hook0:
7748 +       nf_unregister_hook(&ip6t_ops[0]);
7749 + cleanup_table:
7750 +       ip6t_unregister_table(&packet_raw);
7751 +
7752 +       return ret;
7753 +}
7754 +
7755 +static void __exit fini(void)
7756 +{
7757 +       unsigned int i;
7758 +
7759 +       for (i = 0; i < sizeof(ip6t_ops)/sizeof(struct nf_hook_ops); i++)
7760 +               nf_unregister_hook(&ip6t_ops[i]);
7761 +
7762 +       ip6t_unregister_table(&packet_raw);
7763 +}
7764 +
7765 +module_init(init);
7766 +module_exit(fini);
7767 +MODULE_LICENSE("GPL");
This page took 1.043623 seconds and 3 git commands to generate.