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