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