]>
Commit | Line | Data |
---|---|---|
c6410bf7 | 1 | include/linux/netfilter_ipv4/ipt_quota.h | 12 +++ |
2 | net/ipv4/netfilter/Kconfig | 10 +++ | |
3 | net/ipv4/netfilter/Makefile | 1 | |
4 | net/ipv4/netfilter/ipt_quota.c | 96 +++++++++++++++++++++++++++++++ | |
5 | 4 files changed, 119 insertions(+) | |
6 | ||
7 | diff -Nur --exclude '*.orig' linux.org/include/linux/netfilter_ipv4/ipt_quota.h linux/include/linux/netfilter_ipv4/ipt_quota.h | |
8 | --- linux.org/include/linux/netfilter_ipv4/ipt_quota.h 1970-01-01 01:00:00.000000000 +0100 | |
9 | +++ linux/include/linux/netfilter_ipv4/ipt_quota.h 2006-05-04 10:23:57.000000000 +0200 | |
10 | @@ -0,0 +1,12 @@ | |
11 | +#ifndef _IPT_QUOTA_H | |
12 | +#define _IPT_QUOTA_H | |
13 | + | |
14 | +/* print debug info in both kernel/netfilter module & iptable library */ | |
15 | +//#define DEBUG_IPT_QUOTA | |
16 | + | |
17 | +struct ipt_quota_info { | |
18 | + u_int64_t quota; | |
19 | + struct ipt_quota_info *master; | |
20 | +}; | |
21 | + | |
22 | +#endif /*_IPT_QUOTA_H*/ | |
23 | diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/Kconfig linux/net/ipv4/netfilter/Kconfig | |
24 | --- linux.org/net/ipv4/netfilter/Kconfig 2006-05-02 23:38:44.000000000 +0200 | |
25 | +++ linux/net/ipv4/netfilter/Kconfig 2006-05-04 10:23:57.000000000 +0200 | |
26 | @@ -606,5 +606,15 @@ | |
27 | Allows altering the ARP packet payload: source and destination | |
28 | hardware and network addresses. | |
29 | ||
30 | +config IP_NF_MATCH_QUOTA | |
31 | + tristate 'quota match support' | |
32 | + depends on IP_NF_IPTABLES | |
33 | + help | |
34 | + This match implements network quotas. | |
35 | + | |
36 | + If you want to compile it as a module, say M here and read | |
37 | + Documentation/modules.txt. If unsure, say `N'. | |
38 | + | |
39 | + | |
40 | endmenu | |
41 | ||
42 | diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/Makefile linux/net/ipv4/netfilter/Makefile | |
43 | --- linux.org/net/ipv4/netfilter/Makefile 2006-05-02 23:38:44.000000000 +0200 | |
44 | +++ linux/net/ipv4/netfilter/Makefile 2006-05-04 10:23:57.000000000 +0200 | |
45 | @@ -0,0 +0,1 @@ | |
46 | +obj-$(CONFIG_IP_NF_MATCH_QUOTA) += ipt_quota.o | |
47 | diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/ipt_quota.c linux/net/ipv4/netfilter/ipt_quota.c | |
48 | --- linux.org/net/ipv4/netfilter/ipt_quota.c 1970-01-01 01:00:00.000000000 +0100 | |
49 | +++ linux/net/ipv4/netfilter/ipt_quota.c 2006-05-04 10:23:57.000000000 +0200 | |
50 | @@ -0,0 +1,96 @@ | |
51 | +/* | |
52 | + * netfilter module to enforce network quotas | |
53 | + * | |
54 | + * Sam Johnston <samj@samj.net> | |
55 | + * | |
56 | + * 30/01/05: Fixed on SMP --Pablo Neira <pablo@eurodev.net> | |
57 | + */ | |
58 | +#include <linux/module.h> | |
59 | +#include <linux/skbuff.h> | |
60 | +#include <linux/spinlock.h> | |
61 | +#include <linux/interrupt.h> | |
62 | + | |
63 | +#include <linux/netfilter_ipv4/ip_tables.h> | |
64 | +#include <linux/netfilter_ipv4/ipt_quota.h> | |
65 | + | |
66 | +MODULE_LICENSE("GPL"); | |
67 | +MODULE_AUTHOR("Sam Johnston <samj@samj.net>"); | |
68 | + | |
69 | +static spinlock_t quota_lock = SPIN_LOCK_UNLOCKED; | |
70 | + | |
71 | +static int | |
72 | +match(const struct sk_buff *skb, | |
73 | + const struct net_device *in, | |
74 | + const struct net_device *out, | |
75 | + const void *matchinfo, | |
76 | + int offset, unsigned int protoff, int *hotdrop) | |
77 | +{ | |
78 | + struct ipt_quota_info *q = | |
79 | + ((struct ipt_quota_info *) matchinfo)->master; | |
80 | + | |
81 | + if (skb->len < sizeof(struct iphdr)) | |
82 | + return NF_ACCEPT; | |
83 | + | |
84 | + spin_lock_bh("a_lock); | |
85 | + | |
86 | + if (q->quota >= skb->len) { | |
87 | + /* we can afford this one */ | |
88 | + q->quota -= skb->len; | |
89 | + spin_unlock_bh("a_lock); | |
90 | + | |
91 | +#ifdef DEBUG_IPT_QUOTA | |
92 | + printk("IPT Quota OK: %llu datlen %d \n", q->quota, skb->len); | |
93 | +#endif | |
94 | + return 1; | |
95 | + } | |
96 | + | |
97 | + /* so we do not allow even small packets from now on */ | |
98 | + q->quota = 0; | |
99 | + | |
100 | +#ifdef DEBUG_IPT_QUOTA | |
101 | + printk("IPT Quota Failed: %llu datlen %d \n", q->quota, skb->len); | |
102 | +#endif | |
103 | + | |
104 | + spin_unlock_bh("a_lock); | |
105 | + return 0; | |
106 | +} | |
107 | + | |
108 | +static int | |
109 | +checkentry(const char *tablename, | |
110 | + const struct ipt_ip *ip, | |
111 | + void *matchinfo, unsigned int matchsize, unsigned int hook_mask) | |
112 | +{ | |
113 | + /* TODO: spinlocks? sanity checks? */ | |
114 | + struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo; | |
115 | + | |
116 | + if (matchsize != IPT_ALIGN(sizeof (struct ipt_quota_info))) | |
117 | + return 0; | |
118 | + | |
119 | + /* For SMP, we only want to use one set of counters. */ | |
120 | + q->master = q; | |
121 | + | |
122 | + return 1; | |
123 | +} | |
124 | + | |
125 | +static struct ipt_match quota_match = { | |
126 | + .name = "quota", | |
127 | + .match = match, | |
128 | + .checkentry = checkentry, | |
129 | + .me = THIS_MODULE | |
130 | +}; | |
131 | + | |
132 | +static int __init | |
133 | +init(void) | |
134 | +{ | |
135 | + return ipt_register_match("a_match); | |
136 | +} | |
137 | + | |
138 | +static void __exit | |
139 | +fini(void) | |
140 | +{ | |
141 | + ipt_unregister_match("a_match); | |
142 | +} | |
143 | + | |
144 | +module_init(init); | |
145 | +module_exit(fini); | |
146 | + |