include/linux/netfilter_ipv4/ipt_quota.h | 12 +++ net/ipv4/netfilter/Kconfig | 10 +++ net/ipv4/netfilter/Makefile | 1 net/ipv4/netfilter/ipt_quota.c | 96 +++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+) diff -Nur --exclude '*.orig' linux.org/include/linux/netfilter_ipv4/ipt_quota.h linux/include/linux/netfilter_ipv4/ipt_quota.h --- linux.org/include/linux/netfilter_ipv4/ipt_quota.h 1970-01-01 01:00:00.000000000 +0100 +++ linux/include/linux/netfilter_ipv4/ipt_quota.h 2006-05-04 10:23:57.000000000 +0200 @@ -0,0 +1,12 @@ +#ifndef _IPT_QUOTA_H +#define _IPT_QUOTA_H + +/* print debug info in both kernel/netfilter module & iptable library */ +//#define DEBUG_IPT_QUOTA + +struct ipt_quota_info { + u_int64_t quota; + struct ipt_quota_info *master; +}; + +#endif /*_IPT_QUOTA_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:23:57.000000000 +0200 @@ -606,5 +606,15 @@ Allows altering the ARP packet payload: source and destination hardware and network addresses. +config IP_NF_MATCH_QUOTA + tristate 'quota match support' + depends on IP_NF_IPTABLES + help + This match implements network quotas. + + 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:23:57.000000000 +0200 @@ -0,0 +0,1 @@ +obj-$(CONFIG_IP_NF_MATCH_QUOTA) += ipt_quota.o diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/ipt_quota.c linux/net/ipv4/netfilter/ipt_quota.c --- linux.org/net/ipv4/netfilter/ipt_quota.c 1970-01-01 01:00:00.000000000 +0100 +++ linux/net/ipv4/netfilter/ipt_quota.c 2006-05-04 10:23:57.000000000 +0200 @@ -0,0 +1,96 @@ +/* + * netfilter module to enforce network quotas + * + * Sam Johnston + * + * 30/01/05: Fixed on SMP --Pablo Neira + */ +#include +#include +#include +#include + +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Sam Johnston "); + +static spinlock_t quota_lock = SPIN_LOCK_UNLOCKED; + +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, unsigned int protoff, int *hotdrop) +{ + struct ipt_quota_info *q = + ((struct ipt_quota_info *) matchinfo)->master; + + if (skb->len < sizeof(struct iphdr)) + return NF_ACCEPT; + + spin_lock_bh("a_lock); + + if (q->quota >= skb->len) { + /* we can afford this one */ + q->quota -= skb->len; + spin_unlock_bh("a_lock); + +#ifdef DEBUG_IPT_QUOTA + printk("IPT Quota OK: %llu datlen %d \n", q->quota, skb->len); +#endif + return 1; + } + + /* so we do not allow even small packets from now on */ + q->quota = 0; + +#ifdef DEBUG_IPT_QUOTA + printk("IPT Quota Failed: %llu datlen %d \n", q->quota, skb->len); +#endif + + spin_unlock_bh("a_lock); + return 0; +} + +static int +checkentry(const char *tablename, + const struct ipt_ip *ip, + void *matchinfo, unsigned int matchsize, unsigned int hook_mask) +{ + /* TODO: spinlocks? sanity checks? */ + struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo; + + if (matchsize != IPT_ALIGN(sizeof (struct ipt_quota_info))) + return 0; + + /* For SMP, we only want to use one set of counters. */ + q->master = q; + + return 1; +} + +static struct ipt_match quota_match = { + .name = "quota", + .match = match, + .checkentry = checkentry, + .me = THIS_MODULE +}; + +static int __init +init(void) +{ + return ipt_register_match("a_match); +} + +static void __exit +fini(void) +{ + ipt_unregister_match("a_match); +} + +module_init(init); +module_exit(fini); +