1 include/linux/netfilter_ipv4/ipt_nth.h | 19 +++
2 include/linux/netfilter_ipv6/ip6t_nth.h | 19 +++
3 net/ipv4/netfilter/Kconfig | 24 ++++
4 net/ipv4/netfilter/Makefile | 1
5 net/ipv4/netfilter/ipt_nth.c | 166 ++++++++++++++++++++++++++++++
6 net/ipv6/netfilter/Kconfig | 24 ++++
7 net/ipv6/netfilter/Makefile | 1
8 net/ipv6/netfilter/ip6t_nth.c | 172 ++++++++++++++++++++++++++++++++
9 8 files changed, 426 insertions(+)
11 diff -Nur --exclude '*.orig' linux.org/include/linux/netfilter_ipv4/ipt_nth.h linux/include/linux/netfilter_ipv4/ipt_nth.h
12 --- linux.org/include/linux/netfilter_ipv4/ipt_nth.h 1970-01-01 01:00:00.000000000 +0100
13 +++ linux/include/linux/netfilter_ipv4/ipt_nth.h 2006-05-04 10:15:51.000000000 +0200
18 +#include <linux/param.h>
19 +#include <linux/types.h>
21 +#ifndef IPT_NTH_NUM_COUNTERS
22 +#define IPT_NTH_NUM_COUNTERS 16
25 +struct ipt_nth_info {
33 +#endif /*_IPT_NTH_H*/
34 diff -Nur --exclude '*.orig' linux.org/include/linux/netfilter_ipv6/ip6t_nth.h linux/include/linux/netfilter_ipv6/ip6t_nth.h
35 --- linux.org/include/linux/netfilter_ipv6/ip6t_nth.h 1970-01-01 01:00:00.000000000 +0100
36 +++ linux/include/linux/netfilter_ipv6/ip6t_nth.h 2006-05-04 10:15:51.000000000 +0200
41 +#include <linux/param.h>
42 +#include <linux/types.h>
44 +#ifndef IP6T_NTH_NUM_COUNTERS
45 +#define IP6T_NTH_NUM_COUNTERS 16
48 +struct ip6t_nth_info {
56 +#endif /*_IP6T_NTH_H*/
57 diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/Kconfig linux/net/ipv4/netfilter/Kconfig
58 --- linux.org/net/ipv4/netfilter/Kconfig 2006-05-02 23:38:44.000000000 +0200
59 +++ linux/net/ipv4/netfilter/Kconfig 2006-05-04 10:15:51.000000000 +0200
61 Allows altering the ARP packet payload: source and destination
62 hardware and network addresses.
64 +config IP_NF_MATCH_NTH
65 + tristate 'Nth match support'
66 + depends on IP_NF_IPTABLES
68 + This option adds a `Nth' match, which allow you to make
69 + rules that match every Nth packet. By default there are
70 + 16 different counters.
73 + --every Nth Match every Nth packet
74 + [--counter] num Use counter 0-15 (default:0)
75 + [--start] num Initialize the counter at the number 'num'
76 + instead of 0. Must be between 0 and Nth-1
77 + [--packet] num Match on 'num' packet. Must be between 0
80 + If --packet is used for a counter than
81 + there must be Nth number of --packet
82 + rules, covering all values between 0 and
85 + If you want to compile it as a module, say M here and read
86 + Documentation/modules.txt. If unsure, say `N'.
90 diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/Makefile linux/net/ipv4/netfilter/Makefile
91 --- linux.org/net/ipv4/netfilter/Makefile 2006-05-02 23:38:44.000000000 +0200
92 +++ linux/net/ipv4/netfilter/Makefile 2006-05-04 10:15:51.000000000 +0200
94 +obj-$(CONFIG_IP_NF_MATCH_NTH) += ipt_nth.o
95 diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/ipt_nth.c linux/net/ipv4/netfilter/ipt_nth.c
96 --- linux.org/net/ipv4/netfilter/ipt_nth.c 1970-01-01 01:00:00.000000000 +0100
97 +++ linux/net/ipv4/netfilter/ipt_nth.c 2006-05-04 10:15:51.000000000 +0200
100 + This is a module which is used for match support for every Nth packet
101 + This file is distributed under the terms of the GNU General Public
102 + License (GPL). Copies of the GPL can be obtained from:
103 + ftp://prep.ai.mit.edu/pub/gnu/GPL
105 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
106 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
107 + * added support for multiple counters
108 + * added support for matching on individual packets
109 + in the counter cycle
110 + 2004-02-19 Harald Welte <laforge@netfilter.org>
115 +#include <linux/module.h>
116 +#include <linux/skbuff.h>
117 +#include <linux/ip.h>
118 +#include <net/tcp.h>
119 +#include <linux/spinlock.h>
120 +#include <linux/netfilter_ipv4/ip_tables.h>
121 +#include <linux/netfilter_ipv4/ipt_nth.h>
123 +MODULE_LICENSE("GPL");
124 +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>");
127 + * State information.
134 +static struct state states[IPT_NTH_NUM_COUNTERS];
137 +ipt_nth_match(const struct sk_buff *pskb,
138 + const struct net_device *in,
139 + const struct net_device *out,
140 + const void *matchinfo,
142 + unsigned int protoff,
145 + /* Parameters from userspace */
146 + const struct ipt_nth_info *info = matchinfo;
147 + unsigned counter = info->counter;
148 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
150 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
154 + spin_lock(&states[counter].lock);
156 + /* Are we matching every nth packet?*/
157 + if (info->packet == 0xFF)
159 + /* We're matching every nth packet and only every nth packet*/
160 + /* Do we match or invert match? */
161 + if (info->not == 0)
163 + if (states[counter].number == 0)
165 + ++states[counter].number;
168 + if (states[counter].number >= info->every)
169 + states[counter].number = 0; /* reset the counter */
171 + ++states[counter].number;
176 + if (states[counter].number == 0)
178 + ++states[counter].number;
181 + if (states[counter].number >= info->every)
182 + states[counter].number = 0;
184 + ++states[counter].number;
190 + /* We're using the --packet, so there must be a rule for every value */
191 + if (states[counter].number == info->packet)
193 + /* only increment the counter when a match happens */
194 + if (states[counter].number >= info->every)
195 + states[counter].number = 0; /* reset the counter */
197 + ++states[counter].number;
206 + spin_unlock(&states[counter].lock);
210 + spin_unlock(&states[counter].lock);
215 +ipt_nth_checkentry(const char *tablename,
216 + const struct ipt_ip *e,
218 + unsigned int matchsize,
219 + unsigned int hook_mask)
221 + /* Parameters from userspace */
222 + const struct ipt_nth_info *info = matchinfo;
223 + unsigned counter = info->counter;
224 + if((counter < 0) || (counter >= IPT_NTH_NUM_COUNTERS))
226 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1);
230 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_nth_info))) {
231 + printk("nth: matchsize %u != %zu\n", matchsize,
232 + IPT_ALIGN(sizeof(struct ipt_nth_info)));
236 + states[counter].number = info->startat;
241 +static struct ipt_match ipt_nth_reg = {
243 + .match = ipt_nth_match,
244 + .checkentry = ipt_nth_checkentry,
248 +static int __init init(void)
252 + memset(&states, 0, sizeof(states));
253 + for (counter = 0; counter < IPT_NTH_NUM_COUNTERS; counter++)
254 + spin_lock_init(&(states[counter].lock));
256 + return ipt_register_match(&ipt_nth_reg);
259 +static void __exit fini(void)
261 + ipt_unregister_match(&ipt_nth_reg);
266 diff -Nur --exclude '*.orig' linux.org/net/ipv6/netfilter/Kconfig linux/net/ipv6/netfilter/Kconfig
267 --- linux.org/net/ipv6/netfilter/Kconfig 2006-05-02 23:38:44.000000000 +0200
268 +++ linux/net/ipv6/netfilter/Kconfig 2006-05-04 10:15:51.000000000 +0200
270 If you want to compile it as a module, say M here and read
271 <file:Documentation/modules.txt>. If unsure, say `N'.
273 +config IP6_NF_MATCH_NTH
274 + tristate 'Nth match support'
275 + depends on IP6_NF_IPTABLES
277 + This option adds a `Nth' match, which allow you to make
278 + rules that match every Nth packet. By default there are
279 + 16 different counters.
282 + --every Nth Match every Nth packet
283 + [--counter] num Use counter 0-15 (default:0)
284 + [--start] num Initialize the counter at the number 'num'
285 + instead of 0. Must be between 0 and Nth-1
286 + [--packet] num Match on 'num' packet. Must be between 0
289 + If --packet is used for a counter than
290 + there must be Nth number of --packet
291 + rules, covering all values between 0 and
294 + If you want to compile it as a module, say M here and read
295 + Documentation/modules.txt. If unsure, say `N'.
299 diff -Nur --exclude '*.orig' linux.org/net/ipv6/netfilter/Makefile linux/net/ipv6/netfilter/Makefile
300 --- linux.org/net/ipv6/netfilter/Makefile 2006-05-02 23:38:44.000000000 +0200
301 +++ linux/net/ipv6/netfilter/Makefile 2006-05-04 10:15:51.000000000 +0200
303 +obj-$(CONFIG_IP6_NF_MATCH_NTH) += ip6t_nth.o
304 diff -Nur --exclude '*.orig' linux.org/net/ipv6/netfilter/ip6t_nth.c linux/net/ipv6/netfilter/ip6t_nth.c
305 --- linux.org/net/ipv6/netfilter/ip6t_nth.c 1970-01-01 01:00:00.000000000 +0100
306 +++ linux/net/ipv6/netfilter/ip6t_nth.c 2006-05-04 10:15:51.000000000 +0200
309 + This is a module which is used for match support for every Nth packet
310 + This file is distributed under the terms of the GNU General Public
311 + License (GPL). Copies of the GPL can be obtained from:
312 + ftp://prep.ai.mit.edu/pub/gnu/GPL
314 + 2001-07-18 Fabrice MARIE <fabrice@netfilter.org> : initial implementation.
315 + 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
316 + * added support for multiple counters
317 + * added support for matching on individual packets
318 + in the counter cycle
319 + 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
320 + 2005-06-27 Harald Welte <laforg@netfilter.org>: API update
324 +#include <linux/module.h>
325 +#include <linux/skbuff.h>
326 +#include <linux/ip.h>
327 +#include <net/tcp.h>
328 +#include <linux/spinlock.h>
329 +#include <linux/netfilter_ipv6/ip6_tables.h>
330 +#include <linux/netfilter_ipv6/ip6t_nth.h>
332 +MODULE_LICENSE("GPL");
335 + * State information.
342 +static struct state states[IP6T_NTH_NUM_COUNTERS];
345 +ip6t_nth_match(const struct sk_buff *pskb,
346 + const struct net_device *in,
347 + const struct net_device *out,
348 + const void *matchinfo,
350 + unsigned int protoff,
353 + /* Parameters from userspace */
354 + const struct ip6t_nth_info *info = matchinfo;
355 + unsigned counter = info->counter;
356 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
358 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
362 + spin_lock(&states[counter].lock);
364 + /* Are we matching every nth packet?*/
365 + if (info->packet == 0xFF)
367 + /* We're matching every nth packet and only every nth packet*/
368 + /* Do we match or invert match? */
369 + if (info->not == 0)
371 + if (states[counter].number == 0)
373 + ++states[counter].number;
376 + if (states[counter].number >= info->every)
377 + states[counter].number = 0; /* reset the counter */
379 + ++states[counter].number;
384 + if (states[counter].number == 0)
386 + ++states[counter].number;
389 + if (states[counter].number >= info->every)
390 + states[counter].number = 0;
392 + ++states[counter].number;
398 + /* We're using the --packet, so there must be a rule for every value */
399 + if (states[counter].number == info->packet)
401 + /* only increment the counter when a match happens */
402 + if (states[counter].number >= info->every)
403 + states[counter].number = 0; /* reset the counter */
405 + ++states[counter].number;
414 + spin_unlock(&states[counter].lock);
418 + spin_unlock(&states[counter].lock);
423 +ip6t_nth_checkentry(const char *tablename,
424 + const struct ip6t_ip6 *e,
426 + unsigned int matchsize,
427 + unsigned int hook_mask)
429 + /* Parameters from userspace */
430 + const struct ip6t_nth_info *info = matchinfo;
431 + unsigned counter = info->counter;
432 + if((counter < 0) || (counter >= IP6T_NTH_NUM_COUNTERS))
434 + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1);
438 + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_nth_info))) {
439 + printk("nth: matchsize %u != %zu\n", matchsize,
440 + IP6T_ALIGN(sizeof(struct ip6t_nth_info)));
444 + states[counter].number = info->startat;
449 +static struct ip6t_match ip6t_nth_reg = {
451 + .match = ip6t_nth_match,
452 + .checkentry = ip6t_nth_checkentry,
456 +static int __init init(void)
459 + memset(&states, 0, sizeof(states));
460 + if (ip6t_register_match(&ip6t_nth_reg))
463 + for(counter = 0; counter < IP6T_NTH_NUM_COUNTERS; counter++)
465 + spin_lock_init(&(states[counter].lock));
468 + printk("ip6t_nth match loaded\n");
472 +static void __exit fini(void)
474 + ip6t_unregister_match(&ip6t_nth_reg);
475 + printk("ip6t_nth match unloaded\n");