netfilter: xtables: move extension arguments into compound structure (1/6)
[deliverable/linux.git] / net / netfilter / xt_connbytes.c
CommitLineData
9d810fd2
HW
1/* Kernel module to match connection tracking byte counter.
2 * GPL (C) 2002 Martin Devera (devik@cdi.cz).
9d810fd2
HW
3 */
4#include <linux/module.h>
1977f032 5#include <linux/bitops.h>
9d810fd2 6#include <linux/skbuff.h>
6f6d6a1a 7#include <linux/math64.h>
2e4e6a17
HW
8#include <linux/netfilter/x_tables.h>
9#include <linux/netfilter/xt_connbytes.h>
587aa641 10#include <net/netfilter/nf_conntrack.h>
58401572 11#include <net/netfilter/nf_conntrack_acct.h>
9d810fd2 12
9d810fd2
HW
13MODULE_LICENSE("GPL");
14MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
2ae15b64 15MODULE_DESCRIPTION("Xtables: Number of packets/bytes per connection matching");
2e4e6a17 16MODULE_ALIAS("ipt_connbytes");
73aaf935 17MODULE_ALIAS("ip6t_connbytes");
9d810fd2 18
1d93a9cb 19static bool
f7108a20 20connbytes_mt(const struct sk_buff *skb, const struct xt_match_param *par)
9d810fd2 21{
f7108a20 22 const struct xt_connbytes_info *sinfo = par->matchinfo;
a47362a2 23 const struct nf_conn *ct;
587aa641 24 enum ip_conntrack_info ctinfo;
9d810fd2 25 u_int64_t what = 0; /* initialize to make gcc happy */
fb74a841
PM
26 u_int64_t bytes = 0;
27 u_int64_t pkts = 0;
58401572 28 const struct nf_conn_counter *counters;
9d810fd2 29
587aa641
PM
30 ct = nf_ct_get(skb, &ctinfo);
31 if (!ct)
1d93a9cb 32 return false;
58401572
KPO
33
34 counters = nf_conn_acct_find(ct);
35 if (!counters)
36 return false;
9d810fd2
HW
37
38 switch (sinfo->what) {
2e4e6a17 39 case XT_CONNBYTES_PKTS:
9d810fd2 40 switch (sinfo->direction) {
2e4e6a17 41 case XT_CONNBYTES_DIR_ORIGINAL:
9fb9cbb1 42 what = counters[IP_CT_DIR_ORIGINAL].packets;
9d810fd2 43 break;
2e4e6a17 44 case XT_CONNBYTES_DIR_REPLY:
9fb9cbb1 45 what = counters[IP_CT_DIR_REPLY].packets;
9d810fd2 46 break;
2e4e6a17 47 case XT_CONNBYTES_DIR_BOTH:
9fb9cbb1
YK
48 what = counters[IP_CT_DIR_ORIGINAL].packets;
49 what += counters[IP_CT_DIR_REPLY].packets;
9d810fd2
HW
50 break;
51 }
52 break;
2e4e6a17 53 case XT_CONNBYTES_BYTES:
9d810fd2 54 switch (sinfo->direction) {
2e4e6a17 55 case XT_CONNBYTES_DIR_ORIGINAL:
9fb9cbb1 56 what = counters[IP_CT_DIR_ORIGINAL].bytes;
9d810fd2 57 break;
2e4e6a17 58 case XT_CONNBYTES_DIR_REPLY:
9fb9cbb1 59 what = counters[IP_CT_DIR_REPLY].bytes;
9d810fd2 60 break;
2e4e6a17 61 case XT_CONNBYTES_DIR_BOTH:
9fb9cbb1
YK
62 what = counters[IP_CT_DIR_ORIGINAL].bytes;
63 what += counters[IP_CT_DIR_REPLY].bytes;
9d810fd2
HW
64 break;
65 }
66 break;
2e4e6a17 67 case XT_CONNBYTES_AVGPKT:
9d810fd2 68 switch (sinfo->direction) {
2e4e6a17 69 case XT_CONNBYTES_DIR_ORIGINAL:
fb74a841
PM
70 bytes = counters[IP_CT_DIR_ORIGINAL].bytes;
71 pkts = counters[IP_CT_DIR_ORIGINAL].packets;
9d810fd2 72 break;
2e4e6a17 73 case XT_CONNBYTES_DIR_REPLY:
fb74a841
PM
74 bytes = counters[IP_CT_DIR_REPLY].bytes;
75 pkts = counters[IP_CT_DIR_REPLY].packets;
9d810fd2 76 break;
2e4e6a17 77 case XT_CONNBYTES_DIR_BOTH:
fb74a841
PM
78 bytes = counters[IP_CT_DIR_ORIGINAL].bytes +
79 counters[IP_CT_DIR_REPLY].bytes;
80 pkts = counters[IP_CT_DIR_ORIGINAL].packets +
81 counters[IP_CT_DIR_REPLY].packets;
9d810fd2
HW
82 break;
83 }
fb74a841 84 if (pkts != 0)
6f6d6a1a 85 what = div64_u64(bytes, pkts);
9d810fd2
HW
86 break;
87 }
88
89 if (sinfo->count.to)
7c4e36bc 90 return what <= sinfo->count.to && what >= sinfo->count.from;
9d810fd2 91 else
7c4e36bc 92 return what >= sinfo->count.from;
9d810fd2
HW
93}
94
d3c5ee6d
JE
95static bool
96connbytes_mt_check(const char *tablename, const void *ip,
97 const struct xt_match *match, void *matchinfo,
98 unsigned int hook_mask)
9d810fd2 99{
2e4e6a17 100 const struct xt_connbytes_info *sinfo = matchinfo;
9d810fd2 101
2e4e6a17
HW
102 if (sinfo->what != XT_CONNBYTES_PKTS &&
103 sinfo->what != XT_CONNBYTES_BYTES &&
104 sinfo->what != XT_CONNBYTES_AVGPKT)
ccb79bdc 105 return false;
9d810fd2 106
2e4e6a17
HW
107 if (sinfo->direction != XT_CONNBYTES_DIR_ORIGINAL &&
108 sinfo->direction != XT_CONNBYTES_DIR_REPLY &&
109 sinfo->direction != XT_CONNBYTES_DIR_BOTH)
ccb79bdc 110 return false;
9d810fd2 111
11078c37
YK
112 if (nf_ct_l3proto_try_module_get(match->family) < 0) {
113 printk(KERN_WARNING "can't load conntrack support for "
df54aae0 114 "proto=%u\n", match->family);
ccb79bdc 115 return false;
11078c37
YK
116 }
117
ccb79bdc 118 return true;
9d810fd2
HW
119}
120
11078c37 121static void
d3c5ee6d 122connbytes_mt_destroy(const struct xt_match *match, void *matchinfo)
11078c37
YK
123{
124 nf_ct_l3proto_module_put(match->family);
125}
126
d3c5ee6d 127static struct xt_match connbytes_mt_reg[] __read_mostly = {
4470bbc7
PM
128 {
129 .name = "connbytes",
ee999d8b 130 .family = NFPROTO_IPV4,
d3c5ee6d
JE
131 .checkentry = connbytes_mt_check,
132 .match = connbytes_mt,
133 .destroy = connbytes_mt_destroy,
4470bbc7
PM
134 .matchsize = sizeof(struct xt_connbytes_info),
135 .me = THIS_MODULE
136 },
137 {
138 .name = "connbytes",
ee999d8b 139 .family = NFPROTO_IPV6,
d3c5ee6d
JE
140 .checkentry = connbytes_mt_check,
141 .match = connbytes_mt,
142 .destroy = connbytes_mt_destroy,
4470bbc7
PM
143 .matchsize = sizeof(struct xt_connbytes_info),
144 .me = THIS_MODULE
145 },
9d810fd2
HW
146};
147
d3c5ee6d 148static int __init connbytes_mt_init(void)
9d810fd2 149{
d3c5ee6d
JE
150 return xt_register_matches(connbytes_mt_reg,
151 ARRAY_SIZE(connbytes_mt_reg));
9d810fd2
HW
152}
153
d3c5ee6d 154static void __exit connbytes_mt_exit(void)
9d810fd2 155{
d3c5ee6d 156 xt_unregister_matches(connbytes_mt_reg, ARRAY_SIZE(connbytes_mt_reg));
9d810fd2
HW
157}
158
d3c5ee6d
JE
159module_init(connbytes_mt_init);
160module_exit(connbytes_mt_exit);
This page took 0.44834 seconds and 5 git commands to generate.