1 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/include/linux/netfilter.h linux-2.6.5-rc3/include/linux/netfilter.h
2 --- linux-2.6.5-rc3.org/include/linux/netfilter.h 2004-03-30 05:26:16.000000000 +0200
3 +++ linux-2.6.5-rc3/include/linux/netfilter.h 2004-03-30 11:10:29.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ip_conntrack.h
30 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ip_conntrack.h 2004-03-30 05:27:17.000000000 +0200
31 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ip_conntrack.h 2004-03-30 11:11:27.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ip_pool.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ip_pool.h
43 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ip_pool.h 1970-01-01 01:00:00.000000000 +0100
44 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ip_pool.h 2004-03-30 11:11:17.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_NETLINK.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_NETLINK.h
111 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_NETLINK.h 1970-01-01 01:00:00.000000000 +0100
112 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_NETLINK.h 2004-03-30 11:10:39.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_TTL.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_TTL.h
142 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_TTL.h 1970-01-01 01:00:00.000000000 +0100
143 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_TTL.h 2004-03-30 11:10:42.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_ULOG.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_ULOG.h
167 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_ULOG.h 2004-03-30 05:26:10.000000000 +0200
168 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_ULOG.h 2004-03-30 11:10:29.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_connlimit.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_connlimit.h
180 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_connlimit.h 1970-01-01 01:00:00.000000000 +0100
181 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_connlimit.h 2004-03-30 11:10:45.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_conntrack.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_conntrack.h
196 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_conntrack.h 2004-03-30 05:27:00.000000000 +0200
197 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_conntrack.h 2004-03-30 11:11:27.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_dstlimit.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_dstlimit.h
207 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_dstlimit.h 1970-01-01 01:00:00.000000000 +0100
208 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_dstlimit.h 2004-03-30 11:10:47.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_fuzzy.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_fuzzy.h
250 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_fuzzy.h 1970-01-01 01:00:00.000000000 +0100
251 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_fuzzy.h 2004-03-30 11:11:06.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_ipv4options.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_ipv4options.h
275 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_ipv4options.h 1970-01-01 01:00:00.000000000 +0100
276 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_ipv4options.h 2004-03-30 11:11:08.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_mport.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_mport.h
300 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_mport.h 1970-01-01 01:00:00.000000000 +0100
301 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_mport.h 2004-03-30 11:11:11.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_nth.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_nth.h
328 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_nth.h 1970-01-01 01:00:00.000000000 +0100
329 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_nth.h 2004-03-30 11:11:13.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_osf.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_osf.h
351 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_osf.h 1970-01-01 01:00:00.000000000 +0100
352 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_osf.h 2004-03-30 11:11:15.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_pool.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_pool.h
503 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_pool.h 1970-01-01 01:00:00.000000000 +0100
504 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_pool.h 2004-03-30 11:11:17.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_psd.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_psd.h
532 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_psd.h 1970-01-01 01:00:00.000000000 +0100
533 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_psd.h 2004-03-30 11:11:18.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_quota.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_quota.h
576 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_quota.h 1970-01-01 01:00:00.000000000 +0100
577 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_quota.h 2004-03-30 11:11:23.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_random.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_random.h
591 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_random.h 1970-01-01 01:00:00.000000000 +0100
592 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_random.h 2004-03-30 11:11:26.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_realm.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_realm.h
606 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_realm.h 1970-01-01 01:00:00.000000000 +0100
607 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_realm.h 2004-03-30 11:11:29.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_sctp.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_sctp.h
619 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_sctp.h 1970-01-01 01:00:00.000000000 +0100
620 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_sctp.h 2004-03-30 11:11:32.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_state.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_state.h
730 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_state.h 2004-03-30 05:27:06.000000000 +0200
731 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_state.h 2004-03-30 11:11:27.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_time.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_time.h
742 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_time.h 1970-01-01 01:00:00.000000000 +0100
743 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_time.h 2004-03-30 11:11:33.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4/ipt_u32.h linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_u32.h
759 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4/ipt_u32.h 1970-01-01 01:00:00.000000000 +0100
760 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4/ipt_u32.h 2004-03-30 11:11:35.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv4.h linux-2.6.5-rc3/include/linux/netfilter_ipv4.h
803 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv4.h 2004-03-30 05:27:05.000000000 +0200
804 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv4.h 2004-03-30 11:11:27.000000000 +0200
807 enum nf_ip_hook_priorities {
808 NF_IP_PRI_FIRST = INT_MIN,
809 + NF_IP_PRI_CONNTRACK_DEFRAG = -400,
810 + NF_IP_PRI_RAW = -300,
811 NF_IP_PRI_SELINUX_FIRST = -225,
812 NF_IP_PRI_CONNTRACK = -200,
813 NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
814 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/include/linux/netfilter_ipv6/ip6t_HL.h linux-2.6.5-rc3/include/linux/netfilter_ipv6/ip6t_HL.h
815 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv6/ip6t_HL.h 1970-01-01 01:00:00.000000000 +0100
816 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv6/ip6t_HL.h 2004-03-30 11:10:35.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv6/ip6t_REJECT.h linux-2.6.5-rc3/include/linux/netfilter_ipv6/ip6t_REJECT.h
841 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv6/ip6t_REJECT.h 2004-03-30 05:25:30.000000000 +0200
842 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv6/ip6t_REJECT.h 2004-03-30 11:10:40.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h linux-2.6.5-rc3/include/linux/netfilter_ipv6/ip6t_fuzzy.h
868 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h 1970-01-01 01:00:00.000000000 +0100
869 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv6/ip6t_fuzzy.h 2004-03-30 11:11:06.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv6/ip6t_nth.h linux-2.6.5-rc3/include/linux/netfilter_ipv6/ip6t_nth.h
893 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv6/ip6t_nth.h 1970-01-01 01:00:00.000000000 +0100
894 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv6/ip6t_nth.h 2004-03-30 11:11:13.000000000 +0200
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.5-rc3.org/include/linux/netfilter_ipv6/ip6t_random.h linux-2.6.5-rc3/include/linux/netfilter_ipv6/ip6t_random.h
916 --- linux-2.6.5-rc3.org/include/linux/netfilter_ipv6/ip6t_random.h 1970-01-01 01:00:00.000000000 +0100
917 +++ linux-2.6.5-rc3/include/linux/netfilter_ipv6/ip6t_random.h 2004-03-30 11:11:26.000000000 +0200
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.5-rc3.org/net/core/netfilter.c linux-2.6.5-rc3/net/core/netfilter.c
931 --- linux-2.6.5-rc3.org/net/core/netfilter.c 2004-03-30 05:26:13.000000000 +0200
932 +++ linux-2.6.5-rc3/net/core/netfilter.c 2004-03-30 11:10:29.000000000 +0200
935 * February 2000: Modified by James Morris to have 1 queue per protocol.
936 * 15-Mar-2000: Added NF_REPEAT --RR.
937 + * 08-May-2003: Internal logging interface added by Jozsef Kadlecsik.
939 #include <linux/config.h>
940 +#include <linux/kernel.h>
941 #include <linux/netfilter.h>
942 #include <net/protocol.h>
943 #include <linux/init.h>
945 EXPORT_SYMBOL(skb_ip_make_writable);
946 #endif /*CONFIG_INET*/
948 +/* Internal logging interface, which relies on the real
949 + LOG target modules */
951 +#define NF_LOG_PREFIXLEN 128
953 +static nf_logfn *nf_logging[NPROTO]; /* = NULL */
954 +static int reported = 0;
955 +static spinlock_t nf_log_lock = SPIN_LOCK_UNLOCKED;
957 +int nf_log_register(int pf, nf_logfn *logfn)
961 + /* Any setup of logging members must be done before
962 + * substituting pointer. */
964 + spin_lock(&nf_log_lock);
965 + if (!nf_logging[pf]) {
966 + nf_logging[pf] = logfn;
969 + spin_unlock(&nf_log_lock);
973 +void nf_log_unregister(int pf, nf_logfn *logfn)
975 + spin_lock(&nf_log_lock);
976 + if (nf_logging[pf] == logfn)
977 + nf_logging[pf] = NULL;
978 + spin_unlock(&nf_log_lock);
980 + /* Give time to concurrent readers. */
984 +void nf_log_packet(int pf,
985 + unsigned int hooknum,
986 + const struct sk_buff *skb,
987 + const struct net_device *in,
988 + const struct net_device *out,
989 + const char *fmt, ...)
992 + char prefix[NF_LOG_PREFIXLEN];
996 + logfn = nf_logging[pf];
998 + va_start(args, fmt);
999 + vsnprintf(prefix, sizeof(prefix), fmt, args);
1001 + /* We must read logging before nf_logfn[pf] */
1002 + smp_read_barrier_depends();
1003 + logfn(hooknum, skb, in, out, prefix);
1004 + } else if (!reported) {
1005 + printk(KERN_WARNING "nf_log_packet: can\'t log yet, "
1006 + "no backend logging module loaded in!\n");
1009 + rcu_read_unlock();
1011 +EXPORT_SYMBOL(nf_log_register);
1012 +EXPORT_SYMBOL(nf_log_unregister);
1013 +EXPORT_SYMBOL(nf_log_packet);
1015 /* This does not belong here, but ipt_REJECT needs it if connection
1016 tracking in use: without this, connection may not be in hash table,
1017 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/Kconfig linux-2.6.5-rc3/net/ipv4/netfilter/Kconfig
1018 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/Kconfig 2004-03-30 05:27:03.000000000 +0200
1019 +++ linux-2.6.5-rc3/net/ipv4/netfilter/Kconfig 2004-03-30 11:11:35.000000000 +0200
1020 @@ -579,5 +579,123 @@
1022 To compile it as a module, choose M here. If unsure, say N.
1024 +config IP_NF_TARGET_IPV4OPTSSTRIP
1025 + tristate 'IPV4OPTSSTRIP target support'
1026 + depends on IP_NF_MANGLE
1029 +config IP_NF_TARGET_NETLINK
1030 + tristate 'NETLINK target support'
1031 + depends on IP_NF_FILTER
1034 +config IP_NF_TARGET_TTL
1035 + tristate 'TTL target support'
1036 + depends on IP_NF_MANGLE
1039 +config IP_NF_MATCH_CONNLIMIT
1040 + tristate 'Connections/IP limit match support'
1041 + depends on IP_NF_IPTABLES
1044 +config IP_NF_MATCH_DSTLIMIT
1045 + tristate 'dstlimit match support'
1046 + depends on IP_NF_IPTABLES
1049 +config IP_NF_MATCH_FUZZY
1050 + tristate 'fuzzy match support'
1051 + depends on IP_NF_IPTABLES
1054 +config IP_NF_MATCH_IPV4OPTIONS
1055 + tristate 'IPV4OPTIONS match support'
1056 + depends on IP_NF_IPTABLES
1059 +config IP_NF_MATCH_MPORT
1060 + tristate 'Multiple port with ranges match support'
1061 + depends on IP_NF_IPTABLES
1064 +config IP_NF_MATCH_NTH
1065 + tristate 'Nth match support'
1066 + depends on IP_NF_IPTABLES
1069 +config IP_NF_MATCH_OSF
1070 + tristate 'OSF match support'
1071 + depends on IP_NF_IPTABLES
1074 +config IP_POOL_STATISTICS
1075 + bool 'enable statistics on pool usage'
1076 + depends on IP_NF_POOL!=n
1079 + tristate 'IP address pool support'
1080 + depends on IP_NF_IPTABLES
1083 +config IP_NF_MATCH_PSD
1084 + tristate 'psd match support'
1085 + depends on IP_NF_IPTABLES
1088 +config IP_NF_MATCH_QUOTA
1089 + tristate 'quota match support'
1090 + depends on IP_NF_IPTABLES
1093 +config IP_NF_MATCH_RANDOM
1094 + tristate 'random match support'
1095 + depends on IP_NF_IPTABLES
1098 +config IP_NF_TARGET_NOTRACK
1099 + tristate 'NOTRACK target support'
1100 + depends on IP_NF_RAW
1102 + The NOTRACK target allows a select rule to specify
1103 + which packets *not* to enter the conntrack/NAT
1104 + subsystem with all the consequences (no ICMP error tracking,
1105 + no protocol helpers for the selected packets).
1107 + If you want to compile it as a module, say M here and read
1108 + <file:Documentation/modules.txt>. If unsure, say `N'.
1111 + tristate 'raw table support (required for NOTRACK/TRACE)'
1112 + depends on IP_NF_IPTABLES
1114 + This option adds a `raw' table to iptables. This table is the very
1115 + first in the netfilter framework and hooks in at the PREROUTING
1116 + and OUTPUT chains.
1118 + If you want to compile it as a module, say M here and read
1119 + <file:Documentation/modules.txt>. If unsure, say `N'.
1122 +config IP_NF_MATCH_REALM
1123 + tristate 'realm match support'
1124 + depends on IP_NF_IPTABLES && NET_CLS_ROUTE
1127 +config IP_NF_MATCH_SCTP
1128 + tristate 'SCTP protocol match support'
1129 + depends on IP_NF_IPTABLES
1132 +config IP_NF_MATCH_TIME
1133 + tristate 'TIME match support'
1134 + depends on IP_NF_IPTABLES
1137 +config IP_NF_MATCH_U32
1138 + tristate 'U32 match support'
1139 + depends on IP_NF_IPTABLES
1144 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/Makefile linux-2.6.5-rc3/net/ipv4/netfilter/Makefile
1145 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/Makefile 2004-03-30 05:25:35.000000000 +0200
1146 +++ linux-2.6.5-rc3/net/ipv4/netfilter/Makefile 2004-03-30 11:11:35.000000000 +0200
1148 obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
1149 obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
1150 obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
1151 +obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
1154 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
1155 obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
1156 +obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o
1157 +obj-$(CONFIG_IP_NF_MATCH_QUOTA) += ipt_quota.o
1158 +obj-$(CONFIG_IP_NF_MATCH_DSTLIMIT) += ipt_dstlimit.o
1159 obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
1160 +obj-$(CONFIG_IP_NF_POOL) += ipt_pool.o ipt_POOL.o ip_pool.o
1161 obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
1162 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
1164 obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
1165 obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
1167 +obj-$(CONFIG_IP_NF_MATCH_MPORT) += ipt_mport.o
1169 obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
1170 obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
1172 +obj-$(CONFIG_IP_NF_MATCH_TIME) += ipt_time.o
1175 +obj-$(CONFIG_IP_NF_MATCH_RANDOM) += ipt_random.o
1177 +obj-$(CONFIG_IP_NF_MATCH_PSD) += ipt_psd.o
1179 +obj-$(CONFIG_IP_NF_MATCH_OSF) += ipt_osf.o
1182 +obj-$(CONFIG_IP_NF_MATCH_NTH) += ipt_nth.o
1184 +obj-$(CONFIG_IP_NF_MATCH_IPV4OPTIONS) += ipt_ipv4options.o
1187 +obj-$(CONFIG_IP_NF_MATCH_FUZZY) += ipt_fuzzy.o
1189 obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
1191 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
1194 obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o
1196 +obj-$(CONFIG_IP_NF_MATCH_U32) += ipt_u32.o
1199 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
1200 obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
1201 +obj-$(CONFIG_IP_NF_MATCH_CONNLIMIT) += ipt_connlimit.o
1202 obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
1203 obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
1204 +obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
1206 obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
1209 obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
1210 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
1211 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
1212 +obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
1213 +obj-$(CONFIG_IP_NF_TARGET_NETLINK) += ipt_NETLINK.o
1214 +obj-$(CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP) += ipt_IPV4OPTSSTRIP.o
1215 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
1216 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
1217 +obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o
1219 # generic ARP tables
1220 obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
1221 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ip_conntrack_core.c linux-2.6.5-rc3/net/ipv4/netfilter/ip_conntrack_core.c
1222 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ip_conntrack_core.c 2004-03-30 05:25:30.000000000 +0200
1223 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ip_conntrack_core.c 2004-03-30 11:11:27.000000000 +0200
1225 static atomic_t ip_conntrack_count = ATOMIC_INIT(0);
1226 struct list_head *ip_conntrack_hash;
1227 static kmem_cache_t *ip_conntrack_cachep;
1228 +struct ip_conntrack ip_conntrack_untracked;
1230 extern struct ip_conntrack_protocol ip_conntrack_generic_protocol;
1232 @@ -691,42 +692,50 @@
1233 struct ip_conntrack_expect *, tuple);
1234 READ_UNLOCK(&ip_conntrack_expect_tuple_lock);
1236 - /* If master is not in hash table yet (ie. packet hasn't left
1237 - this machine yet), how can other end know about expected?
1238 - Hence these are not the droids you are looking for (if
1239 - master ct never got confirmed, we'd hold a reference to it
1240 - and weird things would happen to future packets). */
1241 - if (expected && !is_confirmed(expected->expectant))
1244 - /* Look up the conntrack helper for master connections only */
1246 - conntrack->helper = ip_ct_find_helper(&repl_tuple);
1248 - /* If the expectation is dying, then this is a loser. */
1250 - && expected->expectant->helper->timeout
1251 - && ! del_timer(&expected->timeout))
1255 - DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
1256 - conntrack, expected);
1257 - /* Welcome, Mr. Bond. We've been expecting you... */
1258 - IP_NF_ASSERT(master_ct(conntrack));
1259 - __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
1260 - conntrack->master = expected;
1261 - expected->sibling = conntrack;
1262 - LIST_DELETE(&ip_conntrack_expect_list, expected);
1263 - expected->expectant->expecting--;
1264 - nf_conntrack_get(&master_ct(conntrack)->infos[0]);
1266 - atomic_inc(&ip_conntrack_count);
1267 + /* If master is not in hash table yet (ie. packet hasn't left
1268 + this machine yet), how can other end know about expected?
1269 + Hence these are not the droids you are looking for (if
1270 + master ct never got confirmed, we'd hold a reference to it
1271 + and weird things would happen to future packets). */
1272 + if (!is_confirmed(expected->expectant)) {
1274 + conntrack->helper = ip_ct_find_helper(&repl_tuple);
1278 + /* Expectation is dying... */
1279 + if (expected->expectant->helper->timeout
1280 + && ! del_timer(&expected->timeout)) {
1284 + DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
1285 + conntrack, expected);
1286 + /* Welcome, Mr. Bond. We've been expecting you... */
1287 + IP_NF_ASSERT(master_ct(conntrack));
1288 + __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
1289 + conntrack->master = expected;
1290 + expected->sibling = conntrack;
1291 + LIST_DELETE(&ip_conntrack_expect_list, expected);
1292 + expected->expectant->expecting--;
1293 + nf_conntrack_get(&master_ct(conntrack)->infos[0]);
1295 + /* this is a braindead... --pablo */
1296 + atomic_inc(&ip_conntrack_count);
1297 + WRITE_UNLOCK(&ip_conntrack_lock);
1299 + if (expected->expectfn)
1300 + expected->expectfn(conntrack);
1304 + conntrack->helper = ip_ct_find_helper(&repl_tuple);
1306 +end: atomic_inc(&ip_conntrack_count);
1307 WRITE_UNLOCK(&ip_conntrack_lock);
1309 - if (expected && expected->expectfn)
1310 - expected->expectfn(conntrack);
1311 - return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
1312 +ret: return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
1315 /* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
1316 @@ -794,6 +803,15 @@
1320 + /* Never happen */
1321 + if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) {
1322 + if (net_ratelimit()) {
1323 + printk(KERN_ERR "ip_conntrack_in: Frag of proto %u (hook=%u)\n",
1324 + (*pskb)->nh.iph->protocol, hooknum);
1329 /* FIXME: Do this right please. --RR */
1330 (*pskb)->nfcache |= NFC_UNKNOWN;
1332 @@ -812,18 +830,10 @@
1336 - /* Previously seen (loopback)? Ignore. Do this before
1337 - fragment check. */
1338 + /* Previously seen (loopback or untracked)? Ignore. */
1342 - /* Gather fragments. */
1343 - if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
1344 - *pskb = ip_ct_gather_frags(*pskb);
1349 proto = ip_ct_find_proto((*pskb)->nh.iph->protocol);
1351 /* It may be an icmp error... */
1352 @@ -1422,6 +1432,18 @@
1354 /* For use by ipt_REJECT */
1355 ip_ct_attach = ip_conntrack_attach;
1357 + /* Set up fake conntrack:
1358 + - to never be deleted, not in any hashes */
1359 + atomic_set(&ip_conntrack_untracked.ct_general.use, 1);
1360 + /* - and look it like as a confirmed connection */
1361 + set_bit(IPS_CONFIRMED_BIT, &ip_conntrack_untracked.status);
1362 + /* - and prepare the ctinfo field for REJECT & NAT. */
1363 + ip_conntrack_untracked.infos[IP_CT_NEW].master =
1364 + ip_conntrack_untracked.infos[IP_CT_RELATED].master =
1365 + ip_conntrack_untracked.infos[IP_CT_RELATED + IP_CT_IS_REPLY].master =
1366 + &ip_conntrack_untracked.ct_general;
1371 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.6.5-rc3/net/ipv4/netfilter/ip_conntrack_standalone.c
1372 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-03-30 05:26:11.000000000 +0200
1373 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-03-30 11:11:27.000000000 +0200
1374 @@ -194,6 +194,26 @@
1375 return ip_conntrack_confirm(*pskb);
1378 +static unsigned int ip_conntrack_defrag(unsigned int hooknum,
1379 + struct sk_buff **pskb,
1380 + const struct net_device *in,
1381 + const struct net_device *out,
1382 + int (*okfn)(struct sk_buff *))
1384 + /* Previously seen (loopback)? Ignore. Do this before
1385 + fragment check. */
1386 + if ((*pskb)->nfct)
1389 + /* Gather fragments. */
1390 + if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
1391 + *pskb = ip_ct_gather_frags(*pskb);
1398 static unsigned int ip_refrag(unsigned int hooknum,
1399 struct sk_buff **pskb,
1400 const struct net_device *in,
1401 @@ -236,6 +256,14 @@
1403 /* Connection tracking may drop packets, but never alters them, so
1404 make it the first hook. */
1405 +static struct nf_hook_ops ip_conntrack_defrag_ops = {
1406 + .hook = ip_conntrack_defrag,
1407 + .owner = THIS_MODULE,
1409 + .hooknum = NF_IP_PRE_ROUTING,
1410 + .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
1413 static struct nf_hook_ops ip_conntrack_in_ops = {
1414 .hook = ip_conntrack_in,
1415 .owner = THIS_MODULE,
1416 @@ -244,6 +272,14 @@
1417 .priority = NF_IP_PRI_CONNTRACK,
1420 +static struct nf_hook_ops ip_conntrack_defrag_local_out_ops = {
1421 + .hook = ip_conntrack_defrag,
1422 + .owner = THIS_MODULE,
1424 + .hooknum = NF_IP_LOCAL_OUT,
1425 + .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
1428 static struct nf_hook_ops ip_conntrack_local_out_ops = {
1429 .hook = ip_conntrack_local,
1430 .owner = THIS_MODULE,
1431 @@ -470,10 +506,20 @@
1432 if (!proc) goto cleanup_init;
1433 proc->owner = THIS_MODULE;
1435 + ret = nf_register_hook(&ip_conntrack_defrag_ops);
1437 + printk("ip_conntrack: can't register pre-routing defrag hook.\n");
1438 + goto cleanup_proc;
1440 + ret = nf_register_hook(&ip_conntrack_defrag_local_out_ops);
1442 + printk("ip_conntrack: can't register local_out defrag hook.\n");
1443 + goto cleanup_defragops;
1445 ret = nf_register_hook(&ip_conntrack_in_ops);
1447 printk("ip_conntrack: can't register pre-routing hook.\n");
1448 - goto cleanup_proc;
1449 + goto cleanup_defraglocalops;
1451 ret = nf_register_hook(&ip_conntrack_local_out_ops);
1453 @@ -511,6 +557,10 @@
1454 nf_unregister_hook(&ip_conntrack_local_out_ops);
1456 nf_unregister_hook(&ip_conntrack_in_ops);
1457 + cleanup_defraglocalops:
1458 + nf_unregister_hook(&ip_conntrack_defrag_local_out_ops);
1459 + cleanup_defragops:
1460 + nf_unregister_hook(&ip_conntrack_defrag_ops);
1462 proc_net_remove("ip_conntrack");
1465 EXPORT_SYMBOL(ip_conntrack_expect_list);
1466 EXPORT_SYMBOL(ip_conntrack_lock);
1467 EXPORT_SYMBOL(ip_conntrack_hash);
1468 +EXPORT_SYMBOL(ip_conntrack_untracked);
1469 EXPORT_SYMBOL_GPL(ip_conntrack_find_get);
1470 EXPORT_SYMBOL_GPL(ip_conntrack_put);
1471 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ip_nat_core.c linux-2.6.5-rc3/net/ipv4/netfilter/ip_nat_core.c
1472 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ip_nat_core.c 2004-03-30 05:25:33.000000000 +0200
1473 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ip_nat_core.c 2004-03-30 11:11:27.000000000 +0200
1474 @@ -1016,6 +1016,10 @@
1475 /* FIXME: Man, this is a hack. <SIGH> */
1476 IP_NF_ASSERT(ip_conntrack_destroyed == NULL);
1477 ip_conntrack_destroyed = &ip_nat_cleanup_conntrack;
1479 + /* Initialize fake conntrack so that NAT will skip it */
1480 + ip_conntrack_untracked.nat.info.initialized |=
1481 + (1 << IP_NAT_MANIP_SRC) | (1 << IP_NAT_MANIP_DST);
1485 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ip_pool.c linux-2.6.5-rc3/net/ipv4/netfilter/ip_pool.c
1486 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ip_pool.c 1970-01-01 01:00:00.000000000 +0100
1487 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ip_pool.c 2004-03-30 11:11:17.000000000 +0200
1489 +/* Kernel module for IP pool management */
1491 +#include <linux/module.h>
1492 +#include <linux/ip.h>
1493 +#include <linux/skbuff.h>
1494 +#include <linux/netfilter_ipv4/ip_tables.h>
1495 +#include <linux/netfilter_ipv4/ip_pool.h>
1496 +#include <linux/errno.h>
1497 +#include <asm/uaccess.h>
1498 +#include <asm/bitops.h>
1499 +#include <linux/interrupt.h>
1500 +#include <linux/spinlock.h>
1505 +#define DP(format, args...)
1508 +MODULE_LICENSE("GPL");
1511 +static int nr_pool = NR_POOL;/* overwrite this when loading module */
1514 + u_int32_t first_ip; /* host byte order, included in range */
1515 + u_int32_t last_ip; /* host byte order, included in range */
1516 + void *members; /* the bitmap proper */
1517 + int nr_use; /* total nr. of tests through this */
1518 + int nr_match; /* total nr. of matches through this */
1522 +static struct ip_pool *POOL;
1524 +static inline struct ip_pool *lookup(ip_pool_t index)
1526 + if (index < 0 || index >= nr_pool) {
1527 + DP("ip_pool:lookup: bad index %d\n", index);
1530 + return POOL+index;
1533 +int ip_pool_match(ip_pool_t index, u_int32_t addr)
1535 + struct ip_pool *pool = lookup(index);
1538 + if (!pool || !pool->members)
1540 + read_lock_bh(&pool->lock);
1541 + if (pool->members) {
1542 + if (addr >= pool->first_ip && addr <= pool->last_ip) {
1543 + addr -= pool->first_ip;
1544 + if (test_bit(addr, pool->members)) {
1546 +#ifdef CONFIG_IP_POOL_STATISTICS
1551 +#ifdef CONFIG_IP_POOL_STATISTICS
1555 + read_unlock_bh(&pool->lock);
1558 +EXPORT_SYMBOL(ip_pool_match);
1560 +static int pool_change(ip_pool_t index, u_int32_t addr, int isdel)
1562 + struct ip_pool *pool;
1565 + pool = lookup(index);
1566 + if ( !pool || !pool->members
1567 + || addr < pool->first_ip || addr > pool->last_ip)
1569 + read_lock_bh(&pool->lock);
1570 + if (pool->members && addr >= pool->first_ip && addr <= pool->last_ip) {
1571 + addr -= pool->first_ip;
1573 + ? (0 != test_and_clear_bit(addr, pool->members))
1574 + : (0 != test_and_set_bit(addr, pool->members));
1576 + read_unlock_bh(&pool->lock);
1580 +int ip_pool_mod(ip_pool_t index, u_int32_t addr, int isdel)
1582 + int res = pool_change(index,addr,isdel);
1584 + if (!isdel) res = !res;
1587 +EXPORT_SYMBOL(ip_pool_mod);
1589 +static inline int bitmap_bytes(u_int32_t a, u_int32_t b)
1591 + return 4*((((b-a+8)/8)+3)/4);
1594 +static inline int poolbytes(ip_pool_t index)
1596 + struct ip_pool *pool = lookup(index);
1598 + return pool ? bitmap_bytes(pool->first_ip, pool->last_ip) : 0;
1601 +static int setpool(
1607 + struct ip_pool_request req;
1609 + DP("ip_pool:setpool: optval=%d, user=%p, len=%d\n", optval, user, len);
1610 + if (!capable(CAP_NET_ADMIN))
1612 + if (optval != SO_IP_POOL)
1614 + if (len != sizeof(req))
1616 + if (copy_from_user(&req, user, sizeof(req)) != 0)
1618 + printk("obsolete op - upgrade your ippool(8) utility.\n");
1622 +static int getpool(
1628 + struct ip_pool_request req;
1629 + struct ip_pool *pool;
1635 + DP("ip_pool:getpool: optval=%d, user=%p\n", optval, user);
1636 + if (!capable(CAP_NET_ADMIN))
1638 + if (optval != SO_IP_POOL)
1640 + if (*len != sizeof(req)) {
1643 + if (copy_from_user(&req, user, sizeof(req)) != 0)
1645 + DP("ip_pool:getpool op=%d, index=%d\n", req.op, req.index);
1646 + if (req.op < IP_POOL_BAD001) {
1647 + printk("obsolete op - upgrade your ippool(8) utility.\n");
1651 + case IP_POOL_HIGH_NR:
1652 + DP("ip_pool HIGH_NR\n");
1653 + req.index = IP_POOL_NONE;
1654 + for (i=0; i<nr_pool; i++)
1655 + if (POOL[i].members)
1657 + return copy_to_user(user, &req, sizeof(req));
1658 + case IP_POOL_LOOKUP:
1659 + DP("ip_pool LOOKUP\n");
1660 + pool = lookup(req.index);
1663 + if (!pool->members)
1665 + req.addr = htonl(pool->first_ip);
1666 + req.addr2 = htonl(pool->last_ip);
1667 + return copy_to_user(user, &req, sizeof(req));
1668 + case IP_POOL_USAGE:
1669 + DP("ip_pool USE\n");
1670 + pool = lookup(req.index);
1673 + if (!pool->members)
1675 + req.addr = pool->nr_use;
1676 + req.addr2 = pool->nr_match;
1677 + return copy_to_user(user, &req, sizeof(req));
1678 + case IP_POOL_TEST_ADDR:
1679 + DP("ip_pool TEST 0x%08x\n", req.addr);
1680 + pool = lookup(req.index);
1684 + read_lock_bh(&pool->lock);
1685 + if (!pool->members) {
1686 + DP("ip_pool TEST_ADDR no members in pool\n");
1688 + goto unlock_and_return_res;
1690 + req.addr = ntohl(req.addr);
1691 + if (req.addr < pool->first_ip) {
1692 + DP("ip_pool TEST_ADDR address < pool bounds\n");
1694 + goto unlock_and_return_res;
1696 + if (req.addr > pool->last_ip) {
1697 + DP("ip_pool TEST_ADDR address > pool bounds\n");
1699 + goto unlock_and_return_res;
1701 + req.addr = (0 != test_bit((req.addr - pool->first_ip),
1703 + read_unlock_bh(&pool->lock);
1704 + return copy_to_user(user, &req, sizeof(req));
1705 + case IP_POOL_FLUSH:
1706 + DP("ip_pool FLUSH not yet implemented.\n");
1708 + case IP_POOL_DESTROY:
1709 + DP("ip_pool DESTROY not yet implemented.\n");
1711 + case IP_POOL_INIT:
1712 + DP("ip_pool INIT 0x%08x-0x%08x\n", req.addr, req.addr2);
1713 + pool = lookup(req.index);
1716 + req.addr = ntohl(req.addr);
1717 + req.addr2 = ntohl(req.addr2);
1718 + if (req.addr > req.addr2) {
1719 + DP("ip_pool INIT bad ip range\n");
1722 + newbytes = bitmap_bytes(req.addr, req.addr2);
1723 + newmembers = kmalloc(newbytes, GFP_KERNEL);
1724 + if (!newmembers) {
1725 + DP("ip_pool INIT out of mem for %d bytes\n", newbytes);
1728 + memset(newmembers, 0, newbytes);
1729 + write_lock_bh(&pool->lock);
1730 + if (pool->members) {
1731 + DP("ip_pool INIT pool %d exists\n", req.index);
1732 + kfree(newmembers);
1734 + goto unlock_and_return_res;
1736 + pool->first_ip = req.addr;
1737 + pool->last_ip = req.addr2;
1739 + pool->nr_match = 0;
1740 + pool->members = newmembers;
1741 + write_unlock_bh(&pool->lock);
1743 + case IP_POOL_ADD_ADDR:
1744 + DP("ip_pool ADD_ADDR 0x%08x\n", req.addr);
1745 + req.addr = pool_change(req.index, ntohl(req.addr), 0);
1746 + return copy_to_user(user, &req, sizeof(req));
1747 + case IP_POOL_DEL_ADDR:
1748 + DP("ip_pool DEL_ADDR 0x%08x\n", req.addr);
1749 + req.addr = pool_change(req.index, ntohl(req.addr), 1);
1750 + return copy_to_user(user, &req, sizeof(req));
1752 + DP("ip_pool:getpool bad op %d\n", req.op);
1757 +unlock_and_return_res:
1759 + read_unlock_bh(&pool->lock);
1763 +static struct nf_sockopt_ops so_pool
1764 += { { NULL, NULL }, PF_INET,
1765 + SO_IP_POOL, SO_IP_POOL+1, &setpool,
1766 + SO_IP_POOL, SO_IP_POOL+1, &getpool,
1769 +MODULE_PARM(nr_pool, "i");
1771 +static int __init init(void)
1776 + if (nr_pool < 1) {
1777 + printk("ip_pool module init: bad nr_pool %d\n", nr_pool);
1780 + POOL = kmalloc(nr_pool * sizeof(*POOL), GFP_KERNEL);
1782 + printk("ip_pool module init: out of memory for nr_pool %d\n",
1786 + for (i=0; i<nr_pool; i++) {
1787 + POOL[i].first_ip = 0;
1788 + POOL[i].last_ip = 0;
1789 + POOL[i].members = 0;
1790 + POOL[i].nr_use = 0;
1791 + POOL[i].nr_match = 0;
1792 + POOL[i].lock = RW_LOCK_UNLOCKED;
1794 + res = nf_register_sockopt(&so_pool);
1795 + DP("ip_pool:init %d pools, result %d\n", nr_pool, res);
1803 +static void __exit fini(void)
1807 + DP("ip_pool:fini BYEBYE\n");
1808 + nf_unregister_sockopt(&so_pool);
1809 + for (i=0; i<nr_pool; i++) {
1810 + if (POOL[i].members) {
1811 + kfree(POOL[i].members);
1812 + POOL[i].members = 0;
1817 + DP("ip_pool:fini these are the famous last words\n");
1823 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ip_tables.c linux-2.6.5-rc3/net/ipv4/netfilter/ip_tables.c
1824 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ip_tables.c 2004-03-30 05:25:36.000000000 +0200
1825 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ip_tables.c 2004-03-30 11:10:33.000000000 +0200
1826 @@ -1716,9 +1716,9 @@
1829 #ifdef CONFIG_PROC_FS
1830 -static inline int print_name(const char *i,
1831 - off_t start_offset, char *buffer, int length,
1832 - off_t *pos, unsigned int *count)
1833 +static int print_name(const char *i,
1834 + off_t start_offset, char *buffer, int length,
1835 + off_t *pos, unsigned int *count)
1837 if ((*count)++ >= start_offset) {
1838 unsigned int namelen;
1839 @@ -1752,6 +1752,15 @@
1843 +static inline int print_target(const struct ipt_target *t,
1844 + off_t start_offset, char *buffer, int length,
1845 + off_t *pos, unsigned int *count)
1847 + if (t != &ipt_standard_target && t != &ipt_error_target)
1849 + return print_name((char *)t, start_offset, buffer, length, pos, count);
1852 static int ipt_get_targets(char *buffer, char **start, off_t offset, int length)
1855 @@ -1760,7 +1769,7 @@
1856 if (down_interruptible(&ipt_mutex) != 0)
1859 - LIST_FIND(&ipt_target, print_name, void *,
1860 + LIST_FIND(&ipt_target, print_target, struct ipt_target *,
1861 offset, buffer, length, &pos, &count);
1864 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c
1865 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 1970-01-01 01:00:00.000000000 +0100
1866 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 2004-03-30 11:10:37.000000000 +0200
1869 + * Strip all IP options in the IP packet header.
1871 + * (C) 2001 by Fabrice MARIE <fabrice@netfilter.org>
1872 + * This software is distributed under GNU GPL v2, 1991
1875 +#include <linux/module.h>
1876 +#include <linux/skbuff.h>
1877 +#include <linux/ip.h>
1878 +#include <net/checksum.h>
1880 +#include <linux/netfilter_ipv4/ip_tables.h>
1882 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
1883 +MODULE_DESCRIPTION("Strip all options in IPv4 packets");
1884 +MODULE_LICENSE("GPL");
1886 +static unsigned int
1887 +target(struct sk_buff **pskb,
1888 + const struct net_device *in,
1889 + const struct net_device *out,
1890 + unsigned int hooknum,
1891 + const void *targinfo,
1894 + struct iphdr *iph;
1895 + struct sk_buff *skb;
1896 + struct ip_options *opt;
1897 + unsigned char *optiph;
1900 + if (!skb_ip_make_writable(pskb, (*pskb)->len))
1904 + iph = (*pskb)->nh.iph;
1905 + optiph = skb->nh.raw;
1906 + l = ((struct ip_options *)(&(IPCB(skb)->opt)))->optlen;
1908 + /* if no options in packet then nothing to clear. */
1909 + if (iph->ihl * 4 == sizeof(struct iphdr))
1910 + return IPT_CONTINUE;
1912 + /* else clear all options */
1913 + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
1914 + memset(optiph+sizeof(struct iphdr), IPOPT_NOOP, l);
1915 + opt = &(IPCB(skb)->opt);
1919 + skb->nfcache |= NFC_ALTERED;
1921 + return IPT_CONTINUE;
1925 +checkentry(const char *tablename,
1926 + const struct ipt_entry *e,
1928 + unsigned int targinfosize,
1929 + unsigned int hook_mask)
1931 + if (strcmp(tablename, "mangle")) {
1932 + printk(KERN_WARNING "IPV4OPTSSTRIP: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1935 + /* nothing else to check because no parameters */
1939 +static struct ipt_target ipt_ipv4optsstrip_reg = {
1940 + .name = "IPV4OPTSSTRIP",
1942 + .checkentry = checkentry,
1943 + .me = THIS_MODULE };
1945 +static int __init init(void)
1947 + return ipt_register_target(&ipt_ipv4optsstrip_reg);
1950 +static void __exit fini(void)
1952 + ipt_unregister_target(&ipt_ipv4optsstrip_reg);
1957 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_LOG.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_LOG.c
1958 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_LOG.c 2004-03-30 05:27:07.000000000 +0200
1959 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_LOG.c 2004-03-30 11:10:29.000000000 +0200
1961 #include <net/tcp.h>
1962 #include <net/route.h>
1964 +#include <linux/netfilter.h>
1965 #include <linux/netfilter_ipv4/ip_tables.h>
1966 #include <linux/netfilter_ipv4/ipt_LOG.h>
1969 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
1970 MODULE_DESCRIPTION("iptables syslog logging module");
1972 +static unsigned int nflog = 1;
1973 +MODULE_PARM(nflog, "i");
1974 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
1977 #define DEBUGP printk
1979 @@ -324,28 +329,25 @@
1980 /* maxlen = 230+ 91 + 230 + 252 = 803 */
1983 -static unsigned int
1984 -ipt_log_target(struct sk_buff **pskb,
1986 +ipt_log_packet(unsigned int hooknum,
1987 + const struct sk_buff *skb,
1988 const struct net_device *in,
1989 const struct net_device *out,
1990 - unsigned int hooknum,
1991 - const void *targinfo,
1993 + const struct ipt_log_info *loginfo,
1994 + const char *level_string,
1995 + const char *prefix)
1997 - const struct ipt_log_info *loginfo = targinfo;
1998 - char level_string[4] = "< >";
2000 - level_string[1] = '0' + (loginfo->level % 8);
2001 spin_lock_bh(&log_lock);
2002 printk(level_string);
2003 printk("%sIN=%s OUT=%s ",
2005 + prefix == NULL ? loginfo->prefix : prefix,
2007 out ? out->name : "");
2008 #ifdef CONFIG_BRIDGE_NETFILTER
2009 - if ((*pskb)->nf_bridge) {
2010 - struct net_device *physindev = (*pskb)->nf_bridge->physindev;
2011 - struct net_device *physoutdev = (*pskb)->nf_bridge->physoutdev;
2012 + if (skb->nf_bridge) {
2013 + struct net_device *physindev = skb->nf_bridge->physindev;
2014 + struct net_device *physoutdev = skb->nf_bridge->physoutdev;
2016 if (physindev && in != physindev)
2017 printk("PHYSIN=%s ", physindev->name);
2018 @@ -357,25 +359,56 @@
2020 /* MAC logging for input chain only. */
2022 - if ((*pskb)->dev && (*pskb)->dev->hard_header_len
2023 - && (*pskb)->mac.raw != (void*)(*pskb)->nh.iph) {
2024 + if (skb->dev && skb->dev->hard_header_len
2025 + && skb->mac.raw != (void*)skb->nh.iph) {
2027 - unsigned char *p = (*pskb)->mac.raw;
2028 - for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++)
2029 + unsigned char *p = skb->mac.raw;
2030 + for (i = 0; i < skb->dev->hard_header_len; i++,p++)
2031 printk("%02x%c", *p,
2032 - i==(*pskb)->dev->hard_header_len - 1
2033 + i==skb->dev->hard_header_len - 1
2039 - dump_packet(loginfo, *pskb, 0);
2040 + dump_packet(loginfo, skb, 0);
2042 spin_unlock_bh(&log_lock);
2045 +static unsigned int
2046 +ipt_log_target(struct sk_buff **pskb,
2047 + const struct net_device *in,
2048 + const struct net_device *out,
2049 + unsigned int hooknum,
2050 + const void *targinfo,
2053 + const struct ipt_log_info *loginfo = targinfo;
2054 + char level_string[4] = "< >";
2056 + level_string[1] = '0' + (loginfo->level % 8);
2057 + ipt_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL);
2059 return IPT_CONTINUE;
2063 +ipt_logfn(unsigned int hooknum,
2064 + const struct sk_buff *skb,
2065 + const struct net_device *in,
2066 + const struct net_device *out,
2067 + const char *prefix)
2069 + struct ipt_log_info loginfo = {
2071 + .logflags = IPT_LOG_MASK,
2075 + ipt_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
2078 static int ipt_log_checkentry(const char *tablename,
2079 const struct ipt_entry *e,
2081 @@ -413,11 +446,18 @@
2083 static int __init init(void)
2085 - return ipt_register_target(&ipt_log_reg);
2086 + if (ipt_register_target(&ipt_log_reg))
2089 + nf_log_register(PF_INET, &ipt_logfn);
2094 static void __exit fini(void)
2097 + nf_log_unregister(PF_INET, &ipt_logfn);
2098 ipt_unregister_target(&ipt_log_reg);
2101 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_NETLINK.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_NETLINK.c
2102 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_NETLINK.c 1970-01-01 01:00:00.000000000 +0100
2103 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_NETLINK.c 2004-03-30 11:10:39.000000000 +0200
2105 +#include <linux/module.h>
2106 +#include <linux/version.h>
2107 +#include <linux/config.h>
2108 +#include <linux/socket.h>
2109 +#include <linux/skbuff.h>
2110 +#include <linux/kernel.h>
2111 +#include <linux/netlink.h>
2112 +#include <linux/netdevice.h>
2113 +#include <linux/mm.h>
2114 +#include <linux/socket.h>
2115 +#include <linux/netfilter_ipv4/ip_tables.h>
2116 +#include <linux/netfilter_ipv4/ipt_NETLINK.h>
2117 +#include <net/sock.h>
2119 +MODULE_AUTHOR("Gianni Tedesco <gianni@ecsc.co.uk>");
2120 +MODULE_DESCRIPTION("Provides iptables NETLINK target similar to ipchains -o");
2121 +MODULE_LICENSE("GPL");
2124 +#define DEBUGP printk
2126 +#define DEBUGP(format, args...)
2129 +static struct sock *ipfwsk;
2131 +static unsigned int ipt_netlink_target(struct sk_buff **pskb,
2132 + unsigned int hooknum,
2133 + const struct net_device *in,
2134 + const struct net_device *out,
2135 + const void *targinfo, void *userinfo)
2137 + struct ipt_nldata *nld = (struct ipt_nldata *)targinfo;
2138 + struct iphdr *ip = (*pskb)->nh.iph;
2139 + struct sk_buff *outskb;
2140 + struct netlink_t nlhdr;
2143 + /* Allocate a socket buffer */
2144 + if ( MASK(nld->flags, USE_SIZE) )
2145 + len = nld->size+sizeof(nlhdr);
2147 + len = ntohs(ip->tot_len)+sizeof(nlhdr);
2149 + outskb=alloc_skb(len, GFP_ATOMIC);
2154 + if ( MASK(nld->flags, USE_MARK) )
2155 + nlhdr.mark=(*pskb)->nfmark=nld->mark;
2157 + nlhdr.mark=(*pskb)->nfmark;
2159 + if ( in && in->name ) {
2160 + strncpy((char *)&nlhdr.iface, in->name, IFNAMSIZ);
2161 + }else if ( out && out->name ){
2162 + strncpy((char *)&nlhdr.iface, out->name, IFNAMSIZ);
2165 + skb_put(outskb, len);
2166 + memcpy(outskb->data, &nlhdr, sizeof(nlhdr));
2167 + memcpy((outskb->data)+sizeof(nlhdr), ip, len-sizeof(nlhdr));
2168 + netlink_broadcast(ipfwsk, outskb, 0, ~0, GFP_ATOMIC);
2170 + if (net_ratelimit())
2171 + printk(KERN_WARNING "ipt_NETLINK: packet drop due to netlink failure\n");
2174 + if ( MASK(nld->flags, USE_DROP) )
2177 + return IPT_CONTINUE;
2180 +static int ipt_netlink_checkentry(const char *tablename,
2181 + const struct ipt_entry *e,
2183 + unsigned int targinfosize,
2184 + unsigned int hookmask)
2186 + //struct ipt_nldata *nld = (struct ipt_nldata *)targinfo;
2191 +static struct ipt_target ipt_netlink_reg = {
2194 + ipt_netlink_target,
2195 + ipt_netlink_checkentry,
2200 +static int __init init(void)
2202 + DEBUGP("ipt_NETLINK: init module\n");
2204 + if (ipt_register_target(&ipt_netlink_reg) != 0) {
2208 + if ( !(ipfwsk=netlink_kernel_create(NETLINK_FIREWALL, NULL)) ){
2215 +static void __exit fini(void)
2217 + DEBUGP("ipt_NETLINK: cleanup_module\n");
2218 + ipt_unregister_target(&ipt_netlink_reg);
2219 +// if(ipfwsk->socket) sock_release(ipfwsk->socket);
2224 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_NOTRACK.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_NOTRACK.c
2225 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_NOTRACK.c 1970-01-01 01:00:00.000000000 +0100
2226 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_NOTRACK.c 2004-03-30 11:11:27.000000000 +0200
2228 +/* This is a module which is used for setting up fake conntracks
2229 + * on packets so that they are not seen by the conntrack/NAT code.
2231 +#include <linux/module.h>
2232 +#include <linux/skbuff.h>
2234 +#include <linux/netfilter_ipv4/ip_tables.h>
2235 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2237 +static unsigned int
2238 +target(struct sk_buff **pskb,
2239 + const struct net_device *in,
2240 + const struct net_device *out,
2241 + unsigned int hooknum,
2242 + const void *targinfo,
2245 + /* Previously seen (loopback)? Ignore. */
2246 + if ((*pskb)->nfct != NULL)
2247 + return IPT_CONTINUE;
2249 + /* Attach fake conntrack entry.
2250 + If there is a real ct entry correspondig to this packet,
2251 + it'll hang aroun till timing out. We don't deal with it
2252 + for performance reasons. JK */
2253 + (*pskb)->nfct = &ip_conntrack_untracked.infos[IP_CT_NEW];
2254 + nf_conntrack_get((*pskb)->nfct);
2256 + return IPT_CONTINUE;
2260 +checkentry(const char *tablename,
2261 + const struct ipt_entry *e,
2263 + unsigned int targinfosize,
2264 + unsigned int hook_mask)
2266 + if (targinfosize != 0) {
2267 + printk(KERN_WARNING "NOTRACK: targinfosize %u != 0\n",
2272 + if (strcmp(tablename, "raw") != 0) {
2273 + printk(KERN_WARNING "NOTRACK: can only be called from \"raw\" table, not \"%s\"\n", tablename);
2280 +static struct ipt_target ipt_notrack_reg = {
2281 + .name = "NOTRACK",
2283 + .checkentry = checkentry,
2287 +static int __init init(void)
2289 + if (ipt_register_target(&ipt_notrack_reg))
2295 +static void __exit fini(void)
2297 + ipt_unregister_target(&ipt_notrack_reg);
2302 +MODULE_LICENSE("GPL");
2303 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_POOL.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_POOL.c
2304 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_POOL.c 1970-01-01 01:00:00.000000000 +0100
2305 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_POOL.c 2004-03-30 11:11:17.000000000 +0200
2307 +/* ipt_POOL.c - netfilter target to manipulate IP pools
2309 + * This target can be used almost everywhere. It acts on some specified
2310 + * IP pool, adding or deleting some IP address in the pool. The address
2311 + * can be either the source (--addsrc, --delsrc), or destination (--add/deldst)
2312 + * of the packet under inspection.
2314 + * The target normally returns IPT_CONTINUE.
2317 +#include <linux/types.h>
2318 +#include <linux/ip.h>
2319 +#include <linux/timer.h>
2320 +#include <linux/module.h>
2321 +#include <linux/netfilter.h>
2322 +#include <linux/netdevice.h>
2323 +#include <linux/if.h>
2324 +#include <linux/inetdevice.h>
2325 +#include <net/protocol.h>
2326 +#include <net/checksum.h>
2327 +#include <linux/netfilter_ipv4.h>
2328 +#include <linux/netfilter_ipv4/ip_nat_rule.h>
2329 +#include <linux/netfilter_ipv4/ipt_pool.h>
2332 +#define DEBUGP printk
2334 +#define DEBUGP(format, args...)
2337 +/*** NOTE NOTE NOTE NOTE ***
2339 +** By sheer luck, I get away with using the "struct ipt_pool_info", as defined
2340 +** in <linux/netfilter_ipv4/ipt_pool.h>, both as the match and target info.
2341 +** Here, in the target implementation, ipt_pool_info.src, if not IP_POOL_NONE,
2342 +** is modified for the source IP address of the packet under inspection.
2343 +** The same way, the ipt_pool_info.dst pool is modified for the destination.
2345 +** The address is added to the pool normally. However, if IPT_POOL_DEL_dir
2346 +** flag is set in ipt_pool_info.flags, the address is deleted from the pool.
2348 +** If a modification was done to the pool, we possibly return ACCEPT or DROP,
2349 +** if the right IPT_POOL_MOD_dir_ACCEPT or _MOD_dir_DROP flags are set.
2350 +** The IPT_POOL_INV_MOD_dir flag inverts the sense of the check (i.e. the
2351 +** ACCEPT and DROP flags are evaluated when the pool was not modified.)
2355 +do_check(const char *tablename,
2356 + const struct ipt_entry *e,
2358 + unsigned int targinfosize,
2359 + unsigned int hook_mask)
2361 + const struct ipt_pool_info *ipi = targinfo;
2363 + if (targinfosize != IPT_ALIGN(sizeof(*ipi))) {
2364 + DEBUGP("POOL_check: size %u.\n", targinfosize);
2367 + DEBUGP("ipt_POOL:do_check(%d,%d,%d)\n",ipi->src,ipi->dst,ipi->flags);
2371 +static unsigned int
2372 +do_target(struct sk_buff **pskb,
2373 + unsigned int hooknum,
2374 + const struct net_device *in,
2375 + const struct net_device *out,
2376 + const void *targinfo,
2379 + const struct ipt_pool_info *ipi = targinfo;
2381 + unsigned int verdict = IPT_CONTINUE;
2383 + if (ipi->src != IP_POOL_NONE) {
2384 + modified = ip_pool_mod(ipi->src, ntohl((*pskb)->nh.iph->saddr),
2385 + ipi->flags & IPT_POOL_DEL_SRC);
2386 + if (!!modified ^ !!(ipi->flags & IPT_POOL_INV_MOD_SRC)) {
2387 + if (ipi->flags & IPT_POOL_MOD_SRC_ACCEPT)
2388 + verdict = NF_ACCEPT;
2389 + else if (ipi->flags & IPT_POOL_MOD_SRC_DROP)
2390 + verdict = NF_DROP;
2393 + if (verdict == IPT_CONTINUE && ipi->dst != IP_POOL_NONE) {
2394 + modified = ip_pool_mod(ipi->dst, ntohl((*pskb)->nh.iph->daddr),
2395 + ipi->flags & IPT_POOL_DEL_DST);
2396 + if (!!modified ^ !!(ipi->flags & IPT_POOL_INV_MOD_DST)) {
2397 + if (ipi->flags & IPT_POOL_MOD_DST_ACCEPT)
2398 + verdict = NF_ACCEPT;
2399 + else if (ipi->flags & IPT_POOL_MOD_DST_DROP)
2400 + verdict = NF_DROP;
2406 +static struct ipt_target pool_reg
2407 += { { NULL, NULL }, "POOL", do_target, do_check, NULL, THIS_MODULE };
2409 +static int __init init(void)
2411 + DEBUGP("init ipt_POOL\n");
2412 + return ipt_register_target(&pool_reg);
2415 +static void __exit fini(void)
2417 + DEBUGP("fini ipt_POOL\n");
2418 + ipt_unregister_target(&pool_reg);
2423 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_TTL.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_TTL.c
2424 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_TTL.c 1970-01-01 01:00:00.000000000 +0100
2425 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_TTL.c 2004-03-30 11:10:42.000000000 +0200
2427 +/* TTL modification target for IP tables
2428 + * (C) 2000 by Harald Welte <laforge@gnumonks.org>
2430 + * Version: $Revision$
2432 + * This software is distributed under the terms of GNU GPL
2435 +#include <linux/module.h>
2436 +#include <linux/skbuff.h>
2437 +#include <linux/ip.h>
2438 +#include <net/checksum.h>
2440 +#include <linux/netfilter_ipv4/ip_tables.h>
2441 +#include <linux/netfilter_ipv4/ipt_TTL.h>
2443 +MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
2444 +MODULE_DESCRIPTION("IP tables TTL modification module");
2445 +MODULE_LICENSE("GPL");
2447 +static unsigned int
2448 +ipt_ttl_target(struct sk_buff **pskb, const struct net_device *in,
2449 + const struct net_device *out, unsigned int hooknum,
2450 + const void *targinfo, void *userinfo)
2452 + struct iphdr *iph;
2453 + const struct ipt_TTL_info *info = targinfo;
2454 + u_int16_t diffs[2];
2457 + if (!skb_ip_make_writable(pskb, (*pskb)->len))
2460 + iph = (*pskb)->nh.iph;
2462 + switch (info->mode) {
2464 + new_ttl = info->ttl;
2467 + new_ttl = iph->ttl + info->ttl;
2468 + if (new_ttl > 255)
2472 + new_ttl = iph->ttl + info->ttl;
2477 + new_ttl = iph->ttl;
2481 + if (new_ttl != iph->ttl) {
2482 + diffs[0] = htons(((unsigned)iph->ttl) << 8) ^ 0xFFFF;
2483 + iph->ttl = new_ttl;
2484 + diffs[1] = htons(((unsigned)iph->ttl) << 8);
2485 + iph->check = csum_fold(csum_partial((char *)diffs,
2487 + iph->check^0xFFFF));
2488 + (*pskb)->nfcache |= NFC_ALTERED;
2491 + return IPT_CONTINUE;
2494 +static int ipt_ttl_checkentry(const char *tablename,
2495 + const struct ipt_entry *e,
2497 + unsigned int targinfosize,
2498 + unsigned int hook_mask)
2500 + struct ipt_TTL_info *info = targinfo;
2502 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_TTL_info))) {
2503 + printk(KERN_WARNING "TTL: targinfosize %u != %Zu\n",
2505 + IPT_ALIGN(sizeof(struct ipt_TTL_info)));
2509 + if (strcmp(tablename, "mangle")) {
2510 + printk(KERN_WARNING "TTL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
2514 + if (info->mode > IPT_TTL_MAXMODE) {
2515 + printk(KERN_WARNING "TTL: invalid or unknown Mode %u\n",
2520 + if ((info->mode != IPT_TTL_SET) && (info->ttl == 0)) {
2521 + printk(KERN_WARNING "TTL: increment/decrement doesn't make sense with value 0\n");
2528 +static struct ipt_target ipt_TTL = {
2530 + .target = ipt_ttl_target,
2531 + .checkentry = ipt_ttl_checkentry,
2535 +static int __init init(void)
2537 + return ipt_register_target(&ipt_TTL);
2540 +static void __exit fini(void)
2542 + ipt_unregister_target(&ipt_TTL);
2547 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_ULOG.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_ULOG.c
2548 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_ULOG.c 2004-03-30 05:26:06.000000000 +0200
2549 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_ULOG.c 2004-03-30 11:10:29.000000000 +0200
2551 #include <linux/netlink.h>
2552 #include <linux/netdevice.h>
2553 #include <linux/mm.h>
2554 +#include <linux/netfilter.h>
2555 #include <linux/netfilter_ipv4/ip_tables.h>
2556 #include <linux/netfilter_ipv4/ipt_ULOG.h>
2557 #include <linux/netfilter_ipv4/lockhelp.h>
2559 MODULE_PARM(flushtimeout, "i");
2560 MODULE_PARM_DESC(flushtimeout, "buffer flush timeout");
2562 +static unsigned int nflog = 1;
2563 +MODULE_PARM(nflog, "i");
2564 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
2566 /* global data structures */
2569 @@ -157,17 +162,17 @@
2573 -static unsigned int ipt_ulog_target(struct sk_buff **pskb,
2574 - const struct net_device *in,
2575 - const struct net_device *out,
2576 - unsigned int hooknum,
2577 - const void *targinfo, void *userinfo)
2578 +static void ipt_ulog_packet(unsigned int hooknum,
2579 + const struct sk_buff *skb,
2580 + const struct net_device *in,
2581 + const struct net_device *out,
2582 + const struct ipt_ulog_info *loginfo,
2583 + const char *prefix)
2586 ulog_packet_msg_t *pm;
2587 size_t size, copy_len;
2588 struct nlmsghdr *nlh;
2589 - struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
2591 /* ffs == find first bit set, necessary because userspace
2592 * is already shifting groupnumber, but we need unshifted.
2595 /* calculate the size of the skb needed */
2596 if ((loginfo->copy_range == 0) ||
2597 - (loginfo->copy_range > (*pskb)->len)) {
2598 - copy_len = (*pskb)->len;
2599 + (loginfo->copy_range > skb->len)) {
2600 + copy_len = skb->len;
2602 copy_len = loginfo->copy_range;
2604 @@ -214,19 +219,21 @@
2606 /* copy hook, prefix, timestamp, payload, etc. */
2607 pm->data_len = copy_len;
2608 - pm->timestamp_sec = (*pskb)->stamp.tv_sec;
2609 - pm->timestamp_usec = (*pskb)->stamp.tv_usec;
2610 - pm->mark = (*pskb)->nfmark;
2611 + pm->timestamp_sec = skb->stamp.tv_sec;
2612 + pm->timestamp_usec = skb->stamp.tv_usec;
2613 + pm->mark = skb->nfmark;
2615 - if (loginfo->prefix[0] != '\0')
2616 + if (prefix != NULL)
2617 + strncpy(pm->prefix, prefix, sizeof(pm->prefix));
2618 + else if (loginfo->prefix[0] != '\0')
2619 strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix));
2621 *(pm->prefix) = '\0';
2623 if (in && in->hard_header_len > 0
2624 - && (*pskb)->mac.raw != (void *) (*pskb)->nh.iph
2625 + && skb->mac.raw != (void *) skb->nh.iph
2626 && in->hard_header_len <= ULOG_MAC_LEN) {
2627 - memcpy(pm->mac, (*pskb)->mac.raw, in->hard_header_len);
2628 + memcpy(pm->mac, skb->mac.raw, in->hard_header_len);
2629 pm->mac_len = in->hard_header_len;
2634 pm->outdev_name[0] = '\0';
2636 - /* copy_len <= (*pskb)->len, so can't fail. */
2637 - if (skb_copy_bits(*pskb, 0, pm->payload, copy_len) < 0)
2638 + /* copy_len <= skb->len, so can't fail. */
2639 + if (skb_copy_bits(skb, 0, pm->payload, copy_len) < 0)
2642 /* check if we are building multi-part messages */
2645 UNLOCK_BH(&ulog_lock);
2647 - return IPT_CONTINUE;
2652 PRINTR("ipt_ULOG: error during NLMSG_PUT\n");
2653 @@ -276,8 +282,35 @@
2654 PRINTR("ipt_ULOG: Error building netlink message\n");
2656 UNLOCK_BH(&ulog_lock);
2659 +static unsigned int ipt_ulog_target(struct sk_buff **pskb,
2660 + const struct net_device *in,
2661 + const struct net_device *out,
2662 + unsigned int hooknum,
2663 + const void *targinfo, void *userinfo)
2665 + struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
2667 - return IPT_CONTINUE;
2668 + ipt_ulog_packet(hooknum, *pskb, in, out, loginfo, NULL);
2670 + return IPT_CONTINUE;
2673 +static void ipt_logfn(unsigned int hooknum,
2674 + const struct sk_buff *skb,
2675 + const struct net_device *in,
2676 + const struct net_device *out,
2677 + const char *prefix)
2679 + struct ipt_ulog_info loginfo = {
2680 + .nl_group = ULOG_DEFAULT_NLGROUP,
2682 + .qthreshold = ULOG_DEFAULT_QTHRESHOLD,
2686 + ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
2689 static int ipt_ulog_checkentry(const char *tablename,
2691 sock_release(nflognl->sk_socket);
2696 + nf_log_register(PF_INET, &ipt_logfn);
2703 DEBUGP("ipt_ULOG: cleanup_module\n");
2706 + nf_log_unregister(PF_INET, &ipt_logfn);
2707 ipt_unregister_target(&ipt_ulog_reg);
2708 sock_release(nflognl->sk_socket);
2710 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_connlimit.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_connlimit.c
2711 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_connlimit.c 1970-01-01 01:00:00.000000000 +0100
2712 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_connlimit.c 2004-03-30 11:10:45.000000000 +0200
2715 + * netfilter module to limit the number of parallel tcp
2716 + * connections per IP address.
2717 + * (c) 2000 Gerd Knorr <kraxel@bytesex.org>
2718 + * Nov 2002: Martin Bene <martin.bene@icomedias.com>:
2719 + * only ignore TIME_WAIT or gone connections
2723 + * Kernel module to match connection tracking information.
2724 + * GPL (C) 1999 Rusty Russell (rusty@rustcorp.com.au).
2726 +#include <linux/module.h>
2727 +#include <linux/skbuff.h>
2728 +#include <linux/list.h>
2729 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2730 +#include <linux/netfilter_ipv4/ip_conntrack_core.h>
2731 +#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
2732 +#include <linux/netfilter_ipv4/ip_tables.h>
2733 +#include <linux/netfilter_ipv4/ipt_connlimit.h>
2737 +MODULE_LICENSE("GPL");
2739 +/* we'll save the tuples of all connections we care about */
2740 +struct ipt_connlimit_conn
2742 + struct list_head list;
2743 + struct ip_conntrack_tuple tuple;
2746 +struct ipt_connlimit_data {
2748 + struct list_head iphash[256];
2751 +static int ipt_iphash(u_int32_t addr)
2755 + hash = addr & 0xff;
2756 + hash ^= (addr >> 8) & 0xff;
2757 + hash ^= (addr >> 16) & 0xff;
2758 + hash ^= (addr >> 24) & 0xff;
2762 +static int count_them(struct ipt_connlimit_data *data,
2763 + u_int32_t addr, u_int32_t mask,
2764 + struct ip_conntrack *ct)
2767 + const static char *tcp[] = { "none", "established", "syn_sent", "syn_recv",
2768 + "fin_wait", "time_wait", "close", "close_wait",
2769 + "last_ack", "listen" };
2771 + int addit = 1, matches = 0;
2772 + struct ip_conntrack_tuple tuple;
2773 + struct ip_conntrack_tuple_hash *found;
2774 + struct ipt_connlimit_conn *conn;
2775 + struct list_head *hash,*lh;
2777 + spin_lock(&data->lock);
2778 + tuple = ct->tuplehash[0].tuple;
2779 + hash = &data->iphash[ipt_iphash(addr & mask)];
2781 + /* check the saved connections */
2782 + for (lh = hash->next; lh != hash; lh = lh->next) {
2783 + conn = list_entry(lh,struct ipt_connlimit_conn,list);
2784 + found = ip_conntrack_find_get(&conn->tuple,ct);
2785 + if (0 == memcmp(&conn->tuple,&tuple,sizeof(tuple)) &&
2787 + found->ctrack->proto.tcp.state != TCP_CONNTRACK_TIME_WAIT) {
2788 + /* Just to be sure we have it only once in the list.
2789 + We should'nt see tuples twice unless someone hooks this
2790 + into a table without "-p tcp --syn" */
2794 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d %s\n",
2795 + ipt_iphash(addr & mask),
2796 + NIPQUAD(conn->tuple.src.ip), ntohs(conn->tuple.src.u.tcp.port),
2797 + NIPQUAD(conn->tuple.dst.ip), ntohs(conn->tuple.dst.u.tcp.port),
2798 + (NULL != found) ? tcp[found->ctrack->proto.tcp.state] : "gone");
2800 + if (NULL == found) {
2801 + /* this one is gone */
2803 + list_del(lh->next);
2807 + if (found->ctrack->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT) {
2808 + /* we don't care about connections which are
2809 + closed already -> ditch it */
2811 + list_del(lh->next);
2813 + nf_conntrack_put(&found->ctrack->infos[0]);
2816 + if ((addr & mask) == (conn->tuple.src.ip & mask)) {
2817 + /* same source IP address -> be counted! */
2820 + nf_conntrack_put(&found->ctrack->infos[0]);
2823 + /* save the new connection in our list */
2825 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d new\n",
2826 + ipt_iphash(addr & mask),
2827 + NIPQUAD(tuple.src.ip), ntohs(tuple.src.u.tcp.port),
2828 + NIPQUAD(tuple.dst.ip), ntohs(tuple.dst.u.tcp.port));
2830 + conn = kmalloc(sizeof(*conn),GFP_ATOMIC);
2833 + memset(conn,0,sizeof(*conn));
2834 + INIT_LIST_HEAD(&conn->list);
2835 + conn->tuple = tuple;
2836 + list_add(&conn->list,hash);
2839 + spin_unlock(&data->lock);
2844 +match(const struct sk_buff *skb,
2845 + const struct net_device *in,
2846 + const struct net_device *out,
2847 + const void *matchinfo,
2851 + const struct ipt_connlimit_info *info = matchinfo;
2852 + int connections, match;
2853 + struct ip_conntrack *ct;
2854 + enum ip_conntrack_info ctinfo;
2856 + ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
2858 + printk("ipt_connlimit: Oops: invalid ct state ?\n");
2862 + connections = count_them(info->data,skb->nh.iph->saddr,info->mask,ct);
2863 + if (-1 == connections) {
2864 + printk("ipt_connlimit: Hmm, kmalloc failed :-(\n");
2865 + *hotdrop = 1; /* let's free some memory :-) */
2868 + match = (info->inverse) ? (connections <= info->limit) : (connections > info->limit);
2870 + printk("ipt_connlimit: src=%u.%u.%u.%u mask=%u.%u.%u.%u "
2871 + "connections=%d limit=%d match=%s\n",
2872 + NIPQUAD(skb->nh.iph->saddr), NIPQUAD(info->mask),
2873 + connections, info->limit, match ? "yes" : "no");
2879 +static int check(const char *tablename,
2880 + const struct ipt_ip *ip,
2882 + unsigned int matchsize,
2883 + unsigned int hook_mask)
2885 + struct ipt_connlimit_info *info = matchinfo;
2889 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_connlimit_info)))
2892 + /* refuse anything but tcp */
2893 + if (ip->proto != IPPROTO_TCP)
2896 + /* init private data */
2897 + info->data = kmalloc(sizeof(struct ipt_connlimit_data),GFP_KERNEL);
2898 + spin_lock_init(&(info->data->lock));
2899 + for (i = 0; i < 256; i++)
2900 + INIT_LIST_HEAD(&(info->data->iphash[i]));
2905 +static void destroy(void *matchinfo, unsigned int matchinfosize)
2907 + struct ipt_connlimit_info *info = matchinfo;
2908 + struct ipt_connlimit_conn *conn;
2909 + struct list_head *hash;
2913 + for (i = 0; i < 256; i++) {
2914 + hash = &(info->data->iphash[i]);
2915 + while (hash != hash->next) {
2916 + conn = list_entry(hash->next,struct ipt_connlimit_conn,list);
2917 + list_del(hash->next);
2921 + kfree(info->data);
2924 +static struct ipt_match connlimit_match = {
2925 + .name = "connlimit",
2927 + .checkentry = &check,
2928 + .destroy = &destroy,
2932 +static int __init init(void)
2934 + return ipt_register_match(&connlimit_match);
2937 +static void __exit fini(void)
2939 + ipt_unregister_match(&connlimit_match);
2944 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_conntrack.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_conntrack.c
2945 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_conntrack.c 2004-03-30 05:27:15.000000000 +0200
2946 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_conntrack.c 2004-03-30 11:11:27.000000000 +0200
2949 #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
2952 - statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
2954 - statebit = IPT_CONNTRACK_STATE_INVALID;
2956 + if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
2957 + statebit = IPT_CONNTRACK_STATE_UNTRACKED;
2959 + statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
2961 + statebit = IPT_CONNTRACK_STATE_INVALID;
2963 if(sinfo->flags & IPT_CONNTRACK_STATE) {
2965 if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip !=
2966 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_dstlimit.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_dstlimit.c
2967 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_dstlimit.c 1970-01-01 01:00:00.000000000 +0100
2968 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_dstlimit.c 2004-03-30 11:10:47.000000000 +0200
2970 +/* iptables match extension to limit the number of packets per second
2971 + * seperately for each destination.
2973 + * (C) 2003 by Harald Welte <laforge@netfilter.org>
2977 + * Development of this code was funded by Astaro AG, http://www.astaro.com/
2979 + * based on ipt_limit.c by:
2980 + * Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
2981 + * Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
2982 + * Rusty Russell <rusty@rustcorp.com.au>
2984 + * The general idea is to create a hash table for every dstip and have a
2985 + * seperate limit counter per tuple. This way you can do something like 'limit
2986 + * the number of syn packets for each of my internal addresses.
2988 + * Ideally this would just be implemented as a general 'hash' match, which would
2989 + * allow us to attach any iptables target to it's hash buckets. But this is
2990 + * not possible in the current iptables architecture. As always, pkttables for
2991 + * 2.7.x will help ;)
2993 +#include <linux/module.h>
2994 +#include <linux/skbuff.h>
2995 +#include <linux/spinlock.h>
2996 +#include <linux/random.h>
2997 +#include <linux/jhash.h>
2998 +#include <linux/slab.h>
2999 +#include <linux/vmalloc.h>
3000 +#include <linux/tcp.h>
3001 +#include <linux/udp.h>
3002 +#include <linux/proc_fs.h>
3003 +#include <linux/seq_file.h>
3005 +#define ASSERT_READ_LOCK(x)
3006 +#define ASSERT_WRITE_LOCK(x)
3007 +#include <linux/netfilter_ipv4/lockhelp.h>
3008 +#include <linux/netfilter_ipv4/listhelp.h>
3010 +#include <linux/netfilter_ipv4/ip_tables.h>
3011 +#include <linux/netfilter_ipv4/ipt_dstlimit.h>
3013 +/* FIXME: this is just for IP_NF_ASSERRT */
3014 +#include <linux/netfilter_ipv4/ip_conntrack.h>
3016 +#define MS2JIFFIES(x) ((x*HZ)/1000)
3018 +MODULE_LICENSE("GPL");
3019 +MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
3020 +MODULE_DESCRIPTION("iptables match for limiting per destination");
3022 +/* need to declare this at the top */
3023 +static struct proc_dir_entry *dstlimit_procdir;
3024 +static struct file_operations dl_file_ops;
3026 +/* hash table crap */
3028 +struct dsthash_dst {
3034 +struct dsthash_ent {
3035 + /* static / read-only parts in the beginning */
3036 + struct list_head list;
3037 + struct dsthash_dst dst;
3039 + /* modified structure members in the end */
3040 + unsigned long expires; /* precalculated expiry time */
3042 + unsigned long prev; /* last modification */
3044 + u_int32_t credit_cap, cost;
3048 +struct ipt_dstlimit_htable {
3049 + struct list_head list; /* global list of all htables */
3052 + struct dstlimit_cfg cfg; /* config */
3054 + /* used internally */
3055 + spinlock_t lock; /* lock for list_head */
3056 + u_int32_t rnd; /* random seed for hash */
3057 + struct timer_list timer; /* timer for gc */
3058 + atomic_t count; /* number entries in table */
3060 + /* seq_file stuff */
3061 + struct proc_dir_entry *pde;
3063 + struct list_head hash[0]; /* hashtable itself */
3066 +DECLARE_RWLOCK(dstlimit_lock); /* protects htables list */
3067 +static LIST_HEAD(dstlimit_htables);
3068 +static kmem_cache_t *dstlimit_cachep;
3070 +static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b)
3072 + return (ent->dst.dst_ip == b->dst_ip
3073 + && ent->dst.port == b->port
3074 + && ent->dst.src_ip == b->src_ip);
3077 +static inline u_int32_t
3078 +hash_dst(const struct ipt_dstlimit_htable *ht, const struct dsthash_dst *dst)
3080 + return (jhash_3words(dst->dst_ip, dst->port,
3081 + dst->src_ip, ht->rnd) % ht->cfg.size);
3084 +static inline struct dsthash_ent *
3085 +__dsthash_find(const struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
3087 + struct dsthash_ent *ent;
3088 + u_int32_t hash = hash_dst(ht, dst);
3089 + MUST_BE_LOCKED(&ht->lock);
3090 + ent = LIST_FIND(&ht->hash[hash], dst_cmp, struct dsthash_ent *, dst);
3094 +/* allocate dsthash_ent, initialize dst, put in htable and lock it */
3095 +static struct dsthash_ent *
3096 +__dsthash_alloc_init(struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
3098 + struct dsthash_ent *ent;
3100 + /* initialize hash with random val at the time we allocate
3101 + * the first hashtable entry */
3103 + get_random_bytes(&ht->rnd, 4);
3105 + if (ht->cfg.max &&
3106 + atomic_read(&ht->count) >= ht->cfg.max) {
3107 + /* FIXME: do something. question is what.. */
3108 + if (net_ratelimit())
3109 + printk(KERN_WARNING
3110 + "ipt_dstlimit: max count of %u reached\n",
3115 + ent = kmem_cache_alloc(dstlimit_cachep, GFP_ATOMIC);
3117 + if (net_ratelimit())
3119 + "ipt_dstlimit: can't allocate dsthash_ent\n");
3123 + atomic_inc(&ht->count);
3125 + ent->dst.dst_ip = dst->dst_ip;
3126 + ent->dst.port = dst->port;
3127 + ent->dst.src_ip = dst->src_ip;
3129 + list_add(&ent->list, &ht->hash[hash_dst(ht, dst)]);
3135 +__dsthash_free(struct ipt_dstlimit_htable *ht, struct dsthash_ent *ent)
3137 + MUST_BE_LOCKED(&ht->lock);
3139 + list_del(&ent->list);
3140 + kmem_cache_free(dstlimit_cachep, ent);
3141 + atomic_dec(&ht->count);
3143 +static void htable_gc(unsigned long htlong);
3145 +static int htable_create(struct ipt_dstlimit_info *minfo)
3148 + unsigned int size;
3149 + struct ipt_dstlimit_htable *hinfo;
3151 + if (minfo->cfg.size)
3152 + size = minfo->cfg.size;
3154 + size = (((num_physpages << PAGE_SHIFT) / 16384)
3155 + / sizeof(struct list_head));
3156 + if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
3161 + /* FIXME: don't use vmalloc() here or anywhere else -HW */
3162 + hinfo = vmalloc(sizeof(struct ipt_dstlimit_htable)
3163 + + (sizeof(struct list_head) * size));
3165 + printk(KERN_ERR "ipt_dstlimit: Unable to create hashtable\n");
3168 + minfo->hinfo = hinfo;
3170 + /* copy match config into hashtable config */
3171 + memcpy(&hinfo->cfg, &minfo->cfg, sizeof(hinfo->cfg));
3172 + hinfo->cfg.size = size;
3173 + if (!hinfo->cfg.max)
3174 + hinfo->cfg.max = 8 * hinfo->cfg.size;
3175 + else if (hinfo->cfg.max < hinfo->cfg.size)
3176 + hinfo->cfg.max = hinfo->cfg.size;
3178 + for (i = 0; i < hinfo->cfg.size; i++)
3179 + INIT_LIST_HEAD(&hinfo->hash[i]);
3181 + atomic_set(&hinfo->count, 0);
3182 + atomic_set(&hinfo->use, 1);
3184 + hinfo->lock = SPIN_LOCK_UNLOCKED;
3185 + hinfo->pde = create_proc_entry(minfo->name, 0, dstlimit_procdir);
3186 + if (!hinfo->pde) {
3190 + hinfo->pde->proc_fops = &dl_file_ops;
3191 + hinfo->pde->data = hinfo;
3193 + init_timer(&hinfo->timer);
3194 + hinfo->timer.expires = jiffies + MS2JIFFIES(hinfo->cfg.gc_interval);
3195 + hinfo->timer.data = (unsigned long )hinfo;
3196 + hinfo->timer.function = htable_gc;
3197 + add_timer(&hinfo->timer);
3199 + WRITE_LOCK(&dstlimit_lock);
3200 + list_add(&hinfo->list, &dstlimit_htables);
3201 + WRITE_UNLOCK(&dstlimit_lock);
3206 +static int select_all(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
3211 +static int select_gc(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
3213 + return (jiffies >= he->expires);
3216 +static void htable_selective_cleanup(struct ipt_dstlimit_htable *ht,
3217 + int (*select)(struct ipt_dstlimit_htable *ht,
3218 + struct dsthash_ent *he))
3222 + IP_NF_ASSERT(ht->cfg.size && ht->cfg.max);
3224 + /* lock hash table and iterate over it */
3225 + LOCK_BH(&ht->lock);
3226 + for (i = 0; i < ht->cfg.size; i++) {
3227 + struct dsthash_ent *dh, *n;
3228 + list_for_each_entry_safe(dh, n, &ht->hash[i], list) {
3229 + if ((*select)(ht, dh))
3230 + __dsthash_free(ht, dh);
3233 + UNLOCK_BH(&ht->lock);
3236 +/* hash table garbage collector, run by timer */
3237 +static void htable_gc(unsigned long htlong)
3239 + struct ipt_dstlimit_htable *ht = (struct ipt_dstlimit_htable *)htlong;
3241 + htable_selective_cleanup(ht, select_gc);
3243 + /* re-add the timer accordingly */
3244 + ht->timer.expires = jiffies + MS2JIFFIES(ht->cfg.gc_interval);
3245 + add_timer(&ht->timer);
3248 +static void htable_destroy(struct ipt_dstlimit_htable *hinfo)
3250 + /* remove timer, if it is pending */
3251 + if (timer_pending(&hinfo->timer))
3252 + del_timer(&hinfo->timer);
3254 + /* remove proc entry */
3255 + remove_proc_entry(hinfo->pde->name, dstlimit_procdir);
3257 + htable_selective_cleanup(hinfo, select_all);
3261 +static struct ipt_dstlimit_htable *htable_find_get(char *name)
3263 + struct ipt_dstlimit_htable *hinfo;
3265 + READ_LOCK(&dstlimit_lock);
3266 + list_for_each_entry(hinfo, &dstlimit_htables, list) {
3267 + if (!strcmp(name, hinfo->pde->name)) {
3268 + atomic_inc(&hinfo->use);
3269 + READ_UNLOCK(&dstlimit_lock);
3273 + READ_UNLOCK(&dstlimit_lock);
3278 +static void htable_put(struct ipt_dstlimit_htable *hinfo)
3280 + if (atomic_dec_and_test(&hinfo->use)) {
3281 + WRITE_LOCK(&dstlimit_lock);
3282 + list_del(&hinfo->list);
3283 + WRITE_UNLOCK(&dstlimit_lock);
3284 + htable_destroy(hinfo);
3289 +/* The algorithm used is the Simple Token Bucket Filter (TBF)
3290 + * see net/sched/sch_tbf.c in the linux source tree
3293 +/* Rusty: This is my (non-mathematically-inclined) understanding of
3294 + this algorithm. The `average rate' in jiffies becomes your initial
3295 + amount of credit `credit' and the most credit you can ever have
3296 + `credit_cap'. The `peak rate' becomes the cost of passing the
3299 + `prev' tracks the last packet hit: you gain one credit per jiffy.
3300 + If you get credit balance more than this, the extra credit is
3301 + discarded. Every time the match passes, you lose `cost' credits;
3302 + if you don't have that many, the test fails.
3304 + See Alexey's formal explanation in net/sched/sch_tbf.c.
3306 + To get the maximum range, we multiply by this factor (ie. you get N
3307 + credits per jiffy). We want to allow a rate as low as 1 per day
3308 + (slowest userspace tool allows), which means
3309 + CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32 ie.
3311 +#define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24))
3313 +/* Repeated shift and or gives us all 1s, final shift and add 1 gives
3314 + * us the power of 2 below the theoretical max, so GCC simply does a
3316 +#define _POW2_BELOW2(x) ((x)|((x)>>1))
3317 +#define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2))
3318 +#define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4))
3319 +#define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8))
3320 +#define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16))
3321 +#define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1)
3323 +#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
3325 +/* Precision saver. */
3326 +static inline u_int32_t
3327 +user2credits(u_int32_t user)
3329 + /* If multiplying would overflow... */
3330 + if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY))
3331 + /* Divide first. */
3332 + return (user / IPT_DSTLIMIT_SCALE) * HZ * CREDITS_PER_JIFFY;
3334 + return (user * HZ * CREDITS_PER_JIFFY) / IPT_DSTLIMIT_SCALE;
3337 +static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
3339 + dh->rateinfo.credit += (now - xchg(&dh->rateinfo.prev, now))
3340 + * CREDITS_PER_JIFFY;
3341 + if (dh->rateinfo.credit > dh->rateinfo.credit_cap)
3342 + dh->rateinfo.credit = dh->rateinfo.credit_cap;
3346 +dstlimit_match(const struct sk_buff *skb,
3347 + const struct net_device *in,
3348 + const struct net_device *out,
3349 + const void *matchinfo,
3353 + struct ipt_dstlimit_info *r =
3354 + ((struct ipt_dstlimit_info *)matchinfo)->u.master;
3355 + struct ipt_dstlimit_htable *hinfo = r->hinfo;
3356 + unsigned long now = jiffies;
3357 + struct dsthash_ent *dh;
3358 + struct dsthash_dst dst;
3360 + memset(&dst, 0, sizeof(dst));
3362 + /* dest ip is always in hash */
3363 + dst.dst_ip = skb->nh.iph->daddr;
3365 + /* source ip only if respective hashmode, otherwise set to
3367 + if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_SIP)
3368 + dst.src_ip = skb->nh.iph->saddr;
3370 + /* dest port only if respective mode */
3371 + if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_DPT) {
3374 + /* Must not be a fragment. */
3378 + /* Must be big enough to read ports (both UDP and TCP have
3379 + them at the start). */
3380 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
3381 + /* We've been asked to examine this packet, and we
3382 + can't. Hence, no choice but to drop. */
3387 + switch (skb->nh.iph->protocol) {
3388 + struct tcphdr *th;
3389 + struct udphdr *uh;
3391 + th = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
3392 + dst.port = th->dest;
3395 + uh = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
3396 + dst.port = uh->dest;
3403 + LOCK_BH(&hinfo->lock);
3404 + dh = __dsthash_find(hinfo, &dst);
3406 + dh = __dsthash_alloc_init(hinfo, &dst);
3409 + /* enomem... don't match == DROP */
3410 + if (net_ratelimit())
3411 + printk(KERN_ERR "%s: ENOMEM\n", __FUNCTION__);
3412 + UNLOCK_BH(&hinfo->lock);
3416 + dh->expires = jiffies + MS2JIFFIES(hinfo->cfg.expire);
3418 + dh->rateinfo.prev = jiffies;
3419 + dh->rateinfo.credit = user2credits(hinfo->cfg.avg *
3420 + hinfo->cfg.burst);
3421 + dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg *
3422 + hinfo->cfg.burst);
3423 + dh->rateinfo.cost = user2credits(hinfo->cfg.avg);
3425 + UNLOCK_BH(&hinfo->lock);
3429 + /* update expiration timeout */
3430 + dh->expires = now + MS2JIFFIES(hinfo->cfg.expire);
3432 + rateinfo_recalc(dh, now);
3433 + if (dh->rateinfo.credit >= dh->rateinfo.cost) {
3434 + /* We're underlimit. */
3435 + dh->rateinfo.credit -= dh->rateinfo.cost;
3436 + UNLOCK_BH(&hinfo->lock);
3440 + UNLOCK_BH(&hinfo->lock);
3442 + /* default case: we're overlimit, thus don't match */
3447 +dstlimit_checkentry(const char *tablename,
3448 + const struct ipt_ip *ip,
3450 + unsigned int matchsize,
3451 + unsigned int hook_mask)
3453 + struct ipt_dstlimit_info *r = matchinfo;
3455 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_dstlimit_info)))
3458 + /* Check for overflow. */
3459 + if (r->cfg.burst == 0
3460 + || user2credits(r->cfg.avg * r->cfg.burst) <
3461 + user2credits(r->cfg.avg)) {
3462 + printk(KERN_ERR "ipt_dstlimit: Overflow, try lower: %u/%u\n",
3463 + r->cfg.avg, r->cfg.burst);
3467 + if (r->cfg.mode == 0
3468 + || r->cfg.mode > (IPT_DSTLIMIT_HASH_DPT
3469 + |IPT_DSTLIMIT_HASH_DIP
3470 + |IPT_DSTLIMIT_HASH_SIP))
3473 + if (!r->cfg.gc_interval)
3476 + if (!r->cfg.expire)
3479 + r->hinfo = htable_find_get(r->name);
3480 + if (!r->hinfo && (htable_create(r) != 0)) {
3484 + /* Ugly hack: For SMP, we only want to use one set */
3491 +dstlimit_destroy(void *matchinfo, unsigned int matchsize)
3493 + struct ipt_dstlimit_info *r = (struct ipt_dstlimit_info *) matchinfo;
3495 + htable_put(r->hinfo);
3498 +static struct ipt_match ipt_dstlimit = {
3499 + .list = { .prev = NULL, .next = NULL },
3500 + .name = "dstlimit",
3501 + .match = dstlimit_match,
3502 + .checkentry = dstlimit_checkentry,
3503 + .destroy = dstlimit_destroy,
3509 +static void *dl_seq_start(struct seq_file *s, loff_t *pos)
3511 + struct proc_dir_entry *pde = s->private;
3512 + struct ipt_dstlimit_htable *htable = pde->data;
3513 + unsigned int *bucket;
3515 + LOCK_BH(&htable->lock);
3516 + if (*pos >= htable->cfg.size)
3519 + bucket = kmalloc(sizeof(unsigned int), GFP_KERNEL);
3521 + return ERR_PTR(-ENOMEM);
3527 +static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
3529 + struct proc_dir_entry *pde = s->private;
3530 + struct ipt_dstlimit_htable *htable = pde->data;
3531 + unsigned int *bucket = (unsigned int *)v;
3533 + *pos = ++(*bucket);
3534 + if (*pos >= htable->cfg.size) {
3541 +static void dl_seq_stop(struct seq_file *s, void *v)
3543 + struct proc_dir_entry *pde = s->private;
3544 + struct ipt_dstlimit_htable *htable = pde->data;
3545 + unsigned int *bucket = (unsigned int *)v;
3549 + UNLOCK_BH(&htable->lock);
3552 +static inline int dl_seq_real_show(struct dsthash_ent *ent, struct seq_file *s)
3554 + /* recalculate to show accurate numbers */
3555 + rateinfo_recalc(ent, jiffies);
3557 + return seq_printf(s, "%ld %u.%u.%u.%u->%u.%u.%u.%u:%u %u %u %u\n",
3558 + (ent->expires - jiffies)/HZ,
3559 + NIPQUAD(ent->dst.src_ip),
3560 + NIPQUAD(ent->dst.dst_ip), ntohs(ent->dst.port),
3561 + ent->rateinfo.credit, ent->rateinfo.credit_cap,
3562 + ent->rateinfo.cost);
3565 +static int dl_seq_show(struct seq_file *s, void *v)
3567 + struct proc_dir_entry *pde = s->private;
3568 + struct ipt_dstlimit_htable *htable = pde->data;
3569 + unsigned int *bucket = (unsigned int *)v;
3571 + if (LIST_FIND_W(&htable->hash[*bucket], dl_seq_real_show,
3572 + struct dsthash_ent *, s)) {
3573 + /* buffer was filled and unable to print that tuple */
3579 +static struct seq_operations dl_seq_ops = {
3580 + .start = dl_seq_start,
3581 + .next = dl_seq_next,
3582 + .stop = dl_seq_stop,
3583 + .show = dl_seq_show
3586 +static int dl_proc_open(struct inode *inode, struct file *file)
3588 + int ret = seq_open(file, &dl_seq_ops);
3591 + struct seq_file *sf = file->private_data;
3592 + sf->private = PDE(inode);
3597 +static struct file_operations dl_file_ops = {
3598 + .owner = THIS_MODULE,
3599 + .open = dl_proc_open,
3601 + .llseek = seq_lseek,
3602 + .release = seq_release
3605 +static int init_or_fini(int fini)
3612 + if (ipt_register_match(&ipt_dstlimit)) {
3614 + goto cleanup_nothing;
3617 + /* FIXME: do we really want HWCACHE_ALIGN since our objects are
3618 + * quite small ? */
3619 + dstlimit_cachep = kmem_cache_create("ipt_dstlimit",
3620 + sizeof(struct dsthash_ent), 0,
3621 + SLAB_HWCACHE_ALIGN, NULL, NULL);
3622 + if (!dstlimit_cachep) {
3623 + printk(KERN_ERR "Unable to create ipt_dstlimit slab cache\n");
3625 + goto cleanup_unreg_match;
3628 + dstlimit_procdir = proc_mkdir("ipt_dstlimit", proc_net);
3629 + if (!dstlimit_procdir) {
3630 + printk(KERN_ERR "Unable to create proc dir entry\n");
3632 + goto cleanup_free_slab;
3638 + remove_proc_entry("ipt_dstlimit", proc_net);
3640 + kmem_cache_destroy(dstlimit_cachep);
3641 +cleanup_unreg_match:
3642 + ipt_unregister_match(&ipt_dstlimit);
3648 +static int __init init(void)
3650 + return init_or_fini(0);
3653 +static void __exit fini(void)
3660 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_fuzzy.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_fuzzy.c
3661 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_fuzzy.c 1970-01-01 01:00:00.000000000 +0100
3662 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_fuzzy.c 2004-03-30 11:11:06.000000000 +0200
3665 + * This module implements a simple TSK FLC
3666 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
3667 + * to limit , in an adaptive and flexible way , the packet rate crossing
3668 + * a given stream . It serves as an initial and very simple (but effective)
3669 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
3670 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
3671 + * into our code in a precise , adaptive and efficient manner.
3672 + * The goal is very similar to that of "limit" match , but using techniques of
3673 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
3674 + * avoiding over and undershoots - and stuff like that .
3677 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
3678 + * 2002-08-17 : Changed to eliminate floating point operations .
3679 + * 2002-08-23 : Coding style changes .
3682 +#include <linux/module.h>
3683 +#include <linux/skbuff.h>
3684 +#include <linux/ip.h>
3685 +#include <linux/random.h>
3686 +#include <net/tcp.h>
3687 +#include <linux/spinlock.h>
3688 +#include <linux/netfilter_ipv4/ip_tables.h>
3689 +#include <linux/netfilter_ipv4/ipt_fuzzy.h>
3692 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
3693 + Expressed in percentage
3696 +#define PAR_LOW 1/100
3699 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED ;
3701 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
3702 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
3703 +MODULE_LICENSE("GPL");
3705 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
3713 + return ( (100*(tx-mini)) / (maxi-mini) );
3716 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
3724 + return ( (100*( maxi - tx )) / ( maxi - mini ) );
3728 +ipt_fuzzy_match(const struct sk_buff *pskb,
3729 + const struct net_device *in,
3730 + const struct net_device *out,
3731 + const void *matchinfo,
3735 + /* From userspace */
3737 + struct ipt_fuzzy_info *info = (struct ipt_fuzzy_info *) matchinfo;
3739 + u_int8_t random_number;
3740 + unsigned long amount;
3741 + u_int8_t howhigh, howlow;
3744 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
3746 + info->bytes_total += pskb->len;
3747 + info->packets_total++;
3749 + info->present_time = jiffies;
3751 + if (info->present_time >= info->previous_time)
3752 + amount = info->present_time - info->previous_time;
3754 + /* There was a transition : I choose to re-sample
3755 + and keep the old acceptance rate...
3759 + info->previous_time = info->present_time;
3760 + info->bytes_total = info->packets_total = 0;
3763 + if (amount > HZ/10) /* More than 100 ms elapsed ... */
3766 + info->mean_rate = (u_int32_t) ((HZ*info->packets_total) \
3769 + info->previous_time = info->present_time;
3770 + info->bytes_total = info->packets_total = 0;
3772 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
3773 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
3775 + info->acceptance_rate = (u_int8_t) \
3776 + (howhigh*PAR_LOW + PAR_HIGH*howlow);
3778 + /* In fact , the above defuzzification would require a denominator
3779 + proportional to (howhigh+howlow) but , in this particular case ,
3780 + that expression is constant .
3781 + An imediate consequence is that it isn't necessary to call
3782 + both mf_high and mf_low - but to keep things understandable ,
3787 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
3790 + if ( info->acceptance_rate < 100 )
3792 + get_random_bytes((void *)(&random_number), 1);
3794 + /* If within the acceptance , it can pass => don't match */
3795 + if (random_number <= (255 * info->acceptance_rate) / 100)
3798 + return 1; /* It can't pass ( It matches ) */
3801 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
3806 +ipt_fuzzy_checkentry(const char *tablename,
3807 + const struct ipt_ip *e,
3809 + unsigned int matchsize,
3810 + unsigned int hook_mask)
3813 + const struct ipt_fuzzy_info *info = matchinfo;
3815 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_fuzzy_info))) {
3816 + printk("ipt_fuzzy: matchsize %u != %u\n", matchsize,
3817 + IPT_ALIGN(sizeof(struct ipt_fuzzy_info)));
3821 + if ((info->minimum_rate < MINFUZZYRATE ) || (info->maximum_rate > MAXFUZZYRATE)
3822 + || (info->minimum_rate >= info->maximum_rate )) {
3823 + printk("ipt_fuzzy: BAD limits , please verify !!!\n");
3830 +static struct ipt_match ipt_fuzzy_reg = {
3832 + .match = ipt_fuzzy_match,
3833 + .checkentry = ipt_fuzzy_checkentry,
3837 +static int __init init(void)
3839 + return ipt_register_match(&ipt_fuzzy_reg);
3842 +static void __exit fini(void)
3844 + ipt_unregister_match(&ipt_fuzzy_reg);
3849 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_helper.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_helper.c
3850 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_helper.c 2004-03-30 05:26:56.000000000 +0200
3851 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_helper.c 2004-03-30 11:10:11.000000000 +0200
3853 struct ip_conntrack_expect *exp;
3854 struct ip_conntrack *ct;
3855 enum ip_conntrack_info ctinfo;
3857 + int ret = info->invert;
3859 ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
3861 DEBUGP("ipt_helper: Eek! invalid conntrack?\n");
3867 DEBUGP("ipt_helper: conntrack %p has no master\n", ct);
3874 DEBUGP("master's name = %s , info->name = %s\n",
3875 exp->expectant->helper->name, info->name);
3877 - ret = !strncmp(exp->expectant->helper->name, info->name,
3878 - strlen(exp->expectant->helper->name)) ^ info->invert;
3879 + ret ^= !strncmp(exp->expectant->helper->name, info->name,
3880 + strlen(exp->expectant->helper->name));
3882 READ_UNLOCK(&ip_conntrack_lock);
3886 static int __init init(void)
3888 - need_ip_conntrack();
3889 return ipt_register_match(&helper_match);
3892 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_ipv4options.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_ipv4options.c
3893 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_ipv4options.c 1970-01-01 01:00:00.000000000 +0100
3894 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_ipv4options.c 2004-03-30 11:11:08.000000000 +0200
3897 + This is a module which is used to match ipv4 options.
3898 + This file is distributed under the terms of the GNU General Public
3899 + License (GPL). Copies of the GPL can be obtained from:
3900 + ftp://prep.ai.mit.edu/pub/gnu/GPL
3902 + 11-mars-2001 Fabrice MARIE <fabrice@netfilter.org> : initial development.
3903 + 12-july-2001 Fabrice MARIE <fabrice@netfilter.org> : added router-alert otions matching. Fixed a bug with no-srr
3904 + 12-august-2001 Imran Patel <ipatel@crosswinds.net> : optimization of the match.
3905 + 18-november-2001 Fabrice MARIE <fabrice@netfilter.org> : added [!] 'any' option match.
3906 + 19-february-2004 Harald Welte <laforge@netfilter.org> : merge with 2.6.x
3909 +#include <linux/module.h>
3910 +#include <linux/skbuff.h>
3911 +#include <net/ip.h>
3913 +#include <linux/netfilter_ipv4/ip_tables.h>
3914 +#include <linux/netfilter_ipv4/ipt_ipv4options.h>
3916 +MODULE_LICENSE("GPL");
3917 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
3920 +match(const struct sk_buff *skb,
3921 + const struct net_device *in,
3922 + const struct net_device *out,
3923 + const void *matchinfo,
3927 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
3928 + const struct iphdr *iph = skb->nh.iph;
3929 + const struct ip_options *opt;
3931 + if (iph->ihl * 4 == sizeof(struct iphdr)) {
3932 + /* No options, so we match only the "DONTs" and the "IGNOREs" */
3934 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) ||
3935 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3936 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
3937 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
3938 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
3939 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
3944 + if ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)
3945 + /* there are options, and we don't need to care which one */
3948 + if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
3949 + /* there are options but we don't want any ! */
3954 + opt = &(IPCB(skb)->opt);
3956 + /* source routing */
3957 + if ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) {
3958 + if (!((opt->srr) & (opt->is_strictroute)))
3961 + else if ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) {
3962 + if (!((opt->srr) & (!opt->is_strictroute)))
3965 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) {
3969 + /* record route */
3970 + if ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) {
3974 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) {
3979 + if ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) {
3983 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) {
3987 + /* router-alert option */
3988 + if ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) {
3989 + if (!opt->router_alert)
3992 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) {
3993 + if (opt->router_alert)
4002 +checkentry(const char *tablename,
4003 + const struct ipt_ip *ip,
4005 + unsigned int matchsize,
4006 + unsigned int hook_mask)
4008 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
4009 + /* Check the size */
4010 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_ipv4options_info)))
4012 + /* Now check the coherence of the data ... */
4013 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) &&
4014 + (((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) ||
4015 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) ||
4016 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) ||
4017 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) ||
4018 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)))
4019 + return 0; /* opposites */
4020 + if (((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) &&
4021 + (((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
4022 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
4023 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
4024 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
4025 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) ||
4026 + ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)))
4027 + return 0; /* opposites */
4028 + if (((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) &&
4029 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR))
4030 + return 0; /* cannot match in the same time loose and strict source routing */
4031 + if ((((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
4032 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR)) &&
4033 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR))
4034 + return 0; /* opposites */
4035 + if (((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) &&
4036 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR))
4037 + return 0; /* opposites */
4038 + if (((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) &&
4039 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
4040 + return 0; /* opposites */
4041 + if (((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) &&
4042 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
4043 + return 0; /* opposites */
4045 + /* everything looks ok. */
4049 +static struct ipt_match ipv4options_match = {
4050 + .name = "ipv4options",
4052 + .checkentry = checkentry,
4056 +static int __init init(void)
4058 + return ipt_register_match(&ipv4options_match);
4061 +static void __exit fini(void)
4063 + ipt_unregister_match(&ipv4options_match);
4068 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_mport.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_mport.c
4069 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_mport.c 1970-01-01 01:00:00.000000000 +0100
4070 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_mport.c 2004-03-30 11:11:11.000000000 +0200
4072 +/* Kernel module to match one of a list of TCP/UDP ports: ports are in
4073 + the same place so we can treat them as equal. */
4074 +#include <linux/module.h>
4075 +#include <linux/types.h>
4076 +#include <linux/udp.h>
4077 +#include <linux/skbuff.h>
4079 +#include <linux/netfilter_ipv4/ipt_mport.h>
4080 +#include <linux/netfilter_ipv4/ip_tables.h>
4082 +MODULE_LICENSE("GPL");
4085 +#define duprintf(format, args...) printk(format , ## args)
4087 +#define duprintf(format, args...)
4090 +/* Returns 1 if the port is matched by the test, 0 otherwise. */
4092 +ports_match(const struct ipt_mport *minfo, u_int16_t src, u_int16_t dst)
4096 + u_int16_t pflags = minfo->pflags;
4097 + for (i=0, m=1; i<IPT_MULTI_PORTS; i++, m<<=1) {
4101 + && minfo->ports[i] == 65535)
4104 + s = minfo->ports[i];
4107 + e = minfo->ports[++i];
4112 + if (minfo->flags & IPT_MPORT_SOURCE
4113 + && src >= s && src <= e)
4116 + if (minfo->flags & IPT_MPORT_DESTINATION
4117 + && dst >= s && dst <= e)
4125 +match(const struct sk_buff *skb,
4126 + const struct net_device *in,
4127 + const struct net_device *out,
4128 + const void *matchinfo,
4133 + const struct ipt_mport *minfo = matchinfo;
4138 + /* Must be big enough to read ports (both UDP and TCP have
4139 + them at the start). */
4140 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
4141 + /* We've been asked to examine this packet, and we
4142 + can't. Hence, no choice but to drop. */
4143 + duprintf("ipt_multiport:"
4144 + " Dropping evil offset=0 tinygram.\n");
4149 + return ports_match(minfo, ntohs(ports[0]), ntohs(ports[1]));
4152 +/* Called when user tries to insert an entry of this type. */
4154 +checkentry(const char *tablename,
4155 + const struct ipt_ip *ip,
4157 + unsigned int matchsize,
4158 + unsigned int hook_mask)
4160 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_mport)))
4163 + /* Must specify proto == TCP/UDP, no unknown flags or bad count */
4164 + return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
4165 + && !(ip->invflags & IPT_INV_PROTO)
4166 + && matchsize == IPT_ALIGN(sizeof(struct ipt_mport));
4169 +static struct ipt_match mport_match = {
4172 + .checkentry = &checkentry,
4176 +static int __init init(void)
4178 + return ipt_register_match(&mport_match);
4181 +static void __exit fini(void)
4183 + ipt_unregister_match(&mport_match);
4188 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_nth.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_nth.c
4189 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_nth.c 1970-01-01 01:00:00.000000000 +0100
4190 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_nth.c 2004-03-30 11:11:13.000000000 +0200
4193 + This is a module which is used for match support for every Nth packet
4194 + This file is distributed under the terms of the GNU General Public
4195 + License (GPL). Copies of the GPL can be obtained from:
4196 + ftp://prep.ai.mit.edu/pub/gnu/GPL
4198 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
4199 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
4200 + * added support for multiple counters
4201 + * added support for matching on individual packets
4202 + in the counter cycle
4203 + 2004-02-19 Harald Welte <laforge@netfilter.org>
4208 +#include <linux/module.h>
4209 +#include <linux/skbuff.h>
4210 +#include <linux/ip.h>
4211 +#include <net/tcp.h>
4212 +#include <linux/spinlock.h>
4213 +#include <linux/netfilter_ipv4/ip_tables.h>
4214 +#include <linux/netfilter_ipv4/ipt_nth.h>
4216 +MODULE_LICENSE("GPL");
4217 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
4220 + * State information.
4227 +static struct state states[IPT_NTH_NUM_COUNTERS];
4230 +ipt_nth_match(const struct sk_buff *pskb,
4231 + const struct net_device *in,
4232 + const struct net_device *out,
4233 + const void *matchinfo,
4237 + /* Parameters from userspace */
4238 + const struct ipt_nth_info *info = matchinfo;
4239 + unsigned counter = info->counter;
4240 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
4242 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
4246 + spin_lock(&states[counter].lock);
4248 + /* Are we matching every nth packet?*/
4249 + if (info->packet == 0xFF)
4251 + /* We're matching every nth packet and only every nth packet*/
4252 + /* Do we match or invert match? */
4253 + if (info->not == 0)
4255 + if (states[counter].number == 0)
4257 + ++states[counter].number;
4260 + if (states[counter].number >= info->every)
4261 + states[counter].number = 0; /* reset the counter */
4263 + ++states[counter].number;
4268 + if (states[counter].number == 0)
4270 + ++states[counter].number;
4273 + if (states[counter].number >= info->every)
4274 + states[counter].number = 0;
4276 + ++states[counter].number;
4282 + /* We're using the --packet, so there must be a rule for every value */
4283 + if (states[counter].number == info->packet)
4285 + /* only increment the counter when a match happens */
4286 + if (states[counter].number >= info->every)
4287 + states[counter].number = 0; /* reset the counter */
4289 + ++states[counter].number;
4298 + spin_unlock(&states[counter].lock);
4302 + spin_unlock(&states[counter].lock);
4307 +ipt_nth_checkentry(const char *tablename,
4308 + const struct ipt_ip *e,
4310 + unsigned int matchsize,
4311 + unsigned int hook_mask)
4313 + /* Parameters from userspace */
4314 + const struct ipt_nth_info *info = matchinfo;
4315 + unsigned counter = info->counter;
4316 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
4318 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
4322 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_nth_info))) {
4323 + printk("nth: matchsize %u != %u\n", matchsize,
4324 + IPT_ALIGN(sizeof(struct ipt_nth_info)));
4328 + states[counter].number = info->startat;
4333 +static struct ipt_match ipt_nth_reg = {
4335 + .match = ipt_nth_match,
4336 + .checkentry = ipt_nth_checkentry,
4340 +static int __init init(void)
4344 + memset(&states, 0, sizeof(states));
4345 + for (counter = 0; counter < IPT_NTH_NUM_COUNTERS; counter++)
4346 + spin_lock_init(&(states[counter].lock));
4348 + return ipt_register_match(&ipt_nth_reg);
4351 +static void __exit fini(void)
4353 + ipt_unregister_match(&ipt_nth_reg);
4358 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_osf.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_osf.c
4359 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_osf.c 1970-01-01 01:00:00.000000000 +0100
4360 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_osf.c 2004-03-30 11:11:15.000000000 +0200
4365 + * Copyright (c) 2003 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
4368 + * This program is free software; you can redistribute it and/or modify
4369 + * it under the terms of the GNU General Public License as published by
4370 + * the Free Software Foundation; either version 2 of the License, or
4371 + * (at your option) any later version.
4373 + * This program is distributed in the hope that it will be useful,
4374 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4375 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4376 + * GNU General Public License for more details.
4378 + * You should have received a copy of the GNU General Public License
4379 + * along with this program; if not, write to the Free Software
4380 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4384 + * OS fingerprint matching module.
4385 + * It simply compares various parameters from SYN packet with
4386 + * some hardcoded ones.
4388 + * Original table was created by Michal Zalewski <lcamtuf@coredump.cx>
4392 +#include <linux/config.h>
4393 +#include <linux/kernel.h>
4394 +#include <linux/types.h>
4395 +#include <linux/string.h>
4396 +#include <linux/smp.h>
4397 +#include <linux/module.h>
4398 +#include <linux/skbuff.h>
4399 +#include <linux/file.h>
4400 +#include <linux/ip.h>
4401 +#include <linux/proc_fs.h>
4402 +#include <linux/fs.h>
4403 +#include <linux/slab.h>
4404 +#include <linux/spinlock.h>
4405 +#include <linux/ctype.h>
4406 +#include <linux/list.h>
4407 +#include <linux/if.h>
4409 +#include <net/sock.h>
4410 +#include <net/ip.h>
4412 +#include <linux/netfilter_ipv4/ip_tables.h>
4414 +#include <linux/netfilter_ipv4/ipt_osf.h>
4419 +#define log(x...) printk(KERN_INFO "ipt_osf: " x)
4420 +#define loga(x...) printk(x)
4422 +#define log(x...) do {} while(0)
4423 +#define loga(x...) do {} while(0)
4426 +#define FMATCH_WRONG 0
4427 +#define FMATCH_OK 1
4428 +#define FMATCH_OPT_WRONG 2
4431 +#define OSFPDEL ':'
4432 +#define MAXOPTSTRLEN 128
4433 +#define OSFFLUSH "FLUSH"
4435 +static rwlock_t osf_lock = RW_LOCK_UNLOCKED;
4436 +static spinlock_t ipt_osf_netlink_lock = SPIN_LOCK_UNLOCKED;
4437 +static struct list_head finger_list;
4438 +static int match(const struct sk_buff *, const struct net_device *, const struct net_device *,
4439 + const void *, int,
4440 + const void *, u_int16_t,
4442 +static int checkentry(const char *, const struct ipt_ip *, void *,
4443 + unsigned int, unsigned int);
4445 +static unsigned long seq, ipt_osf_groups = 1;
4446 +static struct sock *nts;
4448 +static struct ipt_match osf_match =
4458 +static void ipt_osf_nlsend(struct osf_finger *f, const struct sk_buff *sk)
4460 + unsigned int size;
4461 + struct sk_buff *skb;
4462 + struct ipt_osf_nlmsg *data;
4463 + struct nlmsghdr *nlh;
4465 + size = NLMSG_SPACE(sizeof(struct ipt_osf_nlmsg));
4467 + skb = alloc_skb(size, GFP_ATOMIC);
4470 + log("skb_alloc() failed.\n");
4474 + nlh = NLMSG_PUT(skb, 0, seq++, NLMSG_DONE, size - sizeof(*nlh));
4476 + data = (struct ipt_osf_nlmsg *)NLMSG_DATA(nlh);
4478 + memcpy(&data->f, f, sizeof(struct osf_finger));
4479 + memcpy(&data->ip, sk->nh.iph, sizeof(struct iphdr));
4480 + memcpy(&data->tcp, (struct tcphdr *)((u_int32_t *)sk->nh.iph + sk->nh.iph->ihl), sizeof(struct tcphdr));
4482 + NETLINK_CB(skb).dst_groups = ipt_osf_groups;
4483 + netlink_broadcast(nts, skb, 0, ipt_osf_groups, GFP_ATOMIC);
4489 +static inline int smart_dec(const struct sk_buff *skb, unsigned long flags, unsigned char f_ttl)
4491 + struct iphdr *ip = skb->nh.iph;
4493 + if (flags & IPT_OSF_SMART)
4495 + struct in_device *in_dev = in_dev_get(skb->dev);
4499 + if (inet_ifa_match(ip->saddr, ifa))
4501 + in_dev_put(in_dev);
4502 + return (ip->ttl == f_ttl);
4505 + endfor_ifa(in_dev);
4507 + in_dev_put(in_dev);
4508 + return (ip->ttl <= f_ttl);
4511 + return (ip->ttl == f_ttl);
4515 +match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out,
4516 + const void *matchinfo, int offset,
4517 + const void *hdr, u_int16_t datalen,
4520 + struct ipt_osf_info *info = (struct ipt_osf_info *)matchinfo;
4521 + struct iphdr *ip = skb->nh.iph;
4522 + struct tcphdr *tcp;
4523 + int fmatch = FMATCH_WRONG, fcount = 0;
4524 + unsigned long totlen, optsize = 0, window;
4525 + unsigned char df, *optp = NULL, *_optp = NULL;
4526 + char check_WSS = 0;
4527 + struct list_head *ent;
4528 + struct osf_finger *f;
4533 + tcp = (struct tcphdr *)((u_int32_t *)ip + ip->ihl);
4538 + totlen = ntohs(ip->tot_len);
4539 + df = ((ntohs(ip->frag_off) & IP_DF)?1:0);
4540 + window = ntohs(tcp->window);
4542 + if (tcp->doff*4 > sizeof(struct tcphdr))
4544 + _optp = optp = (char *)(tcp+1);
4545 + optsize = tcp->doff*4 - sizeof(struct tcphdr);
4549 + /* Actually we can create hash/table of all genres and search
4550 + * only in appropriate part, but here is initial variant,
4551 + * so will use slow path.
4553 + read_lock(&osf_lock);
4554 + list_for_each(ent, &finger_list)
4556 + f = list_entry(ent, struct osf_finger, flist);
4558 + if (!(info->flags & IPT_OSF_LOG) && strcmp(info->genre, f->genre))
4562 + fmatch = FMATCH_WRONG;
4564 + if (totlen == f->ss && df == f->df &&
4565 + smart_dec(skb, info->flags, f->ttl))
4567 + unsigned long foptsize;
4569 + unsigned short mss = 0;
4573 + switch (f->wss.wc)
4575 + case 0: check_WSS = 0; break;
4576 + case 'S': check_WSS = 1; break;
4577 + case 'T': check_WSS = 2; break;
4578 + case '%': check_WSS = 3; break;
4579 + default: log("Wrong fingerprint wss.wc=%d, %s - %s\n",
4580 + f->wss.wc, f->genre, f->details);
4584 + if (check_WSS == 4)
4587 + /* Check options */
4590 + for (optnum=0; optnum<f->opt_num; ++optnum)
4591 + foptsize += f->opt[optnum].length;
4594 + if (foptsize > MAX_IPOPTLEN || optsize > MAX_IPOPTLEN || optsize != foptsize)
4599 + fmatch = FMATCH_OK;
4600 + loga("\tYEP : matching without options.\n");
4601 + if ((info->flags & IPT_OSF_LOG) &&
4602 + info->loglevel == IPT_OSF_LOGLEVEL_FIRST)
4609 + for (optnum=0; optnum<f->opt_num; ++optnum)
4611 + if (f->opt[optnum].kind == (*optp))
4613 + unsigned char len = f->opt[optnum].length;
4614 + unsigned char *optend = optp + len;
4615 + int loop_cont = 0;
4617 + fmatch = FMATCH_OK;
4623 + mss = ntohs(*(unsigned short *)(optp+2));
4638 + /* Skip kind and length fields*/
4641 + if (f->opt[optnum].wc.val != 0)
4643 + unsigned long tmp = 0;
4645 + /* Hmmm... It looks a bit ugly. :) */
4646 + memcpy(&tmp, optp,
4647 + (len > sizeof(unsigned long)?
4648 + sizeof(unsigned long):len));
4649 + /* 2 + 2: optlen(2 bytes) +
4650 + * kind(1 byte) + length(1 byte) */
4656 + if (f->opt[optnum].wc.wc == '%')
4658 + if ((tmp % f->opt[optnum].wc.val) != 0)
4659 + fmatch = FMATCH_OPT_WRONG;
4661 + else if (tmp != f->opt[optnum].wc.val)
4662 + fmatch = FMATCH_OPT_WRONG;
4669 + fmatch = FMATCH_OPT_WRONG;
4671 + if (fmatch != FMATCH_OK)
4675 + if (fmatch != FMATCH_OPT_WRONG)
4677 + fmatch = FMATCH_WRONG;
4679 + switch (check_WSS)
4682 + if (f->wss.val == 0 || window == f->wss.val)
4683 + fmatch = FMATCH_OK;
4686 +/* Lurked in OpenBSD */
4687 +#define SMART_MSS 1460
4688 + if (window == f->wss.val*mss ||
4689 + window == f->wss.val*SMART_MSS)
4690 + fmatch = FMATCH_OK;
4693 + if (window == f->wss.val*(mss+40) ||
4694 + window == f->wss.val*(SMART_MSS+40))
4695 + fmatch = FMATCH_OK;
4698 + if ((window % f->wss.val) == 0)
4699 + fmatch = FMATCH_OK;
4705 + if (fmatch == FMATCH_OK)
4708 + log("%s [%s:%s:%s] : %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u hops=%d\n",
4709 + f->genre, f->version,
4710 + f->subtype, f->details,
4711 + NIPQUAD(ip->saddr), ntohs(tcp->source),
4712 + NIPQUAD(ip->daddr), ntohs(tcp->dest),
4713 + f->ttl - ip->ttl);
4714 + if (info->flags & IPT_OSF_NETLINK)
4716 + spin_lock_bh(&ipt_osf_netlink_lock);
4717 + ipt_osf_nlsend(f, skb);
4718 + spin_unlock_bh(&ipt_osf_netlink_lock);
4720 + if ((info->flags & IPT_OSF_LOG) &&
4721 + info->loglevel == IPT_OSF_LOGLEVEL_FIRST)
4726 + if (!fcount && (info->flags & (IPT_OSF_LOG | IPT_OSF_NETLINK)))
4728 + unsigned char opt[4 * 15 - sizeof(struct tcphdr)];
4729 + unsigned int i, optsize;
4730 + struct osf_finger fg;
4732 + memset(&fg, 0, sizeof(fg));
4734 + if ((info->flags & IPT_OSF_LOG))
4735 + log("Unknown: %lu:%d:%d:%lu:", window, ip->ttl, df, totlen);
4738 + optsize = tcp->doff * 4 - sizeof(struct tcphdr);
4739 + if (skb_copy_bits(skb, ip->ihl*4 + sizeof(struct tcphdr),
4740 + opt, optsize) < 0)
4742 + if (info->flags & IPT_OSF_LOG)
4743 + loga("TRUNCATED");
4744 + if (info->flags & IPT_OSF_NETLINK)
4745 + strcpy(fg.details, "TRUNCATED");
4749 + for (i = 0; i < optsize; i++)
4751 + if (info->flags & IPT_OSF_LOG)
4752 + loga("%02X", opt[i]);
4754 + if (info->flags & IPT_OSF_NETLINK)
4755 + memcpy(fg.details, opt, MAXDETLEN);
4758 + if ((info->flags & IPT_OSF_LOG))
4759 + loga(" %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n",
4760 + NIPQUAD(ip->saddr), ntohs(tcp->source),
4761 + NIPQUAD(ip->daddr), ntohs(tcp->dest));
4763 + if (info->flags & IPT_OSF_NETLINK)
4765 + fg.wss.val = window;
4769 + strncpy(fg.genre, "Unknown", MAXGENRELEN);
4771 + spin_lock_bh(&ipt_osf_netlink_lock);
4772 + ipt_osf_nlsend(&fg, skb);
4773 + spin_unlock_bh(&ipt_osf_netlink_lock);
4777 + read_unlock(&osf_lock);
4779 + return (fmatch == FMATCH_OK)?1:0;
4783 +checkentry(const char *tablename,
4784 + const struct ipt_ip *ip,
4786 + unsigned int matchsize,
4787 + unsigned int hook_mask)
4789 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_osf_info)))
4791 + if (ip->proto != IPPROTO_TCP)
4797 +static char * osf_strchr(char *ptr, char c)
4801 + tmp = strchr(ptr, c);
4803 + while (tmp && tmp+1 && isspace(*(tmp+1)))
4809 +static struct osf_finger * finger_alloc(void)
4811 + struct osf_finger *f;
4813 + f = kmalloc(sizeof(struct osf_finger), GFP_KERNEL);
4815 + memset(f, 0, sizeof(struct osf_finger));
4820 +static void finger_free(struct osf_finger *f)
4822 + memset(f, 0, sizeof(struct osf_finger));
4827 +static void osf_parse_opt(struct osf_opt *opt, int *optnum, char *obuf, int olen)
4831 + unsigned long val;
4835 + while (ptr != NULL && i < olen)
4844 + ptr = osf_strchr(&obuf[i], OPTDEL);
4849 + i += (int)(ptr-&obuf[i]);
4856 + op = OSFOPT_SACKP;
4857 + ptr = osf_strchr(&obuf[i], OPTDEL);
4862 + i += (int)(ptr-&obuf[i]);
4870 + ptr = osf_strchr(&obuf[i], OPTDEL);
4875 + i += (int)(ptr-&obuf[i]);
4883 + ptr = osf_strchr(&obuf[i], OPTDEL);
4886 + switch (obuf[i+1])
4888 + case '%': wc = '%'; break;
4889 + case 'S': wc = 'S'; break;
4890 + case 'T': wc = 'T'; break;
4891 + default: wc = 0; break;
4897 + val = simple_strtoul(&obuf[i+2], NULL, 10);
4899 + val = simple_strtoul(&obuf[i+1], NULL, 10);
4900 + i += (int)(ptr-&obuf[i]);
4908 + ptr = osf_strchr(&obuf[i], OPTDEL);
4911 + if (obuf[i+1] == '%')
4916 + val = simple_strtoul(&obuf[i+2], NULL, 10);
4918 + val = simple_strtoul(&obuf[i+1], NULL, 10);
4919 + i += (int)(ptr-&obuf[i]);
4927 + ptr = osf_strchr(&obuf[i], OPTDEL);
4932 + i += (int)(ptr-&obuf[i]);
4939 + ptr = osf_strchr(&obuf[i], OPTDEL);
4943 + i += (int)(ptr-&obuf[i]);
4951 + opt[*optnum].kind = IANA_opts[op].kind;
4952 + opt[*optnum].length = IANA_opts[op].length;
4953 + opt[*optnum].wc.wc = wc;
4954 + opt[*optnum].wc.val = val;
4960 +static int osf_proc_read(char *buf, char **start, off_t off, int count, int *eof, void *data)
4962 + struct list_head *ent;
4963 + struct osf_finger *f = NULL;
4969 + read_lock_bh(&osf_lock);
4970 + list_for_each(ent, &finger_list)
4972 + f = list_entry(ent, struct osf_finger, flist);
4974 + log("%s [%s]", f->genre, f->details);
4976 + count += sprintf(buf+count, "%s - %s[%s] : %s",
4977 + f->genre, f->version,
4978 + f->subtype, f->details);
4983 + //count += sprintf(buf+count, " OPT: ");
4984 + for (i=0; i<f->opt_num; ++i)
4986 + //count += sprintf(buf+count, "%d.%c%lu; ",
4987 + // f->opt[i].kind, (f->opt[i].wc.wc)?f->opt[i].wc.wc:' ', f->opt[i].wc.val);
4988 + loga("%d.%c%lu; ",
4989 + f->opt[i].kind, (f->opt[i].wc.wc)?f->opt[i].wc.wc:' ', f->opt[i].wc.val);
4993 + count += sprintf(buf+count, "\n");
4995 + read_unlock_bh(&osf_lock);
5000 +static int osf_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
5004 + char obuf[MAXOPTSTRLEN];
5005 + struct osf_finger *finger;
5006 + struct list_head *ent, *n;
5008 + char *pbeg, *pend;
5010 + if (count == strlen(OSFFLUSH) && !strncmp(buffer, OSFFLUSH, strlen(OSFFLUSH)))
5013 + write_lock_bh(&osf_lock);
5014 + list_for_each_safe(ent, n, &finger_list)
5017 + finger = list_entry(ent, struct osf_finger, flist);
5018 + list_del(&finger->flist);
5019 + finger_free(finger);
5021 + write_unlock_bh(&osf_lock);
5023 + log("Flushed %d entries.\n", i);
5030 + for (i=0; i<count && buffer[i] != '\0'; ++i)
5031 + if (buffer[i] == ':')
5034 + if (cnt != 8 || i != count)
5036 + log("Wrong input line cnt=%d[8], len=%lu[%lu]\n",
5041 + memset(obuf, 0, sizeof(obuf));
5043 + finger = finger_alloc();
5046 + log("Failed to allocate new fingerprint entry.\n");
5050 + pbeg = (char *)buffer;
5051 + pend = osf_strchr(pbeg, OSFPDEL);
5055 + if (pbeg[0] == 'S')
5057 + finger->wss.wc = 'S';
5058 + if (pbeg[1] == '%')
5059 + finger->wss.val = simple_strtoul(pbeg+2, NULL, 10);
5060 + else if (pbeg[1] == '*')
5061 + finger->wss.val = 0;
5063 + finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
5065 + else if (pbeg[0] == 'T')
5067 + finger->wss.wc = 'T';
5068 + if (pbeg[1] == '%')
5069 + finger->wss.val = simple_strtoul(pbeg+2, NULL, 10);
5070 + else if (pbeg[1] == '*')
5071 + finger->wss.val = 0;
5073 + finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
5075 + else if (pbeg[0] == '%')
5077 + finger->wss.wc = '%';
5078 + finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
5080 + else if (isdigit(pbeg[0]))
5082 + finger->wss.wc = 0;
5083 + finger->wss.val = simple_strtoul(pbeg, NULL, 10);
5088 + pend = osf_strchr(pbeg, OSFPDEL);
5092 + finger->ttl = simple_strtoul(pbeg, NULL, 10);
5095 + pend = osf_strchr(pbeg, OSFPDEL);
5099 + finger->df = simple_strtoul(pbeg, NULL, 10);
5102 + pend = osf_strchr(pbeg, OSFPDEL);
5106 + finger->ss = simple_strtoul(pbeg, NULL, 10);
5110 + pend = osf_strchr(pbeg, OSFPDEL);
5114 + cnt = snprintf(obuf, sizeof(obuf), "%s", pbeg);
5118 + pend = osf_strchr(pbeg, OSFPDEL);
5122 + if (pbeg[0] == '@' || pbeg[0] == '*')
5123 + cnt = snprintf(finger->genre, sizeof(finger->genre), "%s", pbeg+1);
5125 + cnt = snprintf(finger->genre, sizeof(finger->genre), "%s", pbeg);
5129 + pend = osf_strchr(pbeg, OSFPDEL);
5133 + cnt = snprintf(finger->version, sizeof(finger->version), "%s", pbeg);
5137 + pend = osf_strchr(pbeg, OSFPDEL);
5141 + cnt = snprintf(finger->subtype, sizeof(finger->subtype), "%s", pbeg);
5145 + cnt = snprintf(finger->details,
5146 + ((count - (pbeg - buffer)+1) > MAXDETLEN)?MAXDETLEN:(count - (pbeg - buffer)+1),
5149 + log("%s - %s[%s] : %s\n",
5150 + finger->genre, finger->version,
5151 + finger->subtype, finger->details);
5153 + osf_parse_opt(finger->opt, &finger->opt_num, obuf, sizeof(obuf));
5156 + write_lock_bh(&osf_lock);
5157 + list_add_tail(&finger->flist, &finger_list);
5158 + write_unlock_bh(&osf_lock);
5163 +static int __init osf_init(void)
5166 + struct proc_dir_entry *p;
5168 + log("Startng OS fingerprint matching module.\n");
5170 + INIT_LIST_HEAD(&finger_list);
5172 + err = ipt_register_match(&osf_match);
5175 + log("Failed to register OS fingerprint matching module.\n");
5179 + p = create_proc_entry("sys/net/ipv4/osf", S_IFREG | 0644, NULL);
5182 + ipt_unregister_match(&osf_match);
5186 + p->write_proc = osf_proc_write;
5187 + p->read_proc = osf_proc_read;
5189 + nts = netlink_kernel_create(NETLINK_NFLOG, NULL);
5192 + log("netlink_kernel_create() failed\n");
5193 + remove_proc_entry("sys/net/ipv4/osf", NULL);
5194 + ipt_unregister_match(&osf_match);
5201 +static void __exit osf_fini(void)
5203 + struct list_head *ent, *n;
5204 + struct osf_finger *f;
5206 + remove_proc_entry("sys/net/ipv4/osf", NULL);
5207 + ipt_unregister_match(&osf_match);
5208 +// if (nts && nts->socket)
5209 +// sock_release(nts->socket);
5211 + list_for_each_safe(ent, n, &finger_list)
5213 + f = list_entry(ent, struct osf_finger, flist);
5214 + list_del(&f->flist);
5218 + log("OS fingerprint matching module finished.\n");
5221 +module_init(osf_init);
5222 +module_exit(osf_fini);
5224 +MODULE_LICENSE("GPL");
5225 +MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
5226 +MODULE_DESCRIPTION("Passive OS fingerprint matching.");
5227 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_pool.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_pool.c
5228 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_pool.c 1970-01-01 01:00:00.000000000 +0100
5229 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_pool.c 2004-03-30 11:11:17.000000000 +0200
5231 +/* Kernel module to match an IP address pool. */
5233 +#include <linux/module.h>
5234 +#include <linux/ip.h>
5235 +#include <linux/skbuff.h>
5237 +#include <linux/netfilter_ipv4/ip_tables.h>
5238 +#include <linux/netfilter_ipv4/ip_pool.h>
5239 +#include <linux/netfilter_ipv4/ipt_pool.h>
5241 +static inline int match_pool(
5246 + if (ip_pool_match(index, ntohl(addr)))
5252 + const struct sk_buff *skb,
5253 + const struct net_device *in,
5254 + const struct net_device *out,
5255 + const void *matchinfo,
5258 + u_int16_t datalen,
5261 + const struct ipt_pool_info *info = matchinfo;
5262 + const struct iphdr *iph = skb->nh.iph;
5264 + if (info->src != IP_POOL_NONE && !match_pool(info->src, iph->saddr,
5265 + info->flags&IPT_POOL_INV_SRC))
5268 + if (info->dst != IP_POOL_NONE && !match_pool(info->dst, iph->daddr,
5269 + info->flags&IPT_POOL_INV_DST))
5275 +static int checkentry(
5276 + const char *tablename,
5277 + const struct ipt_ip *ip,
5279 + unsigned int matchsize,
5280 + unsigned int hook_mask
5282 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_pool_info)))
5287 +static struct ipt_match pool_match
5288 += { { NULL, NULL }, "pool", &match, &checkentry, NULL, THIS_MODULE };
5290 +static int __init init(void)
5292 + return ipt_register_match(&pool_match);
5295 +static void __exit fini(void)
5297 + ipt_unregister_match(&pool_match);
5302 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_psd.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_psd.c
5303 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_psd.c 1970-01-01 01:00:00.000000000 +0100
5304 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_psd.c 2004-03-30 11:11:18.000000000 +0200
5307 + This is a module which is used for PSD (portscan detection)
5308 + Derived from scanlogd v2.1 written by Solar Designer <solar@false.com>
5309 + and LOG target module.
5311 + Copyright (C) 2000,2001 astaro AG
5313 + This file is distributed under the terms of the GNU General Public
5314 + License (GPL). Copies of the GPL can be obtained from:
5315 + ftp://prep.ai.mit.edu/pub/gnu/GPL
5317 + 2000-05-04 Markus Hennig <hennig@astaro.de> : initial
5318 + 2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
5319 + 2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
5320 + 2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified
5321 + 2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
5324 +#include <linux/module.h>
5325 +#include <linux/skbuff.h>
5326 +#include <linux/ip.h>
5327 +#include <net/tcp.h>
5328 +#include <linux/spinlock.h>
5329 +#include <linux/netfilter_ipv4/ip_tables.h>
5330 +#include <linux/netfilter_ipv4/ipt_psd.h>
5333 +#define DEBUGP printk
5335 +#define DEBUGP(format, args...)
5338 +MODULE_LICENSE("GPL");
5339 +MODULE_AUTHOR("Dennis Koslowski <koslowski@astaro.com>");
5341 +#define HF_DADDR_CHANGING 0x01
5342 +#define HF_SPORT_CHANGING 0x02
5343 +#define HF_TOS_CHANGING 0x04
5344 +#define HF_TTL_CHANGING 0x08
5347 + * Information we keep per each target port
5350 + u_int16_t number; /* port number */
5351 + u_int8_t proto; /* protocol number */
5352 + u_int8_t and_flags; /* tcp ANDed flags */
5353 + u_int8_t or_flags; /* tcp ORed flags */
5357 + * Information we keep per each source address.
5360 + struct host *next; /* Next entry with the same hash */
5361 + clock_t timestamp; /* Last update time */
5362 + struct in_addr src_addr; /* Source address */
5363 + struct in_addr dest_addr; /* Destination address */
5364 + unsigned short src_port; /* Source port */
5365 + int count; /* Number of ports in the list */
5366 + int weight; /* Total weight of ports in the list */
5367 + struct port ports[SCAN_MAX_COUNT - 1]; /* List of ports */
5368 + unsigned char tos; /* TOS */
5369 + unsigned char ttl; /* TTL */
5370 + unsigned char flags; /* HF_ flags bitmask */
5374 + * State information.
5378 + struct host list[LIST_SIZE]; /* List of source addresses */
5379 + struct host *hash[HASH_SIZE]; /* Hash: pointers into the list */
5380 + int index; /* Oldest entry to be replaced */
5384 + * Convert an IP address into a hash table index.
5386 +static inline int hashfunc(struct in_addr addr)
5388 + unsigned int value;
5391 + value = addr.s_addr;
5395 + } while ((value >>= HASH_LOG));
5397 + return hash & (HASH_SIZE - 1);
5401 +ipt_psd_match(const struct sk_buff *pskb,
5402 + const struct net_device *in,
5403 + const struct net_device *out,
5404 + const void *matchinfo,
5407 + u_int16_t datalen,
5410 + struct iphdr *ip_hdr;
5411 + struct tcphdr *tcp_hdr;
5412 + struct in_addr addr;
5413 + u_int16_t src_port,dest_port;
5414 + u_int8_t tcp_flags, proto;
5416 + struct host *curr, *last, **head;
5417 + int hash, index, count;
5419 + /* Parameters from userspace */
5420 + const struct ipt_psd_info *psdinfo = matchinfo;
5423 + ip_hdr = pskb->nh.iph;
5425 + /* Sanity check */
5426 + if (ntohs(ip_hdr->frag_off) & IP_OFFSET) {
5427 + DEBUGP("PSD: sanity check failed\n");
5431 + /* TCP or UDP ? */
5432 + proto = ip_hdr->protocol;
5434 + if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
5435 + DEBUGP("PSD: protocol not supported\n");
5439 + /* Get the source address, source & destination ports, and TCP flags */
5441 + addr.s_addr = ip_hdr->saddr;
5443 + tcp_hdr = (struct tcphdr*)((u_int32_t *)ip_hdr + ip_hdr->ihl);
5445 + /* Yep, it´s dirty */
5446 + src_port = tcp_hdr->source;
5447 + dest_port = tcp_hdr->dest;
5449 + if (proto == IPPROTO_TCP) {
5450 + tcp_flags = *((u_int8_t*)tcp_hdr + 13);
5456 + /* We're using IP address 0.0.0.0 for a special purpose here, so don't let
5457 + * them spoof us. [DHCP needs this feature - HW] */
5458 + if (!addr.s_addr) {
5459 + DEBUGP("PSD: spoofed source address (0.0.0.0)\n");
5463 + /* Use jiffies here not to depend on someone setting the time while we're
5464 + * running; we need to be careful with possible return value overflows. */
5467 + spin_lock(&state.lock);
5469 + /* Do we know this source address already? */
5472 + if ((curr = *(head = &state.hash[hash = hashfunc(addr)])))
5474 + if (curr->src_addr.s_addr == addr.s_addr) break;
5476 + if (curr->next) last = curr;
5477 + } while ((curr = curr->next));
5481 + /* We know this address, and the entry isn't too old. Update it. */
5482 + if (now - curr->timestamp <= (psdinfo->delay_threshold*HZ)/100 &&
5483 + time_after_eq(now, curr->timestamp)) {
5485 + /* Just update the appropriate list entry if we've seen this port already */
5486 + for (index = 0; index < curr->count; index++) {
5487 + if (curr->ports[index].number == dest_port) {
5488 + curr->ports[index].proto = proto;
5489 + curr->ports[index].and_flags &= tcp_flags;
5490 + curr->ports[index].or_flags |= tcp_flags;
5491 + goto out_no_match;
5495 + /* TCP/ACK and/or TCP/RST to a new port? This could be an outgoing connection. */
5496 + if (proto == IPPROTO_TCP && (tcp_hdr->ack || tcp_hdr->rst))
5497 + goto out_no_match;
5499 + /* Packet to a new port, and not TCP/ACK: update the timestamp */
5500 + curr->timestamp = now;
5502 + /* Logged this scan already? Then drop the packet. */
5503 + if (curr->weight >= psdinfo->weight_threshold)
5506 + /* Specify if destination address, source port, TOS or TTL are not fixed */
5507 + if (curr->dest_addr.s_addr != ip_hdr->daddr)
5508 + curr->flags |= HF_DADDR_CHANGING;
5509 + if (curr->src_port != src_port)
5510 + curr->flags |= HF_SPORT_CHANGING;
5511 + if (curr->tos != ip_hdr->tos)
5512 + curr->flags |= HF_TOS_CHANGING;
5513 + if (curr->ttl != ip_hdr->ttl)
5514 + curr->flags |= HF_TTL_CHANGING;
5516 + /* Update the total weight */
5517 + curr->weight += (ntohs(dest_port) < 1024) ?
5518 + psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
5520 + /* Got enough destination ports to decide that this is a scan? */
5521 + /* Then log it and drop the packet. */
5522 + if (curr->weight >= psdinfo->weight_threshold)
5525 + /* Remember the new port */
5526 + if (curr->count < SCAN_MAX_COUNT) {
5527 + curr->ports[curr->count].number = dest_port;
5528 + curr->ports[curr->count].proto = proto;
5529 + curr->ports[curr->count].and_flags = tcp_flags;
5530 + curr->ports[curr->count].or_flags = tcp_flags;
5534 + goto out_no_match;
5537 + /* We know this address, but the entry is outdated. Mark it unused, and
5538 + * remove from the hash table. We'll allocate a new entry instead since
5539 + * this one might get re-used too soon. */
5540 + curr->src_addr.s_addr = 0;
5542 + last->next = last->next->next;
5544 + *head = (*head)->next;
5548 + /* We don't need an ACK from a new source address */
5549 + if (proto == IPPROTO_TCP && tcp_hdr->ack)
5550 + goto out_no_match;
5552 + /* Got too many source addresses with the same hash value? Then remove the
5553 + * oldest one from the hash table, so that they can't take too much of our
5554 + * CPU time even with carefully chosen spoofed IP addresses. */
5555 + if (count >= HASH_MAX && last) last->next = NULL;
5557 + /* We're going to re-use the oldest list entry, so remove it from the hash
5558 + * table first (if it is really already in use, and isn't removed from the
5559 + * hash table already because of the HASH_MAX check above). */
5561 + /* First, find it */
5562 + if (state.list[state.index].src_addr.s_addr)
5563 + head = &state.hash[hashfunc(state.list[state.index].src_addr)];
5567 + if ((curr = *head))
5569 + if (curr == &state.list[state.index]) break;
5571 + } while ((curr = curr->next));
5573 + /* Then, remove it */
5576 + last->next = last->next->next;
5578 + *head = (*head)->next;
5581 + /* Get our list entry */
5582 + curr = &state.list[state.index++];
5583 + if (state.index >= LIST_SIZE) state.index = 0;
5585 + /* Link it into the hash table */
5586 + head = &state.hash[hash];
5587 + curr->next = *head;
5590 + /* And fill in the fields */
5591 + curr->timestamp = now;
5592 + curr->src_addr = addr;
5593 + curr->dest_addr.s_addr = ip_hdr->daddr;
5594 + curr->src_port = src_port;
5596 + curr->weight = (ntohs(dest_port) < 1024) ?
5597 + psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
5598 + curr->ports[0].number = dest_port;
5599 + curr->ports[0].proto = proto;
5600 + curr->ports[0].and_flags = tcp_flags;
5601 + curr->ports[0].or_flags = tcp_flags;
5602 + curr->tos = ip_hdr->tos;
5603 + curr->ttl = ip_hdr->ttl;
5606 + spin_unlock(&state.lock);
5610 + spin_unlock(&state.lock);
5614 +static int ipt_psd_checkentry(const char *tablename,
5615 + const struct ipt_ip *e,
5617 + unsigned int matchsize,
5618 + unsigned int hook_mask)
5620 +/* const struct ipt_psd_info *psdinfo = targinfo;*/
5622 + /* we accept TCP only */
5623 +/* if (e->ip.proto != IPPROTO_TCP) { */
5624 +/* DEBUGP("PSD: specified protocol may be TCP only\n"); */
5628 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_psd_info))) {
5629 + DEBUGP("PSD: matchsize %u != %u\n",
5631 + IPT_ALIGN(sizeof(struct ipt_psd_info)));
5638 +static struct ipt_match ipt_psd_reg = {
5642 + ipt_psd_checkentry,
5646 +static int __init init(void)
5648 + if (ipt_register_match(&ipt_psd_reg))
5651 + memset(&state, 0, sizeof(state));
5653 + spin_lock_init(&(state.lock));
5655 + printk("netfilter PSD loaded - (c) astaro AG\n");
5659 +static void __exit fini(void)
5661 + ipt_unregister_match(&ipt_psd_reg);
5662 + printk("netfilter PSD unloaded - (c) astaro AG\n");
5667 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_quota.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_quota.c
5668 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_quota.c 1970-01-01 01:00:00.000000000 +0100
5669 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_quota.c 2004-03-30 11:11:23.000000000 +0200
5672 + * netfilter module to enforce network quotas
5674 + * Sam Johnston <samj@samj.net>
5676 +#include <linux/module.h>
5677 +#include <linux/skbuff.h>
5678 +#include <linux/spinlock.h>
5679 +#include <linux/interrupt.h>
5681 +#include <linux/netfilter_ipv4/ip_tables.h>
5682 +#include <linux/netfilter_ipv4/ipt_quota.h>
5684 +MODULE_LICENSE("GPL");
5685 +MODULE_AUTHOR("Sam Johnston <samj@samj.net>");
5687 +static spinlock_t quota_lock = SPIN_LOCK_UNLOCKED;
5690 +match(const struct sk_buff *skb,
5691 + const struct net_device *in,
5692 + const struct net_device *out,
5693 + const void *matchinfo,
5694 + int offset, int *hotdrop)
5696 + struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
5697 + unsigned int datalen;
5699 + if (skb->len < sizeof(struct iphdr))
5702 + datalen = skb->len - skb->nh.iph->ihl*4;
5704 + spin_lock_bh("a_lock);
5706 + if (q->quota >= datalen) {
5707 + /* we can afford this one */
5708 + q->quota -= datalen;
5709 + spin_unlock_bh("a_lock);
5711 +#ifdef DEBUG_IPT_QUOTA
5712 + printk("IPT Quota OK: %llu datlen %d \n", q->quota, datalen);
5717 + /* so we do not allow even small packets from now on */
5720 +#ifdef DEBUG_IPT_QUOTA
5721 + printk("IPT Quota Failed: %llu datlen %d \n", q->quota, datalen);
5724 + spin_unlock_bh("a_lock);
5729 +checkentry(const char *tablename,
5730 + const struct ipt_ip *ip,
5731 + void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
5733 + /* TODO: spinlocks? sanity checks? */
5734 + if (matchsize != IPT_ALIGN(sizeof (struct ipt_quota_info)))
5740 +static struct ipt_match quota_match = {
5743 + .checkentry = checkentry,
5750 + return ipt_register_match("a_match);
5756 + ipt_unregister_match("a_match);
5762 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_random.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_random.c
5763 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_random.c 1970-01-01 01:00:00.000000000 +0100
5764 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_random.c 2004-03-30 11:11:26.000000000 +0200
5767 + This is a module which is used for a "random" match support.
5768 + This file is distributed under the terms of the GNU General Public
5769 + License (GPL). Copies of the GPL can be obtained from:
5770 + ftp://prep.ai.mit.edu/pub/gnu/GPL
5772 + 2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
5775 +#include <linux/module.h>
5776 +#include <linux/skbuff.h>
5777 +#include <linux/ip.h>
5778 +#include <linux/random.h>
5779 +#include <net/tcp.h>
5780 +#include <linux/spinlock.h>
5781 +#include <linux/netfilter_ipv4/ip_tables.h>
5782 +#include <linux/netfilter_ipv4/ipt_random.h>
5784 +MODULE_LICENSE("GPL");
5787 +ipt_rand_match(const struct sk_buff *pskb,
5788 + const struct net_device *in,
5789 + const struct net_device *out,
5790 + const void *matchinfo,
5793 + u_int16_t datalen,
5796 + /* Parameters from userspace */
5797 + const struct ipt_rand_info *info = matchinfo;
5798 + u_int8_t random_number;
5800 + /* get 1 random number from the kernel random number generation routine */
5801 + get_random_bytes((void *)(&random_number), 1);
5803 + /* Do we match ? */
5804 + if (random_number <= info->average)
5811 +ipt_rand_checkentry(const char *tablename,
5812 + const struct ipt_ip *e,
5814 + unsigned int matchsize,
5815 + unsigned int hook_mask)
5817 + /* Parameters from userspace */
5818 + const struct ipt_rand_info *info = matchinfo;
5820 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_rand_info))) {
5821 + printk("ipt_random: matchsize %u != %u\n", matchsize,
5822 + IPT_ALIGN(sizeof(struct ipt_rand_info)));
5826 + /* must be 1 <= average % <= 99 */
5827 + /* 1 x 2.55 = 2 */
5828 + /* 99 x 2.55 = 252 */
5829 + if ((info->average < 2) || (info->average > 252)) {
5830 + printk("ipt_random: invalid average %u\n", info->average);
5837 +static struct ipt_match ipt_rand_reg = {
5841 + ipt_rand_checkentry,
5845 +static int __init init(void)
5847 + if (ipt_register_match(&ipt_rand_reg))
5850 + printk("ipt_random match loaded\n");
5854 +static void __exit fini(void)
5856 + ipt_unregister_match(&ipt_rand_reg);
5857 + printk("ipt_random match unloaded\n");
5862 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_realm.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_realm.c
5863 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_realm.c 1970-01-01 01:00:00.000000000 +0100
5864 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_realm.c 2004-03-30 11:11:29.000000000 +0200
5866 +/* IP tables module for matching the routing realm
5870 + * (C) 2003 by Sampsa Ranta <sampsa@netsonic.fi>
5872 + * This program is free software; you can redistribute it and/or modify
5873 + * it under the terms of the GNU General Public License version 2 as
5874 + * published by the Free Software Foundation.
5877 +#include <linux/module.h>
5878 +#include <linux/skbuff.h>
5879 +#include <linux/netdevice.h>
5880 +#include <net/route.h>
5882 +#include <linux/netfilter_ipv4/ipt_realm.h>
5883 +#include <linux/netfilter_ipv4/ip_tables.h>
5885 +MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>");
5886 +MODULE_LICENSE("GPL");
5889 +match(const struct sk_buff *skb,
5890 + const struct net_device *in,
5891 + const struct net_device *out,
5892 + const void *matchinfo,
5896 + const struct ipt_realm_info *info = matchinfo;
5897 + struct dst_entry *dst = skb->dst;
5902 + return (info->id == (dst->tclassid & info->mask)) ^ info->invert;
5905 +static int check(const char *tablename,
5906 + const struct ipt_ip *ip,
5908 + unsigned int matchsize,
5909 + unsigned int hook_mask)
5912 + & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) |
5913 + (1 << NF_IP_LOCAL_OUT)| (1 << NF_IP_LOCAL_IN))) {
5914 + printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, "
5915 + "LOCAL_IN or FORWARD.\n");
5919 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info)))
5925 +static struct ipt_match realm_match = {
5928 + .checkentry = check,
5932 +static int __init init(void)
5934 + return ipt_register_match(&realm_match);
5937 +static void __exit fini(void)
5939 + ipt_unregister_match(&realm_match);
5944 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_sctp.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_sctp.c
5945 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_sctp.c 1970-01-01 01:00:00.000000000 +0100
5946 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_sctp.c 2004-03-30 11:11:32.000000000 +0200
5948 +#include <linux/module.h>
5949 +#include <linux/skbuff.h>
5950 +#include <net/ip.h>
5951 +#include <linux/sctp.h>
5953 +#include <linux/netfilter_ipv4/ip_tables.h>
5954 +#include <linux/netfilter_ipv4/ipt_sctp.h>
5957 +#define duprintf(format, args...) printk(format , ## args)
5959 +#define duprintf(format, args...)
5962 +#define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \
5963 + || (!!((invflag) & (option)) ^ (cond)))
5966 +match_flags(const struct ipt_sctp_flag_info *flag_info,
5967 + const int flag_count,
5968 + u_int8_t chunktype,
5969 + u_int8_t chunkflags)
5973 + for (i = 0; i < flag_count; i++) {
5974 + if (flag_info[i].chunktype == chunktype) {
5975 + return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag;
5983 +match_packet(const struct sk_buff *skb,
5984 + const u_int32_t *chunkmap,
5985 + int chunk_match_type,
5986 + const struct ipt_sctp_flag_info *flag_info,
5987 + const int flag_count,
5991 + u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
5992 + sctp_chunkhdr_t sch;
5996 + if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) {
5997 + SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap);
6000 + offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t);
6002 + if (skb_copy_bits(skb, offset, &sch, sizeof(sch)) < 0) {
6003 + duprintf("Dropping invalid SCTP packet.\n");
6008 + duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n",
6009 + ++i, offset, sch.type, htons(sch.length), sch.flags);
6011 + offset += (htons(sch.length) + 3) & ~3;
6013 + duprintf("skb->len: %d\toffset: %d\n", skb->len, offset);
6015 + if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch.type)) {
6016 + switch (chunk_match_type) {
6017 + case SCTP_CHUNK_MATCH_ANY:
6018 + if (match_flags(flag_info, flag_count,
6019 + sch.type, sch.flags)) {
6024 + case SCTP_CHUNK_MATCH_ALL:
6025 + if (match_flags(flag_info, flag_count,
6026 + sch.type, sch.flags)) {
6027 + SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch.type);
6031 + case SCTP_CHUNK_MATCH_ONLY:
6032 + if (!match_flags(flag_info, flag_count,
6033 + sch.type, sch.flags)) {
6039 + switch (chunk_match_type) {
6040 + case SCTP_CHUNK_MATCH_ONLY:
6044 + } while (offset < skb->len);
6046 + switch (chunk_match_type) {
6047 + case SCTP_CHUNK_MATCH_ALL:
6048 + return SCTP_CHUNKMAP_IS_CLEAR(chunkmap);
6049 + case SCTP_CHUNK_MATCH_ANY:
6051 + case SCTP_CHUNK_MATCH_ONLY:
6055 + /* This will never be reached, but required to stop compiler whine */
6060 +match(const struct sk_buff *skb,
6061 + const struct net_device *in,
6062 + const struct net_device *out,
6063 + const void *matchinfo,
6067 + const struct ipt_sctp_info *info;
6068 + sctp_sctphdr_t sh;
6070 + info = (const struct ipt_sctp_info *)matchinfo;
6073 + duprintf("Dropping non-first fragment.. FIXME\n");
6077 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &sh, sizeof(sh)) < 0) {
6078 + duprintf("Dropping evil TCP offset=0 tinygram.\n");
6082 + duprintf("spt: %d\tdpt: %d\n", ntohs(sh.source), ntohs(sh.dest));
6084 + return SCCHECK(((ntohs(sh.source) >= info->spts[0])
6085 + && (ntohs(sh.source) <= info->spts[1])),
6086 + IPT_SCTP_SRC_PORTS, info->flags, info->invflags)
6087 + && SCCHECK(((ntohs(sh.dest) >= info->dpts[0])
6088 + && (ntohs(sh.dest) <= info->dpts[1])),
6089 + IPT_SCTP_DEST_PORTS, info->flags, info->invflags)
6090 + && SCCHECK(match_packet(skb, info->chunkmap, info->chunk_match_type,
6091 + info->flag_info, info->flag_count,
6093 + IPT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
6097 +checkentry(const char *tablename,
6098 + const struct ipt_ip *ip,
6100 + unsigned int matchsize,
6101 + unsigned int hook_mask)
6103 + const struct ipt_sctp_info *info;
6105 + info = (const struct ipt_sctp_info *)matchinfo;
6107 + return ip->proto == IPPROTO_SCTP
6108 + && !(ip->invflags & IPT_INV_PROTO)
6109 + && matchsize == IPT_ALIGN(sizeof(struct ipt_sctp_info))
6110 + && !(info->flags & ~IPT_SCTP_VALID_FLAGS)
6111 + && !(info->invflags & ~IPT_SCTP_VALID_FLAGS)
6112 + && !(info->invflags & ~info->flags)
6113 + && ((!(info->flags & IPT_SCTP_CHUNK_TYPES)) ||
6114 + (info->chunk_match_type &
6115 + (SCTP_CHUNK_MATCH_ALL
6116 + | SCTP_CHUNK_MATCH_ANY
6117 + | SCTP_CHUNK_MATCH_ONLY)));
6120 +static struct ipt_match sctp_match =
6122 + .list = { NULL, NULL},
6125 + .checkentry = &checkentry,
6130 +static int __init init(void)
6132 + return ipt_register_match(&sctp_match);
6135 +static void __exit fini(void)
6137 + ipt_unregister_match(&sctp_match);
6143 +MODULE_LICENSE("GPL");
6144 +MODULE_AUTHOR("Kiran Kumar Immidi");
6145 +MODULE_DESCRIPTION("Match for SCTP protocol packets");
6147 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_state.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_state.c
6148 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_state.c 2004-03-30 05:27:42.000000000 +0200
6149 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_state.c 2004-03-30 11:11:27.000000000 +0200
6151 enum ip_conntrack_info ctinfo;
6152 unsigned int statebit;
6154 - if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
6155 + if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
6156 + statebit = IPT_STATE_UNTRACKED;
6157 + else if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
6158 statebit = IPT_STATE_INVALID;
6160 statebit = IPT_STATE_BIT(ctinfo);
6161 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_time.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_time.c
6162 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_time.c 1970-01-01 01:00:00.000000000 +0100
6163 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_time.c 2004-03-30 11:11:33.000000000 +0200
6166 + This is a module which is used for time matching
6167 + It is using some modified code from dietlibc (localtime() function)
6168 + that you can find at http://www.fefe.de/dietlibc/
6169 + This file is distributed under the terms of the GNU General Public
6170 + License (GPL). Copies of the GPL can be obtained from: ftp://prep.ai.mit.edu/pub/gnu/GPL
6171 + 2001-05-04 Fabrice MARIE <fabrice@netfilter.org> : initial development.
6172 + 2001-21-05 Fabrice MARIE <fabrice@netfilter.org> : bug fix in the match code,
6173 + thanks to "Zeng Yu" <zengy@capitel.com.cn> for bug report.
6174 + 2001-26-09 Fabrice MARIE <fabrice@netfilter.org> : force the match to be in LOCAL_IN or PRE_ROUTING only.
6175 + 2001-30-11 Fabrice : added the possibility to use the match in FORWARD/OUTPUT with a little hack,
6176 + added Nguyen Dang Phuoc Dong <dongnd@tlnet.com.vn> patch to support timezones.
6179 +#include <linux/module.h>
6180 +#include <linux/skbuff.h>
6181 +#include <linux/netfilter_ipv4/ip_tables.h>
6182 +#include <linux/netfilter_ipv4/ipt_time.h>
6183 +#include <linux/time.h>
6185 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
6186 +MODULE_DESCRIPTION("Match arrival timestamp");
6187 +MODULE_LICENSE("GPL");
6191 + int tm_sec; /* Seconds. [0-60] (1 leap second) */
6192 + int tm_min; /* Minutes. [0-59] */
6193 + int tm_hour; /* Hours. [0-23] */
6194 + int tm_mday; /* Day. [1-31] */
6195 + int tm_mon; /* Month. [0-11] */
6196 + int tm_year; /* Year - 1900. */
6197 + int tm_wday; /* Day of week. [0-6] */
6198 + int tm_yday; /* Days in year.[0-365] */
6199 + int tm_isdst; /* DST. [-1/0/1]*/
6201 + long int tm_gmtoff; /* we don't care, we count from GMT */
6202 + const char *tm_zone; /* we don't care, we count from GMT */
6206 +localtime(const time_t *timepr, struct tm *r);
6209 +match(const struct sk_buff *skb,
6210 + const struct net_device *in,
6211 + const struct net_device *out,
6212 + const void *matchinfo,
6215 + u_int16_t datalen,
6218 + const struct ipt_time_info *info = matchinfo; /* match info for rule */
6219 + struct tm currenttime; /* time human readable */
6220 + u_int8_t days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
6221 + u_int16_t packet_time;
6222 + struct timeval kerneltimeval;
6223 + time_t packet_local_time;
6225 + /* if kerneltime=1, we don't read the skb->timestamp but kernel time instead */
6226 + if (info->kerneltime)
6228 + do_gettimeofday(&kerneltimeval);
6229 + packet_local_time = kerneltimeval.tv_sec;
6232 + packet_local_time = skb->stamp.tv_sec;
6234 + /* Transform the timestamp of the packet, in a human readable form */
6235 + localtime(&packet_local_time, ¤ttime);
6237 + /* check if we match this timestamp, we start by the days... */
6238 + if ((days_of_week[currenttime.tm_wday] & info->days_match) != days_of_week[currenttime.tm_wday])
6239 + return 0; /* the day doesn't match */
6241 + /* ... check the time now */
6242 + packet_time = (currenttime.tm_hour * 60) + currenttime.tm_min;
6243 + if ((packet_time < info->time_start) || (packet_time > info->time_stop))
6246 + /* here we match ! */
6251 +checkentry(const char *tablename,
6252 + const struct ipt_ip *ip,
6254 + unsigned int matchsize,
6255 + unsigned int hook_mask)
6257 + struct ipt_time_info *info = matchinfo; /* match info for rule */
6259 + /* First, check that we are in the correct hook */
6260 + /* PRE_ROUTING, LOCAL_IN or FROWARD */
6262 + & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
6264 + printk("ipt_time: error, only valid for PRE_ROUTING, LOCAL_IN, FORWARD and OUTPUT)\n");
6267 + /* we use the kerneltime if we are in forward or output */
6268 + info->kerneltime = 1;
6269 + if (hook_mask & ~((1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
6270 + /* if not, we use the skb time */
6271 + info->kerneltime = 0;
6273 + /* Check the size */
6274 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_time_info)))
6276 + /* Now check the coherence of the data ... */
6277 + if ((info->time_start > 1439) || /* 23*60+59 = 1439*/
6278 + (info->time_stop > 1439))
6280 + printk(KERN_WARNING "ipt_time: invalid argument\n");
6287 +static struct ipt_match time_match
6288 += { { NULL, NULL }, "time", &match, &checkentry, NULL, THIS_MODULE };
6290 +static int __init init(void)
6292 + printk("ipt_time loading\n");
6293 + return ipt_register_match(&time_match);
6296 +static void __exit fini(void)
6298 + ipt_unregister_match(&time_match);
6299 + printk("ipt_time unloaded\n");
6306 +/* The part below is borowed and modified from dietlibc */
6308 +/* seconds per day */
6309 +#define SPD 24*60*60
6312 +localtime(const time_t *timepr, struct tm *r) {
6315 + extern struct timezone sys_tz;
6316 + const unsigned int __spm[12] =
6323 + (31+28+31+30+31+30),
6324 + (31+28+31+30+31+30+31),
6325 + (31+28+31+30+31+30+31+31),
6326 + (31+28+31+30+31+30+31+31+30),
6327 + (31+28+31+30+31+30+31+31+30+31),
6328 + (31+28+31+30+31+30+31+31+30+31+30),
6330 + register time_t work;
6332 + timep = (*timepr) - (sys_tz.tz_minuteswest * 60);
6334 + r->tm_sec=work%60; work/=60;
6335 + r->tm_min=work%60; r->tm_hour=work/60;
6337 + r->tm_wday=(4+work)%7;
6338 + for (i=1970; ; ++i) {
6339 + register time_t k= (!(i%4) && ((i%100) || !(i%400)))?366:365;
6345 + r->tm_year=i-1900;
6346 + for (i=11; i && __spm[i]>work; --i) ;
6348 + r->tm_mday=work-__spm[i]+1;
6350 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_u32.c linux-2.6.5-rc3/net/ipv4/netfilter/ipt_u32.c
6351 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/ipt_u32.c 1970-01-01 01:00:00.000000000 +0100
6352 +++ linux-2.6.5-rc3/net/ipv4/netfilter/ipt_u32.c 2004-03-30 11:11:35.000000000 +0200
6354 +/* Kernel module to match u32 packet content. */
6357 +U32 tests whether quantities of up to 4 bytes extracted from a packet
6358 +have specified values. The specification of what to extract is general
6359 +enough to find data at given offsets from tcp headers or payloads.
6362 + The argument amounts to a program in a small language described below.
6363 + tests := location = value | tests && location = value
6364 + value := range | value , range
6365 + range := number | number : number
6366 + a single number, n, is interpreted the same as n:n
6367 + n:m is interpreted as the range of numbers >=n and <=m
6368 + location := number | location operator number
6369 + operator := & | << | >> | @
6371 + The operators &, <<, >>, && mean the same as in c. The = is really a set
6372 + membership operator and the value syntax describes a set. The @ operator
6373 + is what allows moving to the next header and is described further below.
6375 + *** Until I can find out how to avoid it, there are some artificial limits
6376 + on the size of the tests:
6377 + - no more than 10 ='s (and 9 &&'s) in the u32 argument
6378 + - no more than 10 ranges (and 9 commas) per value
6379 + - no more than 10 numbers (and 9 operators) per location
6381 + To describe the meaning of location, imagine the following machine that
6382 + interprets it. There are three registers:
6383 + A is of type char*, initially the address of the IP header
6384 + B and C are unsigned 32 bit integers, initially zero
6386 + The instructions are:
6387 + number B = number;
6388 + C = (*(A+B)<<24)+(*(A+B+1)<<16)+(*(A+B+2)<<8)+*(A+B+3)
6389 + &number C = C&number
6390 + <<number C = C<<number
6391 + >>number C = C>>number
6392 + @number A = A+C; then do the instruction number
6393 + Any access of memory outside [skb->head,skb->end] causes the match to fail.
6394 + Otherwise the result of the computation is the final value of C.
6396 + Whitespace is allowed but not required in the tests.
6397 + However the characters that do occur there are likely to require
6398 + shell quoting, so it's a good idea to enclose the arguments in quotes.
6401 + match IP packets with total length >= 256
6402 + The IP header contains a total length field in bytes 2-3.
6403 + --u32 "0&0xFFFF=0x100:0xFFFF"
6405 + AND that with FFFF (giving bytes 2-3),
6406 + and test whether that's in the range [0x100:0xFFFF]
6408 +Example: (more realistic, hence more complicated)
6409 + match icmp packets with icmp type 0
6410 + First test that it's an icmp packet, true iff byte 9 (protocol) = 1
6411 + --u32 "6&0xFF=1 && ...
6412 + read bytes 6-9, use & to throw away bytes 6-8 and compare the result to 1
6413 + Next test that it's not a fragment.
6414 + (If so it might be part of such a packet but we can't always tell.)
6415 + n.b. This test is generally needed if you want to match anything
6416 + beyond the IP header.
6417 + The last 6 bits of byte 6 and all of byte 7 are 0 iff this is a complete
6418 + packet (not a fragment). Alternatively, you can allow first fragments
6419 + by only testing the last 5 bits of byte 6.
6420 + ... 4&0x3FFF=0 && ...
6421 + Last test: the first byte past the IP header (the type) is 0
6422 + This is where we have to use the @syntax. The length of the IP header
6423 + (IHL) in 32 bit words is stored in the right half of byte 0 of the
6425 + ... 0>>22&0x3C@0>>24=0"
6426 + The first 0 means read bytes 0-3,
6427 + >>22 means shift that 22 bits to the right. Shifting 24 bits would give
6428 + the first byte, so only 22 bits is four times that plus a few more bits.
6429 + &3C then eliminates the two extra bits on the right and the first four
6430 + bits of the first byte.
6431 + For instance, if IHL=5 then the IP header is 20 (4 x 5) bytes long.
6432 + In this case bytes 0-1 are (in binary) xxxx0101 yyzzzzzz,
6433 + >>22 gives the 10 bit value xxxx0101yy and &3C gives 010100.
6434 + @ means to use this number as a new offset into the packet, and read
6435 + four bytes starting from there. This is the first 4 bytes of the icmp
6436 + payload, of which byte 0 is the icmp type. Therefore we simply shift
6437 + the value 24 to the right to throw out all but the first byte and compare
6438 + the result with 0.
6441 + tcp payload bytes 8-12 is any of 1, 2, 5 or 8
6442 + First we test that the packet is a tcp packet (similar to icmp).
6443 + --u32 "6&0xFF=6 && ...
6444 + Next, test that it's not a fragment (same as above).
6445 + ... 0>>22&0x3C@12>>26&0x3C@8=1,2,5,8"
6446 + 0>>22&3C as above computes the number of bytes in the IP header.
6447 + @ makes this the new offset into the packet, which is the start of the
6448 + tcp header. The length of the tcp header (again in 32 bit words) is
6449 + the left half of byte 12 of the tcp header. The 12>>26&3C
6450 + computes this length in bytes (similar to the IP header before).
6451 + @ makes this the new offset, which is the start of the tcp payload.
6452 + Finally 8 reads bytes 8-12 of the payload and = checks whether the
6453 + result is any of 1, 2, 5 or 8
6456 +#include <linux/module.h>
6457 +#include <linux/skbuff.h>
6459 +#include <linux/netfilter_ipv4/ipt_u32.h>
6460 +#include <linux/netfilter_ipv4/ip_tables.h>
6462 +/* #include <asm-i386/timex.h> for timing */
6464 +MODULE_AUTHOR("Don Cohen <don@isis.cs3-inc.com>");
6465 +MODULE_DESCRIPTION("IP tables u32 matching module");
6466 +MODULE_LICENSE("GPL");
6469 +match(const struct sk_buff *skb,
6470 + const struct net_device *in,
6471 + const struct net_device *out,
6472 + const void *matchinfo,
6475 + u_int16_t datalen,
6478 + const struct ipt_u32 *data = matchinfo;
6480 + unsigned char* origbase = (char*)skb->nh.iph;
6481 + unsigned char* base = origbase;
6482 + unsigned char* head = skb->head;
6483 + unsigned char* end = skb->end;
6485 + u_int32_t pos, val;
6486 + /* unsigned long long cycles1, cycles2, cycles3, cycles4;
6487 + cycles1 = get_cycles(); */
6489 + for (testind=0; testind < data->ntests; testind++) {
6490 + base = origbase; /* reset for each test */
6491 + pos = data->tests[testind].location[0].number;
6492 + if (base+pos+3 > end || base+pos < head)
6494 + val = (base[pos]<<24) + (base[pos+1]<<16) +
6495 + (base[pos+2]<<8) + base[pos+3];
6496 + nnums = data->tests[testind].nnums;
6497 + for (i=1; i < nnums; i++) {
6498 + u_int32_t number = data->tests[testind].location[i].number;
6499 + switch (data->tests[testind].location[i].nextop) {
6501 + val = val & number;
6503 + case IPT_U32_LEFTSH:
6504 + val = val << number;
6506 + case IPT_U32_RIGHTSH:
6507 + val = val >> number;
6510 + base = base + val;
6512 + if (base+pos+3 > end || base+pos < head)
6514 + val = (base[pos]<<24) + (base[pos+1]<<16) +
6515 + (base[pos+2]<<8) + base[pos+3];
6519 + nvals = data->tests[testind].nvalues;
6520 + for (i=0; i < nvals; i++) {
6521 + if ((data->tests[testind].value[i].min <= val) &&
6522 + (val <= data->tests[testind].value[i].max)) {
6526 + if (i >= data->tests[testind].nvalues) {
6527 + /* cycles2 = get_cycles();
6528 + printk("failed %d in %d cycles\n", testind,
6529 + cycles2-cycles1); */
6533 + /* cycles2 = get_cycles();
6534 + printk("succeeded in %d cycles\n", cycles2-cycles1); */
6539 +checkentry(const char *tablename,
6540 + const struct ipt_ip *ip,
6542 + unsigned int matchsize,
6543 + unsigned int hook_mask)
6545 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_u32)))
6550 +static struct ipt_match u32_match
6551 += { { NULL, NULL }, "u32", &match, &checkentry, NULL, THIS_MODULE };
6553 +static int __init init(void)
6555 + return ipt_register_match(&u32_match);
6558 +static void __exit fini(void)
6560 + ipt_unregister_match(&u32_match);
6565 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv4/netfilter/iptable_raw.c linux-2.6.5-rc3/net/ipv4/netfilter/iptable_raw.c
6566 --- linux-2.6.5-rc3.org/net/ipv4/netfilter/iptable_raw.c 1970-01-01 01:00:00.000000000 +0100
6567 +++ linux-2.6.5-rc3/net/ipv4/netfilter/iptable_raw.c 2004-03-30 11:11:27.000000000 +0200
6570 + * 'raw' table, which is the very first hooked in at PRE_ROUTING and LOCAL_OUT .
6572 + * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
6574 +#include <linux/module.h>
6575 +#include <linux/netfilter_ipv4/ip_tables.h>
6577 +#define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
6579 +/* Standard entry. */
6580 +struct ipt_standard
6582 + struct ipt_entry entry;
6583 + struct ipt_standard_target target;
6586 +struct ipt_error_target
6588 + struct ipt_entry_target target;
6589 + char errorname[IPT_FUNCTION_MAXNAMELEN];
6594 + struct ipt_entry entry;
6595 + struct ipt_error_target target;
6600 + struct ipt_replace repl;
6601 + struct ipt_standard entries[2];
6602 + struct ipt_error term;
6603 +} initial_table __initdata
6604 += { { "raw", RAW_VALID_HOOKS, 3,
6605 + sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
6606 + { [NF_IP_PRE_ROUTING] 0,
6607 + [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
6608 + { [NF_IP_PRE_ROUTING] 0,
6609 + [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
6613 + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
6615 + sizeof(struct ipt_entry),
6616 + sizeof(struct ipt_standard),
6617 + 0, { 0, 0 }, { } },
6618 + { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
6619 + -NF_ACCEPT - 1 } },
6621 + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
6623 + sizeof(struct ipt_entry),
6624 + sizeof(struct ipt_standard),
6625 + 0, { 0, 0 }, { } },
6626 + { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
6627 + -NF_ACCEPT - 1 } }
6630 + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
6632 + sizeof(struct ipt_entry),
6633 + sizeof(struct ipt_error),
6634 + 0, { 0, 0 }, { } },
6635 + { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } },
6642 +static struct ipt_table packet_raw = {
6644 + .table = &initial_table.repl,
6645 + .valid_hooks = RAW_VALID_HOOKS,
6646 + .lock = RW_LOCK_UNLOCKED,
6650 +/* The work comes in here from netfilter.c. */
6651 +static unsigned int
6652 +ipt_hook(unsigned int hook,
6653 + struct sk_buff **pskb,
6654 + const struct net_device *in,
6655 + const struct net_device *out,
6656 + int (*okfn)(struct sk_buff *))
6658 + return ipt_do_table(pskb, hook, in, out, &packet_raw, NULL);
6661 +/* 'raw' is the very first table. */
6662 +static struct nf_hook_ops ipt_ops[] = {
6666 + .hooknum = NF_IP_PRE_ROUTING,
6667 + .priority = NF_IP_PRI_RAW
6672 + .hooknum = NF_IP_LOCAL_OUT,
6673 + .priority = NF_IP_PRI_RAW
6677 +static int __init init(void)
6681 + /* Register table */
6682 + ret = ipt_register_table(&packet_raw);
6686 + /* Register hooks */
6687 + ret = nf_register_hook(&ipt_ops[0]);
6689 + goto cleanup_table;
6691 + ret = nf_register_hook(&ipt_ops[1]);
6693 + goto cleanup_hook0;
6698 + nf_unregister_hook(&ipt_ops[0]);
6700 + ipt_unregister_table(&packet_raw);
6705 +static void __exit fini(void)
6709 + for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++)
6710 + nf_unregister_hook(&ipt_ops[i]);
6712 + ipt_unregister_table(&packet_raw);
6717 +MODULE_LICENSE("GPL");
6718 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv6/netfilter/Kconfig linux-2.6.5-rc3/net/ipv6/netfilter/Kconfig
6719 --- linux-2.6.5-rc3.org/net/ipv6/netfilter/Kconfig 2004-03-30 05:27:07.000000000 +0200
6720 +++ linux-2.6.5-rc3/net/ipv6/netfilter/Kconfig 2004-03-30 11:11:27.000000000 +0200
6721 @@ -218,5 +218,42 @@
6722 To compile it as a module, choose M here. If unsure, say N.
6724 #dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES
6725 +config IP6_NF_TARGET_HL
6726 + tristate 'HL target support'
6727 + depends on IP6_NF_MANGLE
6730 +config IP6_NF_TARGET_REJECT
6731 + tristate 'REJECT target support'
6732 + depends on IP6_NF_FILTER
6735 +config IP6_NF_MATCH_FUZZY
6736 + tristate 'Fuzzy match support'
6737 + depends on IP6_NF_FILTER
6740 +config IP6_NF_MATCH_NTH
6741 + tristate 'Nth match support'
6742 + depends on IP6_NF_IPTABLES
6745 +config IP6_NF_MATCH_RANDOM
6746 + tristate 'Random match support'
6747 + depends on IP6_NF_IPTABLES
6751 + tristate 'raw table support (required for TRACE)'
6752 + depends on IP6_NF_IPTABLES
6754 + This option adds a `raw' table to ip6tables. This table is the very
6755 + first in the netfilter framework and hooks in at the PREROUTING
6756 + and OUTPUT chains.
6758 + If you want to compile it as a module, say M here and read
6759 + <file:Documentation/modules.txt>. If unsure, say `N'.
6764 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv6/netfilter/Makefile linux-2.6.5-rc3/net/ipv6/netfilter/Makefile
6765 --- linux-2.6.5-rc3.org/net/ipv6/netfilter/Makefile 2004-03-30 05:26:29.000000000 +0200
6766 +++ linux-2.6.5-rc3/net/ipv6/netfilter/Makefile 2004-03-30 11:11:27.000000000 +0200
6768 obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o
6769 obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
6770 obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o
6771 +obj-$(CONFIG_IP6_NF_MATCH_FUZZY) += ip6t_fuzzy.o
6772 obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
6773 obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
6774 obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
6776 obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
6777 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
6778 obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
6779 +obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
6780 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
6781 obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
6782 +obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
6784 +obj-$(CONFIG_IP6_NF_MATCH_RANDOM) += ip6t_random.o
6786 +obj-$(CONFIG_IP6_NF_MATCH_NTH) += ip6t_nth.o
6787 +obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
6788 obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
6789 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv6/netfilter/ip6t_HL.c linux-2.6.5-rc3/net/ipv6/netfilter/ip6t_HL.c
6790 --- linux-2.6.5-rc3.org/net/ipv6/netfilter/ip6t_HL.c 1970-01-01 01:00:00.000000000 +0100
6791 +++ linux-2.6.5-rc3/net/ipv6/netfilter/ip6t_HL.c 2004-03-30 11:10:35.000000000 +0200
6794 + * Hop Limit modification target for ip6tables
6795 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
6796 + * Based on HW's TTL module
6798 + * This software is distributed under the terms of GNU GPL
6801 +#include <linux/module.h>
6802 +#include <linux/skbuff.h>
6803 +#include <linux/ip.h>
6805 +#include <linux/netfilter_ipv6/ip6_tables.h>
6806 +#include <linux/netfilter_ipv6/ip6t_HL.h>
6808 +MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
6809 +MODULE_DESCRIPTION("IP tables Hop Limit modification module");
6810 +MODULE_LICENSE("GPL");
6812 +static unsigned int ip6t_hl_target(struct sk_buff **pskb, unsigned int hooknum,
6813 + const struct net_device *in, const struct net_device *out,
6814 + const void *targinfo, void *userinfo)
6816 + struct ipv6hdr *ip6h = (*pskb)->nh.ipv6h;
6817 + const struct ip6t_HL_info *info = targinfo;
6818 + u_int16_t diffs[2];
6821 + switch (info->mode) {
6823 + new_hl = info->hop_limit;
6826 + new_hl = ip6h->hop_limit + info->hop_limit;
6831 + new_hl = ip6h->hop_limit + info->hop_limit;
6836 + new_hl = ip6h->hop_limit;
6840 + if (new_hl != ip6h->hop_limit) {
6841 + diffs[0] = htons(((unsigned)ip6h->hop_limit) << 8) ^ 0xFFFF;
6842 + ip6h->hop_limit = new_hl;
6843 + diffs[1] = htons(((unsigned)ip6h->hop_limit) << 8);
6846 + return IP6T_CONTINUE;
6849 +static int ip6t_hl_checkentry(const char *tablename,
6850 + const struct ip6t_entry *e,
6852 + unsigned int targinfosize,
6853 + unsigned int hook_mask)
6855 + struct ip6t_HL_info *info = targinfo;
6857 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_HL_info))) {
6858 + printk(KERN_WARNING "HL: targinfosize %u != %Zu\n",
6860 + IP6T_ALIGN(sizeof(struct ip6t_HL_info)));
6864 + if (strcmp(tablename, "mangle")) {
6865 + printk(KERN_WARNING "HL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
6869 + if (info->mode > IP6T_HL_MAXMODE) {
6870 + printk(KERN_WARNING "HL: invalid or unknown Mode %u\n",
6875 + if ((info->mode != IP6T_HL_SET) && (info->hop_limit == 0)) {
6876 + printk(KERN_WARNING "HL: increment/decrement doesn't make sense with value 0\n");
6883 +static struct ip6t_target ip6t_HL = { { NULL, NULL }, "HL",
6884 + ip6t_hl_target, ip6t_hl_checkentry, NULL, THIS_MODULE };
6886 +static int __init init(void)
6888 + return ip6t_register_target(&ip6t_HL);
6891 +static void __exit fini(void)
6893 + ip6t_unregister_target(&ip6t_HL);
6898 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv6/netfilter/ip6t_LOG.c linux-2.6.5-rc3/net/ipv6/netfilter/ip6t_LOG.c
6899 --- linux-2.6.5-rc3.org/net/ipv6/netfilter/ip6t_LOG.c 2004-03-30 05:25:41.000000000 +0200
6900 +++ linux-2.6.5-rc3/net/ipv6/netfilter/ip6t_LOG.c 2004-03-30 11:10:29.000000000 +0200
6902 #include <net/udp.h>
6903 #include <net/tcp.h>
6904 #include <net/ipv6.h>
6905 +#include <linux/netfilter.h>
6906 #include <linux/netfilter_ipv6/ip6_tables.h>
6908 MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
6909 MODULE_DESCRIPTION("IP6 tables LOG target module");
6910 MODULE_LICENSE("GPL");
6912 +static unsigned int nflog = 1;
6913 +MODULE_PARM(nflog, "i");
6914 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
6917 #include <net/route.h>
6918 #include <linux/netfilter_ipv6/ip6t_LOG.h>
6919 @@ -265,40 +270,38 @@
6923 -static unsigned int
6924 -ip6t_log_target(struct sk_buff **pskb,
6925 - unsigned int hooknum,
6927 +ip6t_log_packet(unsigned int hooknum,
6928 + const struct sk_buff *skb,
6929 const struct net_device *in,
6930 const struct net_device *out,
6931 - const void *targinfo,
6933 + const struct ip6t_log_info *loginfo,
6934 + const char *level_string,
6935 + const char *prefix)
6937 - struct ipv6hdr *ipv6h = (*pskb)->nh.ipv6h;
6938 - const struct ip6t_log_info *loginfo = targinfo;
6939 - char level_string[4] = "< >";
6940 + struct ipv6hdr *ipv6h = skb->nh.ipv6h;
6942 - level_string[1] = '0' + (loginfo->level % 8);
6943 spin_lock_bh(&log_lock);
6944 printk(level_string);
6945 printk("%sIN=%s OUT=%s ",
6947 + prefix == NULL ? loginfo->prefix : prefix,
6949 out ? out->name : "");
6951 /* MAC logging for input chain only. */
6953 - if ((*pskb)->dev && (*pskb)->dev->hard_header_len && (*pskb)->mac.raw != (void*)ipv6h) {
6954 - if ((*pskb)->dev->type != ARPHRD_SIT){
6955 + if (skb->dev && skb->dev->hard_header_len && skb->mac.raw != (void*)ipv6h) {
6956 + if (skb->dev->type != ARPHRD_SIT){
6958 - unsigned char *p = (*pskb)->mac.raw;
6959 - for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++)
6960 + unsigned char *p = skb->mac.raw;
6961 + for (i = 0; i < skb->dev->hard_header_len; i++,p++)
6962 printk("%02x%c", *p,
6963 - i==(*pskb)->dev->hard_header_len - 1
6964 + i==skb->dev->hard_header_len - 1
6968 - unsigned char *p = (*pskb)->mac.raw;
6969 - if ( p - (ETH_ALEN*2+2) > (*pskb)->head ){
6970 + unsigned char *p = skb->mac.raw;
6971 + if ( p - (ETH_ALEN*2+2) > skb->head ){
6973 for (i = 0; i < (ETH_ALEN); i++,p++)
6974 printk("%02x%s", *p,
6975 @@ -309,10 +312,10 @@
6976 i == ETH_ALEN-1 ? ' ' : ':');
6979 - if (((*pskb)->dev->addr_len == 4) &&
6980 - (*pskb)->dev->hard_header_len > 20){
6981 + if ((skb->dev->addr_len == 4) &&
6982 + skb->dev->hard_header_len > 20){
6984 - p = (*pskb)->mac.raw + 12;
6985 + p = skb->mac.raw + 12;
6986 for (i = 0; i < 4; i++,p++)
6988 i == 3 ? "->" : ".");
6989 @@ -328,10 +331,41 @@
6990 dump_packet(loginfo, ipv6h, 1);
6992 spin_unlock_bh(&log_lock);
6995 +static unsigned int
6996 +ip6t_log_target(struct sk_buff **pskb,
6997 + unsigned int hooknum,
6998 + const struct net_device *in,
6999 + const struct net_device *out,
7000 + const void *targinfo,
7003 + const struct ip6t_log_info *loginfo = targinfo;
7004 + char level_string[4] = "< >";
7006 + level_string[1] = '0' + (loginfo->level % 8);
7007 + ip6t_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL);
7009 return IP6T_CONTINUE;
7013 +ip6t_logfn(unsigned int hooknum,
7014 + const struct sk_buff *skb,
7015 + const struct net_device *in,
7016 + const struct net_device *out,
7017 + const char *prefix)
7019 + struct ip6t_log_info loginfo = {
7021 + .logflags = IP6T_LOG_MASK,
7025 + ip6t_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
7028 static int ip6t_log_checkentry(const char *tablename,
7029 const struct ip6t_entry *e,
7031 @@ -360,20 +394,27 @@
7035 -static struct ip6t_target ip6t_log_reg
7036 -= { { NULL, NULL }, "LOG", ip6t_log_target, ip6t_log_checkentry, NULL,
7038 +static struct ip6t_target ip6t_log_reg = {
7040 + .target = ip6t_log_target,
7041 + .checkentry = ip6t_log_checkentry,
7042 + .me = THIS_MODULE,
7045 static int __init init(void)
7047 if (ip6t_register_target(&ip6t_log_reg))
7050 + nf_log_register(PF_INET6, &ip6t_logfn);
7055 static void __exit fini(void)
7058 + nf_log_unregister(PF_INET6, &ip6t_logfn);
7059 ip6t_unregister_target(&ip6t_log_reg);
7062 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv6/netfilter/ip6t_REJECT.c linux-2.6.5-rc3/net/ipv6/netfilter/ip6t_REJECT.c
7063 --- linux-2.6.5-rc3.org/net/ipv6/netfilter/ip6t_REJECT.c 1970-01-01 01:00:00.000000000 +0100
7064 +++ linux-2.6.5-rc3/net/ipv6/netfilter/ip6t_REJECT.c 2004-03-30 11:10:40.000000000 +0200
7067 + * IP6 tables REJECT target module
7068 + * Linux INET6 implementation
7070 + * Copyright (C)2003 USAGI/WIDE Project
7073 + * Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
7075 + * Based on net/ipv4/netfilter/ipt_REJECT.c
7077 + * This program is free software; you can redistribute it and/or
7078 + * modify it under the terms of the GNU General Public License
7079 + * as published by the Free Software Foundation; either version
7080 + * 2 of the License, or (at your option) any later version.
7083 +#include <linux/config.h>
7084 +#include <linux/module.h>
7085 +#include <linux/skbuff.h>
7086 +#include <linux/icmpv6.h>
7087 +#include <net/ipv6.h>
7088 +#include <net/tcp.h>
7089 +#include <net/icmp.h>
7090 +#include <net/ip6_fib.h>
7091 +#include <net/ip6_route.h>
7092 +#include <net/flow.h>
7093 +#include <linux/netfilter_ipv6/ip6_tables.h>
7094 +#include <linux/netfilter_ipv6/ip6t_REJECT.h>
7096 +MODULE_AUTHOR("Yasuyuki KOZAKAI <yasuyuki.kozakai@toshiba.co.jp>");
7097 +MODULE_DESCRIPTION("IP6 tables REJECT target module");
7098 +MODULE_LICENSE("GPL");
7101 +#define DEBUGP printk
7103 +#define DEBUGP(format, args...)
7107 +static void connection_attach(struct sk_buff *new_skb, struct nf_ct_info *nfct)
7109 + void (*attach)(struct sk_buff *, struct nf_ct_info *);
7110 + if (nfct && (attach = ip6_ct_attach) != NULL) {
7112 + attach(new_skb, nfct);
7117 +static int maybe_reroute(struct sk_buff *skb)
7119 + if (skb->nfcache & NFC_ALTERED){
7120 + if (ip6_route_me_harder(skb) != 0){
7126 + return dst_output(skb);
7129 +/* Send RST reply */
7130 +static void send_reset(struct sk_buff *oldskb)
7132 + struct sk_buff *nskb;
7133 + struct tcphdr otcph, *tcph;
7134 + unsigned int otcplen, tcphoff, hh_len;
7136 + struct ipv6hdr *oip6h = oldskb->nh.ipv6h, *ip6h;
7137 + struct dst_entry *dst = NULL;
7140 + proto = oip6h->nexthdr;
7143 + if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) ||
7144 + (!(ipv6_addr_type(&oip6h->daddr) & IPV6_ADDR_UNICAST))) {
7145 + DEBUGP("ip6t_REJECT: addr is not unicast.\n");
7149 + tcphoff = ipv6_skip_exthdr(oldskb, ((u8*)(oip6h+1) - oldskb->data),
7150 + &proto, oldskb->len - ((u8*)(oip6h+1)
7153 + if ((tcphoff < 0) || (tcphoff > oldskb->len)) {
7154 + DEBUGP("ip6t_REJECT: Can't get TCP header.\n");
7158 + otcplen = oldskb->len - tcphoff;
7160 + /* IP header checks: fragment, too short. */
7161 + if ((proto != IPPROTO_TCP) || (otcplen < sizeof(struct tcphdr))) {
7162 + DEBUGP("ip6t_REJECT: proto(%d) != IPPROTO_TCP, or too short. otcplen = %d\n",
7167 + if (skb_copy_bits(oldskb, tcphoff, &otcph, sizeof(struct tcphdr))) {
7168 + if (net_ratelimit())
7169 + printk("ip6t_REJECT: Can't copy tcp header\n");
7173 + /* No RST for RST. */
7175 + DEBUGP("ip6t_REJECT: RST is set\n");
7179 + /* Check checksum. */
7180 + if (csum_ipv6_magic(&oip6h->saddr, &oip6h->daddr, otcplen, IPPROTO_TCP,
7181 + skb_checksum(oldskb, tcphoff, otcplen, 0))) {
7182 + DEBUGP("ip6t_REJECT: TCP checksum is invalid\n");
7186 + memset(&fl, 0, sizeof(fl));
7187 + fl.proto = IPPROTO_TCP;
7188 + ipv6_addr_copy(&fl.fl6_src, &oip6h->daddr);
7189 + ipv6_addr_copy(&fl.fl6_dst, &oip6h->saddr);
7190 + fl.fl_ip_sport = otcph.dest;
7191 + fl.fl_ip_dport = otcph.source;
7192 + err = ip6_dst_lookup(NULL, &dst, &fl);
7194 + if (net_ratelimit())
7195 + printk("ip6t_REJECT: can't find dst. err = %d\n", err);
7199 + hh_len = (dst->dev->hard_header_len + 15)&~15;
7200 + nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr)
7201 + + sizeof(struct tcphdr) + dst->trailer_len,
7205 + if (net_ratelimit())
7206 + printk("ip6t_REJECT: Can't alloc skb\n");
7214 + skb_reserve(nskb, hh_len + dst->header_len);
7216 + ip6h = nskb->nh.ipv6h = (struct ipv6hdr *)
7217 + skb_put(nskb, sizeof(struct ipv6hdr));
7218 + ip6h->version = 6;
7219 + ip6h->hop_limit = dst_metric(dst, RTAX_HOPLIMIT);
7220 + ip6h->nexthdr = IPPROTO_TCP;
7221 + ip6h->payload_len = htons(sizeof(struct tcphdr));
7222 + ipv6_addr_copy(&ip6h->saddr, &oip6h->daddr);
7223 + ipv6_addr_copy(&ip6h->daddr, &oip6h->saddr);
7225 + tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
7226 + /* Truncate to length (no data) */
7227 + tcph->doff = sizeof(struct tcphdr)/4;
7228 + tcph->source = otcph.dest;
7229 + tcph->dest = otcph.source;
7233 + tcph->seq = otcph.ack_seq;
7234 + tcph->ack_seq = 0;
7237 + tcph->ack_seq = htonl(ntohl(otcph.seq) + otcph.syn + otcph.fin
7238 + + otcplen - (otcph.doff<<2));
7243 + ((u_int8_t *)tcph)[13] = 0;
7245 + tcph->ack = needs_ack;
7247 + tcph->urg_ptr = 0;
7250 + /* Adjust TCP checksum */
7251 + tcph->check = csum_ipv6_magic(&nskb->nh.ipv6h->saddr,
7252 + &nskb->nh.ipv6h->daddr,
7253 + sizeof(struct tcphdr), IPPROTO_TCP,
7254 + csum_partial((char *)tcph,
7255 + sizeof(struct tcphdr), 0));
7258 + connection_attach(nskb, oldskb->nfct);
7261 + NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
7267 +static void send_unreach(struct sk_buff *skb_in, unsigned char code)
7269 + struct ipv6hdr *ip6h, *hdr = skb_in->nh.ipv6h;
7270 + struct icmp6hdr *icmp6h;
7271 + struct dst_entry *dst = NULL;
7272 + struct rt6_info *rt;
7275 + unsigned int len, datalen, hh_len;
7276 + int saddr_type, daddr_type;
7277 + unsigned int ptr, ip6off;
7280 + struct sk_buff *nskb;
7283 + saddr_type = ipv6_addr_type(&hdr->saddr);
7284 + daddr_type = ipv6_addr_type(&hdr->daddr);
7286 + if ((!(saddr_type & IPV6_ADDR_UNICAST)) ||
7287 + (!(daddr_type & IPV6_ADDR_UNICAST))) {
7288 + DEBUGP("ip6t_REJECT: addr is not unicast.\n");
7292 + ip6off = skb_in->nh.raw - skb_in->data;
7293 + proto = hdr->nexthdr;
7294 + ptr = ipv6_skip_exthdr(skb_in, ip6off + sizeof(struct ipv6hdr), &proto,
7295 + skb_in->len - ip6off);
7297 + if ((ptr < 0) || (ptr > skb_in->len)) {
7298 + ptr = ip6off + sizeof(struct ipv6hdr);
7299 + proto = hdr->nexthdr;
7300 + } else if (proto == IPPROTO_ICMPV6) {
7303 + if (skb_copy_bits(skb_in, ptr + offsetof(struct icmp6hdr,
7304 + icmp6_type), &type, 1)) {
7305 + DEBUGP("ip6t_REJECT: Can't get ICMPv6 type\n");
7309 + if (!(type & ICMPV6_INFOMSG_MASK)) {
7310 + DEBUGP("ip6t_REJECT: no reply to icmp error\n");
7313 + } else if (proto == IPPROTO_UDP) {
7314 + int plen = skb_in->len - (ptr - ip6off);
7317 + if (plen < sizeof(struct udphdr)) {
7318 + DEBUGP("ip6t_REJECT: too short\n");
7322 + if (skb_copy_bits(skb_in, ptr + offsetof(struct udphdr, check),
7324 + if (net_ratelimit())
7325 + printk("ip6t_REJECT: can't get copy from skb");
7330 + csum_ipv6_magic(&hdr->saddr, &hdr->daddr, plen,
7332 + skb_checksum(skb_in, ptr, plen, 0))) {
7333 + DEBUGP("ip6t_REJECT: UDP checksum is invalid.\n");
7338 + memset(&fl, 0, sizeof(fl));
7339 + fl.proto = IPPROTO_ICMPV6;
7340 + ipv6_addr_copy(&fl.fl6_src, &hdr->daddr);
7341 + ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr);
7342 + fl.fl_icmp_type = ICMPV6_DEST_UNREACH;
7343 + fl.fl_icmp_code = code;
7345 + if (ip6_dst_lookup(NULL, &dst, &fl)) {
7349 + rt = (struct rt6_info *)dst;
7352 + if (rt->rt6i_dst.plen < 128)
7353 + tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
7355 + if (!xrlim_allow(dst, tmo)) {
7356 + if (net_ratelimit())
7357 + printk("ip6t_REJECT: rate limitted\n");
7358 + goto dst_release_out;
7361 + len = skb_in->len + sizeof(struct ipv6hdr) + sizeof(struct icmp6hdr);
7363 + if (len > dst_pmtu(dst))
7364 + len = dst_pmtu(dst);
7365 + if (len > IPV6_MIN_MTU)
7366 + len = IPV6_MIN_MTU;
7368 + datalen = len - sizeof(struct ipv6hdr) - sizeof(struct icmp6hdr);
7369 + hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
7371 + nskb = alloc_skb(hh_len + 15 + dst->header_len + dst->trailer_len + len,
7375 + if (net_ratelimit())
7376 + printk("ip6t_REJECT: can't alloc skb\n");
7377 + goto dst_release_out;
7380 + nskb->priority = 0;
7384 + skb_reserve(nskb, hh_len + dst->header_len);
7386 + ip6h = nskb->nh.ipv6h = (struct ipv6hdr *)
7387 + skb_put(nskb, sizeof(struct ipv6hdr));
7388 + ip6h->version = 6;
7389 + ip6h->hop_limit = dst_metric(dst, RTAX_HOPLIMIT);
7390 + ip6h->nexthdr = IPPROTO_ICMPV6;
7391 + ip6h->payload_len = htons(datalen + sizeof(struct icmp6hdr));
7392 + ipv6_addr_copy(&ip6h->saddr, &hdr->daddr);
7393 + ipv6_addr_copy(&ip6h->daddr, &hdr->saddr);
7395 + icmp6h = (struct icmp6hdr *) skb_put(nskb, sizeof(struct icmp6hdr));
7396 + icmp6h->icmp6_type = ICMPV6_DEST_UNREACH;
7397 + icmp6h->icmp6_code = code;
7398 + icmp6h->icmp6_cksum = 0;
7400 + data = skb_put(nskb, datalen);
7402 + csum = csum_partial((unsigned char *)icmp6h, sizeof(struct icmp6hdr), 0);
7403 + csum = skb_copy_and_csum_bits(skb_in, ip6off, data, datalen, csum);
7404 + icmp6h->icmp6_cksum = csum_ipv6_magic(&hdr->saddr, &hdr->daddr,
7405 + datalen + sizeof(struct icmp6hdr),
7406 + IPPROTO_ICMPV6, csum);
7409 + connection_attach(nskb, skb_in->nfct);
7411 + NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
7418 +static unsigned int reject6_target(struct sk_buff **pskb,
7419 + unsigned int hooknum,
7420 + const struct net_device *in,
7421 + const struct net_device *out,
7422 + const void *targinfo,
7425 + const struct ip6t_reject_info *reject = targinfo;
7427 + DEBUGP(KERN_DEBUG "%s: medium point\n", __FUNCTION__);
7428 + /* WARNING: This code causes reentry within ip6tables.
7429 + This means that the ip6tables jump stack is now crap. We
7430 + must return an absolute verdict. --RR */
7431 + switch (reject->with) {
7432 + case IP6T_ICMP6_NO_ROUTE:
7433 + send_unreach(*pskb, ICMPV6_NOROUTE);
7435 + case IP6T_ICMP6_ADM_PROHIBITED:
7436 + send_unreach(*pskb, ICMPV6_ADM_PROHIBITED);
7438 + case IP6T_ICMP6_NOT_NEIGHBOUR:
7439 + send_unreach(*pskb, ICMPV6_NOT_NEIGHBOUR);
7441 + case IP6T_ICMP6_ADDR_UNREACH:
7442 + send_unreach(*pskb, ICMPV6_ADDR_UNREACH);
7444 + case IP6T_ICMP6_PORT_UNREACH:
7445 + send_unreach(*pskb, ICMPV6_PORT_UNREACH);
7447 + case IP6T_ICMP6_ECHOREPLY:
7450 + case IP6T_TCP_RESET:
7451 + send_reset(*pskb);
7454 + if (net_ratelimit())
7455 + printk(KERN_WARNING "ip6t_REJECT: case %u not handled yet\n", reject->with);
7462 +static int check(const char *tablename,
7463 + const struct ip6t_entry *e,
7465 + unsigned int targinfosize,
7466 + unsigned int hook_mask)
7468 + const struct ip6t_reject_info *rejinfo = targinfo;
7470 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
7471 + DEBUGP("ip6t_REJECT: targinfosize %u != 0\n", targinfosize);
7475 + /* Only allow these for packet filtering. */
7476 + if (strcmp(tablename, "filter") != 0) {
7477 + DEBUGP("ip6t_REJECT: bad table `%s'.\n", tablename);
7481 + if ((hook_mask & ~((1 << NF_IP6_LOCAL_IN)
7482 + | (1 << NF_IP6_FORWARD)
7483 + | (1 << NF_IP6_LOCAL_OUT))) != 0) {
7484 + DEBUGP("ip6t_REJECT: bad hook mask %X\n", hook_mask);
7488 + if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
7489 + printk("ip6t_REJECT: ECHOREPLY is not supported.\n");
7491 + } else if (rejinfo->with == IP6T_TCP_RESET) {
7492 + /* Must specify that it's a TCP packet */
7493 + if (e->ipv6.proto != IPPROTO_TCP
7494 + || (e->ipv6.invflags & IP6T_INV_PROTO)) {
7495 + DEBUGP("ip6t_REJECT: TCP_RESET illegal for non-tcp\n");
7503 +static struct ip6t_target ip6t_reject_reg = {
7505 + .target = reject6_target,
7506 + .checkentry = check,
7510 +static int __init init(void)
7512 + if (ip6t_register_target(&ip6t_reject_reg))
7517 +static void __exit fini(void)
7519 + ip6t_unregister_target(&ip6t_reject_reg);
7524 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv6/netfilter/ip6t_fuzzy.c linux-2.6.5-rc3/net/ipv6/netfilter/ip6t_fuzzy.c
7525 --- linux-2.6.5-rc3.org/net/ipv6/netfilter/ip6t_fuzzy.c 1970-01-01 01:00:00.000000000 +0100
7526 +++ linux-2.6.5-rc3/net/ipv6/netfilter/ip6t_fuzzy.c 2004-03-30 11:11:06.000000000 +0200
7529 + * This module implements a simple TSK FLC
7530 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
7531 + * to limit , in an adaptive and flexible way , the packet rate crossing
7532 + * a given stream . It serves as an initial and very simple (but effective)
7533 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
7534 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
7535 + * into our code in a precise , adaptive and efficient manner.
7536 + * The goal is very similar to that of "limit" match , but using techniques of
7537 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
7538 + * avoiding over and undershoots - and stuff like that .
7541 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
7542 + * 2002-08-17 : Changed to eliminate floating point operations .
7543 + * 2002-08-23 : Coding style changes .
7544 + * 2003-04-08 Maciej Soltysiak <solt@dns.toxicilms.tv> : IPv6 Port
7547 +#include <linux/module.h>
7548 +#include <linux/skbuff.h>
7549 +#include <linux/ipv6.h>
7550 +#include <linux/random.h>
7551 +#include <net/tcp.h>
7552 +#include <linux/spinlock.h>
7553 +#include <linux/netfilter_ipv6/ip6_tables.h>
7554 +#include <linux/netfilter_ipv6/ip6t_fuzzy.h>
7557 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
7558 + Expressed in percentage
7561 +#define PAR_LOW 1/100
7564 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED;
7566 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
7567 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
7568 +MODULE_LICENSE("GPL");
7570 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
7572 + if (tx >= maxi) return 100;
7574 + if (tx <= mini) return 0;
7576 + return ((100 * (tx-mini)) / (maxi-mini));
7579 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
7581 + if (tx <= mini) return 100;
7583 + if (tx >= maxi) return 0;
7585 + return ((100 * (maxi - tx)) / (maxi - mini));
7590 +ip6t_fuzzy_match(const struct sk_buff *pskb,
7591 + const struct net_device *in,
7592 + const struct net_device *out,
7593 + const void *matchinfo,
7596 + u_int16_t datalen,
7599 + /* From userspace */
7601 + struct ip6t_fuzzy_info *info = (struct ip6t_fuzzy_info *) matchinfo;
7603 + u_int8_t random_number;
7604 + unsigned long amount;
7605 + u_int8_t howhigh, howlow;
7608 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
7610 + info->bytes_total += pskb->len;
7611 + info->packets_total++;
7613 + info->present_time = jiffies;
7615 + if (info->present_time >= info->previous_time)
7616 + amount = info->present_time - info->previous_time;
7618 + /* There was a transition : I choose to re-sample
7619 + and keep the old acceptance rate...
7623 + info->previous_time = info->present_time;
7624 + info->bytes_total = info->packets_total = 0;
7627 + if ( amount > HZ/10) {/* More than 100 ms elapsed ... */
7629 + info->mean_rate = (u_int32_t) ((HZ * info->packets_total) \
7632 + info->previous_time = info->present_time;
7633 + info->bytes_total = info->packets_total = 0;
7635 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
7636 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
7638 + info->acceptance_rate = (u_int8_t) \
7639 + (howhigh * PAR_LOW + PAR_HIGH * howlow);
7641 + /* In fact, the above defuzzification would require a denominator
7642 + * proportional to (howhigh+howlow) but, in this particular case,
7643 + * that expression is constant.
7644 + * An imediate consequence is that it is not necessary to call
7645 + * both mf_high and mf_low - but to keep things understandable,
7651 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
7654 + if (info->acceptance_rate < 100)
7656 + get_random_bytes((void *)(&random_number), 1);
7658 + /* If within the acceptance , it can pass => don't match */
7659 + if (random_number <= (255 * info->acceptance_rate) / 100)
7662 + return 1; /* It can't pass (It matches) */
7665 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
7670 +ip6t_fuzzy_checkentry(const char *tablename,
7671 + const struct ip6t_ip6 *ip,
7673 + unsigned int matchsize,
7674 + unsigned int hook_mask)
7677 + const struct ip6t_fuzzy_info *info = matchinfo;
7679 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info))) {
7680 + printk("ip6t_fuzzy: matchsize %u != %u\n", matchsize,
7681 + IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info)));
7685 + if ((info->minimum_rate < MINFUZZYRATE) || (info->maximum_rate > MAXFUZZYRATE)
7686 + || (info->minimum_rate >= info->maximum_rate)) {
7687 + printk("ip6t_fuzzy: BAD limits , please verify !!!\n");
7694 +static struct ip6t_match ip6t_fuzzy_reg = {
7698 + ip6t_fuzzy_checkentry,
7702 +static int __init init(void)
7704 + if (ip6t_register_match(&ip6t_fuzzy_reg))
7710 +static void __exit fini(void)
7712 + ip6t_unregister_match(&ip6t_fuzzy_reg);
7717 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv6/netfilter/ip6t_nth.c linux-2.6.5-rc3/net/ipv6/netfilter/ip6t_nth.c
7718 --- linux-2.6.5-rc3.org/net/ipv6/netfilter/ip6t_nth.c 1970-01-01 01:00:00.000000000 +0100
7719 +++ linux-2.6.5-rc3/net/ipv6/netfilter/ip6t_nth.c 2004-03-30 11:11:13.000000000 +0200
7722 + This is a module which is used for match support for every Nth packet
7723 + This file is distributed under the terms of the GNU General Public
7724 + License (GPL). Copies of the GPL can be obtained from:
7725 + ftp://prep.ai.mit.edu/pub/gnu/GPL
7727 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
7728 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
7729 + * added support for multiple counters
7730 + * added support for matching on individual packets
7731 + in the counter cycle
7732 + 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
7736 +#include <linux/module.h>
7737 +#include <linux/skbuff.h>
7738 +#include <linux/ip.h>
7739 +#include <net/tcp.h>
7740 +#include <linux/spinlock.h>
7741 +#include <linux/netfilter_ipv6/ip6_tables.h>
7742 +#include <linux/netfilter_ipv6/ip6t_nth.h>
7744 +MODULE_LICENSE("GPL");
7747 + * State information.
7754 +static struct state states[IP6T_NTH_NUM_COUNTERS];
7757 +ip6t_nth_match(const struct sk_buff *pskb,
7758 + const struct net_device *in,
7759 + const struct net_device *out,
7760 + const void *matchinfo,
7763 + u_int16_t datalen,
7766 + /* Parameters from userspace */
7767 + const struct ip6t_nth_info *info = matchinfo;
7768 + unsigned counter = info->counter;
7769 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
7771 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
7775 + spin_lock(&states[counter].lock);
7777 + /* Are we matching every nth packet?*/
7778 + if (info->packet == 0xFF)
7780 + /* We're matching every nth packet and only every nth packet*/
7781 + /* Do we match or invert match? */
7782 + if (info->not == 0)
7784 + if (states[counter].number == 0)
7786 + ++states[counter].number;
7789 + if (states[counter].number >= info->every)
7790 + states[counter].number = 0; /* reset the counter */
7792 + ++states[counter].number;
7797 + if (states[counter].number == 0)
7799 + ++states[counter].number;
7802 + if (states[counter].number >= info->every)
7803 + states[counter].number = 0;
7805 + ++states[counter].number;
7811 + /* We're using the --packet, so there must be a rule for every value */
7812 + if (states[counter].number == info->packet)
7814 + /* only increment the counter when a match happens */
7815 + if (states[counter].number >= info->every)
7816 + states[counter].number = 0; /* reset the counter */
7818 + ++states[counter].number;
7827 + spin_unlock(&states[counter].lock);
7831 + spin_unlock(&states[counter].lock);
7836 +ip6t_nth_checkentry(const char *tablename,
7837 + const struct ip6t_ip6 *e,
7839 + unsigned int matchsize,
7840 + unsigned int hook_mask)
7842 + /* Parameters from userspace */
7843 + const struct ip6t_nth_info *info = matchinfo;
7844 + unsigned counter = info->counter;
7845 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
7847 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
7851 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_nth_info))) {
7852 + printk("nth: matchsize %u != %u\n", matchsize,
7853 + IP6T_ALIGN(sizeof(struct ip6t_nth_info)));
7857 + states[counter].number = info->startat;
7862 +static struct ip6t_match ip6t_nth_reg = {
7866 + ip6t_nth_checkentry,
7870 +static int __init init(void)
7873 + memset(&states, 0, sizeof(states));
7874 + if (ip6t_register_match(&ip6t_nth_reg))
7877 + for(counter = 0; counter < IP6T_NTH_NUM_COUNTERS; counter++)
7879 + spin_lock_init(&(states[counter].lock));
7882 + printk("ip6t_nth match loaded\n");
7886 +static void __exit fini(void)
7888 + ip6t_unregister_match(&ip6t_nth_reg);
7889 + printk("ip6t_nth match unloaded\n");
7894 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv6/netfilter/ip6t_random.c linux-2.6.5-rc3/net/ipv6/netfilter/ip6t_random.c
7895 --- linux-2.6.5-rc3.org/net/ipv6/netfilter/ip6t_random.c 1970-01-01 01:00:00.000000000 +0100
7896 +++ linux-2.6.5-rc3/net/ipv6/netfilter/ip6t_random.c 2004-03-30 11:11:26.000000000 +0200
7899 + This is a module which is used for a "random" match support.
7900 + This file is distributed under the terms of the GNU General Public
7901 + License (GPL). Copies of the GPL can be obtained from:
7902 + ftp://prep.ai.mit.edu/pub/gnu/GPL
7904 + 2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
7905 + 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
7908 +#include <linux/module.h>
7909 +#include <linux/skbuff.h>
7910 +#include <linux/ip.h>
7911 +#include <linux/random.h>
7912 +#include <net/tcp.h>
7913 +#include <linux/spinlock.h>
7914 +#include <linux/netfilter_ipv6/ip6_tables.h>
7915 +#include <linux/netfilter_ipv6/ip6t_random.h>
7917 +MODULE_LICENSE("GPL");
7920 +ip6t_rand_match(const struct sk_buff *pskb,
7921 + const struct net_device *in,
7922 + const struct net_device *out,
7923 + const void *matchinfo,
7926 + u_int16_t datalen,
7929 + /* Parameters from userspace */
7930 + const struct ip6t_rand_info *info = matchinfo;
7931 + u_int8_t random_number;
7933 + /* get 1 random number from the kernel random number generation routine */
7934 + get_random_bytes((void *)(&random_number), 1);
7936 + /* Do we match ? */
7937 + if (random_number <= info->average)
7944 +ip6t_rand_checkentry(const char *tablename,
7945 + const struct ip6t_ip6 *e,
7947 + unsigned int matchsize,
7948 + unsigned int hook_mask)
7950 + /* Parameters from userspace */
7951 + const struct ip6t_rand_info *info = matchinfo;
7953 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_rand_info))) {
7954 + printk("ip6t_random: matchsize %u != %u\n", matchsize,
7955 + IP6T_ALIGN(sizeof(struct ip6t_rand_info)));
7959 + /* must be 1 <= average % <= 99 */
7960 + /* 1 x 2.55 = 2 */
7961 + /* 99 x 2.55 = 252 */
7962 + if ((info->average < 2) || (info->average > 252)) {
7963 + printk("ip6t_random: invalid average %u\n", info->average);
7970 +static struct ip6t_match ip6t_rand_reg = {
7974 + ip6t_rand_checkentry,
7978 +static int __init init(void)
7980 + if (ip6t_register_match(&ip6t_rand_reg))
7983 + printk("ip6t_random match loaded\n");
7987 +static void __exit fini(void)
7989 + ip6t_unregister_match(&ip6t_rand_reg);
7990 + printk("ip6t_random match unloaded\n");
7995 diff -Nur --exclude '*.orig' linux-2.6.5-rc3.org/net/ipv6/netfilter/ip6table_raw.c linux-2.6.5-rc3/net/ipv6/netfilter/ip6table_raw.c
7996 --- linux-2.6.5-rc3.org/net/ipv6/netfilter/ip6table_raw.c 1970-01-01 01:00:00.000000000 +0100
7997 +++ linux-2.6.5-rc3/net/ipv6/netfilter/ip6table_raw.c 2004-03-30 11:11:27.000000000 +0200
8000 + * IPv6 raw table, a port of the IPv4 raw table to IPv6
8002 + * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
8004 +#include <linux/module.h>
8005 +#include <linux/netfilter_ipv6/ip6_tables.h>
8007 +#define RAW_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT))
8010 +#define DEBUGP(x, args...) printk(KERN_DEBUG x, ## args)
8012 +#define DEBUGP(x, args...)
8015 +/* Standard entry. */
8016 +struct ip6t_standard
8018 + struct ip6t_entry entry;
8019 + struct ip6t_standard_target target;
8022 +struct ip6t_error_target
8024 + struct ip6t_entry_target target;
8025 + char errorname[IP6T_FUNCTION_MAXNAMELEN];
8030 + struct ip6t_entry entry;
8031 + struct ip6t_error_target target;
8036 + struct ip6t_replace repl;
8037 + struct ip6t_standard entries[2];
8038 + struct ip6t_error term;
8039 +} initial_table __initdata
8040 += { { "raw", RAW_VALID_HOOKS, 3,
8041 + sizeof(struct ip6t_standard) * 2 + sizeof(struct ip6t_error),
8042 + { [NF_IP6_PRE_ROUTING] 0,
8043 + [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) },
8044 + { [NF_IP6_PRE_ROUTING] 0,
8045 + [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) },
8049 + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
8051 + sizeof(struct ip6t_entry),
8052 + sizeof(struct ip6t_standard),
8053 + 0, { 0, 0 }, { } },
8054 + { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
8055 + -NF_ACCEPT - 1 } },
8057 + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
8059 + sizeof(struct ip6t_entry),
8060 + sizeof(struct ip6t_standard),
8061 + 0, { 0, 0 }, { } },
8062 + { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
8063 + -NF_ACCEPT - 1 } },
8066 + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
8068 + sizeof(struct ip6t_entry),
8069 + sizeof(struct ip6t_error),
8070 + 0, { 0, 0 }, { } },
8071 + { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } },
8078 +static struct ip6t_table packet_raw = {
8080 + .table = &initial_table.repl,
8081 + .valid_hooks = RAW_VALID_HOOKS,
8082 + .lock = RW_LOCK_UNLOCKED,
8086 +/* The work comes in here from netfilter.c. */
8087 +static unsigned int
8088 +ip6t_hook(unsigned int hook,
8089 + struct sk_buff **pskb,
8090 + const struct net_device *in,
8091 + const struct net_device *out,
8092 + int (*okfn)(struct sk_buff *))
8094 + return ip6t_do_table(pskb, hook, in, out, &packet_raw, NULL);
8097 +static struct nf_hook_ops ip6t_ops[] = {
8099 + .hook = ip6t_hook,
8101 + .hooknum = NF_IP6_PRE_ROUTING,
8102 + .priority = NF_IP6_PRI_FIRST
8105 + .hook = ip6t_hook,
8107 + .hooknum = NF_IP6_LOCAL_OUT,
8108 + .priority = NF_IP6_PRI_FIRST
8112 +static int __init init(void)
8116 + /* Register table */
8117 + ret = ip6t_register_table(&packet_raw);
8121 + /* Register hooks */
8122 + ret = nf_register_hook(&ip6t_ops[0]);
8124 + goto cleanup_table;
8126 + ret = nf_register_hook(&ip6t_ops[1]);
8128 + goto cleanup_hook0;
8133 + nf_unregister_hook(&ip6t_ops[0]);
8135 + ip6t_unregister_table(&packet_raw);
8140 +static void __exit fini(void)
8144 + for (i = 0; i < sizeof(ip6t_ops)/sizeof(struct nf_hook_ops); i++)
8145 + nf_unregister_hook(&ip6t_ops[i]);
8147 + ip6t_unregister_table(&packet_raw);
8152 +MODULE_LICENSE("GPL");