]>
Commit | Line | Data |
---|---|---|
e00b0090 | 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(+) | |
10 | ||
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 | |
14 | @@ -0,0 +1,19 @@ | |
15 | +#ifndef _IPT_NTH_H | |
16 | +#define _IPT_NTH_H | |
17 | + | |
18 | +#include <linux/param.h> | |
19 | +#include <linux/types.h> | |
20 | + | |
21 | +#ifndef IPT_NTH_NUM_COUNTERS | |
22 | +#define IPT_NTH_NUM_COUNTERS 16 | |
23 | +#endif | |
24 | + | |
25 | +struct ipt_nth_info { | |
26 | + u_int8_t every; | |
27 | + u_int8_t not; | |
28 | + u_int8_t startat; | |
29 | + u_int8_t counter; | |
30 | + u_int8_t packet; | |
31 | +}; | |
32 | + | |
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 | |
37 | @@ -0,0 +1,19 @@ | |
38 | +#ifndef _IP6T_NTH_H | |
39 | +#define _IP6T_NTH_H | |
40 | + | |
41 | +#include <linux/param.h> | |
42 | +#include <linux/types.h> | |
43 | + | |
44 | +#ifndef IP6T_NTH_NUM_COUNTERS | |
45 | +#define IP6T_NTH_NUM_COUNTERS 16 | |
46 | +#endif | |
47 | + | |
48 | +struct ip6t_nth_info { | |
49 | + u_int8_t every; | |
50 | + u_int8_t not; | |
51 | + u_int8_t startat; | |
52 | + u_int8_t counter; | |
53 | + u_int8_t packet; | |
54 | +}; | |
55 | + | |
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 | |
60 | @@ -606,5 +606,29 @@ | |
61 | Allows altering the ARP packet payload: source and destination | |
62 | hardware and network addresses. | |
63 | ||
64 | +config IP_NF_MATCH_NTH | |
65 | + tristate 'Nth match support' | |
66 | + depends on IP_NF_IPTABLES | |
67 | + help | |
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. | |
71 | + | |
72 | + [options] | |
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 | |
78 | + and Nth-1. | |
79 | + | |
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 | |
83 | + Nth-1 inclusively. | |
84 | + | |
85 | + If you want to compile it as a module, say M here and read | |
86 | + Documentation/modules.txt. If unsure, say `N'. | |
87 | + | |
88 | endmenu | |
89 | ||
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 | |
93 | @@ -0,0 +0,1 @@ | |
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 | |
98 | @@ -0,0 +1,166 @@ | |
99 | +/* | |
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 | |
104 | + | |
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> | |
111 | + * port to 2.6.x | |
112 | + | |
113 | +*/ | |
114 | + | |
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> | |
122 | + | |
123 | +MODULE_LICENSE("GPL"); | |
124 | +MODULE_AUTHOR("Fabrice Marie <fabrice@netfilter.org>"); | |
125 | + | |
126 | +/* | |
127 | + * State information. | |
128 | + */ | |
129 | +struct state { | |
130 | + spinlock_t lock; | |
131 | + u_int16_t number; | |
132 | +}; | |
133 | + | |
134 | +static struct state states[IPT_NTH_NUM_COUNTERS]; | |
135 | + | |
136 | +static int | |
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, | |
141 | + int offset, | |
142 | + unsigned int protoff, | |
143 | + int *hotdrop) | |
144 | +{ | |
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)) | |
149 | + { | |
150 | + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1); | |
151 | + return 0; | |
152 | + }; | |
153 | + | |
154 | + spin_lock(&states[counter].lock); | |
155 | + | |
156 | + /* Are we matching every nth packet?*/ | |
157 | + if (info->packet == 0xFF) | |
158 | + { | |
159 | + /* We're matching every nth packet and only every nth packet*/ | |
160 | + /* Do we match or invert match? */ | |
161 | + if (info->not == 0) | |
162 | + { | |
163 | + if (states[counter].number == 0) | |
164 | + { | |
165 | + ++states[counter].number; | |
166 | + goto match; | |
167 | + } | |
168 | + if (states[counter].number >= info->every) | |
169 | + states[counter].number = 0; /* reset the counter */ | |
170 | + else | |
171 | + ++states[counter].number; | |
172 | + goto dontmatch; | |
173 | + } | |
174 | + else | |
175 | + { | |
176 | + if (states[counter].number == 0) | |
177 | + { | |
178 | + ++states[counter].number; | |
179 | + goto dontmatch; | |
180 | + } | |
181 | + if (states[counter].number >= info->every) | |
182 | + states[counter].number = 0; | |
183 | + else | |
184 | + ++states[counter].number; | |
185 | + goto match; | |
186 | + } | |
187 | + } | |
188 | + else | |
189 | + { | |
190 | + /* We're using the --packet, so there must be a rule for every value */ | |
191 | + if (states[counter].number == info->packet) | |
192 | + { | |
193 | + /* only increment the counter when a match happens */ | |
194 | + if (states[counter].number >= info->every) | |
195 | + states[counter].number = 0; /* reset the counter */ | |
196 | + else | |
197 | + ++states[counter].number; | |
198 | + goto match; | |
199 | + } | |
200 | + else | |
201 | + goto dontmatch; | |
202 | + } | |
203 | + | |
204 | + dontmatch: | |
205 | + /* don't match */ | |
206 | + spin_unlock(&states[counter].lock); | |
207 | + return 0; | |
208 | + | |
209 | + match: | |
210 | + spin_unlock(&states[counter].lock); | |
211 | + return 1; | |
212 | +} | |
213 | + | |
214 | +static int | |
215 | +ipt_nth_checkentry(const char *tablename, | |
216 | + const struct ipt_ip *e, | |
217 | + void *matchinfo, | |
218 | + unsigned int matchsize, | |
219 | + unsigned int hook_mask) | |
220 | +{ | |
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)) | |
225 | + { | |
226 | + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IPT_NTH_NUM_COUNTERS-1); | |
227 | + return 0; | |
228 | + }; | |
229 | + | |
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))); | |
233 | + return 0; | |
234 | + } | |
235 | + | |
236 | + states[counter].number = info->startat; | |
237 | + | |
238 | + return 1; | |
239 | +} | |
240 | + | |
241 | +static struct ipt_match ipt_nth_reg = { | |
242 | + .name = "nth", | |
243 | + .match = ipt_nth_match, | |
244 | + .checkentry = ipt_nth_checkentry, | |
245 | + .me = THIS_MODULE | |
246 | +}; | |
247 | + | |
248 | +static int __init init(void) | |
249 | +{ | |
250 | + unsigned counter; | |
251 | + | |
252 | + memset(&states, 0, sizeof(states)); | |
253 | + for (counter = 0; counter < IPT_NTH_NUM_COUNTERS; counter++) | |
254 | + spin_lock_init(&(states[counter].lock)); | |
255 | + | |
256 | + return ipt_register_match(&ipt_nth_reg); | |
257 | +} | |
258 | + | |
259 | +static void __exit fini(void) | |
260 | +{ | |
261 | + ipt_unregister_match(&ipt_nth_reg); | |
262 | +} | |
263 | + | |
264 | +module_init(init); | |
265 | +module_exit(fini); | |
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 | |
269 | @@ -210,5 +210,29 @@ | |
270 | If you want to compile it as a module, say M here and read | |
271 | <file:Documentation/modules.txt>. If unsure, say `N'. | |
272 | ||
273 | +config IP6_NF_MATCH_NTH | |
274 | + tristate 'Nth match support' | |
275 | + depends on IP6_NF_IPTABLES | |
276 | + help | |
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. | |
280 | + | |
281 | + [options] | |
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 | |
287 | + and Nth-1. | |
288 | + | |
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 | |
292 | + Nth-1 inclusively. | |
293 | + | |
294 | + If you want to compile it as a module, say M here and read | |
295 | + Documentation/modules.txt. If unsure, say `N'. | |
296 | + | |
297 | endmenu | |
298 | ||
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 | |
302 | @@ -0,0 +0,1 @@ | |
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 | |
307 | @@ -0,0 +1,172 @@ | |
308 | +/* | |
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 | |
313 | + | |
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 | |
321 | + | |
322 | +*/ | |
323 | + | |
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> | |
331 | + | |
332 | +MODULE_LICENSE("GPL"); | |
333 | + | |
334 | +/* | |
335 | + * State information. | |
336 | + */ | |
337 | +struct state { | |
338 | + spinlock_t lock; | |
339 | + u_int16_t number; | |
340 | +}; | |
341 | + | |
342 | +static struct state states[IP6T_NTH_NUM_COUNTERS]; | |
343 | + | |
344 | +static int | |
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, | |
349 | + int offset, | |
350 | + unsigned int protoff, | |
351 | + int *hotdrop) | |
352 | +{ | |
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)) | |
357 | + { | |
358 | + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1); | |
359 | + return 0; | |
360 | + }; | |
361 | + | |
362 | + spin_lock(&states[counter].lock); | |
363 | + | |
364 | + /* Are we matching every nth packet?*/ | |
365 | + if (info->packet == 0xFF) | |
366 | + { | |
367 | + /* We're matching every nth packet and only every nth packet*/ | |
368 | + /* Do we match or invert match? */ | |
369 | + if (info->not == 0) | |
370 | + { | |
371 | + if (states[counter].number == 0) | |
372 | + { | |
373 | + ++states[counter].number; | |
374 | + goto match; | |
375 | + } | |
376 | + if (states[counter].number >= info->every) | |
377 | + states[counter].number = 0; /* reset the counter */ | |
378 | + else | |
379 | + ++states[counter].number; | |
380 | + goto dontmatch; | |
381 | + } | |
382 | + else | |
383 | + { | |
384 | + if (states[counter].number == 0) | |
385 | + { | |
386 | + ++states[counter].number; | |
387 | + goto dontmatch; | |
388 | + } | |
389 | + if (states[counter].number >= info->every) | |
390 | + states[counter].number = 0; | |
391 | + else | |
392 | + ++states[counter].number; | |
393 | + goto match; | |
394 | + } | |
395 | + } | |
396 | + else | |
397 | + { | |
398 | + /* We're using the --packet, so there must be a rule for every value */ | |
399 | + if (states[counter].number == info->packet) | |
400 | + { | |
401 | + /* only increment the counter when a match happens */ | |
402 | + if (states[counter].number >= info->every) | |
403 | + states[counter].number = 0; /* reset the counter */ | |
404 | + else | |
405 | + ++states[counter].number; | |
406 | + goto match; | |
407 | + } | |
408 | + else | |
409 | + goto dontmatch; | |
410 | + } | |
411 | + | |
412 | + dontmatch: | |
413 | + /* don't match */ | |
414 | + spin_unlock(&states[counter].lock); | |
415 | + return 0; | |
416 | + | |
417 | + match: | |
418 | + spin_unlock(&states[counter].lock); | |
419 | + return 1; | |
420 | +} | |
421 | + | |
422 | +static int | |
423 | +ip6t_nth_checkentry(const char *tablename, | |
424 | + const struct ip6t_ip6 *e, | |
425 | + void *matchinfo, | |
426 | + unsigned int matchsize, | |
427 | + unsigned int hook_mask) | |
428 | +{ | |
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)) | |
433 | + { | |
434 | + printk(KERN_WARNING "nth: invalid counter %u. counter between 0 and %u\n", counter, IP6T_NTH_NUM_COUNTERS-1); | |
435 | + return 0; | |
436 | + }; | |
437 | + | |
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))); | |
441 | + return 0; | |
442 | + } | |
443 | + | |
444 | + states[counter].number = info->startat; | |
445 | + | |
446 | + return 1; | |
447 | +} | |
448 | + | |
449 | +static struct ip6t_match ip6t_nth_reg = { | |
450 | + .name = "nth", | |
451 | + .match = ip6t_nth_match, | |
452 | + .checkentry = ip6t_nth_checkentry, | |
453 | + .me = THIS_MODULE, | |
454 | +}; | |
455 | + | |
456 | +static int __init init(void) | |
457 | +{ | |
458 | + unsigned counter; | |
459 | + memset(&states, 0, sizeof(states)); | |
460 | + if (ip6t_register_match(&ip6t_nth_reg)) | |
461 | + return -EINVAL; | |
462 | + | |
463 | + for(counter = 0; counter < IP6T_NTH_NUM_COUNTERS; counter++) | |
464 | + { | |
465 | + spin_lock_init(&(states[counter].lock)); | |
466 | + }; | |
467 | + | |
468 | + printk("ip6t_nth match loaded\n"); | |
469 | + return 0; | |
470 | +} | |
471 | + | |
472 | +static void __exit fini(void) | |
473 | +{ | |
474 | + ip6t_unregister_match(&ip6t_nth_reg); | |
475 | + printk("ip6t_nth match unloaded\n"); | |
476 | +} | |
477 | + | |
478 | +module_init(init); | |
479 | +module_exit(fini); |