include/linux/netfilter_ipv4/ipt_random.h | 11 +++ include/linux/netfilter_ipv6/ip6t_random.h | 11 +++ net/ipv4/netfilter/Kconfig | 11 +++ net/ipv4/netfilter/Makefile | 1 net/ipv4/netfilter/ipt_random.c | 93 ++++++++++++++++++++++++++++ net/ipv6/netfilter/Kconfig | 11 +++ net/ipv6/netfilter/Makefile | 1 net/ipv6/netfilter/ip6t_random.c | 95 +++++++++++++++++++++++++++++ 8 files changed, 234 insertions(+) diff -Nur --exclude '*.orig' linux.org/include/linux/netfilter_ipv4/ipt_random.h linux/include/linux/netfilter_ipv4/ipt_random.h --- linux.org/include/linux/netfilter_ipv4/ipt_random.h 1970-01-01 01:00:00.000000000 +0100 +++ linux/include/linux/netfilter_ipv4/ipt_random.h 2006-05-04 10:25:13.000000000 +0200 @@ -0,0 +1,11 @@ +#ifndef _IPT_RAND_H +#define _IPT_RAND_H + +#include +#include + +struct ipt_rand_info { + u_int8_t average; +}; + +#endif /*_IPT_RAND_H*/ diff -Nur --exclude '*.orig' linux.org/include/linux/netfilter_ipv6/ip6t_random.h linux/include/linux/netfilter_ipv6/ip6t_random.h --- linux.org/include/linux/netfilter_ipv6/ip6t_random.h 1970-01-01 01:00:00.000000000 +0100 +++ linux/include/linux/netfilter_ipv6/ip6t_random.h 2006-05-04 10:25:13.000000000 +0200 @@ -0,0 +1,11 @@ +#ifndef _IP6T_RAND_H +#define _IP6T_RAND_H + +#include +#include + +struct ip6t_rand_info { + u_int8_t average; +}; + +#endif /*_IP6T_RAND_H*/ diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/Kconfig linux/net/ipv4/netfilter/Kconfig --- linux.org/net/ipv4/netfilter/Kconfig 2006-05-02 23:38:44.000000000 +0200 +++ linux/net/ipv4/netfilter/Kconfig 2006-05-04 10:25:13.000000000 +0200 @@ -606,5 +606,16 @@ Allows altering the ARP packet payload: source and destination hardware and network addresses. +config IP_NF_MATCH_RANDOM + tristate 'random match support' + depends on IP_NF_IPTABLES + help + This option adds a `random' match, + which allow you to match packets randomly + following a given probability. + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say `N'. + endmenu diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/Makefile linux/net/ipv4/netfilter/Makefile --- linux.org/net/ipv4/netfilter/Makefile 2006-05-02 23:38:44.000000000 +0200 +++ linux/net/ipv4/netfilter/Makefile 2006-05-04 10:25:13.000000000 +0200 @@ -0,0 +0,1 @@ +obj-$(CONFIG_IP_NF_MATCH_RANDOM) += ipt_random.o diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/ipt_random.c linux/net/ipv4/netfilter/ipt_random.c --- linux.org/net/ipv4/netfilter/ipt_random.c 1970-01-01 01:00:00.000000000 +0100 +++ linux/net/ipv4/netfilter/ipt_random.c 2006-05-04 10:25:13.000000000 +0200 @@ -0,0 +1,93 @@ +/* + This is a module which is used for a "random" match support. + This file is distributed under the terms of the GNU General Public + License (GPL). Copies of the GPL can be obtained from: + ftp://prep.ai.mit.edu/pub/gnu/GPL + + 2001-10-14 Fabrice MARIE : initial implementation. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +static int +ipt_rand_match(const struct sk_buff *pskb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + unsigned int protoff, + int *hotdrop) +{ + /* Parameters from userspace */ + const struct ipt_rand_info *info = matchinfo; + u_int8_t random_number; + + /* get 1 random number from the kernel random number generation routine */ + get_random_bytes((void *)(&random_number), 1); + + /* Do we match ? */ + if (random_number <= info->average) + return 1; + else + return 0; +} + +static int +ipt_rand_checkentry(const char *tablename, + const struct ipt_ip *e, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + /* Parameters from userspace */ + const struct ipt_rand_info *info = matchinfo; + + if (matchsize != IPT_ALIGN(sizeof(struct ipt_rand_info))) { + printk("ipt_random: matchsize %u != %Zd\n", matchsize, + IPT_ALIGN(sizeof(struct ipt_rand_info))); + return 0; + } + + /* must be 1 <= average % <= 99 */ + /* 1 x 2.55 = 2 */ + /* 99 x 2.55 = 252 */ + if ((info->average < 2) || (info->average > 252)) { + printk("ipt_random: invalid average %u\n", info->average); + return 0; + } + + return 1; +} + +static struct ipt_match ipt_rand_reg = { + .name = "random", + .match = ipt_rand_match, + .checkentry = ipt_rand_checkentry, + .me = THIS_MODULE }; + +static int __init init(void) +{ + if (ipt_register_match(&ipt_rand_reg)) + return -EINVAL; + + printk("ipt_random match loaded\n"); + return 0; +} + +static void __exit fini(void) +{ + ipt_unregister_match(&ipt_rand_reg); + printk("ipt_random match unloaded\n"); +} + +module_init(init); +module_exit(fini); diff -Nur --exclude '*.orig' linux.org/net/ipv6/netfilter/Kconfig linux/net/ipv6/netfilter/Kconfig --- linux.org/net/ipv6/netfilter/Kconfig 2006-05-02 23:38:44.000000000 +0200 +++ linux/net/ipv6/netfilter/Kconfig 2006-05-04 10:25:13.000000000 +0200 @@ -210,5 +210,16 @@ If you want to compile it as a module, say M here and read . If unsure, say `N'. +config IP6_NF_MATCH_RANDOM + tristate 'Random match support' + depends on IP6_NF_IPTABLES + help + This option adds a `random' match, + which allow you to match packets randomly + following a given probability. + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say `N'. + endmenu diff -Nur --exclude '*.orig' linux.org/net/ipv6/netfilter/Makefile linux/net/ipv6/netfilter/Makefile --- linux.org/net/ipv6/netfilter/Makefile 2006-05-02 23:38:44.000000000 +0200 +++ linux/net/ipv6/netfilter/Makefile 2006-05-04 10:25:13.000000000 +0200 @@ -0,0 +0,1 @@ +obj-$(CONFIG_IP6_NF_MATCH_RANDOM) += ip6t_random.o diff -Nur --exclude '*.orig' linux.org/net/ipv6/netfilter/ip6t_random.c linux/net/ipv6/netfilter/ip6t_random.c --- linux.org/net/ipv6/netfilter/ip6t_random.c 1970-01-01 01:00:00.000000000 +0100 +++ linux/net/ipv6/netfilter/ip6t_random.c 2006-05-04 10:25:13.000000000 +0200 @@ -0,0 +1,95 @@ +/* + This is a module which is used for a "random" match support. + This file is distributed under the terms of the GNU General Public + License (GPL). Copies of the GPL can be obtained from: + ftp://prep.ai.mit.edu/pub/gnu/GPL + + 2001-10-14 Fabrice MARIE : initial implementation. + 2003-04-30 Maciej Soltysiak : IPv6 Port +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +static int +ip6t_rand_match(const struct sk_buff *pskb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + unsigned int protoff, + int *hotdrop) +{ + /* Parameters from userspace */ + const struct ip6t_rand_info *info = matchinfo; + u_int8_t random_number; + + /* get 1 random number from the kernel random number generation routine */ + get_random_bytes((void *)(&random_number), 1); + + /* Do we match ? */ + if (random_number <= info->average) + return 1; + else + return 0; +} + +static int +ip6t_rand_checkentry(const char *tablename, + const struct ip6t_ip6 *e, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + /* Parameters from userspace */ + const struct ip6t_rand_info *info = matchinfo; + + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_rand_info))) { + printk("ip6t_random: matchsize %u != %Zd\n", matchsize, + IP6T_ALIGN(sizeof(struct ip6t_rand_info))); + return 0; + } + + /* must be 1 <= average % <= 99 */ + /* 1 x 2.55 = 2 */ + /* 99 x 2.55 = 252 */ + if ((info->average < 2) || (info->average > 252)) { + printk("ip6t_random: invalid average %u\n", info->average); + return 0; + } + + return 1; +} + +static struct ip6t_match ip6t_rand_reg = { + .name = "random", + .match = ip6t_rand_match, + .checkentry = ip6t_rand_checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + if (ip6t_register_match(&ip6t_rand_reg)) + return -EINVAL; + + printk("ip6t_random match loaded\n"); + return 0; +} + +static void __exit fini(void) +{ + ip6t_unregister_match(&ip6t_rand_reg); + printk("ip6t_random match unloaded\n"); +} + +module_init(init); +module_exit(fini);