Author: pluto Date: Thu Sep 15 08:03:36 2005 GMT Module: SOURCES Tag: LINUX_2_6 ---- Log message: - [base] fuzzy match.
---- Files affected: SOURCES: linux-2.6-nf-fuzzy.patch (NONE -> 1.1.2.1) (NEW) ---- Diffs: ================================================================ Index: SOURCES/linux-2.6-nf-fuzzy.patch diff -u /dev/null SOURCES/linux-2.6-nf-fuzzy.patch:1.1.2.1 --- /dev/null Thu Sep 15 10:03:36 2005 +++ SOURCES/linux-2.6-nf-fuzzy.patch Thu Sep 15 10:03:31 2005 @@ -0,0 +1,496 @@ + include/linux/netfilter_ipv4/ipt_fuzzy.h | 21 +++ + include/linux/netfilter_ipv6/ip6t_fuzzy.h | 21 +++ + net/ipv4/netfilter/Kconfig | 10 + + net/ipv4/netfilter/Makefile | 2 + net/ipv4/netfilter/ipt_fuzzy.c | 185 +++++++++++++++++++++++++++++ + net/ipv6/netfilter/Kconfig | 10 + + net/ipv6/netfilter/Makefile | 1 + net/ipv6/netfilter/ip6t_fuzzy.c | 188 ++++++++++++++++++++++++++++++ + 8 files changed, 438 insertions(+) + +diff -uNr linux-2.6.13.1/include.orig/linux/netfilter_ipv4/ipt_fuzzy.h linux-2.6.13.1/include/linux/netfilter_ipv4/ipt_fuzzy.h +--- linux-2.6.13.1/include.orig/linux/netfilter_ipv4/ipt_fuzzy.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.13.1/include/linux/netfilter_ipv4/ipt_fuzzy.h 2005-09-15 10:02:28.111719000 +0200 +@@ -0,0 +1,21 @@ ++#ifndef _IPT_FUZZY_H ++#define _IPT_FUZZY_H ++ ++#include <linux/param.h> ++#include <linux/types.h> ++ ++#define MAXFUZZYRATE 10000000 ++#define MINFUZZYRATE 3 ++ ++struct ipt_fuzzy_info { ++ u_int32_t minimum_rate; ++ u_int32_t maximum_rate; ++ u_int32_t packets_total; ++ u_int32_t bytes_total; ++ u_int32_t previous_time; ++ u_int32_t present_time; ++ u_int32_t mean_rate; ++ u_int8_t acceptance_rate; ++}; ++ ++#endif /*_IPT_FUZZY_H*/ +diff -uNr linux-2.6.13.1/include.orig/linux/netfilter_ipv6/ip6t_fuzzy.h linux-2.6.13.1/include/linux/netfilter_ipv6/ip6t_fuzzy.h +--- linux-2.6.13.1/include.orig/linux/netfilter_ipv6/ip6t_fuzzy.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.13.1/include/linux/netfilter_ipv6/ip6t_fuzzy.h 2005-09-15 10:02:28.115717250 +0200 +@@ -0,0 +1,21 @@ ++#ifndef _IP6T_FUZZY_H ++#define _IP6T_FUZZY_H ++ ++#include <linux/param.h> ++#include <linux/types.h> ++ ++#define MAXFUZZYRATE 10000000 ++#define MINFUZZYRATE 3 ++ ++struct ip6t_fuzzy_info { ++ u_int32_t minimum_rate; ++ u_int32_t maximum_rate; ++ u_int32_t packets_total; ++ u_int32_t bytes_total; ++ u_int32_t previous_time; ++ u_int32_t present_time; ++ u_int32_t mean_rate; ++ u_int8_t acceptance_rate; ++}; ++ ++#endif /*_IP6T_FUZZY_H*/ +diff -uNr linux-2.6.13.1/net.orig/ipv4/netfilter/ipt_fuzzy.c linux-2.6.13.1/net/ipv4/netfilter/ipt_fuzzy.c +--- linux-2.6.13.1/net.orig/ipv4/netfilter/ipt_fuzzy.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.13.1/net/ipv4/netfilter/ipt_fuzzy.c 2005-09-15 10:02:28.115717250 +0200 +@@ -0,0 +1,185 @@ ++/* ++ * This module implements a simple TSK FLC ++ * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims ++ * to limit , in an adaptive and flexible way , the packet rate crossing ++ * a given stream . It serves as an initial and very simple (but effective) ++ * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks. ++ * As a matter of fact , Fuzzy Logic can help us to insert any "behavior" ++ * into our code in a precise , adaptive and efficient manner. ++ * The goal is very similar to that of "limit" match , but using techniques of ++ * Fuzzy Control , that allow us to shape the transfer functions precisely , ++ * avoiding over and undershoots - and stuff like that . ++ * ++ * ++ * 2002-08-10 Hime Aguiar e Oliveira Jr. <[EMAIL PROTECTED]> : Initial version. ++ * 2002-08-17 : Changed to eliminate floating point operations . ++ * 2002-08-23 : Coding style changes . ++*/ ++ ++#include <linux/module.h> ++#include <linux/skbuff.h> ++#include <linux/ip.h> ++#include <linux/random.h> ++#include <net/tcp.h> ++#include <linux/spinlock.h> ++#include <linux/netfilter_ipv4/ip_tables.h> ++#include <linux/netfilter_ipv4/ipt_fuzzy.h> ++ ++/* ++ Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH ++ Expressed in percentage ++*/ ++ ++#define PAR_LOW 1/100 ++#define PAR_HIGH 1 ++ ++static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED ; ++ ++MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <[EMAIL PROTECTED]>"); ++MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module"); ++MODULE_LICENSE("GPL"); ++ ++static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi) ++{ ++ if (tx >= maxi) ++ return 100; ++ ++ if (tx <= mini) ++ return 0; ++ ++ return ( (100*(tx-mini)) / (maxi-mini) ); ++} ++ ++static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi) ++{ ++ if (tx <= mini) ++ return 100; ++ ++ if (tx >= maxi) ++ return 0; ++ ++ return ( (100*( maxi - tx )) / ( maxi - mini ) ); ++} ++ ++static int ++ipt_fuzzy_match(const struct sk_buff *pskb, ++ const struct net_device *in, ++ const struct net_device *out, ++ const void *matchinfo, ++ int offset, ++ int *hotdrop) ++{ ++ /* From userspace */ ++ ++ struct ipt_fuzzy_info *info = (struct ipt_fuzzy_info *) matchinfo; ++ ++ u_int8_t random_number; ++ unsigned long amount; ++ u_int8_t howhigh, howlow; ++ ++ ++ spin_lock_bh(&fuzzy_lock); /* Rise the lock */ ++ ++ info->bytes_total += pskb->len; ++ info->packets_total++; ++ ++ info->present_time = jiffies; ++ ++ if (info->present_time >= info->previous_time) ++ amount = info->present_time - info->previous_time; ++ else { ++ /* There was a transition : I choose to re-sample ++ and keep the old acceptance rate... ++ */ ++ ++ amount = 0; ++ info->previous_time = info->present_time; ++ info->bytes_total = info->packets_total = 0; ++ }; ++ ++ if (amount > HZ/10) /* More than 100 ms elapsed ... */ ++ { ++ ++ info->mean_rate = (u_int32_t) ((HZ*info->packets_total) \ ++ / amount ); ++ ++ info->previous_time = info->present_time; ++ info->bytes_total = info->packets_total = 0; ++ ++ howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate); ++ howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate); ++ ++ info->acceptance_rate = (u_int8_t) \ ++ (howhigh*PAR_LOW + PAR_HIGH*howlow); ++ ++ /* In fact , the above defuzzification would require a denominator ++ proportional to (howhigh+howlow) but , in this particular case , ++ that expression is constant . ++ An imediate consequence is that it isn't necessary to call ++ both mf_high and mf_low - but to keep things understandable , ++ I did so . */ ++ ++ } ++ ++ spin_unlock_bh(&fuzzy_lock); /* Release the lock */ ++ ++ ++ if ( info->acceptance_rate < 100 ) ++ { ++ get_random_bytes((void *)(&random_number), 1); ++ ++ /* If within the acceptance , it can pass => don't match */ ++ if (random_number <= (255 * info->acceptance_rate) / 100) ++ return 0; ++ else ++ return 1; /* It can't pass ( It matches ) */ ++ } ; ++ ++ return 0; /* acceptance_rate == 100 % => Everything passes ... */ ++ ++} ++ ++static int ++ipt_fuzzy_checkentry(const char *tablename, ++ const struct ipt_ip *e, ++ void *matchinfo, ++ unsigned int matchsize, ++ unsigned int hook_mask) ++{ ++ ++ const struct ipt_fuzzy_info *info = matchinfo; ++ ++ if (matchsize != IPT_ALIGN(sizeof(struct ipt_fuzzy_info))) { ++ printk("ipt_fuzzy: matchsize %u != %zu\n", matchsize, ++ IPT_ALIGN(sizeof(struct ipt_fuzzy_info))); ++ return 0; ++ } ++ ++ if ((info->minimum_rate < MINFUZZYRATE ) || (info->maximum_rate > MAXFUZZYRATE) ++ || (info->minimum_rate >= info->maximum_rate )) { ++ printk("ipt_fuzzy: BAD limits , please verify !!!\n"); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static struct ipt_match ipt_fuzzy_reg = { ++ .name = "fuzzy", ++ .match = ipt_fuzzy_match, ++ .checkentry = ipt_fuzzy_checkentry, ++ .me = THIS_MODULE ++}; ++ ++static int __init init(void) ++{ ++ return ipt_register_match(&ipt_fuzzy_reg); ++} ++ ++static void __exit fini(void) ++{ ++ ipt_unregister_match(&ipt_fuzzy_reg); ++} ++ ++module_init(init); ++module_exit(fini); +diff -uNr linux-2.6.13.1/net.orig/ipv4/netfilter/Kconfig linux-2.6.13.1/net/ipv4/netfilter/Kconfig +--- linux-2.6.13.1/net.orig/ipv4/netfilter/Kconfig 2005-09-10 04:42:58.000000000 +0200 ++++ linux-2.6.13.1/net/ipv4/netfilter/Kconfig 2005-09-15 10:02:28.123713750 +0200 +@@ -692,5 +692,15 @@ + Allows altering the ARP packet payload: source and destination + hardware and network addresses. + ++config IP_NF_MATCH_FUZZY ++ tristate 'fuzzy match support' ++ depends on IP_NF_IPTABLES ++ help ++ This option adds a `fuzzy' match, which allows you to match ++ packets according to a fuzzy logic based law. ++ ++ If you want to compile it as a module, say M here and read ++ Documentation/modules.txt. If unsure, say `N'. ++ + endmenu + +diff -uNr linux-2.6.13.1/net.orig/ipv4/netfilter/Makefile linux-2.6.13.1/net/ipv4/netfilter/Makefile +--- linux-2.6.13.1/net.orig/ipv4/netfilter/Makefile 2005-09-10 04:42:58.000000000 +0200 ++++ linux-2.6.13.1/net/ipv4/netfilter/Makefile 2005-09-15 10:02:28.127712000 +0200 +@@ -45,6 +45,8 @@ + obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o + obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o + obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o ++ ++obj-$(CONFIG_IP_NF_MATCH_FUZZY) += ipt_fuzzy.o + obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o + obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o + obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o +diff -uNr linux-2.6.13.1/net.orig/ipv6/netfilter/ip6t_fuzzy.c linux-2.6.13.1/net/ipv6/netfilter/ip6t_fuzzy.c +--- linux-2.6.13.1/net.orig/ipv6/netfilter/ip6t_fuzzy.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.13.1/net/ipv6/netfilter/ip6t_fuzzy.c 2005-09-15 10:02:28.119715500 +0200 +@@ -0,0 +1,188 @@ ++/* ++ * This module implements a simple TSK FLC ++ * (Takagi-Sugeno-Kang Fuzzy Logic Controller) that aims ++ * to limit , in an adaptive and flexible way , the packet rate crossing ++ * a given stream . It serves as an initial and very simple (but effective) ++ * example of how Fuzzy Logic techniques can be applied to defeat DoS attacks. ++ * As a matter of fact , Fuzzy Logic can help us to insert any "behavior" ++ * into our code in a precise , adaptive and efficient manner. ++ * The goal is very similar to that of "limit" match , but using techniques of ++ * Fuzzy Control , that allow us to shape the transfer functions precisely , ++ * avoiding over and undershoots - and stuff like that . ++ * ++ * ++ * 2002-08-10 Hime Aguiar e Oliveira Jr. <[EMAIL PROTECTED]> : Initial version. ++ * 2002-08-17 : Changed to eliminate floating point operations . ++ * 2002-08-23 : Coding style changes . ++ * 2003-04-08 Maciej Soltysiak <[EMAIL PROTECTED]> : IPv6 Port ++ */ ++ ++#include <linux/module.h> ++#include <linux/skbuff.h> ++#include <linux/ipv6.h> ++#include <linux/random.h> ++#include <net/tcp.h> ++#include <linux/spinlock.h> ++#include <linux/netfilter_ipv6/ip6_tables.h> ++#include <linux/netfilter_ipv6/ip6t_fuzzy.h> ++ ++/* ++ Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH ++ Expressed in percentage ++*/ ++ ++#define PAR_LOW 1/100 ++#define PAR_HIGH 1 ++ ++static spinlock_t fuzzy_lock = SPIN_LOCK_UNLOCKED; ++ ++MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <[EMAIL PROTECTED]>"); ++MODULE_DESCRIPTION("IP tables Fuzzy Logic Controller match module"); ++MODULE_LICENSE("GPL"); ++ ++static u_int8_t mf_high(u_int32_t tx,u_int32_t mini,u_int32_t maxi) ++{ ++ if (tx >= maxi) return 100; ++ ++ if (tx <= mini) return 0; ++ ++ return ((100 * (tx-mini)) / (maxi-mini)); ++} ++ ++static u_int8_t mf_low(u_int32_t tx,u_int32_t mini,u_int32_t maxi) ++{ ++ if (tx <= mini) return 100; ++ ++ if (tx >= maxi) return 0; ++ ++ return ((100 * (maxi - tx)) / (maxi - mini)); ++ ++} ++ ++static int ++ip6t_fuzzy_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) ++{ ++ /* From userspace */ ++ ++ struct ip6t_fuzzy_info *info = (struct ip6t_fuzzy_info *) matchinfo; ++ ++ u_int8_t random_number; ++ unsigned long amount; ++ u_int8_t howhigh, howlow; ++ ++ ++ spin_lock_bh(&fuzzy_lock); /* Rise the lock */ ++ ++ info->bytes_total += pskb->len; ++ info->packets_total++; ++ ++ info->present_time = jiffies; ++ ++ if (info->present_time >= info->previous_time) ++ amount = info->present_time - info->previous_time; ++ else { ++ /* There was a transition : I choose to re-sample ++ and keep the old acceptance rate... ++ */ ++ ++ amount = 0; ++ info->previous_time = info->present_time; ++ info->bytes_total = info->packets_total = 0; ++ }; ++ ++ if ( amount > HZ/10) {/* More than 100 ms elapsed ... */ ++ ++ info->mean_rate = (u_int32_t) ((HZ * info->packets_total) \ ++ / amount); ++ ++ info->previous_time = info->present_time; ++ info->bytes_total = info->packets_total = 0; ++ ++ howhigh = mf_high(info->mean_rate,info->minimum_rate,info->maximum_rate); ++ howlow = mf_low(info->mean_rate,info->minimum_rate,info->maximum_rate); ++ ++ info->acceptance_rate = (u_int8_t) \ ++ (howhigh * PAR_LOW + PAR_HIGH * howlow); ++ ++ /* In fact, the above defuzzification would require a denominator ++ * proportional to (howhigh+howlow) but, in this particular case, ++ * that expression is constant. ++ * An imediate consequence is that it is not necessary to call ++ * both mf_high and mf_low - but to keep things understandable, ++ * I did so. ++ */ ++ ++ } ++ ++ spin_unlock_bh(&fuzzy_lock); /* Release the lock */ ++ ++ ++ if (info->acceptance_rate < 100) ++ { ++ get_random_bytes((void *)(&random_number), 1); ++ ++ /* If within the acceptance , it can pass => don't match */ ++ if (random_number <= (255 * info->acceptance_rate) / 100) ++ return 0; ++ else ++ return 1; /* It can't pass (It matches) */ ++ }; ++ ++ return 0; /* acceptance_rate == 100 % => Everything passes ... */ ++ ++} ++ ++static int ++ip6t_fuzzy_checkentry(const char *tablename, ++ const struct ip6t_ip6 *ip, ++ void *matchinfo, ++ unsigned int matchsize, ++ unsigned int hook_mask) ++{ ++ ++ const struct ip6t_fuzzy_info *info = matchinfo; ++ ++ if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info))) { ++ printk("ip6t_fuzzy: matchsize %u != %zu\n", matchsize, ++ IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info))); ++ return 0; ++ } ++ ++ if ((info->minimum_rate < MINFUZZYRATE) || (info->maximum_rate > MAXFUZZYRATE) ++ || (info->minimum_rate >= info->maximum_rate)) { ++ printk("ip6t_fuzzy: BAD limits , please verify !!!\n"); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static struct ip6t_match ip6t_fuzzy_reg = { ++ {NULL, NULL}, ++ "fuzzy", ++ ip6t_fuzzy_match, ++ ip6t_fuzzy_checkentry, ++ NULL, ++ THIS_MODULE }; ++ ++static int __init init(void) ++{ ++ if (ip6t_register_match(&ip6t_fuzzy_reg)) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static void __exit fini(void) ++{ ++ ip6t_unregister_match(&ip6t_fuzzy_reg); ++} ++ ++module_init(init); ++module_exit(fini); +diff -uNr linux-2.6.13.1/net.orig/ipv6/netfilter/Kconfig linux-2.6.13.1/net/ipv6/netfilter/Kconfig +--- linux-2.6.13.1/net.orig/ipv6/netfilter/Kconfig 2005-09-10 04:42:58.000000000 +0200 ++++ linux-2.6.13.1/net/ipv6/netfilter/Kconfig 2005-09-15 10:02:28.131710250 +0200 +@@ -238,5 +238,15 @@ + If you want to compile it as a module, say M here and read + <file:Documentation/modules.txt>. If unsure, say `N'. + ++config IP6_NF_MATCH_FUZZY ++ tristate 'Fuzzy match support' ++ depends on IP6_NF_FILTER ++ help ++ This option adds a `fuzzy' match, which allows you to match ++ packets according to a fuzzy logic based law. ++ ++ If you want to compile it as a module, say M here and read ++ Documentation/modules.txt. If unsure, say `N'. ++ + endmenu + +diff -uNr linux-2.6.13.1/net.orig/ipv6/netfilter/Makefile linux-2.6.13.1/net/ipv6/netfilter/Makefile +--- linux-2.6.13.1/net.orig/ipv6/netfilter/Makefile 2005-09-10 04:42:58.000000000 +0200 ++++ linux-2.6.13.1/net/ipv6/netfilter/Makefile 2005-09-15 10:02:28.131710250 +0200 +@@ -0,0 +0,1 @@ ++obj-$(CONFIG_IP6_NF_MATCH_FUZZY) += ip6t_fuzzy.o ================================================================ _______________________________________________ pld-cvs-commit mailing list pld-cvs-commit@lists.pld-linux.org http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit