1 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ip_pool.h linux-2.6.3-rc3/include/linux/netfilter_ipv4/ip_pool.h
2 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ip_pool.h 1970-01-01 01:00:00.000000000 +0100
3 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv4/ip_pool.h 2004-02-16 11:07:21.518803072 +0100
8 +/***************************************************************************/
9 +/* This program is free software; you can redistribute it and/or modify */
10 +/* it under the terms of the GNU General Public License as published by */
11 +/* the Free Software Foundation; either version 2 of the License, or */
12 +/* (at your option) any later version. */
14 +/* This program is distributed in the hope that it will be useful, */
15 +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
16 +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
17 +/* GNU General Public License for more details. */
19 +/* You should have received a copy of the GNU General Public License */
20 +/* along with this program; if not, write to the Free Software */
21 +/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/
22 +/***************************************************************************/
24 +/* A sockopt of such quality has hardly ever been seen before on the open
25 + * market! This little beauty, hardly ever used: above 64, so it's
26 + * traditionally used for firewalling, not touched (even once!) by the
27 + * 2.0, 2.2 and 2.4 kernels!
29 + * Comes with its own certificate of authenticity, valid anywhere in the
34 +#define SO_IP_POOL 81
36 +typedef int ip_pool_t; /* pool index */
37 +#define IP_POOL_NONE ((ip_pool_t)-1)
39 +struct ip_pool_request {
46 +/* NOTE: I deliberately break the first cut ippool utility. Nobody uses it. */
48 +#define IP_POOL_BAD001 0x00000010
50 +#define IP_POOL_FLUSH 0x00000011 /* req.index, no arguments */
51 +#define IP_POOL_INIT 0x00000012 /* from addr to addr2 incl. */
52 +#define IP_POOL_DESTROY 0x00000013 /* req.index, no arguments */
53 +#define IP_POOL_ADD_ADDR 0x00000014 /* add addr to pool */
54 +#define IP_POOL_DEL_ADDR 0x00000015 /* del addr from pool */
55 +#define IP_POOL_HIGH_NR 0x00000016 /* result in req.index */
56 +#define IP_POOL_LOOKUP 0x00000017 /* result in addr and addr2 */
57 +#define IP_POOL_USAGE 0x00000018 /* result in addr */
58 +#define IP_POOL_TEST_ADDR 0x00000019 /* result (0/1) returned */
62 +/* NOTE: ip_pool_match() and ip_pool_mod() expect ADDR to be host byte order */
63 +extern int ip_pool_match(ip_pool_t pool, u_int32_t addr);
64 +extern int ip_pool_mod(ip_pool_t pool, u_int32_t addr, int isdel);
68 +#endif /*_IP_POOL_H*/
69 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_NETLINK.h linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_NETLINK.h
70 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_NETLINK.h 1970-01-01 01:00:00.000000000 +0100
71 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_NETLINK.h 2004-02-16 11:07:05.880548139 +0100
77 +#define MASK(x,y) (x & y)
78 +#define MASK_SET(x,y) x |= y
79 +#define MASK_UNSET(x,y) x &= ~y
81 +#define USE_MARK 0x00000001
82 +#define USE_DROP 0x00000002
83 +#define USE_SIZE 0x00000004
96 + char iface[IFNAMSIZ];
99 +#endif /*_IPT_FWMON_H*/
100 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_TTL.h linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_TTL.h
101 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_TTL.h 1970-01-01 01:00:00.000000000 +0100
102 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_TTL.h 2004-02-16 11:07:09.253740328 +0100
104 +/* TTL modification module for IP tables
105 + * (C) 2000 by Harald Welte <laforge@gnumonks.org> */
116 +#define IPT_TTL_MAXMODE IPT_TTL_DEC
118 +struct ipt_TTL_info {
125 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_connlimit.h linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_connlimit.h
126 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_connlimit.h 1970-01-01 01:00:00.000000000 +0100
127 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_connlimit.h 2004-02-16 11:07:11.549190614 +0100
129 +#ifndef _IPT_CONNLIMIT_H
130 +#define _IPT_CONNLIMIT_H
132 +struct ipt_connlimit_data;
134 +struct ipt_connlimit_info {
138 + struct ipt_connlimit_data *data;
140 +#endif /* _IPT_CONNLIMIT_H */
141 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_dstlimit.h linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_dstlimit.h
142 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_dstlimit.h 1970-01-01 01:00:00.000000000 +0100
143 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_dstlimit.h 2004-02-16 11:07:13.230787904 +0100
145 +#ifndef _IPT_DSTLIMIT_H
146 +#define _IPT_DSTLIMIT_H
148 +/* timings are in milliseconds. */
149 +#define IPT_DSTLIMIT_SCALE 10000
150 +/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490
151 + seconds, or one every 59 hours. */
153 +/* details of this structure hidden by the implementation */
154 +struct ipt_dstlimit_htable;
156 +#define IPT_DSTLIMIT_HASH_DIP 0x0001
157 +#define IPT_DSTLIMIT_HASH_DPT 0x0002
158 +#define IPT_DSTLIMIT_HASH_SIP 0x0004
160 +struct ipt_dstlimit_info {
161 + u_int32_t mode; /* bitmask of IPT_DSTLIMIT_HASH_* */
162 + u_int32_t avg; /* Average secs between packets * scale */
163 + u_int32_t burst; /* Period multiplier for upper limit. */
165 + /* user specified */
166 + unsigned int size; /* how many buckets */
167 + unsigned int max; /* max number of entries */
168 + unsigned int gc_interval; /* gc interval */
169 + unsigned int expire; /* when do entries expire? */
170 + char name [IFNAMSIZ]; /* name */
172 + struct ipt_dstlimit_htable *hinfo;
174 + /* Used internally by the kernel */
177 + struct ipt_dstlimit_info *master;
180 +#endif /*_IPT_DSTLIMIT_H*/
181 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_fuzzy.h linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_fuzzy.h
182 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_fuzzy.h 1970-01-01 01:00:00.000000000 +0100
183 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_fuzzy.h 2004-02-16 11:07:14.925382080 +0100
185 +#ifndef _IPT_FUZZY_H
186 +#define _IPT_FUZZY_H
188 +#include <linux/param.h>
189 +#include <linux/types.h>
191 +#define MAXFUZZYRATE 10000000
192 +#define MINFUZZYRATE 3
194 +struct ipt_fuzzy_info {
195 + u_int32_t minimum_rate;
196 + u_int32_t maximum_rate;
197 + u_int32_t packets_total;
198 + u_int32_t bytes_total;
199 + u_int32_t previous_time;
200 + u_int32_t present_time;
201 + u_int32_t mean_rate;
202 + u_int8_t acceptance_rate;
205 +#endif /*_IPT_FUZZY_H*/
206 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_ipv4options.h linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_ipv4options.h
207 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_ipv4options.h 1970-01-01 01:00:00.000000000 +0100
208 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_ipv4options.h 2004-02-16 11:07:16.164085433 +0100
210 +#ifndef __ipt_ipv4options_h_included__
211 +#define __ipt_ipv4options_h_included__
213 +#define IPT_IPV4OPTION_MATCH_SSRR 0x01 /* For strict source routing */
214 +#define IPT_IPV4OPTION_MATCH_LSRR 0x02 /* For loose source routing */
215 +#define IPT_IPV4OPTION_DONT_MATCH_SRR 0x04 /* any source routing */
216 +#define IPT_IPV4OPTION_MATCH_RR 0x08 /* For Record route */
217 +#define IPT_IPV4OPTION_DONT_MATCH_RR 0x10
218 +#define IPT_IPV4OPTION_MATCH_TIMESTAMP 0x20 /* For timestamp request */
219 +#define IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP 0x40
220 +#define IPT_IPV4OPTION_MATCH_ROUTER_ALERT 0x80 /* For router-alert */
221 +#define IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT 0x100
222 +#define IPT_IPV4OPTION_MATCH_ANY_OPT 0x200 /* match packet with any option */
223 +#define IPT_IPV4OPTION_DONT_MATCH_ANY_OPT 0x400 /* match packet with no option */
225 +struct ipt_ipv4options_info {
230 +#endif /* __ipt_ipv4options_h_included__ */
231 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_mport.h linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_mport.h
232 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_mport.h 1970-01-01 01:00:00.000000000 +0100
233 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_mport.h 2004-02-16 11:07:17.665725817 +0100
235 +#ifndef _IPT_MPORT_H
236 +#define _IPT_MPORT_H
237 +#include <linux/netfilter_ipv4/ip_tables.h>
239 +#define IPT_MPORT_SOURCE (1<<0)
240 +#define IPT_MPORT_DESTINATION (1<<1)
241 +#define IPT_MPORT_EITHER (IPT_MPORT_SOURCE|IPT_MPORT_DESTINATION)
243 +#define IPT_MULTI_PORTS 15
245 +/* Must fit inside union ipt_matchinfo: 32 bytes */
246 +/* every entry in ports[] except for the last one has one bit in pflags
247 + * associated with it. If this bit is set, the port is the first port of
248 + * a portrange, with the next entry being the last.
249 + * End of list is marked with pflags bit set and port=65535.
250 + * If 14 ports are used (last one does not have a pflag), the last port
251 + * is repeated to fill the last entry in ports[] */
254 + u_int8_t flags:2; /* Type of comparison */
255 + u_int16_t pflags:14; /* Port flags */
256 + u_int16_t ports[IPT_MULTI_PORTS]; /* Ports */
258 +#endif /*_IPT_MPORT_H*/
259 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_nth.h linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_nth.h
260 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_nth.h 1970-01-01 01:00:00.000000000 +0100
261 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_nth.h 2004-02-16 11:07:18.796455028 +0100
266 +#include <linux/param.h>
267 +#include <linux/types.h>
269 +#ifndef IPT_NTH_NUM_COUNTERS
270 +#define IPT_NTH_NUM_COUNTERS 16
273 +struct ipt_nth_info {
281 +#endif /*_IPT_NTH_H*/
282 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_osf.h linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_osf.h
283 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_osf.h 1970-01-01 01:00:00.000000000 +0100
284 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_osf.h 2004-02-16 11:07:19.917186632 +0100
289 + * Copyright (c) 2003 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
292 + * This program is free software; you can redistribute it and/or modify
293 + * it under the terms of the GNU General Public License as published by
294 + * the Free Software Foundation; either version 2 of the License, or
295 + * (at your option) any later version.
297 + * This program is distributed in the hope that it will be useful,
298 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
299 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
300 + * GNU General Public License for more details.
302 + * You should have received a copy of the GNU General Public License
303 + * along with this program; if not, write to the Free Software
304 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
310 +#define MAXGENRELEN 32
311 +#define MAXDETLEN 64
313 +#define IPT_OSF_GENRE 1
314 +#define IPT_OSF_SMART 2
315 +#define IPT_OSF_LOG 4
317 +#define IPT_OSF_LOGLEVEL_ALL 0
318 +#define IPT_OSF_LOGLEVEL_FIRST 1
320 +#include <linux/list.h>
324 + char genre[MAXGENRELEN];
326 + unsigned long flags;
328 + int invert; /* UNSUPPORTED */
337 +/* This struct represents IANA options
338 + * http://www.iana.org/assignments/tcp-parameters
342 + unsigned char kind;
343 + unsigned char length;
351 + struct list_head flist;
356 + char genre[MAXGENRELEN];
357 + char version[MAXGENRELEN], subtype[MAXGENRELEN];
359 + /* Not needed, but for consistency with original table from Michal Zalewski */
360 + char details[MAXDETLEN];
363 + struct osf_opt opt[MAX_IPOPTLEN]; /* In case it is all NOP or EOL */
367 +/* Defines for IANA option kinds */
369 +#define OSFOPT_EOL 0 /* End of options */
370 +#define OSFOPT_NOP 1 /* NOP */
371 +#define OSFOPT_MSS 2 /* Maximum segment size */
372 +#define OSFOPT_WSO 3 /* Window scale option */
373 +#define OSFOPT_SACKP 4 /* SACK permitted */
374 +#define OSFOPT_SACK 5 /* SACK */
375 +#define OSFOPT_ECHO 6
376 +#define OSFOPT_ECHOREPLY 7
377 +#define OSFOPT_TS 8 /* Timestamp option */
378 +#define OSFOPT_POCP 9 /* Partial Order Connection Permitted */
379 +#define OSFOPT_POSP 10 /* Partial Order Service Profile */
380 +/* Others are not used in current OSF */
382 +static struct osf_opt IANA_opts[] =
389 + {5, 1 ,}, /* SACK length is not defined */
395 + {11, 1,}, /* CC: Suppose 1 */
396 + {12, 1,}, /* the same */
397 + {13, 1,}, /* and here too */
399 + {15, 1,}, /* TCP Alternate Checksum Data. Length is not defined */
413 +#endif /* __KERNEL__ */
415 +#endif /* _IPT_OSF_H */
416 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_pool.h linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_pool.h
417 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_pool.h 1970-01-01 01:00:00.000000000 +0100
418 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_pool.h 2004-02-16 11:07:21.518803072 +0100
423 +#include <linux/netfilter_ipv4/ip_pool.h>
425 +#define IPT_POOL_INV_SRC 0x00000001
426 +#define IPT_POOL_INV_DST 0x00000002
427 +#define IPT_POOL_DEL_SRC 0x00000004
428 +#define IPT_POOL_DEL_DST 0x00000008
429 +#define IPT_POOL_INV_MOD_SRC 0x00000010
430 +#define IPT_POOL_INV_MOD_DST 0x00000020
431 +#define IPT_POOL_MOD_SRC_ACCEPT 0x00000040
432 +#define IPT_POOL_MOD_DST_ACCEPT 0x00000080
433 +#define IPT_POOL_MOD_SRC_DROP 0x00000100
434 +#define IPT_POOL_MOD_DST_DROP 0x00000200
437 +struct ipt_pool_info
444 +#endif /*_IPT_POOL_H*/
445 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_psd.h linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_psd.h
446 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_psd.h 1970-01-01 01:00:00.000000000 +0100
447 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_psd.h 2004-02-16 11:07:22.387595011 +0100
452 +#include <linux/param.h>
453 +#include <linux/types.h>
456 + * High port numbers have a lower weight to reduce the frequency of false
457 + * positives, such as from passive mode FTP transfers.
459 +#define PORT_WEIGHT_PRIV 3
460 +#define PORT_WEIGHT_HIGH 1
463 + * Port scan detection thresholds: at least COUNT ports need to be scanned
464 + * from the same source, with no longer than DELAY ticks between ports.
466 +#define SCAN_MIN_COUNT 7
467 +#define SCAN_MAX_COUNT (SCAN_MIN_COUNT * PORT_WEIGHT_PRIV)
468 +#define SCAN_WEIGHT_THRESHOLD SCAN_MAX_COUNT
469 +#define SCAN_DELAY_THRESHOLD (HZ * 3)
472 + * Keep track of up to LIST_SIZE source addresses, using a hash table of
473 + * HASH_SIZE entries for faster lookups, but limiting hash collisions to
474 + * HASH_MAX source addresses per the same hash value.
476 +#define LIST_SIZE 0x100
478 +#define HASH_SIZE (1 << HASH_LOG)
479 +#define HASH_MAX 0x10
481 +struct ipt_psd_info {
482 + unsigned int weight_threshold;
483 + unsigned int delay_threshold;
484 + unsigned short lo_ports_weight;
485 + unsigned short hi_ports_weight;
488 +#endif /*_IPT_PSD_H*/
489 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_quota.h linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_quota.h
490 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_quota.h 1970-01-01 01:00:00.000000000 +0100
491 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_quota.h 2004-02-16 11:07:23.219395809 +0100
493 +#ifndef _IPT_QUOTA_H
494 +#define _IPT_QUOTA_H
496 +/* print debug info in both kernel/netfilter module & iptable library */
497 +//#define DEBUG_IPT_QUOTA
499 +struct ipt_quota_info {
503 +#endif /*_IPT_QUOTA_H*/
504 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_random.h linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_random.h
505 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_random.h 1970-01-01 01:00:00.000000000 +0100
506 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_random.h 2004-02-16 11:07:24.378118313 +0100
511 +#include <linux/param.h>
512 +#include <linux/types.h>
514 +struct ipt_rand_info {
518 +#endif /*_IPT_RAND_H*/
519 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_realm.h linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_realm.h
520 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_realm.h 1970-01-01 01:00:00.000000000 +0100
521 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_realm.h 2004-02-16 11:07:26.369641375 +0100
523 +#ifndef _IPT_REALM_H
524 +#define _IPT_REALM_H
526 +struct ipt_realm_info {
531 +#endif /*_IPT_REALM_H*/
532 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_time.h linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_time.h
533 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_time.h 1970-01-01 01:00:00.000000000 +0100
534 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_time.h 2004-02-16 11:07:27.150454383 +0100
536 +#ifndef __ipt_time_h_included__
537 +#define __ipt_time_h_included__
540 +struct ipt_time_info {
541 + u_int8_t days_match; /* 1 bit per day. -SMTWTFS */
542 + u_int16_t time_start; /* 0 < time_start < 23*60+59 = 1439 */
543 + u_int16_t time_stop; /* 0:0 < time_stat < 23:59 */
544 + u_int8_t kerneltime; /* ignore skb time (and use kerneltime) or not. */
548 +#endif /* __ipt_time_h_included__ */
549 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_u32.h linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_u32.h
550 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv4/ipt_u32.h 1970-01-01 01:00:00.000000000 +0100
551 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv4/ipt_u32.h 2004-02-16 11:07:28.175208970 +0100
555 +#include <linux/netfilter_ipv4/ip_tables.h>
565 +struct ipt_u32_location_element
570 +struct ipt_u32_value_element
575 +/* *** any way to allow for an arbitrary number of elements?
576 + for now I settle for a limit of 10 of each */
577 +#define U32MAXSIZE 10
581 + struct ipt_u32_location_element location[U32MAXSIZE+1];
583 + struct ipt_u32_value_element value[U32MAXSIZE+1];
589 + struct ipt_u32_test tests[U32MAXSIZE+1];
592 +#endif /*_IPT_U32_H*/
593 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv6/ip6t_HL.h linux-2.6.3-rc3/include/linux/netfilter_ipv6/ip6t_HL.h
594 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv6/ip6t_HL.h 1970-01-01 01:00:00.000000000 +0100
595 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv6/ip6t_HL.h 2004-02-16 11:06:53.521507853 +0100
597 +/* Hop Limit modification module for ip6tables
598 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
599 + * Based on HW's TTL module */
601 +#ifndef _IP6T_HOPLIMIT_H
602 +#define _IP6T_HOPLIMIT_H
605 + IP6T_HOPLIMIT_SET = 0,
610 +#define IP6T_HOPLIMIT_MAXMODE IP6T_HOPLIMIT_DEC
612 +struct ip6t_HOPLIMIT_info {
614 + u_int8_t hop_limit;
619 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv6/ip6t_REJECT.h linux-2.6.3-rc3/include/linux/netfilter_ipv6/ip6t_REJECT.h
620 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv6/ip6t_REJECT.h 2004-02-15 03:44:09.000000000 +0100
621 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv6/ip6t_REJECT.h 2004-02-16 11:07:07.812085576 +0100
623 #define _IP6T_REJECT_H
625 enum ip6t_reject_with {
626 - IP6T_ICMP_NET_UNREACHABLE,
627 - IP6T_ICMP_HOST_UNREACHABLE,
628 - IP6T_ICMP_PROT_UNREACHABLE,
629 - IP6T_ICMP_PORT_UNREACHABLE,
630 - IP6T_ICMP_ECHOREPLY
631 + IP6T_ICMP6_NO_ROUTE,
632 + IP6T_ICMP6_ADM_PROHIBITED,
633 + IP6T_ICMP6_NOT_NEIGHBOUR,
634 + IP6T_ICMP6_ADDR_UNREACH,
635 + IP6T_ICMP6_PORT_UNREACH,
636 + IP6T_ICMP6_ECHOREPLY,
640 struct ip6t_reject_info {
641 enum ip6t_reject_with with; /* reject type */
644 -#endif /*_IPT_REJECT_H*/
645 +#endif /*_IP6T_REJECT_H*/
646 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h linux-2.6.3-rc3/include/linux/netfilter_ipv6/ip6t_fuzzy.h
647 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h 1970-01-01 01:00:00.000000000 +0100
648 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv6/ip6t_fuzzy.h 2004-02-16 11:07:14.925382080 +0100
650 +#ifndef _IP6T_FUZZY_H
651 +#define _IP6T_FUZZY_H
653 +#include <linux/param.h>
654 +#include <linux/types.h>
656 +#define MAXFUZZYRATE 10000000
657 +#define MINFUZZYRATE 3
659 +struct ip6t_fuzzy_info {
660 + u_int32_t minimum_rate;
661 + u_int32_t maximum_rate;
662 + u_int32_t packets_total;
663 + u_int32_t bytes_total;
664 + u_int32_t previous_time;
665 + u_int32_t present_time;
666 + u_int32_t mean_rate;
667 + u_int8_t acceptance_rate;
670 +#endif /*_IP6T_FUZZY_H*/
671 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv6/ip6t_nth.h linux-2.6.3-rc3/include/linux/netfilter_ipv6/ip6t_nth.h
672 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv6/ip6t_nth.h 1970-01-01 01:00:00.000000000 +0100
673 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv6/ip6t_nth.h 2004-02-16 11:07:18.796455028 +0100
678 +#include <linux/param.h>
679 +#include <linux/types.h>
681 +#ifndef IP6T_NTH_NUM_COUNTERS
682 +#define IP6T_NTH_NUM_COUNTERS 16
685 +struct ip6t_nth_info {
693 +#endif /*_IP6T_NTH_H*/
694 diff -Nur linux-2.6.3-rc3.org/include/linux/netfilter_ipv6/ip6t_random.h linux-2.6.3-rc3/include/linux/netfilter_ipv6/ip6t_random.h
695 --- linux-2.6.3-rc3.org/include/linux/netfilter_ipv6/ip6t_random.h 1970-01-01 01:00:00.000000000 +0100
696 +++ linux-2.6.3-rc3/include/linux/netfilter_ipv6/ip6t_random.h 2004-02-16 11:07:24.378118313 +0100
698 +#ifndef _IP6T_RAND_H
699 +#define _IP6T_RAND_H
701 +#include <linux/param.h>
702 +#include <linux/types.h>
704 +struct ip6t_rand_info {
708 +#endif /*_IP6T_RAND_H*/
709 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/Kconfig linux-2.6.3-rc3/net/ipv4/netfilter/Kconfig
710 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/Kconfig 2004-02-16 10:08:59.000000000 +0100
711 +++ linux-2.6.3-rc3/net/ipv4/netfilter/Kconfig 2004-02-16 11:07:28.178208252 +0100
712 @@ -588,5 +588,384 @@
714 To compile it as a module, choose M here. If unsure, say N.
716 +config IP_NF_TARGET_IPV4OPTSSTRIP
717 + tristate 'IPV4OPTSSTRIP target support'
718 + depends on IP_NF_MANGLE
720 + This option adds CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP, which supplies a target
721 + module that will allow you to strip all the IP options from a packet.
723 + The target doesn't take any option, and therefore is extremly easy to use :
725 + # iptables -t mangle -A PREROUTING -j IPV4OPTSSTRIP
726 + # iptables -t mangle --list -n
727 + Chain PREROUTING (policy ACCEPT)
728 + target prot opt source destination
729 + IPV4OPTSSTRIP all -- 0.0.0.0/0 0.0.0.0/0
731 + Chain OUTPUT (policy ACCEPT)
732 + target prot opt source destination
734 +config IP_NF_TARGET_NETLINK
735 + tristate 'NETLINK target support'
736 + depends on IP_NF_FILTER
738 + CONFIG_IP_NF_TARGET_NETLINK adds a NETLINK target that sends dropped packets to
739 + userspace via a netlink socket. Apps such as fwmon
740 + (http://firestorm.geek-ware.co.uk) can then recieve and dislpay these packets.
741 + This option is basically a re-implementation of the ipchains -o option.
743 +config IP_NF_TARGET_TTL
744 + tristate 'TTL target support'
745 + depends on IP_NF_MANGLE
747 + This adds an iptables TTL manipulation target, which enables the user
748 + to set the TTL value of an IP packet or to increment / decrement it
751 +config IP_NF_MATCH_CONNLIMIT
752 + tristate 'Connections/IP limit match support'
753 + depends on IP_NF_IPTABLES
755 + This adds an iptables match which allows you to restrict the
756 + number of parallel TCP connections to a server per client IP address
757 + (or address block).
761 + # allow 2 telnet connections per client host
762 + iptables -p tcp --syn --dport 23 -m connlimit --connlimit-above 2 -j REJECT
764 + # you can also match the other way around:
765 + iptables -p tcp --syn --dport 23 -m connlimit ! --connlimit-above 2 -j ACCEPT
767 + # limit the nr of parallel http requests to 16 per class C sized
768 + # network (24 bit netmask)
769 + iptables -p tcp --syn --dport 80 -m connlimit --connlimit-above 16 \
770 + --connlimit-mask 24 -j REJECT
772 +config IP_NF_MATCH_DSTLIMIT
773 + tristate 'dstlimit match support'
774 + depends on IP_NF_IPTABLES
777 + This patch adds a new match called 'dstlimit'.
778 + The idea is to have something like 'limit', but either per
779 + destination-ip or per (destip,destport) tuple.
781 + It gives you the ability to say
782 + '1000 packets per second for every host in 192.168.0.0/16'
783 + '100 packets per second for every service of 192.168.1.1'
787 + A rate just like the limit match
788 + --dstlimit-burst <num>
789 + Burst value, just like limit match
790 + --dstlimit-mode destip | destip-destport
791 + Limit per IP or per port
792 + --dstlimit-name foo
793 + The name for the /proc/net/ipt_dstlimit/foo entry
794 + --dstlimit-htable-size <num>
795 + The number of buckets of the hash table
796 + --dstlimit-htable-max <num>
797 + Maximum entries in the hash
798 + --dstlimit-htable-expire <num>
799 + After how many miliseconds do hash entries expire
800 + --dstlimit-htable-gcinterval <num>
801 + How many miliseconds between garbage collection intervals
804 +config IP_NF_MATCH_FUZZY
805 + tristate 'fuzzy match support'
806 + depends on IP_NF_IPTABLES
808 + This option adds a `fuzzy' match which allows you to match packets according to
809 + a dynamic profile implemented by means of a simple Fuzzy Logic Controller (FLC)
811 +config IP_NF_MATCH_IPV4OPTIONS
812 + tristate 'IPV4OPTIONS match support'
813 + depends on IP_NF_IPTABLES
815 + This option adds an iptables 'ipv4options' match, which allows you to
816 + match on IPv4 header options like source routing, record route, timestamp and
819 + Suppported options are:
821 + To match packets with the flag strict source routing.
823 + To match packets with the flag loose source routing.
825 + To match packets with no flag for source routing.
827 + To match packets with the RR flag.
829 + To match packets with the TS flag.
831 + To match packets with the router-alert option.
833 + To match a packet with at least one IP option, or no IP option
834 + at all if ! is chosen.
837 + $ iptables -A input -m ipv4options --rr -j DROP
838 + will drop packets with the record-route flag.
840 + $ iptables -A input -m ipv4options --ts -j DROP
841 + will drop packets with the timestamp flag.
843 +config IP_NF_MATCH_MPORT
844 + tristate 'Multiple port with ranges match support'
845 + depends on IP_NF_IPTABLES
847 + This module is an enhanced multiport match. It has support for byte
848 + ranges as well as for single ports.
849 + Up to 15 ports are allowed. Note that a portrange uses up 2 port values.
852 + # iptables -A FORWARD -p tcp -m mport --ports 23:42,65
854 +config IP_NF_MATCH_NTH
855 + tristate 'Nth match support'
856 + depends on IP_NF_IPTABLES
858 + This option adds an iptables `Nth' match, which allows you to match every Nth
859 + packet encountered. By default there are 16 different counters that can be
862 + This match functions in one of two ways
863 + 1) Match ever Nth packet, and only the Nth packet.
865 + iptables -t mangle -A PREROUTING -m nth --every 10 -j DROP
866 + This rule will drop every 10th packet.
867 + 2) Unique rule for every packet. This is an easy and quick
868 + method to produce load-balancing for both inbound and outbound.
870 + iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
871 + --every 3 --packet 0 -j SNAT --to-source 10.0.0.5
872 + iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
873 + --every 3 --packet 1 -j SNAT --to-source 10.0.0.6
874 + iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
875 + --every 3 --packet 2 -j SNAT --to-source 10.0.0.7
876 + This example evenly splits connections between the three SNAT
879 + By using the mangle table and iproute2, you can setup complex
880 + load-balanced routing. There's lot of other uses. Be creative!
882 + Suppported options are:
883 + --every Nth Match every Nth packet
884 + [--counter] num Use counter 0-15 (default:0)
885 + [--start] num Initialize the counter at the number 'num'
886 + instead of 0. Must be between 0 and Nth-1
887 + [--packet] num Match on 'num' packet. Must be between 0
889 + If --packet is used for a counter than
890 + there must be Nth number of --packet
891 + rules, covering all values between 0 and
894 +config IP_NF_MATCH_OSF
895 + tristate 'OSF match support'
896 + depends on IP_NF_IPTABLES
898 + The idea of passive OS fingerprint matching exists for quite a long time,
899 + but was created as extension fo OpenBSD pf only some weeks ago.
900 + Original idea was lurked in some OpenBSD mailing list (thanks
901 + grange@open...) and than adopted for Linux netfilter in form of this code.
903 + Original table was created by Michal Zalewski <lcamtuf@coredump.cx> for
904 + his excellent p0f and than changed a bit for more convenience.
906 + This module compares some data(WS, MSS, options and it's order, ttl,
907 + df and others) from first SYN packet (actually from packets with SYN
908 + bit set) with hardcoded in fingers[] table ones.
910 + Example: (Of course this only an example, do not get inspired by this)
912 + # iptables -N LINUX
913 + # iptables -A LINUX -j LOG --log-prefix "Linux"
915 + # iptables -A INPUT -p tcp -m osf --genre Linux -j LINUX
916 + # iptables -A INPUT -p tcp -m osf --genre FreeBSD -j REJECT
918 + NOTE: -p tcp is obviously required as it is a TCP match.
922 + If present, OSF will log determined genres even if they don't match
924 + 0 - log all determined entries,
925 + 1 - only first one.
928 + #iptables -I INPUT -j ACCEPT -p tcp -m osf --genre Linux --log 1 --smart
930 + In syslog you find something like this:
931 + ipt_osf: Windows [Windows XP Pro SP1, 2000 SP3]: 11.22.33.55:4024 -> 11.22.33.44:139
932 + ipt_osf: Unknown: 16384:106:1:48:020405B401010402 44.33.22.11:1239 -> 11.22.33.44:80
935 + if present, OSF will use some smartness to determine remote OS.
936 + Now only not use TTL( with it far remote machines can be determined).
938 + Fingerprints can be loaded through /proc/sys/net/ipv4/osf file.
939 + Only one fingerprint per open/close.
941 + Fingerprints can be downloaded from http://www.openbsd.org/cgi-bin/cvsweb/src/etc/pf.os
943 +config IP_POOL_STATISTICS
944 + bool 'enable statistics on pool usage'
945 + depends on IP_NF_POOL!=n
948 + tristate 'IP address pool support'
949 + depends on IP_NF_IPTABLES
951 + CONFIG_IP_NF_POOL provides a match which lets you use bitmaps with one bit per
952 + address from some range of IP addresses; the match depends on whether a checked
953 + source or destination address has its bit set in the pool. It also provides a
954 + POOL target, which can be used to add or remove the addresses of a packet
957 + There is also a POOL netfilter target, which can be used to set or remove the
958 + addresses of a packet from a pool.
960 + To define and use pools, you need userlevel utilities: a patched iptables, and
961 + the program ippool(8), which defines the pools and their bounds. The current
962 + release of pool matching is ippool-0.0.2, and can be found in the archives of
963 + the netfilter mailing list at http://lists.netfilter.org/.
965 +config IP_NF_MATCH_PSD
966 + tristate 'psd match support'
967 + depends on IP_NF_IPTABLES
969 + This option adds a `psd' match, which supplies portscan
970 + detection match (psd). This match will attempt to detect TCP and UDP
971 + port scans. This match was derived from Solar Designer's scanlogd.
973 + Suppported options are:
975 + --psd-weight-threshold <threshold>
977 + Total weight of the latest TCP/UDP packets with different
978 + destination ports coming from the same host to be treated as port
981 + --psd-delay-threshold <delay>
983 + Delay (in hundredths of second) for the packets with different
984 + destination ports coming from the same host to be treated as
985 + possible port scan subsequence.
987 + --psd-lo-ports-weight <weight>
989 + Weight of the packet with privileged (<=1024) destination port.
991 + --psd-hi-ports-weight <weight>
993 + Weight of the packet with non-priviliged destination port.
995 +config IP_NF_MATCH_QUOTA
996 + tristate 'quota match support'
997 + depends on IP_NF_IPTABLES
999 + This option adds CONFIG_IP_NF_MATCH_QUOTA, which implements network
1000 + quotas by decrementing a byte counter with each packet.
1002 + Supported options are:
1004 + The quota in bytes.
1006 + KNOWN BUGS: this does not work on SMP systems.
1009 +config IP_NF_MATCH_RANDOM
1010 + tristate 'random match support'
1011 + depends on IP_NF_IPTABLES
1013 + This option adds a `random' match,
1014 + which allow you to match packets randomly
1015 + following a given probability.
1017 + Suppported options are:
1019 + [--average] percent will match randomly packets with a probability of
1020 + 'percent'. default is 50%
1022 +config IP_NF_MATCH_REALM
1023 + tristate 'realm match support'
1024 + depends on IP_NF_IPTABLES
1026 + realm match: uses realm key from routing as match criteria similiar to
1027 + one in packet classifier
1029 + /** snip from packet classifier documentation */
1030 + Routing tables based classifier
1031 + CONFIG_NET_CLS_ROUTE4
1032 + If you say Y here, you will be able to classify outgoing packets
1033 + according to the route table entry they matched. If unsure, say Y.
1039 + /sbin/ip route add 194.29.194.0/24 via 194.29.192.1 realm 10
1041 + # source realm is in realm with mask 0xFFFF0000,
1042 + # destination is in realm with mask 0x0000FFFF
1044 + # match destination realm
1045 + /usr/local/sbin/iptables -A OUTPUT -m realm --realm 10 -j LOG
1047 + # match realm of source, this is also determinated by routing,
1048 + /usr/local/sbin/iptables -A INPUT -m realm --realm 655360 -j LOG
1050 + THIS PATCH REQUIRES CONFIG_NET_CLS_ROUTE TO BE SET
1052 +config IP_NF_MATCH_TIME
1053 + tristate 'TIME match support'
1054 + depends on IP_NF_IPTABLES
1057 + This option adds CONFIG_IP_NF_MATCH_TIME, which supplies a time match module.
1058 + This match allows you to filter based on the packet arrival time
1059 + (arrival time at the machine which the netfilter is running on) or
1060 + departure time (for locally generated packets).
1062 + Supported options are:
1064 + The starting point of the time match frame.
1067 + The stopping point of the time match frame
1070 + Days of the week to match separated by a coma, no space
1071 + (one of Sun,Mon,Tue,Wed,Thu,Fri,Sat)
1074 + -A INPUT -m time --timestart 8:00 --timestop 18:00 --days Mon,Tue,Wed,Thu,Fri
1075 + will match packets that have an arrival timestamp in the range 8:00->18:00 from Monday
1078 + -A OUTPUT -m time --timestart 8:00 --timestop 18:00 --Days Mon
1079 + will match the packets (locally generated) that have a departure timestamp
1080 + in the range 8:00->18:00 on Monday only.
1082 +config IP_NF_MATCH_U32
1083 + tristate 'U32 match support'
1084 + depends on IP_NF_IPTABLES
1087 + U32 allows you to extract quantities of up to 4 bytes from a packet,
1088 + AND them with specified masks, shift them by specified amounts and
1089 + test whether the results are in any of a set of specified ranges.
1090 + The specification of what to extract is general enough to skip over
1091 + headers with lengths stored in the packet, as in IP or TCP header
1093 + Details and examples are in the kernel module source.
1097 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/Makefile linux-2.6.3-rc3/net/ipv4/netfilter/Makefile
1098 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/Makefile 2004-02-16 10:08:59.000000000 +0100
1099 +++ linux-2.6.3-rc3/net/ipv4/netfilter/Makefile 2004-02-16 11:07:28.178208252 +0100
1102 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
1103 obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
1104 +obj-$(CONFIG_IP_NF_MATCH_QUOTA) += ipt_quota.o
1105 +obj-$(CONFIG_IP_NF_MATCH_DSTLIMIT) += ipt_dstlimit.o
1106 obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
1107 +obj-$(CONFIG_IP_NF_POOL) += ipt_pool.o ipt_POOL.o ip_pool.o
1108 obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
1109 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
1111 obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
1112 obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
1114 +obj-$(CONFIG_IP_NF_MATCH_MPORT) += ipt_mport.o
1116 obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
1117 obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
1119 +obj-$(CONFIG_IP_NF_MATCH_TIME) += ipt_time.o
1122 +obj-$(CONFIG_IP_NF_MATCH_RANDOM) += ipt_random.o
1124 +obj-$(CONFIG_IP_NF_MATCH_PSD) += ipt_psd.o
1126 +obj-$(CONFIG_IP_NF_MATCH_OSF) += ipt_osf.o
1129 +obj-$(CONFIG_IP_NF_MATCH_NTH) += ipt_nth.o
1131 +obj-$(CONFIG_IP_NF_MATCH_IPV4OPTIONS) += ipt_ipv4options.o
1134 +obj-$(CONFIG_IP_NF_MATCH_FUZZY) += ipt_fuzzy.o
1136 obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
1138 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
1141 obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o
1143 +obj-$(CONFIG_IP_NF_MATCH_U32) += ipt_u32.o
1146 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
1147 obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
1148 +obj-$(CONFIG_IP_NF_MATCH_CONNLIMIT) += ipt_connlimit.o
1149 obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
1150 obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
1151 +obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
1153 obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
1156 obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
1157 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
1158 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
1159 +obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
1160 +obj-$(CONFIG_IP_NF_TARGET_NETLINK) += ipt_NETLINK.o
1161 +obj-$(CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP) += ipt_IPV4OPTSSTRIP.o
1162 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
1163 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
1165 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ip_pool.c linux-2.6.3-rc3/net/ipv4/netfilter/ip_pool.c
1166 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ip_pool.c 1970-01-01 01:00:00.000000000 +0100
1167 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ip_pool.c 2004-02-16 11:07:21.518803072 +0100
1169 +/* Kernel module for IP pool management */
1171 +#include <linux/module.h>
1172 +#include <linux/ip.h>
1173 +#include <linux/skbuff.h>
1174 +#include <linux/netfilter_ipv4/ip_tables.h>
1175 +#include <linux/netfilter_ipv4/ip_pool.h>
1176 +#include <linux/errno.h>
1177 +#include <asm/uaccess.h>
1178 +#include <asm/bitops.h>
1179 +#include <linux/interrupt.h>
1180 +#include <linux/spinlock.h>
1185 +#define DP(format, args...)
1188 +MODULE_LICENSE("GPL");
1191 +static int nr_pool = NR_POOL;/* overwrite this when loading module */
1194 + u_int32_t first_ip; /* host byte order, included in range */
1195 + u_int32_t last_ip; /* host byte order, included in range */
1196 + void *members; /* the bitmap proper */
1197 + int nr_use; /* total nr. of tests through this */
1198 + int nr_match; /* total nr. of matches through this */
1202 +static struct ip_pool *POOL;
1204 +static inline struct ip_pool *lookup(ip_pool_t index)
1206 + if (index < 0 || index >= nr_pool) {
1207 + DP("ip_pool:lookup: bad index %d\n", index);
1210 + return POOL+index;
1213 +int ip_pool_match(ip_pool_t index, u_int32_t addr)
1215 + struct ip_pool *pool = lookup(index);
1218 + if (!pool || !pool->members)
1220 + read_lock_bh(&pool->lock);
1221 + if (pool->members) {
1222 + if (addr >= pool->first_ip && addr <= pool->last_ip) {
1223 + addr -= pool->first_ip;
1224 + if (test_bit(addr, pool->members)) {
1226 +#ifdef CONFIG_IP_POOL_STATISTICS
1231 +#ifdef CONFIG_IP_POOL_STATISTICS
1235 + read_unlock_bh(&pool->lock);
1239 +static int pool_change(ip_pool_t index, u_int32_t addr, int isdel)
1241 + struct ip_pool *pool;
1244 + pool = lookup(index);
1245 + if ( !pool || !pool->members
1246 + || addr < pool->first_ip || addr > pool->last_ip)
1248 + read_lock_bh(&pool->lock);
1249 + if (pool->members && addr >= pool->first_ip && addr <= pool->last_ip) {
1250 + addr -= pool->first_ip;
1252 + ? (0 != test_and_clear_bit(addr, pool->members))
1253 + : (0 != test_and_set_bit(addr, pool->members));
1255 + read_unlock_bh(&pool->lock);
1259 +int ip_pool_mod(ip_pool_t index, u_int32_t addr, int isdel)
1261 + int res = pool_change(index,addr,isdel);
1263 + if (!isdel) res = !res;
1267 +static inline int bitmap_bytes(u_int32_t a, u_int32_t b)
1269 + return 4*((((b-a+8)/8)+3)/4);
1272 +static inline int poolbytes(ip_pool_t index)
1274 + struct ip_pool *pool = lookup(index);
1276 + return pool ? bitmap_bytes(pool->first_ip, pool->last_ip) : 0;
1279 +static int setpool(
1285 + struct ip_pool_request req;
1287 + DP("ip_pool:setpool: optval=%d, user=%p, len=%d\n", optval, user, len);
1288 + if (!capable(CAP_NET_ADMIN))
1290 + if (optval != SO_IP_POOL)
1292 + if (len != sizeof(req))
1294 + if (copy_from_user(&req, user, sizeof(req)) != 0)
1296 + printk("obsolete op - upgrade your ippool(8) utility.\n");
1300 +static int getpool(
1306 + struct ip_pool_request req;
1307 + struct ip_pool *pool;
1313 + DP("ip_pool:getpool: optval=%d, user=%p\n", optval, user);
1314 + if (!capable(CAP_NET_ADMIN))
1316 + if (optval != SO_IP_POOL)
1318 + if (*len != sizeof(req)) {
1321 + if (copy_from_user(&req, user, sizeof(req)) != 0)
1323 + DP("ip_pool:getpool op=%d, index=%d\n", req.op, req.index);
1324 + if (req.op < IP_POOL_BAD001) {
1325 + printk("obsolete op - upgrade your ippool(8) utility.\n");
1329 + case IP_POOL_HIGH_NR:
1330 + DP("ip_pool HIGH_NR\n");
1331 + req.index = IP_POOL_NONE;
1332 + for (i=0; i<nr_pool; i++)
1333 + if (POOL[i].members)
1335 + return copy_to_user(user, &req, sizeof(req));
1336 + case IP_POOL_LOOKUP:
1337 + DP("ip_pool LOOKUP\n");
1338 + pool = lookup(req.index);
1341 + if (!pool->members)
1343 + req.addr = htonl(pool->first_ip);
1344 + req.addr2 = htonl(pool->last_ip);
1345 + return copy_to_user(user, &req, sizeof(req));
1346 + case IP_POOL_USAGE:
1347 + DP("ip_pool USE\n");
1348 + pool = lookup(req.index);
1351 + if (!pool->members)
1353 + req.addr = pool->nr_use;
1354 + req.addr2 = pool->nr_match;
1355 + return copy_to_user(user, &req, sizeof(req));
1356 + case IP_POOL_TEST_ADDR:
1357 + DP("ip_pool TEST 0x%08x\n", req.addr);
1358 + pool = lookup(req.index);
1362 + read_lock_bh(&pool->lock);
1363 + if (!pool->members) {
1364 + DP("ip_pool TEST_ADDR no members in pool\n");
1366 + goto unlock_and_return_res;
1368 + req.addr = ntohl(req.addr);
1369 + if (req.addr < pool->first_ip) {
1370 + DP("ip_pool TEST_ADDR address < pool bounds\n");
1372 + goto unlock_and_return_res;
1374 + if (req.addr > pool->last_ip) {
1375 + DP("ip_pool TEST_ADDR address > pool bounds\n");
1377 + goto unlock_and_return_res;
1379 + req.addr = (0 != test_bit((req.addr - pool->first_ip),
1381 + read_unlock_bh(&pool->lock);
1382 + return copy_to_user(user, &req, sizeof(req));
1383 + case IP_POOL_FLUSH:
1384 + DP("ip_pool FLUSH not yet implemented.\n");
1386 + case IP_POOL_DESTROY:
1387 + DP("ip_pool DESTROY not yet implemented.\n");
1389 + case IP_POOL_INIT:
1390 + DP("ip_pool INIT 0x%08x-0x%08x\n", req.addr, req.addr2);
1391 + pool = lookup(req.index);
1394 + req.addr = ntohl(req.addr);
1395 + req.addr2 = ntohl(req.addr2);
1396 + if (req.addr > req.addr2) {
1397 + DP("ip_pool INIT bad ip range\n");
1400 + newbytes = bitmap_bytes(req.addr, req.addr2);
1401 + newmembers = kmalloc(newbytes, GFP_KERNEL);
1402 + if (!newmembers) {
1403 + DP("ip_pool INIT out of mem for %d bytes\n", newbytes);
1406 + memset(newmembers, 0, newbytes);
1407 + write_lock_bh(&pool->lock);
1408 + if (pool->members) {
1409 + DP("ip_pool INIT pool %d exists\n", req.index);
1410 + kfree(newmembers);
1412 + goto unlock_and_return_res;
1414 + pool->first_ip = req.addr;
1415 + pool->last_ip = req.addr2;
1417 + pool->nr_match = 0;
1418 + pool->members = newmembers;
1419 + write_unlock_bh(&pool->lock);
1421 + case IP_POOL_ADD_ADDR:
1422 + DP("ip_pool ADD_ADDR 0x%08x\n", req.addr);
1423 + req.addr = pool_change(req.index, ntohl(req.addr), 0);
1424 + return copy_to_user(user, &req, sizeof(req));
1425 + case IP_POOL_DEL_ADDR:
1426 + DP("ip_pool DEL_ADDR 0x%08x\n", req.addr);
1427 + req.addr = pool_change(req.index, ntohl(req.addr), 1);
1428 + return copy_to_user(user, &req, sizeof(req));
1430 + DP("ip_pool:getpool bad op %d\n", req.op);
1435 +unlock_and_return_res:
1437 + read_unlock_bh(&pool->lock);
1441 +static struct nf_sockopt_ops so_pool
1442 += { { NULL, NULL }, PF_INET,
1443 + SO_IP_POOL, SO_IP_POOL+1, &setpool,
1444 + SO_IP_POOL, SO_IP_POOL+1, &getpool,
1447 +MODULE_PARM(nr_pool, "i");
1449 +static int __init init(void)
1454 + if (nr_pool < 1) {
1455 + printk("ip_pool module init: bad nr_pool %d\n", nr_pool);
1458 + POOL = kmalloc(nr_pool * sizeof(*POOL), GFP_KERNEL);
1460 + printk("ip_pool module init: out of memory for nr_pool %d\n",
1464 + for (i=0; i<nr_pool; i++) {
1465 + POOL[i].first_ip = 0;
1466 + POOL[i].last_ip = 0;
1467 + POOL[i].members = 0;
1468 + POOL[i].nr_use = 0;
1469 + POOL[i].nr_match = 0;
1470 + POOL[i].lock = RW_LOCK_UNLOCKED;
1472 + res = nf_register_sockopt(&so_pool);
1473 + DP("ip_pool:init %d pools, result %d\n", nr_pool, res);
1481 +static void __exit fini(void)
1485 + DP("ip_pool:fini BYEBYE\n");
1486 + nf_unregister_sockopt(&so_pool);
1487 + for (i=0; i<nr_pool; i++) {
1488 + if (POOL[i].members) {
1489 + kfree(POOL[i].members);
1490 + POOL[i].members = 0;
1495 + DP("ip_pool:fini these are the famous last words\n");
1501 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c
1502 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 1970-01-01 01:00:00.000000000 +0100
1503 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 2004-02-16 11:06:57.518550655 +0100
1506 + * Strip all IP options in the IP packet header.
1508 + * (C) 2001 by Fabrice MARIE <fabrice@netfilter.org>
1509 + * This software is distributed under GNU GPL v2, 1991
1512 +#include <linux/module.h>
1513 +#include <linux/skbuff.h>
1514 +#include <linux/ip.h>
1515 +#include <net/checksum.h>
1517 +#include <linux/netfilter_ipv4/ip_tables.h>
1519 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
1520 +MODULE_DESCRIPTION("Strip all options in IPv4 packets");
1521 +MODULE_LICENSE("GPL");
1523 +static unsigned int
1524 +target(struct sk_buff **pskb,
1525 + unsigned int hooknum,
1526 + const struct net_device *in,
1527 + const struct net_device *out,
1528 + const void *targinfo,
1531 + struct iphdr *iph = (*pskb)->nh.iph;
1532 + struct sk_buff *skb = (*pskb);
1533 + struct ip_options * opt;
1534 + unsigned char * optiph = skb->nh.raw;
1535 + int l = ((struct ip_options *)(&(IPCB(skb)->opt)))->optlen;
1538 + /* if no options in packet then nothing to clear. */
1539 + if (iph->ihl * 4 == sizeof(struct iphdr))
1540 + return IPT_CONTINUE;
1542 + /* else clear all options */
1543 + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
1544 + memset(optiph+sizeof(struct iphdr), IPOPT_NOOP, l);
1545 + opt = &(IPCB(skb)->opt);
1549 + skb->nfcache |= NFC_ALTERED;
1551 + return IPT_CONTINUE;
1555 +checkentry(const char *tablename,
1556 + const struct ipt_entry *e,
1558 + unsigned int targinfosize,
1559 + unsigned int hook_mask)
1561 + if (strcmp(tablename, "mangle")) {
1562 + printk(KERN_WARNING "IPV4OPTSSTRIP: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1565 + /* nothing else to check because no parameters */
1569 +static struct ipt_target ipt_ipv4optsstrip_reg
1570 += { { NULL, NULL }, "IPV4OPTSSTRIP", target, checkentry, NULL, THIS_MODULE };
1572 +static int __init init(void)
1574 + if (ipt_register_target(&ipt_ipv4optsstrip_reg))
1576 + printk("ipt_IPV4OPTSSTRIP loaded\n");
1581 +static void __exit fini(void)
1583 + ipt_unregister_target(&ipt_ipv4optsstrip_reg);
1584 + printk("ipt_IPV4OPTSSTRIP unloaded\n");
1589 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_NETLINK.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_NETLINK.c
1590 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_NETLINK.c 1970-01-01 01:00:00.000000000 +0100
1591 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_NETLINK.c 2004-02-16 11:07:05.880548139 +0100
1593 +#include <linux/module.h>
1594 +#include <linux/version.h>
1595 +#include <linux/config.h>
1596 +#include <linux/socket.h>
1597 +#include <linux/skbuff.h>
1598 +#include <linux/kernel.h>
1599 +#include <linux/netlink.h>
1600 +#include <linux/netdevice.h>
1601 +#include <linux/mm.h>
1602 +#include <linux/socket.h>
1603 +#include <linux/netfilter_ipv4/ip_tables.h>
1604 +#include <linux/netfilter_ipv4/ipt_NETLINK.h>
1605 +#include <net/sock.h>
1607 +MODULE_AUTHOR("Gianni Tedesco <gianni@ecsc.co.uk>");
1608 +MODULE_DESCRIPTION("Provides iptables NETLINK target similar to ipchains -o");
1609 +MODULE_LICENSE("GPL");
1612 +#define DEBUGP printk
1614 +#define DEBUGP(format, args...)
1617 +static struct sock *ipfwsk;
1619 +static unsigned int ipt_netlink_target(struct sk_buff **pskb,
1620 + unsigned int hooknum,
1621 + const struct net_device *in,
1622 + const struct net_device *out,
1623 + const void *targinfo, void *userinfo)
1625 + struct ipt_nldata *nld = (struct ipt_nldata *)targinfo;
1626 + struct iphdr *ip = (*pskb)->nh.iph;
1627 + struct sk_buff *outskb;
1628 + struct netlink_t nlhdr;
1631 + /* Allocate a socket buffer */
1632 + if ( MASK(nld->flags, USE_SIZE) )
1633 + len = nld->size+sizeof(nlhdr);
1635 + len = ntohs(ip->tot_len)+sizeof(nlhdr);
1637 + outskb=alloc_skb(len, GFP_ATOMIC);
1642 + if ( MASK(nld->flags, USE_MARK) )
1643 + nlhdr.mark=(*pskb)->nfmark=nld->mark;
1645 + nlhdr.mark=(*pskb)->nfmark;
1647 + if ( in && in->name ) {
1648 + strncpy((char *)&nlhdr.iface, in->name, IFNAMSIZ);
1649 + }else if ( out && out->name ){
1650 + strncpy((char *)&nlhdr.iface, out->name, IFNAMSIZ);
1653 + skb_put(outskb, len);
1654 + memcpy(outskb->data, &nlhdr, sizeof(nlhdr));
1655 + memcpy((outskb->data)+sizeof(nlhdr), ip, len-sizeof(nlhdr));
1656 + netlink_broadcast(ipfwsk, outskb, 0, ~0, GFP_ATOMIC);
1658 + if (net_ratelimit())
1659 + printk(KERN_WARNING "ipt_NETLINK: packet drop due to netlink failure\n");
1662 + if ( MASK(nld->flags, USE_DROP) )
1665 + return IPT_CONTINUE;
1668 +static int ipt_netlink_checkentry(const char *tablename,
1669 + const struct ipt_entry *e,
1671 + unsigned int targinfosize,
1672 + unsigned int hookmask)
1674 + //struct ipt_nldata *nld = (struct ipt_nldata *)targinfo;
1679 +static struct ipt_target ipt_netlink_reg = {
1682 + ipt_netlink_target,
1683 + ipt_netlink_checkentry,
1688 +static int __init init(void)
1690 + DEBUGP("ipt_NETLINK: init module\n");
1692 + if (ipt_register_target(&ipt_netlink_reg) != 0) {
1696 + if ( !(ipfwsk=netlink_kernel_create(NETLINK_FIREWALL, NULL)) ){
1703 +static void __exit fini(void)
1705 + DEBUGP("ipt_NETLINK: cleanup_module\n");
1706 + ipt_unregister_target(&ipt_netlink_reg);
1707 +// if(ipfwsk->socket) sock_release(ipfwsk->socket);
1712 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_POOL.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_POOL.c
1713 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_POOL.c 1970-01-01 01:00:00.000000000 +0100
1714 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_POOL.c 2004-02-16 11:07:21.518803072 +0100
1716 +/* ipt_POOL.c - netfilter target to manipulate IP pools
1718 + * This target can be used almost everywhere. It acts on some specified
1719 + * IP pool, adding or deleting some IP address in the pool. The address
1720 + * can be either the source (--addsrc, --delsrc), or destination (--add/deldst)
1721 + * of the packet under inspection.
1723 + * The target normally returns IPT_CONTINUE.
1726 +#include <linux/types.h>
1727 +#include <linux/ip.h>
1728 +#include <linux/timer.h>
1729 +#include <linux/module.h>
1730 +#include <linux/netfilter.h>
1731 +#include <linux/netdevice.h>
1732 +#include <linux/if.h>
1733 +#include <linux/inetdevice.h>
1734 +#include <net/protocol.h>
1735 +#include <net/checksum.h>
1736 +#include <linux/netfilter_ipv4.h>
1737 +#include <linux/netfilter_ipv4/ip_nat_rule.h>
1738 +#include <linux/netfilter_ipv4/ipt_pool.h>
1741 +#define DEBUGP printk
1743 +#define DEBUGP(format, args...)
1746 +/*** NOTE NOTE NOTE NOTE ***
1748 +** By sheer luck, I get away with using the "struct ipt_pool_info", as defined
1749 +** in <linux/netfilter_ipv4/ipt_pool.h>, both as the match and target info.
1750 +** Here, in the target implementation, ipt_pool_info.src, if not IP_POOL_NONE,
1751 +** is modified for the source IP address of the packet under inspection.
1752 +** The same way, the ipt_pool_info.dst pool is modified for the destination.
1754 +** The address is added to the pool normally. However, if IPT_POOL_DEL_dir
1755 +** flag is set in ipt_pool_info.flags, the address is deleted from the pool.
1757 +** If a modification was done to the pool, we possibly return ACCEPT or DROP,
1758 +** if the right IPT_POOL_MOD_dir_ACCEPT or _MOD_dir_DROP flags are set.
1759 +** The IPT_POOL_INV_MOD_dir flag inverts the sense of the check (i.e. the
1760 +** ACCEPT and DROP flags are evaluated when the pool was not modified.)
1764 +do_check(const char *tablename,
1765 + const struct ipt_entry *e,
1767 + unsigned int targinfosize,
1768 + unsigned int hook_mask)
1770 + const struct ipt_pool_info *ipi = targinfo;
1772 + if (targinfosize != IPT_ALIGN(sizeof(*ipi))) {
1773 + DEBUGP("POOL_check: size %u.\n", targinfosize);
1776 + DEBUGP("ipt_POOL:do_check(%d,%d,%d)\n",ipi->src,ipi->dst,ipi->flags);
1780 +static unsigned int
1781 +do_target(struct sk_buff **pskb,
1782 + unsigned int hooknum,
1783 + const struct net_device *in,
1784 + const struct net_device *out,
1785 + const void *targinfo,
1788 + const struct ipt_pool_info *ipi = targinfo;
1790 + unsigned int verdict = IPT_CONTINUE;
1792 + if (ipi->src != IP_POOL_NONE) {
1793 + modified = ip_pool_mod(ipi->src, ntohl((*pskb)->nh.iph->saddr),
1794 + ipi->flags & IPT_POOL_DEL_SRC);
1795 + if (!!modified ^ !!(ipi->flags & IPT_POOL_INV_MOD_SRC)) {
1796 + if (ipi->flags & IPT_POOL_MOD_SRC_ACCEPT)
1797 + verdict = NF_ACCEPT;
1798 + else if (ipi->flags & IPT_POOL_MOD_SRC_DROP)
1799 + verdict = NF_DROP;
1802 + if (verdict == IPT_CONTINUE && ipi->dst != IP_POOL_NONE) {
1803 + modified = ip_pool_mod(ipi->dst, ntohl((*pskb)->nh.iph->daddr),
1804 + ipi->flags & IPT_POOL_DEL_DST);
1805 + if (!!modified ^ !!(ipi->flags & IPT_POOL_INV_MOD_DST)) {
1806 + if (ipi->flags & IPT_POOL_MOD_DST_ACCEPT)
1807 + verdict = NF_ACCEPT;
1808 + else if (ipi->flags & IPT_POOL_MOD_DST_DROP)
1809 + verdict = NF_DROP;
1815 +static struct ipt_target pool_reg
1816 += { { NULL, NULL }, "POOL", do_target, do_check, NULL, THIS_MODULE };
1818 +static int __init init(void)
1820 + DEBUGP("init ipt_POOL\n");
1821 + return ipt_register_target(&pool_reg);
1824 +static void __exit fini(void)
1826 + DEBUGP("fini ipt_POOL\n");
1827 + ipt_unregister_target(&pool_reg);
1832 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_TTL.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_TTL.c
1833 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_TTL.c 1970-01-01 01:00:00.000000000 +0100
1834 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_TTL.c 2004-02-16 11:07:09.253740328 +0100
1836 +/* TTL modification target for IP tables
1837 + * (C) 2000 by Harald Welte <laforge@gnumonks.org>
1841 + * This software is distributed under the terms of GNU GPL
1844 +#include <linux/module.h>
1845 +#include <linux/skbuff.h>
1846 +#include <linux/ip.h>
1847 +#include <net/checksum.h>
1849 +#include <linux/netfilter_ipv4/ip_tables.h>
1850 +#include <linux/netfilter_ipv4/ipt_TTL.h>
1852 +MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
1853 +MODULE_DESCRIPTION("IP tables TTL modification module");
1854 +MODULE_LICENSE("GPL");
1856 +static unsigned int ipt_ttl_target(struct sk_buff **pskb, unsigned int hooknum,
1857 + const struct net_device *in, const struct net_device *out,
1858 + const void *targinfo, void *userinfo)
1860 + struct iphdr *iph = (*pskb)->nh.iph;
1861 + const struct ipt_TTL_info *info = targinfo;
1862 + u_int16_t diffs[2];
1865 + switch (info->mode) {
1867 + new_ttl = info->ttl;
1870 + new_ttl = iph->ttl + info->ttl;
1871 + if (new_ttl > 255)
1875 + new_ttl = iph->ttl + info->ttl;
1880 + new_ttl = iph->ttl;
1884 + if (new_ttl != iph->ttl) {
1885 + diffs[0] = htons(((unsigned)iph->ttl) << 8) ^ 0xFFFF;
1886 + iph->ttl = new_ttl;
1887 + diffs[1] = htons(((unsigned)iph->ttl) << 8);
1888 + iph->check = csum_fold(csum_partial((char *)diffs,
1890 + iph->check^0xFFFF));
1891 + (*pskb)->nfcache |= NFC_ALTERED;
1894 + return IPT_CONTINUE;
1897 +static int ipt_ttl_checkentry(const char *tablename,
1898 + const struct ipt_entry *e,
1900 + unsigned int targinfosize,
1901 + unsigned int hook_mask)
1903 + struct ipt_TTL_info *info = targinfo;
1905 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_TTL_info))) {
1906 + printk(KERN_WARNING "TTL: targinfosize %u != %Zu\n",
1908 + IPT_ALIGN(sizeof(struct ipt_TTL_info)));
1912 + if (strcmp(tablename, "mangle")) {
1913 + printk(KERN_WARNING "TTL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1917 + if (info->mode > IPT_TTL_MAXMODE) {
1918 + printk(KERN_WARNING "TTL: invalid or unknown Mode %u\n",
1923 + if ((info->mode != IPT_TTL_SET) && (info->ttl == 0)) {
1924 + printk(KERN_WARNING "TTL: increment/decrement doesn't make sense with value 0\n");
1931 +static struct ipt_target ipt_TTL = { { NULL, NULL }, "TTL",
1932 + ipt_ttl_target, ipt_ttl_checkentry, NULL, THIS_MODULE };
1934 +static int __init init(void)
1936 + return ipt_register_target(&ipt_TTL);
1939 +static void __exit fini(void)
1941 + ipt_unregister_target(&ipt_TTL);
1946 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_connlimit.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_connlimit.c
1947 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_connlimit.c 1970-01-01 01:00:00.000000000 +0100
1948 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_connlimit.c 2004-02-16 11:07:11.549190614 +0100
1951 + * netfilter module to limit the number of parallel tcp
1952 + * connections per IP address.
1953 + * (c) 2000 Gerd Knorr <kraxel@bytesex.org>
1954 + * Nov 2002: Martin Bene <martin.bene@icomedias.com>:
1955 + * only ignore TIME_WAIT or gone connections
1959 + * Kernel module to match connection tracking information.
1960 + * GPL (C) 1999 Rusty Russell (rusty@rustcorp.com.au).
1962 +#include <linux/module.h>
1963 +#include <linux/skbuff.h>
1964 +#include <linux/list.h>
1965 +#include <linux/netfilter_ipv4/ip_conntrack.h>
1966 +#include <linux/netfilter_ipv4/ip_conntrack_core.h>
1967 +#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
1968 +#include <linux/netfilter_ipv4/ip_tables.h>
1969 +#include <linux/netfilter_ipv4/ipt_connlimit.h>
1973 +MODULE_LICENSE("GPL");
1975 +/* we'll save the tuples of all connections we care about */
1976 +struct ipt_connlimit_conn
1978 + struct list_head list;
1979 + struct ip_conntrack_tuple tuple;
1982 +struct ipt_connlimit_data {
1984 + struct list_head iphash[256];
1987 +static int ipt_iphash(u_int32_t addr)
1991 + hash = addr & 0xff;
1992 + hash ^= (addr >> 8) & 0xff;
1993 + hash ^= (addr >> 16) & 0xff;
1994 + hash ^= (addr >> 24) & 0xff;
1998 +static int count_them(struct ipt_connlimit_data *data,
1999 + u_int32_t addr, u_int32_t mask,
2000 + struct ip_conntrack *ct)
2003 + const static char *tcp[] = { "none", "established", "syn_sent", "syn_recv",
2004 + "fin_wait", "time_wait", "close", "close_wait",
2005 + "last_ack", "listen" };
2007 + int addit = 1, matches = 0;
2008 + struct ip_conntrack_tuple tuple;
2009 + struct ip_conntrack_tuple_hash *found;
2010 + struct ipt_connlimit_conn *conn;
2011 + struct list_head *hash,*lh;
2013 + spin_lock(&data->lock);
2014 + tuple = ct->tuplehash[0].tuple;
2015 + hash = &data->iphash[ipt_iphash(addr & mask)];
2017 + /* check the saved connections */
2018 + for (lh = hash->next; lh != hash; lh = lh->next) {
2019 + conn = list_entry(lh,struct ipt_connlimit_conn,list);
2020 + found = ip_conntrack_find_get(&conn->tuple,ct);
2021 + if (0 == memcmp(&conn->tuple,&tuple,sizeof(tuple)) &&
2023 + found->ctrack->proto.tcp.state != TCP_CONNTRACK_TIME_WAIT) {
2024 + /* Just to be sure we have it only once in the list.
2025 + We should'nt see tuples twice unless someone hooks this
2026 + into a table without "-p tcp --syn" */
2030 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d %s\n",
2031 + ipt_iphash(addr & mask),
2032 + NIPQUAD(conn->tuple.src.ip), ntohs(conn->tuple.src.u.tcp.port),
2033 + NIPQUAD(conn->tuple.dst.ip), ntohs(conn->tuple.dst.u.tcp.port),
2034 + (NULL != found) ? tcp[found->ctrack->proto.tcp.state] : "gone");
2036 + if (NULL == found) {
2037 + /* this one is gone */
2039 + list_del(lh->next);
2043 + if (found->ctrack->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT) {
2044 + /* we don't care about connections which are
2045 + closed already -> ditch it */
2047 + list_del(lh->next);
2049 + nf_conntrack_put(&found->ctrack->infos[0]);
2052 + if ((addr & mask) == (conn->tuple.src.ip & mask)) {
2053 + /* same source IP address -> be counted! */
2056 + nf_conntrack_put(&found->ctrack->infos[0]);
2059 + /* save the new connection in our list */
2061 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d new\n",
2062 + ipt_iphash(addr & mask),
2063 + NIPQUAD(tuple.src.ip), ntohs(tuple.src.u.tcp.port),
2064 + NIPQUAD(tuple.dst.ip), ntohs(tuple.dst.u.tcp.port));
2066 + conn = kmalloc(sizeof(*conn),GFP_ATOMIC);
2069 + memset(conn,0,sizeof(*conn));
2070 + INIT_LIST_HEAD(&conn->list);
2071 + conn->tuple = tuple;
2072 + list_add(&conn->list,hash);
2075 + spin_unlock(&data->lock);
2080 +match(const struct sk_buff *skb,
2081 + const struct net_device *in,
2082 + const struct net_device *out,
2083 + const void *matchinfo,
2086 + u_int16_t datalen,
2089 + const struct ipt_connlimit_info *info = matchinfo;
2090 + int connections, match;
2091 + struct ip_conntrack *ct;
2092 + enum ip_conntrack_info ctinfo;
2094 + ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
2096 + printk("ipt_connlimit: Oops: invalid ct state ?\n");
2100 + connections = count_them(info->data,skb->nh.iph->saddr,info->mask,ct);
2101 + if (-1 == connections) {
2102 + printk("ipt_connlimit: Hmm, kmalloc failed :-(\n");
2103 + *hotdrop = 1; /* let's free some memory :-) */
2106 + match = (info->inverse) ? (connections <= info->limit) : (connections > info->limit);
2108 + printk("ipt_connlimit: src=%u.%u.%u.%u mask=%u.%u.%u.%u "
2109 + "connections=%d limit=%d match=%s\n",
2110 + NIPQUAD(skb->nh.iph->saddr), NIPQUAD(info->mask),
2111 + connections, info->limit, match ? "yes" : "no");
2117 +static int check(const char *tablename,
2118 + const struct ipt_ip *ip,
2120 + unsigned int matchsize,
2121 + unsigned int hook_mask)
2123 + struct ipt_connlimit_info *info = matchinfo;
2127 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_connlimit_info)))
2130 + /* refuse anything but tcp */
2131 + if (ip->proto != IPPROTO_TCP)
2134 + /* init private data */
2135 + info->data = kmalloc(sizeof(struct ipt_connlimit_data),GFP_KERNEL);
2136 + spin_lock_init(&(info->data->lock));
2137 + for (i = 0; i < 256; i++)
2138 + INIT_LIST_HEAD(&(info->data->iphash[i]));
2143 +static void destroy(void *matchinfo, unsigned int matchinfosize)
2145 + struct ipt_connlimit_info *info = matchinfo;
2146 + struct ipt_connlimit_conn *conn;
2147 + struct list_head *hash;
2151 + for (i = 0; i < 256; i++) {
2152 + hash = &(info->data->iphash[i]);
2153 + while (hash != hash->next) {
2154 + conn = list_entry(hash->next,struct ipt_connlimit_conn,list);
2155 + list_del(hash->next);
2159 + kfree(info->data);
2162 +static struct ipt_match connlimit_match
2163 += { { NULL, NULL }, "connlimit", &match, &check, &destroy, THIS_MODULE };
2165 +static int __init init(void)
2167 + return ipt_register_match(&connlimit_match);
2170 +static void __exit fini(void)
2172 + ipt_unregister_match(&connlimit_match);
2177 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_dstlimit.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_dstlimit.c
2178 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_dstlimit.c 1970-01-01 01:00:00.000000000 +0100
2179 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_dstlimit.c 2004-02-16 11:07:13.230787904 +0100
2181 +/* iptables match extension to limit the number of packets per second
2182 + * seperately for each destination.
2184 + * (C) 2003 by Harald Welte <laforge@netfilter.org>
2186 + * Development of this code was funded by Astaro AG, http://www.astaro.com/
2188 + * based on ipt_limit.c by:
2189 + * Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
2190 + * Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
2191 + * Rusty Russell <rusty@rustcorp.com.au>
2193 + * The general idea is to create a hash table for every dstip and have a
2194 + * seperate limit counter per tuple. This way you can do something like 'limit
2195 + * the number of syn packets for each of my internal addresses.
2197 + * Ideally this would just be implemented as a general 'hash' match, which would
2198 + * allow us to attach any iptables target to it's hash buckets. But this is
2199 + * not possible in the current iptables architecture. As always, pkttables for
2200 + * 2.7.x will help ;)
2202 +#include <linux/module.h>
2203 +#include <linux/skbuff.h>
2204 +#include <linux/spinlock.h>
2205 +#include <linux/random.h>
2206 +#include <linux/jhash.h>
2207 +#include <linux/slab.h>
2208 +#include <linux/vmalloc.h>
2209 +#include <linux/tcp.h>
2210 +#include <linux/udp.h>
2211 +#include <linux/proc_fs.h>
2212 +#include <linux/seq_file.h>
2214 +#define ASSERT_READ_LOCK(x)
2215 +#define ASSERT_WRITE_LOCK(x)
2216 +#include <linux/netfilter_ipv4/lockhelp.h>
2217 +#include <linux/netfilter_ipv4/listhelp.h>
2219 +#include <linux/netfilter_ipv4/ip_tables.h>
2220 +#include <linux/netfilter_ipv4/ipt_dstlimit.h>
2222 +/* FIXME: this is just for IP_NF_ASSERRT */
2223 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2225 +#define MS2JIFFIES(x) ((x*HZ)/1000)
2227 +MODULE_LICENSE("GPL");
2228 +MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
2229 +MODULE_DESCRIPTION("iptables match for limiting per destination");
2231 +/* need to declare this at the top */
2232 +static struct proc_dir_entry *dstlimit_procdir;
2233 +static struct file_operations dl_file_ops;
2235 +/* hash table crap */
2237 +struct dsthash_dst {
2243 +struct dsthash_ent {
2244 + /* static / read-only parts in the beginning */
2245 + struct list_head list;
2246 + struct dsthash_dst dst;
2248 + /* modified structure members in the end */
2249 + unsigned long expires; /* precalculated expiry time */
2251 + unsigned long prev; /* last modification */
2253 + u_int32_t credit_cap, cost;
2257 +struct ipt_dstlimit_htable {
2258 + struct ipt_dstlimit_info *minfo; /* public structure */
2260 + /* used internally */
2261 + spinlock_t lock; /* lock for list_head */
2262 + u_int32_t rnd; /* random seed for hash */
2263 + struct timer_list timer; /* timer for gc */
2264 + atomic_t count; /* number entries in table */
2266 + /* seq_file stuff */
2267 + struct proc_dir_entry *pde;
2269 + struct list_head hash[0]; /* hashtable itself */
2272 +static kmem_cache_t *dstlimit_cachep;
2274 +static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b)
2276 + return (ent->dst.dst_ip == b->dst_ip
2277 + && ent->dst.port == b->port
2278 + && ent->dst.src_ip == b->src_ip);
2281 +static inline u_int32_t
2282 +hash_dst(const struct ipt_dstlimit_htable *ht, const struct dsthash_dst *dst)
2284 + return (jhash_3words(dst->dst_ip, dst->port,
2285 + dst->src_ip, ht->rnd) % ht->minfo->size);
2288 +static inline struct dsthash_ent *
2289 +__dsthash_find(const struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
2291 + struct dsthash_ent *ent;
2292 + u_int32_t hash = hash_dst(ht, dst);
2293 + MUST_BE_LOCKED(&ht->lock);
2294 + ent = LIST_FIND(&ht->hash[hash], dst_cmp, struct dsthash_ent *, dst);
2298 +/* allocate dsthash_ent, initialize dst, put in htable and lock it */
2299 +static struct dsthash_ent *
2300 +__dsthash_alloc_init(struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
2302 + struct dsthash_ent *ent;
2304 + /* initialize hash with random val at the time we allocate
2305 + * the first hashtable entry */
2307 + get_random_bytes(&ht->rnd, 4);
2309 + if (ht->minfo->max &&
2310 + atomic_read(&ht->count) >= ht->minfo->max) {
2311 + /* FIXME: do something. question is what.. */
2312 + if (net_ratelimit())
2313 + printk("max count of %u reached\n", ht->minfo->max);
2317 + ent = kmem_cache_alloc(dstlimit_cachep, GFP_ATOMIC);
2319 + if (net_ratelimit())
2320 + printk("Can't allocate dsthash_ent\n");
2324 + atomic_inc(&ht->count);
2326 + ent->dst.dst_ip = dst->dst_ip;
2327 + ent->dst.port = dst->port;
2328 + ent->dst.src_ip = dst->src_ip;
2330 + list_add(&ent->list, &ht->hash[hash_dst(ht, dst)]);
2336 +__dsthash_free(struct ipt_dstlimit_htable *ht, struct dsthash_ent *ent)
2338 + MUST_BE_LOCKED(&ht->lock);
2340 + list_del(&ent->list);
2341 + kmem_cache_free(dstlimit_cachep, ent);
2342 + atomic_dec(&ht->count);
2345 +static void htable_gc(unsigned long htlong);
2347 +static int htable_create(struct ipt_dstlimit_info *minfo)
2350 + struct ipt_dstlimit_htable *hinfo;
2352 + if (!minfo->size) {
2353 + minfo->size = (((num_physpages << PAGE_SHIFT) / 16384)
2354 + / sizeof(struct list_head));
2355 + if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
2356 + minfo->size = 8192;
2357 + if (minfo->size < 16)
2361 + minfo->max = 8 * minfo->size;
2362 + else if (minfo->max < minfo->size)
2363 + minfo->max = minfo->size;
2365 + /* FIXME: don't use vmalloc() here or anywhere else -HW */
2366 + hinfo = vmalloc(sizeof(struct ipt_dstlimit_htable)
2367 + + (sizeof(struct list_head) * minfo->size));
2369 + printk(KERN_ERR "Unable to create ipt_dstlimit hash\n");
2373 + for (i = 0; i < minfo->size; i++)
2374 + INIT_LIST_HEAD(&hinfo->hash[i]);
2376 + minfo->hinfo = hinfo;
2378 + hinfo->minfo = minfo;
2379 + atomic_set(&hinfo->count, 0);
2382 + hinfo->lock = SPIN_LOCK_UNLOCKED;
2384 + hinfo->pde = create_proc_entry(minfo->name, 0, dstlimit_procdir);
2385 + if (!hinfo->pde) {
2389 + hinfo->pde->proc_fops = &dl_file_ops;
2390 + hinfo->pde->data = hinfo;
2392 + init_timer(&hinfo->timer);
2393 + hinfo->timer.expires = jiffies + MS2JIFFIES(minfo->gc_interval);
2394 + hinfo->timer.data = (unsigned long )hinfo;
2395 + hinfo->timer.function = htable_gc;
2396 + add_timer(&hinfo->timer);
2401 +static int select_all(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
2406 +static int select_gc(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
2408 + return (jiffies >= he->expires);
2411 +static void htable_selective_cleanup(struct ipt_dstlimit_htable *ht,
2412 + int (*select)(struct ipt_dstlimit_htable *ht,
2413 + struct dsthash_ent *he))
2417 + IP_NF_ASSERT(ht->minfo->size && ht->minfo->max);
2419 + /* lock hash table and iterate over it */
2420 + LOCK_BH(&ht->lock);
2421 + for (i = 0; i < ht->minfo->size; i++) {
2422 + struct dsthash_ent *dh, *n;
2423 + list_for_each_entry_safe(dh, n, &ht->hash[i], list) {
2424 + if ((*select)(ht, dh))
2425 + __dsthash_free(ht, dh);
2428 + UNLOCK_BH(&ht->lock);
2431 +/* hash table garbage collector, run by timer */
2432 +static void htable_gc(unsigned long htlong)
2434 + struct ipt_dstlimit_htable *ht = (struct ipt_dstlimit_htable *)htlong;
2436 + htable_selective_cleanup(ht, select_gc);
2438 + /* re-add the timer accordingly */
2439 + ht->timer.expires = jiffies + MS2JIFFIES(ht->minfo->gc_interval);
2440 + add_timer(&ht->timer);
2443 +/* The algorithm used is the Simple Token Bucket Filter (TBF)
2444 + * see net/sched/sch_tbf.c in the linux source tree
2447 +/* Rusty: This is my (non-mathematically-inclined) understanding of
2448 + this algorithm. The `average rate' in jiffies becomes your initial
2449 + amount of credit `credit' and the most credit you can ever have
2450 + `credit_cap'. The `peak rate' becomes the cost of passing the
2453 + `prev' tracks the last packet hit: you gain one credit per jiffy.
2454 + If you get credit balance more than this, the extra credit is
2455 + discarded. Every time the match passes, you lose `cost' credits;
2456 + if you don't have that many, the test fails.
2458 + See Alexey's formal explanation in net/sched/sch_tbf.c.
2460 + To get the maximum range, we multiply by this factor (ie. you get N
2461 + credits per jiffy). We want to allow a rate as low as 1 per day
2462 + (slowest userspace tool allows), which means
2463 + CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32 ie.
2465 +#define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24))
2467 +/* Repeated shift and or gives us all 1s, final shift and add 1 gives
2468 + * us the power of 2 below the theoretical max, so GCC simply does a
2470 +#define _POW2_BELOW2(x) ((x)|((x)>>1))
2471 +#define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2))
2472 +#define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4))
2473 +#define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8))
2474 +#define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16))
2475 +#define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1)
2477 +#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
2479 +/* Precision saver. */
2480 +static inline u_int32_t
2481 +user2credits(u_int32_t user)
2483 + /* If multiplying would overflow... */
2484 + if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY))
2485 + /* Divide first. */
2486 + return (user / IPT_DSTLIMIT_SCALE) * HZ * CREDITS_PER_JIFFY;
2488 + return (user * HZ * CREDITS_PER_JIFFY) / IPT_DSTLIMIT_SCALE;
2491 +static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
2493 + dh->rateinfo.credit += (now - xchg(&dh->rateinfo.prev, now))
2494 + * CREDITS_PER_JIFFY;
2495 + if (dh->rateinfo.credit > dh->rateinfo.credit_cap)
2496 + dh->rateinfo.credit = dh->rateinfo.credit_cap;
2500 +dstlimit_match(const struct sk_buff *skb,
2501 + const struct net_device *in,
2502 + const struct net_device *out,
2503 + const void *matchinfo,
2506 + u_int16_t datalen,
2509 + struct ipt_dstlimit_info *r =
2510 + ((struct ipt_dstlimit_info *)matchinfo)->u.master;
2511 + unsigned long now = jiffies;
2512 + struct dsthash_ent *dh;
2513 + struct dsthash_dst dst;
2515 + memset(&dst, 0, sizeof(dst));
2517 + /* dest ip is always in hash */
2518 + dst.dst_ip = skb->nh.iph->daddr;
2520 + /* source ip only if respective hashmode, otherwise set to
2522 + if (r->mode & IPT_DSTLIMIT_HASH_SIP)
2523 + dst.src_ip = skb->nh.iph->saddr;
2525 + /* dest port only if respective mode */
2526 + if (r->mode & IPT_DSTLIMIT_HASH_DPT) {
2527 + switch (skb->nh.iph->protocol) {
2528 + struct tcphdr *th;
2529 + struct udphdr *uh;
2531 + th = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
2532 + dst.port = th->dest;
2535 + uh = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
2536 + dst.port = uh->dest;
2543 + LOCK_BH(&r->hinfo->lock);
2544 + dh = __dsthash_find(r->hinfo, &dst);
2546 + dh = __dsthash_alloc_init(r->hinfo, &dst);
2549 + /* enomem... don't match == DROP */
2550 + if (net_ratelimit())
2551 + printk("%s: ENOMEM\n", __FUNCTION__);
2552 + UNLOCK_BH(&r->hinfo->lock);
2556 + dh->expires = jiffies + MS2JIFFIES(r->expire);
2558 + dh->rateinfo.prev = jiffies;
2559 + dh->rateinfo.credit = user2credits(r->avg * r->burst);
2560 + dh->rateinfo.credit_cap = user2credits(r->avg * r->burst);
2561 + dh->rateinfo.cost = user2credits(r->avg);
2563 + UNLOCK_BH(&r->hinfo->lock);
2567 + /* update expiration timeout */
2568 + dh->expires = now + MS2JIFFIES(r->expire);
2570 + rateinfo_recalc(dh, now);
2571 + if (dh->rateinfo.credit >= dh->rateinfo.cost) {
2572 + /* We're underlimit. */
2573 + dh->rateinfo.credit -= dh->rateinfo.cost;
2574 + UNLOCK_BH(&r->hinfo->lock);
2578 + UNLOCK_BH(&r->hinfo->lock);
2580 + /* default case: we're overlimit, thus don't match */
2585 +dstlimit_checkentry(const char *tablename,
2586 + const struct ipt_ip *ip,
2588 + unsigned int matchsize,
2589 + unsigned int hook_mask)
2591 + struct ipt_dstlimit_info *r = matchinfo;
2593 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_dstlimit_info)))
2596 + /* Check for overflow. */
2598 + || user2credits(r->avg * r->burst) < user2credits(r->avg)) {
2599 + printk("Overflow in ipt_dstlimit, try lower: %u/%u\n",
2600 + r->avg, r->burst);
2605 + || r->mode > (IPT_DSTLIMIT_HASH_DPT
2606 + |IPT_DSTLIMIT_HASH_DIP
2607 + |IPT_DSTLIMIT_HASH_SIP))
2610 + if (!r->gc_interval)
2616 + if (htable_create(r) != 0) {
2617 + printk("Unable to create dstlimit htable\n");
2621 + /* Ugly hack: For SMP, we only want to use one set */
2628 +dstlimit_destroy(void *matchinfo, unsigned int matchsize)
2630 + struct ipt_dstlimit_info *r = (struct ipt_dstlimit_info *) matchinfo;
2634 + /* remove timer, if it is pending */
2635 + if (timer_pending(&r->hinfo->timer))
2636 + del_timer(&r->hinfo->timer);
2638 + /* remove proc entry */
2639 + remove_proc_entry(r->name, dstlimit_procdir);
2641 + htable_selective_cleanup(r->hinfo, select_all);
2645 +static struct ipt_match ipt_dstlimit = {
2646 + .list = { .prev = NULL, .next = NULL },
2647 + .name = "dstlimit",
2648 + .match = dstlimit_match,
2649 + .checkentry = dstlimit_checkentry,
2650 + .destroy = dstlimit_destroy,
2656 +static void *dl_seq_start(struct seq_file *s, loff_t *pos)
2658 + struct proc_dir_entry *pde = s->private;
2659 + struct ipt_dstlimit_htable *htable = pde->data;
2660 + unsigned int *bucket;
2662 + LOCK_BH(&htable->lock);
2663 + if (*pos >= htable->minfo->size)
2666 + bucket = kmalloc(sizeof(unsigned int), GFP_KERNEL);
2668 + return ERR_PTR(-ENOMEM);
2674 +static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
2676 + struct proc_dir_entry *pde = s->private;
2677 + struct ipt_dstlimit_htable *htable = pde->data;
2678 + unsigned int *bucket = (unsigned int *)v;
2680 + *pos = ++(*bucket);
2681 + if (*pos >= htable->minfo->size) {
2688 +static void dl_seq_stop(struct seq_file *s, void *v)
2690 + struct proc_dir_entry *pde = s->private;
2691 + struct ipt_dstlimit_htable *htable = pde->data;
2693 + UNLOCK_BH(&htable->lock);
2696 +static inline int dl_seq_real_show(struct dsthash_ent *ent, struct seq_file *s)
2698 + /* recalculate to show accurate numbers */
2699 + rateinfo_recalc(ent, jiffies);
2701 + return seq_printf(s, "%ld %u.%u.%u.%u->%u.%u.%u.%u:%u %u %u %u\n",
2702 + (ent->expires - jiffies)/HZ,
2703 + NIPQUAD(ent->dst.src_ip),
2704 + NIPQUAD(ent->dst.dst_ip), ntohs(ent->dst.port),
2705 + ent->rateinfo.credit, ent->rateinfo.credit_cap,
2706 + ent->rateinfo.cost);
2709 +static int dl_seq_show(struct seq_file *s, void *v)
2711 + struct proc_dir_entry *pde = s->private;
2712 + struct ipt_dstlimit_htable *htable = pde->data;
2713 + unsigned int *bucket = (unsigned int *)v;
2715 + if (LIST_FIND_W(&htable->hash[*bucket], dl_seq_real_show,
2716 + struct dsthash_ent *, s)) {
2717 + /* buffer was filled and unable to print that tuple */
2723 +static struct seq_operations dl_seq_ops = {
2724 + .start = dl_seq_start,
2725 + .next = dl_seq_next,
2726 + .stop = dl_seq_stop,
2727 + .show = dl_seq_show
2730 +static int dl_proc_open(struct inode *inode, struct file *file)
2732 + int ret = seq_open(file, &dl_seq_ops);
2735 + struct seq_file *sf = file->private_data;
2736 + sf->private = PDE(inode);
2741 +static struct file_operations dl_file_ops = {
2742 + .owner = THIS_MODULE,
2743 + .open = dl_proc_open,
2745 + .llseek = seq_lseek,
2746 + .release = seq_release
2749 +static int init_or_fini(int fini)
2756 + if (ipt_register_match(&ipt_dstlimit)) {
2758 + goto cleanup_nothing;
2761 + /* FIXME: do we really want HWCACHE_ALIGN since our objects are
2762 + * quite small ? */
2763 + dstlimit_cachep = kmem_cache_create("ipt_dstlimit",
2764 + sizeof(struct dsthash_ent), 0,
2765 + SLAB_HWCACHE_ALIGN, NULL, NULL);
2766 + if (!dstlimit_cachep) {
2767 + printk(KERN_ERR "Unable to create ipt_dstlimit slab cache\n");
2769 + goto cleanup_unreg_match;
2772 + dstlimit_procdir = proc_mkdir("ipt_dstlimit", proc_net);
2773 + if (!dstlimit_procdir) {
2774 + printk(KERN_ERR "Unable to create proc dir entry\n");
2776 + goto cleanup_free_slab;
2782 + remove_proc_entry("ipt_dstlimit", proc_net);
2784 + kmem_cache_destroy(dstlimit_cachep);
2785 +cleanup_unreg_match:
2786 + ipt_unregister_match(&ipt_dstlimit);
2792 +static int __init init(void)
2794 + return init_or_fini(0);
2797 +static void __exit fini(void)
2804 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_fuzzy.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_fuzzy.c
2805 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_fuzzy.c 1970-01-01 01:00:00.000000000 +0100
2806 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_fuzzy.c 2004-02-16 11:07:14.925382080 +0100
2809 + * This module implements a simple TSK FLC
2810 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
2811 + * to limit , in an adaptive and flexible way , the packet rate crossing
2812 + * a given stream . It serves as an initial and very simple (but effective)
2813 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
2814 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
2815 + * into our code in a precise , adaptive and efficient manner.
2816 + * The goal is very similar to that of "limit" match , but using techniques of
2817 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
2818 + * avoiding over and undershoots - and stuff like that .
2821 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
2822 + * 2002-08-17 : Changed to eliminate floating point operations .
2823 + * 2002-08-23 : Coding style changes .
2826 +#include <linux/module.h>
2827 +#include <linux/skbuff.h>
2828 +#include <linux/ip.h>
2829 +#include <linux/random.h>
2830 +#include <net/tcp.h>
2831 +#include <linux/spinlock.h>
2832 +#include <linux/netfilter_ipv4/ip_tables.h>
2833 +#include <linux/netfilter_ipv4/ipt_fuzzy.h>
2836 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
2837 + Expressed in percentage
2840 +#define PAR_LOW 1/100
2843 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED ;
2845 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
2846 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
2847 +MODULE_LICENSE("GPL");
2849 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
2851 + if (tx >= maxi) return 100;
2853 + if (tx <= mini) return 0;
2855 + return ( (100*(tx-mini)) / (maxi-mini) ) ;
2858 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
2860 + if (tx <= mini) return 100;
2862 + if (tx >= maxi) return 0;
2864 + return ( (100*( maxi - tx )) / ( maxi - mini ) ) ;
2869 +ipt_fuzzy_match(const struct sk_buff *pskb,
2870 + const struct net_device *in,
2871 + const struct net_device *out,
2872 + const void *matchinfo,
2875 + u_int16_t datalen,
2878 + /* From userspace */
2880 + struct ipt_fuzzy_info *info = (struct ipt_fuzzy_info *) matchinfo;
2882 + u_int8_t random_number;
2883 + unsigned long amount ;
2884 + u_int8_t howhigh , howlow ;
2887 + spin_lock_bh(&fuzzy_lock) ; /* Rise the lock */
2889 + info->bytes_total += pskb->len ;
2890 + info->packets_total++ ;
2892 + info->present_time = jiffies ;
2894 + if ( info->present_time >= info->previous_time )
2895 + amount = info->present_time - info->previous_time ;
2897 + /* There was a transition : I choose to re-sample
2898 + and keep the old acceptance rate...
2902 + info->previous_time = info->present_time ;
2903 + info->bytes_total = info->packets_total = 0;
2906 + if ( amount > HZ/10 ) /* More than 100 ms elapsed ... */
2909 + info->mean_rate = (u_int32_t) ( ( HZ * info->packets_total ) \
2912 + info->previous_time = info->present_time ;
2913 + info->bytes_total = info->packets_total = 0 ;
2915 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
2916 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
2918 + info->acceptance_rate = (u_int8_t) \
2919 + ( howhigh*PAR_LOW + PAR_HIGH*howlow ) ;
2921 + /* In fact , the above defuzzification would require a denominator
2922 + proportional to (howhigh+howlow) but , in this particular case ,
2923 + that expression is constant .
2924 + An imediate consequence is that it isn't necessary to call
2925 + both mf_high and mf_low - but to keep things understandable ,
2931 + spin_unlock_bh(&fuzzy_lock) ; /* Release the lock */
2934 + if ( info->acceptance_rate < 100 )
2936 + get_random_bytes((void *)(&random_number), 1);
2938 + /* If within the acceptance , it can pass => don't match */
2939 + if ( random_number <= (255 * info->acceptance_rate) / 100 )
2942 + return 1; /* It can't pass ( It matches ) */
2945 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
2950 +ipt_fuzzy_checkentry(const char *tablename,
2951 + const struct ipt_ip *e,
2953 + unsigned int matchsize,
2954 + unsigned int hook_mask)
2957 + const struct ipt_fuzzy_info *info = matchinfo;
2959 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_fuzzy_info))) {
2960 + printk("ipt_fuzzy: matchsize %u != %u\n", matchsize,
2961 + IPT_ALIGN(sizeof(struct ipt_fuzzy_info)));
2965 +if ((info->minimum_rate < MINFUZZYRATE ) || (info->maximum_rate > MAXFUZZYRATE)
2966 + || (info->minimum_rate >= info->maximum_rate ))
2968 + printk("ipt_fuzzy: BAD limits , please verify !!!\n");
2975 +static struct ipt_match ipt_fuzzy_reg = {
2979 + ipt_fuzzy_checkentry,
2983 +static int __init init(void)
2985 + if (ipt_register_match(&ipt_fuzzy_reg))
2991 +static void __exit fini(void)
2993 + ipt_unregister_match(&ipt_fuzzy_reg);
2998 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_ipv4options.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_ipv4options.c
2999 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_ipv4options.c 1970-01-01 01:00:00.000000000 +0100
3000 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_ipv4options.c 2004-02-16 11:07:16.165085194 +0100
3003 + This is a module which is used to match ipv4 options.
3004 + This file is distributed under the terms of the GNU General Public
3005 + License (GPL). Copies of the GPL can be obtained from:
3006 + ftp://prep.ai.mit.edu/pub/gnu/GPL
3008 + 11-mars-2001 Fabrice MARIE <fabrice@netfilter.org> : initial development.
3009 + 12-july-2001 Fabrice MARIE <fabrice@netfilter.org> : added router-alert otions matching. Fixed a bug with no-srr
3010 + 12-august-2001 Imran Patel <ipatel@crosswinds.net> : optimization of the match.
3011 + 18-november-2001 Fabrice MARIE <fabrice@netfilter.org> : added [!] 'any' option match.
3014 +#include <linux/module.h>
3015 +#include <linux/skbuff.h>
3016 +#include <net/ip.h>
3018 +#include <linux/netfilter_ipv4/ip_tables.h>
3019 +#include <linux/netfilter_ipv4/ipt_ipv4options.h>
3021 +MODULE_LICENSE("GPL");
3024 +match(const struct sk_buff *skb,
3025 + const struct net_device *in,
3026 + const struct net_device *out,
3027 + const void *matchinfo,
3030 + u_int16_t datalen,
3033 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
3034 + const struct iphdr *iph = skb->nh.iph;
3035 + const struct ip_options *opt;
3037 + if (iph->ihl * 4 == sizeof(struct iphdr)) {
3038 + /* No options, so we match only the "DONTs" and the "IGNOREs" */
3040 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) ||
3041 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3042 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
3043 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
3044 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
3045 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
3050 + if ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)
3051 + /* there are options, and we don't need to care which one */
3054 + if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
3055 + /* there are options but we don't want any ! */
3060 + opt = &(IPCB(skb)->opt);
3062 + /* source routing */
3063 + if ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) {
3064 + if (!((opt->srr) & (opt->is_strictroute)))
3067 + else if ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) {
3068 + if (!((opt->srr) & (!opt->is_strictroute)))
3071 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) {
3075 + /* record route */
3076 + if ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) {
3080 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) {
3085 + if ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) {
3089 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) {
3093 + /* router-alert option */
3094 + if ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) {
3095 + if (!opt->router_alert)
3098 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) {
3099 + if (opt->router_alert)
3108 +checkentry(const char *tablename,
3109 + const struct ipt_ip *ip,
3111 + unsigned int matchsize,
3112 + unsigned int hook_mask)
3114 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
3115 + /* Check the size */
3116 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_ipv4options_info)))
3118 + /* Now check the coherence of the data ... */
3119 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) &&
3120 + (((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) ||
3121 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) ||
3122 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) ||
3123 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) ||
3124 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)))
3125 + return 0; /* opposites */
3126 + if (((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) &&
3127 + (((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
3128 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3129 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
3130 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
3131 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) ||
3132 + ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)))
3133 + return 0; /* opposites */
3134 + if (((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) &&
3135 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR))
3136 + return 0; /* cannot match in the same time loose and strict source routing */
3137 + if ((((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3138 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR)) &&
3139 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR))
3140 + return 0; /* opposites */
3141 + if (((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) &&
3142 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR))
3143 + return 0; /* opposites */
3144 + if (((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) &&
3145 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
3146 + return 0; /* opposites */
3147 + if (((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) &&
3148 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
3149 + return 0; /* opposites */
3151 + /* everything looks ok. */
3155 +static struct ipt_match ipv4options_match
3156 += { { NULL, NULL }, "ipv4options", &match, &checkentry, NULL, THIS_MODULE };
3158 +static int __init init(void)
3160 + printk("ipt_ipv4options loading\n");
3161 + return ipt_register_match(&ipv4options_match);
3164 +static void __exit fini(void)
3166 + ipt_unregister_match(&ipv4options_match);
3167 + printk("ipt_ipv4options unloaded\n");
3172 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_mport.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_mport.c
3173 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_mport.c 1970-01-01 01:00:00.000000000 +0100
3174 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_mport.c 2004-02-16 11:07:17.665725817 +0100
3176 +/* Kernel module to match one of a list of TCP/UDP ports: ports are in
3177 + the same place so we can treat them as equal. */
3178 +#include <linux/module.h>
3179 +#include <linux/types.h>
3180 +#include <linux/udp.h>
3181 +#include <linux/skbuff.h>
3183 +#include <linux/netfilter_ipv4/ipt_mport.h>
3184 +#include <linux/netfilter_ipv4/ip_tables.h>
3186 +MODULE_LICENSE("GPL");
3189 +#define duprintf(format, args...) printk(format , ## args)
3191 +#define duprintf(format, args...)
3194 +/* Returns 1 if the port is matched by the test, 0 otherwise. */
3196 +ports_match(const struct ipt_mport *minfo, u_int16_t src, u_int16_t dst)
3200 + u_int16_t pflags = minfo->pflags;
3201 + for (i=0, m=1; i<IPT_MULTI_PORTS; i++, m<<=1) {
3205 + && minfo->ports[i] == 65535)
3208 + s = minfo->ports[i];
3211 + e = minfo->ports[++i];
3216 + if (minfo->flags & IPT_MPORT_SOURCE
3217 + && src >= s && src <= e)
3220 + if (minfo->flags & IPT_MPORT_DESTINATION
3221 + && dst >= s && dst <= e)
3229 +match(const struct sk_buff *skb,
3230 + const struct net_device *in,
3231 + const struct net_device *out,
3232 + const void *matchinfo,
3235 + u_int16_t datalen,
3238 + const struct udphdr *udp = hdr;
3239 + const struct ipt_mport *minfo = matchinfo;
3241 + /* Must be big enough to read ports. */
3242 + if (offset == 0 && datalen < sizeof(struct udphdr)) {
3243 + /* We've been asked to examine this packet, and we
3244 + can't. Hence, no choice but to drop. */
3245 + duprintf("ipt_mport:"
3246 + " Dropping evil offset=0 tinygram.\n");
3251 + /* Must not be a fragment. */
3253 + && ports_match(minfo, ntohs(udp->source), ntohs(udp->dest));
3256 +/* Called when user tries to insert an entry of this type. */
3258 +checkentry(const char *tablename,
3259 + const struct ipt_ip *ip,
3261 + unsigned int matchsize,
3262 + unsigned int hook_mask)
3264 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_mport)))
3267 + /* Must specify proto == TCP/UDP, no unknown flags or bad count */
3268 + return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
3269 + && !(ip->invflags & IPT_INV_PROTO)
3270 + && matchsize == IPT_ALIGN(sizeof(struct ipt_mport));
3273 +static struct ipt_match mport_match
3274 += { { NULL, NULL }, "mport", &match, &checkentry, NULL, THIS_MODULE };
3276 +static int __init init(void)
3278 + return ipt_register_match(&mport_match);
3281 +static void __exit fini(void)
3283 + ipt_unregister_match(&mport_match);
3288 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_nth.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_nth.c
3289 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_nth.c 1970-01-01 01:00:00.000000000 +0100
3290 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_nth.c 2004-02-16 11:07:18.803453352 +0100
3293 + This is a module which is used for match support for every Nth packet
3294 + This file is distributed under the terms of the GNU General Public
3295 + License (GPL). Copies of the GPL can be obtained from:
3296 + ftp://prep.ai.mit.edu/pub/gnu/GPL
3298 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
3299 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
3300 + * added support for multiple counters
3301 + * added support for matching on individual packets
3302 + in the counter cycle
3306 +#include <linux/module.h>
3307 +#include <linux/skbuff.h>
3308 +#include <linux/ip.h>
3309 +#include <net/tcp.h>
3310 +#include <linux/spinlock.h>
3311 +#include <linux/netfilter_ipv4/ip_tables.h>
3312 +#include <linux/netfilter_ipv4/ipt_nth.h>
3314 +MODULE_LICENSE("GPL");
3317 + * State information.
3324 +static struct state states[IPT_NTH_NUM_COUNTERS];
3327 +ipt_nth_match(const struct sk_buff *pskb,
3328 + const struct net_device *in,
3329 + const struct net_device *out,
3330 + const void *matchinfo,
3333 + u_int16_t datalen,
3336 + /* Parameters from userspace */
3337 + const struct ipt_nth_info *info = matchinfo;
3338 + unsigned counter = info->counter;
3339 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
3341 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
3345 + spin_lock(&states[counter].lock);
3347 + /* Are we matching every nth packet?*/
3348 + if (info->packet == 0xFF)
3350 + /* We're matching every nth packet and only every nth packet*/
3351 + /* Do we match or invert match? */
3352 + if (info->not == 0)
3354 + if (states[counter].number == 0)
3356 + ++states[counter].number;
3359 + if (states[counter].number >= info->every)
3360 + states[counter].number = 0; /* reset the counter */
3362 + ++states[counter].number;
3367 + if (states[counter].number == 0)
3369 + ++states[counter].number;
3372 + if (states[counter].number >= info->every)
3373 + states[counter].number = 0;
3375 + ++states[counter].number;
3381 + /* We're using the --packet, so there must be a rule for every value */
3382 + if (states[counter].number == info->packet)
3384 + /* only increment the counter when a match happens */
3385 + if (states[counter].number >= info->every)
3386 + states[counter].number = 0; /* reset the counter */
3388 + ++states[counter].number;
3397 + spin_unlock(&states[counter].lock);
3401 + spin_unlock(&states[counter].lock);
3406 +ipt_nth_checkentry(const char *tablename,
3407 + const struct ipt_ip *e,
3409 + unsigned int matchsize,
3410 + unsigned int hook_mask)
3412 + /* Parameters from userspace */
3413 + const struct ipt_nth_info *info = matchinfo;
3414 + unsigned counter = info->counter;
3415 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
3417 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
3421 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_nth_info))) {
3422 + printk("nth: matchsize %u != %u\n", matchsize,
3423 + IPT_ALIGN(sizeof(struct ipt_nth_info)));
3427 + states[counter].number = info->startat;
3432 +static struct ipt_match ipt_nth_reg = {
3436 + ipt_nth_checkentry,
3440 +static int __init init(void)
3443 + memset(&states, 0, sizeof(states));
3444 + if (ipt_register_match(&ipt_nth_reg))
3447 + for(counter = 0; counter < IPT_NTH_NUM_COUNTERS; counter++)
3449 + spin_lock_init(&(states[counter].lock));
3452 + printk("ipt_nth match loaded\n");
3456 +static void __exit fini(void)
3458 + ipt_unregister_match(&ipt_nth_reg);
3459 + printk("ipt_nth match unloaded\n");
3464 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_osf.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_osf.c
3465 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_osf.c 1970-01-01 01:00:00.000000000 +0100
3466 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_osf.c 2004-02-16 11:07:19.917186632 +0100
3471 + * Copyright (c) 2003 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
3474 + * This program is free software; you can redistribute it and/or modify
3475 + * it under the terms of the GNU General Public License as published by
3476 + * the Free Software Foundation; either version 2 of the License, or
3477 + * (at your option) any later version.
3479 + * This program is distributed in the hope that it will be useful,
3480 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3481 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3482 + * GNU General Public License for more details.
3484 + * You should have received a copy of the GNU General Public License
3485 + * along with this program; if not, write to the Free Software
3486 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3490 + * OS fingerprint matching module.
3491 + * It simply compares various parameters from SYN packet with
3492 + * some hardcoded ones.
3494 + * Original table was created by Michal Zalewski <lcamtuf@coredump.cx>
3498 +#include <linux/config.h>
3499 +#include <linux/kernel.h>
3500 +#include <linux/smp.h>
3501 +#include <linux/module.h>
3502 +#include <linux/skbuff.h>
3503 +#include <linux/file.h>
3504 +#include <linux/ip.h>
3505 +#include <linux/proc_fs.h>
3506 +#include <linux/fs.h>
3507 +#include <linux/slab.h>
3508 +#include <linux/spinlock.h>
3509 +#include <linux/ctype.h>
3510 +#include <linux/list.h>
3512 +#include <net/sock.h>
3513 +#include <net/ip.h>
3515 +#include <linux/netfilter_ipv4/ip_tables.h>
3517 +#include <linux/netfilter_ipv4/ipt_osf.h>
3522 +#define log(x...) printk(KERN_INFO "ipt_osf: " x)
3523 +#define loga(x...) printk(x)
3525 +#define log(x...) do {} while(0)
3526 +#define loga(x...) do {} while(0)
3529 +#define FMATCH_WRONG 0
3530 +#define FMATCH_OK 1
3531 +#define FMATCH_OPT_WRONG 2
3534 +#define OSFPDEL ':'
3535 +#define MAXOPTSTRLEN 128
3536 +#define OSFFLUSH "FLUSH"
3538 +static rwlock_t osf_lock = RW_LOCK_UNLOCKED;
3539 +static struct list_head finger_list;
3541 +static int match(const struct sk_buff *, const struct net_device *, const struct net_device *,
3542 + const void *, int, const void *, u_int16_t, int *);
3543 +static int checkentry(const char *, const struct ipt_ip *, void *,
3544 + unsigned int, unsigned int);
3546 +static struct ipt_match osf_match =
3556 +static inline int smart_dec(unsigned long flags, unsigned char ip_ttl, unsigned char f_ttl)
3558 + if (flags & IPT_OSF_SMART)
3561 + return (ip_ttl == f_ttl);
3565 +match(const struct sk_buff *skb,
3566 + const struct net_device *in,
3567 + const struct net_device *out,
3568 + const void *matchinfo,
3571 + u_int16_t datalen,
3574 + struct ipt_osf_info *info = (struct ipt_osf_info *)matchinfo;
3575 + struct iphdr *ip = skb->nh.iph;
3576 + struct tcphdr *tcp;
3577 + int fmatch = FMATCH_WRONG, fcount = 0;
3578 + unsigned long totlen, optsize = 0, window;
3579 + unsigned char df, *optp = NULL, *_optp = NULL;
3580 + char check_WSS = 0;
3581 + struct list_head *ent;
3582 + struct osf_finger *f;
3587 + tcp = (struct tcphdr *)((u_int32_t *)ip + ip->ihl);
3591 + else if (tcp->ack)
3594 + totlen = ntohs(ip->tot_len);
3595 + df = ((ntohs(ip->frag_off) & IP_DF)?1:0);
3596 + window = ntohs(tcp->window);
3598 + if (tcp->doff*4 > sizeof(struct tcphdr))
3600 + _optp = optp = (char *)(tcp+1);
3601 + optsize = tcp->doff*4 - sizeof(struct tcphdr);
3605 + /* Actually we can create hash/table of all genres and search
3606 + * only in appropriate part, but here is initial variant,
3607 + * so will use slow path.
3609 + read_lock(&osf_lock);
3610 + list_for_each(ent, &finger_list)
3612 + f = list_entry(ent, struct osf_finger, flist);
3614 + if (!(info->flags & IPT_OSF_LOG) && strcmp(info->genre, f->genre))
3618 + fmatch = FMATCH_WRONG;
3620 + if (totlen == f->ss && df == f->df &&
3621 + smart_dec(info->flags, ip->ttl, f->ttl))
3623 + unsigned long foptsize;
3625 + unsigned short mss = 0;
3629 + switch (f->wss.wc)
3631 + case 0: check_WSS = 0; break;
3632 + case 'S': check_WSS = 1; break;
3633 + case 'T': check_WSS = 2; break;
3634 + case '%': check_WSS = 3; break;
3635 + default: log("Wrong fingerprint wss.wc=%d, %s - %s\n",
3636 + f->wss.wc, f->genre, f->details);
3640 + if (check_WSS == 4)
3643 + /* Check options */
3646 + for (optnum=0; optnum<f->opt_num; ++optnum)
3647 + foptsize += f->opt[optnum].length;
3650 + if (foptsize > MAX_IPOPTLEN || optsize > MAX_IPOPTLEN || optsize != foptsize)
3655 + fmatch = FMATCH_OK;
3656 + loga("\tYEP : matching without options.\n");
3657 + if ((info->flags & IPT_OSF_LOG) &&
3658 + info->loglevel == IPT_OSF_LOGLEVEL_FIRST)
3665 + for (optnum=0; optnum<f->opt_num; ++optnum)
3667 + if (f->opt[optnum].kind == (*optp))
3669 + unsigned char len = f->opt[optnum].length;
3670 + unsigned char *optend = optp + len;
3672 + fmatch = FMATCH_OK;
3674 + if (*optp == OSFOPT_MSS) /* MSS */
3675 + mss = ntohs(*(unsigned short *)(optp+2));
3679 + /* Skip kind and length fields*/
3682 + if (f->opt[optnum].wc.wc != 0)
3684 + unsigned long tmp = 0;
3686 + /* Hmmm... It looks a bit ugly. :) */
3687 + memcpy(&tmp, &f->opt[optnum].wc.val,
3688 + (len > sizeof(unsigned long)?
3689 + sizeof(unsigned long):len));
3692 + if (tmp != f->opt[optnum].wc.val)
3693 + fmatch = FMATCH_OPT_WRONG;
3700 + fmatch = FMATCH_OPT_WRONG;
3702 + if (fmatch != FMATCH_OK)
3706 + if (fmatch != FMATCH_OPT_WRONG)
3708 + fmatch = FMATCH_WRONG;
3710 + switch (check_WSS)
3713 + if (window == f->wss.val)
3714 + fmatch = FMATCH_OK;
3717 + if (window == f->wss.val*mss)
3718 + fmatch = FMATCH_OK;
3721 + if (window == f->wss.val*(mss+40))
3722 + fmatch = FMATCH_OK;
3725 + if (window % f->wss.val == 0)
3726 + fmatch = FMATCH_OK;
3732 + if (fmatch == FMATCH_OK)
3735 + log("%s [%s]: %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n",
3736 + f->genre, f->details,
3737 + NIPQUAD(ip->saddr), ntohs(tcp->source),
3738 + NIPQUAD(ip->daddr), ntohs(tcp->dest));
3739 + if ((info->flags & IPT_OSF_LOG) &&
3740 + info->loglevel == IPT_OSF_LOGLEVEL_FIRST)
3745 + if (!fcount && (info->flags & IPT_OSF_LOG))
3747 + log("Unknown: %lu:%d:%d:%lu:", window, ip->ttl, df, totlen);
3750 + unsigned char opt[4 * 15 - sizeof(struct tcphdr)];
3751 + unsigned int i, optsize;
3753 + optsize = tcp->doff * 4 - sizeof(struct tcphdr);
3754 + if (skb_copy_bits(skb, ip->ihl*4 + sizeof(struct tcphdr),
3755 + opt, optsize) < 0)
3756 + loga("TRUNCATED");
3758 + for (i = 0; i < optsize; i++)
3759 + loga("%02X", opt[i]);
3762 + loga(" %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n",
3763 + NIPQUAD(ip->saddr), ntohs(tcp->source),
3764 + NIPQUAD(ip->daddr), ntohs(tcp->dest));
3766 + read_unlock(&osf_lock);
3768 + return (fmatch == FMATCH_OK)?1:0;
3772 +checkentry(const char *tablename,
3773 + const struct ipt_ip *ip,
3775 + unsigned int matchsize,
3776 + unsigned int hook_mask)
3778 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_osf_info)))
3780 + if (ip->proto != IPPROTO_TCP)
3786 +static char * osf_strchr(char *ptr, char c)
3790 + tmp = strchr(ptr, c);
3792 + while (tmp && tmp+1 && isspace(*(tmp+1)))
3798 +static struct osf_finger * finger_alloc(void)
3800 + struct osf_finger *f;
3802 + f = kmalloc(sizeof(struct osf_finger), GFP_KERNEL);
3804 + memset(f, 0, sizeof(struct osf_finger));
3809 +static void finger_free(struct osf_finger *f)
3811 + memset(f, 0, sizeof(struct osf_finger));
3816 +static void osf_parse_opt(struct osf_opt *opt, int *optnum, char *obuf, int olen)
3820 + unsigned long val;
3824 + while (ptr != NULL && i < olen)
3833 + ptr = osf_strchr(&obuf[i], OPTDEL);
3838 + i += (int)(ptr-&obuf[i]);
3845 + op = OSFOPT_SACKP;
3846 + ptr = osf_strchr(&obuf[i], OPTDEL);
3851 + i += (int)(ptr-&obuf[i]);
3859 + ptr = osf_strchr(&obuf[i], OPTDEL);
3864 + i += (int)(ptr-&obuf[i]);
3872 + ptr = osf_strchr(&obuf[i], OPTDEL);
3875 + switch (obuf[i+1])
3877 + case '%': wc = '%'; break;
3878 + case 'S': wc = 'S'; break;
3879 + case 'T': wc = 'T'; break;
3880 + default: wc = 0; break;
3886 + val = simple_strtoul(&obuf[i+2], NULL, 10);
3888 + val = simple_strtoul(&obuf[i+1], NULL, 10);
3889 + i += (int)(ptr-&obuf[i]);
3897 + ptr = osf_strchr(&obuf[i], OPTDEL);
3900 + if (obuf[i+1] == '%')
3905 + val = simple_strtoul(&obuf[i+2], NULL, 10);
3907 + val = simple_strtoul(&obuf[i+1], NULL, 10);
3908 + i += (int)(ptr-&obuf[i]);
3916 + ptr = osf_strchr(&obuf[i], OPTDEL);
3921 + i += (int)(ptr-&obuf[i]);
3928 + ptr = osf_strchr(&obuf[i], OPTDEL);
3932 + i += (int)(ptr-&obuf[i]);
3940 + opt[*optnum].kind = IANA_opts[op].kind;
3941 + opt[*optnum].length = IANA_opts[op].length;
3942 + opt[*optnum].wc.wc = wc;
3943 + opt[*optnum].wc.val = val;
3949 +static int osf_proc_read(char *buf, char **start, off_t off, int count, int *eof, void *data)
3951 + struct list_head *ent;
3952 + struct osf_finger *f = NULL;
3958 + read_lock_bh(&osf_lock);
3959 + list_for_each(ent, &finger_list)
3961 + f = list_entry(ent, struct osf_finger, flist);
3963 + log("%s [%s]", f->genre, f->details);
3965 + count += sprintf(buf+count, "%s - %s[%s] : %s",
3966 + f->genre, f->version,
3967 + f->subtype, f->details);
3972 + //count += sprintf(buf+count, " OPT: ");
3973 + for (i=0; i<f->opt_num; ++i)
3975 + //count += sprintf(buf+count, "%d.%c%lu; ",
3976 + // f->opt[i].kind, (f->opt[i].wc.wc)?f->opt[i].wc.wc:' ', f->opt[i].wc.val);
3977 + loga("%d.%c%lu; ",
3978 + f->opt[i].kind, (f->opt[i].wc.wc)?f->opt[i].wc.wc:' ', f->opt[i].wc.val);
3982 + count += sprintf(buf+count, "\n");
3984 + read_unlock_bh(&osf_lock);
3989 +static int osf_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
3993 + char obuf[MAXOPTSTRLEN];
3994 + struct osf_finger *finger;
3995 + struct list_head *ent, *n;
3997 + char *pbeg, *pend;
3999 + if (count == strlen(OSFFLUSH) && !strncmp(buffer, OSFFLUSH, strlen(OSFFLUSH)))
4002 + write_lock_bh(&osf_lock);
4003 + list_for_each_safe(ent, n, &finger_list)
4006 + finger = list_entry(ent, struct osf_finger, flist);
4007 + list_del(&finger->flist);
4008 + finger_free(finger);
4010 + write_unlock_bh(&osf_lock);
4012 + log("Flushed %d entries.\n", i);
4019 + for (i=0; i<count && buffer[i] != '\0'; ++i)
4020 + if (buffer[i] == ':')
4023 + if (cnt != 8 || i != count)
4025 + log("Wrong input line cnt=%d[8], len=%lu[%lu]\n",
4030 + memset(obuf, 0, sizeof(obuf));
4032 + finger = finger_alloc();
4035 + log("Failed to allocate new fingerprint entry.\n");
4039 + pbeg = (char *)buffer;
4040 + pend = osf_strchr(pbeg, OSFPDEL);
4044 + if (pbeg[0] == 'S')
4046 + finger->wss.wc = 'S';
4047 + if (pbeg[1] == '%')
4048 + finger->wss.val = simple_strtoul(pbeg+2, NULL, 10);
4049 + else if (pbeg[1] == '*')
4050 + finger->wss.val = 0;
4052 + finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
4054 + else if (pbeg[0] == 'T')
4056 + finger->wss.wc = 'T';
4057 + if (pbeg[1] == '%')
4058 + finger->wss.val = simple_strtoul(pbeg+2, NULL, 10);
4059 + else if (pbeg[1] == '*')
4060 + finger->wss.val = 0;
4062 + finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
4064 + if (isdigit(pbeg[0]))
4066 + finger->wss.wc = 0;
4067 + finger->wss.val = simple_strtoul(pbeg, NULL, 10);
4072 + pend = osf_strchr(pbeg, OSFPDEL);
4076 + finger->ttl = simple_strtoul(pbeg, NULL, 10);
4079 + pend = osf_strchr(pbeg, OSFPDEL);
4083 + finger->df = simple_strtoul(pbeg, NULL, 10);
4086 + pend = osf_strchr(pbeg, OSFPDEL);
4090 + finger->ss = simple_strtoul(pbeg, NULL, 10);
4094 + pend = osf_strchr(pbeg, OSFPDEL);
4098 + cnt = snprintf(obuf, sizeof(obuf), "%s", pbeg);
4102 + pend = osf_strchr(pbeg, OSFPDEL);
4106 + if (pbeg[0] == '@' || pbeg[0] == '*')
4107 + cnt = snprintf(finger->genre, sizeof(finger->genre), "%s", pbeg+1);
4109 + cnt = snprintf(finger->genre, sizeof(finger->genre), "%s", pbeg);
4113 + pend = osf_strchr(pbeg, OSFPDEL);
4117 + cnt = snprintf(finger->version, sizeof(finger->version), "%s", pbeg);
4121 + pend = osf_strchr(pbeg, OSFPDEL);
4125 + cnt = snprintf(finger->subtype, sizeof(finger->subtype), "%s", pbeg);
4129 + cnt = snprintf(finger->details,
4130 + ((count - (pbeg - buffer)+1) > MAXDETLEN)?MAXDETLEN:(count - (pbeg - buffer)+1),
4133 + log("%s - %s[%s] : %s\n",
4134 + finger->genre, finger->version,
4135 + finger->subtype, finger->details);
4137 + osf_parse_opt(finger->opt, &finger->opt_num, obuf, sizeof(obuf));
4140 + write_lock_bh(&osf_lock);
4141 + list_add_tail(&finger->flist, &finger_list);
4142 + write_unlock_bh(&osf_lock);
4147 +static int __init osf_init(void)
4150 + struct proc_dir_entry *p;
4152 + log("Startng OS fingerprint matching module.\n");
4154 + INIT_LIST_HEAD(&finger_list);
4156 + err = ipt_register_match(&osf_match);
4159 + log("Failed to register OS fingerprint matching module.\n");
4163 + p = create_proc_entry("sys/net/ipv4/osf", S_IFREG | 0644, NULL);
4166 + ipt_unregister_match(&osf_match);
4170 + p->write_proc = osf_proc_write;
4171 + p->read_proc = osf_proc_read;
4176 +static void __exit osf_fini(void)
4178 + struct list_head *ent, *n;
4179 + struct osf_finger *f;
4181 + remove_proc_entry("sys/net/ipv4/osf", NULL);
4182 + ipt_unregister_match(&osf_match);
4184 + list_for_each_safe(ent, n, &finger_list)
4186 + f = list_entry(ent, struct osf_finger, flist);
4187 + list_del(&f->flist);
4191 + log("OS fingerprint matching module finished.\n");
4194 +module_init(osf_init);
4195 +module_exit(osf_fini);
4197 +MODULE_LICENSE("GPL");
4198 +MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
4199 +MODULE_DESCRIPTION("Passive OS fingerprint matching.");
4201 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_pool.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_pool.c
4202 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_pool.c 1970-01-01 01:00:00.000000000 +0100
4203 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_pool.c 2004-02-16 11:07:21.519802833 +0100
4205 +/* Kernel module to match an IP address pool. */
4207 +#include <linux/module.h>
4208 +#include <linux/ip.h>
4209 +#include <linux/skbuff.h>
4211 +#include <linux/netfilter_ipv4/ip_tables.h>
4212 +#include <linux/netfilter_ipv4/ip_pool.h>
4213 +#include <linux/netfilter_ipv4/ipt_pool.h>
4215 +static inline int match_pool(
4220 + if (ip_pool_match(index, ntohl(addr)))
4226 + const struct sk_buff *skb,
4227 + const struct net_device *in,
4228 + const struct net_device *out,
4229 + const void *matchinfo,
4232 + u_int16_t datalen,
4235 + const struct ipt_pool_info *info = matchinfo;
4236 + const struct iphdr *iph = skb->nh.iph;
4238 + if (info->src != IP_POOL_NONE && !match_pool(info->src, iph->saddr,
4239 + info->flags&IPT_POOL_INV_SRC))
4242 + if (info->dst != IP_POOL_NONE && !match_pool(info->dst, iph->daddr,
4243 + info->flags&IPT_POOL_INV_DST))
4249 +static int checkentry(
4250 + const char *tablename,
4251 + const struct ipt_ip *ip,
4253 + unsigned int matchsize,
4254 + unsigned int hook_mask
4256 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_pool_info)))
4261 +static struct ipt_match pool_match
4262 += { { NULL, NULL }, "pool", &match, &checkentry, NULL, THIS_MODULE };
4264 +static int __init init(void)
4266 + return ipt_register_match(&pool_match);
4269 +static void __exit fini(void)
4271 + ipt_unregister_match(&pool_match);
4276 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_psd.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_psd.c
4277 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_psd.c 1970-01-01 01:00:00.000000000 +0100
4278 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_psd.c 2004-02-16 11:07:22.387595011 +0100
4281 + This is a module which is used for PSD (portscan detection)
4282 + Derived from scanlogd v2.1 written by Solar Designer <solar@false.com>
4283 + and LOG target module.
4285 + Copyright (C) 2000,2001 astaro AG
4287 + This file is distributed under the terms of the GNU General Public
4288 + License (GPL). Copies of the GPL can be obtained from:
4289 + ftp://prep.ai.mit.edu/pub/gnu/GPL
4291 + 2000-05-04 Markus Hennig <hennig@astaro.de> : initial
4292 + 2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
4293 + 2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
4294 + 2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified
4295 + 2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
4298 +#include <linux/module.h>
4299 +#include <linux/skbuff.h>
4300 +#include <linux/ip.h>
4301 +#include <net/tcp.h>
4302 +#include <linux/spinlock.h>
4303 +#include <linux/netfilter_ipv4/ip_tables.h>
4304 +#include <linux/netfilter_ipv4/ipt_psd.h>
4307 +#define DEBUGP printk
4309 +#define DEBUGP(format, args...)
4312 +MODULE_LICENSE("GPL");
4313 +MODULE_AUTHOR("Dennis Koslowski <koslowski@astaro.com>");
4315 +#define HF_DADDR_CHANGING 0x01
4316 +#define HF_SPORT_CHANGING 0x02
4317 +#define HF_TOS_CHANGING 0x04
4318 +#define HF_TTL_CHANGING 0x08
4321 + * Information we keep per each target port
4324 + u_int16_t number; /* port number */
4325 + u_int8_t proto; /* protocol number */
4326 + u_int8_t and_flags; /* tcp ANDed flags */
4327 + u_int8_t or_flags; /* tcp ORed flags */
4331 + * Information we keep per each source address.
4334 + struct host *next; /* Next entry with the same hash */
4335 + clock_t timestamp; /* Last update time */
4336 + struct in_addr src_addr; /* Source address */
4337 + struct in_addr dest_addr; /* Destination address */
4338 + unsigned short src_port; /* Source port */
4339 + int count; /* Number of ports in the list */
4340 + int weight; /* Total weight of ports in the list */
4341 + struct port ports[SCAN_MAX_COUNT - 1]; /* List of ports */
4342 + unsigned char tos; /* TOS */
4343 + unsigned char ttl; /* TTL */
4344 + unsigned char flags; /* HF_ flags bitmask */
4348 + * State information.
4352 + struct host list[LIST_SIZE]; /* List of source addresses */
4353 + struct host *hash[HASH_SIZE]; /* Hash: pointers into the list */
4354 + int index; /* Oldest entry to be replaced */
4358 + * Convert an IP address into a hash table index.
4360 +static inline int hashfunc(struct in_addr addr)
4362 + unsigned int value;
4365 + value = addr.s_addr;
4369 + } while ((value >>= HASH_LOG));
4371 + return hash & (HASH_SIZE - 1);
4375 +ipt_psd_match(const struct sk_buff *pskb,
4376 + const struct net_device *in,
4377 + const struct net_device *out,
4378 + const void *matchinfo,
4381 + u_int16_t datalen,
4384 + struct iphdr *ip_hdr;
4385 + struct tcphdr *tcp_hdr;
4386 + struct in_addr addr;
4387 + u_int16_t src_port,dest_port;
4388 + u_int8_t tcp_flags, proto;
4390 + struct host *curr, *last, **head;
4391 + int hash, index, count;
4393 + /* Parameters from userspace */
4394 + const struct ipt_psd_info *psdinfo = matchinfo;
4397 + ip_hdr = pskb->nh.iph;
4399 + /* Sanity check */
4400 + if (ntohs(ip_hdr->frag_off) & IP_OFFSET) {
4401 + DEBUGP("PSD: sanity check failed\n");
4405 + /* TCP or UDP ? */
4406 + proto = ip_hdr->protocol;
4408 + if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
4409 + DEBUGP("PSD: protocol not supported\n");
4413 + /* Get the source address, source & destination ports, and TCP flags */
4415 + addr.s_addr = ip_hdr->saddr;
4417 + tcp_hdr = (struct tcphdr*)((u_int32_t *)ip_hdr + ip_hdr->ihl);
4419 + /* Yep, it´s dirty */
4420 + src_port = tcp_hdr->source;
4421 + dest_port = tcp_hdr->dest;
4423 + if (proto == IPPROTO_TCP) {
4424 + tcp_flags = *((u_int8_t*)tcp_hdr + 13);
4430 + /* We're using IP address 0.0.0.0 for a special purpose here, so don't let
4431 + * them spoof us. [DHCP needs this feature - HW] */
4432 + if (!addr.s_addr) {
4433 + DEBUGP("PSD: spoofed source address (0.0.0.0)\n");
4437 + /* Use jiffies here not to depend on someone setting the time while we're
4438 + * running; we need to be careful with possible return value overflows. */
4441 + spin_lock(&state.lock);
4443 + /* Do we know this source address already? */
4446 + if ((curr = *(head = &state.hash[hash = hashfunc(addr)])))
4448 + if (curr->src_addr.s_addr == addr.s_addr) break;
4450 + if (curr->next) last = curr;
4451 + } while ((curr = curr->next));
4455 + /* We know this address, and the entry isn't too old. Update it. */
4456 + if (now - curr->timestamp <= (psdinfo->delay_threshold*HZ)/100 &&
4457 + time_after_eq(now, curr->timestamp)) {
4459 + /* Just update the appropriate list entry if we've seen this port already */
4460 + for (index = 0; index < curr->count; index++) {
4461 + if (curr->ports[index].number == dest_port) {
4462 + curr->ports[index].proto = proto;
4463 + curr->ports[index].and_flags &= tcp_flags;
4464 + curr->ports[index].or_flags |= tcp_flags;
4465 + goto out_no_match;
4469 + /* TCP/ACK and/or TCP/RST to a new port? This could be an outgoing connection. */
4470 + if (proto == IPPROTO_TCP && (tcp_hdr->ack || tcp_hdr->rst))
4471 + goto out_no_match;
4473 + /* Packet to a new port, and not TCP/ACK: update the timestamp */
4474 + curr->timestamp = now;
4476 + /* Logged this scan already? Then drop the packet. */
4477 + if (curr->weight >= psdinfo->weight_threshold)
4480 + /* Specify if destination address, source port, TOS or TTL are not fixed */
4481 + if (curr->dest_addr.s_addr != ip_hdr->daddr)
4482 + curr->flags |= HF_DADDR_CHANGING;
4483 + if (curr->src_port != src_port)
4484 + curr->flags |= HF_SPORT_CHANGING;
4485 + if (curr->tos != ip_hdr->tos)
4486 + curr->flags |= HF_TOS_CHANGING;
4487 + if (curr->ttl != ip_hdr->ttl)
4488 + curr->flags |= HF_TTL_CHANGING;
4490 + /* Update the total weight */
4491 + curr->weight += (ntohs(dest_port) < 1024) ?
4492 + psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
4494 + /* Got enough destination ports to decide that this is a scan? */
4495 + /* Then log it and drop the packet. */
4496 + if (curr->weight >= psdinfo->weight_threshold)
4499 + /* Remember the new port */
4500 + if (curr->count < SCAN_MAX_COUNT) {
4501 + curr->ports[curr->count].number = dest_port;
4502 + curr->ports[curr->count].proto = proto;
4503 + curr->ports[curr->count].and_flags = tcp_flags;
4504 + curr->ports[curr->count].or_flags = tcp_flags;
4508 + goto out_no_match;
4511 + /* We know this address, but the entry is outdated. Mark it unused, and
4512 + * remove from the hash table. We'll allocate a new entry instead since
4513 + * this one might get re-used too soon. */
4514 + curr->src_addr.s_addr = 0;
4516 + last->next = last->next->next;
4518 + *head = (*head)->next;
4522 + /* We don't need an ACK from a new source address */
4523 + if (proto == IPPROTO_TCP && tcp_hdr->ack)
4524 + goto out_no_match;
4526 + /* Got too many source addresses with the same hash value? Then remove the
4527 + * oldest one from the hash table, so that they can't take too much of our
4528 + * CPU time even with carefully chosen spoofed IP addresses. */
4529 + if (count >= HASH_MAX && last) last->next = NULL;
4531 + /* We're going to re-use the oldest list entry, so remove it from the hash
4532 + * table first (if it is really already in use, and isn't removed from the
4533 + * hash table already because of the HASH_MAX check above). */
4535 + /* First, find it */
4536 + if (state.list[state.index].src_addr.s_addr)
4537 + head = &state.hash[hashfunc(state.list[state.index].src_addr)];
4541 + if ((curr = *head))
4543 + if (curr == &state.list[state.index]) break;
4545 + } while ((curr = curr->next));
4547 + /* Then, remove it */
4550 + last->next = last->next->next;
4552 + *head = (*head)->next;
4555 + /* Get our list entry */
4556 + curr = &state.list[state.index++];
4557 + if (state.index >= LIST_SIZE) state.index = 0;
4559 + /* Link it into the hash table */
4560 + head = &state.hash[hash];
4561 + curr->next = *head;
4564 + /* And fill in the fields */
4565 + curr->timestamp = now;
4566 + curr->src_addr = addr;
4567 + curr->dest_addr.s_addr = ip_hdr->daddr;
4568 + curr->src_port = src_port;
4570 + curr->weight = (ntohs(dest_port) < 1024) ?
4571 + psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
4572 + curr->ports[0].number = dest_port;
4573 + curr->ports[0].proto = proto;
4574 + curr->ports[0].and_flags = tcp_flags;
4575 + curr->ports[0].or_flags = tcp_flags;
4576 + curr->tos = ip_hdr->tos;
4577 + curr->ttl = ip_hdr->ttl;
4580 + spin_unlock(&state.lock);
4584 + spin_unlock(&state.lock);
4588 +static int ipt_psd_checkentry(const char *tablename,
4589 + const struct ipt_ip *e,
4591 + unsigned int matchsize,
4592 + unsigned int hook_mask)
4594 +/* const struct ipt_psd_info *psdinfo = targinfo;*/
4596 + /* we accept TCP only */
4597 +/* if (e->ip.proto != IPPROTO_TCP) { */
4598 +/* DEBUGP("PSD: specified protocol may be TCP only\n"); */
4602 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_psd_info))) {
4603 + DEBUGP("PSD: matchsize %u != %u\n",
4605 + IPT_ALIGN(sizeof(struct ipt_psd_info)));
4612 +static struct ipt_match ipt_psd_reg = {
4616 + ipt_psd_checkentry,
4620 +static int __init init(void)
4622 + if (ipt_register_match(&ipt_psd_reg))
4625 + memset(&state, 0, sizeof(state));
4627 + spin_lock_init(&(state.lock));
4629 + printk("netfilter PSD loaded - (c) astaro AG\n");
4633 +static void __exit fini(void)
4635 + ipt_unregister_match(&ipt_psd_reg);
4636 + printk("netfilter PSD unloaded - (c) astaro AG\n");
4641 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_quota.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_quota.c
4642 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_quota.c 1970-01-01 01:00:00.000000000 +0100
4643 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_quota.c 2004-02-16 11:07:23.219395809 +0100
4646 + * netfilter module to enforce network quotas
4648 + * Sam Johnston <samj@samj.net>
4650 +#include <linux/module.h>
4651 +#include <linux/skbuff.h>
4652 +#include <linux/spinlock.h>
4653 +#include <linux/interrupt.h>
4655 +#include <linux/netfilter_ipv4/ip_tables.h>
4656 +#include <linux/netfilter_ipv4/ipt_quota.h>
4658 +MODULE_LICENSE("GPL");
4660 +static spinlock_t quota_lock = SPIN_LOCK_UNLOCKED;
4663 +match(const struct sk_buff *skb,
4664 + const struct net_device *in,
4665 + const struct net_device *out,
4666 + const void *matchinfo,
4667 + int offset, const void *hdr, u_int16_t datalen, int *hotdrop)
4670 + struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
4672 + spin_lock_bh("a_lock);
4674 + if (q->quota >= datalen) {
4675 + /* we can afford this one */
4676 + q->quota -= datalen;
4677 + spin_unlock_bh("a_lock);
4679 +#ifdef DEBUG_IPT_QUOTA
4680 + printk("IPT Quota OK: %llu datlen %d \n", q->quota, datalen);
4685 + /* so we do not allow even small packets from now on */
4688 +#ifdef DEBUG_IPT_QUOTA
4689 + printk("IPT Quota Failed: %llu datlen %d \n", q->quota, datalen);
4692 + spin_unlock_bh("a_lock);
4697 +checkentry(const char *tablename,
4698 + const struct ipt_ip *ip,
4699 + void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
4701 + /* TODO: spinlocks? sanity checks? */
4702 + if (matchsize != IPT_ALIGN(sizeof (struct ipt_quota_info)))
4708 +static struct ipt_match quota_match
4709 + = { {NULL, NULL}, "quota", &match, &checkentry, NULL, THIS_MODULE };
4714 + return ipt_register_match("a_match);
4720 + ipt_unregister_match("a_match);
4726 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_random.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_random.c
4727 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_random.c 1970-01-01 01:00:00.000000000 +0100
4728 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_random.c 2004-02-16 11:07:24.379118074 +0100
4731 + This is a module which is used for a "random" match support.
4732 + This file is distributed under the terms of the GNU General Public
4733 + License (GPL). Copies of the GPL can be obtained from:
4734 + ftp://prep.ai.mit.edu/pub/gnu/GPL
4736 + 2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
4739 +#include <linux/module.h>
4740 +#include <linux/skbuff.h>
4741 +#include <linux/ip.h>
4742 +#include <linux/random.h>
4743 +#include <net/tcp.h>
4744 +#include <linux/spinlock.h>
4745 +#include <linux/netfilter_ipv4/ip_tables.h>
4746 +#include <linux/netfilter_ipv4/ipt_random.h>
4748 +MODULE_LICENSE("GPL");
4751 +ipt_rand_match(const struct sk_buff *pskb,
4752 + const struct net_device *in,
4753 + const struct net_device *out,
4754 + const void *matchinfo,
4757 + u_int16_t datalen,
4760 + /* Parameters from userspace */
4761 + const struct ipt_rand_info *info = matchinfo;
4762 + u_int8_t random_number;
4764 + /* get 1 random number from the kernel random number generation routine */
4765 + get_random_bytes((void *)(&random_number), 1);
4767 + /* Do we match ? */
4768 + if (random_number <= info->average)
4775 +ipt_rand_checkentry(const char *tablename,
4776 + const struct ipt_ip *e,
4778 + unsigned int matchsize,
4779 + unsigned int hook_mask)
4781 + /* Parameters from userspace */
4782 + const struct ipt_rand_info *info = matchinfo;
4784 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_rand_info))) {
4785 + printk("ipt_random: matchsize %u != %u\n", matchsize,
4786 + IPT_ALIGN(sizeof(struct ipt_rand_info)));
4790 + /* must be 1 <= average % <= 99 */
4791 + /* 1 x 2.55 = 2 */
4792 + /* 99 x 2.55 = 252 */
4793 + if ((info->average < 2) || (info->average > 252)) {
4794 + printk("ipt_random: invalid average %u\n", info->average);
4801 +static struct ipt_match ipt_rand_reg = {
4805 + ipt_rand_checkentry,
4809 +static int __init init(void)
4811 + if (ipt_register_match(&ipt_rand_reg))
4814 + printk("ipt_random match loaded\n");
4818 +static void __exit fini(void)
4820 + ipt_unregister_match(&ipt_rand_reg);
4821 + printk("ipt_random match unloaded\n");
4826 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_realm.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_realm.c
4827 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_realm.c 1970-01-01 01:00:00.000000000 +0100
4828 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_realm.c 2004-02-16 11:07:26.369641375 +0100
4830 +/* Kernel module to match realm from routing. */
4831 +#include <linux/module.h>
4832 +#include <linux/skbuff.h>
4833 +#include <linux/netdevice.h>
4834 +#include <net/route.h>
4836 +#include <linux/netfilter_ipv4/ipt_realm.h>
4837 +#include <linux/netfilter_ipv4/ip_tables.h>
4839 +MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>");
4840 +MODULE_LICENSE("GPL");
4843 +match(const struct sk_buff *skb,
4844 + const struct net_device *in,
4845 + const struct net_device *out,
4846 + const void *matchinfo,
4849 + u_int16_t datalen,
4852 + const struct ipt_realm_info *info = matchinfo;
4853 + struct dst_entry *dst = skb->dst;
4858 + id = dst->tclassid;
4860 + return (info->id == (id & info->mask)) ^ info->invert;
4863 +static int check(const char *tablename,
4864 + const struct ipt_ip *ip,
4866 + unsigned int matchsize,
4867 + unsigned int hook_mask)
4870 + & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) |
4871 + (1 << NF_IP_LOCAL_OUT)| (1 << NF_IP_LOCAL_IN))) {
4872 + printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, "
4873 + "LOCAL_IN or FORWARD.\n");
4877 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info)))
4883 +static struct ipt_match realm_match
4884 += { { NULL, NULL }, "realm", &match, &check, NULL, THIS_MODULE };
4886 +static int __init init(void)
4888 + return ipt_register_match(&realm_match);
4891 +static void __exit fini(void)
4893 + ipt_unregister_match(&realm_match);
4898 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_time.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_time.c
4899 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_time.c 1970-01-01 01:00:00.000000000 +0100
4900 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_time.c 2004-02-16 11:07:27.150454383 +0100
4903 + This is a module which is used for time matching
4904 + It is using some modified code from dietlibc (localtime() function)
4905 + that you can find at http://www.fefe.de/dietlibc/
4906 + This file is distributed under the terms of the GNU General Public
4907 + License (GPL). Copies of the GPL can be obtained from: ftp://prep.ai.mit.edu/pub/gnu/GPL
4908 + 2001-05-04 Fabrice MARIE <fabrice@netfilter.org> : initial development.
4909 + 2001-21-05 Fabrice MARIE <fabrice@netfilter.org> : bug fix in the match code,
4910 + thanks to "Zeng Yu" <zengy@capitel.com.cn> for bug report.
4911 + 2001-26-09 Fabrice MARIE <fabrice@netfilter.org> : force the match to be in LOCAL_IN or PRE_ROUTING only.
4912 + 2001-30-11 Fabrice : added the possibility to use the match in FORWARD/OUTPUT with a little hack,
4913 + added Nguyen Dang Phuoc Dong <dongnd@tlnet.com.vn> patch to support timezones.
4916 +#include <linux/module.h>
4917 +#include <linux/skbuff.h>
4918 +#include <linux/netfilter_ipv4/ip_tables.h>
4919 +#include <linux/netfilter_ipv4/ipt_time.h>
4920 +#include <linux/time.h>
4922 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
4923 +MODULE_DESCRIPTION("Match arrival timestamp");
4924 +MODULE_LICENSE("GPL");
4928 + int tm_sec; /* Seconds. [0-60] (1 leap second) */
4929 + int tm_min; /* Minutes. [0-59] */
4930 + int tm_hour; /* Hours. [0-23] */
4931 + int tm_mday; /* Day. [1-31] */
4932 + int tm_mon; /* Month. [0-11] */
4933 + int tm_year; /* Year - 1900. */
4934 + int tm_wday; /* Day of week. [0-6] */
4935 + int tm_yday; /* Days in year.[0-365] */
4936 + int tm_isdst; /* DST. [-1/0/1]*/
4938 + long int tm_gmtoff; /* we don't care, we count from GMT */
4939 + const char *tm_zone; /* we don't care, we count from GMT */
4943 +localtime(const time_t *timepr, struct tm *r);
4946 +match(const struct sk_buff *skb,
4947 + const struct net_device *in,
4948 + const struct net_device *out,
4949 + const void *matchinfo,
4952 + u_int16_t datalen,
4955 + const struct ipt_time_info *info = matchinfo; /* match info for rule */
4956 + struct tm currenttime; /* time human readable */
4957 + u_int8_t days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
4958 + u_int16_t packet_time;
4959 + struct timeval kerneltimeval;
4960 + time_t packet_local_time;
4962 + /* if kerneltime=1, we don't read the skb->timestamp but kernel time instead */
4963 + if (info->kerneltime)
4965 + do_gettimeofday(&kerneltimeval);
4966 + packet_local_time = kerneltimeval.tv_sec;
4969 + packet_local_time = skb->stamp.tv_sec;
4971 + /* Transform the timestamp of the packet, in a human readable form */
4972 + localtime(&packet_local_time, ¤ttime);
4974 + /* check if we match this timestamp, we start by the days... */
4975 + if ((days_of_week[currenttime.tm_wday] & info->days_match) != days_of_week[currenttime.tm_wday])
4976 + return 0; /* the day doesn't match */
4978 + /* ... check the time now */
4979 + packet_time = (currenttime.tm_hour * 60) + currenttime.tm_min;
4980 + if ((packet_time < info->time_start) || (packet_time > info->time_stop))
4983 + /* here we match ! */
4988 +checkentry(const char *tablename,
4989 + const struct ipt_ip *ip,
4991 + unsigned int matchsize,
4992 + unsigned int hook_mask)
4994 + struct ipt_time_info *info = matchinfo; /* match info for rule */
4996 + /* First, check that we are in the correct hook */
4997 + /* PRE_ROUTING, LOCAL_IN or FROWARD */
4999 + & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
5001 + printk("ipt_time: error, only valid for PRE_ROUTING, LOCAL_IN, FORWARD and OUTPUT)\n");
5004 + /* we use the kerneltime if we are in forward or output */
5005 + info->kerneltime = 1;
5006 + if (hook_mask & ~((1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
5007 + /* if not, we use the skb time */
5008 + info->kerneltime = 0;
5010 + /* Check the size */
5011 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_time_info)))
5013 + /* Now check the coherence of the data ... */
5014 + if ((info->time_start > 1439) || /* 23*60+59 = 1439*/
5015 + (info->time_stop > 1439))
5017 + printk(KERN_WARNING "ipt_time: invalid argument\n");
5024 +static struct ipt_match time_match
5025 += { { NULL, NULL }, "time", &match, &checkentry, NULL, THIS_MODULE };
5027 +static int __init init(void)
5029 + printk("ipt_time loading\n");
5030 + return ipt_register_match(&time_match);
5033 +static void __exit fini(void)
5035 + ipt_unregister_match(&time_match);
5036 + printk("ipt_time unloaded\n");
5043 +/* The part below is borowed and modified from dietlibc */
5045 +/* seconds per day */
5046 +#define SPD 24*60*60
5049 +localtime(const time_t *timepr, struct tm *r) {
5052 + extern struct timezone sys_tz;
5053 + const unsigned int __spm[12] =
5060 + (31+28+31+30+31+30),
5061 + (31+28+31+30+31+30+31),
5062 + (31+28+31+30+31+30+31+31),
5063 + (31+28+31+30+31+30+31+31+30),
5064 + (31+28+31+30+31+30+31+31+30+31),
5065 + (31+28+31+30+31+30+31+31+30+31+30),
5067 + register time_t work;
5069 + timep = (*timepr) - (sys_tz.tz_minuteswest * 60);
5071 + r->tm_sec=work%60; work/=60;
5072 + r->tm_min=work%60; r->tm_hour=work/60;
5074 + r->tm_wday=(4+work)%7;
5075 + for (i=1970; ; ++i) {
5076 + register time_t k= (!(i%4) && ((i%100) || !(i%400)))?366:365;
5082 + r->tm_year=i-1900;
5083 + for (i=11; i && __spm[i]>work; --i) ;
5085 + r->tm_mday=work-__spm[i]+1;
5087 diff -Nur linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_u32.c linux-2.6.3-rc3/net/ipv4/netfilter/ipt_u32.c
5088 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_u32.c 1970-01-01 01:00:00.000000000 +0100
5089 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_u32.c 2004-02-16 11:07:28.175208970 +0100
5091 +/* Kernel module to match u32 packet content. */
5094 +U32 tests whether quantities of up to 4 bytes extracted from a packet
5095 +have specified values. The specification of what to extract is general
5096 +enough to find data at given offsets from tcp headers or payloads.
5099 + The argument amounts to a program in a small language described below.
5100 + tests := location = value | tests && location = value
5101 + value := range | value , range
5102 + range := number | number : number
5103 + a single number, n, is interpreted the same as n:n
5104 + n:m is interpreted as the range of numbers >=n and <=m
5105 + location := number | location operator number
5106 + operator := & | << | >> | @
5108 + The operators &, <<, >>, && mean the same as in c. The = is really a set
5109 + membership operator and the value syntax describes a set. The @ operator
5110 + is what allows moving to the next header and is described further below.
5112 + *** Until I can find out how to avoid it, there are some artificial limits
5113 + on the size of the tests:
5114 + - no more than 10 ='s (and 9 &&'s) in the u32 argument
5115 + - no more than 10 ranges (and 9 commas) per value
5116 + - no more than 10 numbers (and 9 operators) per location
5118 + To describe the meaning of location, imagine the following machine that
5119 + interprets it. There are three registers:
5120 + A is of type char*, initially the address of the IP header
5121 + B and C are unsigned 32 bit integers, initially zero
5123 + The instructions are:
5124 + number B = number;
5125 + C = (*(A+B)<<24)+(*(A+B+1)<<16)+(*(A+B+2)<<8)+*(A+B+3)
5126 + &number C = C&number
5127 + <<number C = C<<number
5128 + >>number C = C>>number
5129 + @number A = A+C; then do the instruction number
5130 + Any access of memory outside [skb->head,skb->end] causes the match to fail.
5131 + Otherwise the result of the computation is the final value of C.
5133 + Whitespace is allowed but not required in the tests.
5134 + However the characters that do occur there are likely to require
5135 + shell quoting, so it's a good idea to enclose the arguments in quotes.
5138 + match IP packets with total length >= 256
5139 + The IP header contains a total length field in bytes 2-3.
5140 + --u32 "0&0xFFFF=0x100:0xFFFF"
5142 + AND that with FFFF (giving bytes 2-3),
5143 + and test whether that's in the range [0x100:0xFFFF]
5145 +Example: (more realistic, hence more complicated)
5146 + match icmp packets with icmp type 0
5147 + First test that it's an icmp packet, true iff byte 9 (protocol) = 1
5148 + --u32 "6&0xFF=1 && ...
5149 + read bytes 6-9, use & to throw away bytes 6-8 and compare the result to 1
5150 + Next test that it's not a fragment.
5151 + (If so it might be part of such a packet but we can't always tell.)
5152 + n.b. This test is generally needed if you want to match anything
5153 + beyond the IP header.
5154 + The last 6 bits of byte 6 and all of byte 7 are 0 iff this is a complete
5155 + packet (not a fragment). Alternatively, you can allow first fragments
5156 + by only testing the last 5 bits of byte 6.
5157 + ... 4&0x3FFF=0 && ...
5158 + Last test: the first byte past the IP header (the type) is 0
5159 + This is where we have to use the @syntax. The length of the IP header
5160 + (IHL) in 32 bit words is stored in the right half of byte 0 of the
5162 + ... 0>>22&0x3C@0>>24=0"
5163 + The first 0 means read bytes 0-3,
5164 + >>22 means shift that 22 bits to the right. Shifting 24 bits would give
5165 + the first byte, so only 22 bits is four times that plus a few more bits.
5166 + &3C then eliminates the two extra bits on the right and the first four
5167 + bits of the first byte.
5168 + For instance, if IHL=5 then the IP header is 20 (4 x 5) bytes long.
5169 + In this case bytes 0-1 are (in binary) xxxx0101 yyzzzzzz,
5170 + >>22 gives the 10 bit value xxxx0101yy and &3C gives 010100.
5171 + @ means to use this number as a new offset into the packet, and read
5172 + four bytes starting from there. This is the first 4 bytes of the icmp
5173 + payload, of which byte 0 is the icmp type. Therefore we simply shift
5174 + the value 24 to the right to throw out all but the first byte and compare
5175 + the result with 0.
5178 + tcp payload bytes 8-12 is any of 1, 2, 5 or 8
5179 + First we test that the packet is a tcp packet (similar to icmp).
5180 + --u32 "6&0xFF=6 && ...
5181 + Next, test that it's not a fragment (same as above).
5182 + ... 0>>22&0x3C@12>>26&0x3C@8=1,2,5,8"
5183 + 0>>22&3C as above computes the number of bytes in the IP header.
5184 + @ makes this the new offset into the packet, which is the start of the
5185 + tcp header. The length of the tcp header (again in 32 bit words) is
5186 + the left half of byte 12 of the tcp header. The 12>>26&3C
5187 + computes this length in bytes (similar to the IP header before).
5188 + @ makes this the new offset, which is the start of the tcp payload.
5189 + Finally 8 reads bytes 8-12 of the payload and = checks whether the
5190 + result is any of 1, 2, 5 or 8
5193 +#include <linux/module.h>
5194 +#include <linux/skbuff.h>
5196 +#include <linux/netfilter_ipv4/ipt_u32.h>
5197 +#include <linux/netfilter_ipv4/ip_tables.h>
5199 +/* #include <asm-i386/timex.h> for timing */
5201 +MODULE_AUTHOR("Don Cohen <don@isis.cs3-inc.com>");
5202 +MODULE_DESCRIPTION("IP tables u32 matching module");
5203 +MODULE_LICENSE("GPL");
5206 +match(const struct sk_buff *skb,
5207 + const struct net_device *in,
5208 + const struct net_device *out,
5209 + const void *matchinfo,
5212 + u_int16_t datalen,
5215 + const struct ipt_u32 *data = matchinfo;
5217 + unsigned char* origbase = (char*)skb->nh.iph;
5218 + unsigned char* base = origbase;
5219 + unsigned char* head = skb->head;
5220 + unsigned char* end = skb->end;
5222 + u_int32_t pos, val;
5223 + /* unsigned long long cycles1, cycles2, cycles3, cycles4;
5224 + cycles1 = get_cycles(); */
5226 + for (testind=0; testind < data->ntests; testind++) {
5227 + base = origbase; /* reset for each test */
5228 + pos = data->tests[testind].location[0].number;
5229 + if (base+pos+3 > end || base+pos < head)
5231 + val = (base[pos]<<24) + (base[pos+1]<<16) +
5232 + (base[pos+2]<<8) + base[pos+3];
5233 + nnums = data->tests[testind].nnums;
5234 + for (i=1; i < nnums; i++) {
5235 + u_int32_t number = data->tests[testind].location[i].number;
5236 + switch (data->tests[testind].location[i].nextop) {
5238 + val = val & number;
5240 + case IPT_U32_LEFTSH:
5241 + val = val << number;
5243 + case IPT_U32_RIGHTSH:
5244 + val = val >> number;
5247 + base = base + val;
5249 + if (base+pos+3 > end || base+pos < head)
5251 + val = (base[pos]<<24) + (base[pos+1]<<16) +
5252 + (base[pos+2]<<8) + base[pos+3];
5256 + nvals = data->tests[testind].nvalues;
5257 + for (i=0; i < nvals; i++) {
5258 + if ((data->tests[testind].value[i].min <= val) &&
5259 + (val <= data->tests[testind].value[i].max)) {
5263 + if (i >= data->tests[testind].nvalues) {
5264 + /* cycles2 = get_cycles();
5265 + printk("failed %d in %d cycles\n", testind,
5266 + cycles2-cycles1); */
5270 + /* cycles2 = get_cycles();
5271 + printk("succeeded in %d cycles\n", cycles2-cycles1); */
5276 +checkentry(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_u32)))
5287 +static struct ipt_match u32_match
5288 += { { NULL, NULL }, "u32", &match, &checkentry, NULL, THIS_MODULE };
5290 +static int __init init(void)
5292 + return ipt_register_match(&u32_match);
5295 +static void __exit fini(void)
5297 + ipt_unregister_match(&u32_match);
5302 diff -Nur linux-2.6.3-rc3.org/net/ipv6/netfilter/Kconfig linux-2.6.3-rc3/net/ipv6/netfilter/Kconfig
5303 --- linux-2.6.3-rc3.org/net/ipv6/netfilter/Kconfig 2004-02-15 03:45:16.000000000 +0100
5304 +++ linux-2.6.3-rc3/net/ipv6/netfilter/Kconfig 2004-02-16 11:07:24.383117116 +0100
5305 @@ -218,5 +218,85 @@
5306 To compile it as a module, choose M here. If unsure, say N.
5308 #dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES
5309 +config IP6_NF_TARGET_HOPLIMIT
5310 + tristate 'HOPLIMIT target support'
5311 + depends on IP6_NF_MANGLE
5313 + This allows the user to set the IPv6 Hop Limit value on a packet or
5314 + to increment or decrement it by a given value.
5317 + # ip6tables -t mangle -A OUTPUT -j HOPLIMIT --hl-inc 1
5318 + # ip6tables -t mangle -A INPUT -j HOPLIMIT --hl-eq 64
5319 + # ip6tables -t mangle -A OUTPUT -j HOPLIMIT --hl-dec 2
5321 +config IP6_NF_TARGET_REJECT
5322 + tristate 'REJECT target support'
5323 + depends on IP6_NF_FILTER
5325 + This CONFIG_IP6_NF_TARGET_REJECT option adds a REJECT target to ip6tables.
5326 + Please keep in mind that the icmp-types are different from the icmpv6 types
5327 + (see ip6tables -j REJECT -h for more info)
5329 +config IP6_NF_MATCH_FUZZY
5330 + tristate 'Fuzzy match support'
5331 + depends on IP6_NF_FILTER
5333 + This option adds a `fuzzy' match which allows you to match packets according to
5334 + a dynamic profile implemented by means of a simple Fuzzy Logic Controller (FLC)
5336 +config IP6_NF_MATCH_NTH
5337 + tristate 'Nth match support'
5338 + depends on IP6_NF_IPTABLES
5340 + This option adds an iptables `Nth' match, which allows you to match every Nth
5341 + packet encountered. By default there are 16 different counters that can be
5344 + This match functions in one of two ways
5345 + 1) Match ever Nth packet, and only the Nth packet.
5347 + iptables -t mangle -A PREROUTING -m nth --every 10 -j DROP
5348 + This rule will drop every 10th packet.
5349 + 2) Unique rule for every packet. This is an easy and quick
5350 + method to produce load-balancing for both inbound and outbound.
5352 + iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
5353 + --every 3 --packet 0 -j SNAT --to-source 10.0.0.5
5354 + iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
5355 + --every 3 --packet 1 -j SNAT --to-source 10.0.0.6
5356 + iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
5357 + --every 3 --packet 2 -j SNAT --to-source 10.0.0.7
5358 + This example evenly splits connections between the three SNAT
5361 + By using the mangle table and iproute2, you can setup complex
5362 + load-balanced routing. There's lot of other uses. Be creative!
5364 + Suppported options are:
5365 + --every Nth Match every Nth packet
5366 + [--counter] num Use counter 0-15 (default:0)
5367 + [--start] num Initialize the counter at the number 'num'
5368 + instead of 0. Must be between 0 and Nth-1
5369 + [--packet] num Match on 'num' packet. Must be between 0
5371 + If --packet is used for a counter than
5372 + there must be Nth number of --packet
5373 + rules, covering all values between 0 and
5374 + Nth-1 inclusively.
5376 +config IP6_NF_MATCH_RANDOM
5377 + tristate 'Random match support'
5378 + depends on IP6_NF_IPTABLES
5380 + This option adds a `random' match,
5381 + which allow you to match packets randomly
5382 + following a given probability.
5384 + Suppported options are:
5386 + [--average] percent will match randomly packets with a probability of
5387 + 'percent'. default is 50%
5391 diff -Nur linux-2.6.3-rc3.org/net/ipv6/netfilter/Makefile linux-2.6.3-rc3/net/ipv6/netfilter/Makefile
5392 --- linux-2.6.3-rc3.org/net/ipv6/netfilter/Makefile 2004-02-15 03:44:25.000000000 +0100
5393 +++ linux-2.6.3-rc3/net/ipv6/netfilter/Makefile 2004-02-16 11:07:24.383117116 +0100
5395 obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o
5396 obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
5397 obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o
5398 +obj-$(CONFIG_IP6_NF_MATCH_FUZZY) += ip6t_fuzzy.o
5399 obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
5400 obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
5401 obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
5403 obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
5404 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
5405 obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
5406 +obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
5407 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
5408 obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
5410 +obj-$(CONFIG_IP6_NF_MATCH_RANDOM) += ip6t_random.o
5412 +obj-$(CONFIG_IP6_NF_MATCH_NTH) += ip6t_nth.o
5413 +obj-$(CONFIG_IP6_NF_TARGET_HOPLIMIT) += ip6t_HL.o
5414 obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
5415 diff -Nur linux-2.6.3-rc3.org/net/ipv6/netfilter/ip6t_HL.c linux-2.6.3-rc3/net/ipv6/netfilter/ip6t_HL.c
5416 --- linux-2.6.3-rc3.org/net/ipv6/netfilter/ip6t_HL.c 1970-01-01 01:00:00.000000000 +0100
5417 +++ linux-2.6.3-rc3/net/ipv6/netfilter/ip6t_HL.c 2004-02-16 11:06:53.521507853 +0100
5420 + * Hop Limit modification target for ip6tables
5421 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
5422 + * Based on HW's TTL module
5424 + * This software is distributed under the terms of GNU GPL
5427 +#include <linux/module.h>
5428 +#include <linux/skbuff.h>
5429 +#include <linux/ip.h>
5431 +#include <linux/netfilter_ipv6/ip6_tables.h>
5432 +#include <linux/netfilter_ipv6/ip6t_HL.h>
5434 +MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
5435 +MODULE_DESCRIPTION("IP tables Hop Limit modification module");
5436 +MODULE_LICENSE("GPL");
5438 +static unsigned int ip6t_hl_target(struct sk_buff **pskb, unsigned int hooknum,
5439 + const struct net_device *in, const struct net_device *out,
5440 + const void *targinfo, void *userinfo)
5442 + struct ipv6hdr *ip6h = (*pskb)->nh.ipv6h;
5443 + const struct ip6t_HOPLIMIT_info *info = targinfo;
5444 + u_int16_t diffs[2];
5447 + switch (info->mode) {
5448 + case IP6T_HOPLIMIT_SET:
5449 + new_hl = info->hop_limit;
5451 + case IP6T_HOPLIMIT_INC:
5452 + new_hl = ip6h->hop_limit + info->hop_limit;
5456 + case IP6T_HOPLIMIT_DEC:
5457 + new_hl = ip6h->hop_limit + info->hop_limit;
5462 + new_hl = ip6h->hop_limit;
5466 + if (new_hl != ip6h->hop_limit) {
5467 + diffs[0] = htons(((unsigned)ip6h->hop_limit) << 8) ^ 0xFFFF;
5468 + ip6h->hop_limit = new_hl;
5469 + diffs[1] = htons(((unsigned)ip6h->hop_limit) << 8);
5472 + return IP6T_CONTINUE;
5475 +static int ip6t_hl_checkentry(const char *tablename,
5476 + const struct ip6t_entry *e,
5478 + unsigned int targinfosize,
5479 + unsigned int hook_mask)
5481 + struct ip6t_HOPLIMIT_info *info = targinfo;
5483 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_HOPLIMIT_info))) {
5484 + printk(KERN_WARNING "HOPLIMIT: targinfosize %u != %Zu\n",
5486 + IP6T_ALIGN(sizeof(struct ip6t_HOPLIMIT_info)));
5490 + if (strcmp(tablename, "mangle")) {
5491 + printk(KERN_WARNING "HOPLIMIT: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
5495 + if (info->mode > IP6T_HOPLIMIT_MAXMODE) {
5496 + printk(KERN_WARNING "HOPLIMIT: invalid or unknown Mode %u\n",
5501 + if ((info->mode != IP6T_HOPLIMIT_SET) && (info->hop_limit == 0)) {
5502 + printk(KERN_WARNING "HOPLIMIT: increment/decrement doesn't make sense with value 0\n");
5509 +static struct ip6t_target ip6t_HOPLIMIT = { { NULL, NULL }, "HOPLIMIT",
5510 + ip6t_hl_target, ip6t_hl_checkentry, NULL, THIS_MODULE };
5512 +static int __init init(void)
5514 + return ip6t_register_target(&ip6t_HOPLIMIT);
5517 +static void __exit fini(void)
5519 + ip6t_unregister_target(&ip6t_HOPLIMIT);
5524 diff -Nur linux-2.6.3-rc3.org/net/ipv6/netfilter/ip6t_REJECT.c linux-2.6.3-rc3/net/ipv6/netfilter/ip6t_REJECT.c
5525 --- linux-2.6.3-rc3.org/net/ipv6/netfilter/ip6t_REJECT.c 1970-01-01 01:00:00.000000000 +0100
5526 +++ linux-2.6.3-rc3/net/ipv6/netfilter/ip6t_REJECT.c 2004-02-16 11:07:07.805087251 +0100
5529 + * This is a module which is used for rejecting packets.
5530 + * Added support for customized reject packets (Jozsef Kadlecsik).
5532 + * Port to IPv6 / ip6tables (Harald Welte <laforge@gnumonks.org>)
5534 +#include <linux/config.h>
5535 +#include <linux/module.h>
5536 +#include <linux/skbuff.h>
5537 +#include <linux/icmpv6.h>
5538 +#include <net/tcp.h>
5539 +#include <linux/netfilter_ipv6/ip6_tables.h>
5540 +#include <linux/netfilter_ipv6/ip6t_REJECT.h>
5543 +#define DEBUGP printk
5545 +#define DEBUGP(format, args...)
5549 +/* Send RST reply */
5550 +static void send_reset(struct sk_buff *oldskb)
5552 + struct sk_buff *nskb;
5553 + struct tcphdr *otcph, *tcph;
5554 + struct rtable *rt;
5555 + unsigned int otcplen;
5558 + /* IP header checks: fragment, too short. */
5559 + if (oldskb->nh.iph->frag_off & htons(IP_OFFSET)
5560 + || oldskb->len < (oldskb->nh.iph->ihl<<2) + sizeof(struct tcphdr))
5563 + otcph = (struct tcphdr *)((u_int32_t*)oldskb->nh.iph + oldskb->nh.iph->ihl);
5564 + otcplen = oldskb->len - oldskb->nh.iph->ihl*4;
5566 + /* No RST for RST. */
5570 + /* Check checksum. */
5571 + if (tcp_v4_check(otcph, otcplen, oldskb->nh.iph->saddr,
5572 + oldskb->nh.iph->daddr,
5573 + csum_partial((char *)otcph, otcplen, 0)) != 0)
5576 + /* Copy skb (even if skb is about to be dropped, we can't just
5577 + clone it because there may be other things, such as tcpdump,
5578 + interested in it) */
5579 + nskb = skb_copy(oldskb, GFP_ATOMIC);
5583 + /* This packet will not be the same as the other: clear nf fields */
5584 + nf_conntrack_put(nskb->nfct);
5585 + nskb->nfct = NULL;
5586 + nskb->nfcache = 0;
5587 +#ifdef CONFIG_NETFILTER_DEBUG
5588 + nskb->nf_debug = 0;
5591 + tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
5593 + nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
5594 + tcph->source = xchg(&tcph->dest, tcph->source);
5596 + /* Truncate to length (no data) */
5597 + tcph->doff = sizeof(struct tcphdr)/4;
5598 + skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
5599 + nskb->nh.iph->tot_len = htons(nskb->len);
5603 + tcph->seq = otcph->ack_seq;
5604 + tcph->ack_seq = 0;
5607 + tcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn + otcph->fin
5608 + + otcplen - (otcph->doff<<2));
5613 + ((u_int8_t *)tcph)[13] = 0;
5615 + tcph->ack = needs_ack;
5618 + tcph->urg_ptr = 0;
5620 + /* Adjust TCP checksum */
5622 + tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
5623 + nskb->nh.iph->saddr,
5624 + nskb->nh.iph->daddr,
5625 + csum_partial((char *)tcph,
5626 + sizeof(struct tcphdr), 0));
5628 + /* Adjust IP TTL, DF */
5629 + nskb->nh.iph->ttl = MAXTTL;
5630 + /* Set DF, id = 0 */
5631 + nskb->nh.iph->frag_off = htons(IP_DF);
5632 + nskb->nh.iph->id = 0;
5634 + /* Adjust IP checksum */
5635 + nskb->nh.iph->check = 0;
5636 + nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,
5637 + nskb->nh.iph->ihl);
5640 + if (ip_route_output(&rt, nskb->nh.iph->daddr, nskb->nh.iph->saddr,
5641 + RT_TOS(nskb->nh.iph->tos) | RTO_CONN,
5645 + dst_release(nskb->dst);
5646 + nskb->dst = &rt->u.dst;
5648 + /* "Never happens" */
5649 + if (nskb->len > nskb->dst->pmtu)
5652 + NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
5653 + ip_finish_output);
5661 +static unsigned int reject6_target(struct sk_buff **pskb,
5662 + unsigned int hooknum,
5663 + const struct net_device *in,
5664 + const struct net_device *out,
5665 + const void *targinfo,
5668 + const struct ip6t_reject_info *reject = targinfo;
5670 + /* WARNING: This code causes reentry within ip6tables.
5671 + This means that the ip6tables jump stack is now crap. We
5672 + must return an absolute verdict. --RR */
5673 + DEBUGP("REJECTv6: calling icmpv6_send\n");
5674 + switch (reject->with) {
5675 + case IP6T_ICMP6_NO_ROUTE:
5676 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, out);
5678 + case IP6T_ICMP6_ADM_PROHIBITED:
5679 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADM_PROHIBITED, 0, out);
5681 + case IP6T_ICMP6_NOT_NEIGHBOUR:
5682 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOT_NEIGHBOUR, 0, out);
5684 + case IP6T_ICMP6_ADDR_UNREACH:
5685 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, out);
5687 + case IP6T_ICMP6_PORT_UNREACH:
5688 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, out);
5691 + case IPT_ICMP_ECHOREPLY: {
5692 + struct icmp6hdr *icmph = (struct icmphdr *)
5693 + ((u_int32_t *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl);
5694 + unsigned int datalen = (*pskb)->len - (*pskb)->nh.iph->ihl * 4;
5696 + /* Not non-head frags, or truncated */
5697 + if (((ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET) == 0)
5698 + && datalen >= 4) {
5699 + /* Usually I don't like cut & pasting code,
5700 + but dammit, my party is starting in 45
5702 + struct icmp_bxm icmp_param;
5704 + icmp_param.icmph=*icmph;
5705 + icmp_param.icmph.type=ICMP_ECHOREPLY;
5706 + icmp_param.data_ptr=(icmph+1);
5707 + icmp_param.data_len=datalen;
5708 + icmp_reply(&icmp_param, *pskb);
5712 + case IPT_TCP_RESET:
5713 + send_reset(*pskb);
5717 + printk(KERN_WARNING "REJECTv6: case %u not handled yet\n", reject->with);
5724 +static inline int find_ping_match(const struct ip6t_entry_match *m)
5726 + const struct ip6t_icmp *icmpinfo = (const struct ip6t_icmp *)m->data;
5728 + if (strcmp(m->u.kernel.match->name, "icmp6") == 0
5729 + && icmpinfo->type == ICMPV6_ECHO_REQUEST
5730 + && !(icmpinfo->invflags & IP6T_ICMP_INV))
5736 +static int check(const char *tablename,
5737 + const struct ip6t_entry *e,
5739 + unsigned int targinfosize,
5740 + unsigned int hook_mask)
5742 + const struct ip6t_reject_info *rejinfo = targinfo;
5744 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
5745 + DEBUGP("REJECTv6: targinfosize %u != 0\n", targinfosize);
5749 + /* Only allow these for packet filtering. */
5750 + if (strcmp(tablename, "filter") != 0) {
5751 + DEBUGP("REJECTv6: bad table `%s'.\n", tablename);
5754 + if ((hook_mask & ~((1 << NF_IP6_LOCAL_IN)
5755 + | (1 << NF_IP6_FORWARD)
5756 + | (1 << NF_IP6_LOCAL_OUT))) != 0) {
5757 + DEBUGP("REJECTv6: bad hook mask %X\n", hook_mask);
5761 + if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
5762 + /* Must specify that it's an ICMP ping packet. */
5763 + if (e->ipv6.proto != IPPROTO_ICMPV6
5764 + || (e->ipv6.invflags & IP6T_INV_PROTO)) {
5765 + DEBUGP("REJECTv6: ECHOREPLY illegal for non-icmp\n");
5768 + /* Must contain ICMP match. */
5769 + if (IP6T_MATCH_ITERATE(e, find_ping_match) == 0) {
5770 + DEBUGP("REJECTv6: ECHOREPLY illegal for non-ping\n");
5773 + } else if (rejinfo->with == IP6T_TCP_RESET) {
5774 + /* Must specify that it's a TCP packet */
5775 + if (e->ipv6.proto != IPPROTO_TCP
5776 + || (e->ipv6.invflags & IP6T_INV_PROTO)) {
5777 + DEBUGP("REJECTv6: TCP_RESET illegal for non-tcp\n");
5785 +static struct ip6t_target ip6t_reject_reg
5786 += { { NULL, NULL }, "REJECT", reject6_target, check, NULL, THIS_MODULE };
5788 +static int __init init(void)
5790 + if (ip6t_register_target(&ip6t_reject_reg))
5795 +static void __exit fini(void)
5797 + ip6t_unregister_target(&ip6t_reject_reg);
5802 diff -Nur linux-2.6.3-rc3.org/net/ipv6/netfilter/ip6t_fuzzy.c linux-2.6.3-rc3/net/ipv6/netfilter/ip6t_fuzzy.c
5803 --- linux-2.6.3-rc3.org/net/ipv6/netfilter/ip6t_fuzzy.c 1970-01-01 01:00:00.000000000 +0100
5804 +++ linux-2.6.3-rc3/net/ipv6/netfilter/ip6t_fuzzy.c 2004-02-16 11:07:14.926381841 +0100
5807 + * This module implements a simple TSK FLC
5808 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
5809 + * to limit , in an adaptive and flexible way , the packet rate crossing
5810 + * a given stream . It serves as an initial and very simple (but effective)
5811 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
5812 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
5813 + * into our code in a precise , adaptive and efficient manner.
5814 + * The goal is very similar to that of "limit" match , but using techniques of
5815 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
5816 + * avoiding over and undershoots - and stuff like that .
5819 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
5820 + * 2002-08-17 : Changed to eliminate floating point operations .
5821 + * 2002-08-23 : Coding style changes .
5822 + * 2003-04-08 Maciej Soltysiak <solt@dns.toxicilms.tv> : IPv6 Port
5825 +#include <linux/module.h>
5826 +#include <linux/skbuff.h>
5827 +#include <linux/ipv6.h>
5828 +#include <linux/random.h>
5829 +#include <net/tcp.h>
5830 +#include <linux/spinlock.h>
5831 +#include <linux/netfilter_ipv6/ip6_tables.h>
5832 +#include <linux/netfilter_ipv6/ip6t_fuzzy.h>
5835 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
5836 + Expressed in percentage
5839 +#define PAR_LOW 1/100
5842 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED;
5844 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
5845 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
5846 +MODULE_LICENSE("GPL");
5848 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
5850 + if (tx >= maxi) return 100;
5852 + if (tx <= mini) return 0;
5854 + return ((100 * (tx-mini)) / (maxi-mini));
5857 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
5859 + if (tx <= mini) return 100;
5861 + if (tx >= maxi) return 0;
5863 + return ((100 * (maxi - tx)) / (maxi - mini));
5868 +ip6t_fuzzy_match(const struct sk_buff *pskb,
5869 + const struct net_device *in,
5870 + const struct net_device *out,
5871 + const void *matchinfo,
5874 + u_int16_t datalen,
5877 + /* From userspace */
5879 + struct ip6t_fuzzy_info *info = (struct ip6t_fuzzy_info *) matchinfo;
5881 + u_int8_t random_number;
5882 + unsigned long amount;
5883 + u_int8_t howhigh, howlow;
5886 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
5888 + info->bytes_total += pskb->len;
5889 + info->packets_total++;
5891 + info->present_time = jiffies;
5893 + if (info->present_time >= info->previous_time)
5894 + amount = info->present_time - info->previous_time;
5896 + /* There was a transition : I choose to re-sample
5897 + and keep the old acceptance rate...
5901 + info->previous_time = info->present_time;
5902 + info->bytes_total = info->packets_total = 0;
5905 + if ( amount > HZ/10) {/* More than 100 ms elapsed ... */
5907 + info->mean_rate = (u_int32_t) ((HZ * info->packets_total) \
5910 + info->previous_time = info->present_time;
5911 + info->bytes_total = info->packets_total = 0;
5913 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
5914 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
5916 + info->acceptance_rate = (u_int8_t) \
5917 + (howhigh * PAR_LOW + PAR_HIGH * howlow);
5919 + /* In fact, the above defuzzification would require a denominator
5920 + * proportional to (howhigh+howlow) but, in this particular case,
5921 + * that expression is constant.
5922 + * An imediate consequence is that it is not necessary to call
5923 + * both mf_high and mf_low - but to keep things understandable,
5929 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
5932 + if (info->acceptance_rate < 100)
5934 + get_random_bytes((void *)(&random_number), 1);
5936 + /* If within the acceptance , it can pass => don't match */
5937 + if (random_number <= (255 * info->acceptance_rate) / 100)
5940 + return 1; /* It can't pass (It matches) */
5943 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
5948 +ip6t_fuzzy_checkentry(const char *tablename,
5949 + const struct ip6t_ip6 *ip,
5951 + unsigned int matchsize,
5952 + unsigned int hook_mask)
5955 + const struct ip6t_fuzzy_info *info = matchinfo;
5957 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info))) {
5958 + printk("ip6t_fuzzy: matchsize %u != %u\n", matchsize,
5959 + IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info)));
5963 + if ((info->minimum_rate < MINFUZZYRATE) || (info->maximum_rate > MAXFUZZYRATE)
5964 + || (info->minimum_rate >= info->maximum_rate)) {
5965 + printk("ip6t_fuzzy: BAD limits , please verify !!!\n");
5972 +static struct ip6t_match ip6t_fuzzy_reg = {
5976 + ip6t_fuzzy_checkentry,
5980 +static int __init init(void)
5982 + if (ip6t_register_match(&ip6t_fuzzy_reg))
5988 +static void __exit fini(void)
5990 + ip6t_unregister_match(&ip6t_fuzzy_reg);
5995 diff -Nur linux-2.6.3-rc3.org/net/ipv6/netfilter/ip6t_nth.c linux-2.6.3-rc3/net/ipv6/netfilter/ip6t_nth.c
5996 --- linux-2.6.3-rc3.org/net/ipv6/netfilter/ip6t_nth.c 1970-01-01 01:00:00.000000000 +0100
5997 +++ linux-2.6.3-rc3/net/ipv6/netfilter/ip6t_nth.c 2004-02-16 11:07:18.803453352 +0100
6000 + This is a module which is used for match support for every Nth packet
6001 + This file is distributed under the terms of the GNU General Public
6002 + License (GPL). Copies of the GPL can be obtained from:
6003 + ftp://prep.ai.mit.edu/pub/gnu/GPL
6005 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
6006 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
6007 + * added support for multiple counters
6008 + * added support for matching on individual packets
6009 + in the counter cycle
6010 + 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
6014 +#include <linux/module.h>
6015 +#include <linux/skbuff.h>
6016 +#include <linux/ip.h>
6017 +#include <net/tcp.h>
6018 +#include <linux/spinlock.h>
6019 +#include <linux/netfilter_ipv6/ip6_tables.h>
6020 +#include <linux/netfilter_ipv6/ip6t_nth.h>
6022 +MODULE_LICENSE("GPL");
6025 + * State information.
6032 +static struct state states[IP6T_NTH_NUM_COUNTERS];
6035 +ip6t_nth_match(const struct sk_buff *pskb,
6036 + const struct net_device *in,
6037 + const struct net_device *out,
6038 + const void *matchinfo,
6041 + u_int16_t datalen,
6044 + /* Parameters from userspace */
6045 + const struct ip6t_nth_info *info = matchinfo;
6046 + unsigned counter = info->counter;
6047 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
6049 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
6053 + spin_lock(&states[counter].lock);
6055 + /* Are we matching every nth packet?*/
6056 + if (info->packet == 0xFF)
6058 + /* We're matching every nth packet and only every nth packet*/
6059 + /* Do we match or invert match? */
6060 + if (info->not == 0)
6062 + if (states[counter].number == 0)
6064 + ++states[counter].number;
6067 + if (states[counter].number >= info->every)
6068 + states[counter].number = 0; /* reset the counter */
6070 + ++states[counter].number;
6075 + if (states[counter].number == 0)
6077 + ++states[counter].number;
6080 + if (states[counter].number >= info->every)
6081 + states[counter].number = 0;
6083 + ++states[counter].number;
6089 + /* We're using the --packet, so there must be a rule for every value */
6090 + if (states[counter].number == info->packet)
6092 + /* only increment the counter when a match happens */
6093 + if (states[counter].number >= info->every)
6094 + states[counter].number = 0; /* reset the counter */
6096 + ++states[counter].number;
6105 + spin_unlock(&states[counter].lock);
6109 + spin_unlock(&states[counter].lock);
6114 +ip6t_nth_checkentry(const char *tablename,
6115 + const struct ip6t_ip6 *e,
6117 + unsigned int matchsize,
6118 + unsigned int hook_mask)
6120 + /* Parameters from userspace */
6121 + const struct ip6t_nth_info *info = matchinfo;
6122 + unsigned counter = info->counter;
6123 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
6125 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
6129 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_nth_info))) {
6130 + printk("nth: matchsize %u != %u\n", matchsize,
6131 + IP6T_ALIGN(sizeof(struct ip6t_nth_info)));
6135 + states[counter].number = info->startat;
6140 +static struct ip6t_match ip6t_nth_reg = {
6144 + ip6t_nth_checkentry,
6148 +static int __init init(void)
6151 + memset(&states, 0, sizeof(states));
6152 + if (ip6t_register_match(&ip6t_nth_reg))
6155 + for(counter = 0; counter < IP6T_NTH_NUM_COUNTERS; counter++)
6157 + spin_lock_init(&(states[counter].lock));
6160 + printk("ip6t_nth match loaded\n");
6164 +static void __exit fini(void)
6166 + ip6t_unregister_match(&ip6t_nth_reg);
6167 + printk("ip6t_nth match unloaded\n");
6172 diff -Nur linux-2.6.3-rc3.org/net/ipv6/netfilter/ip6t_random.c linux-2.6.3-rc3/net/ipv6/netfilter/ip6t_random.c
6173 --- linux-2.6.3-rc3.org/net/ipv6/netfilter/ip6t_random.c 1970-01-01 01:00:00.000000000 +0100
6174 +++ linux-2.6.3-rc3/net/ipv6/netfilter/ip6t_random.c 2004-02-16 11:07:24.379118074 +0100
6177 + This is a module which is used for a "random" match support.
6178 + This file is distributed under the terms of the GNU General Public
6179 + License (GPL). Copies of the GPL can be obtained from:
6180 + ftp://prep.ai.mit.edu/pub/gnu/GPL
6182 + 2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
6183 + 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
6186 +#include <linux/module.h>
6187 +#include <linux/skbuff.h>
6188 +#include <linux/ip.h>
6189 +#include <linux/random.h>
6190 +#include <net/tcp.h>
6191 +#include <linux/spinlock.h>
6192 +#include <linux/netfilter_ipv6/ip6_tables.h>
6193 +#include <linux/netfilter_ipv6/ip6t_random.h>
6195 +MODULE_LICENSE("GPL");
6198 +ip6t_rand_match(const struct sk_buff *pskb,
6199 + const struct net_device *in,
6200 + const struct net_device *out,
6201 + const void *matchinfo,
6204 + u_int16_t datalen,
6207 + /* Parameters from userspace */
6208 + const struct ip6t_rand_info *info = matchinfo;
6209 + u_int8_t random_number;
6211 + /* get 1 random number from the kernel random number generation routine */
6212 + get_random_bytes((void *)(&random_number), 1);
6214 + /* Do we match ? */
6215 + if (random_number <= info->average)
6222 +ip6t_rand_checkentry(const char *tablename,
6223 + const struct ip6t_ip6 *e,
6225 + unsigned int matchsize,
6226 + unsigned int hook_mask)
6228 + /* Parameters from userspace */
6229 + const struct ip6t_rand_info *info = matchinfo;
6231 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_rand_info))) {
6232 + printk("ip6t_random: matchsize %u != %u\n", matchsize,
6233 + IP6T_ALIGN(sizeof(struct ip6t_rand_info)));
6237 + /* must be 1 <= average % <= 99 */
6238 + /* 1 x 2.55 = 2 */
6239 + /* 99 x 2.55 = 252 */
6240 + if ((info->average < 2) || (info->average > 252)) {
6241 + printk("ip6t_random: invalid average %u\n", info->average);
6248 +static struct ip6t_match ip6t_rand_reg = {
6252 + ip6t_rand_checkentry,
6256 +static int __init init(void)
6258 + if (ip6t_register_match(&ip6t_rand_reg))
6261 + printk("ip6t_random match loaded\n");
6265 +static void __exit fini(void)
6267 + ip6t_unregister_match(&ip6t_rand_reg);
6268 + printk("ip6t_random match unloaded\n");