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 */
610 +#define IP6T_HL_MAXMODE IP6T_HL_DEC
612 +struct ip6t_HL_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);
1238 +EXPORT_SYMBOL(ip_pool_match);
1240 +static int pool_change(ip_pool_t index, u_int32_t addr, int isdel)
1242 + struct ip_pool *pool;
1245 + pool = lookup(index);
1246 + if ( !pool || !pool->members
1247 + || addr < pool->first_ip || addr > pool->last_ip)
1249 + read_lock_bh(&pool->lock);
1250 + if (pool->members && addr >= pool->first_ip && addr <= pool->last_ip) {
1251 + addr -= pool->first_ip;
1253 + ? (0 != test_and_clear_bit(addr, pool->members))
1254 + : (0 != test_and_set_bit(addr, pool->members));
1256 + read_unlock_bh(&pool->lock);
1260 +int ip_pool_mod(ip_pool_t index, u_int32_t addr, int isdel)
1262 + int res = pool_change(index,addr,isdel);
1264 + if (!isdel) res = !res;
1267 +EXPORT_SYMBOL(ip_pool_mod);
1269 +static inline int bitmap_bytes(u_int32_t a, u_int32_t b)
1271 + return 4*((((b-a+8)/8)+3)/4);
1274 +static inline int poolbytes(ip_pool_t index)
1276 + struct ip_pool *pool = lookup(index);
1278 + return pool ? bitmap_bytes(pool->first_ip, pool->last_ip) : 0;
1281 +static int setpool(
1287 + struct ip_pool_request req;
1289 + DP("ip_pool:setpool: optval=%d, user=%p, len=%d\n", optval, user, len);
1290 + if (!capable(CAP_NET_ADMIN))
1292 + if (optval != SO_IP_POOL)
1294 + if (len != sizeof(req))
1296 + if (copy_from_user(&req, user, sizeof(req)) != 0)
1298 + printk("obsolete op - upgrade your ippool(8) utility.\n");
1302 +static int getpool(
1308 + struct ip_pool_request req;
1309 + struct ip_pool *pool;
1315 + DP("ip_pool:getpool: optval=%d, user=%p\n", optval, user);
1316 + if (!capable(CAP_NET_ADMIN))
1318 + if (optval != SO_IP_POOL)
1320 + if (*len != sizeof(req)) {
1323 + if (copy_from_user(&req, user, sizeof(req)) != 0)
1325 + DP("ip_pool:getpool op=%d, index=%d\n", req.op, req.index);
1326 + if (req.op < IP_POOL_BAD001) {
1327 + printk("obsolete op - upgrade your ippool(8) utility.\n");
1331 + case IP_POOL_HIGH_NR:
1332 + DP("ip_pool HIGH_NR\n");
1333 + req.index = IP_POOL_NONE;
1334 + for (i=0; i<nr_pool; i++)
1335 + if (POOL[i].members)
1337 + return copy_to_user(user, &req, sizeof(req));
1338 + case IP_POOL_LOOKUP:
1339 + DP("ip_pool LOOKUP\n");
1340 + pool = lookup(req.index);
1343 + if (!pool->members)
1345 + req.addr = htonl(pool->first_ip);
1346 + req.addr2 = htonl(pool->last_ip);
1347 + return copy_to_user(user, &req, sizeof(req));
1348 + case IP_POOL_USAGE:
1349 + DP("ip_pool USE\n");
1350 + pool = lookup(req.index);
1353 + if (!pool->members)
1355 + req.addr = pool->nr_use;
1356 + req.addr2 = pool->nr_match;
1357 + return copy_to_user(user, &req, sizeof(req));
1358 + case IP_POOL_TEST_ADDR:
1359 + DP("ip_pool TEST 0x%08x\n", req.addr);
1360 + pool = lookup(req.index);
1364 + read_lock_bh(&pool->lock);
1365 + if (!pool->members) {
1366 + DP("ip_pool TEST_ADDR no members in pool\n");
1368 + goto unlock_and_return_res;
1370 + req.addr = ntohl(req.addr);
1371 + if (req.addr < pool->first_ip) {
1372 + DP("ip_pool TEST_ADDR address < pool bounds\n");
1374 + goto unlock_and_return_res;
1376 + if (req.addr > pool->last_ip) {
1377 + DP("ip_pool TEST_ADDR address > pool bounds\n");
1379 + goto unlock_and_return_res;
1381 + req.addr = (0 != test_bit((req.addr - pool->first_ip),
1383 + read_unlock_bh(&pool->lock);
1384 + return copy_to_user(user, &req, sizeof(req));
1385 + case IP_POOL_FLUSH:
1386 + DP("ip_pool FLUSH not yet implemented.\n");
1388 + case IP_POOL_DESTROY:
1389 + DP("ip_pool DESTROY not yet implemented.\n");
1391 + case IP_POOL_INIT:
1392 + DP("ip_pool INIT 0x%08x-0x%08x\n", req.addr, req.addr2);
1393 + pool = lookup(req.index);
1396 + req.addr = ntohl(req.addr);
1397 + req.addr2 = ntohl(req.addr2);
1398 + if (req.addr > req.addr2) {
1399 + DP("ip_pool INIT bad ip range\n");
1402 + newbytes = bitmap_bytes(req.addr, req.addr2);
1403 + newmembers = kmalloc(newbytes, GFP_KERNEL);
1404 + if (!newmembers) {
1405 + DP("ip_pool INIT out of mem for %d bytes\n", newbytes);
1408 + memset(newmembers, 0, newbytes);
1409 + write_lock_bh(&pool->lock);
1410 + if (pool->members) {
1411 + DP("ip_pool INIT pool %d exists\n", req.index);
1412 + kfree(newmembers);
1414 + goto unlock_and_return_res;
1416 + pool->first_ip = req.addr;
1417 + pool->last_ip = req.addr2;
1419 + pool->nr_match = 0;
1420 + pool->members = newmembers;
1421 + write_unlock_bh(&pool->lock);
1423 + case IP_POOL_ADD_ADDR:
1424 + DP("ip_pool ADD_ADDR 0x%08x\n", req.addr);
1425 + req.addr = pool_change(req.index, ntohl(req.addr), 0);
1426 + return copy_to_user(user, &req, sizeof(req));
1427 + case IP_POOL_DEL_ADDR:
1428 + DP("ip_pool DEL_ADDR 0x%08x\n", req.addr);
1429 + req.addr = pool_change(req.index, ntohl(req.addr), 1);
1430 + return copy_to_user(user, &req, sizeof(req));
1432 + DP("ip_pool:getpool bad op %d\n", req.op);
1437 +unlock_and_return_res:
1439 + read_unlock_bh(&pool->lock);
1443 +static struct nf_sockopt_ops so_pool
1444 += { { NULL, NULL }, PF_INET,
1445 + SO_IP_POOL, SO_IP_POOL+1, &setpool,
1446 + SO_IP_POOL, SO_IP_POOL+1, &getpool,
1449 +MODULE_PARM(nr_pool, "i");
1451 +static int __init init(void)
1456 + if (nr_pool < 1) {
1457 + printk("ip_pool module init: bad nr_pool %d\n", nr_pool);
1460 + POOL = kmalloc(nr_pool * sizeof(*POOL), GFP_KERNEL);
1462 + printk("ip_pool module init: out of memory for nr_pool %d\n",
1466 + for (i=0; i<nr_pool; i++) {
1467 + POOL[i].first_ip = 0;
1468 + POOL[i].last_ip = 0;
1469 + POOL[i].members = 0;
1470 + POOL[i].nr_use = 0;
1471 + POOL[i].nr_match = 0;
1472 + POOL[i].lock = RW_LOCK_UNLOCKED;
1474 + res = nf_register_sockopt(&so_pool);
1475 + DP("ip_pool:init %d pools, result %d\n", nr_pool, res);
1483 +static void __exit fini(void)
1487 + DP("ip_pool:fini BYEBYE\n");
1488 + nf_unregister_sockopt(&so_pool);
1489 + for (i=0; i<nr_pool; i++) {
1490 + if (POOL[i].members) {
1491 + kfree(POOL[i].members);
1492 + POOL[i].members = 0;
1497 + DP("ip_pool:fini these are the famous last words\n");
1503 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
1504 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 1970-01-01 01:00:00.000000000 +0100
1505 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 2004-02-16 11:06:57.518550655 +0100
1508 + * Strip all IP options in the IP packet header.
1510 + * (C) 2001 by Fabrice MARIE <fabrice@netfilter.org>
1511 + * This software is distributed under GNU GPL v2, 1991
1514 +#include <linux/module.h>
1515 +#include <linux/skbuff.h>
1516 +#include <linux/ip.h>
1517 +#include <net/checksum.h>
1519 +#include <linux/netfilter_ipv4/ip_tables.h>
1521 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
1522 +MODULE_DESCRIPTION("Strip all options in IPv4 packets");
1523 +MODULE_LICENSE("GPL");
1525 +static unsigned int
1526 +target(struct sk_buff **pskb,
1527 + unsigned int hooknum,
1528 + const struct net_device *in,
1529 + const struct net_device *out,
1530 + const void *targinfo,
1533 + struct iphdr *iph = (*pskb)->nh.iph;
1534 + struct sk_buff *skb = (*pskb);
1535 + struct ip_options * opt;
1536 + unsigned char * optiph = skb->nh.raw;
1537 + int l = ((struct ip_options *)(&(IPCB(skb)->opt)))->optlen;
1540 + /* if no options in packet then nothing to clear. */
1541 + if (iph->ihl * 4 == sizeof(struct iphdr))
1542 + return IPT_CONTINUE;
1544 + /* else clear all options */
1545 + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
1546 + memset(optiph+sizeof(struct iphdr), IPOPT_NOOP, l);
1547 + opt = &(IPCB(skb)->opt);
1551 + skb->nfcache |= NFC_ALTERED;
1553 + return IPT_CONTINUE;
1557 +checkentry(const char *tablename,
1558 + const struct ipt_entry *e,
1560 + unsigned int targinfosize,
1561 + unsigned int hook_mask)
1563 + if (strcmp(tablename, "mangle")) {
1564 + printk(KERN_WARNING "IPV4OPTSSTRIP: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1567 + /* nothing else to check because no parameters */
1571 +static struct ipt_target ipt_ipv4optsstrip_reg
1572 += { { NULL, NULL }, "IPV4OPTSSTRIP", target, checkentry, NULL, THIS_MODULE };
1574 +static int __init init(void)
1576 + if (ipt_register_target(&ipt_ipv4optsstrip_reg))
1578 + printk("ipt_IPV4OPTSSTRIP loaded\n");
1583 +static void __exit fini(void)
1585 + ipt_unregister_target(&ipt_ipv4optsstrip_reg);
1586 + printk("ipt_IPV4OPTSSTRIP unloaded\n");
1591 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
1592 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_NETLINK.c 1970-01-01 01:00:00.000000000 +0100
1593 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_NETLINK.c 2004-02-16 11:07:05.880548139 +0100
1595 +#include <linux/module.h>
1596 +#include <linux/version.h>
1597 +#include <linux/config.h>
1598 +#include <linux/socket.h>
1599 +#include <linux/skbuff.h>
1600 +#include <linux/kernel.h>
1601 +#include <linux/netlink.h>
1602 +#include <linux/netdevice.h>
1603 +#include <linux/mm.h>
1604 +#include <linux/socket.h>
1605 +#include <linux/netfilter_ipv4/ip_tables.h>
1606 +#include <linux/netfilter_ipv4/ipt_NETLINK.h>
1607 +#include <net/sock.h>
1609 +MODULE_AUTHOR("Gianni Tedesco <gianni@ecsc.co.uk>");
1610 +MODULE_DESCRIPTION("Provides iptables NETLINK target similar to ipchains -o");
1611 +MODULE_LICENSE("GPL");
1614 +#define DEBUGP printk
1616 +#define DEBUGP(format, args...)
1619 +static struct sock *ipfwsk;
1621 +static unsigned int ipt_netlink_target(struct sk_buff **pskb,
1622 + unsigned int hooknum,
1623 + const struct net_device *in,
1624 + const struct net_device *out,
1625 + const void *targinfo, void *userinfo)
1627 + struct ipt_nldata *nld = (struct ipt_nldata *)targinfo;
1628 + struct iphdr *ip = (*pskb)->nh.iph;
1629 + struct sk_buff *outskb;
1630 + struct netlink_t nlhdr;
1633 + /* Allocate a socket buffer */
1634 + if ( MASK(nld->flags, USE_SIZE) )
1635 + len = nld->size+sizeof(nlhdr);
1637 + len = ntohs(ip->tot_len)+sizeof(nlhdr);
1639 + outskb=alloc_skb(len, GFP_ATOMIC);
1644 + if ( MASK(nld->flags, USE_MARK) )
1645 + nlhdr.mark=(*pskb)->nfmark=nld->mark;
1647 + nlhdr.mark=(*pskb)->nfmark;
1649 + if ( in && in->name ) {
1650 + strncpy((char *)&nlhdr.iface, in->name, IFNAMSIZ);
1651 + }else if ( out && out->name ){
1652 + strncpy((char *)&nlhdr.iface, out->name, IFNAMSIZ);
1655 + skb_put(outskb, len);
1656 + memcpy(outskb->data, &nlhdr, sizeof(nlhdr));
1657 + memcpy((outskb->data)+sizeof(nlhdr), ip, len-sizeof(nlhdr));
1658 + netlink_broadcast(ipfwsk, outskb, 0, ~0, GFP_ATOMIC);
1660 + if (net_ratelimit())
1661 + printk(KERN_WARNING "ipt_NETLINK: packet drop due to netlink failure\n");
1664 + if ( MASK(nld->flags, USE_DROP) )
1667 + return IPT_CONTINUE;
1670 +static int ipt_netlink_checkentry(const char *tablename,
1671 + const struct ipt_entry *e,
1673 + unsigned int targinfosize,
1674 + unsigned int hookmask)
1676 + //struct ipt_nldata *nld = (struct ipt_nldata *)targinfo;
1681 +static struct ipt_target ipt_netlink_reg = {
1684 + ipt_netlink_target,
1685 + ipt_netlink_checkentry,
1690 +static int __init init(void)
1692 + DEBUGP("ipt_NETLINK: init module\n");
1694 + if (ipt_register_target(&ipt_netlink_reg) != 0) {
1698 + if ( !(ipfwsk=netlink_kernel_create(NETLINK_FIREWALL, NULL)) ){
1705 +static void __exit fini(void)
1707 + DEBUGP("ipt_NETLINK: cleanup_module\n");
1708 + ipt_unregister_target(&ipt_netlink_reg);
1709 +// if(ipfwsk->socket) sock_release(ipfwsk->socket);
1714 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
1715 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_POOL.c 1970-01-01 01:00:00.000000000 +0100
1716 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_POOL.c 2004-02-16 11:07:21.518803072 +0100
1718 +/* ipt_POOL.c - netfilter target to manipulate IP pools
1720 + * This target can be used almost everywhere. It acts on some specified
1721 + * IP pool, adding or deleting some IP address in the pool. The address
1722 + * can be either the source (--addsrc, --delsrc), or destination (--add/deldst)
1723 + * of the packet under inspection.
1725 + * The target normally returns IPT_CONTINUE.
1728 +#include <linux/types.h>
1729 +#include <linux/ip.h>
1730 +#include <linux/timer.h>
1731 +#include <linux/module.h>
1732 +#include <linux/netfilter.h>
1733 +#include <linux/netdevice.h>
1734 +#include <linux/if.h>
1735 +#include <linux/inetdevice.h>
1736 +#include <net/protocol.h>
1737 +#include <net/checksum.h>
1738 +#include <linux/netfilter_ipv4.h>
1739 +#include <linux/netfilter_ipv4/ip_nat_rule.h>
1740 +#include <linux/netfilter_ipv4/ipt_pool.h>
1743 +#define DEBUGP printk
1745 +#define DEBUGP(format, args...)
1748 +/*** NOTE NOTE NOTE NOTE ***
1750 +** By sheer luck, I get away with using the "struct ipt_pool_info", as defined
1751 +** in <linux/netfilter_ipv4/ipt_pool.h>, both as the match and target info.
1752 +** Here, in the target implementation, ipt_pool_info.src, if not IP_POOL_NONE,
1753 +** is modified for the source IP address of the packet under inspection.
1754 +** The same way, the ipt_pool_info.dst pool is modified for the destination.
1756 +** The address is added to the pool normally. However, if IPT_POOL_DEL_dir
1757 +** flag is set in ipt_pool_info.flags, the address is deleted from the pool.
1759 +** If a modification was done to the pool, we possibly return ACCEPT or DROP,
1760 +** if the right IPT_POOL_MOD_dir_ACCEPT or _MOD_dir_DROP flags are set.
1761 +** The IPT_POOL_INV_MOD_dir flag inverts the sense of the check (i.e. the
1762 +** ACCEPT and DROP flags are evaluated when the pool was not modified.)
1766 +do_check(const char *tablename,
1767 + const struct ipt_entry *e,
1769 + unsigned int targinfosize,
1770 + unsigned int hook_mask)
1772 + const struct ipt_pool_info *ipi = targinfo;
1774 + if (targinfosize != IPT_ALIGN(sizeof(*ipi))) {
1775 + DEBUGP("POOL_check: size %u.\n", targinfosize);
1778 + DEBUGP("ipt_POOL:do_check(%d,%d,%d)\n",ipi->src,ipi->dst,ipi->flags);
1782 +static unsigned int
1783 +do_target(struct sk_buff **pskb,
1784 + unsigned int hooknum,
1785 + const struct net_device *in,
1786 + const struct net_device *out,
1787 + const void *targinfo,
1790 + const struct ipt_pool_info *ipi = targinfo;
1792 + unsigned int verdict = IPT_CONTINUE;
1794 + if (ipi->src != IP_POOL_NONE) {
1795 + modified = ip_pool_mod(ipi->src, ntohl((*pskb)->nh.iph->saddr),
1796 + ipi->flags & IPT_POOL_DEL_SRC);
1797 + if (!!modified ^ !!(ipi->flags & IPT_POOL_INV_MOD_SRC)) {
1798 + if (ipi->flags & IPT_POOL_MOD_SRC_ACCEPT)
1799 + verdict = NF_ACCEPT;
1800 + else if (ipi->flags & IPT_POOL_MOD_SRC_DROP)
1801 + verdict = NF_DROP;
1804 + if (verdict == IPT_CONTINUE && ipi->dst != IP_POOL_NONE) {
1805 + modified = ip_pool_mod(ipi->dst, ntohl((*pskb)->nh.iph->daddr),
1806 + ipi->flags & IPT_POOL_DEL_DST);
1807 + if (!!modified ^ !!(ipi->flags & IPT_POOL_INV_MOD_DST)) {
1808 + if (ipi->flags & IPT_POOL_MOD_DST_ACCEPT)
1809 + verdict = NF_ACCEPT;
1810 + else if (ipi->flags & IPT_POOL_MOD_DST_DROP)
1811 + verdict = NF_DROP;
1817 +static struct ipt_target pool_reg
1818 += { { NULL, NULL }, "POOL", do_target, do_check, NULL, THIS_MODULE };
1820 +static int __init init(void)
1822 + DEBUGP("init ipt_POOL\n");
1823 + return ipt_register_target(&pool_reg);
1826 +static void __exit fini(void)
1828 + DEBUGP("fini ipt_POOL\n");
1829 + ipt_unregister_target(&pool_reg);
1834 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
1835 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_TTL.c 1970-01-01 01:00:00.000000000 +0100
1836 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_TTL.c 2004-02-16 11:07:09.253740328 +0100
1838 +/* TTL modification target for IP tables
1839 + * (C) 2000 by Harald Welte <laforge@gnumonks.org>
1843 + * This software is distributed under the terms of GNU GPL
1846 +#include <linux/module.h>
1847 +#include <linux/skbuff.h>
1848 +#include <linux/ip.h>
1849 +#include <net/checksum.h>
1851 +#include <linux/netfilter_ipv4/ip_tables.h>
1852 +#include <linux/netfilter_ipv4/ipt_TTL.h>
1854 +MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
1855 +MODULE_DESCRIPTION("IP tables TTL modification module");
1856 +MODULE_LICENSE("GPL");
1858 +static unsigned int ipt_ttl_target(struct sk_buff **pskb, unsigned int hooknum,
1859 + const struct net_device *in, const struct net_device *out,
1860 + const void *targinfo, void *userinfo)
1862 + struct iphdr *iph = (*pskb)->nh.iph;
1863 + const struct ipt_TTL_info *info = targinfo;
1864 + u_int16_t diffs[2];
1867 + switch (info->mode) {
1869 + new_ttl = info->ttl;
1872 + new_ttl = iph->ttl + info->ttl;
1873 + if (new_ttl > 255)
1877 + new_ttl = iph->ttl + info->ttl;
1882 + new_ttl = iph->ttl;
1886 + if (new_ttl != iph->ttl) {
1887 + diffs[0] = htons(((unsigned)iph->ttl) << 8) ^ 0xFFFF;
1888 + iph->ttl = new_ttl;
1889 + diffs[1] = htons(((unsigned)iph->ttl) << 8);
1890 + iph->check = csum_fold(csum_partial((char *)diffs,
1892 + iph->check^0xFFFF));
1893 + (*pskb)->nfcache |= NFC_ALTERED;
1896 + return IPT_CONTINUE;
1899 +static int ipt_ttl_checkentry(const char *tablename,
1900 + const struct ipt_entry *e,
1902 + unsigned int targinfosize,
1903 + unsigned int hook_mask)
1905 + struct ipt_TTL_info *info = targinfo;
1907 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_TTL_info))) {
1908 + printk(KERN_WARNING "TTL: targinfosize %u != %Zu\n",
1910 + IPT_ALIGN(sizeof(struct ipt_TTL_info)));
1914 + if (strcmp(tablename, "mangle")) {
1915 + printk(KERN_WARNING "TTL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1919 + if (info->mode > IPT_TTL_MAXMODE) {
1920 + printk(KERN_WARNING "TTL: invalid or unknown Mode %u\n",
1925 + if ((info->mode != IPT_TTL_SET) && (info->ttl == 0)) {
1926 + printk(KERN_WARNING "TTL: increment/decrement doesn't make sense with value 0\n");
1933 +static struct ipt_target ipt_TTL = { { NULL, NULL }, "TTL",
1934 + ipt_ttl_target, ipt_ttl_checkentry, NULL, THIS_MODULE };
1936 +static int __init init(void)
1938 + return ipt_register_target(&ipt_TTL);
1941 +static void __exit fini(void)
1943 + ipt_unregister_target(&ipt_TTL);
1948 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
1949 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_connlimit.c 1970-01-01 01:00:00.000000000 +0100
1950 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_connlimit.c 2004-02-16 11:07:11.549190614 +0100
1953 + * netfilter module to limit the number of parallel tcp
1954 + * connections per IP address.
1955 + * (c) 2000 Gerd Knorr <kraxel@bytesex.org>
1956 + * Nov 2002: Martin Bene <martin.bene@icomedias.com>:
1957 + * only ignore TIME_WAIT or gone connections
1961 + * Kernel module to match connection tracking information.
1962 + * GPL (C) 1999 Rusty Russell (rusty@rustcorp.com.au).
1964 +#include <linux/module.h>
1965 +#include <linux/skbuff.h>
1966 +#include <linux/list.h>
1967 +#include <linux/netfilter_ipv4/ip_conntrack.h>
1968 +#include <linux/netfilter_ipv4/ip_conntrack_core.h>
1969 +#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
1970 +#include <linux/netfilter_ipv4/ip_tables.h>
1971 +#include <linux/netfilter_ipv4/ipt_connlimit.h>
1975 +MODULE_LICENSE("GPL");
1977 +/* we'll save the tuples of all connections we care about */
1978 +struct ipt_connlimit_conn
1980 + struct list_head list;
1981 + struct ip_conntrack_tuple tuple;
1984 +struct ipt_connlimit_data {
1986 + struct list_head iphash[256];
1989 +static int ipt_iphash(u_int32_t addr)
1993 + hash = addr & 0xff;
1994 + hash ^= (addr >> 8) & 0xff;
1995 + hash ^= (addr >> 16) & 0xff;
1996 + hash ^= (addr >> 24) & 0xff;
2000 +static int count_them(struct ipt_connlimit_data *data,
2001 + u_int32_t addr, u_int32_t mask,
2002 + struct ip_conntrack *ct)
2005 + const static char *tcp[] = { "none", "established", "syn_sent", "syn_recv",
2006 + "fin_wait", "time_wait", "close", "close_wait",
2007 + "last_ack", "listen" };
2009 + int addit = 1, matches = 0;
2010 + struct ip_conntrack_tuple tuple;
2011 + struct ip_conntrack_tuple_hash *found;
2012 + struct ipt_connlimit_conn *conn;
2013 + struct list_head *hash,*lh;
2015 + spin_lock(&data->lock);
2016 + tuple = ct->tuplehash[0].tuple;
2017 + hash = &data->iphash[ipt_iphash(addr & mask)];
2019 + /* check the saved connections */
2020 + for (lh = hash->next; lh != hash; lh = lh->next) {
2021 + conn = list_entry(lh,struct ipt_connlimit_conn,list);
2022 + found = ip_conntrack_find_get(&conn->tuple,ct);
2023 + if (0 == memcmp(&conn->tuple,&tuple,sizeof(tuple)) &&
2025 + found->ctrack->proto.tcp.state != TCP_CONNTRACK_TIME_WAIT) {
2026 + /* Just to be sure we have it only once in the list.
2027 + We should'nt see tuples twice unless someone hooks this
2028 + into a table without "-p tcp --syn" */
2032 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d %s\n",
2033 + ipt_iphash(addr & mask),
2034 + NIPQUAD(conn->tuple.src.ip), ntohs(conn->tuple.src.u.tcp.port),
2035 + NIPQUAD(conn->tuple.dst.ip), ntohs(conn->tuple.dst.u.tcp.port),
2036 + (NULL != found) ? tcp[found->ctrack->proto.tcp.state] : "gone");
2038 + if (NULL == found) {
2039 + /* this one is gone */
2041 + list_del(lh->next);
2045 + if (found->ctrack->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT) {
2046 + /* we don't care about connections which are
2047 + closed already -> ditch it */
2049 + list_del(lh->next);
2051 + nf_conntrack_put(&found->ctrack->infos[0]);
2054 + if ((addr & mask) == (conn->tuple.src.ip & mask)) {
2055 + /* same source IP address -> be counted! */
2058 + nf_conntrack_put(&found->ctrack->infos[0]);
2061 + /* save the new connection in our list */
2063 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d new\n",
2064 + ipt_iphash(addr & mask),
2065 + NIPQUAD(tuple.src.ip), ntohs(tuple.src.u.tcp.port),
2066 + NIPQUAD(tuple.dst.ip), ntohs(tuple.dst.u.tcp.port));
2068 + conn = kmalloc(sizeof(*conn),GFP_ATOMIC);
2071 + memset(conn,0,sizeof(*conn));
2072 + INIT_LIST_HEAD(&conn->list);
2073 + conn->tuple = tuple;
2074 + list_add(&conn->list,hash);
2077 + spin_unlock(&data->lock);
2082 +match(const struct sk_buff *skb,
2083 + const struct net_device *in,
2084 + const struct net_device *out,
2085 + const void *matchinfo,
2088 + u_int16_t datalen,
2091 + const struct ipt_connlimit_info *info = matchinfo;
2092 + int connections, match;
2093 + struct ip_conntrack *ct;
2094 + enum ip_conntrack_info ctinfo;
2096 + ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
2098 + printk("ipt_connlimit: Oops: invalid ct state ?\n");
2102 + connections = count_them(info->data,skb->nh.iph->saddr,info->mask,ct);
2103 + if (-1 == connections) {
2104 + printk("ipt_connlimit: Hmm, kmalloc failed :-(\n");
2105 + *hotdrop = 1; /* let's free some memory :-) */
2108 + match = (info->inverse) ? (connections <= info->limit) : (connections > info->limit);
2110 + printk("ipt_connlimit: src=%u.%u.%u.%u mask=%u.%u.%u.%u "
2111 + "connections=%d limit=%d match=%s\n",
2112 + NIPQUAD(skb->nh.iph->saddr), NIPQUAD(info->mask),
2113 + connections, info->limit, match ? "yes" : "no");
2119 +static int check(const char *tablename,
2120 + const struct ipt_ip *ip,
2122 + unsigned int matchsize,
2123 + unsigned int hook_mask)
2125 + struct ipt_connlimit_info *info = matchinfo;
2129 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_connlimit_info)))
2132 + /* refuse anything but tcp */
2133 + if (ip->proto != IPPROTO_TCP)
2136 + /* init private data */
2137 + info->data = kmalloc(sizeof(struct ipt_connlimit_data),GFP_KERNEL);
2138 + spin_lock_init(&(info->data->lock));
2139 + for (i = 0; i < 256; i++)
2140 + INIT_LIST_HEAD(&(info->data->iphash[i]));
2145 +static void destroy(void *matchinfo, unsigned int matchinfosize)
2147 + struct ipt_connlimit_info *info = matchinfo;
2148 + struct ipt_connlimit_conn *conn;
2149 + struct list_head *hash;
2153 + for (i = 0; i < 256; i++) {
2154 + hash = &(info->data->iphash[i]);
2155 + while (hash != hash->next) {
2156 + conn = list_entry(hash->next,struct ipt_connlimit_conn,list);
2157 + list_del(hash->next);
2161 + kfree(info->data);
2164 +static struct ipt_match connlimit_match
2165 += { { NULL, NULL }, "connlimit", &match, &check, &destroy, THIS_MODULE };
2167 +static int __init init(void)
2169 + return ipt_register_match(&connlimit_match);
2172 +static void __exit fini(void)
2174 + ipt_unregister_match(&connlimit_match);
2179 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
2180 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_dstlimit.c 1970-01-01 01:00:00.000000000 +0100
2181 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_dstlimit.c 2004-02-16 11:07:13.230787904 +0100
2183 +/* iptables match extension to limit the number of packets per second
2184 + * seperately for each destination.
2186 + * (C) 2003 by Harald Welte <laforge@netfilter.org>
2188 + * Development of this code was funded by Astaro AG, http://www.astaro.com/
2190 + * based on ipt_limit.c by:
2191 + * Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
2192 + * Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
2193 + * Rusty Russell <rusty@rustcorp.com.au>
2195 + * The general idea is to create a hash table for every dstip and have a
2196 + * seperate limit counter per tuple. This way you can do something like 'limit
2197 + * the number of syn packets for each of my internal addresses.
2199 + * Ideally this would just be implemented as a general 'hash' match, which would
2200 + * allow us to attach any iptables target to it's hash buckets. But this is
2201 + * not possible in the current iptables architecture. As always, pkttables for
2202 + * 2.7.x will help ;)
2204 +#include <linux/module.h>
2205 +#include <linux/skbuff.h>
2206 +#include <linux/spinlock.h>
2207 +#include <linux/random.h>
2208 +#include <linux/jhash.h>
2209 +#include <linux/slab.h>
2210 +#include <linux/vmalloc.h>
2211 +#include <linux/tcp.h>
2212 +#include <linux/udp.h>
2213 +#include <linux/proc_fs.h>
2214 +#include <linux/seq_file.h>
2216 +#define ASSERT_READ_LOCK(x)
2217 +#define ASSERT_WRITE_LOCK(x)
2218 +#include <linux/netfilter_ipv4/lockhelp.h>
2219 +#include <linux/netfilter_ipv4/listhelp.h>
2221 +#include <linux/netfilter_ipv4/ip_tables.h>
2222 +#include <linux/netfilter_ipv4/ipt_dstlimit.h>
2224 +/* FIXME: this is just for IP_NF_ASSERRT */
2225 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2227 +#define MS2JIFFIES(x) ((x*HZ)/1000)
2229 +MODULE_LICENSE("GPL");
2230 +MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
2231 +MODULE_DESCRIPTION("iptables match for limiting per destination");
2233 +/* need to declare this at the top */
2234 +static struct proc_dir_entry *dstlimit_procdir;
2235 +static struct file_operations dl_file_ops;
2237 +/* hash table crap */
2239 +struct dsthash_dst {
2245 +struct dsthash_ent {
2246 + /* static / read-only parts in the beginning */
2247 + struct list_head list;
2248 + struct dsthash_dst dst;
2250 + /* modified structure members in the end */
2251 + unsigned long expires; /* precalculated expiry time */
2253 + unsigned long prev; /* last modification */
2255 + u_int32_t credit_cap, cost;
2259 +struct ipt_dstlimit_htable {
2260 + struct ipt_dstlimit_info *minfo; /* public structure */
2262 + /* used internally */
2263 + spinlock_t lock; /* lock for list_head */
2264 + u_int32_t rnd; /* random seed for hash */
2265 + struct timer_list timer; /* timer for gc */
2266 + atomic_t count; /* number entries in table */
2268 + /* seq_file stuff */
2269 + struct proc_dir_entry *pde;
2271 + struct list_head hash[0]; /* hashtable itself */
2274 +static kmem_cache_t *dstlimit_cachep;
2276 +static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b)
2278 + return (ent->dst.dst_ip == b->dst_ip
2279 + && ent->dst.port == b->port
2280 + && ent->dst.src_ip == b->src_ip);
2283 +static inline u_int32_t
2284 +hash_dst(const struct ipt_dstlimit_htable *ht, const struct dsthash_dst *dst)
2286 + return (jhash_3words(dst->dst_ip, dst->port,
2287 + dst->src_ip, ht->rnd) % ht->minfo->size);
2290 +static inline struct dsthash_ent *
2291 +__dsthash_find(const struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
2293 + struct dsthash_ent *ent;
2294 + u_int32_t hash = hash_dst(ht, dst);
2295 + MUST_BE_LOCKED(&ht->lock);
2296 + ent = LIST_FIND(&ht->hash[hash], dst_cmp, struct dsthash_ent *, dst);
2300 +/* allocate dsthash_ent, initialize dst, put in htable and lock it */
2301 +static struct dsthash_ent *
2302 +__dsthash_alloc_init(struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
2304 + struct dsthash_ent *ent;
2306 + /* initialize hash with random val at the time we allocate
2307 + * the first hashtable entry */
2309 + get_random_bytes(&ht->rnd, 4);
2311 + if (ht->minfo->max &&
2312 + atomic_read(&ht->count) >= ht->minfo->max) {
2313 + /* FIXME: do something. question is what.. */
2314 + if (net_ratelimit())
2315 + printk("max count of %u reached\n", ht->minfo->max);
2319 + ent = kmem_cache_alloc(dstlimit_cachep, GFP_ATOMIC);
2321 + if (net_ratelimit())
2322 + printk("Can't allocate dsthash_ent\n");
2326 + atomic_inc(&ht->count);
2328 + ent->dst.dst_ip = dst->dst_ip;
2329 + ent->dst.port = dst->port;
2330 + ent->dst.src_ip = dst->src_ip;
2332 + list_add(&ent->list, &ht->hash[hash_dst(ht, dst)]);
2338 +__dsthash_free(struct ipt_dstlimit_htable *ht, struct dsthash_ent *ent)
2340 + MUST_BE_LOCKED(&ht->lock);
2342 + list_del(&ent->list);
2343 + kmem_cache_free(dstlimit_cachep, ent);
2344 + atomic_dec(&ht->count);
2347 +static void htable_gc(unsigned long htlong);
2349 +static int htable_create(struct ipt_dstlimit_info *minfo)
2352 + struct ipt_dstlimit_htable *hinfo;
2354 + if (!minfo->size) {
2355 + minfo->size = (((num_physpages << PAGE_SHIFT) / 16384)
2356 + / sizeof(struct list_head));
2357 + if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
2358 + minfo->size = 8192;
2359 + if (minfo->size < 16)
2363 + minfo->max = 8 * minfo->size;
2364 + else if (minfo->max < minfo->size)
2365 + minfo->max = minfo->size;
2367 + /* FIXME: don't use vmalloc() here or anywhere else -HW */
2368 + hinfo = vmalloc(sizeof(struct ipt_dstlimit_htable)
2369 + + (sizeof(struct list_head) * minfo->size));
2371 + printk(KERN_ERR "Unable to create ipt_dstlimit hash\n");
2375 + for (i = 0; i < minfo->size; i++)
2376 + INIT_LIST_HEAD(&hinfo->hash[i]);
2378 + minfo->hinfo = hinfo;
2380 + hinfo->minfo = minfo;
2381 + atomic_set(&hinfo->count, 0);
2384 + hinfo->lock = SPIN_LOCK_UNLOCKED;
2386 + hinfo->pde = create_proc_entry(minfo->name, 0, dstlimit_procdir);
2387 + if (!hinfo->pde) {
2391 + hinfo->pde->proc_fops = &dl_file_ops;
2392 + hinfo->pde->data = hinfo;
2394 + init_timer(&hinfo->timer);
2395 + hinfo->timer.expires = jiffies + MS2JIFFIES(minfo->gc_interval);
2396 + hinfo->timer.data = (unsigned long )hinfo;
2397 + hinfo->timer.function = htable_gc;
2398 + add_timer(&hinfo->timer);
2403 +static int select_all(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
2408 +static int select_gc(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
2410 + return (jiffies >= he->expires);
2413 +static void htable_selective_cleanup(struct ipt_dstlimit_htable *ht,
2414 + int (*select)(struct ipt_dstlimit_htable *ht,
2415 + struct dsthash_ent *he))
2419 + IP_NF_ASSERT(ht->minfo->size && ht->minfo->max);
2421 + /* lock hash table and iterate over it */
2422 + LOCK_BH(&ht->lock);
2423 + for (i = 0; i < ht->minfo->size; i++) {
2424 + struct dsthash_ent *dh, *n;
2425 + list_for_each_entry_safe(dh, n, &ht->hash[i], list) {
2426 + if ((*select)(ht, dh))
2427 + __dsthash_free(ht, dh);
2430 + UNLOCK_BH(&ht->lock);
2433 +/* hash table garbage collector, run by timer */
2434 +static void htable_gc(unsigned long htlong)
2436 + struct ipt_dstlimit_htable *ht = (struct ipt_dstlimit_htable *)htlong;
2438 + htable_selective_cleanup(ht, select_gc);
2440 + /* re-add the timer accordingly */
2441 + ht->timer.expires = jiffies + MS2JIFFIES(ht->minfo->gc_interval);
2442 + add_timer(&ht->timer);
2445 +/* The algorithm used is the Simple Token Bucket Filter (TBF)
2446 + * see net/sched/sch_tbf.c in the linux source tree
2449 +/* Rusty: This is my (non-mathematically-inclined) understanding of
2450 + this algorithm. The `average rate' in jiffies becomes your initial
2451 + amount of credit `credit' and the most credit you can ever have
2452 + `credit_cap'. The `peak rate' becomes the cost of passing the
2455 + `prev' tracks the last packet hit: you gain one credit per jiffy.
2456 + If you get credit balance more than this, the extra credit is
2457 + discarded. Every time the match passes, you lose `cost' credits;
2458 + if you don't have that many, the test fails.
2460 + See Alexey's formal explanation in net/sched/sch_tbf.c.
2462 + To get the maximum range, we multiply by this factor (ie. you get N
2463 + credits per jiffy). We want to allow a rate as low as 1 per day
2464 + (slowest userspace tool allows), which means
2465 + CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32 ie.
2467 +#define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24))
2469 +/* Repeated shift and or gives us all 1s, final shift and add 1 gives
2470 + * us the power of 2 below the theoretical max, so GCC simply does a
2472 +#define _POW2_BELOW2(x) ((x)|((x)>>1))
2473 +#define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2))
2474 +#define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4))
2475 +#define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8))
2476 +#define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16))
2477 +#define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1)
2479 +#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
2481 +/* Precision saver. */
2482 +static inline u_int32_t
2483 +user2credits(u_int32_t user)
2485 + /* If multiplying would overflow... */
2486 + if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY))
2487 + /* Divide first. */
2488 + return (user / IPT_DSTLIMIT_SCALE) * HZ * CREDITS_PER_JIFFY;
2490 + return (user * HZ * CREDITS_PER_JIFFY) / IPT_DSTLIMIT_SCALE;
2493 +static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
2495 + dh->rateinfo.credit += (now - xchg(&dh->rateinfo.prev, now))
2496 + * CREDITS_PER_JIFFY;
2497 + if (dh->rateinfo.credit > dh->rateinfo.credit_cap)
2498 + dh->rateinfo.credit = dh->rateinfo.credit_cap;
2502 +dstlimit_match(const struct sk_buff *skb,
2503 + const struct net_device *in,
2504 + const struct net_device *out,
2505 + const void *matchinfo,
2508 + u_int16_t datalen,
2511 + struct ipt_dstlimit_info *r =
2512 + ((struct ipt_dstlimit_info *)matchinfo)->u.master;
2513 + unsigned long now = jiffies;
2514 + struct dsthash_ent *dh;
2515 + struct dsthash_dst dst;
2517 + memset(&dst, 0, sizeof(dst));
2519 + /* dest ip is always in hash */
2520 + dst.dst_ip = skb->nh.iph->daddr;
2522 + /* source ip only if respective hashmode, otherwise set to
2524 + if (r->mode & IPT_DSTLIMIT_HASH_SIP)
2525 + dst.src_ip = skb->nh.iph->saddr;
2527 + /* dest port only if respective mode */
2528 + if (r->mode & IPT_DSTLIMIT_HASH_DPT) {
2529 + switch (skb->nh.iph->protocol) {
2530 + struct tcphdr *th;
2531 + struct udphdr *uh;
2533 + th = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
2534 + dst.port = th->dest;
2537 + uh = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
2538 + dst.port = uh->dest;
2545 + LOCK_BH(&r->hinfo->lock);
2546 + dh = __dsthash_find(r->hinfo, &dst);
2548 + dh = __dsthash_alloc_init(r->hinfo, &dst);
2551 + /* enomem... don't match == DROP */
2552 + if (net_ratelimit())
2553 + printk("%s: ENOMEM\n", __FUNCTION__);
2554 + UNLOCK_BH(&r->hinfo->lock);
2558 + dh->expires = jiffies + MS2JIFFIES(r->expire);
2560 + dh->rateinfo.prev = jiffies;
2561 + dh->rateinfo.credit = user2credits(r->avg * r->burst);
2562 + dh->rateinfo.credit_cap = user2credits(r->avg * r->burst);
2563 + dh->rateinfo.cost = user2credits(r->avg);
2565 + UNLOCK_BH(&r->hinfo->lock);
2569 + /* update expiration timeout */
2570 + dh->expires = now + MS2JIFFIES(r->expire);
2572 + rateinfo_recalc(dh, now);
2573 + if (dh->rateinfo.credit >= dh->rateinfo.cost) {
2574 + /* We're underlimit. */
2575 + dh->rateinfo.credit -= dh->rateinfo.cost;
2576 + UNLOCK_BH(&r->hinfo->lock);
2580 + UNLOCK_BH(&r->hinfo->lock);
2582 + /* default case: we're overlimit, thus don't match */
2587 +dstlimit_checkentry(const char *tablename,
2588 + const struct ipt_ip *ip,
2590 + unsigned int matchsize,
2591 + unsigned int hook_mask)
2593 + struct ipt_dstlimit_info *r = matchinfo;
2595 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_dstlimit_info)))
2598 + /* Check for overflow. */
2600 + || user2credits(r->avg * r->burst) < user2credits(r->avg)) {
2601 + printk("Overflow in ipt_dstlimit, try lower: %u/%u\n",
2602 + r->avg, r->burst);
2607 + || r->mode > (IPT_DSTLIMIT_HASH_DPT
2608 + |IPT_DSTLIMIT_HASH_DIP
2609 + |IPT_DSTLIMIT_HASH_SIP))
2612 + if (!r->gc_interval)
2618 + if (htable_create(r) != 0) {
2619 + printk("Unable to create dstlimit htable\n");
2623 + /* Ugly hack: For SMP, we only want to use one set */
2630 +dstlimit_destroy(void *matchinfo, unsigned int matchsize)
2632 + struct ipt_dstlimit_info *r = (struct ipt_dstlimit_info *) matchinfo;
2636 + /* remove timer, if it is pending */
2637 + if (timer_pending(&r->hinfo->timer))
2638 + del_timer(&r->hinfo->timer);
2640 + /* remove proc entry */
2641 + remove_proc_entry(r->name, dstlimit_procdir);
2643 + htable_selective_cleanup(r->hinfo, select_all);
2647 +static struct ipt_match ipt_dstlimit = {
2648 + .list = { .prev = NULL, .next = NULL },
2649 + .name = "dstlimit",
2650 + .match = dstlimit_match,
2651 + .checkentry = dstlimit_checkentry,
2652 + .destroy = dstlimit_destroy,
2658 +static void *dl_seq_start(struct seq_file *s, loff_t *pos)
2660 + struct proc_dir_entry *pde = s->private;
2661 + struct ipt_dstlimit_htable *htable = pde->data;
2662 + unsigned int *bucket;
2664 + LOCK_BH(&htable->lock);
2665 + if (*pos >= htable->minfo->size)
2668 + bucket = kmalloc(sizeof(unsigned int), GFP_KERNEL);
2670 + return ERR_PTR(-ENOMEM);
2676 +static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
2678 + struct proc_dir_entry *pde = s->private;
2679 + struct ipt_dstlimit_htable *htable = pde->data;
2680 + unsigned int *bucket = (unsigned int *)v;
2682 + *pos = ++(*bucket);
2683 + if (*pos >= htable->minfo->size) {
2690 +static void dl_seq_stop(struct seq_file *s, void *v)
2692 + struct proc_dir_entry *pde = s->private;
2693 + struct ipt_dstlimit_htable *htable = pde->data;
2695 + UNLOCK_BH(&htable->lock);
2698 +static inline int dl_seq_real_show(struct dsthash_ent *ent, struct seq_file *s)
2700 + /* recalculate to show accurate numbers */
2701 + rateinfo_recalc(ent, jiffies);
2703 + return seq_printf(s, "%ld %u.%u.%u.%u->%u.%u.%u.%u:%u %u %u %u\n",
2704 + (ent->expires - jiffies)/HZ,
2705 + NIPQUAD(ent->dst.src_ip),
2706 + NIPQUAD(ent->dst.dst_ip), ntohs(ent->dst.port),
2707 + ent->rateinfo.credit, ent->rateinfo.credit_cap,
2708 + ent->rateinfo.cost);
2711 +static int dl_seq_show(struct seq_file *s, void *v)
2713 + struct proc_dir_entry *pde = s->private;
2714 + struct ipt_dstlimit_htable *htable = pde->data;
2715 + unsigned int *bucket = (unsigned int *)v;
2717 + if (LIST_FIND_W(&htable->hash[*bucket], dl_seq_real_show,
2718 + struct dsthash_ent *, s)) {
2719 + /* buffer was filled and unable to print that tuple */
2725 +static struct seq_operations dl_seq_ops = {
2726 + .start = dl_seq_start,
2727 + .next = dl_seq_next,
2728 + .stop = dl_seq_stop,
2729 + .show = dl_seq_show
2732 +static int dl_proc_open(struct inode *inode, struct file *file)
2734 + int ret = seq_open(file, &dl_seq_ops);
2737 + struct seq_file *sf = file->private_data;
2738 + sf->private = PDE(inode);
2743 +static struct file_operations dl_file_ops = {
2744 + .owner = THIS_MODULE,
2745 + .open = dl_proc_open,
2747 + .llseek = seq_lseek,
2748 + .release = seq_release
2751 +static int init_or_fini(int fini)
2758 + if (ipt_register_match(&ipt_dstlimit)) {
2760 + goto cleanup_nothing;
2763 + /* FIXME: do we really want HWCACHE_ALIGN since our objects are
2764 + * quite small ? */
2765 + dstlimit_cachep = kmem_cache_create("ipt_dstlimit",
2766 + sizeof(struct dsthash_ent), 0,
2767 + SLAB_HWCACHE_ALIGN, NULL, NULL);
2768 + if (!dstlimit_cachep) {
2769 + printk(KERN_ERR "Unable to create ipt_dstlimit slab cache\n");
2771 + goto cleanup_unreg_match;
2774 + dstlimit_procdir = proc_mkdir("ipt_dstlimit", proc_net);
2775 + if (!dstlimit_procdir) {
2776 + printk(KERN_ERR "Unable to create proc dir entry\n");
2778 + goto cleanup_free_slab;
2784 + remove_proc_entry("ipt_dstlimit", proc_net);
2786 + kmem_cache_destroy(dstlimit_cachep);
2787 +cleanup_unreg_match:
2788 + ipt_unregister_match(&ipt_dstlimit);
2794 +static int __init init(void)
2796 + return init_or_fini(0);
2799 +static void __exit fini(void)
2806 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
2807 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_fuzzy.c 1970-01-01 01:00:00.000000000 +0100
2808 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_fuzzy.c 2004-02-16 11:07:14.925382080 +0100
2811 + * This module implements a simple TSK FLC
2812 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
2813 + * to limit , in an adaptive and flexible way , the packet rate crossing
2814 + * a given stream . It serves as an initial and very simple (but effective)
2815 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
2816 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
2817 + * into our code in a precise , adaptive and efficient manner.
2818 + * The goal is very similar to that of "limit" match , but using techniques of
2819 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
2820 + * avoiding over and undershoots - and stuff like that .
2823 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
2824 + * 2002-08-17 : Changed to eliminate floating point operations .
2825 + * 2002-08-23 : Coding style changes .
2828 +#include <linux/module.h>
2829 +#include <linux/skbuff.h>
2830 +#include <linux/ip.h>
2831 +#include <linux/random.h>
2832 +#include <net/tcp.h>
2833 +#include <linux/spinlock.h>
2834 +#include <linux/netfilter_ipv4/ip_tables.h>
2835 +#include <linux/netfilter_ipv4/ipt_fuzzy.h>
2838 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
2839 + Expressed in percentage
2842 +#define PAR_LOW 1/100
2845 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED ;
2847 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
2848 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
2849 +MODULE_LICENSE("GPL");
2851 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
2853 + if (tx >= maxi) return 100;
2855 + if (tx <= mini) return 0;
2857 + return ( (100*(tx-mini)) / (maxi-mini) ) ;
2860 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
2862 + if (tx <= mini) return 100;
2864 + if (tx >= maxi) return 0;
2866 + return ( (100*( maxi - tx )) / ( maxi - mini ) ) ;
2871 +ipt_fuzzy_match(const struct sk_buff *pskb,
2872 + const struct net_device *in,
2873 + const struct net_device *out,
2874 + const void *matchinfo,
2877 + u_int16_t datalen,
2880 + /* From userspace */
2882 + struct ipt_fuzzy_info *info = (struct ipt_fuzzy_info *) matchinfo;
2884 + u_int8_t random_number;
2885 + unsigned long amount ;
2886 + u_int8_t howhigh , howlow ;
2889 + spin_lock_bh(&fuzzy_lock) ; /* Rise the lock */
2891 + info->bytes_total += pskb->len ;
2892 + info->packets_total++ ;
2894 + info->present_time = jiffies ;
2896 + if ( info->present_time >= info->previous_time )
2897 + amount = info->present_time - info->previous_time ;
2899 + /* There was a transition : I choose to re-sample
2900 + and keep the old acceptance rate...
2904 + info->previous_time = info->present_time ;
2905 + info->bytes_total = info->packets_total = 0;
2908 + if ( amount > HZ/10 ) /* More than 100 ms elapsed ... */
2911 + info->mean_rate = (u_int32_t) ( ( HZ * info->packets_total ) \
2914 + info->previous_time = info->present_time ;
2915 + info->bytes_total = info->packets_total = 0 ;
2917 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
2918 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
2920 + info->acceptance_rate = (u_int8_t) \
2921 + ( howhigh*PAR_LOW + PAR_HIGH*howlow ) ;
2923 + /* In fact , the above defuzzification would require a denominator
2924 + proportional to (howhigh+howlow) but , in this particular case ,
2925 + that expression is constant .
2926 + An imediate consequence is that it isn't necessary to call
2927 + both mf_high and mf_low - but to keep things understandable ,
2933 + spin_unlock_bh(&fuzzy_lock) ; /* Release the lock */
2936 + if ( info->acceptance_rate < 100 )
2938 + get_random_bytes((void *)(&random_number), 1);
2940 + /* If within the acceptance , it can pass => don't match */
2941 + if ( random_number <= (255 * info->acceptance_rate) / 100 )
2944 + return 1; /* It can't pass ( It matches ) */
2947 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
2952 +ipt_fuzzy_checkentry(const char *tablename,
2953 + const struct ipt_ip *e,
2955 + unsigned int matchsize,
2956 + unsigned int hook_mask)
2959 + const struct ipt_fuzzy_info *info = matchinfo;
2961 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_fuzzy_info))) {
2962 + printk("ipt_fuzzy: matchsize %u != %u\n", matchsize,
2963 + IPT_ALIGN(sizeof(struct ipt_fuzzy_info)));
2967 +if ((info->minimum_rate < MINFUZZYRATE ) || (info->maximum_rate > MAXFUZZYRATE)
2968 + || (info->minimum_rate >= info->maximum_rate ))
2970 + printk("ipt_fuzzy: BAD limits , please verify !!!\n");
2977 +static struct ipt_match ipt_fuzzy_reg = {
2981 + ipt_fuzzy_checkentry,
2985 +static int __init init(void)
2987 + if (ipt_register_match(&ipt_fuzzy_reg))
2993 +static void __exit fini(void)
2995 + ipt_unregister_match(&ipt_fuzzy_reg);
3000 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
3001 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_ipv4options.c 1970-01-01 01:00:00.000000000 +0100
3002 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_ipv4options.c 2004-02-16 11:07:16.165085194 +0100
3005 + This is a module which is used to match ipv4 options.
3006 + This file is distributed under the terms of the GNU General Public
3007 + License (GPL). Copies of the GPL can be obtained from:
3008 + ftp://prep.ai.mit.edu/pub/gnu/GPL
3010 + 11-mars-2001 Fabrice MARIE <fabrice@netfilter.org> : initial development.
3011 + 12-july-2001 Fabrice MARIE <fabrice@netfilter.org> : added router-alert otions matching. Fixed a bug with no-srr
3012 + 12-august-2001 Imran Patel <ipatel@crosswinds.net> : optimization of the match.
3013 + 18-november-2001 Fabrice MARIE <fabrice@netfilter.org> : added [!] 'any' option match.
3016 +#include <linux/module.h>
3017 +#include <linux/skbuff.h>
3018 +#include <net/ip.h>
3020 +#include <linux/netfilter_ipv4/ip_tables.h>
3021 +#include <linux/netfilter_ipv4/ipt_ipv4options.h>
3023 +MODULE_LICENSE("GPL");
3026 +match(const struct sk_buff *skb,
3027 + const struct net_device *in,
3028 + const struct net_device *out,
3029 + const void *matchinfo,
3032 + u_int16_t datalen,
3035 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
3036 + const struct iphdr *iph = skb->nh.iph;
3037 + const struct ip_options *opt;
3039 + if (iph->ihl * 4 == sizeof(struct iphdr)) {
3040 + /* No options, so we match only the "DONTs" and the "IGNOREs" */
3042 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) ||
3043 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3044 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
3045 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
3046 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
3047 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
3052 + if ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)
3053 + /* there are options, and we don't need to care which one */
3056 + if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
3057 + /* there are options but we don't want any ! */
3062 + opt = &(IPCB(skb)->opt);
3064 + /* source routing */
3065 + if ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) {
3066 + if (!((opt->srr) & (opt->is_strictroute)))
3069 + else if ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) {
3070 + if (!((opt->srr) & (!opt->is_strictroute)))
3073 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) {
3077 + /* record route */
3078 + if ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) {
3082 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) {
3087 + if ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) {
3091 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) {
3095 + /* router-alert option */
3096 + if ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) {
3097 + if (!opt->router_alert)
3100 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) {
3101 + if (opt->router_alert)
3110 +checkentry(const char *tablename,
3111 + const struct ipt_ip *ip,
3113 + unsigned int matchsize,
3114 + unsigned int hook_mask)
3116 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
3117 + /* Check the size */
3118 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_ipv4options_info)))
3120 + /* Now check the coherence of the data ... */
3121 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) &&
3122 + (((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) ||
3123 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) ||
3124 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) ||
3125 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) ||
3126 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)))
3127 + return 0; /* opposites */
3128 + if (((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) &&
3129 + (((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
3130 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3131 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
3132 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
3133 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) ||
3134 + ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)))
3135 + return 0; /* opposites */
3136 + if (((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) &&
3137 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR))
3138 + return 0; /* cannot match in the same time loose and strict source routing */
3139 + if ((((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3140 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR)) &&
3141 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR))
3142 + return 0; /* opposites */
3143 + if (((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) &&
3144 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR))
3145 + return 0; /* opposites */
3146 + if (((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) &&
3147 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
3148 + return 0; /* opposites */
3149 + if (((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) &&
3150 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
3151 + return 0; /* opposites */
3153 + /* everything looks ok. */
3157 +static struct ipt_match ipv4options_match
3158 += { { NULL, NULL }, "ipv4options", &match, &checkentry, NULL, THIS_MODULE };
3160 +static int __init init(void)
3162 + printk("ipt_ipv4options loading\n");
3163 + return ipt_register_match(&ipv4options_match);
3166 +static void __exit fini(void)
3168 + ipt_unregister_match(&ipv4options_match);
3169 + printk("ipt_ipv4options unloaded\n");
3174 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
3175 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_mport.c 1970-01-01 01:00:00.000000000 +0100
3176 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_mport.c 2004-02-16 11:07:17.665725817 +0100
3178 +/* Kernel module to match one of a list of TCP/UDP ports: ports are in
3179 + the same place so we can treat them as equal. */
3180 +#include <linux/module.h>
3181 +#include <linux/types.h>
3182 +#include <linux/udp.h>
3183 +#include <linux/skbuff.h>
3185 +#include <linux/netfilter_ipv4/ipt_mport.h>
3186 +#include <linux/netfilter_ipv4/ip_tables.h>
3188 +MODULE_LICENSE("GPL");
3191 +#define duprintf(format, args...) printk(format , ## args)
3193 +#define duprintf(format, args...)
3196 +/* Returns 1 if the port is matched by the test, 0 otherwise. */
3198 +ports_match(const struct ipt_mport *minfo, u_int16_t src, u_int16_t dst)
3202 + u_int16_t pflags = minfo->pflags;
3203 + for (i=0, m=1; i<IPT_MULTI_PORTS; i++, m<<=1) {
3207 + && minfo->ports[i] == 65535)
3210 + s = minfo->ports[i];
3213 + e = minfo->ports[++i];
3218 + if (minfo->flags & IPT_MPORT_SOURCE
3219 + && src >= s && src <= e)
3222 + if (minfo->flags & IPT_MPORT_DESTINATION
3223 + && dst >= s && dst <= e)
3231 +match(const struct sk_buff *skb,
3232 + const struct net_device *in,
3233 + const struct net_device *out,
3234 + const void *matchinfo,
3237 + u_int16_t datalen,
3240 + const struct udphdr *udp = hdr;
3241 + const struct ipt_mport *minfo = matchinfo;
3243 + /* Must be big enough to read ports. */
3244 + if (offset == 0 && datalen < sizeof(struct udphdr)) {
3245 + /* We've been asked to examine this packet, and we
3246 + can't. Hence, no choice but to drop. */
3247 + duprintf("ipt_mport:"
3248 + " Dropping evil offset=0 tinygram.\n");
3253 + /* Must not be a fragment. */
3255 + && ports_match(minfo, ntohs(udp->source), ntohs(udp->dest));
3258 +/* Called when user tries to insert an entry of this type. */
3260 +checkentry(const char *tablename,
3261 + const struct ipt_ip *ip,
3263 + unsigned int matchsize,
3264 + unsigned int hook_mask)
3266 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_mport)))
3269 + /* Must specify proto == TCP/UDP, no unknown flags or bad count */
3270 + return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
3271 + && !(ip->invflags & IPT_INV_PROTO)
3272 + && matchsize == IPT_ALIGN(sizeof(struct ipt_mport));
3275 +static struct ipt_match mport_match
3276 += { { NULL, NULL }, "mport", &match, &checkentry, NULL, THIS_MODULE };
3278 +static int __init init(void)
3280 + return ipt_register_match(&mport_match);
3283 +static void __exit fini(void)
3285 + ipt_unregister_match(&mport_match);
3290 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
3291 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_nth.c 1970-01-01 01:00:00.000000000 +0100
3292 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_nth.c 2004-02-16 11:07:18.803453352 +0100
3295 + This is a module which is used for match support for every Nth packet
3296 + This file is distributed under the terms of the GNU General Public
3297 + License (GPL). Copies of the GPL can be obtained from:
3298 + ftp://prep.ai.mit.edu/pub/gnu/GPL
3300 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
3301 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
3302 + * added support for multiple counters
3303 + * added support for matching on individual packets
3304 + in the counter cycle
3308 +#include <linux/module.h>
3309 +#include <linux/skbuff.h>
3310 +#include <linux/ip.h>
3311 +#include <net/tcp.h>
3312 +#include <linux/spinlock.h>
3313 +#include <linux/netfilter_ipv4/ip_tables.h>
3314 +#include <linux/netfilter_ipv4/ipt_nth.h>
3316 +MODULE_LICENSE("GPL");
3319 + * State information.
3326 +static struct state states[IPT_NTH_NUM_COUNTERS];
3329 +ipt_nth_match(const struct sk_buff *pskb,
3330 + const struct net_device *in,
3331 + const struct net_device *out,
3332 + const void *matchinfo,
3335 + u_int16_t datalen,
3338 + /* Parameters from userspace */
3339 + const struct ipt_nth_info *info = matchinfo;
3340 + unsigned counter = info->counter;
3341 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
3343 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
3347 + spin_lock(&states[counter].lock);
3349 + /* Are we matching every nth packet?*/
3350 + if (info->packet == 0xFF)
3352 + /* We're matching every nth packet and only every nth packet*/
3353 + /* Do we match or invert match? */
3354 + if (info->not == 0)
3356 + if (states[counter].number == 0)
3358 + ++states[counter].number;
3361 + if (states[counter].number >= info->every)
3362 + states[counter].number = 0; /* reset the counter */
3364 + ++states[counter].number;
3369 + if (states[counter].number == 0)
3371 + ++states[counter].number;
3374 + if (states[counter].number >= info->every)
3375 + states[counter].number = 0;
3377 + ++states[counter].number;
3383 + /* We're using the --packet, so there must be a rule for every value */
3384 + if (states[counter].number == info->packet)
3386 + /* only increment the counter when a match happens */
3387 + if (states[counter].number >= info->every)
3388 + states[counter].number = 0; /* reset the counter */
3390 + ++states[counter].number;
3399 + spin_unlock(&states[counter].lock);
3403 + spin_unlock(&states[counter].lock);
3408 +ipt_nth_checkentry(const char *tablename,
3409 + const struct ipt_ip *e,
3411 + unsigned int matchsize,
3412 + unsigned int hook_mask)
3414 + /* Parameters from userspace */
3415 + const struct ipt_nth_info *info = matchinfo;
3416 + unsigned counter = info->counter;
3417 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
3419 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
3423 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_nth_info))) {
3424 + printk("nth: matchsize %u != %u\n", matchsize,
3425 + IPT_ALIGN(sizeof(struct ipt_nth_info)));
3429 + states[counter].number = info->startat;
3434 +static struct ipt_match ipt_nth_reg = {
3438 + ipt_nth_checkentry,
3442 +static int __init init(void)
3445 + memset(&states, 0, sizeof(states));
3446 + if (ipt_register_match(&ipt_nth_reg))
3449 + for(counter = 0; counter < IPT_NTH_NUM_COUNTERS; counter++)
3451 + spin_lock_init(&(states[counter].lock));
3454 + printk("ipt_nth match loaded\n");
3458 +static void __exit fini(void)
3460 + ipt_unregister_match(&ipt_nth_reg);
3461 + printk("ipt_nth match unloaded\n");
3466 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
3467 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_osf.c 1970-01-01 01:00:00.000000000 +0100
3468 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_osf.c 2004-02-16 11:07:19.917186632 +0100
3473 + * Copyright (c) 2003 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
3476 + * This program is free software; you can redistribute it and/or modify
3477 + * it under the terms of the GNU General Public License as published by
3478 + * the Free Software Foundation; either version 2 of the License, or
3479 + * (at your option) any later version.
3481 + * This program is distributed in the hope that it will be useful,
3482 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3483 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3484 + * GNU General Public License for more details.
3486 + * You should have received a copy of the GNU General Public License
3487 + * along with this program; if not, write to the Free Software
3488 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3492 + * OS fingerprint matching module.
3493 + * It simply compares various parameters from SYN packet with
3494 + * some hardcoded ones.
3496 + * Original table was created by Michal Zalewski <lcamtuf@coredump.cx>
3500 +#include <linux/config.h>
3501 +#include <linux/kernel.h>
3502 +#include <linux/smp.h>
3503 +#include <linux/module.h>
3504 +#include <linux/skbuff.h>
3505 +#include <linux/file.h>
3506 +#include <linux/ip.h>
3507 +#include <linux/proc_fs.h>
3508 +#include <linux/fs.h>
3509 +#include <linux/slab.h>
3510 +#include <linux/spinlock.h>
3511 +#include <linux/ctype.h>
3512 +#include <linux/list.h>
3514 +#include <net/sock.h>
3515 +#include <net/ip.h>
3517 +#include <linux/netfilter_ipv4/ip_tables.h>
3519 +#include <linux/netfilter_ipv4/ipt_osf.h>
3524 +#define log(x...) printk(KERN_INFO "ipt_osf: " x)
3525 +#define loga(x...) printk(x)
3527 +#define log(x...) do {} while(0)
3528 +#define loga(x...) do {} while(0)
3531 +#define FMATCH_WRONG 0
3532 +#define FMATCH_OK 1
3533 +#define FMATCH_OPT_WRONG 2
3536 +#define OSFPDEL ':'
3537 +#define MAXOPTSTRLEN 128
3538 +#define OSFFLUSH "FLUSH"
3540 +static rwlock_t osf_lock = RW_LOCK_UNLOCKED;
3541 +static struct list_head finger_list;
3543 +static int match(const struct sk_buff *, const struct net_device *, const struct net_device *,
3544 + const void *, int, const void *, u_int16_t, int *);
3545 +static int checkentry(const char *, const struct ipt_ip *, void *,
3546 + unsigned int, unsigned int);
3548 +static struct ipt_match osf_match =
3558 +static inline int smart_dec(unsigned long flags, unsigned char ip_ttl, unsigned char f_ttl)
3560 + if (flags & IPT_OSF_SMART)
3563 + return (ip_ttl == f_ttl);
3567 +match(const struct sk_buff *skb,
3568 + const struct net_device *in,
3569 + const struct net_device *out,
3570 + const void *matchinfo,
3573 + u_int16_t datalen,
3576 + struct ipt_osf_info *info = (struct ipt_osf_info *)matchinfo;
3577 + struct iphdr *ip = skb->nh.iph;
3578 + struct tcphdr *tcp;
3579 + int fmatch = FMATCH_WRONG, fcount = 0;
3580 + unsigned long totlen, optsize = 0, window;
3581 + unsigned char df, *optp = NULL, *_optp = NULL;
3582 + char check_WSS = 0;
3583 + struct list_head *ent;
3584 + struct osf_finger *f;
3589 + tcp = (struct tcphdr *)((u_int32_t *)ip + ip->ihl);
3593 + else if (tcp->ack)
3596 + totlen = ntohs(ip->tot_len);
3597 + df = ((ntohs(ip->frag_off) & IP_DF)?1:0);
3598 + window = ntohs(tcp->window);
3600 + if (tcp->doff*4 > sizeof(struct tcphdr))
3602 + _optp = optp = (char *)(tcp+1);
3603 + optsize = tcp->doff*4 - sizeof(struct tcphdr);
3607 + /* Actually we can create hash/table of all genres and search
3608 + * only in appropriate part, but here is initial variant,
3609 + * so will use slow path.
3611 + read_lock(&osf_lock);
3612 + list_for_each(ent, &finger_list)
3614 + f = list_entry(ent, struct osf_finger, flist);
3616 + if (!(info->flags & IPT_OSF_LOG) && strcmp(info->genre, f->genre))
3620 + fmatch = FMATCH_WRONG;
3622 + if (totlen == f->ss && df == f->df &&
3623 + smart_dec(info->flags, ip->ttl, f->ttl))
3625 + unsigned long foptsize;
3627 + unsigned short mss = 0;
3631 + switch (f->wss.wc)
3633 + case 0: check_WSS = 0; break;
3634 + case 'S': check_WSS = 1; break;
3635 + case 'T': check_WSS = 2; break;
3636 + case '%': check_WSS = 3; break;
3637 + default: log("Wrong fingerprint wss.wc=%d, %s - %s\n",
3638 + f->wss.wc, f->genre, f->details);
3642 + if (check_WSS == 4)
3645 + /* Check options */
3648 + for (optnum=0; optnum<f->opt_num; ++optnum)
3649 + foptsize += f->opt[optnum].length;
3652 + if (foptsize > MAX_IPOPTLEN || optsize > MAX_IPOPTLEN || optsize != foptsize)
3657 + fmatch = FMATCH_OK;
3658 + loga("\tYEP : matching without options.\n");
3659 + if ((info->flags & IPT_OSF_LOG) &&
3660 + info->loglevel == IPT_OSF_LOGLEVEL_FIRST)
3667 + for (optnum=0; optnum<f->opt_num; ++optnum)
3669 + if (f->opt[optnum].kind == (*optp))
3671 + unsigned char len = f->opt[optnum].length;
3672 + unsigned char *optend = optp + len;
3674 + fmatch = FMATCH_OK;
3676 + if (*optp == OSFOPT_MSS) /* MSS */
3677 + mss = ntohs(*(unsigned short *)(optp+2));
3681 + /* Skip kind and length fields*/
3684 + if (f->opt[optnum].wc.wc != 0)
3686 + unsigned long tmp = 0;
3688 + /* Hmmm... It looks a bit ugly. :) */
3689 + memcpy(&tmp, &f->opt[optnum].wc.val,
3690 + (len > sizeof(unsigned long)?
3691 + sizeof(unsigned long):len));
3694 + if (tmp != f->opt[optnum].wc.val)
3695 + fmatch = FMATCH_OPT_WRONG;
3702 + fmatch = FMATCH_OPT_WRONG;
3704 + if (fmatch != FMATCH_OK)
3708 + if (fmatch != FMATCH_OPT_WRONG)
3710 + fmatch = FMATCH_WRONG;
3712 + switch (check_WSS)
3715 + if (window == f->wss.val)
3716 + fmatch = FMATCH_OK;
3719 + if (window == f->wss.val*mss)
3720 + fmatch = FMATCH_OK;
3723 + if (window == f->wss.val*(mss+40))
3724 + fmatch = FMATCH_OK;
3727 + if (window % f->wss.val == 0)
3728 + fmatch = FMATCH_OK;
3734 + if (fmatch == FMATCH_OK)
3737 + log("%s [%s]: %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n",
3738 + f->genre, f->details,
3739 + NIPQUAD(ip->saddr), ntohs(tcp->source),
3740 + NIPQUAD(ip->daddr), ntohs(tcp->dest));
3741 + if ((info->flags & IPT_OSF_LOG) &&
3742 + info->loglevel == IPT_OSF_LOGLEVEL_FIRST)
3747 + if (!fcount && (info->flags & IPT_OSF_LOG))
3749 + log("Unknown: %lu:%d:%d:%lu:", window, ip->ttl, df, totlen);
3752 + unsigned char opt[4 * 15 - sizeof(struct tcphdr)];
3753 + unsigned int i, optsize;
3755 + optsize = tcp->doff * 4 - sizeof(struct tcphdr);
3756 + if (skb_copy_bits(skb, ip->ihl*4 + sizeof(struct tcphdr),
3757 + opt, optsize) < 0)
3758 + loga("TRUNCATED");
3760 + for (i = 0; i < optsize; i++)
3761 + loga("%02X", opt[i]);
3764 + loga(" %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n",
3765 + NIPQUAD(ip->saddr), ntohs(tcp->source),
3766 + NIPQUAD(ip->daddr), ntohs(tcp->dest));
3768 + read_unlock(&osf_lock);
3770 + return (fmatch == FMATCH_OK)?1:0;
3774 +checkentry(const char *tablename,
3775 + const struct ipt_ip *ip,
3777 + unsigned int matchsize,
3778 + unsigned int hook_mask)
3780 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_osf_info)))
3782 + if (ip->proto != IPPROTO_TCP)
3788 +static char * osf_strchr(char *ptr, char c)
3792 + tmp = strchr(ptr, c);
3794 + while (tmp && tmp+1 && isspace(*(tmp+1)))
3800 +static struct osf_finger * finger_alloc(void)
3802 + struct osf_finger *f;
3804 + f = kmalloc(sizeof(struct osf_finger), GFP_KERNEL);
3806 + memset(f, 0, sizeof(struct osf_finger));
3811 +static void finger_free(struct osf_finger *f)
3813 + memset(f, 0, sizeof(struct osf_finger));
3818 +static void osf_parse_opt(struct osf_opt *opt, int *optnum, char *obuf, int olen)
3822 + unsigned long val;
3826 + while (ptr != NULL && i < olen)
3835 + ptr = osf_strchr(&obuf[i], OPTDEL);
3840 + i += (int)(ptr-&obuf[i]);
3847 + op = OSFOPT_SACKP;
3848 + ptr = osf_strchr(&obuf[i], OPTDEL);
3853 + i += (int)(ptr-&obuf[i]);
3861 + ptr = osf_strchr(&obuf[i], OPTDEL);
3866 + i += (int)(ptr-&obuf[i]);
3874 + ptr = osf_strchr(&obuf[i], OPTDEL);
3877 + switch (obuf[i+1])
3879 + case '%': wc = '%'; break;
3880 + case 'S': wc = 'S'; break;
3881 + case 'T': wc = 'T'; break;
3882 + default: wc = 0; break;
3888 + val = simple_strtoul(&obuf[i+2], NULL, 10);
3890 + val = simple_strtoul(&obuf[i+1], NULL, 10);
3891 + i += (int)(ptr-&obuf[i]);
3899 + ptr = osf_strchr(&obuf[i], OPTDEL);
3902 + if (obuf[i+1] == '%')
3907 + val = simple_strtoul(&obuf[i+2], NULL, 10);
3909 + val = simple_strtoul(&obuf[i+1], NULL, 10);
3910 + i += (int)(ptr-&obuf[i]);
3918 + ptr = osf_strchr(&obuf[i], OPTDEL);
3923 + i += (int)(ptr-&obuf[i]);
3930 + ptr = osf_strchr(&obuf[i], OPTDEL);
3934 + i += (int)(ptr-&obuf[i]);
3942 + opt[*optnum].kind = IANA_opts[op].kind;
3943 + opt[*optnum].length = IANA_opts[op].length;
3944 + opt[*optnum].wc.wc = wc;
3945 + opt[*optnum].wc.val = val;
3951 +static int osf_proc_read(char *buf, char **start, off_t off, int count, int *eof, void *data)
3953 + struct list_head *ent;
3954 + struct osf_finger *f = NULL;
3960 + read_lock_bh(&osf_lock);
3961 + list_for_each(ent, &finger_list)
3963 + f = list_entry(ent, struct osf_finger, flist);
3965 + log("%s [%s]", f->genre, f->details);
3967 + count += sprintf(buf+count, "%s - %s[%s] : %s",
3968 + f->genre, f->version,
3969 + f->subtype, f->details);
3974 + //count += sprintf(buf+count, " OPT: ");
3975 + for (i=0; i<f->opt_num; ++i)
3977 + //count += sprintf(buf+count, "%d.%c%lu; ",
3978 + // f->opt[i].kind, (f->opt[i].wc.wc)?f->opt[i].wc.wc:' ', f->opt[i].wc.val);
3979 + loga("%d.%c%lu; ",
3980 + f->opt[i].kind, (f->opt[i].wc.wc)?f->opt[i].wc.wc:' ', f->opt[i].wc.val);
3984 + count += sprintf(buf+count, "\n");
3986 + read_unlock_bh(&osf_lock);
3991 +static int osf_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
3995 + char obuf[MAXOPTSTRLEN];
3996 + struct osf_finger *finger;
3997 + struct list_head *ent, *n;
3999 + char *pbeg, *pend;
4001 + if (count == strlen(OSFFLUSH) && !strncmp(buffer, OSFFLUSH, strlen(OSFFLUSH)))
4004 + write_lock_bh(&osf_lock);
4005 + list_for_each_safe(ent, n, &finger_list)
4008 + finger = list_entry(ent, struct osf_finger, flist);
4009 + list_del(&finger->flist);
4010 + finger_free(finger);
4012 + write_unlock_bh(&osf_lock);
4014 + log("Flushed %d entries.\n", i);
4021 + for (i=0; i<count && buffer[i] != '\0'; ++i)
4022 + if (buffer[i] == ':')
4025 + if (cnt != 8 || i != count)
4027 + log("Wrong input line cnt=%d[8], len=%lu[%lu]\n",
4032 + memset(obuf, 0, sizeof(obuf));
4034 + finger = finger_alloc();
4037 + log("Failed to allocate new fingerprint entry.\n");
4041 + pbeg = (char *)buffer;
4042 + pend = osf_strchr(pbeg, OSFPDEL);
4046 + if (pbeg[0] == 'S')
4048 + finger->wss.wc = 'S';
4049 + if (pbeg[1] == '%')
4050 + finger->wss.val = simple_strtoul(pbeg+2, NULL, 10);
4051 + else if (pbeg[1] == '*')
4052 + finger->wss.val = 0;
4054 + finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
4056 + else if (pbeg[0] == 'T')
4058 + finger->wss.wc = 'T';
4059 + if (pbeg[1] == '%')
4060 + finger->wss.val = simple_strtoul(pbeg+2, NULL, 10);
4061 + else if (pbeg[1] == '*')
4062 + finger->wss.val = 0;
4064 + finger->wss.val = simple_strtoul(pbeg+1, NULL, 10);
4066 + if (isdigit(pbeg[0]))
4068 + finger->wss.wc = 0;
4069 + finger->wss.val = simple_strtoul(pbeg, NULL, 10);
4074 + pend = osf_strchr(pbeg, OSFPDEL);
4078 + finger->ttl = simple_strtoul(pbeg, NULL, 10);
4081 + pend = osf_strchr(pbeg, OSFPDEL);
4085 + finger->df = simple_strtoul(pbeg, NULL, 10);
4088 + pend = osf_strchr(pbeg, OSFPDEL);
4092 + finger->ss = simple_strtoul(pbeg, NULL, 10);
4096 + pend = osf_strchr(pbeg, OSFPDEL);
4100 + cnt = snprintf(obuf, sizeof(obuf), "%s", pbeg);
4104 + pend = osf_strchr(pbeg, OSFPDEL);
4108 + if (pbeg[0] == '@' || pbeg[0] == '*')
4109 + cnt = snprintf(finger->genre, sizeof(finger->genre), "%s", pbeg+1);
4111 + cnt = snprintf(finger->genre, sizeof(finger->genre), "%s", pbeg);
4115 + pend = osf_strchr(pbeg, OSFPDEL);
4119 + cnt = snprintf(finger->version, sizeof(finger->version), "%s", pbeg);
4123 + pend = osf_strchr(pbeg, OSFPDEL);
4127 + cnt = snprintf(finger->subtype, sizeof(finger->subtype), "%s", pbeg);
4131 + cnt = snprintf(finger->details,
4132 + ((count - (pbeg - buffer)+1) > MAXDETLEN)?MAXDETLEN:(count - (pbeg - buffer)+1),
4135 + log("%s - %s[%s] : %s\n",
4136 + finger->genre, finger->version,
4137 + finger->subtype, finger->details);
4139 + osf_parse_opt(finger->opt, &finger->opt_num, obuf, sizeof(obuf));
4142 + write_lock_bh(&osf_lock);
4143 + list_add_tail(&finger->flist, &finger_list);
4144 + write_unlock_bh(&osf_lock);
4149 +static int __init osf_init(void)
4152 + struct proc_dir_entry *p;
4154 + log("Startng OS fingerprint matching module.\n");
4156 + INIT_LIST_HEAD(&finger_list);
4158 + err = ipt_register_match(&osf_match);
4161 + log("Failed to register OS fingerprint matching module.\n");
4165 + p = create_proc_entry("sys/net/ipv4/osf", S_IFREG | 0644, NULL);
4168 + ipt_unregister_match(&osf_match);
4172 + p->write_proc = osf_proc_write;
4173 + p->read_proc = osf_proc_read;
4178 +static void __exit osf_fini(void)
4180 + struct list_head *ent, *n;
4181 + struct osf_finger *f;
4183 + remove_proc_entry("sys/net/ipv4/osf", NULL);
4184 + ipt_unregister_match(&osf_match);
4186 + list_for_each_safe(ent, n, &finger_list)
4188 + f = list_entry(ent, struct osf_finger, flist);
4189 + list_del(&f->flist);
4193 + log("OS fingerprint matching module finished.\n");
4196 +module_init(osf_init);
4197 +module_exit(osf_fini);
4199 +MODULE_LICENSE("GPL");
4200 +MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
4201 +MODULE_DESCRIPTION("Passive OS fingerprint matching.");
4203 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
4204 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_pool.c 1970-01-01 01:00:00.000000000 +0100
4205 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_pool.c 2004-02-16 11:07:21.519802833 +0100
4207 +/* Kernel module to match an IP address pool. */
4209 +#include <linux/module.h>
4210 +#include <linux/ip.h>
4211 +#include <linux/skbuff.h>
4213 +#include <linux/netfilter_ipv4/ip_tables.h>
4214 +#include <linux/netfilter_ipv4/ip_pool.h>
4215 +#include <linux/netfilter_ipv4/ipt_pool.h>
4217 +static inline int match_pool(
4222 + if (ip_pool_match(index, ntohl(addr)))
4228 + const struct sk_buff *skb,
4229 + const struct net_device *in,
4230 + const struct net_device *out,
4231 + const void *matchinfo,
4234 + u_int16_t datalen,
4237 + const struct ipt_pool_info *info = matchinfo;
4238 + const struct iphdr *iph = skb->nh.iph;
4240 + if (info->src != IP_POOL_NONE && !match_pool(info->src, iph->saddr,
4241 + info->flags&IPT_POOL_INV_SRC))
4244 + if (info->dst != IP_POOL_NONE && !match_pool(info->dst, iph->daddr,
4245 + info->flags&IPT_POOL_INV_DST))
4251 +static int checkentry(
4252 + const char *tablename,
4253 + const struct ipt_ip *ip,
4255 + unsigned int matchsize,
4256 + unsigned int hook_mask
4258 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_pool_info)))
4263 +static struct ipt_match pool_match
4264 += { { NULL, NULL }, "pool", &match, &checkentry, NULL, THIS_MODULE };
4266 +static int __init init(void)
4268 + return ipt_register_match(&pool_match);
4271 +static void __exit fini(void)
4273 + ipt_unregister_match(&pool_match);
4278 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
4279 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_psd.c 1970-01-01 01:00:00.000000000 +0100
4280 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_psd.c 2004-02-16 11:07:22.387595011 +0100
4283 + This is a module which is used for PSD (portscan detection)
4284 + Derived from scanlogd v2.1 written by Solar Designer <solar@false.com>
4285 + and LOG target module.
4287 + Copyright (C) 2000,2001 astaro AG
4289 + This file is distributed under the terms of the GNU General Public
4290 + License (GPL). Copies of the GPL can be obtained from:
4291 + ftp://prep.ai.mit.edu/pub/gnu/GPL
4293 + 2000-05-04 Markus Hennig <hennig@astaro.de> : initial
4294 + 2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
4295 + 2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
4296 + 2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified
4297 + 2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
4300 +#include <linux/module.h>
4301 +#include <linux/skbuff.h>
4302 +#include <linux/ip.h>
4303 +#include <net/tcp.h>
4304 +#include <linux/spinlock.h>
4305 +#include <linux/netfilter_ipv4/ip_tables.h>
4306 +#include <linux/netfilter_ipv4/ipt_psd.h>
4309 +#define DEBUGP printk
4311 +#define DEBUGP(format, args...)
4314 +MODULE_LICENSE("GPL");
4315 +MODULE_AUTHOR("Dennis Koslowski <koslowski@astaro.com>");
4317 +#define HF_DADDR_CHANGING 0x01
4318 +#define HF_SPORT_CHANGING 0x02
4319 +#define HF_TOS_CHANGING 0x04
4320 +#define HF_TTL_CHANGING 0x08
4323 + * Information we keep per each target port
4326 + u_int16_t number; /* port number */
4327 + u_int8_t proto; /* protocol number */
4328 + u_int8_t and_flags; /* tcp ANDed flags */
4329 + u_int8_t or_flags; /* tcp ORed flags */
4333 + * Information we keep per each source address.
4336 + struct host *next; /* Next entry with the same hash */
4337 + clock_t timestamp; /* Last update time */
4338 + struct in_addr src_addr; /* Source address */
4339 + struct in_addr dest_addr; /* Destination address */
4340 + unsigned short src_port; /* Source port */
4341 + int count; /* Number of ports in the list */
4342 + int weight; /* Total weight of ports in the list */
4343 + struct port ports[SCAN_MAX_COUNT - 1]; /* List of ports */
4344 + unsigned char tos; /* TOS */
4345 + unsigned char ttl; /* TTL */
4346 + unsigned char flags; /* HF_ flags bitmask */
4350 + * State information.
4354 + struct host list[LIST_SIZE]; /* List of source addresses */
4355 + struct host *hash[HASH_SIZE]; /* Hash: pointers into the list */
4356 + int index; /* Oldest entry to be replaced */
4360 + * Convert an IP address into a hash table index.
4362 +static inline int hashfunc(struct in_addr addr)
4364 + unsigned int value;
4367 + value = addr.s_addr;
4371 + } while ((value >>= HASH_LOG));
4373 + return hash & (HASH_SIZE - 1);
4377 +ipt_psd_match(const struct sk_buff *pskb,
4378 + const struct net_device *in,
4379 + const struct net_device *out,
4380 + const void *matchinfo,
4383 + u_int16_t datalen,
4386 + struct iphdr *ip_hdr;
4387 + struct tcphdr *tcp_hdr;
4388 + struct in_addr addr;
4389 + u_int16_t src_port,dest_port;
4390 + u_int8_t tcp_flags, proto;
4392 + struct host *curr, *last, **head;
4393 + int hash, index, count;
4395 + /* Parameters from userspace */
4396 + const struct ipt_psd_info *psdinfo = matchinfo;
4399 + ip_hdr = pskb->nh.iph;
4401 + /* Sanity check */
4402 + if (ntohs(ip_hdr->frag_off) & IP_OFFSET) {
4403 + DEBUGP("PSD: sanity check failed\n");
4407 + /* TCP or UDP ? */
4408 + proto = ip_hdr->protocol;
4410 + if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
4411 + DEBUGP("PSD: protocol not supported\n");
4415 + /* Get the source address, source & destination ports, and TCP flags */
4417 + addr.s_addr = ip_hdr->saddr;
4419 + tcp_hdr = (struct tcphdr*)((u_int32_t *)ip_hdr + ip_hdr->ihl);
4421 + /* Yep, it´s dirty */
4422 + src_port = tcp_hdr->source;
4423 + dest_port = tcp_hdr->dest;
4425 + if (proto == IPPROTO_TCP) {
4426 + tcp_flags = *((u_int8_t*)tcp_hdr + 13);
4432 + /* We're using IP address 0.0.0.0 for a special purpose here, so don't let
4433 + * them spoof us. [DHCP needs this feature - HW] */
4434 + if (!addr.s_addr) {
4435 + DEBUGP("PSD: spoofed source address (0.0.0.0)\n");
4439 + /* Use jiffies here not to depend on someone setting the time while we're
4440 + * running; we need to be careful with possible return value overflows. */
4443 + spin_lock(&state.lock);
4445 + /* Do we know this source address already? */
4448 + if ((curr = *(head = &state.hash[hash = hashfunc(addr)])))
4450 + if (curr->src_addr.s_addr == addr.s_addr) break;
4452 + if (curr->next) last = curr;
4453 + } while ((curr = curr->next));
4457 + /* We know this address, and the entry isn't too old. Update it. */
4458 + if (now - curr->timestamp <= (psdinfo->delay_threshold*HZ)/100 &&
4459 + time_after_eq(now, curr->timestamp)) {
4461 + /* Just update the appropriate list entry if we've seen this port already */
4462 + for (index = 0; index < curr->count; index++) {
4463 + if (curr->ports[index].number == dest_port) {
4464 + curr->ports[index].proto = proto;
4465 + curr->ports[index].and_flags &= tcp_flags;
4466 + curr->ports[index].or_flags |= tcp_flags;
4467 + goto out_no_match;
4471 + /* TCP/ACK and/or TCP/RST to a new port? This could be an outgoing connection. */
4472 + if (proto == IPPROTO_TCP && (tcp_hdr->ack || tcp_hdr->rst))
4473 + goto out_no_match;
4475 + /* Packet to a new port, and not TCP/ACK: update the timestamp */
4476 + curr->timestamp = now;
4478 + /* Logged this scan already? Then drop the packet. */
4479 + if (curr->weight >= psdinfo->weight_threshold)
4482 + /* Specify if destination address, source port, TOS or TTL are not fixed */
4483 + if (curr->dest_addr.s_addr != ip_hdr->daddr)
4484 + curr->flags |= HF_DADDR_CHANGING;
4485 + if (curr->src_port != src_port)
4486 + curr->flags |= HF_SPORT_CHANGING;
4487 + if (curr->tos != ip_hdr->tos)
4488 + curr->flags |= HF_TOS_CHANGING;
4489 + if (curr->ttl != ip_hdr->ttl)
4490 + curr->flags |= HF_TTL_CHANGING;
4492 + /* Update the total weight */
4493 + curr->weight += (ntohs(dest_port) < 1024) ?
4494 + psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
4496 + /* Got enough destination ports to decide that this is a scan? */
4497 + /* Then log it and drop the packet. */
4498 + if (curr->weight >= psdinfo->weight_threshold)
4501 + /* Remember the new port */
4502 + if (curr->count < SCAN_MAX_COUNT) {
4503 + curr->ports[curr->count].number = dest_port;
4504 + curr->ports[curr->count].proto = proto;
4505 + curr->ports[curr->count].and_flags = tcp_flags;
4506 + curr->ports[curr->count].or_flags = tcp_flags;
4510 + goto out_no_match;
4513 + /* We know this address, but the entry is outdated. Mark it unused, and
4514 + * remove from the hash table. We'll allocate a new entry instead since
4515 + * this one might get re-used too soon. */
4516 + curr->src_addr.s_addr = 0;
4518 + last->next = last->next->next;
4520 + *head = (*head)->next;
4524 + /* We don't need an ACK from a new source address */
4525 + if (proto == IPPROTO_TCP && tcp_hdr->ack)
4526 + goto out_no_match;
4528 + /* Got too many source addresses with the same hash value? Then remove the
4529 + * oldest one from the hash table, so that they can't take too much of our
4530 + * CPU time even with carefully chosen spoofed IP addresses. */
4531 + if (count >= HASH_MAX && last) last->next = NULL;
4533 + /* We're going to re-use the oldest list entry, so remove it from the hash
4534 + * table first (if it is really already in use, and isn't removed from the
4535 + * hash table already because of the HASH_MAX check above). */
4537 + /* First, find it */
4538 + if (state.list[state.index].src_addr.s_addr)
4539 + head = &state.hash[hashfunc(state.list[state.index].src_addr)];
4543 + if ((curr = *head))
4545 + if (curr == &state.list[state.index]) break;
4547 + } while ((curr = curr->next));
4549 + /* Then, remove it */
4552 + last->next = last->next->next;
4554 + *head = (*head)->next;
4557 + /* Get our list entry */
4558 + curr = &state.list[state.index++];
4559 + if (state.index >= LIST_SIZE) state.index = 0;
4561 + /* Link it into the hash table */
4562 + head = &state.hash[hash];
4563 + curr->next = *head;
4566 + /* And fill in the fields */
4567 + curr->timestamp = now;
4568 + curr->src_addr = addr;
4569 + curr->dest_addr.s_addr = ip_hdr->daddr;
4570 + curr->src_port = src_port;
4572 + curr->weight = (ntohs(dest_port) < 1024) ?
4573 + psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
4574 + curr->ports[0].number = dest_port;
4575 + curr->ports[0].proto = proto;
4576 + curr->ports[0].and_flags = tcp_flags;
4577 + curr->ports[0].or_flags = tcp_flags;
4578 + curr->tos = ip_hdr->tos;
4579 + curr->ttl = ip_hdr->ttl;
4582 + spin_unlock(&state.lock);
4586 + spin_unlock(&state.lock);
4590 +static int ipt_psd_checkentry(const char *tablename,
4591 + const struct ipt_ip *e,
4593 + unsigned int matchsize,
4594 + unsigned int hook_mask)
4596 +/* const struct ipt_psd_info *psdinfo = targinfo;*/
4598 + /* we accept TCP only */
4599 +/* if (e->ip.proto != IPPROTO_TCP) { */
4600 +/* DEBUGP("PSD: specified protocol may be TCP only\n"); */
4604 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_psd_info))) {
4605 + DEBUGP("PSD: matchsize %u != %u\n",
4607 + IPT_ALIGN(sizeof(struct ipt_psd_info)));
4614 +static struct ipt_match ipt_psd_reg = {
4618 + ipt_psd_checkentry,
4622 +static int __init init(void)
4624 + if (ipt_register_match(&ipt_psd_reg))
4627 + memset(&state, 0, sizeof(state));
4629 + spin_lock_init(&(state.lock));
4631 + printk("netfilter PSD loaded - (c) astaro AG\n");
4635 +static void __exit fini(void)
4637 + ipt_unregister_match(&ipt_psd_reg);
4638 + printk("netfilter PSD unloaded - (c) astaro AG\n");
4643 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
4644 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_quota.c 1970-01-01 01:00:00.000000000 +0100
4645 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_quota.c 2004-02-16 11:07:23.219395809 +0100
4648 + * netfilter module to enforce network quotas
4650 + * Sam Johnston <samj@samj.net>
4652 +#include <linux/module.h>
4653 +#include <linux/skbuff.h>
4654 +#include <linux/spinlock.h>
4655 +#include <linux/interrupt.h>
4657 +#include <linux/netfilter_ipv4/ip_tables.h>
4658 +#include <linux/netfilter_ipv4/ipt_quota.h>
4660 +MODULE_LICENSE("GPL");
4662 +static spinlock_t quota_lock = SPIN_LOCK_UNLOCKED;
4665 +match(const struct sk_buff *skb,
4666 + const struct net_device *in,
4667 + const struct net_device *out,
4668 + const void *matchinfo,
4669 + int offset, const void *hdr, u_int16_t datalen, int *hotdrop)
4672 + struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
4674 + spin_lock_bh("a_lock);
4676 + if (q->quota >= datalen) {
4677 + /* we can afford this one */
4678 + q->quota -= datalen;
4679 + spin_unlock_bh("a_lock);
4681 +#ifdef DEBUG_IPT_QUOTA
4682 + printk("IPT Quota OK: %llu datlen %d \n", q->quota, datalen);
4687 + /* so we do not allow even small packets from now on */
4690 +#ifdef DEBUG_IPT_QUOTA
4691 + printk("IPT Quota Failed: %llu datlen %d \n", q->quota, datalen);
4694 + spin_unlock_bh("a_lock);
4699 +checkentry(const char *tablename,
4700 + const struct ipt_ip *ip,
4701 + void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
4703 + /* TODO: spinlocks? sanity checks? */
4704 + if (matchsize != IPT_ALIGN(sizeof (struct ipt_quota_info)))
4710 +static struct ipt_match quota_match
4711 + = { {NULL, NULL}, "quota", &match, &checkentry, NULL, THIS_MODULE };
4716 + return ipt_register_match("a_match);
4722 + ipt_unregister_match("a_match);
4728 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
4729 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_random.c 1970-01-01 01:00:00.000000000 +0100
4730 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_random.c 2004-02-16 11:07:24.379118074 +0100
4733 + This is a module which is used for a "random" match support.
4734 + This file is distributed under the terms of the GNU General Public
4735 + License (GPL). Copies of the GPL can be obtained from:
4736 + ftp://prep.ai.mit.edu/pub/gnu/GPL
4738 + 2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
4741 +#include <linux/module.h>
4742 +#include <linux/skbuff.h>
4743 +#include <linux/ip.h>
4744 +#include <linux/random.h>
4745 +#include <net/tcp.h>
4746 +#include <linux/spinlock.h>
4747 +#include <linux/netfilter_ipv4/ip_tables.h>
4748 +#include <linux/netfilter_ipv4/ipt_random.h>
4750 +MODULE_LICENSE("GPL");
4753 +ipt_rand_match(const struct sk_buff *pskb,
4754 + const struct net_device *in,
4755 + const struct net_device *out,
4756 + const void *matchinfo,
4759 + u_int16_t datalen,
4762 + /* Parameters from userspace */
4763 + const struct ipt_rand_info *info = matchinfo;
4764 + u_int8_t random_number;
4766 + /* get 1 random number from the kernel random number generation routine */
4767 + get_random_bytes((void *)(&random_number), 1);
4769 + /* Do we match ? */
4770 + if (random_number <= info->average)
4777 +ipt_rand_checkentry(const char *tablename,
4778 + const struct ipt_ip *e,
4780 + unsigned int matchsize,
4781 + unsigned int hook_mask)
4783 + /* Parameters from userspace */
4784 + const struct ipt_rand_info *info = matchinfo;
4786 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_rand_info))) {
4787 + printk("ipt_random: matchsize %u != %u\n", matchsize,
4788 + IPT_ALIGN(sizeof(struct ipt_rand_info)));
4792 + /* must be 1 <= average % <= 99 */
4793 + /* 1 x 2.55 = 2 */
4794 + /* 99 x 2.55 = 252 */
4795 + if ((info->average < 2) || (info->average > 252)) {
4796 + printk("ipt_random: invalid average %u\n", info->average);
4803 +static struct ipt_match ipt_rand_reg = {
4807 + ipt_rand_checkentry,
4811 +static int __init init(void)
4813 + if (ipt_register_match(&ipt_rand_reg))
4816 + printk("ipt_random match loaded\n");
4820 +static void __exit fini(void)
4822 + ipt_unregister_match(&ipt_rand_reg);
4823 + printk("ipt_random match unloaded\n");
4828 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
4829 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_realm.c 1970-01-01 01:00:00.000000000 +0100
4830 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_realm.c 2004-02-16 11:07:26.369641375 +0100
4832 +/* Kernel module to match realm from routing. */
4833 +#include <linux/module.h>
4834 +#include <linux/skbuff.h>
4835 +#include <linux/netdevice.h>
4836 +#include <net/route.h>
4838 +#include <linux/netfilter_ipv4/ipt_realm.h>
4839 +#include <linux/netfilter_ipv4/ip_tables.h>
4841 +MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>");
4842 +MODULE_LICENSE("GPL");
4845 +match(const struct sk_buff *skb,
4846 + const struct net_device *in,
4847 + const struct net_device *out,
4848 + const void *matchinfo,
4851 + u_int16_t datalen,
4854 + const struct ipt_realm_info *info = matchinfo;
4855 + struct dst_entry *dst = skb->dst;
4860 + id = dst->tclassid;
4862 + return (info->id == (id & info->mask)) ^ info->invert;
4865 +static int check(const char *tablename,
4866 + const struct ipt_ip *ip,
4868 + unsigned int matchsize,
4869 + unsigned int hook_mask)
4872 + & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) |
4873 + (1 << NF_IP_LOCAL_OUT)| (1 << NF_IP_LOCAL_IN))) {
4874 + printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, "
4875 + "LOCAL_IN or FORWARD.\n");
4879 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info)))
4885 +static struct ipt_match realm_match
4886 += { { NULL, NULL }, "realm", &match, &check, NULL, THIS_MODULE };
4888 +static int __init init(void)
4890 + return ipt_register_match(&realm_match);
4893 +static void __exit fini(void)
4895 + ipt_unregister_match(&realm_match);
4900 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
4901 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_time.c 1970-01-01 01:00:00.000000000 +0100
4902 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_time.c 2004-02-16 11:07:27.150454383 +0100
4905 + This is a module which is used for time matching
4906 + It is using some modified code from dietlibc (localtime() function)
4907 + that you can find at http://www.fefe.de/dietlibc/
4908 + This file is distributed under the terms of the GNU General Public
4909 + License (GPL). Copies of the GPL can be obtained from: ftp://prep.ai.mit.edu/pub/gnu/GPL
4910 + 2001-05-04 Fabrice MARIE <fabrice@netfilter.org> : initial development.
4911 + 2001-21-05 Fabrice MARIE <fabrice@netfilter.org> : bug fix in the match code,
4912 + thanks to "Zeng Yu" <zengy@capitel.com.cn> for bug report.
4913 + 2001-26-09 Fabrice MARIE <fabrice@netfilter.org> : force the match to be in LOCAL_IN or PRE_ROUTING only.
4914 + 2001-30-11 Fabrice : added the possibility to use the match in FORWARD/OUTPUT with a little hack,
4915 + added Nguyen Dang Phuoc Dong <dongnd@tlnet.com.vn> patch to support timezones.
4918 +#include <linux/module.h>
4919 +#include <linux/skbuff.h>
4920 +#include <linux/netfilter_ipv4/ip_tables.h>
4921 +#include <linux/netfilter_ipv4/ipt_time.h>
4922 +#include <linux/time.h>
4924 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
4925 +MODULE_DESCRIPTION("Match arrival timestamp");
4926 +MODULE_LICENSE("GPL");
4930 + int tm_sec; /* Seconds. [0-60] (1 leap second) */
4931 + int tm_min; /* Minutes. [0-59] */
4932 + int tm_hour; /* Hours. [0-23] */
4933 + int tm_mday; /* Day. [1-31] */
4934 + int tm_mon; /* Month. [0-11] */
4935 + int tm_year; /* Year - 1900. */
4936 + int tm_wday; /* Day of week. [0-6] */
4937 + int tm_yday; /* Days in year.[0-365] */
4938 + int tm_isdst; /* DST. [-1/0/1]*/
4940 + long int tm_gmtoff; /* we don't care, we count from GMT */
4941 + const char *tm_zone; /* we don't care, we count from GMT */
4945 +localtime(const time_t *timepr, struct tm *r);
4948 +match(const struct sk_buff *skb,
4949 + const struct net_device *in,
4950 + const struct net_device *out,
4951 + const void *matchinfo,
4954 + u_int16_t datalen,
4957 + const struct ipt_time_info *info = matchinfo; /* match info for rule */
4958 + struct tm currenttime; /* time human readable */
4959 + u_int8_t days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
4960 + u_int16_t packet_time;
4961 + struct timeval kerneltimeval;
4962 + time_t packet_local_time;
4964 + /* if kerneltime=1, we don't read the skb->timestamp but kernel time instead */
4965 + if (info->kerneltime)
4967 + do_gettimeofday(&kerneltimeval);
4968 + packet_local_time = kerneltimeval.tv_sec;
4971 + packet_local_time = skb->stamp.tv_sec;
4973 + /* Transform the timestamp of the packet, in a human readable form */
4974 + localtime(&packet_local_time, ¤ttime);
4976 + /* check if we match this timestamp, we start by the days... */
4977 + if ((days_of_week[currenttime.tm_wday] & info->days_match) != days_of_week[currenttime.tm_wday])
4978 + return 0; /* the day doesn't match */
4980 + /* ... check the time now */
4981 + packet_time = (currenttime.tm_hour * 60) + currenttime.tm_min;
4982 + if ((packet_time < info->time_start) || (packet_time > info->time_stop))
4985 + /* here we match ! */
4990 +checkentry(const char *tablename,
4991 + const struct ipt_ip *ip,
4993 + unsigned int matchsize,
4994 + unsigned int hook_mask)
4996 + struct ipt_time_info *info = matchinfo; /* match info for rule */
4998 + /* First, check that we are in the correct hook */
4999 + /* PRE_ROUTING, LOCAL_IN or FROWARD */
5001 + & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
5003 + printk("ipt_time: error, only valid for PRE_ROUTING, LOCAL_IN, FORWARD and OUTPUT)\n");
5006 + /* we use the kerneltime if we are in forward or output */
5007 + info->kerneltime = 1;
5008 + if (hook_mask & ~((1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
5009 + /* if not, we use the skb time */
5010 + info->kerneltime = 0;
5012 + /* Check the size */
5013 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_time_info)))
5015 + /* Now check the coherence of the data ... */
5016 + if ((info->time_start > 1439) || /* 23*60+59 = 1439*/
5017 + (info->time_stop > 1439))
5019 + printk(KERN_WARNING "ipt_time: invalid argument\n");
5026 +static struct ipt_match time_match
5027 += { { NULL, NULL }, "time", &match, &checkentry, NULL, THIS_MODULE };
5029 +static int __init init(void)
5031 + printk("ipt_time loading\n");
5032 + return ipt_register_match(&time_match);
5035 +static void __exit fini(void)
5037 + ipt_unregister_match(&time_match);
5038 + printk("ipt_time unloaded\n");
5045 +/* The part below is borowed and modified from dietlibc */
5047 +/* seconds per day */
5048 +#define SPD 24*60*60
5051 +localtime(const time_t *timepr, struct tm *r) {
5054 + extern struct timezone sys_tz;
5055 + const unsigned int __spm[12] =
5062 + (31+28+31+30+31+30),
5063 + (31+28+31+30+31+30+31),
5064 + (31+28+31+30+31+30+31+31),
5065 + (31+28+31+30+31+30+31+31+30),
5066 + (31+28+31+30+31+30+31+31+30+31),
5067 + (31+28+31+30+31+30+31+31+30+31+30),
5069 + register time_t work;
5071 + timep = (*timepr) - (sys_tz.tz_minuteswest * 60);
5073 + r->tm_sec=work%60; work/=60;
5074 + r->tm_min=work%60; r->tm_hour=work/60;
5076 + r->tm_wday=(4+work)%7;
5077 + for (i=1970; ; ++i) {
5078 + register time_t k= (!(i%4) && ((i%100) || !(i%400)))?366:365;
5084 + r->tm_year=i-1900;
5085 + for (i=11; i && __spm[i]>work; --i) ;
5087 + r->tm_mday=work-__spm[i]+1;
5089 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
5090 --- linux-2.6.3-rc3.org/net/ipv4/netfilter/ipt_u32.c 1970-01-01 01:00:00.000000000 +0100
5091 +++ linux-2.6.3-rc3/net/ipv4/netfilter/ipt_u32.c 2004-02-16 11:07:28.175208970 +0100
5093 +/* Kernel module to match u32 packet content. */
5096 +U32 tests whether quantities of up to 4 bytes extracted from a packet
5097 +have specified values. The specification of what to extract is general
5098 +enough to find data at given offsets from tcp headers or payloads.
5101 + The argument amounts to a program in a small language described below.
5102 + tests := location = value | tests && location = value
5103 + value := range | value , range
5104 + range := number | number : number
5105 + a single number, n, is interpreted the same as n:n
5106 + n:m is interpreted as the range of numbers >=n and <=m
5107 + location := number | location operator number
5108 + operator := & | << | >> | @
5110 + The operators &, <<, >>, && mean the same as in c. The = is really a set
5111 + membership operator and the value syntax describes a set. The @ operator
5112 + is what allows moving to the next header and is described further below.
5114 + *** Until I can find out how to avoid it, there are some artificial limits
5115 + on the size of the tests:
5116 + - no more than 10 ='s (and 9 &&'s) in the u32 argument
5117 + - no more than 10 ranges (and 9 commas) per value
5118 + - no more than 10 numbers (and 9 operators) per location
5120 + To describe the meaning of location, imagine the following machine that
5121 + interprets it. There are three registers:
5122 + A is of type char*, initially the address of the IP header
5123 + B and C are unsigned 32 bit integers, initially zero
5125 + The instructions are:
5126 + number B = number;
5127 + C = (*(A+B)<<24)+(*(A+B+1)<<16)+(*(A+B+2)<<8)+*(A+B+3)
5128 + &number C = C&number
5129 + <<number C = C<<number
5130 + >>number C = C>>number
5131 + @number A = A+C; then do the instruction number
5132 + Any access of memory outside [skb->head,skb->end] causes the match to fail.
5133 + Otherwise the result of the computation is the final value of C.
5135 + Whitespace is allowed but not required in the tests.
5136 + However the characters that do occur there are likely to require
5137 + shell quoting, so it's a good idea to enclose the arguments in quotes.
5140 + match IP packets with total length >= 256
5141 + The IP header contains a total length field in bytes 2-3.
5142 + --u32 "0&0xFFFF=0x100:0xFFFF"
5144 + AND that with FFFF (giving bytes 2-3),
5145 + and test whether that's in the range [0x100:0xFFFF]
5147 +Example: (more realistic, hence more complicated)
5148 + match icmp packets with icmp type 0
5149 + First test that it's an icmp packet, true iff byte 9 (protocol) = 1
5150 + --u32 "6&0xFF=1 && ...
5151 + read bytes 6-9, use & to throw away bytes 6-8 and compare the result to 1
5152 + Next test that it's not a fragment.
5153 + (If so it might be part of such a packet but we can't always tell.)
5154 + n.b. This test is generally needed if you want to match anything
5155 + beyond the IP header.
5156 + The last 6 bits of byte 6 and all of byte 7 are 0 iff this is a complete
5157 + packet (not a fragment). Alternatively, you can allow first fragments
5158 + by only testing the last 5 bits of byte 6.
5159 + ... 4&0x3FFF=0 && ...
5160 + Last test: the first byte past the IP header (the type) is 0
5161 + This is where we have to use the @syntax. The length of the IP header
5162 + (IHL) in 32 bit words is stored in the right half of byte 0 of the
5164 + ... 0>>22&0x3C@0>>24=0"
5165 + The first 0 means read bytes 0-3,
5166 + >>22 means shift that 22 bits to the right. Shifting 24 bits would give
5167 + the first byte, so only 22 bits is four times that plus a few more bits.
5168 + &3C then eliminates the two extra bits on the right and the first four
5169 + bits of the first byte.
5170 + For instance, if IHL=5 then the IP header is 20 (4 x 5) bytes long.
5171 + In this case bytes 0-1 are (in binary) xxxx0101 yyzzzzzz,
5172 + >>22 gives the 10 bit value xxxx0101yy and &3C gives 010100.
5173 + @ means to use this number as a new offset into the packet, and read
5174 + four bytes starting from there. This is the first 4 bytes of the icmp
5175 + payload, of which byte 0 is the icmp type. Therefore we simply shift
5176 + the value 24 to the right to throw out all but the first byte and compare
5177 + the result with 0.
5180 + tcp payload bytes 8-12 is any of 1, 2, 5 or 8
5181 + First we test that the packet is a tcp packet (similar to icmp).
5182 + --u32 "6&0xFF=6 && ...
5183 + Next, test that it's not a fragment (same as above).
5184 + ... 0>>22&0x3C@12>>26&0x3C@8=1,2,5,8"
5185 + 0>>22&3C as above computes the number of bytes in the IP header.
5186 + @ makes this the new offset into the packet, which is the start of the
5187 + tcp header. The length of the tcp header (again in 32 bit words) is
5188 + the left half of byte 12 of the tcp header. The 12>>26&3C
5189 + computes this length in bytes (similar to the IP header before).
5190 + @ makes this the new offset, which is the start of the tcp payload.
5191 + Finally 8 reads bytes 8-12 of the payload and = checks whether the
5192 + result is any of 1, 2, 5 or 8
5195 +#include <linux/module.h>
5196 +#include <linux/skbuff.h>
5198 +#include <linux/netfilter_ipv4/ipt_u32.h>
5199 +#include <linux/netfilter_ipv4/ip_tables.h>
5201 +/* #include <asm-i386/timex.h> for timing */
5203 +MODULE_AUTHOR("Don Cohen <don@isis.cs3-inc.com>");
5204 +MODULE_DESCRIPTION("IP tables u32 matching module");
5205 +MODULE_LICENSE("GPL");
5208 +match(const struct sk_buff *skb,
5209 + const struct net_device *in,
5210 + const struct net_device *out,
5211 + const void *matchinfo,
5214 + u_int16_t datalen,
5217 + const struct ipt_u32 *data = matchinfo;
5219 + unsigned char* origbase = (char*)skb->nh.iph;
5220 + unsigned char* base = origbase;
5221 + unsigned char* head = skb->head;
5222 + unsigned char* end = skb->end;
5224 + u_int32_t pos, val;
5225 + /* unsigned long long cycles1, cycles2, cycles3, cycles4;
5226 + cycles1 = get_cycles(); */
5228 + for (testind=0; testind < data->ntests; testind++) {
5229 + base = origbase; /* reset for each test */
5230 + pos = data->tests[testind].location[0].number;
5231 + if (base+pos+3 > end || base+pos < head)
5233 + val = (base[pos]<<24) + (base[pos+1]<<16) +
5234 + (base[pos+2]<<8) + base[pos+3];
5235 + nnums = data->tests[testind].nnums;
5236 + for (i=1; i < nnums; i++) {
5237 + u_int32_t number = data->tests[testind].location[i].number;
5238 + switch (data->tests[testind].location[i].nextop) {
5240 + val = val & number;
5242 + case IPT_U32_LEFTSH:
5243 + val = val << number;
5245 + case IPT_U32_RIGHTSH:
5246 + val = val >> number;
5249 + base = base + val;
5251 + if (base+pos+3 > end || base+pos < head)
5253 + val = (base[pos]<<24) + (base[pos+1]<<16) +
5254 + (base[pos+2]<<8) + base[pos+3];
5258 + nvals = data->tests[testind].nvalues;
5259 + for (i=0; i < nvals; i++) {
5260 + if ((data->tests[testind].value[i].min <= val) &&
5261 + (val <= data->tests[testind].value[i].max)) {
5265 + if (i >= data->tests[testind].nvalues) {
5266 + /* cycles2 = get_cycles();
5267 + printk("failed %d in %d cycles\n", testind,
5268 + cycles2-cycles1); */
5272 + /* cycles2 = get_cycles();
5273 + printk("succeeded in %d cycles\n", cycles2-cycles1); */
5278 +checkentry(const char *tablename,
5279 + const struct ipt_ip *ip,
5281 + unsigned int matchsize,
5282 + unsigned int hook_mask)
5284 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_u32)))
5289 +static struct ipt_match u32_match
5290 += { { NULL, NULL }, "u32", &match, &checkentry, NULL, THIS_MODULE };
5292 +static int __init init(void)
5294 + return ipt_register_match(&u32_match);
5297 +static void __exit fini(void)
5299 + ipt_unregister_match(&u32_match);
5304 diff -Nur linux-2.6.3-rc3.org/net/ipv6/netfilter/Kconfig linux-2.6.3-rc3/net/ipv6/netfilter/Kconfig
5305 --- linux-2.6.3-rc3.org/net/ipv6/netfilter/Kconfig 2004-02-15 03:45:16.000000000 +0100
5306 +++ linux-2.6.3-rc3/net/ipv6/netfilter/Kconfig 2004-02-16 11:07:24.383117116 +0100
5307 @@ -218,5 +218,85 @@
5308 To compile it as a module, choose M here. If unsure, say N.
5310 #dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES
5311 +config IP6_NF_TARGET_HL
5312 + tristate 'HL target support'
5313 + depends on IP6_NF_MANGLE
5315 + This allows the user to set the IPv6 Hop Limit value on a packet or
5316 + to increment or decrement it by a given value.
5319 + # ip6tables -t mangle -A OUTPUT -j HL --hl-inc 1
5320 + # ip6tables -t mangle -A INPUT -j HL --hl-eq 64
5321 + # ip6tables -t mangle -A OUTPUT -j HL --hl-dec 2
5323 +config IP6_NF_TARGET_REJECT
5324 + tristate 'REJECT target support'
5325 + depends on IP6_NF_FILTER
5327 + This CONFIG_IP6_NF_TARGET_REJECT option adds a REJECT target to ip6tables.
5328 + Please keep in mind that the icmp-types are different from the icmpv6 types
5329 + (see ip6tables -j REJECT -h for more info)
5331 +config IP6_NF_MATCH_FUZZY
5332 + tristate 'Fuzzy match support'
5333 + depends on IP6_NF_FILTER
5335 + This option adds a `fuzzy' match which allows you to match packets according to
5336 + a dynamic profile implemented by means of a simple Fuzzy Logic Controller (FLC)
5338 +config IP6_NF_MATCH_NTH
5339 + tristate 'Nth match support'
5340 + depends on IP6_NF_IPTABLES
5342 + This option adds an iptables `Nth' match, which allows you to match every Nth
5343 + packet encountered. By default there are 16 different counters that can be
5346 + This match functions in one of two ways
5347 + 1) Match ever Nth packet, and only the Nth packet.
5349 + iptables -t mangle -A PREROUTING -m nth --every 10 -j DROP
5350 + This rule will drop every 10th packet.
5351 + 2) Unique rule for every packet. This is an easy and quick
5352 + method to produce load-balancing for both inbound and outbound.
5354 + iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
5355 + --every 3 --packet 0 -j SNAT --to-source 10.0.0.5
5356 + iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
5357 + --every 3 --packet 1 -j SNAT --to-source 10.0.0.6
5358 + iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 \
5359 + --every 3 --packet 2 -j SNAT --to-source 10.0.0.7
5360 + This example evenly splits connections between the three SNAT
5363 + By using the mangle table and iproute2, you can setup complex
5364 + load-balanced routing. There's lot of other uses. Be creative!
5366 + Suppported options are:
5367 + --every Nth Match every Nth packet
5368 + [--counter] num Use counter 0-15 (default:0)
5369 + [--start] num Initialize the counter at the number 'num'
5370 + instead of 0. Must be between 0 and Nth-1
5371 + [--packet] num Match on 'num' packet. Must be between 0
5373 + If --packet is used for a counter than
5374 + there must be Nth number of --packet
5375 + rules, covering all values between 0 and
5376 + Nth-1 inclusively.
5378 +config IP6_NF_MATCH_RANDOM
5379 + tristate 'Random match support'
5380 + depends on IP6_NF_IPTABLES
5382 + This option adds a `random' match,
5383 + which allow you to match packets randomly
5384 + following a given probability.
5386 + Suppported options are:
5388 + [--average] percent will match randomly packets with a probability of
5389 + 'percent'. default is 50%
5393 diff -Nur linux-2.6.3-rc3.org/net/ipv6/netfilter/Makefile linux-2.6.3-rc3/net/ipv6/netfilter/Makefile
5394 --- linux-2.6.3-rc3.org/net/ipv6/netfilter/Makefile 2004-02-15 03:44:25.000000000 +0100
5395 +++ linux-2.6.3-rc3/net/ipv6/netfilter/Makefile 2004-02-16 11:07:24.383117116 +0100
5397 obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o
5398 obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
5399 obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o
5400 +obj-$(CONFIG_IP6_NF_MATCH_FUZZY) += ip6t_fuzzy.o
5401 obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
5402 obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
5403 obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
5405 obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
5406 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
5407 obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
5408 +obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
5409 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
5410 obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
5412 +obj-$(CONFIG_IP6_NF_MATCH_RANDOM) += ip6t_random.o
5414 +obj-$(CONFIG_IP6_NF_MATCH_NTH) += ip6t_nth.o
5415 +obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
5416 obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
5417 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
5418 --- linux-2.6.3-rc3.org/net/ipv6/netfilter/ip6t_HL.c 1970-01-01 01:00:00.000000000 +0100
5419 +++ linux-2.6.3-rc3/net/ipv6/netfilter/ip6t_HL.c 2004-02-16 11:06:53.521507853 +0100
5422 + * Hop Limit modification target for ip6tables
5423 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
5424 + * Based on HW's TTL module
5426 + * This software is distributed under the terms of GNU GPL
5429 +#include <linux/module.h>
5430 +#include <linux/skbuff.h>
5431 +#include <linux/ip.h>
5433 +#include <linux/netfilter_ipv6/ip6_tables.h>
5434 +#include <linux/netfilter_ipv6/ip6t_HL.h>
5436 +MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
5437 +MODULE_DESCRIPTION("IP tables Hop Limit modification module");
5438 +MODULE_LICENSE("GPL");
5440 +static unsigned int ip6t_hl_target(struct sk_buff **pskb, unsigned int hooknum,
5441 + const struct net_device *in, const struct net_device *out,
5442 + const void *targinfo, void *userinfo)
5444 + struct ipv6hdr *ip6h = (*pskb)->nh.ipv6h;
5445 + const struct ip6t_HL_info *info = targinfo;
5446 + u_int16_t diffs[2];
5449 + switch (info->mode) {
5451 + new_hl = info->hop_limit;
5454 + new_hl = ip6h->hop_limit + info->hop_limit;
5459 + new_hl = ip6h->hop_limit + info->hop_limit;
5464 + new_hl = ip6h->hop_limit;
5468 + if (new_hl != ip6h->hop_limit) {
5469 + diffs[0] = htons(((unsigned)ip6h->hop_limit) << 8) ^ 0xFFFF;
5470 + ip6h->hop_limit = new_hl;
5471 + diffs[1] = htons(((unsigned)ip6h->hop_limit) << 8);
5474 + return IP6T_CONTINUE;
5477 +static int ip6t_hl_checkentry(const char *tablename,
5478 + const struct ip6t_entry *e,
5480 + unsigned int targinfosize,
5481 + unsigned int hook_mask)
5483 + struct ip6t_HL_info *info = targinfo;
5485 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_HL_info))) {
5486 + printk(KERN_WARNING "HL: targinfosize %u != %Zu\n",
5488 + IP6T_ALIGN(sizeof(struct ip6t_HL_info)));
5492 + if (strcmp(tablename, "mangle")) {
5493 + printk(KERN_WARNING "HL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
5497 + if (info->mode > IP6T_HL_MAXMODE) {
5498 + printk(KERN_WARNING "HL: invalid or unknown Mode %u\n",
5503 + if ((info->mode != IP6T_HL_SET) && (info->hop_limit == 0)) {
5504 + printk(KERN_WARNING "HL: increment/decrement doesn't make sense with value 0\n");
5511 +static struct ip6t_target ip6t_HL = { { NULL, NULL }, "HL",
5512 + ip6t_hl_target, ip6t_hl_checkentry, NULL, THIS_MODULE };
5514 +static int __init init(void)
5516 + return ip6t_register_target(&ip6t_HL);
5519 +static void __exit fini(void)
5521 + ip6t_unregister_target(&ip6t_HL);
5526 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
5527 --- linux-2.6.3-rc3.org/net/ipv6/netfilter/ip6t_REJECT.c 1970-01-01 01:00:00.000000000 +0100
5528 +++ linux-2.6.3-rc3/net/ipv6/netfilter/ip6t_REJECT.c 2004-02-16 11:07:07.805087251 +0100
5531 + * This is a module which is used for rejecting packets.
5532 + * Added support for customized reject packets (Jozsef Kadlecsik).
5534 + * Port to IPv6 / ip6tables (Harald Welte <laforge@gnumonks.org>)
5536 +#include <linux/config.h>
5537 +#include <linux/module.h>
5538 +#include <linux/skbuff.h>
5539 +#include <linux/icmpv6.h>
5540 +#include <net/tcp.h>
5541 +#include <linux/netfilter_ipv6/ip6_tables.h>
5542 +#include <linux/netfilter_ipv6/ip6t_REJECT.h>
5545 +#define DEBUGP printk
5547 +#define DEBUGP(format, args...)
5551 +/* Send RST reply */
5552 +static void send_reset(struct sk_buff *oldskb)
5554 + struct sk_buff *nskb;
5555 + struct tcphdr *otcph, *tcph;
5556 + struct rtable *rt;
5557 + unsigned int otcplen;
5560 + /* IP header checks: fragment, too short. */
5561 + if (oldskb->nh.iph->frag_off & htons(IP_OFFSET)
5562 + || oldskb->len < (oldskb->nh.iph->ihl<<2) + sizeof(struct tcphdr))
5565 + otcph = (struct tcphdr *)((u_int32_t*)oldskb->nh.iph + oldskb->nh.iph->ihl);
5566 + otcplen = oldskb->len - oldskb->nh.iph->ihl*4;
5568 + /* No RST for RST. */
5572 + /* Check checksum. */
5573 + if (tcp_v4_check(otcph, otcplen, oldskb->nh.iph->saddr,
5574 + oldskb->nh.iph->daddr,
5575 + csum_partial((char *)otcph, otcplen, 0)) != 0)
5578 + /* Copy skb (even if skb is about to be dropped, we can't just
5579 + clone it because there may be other things, such as tcpdump,
5580 + interested in it) */
5581 + nskb = skb_copy(oldskb, GFP_ATOMIC);
5585 + /* This packet will not be the same as the other: clear nf fields */
5586 + nf_conntrack_put(nskb->nfct);
5587 + nskb->nfct = NULL;
5588 + nskb->nfcache = 0;
5589 +#ifdef CONFIG_NETFILTER_DEBUG
5590 + nskb->nf_debug = 0;
5593 + tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
5595 + nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
5596 + tcph->source = xchg(&tcph->dest, tcph->source);
5598 + /* Truncate to length (no data) */
5599 + tcph->doff = sizeof(struct tcphdr)/4;
5600 + skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
5601 + nskb->nh.iph->tot_len = htons(nskb->len);
5605 + tcph->seq = otcph->ack_seq;
5606 + tcph->ack_seq = 0;
5609 + tcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn + otcph->fin
5610 + + otcplen - (otcph->doff<<2));
5615 + ((u_int8_t *)tcph)[13] = 0;
5617 + tcph->ack = needs_ack;
5620 + tcph->urg_ptr = 0;
5622 + /* Adjust TCP checksum */
5624 + tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
5625 + nskb->nh.iph->saddr,
5626 + nskb->nh.iph->daddr,
5627 + csum_partial((char *)tcph,
5628 + sizeof(struct tcphdr), 0));
5630 + /* Adjust IP TTL, DF */
5631 + nskb->nh.iph->ttl = MAXTTL;
5632 + /* Set DF, id = 0 */
5633 + nskb->nh.iph->frag_off = htons(IP_DF);
5634 + nskb->nh.iph->id = 0;
5636 + /* Adjust IP checksum */
5637 + nskb->nh.iph->check = 0;
5638 + nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,
5639 + nskb->nh.iph->ihl);
5642 + if (ip_route_output(&rt, nskb->nh.iph->daddr, nskb->nh.iph->saddr,
5643 + RT_TOS(nskb->nh.iph->tos) | RTO_CONN,
5647 + dst_release(nskb->dst);
5648 + nskb->dst = &rt->u.dst;
5650 + /* "Never happens" */
5651 + if (nskb->len > nskb->dst->pmtu)
5654 + NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
5655 + ip_finish_output);
5663 +static unsigned int reject6_target(struct sk_buff **pskb,
5664 + unsigned int hooknum,
5665 + const struct net_device *in,
5666 + const struct net_device *out,
5667 + const void *targinfo,
5670 + const struct ip6t_reject_info *reject = targinfo;
5672 + /* WARNING: This code causes reentry within ip6tables.
5673 + This means that the ip6tables jump stack is now crap. We
5674 + must return an absolute verdict. --RR */
5675 + DEBUGP("REJECTv6: calling icmpv6_send\n");
5676 + switch (reject->with) {
5677 + case IP6T_ICMP6_NO_ROUTE:
5678 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, out);
5680 + case IP6T_ICMP6_ADM_PROHIBITED:
5681 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADM_PROHIBITED, 0, out);
5683 + case IP6T_ICMP6_NOT_NEIGHBOUR:
5684 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOT_NEIGHBOUR, 0, out);
5686 + case IP6T_ICMP6_ADDR_UNREACH:
5687 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, out);
5689 + case IP6T_ICMP6_PORT_UNREACH:
5690 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, out);
5693 + case IPT_ICMP_ECHOREPLY: {
5694 + struct icmp6hdr *icmph = (struct icmphdr *)
5695 + ((u_int32_t *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl);
5696 + unsigned int datalen = (*pskb)->len - (*pskb)->nh.iph->ihl * 4;
5698 + /* Not non-head frags, or truncated */
5699 + if (((ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET) == 0)
5700 + && datalen >= 4) {
5701 + /* Usually I don't like cut & pasting code,
5702 + but dammit, my party is starting in 45
5704 + struct icmp_bxm icmp_param;
5706 + icmp_param.icmph=*icmph;
5707 + icmp_param.icmph.type=ICMP_ECHOREPLY;
5708 + icmp_param.data_ptr=(icmph+1);
5709 + icmp_param.data_len=datalen;
5710 + icmp_reply(&icmp_param, *pskb);
5714 + case IPT_TCP_RESET:
5715 + send_reset(*pskb);
5719 + printk(KERN_WARNING "REJECTv6: case %u not handled yet\n", reject->with);
5726 +static inline int find_ping_match(const struct ip6t_entry_match *m)
5728 + const struct ip6t_icmp *icmpinfo = (const struct ip6t_icmp *)m->data;
5730 + if (strcmp(m->u.kernel.match->name, "icmp6") == 0
5731 + && icmpinfo->type == ICMPV6_ECHO_REQUEST
5732 + && !(icmpinfo->invflags & IP6T_ICMP_INV))
5738 +static int check(const char *tablename,
5739 + const struct ip6t_entry *e,
5741 + unsigned int targinfosize,
5742 + unsigned int hook_mask)
5744 + const struct ip6t_reject_info *rejinfo = targinfo;
5746 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
5747 + DEBUGP("REJECTv6: targinfosize %u != 0\n", targinfosize);
5751 + /* Only allow these for packet filtering. */
5752 + if (strcmp(tablename, "filter") != 0) {
5753 + DEBUGP("REJECTv6: bad table `%s'.\n", tablename);
5756 + if ((hook_mask & ~((1 << NF_IP6_LOCAL_IN)
5757 + | (1 << NF_IP6_FORWARD)
5758 + | (1 << NF_IP6_LOCAL_OUT))) != 0) {
5759 + DEBUGP("REJECTv6: bad hook mask %X\n", hook_mask);
5763 + if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
5764 + /* Must specify that it's an ICMP ping packet. */
5765 + if (e->ipv6.proto != IPPROTO_ICMPV6
5766 + || (e->ipv6.invflags & IP6T_INV_PROTO)) {
5767 + DEBUGP("REJECTv6: ECHOREPLY illegal for non-icmp\n");
5770 + /* Must contain ICMP match. */
5771 + if (IP6T_MATCH_ITERATE(e, find_ping_match) == 0) {
5772 + DEBUGP("REJECTv6: ECHOREPLY illegal for non-ping\n");
5775 + } else if (rejinfo->with == IP6T_TCP_RESET) {
5776 + /* Must specify that it's a TCP packet */
5777 + if (e->ipv6.proto != IPPROTO_TCP
5778 + || (e->ipv6.invflags & IP6T_INV_PROTO)) {
5779 + DEBUGP("REJECTv6: TCP_RESET illegal for non-tcp\n");
5787 +static struct ip6t_target ip6t_reject_reg
5788 += { { NULL, NULL }, "REJECT", reject6_target, check, NULL, THIS_MODULE };
5790 +static int __init init(void)
5792 + if (ip6t_register_target(&ip6t_reject_reg))
5797 +static void __exit fini(void)
5799 + ip6t_unregister_target(&ip6t_reject_reg);
5804 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
5805 --- linux-2.6.3-rc3.org/net/ipv6/netfilter/ip6t_fuzzy.c 1970-01-01 01:00:00.000000000 +0100
5806 +++ linux-2.6.3-rc3/net/ipv6/netfilter/ip6t_fuzzy.c 2004-02-16 11:07:14.926381841 +0100
5809 + * This module implements a simple TSK FLC
5810 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
5811 + * to limit , in an adaptive and flexible way , the packet rate crossing
5812 + * a given stream . It serves as an initial and very simple (but effective)
5813 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
5814 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
5815 + * into our code in a precise , adaptive and efficient manner.
5816 + * The goal is very similar to that of "limit" match , but using techniques of
5817 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
5818 + * avoiding over and undershoots - and stuff like that .
5821 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
5822 + * 2002-08-17 : Changed to eliminate floating point operations .
5823 + * 2002-08-23 : Coding style changes .
5824 + * 2003-04-08 Maciej Soltysiak <solt@dns.toxicilms.tv> : IPv6 Port
5827 +#include <linux/module.h>
5828 +#include <linux/skbuff.h>
5829 +#include <linux/ipv6.h>
5830 +#include <linux/random.h>
5831 +#include <net/tcp.h>
5832 +#include <linux/spinlock.h>
5833 +#include <linux/netfilter_ipv6/ip6_tables.h>
5834 +#include <linux/netfilter_ipv6/ip6t_fuzzy.h>
5837 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
5838 + Expressed in percentage
5841 +#define PAR_LOW 1/100
5844 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED;
5846 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
5847 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
5848 +MODULE_LICENSE("GPL");
5850 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
5852 + if (tx >= maxi) return 100;
5854 + if (tx <= mini) return 0;
5856 + return ((100 * (tx-mini)) / (maxi-mini));
5859 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
5861 + if (tx <= mini) return 100;
5863 + if (tx >= maxi) return 0;
5865 + return ((100 * (maxi - tx)) / (maxi - mini));
5870 +ip6t_fuzzy_match(const struct sk_buff *pskb,
5871 + const struct net_device *in,
5872 + const struct net_device *out,
5873 + const void *matchinfo,
5876 + u_int16_t datalen,
5879 + /* From userspace */
5881 + struct ip6t_fuzzy_info *info = (struct ip6t_fuzzy_info *) matchinfo;
5883 + u_int8_t random_number;
5884 + unsigned long amount;
5885 + u_int8_t howhigh, howlow;
5888 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
5890 + info->bytes_total += pskb->len;
5891 + info->packets_total++;
5893 + info->present_time = jiffies;
5895 + if (info->present_time >= info->previous_time)
5896 + amount = info->present_time - info->previous_time;
5898 + /* There was a transition : I choose to re-sample
5899 + and keep the old acceptance rate...
5903 + info->previous_time = info->present_time;
5904 + info->bytes_total = info->packets_total = 0;
5907 + if ( amount > HZ/10) {/* More than 100 ms elapsed ... */
5909 + info->mean_rate = (u_int32_t) ((HZ * info->packets_total) \
5912 + info->previous_time = info->present_time;
5913 + info->bytes_total = info->packets_total = 0;
5915 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
5916 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
5918 + info->acceptance_rate = (u_int8_t) \
5919 + (howhigh * PAR_LOW + PAR_HIGH * howlow);
5921 + /* In fact, the above defuzzification would require a denominator
5922 + * proportional to (howhigh+howlow) but, in this particular case,
5923 + * that expression is constant.
5924 + * An imediate consequence is that it is not necessary to call
5925 + * both mf_high and mf_low - but to keep things understandable,
5931 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
5934 + if (info->acceptance_rate < 100)
5936 + get_random_bytes((void *)(&random_number), 1);
5938 + /* If within the acceptance , it can pass => don't match */
5939 + if (random_number <= (255 * info->acceptance_rate) / 100)
5942 + return 1; /* It can't pass (It matches) */
5945 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
5950 +ip6t_fuzzy_checkentry(const char *tablename,
5951 + const struct ip6t_ip6 *ip,
5953 + unsigned int matchsize,
5954 + unsigned int hook_mask)
5957 + const struct ip6t_fuzzy_info *info = matchinfo;
5959 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info))) {
5960 + printk("ip6t_fuzzy: matchsize %u != %u\n", matchsize,
5961 + IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info)));
5965 + if ((info->minimum_rate < MINFUZZYRATE) || (info->maximum_rate > MAXFUZZYRATE)
5966 + || (info->minimum_rate >= info->maximum_rate)) {
5967 + printk("ip6t_fuzzy: BAD limits , please verify !!!\n");
5974 +static struct ip6t_match ip6t_fuzzy_reg = {
5978 + ip6t_fuzzy_checkentry,
5982 +static int __init init(void)
5984 + if (ip6t_register_match(&ip6t_fuzzy_reg))
5990 +static void __exit fini(void)
5992 + ip6t_unregister_match(&ip6t_fuzzy_reg);
5997 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
5998 --- linux-2.6.3-rc3.org/net/ipv6/netfilter/ip6t_nth.c 1970-01-01 01:00:00.000000000 +0100
5999 +++ linux-2.6.3-rc3/net/ipv6/netfilter/ip6t_nth.c 2004-02-16 11:07:18.803453352 +0100
6002 + This is a module which is used for match support for every Nth packet
6003 + This file is distributed under the terms of the GNU General Public
6004 + License (GPL). Copies of the GPL can be obtained from:
6005 + ftp://prep.ai.mit.edu/pub/gnu/GPL
6007 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
6008 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
6009 + * added support for multiple counters
6010 + * added support for matching on individual packets
6011 + in the counter cycle
6012 + 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
6016 +#include <linux/module.h>
6017 +#include <linux/skbuff.h>
6018 +#include <linux/ip.h>
6019 +#include <net/tcp.h>
6020 +#include <linux/spinlock.h>
6021 +#include <linux/netfilter_ipv6/ip6_tables.h>
6022 +#include <linux/netfilter_ipv6/ip6t_nth.h>
6024 +MODULE_LICENSE("GPL");
6027 + * State information.
6034 +static struct state states[IP6T_NTH_NUM_COUNTERS];
6037 +ip6t_nth_match(const struct sk_buff *pskb,
6038 + const struct net_device *in,
6039 + const struct net_device *out,
6040 + const void *matchinfo,
6043 + u_int16_t datalen,
6046 + /* Parameters from userspace */
6047 + const struct ip6t_nth_info *info = matchinfo;
6048 + unsigned counter = info->counter;
6049 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
6051 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
6055 + spin_lock(&states[counter].lock);
6057 + /* Are we matching every nth packet?*/
6058 + if (info->packet == 0xFF)
6060 + /* We're matching every nth packet and only every nth packet*/
6061 + /* Do we match or invert match? */
6062 + if (info->not == 0)
6064 + if (states[counter].number == 0)
6066 + ++states[counter].number;
6069 + if (states[counter].number >= info->every)
6070 + states[counter].number = 0; /* reset the counter */
6072 + ++states[counter].number;
6077 + if (states[counter].number == 0)
6079 + ++states[counter].number;
6082 + if (states[counter].number >= info->every)
6083 + states[counter].number = 0;
6085 + ++states[counter].number;
6091 + /* We're using the --packet, so there must be a rule for every value */
6092 + if (states[counter].number == info->packet)
6094 + /* only increment the counter when a match happens */
6095 + if (states[counter].number >= info->every)
6096 + states[counter].number = 0; /* reset the counter */
6098 + ++states[counter].number;
6107 + spin_unlock(&states[counter].lock);
6111 + spin_unlock(&states[counter].lock);
6116 +ip6t_nth_checkentry(const char *tablename,
6117 + const struct ip6t_ip6 *e,
6119 + unsigned int matchsize,
6120 + unsigned int hook_mask)
6122 + /* Parameters from userspace */
6123 + const struct ip6t_nth_info *info = matchinfo;
6124 + unsigned counter = info->counter;
6125 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
6127 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
6131 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_nth_info))) {
6132 + printk("nth: matchsize %u != %u\n", matchsize,
6133 + IP6T_ALIGN(sizeof(struct ip6t_nth_info)));
6137 + states[counter].number = info->startat;
6142 +static struct ip6t_match ip6t_nth_reg = {
6146 + ip6t_nth_checkentry,
6150 +static int __init init(void)
6153 + memset(&states, 0, sizeof(states));
6154 + if (ip6t_register_match(&ip6t_nth_reg))
6157 + for(counter = 0; counter < IP6T_NTH_NUM_COUNTERS; counter++)
6159 + spin_lock_init(&(states[counter].lock));
6162 + printk("ip6t_nth match loaded\n");
6166 +static void __exit fini(void)
6168 + ip6t_unregister_match(&ip6t_nth_reg);
6169 + printk("ip6t_nth match unloaded\n");
6174 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
6175 --- linux-2.6.3-rc3.org/net/ipv6/netfilter/ip6t_random.c 1970-01-01 01:00:00.000000000 +0100
6176 +++ linux-2.6.3-rc3/net/ipv6/netfilter/ip6t_random.c 2004-02-16 11:07:24.379118074 +0100
6179 + This is a module which is used for a "random" match support.
6180 + This file is distributed under the terms of the GNU General Public
6181 + License (GPL). Copies of the GPL can be obtained from:
6182 + ftp://prep.ai.mit.edu/pub/gnu/GPL
6184 + 2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
6185 + 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
6188 +#include <linux/module.h>
6189 +#include <linux/skbuff.h>
6190 +#include <linux/ip.h>
6191 +#include <linux/random.h>
6192 +#include <net/tcp.h>
6193 +#include <linux/spinlock.h>
6194 +#include <linux/netfilter_ipv6/ip6_tables.h>
6195 +#include <linux/netfilter_ipv6/ip6t_random.h>
6197 +MODULE_LICENSE("GPL");
6200 +ip6t_rand_match(const struct sk_buff *pskb,
6201 + const struct net_device *in,
6202 + const struct net_device *out,
6203 + const void *matchinfo,
6206 + u_int16_t datalen,
6209 + /* Parameters from userspace */
6210 + const struct ip6t_rand_info *info = matchinfo;
6211 + u_int8_t random_number;
6213 + /* get 1 random number from the kernel random number generation routine */
6214 + get_random_bytes((void *)(&random_number), 1);
6216 + /* Do we match ? */
6217 + if (random_number <= info->average)
6224 +ip6t_rand_checkentry(const char *tablename,
6225 + const struct ip6t_ip6 *e,
6227 + unsigned int matchsize,
6228 + unsigned int hook_mask)
6230 + /* Parameters from userspace */
6231 + const struct ip6t_rand_info *info = matchinfo;
6233 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_rand_info))) {
6234 + printk("ip6t_random: matchsize %u != %u\n", matchsize,
6235 + IP6T_ALIGN(sizeof(struct ip6t_rand_info)));
6239 + /* must be 1 <= average % <= 99 */
6240 + /* 1 x 2.55 = 2 */
6241 + /* 99 x 2.55 = 252 */
6242 + if ((info->average < 2) || (info->average > 252)) {
6243 + printk("ip6t_random: invalid average %u\n", info->average);
6250 +static struct ip6t_match ip6t_rand_reg = {
6254 + ip6t_rand_checkentry,
6258 +static int __init init(void)
6260 + if (ip6t_register_match(&ip6t_rand_reg))
6263 + printk("ip6t_random match loaded\n");
6267 +static void __exit fini(void)
6269 + ip6t_unregister_match(&ip6t_rand_reg);
6270 + printk("ip6t_random match unloaded\n");