1 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter.h linux-2.6.6-rc1/include/linux/netfilter.h
2 --- linux-2.6.6-rc1.org/include/linux/netfilter.h 2004-04-15 03:34:48.000000000 +0200
3 +++ linux-2.6.6-rc1/include/linux/netfilter.h 2004-04-15 21:20:32.000000000 +0200
6 extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
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);
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);
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, ...);
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
29 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ip_conntrack.h
30 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ip_conntrack.h 2004-04-15 03:35:50.000000000 +0200
31 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ip_conntrack.h 2004-04-15 21:21:20.000000000 +0200
33 /* Call me when a conntrack is destroyed. */
34 extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack);
36 +/* Fake conntrack entry for untracked connections */
37 +extern struct ip_conntrack ip_conntrack_untracked;
39 /* Returns new sk_buff, or NULL */
41 ip_ct_gather_frags(struct sk_buff *skb);
42 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ip_pool.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ip_pool.h
43 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ip_pool.h 1970-01-01 01:00:00.000000000 +0100
44 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ip_pool.h 2004-04-15 21:21:08.000000000 +0200
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. */
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. */
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 +/***************************************************************************/
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!
70 + * Comes with its own certificate of authenticity, valid anywhere in the
75 +#define SO_IP_POOL 81
77 +typedef int ip_pool_t; /* pool index */
78 +#define IP_POOL_NONE ((ip_pool_t)-1)
80 +struct ip_pool_request {
87 +/* NOTE: I deliberately break the first cut ippool utility. Nobody uses it. */
89 +#define IP_POOL_BAD001 0x00000010
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 */
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);
109 +#endif /*_IP_POOL_H*/
110 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_NETLINK.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_NETLINK.h
111 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_NETLINK.h 1970-01-01 01:00:00.000000000 +0100
112 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_NETLINK.h 2004-04-15 21:20:44.000000000 +0200
114 +#ifndef _IPT_FWMON_H
115 +#define _IPT_FWMON_H
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
122 +#define USE_MARK 0x00000001
123 +#define USE_DROP 0x00000002
124 +#define USE_SIZE 0x00000004
128 + unsigned int flags;
137 + char iface[IFNAMSIZ];
140 +#endif /*_IPT_FWMON_H*/
141 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_TTL.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_TTL.h
142 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_TTL.h 1970-01-01 01:00:00.000000000 +0100
143 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_TTL.h 2004-04-15 21:20:49.000000000 +0200
145 +/* TTL modification module for IP tables
146 + * (C) 2000 by Harald Welte <laforge@gnumonks.org> */
157 +#define IPT_TTL_MAXMODE IPT_TTL_DEC
159 +struct ipt_TTL_info {
166 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_ULOG.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_ULOG.h
167 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_ULOG.h 2004-04-15 03:34:36.000000000 +0200
168 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_ULOG.h 2004-04-15 21:20:32.000000000 +0200
170 #define NETLINK_NFLOG 5
173 +#define ULOG_DEFAULT_NLGROUP 1
174 +#define ULOG_DEFAULT_QTHRESHOLD 1
176 #define ULOG_MAC_LEN 80
177 #define ULOG_PREFIX_LEN 32
179 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_connlimit.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_connlimit.h
180 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_connlimit.h 1970-01-01 01:00:00.000000000 +0100
181 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_connlimit.h 2004-04-15 21:20:53.000000000 +0200
183 +#ifndef _IPT_CONNLIMIT_H
184 +#define _IPT_CONNLIMIT_H
186 +struct ipt_connlimit_data;
188 +struct ipt_connlimit_info {
192 + struct ipt_connlimit_data *data;
194 +#endif /* _IPT_CONNLIMIT_H */
195 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_conntrack.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_conntrack.h
196 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_conntrack.h 2004-04-15 03:35:20.000000000 +0200
197 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_conntrack.h 2004-04-15 21:21:20.000000000 +0200
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))
204 /* flags, invflags: */
205 #define IPT_CONNTRACK_STATE 0x01
206 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_dstlimit.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_dstlimit.h
207 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_dstlimit.h 1970-01-01 01:00:00.000000000 +0100
208 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_dstlimit.h 2004-04-15 21:20:56.000000000 +0200
210 +#ifndef _IPT_DSTLIMIT_H
211 +#define _IPT_DSTLIMIT_H
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. */
218 +/* details of this structure hidden by the implementation */
219 +struct ipt_dstlimit_htable;
221 +#define IPT_DSTLIMIT_HASH_DIP 0x0001
222 +#define IPT_DSTLIMIT_HASH_DPT 0x0002
223 +#define IPT_DSTLIMIT_HASH_SIP 0x0004
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. */
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? */
237 +struct ipt_dstlimit_info {
238 + char name [IFNAMSIZ]; /* name */
239 + struct dstlimit_cfg cfg;
240 + struct ipt_dstlimit_htable *hinfo;
242 + /* Used internally by the kernel */
245 + struct ipt_dstlimit_info *master;
248 +#endif /*_IPT_DSTLIMIT_H*/
249 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_fuzzy.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_fuzzy.h
250 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_fuzzy.h 1970-01-01 01:00:00.000000000 +0100
251 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_fuzzy.h 2004-04-15 21:20:59.000000000 +0200
253 +#ifndef _IPT_FUZZY_H
254 +#define _IPT_FUZZY_H
256 +#include <linux/param.h>
257 +#include <linux/types.h>
259 +#define MAXFUZZYRATE 10000000
260 +#define MINFUZZYRATE 3
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;
273 +#endif /*_IPT_FUZZY_H*/
274 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_ipv4options.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_ipv4options.h
275 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_ipv4options.h 1970-01-01 01:00:00.000000000 +0100
276 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_ipv4options.h 2004-04-15 21:21:01.000000000 +0200
278 +#ifndef __ipt_ipv4options_h_included__
279 +#define __ipt_ipv4options_h_included__
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 */
293 +struct ipt_ipv4options_info {
298 +#endif /* __ipt_ipv4options_h_included__ */
299 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_mport.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_mport.h
300 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_mport.h 1970-01-01 01:00:00.000000000 +0100
301 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_mport.h 2004-04-15 21:21:03.000000000 +0200
303 +#ifndef _IPT_MPORT_H
304 +#define _IPT_MPORT_H
305 +#include <linux/netfilter_ipv4/ip_tables.h>
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)
311 +#define IPT_MULTI_PORTS 15
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[] */
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 */
326 +#endif /*_IPT_MPORT_H*/
327 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_nth.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_nth.h
328 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_nth.h 1970-01-01 01:00:00.000000000 +0100
329 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_nth.h 2004-04-15 21:21:05.000000000 +0200
334 +#include <linux/param.h>
335 +#include <linux/types.h>
337 +#ifndef IPT_NTH_NUM_COUNTERS
338 +#define IPT_NTH_NUM_COUNTERS 16
341 +struct ipt_nth_info {
349 +#endif /*_IPT_NTH_H*/
350 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_osf.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_osf.h
351 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_osf.h 1970-01-01 01:00:00.000000000 +0100
352 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_osf.h 2004-04-15 21:21:06.000000000 +0200
357 + * Copyright (c) 2003 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
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.
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.
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
378 +#define MAXGENRELEN 32
379 +#define MAXDETLEN 64
381 +#define IPT_OSF_GENRE 1
382 +#define IPT_OSF_SMART 2
383 +#define IPT_OSF_LOG 4
384 +#define IPT_OSF_NETLINK 8
386 +#define IPT_OSF_LOGLEVEL_ALL 0
387 +#define IPT_OSF_LOGLEVEL_FIRST 1
389 +#include <linux/list.h>
392 +#include <netinet/ip.h>
393 +#include <netinet/tcp.h>
397 + struct list_head *prev, *next;
403 + char genre[MAXGENRELEN];
405 + unsigned long flags;
407 + int invert; /* UNSUPPORTED */
416 +/* This struct represents IANA options
417 + * http://www.iana.org/assignments/tcp-parameters
421 + unsigned char kind;
422 + unsigned char length;
428 + struct list_head flist;
433 + unsigned char genre[MAXGENRELEN];
434 + unsigned char version[MAXGENRELEN], subtype[MAXGENRELEN];
436 + /* Not needed, but for consistency with original table from Michal Zalewski */
437 + unsigned char details[MAXDETLEN];
440 + struct osf_opt opt[MAX_IPOPTLEN]; /* In case it is all NOP or EOL */
444 +struct ipt_osf_nlmsg
446 + struct osf_finger f;
453 +/* Defines for IANA option kinds */
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 */
468 +static struct osf_opt IANA_opts[] =
475 + {5, 1 ,}, /* SACK length is not defined */
481 + {11, 1,}, /* CC: Suppose 1 */
482 + {12, 1,}, /* the same */
483 + {13, 1,}, /* and here too */
485 + {15, 1,}, /* TCP Alternate Checksum Data. Length is not defined */
499 +#endif /* __KERNEL__ */
501 +#endif /* _IPT_OSF_H */
502 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_pool.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_pool.h
503 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_pool.h 1970-01-01 01:00:00.000000000 +0100
504 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_pool.h 2004-04-15 21:21:08.000000000 +0200
509 +#include <linux/netfilter_ipv4/ip_pool.h>
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
523 +struct ipt_pool_info
530 +#endif /*_IPT_POOL_H*/
531 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_psd.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_psd.h
532 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_psd.h 1970-01-01 01:00:00.000000000 +0100
533 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_psd.h 2004-04-15 21:21:10.000000000 +0200
538 +#include <linux/param.h>
539 +#include <linux/types.h>
542 + * High port numbers have a lower weight to reduce the frequency of false
543 + * positives, such as from passive mode FTP transfers.
545 +#define PORT_WEIGHT_PRIV 3
546 +#define PORT_WEIGHT_HIGH 1
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.
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)
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.
562 +#define LIST_SIZE 0x100
564 +#define HASH_SIZE (1 << HASH_LOG)
565 +#define HASH_MAX 0x10
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;
574 +#endif /*_IPT_PSD_H*/
575 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_quota.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_quota.h
576 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_quota.h 1970-01-01 01:00:00.000000000 +0100
577 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_quota.h 2004-04-15 21:21:16.000000000 +0200
579 +#ifndef _IPT_QUOTA_H
580 +#define _IPT_QUOTA_H
582 +/* print debug info in both kernel/netfilter module & iptable library */
583 +//#define DEBUG_IPT_QUOTA
585 +struct ipt_quota_info {
589 +#endif /*_IPT_QUOTA_H*/
590 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_random.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_random.h
591 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_random.h 1970-01-01 01:00:00.000000000 +0100
592 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_random.h 2004-04-15 21:21:18.000000000 +0200
597 +#include <linux/param.h>
598 +#include <linux/types.h>
600 +struct ipt_rand_info {
604 +#endif /*_IPT_RAND_H*/
605 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_realm.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_realm.h
606 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_realm.h 1970-01-01 01:00:00.000000000 +0100
607 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_realm.h 2004-04-15 21:21:22.000000000 +0200
609 +#ifndef _IPT_REALM_H
610 +#define _IPT_REALM_H
612 +struct ipt_realm_info {
617 +#endif /*_IPT_REALM_H*/
618 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_sctp.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_sctp.h
619 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_sctp.h 1970-01-01 01:00:00.000000000 +0100
620 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_sctp.h 2004-04-15 21:21:23.000000000 +0200
622 +#ifndef _IPT_SCTP_H_
623 +#define _IPT_SCTP_H_
625 +#define IPT_SCTP_SRC_PORTS 0x01
626 +#define IPT_SCTP_DEST_PORTS 0x02
627 +#define IPT_SCTP_CHUNK_TYPES 0x04
629 +#define IPT_SCTP_VALID_FLAGS 0x07
631 +#define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0]))
634 +struct ipt_sctp_flag_info {
635 + u_int8_t chunktype;
637 + u_int8_t flag_mask;
640 +#define IPT_NUM_SCTP_FLAGS 4
642 +struct ipt_sctp_info {
643 + u_int16_t dpts[2]; /* Min, Max */
644 + u_int16_t spts[2]; /* Min, Max */
646 + u_int32_t chunkmap[256 / sizeof (u_int32_t)]; /* Bit mask of chunks to be matched according to RFC 2960 */
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 */
652 + u_int32_t chunk_match_type;
653 + struct ipt_sctp_flag_info flag_info[IPT_NUM_SCTP_FLAGS];
657 + u_int32_t invflags;
660 +#define bytes(type) (sizeof(type) * 8)
662 +#define SCTP_CHUNKMAP_SET(chunkmap, type) \
664 + chunkmap[type / bytes(u_int32_t)] |= \
665 + 1 << (type % bytes(u_int32_t)); \
668 +#define SCTP_CHUNKMAP_CLEAR(chunkmap, type) \
670 + chunkmap[type / bytes(u_int32_t)] &= \
671 + ~(1 << (type % bytes(u_int32_t))); \
674 +#define SCTP_CHUNKMAP_IS_SET(chunkmap, type) \
676 + (chunkmap[type / bytes (u_int32_t)] & \
677 + (1 << (type % bytes (u_int32_t)))) ? 1: 0; \
680 +#define SCTP_CHUNKMAP_RESET(chunkmap) \
683 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
687 +#define SCTP_CHUNKMAP_SET_ALL(chunkmap) \
690 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
691 + chunkmap[i] = ~0; \
694 +#define SCTP_CHUNKMAP_COPY(destmap, srcmap) \
697 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
698 + destmap[i] = srcmap[i]; \
701 +#define SCTP_CHUNKMAP_IS_CLEAR(chunkmap) \
705 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \
706 + if (chunkmap[i]) { \
714 +#define SCTP_CHUNKMAP_IS_ALL_SET(chunkmap) \
718 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \
719 + if (chunkmap[i] != ~0) { \
727 +#endif /* _IPT_SCTP_H_ */
729 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_state.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_state.h
730 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_state.h 2004-04-15 03:35:37.000000000 +0200
731 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_state.h 2004-04-15 21:21:20.000000000 +0200
733 #define IPT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
734 #define IPT_STATE_INVALID (1 << 0)
736 +#define IPT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1))
738 struct ipt_state_info
740 unsigned int statemask;
741 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_time.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_time.h
742 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_time.h 1970-01-01 01:00:00.000000000 +0100
743 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_time.h 2004-04-15 21:21:26.000000000 +0200
745 +#ifndef __ipt_time_h_included__
746 +#define __ipt_time_h_included__
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. */
757 +#endif /* __ipt_time_h_included__ */
758 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_u32.h linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_u32.h
759 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4/ipt_u32.h 1970-01-01 01:00:00.000000000 +0100
760 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4/ipt_u32.h 2004-04-15 21:21:29.000000000 +0200
764 +#include <linux/netfilter_ipv4/ip_tables.h>
774 +struct ipt_u32_location_element
779 +struct ipt_u32_value_element
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
790 + struct ipt_u32_location_element location[U32MAXSIZE+1];
792 + struct ipt_u32_value_element value[U32MAXSIZE+1];
798 + struct ipt_u32_test tests[U32MAXSIZE+1];
801 +#endif /*_IPT_U32_H*/
802 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv4.h linux-2.6.6-rc1/include/linux/netfilter_ipv4.h
803 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv4.h 2004-04-15 03:35:36.000000000 +0200
804 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv4.h 2004-04-15 21:21:20.000000000 +0200
807 enum nf_ip_hook_priorities {
808 NF_IP_PRI_FIRST = INT_MIN,
809 + NF_IP_PRI_CONNTRACK_DEFRAG = -400,
810 + NF_IP_PRI_RAW = -300,
811 NF_IP_PRI_SELINUX_FIRST = -225,
812 NF_IP_PRI_CONNTRACK = -200,
813 NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
814 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv6/ip6t_HL.h linux-2.6.6-rc1/include/linux/netfilter_ipv6/ip6t_HL.h
815 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv6/ip6t_HL.h 1970-01-01 01:00:00.000000000 +0100
816 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv6/ip6t_HL.h 2004-04-15 21:20:38.000000000 +0200
818 +/* Hop Limit modification module for ip6tables
819 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
820 + * Based on HW's TTL module */
831 +#define IP6T_HL_MAXMODE IP6T_HL_DEC
833 +struct ip6t_HL_info {
835 + u_int8_t hop_limit;
840 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv6/ip6t_REJECT.h linux-2.6.6-rc1/include/linux/netfilter_ipv6/ip6t_REJECT.h
841 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv6/ip6t_REJECT.h 2004-04-15 03:33:49.000000000 +0200
842 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv6/ip6t_REJECT.h 2004-04-15 21:20:47.000000000 +0200
844 #define _IP6T_REJECT_H
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,
861 struct ip6t_reject_info {
862 enum ip6t_reject_with with; /* reject type */
865 -#endif /*_IPT_REJECT_H*/
866 +#endif /*_IP6T_REJECT_H*/
867 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h linux-2.6.6-rc1/include/linux/netfilter_ipv6/ip6t_fuzzy.h
868 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h 1970-01-01 01:00:00.000000000 +0100
869 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv6/ip6t_fuzzy.h 2004-04-15 21:20:59.000000000 +0200
871 +#ifndef _IP6T_FUZZY_H
872 +#define _IP6T_FUZZY_H
874 +#include <linux/param.h>
875 +#include <linux/types.h>
877 +#define MAXFUZZYRATE 10000000
878 +#define MINFUZZYRATE 3
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;
891 +#endif /*_IP6T_FUZZY_H*/
892 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv6/ip6t_nth.h linux-2.6.6-rc1/include/linux/netfilter_ipv6/ip6t_nth.h
893 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv6/ip6t_nth.h 1970-01-01 01:00:00.000000000 +0100
894 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv6/ip6t_nth.h 2004-04-15 21:21:05.000000000 +0200
899 +#include <linux/param.h>
900 +#include <linux/types.h>
902 +#ifndef IP6T_NTH_NUM_COUNTERS
903 +#define IP6T_NTH_NUM_COUNTERS 16
906 +struct ip6t_nth_info {
914 +#endif /*_IP6T_NTH_H*/
915 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/netfilter_ipv6/ip6t_random.h linux-2.6.6-rc1/include/linux/netfilter_ipv6/ip6t_random.h
916 --- linux-2.6.6-rc1.org/include/linux/netfilter_ipv6/ip6t_random.h 1970-01-01 01:00:00.000000000 +0100
917 +++ linux-2.6.6-rc1/include/linux/netfilter_ipv6/ip6t_random.h 2004-04-15 21:21:18.000000000 +0200
919 +#ifndef _IP6T_RAND_H
920 +#define _IP6T_RAND_H
922 +#include <linux/param.h>
923 +#include <linux/types.h>
925 +struct ip6t_rand_info {
929 +#endif /*_IP6T_RAND_H*/
930 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/include/linux/skbuff.h linux-2.6.6-rc1/include/linux/skbuff.h
931 --- linux-2.6.6-rc1.org/include/linux/skbuff.h 2004-04-15 03:35:04.000000000 +0200
932 +++ linux-2.6.6-rc1/include/linux/skbuff.h 2004-04-15 21:20:34.000000000 +0200
933 @@ -1201,6 +1201,14 @@
935 atomic_inc(&nfct->master->use);
937 +static inline void nf_reset(struct sk_buff *skb)
939 + nf_conntrack_put(skb->nfct);
941 +#ifdef CONFIG_NETFILTER_DEBUG
946 #ifdef CONFIG_BRIDGE_NETFILTER
947 static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge)
948 @@ -1213,9 +1221,10 @@
950 atomic_inc(&nf_bridge->use);
955 +#endif /* CONFIG_BRIDGE_NETFILTER */
956 +#else /* CONFIG_NETFILTER */
957 +static inline void nf_reset(struct sk_buff *skb) {}
958 +#endif /* CONFIG_NETFILTER */
960 #endif /* __KERNEL__ */
961 #endif /* _LINUX_SKBUFF_H */
962 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/core/netfilter.c linux-2.6.6-rc1/net/core/netfilter.c
963 --- linux-2.6.6-rc1.org/net/core/netfilter.c 2004-04-15 03:34:47.000000000 +0200
964 +++ linux-2.6.6-rc1/net/core/netfilter.c 2004-04-15 21:20:33.000000000 +0200
967 * February 2000: Modified by James Morris to have 1 queue per protocol.
968 * 15-Mar-2000: Added NF_REPEAT --RR.
969 + * 08-May-2003: Internal logging interface added by Jozsef Kadlecsik.
971 #include <linux/config.h>
972 +#include <linux/kernel.h>
973 #include <linux/netfilter.h>
974 #include <net/protocol.h>
975 #include <linux/init.h>
977 EXPORT_SYMBOL(skb_ip_make_writable);
978 #endif /*CONFIG_INET*/
980 +/* Internal logging interface, which relies on the real
981 + LOG target modules */
983 +#define NF_LOG_PREFIXLEN 128
985 +static nf_logfn *nf_logging[NPROTO]; /* = NULL */
986 +static int reported = 0;
987 +static spinlock_t nf_log_lock = SPIN_LOCK_UNLOCKED;
989 +int nf_log_register(int pf, nf_logfn *logfn)
993 + /* Any setup of logging members must be done before
994 + * substituting pointer. */
996 + spin_lock(&nf_log_lock);
997 + if (!nf_logging[pf]) {
998 + nf_logging[pf] = logfn;
1001 + spin_unlock(&nf_log_lock);
1005 +void nf_log_unregister(int pf, nf_logfn *logfn)
1007 + spin_lock(&nf_log_lock);
1008 + if (nf_logging[pf] == logfn)
1009 + nf_logging[pf] = NULL;
1010 + spin_unlock(&nf_log_lock);
1012 + /* Give time to concurrent readers. */
1013 + synchronize_net();
1016 +void nf_log_packet(int pf,
1017 + unsigned int hooknum,
1018 + const struct sk_buff *skb,
1019 + const struct net_device *in,
1020 + const struct net_device *out,
1021 + const char *fmt, ...)
1024 + char prefix[NF_LOG_PREFIXLEN];
1028 + logfn = nf_logging[pf];
1030 + va_start(args, fmt);
1031 + vsnprintf(prefix, sizeof(prefix), fmt, args);
1033 + /* We must read logging before nf_logfn[pf] */
1034 + smp_read_barrier_depends();
1035 + logfn(hooknum, skb, in, out, prefix);
1036 + } else if (!reported) {
1037 + printk(KERN_WARNING "nf_log_packet: can\'t log yet, "
1038 + "no backend logging module loaded in!\n");
1041 + rcu_read_unlock();
1043 +EXPORT_SYMBOL(nf_log_register);
1044 +EXPORT_SYMBOL(nf_log_unregister);
1045 +EXPORT_SYMBOL(nf_log_packet);
1047 /* This does not belong here, but ipt_REJECT needs it if connection
1048 tracking in use: without this, connection may not be in hash table,
1049 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/ip_gre.c linux-2.6.6-rc1/net/ipv4/ip_gre.c
1050 --- linux-2.6.6-rc1.org/net/ipv4/ip_gre.c 2004-04-15 03:35:20.000000000 +0200
1051 +++ linux-2.6.6-rc1/net/ipv4/ip_gre.c 2004-04-15 21:20:34.000000000 +0200
1052 @@ -643,13 +643,7 @@
1053 skb->dev = tunnel->dev;
1054 dst_release(skb->dst);
1056 -#ifdef CONFIG_NETFILTER
1057 - nf_conntrack_put(skb->nfct);
1059 -#ifdef CONFIG_NETFILTER_DEBUG
1060 - skb->nf_debug = 0;
1064 ipgre_ecn_decapsulate(iph, skb);
1066 read_unlock(&ipgre_lock);
1067 @@ -877,13 +871,7 @@
1071 -#ifdef CONFIG_NETFILTER
1072 - nf_conntrack_put(skb->nfct);
1074 -#ifdef CONFIG_NETFILTER_DEBUG
1075 - skb->nf_debug = 0;
1081 tunnel->recursion--;
1082 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/ip_input.c linux-2.6.6-rc1/net/ipv4/ip_input.c
1083 --- linux-2.6.6-rc1.org/net/ipv4/ip_input.c 2004-04-15 03:33:53.000000000 +0200
1084 +++ linux-2.6.6-rc1/net/ipv4/ip_input.c 2004-04-15 21:20:34.000000000 +0200
1085 @@ -202,17 +202,13 @@
1087 #ifdef CONFIG_NETFILTER_DEBUG
1088 nf_debug_ip_local_deliver(skb);
1089 - skb->nf_debug = 0;
1090 #endif /*CONFIG_NETFILTER_DEBUG*/
1092 __skb_pull(skb, ihl);
1094 -#ifdef CONFIG_NETFILTER
1095 /* Free reference early: we don't need it any more, and it may
1096 hold ip_conntrack module loaded indefinitely. */
1097 - nf_conntrack_put(skb->nfct);
1099 -#endif /*CONFIG_NETFILTER*/
1102 /* Point into the IP datagram, just past the header. */
1103 skb->h.raw = skb->data;
1104 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/ipip.c linux-2.6.6-rc1/net/ipv4/ipip.c
1105 --- linux-2.6.6-rc1.org/net/ipv4/ipip.c 2004-04-15 03:36:03.000000000 +0200
1106 +++ linux-2.6.6-rc1/net/ipv4/ipip.c 2004-04-15 21:20:34.000000000 +0200
1107 @@ -496,13 +496,7 @@
1108 skb->dev = tunnel->dev;
1109 dst_release(skb->dst);
1111 -#ifdef CONFIG_NETFILTER
1112 - nf_conntrack_put(skb->nfct);
1114 -#ifdef CONFIG_NETFILTER_DEBUG
1115 - skb->nf_debug = 0;
1119 ipip_ecn_decapsulate(iph, skb);
1121 read_unlock(&ipip_lock);
1122 @@ -647,13 +641,7 @@
1123 if ((iph->ttl = tiph->ttl) == 0)
1124 iph->ttl = old_iph->ttl;
1126 -#ifdef CONFIG_NETFILTER
1127 - nf_conntrack_put(skb->nfct);
1129 -#ifdef CONFIG_NETFILTER_DEBUG
1130 - skb->nf_debug = 0;
1136 tunnel->recursion--;
1137 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/Kconfig linux-2.6.6-rc1/net/ipv4/netfilter/Kconfig
1138 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/Kconfig 2004-04-15 03:35:36.000000000 +0200
1139 +++ linux-2.6.6-rc1/net/ipv4/netfilter/Kconfig 2004-04-15 21:21:29.000000000 +0200
1140 @@ -579,5 +579,123 @@
1142 To compile it as a module, choose M here. If unsure, say N.
1144 +config IP_NF_TARGET_IPV4OPTSSTRIP
1145 + tristate 'IPV4OPTSSTRIP target support'
1146 + depends on IP_NF_MANGLE
1149 +config IP_NF_TARGET_NETLINK
1150 + tristate 'NETLINK target support'
1151 + depends on IP_NF_FILTER
1154 +config IP_NF_TARGET_TTL
1155 + tristate 'TTL target support'
1156 + depends on IP_NF_MANGLE
1159 +config IP_NF_MATCH_CONNLIMIT
1160 + tristate 'Connections/IP limit match support'
1161 + depends on IP_NF_IPTABLES
1164 +config IP_NF_MATCH_DSTLIMIT
1165 + tristate 'dstlimit match support'
1166 + depends on IP_NF_IPTABLES
1169 +config IP_NF_MATCH_FUZZY
1170 + tristate 'fuzzy match support'
1171 + depends on IP_NF_IPTABLES
1174 +config IP_NF_MATCH_IPV4OPTIONS
1175 + tristate 'IPV4OPTIONS match support'
1176 + depends on IP_NF_IPTABLES
1179 +config IP_NF_MATCH_MPORT
1180 + tristate 'Multiple port with ranges match support'
1181 + depends on IP_NF_IPTABLES
1184 +config IP_NF_MATCH_NTH
1185 + tristate 'Nth match support'
1186 + depends on IP_NF_IPTABLES
1189 +config IP_NF_MATCH_OSF
1190 + tristate 'OSF match support'
1191 + depends on IP_NF_IPTABLES
1194 +config IP_POOL_STATISTICS
1195 + bool 'enable statistics on pool usage'
1196 + depends on IP_NF_POOL!=n
1199 + tristate 'IP address pool support'
1200 + depends on IP_NF_IPTABLES
1203 +config IP_NF_MATCH_PSD
1204 + tristate 'psd match support'
1205 + depends on IP_NF_IPTABLES
1208 +config IP_NF_MATCH_QUOTA
1209 + tristate 'quota match support'
1210 + depends on IP_NF_IPTABLES
1213 +config IP_NF_MATCH_RANDOM
1214 + tristate 'random match support'
1215 + depends on IP_NF_IPTABLES
1218 +config IP_NF_TARGET_NOTRACK
1219 + tristate 'NOTRACK target support'
1220 + depends on IP_NF_RAW
1222 + The NOTRACK target allows a select rule to specify
1223 + which packets *not* to enter the conntrack/NAT
1224 + subsystem with all the consequences (no ICMP error tracking,
1225 + no protocol helpers for the selected packets).
1227 + If you want to compile it as a module, say M here and read
1228 + <file:Documentation/modules.txt>. If unsure, say `N'.
1231 + tristate 'raw table support (required for NOTRACK/TRACE)'
1232 + depends on IP_NF_IPTABLES
1234 + This option adds a `raw' table to iptables. This table is the very
1235 + first in the netfilter framework and hooks in at the PREROUTING
1236 + and OUTPUT chains.
1238 + If you want to compile it as a module, say M here and read
1239 + <file:Documentation/modules.txt>. If unsure, say `N'.
1242 +config IP_NF_MATCH_REALM
1243 + tristate 'realm match support'
1244 + depends on IP_NF_IPTABLES && NET_CLS_ROUTE
1247 +config IP_NF_MATCH_SCTP
1248 + tristate 'SCTP protocol match support'
1249 + depends on IP_NF_IPTABLES
1252 +config IP_NF_MATCH_TIME
1253 + tristate 'TIME match support'
1254 + depends on IP_NF_IPTABLES
1257 +config IP_NF_MATCH_U32
1258 + tristate 'U32 match support'
1259 + depends on IP_NF_IPTABLES
1264 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/Makefile linux-2.6.6-rc1/net/ipv4/netfilter/Makefile
1265 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/Makefile 2004-04-15 03:34:03.000000000 +0200
1266 +++ linux-2.6.6-rc1/net/ipv4/netfilter/Makefile 2004-04-15 21:21:29.000000000 +0200
1268 obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
1269 obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
1270 obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
1271 +obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
1274 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
1275 obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
1276 +obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o
1277 +obj-$(CONFIG_IP_NF_MATCH_QUOTA) += ipt_quota.o
1278 +obj-$(CONFIG_IP_NF_MATCH_DSTLIMIT) += ipt_dstlimit.o
1279 obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
1280 +obj-$(CONFIG_IP_NF_POOL) += ipt_pool.o ipt_POOL.o ip_pool.o
1281 obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
1282 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
1284 obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
1285 obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
1287 +obj-$(CONFIG_IP_NF_MATCH_MPORT) += ipt_mport.o
1289 obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
1290 obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
1292 +obj-$(CONFIG_IP_NF_MATCH_TIME) += ipt_time.o
1295 +obj-$(CONFIG_IP_NF_MATCH_RANDOM) += ipt_random.o
1297 +obj-$(CONFIG_IP_NF_MATCH_PSD) += ipt_psd.o
1299 +obj-$(CONFIG_IP_NF_MATCH_OSF) += ipt_osf.o
1302 +obj-$(CONFIG_IP_NF_MATCH_NTH) += ipt_nth.o
1304 +obj-$(CONFIG_IP_NF_MATCH_IPV4OPTIONS) += ipt_ipv4options.o
1307 +obj-$(CONFIG_IP_NF_MATCH_FUZZY) += ipt_fuzzy.o
1309 obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
1311 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
1314 obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o
1316 +obj-$(CONFIG_IP_NF_MATCH_U32) += ipt_u32.o
1319 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
1320 obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
1321 +obj-$(CONFIG_IP_NF_MATCH_CONNLIMIT) += ipt_connlimit.o
1322 obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
1323 obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
1324 +obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
1326 obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
1329 obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
1330 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
1331 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
1332 +obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
1333 +obj-$(CONFIG_IP_NF_TARGET_NETLINK) += ipt_NETLINK.o
1334 +obj-$(CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP) += ipt_IPV4OPTSSTRIP.o
1335 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
1336 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
1337 +obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o
1339 # generic ARP tables
1340 obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
1341 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ip_conntrack_core.c linux-2.6.6-rc1/net/ipv4/netfilter/ip_conntrack_core.c
1342 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ip_conntrack_core.c 2004-04-15 03:33:47.000000000 +0200
1343 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ip_conntrack_core.c 2004-04-15 21:21:20.000000000 +0200
1345 static atomic_t ip_conntrack_count = ATOMIC_INIT(0);
1346 struct list_head *ip_conntrack_hash;
1347 static kmem_cache_t *ip_conntrack_cachep;
1348 +struct ip_conntrack ip_conntrack_untracked;
1350 extern struct ip_conntrack_protocol ip_conntrack_generic_protocol;
1352 @@ -691,42 +692,50 @@
1353 struct ip_conntrack_expect *, tuple);
1354 READ_UNLOCK(&ip_conntrack_expect_tuple_lock);
1356 - /* If master is not in hash table yet (ie. packet hasn't left
1357 - this machine yet), how can other end know about expected?
1358 - Hence these are not the droids you are looking for (if
1359 - master ct never got confirmed, we'd hold a reference to it
1360 - and weird things would happen to future packets). */
1361 - if (expected && !is_confirmed(expected->expectant))
1364 - /* Look up the conntrack helper for master connections only */
1366 - conntrack->helper = ip_ct_find_helper(&repl_tuple);
1368 - /* If the expectation is dying, then this is a loser. */
1370 - && expected->expectant->helper->timeout
1371 - && ! del_timer(&expected->timeout))
1375 - DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
1376 - conntrack, expected);
1377 - /* Welcome, Mr. Bond. We've been expecting you... */
1378 - IP_NF_ASSERT(master_ct(conntrack));
1379 - __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
1380 - conntrack->master = expected;
1381 - expected->sibling = conntrack;
1382 - LIST_DELETE(&ip_conntrack_expect_list, expected);
1383 - expected->expectant->expecting--;
1384 - nf_conntrack_get(&master_ct(conntrack)->infos[0]);
1386 - atomic_inc(&ip_conntrack_count);
1387 + /* If master is not in hash table yet (ie. packet hasn't left
1388 + this machine yet), how can other end know about expected?
1389 + Hence these are not the droids you are looking for (if
1390 + master ct never got confirmed, we'd hold a reference to it
1391 + and weird things would happen to future packets). */
1392 + if (!is_confirmed(expected->expectant)) {
1394 + conntrack->helper = ip_ct_find_helper(&repl_tuple);
1398 + /* Expectation is dying... */
1399 + if (expected->expectant->helper->timeout
1400 + && ! del_timer(&expected->timeout)) {
1404 + DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
1405 + conntrack, expected);
1406 + /* Welcome, Mr. Bond. We've been expecting you... */
1407 + IP_NF_ASSERT(master_ct(conntrack));
1408 + __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
1409 + conntrack->master = expected;
1410 + expected->sibling = conntrack;
1411 + LIST_DELETE(&ip_conntrack_expect_list, expected);
1412 + expected->expectant->expecting--;
1413 + nf_conntrack_get(&master_ct(conntrack)->infos[0]);
1415 + /* this is a braindead... --pablo */
1416 + atomic_inc(&ip_conntrack_count);
1417 + WRITE_UNLOCK(&ip_conntrack_lock);
1419 + if (expected->expectfn)
1420 + expected->expectfn(conntrack);
1424 + conntrack->helper = ip_ct_find_helper(&repl_tuple);
1426 +end: atomic_inc(&ip_conntrack_count);
1427 WRITE_UNLOCK(&ip_conntrack_lock);
1429 - if (expected && expected->expectfn)
1430 - expected->expectfn(conntrack);
1431 - return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
1432 +ret: return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
1435 /* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
1436 @@ -794,6 +803,15 @@
1440 + /* Never happen */
1441 + if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) {
1442 + if (net_ratelimit()) {
1443 + printk(KERN_ERR "ip_conntrack_in: Frag of proto %u (hook=%u)\n",
1444 + (*pskb)->nh.iph->protocol, hooknum);
1449 /* FIXME: Do this right please. --RR */
1450 (*pskb)->nfcache |= NFC_UNKNOWN;
1452 @@ -812,18 +830,10 @@
1456 - /* Previously seen (loopback)? Ignore. Do this before
1457 - fragment check. */
1458 + /* Previously seen (loopback or untracked)? Ignore. */
1462 - /* Gather fragments. */
1463 - if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
1464 - *pskb = ip_ct_gather_frags(*pskb);
1469 proto = ip_ct_find_proto((*pskb)->nh.iph->protocol);
1471 /* It may be an icmp error... */
1472 @@ -1422,6 +1432,18 @@
1474 /* For use by ipt_REJECT */
1475 ip_ct_attach = ip_conntrack_attach;
1477 + /* Set up fake conntrack:
1478 + - to never be deleted, not in any hashes */
1479 + atomic_set(&ip_conntrack_untracked.ct_general.use, 1);
1480 + /* - and look it like as a confirmed connection */
1481 + set_bit(IPS_CONFIRMED_BIT, &ip_conntrack_untracked.status);
1482 + /* - and prepare the ctinfo field for REJECT & NAT. */
1483 + ip_conntrack_untracked.infos[IP_CT_NEW].master =
1484 + ip_conntrack_untracked.infos[IP_CT_RELATED].master =
1485 + ip_conntrack_untracked.infos[IP_CT_RELATED + IP_CT_IS_REPLY].master =
1486 + &ip_conntrack_untracked.ct_general;
1491 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.6.6-rc1/net/ipv4/netfilter/ip_conntrack_standalone.c
1492 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-04-15 03:34:37.000000000 +0200
1493 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-04-15 21:21:20.000000000 +0200
1494 @@ -194,6 +194,26 @@
1495 return ip_conntrack_confirm(*pskb);
1498 +static unsigned int ip_conntrack_defrag(unsigned int hooknum,
1499 + struct sk_buff **pskb,
1500 + const struct net_device *in,
1501 + const struct net_device *out,
1502 + int (*okfn)(struct sk_buff *))
1504 + /* Previously seen (loopback)? Ignore. Do this before
1505 + fragment check. */
1506 + if ((*pskb)->nfct)
1509 + /* Gather fragments. */
1510 + if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
1511 + *pskb = ip_ct_gather_frags(*pskb);
1518 static unsigned int ip_refrag(unsigned int hooknum,
1519 struct sk_buff **pskb,
1520 const struct net_device *in,
1521 @@ -236,6 +256,14 @@
1523 /* Connection tracking may drop packets, but never alters them, so
1524 make it the first hook. */
1525 +static struct nf_hook_ops ip_conntrack_defrag_ops = {
1526 + .hook = ip_conntrack_defrag,
1527 + .owner = THIS_MODULE,
1529 + .hooknum = NF_IP_PRE_ROUTING,
1530 + .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
1533 static struct nf_hook_ops ip_conntrack_in_ops = {
1534 .hook = ip_conntrack_in,
1535 .owner = THIS_MODULE,
1536 @@ -244,6 +272,14 @@
1537 .priority = NF_IP_PRI_CONNTRACK,
1540 +static struct nf_hook_ops ip_conntrack_defrag_local_out_ops = {
1541 + .hook = ip_conntrack_defrag,
1542 + .owner = THIS_MODULE,
1544 + .hooknum = NF_IP_LOCAL_OUT,
1545 + .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
1548 static struct nf_hook_ops ip_conntrack_local_out_ops = {
1549 .hook = ip_conntrack_local,
1550 .owner = THIS_MODULE,
1551 @@ -470,10 +506,20 @@
1552 if (!proc) goto cleanup_init;
1553 proc->owner = THIS_MODULE;
1555 + ret = nf_register_hook(&ip_conntrack_defrag_ops);
1557 + printk("ip_conntrack: can't register pre-routing defrag hook.\n");
1558 + goto cleanup_proc;
1560 + ret = nf_register_hook(&ip_conntrack_defrag_local_out_ops);
1562 + printk("ip_conntrack: can't register local_out defrag hook.\n");
1563 + goto cleanup_defragops;
1565 ret = nf_register_hook(&ip_conntrack_in_ops);
1567 printk("ip_conntrack: can't register pre-routing hook.\n");
1568 - goto cleanup_proc;
1569 + goto cleanup_defraglocalops;
1571 ret = nf_register_hook(&ip_conntrack_local_out_ops);
1573 @@ -511,6 +557,10 @@
1574 nf_unregister_hook(&ip_conntrack_local_out_ops);
1576 nf_unregister_hook(&ip_conntrack_in_ops);
1577 + cleanup_defraglocalops:
1578 + nf_unregister_hook(&ip_conntrack_defrag_local_out_ops);
1579 + cleanup_defragops:
1580 + nf_unregister_hook(&ip_conntrack_defrag_ops);
1582 proc_net_remove("ip_conntrack");
1585 EXPORT_SYMBOL(ip_conntrack_expect_list);
1586 EXPORT_SYMBOL(ip_conntrack_lock);
1587 EXPORT_SYMBOL(ip_conntrack_hash);
1588 +EXPORT_SYMBOL(ip_conntrack_untracked);
1589 EXPORT_SYMBOL_GPL(ip_conntrack_find_get);
1590 EXPORT_SYMBOL_GPL(ip_conntrack_put);
1591 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ip_nat_core.c linux-2.6.6-rc1/net/ipv4/netfilter/ip_nat_core.c
1592 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ip_nat_core.c 2004-04-15 03:34:01.000000000 +0200
1593 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ip_nat_core.c 2004-04-15 21:21:20.000000000 +0200
1594 @@ -1016,6 +1016,10 @@
1595 /* FIXME: Man, this is a hack. <SIGH> */
1596 IP_NF_ASSERT(ip_conntrack_destroyed == NULL);
1597 ip_conntrack_destroyed = &ip_nat_cleanup_conntrack;
1599 + /* Initialize fake conntrack so that NAT will skip it */
1600 + ip_conntrack_untracked.nat.info.initialized |=
1601 + (1 << IP_NAT_MANIP_SRC) | (1 << IP_NAT_MANIP_DST);
1605 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ip_pool.c linux-2.6.6-rc1/net/ipv4/netfilter/ip_pool.c
1606 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ip_pool.c 1970-01-01 01:00:00.000000000 +0100
1607 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ip_pool.c 2004-04-15 21:21:08.000000000 +0200
1609 +/* Kernel module for IP pool management */
1611 +#include <linux/module.h>
1612 +#include <linux/ip.h>
1613 +#include <linux/skbuff.h>
1614 +#include <linux/netfilter_ipv4/ip_tables.h>
1615 +#include <linux/netfilter_ipv4/ip_pool.h>
1616 +#include <linux/errno.h>
1617 +#include <asm/uaccess.h>
1618 +#include <asm/bitops.h>
1619 +#include <linux/interrupt.h>
1620 +#include <linux/spinlock.h>
1625 +#define DP(format, args...)
1628 +MODULE_LICENSE("GPL");
1631 +static int nr_pool = NR_POOL;/* overwrite this when loading module */
1634 + u_int32_t first_ip; /* host byte order, included in range */
1635 + u_int32_t last_ip; /* host byte order, included in range */
1636 + void *members; /* the bitmap proper */
1637 + int nr_use; /* total nr. of tests through this */
1638 + int nr_match; /* total nr. of matches through this */
1642 +static struct ip_pool *POOL;
1644 +static inline struct ip_pool *lookup(ip_pool_t index)
1646 + if (index < 0 || index >= nr_pool) {
1647 + DP("ip_pool:lookup: bad index %d\n", index);
1650 + return POOL+index;
1653 +int ip_pool_match(ip_pool_t index, u_int32_t addr)
1655 + struct ip_pool *pool = lookup(index);
1658 + if (!pool || !pool->members)
1660 + read_lock_bh(&pool->lock);
1661 + if (pool->members) {
1662 + if (addr >= pool->first_ip && addr <= pool->last_ip) {
1663 + addr -= pool->first_ip;
1664 + if (test_bit(addr, pool->members)) {
1666 +#ifdef CONFIG_IP_POOL_STATISTICS
1671 +#ifdef CONFIG_IP_POOL_STATISTICS
1675 + read_unlock_bh(&pool->lock);
1679 +static int pool_change(ip_pool_t index, u_int32_t addr, int isdel)
1681 + struct ip_pool *pool;
1684 + pool = lookup(index);
1685 + if ( !pool || !pool->members
1686 + || addr < pool->first_ip || addr > pool->last_ip)
1688 + read_lock_bh(&pool->lock);
1689 + if (pool->members && addr >= pool->first_ip && addr <= pool->last_ip) {
1690 + addr -= pool->first_ip;
1692 + ? (0 != test_and_clear_bit(addr, pool->members))
1693 + : (0 != test_and_set_bit(addr, pool->members));
1695 + read_unlock_bh(&pool->lock);
1699 +int ip_pool_mod(ip_pool_t index, u_int32_t addr, int isdel)
1701 + int res = pool_change(index,addr,isdel);
1703 + if (!isdel) res = !res;
1707 +static inline int bitmap_bytes(u_int32_t a, u_int32_t b)
1709 + return 4*((((b-a+8)/8)+3)/4);
1712 +static inline int poolbytes(ip_pool_t index)
1714 + struct ip_pool *pool = lookup(index);
1716 + return pool ? bitmap_bytes(pool->first_ip, pool->last_ip) : 0;
1719 +static int setpool(
1725 + struct ip_pool_request req;
1727 + DP("ip_pool:setpool: optval=%d, user=%p, len=%d\n", optval, user, len);
1728 + if (!capable(CAP_NET_ADMIN))
1730 + if (optval != SO_IP_POOL)
1732 + if (len != sizeof(req))
1734 + if (copy_from_user(&req, user, sizeof(req)) != 0)
1736 + printk("obsolete op - upgrade your ippool(8) utility.\n");
1740 +static int getpool(
1746 + struct ip_pool_request req;
1747 + struct ip_pool *pool;
1753 + DP("ip_pool:getpool: optval=%d, user=%p\n", optval, user);
1754 + if (!capable(CAP_NET_ADMIN))
1756 + if (optval != SO_IP_POOL)
1758 + if (*len != sizeof(req)) {
1761 + if (copy_from_user(&req, user, sizeof(req)) != 0)
1763 + DP("ip_pool:getpool op=%d, index=%d\n", req.op, req.index);
1764 + if (req.op < IP_POOL_BAD001) {
1765 + printk("obsolete op - upgrade your ippool(8) utility.\n");
1769 + case IP_POOL_HIGH_NR:
1770 + DP("ip_pool HIGH_NR\n");
1771 + req.index = IP_POOL_NONE;
1772 + for (i=0; i<nr_pool; i++)
1773 + if (POOL[i].members)
1775 + return copy_to_user(user, &req, sizeof(req));
1776 + case IP_POOL_LOOKUP:
1777 + DP("ip_pool LOOKUP\n");
1778 + pool = lookup(req.index);
1781 + if (!pool->members)
1783 + req.addr = htonl(pool->first_ip);
1784 + req.addr2 = htonl(pool->last_ip);
1785 + return copy_to_user(user, &req, sizeof(req));
1786 + case IP_POOL_USAGE:
1787 + DP("ip_pool USE\n");
1788 + pool = lookup(req.index);
1791 + if (!pool->members)
1793 + req.addr = pool->nr_use;
1794 + req.addr2 = pool->nr_match;
1795 + return copy_to_user(user, &req, sizeof(req));
1796 + case IP_POOL_TEST_ADDR:
1797 + DP("ip_pool TEST 0x%08x\n", req.addr);
1798 + pool = lookup(req.index);
1802 + read_lock_bh(&pool->lock);
1803 + if (!pool->members) {
1804 + DP("ip_pool TEST_ADDR no members in pool\n");
1806 + goto unlock_and_return_res;
1808 + req.addr = ntohl(req.addr);
1809 + if (req.addr < pool->first_ip) {
1810 + DP("ip_pool TEST_ADDR address < pool bounds\n");
1812 + goto unlock_and_return_res;
1814 + if (req.addr > pool->last_ip) {
1815 + DP("ip_pool TEST_ADDR address > pool bounds\n");
1817 + goto unlock_and_return_res;
1819 + req.addr = (0 != test_bit((req.addr - pool->first_ip),
1821 + read_unlock_bh(&pool->lock);
1822 + return copy_to_user(user, &req, sizeof(req));
1823 + case IP_POOL_FLUSH:
1824 + DP("ip_pool FLUSH not yet implemented.\n");
1826 + case IP_POOL_DESTROY:
1827 + DP("ip_pool DESTROY not yet implemented.\n");
1829 + case IP_POOL_INIT:
1830 + DP("ip_pool INIT 0x%08x-0x%08x\n", req.addr, req.addr2);
1831 + pool = lookup(req.index);
1834 + req.addr = ntohl(req.addr);
1835 + req.addr2 = ntohl(req.addr2);
1836 + if (req.addr > req.addr2) {
1837 + DP("ip_pool INIT bad ip range\n");
1840 + newbytes = bitmap_bytes(req.addr, req.addr2);
1841 + newmembers = kmalloc(newbytes, GFP_KERNEL);
1842 + if (!newmembers) {
1843 + DP("ip_pool INIT out of mem for %d bytes\n", newbytes);
1846 + memset(newmembers, 0, newbytes);
1847 + write_lock_bh(&pool->lock);
1848 + if (pool->members) {
1849 + DP("ip_pool INIT pool %d exists\n", req.index);
1850 + kfree(newmembers);
1852 + goto unlock_and_return_res;
1854 + pool->first_ip = req.addr;
1855 + pool->last_ip = req.addr2;
1857 + pool->nr_match = 0;
1858 + pool->members = newmembers;
1859 + write_unlock_bh(&pool->lock);
1861 + case IP_POOL_ADD_ADDR:
1862 + DP("ip_pool ADD_ADDR 0x%08x\n", req.addr);
1863 + req.addr = pool_change(req.index, ntohl(req.addr), 0);
1864 + return copy_to_user(user, &req, sizeof(req));
1865 + case IP_POOL_DEL_ADDR:
1866 + DP("ip_pool DEL_ADDR 0x%08x\n", req.addr);
1867 + req.addr = pool_change(req.index, ntohl(req.addr), 1);
1868 + return copy_to_user(user, &req, sizeof(req));
1870 + DP("ip_pool:getpool bad op %d\n", req.op);
1875 +unlock_and_return_res:
1877 + read_unlock_bh(&pool->lock);
1881 +static struct nf_sockopt_ops so_pool
1882 += { { NULL, NULL }, PF_INET,
1883 + SO_IP_POOL, SO_IP_POOL+1, &setpool,
1884 + SO_IP_POOL, SO_IP_POOL+1, &getpool,
1887 +MODULE_PARM(nr_pool, "i");
1889 +static int __init init(void)
1894 + if (nr_pool < 1) {
1895 + printk("ip_pool module init: bad nr_pool %d\n", nr_pool);
1898 + POOL = kmalloc(nr_pool * sizeof(*POOL), GFP_KERNEL);
1900 + printk("ip_pool module init: out of memory for nr_pool %d\n",
1904 + for (i=0; i<nr_pool; i++) {
1905 + POOL[i].first_ip = 0;
1906 + POOL[i].last_ip = 0;
1907 + POOL[i].members = 0;
1908 + POOL[i].nr_use = 0;
1909 + POOL[i].nr_match = 0;
1910 + POOL[i].lock = RW_LOCK_UNLOCKED;
1912 + res = nf_register_sockopt(&so_pool);
1913 + DP("ip_pool:init %d pools, result %d\n", nr_pool, res);
1921 +static void __exit fini(void)
1925 + DP("ip_pool:fini BYEBYE\n");
1926 + nf_unregister_sockopt(&so_pool);
1927 + for (i=0; i<nr_pool; i++) {
1928 + if (POOL[i].members) {
1929 + kfree(POOL[i].members);
1930 + POOL[i].members = 0;
1935 + DP("ip_pool:fini these are the famous last words\n");
1941 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ip_tables.c linux-2.6.6-rc1/net/ipv4/netfilter/ip_tables.c
1942 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ip_tables.c 2004-04-15 03:34:03.000000000 +0200
1943 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ip_tables.c 2004-04-15 21:20:36.000000000 +0200
1944 @@ -1716,9 +1716,9 @@
1947 #ifdef CONFIG_PROC_FS
1948 -static inline int print_name(const char *i,
1949 - off_t start_offset, char *buffer, int length,
1950 - off_t *pos, unsigned int *count)
1951 +static int print_name(const char *i,
1952 + off_t start_offset, char *buffer, int length,
1953 + off_t *pos, unsigned int *count)
1955 if ((*count)++ >= start_offset) {
1956 unsigned int namelen;
1957 @@ -1752,6 +1752,15 @@
1961 +static inline int print_target(const struct ipt_target *t,
1962 + off_t start_offset, char *buffer, int length,
1963 + off_t *pos, unsigned int *count)
1965 + if (t != &ipt_standard_target && t != &ipt_error_target)
1967 + return print_name((char *)t, start_offset, buffer, length, pos, count);
1970 static int ipt_get_targets(char *buffer, char **start, off_t offset, int length)
1973 @@ -1760,7 +1769,7 @@
1974 if (down_interruptible(&ipt_mutex) != 0)
1977 - LIST_FIND(&ipt_target, print_name, void *,
1978 + LIST_FIND(&ipt_target, print_target, struct ipt_target *,
1979 offset, buffer, length, &pos, &count);
1982 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c
1983 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 1970-01-01 01:00:00.000000000 +0100
1984 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 2004-04-15 21:20:41.000000000 +0200
1987 + * Strip all IP options in the IP packet header.
1989 + * (C) 2001 by Fabrice MARIE <fabrice@netfilter.org>
1990 + * This software is distributed under GNU GPL v2, 1991
1993 +#include <linux/module.h>
1994 +#include <linux/skbuff.h>
1995 +#include <linux/ip.h>
1996 +#include <net/checksum.h>
1998 +#include <linux/netfilter_ipv4/ip_tables.h>
2000 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
2001 +MODULE_DESCRIPTION("Strip all options in IPv4 packets");
2002 +MODULE_LICENSE("GPL");
2004 +static unsigned int
2005 +target(struct sk_buff **pskb,
2006 + const struct net_device *in,
2007 + const struct net_device *out,
2008 + unsigned int hooknum,
2009 + const void *targinfo,
2012 + struct iphdr *iph;
2013 + struct sk_buff *skb;
2014 + struct ip_options *opt;
2015 + unsigned char *optiph;
2018 + if (!skb_ip_make_writable(pskb, (*pskb)->len))
2022 + iph = (*pskb)->nh.iph;
2023 + optiph = skb->nh.raw;
2024 + l = ((struct ip_options *)(&(IPCB(skb)->opt)))->optlen;
2026 + /* if no options in packet then nothing to clear. */
2027 + if (iph->ihl * 4 == sizeof(struct iphdr))
2028 + return IPT_CONTINUE;
2030 + /* else clear all options */
2031 + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
2032 + memset(optiph+sizeof(struct iphdr), IPOPT_NOOP, l);
2033 + opt = &(IPCB(skb)->opt);
2037 + skb->nfcache |= NFC_ALTERED;
2039 + return IPT_CONTINUE;
2043 +checkentry(const char *tablename,
2044 + const struct ipt_entry *e,
2046 + unsigned int targinfosize,
2047 + unsigned int hook_mask)
2049 + if (strcmp(tablename, "mangle")) {
2050 + printk(KERN_WARNING "IPV4OPTSSTRIP: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
2053 + /* nothing else to check because no parameters */
2057 +static struct ipt_target ipt_ipv4optsstrip_reg = {
2058 + .name = "IPV4OPTSSTRIP",
2060 + .checkentry = checkentry,
2061 + .me = THIS_MODULE };
2063 +static int __init init(void)
2065 + return ipt_register_target(&ipt_ipv4optsstrip_reg);
2068 +static void __exit fini(void)
2070 + ipt_unregister_target(&ipt_ipv4optsstrip_reg);
2075 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_LOG.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_LOG.c
2076 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_LOG.c 2004-04-15 03:35:37.000000000 +0200
2077 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_LOG.c 2004-04-15 21:20:33.000000000 +0200
2079 #include <net/tcp.h>
2080 #include <net/route.h>
2082 +#include <linux/netfilter.h>
2083 #include <linux/netfilter_ipv4/ip_tables.h>
2084 #include <linux/netfilter_ipv4/ipt_LOG.h>
2087 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
2088 MODULE_DESCRIPTION("iptables syslog logging module");
2090 +static unsigned int nflog = 1;
2091 +MODULE_PARM(nflog, "i");
2092 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
2095 #define DEBUGP printk
2097 @@ -324,28 +329,25 @@
2098 /* maxlen = 230+ 91 + 230 + 252 = 803 */
2101 -static unsigned int
2102 -ipt_log_target(struct sk_buff **pskb,
2104 +ipt_log_packet(unsigned int hooknum,
2105 + const struct sk_buff *skb,
2106 const struct net_device *in,
2107 const struct net_device *out,
2108 - unsigned int hooknum,
2109 - const void *targinfo,
2111 + const struct ipt_log_info *loginfo,
2112 + const char *level_string,
2113 + const char *prefix)
2115 - const struct ipt_log_info *loginfo = targinfo;
2116 - char level_string[4] = "< >";
2118 - level_string[1] = '0' + (loginfo->level % 8);
2119 spin_lock_bh(&log_lock);
2120 printk(level_string);
2121 printk("%sIN=%s OUT=%s ",
2123 + prefix == NULL ? loginfo->prefix : prefix,
2125 out ? out->name : "");
2126 #ifdef CONFIG_BRIDGE_NETFILTER
2127 - if ((*pskb)->nf_bridge) {
2128 - struct net_device *physindev = (*pskb)->nf_bridge->physindev;
2129 - struct net_device *physoutdev = (*pskb)->nf_bridge->physoutdev;
2130 + if (skb->nf_bridge) {
2131 + struct net_device *physindev = skb->nf_bridge->physindev;
2132 + struct net_device *physoutdev = skb->nf_bridge->physoutdev;
2134 if (physindev && in != physindev)
2135 printk("PHYSIN=%s ", physindev->name);
2136 @@ -357,25 +359,56 @@
2138 /* MAC logging for input chain only. */
2140 - if ((*pskb)->dev && (*pskb)->dev->hard_header_len
2141 - && (*pskb)->mac.raw != (void*)(*pskb)->nh.iph) {
2142 + if (skb->dev && skb->dev->hard_header_len
2143 + && skb->mac.raw != (void*)skb->nh.iph) {
2145 - unsigned char *p = (*pskb)->mac.raw;
2146 - for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++)
2147 + unsigned char *p = skb->mac.raw;
2148 + for (i = 0; i < skb->dev->hard_header_len; i++,p++)
2149 printk("%02x%c", *p,
2150 - i==(*pskb)->dev->hard_header_len - 1
2151 + i==skb->dev->hard_header_len - 1
2157 - dump_packet(loginfo, *pskb, 0);
2158 + dump_packet(loginfo, skb, 0);
2160 spin_unlock_bh(&log_lock);
2163 +static unsigned int
2164 +ipt_log_target(struct sk_buff **pskb,
2165 + const struct net_device *in,
2166 + const struct net_device *out,
2167 + unsigned int hooknum,
2168 + const void *targinfo,
2171 + const struct ipt_log_info *loginfo = targinfo;
2172 + char level_string[4] = "< >";
2174 + level_string[1] = '0' + (loginfo->level % 8);
2175 + ipt_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL);
2177 return IPT_CONTINUE;
2181 +ipt_logfn(unsigned int hooknum,
2182 + const struct sk_buff *skb,
2183 + const struct net_device *in,
2184 + const struct net_device *out,
2185 + const char *prefix)
2187 + struct ipt_log_info loginfo = {
2189 + .logflags = IPT_LOG_MASK,
2193 + ipt_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
2196 static int ipt_log_checkentry(const char *tablename,
2197 const struct ipt_entry *e,
2199 @@ -413,11 +446,18 @@
2201 static int __init init(void)
2203 - return ipt_register_target(&ipt_log_reg);
2204 + if (ipt_register_target(&ipt_log_reg))
2207 + nf_log_register(PF_INET, &ipt_logfn);
2212 static void __exit fini(void)
2215 + nf_log_unregister(PF_INET, &ipt_logfn);
2216 ipt_unregister_target(&ipt_log_reg);
2219 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_NETLINK.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_NETLINK.c
2220 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_NETLINK.c 1970-01-01 01:00:00.000000000 +0100
2221 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_NETLINK.c 2004-04-15 21:20:44.000000000 +0200
2223 +#include <linux/module.h>
2224 +#include <linux/version.h>
2225 +#include <linux/config.h>
2226 +#include <linux/socket.h>
2227 +#include <linux/skbuff.h>
2228 +#include <linux/kernel.h>
2229 +#include <linux/netlink.h>
2230 +#include <linux/netdevice.h>
2231 +#include <linux/mm.h>
2232 +#include <linux/socket.h>
2233 +#include <linux/netfilter_ipv4/ip_tables.h>
2234 +#include <linux/netfilter_ipv4/ipt_NETLINK.h>
2235 +#include <net/sock.h>
2237 +MODULE_AUTHOR("Gianni Tedesco <gianni@ecsc.co.uk>");
2238 +MODULE_DESCRIPTION("Provides iptables NETLINK target similar to ipchains -o");
2239 +MODULE_LICENSE("GPL");
2242 +#define DEBUGP printk
2244 +#define DEBUGP(format, args...)
2247 +static struct sock *ipfwsk;
2249 +static unsigned int ipt_netlink_target(struct sk_buff **pskb,
2250 + unsigned int hooknum,
2251 + const struct net_device *in,
2252 + const struct net_device *out,
2253 + const void *targinfo, void *userinfo)
2255 + struct ipt_nldata *nld = (struct ipt_nldata *)targinfo;
2256 + struct iphdr *ip = (*pskb)->nh.iph;
2257 + struct sk_buff *outskb;
2258 + struct netlink_t nlhdr;
2261 + /* Allocate a socket buffer */
2262 + if ( MASK(nld->flags, USE_SIZE) )
2263 + len = nld->size+sizeof(nlhdr);
2265 + len = ntohs(ip->tot_len)+sizeof(nlhdr);
2267 + outskb=alloc_skb(len, GFP_ATOMIC);
2272 + if ( MASK(nld->flags, USE_MARK) )
2273 + nlhdr.mark=(*pskb)->nfmark=nld->mark;
2275 + nlhdr.mark=(*pskb)->nfmark;
2277 + if ( in && in->name ) {
2278 + strncpy((char *)&nlhdr.iface, in->name, IFNAMSIZ);
2279 + }else if ( out && out->name ){
2280 + strncpy((char *)&nlhdr.iface, out->name, IFNAMSIZ);
2283 + skb_put(outskb, len);
2284 + memcpy(outskb->data, &nlhdr, sizeof(nlhdr));
2285 + memcpy((outskb->data)+sizeof(nlhdr), ip, len-sizeof(nlhdr));
2286 + netlink_broadcast(ipfwsk, outskb, 0, ~0, GFP_ATOMIC);
2288 + if (net_ratelimit())
2289 + printk(KERN_WARNING "ipt_NETLINK: packet drop due to netlink failure\n");
2292 + if ( MASK(nld->flags, USE_DROP) )
2295 + return IPT_CONTINUE;
2298 +static int ipt_netlink_checkentry(const char *tablename,
2299 + const struct ipt_entry *e,
2301 + unsigned int targinfosize,
2302 + unsigned int hookmask)
2304 + //struct ipt_nldata *nld = (struct ipt_nldata *)targinfo;
2309 +static struct ipt_target ipt_netlink_reg = {
2312 + ipt_netlink_target,
2313 + ipt_netlink_checkentry,
2318 +static int __init init(void)
2320 + DEBUGP("ipt_NETLINK: init module\n");
2322 + if (ipt_register_target(&ipt_netlink_reg) != 0) {
2326 + if ( !(ipfwsk=netlink_kernel_create(NETLINK_FIREWALL, NULL)) ){
2333 +static void __exit fini(void)
2335 + DEBUGP("ipt_NETLINK: cleanup_module\n");
2336 + ipt_unregister_target(&ipt_netlink_reg);
2337 + if(ipfwsk->socket) sock_release(ipfwsk->socket);
2342 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_NOTRACK.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_NOTRACK.c
2343 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_NOTRACK.c 1970-01-01 01:00:00.000000000 +0100
2344 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_NOTRACK.c 2004-04-15 21:21:20.000000000 +0200
2346 +/* This is a module which is used for setting up fake conntracks
2347 + * on packets so that they are not seen by the conntrack/NAT code.
2349 +#include <linux/module.h>
2350 +#include <linux/skbuff.h>
2352 +#include <linux/netfilter_ipv4/ip_tables.h>
2353 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2355 +static unsigned int
2356 +target(struct sk_buff **pskb,
2357 + const struct net_device *in,
2358 + const struct net_device *out,
2359 + unsigned int hooknum,
2360 + const void *targinfo,
2363 + /* Previously seen (loopback)? Ignore. */
2364 + if ((*pskb)->nfct != NULL)
2365 + return IPT_CONTINUE;
2367 + /* Attach fake conntrack entry.
2368 + If there is a real ct entry correspondig to this packet,
2369 + it'll hang aroun till timing out. We don't deal with it
2370 + for performance reasons. JK */
2371 + (*pskb)->nfct = &ip_conntrack_untracked.infos[IP_CT_NEW];
2372 + nf_conntrack_get((*pskb)->nfct);
2374 + return IPT_CONTINUE;
2378 +checkentry(const char *tablename,
2379 + const struct ipt_entry *e,
2381 + unsigned int targinfosize,
2382 + unsigned int hook_mask)
2384 + if (targinfosize != 0) {
2385 + printk(KERN_WARNING "NOTRACK: targinfosize %u != 0\n",
2390 + if (strcmp(tablename, "raw") != 0) {
2391 + printk(KERN_WARNING "NOTRACK: can only be called from \"raw\" table, not \"%s\"\n", tablename);
2398 +static struct ipt_target ipt_notrack_reg = {
2399 + .name = "NOTRACK",
2401 + .checkentry = checkentry,
2405 +static int __init init(void)
2407 + if (ipt_register_target(&ipt_notrack_reg))
2413 +static void __exit fini(void)
2415 + ipt_unregister_target(&ipt_notrack_reg);
2420 +MODULE_LICENSE("GPL");
2421 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_POOL.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_POOL.c
2422 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_POOL.c 1970-01-01 01:00:00.000000000 +0100
2423 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_POOL.c 2004-04-15 21:21:08.000000000 +0200
2425 +/* ipt_POOL.c - netfilter target to manipulate IP pools
2427 + * This target can be used almost everywhere. It acts on some specified
2428 + * IP pool, adding or deleting some IP address in the pool. The address
2429 + * can be either the source (--addsrc, --delsrc), or destination (--add/deldst)
2430 + * of the packet under inspection.
2432 + * The target normally returns IPT_CONTINUE.
2435 +#include <linux/types.h>
2436 +#include <linux/ip.h>
2437 +#include <linux/timer.h>
2438 +#include <linux/module.h>
2439 +#include <linux/netfilter.h>
2440 +#include <linux/netdevice.h>
2441 +#include <linux/if.h>
2442 +#include <linux/inetdevice.h>
2443 +#include <net/protocol.h>
2444 +#include <net/checksum.h>
2445 +#include <linux/netfilter_ipv4.h>
2446 +#include <linux/netfilter_ipv4/ip_nat_rule.h>
2447 +#include <linux/netfilter_ipv4/ipt_pool.h>
2450 +#define DEBUGP printk
2452 +#define DEBUGP(format, args...)
2455 +/*** NOTE NOTE NOTE NOTE ***
2457 +** By sheer luck, I get away with using the "struct ipt_pool_info", as defined
2458 +** in <linux/netfilter_ipv4/ipt_pool.h>, both as the match and target info.
2459 +** Here, in the target implementation, ipt_pool_info.src, if not IP_POOL_NONE,
2460 +** is modified for the source IP address of the packet under inspection.
2461 +** The same way, the ipt_pool_info.dst pool is modified for the destination.
2463 +** The address is added to the pool normally. However, if IPT_POOL_DEL_dir
2464 +** flag is set in ipt_pool_info.flags, the address is deleted from the pool.
2466 +** If a modification was done to the pool, we possibly return ACCEPT or DROP,
2467 +** if the right IPT_POOL_MOD_dir_ACCEPT or _MOD_dir_DROP flags are set.
2468 +** The IPT_POOL_INV_MOD_dir flag inverts the sense of the check (i.e. the
2469 +** ACCEPT and DROP flags are evaluated when the pool was not modified.)
2473 +do_check(const char *tablename,
2474 + const struct ipt_entry *e,
2476 + unsigned int targinfosize,
2477 + unsigned int hook_mask)
2479 + const struct ipt_pool_info *ipi = targinfo;
2481 + if (targinfosize != IPT_ALIGN(sizeof(*ipi))) {
2482 + DEBUGP("POOL_check: size %u.\n", targinfosize);
2485 + DEBUGP("ipt_POOL:do_check(%d,%d,%d)\n",ipi->src,ipi->dst,ipi->flags);
2489 +static unsigned int
2490 +do_target(struct sk_buff **pskb,
2491 + unsigned int hooknum,
2492 + const struct net_device *in,
2493 + const struct net_device *out,
2494 + const void *targinfo,
2497 + const struct ipt_pool_info *ipi = targinfo;
2499 + unsigned int verdict = IPT_CONTINUE;
2501 + if (ipi->src != IP_POOL_NONE) {
2502 + modified = ip_pool_mod(ipi->src, ntohl((*pskb)->nh.iph->saddr),
2503 + ipi->flags & IPT_POOL_DEL_SRC);
2504 + if (!!modified ^ !!(ipi->flags & IPT_POOL_INV_MOD_SRC)) {
2505 + if (ipi->flags & IPT_POOL_MOD_SRC_ACCEPT)
2506 + verdict = NF_ACCEPT;
2507 + else if (ipi->flags & IPT_POOL_MOD_SRC_DROP)
2508 + verdict = NF_DROP;
2511 + if (verdict == IPT_CONTINUE && ipi->dst != IP_POOL_NONE) {
2512 + modified = ip_pool_mod(ipi->dst, ntohl((*pskb)->nh.iph->daddr),
2513 + ipi->flags & IPT_POOL_DEL_DST);
2514 + if (!!modified ^ !!(ipi->flags & IPT_POOL_INV_MOD_DST)) {
2515 + if (ipi->flags & IPT_POOL_MOD_DST_ACCEPT)
2516 + verdict = NF_ACCEPT;
2517 + else if (ipi->flags & IPT_POOL_MOD_DST_DROP)
2518 + verdict = NF_DROP;
2524 +static struct ipt_target pool_reg
2525 += { { NULL, NULL }, "POOL", do_target, do_check, NULL, THIS_MODULE };
2527 +static int __init init(void)
2529 + DEBUGP("init ipt_POOL\n");
2530 + return ipt_register_target(&pool_reg);
2533 +static void __exit fini(void)
2535 + DEBUGP("fini ipt_POOL\n");
2536 + ipt_unregister_target(&pool_reg);
2541 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_TTL.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_TTL.c
2542 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_TTL.c 1970-01-01 01:00:00.000000000 +0100
2543 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_TTL.c 2004-04-15 21:20:49.000000000 +0200
2545 +/* TTL modification target for IP tables
2546 + * (C) 2000 by Harald Welte <laforge@gnumonks.org>
2548 + * Version: $Revision$
2550 + * This software is distributed under the terms of GNU GPL
2553 +#include <linux/module.h>
2554 +#include <linux/skbuff.h>
2555 +#include <linux/ip.h>
2556 +#include <net/checksum.h>
2558 +#include <linux/netfilter_ipv4/ip_tables.h>
2559 +#include <linux/netfilter_ipv4/ipt_TTL.h>
2561 +MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
2562 +MODULE_DESCRIPTION("IP tables TTL modification module");
2563 +MODULE_LICENSE("GPL");
2565 +static unsigned int
2566 +ipt_ttl_target(struct sk_buff **pskb, const struct net_device *in,
2567 + const struct net_device *out, unsigned int hooknum,
2568 + const void *targinfo, void *userinfo)
2570 + struct iphdr *iph;
2571 + const struct ipt_TTL_info *info = targinfo;
2572 + u_int16_t diffs[2];
2575 + if (!skb_ip_make_writable(pskb, (*pskb)->len))
2578 + iph = (*pskb)->nh.iph;
2580 + switch (info->mode) {
2582 + new_ttl = info->ttl;
2585 + new_ttl = iph->ttl + info->ttl;
2586 + if (new_ttl > 255)
2590 + new_ttl = iph->ttl + info->ttl;
2595 + new_ttl = iph->ttl;
2599 + if (new_ttl != iph->ttl) {
2600 + diffs[0] = htons(((unsigned)iph->ttl) << 8) ^ 0xFFFF;
2601 + iph->ttl = new_ttl;
2602 + diffs[1] = htons(((unsigned)iph->ttl) << 8);
2603 + iph->check = csum_fold(csum_partial((char *)diffs,
2605 + iph->check^0xFFFF));
2606 + (*pskb)->nfcache |= NFC_ALTERED;
2609 + return IPT_CONTINUE;
2612 +static int ipt_ttl_checkentry(const char *tablename,
2613 + const struct ipt_entry *e,
2615 + unsigned int targinfosize,
2616 + unsigned int hook_mask)
2618 + struct ipt_TTL_info *info = targinfo;
2620 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_TTL_info))) {
2621 + printk(KERN_WARNING "TTL: targinfosize %u != %Zu\n",
2623 + IPT_ALIGN(sizeof(struct ipt_TTL_info)));
2627 + if (strcmp(tablename, "mangle")) {
2628 + printk(KERN_WARNING "TTL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
2632 + if (info->mode > IPT_TTL_MAXMODE) {
2633 + printk(KERN_WARNING "TTL: invalid or unknown Mode %u\n",
2638 + if ((info->mode != IPT_TTL_SET) && (info->ttl == 0)) {
2639 + printk(KERN_WARNING "TTL: increment/decrement doesn't make sense with value 0\n");
2646 +static struct ipt_target ipt_TTL = {
2648 + .target = ipt_ttl_target,
2649 + .checkentry = ipt_ttl_checkentry,
2653 +static int __init init(void)
2655 + return ipt_register_target(&ipt_TTL);
2658 +static void __exit fini(void)
2660 + ipt_unregister_target(&ipt_TTL);
2665 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_ULOG.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_ULOG.c
2666 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_ULOG.c 2004-04-15 03:34:35.000000000 +0200
2667 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_ULOG.c 2004-04-15 21:20:33.000000000 +0200
2669 #include <linux/netlink.h>
2670 #include <linux/netdevice.h>
2671 #include <linux/mm.h>
2672 +#include <linux/netfilter.h>
2673 #include <linux/netfilter_ipv4/ip_tables.h>
2674 #include <linux/netfilter_ipv4/ipt_ULOG.h>
2675 #include <linux/netfilter_ipv4/lockhelp.h>
2677 MODULE_PARM(flushtimeout, "i");
2678 MODULE_PARM_DESC(flushtimeout, "buffer flush timeout");
2680 +static unsigned int nflog = 1;
2681 +MODULE_PARM(nflog, "i");
2682 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
2684 /* global data structures */
2687 @@ -157,17 +162,17 @@
2691 -static unsigned int ipt_ulog_target(struct sk_buff **pskb,
2692 - const struct net_device *in,
2693 - const struct net_device *out,
2694 - unsigned int hooknum,
2695 - const void *targinfo, void *userinfo)
2696 +static void ipt_ulog_packet(unsigned int hooknum,
2697 + const struct sk_buff *skb,
2698 + const struct net_device *in,
2699 + const struct net_device *out,
2700 + const struct ipt_ulog_info *loginfo,
2701 + const char *prefix)
2704 ulog_packet_msg_t *pm;
2705 size_t size, copy_len;
2706 struct nlmsghdr *nlh;
2707 - struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
2709 /* ffs == find first bit set, necessary because userspace
2710 * is already shifting groupnumber, but we need unshifted.
2713 /* calculate the size of the skb needed */
2714 if ((loginfo->copy_range == 0) ||
2715 - (loginfo->copy_range > (*pskb)->len)) {
2716 - copy_len = (*pskb)->len;
2717 + (loginfo->copy_range > skb->len)) {
2718 + copy_len = skb->len;
2720 copy_len = loginfo->copy_range;
2722 @@ -214,19 +219,21 @@
2724 /* copy hook, prefix, timestamp, payload, etc. */
2725 pm->data_len = copy_len;
2726 - pm->timestamp_sec = (*pskb)->stamp.tv_sec;
2727 - pm->timestamp_usec = (*pskb)->stamp.tv_usec;
2728 - pm->mark = (*pskb)->nfmark;
2729 + pm->timestamp_sec = skb->stamp.tv_sec;
2730 + pm->timestamp_usec = skb->stamp.tv_usec;
2731 + pm->mark = skb->nfmark;
2733 - if (loginfo->prefix[0] != '\0')
2734 + if (prefix != NULL)
2735 + strncpy(pm->prefix, prefix, sizeof(pm->prefix));
2736 + else if (loginfo->prefix[0] != '\0')
2737 strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix));
2739 *(pm->prefix) = '\0';
2741 if (in && in->hard_header_len > 0
2742 - && (*pskb)->mac.raw != (void *) (*pskb)->nh.iph
2743 + && skb->mac.raw != (void *) skb->nh.iph
2744 && in->hard_header_len <= ULOG_MAC_LEN) {
2745 - memcpy(pm->mac, (*pskb)->mac.raw, in->hard_header_len);
2746 + memcpy(pm->mac, skb->mac.raw, in->hard_header_len);
2747 pm->mac_len = in->hard_header_len;
2752 pm->outdev_name[0] = '\0';
2754 - /* copy_len <= (*pskb)->len, so can't fail. */
2755 - if (skb_copy_bits(*pskb, 0, pm->payload, copy_len) < 0)
2756 + /* copy_len <= skb->len, so can't fail. */
2757 + if (skb_copy_bits(skb, 0, pm->payload, copy_len) < 0)
2760 /* check if we are building multi-part messages */
2763 UNLOCK_BH(&ulog_lock);
2765 - return IPT_CONTINUE;
2770 PRINTR("ipt_ULOG: error during NLMSG_PUT\n");
2771 @@ -276,8 +282,35 @@
2772 PRINTR("ipt_ULOG: Error building netlink message\n");
2774 UNLOCK_BH(&ulog_lock);
2777 +static unsigned int ipt_ulog_target(struct sk_buff **pskb,
2778 + const struct net_device *in,
2779 + const struct net_device *out,
2780 + unsigned int hooknum,
2781 + const void *targinfo, void *userinfo)
2783 + struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
2785 - return IPT_CONTINUE;
2786 + ipt_ulog_packet(hooknum, *pskb, in, out, loginfo, NULL);
2788 + return IPT_CONTINUE;
2791 +static void ipt_logfn(unsigned int hooknum,
2792 + const struct sk_buff *skb,
2793 + const struct net_device *in,
2794 + const struct net_device *out,
2795 + const char *prefix)
2797 + struct ipt_ulog_info loginfo = {
2798 + .nl_group = ULOG_DEFAULT_NLGROUP,
2800 + .qthreshold = ULOG_DEFAULT_QTHRESHOLD,
2804 + ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
2807 static int ipt_ulog_checkentry(const char *tablename,
2809 sock_release(nflognl->sk_socket);
2814 + nf_log_register(PF_INET, &ipt_logfn);
2821 DEBUGP("ipt_ULOG: cleanup_module\n");
2824 + nf_log_unregister(PF_INET, &ipt_logfn);
2825 ipt_unregister_target(&ipt_ulog_reg);
2826 sock_release(nflognl->sk_socket);
2828 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_connlimit.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_connlimit.c
2829 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_connlimit.c 1970-01-01 01:00:00.000000000 +0100
2830 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_connlimit.c 2004-04-15 21:20:53.000000000 +0200
2833 + * netfilter module to limit the number of parallel tcp
2834 + * connections per IP address.
2835 + * (c) 2000 Gerd Knorr <kraxel@bytesex.org>
2836 + * Nov 2002: Martin Bene <martin.bene@icomedias.com>:
2837 + * only ignore TIME_WAIT or gone connections
2841 + * Kernel module to match connection tracking information.
2842 + * GPL (C) 1999 Rusty Russell (rusty@rustcorp.com.au).
2844 +#include <linux/module.h>
2845 +#include <linux/skbuff.h>
2846 +#include <linux/list.h>
2847 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2848 +#include <linux/netfilter_ipv4/ip_conntrack_core.h>
2849 +#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
2850 +#include <linux/netfilter_ipv4/ip_tables.h>
2851 +#include <linux/netfilter_ipv4/ipt_connlimit.h>
2855 +MODULE_LICENSE("GPL");
2857 +/* we'll save the tuples of all connections we care about */
2858 +struct ipt_connlimit_conn
2860 + struct list_head list;
2861 + struct ip_conntrack_tuple tuple;
2864 +struct ipt_connlimit_data {
2866 + struct list_head iphash[256];
2869 +static int ipt_iphash(u_int32_t addr)
2873 + hash = addr & 0xff;
2874 + hash ^= (addr >> 8) & 0xff;
2875 + hash ^= (addr >> 16) & 0xff;
2876 + hash ^= (addr >> 24) & 0xff;
2880 +static int count_them(struct ipt_connlimit_data *data,
2881 + u_int32_t addr, u_int32_t mask,
2882 + struct ip_conntrack *ct)
2885 + const static char *tcp[] = { "none", "established", "syn_sent", "syn_recv",
2886 + "fin_wait", "time_wait", "close", "close_wait",
2887 + "last_ack", "listen" };
2889 + int addit = 1, matches = 0;
2890 + struct ip_conntrack_tuple tuple;
2891 + struct ip_conntrack_tuple_hash *found;
2892 + struct ipt_connlimit_conn *conn;
2893 + struct list_head *hash,*lh;
2895 + spin_lock(&data->lock);
2896 + tuple = ct->tuplehash[0].tuple;
2897 + hash = &data->iphash[ipt_iphash(addr & mask)];
2899 + /* check the saved connections */
2900 + for (lh = hash->next; lh != hash; lh = lh->next) {
2901 + conn = list_entry(lh,struct ipt_connlimit_conn,list);
2902 + found = ip_conntrack_find_get(&conn->tuple,ct);
2903 + if (0 == memcmp(&conn->tuple,&tuple,sizeof(tuple)) &&
2905 + found->ctrack->proto.tcp.state != TCP_CONNTRACK_TIME_WAIT) {
2906 + /* Just to be sure we have it only once in the list.
2907 + We should'nt see tuples twice unless someone hooks this
2908 + into a table without "-p tcp --syn" */
2912 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d %s\n",
2913 + ipt_iphash(addr & mask),
2914 + NIPQUAD(conn->tuple.src.ip), ntohs(conn->tuple.src.u.tcp.port),
2915 + NIPQUAD(conn->tuple.dst.ip), ntohs(conn->tuple.dst.u.tcp.port),
2916 + (NULL != found) ? tcp[found->ctrack->proto.tcp.state] : "gone");
2918 + if (NULL == found) {
2919 + /* this one is gone */
2921 + list_del(lh->next);
2925 + if (found->ctrack->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT) {
2926 + /* we don't care about connections which are
2927 + closed already -> ditch it */
2929 + list_del(lh->next);
2931 + nf_conntrack_put(&found->ctrack->infos[0]);
2934 + if ((addr & mask) == (conn->tuple.src.ip & mask)) {
2935 + /* same source IP address -> be counted! */
2938 + nf_conntrack_put(&found->ctrack->infos[0]);
2941 + /* save the new connection in our list */
2943 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d new\n",
2944 + ipt_iphash(addr & mask),
2945 + NIPQUAD(tuple.src.ip), ntohs(tuple.src.u.tcp.port),
2946 + NIPQUAD(tuple.dst.ip), ntohs(tuple.dst.u.tcp.port));
2948 + conn = kmalloc(sizeof(*conn),GFP_ATOMIC);
2951 + memset(conn,0,sizeof(*conn));
2952 + INIT_LIST_HEAD(&conn->list);
2953 + conn->tuple = tuple;
2954 + list_add(&conn->list,hash);
2957 + spin_unlock(&data->lock);
2962 +match(const struct sk_buff *skb,
2963 + const struct net_device *in,
2964 + const struct net_device *out,
2965 + const void *matchinfo,
2969 + const struct ipt_connlimit_info *info = matchinfo;
2970 + int connections, match;
2971 + struct ip_conntrack *ct;
2972 + enum ip_conntrack_info ctinfo;
2974 + ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
2976 + printk("ipt_connlimit: Oops: invalid ct state ?\n");
2980 + connections = count_them(info->data,skb->nh.iph->saddr,info->mask,ct);
2981 + if (-1 == connections) {
2982 + printk("ipt_connlimit: Hmm, kmalloc failed :-(\n");
2983 + *hotdrop = 1; /* let's free some memory :-) */
2986 + match = (info->inverse) ? (connections <= info->limit) : (connections > info->limit);
2988 + printk("ipt_connlimit: src=%u.%u.%u.%u mask=%u.%u.%u.%u "
2989 + "connections=%d limit=%d match=%s\n",
2990 + NIPQUAD(skb->nh.iph->saddr), NIPQUAD(info->mask),
2991 + connections, info->limit, match ? "yes" : "no");
2997 +static int check(const char *tablename,
2998 + const struct ipt_ip *ip,
3000 + unsigned int matchsize,
3001 + unsigned int hook_mask)
3003 + struct ipt_connlimit_info *info = matchinfo;
3007 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_connlimit_info)))
3010 + /* refuse anything but tcp */
3011 + if (ip->proto != IPPROTO_TCP)
3014 + /* init private data */
3015 + info->data = kmalloc(sizeof(struct ipt_connlimit_data),GFP_KERNEL);
3016 + spin_lock_init(&(info->data->lock));
3017 + for (i = 0; i < 256; i++)
3018 + INIT_LIST_HEAD(&(info->data->iphash[i]));
3023 +static void destroy(void *matchinfo, unsigned int matchinfosize)
3025 + struct ipt_connlimit_info *info = matchinfo;
3026 + struct ipt_connlimit_conn *conn;
3027 + struct list_head *hash;
3031 + for (i = 0; i < 256; i++) {
3032 + hash = &(info->data->iphash[i]);
3033 + while (hash != hash->next) {
3034 + conn = list_entry(hash->next,struct ipt_connlimit_conn,list);
3035 + list_del(hash->next);
3039 + kfree(info->data);
3042 +static struct ipt_match connlimit_match = {
3043 + .name = "connlimit",
3045 + .checkentry = &check,
3046 + .destroy = &destroy,
3050 +static int __init init(void)
3052 + return ipt_register_match(&connlimit_match);
3055 +static void __exit fini(void)
3057 + ipt_unregister_match(&connlimit_match);
3062 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_conntrack.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_conntrack.c
3063 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_conntrack.c 2004-04-15 03:35:37.000000000 +0200
3064 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_conntrack.c 2004-04-15 21:21:20.000000000 +0200
3067 #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
3070 - statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
3072 - statebit = IPT_CONNTRACK_STATE_INVALID;
3074 + if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
3075 + statebit = IPT_CONNTRACK_STATE_UNTRACKED;
3077 + statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
3079 + statebit = IPT_CONNTRACK_STATE_INVALID;
3081 if(sinfo->flags & IPT_CONNTRACK_STATE) {
3083 if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip !=
3084 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_dstlimit.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_dstlimit.c
3085 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_dstlimit.c 1970-01-01 01:00:00.000000000 +0100
3086 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_dstlimit.c 2004-04-15 21:20:56.000000000 +0200
3088 +/* iptables match extension to limit the number of packets per second
3089 + * seperately for each destination.
3091 + * (C) 2003 by Harald Welte <laforge@netfilter.org>
3095 + * Development of this code was funded by Astaro AG, http://www.astaro.com/
3097 + * based on ipt_limit.c by:
3098 + * Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
3099 + * Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
3100 + * Rusty Russell <rusty@rustcorp.com.au>
3102 + * The general idea is to create a hash table for every dstip and have a
3103 + * seperate limit counter per tuple. This way you can do something like 'limit
3104 + * the number of syn packets for each of my internal addresses.
3106 + * Ideally this would just be implemented as a general 'hash' match, which would
3107 + * allow us to attach any iptables target to it's hash buckets. But this is
3108 + * not possible in the current iptables architecture. As always, pkttables for
3109 + * 2.7.x will help ;)
3111 +#include <linux/module.h>
3112 +#include <linux/skbuff.h>
3113 +#include <linux/spinlock.h>
3114 +#include <linux/random.h>
3115 +#include <linux/jhash.h>
3116 +#include <linux/slab.h>
3117 +#include <linux/vmalloc.h>
3118 +#include <linux/tcp.h>
3119 +#include <linux/udp.h>
3120 +#include <linux/proc_fs.h>
3121 +#include <linux/seq_file.h>
3123 +#define ASSERT_READ_LOCK(x)
3124 +#define ASSERT_WRITE_LOCK(x)
3125 +#include <linux/netfilter_ipv4/lockhelp.h>
3126 +#include <linux/netfilter_ipv4/listhelp.h>
3128 +#include <linux/netfilter_ipv4/ip_tables.h>
3129 +#include <linux/netfilter_ipv4/ipt_dstlimit.h>
3131 +/* FIXME: this is just for IP_NF_ASSERRT */
3132 +#include <linux/netfilter_ipv4/ip_conntrack.h>
3134 +#define MS2JIFFIES(x) ((x*HZ)/1000)
3136 +MODULE_LICENSE("GPL");
3137 +MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
3138 +MODULE_DESCRIPTION("iptables match for limiting per destination");
3140 +/* need to declare this at the top */
3141 +static struct proc_dir_entry *dstlimit_procdir;
3142 +static struct file_operations dl_file_ops;
3144 +/* hash table crap */
3146 +struct dsthash_dst {
3152 +struct dsthash_ent {
3153 + /* static / read-only parts in the beginning */
3154 + struct list_head list;
3155 + struct dsthash_dst dst;
3157 + /* modified structure members in the end */
3158 + unsigned long expires; /* precalculated expiry time */
3160 + unsigned long prev; /* last modification */
3162 + u_int32_t credit_cap, cost;
3166 +struct ipt_dstlimit_htable {
3167 + struct list_head list; /* global list of all htables */
3170 + struct dstlimit_cfg cfg; /* config */
3172 + /* used internally */
3173 + spinlock_t lock; /* lock for list_head */
3174 + u_int32_t rnd; /* random seed for hash */
3175 + struct timer_list timer; /* timer for gc */
3176 + atomic_t count; /* number entries in table */
3178 + /* seq_file stuff */
3179 + struct proc_dir_entry *pde;
3181 + struct list_head hash[0]; /* hashtable itself */
3184 +DECLARE_RWLOCK(dstlimit_lock); /* protects htables list */
3185 +static LIST_HEAD(dstlimit_htables);
3186 +static kmem_cache_t *dstlimit_cachep;
3188 +static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b)
3190 + return (ent->dst.dst_ip == b->dst_ip
3191 + && ent->dst.port == b->port
3192 + && ent->dst.src_ip == b->src_ip);
3195 +static inline u_int32_t
3196 +hash_dst(const struct ipt_dstlimit_htable *ht, const struct dsthash_dst *dst)
3198 + return (jhash_3words(dst->dst_ip, dst->port,
3199 + dst->src_ip, ht->rnd) % ht->cfg.size);
3202 +static inline struct dsthash_ent *
3203 +__dsthash_find(const struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
3205 + struct dsthash_ent *ent;
3206 + u_int32_t hash = hash_dst(ht, dst);
3207 + MUST_BE_LOCKED(&ht->lock);
3208 + ent = LIST_FIND(&ht->hash[hash], dst_cmp, struct dsthash_ent *, dst);
3212 +/* allocate dsthash_ent, initialize dst, put in htable and lock it */
3213 +static struct dsthash_ent *
3214 +__dsthash_alloc_init(struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
3216 + struct dsthash_ent *ent;
3218 + /* initialize hash with random val at the time we allocate
3219 + * the first hashtable entry */
3221 + get_random_bytes(&ht->rnd, 4);
3223 + if (ht->cfg.max &&
3224 + atomic_read(&ht->count) >= ht->cfg.max) {
3225 + /* FIXME: do something. question is what.. */
3226 + if (net_ratelimit())
3227 + printk(KERN_WARNING
3228 + "ipt_dstlimit: max count of %u reached\n",
3233 + ent = kmem_cache_alloc(dstlimit_cachep, GFP_ATOMIC);
3235 + if (net_ratelimit())
3237 + "ipt_dstlimit: can't allocate dsthash_ent\n");
3241 + atomic_inc(&ht->count);
3243 + ent->dst.dst_ip = dst->dst_ip;
3244 + ent->dst.port = dst->port;
3245 + ent->dst.src_ip = dst->src_ip;
3247 + list_add(&ent->list, &ht->hash[hash_dst(ht, dst)]);
3253 +__dsthash_free(struct ipt_dstlimit_htable *ht, struct dsthash_ent *ent)
3255 + MUST_BE_LOCKED(&ht->lock);
3257 + list_del(&ent->list);
3258 + kmem_cache_free(dstlimit_cachep, ent);
3259 + atomic_dec(&ht->count);
3261 +static void htable_gc(unsigned long htlong);
3263 +static int htable_create(struct ipt_dstlimit_info *minfo)
3266 + unsigned int size;
3267 + struct ipt_dstlimit_htable *hinfo;
3269 + if (minfo->cfg.size)
3270 + size = minfo->cfg.size;
3272 + size = (((num_physpages << PAGE_SHIFT) / 16384)
3273 + / sizeof(struct list_head));
3274 + if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
3279 + /* FIXME: don't use vmalloc() here or anywhere else -HW */
3280 + hinfo = vmalloc(sizeof(struct ipt_dstlimit_htable)
3281 + + (sizeof(struct list_head) * size));
3283 + printk(KERN_ERR "ipt_dstlimit: Unable to create hashtable\n");
3286 + minfo->hinfo = hinfo;
3288 + /* copy match config into hashtable config */
3289 + memcpy(&hinfo->cfg, &minfo->cfg, sizeof(hinfo->cfg));
3290 + hinfo->cfg.size = size;
3291 + if (!hinfo->cfg.max)
3292 + hinfo->cfg.max = 8 * hinfo->cfg.size;
3293 + else if (hinfo->cfg.max < hinfo->cfg.size)
3294 + hinfo->cfg.max = hinfo->cfg.size;
3296 + for (i = 0; i < hinfo->cfg.size; i++)
3297 + INIT_LIST_HEAD(&hinfo->hash[i]);
3299 + atomic_set(&hinfo->count, 0);
3300 + atomic_set(&hinfo->use, 1);
3302 + hinfo->lock = SPIN_LOCK_UNLOCKED;
3303 + hinfo->pde = create_proc_entry(minfo->name, 0, dstlimit_procdir);
3304 + if (!hinfo->pde) {
3308 + hinfo->pde->proc_fops = &dl_file_ops;
3309 + hinfo->pde->data = hinfo;
3311 + init_timer(&hinfo->timer);
3312 + hinfo->timer.expires = jiffies + MS2JIFFIES(hinfo->cfg.gc_interval);
3313 + hinfo->timer.data = (unsigned long )hinfo;
3314 + hinfo->timer.function = htable_gc;
3315 + add_timer(&hinfo->timer);
3317 + WRITE_LOCK(&dstlimit_lock);
3318 + list_add(&hinfo->list, &dstlimit_htables);
3319 + WRITE_UNLOCK(&dstlimit_lock);
3324 +static int select_all(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
3329 +static int select_gc(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
3331 + return (jiffies >= he->expires);
3334 +static void htable_selective_cleanup(struct ipt_dstlimit_htable *ht,
3335 + int (*select)(struct ipt_dstlimit_htable *ht,
3336 + struct dsthash_ent *he))
3340 + IP_NF_ASSERT(ht->cfg.size && ht->cfg.max);
3342 + /* lock hash table and iterate over it */
3343 + LOCK_BH(&ht->lock);
3344 + for (i = 0; i < ht->cfg.size; i++) {
3345 + struct dsthash_ent *dh, *n;
3346 + list_for_each_entry_safe(dh, n, &ht->hash[i], list) {
3347 + if ((*select)(ht, dh))
3348 + __dsthash_free(ht, dh);
3351 + UNLOCK_BH(&ht->lock);
3354 +/* hash table garbage collector, run by timer */
3355 +static void htable_gc(unsigned long htlong)
3357 + struct ipt_dstlimit_htable *ht = (struct ipt_dstlimit_htable *)htlong;
3359 + htable_selective_cleanup(ht, select_gc);
3361 + /* re-add the timer accordingly */
3362 + ht->timer.expires = jiffies + MS2JIFFIES(ht->cfg.gc_interval);
3363 + add_timer(&ht->timer);
3366 +static void htable_destroy(struct ipt_dstlimit_htable *hinfo)
3368 + /* remove timer, if it is pending */
3369 + if (timer_pending(&hinfo->timer))
3370 + del_timer(&hinfo->timer);
3372 + /* remove proc entry */
3373 + remove_proc_entry(hinfo->pde->name, dstlimit_procdir);
3375 + htable_selective_cleanup(hinfo, select_all);
3379 +static struct ipt_dstlimit_htable *htable_find_get(char *name)
3381 + struct ipt_dstlimit_htable *hinfo;
3383 + READ_LOCK(&dstlimit_lock);
3384 + list_for_each_entry(hinfo, &dstlimit_htables, list) {
3385 + if (!strcmp(name, hinfo->pde->name)) {
3386 + atomic_inc(&hinfo->use);
3387 + READ_UNLOCK(&dstlimit_lock);
3391 + READ_UNLOCK(&dstlimit_lock);
3396 +static void htable_put(struct ipt_dstlimit_htable *hinfo)
3398 + if (atomic_dec_and_test(&hinfo->use)) {
3399 + WRITE_LOCK(&dstlimit_lock);
3400 + list_del(&hinfo->list);
3401 + WRITE_UNLOCK(&dstlimit_lock);
3402 + htable_destroy(hinfo);
3407 +/* The algorithm used is the Simple Token Bucket Filter (TBF)
3408 + * see net/sched/sch_tbf.c in the linux source tree
3411 +/* Rusty: This is my (non-mathematically-inclined) understanding of
3412 + this algorithm. The `average rate' in jiffies becomes your initial
3413 + amount of credit `credit' and the most credit you can ever have
3414 + `credit_cap'. The `peak rate' becomes the cost of passing the
3417 + `prev' tracks the last packet hit: you gain one credit per jiffy.
3418 + If you get credit balance more than this, the extra credit is
3419 + discarded. Every time the match passes, you lose `cost' credits;
3420 + if you don't have that many, the test fails.
3422 + See Alexey's formal explanation in net/sched/sch_tbf.c.
3424 + To get the maximum range, we multiply by this factor (ie. you get N
3425 + credits per jiffy). We want to allow a rate as low as 1 per day
3426 + (slowest userspace tool allows), which means
3427 + CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32 ie.
3429 +#define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24))
3431 +/* Repeated shift and or gives us all 1s, final shift and add 1 gives
3432 + * us the power of 2 below the theoretical max, so GCC simply does a
3434 +#define _POW2_BELOW2(x) ((x)|((x)>>1))
3435 +#define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2))
3436 +#define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4))
3437 +#define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8))
3438 +#define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16))
3439 +#define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1)
3441 +#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
3443 +/* Precision saver. */
3444 +static inline u_int32_t
3445 +user2credits(u_int32_t user)
3447 + /* If multiplying would overflow... */
3448 + if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY))
3449 + /* Divide first. */
3450 + return (user / IPT_DSTLIMIT_SCALE) * HZ * CREDITS_PER_JIFFY;
3452 + return (user * HZ * CREDITS_PER_JIFFY) / IPT_DSTLIMIT_SCALE;
3455 +static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
3457 + dh->rateinfo.credit += (now - xchg(&dh->rateinfo.prev, now))
3458 + * CREDITS_PER_JIFFY;
3459 + if (dh->rateinfo.credit > dh->rateinfo.credit_cap)
3460 + dh->rateinfo.credit = dh->rateinfo.credit_cap;
3464 +dstlimit_match(const struct sk_buff *skb,
3465 + const struct net_device *in,
3466 + const struct net_device *out,
3467 + const void *matchinfo,
3471 + struct ipt_dstlimit_info *r =
3472 + ((struct ipt_dstlimit_info *)matchinfo)->u.master;
3473 + struct ipt_dstlimit_htable *hinfo = r->hinfo;
3474 + unsigned long now = jiffies;
3475 + struct dsthash_ent *dh;
3476 + struct dsthash_dst dst;
3478 + memset(&dst, 0, sizeof(dst));
3480 + /* dest ip is always in hash */
3481 + dst.dst_ip = skb->nh.iph->daddr;
3483 + /* source ip only if respective hashmode, otherwise set to
3485 + if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_SIP)
3486 + dst.src_ip = skb->nh.iph->saddr;
3488 + /* dest port only if respective mode */
3489 + if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_DPT) {
3492 + /* Must not be a fragment. */
3496 + /* Must be big enough to read ports (both UDP and TCP have
3497 + them at the start). */
3498 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
3499 + /* We've been asked to examine this packet, and we
3500 + can't. Hence, no choice but to drop. */
3505 + switch (skb->nh.iph->protocol) {
3506 + struct tcphdr *th;
3507 + struct udphdr *uh;
3509 + th = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
3510 + dst.port = th->dest;
3513 + uh = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
3514 + dst.port = uh->dest;
3521 + LOCK_BH(&hinfo->lock);
3522 + dh = __dsthash_find(hinfo, &dst);
3524 + dh = __dsthash_alloc_init(hinfo, &dst);
3527 + /* enomem... don't match == DROP */
3528 + if (net_ratelimit())
3529 + printk(KERN_ERR "%s: ENOMEM\n", __FUNCTION__);
3530 + UNLOCK_BH(&hinfo->lock);
3534 + dh->expires = jiffies + MS2JIFFIES(hinfo->cfg.expire);
3536 + dh->rateinfo.prev = jiffies;
3537 + dh->rateinfo.credit = user2credits(hinfo->cfg.avg *
3538 + hinfo->cfg.burst);
3539 + dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg *
3540 + hinfo->cfg.burst);
3541 + dh->rateinfo.cost = user2credits(hinfo->cfg.avg);
3543 + UNLOCK_BH(&hinfo->lock);
3547 + /* update expiration timeout */
3548 + dh->expires = now + MS2JIFFIES(hinfo->cfg.expire);
3550 + rateinfo_recalc(dh, now);
3551 + if (dh->rateinfo.credit >= dh->rateinfo.cost) {
3552 + /* We're underlimit. */
3553 + dh->rateinfo.credit -= dh->rateinfo.cost;
3554 + UNLOCK_BH(&hinfo->lock);
3558 + UNLOCK_BH(&hinfo->lock);
3560 + /* default case: we're overlimit, thus don't match */
3565 +dstlimit_checkentry(const char *tablename,
3566 + const struct ipt_ip *ip,
3568 + unsigned int matchsize,
3569 + unsigned int hook_mask)
3571 + struct ipt_dstlimit_info *r = matchinfo;
3573 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_dstlimit_info)))
3576 + /* Check for overflow. */
3577 + if (r->cfg.burst == 0
3578 + || user2credits(r->cfg.avg * r->cfg.burst) <
3579 + user2credits(r->cfg.avg)) {
3580 + printk(KERN_ERR "ipt_dstlimit: Overflow, try lower: %u/%u\n",
3581 + r->cfg.avg, r->cfg.burst);
3585 + if (r->cfg.mode == 0
3586 + || r->cfg.mode > (IPT_DSTLIMIT_HASH_DPT
3587 + |IPT_DSTLIMIT_HASH_DIP
3588 + |IPT_DSTLIMIT_HASH_SIP))
3591 + if (!r->cfg.gc_interval)
3594 + if (!r->cfg.expire)
3597 + r->hinfo = htable_find_get(r->name);
3598 + if (!r->hinfo && (htable_create(r) != 0)) {
3602 + /* Ugly hack: For SMP, we only want to use one set */
3609 +dstlimit_destroy(void *matchinfo, unsigned int matchsize)
3611 + struct ipt_dstlimit_info *r = (struct ipt_dstlimit_info *) matchinfo;
3613 + htable_put(r->hinfo);
3616 +static struct ipt_match ipt_dstlimit = {
3617 + .list = { .prev = NULL, .next = NULL },
3618 + .name = "dstlimit",
3619 + .match = dstlimit_match,
3620 + .checkentry = dstlimit_checkentry,
3621 + .destroy = dstlimit_destroy,
3627 +static void *dl_seq_start(struct seq_file *s, loff_t *pos)
3629 + struct proc_dir_entry *pde = s->private;
3630 + struct ipt_dstlimit_htable *htable = pde->data;
3631 + unsigned int *bucket;
3633 + LOCK_BH(&htable->lock);
3634 + if (*pos >= htable->cfg.size)
3637 + bucket = kmalloc(sizeof(unsigned int), GFP_KERNEL);
3639 + return ERR_PTR(-ENOMEM);
3645 +static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
3647 + struct proc_dir_entry *pde = s->private;
3648 + struct ipt_dstlimit_htable *htable = pde->data;
3649 + unsigned int *bucket = (unsigned int *)v;
3651 + *pos = ++(*bucket);
3652 + if (*pos >= htable->cfg.size) {
3659 +static void dl_seq_stop(struct seq_file *s, void *v)
3661 + struct proc_dir_entry *pde = s->private;
3662 + struct ipt_dstlimit_htable *htable = pde->data;
3663 + unsigned int *bucket = (unsigned int *)v;
3667 + UNLOCK_BH(&htable->lock);
3670 +static inline int dl_seq_real_show(struct dsthash_ent *ent, struct seq_file *s)
3672 + /* recalculate to show accurate numbers */
3673 + rateinfo_recalc(ent, jiffies);
3675 + return seq_printf(s, "%ld %u.%u.%u.%u->%u.%u.%u.%u:%u %u %u %u\n",
3676 + (ent->expires - jiffies)/HZ,
3677 + NIPQUAD(ent->dst.src_ip),
3678 + NIPQUAD(ent->dst.dst_ip), ntohs(ent->dst.port),
3679 + ent->rateinfo.credit, ent->rateinfo.credit_cap,
3680 + ent->rateinfo.cost);
3683 +static int dl_seq_show(struct seq_file *s, void *v)
3685 + struct proc_dir_entry *pde = s->private;
3686 + struct ipt_dstlimit_htable *htable = pde->data;
3687 + unsigned int *bucket = (unsigned int *)v;
3689 + if (LIST_FIND_W(&htable->hash[*bucket], dl_seq_real_show,
3690 + struct dsthash_ent *, s)) {
3691 + /* buffer was filled and unable to print that tuple */
3697 +static struct seq_operations dl_seq_ops = {
3698 + .start = dl_seq_start,
3699 + .next = dl_seq_next,
3700 + .stop = dl_seq_stop,
3701 + .show = dl_seq_show
3704 +static int dl_proc_open(struct inode *inode, struct file *file)
3706 + int ret = seq_open(file, &dl_seq_ops);
3709 + struct seq_file *sf = file->private_data;
3710 + sf->private = PDE(inode);
3715 +static struct file_operations dl_file_ops = {
3716 + .owner = THIS_MODULE,
3717 + .open = dl_proc_open,
3719 + .llseek = seq_lseek,
3720 + .release = seq_release
3723 +static int init_or_fini(int fini)
3730 + if (ipt_register_match(&ipt_dstlimit)) {
3732 + goto cleanup_nothing;
3735 + /* FIXME: do we really want HWCACHE_ALIGN since our objects are
3736 + * quite small ? */
3737 + dstlimit_cachep = kmem_cache_create("ipt_dstlimit",
3738 + sizeof(struct dsthash_ent), 0,
3739 + SLAB_HWCACHE_ALIGN, NULL, NULL);
3740 + if (!dstlimit_cachep) {
3741 + printk(KERN_ERR "Unable to create ipt_dstlimit slab cache\n");
3743 + goto cleanup_unreg_match;
3746 + dstlimit_procdir = proc_mkdir("ipt_dstlimit", proc_net);
3747 + if (!dstlimit_procdir) {
3748 + printk(KERN_ERR "Unable to create proc dir entry\n");
3750 + goto cleanup_free_slab;
3756 + remove_proc_entry("ipt_dstlimit", proc_net);
3758 + kmem_cache_destroy(dstlimit_cachep);
3759 +cleanup_unreg_match:
3760 + ipt_unregister_match(&ipt_dstlimit);
3766 +static int __init init(void)
3768 + return init_or_fini(0);
3771 +static void __exit fini(void)
3778 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_fuzzy.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_fuzzy.c
3779 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_fuzzy.c 1970-01-01 01:00:00.000000000 +0100
3780 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_fuzzy.c 2004-04-15 21:20:59.000000000 +0200
3783 + * This module implements a simple TSK FLC
3784 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
3785 + * to limit , in an adaptive and flexible way , the packet rate crossing
3786 + * a given stream . It serves as an initial and very simple (but effective)
3787 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
3788 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
3789 + * into our code in a precise , adaptive and efficient manner.
3790 + * The goal is very similar to that of "limit" match , but using techniques of
3791 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
3792 + * avoiding over and undershoots - and stuff like that .
3795 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
3796 + * 2002-08-17 : Changed to eliminate floating point operations .
3797 + * 2002-08-23 : Coding style changes .
3800 +#include <linux/module.h>
3801 +#include <linux/skbuff.h>
3802 +#include <linux/ip.h>
3803 +#include <linux/random.h>
3804 +#include <net/tcp.h>
3805 +#include <linux/spinlock.h>
3806 +#include <linux/netfilter_ipv4/ip_tables.h>
3807 +#include <linux/netfilter_ipv4/ipt_fuzzy.h>
3810 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
3811 + Expressed in percentage
3814 +#define PAR_LOW 1/100
3817 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED ;
3819 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
3820 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
3821 +MODULE_LICENSE("GPL");
3823 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
3831 + return ( (100*(tx-mini)) / (maxi-mini) );
3834 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
3842 + return ( (100*( maxi - tx )) / ( maxi - mini ) );
3846 +ipt_fuzzy_match(const struct sk_buff *pskb,
3847 + const struct net_device *in,
3848 + const struct net_device *out,
3849 + const void *matchinfo,
3853 + /* From userspace */
3855 + struct ipt_fuzzy_info *info = (struct ipt_fuzzy_info *) matchinfo;
3857 + u_int8_t random_number;
3858 + unsigned long amount;
3859 + u_int8_t howhigh, howlow;
3862 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
3864 + info->bytes_total += pskb->len;
3865 + info->packets_total++;
3867 + info->present_time = jiffies;
3869 + if (info->present_time >= info->previous_time)
3870 + amount = info->present_time - info->previous_time;
3872 + /* There was a transition : I choose to re-sample
3873 + and keep the old acceptance rate...
3877 + info->previous_time = info->present_time;
3878 + info->bytes_total = info->packets_total = 0;
3881 + if (amount > HZ/10) /* More than 100 ms elapsed ... */
3884 + info->mean_rate = (u_int32_t) ((HZ*info->packets_total) \
3887 + info->previous_time = info->present_time;
3888 + info->bytes_total = info->packets_total = 0;
3890 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
3891 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
3893 + info->acceptance_rate = (u_int8_t) \
3894 + (howhigh*PAR_LOW + PAR_HIGH*howlow);
3896 + /* In fact , the above defuzzification would require a denominator
3897 + proportional to (howhigh+howlow) but , in this particular case ,
3898 + that expression is constant .
3899 + An imediate consequence is that it isn't necessary to call
3900 + both mf_high and mf_low - but to keep things understandable ,
3905 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
3908 + if ( info->acceptance_rate < 100 )
3910 + get_random_bytes((void *)(&random_number), 1);
3912 + /* If within the acceptance , it can pass => don't match */
3913 + if (random_number <= (255 * info->acceptance_rate) / 100)
3916 + return 1; /* It can't pass ( It matches ) */
3919 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
3924 +ipt_fuzzy_checkentry(const char *tablename,
3925 + const struct ipt_ip *e,
3927 + unsigned int matchsize,
3928 + unsigned int hook_mask)
3931 + const struct ipt_fuzzy_info *info = matchinfo;
3933 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_fuzzy_info))) {
3934 + printk("ipt_fuzzy: matchsize %u != %u\n", matchsize,
3935 + IPT_ALIGN(sizeof(struct ipt_fuzzy_info)));
3939 + if ((info->minimum_rate < MINFUZZYRATE ) || (info->maximum_rate > MAXFUZZYRATE)
3940 + || (info->minimum_rate >= info->maximum_rate )) {
3941 + printk("ipt_fuzzy: BAD limits , please verify !!!\n");
3948 +static struct ipt_match ipt_fuzzy_reg = {
3950 + .match = ipt_fuzzy_match,
3951 + .checkentry = ipt_fuzzy_checkentry,
3955 +static int __init init(void)
3957 + return ipt_register_match(&ipt_fuzzy_reg);
3960 +static void __exit fini(void)
3962 + ipt_unregister_match(&ipt_fuzzy_reg);
3967 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_helper.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_helper.c
3968 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_helper.c 2004-04-15 03:35:20.000000000 +0200
3969 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_helper.c 2004-04-15 21:20:30.000000000 +0200
3971 struct ip_conntrack_expect *exp;
3972 struct ip_conntrack *ct;
3973 enum ip_conntrack_info ctinfo;
3975 + int ret = info->invert;
3977 ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
3979 DEBUGP("ipt_helper: Eek! invalid conntrack?\n");
3985 DEBUGP("ipt_helper: conntrack %p has no master\n", ct);
3992 DEBUGP("master's name = %s , info->name = %s\n",
3993 exp->expectant->helper->name, info->name);
3995 - ret = !strncmp(exp->expectant->helper->name, info->name,
3996 - strlen(exp->expectant->helper->name)) ^ info->invert;
3997 + ret ^= !strncmp(exp->expectant->helper->name, info->name,
3998 + strlen(exp->expectant->helper->name));
4000 READ_UNLOCK(&ip_conntrack_lock);
4004 static int __init init(void)
4006 - need_ip_conntrack();
4007 return ipt_register_match(&helper_match);
4010 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_ipv4options.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_ipv4options.c
4011 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_ipv4options.c 1970-01-01 01:00:00.000000000 +0100
4012 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_ipv4options.c 2004-04-15 21:21:01.000000000 +0200
4015 + This is a module which is used to match ipv4 options.
4016 + This file is distributed under the terms of the GNU General Public
4017 + License (GPL). Copies of the GPL can be obtained from:
4018 + ftp://prep.ai.mit.edu/pub/gnu/GPL
4020 + 11-mars-2001 Fabrice MARIE <fabrice@netfilter.org> : initial development.
4021 + 12-july-2001 Fabrice MARIE <fabrice@netfilter.org> : added router-alert otions matching. Fixed a bug with no-srr
4022 + 12-august-2001 Imran Patel <ipatel@crosswinds.net> : optimization of the match.
4023 + 18-november-2001 Fabrice MARIE <fabrice@netfilter.org> : added [!] 'any' option match.
4024 + 19-february-2004 Harald Welte <laforge@netfilter.org> : merge with 2.6.x
4027 +#include <linux/module.h>
4028 +#include <linux/skbuff.h>
4029 +#include <net/ip.h>
4031 +#include <linux/netfilter_ipv4/ip_tables.h>
4032 +#include <linux/netfilter_ipv4/ipt_ipv4options.h>
4034 +MODULE_LICENSE("GPL");
4035 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
4038 +match(const struct sk_buff *skb,
4039 + const struct net_device *in,
4040 + const struct net_device *out,
4041 + const void *matchinfo,
4045 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
4046 + const struct iphdr *iph = skb->nh.iph;
4047 + const struct ip_options *opt;
4049 + if (iph->ihl * 4 == sizeof(struct iphdr)) {
4050 + /* No options, so we match only the "DONTs" and the "IGNOREs" */
4052 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) ||
4053 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
4054 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
4055 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
4056 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
4057 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
4062 + if ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)
4063 + /* there are options, and we don't need to care which one */
4066 + if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
4067 + /* there are options but we don't want any ! */
4072 + opt = &(IPCB(skb)->opt);
4074 + /* source routing */
4075 + if ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) {
4076 + if (!((opt->srr) & (opt->is_strictroute)))
4079 + else if ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) {
4080 + if (!((opt->srr) & (!opt->is_strictroute)))
4083 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) {
4087 + /* record route */
4088 + if ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) {
4092 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) {
4097 + if ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) {
4101 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) {
4105 + /* router-alert option */
4106 + if ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) {
4107 + if (!opt->router_alert)
4110 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) {
4111 + if (opt->router_alert)
4120 +checkentry(const char *tablename,
4121 + const struct ipt_ip *ip,
4123 + unsigned int matchsize,
4124 + unsigned int hook_mask)
4126 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
4127 + /* Check the size */
4128 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_ipv4options_info)))
4130 + /* Now check the coherence of the data ... */
4131 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) &&
4132 + (((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) ||
4133 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) ||
4134 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) ||
4135 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) ||
4136 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)))
4137 + return 0; /* opposites */
4138 + if (((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) &&
4139 + (((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
4140 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
4141 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
4142 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
4143 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) ||
4144 + ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)))
4145 + return 0; /* opposites */
4146 + if (((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) &&
4147 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR))
4148 + return 0; /* cannot match in the same time loose and strict source routing */
4149 + if ((((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
4150 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR)) &&
4151 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR))
4152 + return 0; /* opposites */
4153 + if (((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) &&
4154 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR))
4155 + return 0; /* opposites */
4156 + if (((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) &&
4157 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
4158 + return 0; /* opposites */
4159 + if (((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) &&
4160 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
4161 + return 0; /* opposites */
4163 + /* everything looks ok. */
4167 +static struct ipt_match ipv4options_match = {
4168 + .name = "ipv4options",
4170 + .checkentry = checkentry,
4174 +static int __init init(void)
4176 + return ipt_register_match(&ipv4options_match);
4179 +static void __exit fini(void)
4181 + ipt_unregister_match(&ipv4options_match);
4186 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_mport.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_mport.c
4187 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_mport.c 1970-01-01 01:00:00.000000000 +0100
4188 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_mport.c 2004-04-15 21:21:03.000000000 +0200
4190 +/* Kernel module to match one of a list of TCP/UDP ports: ports are in
4191 + the same place so we can treat them as equal. */
4192 +#include <linux/module.h>
4193 +#include <linux/types.h>
4194 +#include <linux/udp.h>
4195 +#include <linux/skbuff.h>
4197 +#include <linux/netfilter_ipv4/ipt_mport.h>
4198 +#include <linux/netfilter_ipv4/ip_tables.h>
4200 +MODULE_LICENSE("GPL");
4203 +#define duprintf(format, args...) printk(format , ## args)
4205 +#define duprintf(format, args...)
4208 +/* Returns 1 if the port is matched by the test, 0 otherwise. */
4210 +ports_match(const struct ipt_mport *minfo, u_int16_t src, u_int16_t dst)
4214 + u_int16_t pflags = minfo->pflags;
4215 + for (i=0, m=1; i<IPT_MULTI_PORTS; i++, m<<=1) {
4219 + && minfo->ports[i] == 65535)
4222 + s = minfo->ports[i];
4225 + e = minfo->ports[++i];
4230 + if (minfo->flags & IPT_MPORT_SOURCE
4231 + && src >= s && src <= e)
4234 + if (minfo->flags & IPT_MPORT_DESTINATION
4235 + && dst >= s && dst <= e)
4243 +match(const struct sk_buff *skb,
4244 + const struct net_device *in,
4245 + const struct net_device *out,
4246 + const void *matchinfo,
4251 + const struct ipt_mport *minfo = matchinfo;
4256 + /* Must be big enough to read ports (both UDP and TCP have
4257 + them at the start). */
4258 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
4259 + /* We've been asked to examine this packet, and we
4260 + can't. Hence, no choice but to drop. */
4261 + duprintf("ipt_multiport:"
4262 + " Dropping evil offset=0 tinygram.\n");
4267 + return ports_match(minfo, ntohs(ports[0]), ntohs(ports[1]));
4270 +/* Called when user tries to insert an entry of this type. */
4272 +checkentry(const char *tablename,
4273 + const struct ipt_ip *ip,
4275 + unsigned int matchsize,
4276 + unsigned int hook_mask)
4278 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_mport)))
4281 + /* Must specify proto == TCP/UDP, no unknown flags or bad count */
4282 + return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
4283 + && !(ip->invflags & IPT_INV_PROTO)
4284 + && matchsize == IPT_ALIGN(sizeof(struct ipt_mport));
4287 +static struct ipt_match mport_match = {
4290 + .checkentry = &checkentry,
4294 +static int __init init(void)
4296 + return ipt_register_match(&mport_match);
4299 +static void __exit fini(void)
4301 + ipt_unregister_match(&mport_match);
4306 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_nth.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_nth.c
4307 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_nth.c 1970-01-01 01:00:00.000000000 +0100
4308 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_nth.c 2004-04-15 21:21:05.000000000 +0200
4311 + This is a module which is used for match support for every Nth packet
4312 + This file is distributed under the terms of the GNU General Public
4313 + License (GPL). Copies of the GPL can be obtained from:
4314 + ftp://prep.ai.mit.edu/pub/gnu/GPL
4316 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
4317 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
4318 + * added support for multiple counters
4319 + * added support for matching on individual packets
4320 + in the counter cycle
4321 + 2004-02-19 Harald Welte <laforge@netfilter.org>
4326 +#include <linux/module.h>
4327 +#include <linux/skbuff.h>
4328 +#include <linux/ip.h>
4329 +#include <net/tcp.h>
4330 +#include <linux/spinlock.h>
4331 +#include <linux/netfilter_ipv4/ip_tables.h>
4332 +#include <linux/netfilter_ipv4/ipt_nth.h>
4334 +MODULE_LICENSE("GPL");
4335 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
4338 + * State information.
4345 +static struct state states[IPT_NTH_NUM_COUNTERS];
4348 +ipt_nth_match(const struct sk_buff *pskb,
4349 + const struct net_device *in,
4350 + const struct net_device *out,
4351 + const void *matchinfo,
4355 + /* Parameters from userspace */
4356 + const struct ipt_nth_info *info = matchinfo;
4357 + unsigned counter = info->counter;
4358 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
4360 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
4364 + spin_lock(&states[counter].lock);
4366 + /* Are we matching every nth packet?*/
4367 + if (info->packet == 0xFF)
4369 + /* We're matching every nth packet and only every nth packet*/
4370 + /* Do we match or invert match? */
4371 + if (info->not == 0)
4373 + if (states[counter].number == 0)
4375 + ++states[counter].number;
4378 + if (states[counter].number >= info->every)
4379 + states[counter].number = 0; /* reset the counter */
4381 + ++states[counter].number;
4386 + if (states[counter].number == 0)
4388 + ++states[counter].number;
4391 + if (states[counter].number >= info->every)
4392 + states[counter].number = 0;
4394 + ++states[counter].number;
4400 + /* We're using the --packet, so there must be a rule for every value */
4401 + if (states[counter].number == info->packet)
4403 + /* only increment the counter when a match happens */
4404 + if (states[counter].number >= info->every)
4405 + states[counter].number = 0; /* reset the counter */
4407 + ++states[counter].number;
4416 + spin_unlock(&states[counter].lock);
4420 + spin_unlock(&states[counter].lock);
4425 +ipt_nth_checkentry(const char *tablename,
4426 + const struct ipt_ip *e,
4428 + unsigned int matchsize,
4429 + unsigned int hook_mask)
4431 + /* Parameters from userspace */
4432 + const struct ipt_nth_info *info = matchinfo;
4433 + unsigned counter = info->counter;
4434 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
4436 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
4440 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_nth_info))) {
4441 + printk("nth: matchsize %u != %u\n", matchsize,
4442 + IPT_ALIGN(sizeof(struct ipt_nth_info)));
4446 + states[counter].number = info->startat;
4451 +static struct ipt_match ipt_nth_reg = {
4453 + .match = ipt_nth_match,
4454 + .checkentry = ipt_nth_checkentry,
4458 +static int __init init(void)
4462 + memset(&states, 0, sizeof(states));
4463 + for (counter = 0; counter < IPT_NTH_NUM_COUNTERS; counter++)
4464 + spin_lock_init(&(states[counter].lock));
4466 + return ipt_register_match(&ipt_nth_reg);
4469 +static void __exit fini(void)
4471 + ipt_unregister_match(&ipt_nth_reg);
4476 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_osf.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_osf.c
4477 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_osf.c 1970-01-01 01:00:00.000000000 +0100
4478 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_osf.c 2004-04-15 21:21:06.000000000 +0200
4483 + * Copyright (c) 2003 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
4486 + * This program is free software; you can redistribute it and/or modify
4487 + * it under the terms of the GNU General Public License as published by
4488 + * the Free Software Foundation; either version 2 of the License, or
4489 + * (at your option) any later version.
4491 + * This program is distributed in the hope that it will be useful,
4492 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4493 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4494 + * GNU General Public License for more details.
4496 + * You should have received a copy of the GNU General Public License
4497 + * along with this program; if not, write to the Free Software
4498 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4502 + * OS fingerprint matching module.
4503 + * It simply compares various parameters from SYN packet with
4504 + * some hardcoded ones.
4506 + * Original table was created by Michal Zalewski <lcamtuf@coredump.cx>
4510 +#include <linux/config.h>
4511 +#include <linux/kernel.h>
4512 +#include <linux/types.h>
4513 +#include <linux/string.h>
4514 +#include <linux/smp.h>
4515 +#include <linux/module.h>
4516 +#include <linux/skbuff.h>
4517 +#include <linux/file.h>
4518 +#include <linux/ip.h>
4519 +#include <linux/proc_fs.h>
4520 +#include <linux/fs.h>
4521 +#include <linux/slab.h>
4522 +#include <linux/spinlock.h>
4523 +#include <linux/ctype.h>
4524 +#include <linux/list.h>
4525 +#include <linux/if.h>
4527 +#include <net/sock.h>
4528 +#include <net/ip.h>
4530 +#include <linux/netfilter_ipv4/ip_tables.h>
4532 +#include <linux/netfilter_ipv4/ipt_osf.h>
4537 +#define log(x...) printk(KERN_INFO "ipt_osf: " x)
4538 +#define loga(x...) printk(x)
4540 +#define log(x...) do {} while(0)
4541 +#define loga(x...) do {} while(0)
4544 +#define FMATCH_WRONG 0
4545 +#define FMATCH_OK 1
4546 +#define FMATCH_OPT_WRONG 2
4549 +#define OSFPDEL ':'
4550 +#define MAXOPTSTRLEN 128
4551 +#define OSFFLUSH "FLUSH"
4553 +static rwlock_t osf_lock = RW_LOCK_UNLOCKED;
4554 +static spinlock_t ipt_osf_netlink_lock = SPIN_LOCK_UNLOCKED;
4555 +static struct list_head finger_list;
4556 +static int match(const struct sk_buff *, const struct net_device *, const struct net_device *,
4557 + const void *, int,
4558 + const void *, u_int16_t,
4560 +static int checkentry(const char *, const struct ipt_ip *, void *,
4561 + unsigned int, unsigned int);
4563 +static unsigned long seq, ipt_osf_groups = 1;
4564 +static struct sock *nts;
4566 +static struct ipt_match osf_match =
4576 +static void ipt_osf_nlsend(struct osf_finger *f, const struct sk_buff *sk)
4578 + unsigned int size;
4579 + struct sk_buff *skb;
4580 + struct ipt_osf_nlmsg *data;
4581 + struct nlmsghdr *nlh;
4583 + size = NLMSG_SPACE(sizeof(struct ipt_osf_nlmsg));
4585 + skb = alloc_skb(size, GFP_ATOMIC);
4588 + log("skb_alloc() failed.\n");
4592 + nlh = NLMSG_PUT(skb, 0, seq++, NLMSG_DONE, size - sizeof(*nlh));
4594 + data = (struct ipt_osf_nlmsg *)NLMSG_DATA(nlh);
4596 + memcpy(&data->f, f, sizeof(struct osf_finger));
4597 + memcpy(&data->ip, sk->nh.iph, sizeof(struct iphdr));
4598 + memcpy(&data->tcp, (struct tcphdr *)((u_int32_t *)sk->nh.iph + sk->nh.iph->ihl), sizeof(struct tcphdr));
4600 + NETLINK_CB(skb).dst_groups = ipt_osf_groups;
4601 + netlink_broadcast(nts, skb, 0, ipt_osf_groups, GFP_ATOMIC);
4607 +static inline int smart_dec(const struct sk_buff *skb, unsigned long flags, unsigned char f_ttl)
4609 + struct iphdr *ip = skb->nh.iph;
4611 + if (flags & IPT_OSF_SMART)
4613 + struct in_device *in_dev = in_dev_get(skb->dev);
4617 + if (inet_ifa_match(ip->saddr, ifa))
4619 + in_dev_put(in_dev);
4620 + return (ip->ttl == f_ttl);
4623 + endfor_ifa(in_dev);
4625 + in_dev_put(in_dev);
4626 + return (ip->ttl <= f_ttl);
4629 + return (ip->ttl == f_ttl);
4633 +match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out,
4634 + const void *matchinfo, int offset,
4635 + const void *hdr, u_int16_t datalen,
4638 + struct ipt_osf_info *info = (struct ipt_osf_info *)matchinfo;
4639 + struct iphdr *ip = skb->nh.iph;
4640 + struct tcphdr *tcp;
4641 + int fmatch = FMATCH_WRONG, fcount = 0;
4642 + unsigned long totlen, optsize = 0, window;
4643 + unsigned char df, *optp = NULL, *_optp = NULL;
4644 + char check_WSS = 0;
4645 + struct list_head *ent;
4646 + struct osf_finger *f;
4651 + tcp = (struct tcphdr *)((u_int32_t *)ip + ip->ihl);
4656 + totlen = ntohs(ip->tot_len);
4657 + df = ((ntohs(ip->frag_off) & IP_DF)?1:0);
4658 + window = ntohs(tcp->window);
4660 + if (tcp->doff*4 > sizeof(struct tcphdr))
4662 + _optp = optp = (char *)(tcp+1);
4663 + optsize = tcp->doff*4 - sizeof(struct tcphdr);
4667 + /* Actually we can create hash/table of all genres and search
4668 + * only in appropriate part, but here is initial variant,
4669 + * so will use slow path.
4671 + read_lock(&osf_lock);
4672 + list_for_each(ent, &finger_list)
4674 + f = list_entry(ent, struct osf_finger, flist);
4676 + if (!(info->flags & IPT_OSF_LOG) && strcmp(info->genre, f->genre))
4680 + fmatch = FMATCH_WRONG;
4682 + if (totlen == f->ss && df == f->df &&
4683 + smart_dec(skb, info->flags, f->ttl))
4685 + unsigned long foptsize;
4687 + unsigned short mss = 0;
4691 + switch (f->wss.wc)
4693 + case 0: check_WSS = 0; break;
4694 + case 'S': check_WSS = 1; break;
4695 + case 'T': check_WSS = 2; break;
4696 + case '%': check_WSS = 3; break;
4697 + default: log("Wrong fingerprint wss.wc=%d, %s - %s\n",
4698 + f->wss.wc, f->genre, f->details);
4702 + if (check_WSS == 4)
4705 + /* Check options */
4708 + for (optnum=0; optnum<f->opt_num; ++optnum)
4709 + foptsize += f->opt[optnum].length;
4712 + if (foptsize > MAX_IPOPTLEN || optsize > MAX_IPOPTLEN || optsize != foptsize)
4717 + fmatch = FMATCH_OK;
4718 + loga("\tYEP : matching without options.\n");
4719 + if ((info->flags & IPT_OSF_LOG) &&
4720 + info->loglevel == IPT_OSF_LOGLEVEL_FIRST)
4727 + for (optnum=0; optnum<f->opt_num; ++optnum)
4729 + if (f->opt[optnum].kind == (*optp))
4731 + unsigned char len = f->opt[optnum].length;
4732 + unsigned char *optend = optp + len;
4733 + int loop_cont = 0;
4735 + fmatch = FMATCH_OK;
4741 + mss = ntohs(*(unsigned short *)(optp+2));
4756 + /* Skip kind and length fields*/
4759 + if (f->opt[optnum].wc.val != 0)
4761 + unsigned long tmp = 0;
4763 + /* Hmmm... It looks a bit ugly. :) */
4764 + memcpy(&tmp, optp,
4765 + (len > sizeof(unsigned long)?
4766 + sizeof(unsigned long):len));
4767 + /* 2 + 2: optlen(2 bytes) +
4768 + * kind(1 byte) + length(1 byte) */
4774 + if (f->opt[optnum].wc.wc == '%')
4776 + if ((tmp % f->opt[optnum].wc.val) != 0)
4777 + fmatch = FMATCH_OPT_WRONG;
4779 + else if (tmp != f->opt[optnum].wc.val)
4780 + fmatch = FMATCH_OPT_WRONG;
4787 + fmatch = FMATCH_OPT_WRONG;
4789 + if (fmatch != FMATCH_OK)
4793 + if (fmatch != FMATCH_OPT_WRONG)
4795 + fmatch = FMATCH_WRONG;
4797 + switch (check_WSS)
4800 + if (f->wss.val == 0 || window == f->wss.val)
4801 + fmatch = FMATCH_OK;
4804 +/* Lurked in OpenBSD */
4805 +#define SMART_MSS 1460
4806 + if (window == f->wss.val*mss ||
4807 + window == f->wss.val*SMART_MSS)
4808 + fmatch = FMATCH_OK;
4811 + if (window == f->wss.val*(mss+40) ||
4812 + window == f->wss.val*(SMART_MSS+40))
4813 + fmatch = FMATCH_OK;
4816 + if ((window % f->wss.val) == 0)
4817 + fmatch = FMATCH_OK;
4823 + if (fmatch == FMATCH_OK)
4826 + log("%s [%s:%s:%s] : %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u hops=%d\n",
4827 + f->genre, f->version,
4828 + f->subtype, f->details,
4829 + NIPQUAD(ip->saddr), ntohs(tcp->source),
4830 + NIPQUAD(ip->daddr), ntohs(tcp->dest),
4831 + f->ttl - ip->ttl);
4832 + if (info->flags & IPT_OSF_NETLINK)
4834 + spin_lock_bh(&ipt_osf_netlink_lock);
4835 + ipt_osf_nlsend(f, skb);
4836 + spin_unlock_bh(&ipt_osf_netlink_lock);
4838 + if ((info->flags & IPT_OSF_LOG) &&
4839 + info->loglevel == IPT_OSF_LOGLEVEL_FIRST)
4844 + if (!fcount && (info->flags & (IPT_OSF_LOG | IPT_OSF_NETLINK)))
4846 + unsigned char opt[4 * 15 - sizeof(struct tcphdr)];
4847 + unsigned int i, optsize;
4848 + struct osf_finger fg;
4850 + memset(&fg, 0, sizeof(fg));
4852 + if ((info->flags & IPT_OSF_LOG))
4853 + log("Unknown: %lu:%d:%d:%lu:", window, ip->ttl, df, totlen);
4856 + optsize = tcp->doff * 4 - sizeof(struct tcphdr);
4857 + if (skb_copy_bits(skb, ip->ihl*4 + sizeof(struct tcphdr),
4858 + opt, optsize) < 0)
4860 + if (info->flags & IPT_OSF_LOG)
4861 + loga("TRUNCATED");
4862 + if (info->flags & IPT_OSF_NETLINK)
4863 + strcpy(fg.details, "TRUNCATED");
4867 + for (i = 0; i < optsize; i++)
4869 + if (info->flags & IPT_OSF_LOG)
4870 + loga("%02X", opt[i]);
4872 + if (info->flags & IPT_OSF_NETLINK)
4873 + memcpy(fg.details, opt, MAXDETLEN);
4876 + if ((info->flags & IPT_OSF_LOG))
4877 + loga(" %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n",
4878 + NIPQUAD(ip->saddr), ntohs(tcp->source),
4879 + NIPQUAD(ip->daddr), ntohs(tcp->dest));
4881 + if (info->flags & IPT_OSF_NETLINK)
4883 + fg.wss.val = window;
4887 + strncpy(fg.genre, "Unknown", MAXGENRELEN);
4889 + spin_lock_bh(&ipt_osf_netlink_lock);
4890 + ipt_osf_nlsend(&fg, skb);
4891 + spin_unlock_bh(&ipt_osf_netlink_lock);
4895 + read_unlock(&osf_lock);
4897 + return (fmatch == FMATCH_OK)?1:0;
4901 +checkentry(const char *tablename,
4902 + const struct ipt_ip *ip,
4904 + unsigned int matchsize,
4905 + unsigned int hook_mask)
4907 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_osf_info)))
4909 + if (ip->proto != IPPROTO_TCP)
4915 +static char * osf_strchr(char *ptr, char c)
4919 + tmp = strchr(ptr, c);
4921 + while (tmp && tmp+1 && isspace(*(tmp+1)))
4927 +static struct osf_finger * finger_alloc(void)
4929 + struct osf_finger *f;
4931 + f = kmalloc(sizeof(struct osf_finger), GFP_KERNEL);
4933 + memset(f, 0, sizeof(struct osf_finger));
4938 +static void finger_free(struct osf_finger *f)
4940 + memset(f, 0, sizeof(struct osf_finger));
4945 +static void osf_parse_opt(struct osf_opt *opt, int *optnum, char *obuf, int olen)
4949 + unsigned long val;
4953 + while (ptr != NULL && i < olen)
4962 + ptr = osf_strchr(&obuf[i], OPTDEL);
4967 + i += (int)(ptr-&obuf[i]);
4974 + op = OSFOPT_SACKP;
4975 + ptr = osf_strchr(&obuf[i], OPTDEL);
4980 + i += (int)(ptr-&obuf[i]);
4988 + ptr = osf_strchr(&obuf[i], OPTDEL);
4993 + i += (int)(ptr-&obuf[i]);
5001 + ptr = osf_strchr(&obuf[i], OPTDEL);
5004 + switch (obuf[i+1])
5006 + case '%': wc = '%'; break;
5007 + case 'S': wc = 'S'; break;
5008 + case 'T': wc = 'T'; break;
5009 + default: wc = 0; break;
5015 + val = simple_strtoul(&obuf[i+2], NULL, 10);
5017 + val = simple_strtoul(&obuf[i+1], NULL, 10);
5018 + i += (int)(ptr-&obuf[i]);
5026 + ptr = osf_strchr(&obuf[i], OPTDEL);
5029 + if (obuf[i+1] == '%')
5034 + val = simple_strtoul(&obuf[i+2], NULL, 10);
5036 + val = simple_strtoul(&obuf[i+1], NULL, 10);
5037 + i += (int)(ptr-&obuf[i]);
5045 + ptr = osf_strchr(&obuf[i], OPTDEL);
5050 + i += (int)(ptr-&obuf[i]);
5057 + ptr = osf_strchr(&obuf[i], OPTDEL);
5061 + i += (int)(ptr-&obuf[i]);
5069 + opt[*optnum].kind = IANA_opts[op].kind;
5070 + opt[*optnum].length = IANA_opts[op].length;
5071 + opt[*optnum].wc.wc = wc;
5072 + opt[*optnum].wc.val = val;
5078 +static int osf_proc_read(char *buf, char **start, off_t off, int count, int *eof, void *data)
5080 + struct list_head *ent;
5081 + struct osf_finger *f = NULL;
5087 + read_lock_bh(&osf_lock);
5088 + list_for_each(ent, &finger_list)
5090 + f = list_entry(ent, struct osf_finger, flist);
5092 + log("%s [%s]", f->genre, f->details);
5094 + count += sprintf(buf+count, "%s - %s[%s] : %s",
5095 + f->genre, f->version,
5096 + f->subtype, f->details);
5101 + //count += sprintf(buf+count, " OPT: ");
5102 + for (i=0; i<f->opt_num; ++i)
5104 + //count += sprintf(buf+count, "%d.%c%lu; ",
5105 + // f->opt[i].kind, (f->opt[i].wc.wc)?f->opt[i].wc.wc:' ', f->opt[i].wc.val);
5106 + loga("%d.%c%lu; ",
5107 + f->opt[i].kind, (f->opt[i].wc.wc)?f->opt[i].wc.wc:' ', f->opt[i].wc.val);
5111 + count += sprintf(buf+count, "\n");
5113 + read_unlock_bh(&osf_lock);
5118 +static int osf_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
5122 + char obuf[MAXOPTSTRLEN];
5123 + struct osf_finger *finger;
5124 + struct list_head *ent, *n;
5126 + char *pbeg, *pend;
5128 + if (count == strlen(OSFFLUSH) && !strncmp(buffer, OSFFLUSH, strlen(OSFFLUSH)))
5131 + write_lock_bh(&osf_lock);
5132 + list_for_each_safe(ent, n, &finger_list)
5135 + finger = list_entry(ent, struct osf_finger, flist);
5136 + list_del(&finger->flist);
5137 + finger_free(finger);
5139 + write_unlock_bh(&osf_lock);
5141 + log("Flushed %d entries.\n", i);
5148 + for (i=0; i<count && buffer[i] != '\0'; ++i)
5149 + if (buffer[i] == ':')
5152 + if (cnt != 8 || i != count)
5154 + log("Wrong input line cnt=%d[8], len=%lu[%lu]\n",
5159 + memset(obuf, 0, sizeof(obuf));
5161 + finger = finger_alloc();
5164 + log("Failed to allocate new fingerprint entry.\n");
5168 + pbeg = (char *)buffer;
5169 + pend = osf_strchr(pbeg, OSFPDEL);
5173 + if (pbeg[0] == 'S')
5175 + finger->wss.wc = 'S';
5176 + if (pbeg[1] == '%')
5177 + finger->wss.val = simple_strtoul(pbeg+2, NULL, 10);
5178 + else if (pbeg[1] == '*')
5179 + finger->wss.val = 0;
5181 + finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
5183 + else if (pbeg[0] == 'T')
5185 + finger->wss.wc = 'T';
5186 + if (pbeg[1] == '%')
5187 + finger->wss.val = simple_strtoul(pbeg+2, NULL, 10);
5188 + else if (pbeg[1] == '*')
5189 + finger->wss.val = 0;
5191 + finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
5193 + else if (pbeg[0] == '%')
5195 + finger->wss.wc = '%';
5196 + finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
5198 + else if (isdigit(pbeg[0]))
5200 + finger->wss.wc = 0;
5201 + finger->wss.val = simple_strtoul(pbeg, NULL, 10);
5206 + pend = osf_strchr(pbeg, OSFPDEL);
5210 + finger->ttl = simple_strtoul(pbeg, NULL, 10);
5213 + pend = osf_strchr(pbeg, OSFPDEL);
5217 + finger->df = simple_strtoul(pbeg, NULL, 10);
5220 + pend = osf_strchr(pbeg, OSFPDEL);
5224 + finger->ss = simple_strtoul(pbeg, NULL, 10);
5228 + pend = osf_strchr(pbeg, OSFPDEL);
5232 + cnt = snprintf(obuf, sizeof(obuf), "%s", pbeg);
5236 + pend = osf_strchr(pbeg, OSFPDEL);
5240 + if (pbeg[0] == '@' || pbeg[0] == '*')
5241 + cnt = snprintf(finger->genre, sizeof(finger->genre), "%s", pbeg+1);
5243 + cnt = snprintf(finger->genre, sizeof(finger->genre), "%s", pbeg);
5247 + pend = osf_strchr(pbeg, OSFPDEL);
5251 + cnt = snprintf(finger->version, sizeof(finger->version), "%s", pbeg);
5255 + pend = osf_strchr(pbeg, OSFPDEL);
5259 + cnt = snprintf(finger->subtype, sizeof(finger->subtype), "%s", pbeg);
5263 + cnt = snprintf(finger->details,
5264 + ((count - (pbeg - buffer)+1) > MAXDETLEN)?MAXDETLEN:(count - (pbeg - buffer)+1),
5267 + log("%s - %s[%s] : %s\n",
5268 + finger->genre, finger->version,
5269 + finger->subtype, finger->details);
5271 + osf_parse_opt(finger->opt, &finger->opt_num, obuf, sizeof(obuf));
5274 + write_lock_bh(&osf_lock);
5275 + list_add_tail(&finger->flist, &finger_list);
5276 + write_unlock_bh(&osf_lock);
5281 +static int __init osf_init(void)
5284 + struct proc_dir_entry *p;
5286 + log("Startng OS fingerprint matching module.\n");
5288 + INIT_LIST_HEAD(&finger_list);
5290 + err = ipt_register_match(&osf_match);
5293 + log("Failed to register OS fingerprint matching module.\n");
5297 + p = create_proc_entry("sys/net/ipv4/osf", S_IFREG | 0644, NULL);
5300 + ipt_unregister_match(&osf_match);
5304 + p->write_proc = osf_proc_write;
5305 + p->read_proc = osf_proc_read;
5307 + nts = netlink_kernel_create(NETLINK_NFLOG, NULL);
5310 + log("netlink_kernel_create() failed\n");
5311 + remove_proc_entry("sys/net/ipv4/osf", NULL);
5312 + ipt_unregister_match(&osf_match);
5319 +static void __exit osf_fini(void)
5321 + struct list_head *ent, *n;
5322 + struct osf_finger *f;
5324 + remove_proc_entry("sys/net/ipv4/osf", NULL);
5325 + ipt_unregister_match(&osf_match);
5326 + if (nts && nts->socket)
5327 + sock_release(nts->socket);
5329 + list_for_each_safe(ent, n, &finger_list)
5331 + f = list_entry(ent, struct osf_finger, flist);
5332 + list_del(&f->flist);
5336 + log("OS fingerprint matching module finished.\n");
5339 +module_init(osf_init);
5340 +module_exit(osf_fini);
5342 +MODULE_LICENSE("GPL");
5343 +MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
5344 +MODULE_DESCRIPTION("Passive OS fingerprint matching.");
5345 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_pool.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_pool.c
5346 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_pool.c 1970-01-01 01:00:00.000000000 +0100
5347 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_pool.c 2004-04-15 21:21:08.000000000 +0200
5349 +/* Kernel module to match an IP address pool. */
5351 +#include <linux/module.h>
5352 +#include <linux/ip.h>
5353 +#include <linux/skbuff.h>
5355 +#include <linux/netfilter_ipv4/ip_tables.h>
5356 +#include <linux/netfilter_ipv4/ip_pool.h>
5357 +#include <linux/netfilter_ipv4/ipt_pool.h>
5359 +static inline int match_pool(
5364 + if (ip_pool_match(index, ntohl(addr)))
5370 + const struct sk_buff *skb,
5371 + const struct net_device *in,
5372 + const struct net_device *out,
5373 + const void *matchinfo,
5376 + u_int16_t datalen,
5379 + const struct ipt_pool_info *info = matchinfo;
5380 + const struct iphdr *iph = skb->nh.iph;
5382 + if (info->src != IP_POOL_NONE && !match_pool(info->src, iph->saddr,
5383 + info->flags&IPT_POOL_INV_SRC))
5386 + if (info->dst != IP_POOL_NONE && !match_pool(info->dst, iph->daddr,
5387 + info->flags&IPT_POOL_INV_DST))
5393 +static int checkentry(
5394 + const char *tablename,
5395 + const struct ipt_ip *ip,
5397 + unsigned int matchsize,
5398 + unsigned int hook_mask
5400 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_pool_info)))
5405 +static struct ipt_match pool_match
5406 += { { NULL, NULL }, "pool", &match, &checkentry, NULL, THIS_MODULE };
5408 +static int __init init(void)
5410 + return ipt_register_match(&pool_match);
5413 +static void __exit fini(void)
5415 + ipt_unregister_match(&pool_match);
5420 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_psd.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_psd.c
5421 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_psd.c 1970-01-01 01:00:00.000000000 +0100
5422 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_psd.c 2004-04-15 21:21:10.000000000 +0200
5425 + This is a module which is used for PSD (portscan detection)
5426 + Derived from scanlogd v2.1 written by Solar Designer <solar@false.com>
5427 + and LOG target module.
5429 + Copyright (C) 2000,2001 astaro AG
5431 + This file is distributed under the terms of the GNU General Public
5432 + License (GPL). Copies of the GPL can be obtained from:
5433 + ftp://prep.ai.mit.edu/pub/gnu/GPL
5435 + 2000-05-04 Markus Hennig <hennig@astaro.de> : initial
5436 + 2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
5437 + 2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
5438 + 2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified
5439 + 2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
5442 +#include <linux/module.h>
5443 +#include <linux/skbuff.h>
5444 +#include <linux/ip.h>
5445 +#include <net/tcp.h>
5446 +#include <linux/spinlock.h>
5447 +#include <linux/netfilter_ipv4/ip_tables.h>
5448 +#include <linux/netfilter_ipv4/ipt_psd.h>
5451 +#define DEBUGP printk
5453 +#define DEBUGP(format, args...)
5456 +MODULE_LICENSE("GPL");
5457 +MODULE_AUTHOR("Dennis Koslowski <koslowski@astaro.com>");
5459 +#define HF_DADDR_CHANGING 0x01
5460 +#define HF_SPORT_CHANGING 0x02
5461 +#define HF_TOS_CHANGING 0x04
5462 +#define HF_TTL_CHANGING 0x08
5465 + * Information we keep per each target port
5468 + u_int16_t number; /* port number */
5469 + u_int8_t proto; /* protocol number */
5470 + u_int8_t and_flags; /* tcp ANDed flags */
5471 + u_int8_t or_flags; /* tcp ORed flags */
5475 + * Information we keep per each source address.
5478 + struct host *next; /* Next entry with the same hash */
5479 + clock_t timestamp; /* Last update time */
5480 + struct in_addr src_addr; /* Source address */
5481 + struct in_addr dest_addr; /* Destination address */
5482 + unsigned short src_port; /* Source port */
5483 + int count; /* Number of ports in the list */
5484 + int weight; /* Total weight of ports in the list */
5485 + struct port ports[SCAN_MAX_COUNT - 1]; /* List of ports */
5486 + unsigned char tos; /* TOS */
5487 + unsigned char ttl; /* TTL */
5488 + unsigned char flags; /* HF_ flags bitmask */
5492 + * State information.
5496 + struct host list[LIST_SIZE]; /* List of source addresses */
5497 + struct host *hash[HASH_SIZE]; /* Hash: pointers into the list */
5498 + int index; /* Oldest entry to be replaced */
5502 + * Convert an IP address into a hash table index.
5504 +static inline int hashfunc(struct in_addr addr)
5506 + unsigned int value;
5509 + value = addr.s_addr;
5513 + } while ((value >>= HASH_LOG));
5515 + return hash & (HASH_SIZE - 1);
5519 +ipt_psd_match(const struct sk_buff *pskb,
5520 + const struct net_device *in,
5521 + const struct net_device *out,
5522 + const void *matchinfo,
5525 + u_int16_t datalen,
5528 + struct iphdr *ip_hdr;
5529 + struct tcphdr *tcp_hdr;
5530 + struct in_addr addr;
5531 + u_int16_t src_port,dest_port;
5532 + u_int8_t tcp_flags, proto;
5534 + struct host *curr, *last, **head;
5535 + int hash, index, count;
5537 + /* Parameters from userspace */
5538 + const struct ipt_psd_info *psdinfo = matchinfo;
5541 + ip_hdr = pskb->nh.iph;
5543 + /* Sanity check */
5544 + if (ntohs(ip_hdr->frag_off) & IP_OFFSET) {
5545 + DEBUGP("PSD: sanity check failed\n");
5549 + /* TCP or UDP ? */
5550 + proto = ip_hdr->protocol;
5552 + if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
5553 + DEBUGP("PSD: protocol not supported\n");
5557 + /* Get the source address, source & destination ports, and TCP flags */
5559 + addr.s_addr = ip_hdr->saddr;
5561 + tcp_hdr = (struct tcphdr*)((u_int32_t *)ip_hdr + ip_hdr->ihl);
5563 + /* Yep, it´s dirty */
5564 + src_port = tcp_hdr->source;
5565 + dest_port = tcp_hdr->dest;
5567 + if (proto == IPPROTO_TCP) {
5568 + tcp_flags = *((u_int8_t*)tcp_hdr + 13);
5574 + /* We're using IP address 0.0.0.0 for a special purpose here, so don't let
5575 + * them spoof us. [DHCP needs this feature - HW] */
5576 + if (!addr.s_addr) {
5577 + DEBUGP("PSD: spoofed source address (0.0.0.0)\n");
5581 + /* Use jiffies here not to depend on someone setting the time while we're
5582 + * running; we need to be careful with possible return value overflows. */
5585 + spin_lock(&state.lock);
5587 + /* Do we know this source address already? */
5590 + if ((curr = *(head = &state.hash[hash = hashfunc(addr)])))
5592 + if (curr->src_addr.s_addr == addr.s_addr) break;
5594 + if (curr->next) last = curr;
5595 + } while ((curr = curr->next));
5599 + /* We know this address, and the entry isn't too old. Update it. */
5600 + if (now - curr->timestamp <= (psdinfo->delay_threshold*HZ)/100 &&
5601 + time_after_eq(now, curr->timestamp)) {
5603 + /* Just update the appropriate list entry if we've seen this port already */
5604 + for (index = 0; index < curr->count; index++) {
5605 + if (curr->ports[index].number == dest_port) {
5606 + curr->ports[index].proto = proto;
5607 + curr->ports[index].and_flags &= tcp_flags;
5608 + curr->ports[index].or_flags |= tcp_flags;
5609 + goto out_no_match;
5613 + /* TCP/ACK and/or TCP/RST to a new port? This could be an outgoing connection. */
5614 + if (proto == IPPROTO_TCP && (tcp_hdr->ack || tcp_hdr->rst))
5615 + goto out_no_match;
5617 + /* Packet to a new port, and not TCP/ACK: update the timestamp */
5618 + curr->timestamp = now;
5620 + /* Logged this scan already? Then drop the packet. */
5621 + if (curr->weight >= psdinfo->weight_threshold)
5624 + /* Specify if destination address, source port, TOS or TTL are not fixed */
5625 + if (curr->dest_addr.s_addr != ip_hdr->daddr)
5626 + curr->flags |= HF_DADDR_CHANGING;
5627 + if (curr->src_port != src_port)
5628 + curr->flags |= HF_SPORT_CHANGING;
5629 + if (curr->tos != ip_hdr->tos)
5630 + curr->flags |= HF_TOS_CHANGING;
5631 + if (curr->ttl != ip_hdr->ttl)
5632 + curr->flags |= HF_TTL_CHANGING;
5634 + /* Update the total weight */
5635 + curr->weight += (ntohs(dest_port) < 1024) ?
5636 + psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
5638 + /* Got enough destination ports to decide that this is a scan? */
5639 + /* Then log it and drop the packet. */
5640 + if (curr->weight >= psdinfo->weight_threshold)
5643 + /* Remember the new port */
5644 + if (curr->count < SCAN_MAX_COUNT) {
5645 + curr->ports[curr->count].number = dest_port;
5646 + curr->ports[curr->count].proto = proto;
5647 + curr->ports[curr->count].and_flags = tcp_flags;
5648 + curr->ports[curr->count].or_flags = tcp_flags;
5652 + goto out_no_match;
5655 + /* We know this address, but the entry is outdated. Mark it unused, and
5656 + * remove from the hash table. We'll allocate a new entry instead since
5657 + * this one might get re-used too soon. */
5658 + curr->src_addr.s_addr = 0;
5660 + last->next = last->next->next;
5662 + *head = (*head)->next;
5666 + /* We don't need an ACK from a new source address */
5667 + if (proto == IPPROTO_TCP && tcp_hdr->ack)
5668 + goto out_no_match;
5670 + /* Got too many source addresses with the same hash value? Then remove the
5671 + * oldest one from the hash table, so that they can't take too much of our
5672 + * CPU time even with carefully chosen spoofed IP addresses. */
5673 + if (count >= HASH_MAX && last) last->next = NULL;
5675 + /* We're going to re-use the oldest list entry, so remove it from the hash
5676 + * table first (if it is really already in use, and isn't removed from the
5677 + * hash table already because of the HASH_MAX check above). */
5679 + /* First, find it */
5680 + if (state.list[state.index].src_addr.s_addr)
5681 + head = &state.hash[hashfunc(state.list[state.index].src_addr)];
5685 + if ((curr = *head))
5687 + if (curr == &state.list[state.index]) break;
5689 + } while ((curr = curr->next));
5691 + /* Then, remove it */
5694 + last->next = last->next->next;
5696 + *head = (*head)->next;
5699 + /* Get our list entry */
5700 + curr = &state.list[state.index++];
5701 + if (state.index >= LIST_SIZE) state.index = 0;
5703 + /* Link it into the hash table */
5704 + head = &state.hash[hash];
5705 + curr->next = *head;
5708 + /* And fill in the fields */
5709 + curr->timestamp = now;
5710 + curr->src_addr = addr;
5711 + curr->dest_addr.s_addr = ip_hdr->daddr;
5712 + curr->src_port = src_port;
5714 + curr->weight = (ntohs(dest_port) < 1024) ?
5715 + psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
5716 + curr->ports[0].number = dest_port;
5717 + curr->ports[0].proto = proto;
5718 + curr->ports[0].and_flags = tcp_flags;
5719 + curr->ports[0].or_flags = tcp_flags;
5720 + curr->tos = ip_hdr->tos;
5721 + curr->ttl = ip_hdr->ttl;
5724 + spin_unlock(&state.lock);
5728 + spin_unlock(&state.lock);
5732 +static int ipt_psd_checkentry(const char *tablename,
5733 + const struct ipt_ip *e,
5735 + unsigned int matchsize,
5736 + unsigned int hook_mask)
5738 +/* const struct ipt_psd_info *psdinfo = targinfo;*/
5740 + /* we accept TCP only */
5741 +/* if (e->ip.proto != IPPROTO_TCP) { */
5742 +/* DEBUGP("PSD: specified protocol may be TCP only\n"); */
5746 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_psd_info))) {
5747 + DEBUGP("PSD: matchsize %u != %u\n",
5749 + IPT_ALIGN(sizeof(struct ipt_psd_info)));
5756 +static struct ipt_match ipt_psd_reg = {
5760 + ipt_psd_checkentry,
5764 +static int __init init(void)
5766 + if (ipt_register_match(&ipt_psd_reg))
5769 + memset(&state, 0, sizeof(state));
5771 + spin_lock_init(&(state.lock));
5773 + printk("netfilter PSD loaded - (c) astaro AG\n");
5777 +static void __exit fini(void)
5779 + ipt_unregister_match(&ipt_psd_reg);
5780 + printk("netfilter PSD unloaded - (c) astaro AG\n");
5785 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_quota.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_quota.c
5786 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_quota.c 1970-01-01 01:00:00.000000000 +0100
5787 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_quota.c 2004-04-15 21:21:16.000000000 +0200
5790 + * netfilter module to enforce network quotas
5792 + * Sam Johnston <samj@samj.net>
5794 +#include <linux/module.h>
5795 +#include <linux/skbuff.h>
5796 +#include <linux/spinlock.h>
5797 +#include <linux/interrupt.h>
5799 +#include <linux/netfilter_ipv4/ip_tables.h>
5800 +#include <linux/netfilter_ipv4/ipt_quota.h>
5802 +MODULE_LICENSE("GPL");
5803 +MODULE_AUTHOR("Sam Johnston <samj@samj.net>");
5805 +static spinlock_t quota_lock = SPIN_LOCK_UNLOCKED;
5808 +match(const struct sk_buff *skb,
5809 + const struct net_device *in,
5810 + const struct net_device *out,
5811 + const void *matchinfo,
5812 + int offset, int *hotdrop)
5814 + struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
5815 + unsigned int datalen;
5817 + if (skb->len < sizeof(struct iphdr))
5820 + datalen = skb->len - skb->nh.iph->ihl*4;
5822 + spin_lock_bh("a_lock);
5824 + if (q->quota >= datalen) {
5825 + /* we can afford this one */
5826 + q->quota -= datalen;
5827 + spin_unlock_bh("a_lock);
5829 +#ifdef DEBUG_IPT_QUOTA
5830 + printk("IPT Quota OK: %llu datlen %d \n", q->quota, datalen);
5835 + /* so we do not allow even small packets from now on */
5838 +#ifdef DEBUG_IPT_QUOTA
5839 + printk("IPT Quota Failed: %llu datlen %d \n", q->quota, datalen);
5842 + spin_unlock_bh("a_lock);
5847 +checkentry(const char *tablename,
5848 + const struct ipt_ip *ip,
5849 + void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
5851 + /* TODO: spinlocks? sanity checks? */
5852 + if (matchsize != IPT_ALIGN(sizeof (struct ipt_quota_info)))
5858 +static struct ipt_match quota_match = {
5861 + .checkentry = checkentry,
5868 + return ipt_register_match("a_match);
5874 + ipt_unregister_match("a_match);
5880 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_random.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_random.c
5881 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_random.c 1970-01-01 01:00:00.000000000 +0100
5882 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_random.c 2004-04-15 21:21:18.000000000 +0200
5885 + This is a module which is used for a "random" match support.
5886 + This file is distributed under the terms of the GNU General Public
5887 + License (GPL). Copies of the GPL can be obtained from:
5888 + ftp://prep.ai.mit.edu/pub/gnu/GPL
5890 + 2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
5893 +#include <linux/module.h>
5894 +#include <linux/skbuff.h>
5895 +#include <linux/ip.h>
5896 +#include <linux/random.h>
5897 +#include <net/tcp.h>
5898 +#include <linux/spinlock.h>
5899 +#include <linux/netfilter_ipv4/ip_tables.h>
5900 +#include <linux/netfilter_ipv4/ipt_random.h>
5902 +MODULE_LICENSE("GPL");
5905 +ipt_rand_match(const struct sk_buff *pskb,
5906 + const struct net_device *in,
5907 + const struct net_device *out,
5908 + const void *matchinfo,
5911 + u_int16_t datalen,
5914 + /* Parameters from userspace */
5915 + const struct ipt_rand_info *info = matchinfo;
5916 + u_int8_t random_number;
5918 + /* get 1 random number from the kernel random number generation routine */
5919 + get_random_bytes((void *)(&random_number), 1);
5921 + /* Do we match ? */
5922 + if (random_number <= info->average)
5929 +ipt_rand_checkentry(const char *tablename,
5930 + const struct ipt_ip *e,
5932 + unsigned int matchsize,
5933 + unsigned int hook_mask)
5935 + /* Parameters from userspace */
5936 + const struct ipt_rand_info *info = matchinfo;
5938 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_rand_info))) {
5939 + printk("ipt_random: matchsize %u != %u\n", matchsize,
5940 + IPT_ALIGN(sizeof(struct ipt_rand_info)));
5944 + /* must be 1 <= average % <= 99 */
5945 + /* 1 x 2.55 = 2 */
5946 + /* 99 x 2.55 = 252 */
5947 + if ((info->average < 2) || (info->average > 252)) {
5948 + printk("ipt_random: invalid average %u\n", info->average);
5955 +static struct ipt_match ipt_rand_reg = {
5959 + ipt_rand_checkentry,
5963 +static int __init init(void)
5965 + if (ipt_register_match(&ipt_rand_reg))
5968 + printk("ipt_random match loaded\n");
5972 +static void __exit fini(void)
5974 + ipt_unregister_match(&ipt_rand_reg);
5975 + printk("ipt_random match unloaded\n");
5980 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_realm.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_realm.c
5981 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_realm.c 1970-01-01 01:00:00.000000000 +0100
5982 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_realm.c 2004-04-15 21:21:22.000000000 +0200
5984 +/* IP tables module for matching the routing realm
5988 + * (C) 2003 by Sampsa Ranta <sampsa@netsonic.fi>
5990 + * This program is free software; you can redistribute it and/or modify
5991 + * it under the terms of the GNU General Public License version 2 as
5992 + * published by the Free Software Foundation.
5995 +#include <linux/module.h>
5996 +#include <linux/skbuff.h>
5997 +#include <linux/netdevice.h>
5998 +#include <net/route.h>
6000 +#include <linux/netfilter_ipv4/ipt_realm.h>
6001 +#include <linux/netfilter_ipv4/ip_tables.h>
6003 +MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>");
6004 +MODULE_LICENSE("GPL");
6007 +match(const struct sk_buff *skb,
6008 + const struct net_device *in,
6009 + const struct net_device *out,
6010 + const void *matchinfo,
6014 + const struct ipt_realm_info *info = matchinfo;
6015 + struct dst_entry *dst = skb->dst;
6020 + return (info->id == (dst->tclassid & info->mask)) ^ info->invert;
6023 +static int check(const char *tablename,
6024 + const struct ipt_ip *ip,
6026 + unsigned int matchsize,
6027 + unsigned int hook_mask)
6030 + & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) |
6031 + (1 << NF_IP_LOCAL_OUT)| (1 << NF_IP_LOCAL_IN))) {
6032 + printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, "
6033 + "LOCAL_IN or FORWARD.\n");
6037 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info)))
6043 +static struct ipt_match realm_match = {
6046 + .checkentry = check,
6050 +static int __init init(void)
6052 + return ipt_register_match(&realm_match);
6055 +static void __exit fini(void)
6057 + ipt_unregister_match(&realm_match);
6062 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_sctp.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_sctp.c
6063 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_sctp.c 1970-01-01 01:00:00.000000000 +0100
6064 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_sctp.c 2004-04-15 21:21:23.000000000 +0200
6066 +#include <linux/module.h>
6067 +#include <linux/skbuff.h>
6068 +#include <net/ip.h>
6069 +#include <linux/sctp.h>
6071 +#include <linux/netfilter_ipv4/ip_tables.h>
6072 +#include <linux/netfilter_ipv4/ipt_sctp.h>
6075 +#define duprintf(format, args...) printk(format , ## args)
6077 +#define duprintf(format, args...)
6080 +#define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \
6081 + || (!!((invflag) & (option)) ^ (cond)))
6084 +match_flags(const struct ipt_sctp_flag_info *flag_info,
6085 + const int flag_count,
6086 + u_int8_t chunktype,
6087 + u_int8_t chunkflags)
6091 + for (i = 0; i < flag_count; i++) {
6092 + if (flag_info[i].chunktype == chunktype) {
6093 + return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag;
6101 +match_packet(const struct sk_buff *skb,
6102 + const u_int32_t *chunkmap,
6103 + int chunk_match_type,
6104 + const struct ipt_sctp_flag_info *flag_info,
6105 + const int flag_count,
6109 + u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
6110 + sctp_chunkhdr_t sch;
6114 + if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) {
6115 + SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap);
6118 + offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t);
6120 + if (skb_copy_bits(skb, offset, &sch, sizeof(sch)) < 0) {
6121 + duprintf("Dropping invalid SCTP packet.\n");
6126 + duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n",
6127 + ++i, offset, sch.type, htons(sch.length), sch.flags);
6129 + offset += (htons(sch.length) + 3) & ~3;
6131 + duprintf("skb->len: %d\toffset: %d\n", skb->len, offset);
6133 + if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch.type)) {
6134 + switch (chunk_match_type) {
6135 + case SCTP_CHUNK_MATCH_ANY:
6136 + if (match_flags(flag_info, flag_count,
6137 + sch.type, sch.flags)) {
6142 + case SCTP_CHUNK_MATCH_ALL:
6143 + if (match_flags(flag_info, flag_count,
6144 + sch.type, sch.flags)) {
6145 + SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch.type);
6149 + case SCTP_CHUNK_MATCH_ONLY:
6150 + if (!match_flags(flag_info, flag_count,
6151 + sch.type, sch.flags)) {
6157 + switch (chunk_match_type) {
6158 + case SCTP_CHUNK_MATCH_ONLY:
6162 + } while (offset < skb->len);
6164 + switch (chunk_match_type) {
6165 + case SCTP_CHUNK_MATCH_ALL:
6166 + return SCTP_CHUNKMAP_IS_CLEAR(chunkmap);
6167 + case SCTP_CHUNK_MATCH_ANY:
6169 + case SCTP_CHUNK_MATCH_ONLY:
6173 + /* This will never be reached, but required to stop compiler whine */
6178 +match(const struct sk_buff *skb,
6179 + const struct net_device *in,
6180 + const struct net_device *out,
6181 + const void *matchinfo,
6185 + const struct ipt_sctp_info *info;
6186 + sctp_sctphdr_t sh;
6188 + info = (const struct ipt_sctp_info *)matchinfo;
6191 + duprintf("Dropping non-first fragment.. FIXME\n");
6195 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &sh, sizeof(sh)) < 0) {
6196 + duprintf("Dropping evil TCP offset=0 tinygram.\n");
6200 + duprintf("spt: %d\tdpt: %d\n", ntohs(sh.source), ntohs(sh.dest));
6202 + return SCCHECK(((ntohs(sh.source) >= info->spts[0])
6203 + && (ntohs(sh.source) <= info->spts[1])),
6204 + IPT_SCTP_SRC_PORTS, info->flags, info->invflags)
6205 + && SCCHECK(((ntohs(sh.dest) >= info->dpts[0])
6206 + && (ntohs(sh.dest) <= info->dpts[1])),
6207 + IPT_SCTP_DEST_PORTS, info->flags, info->invflags)
6208 + && SCCHECK(match_packet(skb, info->chunkmap, info->chunk_match_type,
6209 + info->flag_info, info->flag_count,
6211 + IPT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
6215 +checkentry(const char *tablename,
6216 + const struct ipt_ip *ip,
6218 + unsigned int matchsize,
6219 + unsigned int hook_mask)
6221 + const struct ipt_sctp_info *info;
6223 + info = (const struct ipt_sctp_info *)matchinfo;
6225 + return ip->proto == IPPROTO_SCTP
6226 + && !(ip->invflags & IPT_INV_PROTO)
6227 + && matchsize == IPT_ALIGN(sizeof(struct ipt_sctp_info))
6228 + && !(info->flags & ~IPT_SCTP_VALID_FLAGS)
6229 + && !(info->invflags & ~IPT_SCTP_VALID_FLAGS)
6230 + && !(info->invflags & ~info->flags)
6231 + && ((!(info->flags & IPT_SCTP_CHUNK_TYPES)) ||
6232 + (info->chunk_match_type &
6233 + (SCTP_CHUNK_MATCH_ALL
6234 + | SCTP_CHUNK_MATCH_ANY
6235 + | SCTP_CHUNK_MATCH_ONLY)));
6238 +static struct ipt_match sctp_match =
6240 + .list = { NULL, NULL},
6243 + .checkentry = &checkentry,
6248 +static int __init init(void)
6250 + return ipt_register_match(&sctp_match);
6253 +static void __exit fini(void)
6255 + ipt_unregister_match(&sctp_match);
6261 +MODULE_LICENSE("GPL");
6262 +MODULE_AUTHOR("Kiran Kumar Immidi");
6263 +MODULE_DESCRIPTION("Match for SCTP protocol packets");
6265 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_state.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_state.c
6266 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_state.c 2004-04-15 03:36:03.000000000 +0200
6267 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_state.c 2004-04-15 21:21:20.000000000 +0200
6269 enum ip_conntrack_info ctinfo;
6270 unsigned int statebit;
6272 - if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
6273 + if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
6274 + statebit = IPT_STATE_UNTRACKED;
6275 + else if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
6276 statebit = IPT_STATE_INVALID;
6278 statebit = IPT_STATE_BIT(ctinfo);
6279 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_time.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_time.c
6280 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_time.c 1970-01-01 01:00:00.000000000 +0100
6281 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_time.c 2004-04-15 21:21:26.000000000 +0200
6284 + This is a module which is used for time matching
6285 + It is using some modified code from dietlibc (localtime() function)
6286 + that you can find at http://www.fefe.de/dietlibc/
6287 + This file is distributed under the terms of the GNU General Public
6288 + License (GPL). Copies of the GPL can be obtained from: ftp://prep.ai.mit.edu/pub/gnu/GPL
6289 + 2001-05-04 Fabrice MARIE <fabrice@netfilter.org> : initial development.
6290 + 2001-21-05 Fabrice MARIE <fabrice@netfilter.org> : bug fix in the match code,
6291 + thanks to "Zeng Yu" <zengy@capitel.com.cn> for bug report.
6292 + 2001-26-09 Fabrice MARIE <fabrice@netfilter.org> : force the match to be in LOCAL_IN or PRE_ROUTING only.
6293 + 2001-30-11 Fabrice : added the possibility to use the match in FORWARD/OUTPUT with a little hack,
6294 + added Nguyen Dang Phuoc Dong <dongnd@tlnet.com.vn> patch to support timezones.
6297 +#include <linux/module.h>
6298 +#include <linux/skbuff.h>
6299 +#include <linux/netfilter_ipv4/ip_tables.h>
6300 +#include <linux/netfilter_ipv4/ipt_time.h>
6301 +#include <linux/time.h>
6303 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
6304 +MODULE_DESCRIPTION("Match arrival timestamp");
6305 +MODULE_LICENSE("GPL");
6309 + int tm_sec; /* Seconds. [0-60] (1 leap second) */
6310 + int tm_min; /* Minutes. [0-59] */
6311 + int tm_hour; /* Hours. [0-23] */
6312 + int tm_mday; /* Day. [1-31] */
6313 + int tm_mon; /* Month. [0-11] */
6314 + int tm_year; /* Year - 1900. */
6315 + int tm_wday; /* Day of week. [0-6] */
6316 + int tm_yday; /* Days in year.[0-365] */
6317 + int tm_isdst; /* DST. [-1/0/1]*/
6319 + long int tm_gmtoff; /* we don't care, we count from GMT */
6320 + const char *tm_zone; /* we don't care, we count from GMT */
6324 +localtime(const time_t *timepr, struct tm *r);
6327 +match(const struct sk_buff *skb,
6328 + const struct net_device *in,
6329 + const struct net_device *out,
6330 + const void *matchinfo,
6333 + u_int16_t datalen,
6336 + const struct ipt_time_info *info = matchinfo; /* match info for rule */
6337 + struct tm currenttime; /* time human readable */
6338 + u_int8_t days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
6339 + u_int16_t packet_time;
6340 + struct timeval kerneltimeval;
6341 + time_t packet_local_time;
6343 + /* if kerneltime=1, we don't read the skb->timestamp but kernel time instead */
6344 + if (info->kerneltime)
6346 + do_gettimeofday(&kerneltimeval);
6347 + packet_local_time = kerneltimeval.tv_sec;
6350 + packet_local_time = skb->stamp.tv_sec;
6352 + /* Transform the timestamp of the packet, in a human readable form */
6353 + localtime(&packet_local_time, ¤ttime);
6355 + /* check if we match this timestamp, we start by the days... */
6356 + if ((days_of_week[currenttime.tm_wday] & info->days_match) != days_of_week[currenttime.tm_wday])
6357 + return 0; /* the day doesn't match */
6359 + /* ... check the time now */
6360 + packet_time = (currenttime.tm_hour * 60) + currenttime.tm_min;
6361 + if ((packet_time < info->time_start) || (packet_time > info->time_stop))
6364 + /* here we match ! */
6369 +checkentry(const char *tablename,
6370 + const struct ipt_ip *ip,
6372 + unsigned int matchsize,
6373 + unsigned int hook_mask)
6375 + struct ipt_time_info *info = matchinfo; /* match info for rule */
6377 + /* First, check that we are in the correct hook */
6378 + /* PRE_ROUTING, LOCAL_IN or FROWARD */
6380 + & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
6382 + printk("ipt_time: error, only valid for PRE_ROUTING, LOCAL_IN, FORWARD and OUTPUT)\n");
6385 + /* we use the kerneltime if we are in forward or output */
6386 + info->kerneltime = 1;
6387 + if (hook_mask & ~((1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
6388 + /* if not, we use the skb time */
6389 + info->kerneltime = 0;
6391 + /* Check the size */
6392 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_time_info)))
6394 + /* Now check the coherence of the data ... */
6395 + if ((info->time_start > 1439) || /* 23*60+59 = 1439*/
6396 + (info->time_stop > 1439))
6398 + printk(KERN_WARNING "ipt_time: invalid argument\n");
6405 +static struct ipt_match time_match
6406 += { { NULL, NULL }, "time", &match, &checkentry, NULL, THIS_MODULE };
6408 +static int __init init(void)
6410 + printk("ipt_time loading\n");
6411 + return ipt_register_match(&time_match);
6414 +static void __exit fini(void)
6416 + ipt_unregister_match(&time_match);
6417 + printk("ipt_time unloaded\n");
6424 +/* The part below is borowed and modified from dietlibc */
6426 +/* seconds per day */
6427 +#define SPD 24*60*60
6430 +localtime(const time_t *timepr, struct tm *r) {
6433 + extern struct timezone sys_tz;
6434 + const unsigned int __spm[12] =
6441 + (31+28+31+30+31+30),
6442 + (31+28+31+30+31+30+31),
6443 + (31+28+31+30+31+30+31+31),
6444 + (31+28+31+30+31+30+31+31+30),
6445 + (31+28+31+30+31+30+31+31+30+31),
6446 + (31+28+31+30+31+30+31+31+30+31+30),
6448 + register time_t work;
6450 + timep = (*timepr) - (sys_tz.tz_minuteswest * 60);
6452 + r->tm_sec=work%60; work/=60;
6453 + r->tm_min=work%60; r->tm_hour=work/60;
6455 + r->tm_wday=(4+work)%7;
6456 + for (i=1970; ; ++i) {
6457 + register time_t k= (!(i%4) && ((i%100) || !(i%400)))?366:365;
6463 + r->tm_year=i-1900;
6464 + for (i=11; i && __spm[i]>work; --i) ;
6466 + r->tm_mday=work-__spm[i]+1;
6468 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_u32.c linux-2.6.6-rc1/net/ipv4/netfilter/ipt_u32.c
6469 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/ipt_u32.c 1970-01-01 01:00:00.000000000 +0100
6470 +++ linux-2.6.6-rc1/net/ipv4/netfilter/ipt_u32.c 2004-04-15 21:21:29.000000000 +0200
6472 +/* Kernel module to match u32 packet content. */
6475 +U32 tests whether quantities of up to 4 bytes extracted from a packet
6476 +have specified values. The specification of what to extract is general
6477 +enough to find data at given offsets from tcp headers or payloads.
6480 + The argument amounts to a program in a small language described below.
6481 + tests := location = value | tests && location = value
6482 + value := range | value , range
6483 + range := number | number : number
6484 + a single number, n, is interpreted the same as n:n
6485 + n:m is interpreted as the range of numbers >=n and <=m
6486 + location := number | location operator number
6487 + operator := & | << | >> | @
6489 + The operators &, <<, >>, && mean the same as in c. The = is really a set
6490 + membership operator and the value syntax describes a set. The @ operator
6491 + is what allows moving to the next header and is described further below.
6493 + *** Until I can find out how to avoid it, there are some artificial limits
6494 + on the size of the tests:
6495 + - no more than 10 ='s (and 9 &&'s) in the u32 argument
6496 + - no more than 10 ranges (and 9 commas) per value
6497 + - no more than 10 numbers (and 9 operators) per location
6499 + To describe the meaning of location, imagine the following machine that
6500 + interprets it. There are three registers:
6501 + A is of type char*, initially the address of the IP header
6502 + B and C are unsigned 32 bit integers, initially zero
6504 + The instructions are:
6505 + number B = number;
6506 + C = (*(A+B)<<24)+(*(A+B+1)<<16)+(*(A+B+2)<<8)+*(A+B+3)
6507 + &number C = C&number
6508 + <<number C = C<<number
6509 + >>number C = C>>number
6510 + @number A = A+C; then do the instruction number
6511 + Any access of memory outside [skb->head,skb->end] causes the match to fail.
6512 + Otherwise the result of the computation is the final value of C.
6514 + Whitespace is allowed but not required in the tests.
6515 + However the characters that do occur there are likely to require
6516 + shell quoting, so it's a good idea to enclose the arguments in quotes.
6519 + match IP packets with total length >= 256
6520 + The IP header contains a total length field in bytes 2-3.
6521 + --u32 "0&0xFFFF=0x100:0xFFFF"
6523 + AND that with FFFF (giving bytes 2-3),
6524 + and test whether that's in the range [0x100:0xFFFF]
6526 +Example: (more realistic, hence more complicated)
6527 + match icmp packets with icmp type 0
6528 + First test that it's an icmp packet, true iff byte 9 (protocol) = 1
6529 + --u32 "6&0xFF=1 && ...
6530 + read bytes 6-9, use & to throw away bytes 6-8 and compare the result to 1
6531 + Next test that it's not a fragment.
6532 + (If so it might be part of such a packet but we can't always tell.)
6533 + n.b. This test is generally needed if you want to match anything
6534 + beyond the IP header.
6535 + The last 6 bits of byte 6 and all of byte 7 are 0 iff this is a complete
6536 + packet (not a fragment). Alternatively, you can allow first fragments
6537 + by only testing the last 5 bits of byte 6.
6538 + ... 4&0x3FFF=0 && ...
6539 + Last test: the first byte past the IP header (the type) is 0
6540 + This is where we have to use the @syntax. The length of the IP header
6541 + (IHL) in 32 bit words is stored in the right half of byte 0 of the
6543 + ... 0>>22&0x3C@0>>24=0"
6544 + The first 0 means read bytes 0-3,
6545 + >>22 means shift that 22 bits to the right. Shifting 24 bits would give
6546 + the first byte, so only 22 bits is four times that plus a few more bits.
6547 + &3C then eliminates the two extra bits on the right and the first four
6548 + bits of the first byte.
6549 + For instance, if IHL=5 then the IP header is 20 (4 x 5) bytes long.
6550 + In this case bytes 0-1 are (in binary) xxxx0101 yyzzzzzz,
6551 + >>22 gives the 10 bit value xxxx0101yy and &3C gives 010100.
6552 + @ means to use this number as a new offset into the packet, and read
6553 + four bytes starting from there. This is the first 4 bytes of the icmp
6554 + payload, of which byte 0 is the icmp type. Therefore we simply shift
6555 + the value 24 to the right to throw out all but the first byte and compare
6556 + the result with 0.
6559 + tcp payload bytes 8-12 is any of 1, 2, 5 or 8
6560 + First we test that the packet is a tcp packet (similar to icmp).
6561 + --u32 "6&0xFF=6 && ...
6562 + Next, test that it's not a fragment (same as above).
6563 + ... 0>>22&0x3C@12>>26&0x3C@8=1,2,5,8"
6564 + 0>>22&3C as above computes the number of bytes in the IP header.
6565 + @ makes this the new offset into the packet, which is the start of the
6566 + tcp header. The length of the tcp header (again in 32 bit words) is
6567 + the left half of byte 12 of the tcp header. The 12>>26&3C
6568 + computes this length in bytes (similar to the IP header before).
6569 + @ makes this the new offset, which is the start of the tcp payload.
6570 + Finally 8 reads bytes 8-12 of the payload and = checks whether the
6571 + result is any of 1, 2, 5 or 8
6574 +#include <linux/module.h>
6575 +#include <linux/skbuff.h>
6577 +#include <linux/netfilter_ipv4/ipt_u32.h>
6578 +#include <linux/netfilter_ipv4/ip_tables.h>
6580 +/* #include <asm-i386/timex.h> for timing */
6582 +MODULE_AUTHOR("Don Cohen <don@isis.cs3-inc.com>");
6583 +MODULE_DESCRIPTION("IP tables u32 matching module");
6584 +MODULE_LICENSE("GPL");
6587 +match(const struct sk_buff *skb,
6588 + const struct net_device *in,
6589 + const struct net_device *out,
6590 + const void *matchinfo,
6593 + u_int16_t datalen,
6596 + const struct ipt_u32 *data = matchinfo;
6598 + unsigned char* origbase = (char*)skb->nh.iph;
6599 + unsigned char* base = origbase;
6600 + unsigned char* head = skb->head;
6601 + unsigned char* end = skb->end;
6603 + u_int32_t pos, val;
6604 + /* unsigned long long cycles1, cycles2, cycles3, cycles4;
6605 + cycles1 = get_cycles(); */
6607 + for (testind=0; testind < data->ntests; testind++) {
6608 + base = origbase; /* reset for each test */
6609 + pos = data->tests[testind].location[0].number;
6610 + if (base+pos+3 > end || base+pos < head)
6612 + val = (base[pos]<<24) + (base[pos+1]<<16) +
6613 + (base[pos+2]<<8) + base[pos+3];
6614 + nnums = data->tests[testind].nnums;
6615 + for (i=1; i < nnums; i++) {
6616 + u_int32_t number = data->tests[testind].location[i].number;
6617 + switch (data->tests[testind].location[i].nextop) {
6619 + val = val & number;
6621 + case IPT_U32_LEFTSH:
6622 + val = val << number;
6624 + case IPT_U32_RIGHTSH:
6625 + val = val >> number;
6628 + base = base + val;
6630 + if (base+pos+3 > end || base+pos < head)
6632 + val = (base[pos]<<24) + (base[pos+1]<<16) +
6633 + (base[pos+2]<<8) + base[pos+3];
6637 + nvals = data->tests[testind].nvalues;
6638 + for (i=0; i < nvals; i++) {
6639 + if ((data->tests[testind].value[i].min <= val) &&
6640 + (val <= data->tests[testind].value[i].max)) {
6644 + if (i >= data->tests[testind].nvalues) {
6645 + /* cycles2 = get_cycles();
6646 + printk("failed %d in %d cycles\n", testind,
6647 + cycles2-cycles1); */
6651 + /* cycles2 = get_cycles();
6652 + printk("succeeded in %d cycles\n", cycles2-cycles1); */
6657 +checkentry(const char *tablename,
6658 + const struct ipt_ip *ip,
6660 + unsigned int matchsize,
6661 + unsigned int hook_mask)
6663 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_u32)))
6668 +static struct ipt_match u32_match
6669 += { { NULL, NULL }, "u32", &match, &checkentry, NULL, THIS_MODULE };
6671 +static int __init init(void)
6673 + return ipt_register_match(&u32_match);
6676 +static void __exit fini(void)
6678 + ipt_unregister_match(&u32_match);
6683 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv4/netfilter/iptable_raw.c linux-2.6.6-rc1/net/ipv4/netfilter/iptable_raw.c
6684 --- linux-2.6.6-rc1.org/net/ipv4/netfilter/iptable_raw.c 1970-01-01 01:00:00.000000000 +0100
6685 +++ linux-2.6.6-rc1/net/ipv4/netfilter/iptable_raw.c 2004-04-15 21:21:20.000000000 +0200
6688 + * 'raw' table, which is the very first hooked in at PRE_ROUTING and LOCAL_OUT .
6690 + * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
6692 +#include <linux/module.h>
6693 +#include <linux/netfilter_ipv4/ip_tables.h>
6695 +#define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
6697 +/* Standard entry. */
6698 +struct ipt_standard
6700 + struct ipt_entry entry;
6701 + struct ipt_standard_target target;
6704 +struct ipt_error_target
6706 + struct ipt_entry_target target;
6707 + char errorname[IPT_FUNCTION_MAXNAMELEN];
6712 + struct ipt_entry entry;
6713 + struct ipt_error_target target;
6718 + struct ipt_replace repl;
6719 + struct ipt_standard entries[2];
6720 + struct ipt_error term;
6721 +} initial_table __initdata
6722 += { { "raw", RAW_VALID_HOOKS, 3,
6723 + sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
6724 + { [NF_IP_PRE_ROUTING] 0,
6725 + [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
6726 + { [NF_IP_PRE_ROUTING] 0,
6727 + [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
6731 + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
6733 + sizeof(struct ipt_entry),
6734 + sizeof(struct ipt_standard),
6735 + 0, { 0, 0 }, { } },
6736 + { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
6737 + -NF_ACCEPT - 1 } },
6739 + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
6741 + sizeof(struct ipt_entry),
6742 + sizeof(struct ipt_standard),
6743 + 0, { 0, 0 }, { } },
6744 + { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
6745 + -NF_ACCEPT - 1 } }
6748 + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
6750 + sizeof(struct ipt_entry),
6751 + sizeof(struct ipt_error),
6752 + 0, { 0, 0 }, { } },
6753 + { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } },
6760 +static struct ipt_table packet_raw = {
6762 + .table = &initial_table.repl,
6763 + .valid_hooks = RAW_VALID_HOOKS,
6764 + .lock = RW_LOCK_UNLOCKED,
6768 +/* The work comes in here from netfilter.c. */
6769 +static unsigned int
6770 +ipt_hook(unsigned int hook,
6771 + struct sk_buff **pskb,
6772 + const struct net_device *in,
6773 + const struct net_device *out,
6774 + int (*okfn)(struct sk_buff *))
6776 + return ipt_do_table(pskb, hook, in, out, &packet_raw, NULL);
6779 +/* 'raw' is the very first table. */
6780 +static struct nf_hook_ops ipt_ops[] = {
6784 + .hooknum = NF_IP_PRE_ROUTING,
6785 + .priority = NF_IP_PRI_RAW
6790 + .hooknum = NF_IP_LOCAL_OUT,
6791 + .priority = NF_IP_PRI_RAW
6795 +static int __init init(void)
6799 + /* Register table */
6800 + ret = ipt_register_table(&packet_raw);
6804 + /* Register hooks */
6805 + ret = nf_register_hook(&ipt_ops[0]);
6807 + goto cleanup_table;
6809 + ret = nf_register_hook(&ipt_ops[1]);
6811 + goto cleanup_hook0;
6816 + nf_unregister_hook(&ipt_ops[0]);
6818 + ipt_unregister_table(&packet_raw);
6823 +static void __exit fini(void)
6827 + for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++)
6828 + nf_unregister_hook(&ipt_ops[i]);
6830 + ipt_unregister_table(&packet_raw);
6835 +MODULE_LICENSE("GPL");
6836 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv6/ip6_tunnel.c linux-2.6.6-rc1/net/ipv6/ip6_tunnel.c
6837 --- linux-2.6.6-rc1.org/net/ipv6/ip6_tunnel.c 2004-04-15 03:33:53.000000000 +0200
6838 +++ linux-2.6.6-rc1/net/ipv6/ip6_tunnel.c 2004-04-15 21:20:34.000000000 +0200
6839 @@ -715,13 +715,7 @@
6840 ipv6h->nexthdr = proto;
6841 ipv6_addr_copy(&ipv6h->saddr, &fl.fl6_src);
6842 ipv6_addr_copy(&ipv6h->daddr, &fl.fl6_dst);
6843 -#ifdef CONFIG_NETFILTER
6844 - nf_conntrack_put(skb->nfct);
6846 -#ifdef CONFIG_NETFILTER_DEBUG
6847 - skb->nf_debug = 0;
6852 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL,
6853 skb->dst->dev, dst_output);
6854 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv6/netfilter/Kconfig linux-2.6.6-rc1/net/ipv6/netfilter/Kconfig
6855 --- linux-2.6.6-rc1.org/net/ipv6/netfilter/Kconfig 2004-04-15 03:35:37.000000000 +0200
6856 +++ linux-2.6.6-rc1/net/ipv6/netfilter/Kconfig 2004-04-15 21:21:20.000000000 +0200
6857 @@ -218,5 +218,42 @@
6858 To compile it as a module, choose M here. If unsure, say N.
6860 #dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES
6861 +config IP6_NF_TARGET_HL
6862 + tristate 'HL target support'
6863 + depends on IP6_NF_MANGLE
6866 +config IP6_NF_TARGET_REJECT
6867 + tristate 'REJECT target support'
6868 + depends on IP6_NF_FILTER
6871 +config IP6_NF_MATCH_FUZZY
6872 + tristate 'Fuzzy match support'
6873 + depends on IP6_NF_FILTER
6876 +config IP6_NF_MATCH_NTH
6877 + tristate 'Nth match support'
6878 + depends on IP6_NF_IPTABLES
6881 +config IP6_NF_MATCH_RANDOM
6882 + tristate 'Random match support'
6883 + depends on IP6_NF_IPTABLES
6887 + tristate 'raw table support (required for TRACE)'
6888 + depends on IP6_NF_IPTABLES
6890 + This option adds a `raw' table to ip6tables. This table is the very
6891 + first in the netfilter framework and hooks in at the PREROUTING
6892 + and OUTPUT chains.
6894 + If you want to compile it as a module, say M here and read
6895 + <file:Documentation/modules.txt>. If unsure, say `N'.
6900 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv6/netfilter/Makefile linux-2.6.6-rc1/net/ipv6/netfilter/Makefile
6901 --- linux-2.6.6-rc1.org/net/ipv6/netfilter/Makefile 2004-04-15 03:35:04.000000000 +0200
6902 +++ linux-2.6.6-rc1/net/ipv6/netfilter/Makefile 2004-04-15 21:21:20.000000000 +0200
6904 obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o
6905 obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
6906 obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o
6907 +obj-$(CONFIG_IP6_NF_MATCH_FUZZY) += ip6t_fuzzy.o
6908 obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
6909 obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
6910 obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
6912 obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
6913 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
6914 obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
6915 +obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
6916 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
6917 obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
6918 +obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
6920 +obj-$(CONFIG_IP6_NF_MATCH_RANDOM) += ip6t_random.o
6922 +obj-$(CONFIG_IP6_NF_MATCH_NTH) += ip6t_nth.o
6923 +obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
6924 obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
6925 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv6/netfilter/ip6t_HL.c linux-2.6.6-rc1/net/ipv6/netfilter/ip6t_HL.c
6926 --- linux-2.6.6-rc1.org/net/ipv6/netfilter/ip6t_HL.c 1970-01-01 01:00:00.000000000 +0100
6927 +++ linux-2.6.6-rc1/net/ipv6/netfilter/ip6t_HL.c 2004-04-15 21:20:38.000000000 +0200
6930 + * Hop Limit modification target for ip6tables
6931 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
6932 + * Based on HW's TTL module
6934 + * This software is distributed under the terms of GNU GPL
6937 +#include <linux/module.h>
6938 +#include <linux/skbuff.h>
6939 +#include <linux/ip.h>
6941 +#include <linux/netfilter_ipv6/ip6_tables.h>
6942 +#include <linux/netfilter_ipv6/ip6t_HL.h>
6944 +MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
6945 +MODULE_DESCRIPTION("IP tables Hop Limit modification module");
6946 +MODULE_LICENSE("GPL");
6948 +static unsigned int ip6t_hl_target(struct sk_buff **pskb, unsigned int hooknum,
6949 + const struct net_device *in, const struct net_device *out,
6950 + const void *targinfo, void *userinfo)
6952 + struct ipv6hdr *ip6h = (*pskb)->nh.ipv6h;
6953 + const struct ip6t_HL_info *info = targinfo;
6954 + u_int16_t diffs[2];
6957 + switch (info->mode) {
6959 + new_hl = info->hop_limit;
6962 + new_hl = ip6h->hop_limit + info->hop_limit;
6967 + new_hl = ip6h->hop_limit + info->hop_limit;
6972 + new_hl = ip6h->hop_limit;
6976 + if (new_hl != ip6h->hop_limit) {
6977 + diffs[0] = htons(((unsigned)ip6h->hop_limit) << 8) ^ 0xFFFF;
6978 + ip6h->hop_limit = new_hl;
6979 + diffs[1] = htons(((unsigned)ip6h->hop_limit) << 8);
6982 + return IP6T_CONTINUE;
6985 +static int ip6t_hl_checkentry(const char *tablename,
6986 + const struct ip6t_entry *e,
6988 + unsigned int targinfosize,
6989 + unsigned int hook_mask)
6991 + struct ip6t_HL_info *info = targinfo;
6993 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_HL_info))) {
6994 + printk(KERN_WARNING "HL: targinfosize %u != %Zu\n",
6996 + IP6T_ALIGN(sizeof(struct ip6t_HL_info)));
7000 + if (strcmp(tablename, "mangle")) {
7001 + printk(KERN_WARNING "HL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
7005 + if (info->mode > IP6T_HL_MAXMODE) {
7006 + printk(KERN_WARNING "HL: invalid or unknown Mode %u\n",
7011 + if ((info->mode != IP6T_HL_SET) && (info->hop_limit == 0)) {
7012 + printk(KERN_WARNING "HL: increment/decrement doesn't make sense with value 0\n");
7019 +static struct ip6t_target ip6t_HL = { { NULL, NULL }, "HL",
7020 + ip6t_hl_target, ip6t_hl_checkentry, NULL, THIS_MODULE };
7022 +static int __init init(void)
7024 + return ip6t_register_target(&ip6t_HL);
7027 +static void __exit fini(void)
7029 + ip6t_unregister_target(&ip6t_HL);
7034 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv6/netfilter/ip6t_LOG.c linux-2.6.6-rc1/net/ipv6/netfilter/ip6t_LOG.c
7035 --- linux-2.6.6-rc1.org/net/ipv6/netfilter/ip6t_LOG.c 2004-04-15 03:34:34.000000000 +0200
7036 +++ linux-2.6.6-rc1/net/ipv6/netfilter/ip6t_LOG.c 2004-04-15 21:20:33.000000000 +0200
7038 #include <net/udp.h>
7039 #include <net/tcp.h>
7040 #include <net/ipv6.h>
7041 +#include <linux/netfilter.h>
7042 #include <linux/netfilter_ipv6/ip6_tables.h>
7044 MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
7045 MODULE_DESCRIPTION("IP6 tables LOG target module");
7046 MODULE_LICENSE("GPL");
7048 +static unsigned int nflog = 1;
7049 +MODULE_PARM(nflog, "i");
7050 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
7053 #include <net/route.h>
7054 #include <linux/netfilter_ipv6/ip6t_LOG.h>
7055 @@ -265,40 +270,38 @@
7059 -static unsigned int
7060 -ip6t_log_target(struct sk_buff **pskb,
7061 - unsigned int hooknum,
7063 +ip6t_log_packet(unsigned int hooknum,
7064 + const struct sk_buff *skb,
7065 const struct net_device *in,
7066 const struct net_device *out,
7067 - const void *targinfo,
7069 + const struct ip6t_log_info *loginfo,
7070 + const char *level_string,
7071 + const char *prefix)
7073 - struct ipv6hdr *ipv6h = (*pskb)->nh.ipv6h;
7074 - const struct ip6t_log_info *loginfo = targinfo;
7075 - char level_string[4] = "< >";
7076 + struct ipv6hdr *ipv6h = skb->nh.ipv6h;
7078 - level_string[1] = '0' + (loginfo->level % 8);
7079 spin_lock_bh(&log_lock);
7080 printk(level_string);
7081 printk("%sIN=%s OUT=%s ",
7083 + prefix == NULL ? loginfo->prefix : prefix,
7085 out ? out->name : "");
7087 /* MAC logging for input chain only. */
7089 - if ((*pskb)->dev && (*pskb)->dev->hard_header_len && (*pskb)->mac.raw != (void*)ipv6h) {
7090 - if ((*pskb)->dev->type != ARPHRD_SIT){
7091 + if (skb->dev && skb->dev->hard_header_len && skb->mac.raw != (void*)ipv6h) {
7092 + if (skb->dev->type != ARPHRD_SIT){
7094 - unsigned char *p = (*pskb)->mac.raw;
7095 - for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++)
7096 + unsigned char *p = skb->mac.raw;
7097 + for (i = 0; i < skb->dev->hard_header_len; i++,p++)
7098 printk("%02x%c", *p,
7099 - i==(*pskb)->dev->hard_header_len - 1
7100 + i==skb->dev->hard_header_len - 1
7104 - unsigned char *p = (*pskb)->mac.raw;
7105 - if ( p - (ETH_ALEN*2+2) > (*pskb)->head ){
7106 + unsigned char *p = skb->mac.raw;
7107 + if ( p - (ETH_ALEN*2+2) > skb->head ){
7109 for (i = 0; i < (ETH_ALEN); i++,p++)
7110 printk("%02x%s", *p,
7111 @@ -309,10 +312,10 @@
7112 i == ETH_ALEN-1 ? ' ' : ':');
7115 - if (((*pskb)->dev->addr_len == 4) &&
7116 - (*pskb)->dev->hard_header_len > 20){
7117 + if ((skb->dev->addr_len == 4) &&
7118 + skb->dev->hard_header_len > 20){
7120 - p = (*pskb)->mac.raw + 12;
7121 + p = skb->mac.raw + 12;
7122 for (i = 0; i < 4; i++,p++)
7124 i == 3 ? "->" : ".");
7125 @@ -328,10 +331,41 @@
7126 dump_packet(loginfo, ipv6h, 1);
7128 spin_unlock_bh(&log_lock);
7131 +static unsigned int
7132 +ip6t_log_target(struct sk_buff **pskb,
7133 + unsigned int hooknum,
7134 + const struct net_device *in,
7135 + const struct net_device *out,
7136 + const void *targinfo,
7139 + const struct ip6t_log_info *loginfo = targinfo;
7140 + char level_string[4] = "< >";
7142 + level_string[1] = '0' + (loginfo->level % 8);
7143 + ip6t_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL);
7145 return IP6T_CONTINUE;
7149 +ip6t_logfn(unsigned int hooknum,
7150 + const struct sk_buff *skb,
7151 + const struct net_device *in,
7152 + const struct net_device *out,
7153 + const char *prefix)
7155 + struct ip6t_log_info loginfo = {
7157 + .logflags = IP6T_LOG_MASK,
7161 + ip6t_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
7164 static int ip6t_log_checkentry(const char *tablename,
7165 const struct ip6t_entry *e,
7167 @@ -360,20 +394,27 @@
7171 -static struct ip6t_target ip6t_log_reg
7172 -= { { NULL, NULL }, "LOG", ip6t_log_target, ip6t_log_checkentry, NULL,
7174 +static struct ip6t_target ip6t_log_reg = {
7176 + .target = ip6t_log_target,
7177 + .checkentry = ip6t_log_checkentry,
7178 + .me = THIS_MODULE,
7181 static int __init init(void)
7183 if (ip6t_register_target(&ip6t_log_reg))
7186 + nf_log_register(PF_INET6, &ip6t_logfn);
7191 static void __exit fini(void)
7194 + nf_log_unregister(PF_INET6, &ip6t_logfn);
7195 ip6t_unregister_target(&ip6t_log_reg);
7198 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv6/netfilter/ip6t_REJECT.c linux-2.6.6-rc1/net/ipv6/netfilter/ip6t_REJECT.c
7199 --- linux-2.6.6-rc1.org/net/ipv6/netfilter/ip6t_REJECT.c 1970-01-01 01:00:00.000000000 +0100
7200 +++ linux-2.6.6-rc1/net/ipv6/netfilter/ip6t_REJECT.c 2004-04-15 21:20:47.000000000 +0200
7203 + * IP6 tables REJECT target module
7204 + * Linux INET6 implementation
7206 + * Copyright (C)2003 USAGI/WIDE Project
7209 + * Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
7211 + * Based on net/ipv4/netfilter/ipt_REJECT.c
7213 + * This program is free software; you can redistribute it and/or
7214 + * modify it under the terms of the GNU General Public License
7215 + * as published by the Free Software Foundation; either version
7216 + * 2 of the License, or (at your option) any later version.
7219 +#include <linux/config.h>
7220 +#include <linux/module.h>
7221 +#include <linux/skbuff.h>
7222 +#include <linux/icmpv6.h>
7223 +#include <net/ipv6.h>
7224 +#include <net/tcp.h>
7225 +#include <net/icmp.h>
7226 +#include <net/ip6_fib.h>
7227 +#include <net/ip6_route.h>
7228 +#include <net/flow.h>
7229 +#include <linux/netfilter_ipv6/ip6_tables.h>
7230 +#include <linux/netfilter_ipv6/ip6t_REJECT.h>
7232 +MODULE_AUTHOR("Yasuyuki KOZAKAI <yasuyuki.kozakai@toshiba.co.jp>");
7233 +MODULE_DESCRIPTION("IP6 tables REJECT target module");
7234 +MODULE_LICENSE("GPL");
7237 +#define DEBUGP printk
7239 +#define DEBUGP(format, args...)
7243 +static void connection_attach(struct sk_buff *new_skb, struct nf_ct_info *nfct)
7245 + void (*attach)(struct sk_buff *, struct nf_ct_info *);
7246 + if (nfct && (attach = ip6_ct_attach) != NULL) {
7248 + attach(new_skb, nfct);
7253 +static int maybe_reroute(struct sk_buff *skb)
7255 + if (skb->nfcache & NFC_ALTERED){
7256 + if (ip6_route_me_harder(skb) != 0){
7262 + return dst_output(skb);
7265 +/* Send RST reply */
7266 +static void send_reset(struct sk_buff *oldskb)
7268 + struct sk_buff *nskb;
7269 + struct tcphdr otcph, *tcph;
7270 + unsigned int otcplen, tcphoff, hh_len;
7272 + struct ipv6hdr *oip6h = oldskb->nh.ipv6h, *ip6h;
7273 + struct dst_entry *dst = NULL;
7276 + proto = oip6h->nexthdr;
7279 + if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) ||
7280 + (!(ipv6_addr_type(&oip6h->daddr) & IPV6_ADDR_UNICAST))) {
7281 + DEBUGP("ip6t_REJECT: addr is not unicast.\n");
7285 + tcphoff = ipv6_skip_exthdr(oldskb, ((u8*)(oip6h+1) - oldskb->data),
7286 + &proto, oldskb->len - ((u8*)(oip6h+1)
7289 + if ((tcphoff < 0) || (tcphoff > oldskb->len)) {
7290 + DEBUGP("ip6t_REJECT: Can't get TCP header.\n");
7294 + otcplen = oldskb->len - tcphoff;
7296 + /* IP header checks: fragment, too short. */
7297 + if ((proto != IPPROTO_TCP) || (otcplen < sizeof(struct tcphdr))) {
7298 + DEBUGP("ip6t_REJECT: proto(%d) != IPPROTO_TCP, or too short. otcplen = %d\n",
7303 + if (skb_copy_bits(oldskb, tcphoff, &otcph, sizeof(struct tcphdr))) {
7304 + if (net_ratelimit())
7305 + printk("ip6t_REJECT: Can't copy tcp header\n");
7309 + /* No RST for RST. */
7311 + DEBUGP("ip6t_REJECT: RST is set\n");
7315 + /* Check checksum. */
7316 + if (csum_ipv6_magic(&oip6h->saddr, &oip6h->daddr, otcplen, IPPROTO_TCP,
7317 + skb_checksum(oldskb, tcphoff, otcplen, 0))) {
7318 + DEBUGP("ip6t_REJECT: TCP checksum is invalid\n");
7322 + memset(&fl, 0, sizeof(fl));
7323 + fl.proto = IPPROTO_TCP;
7324 + ipv6_addr_copy(&fl.fl6_src, &oip6h->daddr);
7325 + ipv6_addr_copy(&fl.fl6_dst, &oip6h->saddr);
7326 + fl.fl_ip_sport = otcph.dest;
7327 + fl.fl_ip_dport = otcph.source;
7328 + err = ip6_dst_lookup(NULL, &dst, &fl);
7330 + if (net_ratelimit())
7331 + printk("ip6t_REJECT: can't find dst. err = %d\n", err);
7335 + hh_len = (dst->dev->hard_header_len + 15)&~15;
7336 + nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr)
7337 + + sizeof(struct tcphdr) + dst->trailer_len,
7341 + if (net_ratelimit())
7342 + printk("ip6t_REJECT: Can't alloc skb\n");
7350 + skb_reserve(nskb, hh_len + dst->header_len);
7352 + ip6h = nskb->nh.ipv6h = (struct ipv6hdr *)
7353 + skb_put(nskb, sizeof(struct ipv6hdr));
7354 + ip6h->version = 6;
7355 + ip6h->hop_limit = dst_metric(dst, RTAX_HOPLIMIT);
7356 + ip6h->nexthdr = IPPROTO_TCP;
7357 + ip6h->payload_len = htons(sizeof(struct tcphdr));
7358 + ipv6_addr_copy(&ip6h->saddr, &oip6h->daddr);
7359 + ipv6_addr_copy(&ip6h->daddr, &oip6h->saddr);
7361 + tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
7362 + /* Truncate to length (no data) */
7363 + tcph->doff = sizeof(struct tcphdr)/4;
7364 + tcph->source = otcph.dest;
7365 + tcph->dest = otcph.source;
7369 + tcph->seq = otcph.ack_seq;
7370 + tcph->ack_seq = 0;
7373 + tcph->ack_seq = htonl(ntohl(otcph.seq) + otcph.syn + otcph.fin
7374 + + otcplen - (otcph.doff<<2));
7379 + ((u_int8_t *)tcph)[13] = 0;
7381 + tcph->ack = needs_ack;
7383 + tcph->urg_ptr = 0;
7386 + /* Adjust TCP checksum */
7387 + tcph->check = csum_ipv6_magic(&nskb->nh.ipv6h->saddr,
7388 + &nskb->nh.ipv6h->daddr,
7389 + sizeof(struct tcphdr), IPPROTO_TCP,
7390 + csum_partial((char *)tcph,
7391 + sizeof(struct tcphdr), 0));
7394 + connection_attach(nskb, oldskb->nfct);
7397 + NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
7403 +static void send_unreach(struct sk_buff *skb_in, unsigned char code)
7405 + struct ipv6hdr *ip6h, *hdr = skb_in->nh.ipv6h;
7406 + struct icmp6hdr *icmp6h;
7407 + struct dst_entry *dst = NULL;
7408 + struct rt6_info *rt;
7411 + unsigned int len, datalen, hh_len;
7412 + int saddr_type, daddr_type;
7413 + unsigned int ptr, ip6off;
7416 + struct sk_buff *nskb;
7419 + saddr_type = ipv6_addr_type(&hdr->saddr);
7420 + daddr_type = ipv6_addr_type(&hdr->daddr);
7422 + if ((!(saddr_type & IPV6_ADDR_UNICAST)) ||
7423 + (!(daddr_type & IPV6_ADDR_UNICAST))) {
7424 + DEBUGP("ip6t_REJECT: addr is not unicast.\n");
7428 + ip6off = skb_in->nh.raw - skb_in->data;
7429 + proto = hdr->nexthdr;
7430 + ptr = ipv6_skip_exthdr(skb_in, ip6off + sizeof(struct ipv6hdr), &proto,
7431 + skb_in->len - ip6off);
7433 + if ((ptr < 0) || (ptr > skb_in->len)) {
7434 + ptr = ip6off + sizeof(struct ipv6hdr);
7435 + proto = hdr->nexthdr;
7436 + } else if (proto == IPPROTO_ICMPV6) {
7439 + if (skb_copy_bits(skb_in, ptr + offsetof(struct icmp6hdr,
7440 + icmp6_type), &type, 1)) {
7441 + DEBUGP("ip6t_REJECT: Can't get ICMPv6 type\n");
7445 + if (!(type & ICMPV6_INFOMSG_MASK)) {
7446 + DEBUGP("ip6t_REJECT: no reply to icmp error\n");
7449 + } else if (proto == IPPROTO_UDP) {
7450 + int plen = skb_in->len - (ptr - ip6off);
7453 + if (plen < sizeof(struct udphdr)) {
7454 + DEBUGP("ip6t_REJECT: too short\n");
7458 + if (skb_copy_bits(skb_in, ptr + offsetof(struct udphdr, check),
7460 + if (net_ratelimit())
7461 + printk("ip6t_REJECT: can't get copy from skb");
7466 + csum_ipv6_magic(&hdr->saddr, &hdr->daddr, plen,
7468 + skb_checksum(skb_in, ptr, plen, 0))) {
7469 + DEBUGP("ip6t_REJECT: UDP checksum is invalid.\n");
7474 + memset(&fl, 0, sizeof(fl));
7475 + fl.proto = IPPROTO_ICMPV6;
7476 + ipv6_addr_copy(&fl.fl6_src, &hdr->daddr);
7477 + ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr);
7478 + fl.fl_icmp_type = ICMPV6_DEST_UNREACH;
7479 + fl.fl_icmp_code = code;
7481 + if (ip6_dst_lookup(NULL, &dst, &fl)) {
7485 + rt = (struct rt6_info *)dst;
7488 + if (rt->rt6i_dst.plen < 128)
7489 + tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
7491 + if (!xrlim_allow(dst, tmo)) {
7492 + if (net_ratelimit())
7493 + printk("ip6t_REJECT: rate limitted\n");
7494 + goto dst_release_out;
7497 + len = skb_in->len + sizeof(struct ipv6hdr) + sizeof(struct icmp6hdr);
7499 + if (len > dst_pmtu(dst))
7500 + len = dst_pmtu(dst);
7501 + if (len > IPV6_MIN_MTU)
7502 + len = IPV6_MIN_MTU;
7504 + datalen = len - sizeof(struct ipv6hdr) - sizeof(struct icmp6hdr);
7505 + hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
7507 + nskb = alloc_skb(hh_len + 15 + dst->header_len + dst->trailer_len + len,
7511 + if (net_ratelimit())
7512 + printk("ip6t_REJECT: can't alloc skb\n");
7513 + goto dst_release_out;
7516 + nskb->priority = 0;
7520 + skb_reserve(nskb, hh_len + dst->header_len);
7522 + ip6h = nskb->nh.ipv6h = (struct ipv6hdr *)
7523 + skb_put(nskb, sizeof(struct ipv6hdr));
7524 + ip6h->version = 6;
7525 + ip6h->hop_limit = dst_metric(dst, RTAX_HOPLIMIT);
7526 + ip6h->nexthdr = IPPROTO_ICMPV6;
7527 + ip6h->payload_len = htons(datalen + sizeof(struct icmp6hdr));
7528 + ipv6_addr_copy(&ip6h->saddr, &hdr->daddr);
7529 + ipv6_addr_copy(&ip6h->daddr, &hdr->saddr);
7531 + icmp6h = (struct icmp6hdr *) skb_put(nskb, sizeof(struct icmp6hdr));
7532 + icmp6h->icmp6_type = ICMPV6_DEST_UNREACH;
7533 + icmp6h->icmp6_code = code;
7534 + icmp6h->icmp6_cksum = 0;
7536 + data = skb_put(nskb, datalen);
7538 + csum = csum_partial((unsigned char *)icmp6h, sizeof(struct icmp6hdr), 0);
7539 + csum = skb_copy_and_csum_bits(skb_in, ip6off, data, datalen, csum);
7540 + icmp6h->icmp6_cksum = csum_ipv6_magic(&hdr->saddr, &hdr->daddr,
7541 + datalen + sizeof(struct icmp6hdr),
7542 + IPPROTO_ICMPV6, csum);
7545 + connection_attach(nskb, skb_in->nfct);
7547 + NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
7554 +static unsigned int reject6_target(struct sk_buff **pskb,
7555 + unsigned int hooknum,
7556 + const struct net_device *in,
7557 + const struct net_device *out,
7558 + const void *targinfo,
7561 + const struct ip6t_reject_info *reject = targinfo;
7563 + DEBUGP(KERN_DEBUG "%s: medium point\n", __FUNCTION__);
7564 + /* WARNING: This code causes reentry within ip6tables.
7565 + This means that the ip6tables jump stack is now crap. We
7566 + must return an absolute verdict. --RR */
7567 + switch (reject->with) {
7568 + case IP6T_ICMP6_NO_ROUTE:
7569 + send_unreach(*pskb, ICMPV6_NOROUTE);
7571 + case IP6T_ICMP6_ADM_PROHIBITED:
7572 + send_unreach(*pskb, ICMPV6_ADM_PROHIBITED);
7574 + case IP6T_ICMP6_NOT_NEIGHBOUR:
7575 + send_unreach(*pskb, ICMPV6_NOT_NEIGHBOUR);
7577 + case IP6T_ICMP6_ADDR_UNREACH:
7578 + send_unreach(*pskb, ICMPV6_ADDR_UNREACH);
7580 + case IP6T_ICMP6_PORT_UNREACH:
7581 + send_unreach(*pskb, ICMPV6_PORT_UNREACH);
7583 + case IP6T_ICMP6_ECHOREPLY:
7586 + case IP6T_TCP_RESET:
7587 + send_reset(*pskb);
7590 + if (net_ratelimit())
7591 + printk(KERN_WARNING "ip6t_REJECT: case %u not handled yet\n", reject->with);
7598 +static int check(const char *tablename,
7599 + const struct ip6t_entry *e,
7601 + unsigned int targinfosize,
7602 + unsigned int hook_mask)
7604 + const struct ip6t_reject_info *rejinfo = targinfo;
7606 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
7607 + DEBUGP("ip6t_REJECT: targinfosize %u != 0\n", targinfosize);
7611 + /* Only allow these for packet filtering. */
7612 + if (strcmp(tablename, "filter") != 0) {
7613 + DEBUGP("ip6t_REJECT: bad table `%s'.\n", tablename);
7617 + if ((hook_mask & ~((1 << NF_IP6_LOCAL_IN)
7618 + | (1 << NF_IP6_FORWARD)
7619 + | (1 << NF_IP6_LOCAL_OUT))) != 0) {
7620 + DEBUGP("ip6t_REJECT: bad hook mask %X\n", hook_mask);
7624 + if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
7625 + printk("ip6t_REJECT: ECHOREPLY is not supported.\n");
7627 + } else if (rejinfo->with == IP6T_TCP_RESET) {
7628 + /* Must specify that it's a TCP packet */
7629 + if (e->ipv6.proto != IPPROTO_TCP
7630 + || (e->ipv6.invflags & IP6T_INV_PROTO)) {
7631 + DEBUGP("ip6t_REJECT: TCP_RESET illegal for non-tcp\n");
7639 +static struct ip6t_target ip6t_reject_reg = {
7641 + .target = reject6_target,
7642 + .checkentry = check,
7646 +static int __init init(void)
7648 + if (ip6t_register_target(&ip6t_reject_reg))
7653 +static void __exit fini(void)
7655 + ip6t_unregister_target(&ip6t_reject_reg);
7660 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv6/netfilter/ip6t_fuzzy.c linux-2.6.6-rc1/net/ipv6/netfilter/ip6t_fuzzy.c
7661 --- linux-2.6.6-rc1.org/net/ipv6/netfilter/ip6t_fuzzy.c 1970-01-01 01:00:00.000000000 +0100
7662 +++ linux-2.6.6-rc1/net/ipv6/netfilter/ip6t_fuzzy.c 2004-04-15 21:20:59.000000000 +0200
7665 + * This module implements a simple TSK FLC
7666 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
7667 + * to limit , in an adaptive and flexible way , the packet rate crossing
7668 + * a given stream . It serves as an initial and very simple (but effective)
7669 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
7670 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
7671 + * into our code in a precise , adaptive and efficient manner.
7672 + * The goal is very similar to that of "limit" match , but using techniques of
7673 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
7674 + * avoiding over and undershoots - and stuff like that .
7677 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
7678 + * 2002-08-17 : Changed to eliminate floating point operations .
7679 + * 2002-08-23 : Coding style changes .
7680 + * 2003-04-08 Maciej Soltysiak <solt@dns.toxicilms.tv> : IPv6 Port
7683 +#include <linux/module.h>
7684 +#include <linux/skbuff.h>
7685 +#include <linux/ipv6.h>
7686 +#include <linux/random.h>
7687 +#include <net/tcp.h>
7688 +#include <linux/spinlock.h>
7689 +#include <linux/netfilter_ipv6/ip6_tables.h>
7690 +#include <linux/netfilter_ipv6/ip6t_fuzzy.h>
7693 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
7694 + Expressed in percentage
7697 +#define PAR_LOW 1/100
7700 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED;
7702 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
7703 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
7704 +MODULE_LICENSE("GPL");
7706 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
7708 + if (tx >= maxi) return 100;
7710 + if (tx <= mini) return 0;
7712 + return ((100 * (tx-mini)) / (maxi-mini));
7715 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
7717 + if (tx <= mini) return 100;
7719 + if (tx >= maxi) return 0;
7721 + return ((100 * (maxi - tx)) / (maxi - mini));
7726 +ip6t_fuzzy_match(const struct sk_buff *pskb,
7727 + const struct net_device *in,
7728 + const struct net_device *out,
7729 + const void *matchinfo,
7732 + u_int16_t datalen,
7735 + /* From userspace */
7737 + struct ip6t_fuzzy_info *info = (struct ip6t_fuzzy_info *) matchinfo;
7739 + u_int8_t random_number;
7740 + unsigned long amount;
7741 + u_int8_t howhigh, howlow;
7744 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
7746 + info->bytes_total += pskb->len;
7747 + info->packets_total++;
7749 + info->present_time = jiffies;
7751 + if (info->present_time >= info->previous_time)
7752 + amount = info->present_time - info->previous_time;
7754 + /* There was a transition : I choose to re-sample
7755 + and keep the old acceptance rate...
7759 + info->previous_time = info->present_time;
7760 + info->bytes_total = info->packets_total = 0;
7763 + if ( amount > HZ/10) {/* More than 100 ms elapsed ... */
7765 + info->mean_rate = (u_int32_t) ((HZ * info->packets_total) \
7768 + info->previous_time = info->present_time;
7769 + info->bytes_total = info->packets_total = 0;
7771 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
7772 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
7774 + info->acceptance_rate = (u_int8_t) \
7775 + (howhigh * PAR_LOW + PAR_HIGH * howlow);
7777 + /* In fact, the above defuzzification would require a denominator
7778 + * proportional to (howhigh+howlow) but, in this particular case,
7779 + * that expression is constant.
7780 + * An imediate consequence is that it is not necessary to call
7781 + * both mf_high and mf_low - but to keep things understandable,
7787 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
7790 + if (info->acceptance_rate < 100)
7792 + get_random_bytes((void *)(&random_number), 1);
7794 + /* If within the acceptance , it can pass => don't match */
7795 + if (random_number <= (255 * info->acceptance_rate) / 100)
7798 + return 1; /* It can't pass (It matches) */
7801 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
7806 +ip6t_fuzzy_checkentry(const char *tablename,
7807 + const struct ip6t_ip6 *ip,
7809 + unsigned int matchsize,
7810 + unsigned int hook_mask)
7813 + const struct ip6t_fuzzy_info *info = matchinfo;
7815 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info))) {
7816 + printk("ip6t_fuzzy: matchsize %u != %u\n", matchsize,
7817 + IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info)));
7821 + if ((info->minimum_rate < MINFUZZYRATE) || (info->maximum_rate > MAXFUZZYRATE)
7822 + || (info->minimum_rate >= info->maximum_rate)) {
7823 + printk("ip6t_fuzzy: BAD limits , please verify !!!\n");
7830 +static struct ip6t_match ip6t_fuzzy_reg = {
7834 + ip6t_fuzzy_checkentry,
7838 +static int __init init(void)
7840 + if (ip6t_register_match(&ip6t_fuzzy_reg))
7846 +static void __exit fini(void)
7848 + ip6t_unregister_match(&ip6t_fuzzy_reg);
7853 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv6/netfilter/ip6t_nth.c linux-2.6.6-rc1/net/ipv6/netfilter/ip6t_nth.c
7854 --- linux-2.6.6-rc1.org/net/ipv6/netfilter/ip6t_nth.c 1970-01-01 01:00:00.000000000 +0100
7855 +++ linux-2.6.6-rc1/net/ipv6/netfilter/ip6t_nth.c 2004-04-15 21:21:05.000000000 +0200
7858 + This is a module which is used for match support for every Nth packet
7859 + This file is distributed under the terms of the GNU General Public
7860 + License (GPL). Copies of the GPL can be obtained from:
7861 + ftp://prep.ai.mit.edu/pub/gnu/GPL
7863 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
7864 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
7865 + * added support for multiple counters
7866 + * added support for matching on individual packets
7867 + in the counter cycle
7868 + 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
7872 +#include <linux/module.h>
7873 +#include <linux/skbuff.h>
7874 +#include <linux/ip.h>
7875 +#include <net/tcp.h>
7876 +#include <linux/spinlock.h>
7877 +#include <linux/netfilter_ipv6/ip6_tables.h>
7878 +#include <linux/netfilter_ipv6/ip6t_nth.h>
7880 +MODULE_LICENSE("GPL");
7883 + * State information.
7890 +static struct state states[IP6T_NTH_NUM_COUNTERS];
7893 +ip6t_nth_match(const struct sk_buff *pskb,
7894 + const struct net_device *in,
7895 + const struct net_device *out,
7896 + const void *matchinfo,
7899 + u_int16_t datalen,
7902 + /* Parameters from userspace */
7903 + const struct ip6t_nth_info *info = matchinfo;
7904 + unsigned counter = info->counter;
7905 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
7907 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
7911 + spin_lock(&states[counter].lock);
7913 + /* Are we matching every nth packet?*/
7914 + if (info->packet == 0xFF)
7916 + /* We're matching every nth packet and only every nth packet*/
7917 + /* Do we match or invert match? */
7918 + if (info->not == 0)
7920 + if (states[counter].number == 0)
7922 + ++states[counter].number;
7925 + if (states[counter].number >= info->every)
7926 + states[counter].number = 0; /* reset the counter */
7928 + ++states[counter].number;
7933 + if (states[counter].number == 0)
7935 + ++states[counter].number;
7938 + if (states[counter].number >= info->every)
7939 + states[counter].number = 0;
7941 + ++states[counter].number;
7947 + /* We're using the --packet, so there must be a rule for every value */
7948 + if (states[counter].number == info->packet)
7950 + /* only increment the counter when a match happens */
7951 + if (states[counter].number >= info->every)
7952 + states[counter].number = 0; /* reset the counter */
7954 + ++states[counter].number;
7963 + spin_unlock(&states[counter].lock);
7967 + spin_unlock(&states[counter].lock);
7972 +ip6t_nth_checkentry(const char *tablename,
7973 + const struct ip6t_ip6 *e,
7975 + unsigned int matchsize,
7976 + unsigned int hook_mask)
7978 + /* Parameters from userspace */
7979 + const struct ip6t_nth_info *info = matchinfo;
7980 + unsigned counter = info->counter;
7981 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
7983 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
7987 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_nth_info))) {
7988 + printk("nth: matchsize %u != %u\n", matchsize,
7989 + IP6T_ALIGN(sizeof(struct ip6t_nth_info)));
7993 + states[counter].number = info->startat;
7998 +static struct ip6t_match ip6t_nth_reg = {
8002 + ip6t_nth_checkentry,
8006 +static int __init init(void)
8009 + memset(&states, 0, sizeof(states));
8010 + if (ip6t_register_match(&ip6t_nth_reg))
8013 + for(counter = 0; counter < IP6T_NTH_NUM_COUNTERS; counter++)
8015 + spin_lock_init(&(states[counter].lock));
8018 + printk("ip6t_nth match loaded\n");
8022 +static void __exit fini(void)
8024 + ip6t_unregister_match(&ip6t_nth_reg);
8025 + printk("ip6t_nth match unloaded\n");
8030 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv6/netfilter/ip6t_random.c linux-2.6.6-rc1/net/ipv6/netfilter/ip6t_random.c
8031 --- linux-2.6.6-rc1.org/net/ipv6/netfilter/ip6t_random.c 1970-01-01 01:00:00.000000000 +0100
8032 +++ linux-2.6.6-rc1/net/ipv6/netfilter/ip6t_random.c 2004-04-15 21:21:18.000000000 +0200
8035 + This is a module which is used for a "random" match support.
8036 + This file is distributed under the terms of the GNU General Public
8037 + License (GPL). Copies of the GPL can be obtained from:
8038 + ftp://prep.ai.mit.edu/pub/gnu/GPL
8040 + 2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
8041 + 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
8044 +#include <linux/module.h>
8045 +#include <linux/skbuff.h>
8046 +#include <linux/ip.h>
8047 +#include <linux/random.h>
8048 +#include <net/tcp.h>
8049 +#include <linux/spinlock.h>
8050 +#include <linux/netfilter_ipv6/ip6_tables.h>
8051 +#include <linux/netfilter_ipv6/ip6t_random.h>
8053 +MODULE_LICENSE("GPL");
8056 +ip6t_rand_match(const struct sk_buff *pskb,
8057 + const struct net_device *in,
8058 + const struct net_device *out,
8059 + const void *matchinfo,
8062 + u_int16_t datalen,
8065 + /* Parameters from userspace */
8066 + const struct ip6t_rand_info *info = matchinfo;
8067 + u_int8_t random_number;
8069 + /* get 1 random number from the kernel random number generation routine */
8070 + get_random_bytes((void *)(&random_number), 1);
8072 + /* Do we match ? */
8073 + if (random_number <= info->average)
8080 +ip6t_rand_checkentry(const char *tablename,
8081 + const struct ip6t_ip6 *e,
8083 + unsigned int matchsize,
8084 + unsigned int hook_mask)
8086 + /* Parameters from userspace */
8087 + const struct ip6t_rand_info *info = matchinfo;
8089 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_rand_info))) {
8090 + printk("ip6t_random: matchsize %u != %u\n", matchsize,
8091 + IP6T_ALIGN(sizeof(struct ip6t_rand_info)));
8095 + /* must be 1 <= average % <= 99 */
8096 + /* 1 x 2.55 = 2 */
8097 + /* 99 x 2.55 = 252 */
8098 + if ((info->average < 2) || (info->average > 252)) {
8099 + printk("ip6t_random: invalid average %u\n", info->average);
8106 +static struct ip6t_match ip6t_rand_reg = {
8110 + ip6t_rand_checkentry,
8114 +static int __init init(void)
8116 + if (ip6t_register_match(&ip6t_rand_reg))
8119 + printk("ip6t_random match loaded\n");
8123 +static void __exit fini(void)
8125 + ip6t_unregister_match(&ip6t_rand_reg);
8126 + printk("ip6t_random match unloaded\n");
8131 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv6/netfilter/ip6table_raw.c linux-2.6.6-rc1/net/ipv6/netfilter/ip6table_raw.c
8132 --- linux-2.6.6-rc1.org/net/ipv6/netfilter/ip6table_raw.c 1970-01-01 01:00:00.000000000 +0100
8133 +++ linux-2.6.6-rc1/net/ipv6/netfilter/ip6table_raw.c 2004-04-15 21:21:20.000000000 +0200
8136 + * IPv6 raw table, a port of the IPv4 raw table to IPv6
8138 + * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
8140 +#include <linux/module.h>
8141 +#include <linux/netfilter_ipv6/ip6_tables.h>
8143 +#define RAW_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT))
8146 +#define DEBUGP(x, args...) printk(KERN_DEBUG x, ## args)
8148 +#define DEBUGP(x, args...)
8151 +/* Standard entry. */
8152 +struct ip6t_standard
8154 + struct ip6t_entry entry;
8155 + struct ip6t_standard_target target;
8158 +struct ip6t_error_target
8160 + struct ip6t_entry_target target;
8161 + char errorname[IP6T_FUNCTION_MAXNAMELEN];
8166 + struct ip6t_entry entry;
8167 + struct ip6t_error_target target;
8172 + struct ip6t_replace repl;
8173 + struct ip6t_standard entries[2];
8174 + struct ip6t_error term;
8175 +} initial_table __initdata
8176 += { { "raw", RAW_VALID_HOOKS, 3,
8177 + sizeof(struct ip6t_standard) * 2 + sizeof(struct ip6t_error),
8178 + { [NF_IP6_PRE_ROUTING] 0,
8179 + [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) },
8180 + { [NF_IP6_PRE_ROUTING] 0,
8181 + [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) },
8185 + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
8187 + sizeof(struct ip6t_entry),
8188 + sizeof(struct ip6t_standard),
8189 + 0, { 0, 0 }, { } },
8190 + { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
8191 + -NF_ACCEPT - 1 } },
8193 + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
8195 + sizeof(struct ip6t_entry),
8196 + sizeof(struct ip6t_standard),
8197 + 0, { 0, 0 }, { } },
8198 + { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
8199 + -NF_ACCEPT - 1 } },
8202 + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
8204 + sizeof(struct ip6t_entry),
8205 + sizeof(struct ip6t_error),
8206 + 0, { 0, 0 }, { } },
8207 + { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } },
8214 +static struct ip6t_table packet_raw = {
8216 + .table = &initial_table.repl,
8217 + .valid_hooks = RAW_VALID_HOOKS,
8218 + .lock = RW_LOCK_UNLOCKED,
8222 +/* The work comes in here from netfilter.c. */
8223 +static unsigned int
8224 +ip6t_hook(unsigned int hook,
8225 + struct sk_buff **pskb,
8226 + const struct net_device *in,
8227 + const struct net_device *out,
8228 + int (*okfn)(struct sk_buff *))
8230 + return ip6t_do_table(pskb, hook, in, out, &packet_raw, NULL);
8233 +static struct nf_hook_ops ip6t_ops[] = {
8235 + .hook = ip6t_hook,
8237 + .hooknum = NF_IP6_PRE_ROUTING,
8238 + .priority = NF_IP6_PRI_FIRST
8241 + .hook = ip6t_hook,
8243 + .hooknum = NF_IP6_LOCAL_OUT,
8244 + .priority = NF_IP6_PRI_FIRST
8248 +static int __init init(void)
8252 + /* Register table */
8253 + ret = ip6t_register_table(&packet_raw);
8257 + /* Register hooks */
8258 + ret = nf_register_hook(&ip6t_ops[0]);
8260 + goto cleanup_table;
8262 + ret = nf_register_hook(&ip6t_ops[1]);
8264 + goto cleanup_hook0;
8269 + nf_unregister_hook(&ip6t_ops[0]);
8271 + ip6t_unregister_table(&packet_raw);
8276 +static void __exit fini(void)
8280 + for (i = 0; i < sizeof(ip6t_ops)/sizeof(struct nf_hook_ops); i++)
8281 + nf_unregister_hook(&ip6t_ops[i]);
8283 + ip6t_unregister_table(&packet_raw);
8288 +MODULE_LICENSE("GPL");
8289 diff -Nur --exclude '*.orig' linux-2.6.6-rc1.org/net/ipv6/sit.c linux-2.6.6-rc1/net/ipv6/sit.c
8290 --- linux-2.6.6-rc1.org/net/ipv6/sit.c 2004-04-15 03:35:37.000000000 +0200
8291 +++ linux-2.6.6-rc1/net/ipv6/sit.c 2004-04-15 21:20:34.000000000 +0200
8292 @@ -388,13 +388,7 @@
8293 skb->dev = tunnel->dev;
8294 dst_release(skb->dst);
8296 -#ifdef CONFIG_NETFILTER
8297 - nf_conntrack_put(skb->nfct);
8299 -#ifdef CONFIG_NETFILTER_DEBUG
8300 - skb->nf_debug = 0;
8304 ipip6_ecn_decapsulate(iph, skb);
8306 read_unlock(&ipip6_lock);
8307 @@ -580,13 +574,7 @@
8308 if ((iph->ttl = tiph->ttl) == 0)
8309 iph->ttl = iph6->hop_limit;
8311 -#ifdef CONFIG_NETFILTER
8312 - nf_conntrack_put(skb->nfct);
8314 -#ifdef CONFIG_NETFILTER_DEBUG
8315 - skb->nf_debug = 0;
8321 tunnel->recursion--;