diff -urN linux-2.4.20-orig/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.4.20/include/linux/netfilter_ipv4/ip_conntrack.h --- linux-2.4.20-orig/include/linux/netfilter_ipv4/ip_conntrack.h Fri Nov 29 00:53:15 2002 +++ linux-2.4.20/include/linux/netfilter_ipv4/ip_conntrack.h Mon Apr 21 05:07:03 2003 @@ -183,6 +183,9 @@ /* Storage reserved for other modules: */ + /* devik: store num of bytes transfered; counter uses saturated incr. */ + unsigned long bytes; + union ip_conntrack_proto proto; union ip_conntrack_help help; diff -urN linux-2.4.20-orig/include/linux/netfilter_ipv4/ipt_connbytes.h linux-2.4.20/include/linux/netfilter_ipv4/ipt_connbytes.h --- linux-2.4.20-orig/include/linux/netfilter_ipv4/ipt_connbytes.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.20/include/linux/netfilter_ipv4/ipt_connbytes.h Mon Apr 21 05:07:03 2003 @@ -0,0 +1,10 @@ +#ifndef _IPT_CONNBYTES_H +#define _IPT_CONNBYTES_H + +struct ipt_connbytes_info +{ + /* if from<=to then it matches the range; if from>to then + inverse range is matched */ + unsigned long from,to; +}; +#endif diff -urN linux-2.4.20-orig/net/ipv4/netfilter/Config.in linux-2.4.20/net/ipv4/netfilter/Config.in --- linux-2.4.20-orig/net/ipv4/netfilter/Config.in Fri Nov 29 00:53:15 2002 +++ linux-2.4.20/net/ipv4/netfilter/Config.in Mon Apr 21 05:07:03 2003 @@ -35,6 +35,7 @@ fi if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then dep_tristate ' Connection state match support' CONFIG_IP_NF_MATCH_STATE $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES + dep_tristate ' Connection byte counter support' CONFIG_IP_NF_MATCH_CONNBYTES $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES dep_tristate ' Connection tracking match support' CONFIG_IP_NF_MATCH_CONNTRACK $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then diff -urN linux-2.4.20-orig/net/ipv4/netfilter/Makefile linux-2.4.20/net/ipv4/netfilter/Makefile --- linux-2.4.20-orig/net/ipv4/netfilter/Makefile Fri Nov 29 00:53:15 2002 +++ linux-2.4.20/net/ipv4/netfilter/Makefile Mon Apr 21 05:07:03 2003 @@ -73,6 +73,7 @@ obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o +obj-$(CONFIG_IP_NF_MATCH_CONNBYTES) += ipt_connbytes.o obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o diff -urN linux-2.4.20-orig/net/ipv4/netfilter/ip_conntrack_core.c linux-2.4.20/net/ipv4/netfilter/ip_conntrack_core.c --- linux-2.4.20-orig/net/ipv4/netfilter/ip_conntrack_core.c Fri Nov 29 00:53:15 2002 +++ linux-2.4.20/net/ipv4/netfilter/ip_conntrack_core.c Mon Apr 21 05:07:03 2003 @@ -784,6 +784,13 @@ *set_reply = 0; } skb->nfct = &h->ctrack->infos[*ctinfo]; + + /* devik: increment bytes in connection here */ + if (h->ctrack->bytes + skb->len >= 0xffff0000) + h->ctrack->bytes = 0xffff0000; + else + h->ctrack->bytes += skb->len; + return h->ctrack; } diff -urN linux-2.4.20-orig/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.4.20/net/ipv4/netfilter/ip_conntrack_standalone.c --- linux-2.4.20-orig/net/ipv4/netfilter/ip_conntrack_standalone.c Fri Nov 29 00:53:15 2002 +++ linux-2.4.20/net/ipv4/netfilter/ip_conntrack_standalone.c Mon Apr 21 05:07:03 2003 @@ -104,6 +104,7 @@ len += sprintf(buffer + len, "[ASSURED] "); len += sprintf(buffer + len, "use=%u ", atomic_read(&conntrack->ct_general.use)); + len += sprintf(buffer + len, "bytes=%lu ",conntrack->bytes); /* devik */ len += sprintf(buffer + len, "\n"); return len; diff -urN linux-2.4.20-orig/net/ipv4/netfilter/ipt_connbytes.c linux-2.4.20/net/ipv4/netfilter/ipt_connbytes.c --- linux-2.4.20-orig/net/ipv4/netfilter/ipt_connbytes.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.20/net/ipv4/netfilter/ipt_connbytes.c Mon Apr 21 05:07:03 2003 @@ -0,0 +1,65 @@ +/* Kernel module to match connection tracking byte counter. + * GPL (C) 2002 Martin Devera (devik@cdi.cz). + */ +#include +#include +#include +#include +#include + +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + const void *hdr, + u_int16_t datalen, + int *hotdrop) +{ + const struct ipt_connbytes_info *sinfo = matchinfo; + enum ip_conntrack_info ctinfo; + struct ip_conntrack *ct; + + if (!(ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo))) + return 0; /* no match */ + + if (sinfo->from > sinfo->to) + return (ct->bytes < sinfo->to || ct->bytes > sinfo->from); + else + return (ct->bytes >= sinfo->from && ct->bytes <= sinfo->to); +} + +static int check(const char *tablename, + const struct ipt_ip *ip, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + if (matchsize != IPT_ALIGN(sizeof(struct ipt_connbytes_info))) + return 0; + + return 1; +} + +static struct ipt_match state_match += { { NULL, NULL }, "connbytes", &match, &check, NULL, THIS_MODULE }; + +static int __init init(void) +{ + /* NULL if ip_conntrack not a module */ + if (ip_conntrack_module) + __MOD_INC_USE_COUNT(ip_conntrack_module); + return ipt_register_match(&state_match); +} + +static void __exit fini(void) +{ + ipt_unregister_match(&state_match); + if (ip_conntrack_module) + __MOD_DEC_USE_COUNT(ip_conntrack_module); +} + +module_init(init); +module_exit(fini); +MODULE_LICENSE("GPL");