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