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