1 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter.h linux-2.6.4-rc2/include/linux/netfilter.h
2 --- linux-2.6.4-rc2.org/include/linux/netfilter.h 2004-03-04 06:16:47.000000000 +0000
3 +++ linux-2.6.4-rc2/include/linux/netfilter.h 2004-03-07 08:43:12.000000000 +0000
6 extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
8 +typedef void nf_logfn(unsigned int hooknum,
9 + const struct sk_buff *skb,
10 + const struct net_device *in,
11 + const struct net_device *out,
12 + const char *prefix);
14 +/* Function to register/unregister log function. */
15 +int nf_log_register(int pf, nf_logfn *logfn);
16 +void nf_log_unregister(int pf, nf_logfn *logfn);
18 +/* Calls the registered backend logging function */
19 +void nf_log_packet(int pf,
20 + unsigned int hooknum,
21 + const struct sk_buff *skb,
22 + const struct net_device *in,
23 + const struct net_device *out,
24 + const char *fmt, ...);
26 /* Activate hook; either okfn or kfree_skb called, unless a hook
27 returns NF_STOLEN (in which case, it's up to the hook to deal with
29 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.4-rc2/include/linux/netfilter_ipv4/ip_conntrack.h
30 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ip_conntrack.h 2004-03-04 06:17:04.000000000 +0000
31 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv4/ip_conntrack.h 2004-03-07 08:43:29.000000000 +0000
33 /* Call me when a conntrack is destroyed. */
34 extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack);
36 +/* Fake conntrack entry for untracked connections */
37 +extern struct ip_conntrack ip_conntrack_untracked;
39 /* Returns new sk_buff, or NULL */
41 ip_ct_gather_frags(struct sk_buff *skb);
42 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_TTL.h linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_TTL.h
43 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_TTL.h 1970-01-01 00:00:00.000000000 +0000
44 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_TTL.h 2004-03-07 08:43:16.000000000 +0000
46 +/* TTL modification module for IP tables
47 + * (C) 2000 by Harald Welte <laforge@gnumonks.org> */
58 +#define IPT_TTL_MAXMODE IPT_TTL_DEC
60 +struct ipt_TTL_info {
67 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_ULOG.h linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_ULOG.h
68 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_ULOG.h 2004-03-04 06:16:43.000000000 +0000
69 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_ULOG.h 2004-03-07 08:43:12.000000000 +0000
71 #define NETLINK_NFLOG 5
74 +#define ULOG_DEFAULT_NLGROUP 1
75 +#define ULOG_DEFAULT_QTHRESHOLD 1
77 #define ULOG_MAC_LEN 80
78 #define ULOG_PREFIX_LEN 32
80 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_connlimit.h linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_connlimit.h
81 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_connlimit.h 1970-01-01 00:00:00.000000000 +0000
82 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_connlimit.h 2004-03-07 08:43:18.000000000 +0000
84 +#ifndef _IPT_CONNLIMIT_H
85 +#define _IPT_CONNLIMIT_H
87 +struct ipt_connlimit_data;
89 +struct ipt_connlimit_info {
93 + struct ipt_connlimit_data *data;
95 +#endif /* _IPT_CONNLIMIT_H */
96 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_conntrack.h linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_conntrack.h
97 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_conntrack.h 2004-03-04 06:16:55.000000000 +0000
98 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_conntrack.h 2004-03-07 08:43:29.000000000 +0000
101 #define IPT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1))
102 #define IPT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2))
103 +#define IPT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3))
105 /* flags, invflags: */
106 #define IPT_CONNTRACK_STATE 0x01
107 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_dstlimit.h linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_dstlimit.h
108 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_dstlimit.h 1970-01-01 00:00:00.000000000 +0000
109 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_dstlimit.h 2004-03-07 08:43:19.000000000 +0000
111 +#ifndef _IPT_DSTLIMIT_H
112 +#define _IPT_DSTLIMIT_H
114 +/* timings are in milliseconds. */
115 +#define IPT_DSTLIMIT_SCALE 10000
116 +/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490
117 + seconds, or one every 59 hours. */
119 +/* details of this structure hidden by the implementation */
120 +struct ipt_dstlimit_htable;
122 +#define IPT_DSTLIMIT_HASH_DIP 0x0001
123 +#define IPT_DSTLIMIT_HASH_DPT 0x0002
124 +#define IPT_DSTLIMIT_HASH_SIP 0x0004
126 +struct dstlimit_cfg {
127 + u_int32_t mode; /* bitmask of IPT_DSTLIMIT_HASH_* */
128 + u_int32_t avg; /* Average secs between packets * scale */
129 + u_int32_t burst; /* Period multiplier for upper limit. */
131 + /* user specified */
132 + u_int32_t size; /* how many buckets */
133 + u_int32_t max; /* max number of entries */
134 + u_int32_t gc_interval; /* gc interval */
135 + u_int32_t expire; /* when do entries expire? */
138 +struct ipt_dstlimit_info {
139 + char name [IFNAMSIZ]; /* name */
140 + struct dstlimit_cfg cfg;
141 + struct ipt_dstlimit_htable *hinfo;
143 + /* Used internally by the kernel */
146 + struct ipt_dstlimit_info *master;
149 +#endif /*_IPT_DSTLIMIT_H*/
150 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_fuzzy.h linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_fuzzy.h
151 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_fuzzy.h 1970-01-01 00:00:00.000000000 +0000
152 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_fuzzy.h 2004-03-07 08:43:19.000000000 +0000
154 +#ifndef _IPT_FUZZY_H
155 +#define _IPT_FUZZY_H
157 +#include <linux/param.h>
158 +#include <linux/types.h>
160 +#define MAXFUZZYRATE 10000000
161 +#define MINFUZZYRATE 3
163 +struct ipt_fuzzy_info {
164 + u_int32_t minimum_rate;
165 + u_int32_t maximum_rate;
166 + u_int32_t packets_total;
167 + u_int32_t bytes_total;
168 + u_int32_t previous_time;
169 + u_int32_t present_time;
170 + u_int32_t mean_rate;
171 + u_int8_t acceptance_rate;
174 +#endif /*_IPT_FUZZY_H*/
175 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_ipv4options.h linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_ipv4options.h
176 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_ipv4options.h 1970-01-01 00:00:00.000000000 +0000
177 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_ipv4options.h 2004-03-07 08:43:20.000000000 +0000
179 +#ifndef __ipt_ipv4options_h_included__
180 +#define __ipt_ipv4options_h_included__
182 +#define IPT_IPV4OPTION_MATCH_SSRR 0x01 /* For strict source routing */
183 +#define IPT_IPV4OPTION_MATCH_LSRR 0x02 /* For loose source routing */
184 +#define IPT_IPV4OPTION_DONT_MATCH_SRR 0x04 /* any source routing */
185 +#define IPT_IPV4OPTION_MATCH_RR 0x08 /* For Record route */
186 +#define IPT_IPV4OPTION_DONT_MATCH_RR 0x10
187 +#define IPT_IPV4OPTION_MATCH_TIMESTAMP 0x20 /* For timestamp request */
188 +#define IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP 0x40
189 +#define IPT_IPV4OPTION_MATCH_ROUTER_ALERT 0x80 /* For router-alert */
190 +#define IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT 0x100
191 +#define IPT_IPV4OPTION_MATCH_ANY_OPT 0x200 /* match packet with any option */
192 +#define IPT_IPV4OPTION_DONT_MATCH_ANY_OPT 0x400 /* match packet with no option */
194 +struct ipt_ipv4options_info {
199 +#endif /* __ipt_ipv4options_h_included__ */
200 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_mport.h linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_mport.h
201 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_mport.h 1970-01-01 00:00:00.000000000 +0000
202 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_mport.h 2004-03-07 08:43:23.000000000 +0000
204 +#ifndef _IPT_MPORT_H
205 +#define _IPT_MPORT_H
206 +#include <linux/netfilter_ipv4/ip_tables.h>
208 +#define IPT_MPORT_SOURCE (1<<0)
209 +#define IPT_MPORT_DESTINATION (1<<1)
210 +#define IPT_MPORT_EITHER (IPT_MPORT_SOURCE|IPT_MPORT_DESTINATION)
212 +#define IPT_MULTI_PORTS 15
214 +/* Must fit inside union ipt_matchinfo: 32 bytes */
215 +/* every entry in ports[] except for the last one has one bit in pflags
216 + * associated with it. If this bit is set, the port is the first port of
217 + * a portrange, with the next entry being the last.
218 + * End of list is marked with pflags bit set and port=65535.
219 + * If 14 ports are used (last one does not have a pflag), the last port
220 + * is repeated to fill the last entry in ports[] */
223 + u_int8_t flags:2; /* Type of comparison */
224 + u_int16_t pflags:14; /* Port flags */
225 + u_int16_t ports[IPT_MULTI_PORTS]; /* Ports */
227 +#endif /*_IPT_MPORT_H*/
228 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_nth.h linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_nth.h
229 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_nth.h 1970-01-01 00:00:00.000000000 +0000
230 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_nth.h 2004-03-07 08:43:24.000000000 +0000
235 +#include <linux/param.h>
236 +#include <linux/types.h>
238 +#ifndef IPT_NTH_NUM_COUNTERS
239 +#define IPT_NTH_NUM_COUNTERS 16
242 +struct ipt_nth_info {
250 +#endif /*_IPT_NTH_H*/
251 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_quota.h linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_quota.h
252 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_quota.h 1970-01-01 00:00:00.000000000 +0000
253 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_quota.h 2004-03-07 08:43:28.000000000 +0000
255 +#ifndef _IPT_QUOTA_H
256 +#define _IPT_QUOTA_H
258 +/* print debug info in both kernel/netfilter module & iptable library */
259 +//#define DEBUG_IPT_QUOTA
261 +struct ipt_quota_info {
265 +#endif /*_IPT_QUOTA_H*/
266 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_realm.h linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_realm.h
267 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_realm.h 1970-01-01 00:00:00.000000000 +0000
268 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_realm.h 2004-03-07 08:43:30.000000000 +0000
270 +#ifndef _IPT_REALM_H
271 +#define _IPT_REALM_H
273 +struct ipt_realm_info {
278 +#endif /*_IPT_REALM_H*/
279 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_sctp.h linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_sctp.h
280 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_sctp.h 1970-01-01 00:00:00.000000000 +0000
281 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_sctp.h 2004-03-07 08:43:31.000000000 +0000
283 +#ifndef _IPT_SCTP_H_
284 +#define _IPT_SCTP_H_
286 +#define IPT_SCTP_SRC_PORTS 0x01
287 +#define IPT_SCTP_DEST_PORTS 0x02
288 +#define IPT_SCTP_CHUNK_TYPES 0x04
290 +#define IPT_SCTP_VALID_FLAGS 0x07
292 +#define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0]))
295 +struct ipt_sctp_flag_info {
296 + u_int8_t chunktype;
298 + u_int8_t flag_mask;
301 +#define IPT_NUM_SCTP_FLAGS 4
303 +struct ipt_sctp_info {
304 + u_int16_t dpts[2]; /* Min, Max */
305 + u_int16_t spts[2]; /* Min, Max */
307 + u_int32_t chunkmap[256 / sizeof (u_int32_t)]; /* Bit mask of chunks to be matched according to RFC 2960 */
309 +#define SCTP_CHUNK_MATCH_ANY 0x01 /* Match if any of the chunk types are present */
310 +#define SCTP_CHUNK_MATCH_ALL 0x02 /* Match if all of the chunk types are present */
311 +#define SCTP_CHUNK_MATCH_ONLY 0x04 /* Match if these are the only chunk types present */
313 + u_int32_t chunk_match_type;
314 + struct ipt_sctp_flag_info flag_info[IPT_NUM_SCTP_FLAGS];
318 + u_int32_t invflags;
321 +#define bytes(type) (sizeof(type) * 8)
323 +#define SCTP_CHUNKMAP_SET(chunkmap, type) \
325 + chunkmap[type / bytes(u_int32_t)] |= \
326 + 1 << (type % bytes(u_int32_t)); \
329 +#define SCTP_CHUNKMAP_CLEAR(chunkmap, type) \
331 + chunkmap[type / bytes(u_int32_t)] &= \
332 + ~(1 << (type % bytes(u_int32_t))); \
335 +#define SCTP_CHUNKMAP_IS_SET(chunkmap, type) \
337 + (chunkmap[type / bytes (u_int32_t)] & \
338 + (1 << (type % bytes (u_int32_t)))) ? 1: 0; \
341 +#define SCTP_CHUNKMAP_RESET(chunkmap) \
344 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
348 +#define SCTP_CHUNKMAP_SET_ALL(chunkmap) \
351 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
352 + chunkmap[i] = ~0; \
355 +#define SCTP_CHUNKMAP_COPY(destmap, srcmap) \
358 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
359 + destmap[i] = srcmap[i]; \
362 +#define SCTP_CHUNKMAP_IS_CLEAR(chunkmap) \
366 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \
367 + if (chunkmap[i]) { \
375 +#define SCTP_CHUNKMAP_IS_ALL_SET(chunkmap) \
379 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \
380 + if (chunkmap[i] != ~0) { \
388 +#endif /* _IPT_SCTP_H_ */
390 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_state.h linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_state.h
391 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_state.h 2004-03-04 06:17:00.000000000 +0000
392 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_state.h 2004-03-07 08:43:29.000000000 +0000
394 #define IPT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
395 #define IPT_STATE_INVALID (1 << 0)
397 +#define IPT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1))
399 struct ipt_state_info
401 unsigned int statemask;
402 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_u32.h linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_u32.h
403 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv4/ipt_u32.h 1970-01-01 00:00:00.000000000 +0000
404 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv4/ipt_u32.h 2004-03-07 08:44:17.000000000 +0000
408 +#include <linux/netfilter_ipv4/ip_tables.h>
418 +struct ipt_u32_location_element
423 +struct ipt_u32_value_element
428 +/* *** any way to allow for an arbitrary number of elements?
429 + for now I settle for a limit of 10 of each */
430 +#define U32MAXSIZE 10
434 + struct ipt_u32_location_element location[U32MAXSIZE+1];
436 + struct ipt_u32_value_element value[U32MAXSIZE+1];
442 + struct ipt_u32_test tests[U32MAXSIZE+1];
445 +#endif /*_IPT_U32_H*/
446 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv4.h linux-2.6.4-rc2/include/linux/netfilter_ipv4.h
447 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv4.h 2004-03-04 06:16:58.000000000 +0000
448 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv4.h 2004-03-07 08:43:29.000000000 +0000
451 enum nf_ip_hook_priorities {
452 NF_IP_PRI_FIRST = INT_MIN,
453 + NF_IP_PRI_CONNTRACK_DEFRAG = -400,
454 + NF_IP_PRI_RAW = -300,
455 NF_IP_PRI_SELINUX_FIRST = -225,
456 NF_IP_PRI_CONNTRACK = -200,
457 NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
458 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv6/ip6t_HL.h linux-2.6.4-rc2/include/linux/netfilter_ipv6/ip6t_HL.h
459 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv6/ip6t_HL.h 1970-01-01 00:00:00.000000000 +0000
460 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv6/ip6t_HL.h 2004-03-07 08:43:13.000000000 +0000
462 +/* Hop Limit modification module for ip6tables
463 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
464 + * Based on HW's TTL module */
475 +#define IP6T_HL_MAXMODE IP6T_HL_DEC
477 +struct ip6t_HL_info {
479 + u_int8_t hop_limit;
484 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv6/ip6t_REJECT.h linux-2.6.4-rc2/include/linux/netfilter_ipv6/ip6t_REJECT.h
485 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv6/ip6t_REJECT.h 2004-03-04 06:16:34.000000000 +0000
486 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv6/ip6t_REJECT.h 2004-03-07 08:43:15.000000000 +0000
488 #define _IP6T_REJECT_H
490 enum ip6t_reject_with {
491 - IP6T_ICMP_NET_UNREACHABLE,
492 - IP6T_ICMP_HOST_UNREACHABLE,
493 - IP6T_ICMP_PROT_UNREACHABLE,
494 - IP6T_ICMP_PORT_UNREACHABLE,
495 - IP6T_ICMP_ECHOREPLY
496 + IP6T_ICMP6_NO_ROUTE,
497 + IP6T_ICMP6_ADM_PROHIBITED,
498 + IP6T_ICMP6_NOT_NEIGHBOUR,
499 + IP6T_ICMP6_ADDR_UNREACH,
500 + IP6T_ICMP6_PORT_UNREACH,
501 + IP6T_ICMP6_ECHOREPLY,
505 struct ip6t_reject_info {
506 enum ip6t_reject_with with; /* reject type */
509 -#endif /*_IPT_REJECT_H*/
510 +#endif /*_IP6T_REJECT_H*/
511 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h linux-2.6.4-rc2/include/linux/netfilter_ipv6/ip6t_fuzzy.h
512 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv6/ip6t_fuzzy.h 1970-01-01 00:00:00.000000000 +0000
513 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv6/ip6t_fuzzy.h 2004-03-07 08:43:19.000000000 +0000
515 +#ifndef _IP6T_FUZZY_H
516 +#define _IP6T_FUZZY_H
518 +#include <linux/param.h>
519 +#include <linux/types.h>
521 +#define MAXFUZZYRATE 10000000
522 +#define MINFUZZYRATE 3
524 +struct ip6t_fuzzy_info {
525 + u_int32_t minimum_rate;
526 + u_int32_t maximum_rate;
527 + u_int32_t packets_total;
528 + u_int32_t bytes_total;
529 + u_int32_t previous_time;
530 + u_int32_t present_time;
531 + u_int32_t mean_rate;
532 + u_int8_t acceptance_rate;
535 +#endif /*_IP6T_FUZZY_H*/
536 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/include/linux/netfilter_ipv6/ip6t_nth.h linux-2.6.4-rc2/include/linux/netfilter_ipv6/ip6t_nth.h
537 --- linux-2.6.4-rc2.org/include/linux/netfilter_ipv6/ip6t_nth.h 1970-01-01 00:00:00.000000000 +0000
538 +++ linux-2.6.4-rc2/include/linux/netfilter_ipv6/ip6t_nth.h 2004-03-07 08:43:24.000000000 +0000
543 +#include <linux/param.h>
544 +#include <linux/types.h>
546 +#ifndef IP6T_NTH_NUM_COUNTERS
547 +#define IP6T_NTH_NUM_COUNTERS 16
550 +struct ip6t_nth_info {
558 +#endif /*_IP6T_NTH_H*/
559 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/core/netfilter.c linux-2.6.4-rc2/net/core/netfilter.c
560 --- linux-2.6.4-rc2.org/net/core/netfilter.c 2004-03-04 06:16:45.000000000 +0000
561 +++ linux-2.6.4-rc2/net/core/netfilter.c 2004-03-07 08:43:12.000000000 +0000
564 * February 2000: Modified by James Morris to have 1 queue per protocol.
565 * 15-Mar-2000: Added NF_REPEAT --RR.
566 + * 08-May-2003: Internal logging interface added by Jozsef Kadlecsik.
568 #include <linux/config.h>
569 +#include <linux/kernel.h>
570 #include <linux/netfilter.h>
571 #include <net/protocol.h>
572 #include <linux/init.h>
574 } queue_handler[NPROTO];
575 static rwlock_t queue_handler_lock = RW_LOCK_UNLOCKED;
578 + * nf_register_hook - Register with a netfilter hook
579 + * @reg: Hook operations to be registered
581 int nf_register_hook(struct nf_hook_ops *reg)
589 + * nf_unregister_hook - Unregister from a netfilter hook
590 + * @reg: hook operations to be unregistered
592 void nf_unregister_hook(struct nf_hook_ops *reg)
594 spin_lock_bh(&nf_hook_lock);
600 + * nf_register_queue_handler - Registere a queue handler with netfilter
601 + * @pf: protocol family
602 + * @outfn: function called by core to enqueue a packet
603 + * @data: opaque parameter, passed through
605 + * This function registers a queue handler with netfilter. There can only
606 + * be one queue handler for every protocol family.
608 + * A queue handler _must_ reinject every packet via nf_reinject, no
611 int nf_register_queue_handler(int pf, nf_queue_outfn_t outfn, void *data)
618 -/* The caller must flush their queue before this */
620 + * nf_unregister_queue_handler - Unregister queue handler from netfilter
621 + * @pf: protocol family
623 + * The caller must flush their queue before unregistering
625 int nf_unregister_queue_handler(int pf)
627 write_lock_bh(&queue_handler_lock);
633 + * nf_reinject - Reinject a packet from a queue handler
634 + * @skb: the packet to be reinjected
635 + * @info: info which was passed to the outfn() of the queue handler
636 + * @verdict: verdict (NF_ACCEPT, ...) for this packet
638 + * This is the function called by a queue handler to reinject a
641 void nf_reinject(struct sk_buff *skb, struct nf_info *info,
642 unsigned int verdict)
645 EXPORT_SYMBOL(skb_ip_make_writable);
646 #endif /*CONFIG_INET*/
648 +/* Internal logging interface, which relies on the real
649 + LOG target modules */
651 +#define NF_LOG_PREFIXLEN 128
653 +static nf_logfn *nf_logging[NPROTO]; /* = NULL */
654 +static int reported = 0;
655 +static spinlock_t nf_log_lock = SPIN_LOCK_UNLOCKED;
657 +int nf_log_register(int pf, nf_logfn *logfn)
661 + /* Any setup of logging members must be done before
662 + * substituting pointer. */
664 + spin_lock(&nf_log_lock);
665 + if (!nf_logging[pf]) {
666 + nf_logging[pf] = logfn;
669 + spin_unlock(&nf_log_lock);
673 +void nf_log_unregister(int pf, nf_logfn *logfn)
675 + spin_lock(&nf_log_lock);
676 + if (nf_logging[pf] == logfn)
677 + nf_logging[pf] = NULL;
678 + spin_unlock(&nf_log_lock);
680 + /* Give time to concurrent readers. */
684 +void nf_log_packet(int pf,
685 + unsigned int hooknum,
686 + const struct sk_buff *skb,
687 + const struct net_device *in,
688 + const struct net_device *out,
689 + const char *fmt, ...)
692 + char prefix[NF_LOG_PREFIXLEN];
696 + logfn = nf_logging[pf];
698 + va_start(args, fmt);
699 + vsnprintf(prefix, sizeof(prefix), fmt, args);
701 + /* We must read logging before nf_logfn[pf] */
702 + smp_read_barrier_depends();
703 + logfn(hooknum, skb, in, out, prefix);
704 + } else if (!reported) {
705 + printk(KERN_WARNING "nf_log_packet: can\'t log yet, "
706 + "no backend logging module loaded in!\n");
711 +EXPORT_SYMBOL(nf_log_register);
712 +EXPORT_SYMBOL(nf_log_unregister);
713 +EXPORT_SYMBOL(nf_log_packet);
715 /* This does not belong here, but ipt_REJECT needs it if connection
716 tracking in use: without this, connection may not be in hash table,
717 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/Kconfig linux-2.6.4-rc2/net/ipv4/netfilter/Kconfig
718 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/Kconfig 2004-03-04 06:16:58.000000000 +0000
719 +++ linux-2.6.4-rc2/net/ipv4/netfilter/Kconfig 2004-03-07 08:44:17.000000000 +0000
722 To compile it as a module, choose M here. If unsure, say N.
724 +config IP_NF_TARGET_IPV4OPTSSTRIP
725 + tristate 'IPV4OPTSSTRIP target support'
726 + depends on IP_NF_MANGLE
729 +config IP_NF_TARGET_TTL
730 + tristate 'TTL target support'
731 + depends on IP_NF_MANGLE
734 +config IP_NF_MATCH_CONNLIMIT
735 + tristate 'Connections/IP limit match support'
736 + depends on IP_NF_IPTABLES
739 +config IP_NF_MATCH_DSTLIMIT
740 + tristate 'dstlimit match support'
741 + depends on IP_NF_IPTABLES
744 +config IP_NF_MATCH_FUZZY
745 + tristate 'fuzzy match support'
746 + depends on IP_NF_IPTABLES
749 +config IP_NF_MATCH_IPV4OPTIONS
750 + tristate 'IPV4OPTIONS match support'
751 + depends on IP_NF_IPTABLES
754 +config IP_NF_MATCH_MPORT
755 + tristate 'Multiple port with ranges match support'
756 + depends on IP_NF_IPTABLES
759 +config IP_NF_MATCH_NTH
760 + tristate 'Nth match support'
761 + depends on IP_NF_IPTABLES
764 +config IP_NF_MATCH_QUOTA
765 + tristate 'quota match support'
766 + depends on IP_NF_IPTABLES
769 +config IP_NF_TARGET_NOTRACK
770 + tristate 'NOTRACK target support'
771 + depends on IP_NF_RAW
773 + The NOTRACK target allows a select rule to specify
774 + which packets *not* to enter the conntrack/NAT
775 + subsystem with all the consequences (no ICMP error tracking,
776 + no protocol helpers for the selected packets).
778 + If you want to compile it as a module, say M here and read
779 + <file:Documentation/modules.txt>. If unsure, say `N'.
782 + tristate 'raw table support (required for NOTRACK/TRACE)'
783 + depends on IP_NF_IPTABLES
785 + This option adds a `raw' table to iptables. This table is the very
786 + first in the netfilter framework and hooks in at the PREROUTING
789 + If you want to compile it as a module, say M here and read
790 + <file:Documentation/modules.txt>. If unsure, say `N'.
793 +config IP_NF_MATCH_REALM
794 + tristate 'realm match support'
795 + depends on IP_NF_IPTABLES && NET_CLS_ROUTE
798 +config IP_NF_MATCH_SCTP
799 + tristate 'SCTP protocol match support'
800 + depends on IP_NF_IPTABLES
803 +config IP_NF_MATCH_U32
804 + tristate 'U32 match support'
805 + depends on IP_NF_IPTABLES
810 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/Makefile linux-2.6.4-rc2/net/ipv4/netfilter/Makefile
811 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/Makefile 2004-03-04 06:16:38.000000000 +0000
812 +++ linux-2.6.4-rc2/net/ipv4/netfilter/Makefile 2004-03-07 08:44:17.000000000 +0000
814 obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
815 obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
816 obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
817 +obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
820 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
821 obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
822 +obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o
823 +obj-$(CONFIG_IP_NF_MATCH_QUOTA) += ipt_quota.o
824 +obj-$(CONFIG_IP_NF_MATCH_DSTLIMIT) += ipt_dstlimit.o
825 obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
826 obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
827 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
829 obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
830 obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
832 +obj-$(CONFIG_IP_NF_MATCH_MPORT) += ipt_mport.o
834 obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
835 obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
837 +obj-$(CONFIG_IP_NF_MATCH_NTH) += ipt_nth.o
839 +obj-$(CONFIG_IP_NF_MATCH_IPV4OPTIONS) += ipt_ipv4options.o
842 +obj-$(CONFIG_IP_NF_MATCH_FUZZY) += ipt_fuzzy.o
844 obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
846 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
849 obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o
851 +obj-$(CONFIG_IP_NF_MATCH_U32) += ipt_u32.o
854 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
855 obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
856 +obj-$(CONFIG_IP_NF_MATCH_CONNLIMIT) += ipt_connlimit.o
857 obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
858 obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
859 +obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
861 obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
864 obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
865 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
866 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
867 +obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
868 +obj-$(CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP) += ipt_IPV4OPTSSTRIP.o
869 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
870 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
871 +obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o
874 obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
875 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ip_conntrack_core.c linux-2.6.4-rc2/net/ipv4/netfilter/ip_conntrack_core.c
876 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ip_conntrack_core.c 2004-03-04 06:16:34.000000000 +0000
877 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ip_conntrack_core.c 2004-03-07 08:43:29.000000000 +0000
879 * 16 Jul 2002: Harald Welte <laforge@gnumonks.org>
880 * - add usage/reference counts to ip_conntrack_expect
881 * - export ip_conntrack[_expect]_{find_get,put} functions
882 + * 05 Aug 2002: Harald Welte <laforge@gnumonks.org>
883 + * - added DocBook-style comments for public API
886 #include <linux/config.h>
888 static atomic_t ip_conntrack_count = ATOMIC_INIT(0);
889 struct list_head *ip_conntrack_hash;
890 static kmem_cache_t *ip_conntrack_cachep;
891 +struct ip_conntrack ip_conntrack_untracked;
893 extern struct ip_conntrack_protocol ip_conntrack_generic_protocol;
900 + * ip_ct_find_proto - Find layer 4 protocol helper for given protocol number
901 + * @protocol: protocol number
903 struct ip_conntrack_protocol *ip_ct_find_proto(u_int8_t protocol)
905 struct ip_conntrack_protocol *p;
907 static int ip_conntrack_hash_rnd_initted;
908 static unsigned int ip_conntrack_hash_rnd;
911 + * hash_conntrack - Calculate the position of an entry in the connection
913 + * @tuple: conntrack tuple which we want to calculate the hash position
916 hash_conntrack(const struct ip_conntrack_tuple *tuple)
919 ip_conntrack_hash_rnd) % ip_conntrack_htable_size);
923 + * get_tuple - set all the fields of a tuple which is passed as parameter
924 + * given a network buffer.
925 + * @iph:pointer an IP header.
926 + * @skb:network buffer for which we want to generate the tuple
927 + * @dataoff: FIXME: Deprecated?
928 + * @tuple: tuple which will be generate. Used as return parameter.
929 + * @protocol: structure which contains pointer to protocol specific functions.
931 + * Note: This function doesn't allocate space for the tuple passed as
932 + * parameter. The function pkt_to_packet which set all the protocol specific
933 + * fields of a given tuple.
936 get_tuple(const struct iphdr *iph,
937 const struct sk_buff *skb,
939 return protocol->pkt_to_tuple(skb, dataoff, tuple);
943 + * invert_tuple - Returns the inverse of a given tuple. It is used to
944 + * calculate the tuple which represents the other sense of the flow
946 + * @inverse: the inverted tuple. Use as return value.
947 + * @orig: the original tuple which will be inverted.
948 + * @protocol: a pointer to the protocol structure which contains all the
949 + * specifical functions available for this tuple.
952 invert_tuple(struct ip_conntrack_tuple *inverse,
953 const struct ip_conntrack_tuple *orig,
956 /* ip_conntrack_expect helper functions */
958 -/* Compare tuple parts depending on mask. */
960 + * expect_cmp - compare a tuple with a expectation depending on a mask
961 + * @i: pointer to an expectation.
962 + * @tuple: tuple which will be compared with the expectation tuple.
964 + * Actually the tuple field of an expectation is compared with a tuple
965 + * This function is used by LIST_FIND to find a expectation which match a te
968 static inline int expect_cmp(const struct ip_conntrack_expect *i,
969 const struct ip_conntrack_tuple *tuple)
972 return ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask);
976 + * destroy_expect - Release all the resources allocated by an expectation.
977 + * @exp: pointer to the expectation which we want to release.
980 destroy_expect(struct ip_conntrack_expect *exp)
988 + * ip_conntrack_expect_put - it decrements the counter of use related
989 + * associated to an expectation and it calls destroy_expect.
990 + * @exp: pointer to the expectation which we want to release.
992 inline void ip_conntrack_expect_put(struct ip_conntrack_expect *exp)
996 struct ip_conntrack_expect *, tuple);
999 -/* Find a expectation corresponding to a tuple. */
1001 + * ip_conntrack_find_get - find conntrack according to tuple
1002 + * @tuple: conntrack tuple for which we search conntrack
1003 + * @ignored_conntrack: ignore this conntrack during search
1005 + * This function increments the reference count of the found
1006 + * conntrack (if any).
1008 struct ip_conntrack_expect *
1009 ip_conntrack_expect_find_get(const struct ip_conntrack_tuple *tuple)
1011 @@ -381,7 +438,14 @@
1015 -/* Find a connection corresponding to a tuple. */
1017 + * ip_conntrack_find_get - find conntrack according to tuple
1018 + * @tuple: conntrack tuple for which we search conntrack
1019 + * @ignored_conntrack: ignore this conntrack during search
1021 + * This function increments the reference count of the found
1022 + * conntrack (if any).
1024 struct ip_conntrack_tuple_hash *
1025 ip_conntrack_find_get(const struct ip_conntrack_tuple *tuple,
1026 const struct ip_conntrack *ignored_conntrack)
1027 @@ -409,7 +473,14 @@
1031 -/* Return conntrack and conntrack_info given skb->nfct->master */
1033 + * ip_conntrack_get - Return conntrack and conntrack_info for given skb
1034 + * @skb: skb for which we want to find conntrack and conntrack_info
1035 + * @ctinfo: pointer to ctinfo, used as return value
1037 + * This function resolves the respective conntrack and conntrack_info
1038 + * structures for the connection this packet (skb) is part of.
1040 struct ip_conntrack *
1041 ip_conntrack_get(struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
1043 @@ -479,8 +550,14 @@
1047 -/* Returns true if a connection correspondings to the tuple (required
1050 + * ip_conntrack_tuple_taken - Find out if tuple is already in use
1051 + * @tuple: tuple to be used for this test
1052 + * @ignored_conntrack: conntrack which is excluded from result
1054 + * This function is called by the NAT code in order to find out if
1055 + * a particular tuple is already in use by some connection.
1058 ip_conntrack_tuple_taken(const struct ip_conntrack_tuple *tuple,
1059 const struct ip_conntrack *ignored_conntrack)
1060 @@ -606,7 +683,13 @@
1062 return ip_ct_tuple_mask_cmp(rtuple, &i->tuple, &i->mask);
1066 + * ip_ct_find_helper - Find application helper according to tuple
1067 + * @tuple: tuple for which helper needs to be found
1069 + * This function is used to determine if any registered conntrack helper
1070 + * is to be used for the given tuple.
1072 struct ip_conntrack_helper *ip_ct_find_helper(const struct ip_conntrack_tuple *tuple)
1074 return LIST_FIND(&helpers, helper_cmp,
1075 @@ -691,42 +774,50 @@
1076 struct ip_conntrack_expect *, tuple);
1077 READ_UNLOCK(&ip_conntrack_expect_tuple_lock);
1079 - /* If master is not in hash table yet (ie. packet hasn't left
1080 - this machine yet), how can other end know about expected?
1081 - Hence these are not the droids you are looking for (if
1082 - master ct never got confirmed, we'd hold a reference to it
1083 - and weird things would happen to future packets). */
1084 - if (expected && !is_confirmed(expected->expectant))
1087 - /* Look up the conntrack helper for master connections only */
1089 - conntrack->helper = ip_ct_find_helper(&repl_tuple);
1091 - /* If the expectation is dying, then this is a loser. */
1093 - && expected->expectant->helper->timeout
1094 - && ! del_timer(&expected->timeout))
1098 - DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
1099 - conntrack, expected);
1100 - /* Welcome, Mr. Bond. We've been expecting you... */
1101 - IP_NF_ASSERT(master_ct(conntrack));
1102 - __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
1103 - conntrack->master = expected;
1104 - expected->sibling = conntrack;
1105 - LIST_DELETE(&ip_conntrack_expect_list, expected);
1106 - expected->expectant->expecting--;
1107 - nf_conntrack_get(&master_ct(conntrack)->infos[0]);
1109 - atomic_inc(&ip_conntrack_count);
1110 + /* If master is not in hash table yet (ie. packet hasn't left
1111 + this machine yet), how can other end know about expected?
1112 + Hence these are not the droids you are looking for (if
1113 + master ct never got confirmed, we'd hold a reference to it
1114 + and weird things would happen to future packets). */
1115 + if (!is_confirmed(expected->expectant)) {
1117 + conntrack->helper = ip_ct_find_helper(&repl_tuple);
1121 + /* Expectation is dying... */
1122 + if (expected->expectant->helper->timeout
1123 + && ! del_timer(&expected->timeout)) {
1127 + DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
1128 + conntrack, expected);
1129 + /* Welcome, Mr. Bond. We've been expecting you... */
1130 + IP_NF_ASSERT(master_ct(conntrack));
1131 + __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
1132 + conntrack->master = expected;
1133 + expected->sibling = conntrack;
1134 + LIST_DELETE(&ip_conntrack_expect_list, expected);
1135 + expected->expectant->expecting--;
1136 + nf_conntrack_get(&master_ct(conntrack)->infos[0]);
1138 + /* this is a braindead... --pablo */
1139 + atomic_inc(&ip_conntrack_count);
1140 + WRITE_UNLOCK(&ip_conntrack_lock);
1142 + if (expected->expectfn)
1143 + expected->expectfn(conntrack);
1147 + conntrack->helper = ip_ct_find_helper(&repl_tuple);
1149 +end: atomic_inc(&ip_conntrack_count);
1150 WRITE_UNLOCK(&ip_conntrack_lock);
1152 - if (expected && expected->expectfn)
1153 - expected->expectfn(conntrack);
1154 - return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
1155 +ret: return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
1158 /* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
1159 @@ -794,6 +885,15 @@
1163 + /* Never happen */
1164 + if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) {
1165 + if (net_ratelimit()) {
1166 + printk(KERN_ERR "ip_conntrack_in: Frag of proto %u (hook=%u)\n",
1167 + (*pskb)->nh.iph->protocol, hooknum);
1172 /* FIXME: Do this right please. --RR */
1173 (*pskb)->nfcache |= NFC_UNKNOWN;
1175 @@ -812,18 +912,10 @@
1179 - /* Previously seen (loopback)? Ignore. Do this before
1180 - fragment check. */
1181 + /* Previously seen (loopback or untracked)? Ignore. */
1185 - /* Gather fragments. */
1186 - if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
1187 - *pskb = ip_ct_gather_frags(*pskb);
1192 proto = ip_ct_find_proto((*pskb)->nh.iph->protocol);
1194 /* It may be an icmp error... */
1195 @@ -900,6 +992,14 @@
1196 return ip_ct_tuple_mask_cmp(&i->tuple, tuple, &intersect_mask);
1200 + * ip_conntrack_unexpect_related - Unexpect a related connection
1201 + * @expect: expecattin to be removed
1203 + * This function removes an existing expectation, that has not yet been
1204 + * confirmed (i.e. expectation was issued, but expected connection didn't
1207 inline void ip_conntrack_unexpect_related(struct ip_conntrack_expect *expect)
1209 WRITE_LOCK(&ip_conntrack_lock);
1210 @@ -917,7 +1017,20 @@
1211 WRITE_UNLOCK(&ip_conntrack_lock);
1214 -/* Add a related connection. */
1216 + * ip_conntrack_expect_related - Expect a related connection
1217 + * @related_to: master conntrack
1218 + * @expect: expectation with all values filled in
1220 + * This function is called by conntrack application helpers who
1221 + * have detected that the control (master) connection is just about
1222 + * to negotiate a related slave connection.
1224 + * Note: This function allocates it's own struct ip_conntrack_expect,
1225 + * copying the values from the 'expect' parameter. Thus, 'expect' can
1226 + * be allocated on the stack and does not need to be valid after this
1227 + * function returns.
1229 int ip_conntrack_expect_related(struct ip_conntrack *related_to,
1230 struct ip_conntrack_expect *expect)
1232 @@ -1047,7 +1160,15 @@
1236 -/* Change tuple in an existing expectation */
1238 + * ip_conntrack_change_expect - Change tuple in existing expectation
1239 + * @expect: expectation which is to be changed
1240 + * @newtuple: new tuple for expect
1242 + * This function is mostly called by NAT application helpers, who want to
1243 + * change an expectation issued by their respective conntrack application
1244 + * helper counterpart.
1246 int ip_conntrack_change_expect(struct ip_conntrack_expect *expect,
1247 struct ip_conntrack_tuple *newtuple)
1249 @@ -1088,8 +1209,15 @@
1253 -/* Alter reply tuple (maybe alter helper). If it's already taken,
1254 - return 0 and don't do alteration. */
1256 + * ip_conntrack_alter_reply - Alter reply tuple of conntrack
1257 + * @conntrack: conntrack whose reply tuple we want to alter
1258 + * @newreply: designated reply tuple for this conntrack
1260 + * This function alters the reply tuple of a conntrack to the given
1261 + * newreply tuple. If this newreply tuple is already taken, return 0
1262 + * and don't do alteration
1264 int ip_conntrack_alter_reply(struct ip_conntrack *conntrack,
1265 const struct ip_conntrack_tuple *newreply)
1267 @@ -1114,6 +1242,13 @@
1272 + * ip_conntrack_helper_register - Register a conntrack application helper
1273 + * @me: structure describing the helper
1275 + * This function is called by conntrack application helpers to register
1276 + * themselves with the conntrack core.
1278 int ip_conntrack_helper_register(struct ip_conntrack_helper *me)
1280 WRITE_LOCK(&ip_conntrack_lock);
1281 @@ -1135,6 +1270,13 @@
1286 + * ip_conntrack_helper_unregister - Unregister a conntrack application helper
1287 + * @me: structure describing the helper
1289 + * This function is called by conntrack application helpers to unregister
1290 + * themselvers from the conntrack core.
1292 void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me)
1295 @@ -1153,7 +1295,14 @@
1299 -/* Refresh conntrack for this many jiffies. */
1301 + * ip_ct_refresh - Refresh conntrack timer for given conntrack
1302 + * @ct: conntrack which we want to refresh
1303 + * @extra_jiffies: number of jiffies to add
1305 + * This function is called by protocol helpers and application helpers in
1306 + * order to change the expiration timer of a conntrack entry.
1308 void ip_ct_refresh(struct ip_conntrack *ct, unsigned long extra_jiffies)
1310 IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct);
1311 @@ -1172,7 +1321,16 @@
1312 WRITE_UNLOCK(&ip_conntrack_lock);
1315 -/* Returns new sk_buff, or NULL */
1318 + * ip_ct_gather_frags - Gather fragments of a particular skb
1319 + * @skb: pointer to sk_buff of fragmented IP packet
1321 + * This code is just a wrapper around the defragmentation code in the core IPv4
1322 + * stack. It also takes care of nonlinear skb's.
1324 + * Returns new sk_buff, or NULL
1327 ip_ct_gather_frags(struct sk_buff *skb)
1329 @@ -1256,6 +1414,16 @@
1334 + * ip_ct_selective_cleanup - Selectively delete a set of conntrack entries
1335 + * @kill: callback function selecting which entries to delete
1336 + * @data: opaque data pointer, becomes 2nd argument for kill function
1338 + * This function can be used to selectively delete elements of the conntrack
1339 + * hashtable. The function iterates over the list of conntrack entries and
1340 + * calls the 'kill' function for every entry. If the return value is true,
1341 + * the connection is deleted (death_by_timeout).
1344 ip_ct_selective_cleanup(int (*kill)(const struct ip_conntrack *i, void *data),
1346 @@ -1422,6 +1590,18 @@
1348 /* For use by ipt_REJECT */
1349 ip_ct_attach = ip_conntrack_attach;
1351 + /* Set up fake conntrack:
1352 + - to never be deleted, not in any hashes */
1353 + atomic_set(&ip_conntrack_untracked.ct_general.use, 1);
1354 + /* - and look it like as a confirmed connection */
1355 + set_bit(IPS_CONFIRMED_BIT, &ip_conntrack_untracked.status);
1356 + /* - and prepare the ctinfo field for REJECT & NAT. */
1357 + ip_conntrack_untracked.infos[IP_CT_NEW].master =
1358 + ip_conntrack_untracked.infos[IP_CT_RELATED].master =
1359 + ip_conntrack_untracked.infos[IP_CT_RELATED + IP_CT_IS_REPLY].master =
1360 + &ip_conntrack_untracked.ct_general;
1365 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.6.4-rc2/net/ipv4/netfilter/ip_conntrack_standalone.c
1366 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-03-04 06:16:44.000000000 +0000
1367 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-03-07 08:43:29.000000000 +0000
1368 @@ -194,6 +194,26 @@
1369 return ip_conntrack_confirm(*pskb);
1372 +static unsigned int ip_conntrack_defrag(unsigned int hooknum,
1373 + struct sk_buff **pskb,
1374 + const struct net_device *in,
1375 + const struct net_device *out,
1376 + int (*okfn)(struct sk_buff *))
1378 + /* Previously seen (loopback)? Ignore. Do this before
1379 + fragment check. */
1380 + if ((*pskb)->nfct)
1383 + /* Gather fragments. */
1384 + if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
1385 + *pskb = ip_ct_gather_frags(*pskb);
1392 static unsigned int ip_refrag(unsigned int hooknum,
1393 struct sk_buff **pskb,
1394 const struct net_device *in,
1395 @@ -236,6 +256,14 @@
1397 /* Connection tracking may drop packets, but never alters them, so
1398 make it the first hook. */
1399 +static struct nf_hook_ops ip_conntrack_defrag_ops = {
1400 + .hook = ip_conntrack_defrag,
1401 + .owner = THIS_MODULE,
1403 + .hooknum = NF_IP_PRE_ROUTING,
1404 + .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
1407 static struct nf_hook_ops ip_conntrack_in_ops = {
1408 .hook = ip_conntrack_in,
1409 .owner = THIS_MODULE,
1410 @@ -244,6 +272,14 @@
1411 .priority = NF_IP_PRI_CONNTRACK,
1414 +static struct nf_hook_ops ip_conntrack_defrag_local_out_ops = {
1415 + .hook = ip_conntrack_defrag,
1416 + .owner = THIS_MODULE,
1418 + .hooknum = NF_IP_LOCAL_OUT,
1419 + .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
1422 static struct nf_hook_ops ip_conntrack_local_out_ops = {
1423 .hook = ip_conntrack_local,
1424 .owner = THIS_MODULE,
1425 @@ -470,10 +506,20 @@
1426 if (!proc) goto cleanup_init;
1427 proc->owner = THIS_MODULE;
1429 + ret = nf_register_hook(&ip_conntrack_defrag_ops);
1431 + printk("ip_conntrack: can't register pre-routing defrag hook.\n");
1432 + goto cleanup_proc;
1434 + ret = nf_register_hook(&ip_conntrack_defrag_local_out_ops);
1436 + printk("ip_conntrack: can't register local_out defrag hook.\n");
1437 + goto cleanup_defragops;
1439 ret = nf_register_hook(&ip_conntrack_in_ops);
1441 printk("ip_conntrack: can't register pre-routing hook.\n");
1442 - goto cleanup_proc;
1443 + goto cleanup_defraglocalops;
1445 ret = nf_register_hook(&ip_conntrack_local_out_ops);
1447 @@ -511,6 +557,10 @@
1448 nf_unregister_hook(&ip_conntrack_local_out_ops);
1450 nf_unregister_hook(&ip_conntrack_in_ops);
1451 + cleanup_defraglocalops:
1452 + nf_unregister_hook(&ip_conntrack_defrag_local_out_ops);
1453 + cleanup_defragops:
1454 + nf_unregister_hook(&ip_conntrack_defrag_ops);
1456 proc_net_remove("ip_conntrack");
1458 @@ -519,13 +569,20 @@
1462 -/* FIXME: Allow NULL functions and sub in pointers to generic for
1465 + * ip_conntrack_protocol_register - Register layer 4 protocol helper
1466 + * @proto: structure describing this layer 4 protocol helper
1468 + * This function is called by layer 4 protocol helpers to register
1469 + * themselves with the conntrack core.
1471 int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto)
1474 struct list_head *i;
1476 + /* FIXME: Allow NULL functions and sub in pointers to generic for
1478 WRITE_LOCK(&ip_conntrack_lock);
1479 list_for_each(i, &protocol_list) {
1480 if (((struct ip_conntrack_protocol *)i)->proto
1481 @@ -542,12 +599,20 @@
1486 + * ip_conntrack_protocol_unregister - Unregister layer 4 protocol helper
1487 + * @proto: structure describing this layer 4 protocol helper
1489 + * This function is called byh layer 4 protocol helpers to unregister
1490 + * themselvers from the conntrack core. Please note that all conntrack
1491 + * entries for this protocol are deleted from the conntrack hash table.
1493 void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto)
1495 WRITE_LOCK(&ip_conntrack_lock);
1497 - /* ip_ct_find_proto() returns proto_generic in case there is no protocol
1498 - * helper. So this should be enough - HW */
1499 + /* ip_ct_find_proto() returns proto_generic in case there is no
1500 + * protocol helper. So this should be enough - HW */
1501 LIST_DELETE(&protocol_list, proto);
1502 WRITE_UNLOCK(&ip_conntrack_lock);
1505 EXPORT_SYMBOL(ip_conntrack_expect_list);
1506 EXPORT_SYMBOL(ip_conntrack_lock);
1507 EXPORT_SYMBOL(ip_conntrack_hash);
1508 +EXPORT_SYMBOL(ip_conntrack_untracked);
1509 EXPORT_SYMBOL_GPL(ip_conntrack_find_get);
1510 EXPORT_SYMBOL_GPL(ip_conntrack_put);
1511 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ip_nat_core.c linux-2.6.4-rc2/net/ipv4/netfilter/ip_nat_core.c
1512 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ip_nat_core.c 2004-03-04 06:16:37.000000000 +0000
1513 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ip_nat_core.c 2004-03-07 08:43:29.000000000 +0000
1515 WRITE_UNLOCK(&ip_nat_lock);
1518 -/* We do checksum mangling, so if they were wrong before they're still
1519 - * wrong. Also works for incomplete packets (eg. ICMP dest
1520 - * unreachables.) */
1522 + * ip_nat_cheat_check - Incremental checksum change for IP/TCP checksum
1523 + * @oldvalinv: bit-inverted old value of 32bit word
1524 + * @newval: new value of 32bit word
1525 + * @oldcheck: old checksum value
1527 + * This function implements incremental checksum mangling, so if a checksum
1528 + * was wrong it will still be wrong after mangling. Also works for incomplete
1529 + * packets (eg. ICMP dest unreachables). Return value is the new checksum.
1532 ip_nat_cheat_check(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
1534 @@ -124,7 +131,14 @@
1538 -/* Is this tuple already taken? (not by us) */
1540 + * ip_nat_used_tuple - Is this tuple already in use?
1541 + * @tuple: tuple to be used for this check
1542 + * @ignored_conntrack: conntrack excluded from this check
1544 + * This function checks for the reply (inverted) tuple in the conntrack
1545 + * hash. This is necessarry with NAT, since there is no fixed mapping.
1548 ip_nat_used_tuple(const struct ip_conntrack_tuple *tuple,
1549 const struct ip_conntrack *ignored_conntrack)
1550 @@ -515,6 +529,19 @@
1555 + * ip_nat_setup_info - Set up NAT mappings for NEW packet
1556 + * @conntrack: conntrack on which we operate
1557 + * @mr: address/port range which is valid for this NAT mapping
1558 + * @hooknum: hook at which this NAT mapping applies
1560 + * This function is called by NAT targets (SNAT,DNAT,...) and by
1561 + * the NAT application helper modules. It is called for the NEW packet
1562 + * of a connection in order to specify which NAT mappings shall apply to
1563 + * this connection at a given hook.
1565 + * Note: The reply mappings are created automagically by this function.
1568 ip_nat_setup_info(struct ip_conntrack *conntrack,
1569 const struct ip_nat_multi_range *mr,
1570 @@ -1016,6 +1043,10 @@
1571 /* FIXME: Man, this is a hack. <SIGH> */
1572 IP_NF_ASSERT(ip_conntrack_destroyed == NULL);
1573 ip_conntrack_destroyed = &ip_nat_cleanup_conntrack;
1575 + /* Initialize fake conntrack so that NAT will skip it */
1576 + ip_conntrack_untracked.nat.info.initialized |=
1577 + (1 << IP_NAT_MANIP_SRC) | (1 << IP_NAT_MANIP_DST);
1581 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ip_nat_helper.c linux-2.6.4-rc2/net/ipv4/netfilter/ip_nat_helper.c
1582 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ip_nat_helper.c 2004-03-04 06:16:38.000000000 +0000
1583 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ip_nat_helper.c 2004-03-07 08:43:10.000000000 +0000
1584 @@ -150,9 +150,19 @@
1588 -/* Generic function for mangling variable-length address changes inside
1589 - * NATed TCP connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX
1590 - * command in FTP).
1592 + * ip_nat_mangle_tcp_packet - Mangle and potentially resize payload packet
1593 + * @skb: pointer to skb of packet on which we operate
1594 + * @ct: conntrack of the connection to which this packet belongs
1595 + * @ctinfo: conntrack_info of the connection to which this packet belongs
1596 + * @match_offset: offset in bytes where to-be-manipulated part starts
1597 + * @match_len: lenght of the to-be-manipulated part
1598 + * @rep_buffer: pointer to buffer containing replacement
1599 + * @rep_len: length of replacement
1601 + * Generic function for mangling fixed and variable-length changes inside
1602 + * NATed TCP connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX command
1605 * Takes care about all the nasty sequence number changes, checksumming,
1606 * skb enlargement, ...
1607 @@ -198,16 +208,27 @@
1611 -/* Generic function for mangling variable-length address changes inside
1612 - * NATed UDP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX
1613 - * command in the Amanda protocol)
1615 + * ip_nat_mangle_udp_packet - Mangle and potentially resize payload packet
1616 + * @skb: pointer to skb of packet on which we operate
1617 + * @ct: conntrack of the connection to which this packet belongs
1618 + * @ctinfo: conntrack_info of the connection to which this packet belongs
1619 + * @match_offset: offset in bytes where to-be-manipulated part starts
1620 + * @match_len: lenght of the to-be-manipulated part
1621 + * @rep_buffer: pointer to buffer containing replacement
1622 + * @rep_len: length of replacement
1624 + * Generic function for mangling fixed and variable-length changes inside
1625 + * NATed TCP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX
1626 + * commad in the Amanda protocol)
1628 * Takes care about all the nasty sequence number changes, checksumming,
1629 * skb enlargement, ...
1631 - * XXX - This function could be merged with ip_nat_mangle_tcp_packet which
1632 - * should be fairly easy to do.
1634 + * FIXME: should be unified with ip_nat_mangle_tcp_packet!!
1639 ip_nat_mangle_udp_packet(struct sk_buff **pskb,
1640 struct ip_conntrack *ct,
1641 @@ -405,6 +426,13 @@
1642 return ip_ct_tuple_mask_cmp(tuple, &helper->tuple, &helper->mask);
1646 + * ip_nat_helper_register - Register NAT application helper
1647 + * @me: structure describing the helper
1649 + * This function is called by NAT application helpers to register
1650 + * themselves with the NAT core.
1652 int ip_nat_helper_register(struct ip_nat_helper *me)
1655 @@ -431,6 +459,13 @@
1660 + * ip_nat_helper_unregister - Unregister NAT application helper
1661 + * @me: structure describing the helper
1663 + * This function is called by NAT application helpers to unregister
1664 + * themselves from the NAT core.
1666 void ip_nat_helper_unregister(struct ip_nat_helper *me)
1668 WRITE_LOCK(&ip_nat_lock);
1669 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ip_nat_standalone.c linux-2.6.4-rc2/net/ipv4/netfilter/ip_nat_standalone.c
1670 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ip_nat_standalone.c 2004-03-04 06:16:55.000000000 +0000
1671 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ip_nat_standalone.c 2004-03-07 08:43:10.000000000 +0000
1672 @@ -266,7 +266,13 @@
1676 -/* Protocol registration. */
1678 + * ip_nat_protocol_register - Register a layer 4 protocol helper
1679 + * @proto: structure describing this helper
1681 + * This function is called by NAT layer 4 protocol helpers to register
1682 + * themselvers with the NAT core.
1684 int ip_nat_protocol_register(struct ip_nat_protocol *proto)
1687 @@ -287,9 +293,16 @@
1691 -/* Noone stores the protocol anywhere; simply delete it. */
1693 + * ip_nat_protocol_unregister - Unregister a layer 4 protocol helper
1694 + * @proto: structure describing the helper
1696 + * This function is called by NAT layer 4 protocol helpers to
1697 + * unregister themselves from the NAT core.
1699 void ip_nat_protocol_unregister(struct ip_nat_protocol *proto)
1701 + /* Noone stores the protocol anywhere; simply delete it. */
1702 WRITE_LOCK(&ip_nat_lock);
1703 LIST_DELETE(&protos, proto);
1704 WRITE_UNLOCK(&ip_nat_lock);
1705 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c linux-2.6.4-rc2/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c
1706 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 1970-01-01 00:00:00.000000000 +0000
1707 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c 2004-03-07 08:43:14.000000000 +0000
1710 + * Strip all IP options in the IP packet header.
1712 + * (C) 2001 by Fabrice MARIE <fabrice@netfilter.org>
1713 + * This software is distributed under GNU GPL v2, 1991
1716 +#include <linux/module.h>
1717 +#include <linux/skbuff.h>
1718 +#include <linux/ip.h>
1719 +#include <net/checksum.h>
1721 +#include <linux/netfilter_ipv4/ip_tables.h>
1723 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
1724 +MODULE_DESCRIPTION("Strip all options in IPv4 packets");
1725 +MODULE_LICENSE("GPL");
1727 +static unsigned int
1728 +target(struct sk_buff **pskb,
1729 + const struct net_device *in,
1730 + const struct net_device *out,
1731 + unsigned int hooknum,
1732 + const void *targinfo,
1735 + struct iphdr *iph;
1736 + struct sk_buff *skb;
1737 + struct ip_options *opt;
1738 + unsigned char *optiph;
1741 + if (!skb_ip_make_writable(pskb, (*pskb)->len))
1745 + iph = (*pskb)->nh.iph;
1746 + optiph = skb->nh.raw;
1747 + l = ((struct ip_options *)(&(IPCB(skb)->opt)))->optlen;
1749 + /* if no options in packet then nothing to clear. */
1750 + if (iph->ihl * 4 == sizeof(struct iphdr))
1751 + return IPT_CONTINUE;
1753 + /* else clear all options */
1754 + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
1755 + memset(optiph+sizeof(struct iphdr), IPOPT_NOOP, l);
1756 + opt = &(IPCB(skb)->opt);
1760 + skb->nfcache |= NFC_ALTERED;
1762 + return IPT_CONTINUE;
1766 +checkentry(const char *tablename,
1767 + const struct ipt_entry *e,
1769 + unsigned int targinfosize,
1770 + unsigned int hook_mask)
1772 + if (strcmp(tablename, "mangle")) {
1773 + printk(KERN_WARNING "IPV4OPTSSTRIP: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
1776 + /* nothing else to check because no parameters */
1780 +static struct ipt_target ipt_ipv4optsstrip_reg = {
1781 + .name = "IPV4OPTSSTRIP",
1783 + .checkentry = checkentry,
1784 + .me = THIS_MODULE };
1786 +static int __init init(void)
1788 + return ipt_register_target(&ipt_ipv4optsstrip_reg);
1791 +static void __exit fini(void)
1793 + ipt_unregister_target(&ipt_ipv4optsstrip_reg);
1798 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_LOG.c linux-2.6.4-rc2/net/ipv4/netfilter/ipt_LOG.c
1799 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_LOG.c 2004-03-04 06:17:03.000000000 +0000
1800 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ipt_LOG.c 2004-03-07 08:43:12.000000000 +0000
1802 #include <net/tcp.h>
1803 #include <net/route.h>
1805 +#include <linux/netfilter.h>
1806 #include <linux/netfilter_ipv4/ip_tables.h>
1807 #include <linux/netfilter_ipv4/ipt_LOG.h>
1810 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
1811 MODULE_DESCRIPTION("iptables syslog logging module");
1813 +static unsigned int nflog = 1;
1814 +MODULE_PARM(nflog, "i");
1815 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
1818 #define DEBUGP printk
1820 @@ -324,28 +329,25 @@
1821 /* maxlen = 230+ 91 + 230 + 252 = 803 */
1824 -static unsigned int
1825 -ipt_log_target(struct sk_buff **pskb,
1827 +ipt_log_packet(unsigned int hooknum,
1828 + const struct sk_buff *skb,
1829 const struct net_device *in,
1830 const struct net_device *out,
1831 - unsigned int hooknum,
1832 - const void *targinfo,
1834 + const struct ipt_log_info *loginfo,
1835 + const char *level_string,
1836 + const char *prefix)
1838 - const struct ipt_log_info *loginfo = targinfo;
1839 - char level_string[4] = "< >";
1841 - level_string[1] = '0' + (loginfo->level % 8);
1842 spin_lock_bh(&log_lock);
1843 printk(level_string);
1844 printk("%sIN=%s OUT=%s ",
1846 + prefix == NULL ? loginfo->prefix : prefix,
1848 out ? out->name : "");
1849 #ifdef CONFIG_BRIDGE_NETFILTER
1850 - if ((*pskb)->nf_bridge) {
1851 - struct net_device *physindev = (*pskb)->nf_bridge->physindev;
1852 - struct net_device *physoutdev = (*pskb)->nf_bridge->physoutdev;
1853 + if (skb->nf_bridge) {
1854 + struct net_device *physindev = skb->nf_bridge->physindev;
1855 + struct net_device *physoutdev = skb->nf_bridge->physoutdev;
1857 if (physindev && in != physindev)
1858 printk("PHYSIN=%s ", physindev->name);
1859 @@ -357,25 +359,56 @@
1861 /* MAC logging for input chain only. */
1863 - if ((*pskb)->dev && (*pskb)->dev->hard_header_len
1864 - && (*pskb)->mac.raw != (void*)(*pskb)->nh.iph) {
1865 + if (skb->dev && skb->dev->hard_header_len
1866 + && skb->mac.raw != (void*)skb->nh.iph) {
1868 - unsigned char *p = (*pskb)->mac.raw;
1869 - for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++)
1870 + unsigned char *p = skb->mac.raw;
1871 + for (i = 0; i < skb->dev->hard_header_len; i++,p++)
1872 printk("%02x%c", *p,
1873 - i==(*pskb)->dev->hard_header_len - 1
1874 + i==skb->dev->hard_header_len - 1
1880 - dump_packet(loginfo, *pskb, 0);
1881 + dump_packet(loginfo, skb, 0);
1883 spin_unlock_bh(&log_lock);
1886 +static unsigned int
1887 +ipt_log_target(struct sk_buff **pskb,
1888 + const struct net_device *in,
1889 + const struct net_device *out,
1890 + unsigned int hooknum,
1891 + const void *targinfo,
1894 + const struct ipt_log_info *loginfo = targinfo;
1895 + char level_string[4] = "< >";
1897 + level_string[1] = '0' + (loginfo->level % 8);
1898 + ipt_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL);
1900 return IPT_CONTINUE;
1904 +ipt_logfn(unsigned int hooknum,
1905 + const struct sk_buff *skb,
1906 + const struct net_device *in,
1907 + const struct net_device *out,
1908 + const char *prefix)
1910 + struct ipt_log_info loginfo = {
1912 + .logflags = IPT_LOG_MASK,
1916 + ipt_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
1919 static int ipt_log_checkentry(const char *tablename,
1920 const struct ipt_entry *e,
1922 @@ -413,11 +446,18 @@
1924 static int __init init(void)
1926 - return ipt_register_target(&ipt_log_reg);
1927 + if (ipt_register_target(&ipt_log_reg))
1930 + nf_log_register(PF_INET, &ipt_logfn);
1935 static void __exit fini(void)
1938 + nf_log_unregister(PF_INET, &ipt_logfn);
1939 ipt_unregister_target(&ipt_log_reg);
1942 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_NOTRACK.c linux-2.6.4-rc2/net/ipv4/netfilter/ipt_NOTRACK.c
1943 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_NOTRACK.c 1970-01-01 00:00:00.000000000 +0000
1944 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ipt_NOTRACK.c 2004-03-07 08:43:29.000000000 +0000
1946 +/* This is a module which is used for setting up fake conntracks
1947 + * on packets so that they are not seen by the conntrack/NAT code.
1949 +#include <linux/module.h>
1950 +#include <linux/skbuff.h>
1952 +#include <linux/netfilter_ipv4/ip_tables.h>
1953 +#include <linux/netfilter_ipv4/ip_conntrack.h>
1955 +static unsigned int
1956 +target(struct sk_buff **pskb,
1957 + const struct net_device *in,
1958 + const struct net_device *out,
1959 + unsigned int hooknum,
1960 + const void *targinfo,
1963 + /* Previously seen (loopback)? Ignore. */
1964 + if ((*pskb)->nfct != NULL)
1965 + return IPT_CONTINUE;
1967 + /* Attach fake conntrack entry.
1968 + If there is a real ct entry correspondig to this packet,
1969 + it'll hang aroun till timing out. We don't deal with it
1970 + for performance reasons. JK */
1971 + (*pskb)->nfct = &ip_conntrack_untracked.infos[IP_CT_NEW];
1972 + nf_conntrack_get((*pskb)->nfct);
1974 + return IPT_CONTINUE;
1978 +checkentry(const char *tablename,
1979 + const struct ipt_entry *e,
1981 + unsigned int targinfosize,
1982 + unsigned int hook_mask)
1984 + if (targinfosize != 0) {
1985 + printk(KERN_WARNING "NOTRACK: targinfosize %u != 0\n",
1990 + if (strcmp(tablename, "raw") != 0) {
1991 + printk(KERN_WARNING "NOTRACK: can only be called from \"raw\" table, not \"%s\"\n", tablename);
1998 +static struct ipt_target ipt_notrack_reg = {
1999 + .name = "NOTRACK",
2001 + .checkentry = checkentry,
2005 +static int __init init(void)
2007 + if (ipt_register_target(&ipt_notrack_reg))
2013 +static void __exit fini(void)
2015 + ipt_unregister_target(&ipt_notrack_reg);
2020 +MODULE_LICENSE("GPL");
2021 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_TTL.c linux-2.6.4-rc2/net/ipv4/netfilter/ipt_TTL.c
2022 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_TTL.c 1970-01-01 00:00:00.000000000 +0000
2023 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ipt_TTL.c 2004-03-07 08:43:16.000000000 +0000
2025 +/* TTL modification target for IP tables
2026 + * (C) 2000 by Harald Welte <laforge@gnumonks.org>
2028 + * Version: $Revision$
2030 + * This software is distributed under the terms of GNU GPL
2033 +#include <linux/module.h>
2034 +#include <linux/skbuff.h>
2035 +#include <linux/ip.h>
2036 +#include <net/checksum.h>
2038 +#include <linux/netfilter_ipv4/ip_tables.h>
2039 +#include <linux/netfilter_ipv4/ipt_TTL.h>
2041 +MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
2042 +MODULE_DESCRIPTION("IP tables TTL modification module");
2043 +MODULE_LICENSE("GPL");
2045 +static unsigned int
2046 +ipt_ttl_target(struct sk_buff **pskb, const struct net_device *in,
2047 + const struct net_device *out, unsigned int hooknum,
2048 + const void *targinfo, void *userinfo)
2050 + struct iphdr *iph;
2051 + const struct ipt_TTL_info *info = targinfo;
2052 + u_int16_t diffs[2];
2055 + if (!skb_ip_make_writable(pskb, (*pskb)->len))
2058 + iph = (*pskb)->nh.iph;
2060 + switch (info->mode) {
2062 + new_ttl = info->ttl;
2065 + new_ttl = iph->ttl + info->ttl;
2066 + if (new_ttl > 255)
2070 + new_ttl = iph->ttl + info->ttl;
2075 + new_ttl = iph->ttl;
2079 + if (new_ttl != iph->ttl) {
2080 + diffs[0] = htons(((unsigned)iph->ttl) << 8) ^ 0xFFFF;
2081 + iph->ttl = new_ttl;
2082 + diffs[1] = htons(((unsigned)iph->ttl) << 8);
2083 + iph->check = csum_fold(csum_partial((char *)diffs,
2085 + iph->check^0xFFFF));
2086 + (*pskb)->nfcache |= NFC_ALTERED;
2089 + return IPT_CONTINUE;
2092 +static int ipt_ttl_checkentry(const char *tablename,
2093 + const struct ipt_entry *e,
2095 + unsigned int targinfosize,
2096 + unsigned int hook_mask)
2098 + struct ipt_TTL_info *info = targinfo;
2100 + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_TTL_info))) {
2101 + printk(KERN_WARNING "TTL: targinfosize %u != %Zu\n",
2103 + IPT_ALIGN(sizeof(struct ipt_TTL_info)));
2107 + if (strcmp(tablename, "mangle")) {
2108 + printk(KERN_WARNING "TTL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
2112 + if (info->mode > IPT_TTL_MAXMODE) {
2113 + printk(KERN_WARNING "TTL: invalid or unknown Mode %u\n",
2118 + if ((info->mode != IPT_TTL_SET) && (info->ttl == 0)) {
2119 + printk(KERN_WARNING "TTL: increment/decrement doesn't make sense with value 0\n");
2126 +static struct ipt_target ipt_TTL = {
2128 + .target = ipt_ttl_target,
2129 + .checkentry = ipt_ttl_checkentry,
2133 +static int __init init(void)
2135 + return ipt_register_target(&ipt_TTL);
2138 +static void __exit fini(void)
2140 + ipt_unregister_target(&ipt_TTL);
2145 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_ULOG.c linux-2.6.4-rc2/net/ipv4/netfilter/ipt_ULOG.c
2146 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_ULOG.c 2004-03-04 06:16:42.000000000 +0000
2147 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ipt_ULOG.c 2004-03-07 08:43:12.000000000 +0000
2149 #include <linux/netlink.h>
2150 #include <linux/netdevice.h>
2151 #include <linux/mm.h>
2152 +#include <linux/netfilter.h>
2153 #include <linux/netfilter_ipv4/ip_tables.h>
2154 #include <linux/netfilter_ipv4/ipt_ULOG.h>
2155 #include <linux/netfilter_ipv4/lockhelp.h>
2157 MODULE_PARM(flushtimeout, "i");
2158 MODULE_PARM_DESC(flushtimeout, "buffer flush timeout");
2160 +static unsigned int nflog = 1;
2161 +MODULE_PARM(nflog, "i");
2162 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
2164 /* global data structures */
2167 @@ -157,17 +162,17 @@
2171 -static unsigned int ipt_ulog_target(struct sk_buff **pskb,
2172 - const struct net_device *in,
2173 - const struct net_device *out,
2174 - unsigned int hooknum,
2175 - const void *targinfo, void *userinfo)
2176 +static void ipt_ulog_packet(unsigned int hooknum,
2177 + const struct sk_buff *skb,
2178 + const struct net_device *in,
2179 + const struct net_device *out,
2180 + const struct ipt_ulog_info *loginfo,
2181 + const char *prefix)
2184 ulog_packet_msg_t *pm;
2185 size_t size, copy_len;
2186 struct nlmsghdr *nlh;
2187 - struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
2189 /* ffs == find first bit set, necessary because userspace
2190 * is already shifting groupnumber, but we need unshifted.
2193 /* calculate the size of the skb needed */
2194 if ((loginfo->copy_range == 0) ||
2195 - (loginfo->copy_range > (*pskb)->len)) {
2196 - copy_len = (*pskb)->len;
2197 + (loginfo->copy_range > skb->len)) {
2198 + copy_len = skb->len;
2200 copy_len = loginfo->copy_range;
2202 @@ -214,19 +219,21 @@
2204 /* copy hook, prefix, timestamp, payload, etc. */
2205 pm->data_len = copy_len;
2206 - pm->timestamp_sec = (*pskb)->stamp.tv_sec;
2207 - pm->timestamp_usec = (*pskb)->stamp.tv_usec;
2208 - pm->mark = (*pskb)->nfmark;
2209 + pm->timestamp_sec = skb->stamp.tv_sec;
2210 + pm->timestamp_usec = skb->stamp.tv_usec;
2211 + pm->mark = skb->nfmark;
2213 - if (loginfo->prefix[0] != '\0')
2214 + if (prefix != NULL)
2215 + strncpy(pm->prefix, prefix, sizeof(pm->prefix));
2216 + else if (loginfo->prefix[0] != '\0')
2217 strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix));
2219 *(pm->prefix) = '\0';
2221 if (in && in->hard_header_len > 0
2222 - && (*pskb)->mac.raw != (void *) (*pskb)->nh.iph
2223 + && skb->mac.raw != (void *) skb->nh.iph
2224 && in->hard_header_len <= ULOG_MAC_LEN) {
2225 - memcpy(pm->mac, (*pskb)->mac.raw, in->hard_header_len);
2226 + memcpy(pm->mac, skb->mac.raw, in->hard_header_len);
2227 pm->mac_len = in->hard_header_len;
2232 pm->outdev_name[0] = '\0';
2234 - /* copy_len <= (*pskb)->len, so can't fail. */
2235 - if (skb_copy_bits(*pskb, 0, pm->payload, copy_len) < 0)
2236 + /* copy_len <= skb->len, so can't fail. */
2237 + if (skb_copy_bits(skb, 0, pm->payload, copy_len) < 0)
2240 /* check if we are building multi-part messages */
2243 UNLOCK_BH(&ulog_lock);
2245 - return IPT_CONTINUE;
2250 PRINTR("ipt_ULOG: error during NLMSG_PUT\n");
2251 @@ -276,8 +282,35 @@
2252 PRINTR("ipt_ULOG: Error building netlink message\n");
2254 UNLOCK_BH(&ulog_lock);
2257 +static unsigned int ipt_ulog_target(struct sk_buff **pskb,
2258 + const struct net_device *in,
2259 + const struct net_device *out,
2260 + unsigned int hooknum,
2261 + const void *targinfo, void *userinfo)
2263 + struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
2265 - return IPT_CONTINUE;
2266 + ipt_ulog_packet(hooknum, *pskb, in, out, loginfo, NULL);
2268 + return IPT_CONTINUE;
2271 +static void ipt_logfn(unsigned int hooknum,
2272 + const struct sk_buff *skb,
2273 + const struct net_device *in,
2274 + const struct net_device *out,
2275 + const char *prefix)
2277 + struct ipt_ulog_info loginfo = {
2278 + .nl_group = ULOG_DEFAULT_NLGROUP,
2280 + .qthreshold = ULOG_DEFAULT_QTHRESHOLD,
2284 + ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
2287 static int ipt_ulog_checkentry(const char *tablename,
2289 sock_release(nflognl->sk_socket);
2294 + nf_log_register(PF_INET, &ipt_logfn);
2301 DEBUGP("ipt_ULOG: cleanup_module\n");
2304 + nf_log_unregister(PF_INET, &ipt_logfn);
2305 ipt_unregister_target(&ipt_ulog_reg);
2306 sock_release(nflognl->sk_socket);
2308 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_connlimit.c linux-2.6.4-rc2/net/ipv4/netfilter/ipt_connlimit.c
2309 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_connlimit.c 1970-01-01 00:00:00.000000000 +0000
2310 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ipt_connlimit.c 2004-03-07 08:43:18.000000000 +0000
2313 + * netfilter module to limit the number of parallel tcp
2314 + * connections per IP address.
2315 + * (c) 2000 Gerd Knorr <kraxel@bytesex.org>
2316 + * Nov 2002: Martin Bene <martin.bene@icomedias.com>:
2317 + * only ignore TIME_WAIT or gone connections
2321 + * Kernel module to match connection tracking information.
2322 + * GPL (C) 1999 Rusty Russell (rusty@rustcorp.com.au).
2324 +#include <linux/module.h>
2325 +#include <linux/skbuff.h>
2326 +#include <linux/list.h>
2327 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2328 +#include <linux/netfilter_ipv4/ip_conntrack_core.h>
2329 +#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
2330 +#include <linux/netfilter_ipv4/ip_tables.h>
2331 +#include <linux/netfilter_ipv4/ipt_connlimit.h>
2335 +MODULE_LICENSE("GPL");
2337 +/* we'll save the tuples of all connections we care about */
2338 +struct ipt_connlimit_conn
2340 + struct list_head list;
2341 + struct ip_conntrack_tuple tuple;
2344 +struct ipt_connlimit_data {
2346 + struct list_head iphash[256];
2349 +static int ipt_iphash(u_int32_t addr)
2353 + hash = addr & 0xff;
2354 + hash ^= (addr >> 8) & 0xff;
2355 + hash ^= (addr >> 16) & 0xff;
2356 + hash ^= (addr >> 24) & 0xff;
2360 +static int count_them(struct ipt_connlimit_data *data,
2361 + u_int32_t addr, u_int32_t mask,
2362 + struct ip_conntrack *ct)
2365 + const static char *tcp[] = { "none", "established", "syn_sent", "syn_recv",
2366 + "fin_wait", "time_wait", "close", "close_wait",
2367 + "last_ack", "listen" };
2369 + int addit = 1, matches = 0;
2370 + struct ip_conntrack_tuple tuple;
2371 + struct ip_conntrack_tuple_hash *found;
2372 + struct ipt_connlimit_conn *conn;
2373 + struct list_head *hash,*lh;
2375 + spin_lock(&data->lock);
2376 + tuple = ct->tuplehash[0].tuple;
2377 + hash = &data->iphash[ipt_iphash(addr & mask)];
2379 + /* check the saved connections */
2380 + for (lh = hash->next; lh != hash; lh = lh->next) {
2381 + conn = list_entry(lh,struct ipt_connlimit_conn,list);
2382 + found = ip_conntrack_find_get(&conn->tuple,ct);
2383 + if (0 == memcmp(&conn->tuple,&tuple,sizeof(tuple)) &&
2385 + found->ctrack->proto.tcp.state != TCP_CONNTRACK_TIME_WAIT) {
2386 + /* Just to be sure we have it only once in the list.
2387 + We should'nt see tuples twice unless someone hooks this
2388 + into a table without "-p tcp --syn" */
2392 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d %s\n",
2393 + ipt_iphash(addr & mask),
2394 + NIPQUAD(conn->tuple.src.ip), ntohs(conn->tuple.src.u.tcp.port),
2395 + NIPQUAD(conn->tuple.dst.ip), ntohs(conn->tuple.dst.u.tcp.port),
2396 + (NULL != found) ? tcp[found->ctrack->proto.tcp.state] : "gone");
2398 + if (NULL == found) {
2399 + /* this one is gone */
2401 + list_del(lh->next);
2405 + if (found->ctrack->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT) {
2406 + /* we don't care about connections which are
2407 + closed already -> ditch it */
2409 + list_del(lh->next);
2411 + nf_conntrack_put(&found->ctrack->infos[0]);
2414 + if ((addr & mask) == (conn->tuple.src.ip & mask)) {
2415 + /* same source IP address -> be counted! */
2418 + nf_conntrack_put(&found->ctrack->infos[0]);
2421 + /* save the new connection in our list */
2423 + printk("ipt_connlimit [%d]: src=%u.%u.%u.%u:%d dst=%u.%u.%u.%u:%d new\n",
2424 + ipt_iphash(addr & mask),
2425 + NIPQUAD(tuple.src.ip), ntohs(tuple.src.u.tcp.port),
2426 + NIPQUAD(tuple.dst.ip), ntohs(tuple.dst.u.tcp.port));
2428 + conn = kmalloc(sizeof(*conn),GFP_ATOMIC);
2431 + memset(conn,0,sizeof(*conn));
2432 + INIT_LIST_HEAD(&conn->list);
2433 + conn->tuple = tuple;
2434 + list_add(&conn->list,hash);
2437 + spin_unlock(&data->lock);
2442 +match(const struct sk_buff *skb,
2443 + const struct net_device *in,
2444 + const struct net_device *out,
2445 + const void *matchinfo,
2449 + const struct ipt_connlimit_info *info = matchinfo;
2450 + int connections, match;
2451 + struct ip_conntrack *ct;
2452 + enum ip_conntrack_info ctinfo;
2454 + ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
2456 + printk("ipt_connlimit: Oops: invalid ct state ?\n");
2460 + connections = count_them(info->data,skb->nh.iph->saddr,info->mask,ct);
2461 + if (-1 == connections) {
2462 + printk("ipt_connlimit: Hmm, kmalloc failed :-(\n");
2463 + *hotdrop = 1; /* let's free some memory :-) */
2466 + match = (info->inverse) ? (connections <= info->limit) : (connections > info->limit);
2468 + printk("ipt_connlimit: src=%u.%u.%u.%u mask=%u.%u.%u.%u "
2469 + "connections=%d limit=%d match=%s\n",
2470 + NIPQUAD(skb->nh.iph->saddr), NIPQUAD(info->mask),
2471 + connections, info->limit, match ? "yes" : "no");
2477 +static int check(const char *tablename,
2478 + const struct ipt_ip *ip,
2480 + unsigned int matchsize,
2481 + unsigned int hook_mask)
2483 + struct ipt_connlimit_info *info = matchinfo;
2487 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_connlimit_info)))
2490 + /* refuse anything but tcp */
2491 + if (ip->proto != IPPROTO_TCP)
2494 + /* init private data */
2495 + info->data = kmalloc(sizeof(struct ipt_connlimit_data),GFP_KERNEL);
2496 + spin_lock_init(&(info->data->lock));
2497 + for (i = 0; i < 256; i++)
2498 + INIT_LIST_HEAD(&(info->data->iphash[i]));
2503 +static void destroy(void *matchinfo, unsigned int matchinfosize)
2505 + struct ipt_connlimit_info *info = matchinfo;
2506 + struct ipt_connlimit_conn *conn;
2507 + struct list_head *hash;
2511 + for (i = 0; i < 256; i++) {
2512 + hash = &(info->data->iphash[i]);
2513 + while (hash != hash->next) {
2514 + conn = list_entry(hash->next,struct ipt_connlimit_conn,list);
2515 + list_del(hash->next);
2519 + kfree(info->data);
2522 +static struct ipt_match connlimit_match = {
2523 + .name = "connlimit",
2525 + .checkentry = &check,
2526 + .destroy = &destroy,
2530 +static int __init init(void)
2532 + return ipt_register_match(&connlimit_match);
2535 +static void __exit fini(void)
2537 + ipt_unregister_match(&connlimit_match);
2542 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_conntrack.c linux-2.6.4-rc2/net/ipv4/netfilter/ipt_conntrack.c
2543 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_conntrack.c 2004-03-04 06:17:04.000000000 +0000
2544 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ipt_conntrack.c 2004-03-07 08:43:29.000000000 +0000
2547 #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
2550 - statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
2552 - statebit = IPT_CONNTRACK_STATE_INVALID;
2554 + if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
2555 + statebit = IPT_CONNTRACK_STATE_UNTRACKED;
2557 + statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
2559 + statebit = IPT_CONNTRACK_STATE_INVALID;
2561 if(sinfo->flags & IPT_CONNTRACK_STATE) {
2563 if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip !=
2564 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_dstlimit.c linux-2.6.4-rc2/net/ipv4/netfilter/ipt_dstlimit.c
2565 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_dstlimit.c 1970-01-01 00:00:00.000000000 +0000
2566 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ipt_dstlimit.c 2004-03-07 08:43:19.000000000 +0000
2568 +/* iptables match extension to limit the number of packets per second
2569 + * seperately for each destination.
2571 + * (C) 2003 by Harald Welte <laforge@netfilter.org>
2575 + * Development of this code was funded by Astaro AG, http://www.astaro.com/
2577 + * based on ipt_limit.c by:
2578 + * Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
2579 + * Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
2580 + * Rusty Russell <rusty@rustcorp.com.au>
2582 + * The general idea is to create a hash table for every dstip and have a
2583 + * seperate limit counter per tuple. This way you can do something like 'limit
2584 + * the number of syn packets for each of my internal addresses.
2586 + * Ideally this would just be implemented as a general 'hash' match, which would
2587 + * allow us to attach any iptables target to it's hash buckets. But this is
2588 + * not possible in the current iptables architecture. As always, pkttables for
2589 + * 2.7.x will help ;)
2591 +#include <linux/module.h>
2592 +#include <linux/skbuff.h>
2593 +#include <linux/spinlock.h>
2594 +#include <linux/random.h>
2595 +#include <linux/jhash.h>
2596 +#include <linux/slab.h>
2597 +#include <linux/vmalloc.h>
2598 +#include <linux/tcp.h>
2599 +#include <linux/udp.h>
2600 +#include <linux/proc_fs.h>
2601 +#include <linux/seq_file.h>
2603 +#define ASSERT_READ_LOCK(x)
2604 +#define ASSERT_WRITE_LOCK(x)
2605 +#include <linux/netfilter_ipv4/lockhelp.h>
2606 +#include <linux/netfilter_ipv4/listhelp.h>
2608 +#include <linux/netfilter_ipv4/ip_tables.h>
2609 +#include <linux/netfilter_ipv4/ipt_dstlimit.h>
2611 +/* FIXME: this is just for IP_NF_ASSERRT */
2612 +#include <linux/netfilter_ipv4/ip_conntrack.h>
2614 +#define MS2JIFFIES(x) ((x*HZ)/1000)
2616 +MODULE_LICENSE("GPL");
2617 +MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
2618 +MODULE_DESCRIPTION("iptables match for limiting per destination");
2620 +/* need to declare this at the top */
2621 +static struct proc_dir_entry *dstlimit_procdir;
2622 +static struct file_operations dl_file_ops;
2624 +/* hash table crap */
2626 +struct dsthash_dst {
2632 +struct dsthash_ent {
2633 + /* static / read-only parts in the beginning */
2634 + struct list_head list;
2635 + struct dsthash_dst dst;
2637 + /* modified structure members in the end */
2638 + unsigned long expires; /* precalculated expiry time */
2640 + unsigned long prev; /* last modification */
2642 + u_int32_t credit_cap, cost;
2646 +struct ipt_dstlimit_htable {
2647 + struct list_head list; /* global list of all htables */
2650 + struct dstlimit_cfg cfg; /* config */
2652 + /* used internally */
2653 + spinlock_t lock; /* lock for list_head */
2654 + u_int32_t rnd; /* random seed for hash */
2655 + struct timer_list timer; /* timer for gc */
2656 + atomic_t count; /* number entries in table */
2658 + /* seq_file stuff */
2659 + struct proc_dir_entry *pde;
2661 + struct list_head hash[0]; /* hashtable itself */
2664 +DECLARE_RWLOCK(dstlimit_lock); /* protects htables list */
2665 +static LIST_HEAD(dstlimit_htables);
2666 +static kmem_cache_t *dstlimit_cachep;
2668 +static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b)
2670 + return (ent->dst.dst_ip == b->dst_ip
2671 + && ent->dst.port == b->port
2672 + && ent->dst.src_ip == b->src_ip);
2675 +static inline u_int32_t
2676 +hash_dst(const struct ipt_dstlimit_htable *ht, const struct dsthash_dst *dst)
2678 + return (jhash_3words(dst->dst_ip, dst->port,
2679 + dst->src_ip, ht->rnd) % ht->cfg.size);
2682 +static inline struct dsthash_ent *
2683 +__dsthash_find(const struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
2685 + struct dsthash_ent *ent;
2686 + u_int32_t hash = hash_dst(ht, dst);
2687 + MUST_BE_LOCKED(&ht->lock);
2688 + ent = LIST_FIND(&ht->hash[hash], dst_cmp, struct dsthash_ent *, dst);
2692 +/* allocate dsthash_ent, initialize dst, put in htable and lock it */
2693 +static struct dsthash_ent *
2694 +__dsthash_alloc_init(struct ipt_dstlimit_htable *ht, struct dsthash_dst *dst)
2696 + struct dsthash_ent *ent;
2698 + /* initialize hash with random val at the time we allocate
2699 + * the first hashtable entry */
2701 + get_random_bytes(&ht->rnd, 4);
2703 + if (ht->cfg.max &&
2704 + atomic_read(&ht->count) >= ht->cfg.max) {
2705 + /* FIXME: do something. question is what.. */
2706 + if (net_ratelimit())
2707 + printk(KERN_WARNING
2708 + "ipt_dstlimit: max count of %u reached\n",
2713 + ent = kmem_cache_alloc(dstlimit_cachep, GFP_ATOMIC);
2715 + if (net_ratelimit())
2717 + "ipt_dstlimit: can't allocate dsthash_ent\n");
2721 + atomic_inc(&ht->count);
2723 + ent->dst.dst_ip = dst->dst_ip;
2724 + ent->dst.port = dst->port;
2725 + ent->dst.src_ip = dst->src_ip;
2727 + list_add(&ent->list, &ht->hash[hash_dst(ht, dst)]);
2733 +__dsthash_free(struct ipt_dstlimit_htable *ht, struct dsthash_ent *ent)
2735 + MUST_BE_LOCKED(&ht->lock);
2737 + list_del(&ent->list);
2738 + kmem_cache_free(dstlimit_cachep, ent);
2739 + atomic_dec(&ht->count);
2741 +static void htable_gc(unsigned long htlong);
2743 +static int htable_create(struct ipt_dstlimit_info *minfo)
2746 + unsigned int size;
2747 + struct ipt_dstlimit_htable *hinfo;
2749 + if (minfo->cfg.size)
2750 + size = minfo->cfg.size;
2752 + size = (((num_physpages << PAGE_SHIFT) / 16384)
2753 + / sizeof(struct list_head));
2754 + if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
2759 + /* FIXME: don't use vmalloc() here or anywhere else -HW */
2760 + hinfo = vmalloc(sizeof(struct ipt_dstlimit_htable)
2761 + + (sizeof(struct list_head) * size));
2763 + printk(KERN_ERR "ipt_dstlimit: Unable to create hashtable\n");
2766 + minfo->hinfo = hinfo;
2768 + /* copy match config into hashtable config */
2769 + memcpy(&hinfo->cfg, &minfo->cfg, sizeof(hinfo->cfg));
2770 + hinfo->cfg.size = size;
2771 + if (!hinfo->cfg.max)
2772 + hinfo->cfg.max = 8 * hinfo->cfg.size;
2773 + else if (hinfo->cfg.max < hinfo->cfg.size)
2774 + hinfo->cfg.max = hinfo->cfg.size;
2776 + for (i = 0; i < hinfo->cfg.size; i++)
2777 + INIT_LIST_HEAD(&hinfo->hash[i]);
2779 + atomic_set(&hinfo->count, 0);
2780 + atomic_set(&hinfo->use, 1);
2782 + hinfo->lock = SPIN_LOCK_UNLOCKED;
2783 + hinfo->pde = create_proc_entry(minfo->name, 0, dstlimit_procdir);
2784 + if (!hinfo->pde) {
2788 + hinfo->pde->proc_fops = &dl_file_ops;
2789 + hinfo->pde->data = hinfo;
2791 + init_timer(&hinfo->timer);
2792 + hinfo->timer.expires = jiffies + MS2JIFFIES(hinfo->cfg.gc_interval);
2793 + hinfo->timer.data = (unsigned long )hinfo;
2794 + hinfo->timer.function = htable_gc;
2795 + add_timer(&hinfo->timer);
2797 + WRITE_LOCK(&dstlimit_lock);
2798 + list_add(&hinfo->list, &dstlimit_htables);
2799 + WRITE_UNLOCK(&dstlimit_lock);
2804 +static int select_all(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
2809 +static int select_gc(struct ipt_dstlimit_htable *ht, struct dsthash_ent *he)
2811 + return (jiffies >= he->expires);
2814 +static void htable_selective_cleanup(struct ipt_dstlimit_htable *ht,
2815 + int (*select)(struct ipt_dstlimit_htable *ht,
2816 + struct dsthash_ent *he))
2820 + IP_NF_ASSERT(ht->cfg.size && ht->cfg.max);
2822 + /* lock hash table and iterate over it */
2823 + LOCK_BH(&ht->lock);
2824 + for (i = 0; i < ht->cfg.size; i++) {
2825 + struct dsthash_ent *dh, *n;
2826 + list_for_each_entry_safe(dh, n, &ht->hash[i], list) {
2827 + if ((*select)(ht, dh))
2828 + __dsthash_free(ht, dh);
2831 + UNLOCK_BH(&ht->lock);
2834 +/* hash table garbage collector, run by timer */
2835 +static void htable_gc(unsigned long htlong)
2837 + struct ipt_dstlimit_htable *ht = (struct ipt_dstlimit_htable *)htlong;
2839 + htable_selective_cleanup(ht, select_gc);
2841 + /* re-add the timer accordingly */
2842 + ht->timer.expires = jiffies + MS2JIFFIES(ht->cfg.gc_interval);
2843 + add_timer(&ht->timer);
2846 +static void htable_destroy(struct ipt_dstlimit_htable *hinfo)
2848 + /* remove timer, if it is pending */
2849 + if (timer_pending(&hinfo->timer))
2850 + del_timer(&hinfo->timer);
2852 + /* remove proc entry */
2853 + remove_proc_entry(hinfo->pde->name, dstlimit_procdir);
2855 + htable_selective_cleanup(hinfo, select_all);
2859 +static struct ipt_dstlimit_htable *htable_find_get(char *name)
2861 + struct ipt_dstlimit_htable *hinfo;
2863 + READ_LOCK(&dstlimit_lock);
2864 + list_for_each_entry(hinfo, &dstlimit_htables, list) {
2865 + if (!strcmp(name, hinfo->pde->name)) {
2866 + atomic_inc(&hinfo->use);
2867 + READ_UNLOCK(&dstlimit_lock);
2871 + READ_UNLOCK(&dstlimit_lock);
2876 +static void htable_put(struct ipt_dstlimit_htable *hinfo)
2878 + if (atomic_dec_and_test(&hinfo->use)) {
2879 + WRITE_LOCK(&dstlimit_lock);
2880 + list_del(&hinfo->list);
2881 + WRITE_UNLOCK(&dstlimit_lock);
2882 + htable_destroy(hinfo);
2887 +/* The algorithm used is the Simple Token Bucket Filter (TBF)
2888 + * see net/sched/sch_tbf.c in the linux source tree
2891 +/* Rusty: This is my (non-mathematically-inclined) understanding of
2892 + this algorithm. The `average rate' in jiffies becomes your initial
2893 + amount of credit `credit' and the most credit you can ever have
2894 + `credit_cap'. The `peak rate' becomes the cost of passing the
2897 + `prev' tracks the last packet hit: you gain one credit per jiffy.
2898 + If you get credit balance more than this, the extra credit is
2899 + discarded. Every time the match passes, you lose `cost' credits;
2900 + if you don't have that many, the test fails.
2902 + See Alexey's formal explanation in net/sched/sch_tbf.c.
2904 + To get the maximum range, we multiply by this factor (ie. you get N
2905 + credits per jiffy). We want to allow a rate as low as 1 per day
2906 + (slowest userspace tool allows), which means
2907 + CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32 ie.
2909 +#define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24))
2911 +/* Repeated shift and or gives us all 1s, final shift and add 1 gives
2912 + * us the power of 2 below the theoretical max, so GCC simply does a
2914 +#define _POW2_BELOW2(x) ((x)|((x)>>1))
2915 +#define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2))
2916 +#define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4))
2917 +#define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8))
2918 +#define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16))
2919 +#define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1)
2921 +#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
2923 +/* Precision saver. */
2924 +static inline u_int32_t
2925 +user2credits(u_int32_t user)
2927 + /* If multiplying would overflow... */
2928 + if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY))
2929 + /* Divide first. */
2930 + return (user / IPT_DSTLIMIT_SCALE) * HZ * CREDITS_PER_JIFFY;
2932 + return (user * HZ * CREDITS_PER_JIFFY) / IPT_DSTLIMIT_SCALE;
2935 +static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
2937 + dh->rateinfo.credit += (now - xchg(&dh->rateinfo.prev, now))
2938 + * CREDITS_PER_JIFFY;
2939 + if (dh->rateinfo.credit > dh->rateinfo.credit_cap)
2940 + dh->rateinfo.credit = dh->rateinfo.credit_cap;
2944 +dstlimit_match(const struct sk_buff *skb,
2945 + const struct net_device *in,
2946 + const struct net_device *out,
2947 + const void *matchinfo,
2951 + struct ipt_dstlimit_info *r =
2952 + ((struct ipt_dstlimit_info *)matchinfo)->u.master;
2953 + struct ipt_dstlimit_htable *hinfo = r->hinfo;
2954 + unsigned long now = jiffies;
2955 + struct dsthash_ent *dh;
2956 + struct dsthash_dst dst;
2958 + memset(&dst, 0, sizeof(dst));
2960 + /* dest ip is always in hash */
2961 + dst.dst_ip = skb->nh.iph->daddr;
2963 + /* source ip only if respective hashmode, otherwise set to
2965 + if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_SIP)
2966 + dst.src_ip = skb->nh.iph->saddr;
2968 + /* dest port only if respective mode */
2969 + if (hinfo->cfg.mode & IPT_DSTLIMIT_HASH_DPT) {
2972 + /* Must not be a fragment. */
2976 + /* Must be big enough to read ports (both UDP and TCP have
2977 + them at the start). */
2978 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
2979 + /* We've been asked to examine this packet, and we
2980 + can't. Hence, no choice but to drop. */
2985 + switch (skb->nh.iph->protocol) {
2986 + struct tcphdr *th;
2987 + struct udphdr *uh;
2989 + th = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
2990 + dst.port = th->dest;
2993 + uh = (void *)skb->nh.iph+skb->nh.iph->ihl*4;
2994 + dst.port = uh->dest;
3001 + LOCK_BH(&hinfo->lock);
3002 + dh = __dsthash_find(hinfo, &dst);
3004 + dh = __dsthash_alloc_init(hinfo, &dst);
3007 + /* enomem... don't match == DROP */
3008 + if (net_ratelimit())
3009 + printk(KERN_ERR "%s: ENOMEM\n", __FUNCTION__);
3010 + UNLOCK_BH(&hinfo->lock);
3014 + dh->expires = jiffies + MS2JIFFIES(hinfo->cfg.expire);
3016 + dh->rateinfo.prev = jiffies;
3017 + dh->rateinfo.credit = user2credits(hinfo->cfg.avg *
3018 + hinfo->cfg.burst);
3019 + dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg *
3020 + hinfo->cfg.burst);
3021 + dh->rateinfo.cost = user2credits(hinfo->cfg.avg);
3023 + UNLOCK_BH(&hinfo->lock);
3027 + /* update expiration timeout */
3028 + dh->expires = now + MS2JIFFIES(hinfo->cfg.expire);
3030 + rateinfo_recalc(dh, now);
3031 + if (dh->rateinfo.credit >= dh->rateinfo.cost) {
3032 + /* We're underlimit. */
3033 + dh->rateinfo.credit -= dh->rateinfo.cost;
3034 + UNLOCK_BH(&hinfo->lock);
3038 + UNLOCK_BH(&hinfo->lock);
3040 + /* default case: we're overlimit, thus don't match */
3045 +dstlimit_checkentry(const char *tablename,
3046 + const struct ipt_ip *ip,
3048 + unsigned int matchsize,
3049 + unsigned int hook_mask)
3051 + struct ipt_dstlimit_info *r = matchinfo;
3053 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_dstlimit_info)))
3056 + /* Check for overflow. */
3057 + if (r->cfg.burst == 0
3058 + || user2credits(r->cfg.avg * r->cfg.burst) <
3059 + user2credits(r->cfg.avg)) {
3060 + printk(KERN_ERR "ipt_dstlimit: Overflow, try lower: %u/%u\n",
3061 + r->cfg.avg, r->cfg.burst);
3065 + if (r->cfg.mode == 0
3066 + || r->cfg.mode > (IPT_DSTLIMIT_HASH_DPT
3067 + |IPT_DSTLIMIT_HASH_DIP
3068 + |IPT_DSTLIMIT_HASH_SIP))
3071 + if (!r->cfg.gc_interval)
3074 + if (!r->cfg.expire)
3077 + r->hinfo = htable_find_get(r->name);
3078 + if (!r->hinfo && (htable_create(r) != 0)) {
3082 + /* Ugly hack: For SMP, we only want to use one set */
3089 +dstlimit_destroy(void *matchinfo, unsigned int matchsize)
3091 + struct ipt_dstlimit_info *r = (struct ipt_dstlimit_info *) matchinfo;
3093 + htable_put(r->hinfo);
3096 +static struct ipt_match ipt_dstlimit = {
3097 + .list = { .prev = NULL, .next = NULL },
3098 + .name = "dstlimit",
3099 + .match = dstlimit_match,
3100 + .checkentry = dstlimit_checkentry,
3101 + .destroy = dstlimit_destroy,
3107 +static void *dl_seq_start(struct seq_file *s, loff_t *pos)
3109 + struct proc_dir_entry *pde = s->private;
3110 + struct ipt_dstlimit_htable *htable = pde->data;
3111 + unsigned int *bucket;
3113 + LOCK_BH(&htable->lock);
3114 + if (*pos >= htable->cfg.size)
3117 + bucket = kmalloc(sizeof(unsigned int), GFP_KERNEL);
3119 + return ERR_PTR(-ENOMEM);
3125 +static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
3127 + struct proc_dir_entry *pde = s->private;
3128 + struct ipt_dstlimit_htable *htable = pde->data;
3129 + unsigned int *bucket = (unsigned int *)v;
3131 + *pos = ++(*bucket);
3132 + if (*pos >= htable->cfg.size) {
3139 +static void dl_seq_stop(struct seq_file *s, void *v)
3141 + struct proc_dir_entry *pde = s->private;
3142 + struct ipt_dstlimit_htable *htable = pde->data;
3143 + unsigned int *bucket = (unsigned int *)v;
3147 + UNLOCK_BH(&htable->lock);
3150 +static inline int dl_seq_real_show(struct dsthash_ent *ent, struct seq_file *s)
3152 + /* recalculate to show accurate numbers */
3153 + rateinfo_recalc(ent, jiffies);
3155 + return seq_printf(s, "%ld %u.%u.%u.%u->%u.%u.%u.%u:%u %u %u %u\n",
3156 + (ent->expires - jiffies)/HZ,
3157 + NIPQUAD(ent->dst.src_ip),
3158 + NIPQUAD(ent->dst.dst_ip), ntohs(ent->dst.port),
3159 + ent->rateinfo.credit, ent->rateinfo.credit_cap,
3160 + ent->rateinfo.cost);
3163 +static int dl_seq_show(struct seq_file *s, void *v)
3165 + struct proc_dir_entry *pde = s->private;
3166 + struct ipt_dstlimit_htable *htable = pde->data;
3167 + unsigned int *bucket = (unsigned int *)v;
3169 + if (LIST_FIND_W(&htable->hash[*bucket], dl_seq_real_show,
3170 + struct dsthash_ent *, s)) {
3171 + /* buffer was filled and unable to print that tuple */
3177 +static struct seq_operations dl_seq_ops = {
3178 + .start = dl_seq_start,
3179 + .next = dl_seq_next,
3180 + .stop = dl_seq_stop,
3181 + .show = dl_seq_show
3184 +static int dl_proc_open(struct inode *inode, struct file *file)
3186 + int ret = seq_open(file, &dl_seq_ops);
3189 + struct seq_file *sf = file->private_data;
3190 + sf->private = PDE(inode);
3195 +static struct file_operations dl_file_ops = {
3196 + .owner = THIS_MODULE,
3197 + .open = dl_proc_open,
3199 + .llseek = seq_lseek,
3200 + .release = seq_release
3203 +static int init_or_fini(int fini)
3210 + if (ipt_register_match(&ipt_dstlimit)) {
3212 + goto cleanup_nothing;
3215 + /* FIXME: do we really want HWCACHE_ALIGN since our objects are
3216 + * quite small ? */
3217 + dstlimit_cachep = kmem_cache_create("ipt_dstlimit",
3218 + sizeof(struct dsthash_ent), 0,
3219 + SLAB_HWCACHE_ALIGN, NULL, NULL);
3220 + if (!dstlimit_cachep) {
3221 + printk(KERN_ERR "Unable to create ipt_dstlimit slab cache\n");
3223 + goto cleanup_unreg_match;
3226 + dstlimit_procdir = proc_mkdir("ipt_dstlimit", proc_net);
3227 + if (!dstlimit_procdir) {
3228 + printk(KERN_ERR "Unable to create proc dir entry\n");
3230 + goto cleanup_free_slab;
3236 + remove_proc_entry("ipt_dstlimit", proc_net);
3238 + kmem_cache_destroy(dstlimit_cachep);
3239 +cleanup_unreg_match:
3240 + ipt_unregister_match(&ipt_dstlimit);
3246 +static int __init init(void)
3248 + return init_or_fini(0);
3251 +static void __exit fini(void)
3258 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_fuzzy.c linux-2.6.4-rc2/net/ipv4/netfilter/ipt_fuzzy.c
3259 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_fuzzy.c 1970-01-01 00:00:00.000000000 +0000
3260 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ipt_fuzzy.c 2004-03-07 08:43:19.000000000 +0000
3263 + * This module implements a simple TSK FLC
3264 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
3265 + * to limit , in an adaptive and flexible way , the packet rate crossing
3266 + * a given stream . It serves as an initial and very simple (but effective)
3267 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
3268 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
3269 + * into our code in a precise , adaptive and efficient manner.
3270 + * The goal is very similar to that of "limit" match , but using techniques of
3271 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
3272 + * avoiding over and undershoots - and stuff like that .
3275 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
3276 + * 2002-08-17 : Changed to eliminate floating point operations .
3277 + * 2002-08-23 : Coding style changes .
3280 +#include <linux/module.h>
3281 +#include <linux/skbuff.h>
3282 +#include <linux/ip.h>
3283 +#include <linux/random.h>
3284 +#include <net/tcp.h>
3285 +#include <linux/spinlock.h>
3286 +#include <linux/netfilter_ipv4/ip_tables.h>
3287 +#include <linux/netfilter_ipv4/ipt_fuzzy.h>
3290 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
3291 + Expressed in percentage
3294 +#define PAR_LOW 1/100
3297 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED ;
3299 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
3300 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
3301 +MODULE_LICENSE("GPL");
3303 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
3311 + return ( (100*(tx-mini)) / (maxi-mini) );
3314 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
3322 + return ( (100*( maxi - tx )) / ( maxi - mini ) );
3326 +ipt_fuzzy_match(const struct sk_buff *pskb,
3327 + const struct net_device *in,
3328 + const struct net_device *out,
3329 + const void *matchinfo,
3333 + /* From userspace */
3335 + struct ipt_fuzzy_info *info = (struct ipt_fuzzy_info *) matchinfo;
3337 + u_int8_t random_number;
3338 + unsigned long amount;
3339 + u_int8_t howhigh, howlow;
3342 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
3344 + info->bytes_total += pskb->len;
3345 + info->packets_total++;
3347 + info->present_time = jiffies;
3349 + if (info->present_time >= info->previous_time)
3350 + amount = info->present_time - info->previous_time;
3352 + /* There was a transition : I choose to re-sample
3353 + and keep the old acceptance rate...
3357 + info->previous_time = info->present_time;
3358 + info->bytes_total = info->packets_total = 0;
3361 + if (amount > HZ/10) /* More than 100 ms elapsed ... */
3364 + info->mean_rate = (u_int32_t) ((HZ*info->packets_total) \
3367 + info->previous_time = info->present_time;
3368 + info->bytes_total = info->packets_total = 0;
3370 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
3371 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
3373 + info->acceptance_rate = (u_int8_t) \
3374 + (howhigh*PAR_LOW + PAR_HIGH*howlow);
3376 + /* In fact , the above defuzzification would require a denominator
3377 + proportional to (howhigh+howlow) but , in this particular case ,
3378 + that expression is constant .
3379 + An imediate consequence is that it isn't necessary to call
3380 + both mf_high and mf_low - but to keep things understandable ,
3385 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
3388 + if ( info->acceptance_rate < 100 )
3390 + get_random_bytes((void *)(&random_number), 1);
3392 + /* If within the acceptance , it can pass => don't match */
3393 + if (random_number <= (255 * info->acceptance_rate) / 100)
3396 + return 1; /* It can't pass ( It matches ) */
3399 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
3404 +ipt_fuzzy_checkentry(const char *tablename,
3405 + const struct ipt_ip *e,
3407 + unsigned int matchsize,
3408 + unsigned int hook_mask)
3411 + const struct ipt_fuzzy_info *info = matchinfo;
3413 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_fuzzy_info))) {
3414 + printk("ipt_fuzzy: matchsize %u != %u\n", matchsize,
3415 + IPT_ALIGN(sizeof(struct ipt_fuzzy_info)));
3419 + if ((info->minimum_rate < MINFUZZYRATE ) || (info->maximum_rate > MAXFUZZYRATE)
3420 + || (info->minimum_rate >= info->maximum_rate )) {
3421 + printk("ipt_fuzzy: BAD limits , please verify !!!\n");
3428 +static struct ipt_match ipt_fuzzy_reg = {
3430 + .match = ipt_fuzzy_match,
3431 + .checkentry = ipt_fuzzy_checkentry,
3435 +static int __init init(void)
3437 + return ipt_register_match(&ipt_fuzzy_reg);
3440 +static void __exit fini(void)
3442 + ipt_unregister_match(&ipt_fuzzy_reg);
3447 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_ipv4options.c linux-2.6.4-rc2/net/ipv4/netfilter/ipt_ipv4options.c
3448 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_ipv4options.c 1970-01-01 00:00:00.000000000 +0000
3449 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ipt_ipv4options.c 2004-03-07 08:43:20.000000000 +0000
3452 + This is a module which is used to match ipv4 options.
3453 + This file is distributed under the terms of the GNU General Public
3454 + License (GPL). Copies of the GPL can be obtained from:
3455 + ftp://prep.ai.mit.edu/pub/gnu/GPL
3457 + 11-mars-2001 Fabrice MARIE <fabrice@netfilter.org> : initial development.
3458 + 12-july-2001 Fabrice MARIE <fabrice@netfilter.org> : added router-alert otions matching. Fixed a bug with no-srr
3459 + 12-august-2001 Imran Patel <ipatel@crosswinds.net> : optimization of the match.
3460 + 18-november-2001 Fabrice MARIE <fabrice@netfilter.org> : added [!] 'any' option match.
3461 + 19-february-2004 Harald Welte <laforge@netfilter.org> : merge with 2.6.x
3464 +#include <linux/module.h>
3465 +#include <linux/skbuff.h>
3466 +#include <net/ip.h>
3468 +#include <linux/netfilter_ipv4/ip_tables.h>
3469 +#include <linux/netfilter_ipv4/ipt_ipv4options.h>
3471 +MODULE_LICENSE("GPL");
3472 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
3475 +match(const struct sk_buff *skb,
3476 + const struct net_device *in,
3477 + const struct net_device *out,
3478 + const void *matchinfo,
3482 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
3483 + const struct iphdr *iph = skb->nh.iph;
3484 + const struct ip_options *opt;
3486 + if (iph->ihl * 4 == sizeof(struct iphdr)) {
3487 + /* No options, so we match only the "DONTs" and the "IGNOREs" */
3489 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) ||
3490 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3491 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
3492 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
3493 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
3494 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
3499 + if ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)
3500 + /* there are options, and we don't need to care which one */
3503 + if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
3504 + /* there are options but we don't want any ! */
3509 + opt = &(IPCB(skb)->opt);
3511 + /* source routing */
3512 + if ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) {
3513 + if (!((opt->srr) & (opt->is_strictroute)))
3516 + else if ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) {
3517 + if (!((opt->srr) & (!opt->is_strictroute)))
3520 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) {
3524 + /* record route */
3525 + if ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) {
3529 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) {
3534 + if ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) {
3538 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) {
3542 + /* router-alert option */
3543 + if ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) {
3544 + if (!opt->router_alert)
3547 + else if ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) {
3548 + if (opt->router_alert)
3557 +checkentry(const char *tablename,
3558 + const struct ipt_ip *ip,
3560 + unsigned int matchsize,
3561 + unsigned int hook_mask)
3563 + const struct ipt_ipv4options_info *info = matchinfo; /* match info for rule */
3564 + /* Check the size */
3565 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_ipv4options_info)))
3567 + /* Now check the coherence of the data ... */
3568 + if (((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT) &&
3569 + (((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR) ||
3570 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR) ||
3571 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) ||
3572 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) ||
3573 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)))
3574 + return 0; /* opposites */
3575 + if (((info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) == IPT_IPV4OPTION_DONT_MATCH_ANY_OPT) &&
3576 + (((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR) ||
3577 + ((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3578 + ((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) ||
3579 + ((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
3580 + ((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) ||
3581 + ((info->options & IPT_IPV4OPTION_MATCH_ANY_OPT) == IPT_IPV4OPTION_MATCH_ANY_OPT)))
3582 + return 0; /* opposites */
3583 + if (((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) &&
3584 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR))
3585 + return 0; /* cannot match in the same time loose and strict source routing */
3586 + if ((((info->options & IPT_IPV4OPTION_MATCH_SSRR) == IPT_IPV4OPTION_MATCH_SSRR) ||
3587 + ((info->options & IPT_IPV4OPTION_MATCH_LSRR) == IPT_IPV4OPTION_MATCH_LSRR)) &&
3588 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) == IPT_IPV4OPTION_DONT_MATCH_SRR))
3589 + return 0; /* opposites */
3590 + if (((info->options & IPT_IPV4OPTION_MATCH_RR) == IPT_IPV4OPTION_MATCH_RR) &&
3591 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_RR) == IPT_IPV4OPTION_DONT_MATCH_RR))
3592 + return 0; /* opposites */
3593 + if (((info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) == IPT_IPV4OPTION_MATCH_TIMESTAMP) &&
3594 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) == IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
3595 + return 0; /* opposites */
3596 + if (((info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_MATCH_ROUTER_ALERT) &&
3597 + ((info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT) == IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
3598 + return 0; /* opposites */
3600 + /* everything looks ok. */
3604 +static struct ipt_match ipv4options_match = {
3605 + .name = "ipv4options",
3607 + .checkentry = checkentry,
3611 +static int __init init(void)
3613 + return ipt_register_match(&ipv4options_match);
3616 +static void __exit fini(void)
3618 + ipt_unregister_match(&ipv4options_match);
3623 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_mport.c linux-2.6.4-rc2/net/ipv4/netfilter/ipt_mport.c
3624 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_mport.c 1970-01-01 00:00:00.000000000 +0000
3625 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ipt_mport.c 2004-03-07 08:43:23.000000000 +0000
3627 +/* Kernel module to match one of a list of TCP/UDP ports: ports are in
3628 + the same place so we can treat them as equal. */
3629 +#include <linux/module.h>
3630 +#include <linux/types.h>
3631 +#include <linux/udp.h>
3632 +#include <linux/skbuff.h>
3634 +#include <linux/netfilter_ipv4/ipt_mport.h>
3635 +#include <linux/netfilter_ipv4/ip_tables.h>
3637 +MODULE_LICENSE("GPL");
3640 +#define duprintf(format, args...) printk(format , ## args)
3642 +#define duprintf(format, args...)
3645 +/* Returns 1 if the port is matched by the test, 0 otherwise. */
3647 +ports_match(const struct ipt_mport *minfo, u_int16_t src, u_int16_t dst)
3651 + u_int16_t pflags = minfo->pflags;
3652 + for (i=0, m=1; i<IPT_MULTI_PORTS; i++, m<<=1) {
3656 + && minfo->ports[i] == 65535)
3659 + s = minfo->ports[i];
3662 + e = minfo->ports[++i];
3667 + if (minfo->flags & IPT_MPORT_SOURCE
3668 + && src >= s && src <= e)
3671 + if (minfo->flags & IPT_MPORT_DESTINATION
3672 + && dst >= s && dst <= e)
3680 +match(const struct sk_buff *skb,
3681 + const struct net_device *in,
3682 + const struct net_device *out,
3683 + const void *matchinfo,
3688 + const struct ipt_mport *minfo = matchinfo;
3693 + /* Must be big enough to read ports (both UDP and TCP have
3694 + them at the start). */
3695 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
3696 + /* We've been asked to examine this packet, and we
3697 + can't. Hence, no choice but to drop. */
3698 + duprintf("ipt_multiport:"
3699 + " Dropping evil offset=0 tinygram.\n");
3704 + return ports_match(minfo, ntohs(ports[0]), ntohs(ports[1]));
3707 +/* Called when user tries to insert an entry of this type. */
3709 +checkentry(const char *tablename,
3710 + const struct ipt_ip *ip,
3712 + unsigned int matchsize,
3713 + unsigned int hook_mask)
3715 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_mport)))
3718 + /* Must specify proto == TCP/UDP, no unknown flags or bad count */
3719 + return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
3720 + && !(ip->invflags & IPT_INV_PROTO)
3721 + && matchsize == IPT_ALIGN(sizeof(struct ipt_mport));
3724 +static struct ipt_match mport_match = {
3727 + .checkentry = &checkentry,
3731 +static int __init init(void)
3733 + return ipt_register_match(&mport_match);
3736 +static void __exit fini(void)
3738 + ipt_unregister_match(&mport_match);
3743 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_nth.c linux-2.6.4-rc2/net/ipv4/netfilter/ipt_nth.c
3744 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_nth.c 1970-01-01 00:00:00.000000000 +0000
3745 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ipt_nth.c 2004-03-07 08:43:24.000000000 +0000
3748 + This is a module which is used for match support for every Nth packet
3749 + This file is distributed under the terms of the GNU General Public
3750 + License (GPL). Copies of the GPL can be obtained from:
3751 + ftp://prep.ai.mit.edu/pub/gnu/GPL
3753 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
3754 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
3755 + * added support for multiple counters
3756 + * added support for matching on individual packets
3757 + in the counter cycle
3758 + 2004-02-19 Harald Welte <laforge@netfilter.org>
3763 +#include <linux/module.h>
3764 +#include <linux/skbuff.h>
3765 +#include <linux/ip.h>
3766 +#include <net/tcp.h>
3767 +#include <linux/spinlock.h>
3768 +#include <linux/netfilter_ipv4/ip_tables.h>
3769 +#include <linux/netfilter_ipv4/ipt_nth.h>
3771 +MODULE_LICENSE("GPL");
3772 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
3775 + * State information.
3782 +static struct state states[IPT_NTH_NUM_COUNTERS];
3785 +ipt_nth_match(const struct sk_buff *pskb,
3786 + const struct net_device *in,
3787 + const struct net_device *out,
3788 + const void *matchinfo,
3792 + /* Parameters from userspace */
3793 + const struct ipt_nth_info *info = matchinfo;
3794 + unsigned counter = info->counter;
3795 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
3797 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
3801 + spin_lock(&states[counter].lock);
3803 + /* Are we matching every nth packet?*/
3804 + if (info->packet == 0xFF)
3806 + /* We're matching every nth packet and only every nth packet*/
3807 + /* Do we match or invert match? */
3808 + if (info->not == 0)
3810 + if (states[counter].number == 0)
3812 + ++states[counter].number;
3815 + if (states[counter].number >= info->every)
3816 + states[counter].number = 0; /* reset the counter */
3818 + ++states[counter].number;
3823 + if (states[counter].number == 0)
3825 + ++states[counter].number;
3828 + if (states[counter].number >= info->every)
3829 + states[counter].number = 0;
3831 + ++states[counter].number;
3837 + /* We're using the --packet, so there must be a rule for every value */
3838 + if (states[counter].number == info->packet)
3840 + /* only increment the counter when a match happens */
3841 + if (states[counter].number >= info->every)
3842 + states[counter].number = 0; /* reset the counter */
3844 + ++states[counter].number;
3853 + spin_unlock(&states[counter].lock);
3857 + spin_unlock(&states[counter].lock);
3862 +ipt_nth_checkentry(const char *tablename,
3863 + const struct ipt_ip *e,
3865 + unsigned int matchsize,
3866 + unsigned int hook_mask)
3868 + /* Parameters from userspace */
3869 + const struct ipt_nth_info *info = matchinfo;
3870 + unsigned counter = info->counter;
3871 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
3873 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
3877 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_nth_info))) {
3878 + printk("nth: matchsize %u != %u\n", matchsize,
3879 + IPT_ALIGN(sizeof(struct ipt_nth_info)));
3883 + states[counter].number = info->startat;
3888 +static struct ipt_match ipt_nth_reg = {
3890 + .match = ipt_nth_match,
3891 + .checkentry = ipt_nth_checkentry,
3895 +static int __init init(void)
3899 + memset(&states, 0, sizeof(states));
3900 + for (counter = 0; counter < IPT_NTH_NUM_COUNTERS; counter++)
3901 + spin_lock_init(&(states[counter].lock));
3903 + return ipt_register_match(&ipt_nth_reg);
3906 +static void __exit fini(void)
3908 + ipt_unregister_match(&ipt_nth_reg);
3913 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_quota.c linux-2.6.4-rc2/net/ipv4/netfilter/ipt_quota.c
3914 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_quota.c 1970-01-01 00:00:00.000000000 +0000
3915 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ipt_quota.c 2004-03-07 08:43:28.000000000 +0000
3918 + * netfilter module to enforce network quotas
3920 + * Sam Johnston <samj@samj.net>
3922 +#include <linux/module.h>
3923 +#include <linux/skbuff.h>
3924 +#include <linux/spinlock.h>
3925 +#include <linux/interrupt.h>
3927 +#include <linux/netfilter_ipv4/ip_tables.h>
3928 +#include <linux/netfilter_ipv4/ipt_quota.h>
3930 +MODULE_LICENSE("GPL");
3931 +MODULE_AUTHOR("Sam Johnston <samj@samj.net>");
3933 +static spinlock_t quota_lock = SPIN_LOCK_UNLOCKED;
3936 +match(const struct sk_buff *skb,
3937 + const struct net_device *in,
3938 + const struct net_device *out,
3939 + const void *matchinfo,
3940 + int offset, int *hotdrop)
3942 + struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
3943 + unsigned int datalen;
3945 + if (skb->len < sizeof(struct iphdr))
3948 + datalen = skb->len - skb->nh.iph->ihl*4;
3950 + spin_lock_bh("a_lock);
3952 + if (q->quota >= datalen) {
3953 + /* we can afford this one */
3954 + q->quota -= datalen;
3955 + spin_unlock_bh("a_lock);
3957 +#ifdef DEBUG_IPT_QUOTA
3958 + printk("IPT Quota OK: %llu datlen %d \n", q->quota, datalen);
3963 + /* so we do not allow even small packets from now on */
3966 +#ifdef DEBUG_IPT_QUOTA
3967 + printk("IPT Quota Failed: %llu datlen %d \n", q->quota, datalen);
3970 + spin_unlock_bh("a_lock);
3975 +checkentry(const char *tablename,
3976 + const struct ipt_ip *ip,
3977 + void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
3979 + /* TODO: spinlocks? sanity checks? */
3980 + if (matchsize != IPT_ALIGN(sizeof (struct ipt_quota_info)))
3986 +static struct ipt_match quota_match = {
3989 + .checkentry = checkentry,
3996 + return ipt_register_match("a_match);
4002 + ipt_unregister_match("a_match);
4008 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_realm.c linux-2.6.4-rc2/net/ipv4/netfilter/ipt_realm.c
4009 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_realm.c 1970-01-01 00:00:00.000000000 +0000
4010 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ipt_realm.c 2004-03-07 08:43:30.000000000 +0000
4012 +/* IP tables module for matching the routing realm
4016 + * (C) 2003 by Sampsa Ranta <sampsa@netsonic.fi>
4018 + * This program is free software; you can redistribute it and/or modify
4019 + * it under the terms of the GNU General Public License version 2 as
4020 + * published by the Free Software Foundation.
4023 +#include <linux/module.h>
4024 +#include <linux/skbuff.h>
4025 +#include <linux/netdevice.h>
4026 +#include <net/route.h>
4028 +#include <linux/netfilter_ipv4/ipt_realm.h>
4029 +#include <linux/netfilter_ipv4/ip_tables.h>
4031 +MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>");
4032 +MODULE_LICENSE("GPL");
4035 +match(const struct sk_buff *skb,
4036 + const struct net_device *in,
4037 + const struct net_device *out,
4038 + const void *matchinfo,
4042 + const struct ipt_realm_info *info = matchinfo;
4043 + struct dst_entry *dst = skb->dst;
4048 + return (info->id == (dst->tclassid & info->mask)) ^ info->invert;
4051 +static int check(const char *tablename,
4052 + const struct ipt_ip *ip,
4054 + unsigned int matchsize,
4055 + unsigned int hook_mask)
4058 + & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) |
4059 + (1 << NF_IP_LOCAL_OUT)| (1 << NF_IP_LOCAL_IN))) {
4060 + printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, "
4061 + "LOCAL_IN or FORWARD.\n");
4065 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info)))
4071 +static struct ipt_match realm_match = {
4074 + .checkentry = check,
4078 +static int __init init(void)
4080 + return ipt_register_match(&realm_match);
4083 +static void __exit fini(void)
4085 + ipt_unregister_match(&realm_match);
4090 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_sctp.c linux-2.6.4-rc2/net/ipv4/netfilter/ipt_sctp.c
4091 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_sctp.c 1970-01-01 00:00:00.000000000 +0000
4092 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ipt_sctp.c 2004-03-07 08:43:31.000000000 +0000
4094 +#include <linux/module.h>
4095 +#include <linux/skbuff.h>
4096 +#include <net/ip.h>
4097 +#include <linux/sctp.h>
4099 +#include <linux/netfilter_ipv4/ip_tables.h>
4100 +#include <linux/netfilter_ipv4/ipt_sctp.h>
4103 +#define duprintf(format, args...) printk(format , ## args)
4105 +#define duprintf(format, args...)
4108 +#define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \
4109 + || (!!((invflag) & (option)) ^ (cond)))
4112 +match_flags(const struct ipt_sctp_flag_info *flag_info,
4113 + const int flag_count,
4114 + u_int8_t chunktype,
4115 + u_int8_t chunkflags)
4119 + for (i = 0; i < flag_count; i++) {
4120 + if (flag_info[i].chunktype == chunktype) {
4121 + return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag;
4129 +match_packet(const struct sk_buff *skb,
4130 + const u_int32_t *chunkmap,
4131 + int chunk_match_type,
4132 + const struct ipt_sctp_flag_info *flag_info,
4133 + const int flag_count,
4137 + u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
4138 + sctp_chunkhdr_t sch;
4140 + if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) {
4141 + SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap);
4144 + offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t);
4146 + if (skb_copy_bits(skb, offset, &sch, sizeof(sch)) < 0) {
4147 + duprintf("Dropping invalid SCTP packet.\n");
4152 +// duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n",
4153 +// ++i, offset, sch.type, htons(sch.length), sch.flags);
4155 + offset += (htons(sch.length) + 3) & ~3;
4157 + duprintf("skb->len: %d\toffset: %d\n", skb->len, offset);
4159 + if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch.type)) {
4160 + switch (chunk_match_type) {
4161 + case SCTP_CHUNK_MATCH_ANY:
4162 + if (match_flags(flag_info, flag_count,
4163 + sch.type, sch.flags)) {
4168 + case SCTP_CHUNK_MATCH_ALL:
4169 + if (match_flags(flag_info, flag_count,
4170 + sch.type, sch.flags)) {
4171 + SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch.type);
4175 + case SCTP_CHUNK_MATCH_ONLY:
4176 + if (!match_flags(flag_info, flag_count,
4177 + sch.type, sch.flags)) {
4183 + switch (chunk_match_type) {
4184 + case SCTP_CHUNK_MATCH_ONLY:
4188 + } while (offset < skb->len);
4190 + switch (chunk_match_type) {
4191 + case SCTP_CHUNK_MATCH_ALL:
4192 + return SCTP_CHUNKMAP_IS_CLEAR(chunkmap);
4193 + case SCTP_CHUNK_MATCH_ANY:
4195 + case SCTP_CHUNK_MATCH_ONLY:
4199 + /* This will never be reached, but required to stop compiler whine */
4204 +match(const struct sk_buff *skb,
4205 + const struct net_device *in,
4206 + const struct net_device *out,
4207 + const void *matchinfo,
4211 + const struct ipt_sctp_info *info;
4212 + sctp_sctphdr_t sh;
4214 + info = (const struct ipt_sctp_info *)matchinfo;
4217 + duprintf("Dropping non-first fragment.. FIXME\n");
4221 + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &sh, sizeof(sh)) < 0) {
4222 + duprintf("Dropping evil TCP offset=0 tinygram.\n");
4226 + duprintf("spt: %d\tdpt: %d\n", ntohs(sh.source), ntohs(sh.dest));
4228 + return SCCHECK(((ntohs(sh.source) >= info->spts[0])
4229 + && (ntohs(sh.source) <= info->spts[1])),
4230 + IPT_SCTP_SRC_PORTS, info->flags, info->invflags)
4231 + && SCCHECK(((ntohs(sh.dest) >= info->dpts[0])
4232 + && (ntohs(sh.dest) <= info->dpts[1])),
4233 + IPT_SCTP_DEST_PORTS, info->flags, info->invflags)
4234 + && SCCHECK(match_packet(skb, info->chunkmap, info->chunk_match_type,
4235 + info->flag_info, info->flag_count,
4237 + IPT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
4241 +checkentry(const char *tablename,
4242 + const struct ipt_ip *ip,
4244 + unsigned int matchsize,
4245 + unsigned int hook_mask)
4247 + const struct ipt_sctp_info *info;
4249 + info = (const struct ipt_sctp_info *)matchinfo;
4251 + return ip->proto == IPPROTO_SCTP
4252 + && !(ip->invflags & IPT_INV_PROTO)
4253 + && matchsize == IPT_ALIGN(sizeof(struct ipt_sctp_info))
4254 + && !(info->flags & ~IPT_SCTP_VALID_FLAGS)
4255 + && !(info->invflags & ~IPT_SCTP_VALID_FLAGS)
4256 + && !(info->invflags & ~info->flags)
4257 + && ((!(info->flags & IPT_SCTP_CHUNK_TYPES)) ||
4258 + (info->chunk_match_type &
4259 + (SCTP_CHUNK_MATCH_ALL
4260 + | SCTP_CHUNK_MATCH_ANY
4261 + | SCTP_CHUNK_MATCH_ONLY)));
4264 +static struct ipt_match sctp_match =
4266 + .list = { NULL, NULL},
4269 + .checkentry = &checkentry,
4274 +static int __init init(void)
4276 + return ipt_register_match(&sctp_match);
4279 +static void __exit fini(void)
4281 + ipt_unregister_match(&sctp_match);
4287 +MODULE_LICENSE("GPL");
4288 +MODULE_AUTHOR("Kiran Kumar Immidi");
4289 +MODULE_DESCRIPTION("Match for SCTP protocol packets");
4291 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_state.c linux-2.6.4-rc2/net/ipv4/netfilter/ipt_state.c
4292 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_state.c 2004-03-04 06:17:10.000000000 +0000
4293 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ipt_state.c 2004-03-07 08:43:29.000000000 +0000
4295 enum ip_conntrack_info ctinfo;
4296 unsigned int statebit;
4298 - if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
4299 + if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
4300 + statebit = IPT_STATE_UNTRACKED;
4301 + else if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
4302 statebit = IPT_STATE_INVALID;
4304 statebit = IPT_STATE_BIT(ctinfo);
4305 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_u32.c linux-2.6.4-rc2/net/ipv4/netfilter/ipt_u32.c
4306 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/ipt_u32.c 1970-01-01 00:00:00.000000000 +0000
4307 +++ linux-2.6.4-rc2/net/ipv4/netfilter/ipt_u32.c 2004-03-07 08:44:17.000000000 +0000
4309 +/* Kernel module to match u32 packet content. */
4312 +U32 tests whether quantities of up to 4 bytes extracted from a packet
4313 +have specified values. The specification of what to extract is general
4314 +enough to find data at given offsets from tcp headers or payloads.
4317 + The argument amounts to a program in a small language described below.
4318 + tests := location = value | tests && location = value
4319 + value := range | value , range
4320 + range := number | number : number
4321 + a single number, n, is interpreted the same as n:n
4322 + n:m is interpreted as the range of numbers >=n and <=m
4323 + location := number | location operator number
4324 + operator := & | << | >> | @
4326 + The operators &, <<, >>, && mean the same as in c. The = is really a set
4327 + membership operator and the value syntax describes a set. The @ operator
4328 + is what allows moving to the next header and is described further below.
4330 + *** Until I can find out how to avoid it, there are some artificial limits
4331 + on the size of the tests:
4332 + - no more than 10 ='s (and 9 &&'s) in the u32 argument
4333 + - no more than 10 ranges (and 9 commas) per value
4334 + - no more than 10 numbers (and 9 operators) per location
4336 + To describe the meaning of location, imagine the following machine that
4337 + interprets it. There are three registers:
4338 + A is of type char*, initially the address of the IP header
4339 + B and C are unsigned 32 bit integers, initially zero
4341 + The instructions are:
4342 + number B = number;
4343 + C = (*(A+B)<<24)+(*(A+B+1)<<16)+(*(A+B+2)<<8)+*(A+B+3)
4344 + &number C = C&number
4345 + <<number C = C<<number
4346 + >>number C = C>>number
4347 + @number A = A+C; then do the instruction number
4348 + Any access of memory outside [skb->head,skb->end] causes the match to fail.
4349 + Otherwise the result of the computation is the final value of C.
4351 + Whitespace is allowed but not required in the tests.
4352 + However the characters that do occur there are likely to require
4353 + shell quoting, so it's a good idea to enclose the arguments in quotes.
4356 + match IP packets with total length >= 256
4357 + The IP header contains a total length field in bytes 2-3.
4358 + --u32 "0&0xFFFF=0x100:0xFFFF"
4360 + AND that with FFFF (giving bytes 2-3),
4361 + and test whether that's in the range [0x100:0xFFFF]
4363 +Example: (more realistic, hence more complicated)
4364 + match icmp packets with icmp type 0
4365 + First test that it's an icmp packet, true iff byte 9 (protocol) = 1
4366 + --u32 "6&0xFF=1 && ...
4367 + read bytes 6-9, use & to throw away bytes 6-8 and compare the result to 1
4368 + Next test that it's not a fragment.
4369 + (If so it might be part of such a packet but we can't always tell.)
4370 + n.b. This test is generally needed if you want to match anything
4371 + beyond the IP header.
4372 + The last 6 bits of byte 6 and all of byte 7 are 0 iff this is a complete
4373 + packet (not a fragment). Alternatively, you can allow first fragments
4374 + by only testing the last 5 bits of byte 6.
4375 + ... 4&0x3FFF=0 && ...
4376 + Last test: the first byte past the IP header (the type) is 0
4377 + This is where we have to use the @syntax. The length of the IP header
4378 + (IHL) in 32 bit words is stored in the right half of byte 0 of the
4380 + ... 0>>22&0x3C@0>>24=0"
4381 + The first 0 means read bytes 0-3,
4382 + >>22 means shift that 22 bits to the right. Shifting 24 bits would give
4383 + the first byte, so only 22 bits is four times that plus a few more bits.
4384 + &3C then eliminates the two extra bits on the right and the first four
4385 + bits of the first byte.
4386 + For instance, if IHL=5 then the IP header is 20 (4 x 5) bytes long.
4387 + In this case bytes 0-1 are (in binary) xxxx0101 yyzzzzzz,
4388 + >>22 gives the 10 bit value xxxx0101yy and &3C gives 010100.
4389 + @ means to use this number as a new offset into the packet, and read
4390 + four bytes starting from there. This is the first 4 bytes of the icmp
4391 + payload, of which byte 0 is the icmp type. Therefore we simply shift
4392 + the value 24 to the right to throw out all but the first byte and compare
4393 + the result with 0.
4396 + tcp payload bytes 8-12 is any of 1, 2, 5 or 8
4397 + First we test that the packet is a tcp packet (similar to icmp).
4398 + --u32 "6&0xFF=6 && ...
4399 + Next, test that it's not a fragment (same as above).
4400 + ... 0>>22&0x3C@12>>26&0x3C@8=1,2,5,8"
4401 + 0>>22&3C as above computes the number of bytes in the IP header.
4402 + @ makes this the new offset into the packet, which is the start of the
4403 + tcp header. The length of the tcp header (again in 32 bit words) is
4404 + the left half of byte 12 of the tcp header. The 12>>26&3C
4405 + computes this length in bytes (similar to the IP header before).
4406 + @ makes this the new offset, which is the start of the tcp payload.
4407 + Finally 8 reads bytes 8-12 of the payload and = checks whether the
4408 + result is any of 1, 2, 5 or 8
4411 +#include <linux/module.h>
4412 +#include <linux/skbuff.h>
4414 +#include <linux/netfilter_ipv4/ipt_u32.h>
4415 +#include <linux/netfilter_ipv4/ip_tables.h>
4417 +/* #include <asm-i386/timex.h> for timing */
4419 +MODULE_AUTHOR("Don Cohen <don@isis.cs3-inc.com>");
4420 +MODULE_DESCRIPTION("IP tables u32 matching module");
4421 +MODULE_LICENSE("GPL");
4424 +match(const struct sk_buff *skb,
4425 + const struct net_device *in,
4426 + const struct net_device *out,
4427 + const void *matchinfo,
4430 + u_int16_t datalen,
4433 + const struct ipt_u32 *data = matchinfo;
4435 + unsigned char* origbase = (char*)skb->nh.iph;
4436 + unsigned char* base = origbase;
4437 + unsigned char* head = skb->head;
4438 + unsigned char* end = skb->end;
4440 + u_int32_t pos, val;
4441 + /* unsigned long long cycles1, cycles2, cycles3, cycles4;
4442 + cycles1 = get_cycles(); */
4444 + for (testind=0; testind < data->ntests; testind++) {
4445 + base = origbase; /* reset for each test */
4446 + pos = data->tests[testind].location[0].number;
4447 + if (base+pos+3 > end || base+pos < head)
4449 + val = (base[pos]<<24) + (base[pos+1]<<16) +
4450 + (base[pos+2]<<8) + base[pos+3];
4451 + nnums = data->tests[testind].nnums;
4452 + for (i=1; i < nnums; i++) {
4453 + u_int32_t number = data->tests[testind].location[i].number;
4454 + switch (data->tests[testind].location[i].nextop) {
4456 + val = val & number;
4458 + case IPT_U32_LEFTSH:
4459 + val = val << number;
4461 + case IPT_U32_RIGHTSH:
4462 + val = val >> number;
4465 + base = base + val;
4467 + if (base+pos+3 > end || base+pos < head)
4469 + val = (base[pos]<<24) + (base[pos+1]<<16) +
4470 + (base[pos+2]<<8) + base[pos+3];
4474 + nvals = data->tests[testind].nvalues;
4475 + for (i=0; i < nvals; i++) {
4476 + if ((data->tests[testind].value[i].min <= val) &&
4477 + (val <= data->tests[testind].value[i].max)) {
4481 + if (i >= data->tests[testind].nvalues) {
4482 + /* cycles2 = get_cycles();
4483 + printk("failed %d in %d cycles\n", testind,
4484 + cycles2-cycles1); */
4488 + /* cycles2 = get_cycles();
4489 + printk("succeeded in %d cycles\n", cycles2-cycles1); */
4494 +checkentry(const char *tablename,
4495 + const struct ipt_ip *ip,
4497 + unsigned int matchsize,
4498 + unsigned int hook_mask)
4500 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_u32)))
4505 +static struct ipt_match u32_match
4506 += { { NULL, NULL }, "u32", &match, &checkentry, NULL, THIS_MODULE };
4508 +static int __init init(void)
4510 + return ipt_register_match(&u32_match);
4513 +static void __exit fini(void)
4515 + ipt_unregister_match(&u32_match);
4520 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv4/netfilter/iptable_raw.c linux-2.6.4-rc2/net/ipv4/netfilter/iptable_raw.c
4521 --- linux-2.6.4-rc2.org/net/ipv4/netfilter/iptable_raw.c 1970-01-01 00:00:00.000000000 +0000
4522 +++ linux-2.6.4-rc2/net/ipv4/netfilter/iptable_raw.c 2004-03-07 08:43:29.000000000 +0000
4525 + * 'raw' table, which is the very first hooked in at PRE_ROUTING and LOCAL_OUT .
4527 + * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
4529 +#include <linux/module.h>
4530 +#include <linux/netfilter_ipv4/ip_tables.h>
4532 +#define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
4534 +/* Standard entry. */
4535 +struct ipt_standard
4537 + struct ipt_entry entry;
4538 + struct ipt_standard_target target;
4541 +struct ipt_error_target
4543 + struct ipt_entry_target target;
4544 + char errorname[IPT_FUNCTION_MAXNAMELEN];
4549 + struct ipt_entry entry;
4550 + struct ipt_error_target target;
4555 + struct ipt_replace repl;
4556 + struct ipt_standard entries[2];
4557 + struct ipt_error term;
4558 +} initial_table __initdata
4559 += { { "raw", RAW_VALID_HOOKS, 3,
4560 + sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
4561 + { [NF_IP_PRE_ROUTING] 0,
4562 + [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
4563 + { [NF_IP_PRE_ROUTING] 0,
4564 + [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
4568 + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
4570 + sizeof(struct ipt_entry),
4571 + sizeof(struct ipt_standard),
4572 + 0, { 0, 0 }, { } },
4573 + { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
4574 + -NF_ACCEPT - 1 } },
4576 + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
4578 + sizeof(struct ipt_entry),
4579 + sizeof(struct ipt_standard),
4580 + 0, { 0, 0 }, { } },
4581 + { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
4582 + -NF_ACCEPT - 1 } }
4585 + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
4587 + sizeof(struct ipt_entry),
4588 + sizeof(struct ipt_error),
4589 + 0, { 0, 0 }, { } },
4590 + { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } },
4597 +static struct ipt_table packet_raw = {
4599 + .table = &initial_table.repl,
4600 + .valid_hooks = RAW_VALID_HOOKS,
4601 + .lock = RW_LOCK_UNLOCKED,
4605 +/* The work comes in here from netfilter.c. */
4606 +static unsigned int
4607 +ipt_hook(unsigned int hook,
4608 + struct sk_buff **pskb,
4609 + const struct net_device *in,
4610 + const struct net_device *out,
4611 + int (*okfn)(struct sk_buff *))
4613 + return ipt_do_table(pskb, hook, in, out, &packet_raw, NULL);
4616 +/* 'raw' is the very first table. */
4617 +static struct nf_hook_ops ipt_ops[] = {
4621 + .hooknum = NF_IP_PRE_ROUTING,
4622 + .priority = NF_IP_PRI_RAW
4627 + .hooknum = NF_IP_LOCAL_OUT,
4628 + .priority = NF_IP_PRI_RAW
4632 +static int __init init(void)
4636 + /* Register table */
4637 + ret = ipt_register_table(&packet_raw);
4641 + /* Register hooks */
4642 + ret = nf_register_hook(&ipt_ops[0]);
4644 + goto cleanup_table;
4646 + ret = nf_register_hook(&ipt_ops[1]);
4648 + goto cleanup_hook0;
4653 + nf_unregister_hook(&ipt_ops[0]);
4655 + ipt_unregister_table(&packet_raw);
4660 +static void __exit fini(void)
4664 + for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++)
4665 + nf_unregister_hook(&ipt_ops[i]);
4667 + ipt_unregister_table(&packet_raw);
4672 +MODULE_LICENSE("GPL");
4673 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv6/netfilter/Kconfig linux-2.6.4-rc2/net/ipv6/netfilter/Kconfig
4674 --- linux-2.6.4-rc2.org/net/ipv6/netfilter/Kconfig 2004-03-04 06:17:03.000000000 +0000
4675 +++ linux-2.6.4-rc2/net/ipv6/netfilter/Kconfig 2004-03-07 08:43:29.000000000 +0000
4676 @@ -218,5 +218,37 @@
4677 To compile it as a module, choose M here. If unsure, say N.
4679 #dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES
4680 +config IP6_NF_TARGET_HL
4681 + tristate 'HL target support'
4682 + depends on IP6_NF_MANGLE
4685 +config IP6_NF_TARGET_REJECT
4686 + tristate 'REJECT target support'
4687 + depends on IP6_NF_FILTER
4690 +config IP6_NF_MATCH_FUZZY
4691 + tristate 'Fuzzy match support'
4692 + depends on IP6_NF_FILTER
4695 +config IP6_NF_MATCH_NTH
4696 + tristate 'Nth match support'
4697 + depends on IP6_NF_IPTABLES
4701 + tristate 'raw table support (required for TRACE)'
4702 + depends on IP6_NF_IPTABLES
4704 + This option adds a `raw' table to ip6tables. This table is the very
4705 + first in the netfilter framework and hooks in at the PREROUTING
4706 + and OUTPUT chains.
4708 + If you want to compile it as a module, say M here and read
4709 + <file:Documentation/modules.txt>. If unsure, say `N'.
4714 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv6/netfilter/Makefile linux-2.6.4-rc2/net/ipv6/netfilter/Makefile
4715 --- linux-2.6.4-rc2.org/net/ipv6/netfilter/Makefile 2004-03-04 06:16:48.000000000 +0000
4716 +++ linux-2.6.4-rc2/net/ipv6/netfilter/Makefile 2004-03-07 08:43:29.000000000 +0000
4718 obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o
4719 obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
4720 obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o
4721 +obj-$(CONFIG_IP6_NF_MATCH_FUZZY) += ip6t_fuzzy.o
4722 obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
4723 obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
4724 obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
4726 obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
4727 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
4728 obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
4729 +obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
4730 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
4731 obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
4732 +obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
4734 +obj-$(CONFIG_IP6_NF_MATCH_NTH) += ip6t_nth.o
4735 +obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
4736 obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
4737 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv6/netfilter/ip6t_HL.c linux-2.6.4-rc2/net/ipv6/netfilter/ip6t_HL.c
4738 --- linux-2.6.4-rc2.org/net/ipv6/netfilter/ip6t_HL.c 1970-01-01 00:00:00.000000000 +0000
4739 +++ linux-2.6.4-rc2/net/ipv6/netfilter/ip6t_HL.c 2004-03-07 08:43:13.000000000 +0000
4742 + * Hop Limit modification target for ip6tables
4743 + * Maciej Soltysiak <solt@dns.toxicfilms.tv>
4744 + * Based on HW's TTL module
4746 + * This software is distributed under the terms of GNU GPL
4749 +#include <linux/module.h>
4750 +#include <linux/skbuff.h>
4751 +#include <linux/ip.h>
4753 +#include <linux/netfilter_ipv6/ip6_tables.h>
4754 +#include <linux/netfilter_ipv6/ip6t_HL.h>
4756 +MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
4757 +MODULE_DESCRIPTION("IP tables Hop Limit modification module");
4758 +MODULE_LICENSE("GPL");
4760 +static unsigned int ip6t_hl_target(struct sk_buff **pskb, unsigned int hooknum,
4761 + const struct net_device *in, const struct net_device *out,
4762 + const void *targinfo, void *userinfo)
4764 + struct ipv6hdr *ip6h = (*pskb)->nh.ipv6h;
4765 + const struct ip6t_HL_info *info = targinfo;
4766 + u_int16_t diffs[2];
4769 + switch (info->mode) {
4771 + new_hl = info->hop_limit;
4774 + new_hl = ip6h->hop_limit + info->hop_limit;
4779 + new_hl = ip6h->hop_limit + info->hop_limit;
4784 + new_hl = ip6h->hop_limit;
4788 + if (new_hl != ip6h->hop_limit) {
4789 + diffs[0] = htons(((unsigned)ip6h->hop_limit) << 8) ^ 0xFFFF;
4790 + ip6h->hop_limit = new_hl;
4791 + diffs[1] = htons(((unsigned)ip6h->hop_limit) << 8);
4794 + return IP6T_CONTINUE;
4797 +static int ip6t_hl_checkentry(const char *tablename,
4798 + const struct ip6t_entry *e,
4800 + unsigned int targinfosize,
4801 + unsigned int hook_mask)
4803 + struct ip6t_HL_info *info = targinfo;
4805 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_HL_info))) {
4806 + printk(KERN_WARNING "HL: targinfosize %u != %Zu\n",
4808 + IP6T_ALIGN(sizeof(struct ip6t_HL_info)));
4812 + if (strcmp(tablename, "mangle")) {
4813 + printk(KERN_WARNING "HL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
4817 + if (info->mode > IP6T_HL_MAXMODE) {
4818 + printk(KERN_WARNING "HL: invalid or unknown Mode %u\n",
4823 + if ((info->mode != IP6T_HL_SET) && (info->hop_limit == 0)) {
4824 + printk(KERN_WARNING "HL: increment/decrement doesn't make sense with value 0\n");
4831 +static struct ip6t_target ip6t_HL = { { NULL, NULL }, "HL",
4832 + ip6t_hl_target, ip6t_hl_checkentry, NULL, THIS_MODULE };
4834 +static int __init init(void)
4836 + return ip6t_register_target(&ip6t_HL);
4839 +static void __exit fini(void)
4841 + ip6t_unregister_target(&ip6t_HL);
4846 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv6/netfilter/ip6t_LOG.c linux-2.6.4-rc2/net/ipv6/netfilter/ip6t_LOG.c
4847 --- linux-2.6.4-rc2.org/net/ipv6/netfilter/ip6t_LOG.c 2004-03-04 06:16:41.000000000 +0000
4848 +++ linux-2.6.4-rc2/net/ipv6/netfilter/ip6t_LOG.c 2004-03-07 08:43:12.000000000 +0000
4850 #include <net/udp.h>
4851 #include <net/tcp.h>
4852 #include <net/ipv6.h>
4853 +#include <linux/netfilter.h>
4854 #include <linux/netfilter_ipv6/ip6_tables.h>
4856 MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
4857 MODULE_DESCRIPTION("IP6 tables LOG target module");
4858 MODULE_LICENSE("GPL");
4860 +static unsigned int nflog = 1;
4861 +MODULE_PARM(nflog, "i");
4862 +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
4865 #include <net/route.h>
4866 #include <linux/netfilter_ipv6/ip6t_LOG.h>
4867 @@ -265,40 +270,38 @@
4871 -static unsigned int
4872 -ip6t_log_target(struct sk_buff **pskb,
4873 - unsigned int hooknum,
4875 +ip6t_log_packet(unsigned int hooknum,
4876 + const struct sk_buff *skb,
4877 const struct net_device *in,
4878 const struct net_device *out,
4879 - const void *targinfo,
4881 + const struct ip6t_log_info *loginfo,
4882 + const char *level_string,
4883 + const char *prefix)
4885 - struct ipv6hdr *ipv6h = (*pskb)->nh.ipv6h;
4886 - const struct ip6t_log_info *loginfo = targinfo;
4887 - char level_string[4] = "< >";
4888 + struct ipv6hdr *ipv6h = skb->nh.ipv6h;
4890 - level_string[1] = '0' + (loginfo->level % 8);
4891 spin_lock_bh(&log_lock);
4892 printk(level_string);
4893 printk("%sIN=%s OUT=%s ",
4895 + prefix == NULL ? loginfo->prefix : prefix,
4897 out ? out->name : "");
4899 /* MAC logging for input chain only. */
4901 - if ((*pskb)->dev && (*pskb)->dev->hard_header_len && (*pskb)->mac.raw != (void*)ipv6h) {
4902 - if ((*pskb)->dev->type != ARPHRD_SIT){
4903 + if (skb->dev && skb->dev->hard_header_len && skb->mac.raw != (void*)ipv6h) {
4904 + if (skb->dev->type != ARPHRD_SIT){
4906 - unsigned char *p = (*pskb)->mac.raw;
4907 - for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++)
4908 + unsigned char *p = skb->mac.raw;
4909 + for (i = 0; i < skb->dev->hard_header_len; i++,p++)
4910 printk("%02x%c", *p,
4911 - i==(*pskb)->dev->hard_header_len - 1
4912 + i==skb->dev->hard_header_len - 1
4916 - unsigned char *p = (*pskb)->mac.raw;
4917 - if ( p - (ETH_ALEN*2+2) > (*pskb)->head ){
4918 + unsigned char *p = skb->mac.raw;
4919 + if ( p - (ETH_ALEN*2+2) > skb->head ){
4921 for (i = 0; i < (ETH_ALEN); i++,p++)
4922 printk("%02x%s", *p,
4923 @@ -309,10 +312,10 @@
4924 i == ETH_ALEN-1 ? ' ' : ':');
4927 - if (((*pskb)->dev->addr_len == 4) &&
4928 - (*pskb)->dev->hard_header_len > 20){
4929 + if ((skb->dev->addr_len == 4) &&
4930 + skb->dev->hard_header_len > 20){
4932 - p = (*pskb)->mac.raw + 12;
4933 + p = skb->mac.raw + 12;
4934 for (i = 0; i < 4; i++,p++)
4936 i == 3 ? "->" : ".");
4937 @@ -328,10 +331,41 @@
4938 dump_packet(loginfo, ipv6h, 1);
4940 spin_unlock_bh(&log_lock);
4943 +static unsigned int
4944 +ip6t_log_target(struct sk_buff **pskb,
4945 + unsigned int hooknum,
4946 + const struct net_device *in,
4947 + const struct net_device *out,
4948 + const void *targinfo,
4951 + const struct ip6t_log_info *loginfo = targinfo;
4952 + char level_string[4] = "< >";
4954 + level_string[1] = '0' + (loginfo->level % 8);
4955 + ip6t_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL);
4957 return IP6T_CONTINUE;
4961 +ip6t_logfn(unsigned int hooknum,
4962 + const struct sk_buff *skb,
4963 + const struct net_device *in,
4964 + const struct net_device *out,
4965 + const char *prefix)
4967 + struct ip6t_log_info loginfo = {
4969 + .logflags = IP6T_LOG_MASK,
4973 + ip6t_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
4976 static int ip6t_log_checkentry(const char *tablename,
4977 const struct ip6t_entry *e,
4979 @@ -360,20 +394,27 @@
4983 -static struct ip6t_target ip6t_log_reg
4984 -= { { NULL, NULL }, "LOG", ip6t_log_target, ip6t_log_checkentry, NULL,
4986 +static struct ip6t_target ip6t_log_reg = {
4988 + .target = ip6t_log_target,
4989 + .checkentry = ip6t_log_checkentry,
4990 + .me = THIS_MODULE,
4993 static int __init init(void)
4995 if (ip6t_register_target(&ip6t_log_reg))
4998 + nf_log_register(PF_INET6, &ip6t_logfn);
5003 static void __exit fini(void)
5006 + nf_log_unregister(PF_INET6, &ip6t_logfn);
5007 ip6t_unregister_target(&ip6t_log_reg);
5010 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv6/netfilter/ip6t_REJECT.c linux-2.6.4-rc2/net/ipv6/netfilter/ip6t_REJECT.c
5011 --- linux-2.6.4-rc2.org/net/ipv6/netfilter/ip6t_REJECT.c 1970-01-01 00:00:00.000000000 +0000
5012 +++ linux-2.6.4-rc2/net/ipv6/netfilter/ip6t_REJECT.c 2004-03-07 08:43:15.000000000 +0000
5015 + * This is a module which is used for rejecting packets.
5016 + * Added support for customized reject packets (Jozsef Kadlecsik).
5018 + * Port to IPv6 / ip6tables (Harald Welte <laforge@gnumonks.org>)
5020 +#include <linux/config.h>
5021 +#include <linux/module.h>
5022 +#include <linux/skbuff.h>
5023 +#include <linux/icmpv6.h>
5024 +#include <net/tcp.h>
5025 +#include <linux/netfilter_ipv6/ip6_tables.h>
5026 +#include <linux/netfilter_ipv6/ip6t_REJECT.h>
5029 +#define DEBUGP printk
5031 +#define DEBUGP(format, args...)
5035 +/* Send RST reply */
5036 +static void send_reset(struct sk_buff *oldskb)
5038 + struct sk_buff *nskb;
5039 + struct tcphdr *otcph, *tcph;
5040 + struct rtable *rt;
5041 + unsigned int otcplen;
5044 + /* IP header checks: fragment, too short. */
5045 + if (oldskb->nh.iph->frag_off & htons(IP_OFFSET)
5046 + || oldskb->len < (oldskb->nh.iph->ihl<<2) + sizeof(struct tcphdr))
5049 + otcph = (struct tcphdr *)((u_int32_t*)oldskb->nh.iph + oldskb->nh.iph->ihl);
5050 + otcplen = oldskb->len - oldskb->nh.iph->ihl*4;
5052 + /* No RST for RST. */
5056 + /* Check checksum. */
5057 + if (tcp_v4_check(otcph, otcplen, oldskb->nh.iph->saddr,
5058 + oldskb->nh.iph->daddr,
5059 + csum_partial((char *)otcph, otcplen, 0)) != 0)
5062 + /* Copy skb (even if skb is about to be dropped, we can't just
5063 + clone it because there may be other things, such as tcpdump,
5064 + interested in it) */
5065 + nskb = skb_copy(oldskb, GFP_ATOMIC);
5069 + /* This packet will not be the same as the other: clear nf fields */
5070 + nf_conntrack_put(nskb->nfct);
5071 + nskb->nfct = NULL;
5072 + nskb->nfcache = 0;
5073 +#ifdef CONFIG_NETFILTER_DEBUG
5074 + nskb->nf_debug = 0;
5077 + tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
5079 + nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
5080 + tcph->source = xchg(&tcph->dest, tcph->source);
5082 + /* Truncate to length (no data) */
5083 + tcph->doff = sizeof(struct tcphdr)/4;
5084 + skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
5085 + nskb->nh.iph->tot_len = htons(nskb->len);
5089 + tcph->seq = otcph->ack_seq;
5090 + tcph->ack_seq = 0;
5093 + tcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn + otcph->fin
5094 + + otcplen - (otcph->doff<<2));
5099 + ((u_int8_t *)tcph)[13] = 0;
5101 + tcph->ack = needs_ack;
5104 + tcph->urg_ptr = 0;
5106 + /* Adjust TCP checksum */
5108 + tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
5109 + nskb->nh.iph->saddr,
5110 + nskb->nh.iph->daddr,
5111 + csum_partial((char *)tcph,
5112 + sizeof(struct tcphdr), 0));
5114 + /* Adjust IP TTL, DF */
5115 + nskb->nh.iph->ttl = MAXTTL;
5116 + /* Set DF, id = 0 */
5117 + nskb->nh.iph->frag_off = htons(IP_DF);
5118 + nskb->nh.iph->id = 0;
5120 + /* Adjust IP checksum */
5121 + nskb->nh.iph->check = 0;
5122 + nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,
5123 + nskb->nh.iph->ihl);
5126 + if (ip_route_output(&rt, nskb->nh.iph->daddr, nskb->nh.iph->saddr,
5127 + RT_TOS(nskb->nh.iph->tos) | RTO_CONN,
5131 + dst_release(nskb->dst);
5132 + nskb->dst = &rt->u.dst;
5134 + /* "Never happens" */
5135 + if (nskb->len > nskb->dst->pmtu)
5138 + NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
5139 + ip_finish_output);
5147 +static unsigned int reject6_target(struct sk_buff **pskb,
5148 + unsigned int hooknum,
5149 + const struct net_device *in,
5150 + const struct net_device *out,
5151 + const void *targinfo,
5154 + const struct ip6t_reject_info *reject = targinfo;
5156 + /* WARNING: This code causes reentry within ip6tables.
5157 + This means that the ip6tables jump stack is now crap. We
5158 + must return an absolute verdict. --RR */
5159 + DEBUGP("REJECTv6: calling icmpv6_send\n");
5160 + switch (reject->with) {
5161 + case IP6T_ICMP6_NO_ROUTE:
5162 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, out);
5164 + case IP6T_ICMP6_ADM_PROHIBITED:
5165 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADM_PROHIBITED, 0, out);
5167 + case IP6T_ICMP6_NOT_NEIGHBOUR:
5168 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_NOT_NEIGHBOUR, 0, out);
5170 + case IP6T_ICMP6_ADDR_UNREACH:
5171 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, out);
5173 + case IP6T_ICMP6_PORT_UNREACH:
5174 + icmpv6_send(*pskb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, out);
5177 + case IPT_ICMP_ECHOREPLY: {
5178 + struct icmp6hdr *icmph = (struct icmphdr *)
5179 + ((u_int32_t *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl);
5180 + unsigned int datalen = (*pskb)->len - (*pskb)->nh.iph->ihl * 4;
5182 + /* Not non-head frags, or truncated */
5183 + if (((ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET) == 0)
5184 + && datalen >= 4) {
5185 + /* Usually I don't like cut & pasting code,
5186 + but dammit, my party is starting in 45
5188 + struct icmp_bxm icmp_param;
5190 + icmp_param.icmph=*icmph;
5191 + icmp_param.icmph.type=ICMP_ECHOREPLY;
5192 + icmp_param.data_ptr=(icmph+1);
5193 + icmp_param.data_len=datalen;
5194 + icmp_reply(&icmp_param, *pskb);
5198 + case IPT_TCP_RESET:
5199 + send_reset(*pskb);
5203 + printk(KERN_WARNING "REJECTv6: case %u not handled yet\n", reject->with);
5210 +static inline int find_ping_match(const struct ip6t_entry_match *m)
5212 + const struct ip6t_icmp *icmpinfo = (const struct ip6t_icmp *)m->data;
5214 + if (strcmp(m->u.kernel.match->name, "icmp6") == 0
5215 + && icmpinfo->type == ICMPV6_ECHO_REQUEST
5216 + && !(icmpinfo->invflags & IP6T_ICMP_INV))
5222 +static int check(const char *tablename,
5223 + const struct ip6t_entry *e,
5225 + unsigned int targinfosize,
5226 + unsigned int hook_mask)
5228 + const struct ip6t_reject_info *rejinfo = targinfo;
5230 + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
5231 + DEBUGP("REJECTv6: targinfosize %u != 0\n", targinfosize);
5235 + /* Only allow these for packet filtering. */
5236 + if (strcmp(tablename, "filter") != 0) {
5237 + DEBUGP("REJECTv6: bad table `%s'.\n", tablename);
5240 + if ((hook_mask & ~((1 << NF_IP6_LOCAL_IN)
5241 + | (1 << NF_IP6_FORWARD)
5242 + | (1 << NF_IP6_LOCAL_OUT))) != 0) {
5243 + DEBUGP("REJECTv6: bad hook mask %X\n", hook_mask);
5247 + if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
5248 + /* Must specify that it's an ICMP ping packet. */
5249 + if (e->ipv6.proto != IPPROTO_ICMPV6
5250 + || (e->ipv6.invflags & IP6T_INV_PROTO)) {
5251 + DEBUGP("REJECTv6: ECHOREPLY illegal for non-icmp\n");
5254 + /* Must contain ICMP match. */
5255 + if (IP6T_MATCH_ITERATE(e, find_ping_match) == 0) {
5256 + DEBUGP("REJECTv6: ECHOREPLY illegal for non-ping\n");
5259 + } else if (rejinfo->with == IP6T_TCP_RESET) {
5260 + /* Must specify that it's a TCP packet */
5261 + if (e->ipv6.proto != IPPROTO_TCP
5262 + || (e->ipv6.invflags & IP6T_INV_PROTO)) {
5263 + DEBUGP("REJECTv6: TCP_RESET illegal for non-tcp\n");
5271 +static struct ip6t_target ip6t_reject_reg
5272 += { { NULL, NULL }, "REJECT", reject6_target, check, NULL, THIS_MODULE };
5274 +static int __init init(void)
5276 + if (ip6t_register_target(&ip6t_reject_reg))
5281 +static void __exit fini(void)
5283 + ip6t_unregister_target(&ip6t_reject_reg);
5288 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv6/netfilter/ip6t_fuzzy.c linux-2.6.4-rc2/net/ipv6/netfilter/ip6t_fuzzy.c
5289 --- linux-2.6.4-rc2.org/net/ipv6/netfilter/ip6t_fuzzy.c 1970-01-01 00:00:00.000000000 +0000
5290 +++ linux-2.6.4-rc2/net/ipv6/netfilter/ip6t_fuzzy.c 2004-03-07 08:43:19.000000000 +0000
5293 + * This module implements a simple TSK FLC
5294 + * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims
5295 + * to limit , in an adaptive and flexible way , the packet rate crossing
5296 + * a given stream . It serves as an initial and very simple (but effective)
5297 + * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks.
5298 + * As a matter of fact , Fuzzy Logic can help us to insert any "behavior"
5299 + * into our code in a precise , adaptive and efficient manner.
5300 + * The goal is very similar to that of "limit" match , but using techniques of
5301 + * Fuzzy Control , that allow us to shape the transfer functions precisely ,
5302 + * avoiding over and undershoots - and stuff like that .
5305 + * 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
5306 + * 2002-08-17 : Changed to eliminate floating point operations .
5307 + * 2002-08-23 : Coding style changes .
5308 + * 2003-04-08 Maciej Soltysiak <solt@dns.toxicilms.tv> : IPv6 Port
5311 +#include <linux/module.h>
5312 +#include <linux/skbuff.h>
5313 +#include <linux/ipv6.h>
5314 +#include <linux/random.h>
5315 +#include <net/tcp.h>
5316 +#include <linux/spinlock.h>
5317 +#include <linux/netfilter_ipv6/ip6_tables.h>
5318 +#include <linux/netfilter_ipv6/ip6t_fuzzy.h>
5321 + Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
5322 + Expressed in percentage
5325 +#define PAR_LOW 1/100
5328 +static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED;
5330 +MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
5331 +MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module");
5332 +MODULE_LICENSE("GPL");
5334 +static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
5336 + if (tx >= maxi) return 100;
5338 + if (tx <= mini) return 0;
5340 + return ((100 * (tx-mini)) / (maxi-mini));
5343 +static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi)
5345 + if (tx <= mini) return 100;
5347 + if (tx >= maxi) return 0;
5349 + return ((100 * (maxi - tx)) / (maxi - mini));
5354 +ip6t_fuzzy_match(const struct sk_buff *pskb,
5355 + const struct net_device *in,
5356 + const struct net_device *out,
5357 + const void *matchinfo,
5360 + u_int16_t datalen,
5363 + /* From userspace */
5365 + struct ip6t_fuzzy_info *info = (struct ip6t_fuzzy_info *) matchinfo;
5367 + u_int8_t random_number;
5368 + unsigned long amount;
5369 + u_int8_t howhigh, howlow;
5372 + spin_lock_bh(&fuzzy_lock); /* Rise the lock */
5374 + info->bytes_total += pskb->len;
5375 + info->packets_total++;
5377 + info->present_time = jiffies;
5379 + if (info->present_time >= info->previous_time)
5380 + amount = info->present_time - info->previous_time;
5382 + /* There was a transition : I choose to re-sample
5383 + and keep the old acceptance rate...
5387 + info->previous_time = info->present_time;
5388 + info->bytes_total = info->packets_total = 0;
5391 + if ( amount > HZ/10) {/* More than 100 ms elapsed ... */
5393 + info->mean_rate = (u_int32_t) ((HZ * info->packets_total) \
5396 + info->previous_time = info->present_time;
5397 + info->bytes_total = info->packets_total = 0;
5399 + howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate);
5400 + howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate);
5402 + info->acceptance_rate = (u_int8_t) \
5403 + (howhigh * PAR_LOW + PAR_HIGH * howlow);
5405 + /* In fact, the above defuzzification would require a denominator
5406 + * proportional to (howhigh+howlow) but, in this particular case,
5407 + * that expression is constant.
5408 + * An imediate consequence is that it is not necessary to call
5409 + * both mf_high and mf_low - but to keep things understandable,
5415 + spin_unlock_bh(&fuzzy_lock); /* Release the lock */
5418 + if (info->acceptance_rate < 100)
5420 + get_random_bytes((void *)(&random_number), 1);
5422 + /* If within the acceptance , it can pass => don't match */
5423 + if (random_number <= (255 * info->acceptance_rate) / 100)
5426 + return 1; /* It can't pass (It matches) */
5429 + return 0; /* acceptance_rate == 100 % => Everything passes ... */
5434 +ip6t_fuzzy_checkentry(const char *tablename,
5435 + const struct ip6t_ip6 *ip,
5437 + unsigned int matchsize,
5438 + unsigned int hook_mask)
5441 + const struct ip6t_fuzzy_info *info = matchinfo;
5443 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info))) {
5444 + printk("ip6t_fuzzy: matchsize %u != %u\n", matchsize,
5445 + IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info)));
5449 + if ((info->minimum_rate < MINFUZZYRATE) || (info->maximum_rate > MAXFUZZYRATE)
5450 + || (info->minimum_rate >= info->maximum_rate)) {
5451 + printk("ip6t_fuzzy: BAD limits , please verify !!!\n");
5458 +static struct ip6t_match ip6t_fuzzy_reg = {
5462 + ip6t_fuzzy_checkentry,
5466 +static int __init init(void)
5468 + if (ip6t_register_match(&ip6t_fuzzy_reg))
5474 +static void __exit fini(void)
5476 + ip6t_unregister_match(&ip6t_fuzzy_reg);
5481 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv6/netfilter/ip6t_nth.c linux-2.6.4-rc2/net/ipv6/netfilter/ip6t_nth.c
5482 --- linux-2.6.4-rc2.org/net/ipv6/netfilter/ip6t_nth.c 1970-01-01 00:00:00.000000000 +0000
5483 +++ linux-2.6.4-rc2/net/ipv6/netfilter/ip6t_nth.c 2004-03-07 08:43:24.000000000 +0000
5486 + This is a module which is used for match support for every Nth packet
5487 + This file is distributed under the terms of the GNU General Public
5488 + License (GPL). Copies of the GPL can be obtained from:
5489 + ftp://prep.ai.mit.edu/pub/gnu/GPL
5491 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
5492 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
5493 + * added support for multiple counters
5494 + * added support for matching on individual packets
5495 + in the counter cycle
5496 + 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
5500 +#include <linux/module.h>
5501 +#include <linux/skbuff.h>
5502 +#include <linux/ip.h>
5503 +#include <net/tcp.h>
5504 +#include <linux/spinlock.h>
5505 +#include <linux/netfilter_ipv6/ip6_tables.h>
5506 +#include <linux/netfilter_ipv6/ip6t_nth.h>
5508 +MODULE_LICENSE("GPL");
5511 + * State information.
5518 +static struct state states[IP6T_NTH_NUM_COUNTERS];
5521 +ip6t_nth_match(const struct sk_buff *pskb,
5522 + const struct net_device *in,
5523 + const struct net_device *out,
5524 + const void *matchinfo,
5527 + u_int16_t datalen,
5530 + /* Parameters from userspace */
5531 + const struct ip6t_nth_info *info = matchinfo;
5532 + unsigned counter = info->counter;
5533 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
5535 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
5539 + spin_lock(&states[counter].lock);
5541 + /* Are we matching every nth packet?*/
5542 + if (info->packet == 0xFF)
5544 + /* We're matching every nth packet and only every nth packet*/
5545 + /* Do we match or invert match? */
5546 + if (info->not == 0)
5548 + if (states[counter].number == 0)
5550 + ++states[counter].number;
5553 + if (states[counter].number >= info->every)
5554 + states[counter].number = 0; /* reset the counter */
5556 + ++states[counter].number;
5561 + if (states[counter].number == 0)
5563 + ++states[counter].number;
5566 + if (states[counter].number >= info->every)
5567 + states[counter].number = 0;
5569 + ++states[counter].number;
5575 + /* We're using the --packet, so there must be a rule for every value */
5576 + if (states[counter].number == info->packet)
5578 + /* only increment the counter when a match happens */
5579 + if (states[counter].number >= info->every)
5580 + states[counter].number = 0; /* reset the counter */
5582 + ++states[counter].number;
5591 + spin_unlock(&states[counter].lock);
5595 + spin_unlock(&states[counter].lock);
5600 +ip6t_nth_checkentry(const char *tablename,
5601 + const struct ip6t_ip6 *e,
5603 + unsigned int matchsize,
5604 + unsigned int hook_mask)
5606 + /* Parameters from userspace */
5607 + const struct ip6t_nth_info *info = matchinfo;
5608 + unsigned counter = info->counter;
5609 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
5611 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
5615 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_nth_info))) {
5616 + printk("nth: matchsize %u != %u\n", matchsize,
5617 + IP6T_ALIGN(sizeof(struct ip6t_nth_info)));
5621 + states[counter].number = info->startat;
5626 +static struct ip6t_match ip6t_nth_reg = {
5630 + ip6t_nth_checkentry,
5634 +static int __init init(void)
5637 + memset(&states, 0, sizeof(states));
5638 + if (ip6t_register_match(&ip6t_nth_reg))
5641 + for(counter = 0; counter < IP6T_NTH_NUM_COUNTERS; counter++)
5643 + spin_lock_init(&(states[counter].lock));
5646 + printk("ip6t_nth match loaded\n");
5650 +static void __exit fini(void)
5652 + ip6t_unregister_match(&ip6t_nth_reg);
5653 + printk("ip6t_nth match unloaded\n");
5658 diff -Nur --exclude '*.orig' linux-2.6.4-rc2.org/net/ipv6/netfilter/ip6table_raw.c linux-2.6.4-rc2/net/ipv6/netfilter/ip6table_raw.c
5659 --- linux-2.6.4-rc2.org/net/ipv6/netfilter/ip6table_raw.c 1970-01-01 00:00:00.000000000 +0000
5660 +++ linux-2.6.4-rc2/net/ipv6/netfilter/ip6table_raw.c 2004-03-07 08:43:29.000000000 +0000
5663 + * IPv6 raw table, a port of the IPv4 raw table to IPv6
5665 + * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
5667 +#include <linux/module.h>
5668 +#include <linux/netfilter_ipv6/ip6_tables.h>
5670 +#define RAW_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT))
5673 +#define DEBUGP(x, args...) printk(KERN_DEBUG x, ## args)
5675 +#define DEBUGP(x, args...)
5678 +/* Standard entry. */
5679 +struct ip6t_standard
5681 + struct ip6t_entry entry;
5682 + struct ip6t_standard_target target;
5685 +struct ip6t_error_target
5687 + struct ip6t_entry_target target;
5688 + char errorname[IP6T_FUNCTION_MAXNAMELEN];
5693 + struct ip6t_entry entry;
5694 + struct ip6t_error_target target;
5699 + struct ip6t_replace repl;
5700 + struct ip6t_standard entries[2];
5701 + struct ip6t_error term;
5702 +} initial_table __initdata
5703 += { { "raw", RAW_VALID_HOOKS, 3,
5704 + sizeof(struct ip6t_standard) * 2 + sizeof(struct ip6t_error),
5705 + { [NF_IP6_PRE_ROUTING] 0,
5706 + [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) },
5707 + { [NF_IP6_PRE_ROUTING] 0,
5708 + [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) },
5712 + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
5714 + sizeof(struct ip6t_entry),
5715 + sizeof(struct ip6t_standard),
5716 + 0, { 0, 0 }, { } },
5717 + { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
5718 + -NF_ACCEPT - 1 } },
5720 + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
5722 + sizeof(struct ip6t_entry),
5723 + sizeof(struct ip6t_standard),
5724 + 0, { 0, 0 }, { } },
5725 + { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
5726 + -NF_ACCEPT - 1 } },
5729 + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
5731 + sizeof(struct ip6t_entry),
5732 + sizeof(struct ip6t_error),
5733 + 0, { 0, 0 }, { } },
5734 + { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } },
5741 +static struct ip6t_table packet_raw = {
5743 + .table = &initial_table.repl,
5744 + .valid_hooks = RAW_VALID_HOOKS,
5745 + .lock = RW_LOCK_UNLOCKED,
5749 +/* The work comes in here from netfilter.c. */
5750 +static unsigned int
5751 +ip6t_hook(unsigned int hook,
5752 + struct sk_buff **pskb,
5753 + const struct net_device *in,
5754 + const struct net_device *out,
5755 + int (*okfn)(struct sk_buff *))
5757 + return ip6t_do_table(pskb, hook, in, out, &packet_raw, NULL);
5760 +static struct nf_hook_ops ip6t_ops[] = {
5762 + .hook = ip6t_hook,
5764 + .hooknum = NF_IP6_PRE_ROUTING,
5765 + .priority = NF_IP6_PRI_FIRST
5768 + .hook = ip6t_hook,
5770 + .hooknum = NF_IP6_LOCAL_OUT,
5771 + .priority = NF_IP6_PRI_FIRST
5775 +static int __init init(void)
5779 + /* Register table */
5780 + ret = ip6t_register_table(&packet_raw);
5784 + /* Register hooks */
5785 + ret = nf_register_hook(&ip6t_ops[0]);
5787 + goto cleanup_table;
5789 + ret = nf_register_hook(&ip6t_ops[1]);
5791 + goto cleanup_hook0;
5796 + nf_unregister_hook(&ip6t_ops[0]);
5798 + ip6t_unregister_table(&packet_raw);
5803 +static void __exit fini(void)
5807 + for (i = 0; i < sizeof(ip6t_ops)/sizeof(struct nf_hook_ops); i++)
5808 + nf_unregister_hook(&ip6t_ops[i]);
5810 + ip6t_unregister_table(&packet_raw);
5815 +MODULE_LICENSE("GPL");