Blame view
net/netfilter/nf_conntrack_amanda.c
5.92 KB
169589005 [NETFILTER]: nf_c... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* Amanda extension for IP connection tracking * * (C) 2002 by Brian J. Murrell <netfilter@interlinx.bc.ca> * based on HW's ip_conntrack_irc.c as well as other modules * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/textsearch.h> #include <linux/skbuff.h> #include <linux/in.h> #include <linux/udp.h> |
1863f0965 [NETFILTER]: nf_c... |
18 |
#include <linux/netfilter.h> |
5a0e3ad6a include cleanup: ... |
19 |
#include <linux/gfp.h> |
169589005 [NETFILTER]: nf_c... |
20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#include <net/netfilter/nf_conntrack.h> #include <net/netfilter/nf_conntrack_expect.h> #include <net/netfilter/nf_conntrack_ecache.h> #include <net/netfilter/nf_conntrack_helper.h> #include <linux/netfilter/nf_conntrack_amanda.h> static unsigned int master_timeout __read_mostly = 300; static char *ts_algo = "kmp"; MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>"); MODULE_DESCRIPTION("Amanda connection tracking module"); MODULE_LICENSE("GPL"); MODULE_ALIAS("ip_conntrack_amanda"); |
4dc06f963 netfilter: nf_con... |
34 |
MODULE_ALIAS_NFCT_HELPER("amanda"); |
169589005 [NETFILTER]: nf_c... |
35 36 37 38 39 |
module_param(master_timeout, uint, 0600); MODULE_PARM_DESC(master_timeout, "timeout for the master connection"); module_param(ts_algo, charp, 0400); MODULE_PARM_DESC(ts_algo, "textsearch algorithm to use (default kmp)"); |
3db05fea5 [NETFILTER]: Repl... |
40 |
unsigned int (*nf_nat_amanda_hook)(struct sk_buff *skb, |
169589005 [NETFILTER]: nf_c... |
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
enum ip_conntrack_info ctinfo, unsigned int matchoff, unsigned int matchlen, struct nf_conntrack_expect *exp) __read_mostly; EXPORT_SYMBOL_GPL(nf_nat_amanda_hook); enum amanda_strings { SEARCH_CONNECT, SEARCH_NEWLINE, SEARCH_DATA, SEARCH_MESG, SEARCH_INDEX, }; static struct { |
58c0fb0dd [NETFILTER]: anno... |
57 |
const char *string; |
169589005 [NETFILTER]: nf_c... |
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
size_t len; struct ts_config *ts; } search[] __read_mostly = { [SEARCH_CONNECT] = { .string = "CONNECT ", .len = 8, }, [SEARCH_NEWLINE] = { .string = " ", .len = 1, }, [SEARCH_DATA] = { .string = "DATA ", .len = 5, }, [SEARCH_MESG] = { .string = "MESG ", .len = 5, }, [SEARCH_INDEX] = { .string = "INDEX ", .len = 6, }, }; |
3db05fea5 [NETFILTER]: Repl... |
83 |
static int amanda_help(struct sk_buff *skb, |
169589005 [NETFILTER]: nf_c... |
84 85 86 87 88 89 90 91 92 93 94 |
unsigned int protoff, struct nf_conn *ct, enum ip_conntrack_info ctinfo) { struct ts_state ts; struct nf_conntrack_expect *exp; struct nf_conntrack_tuple *tuple; unsigned int dataoff, start, stop, off, i; char pbuf[sizeof("65535")], *tmp; u_int16_t len; __be16 port; |
169589005 [NETFILTER]: nf_c... |
95 96 97 98 99 100 101 102 103 |
int ret = NF_ACCEPT; typeof(nf_nat_amanda_hook) nf_nat_amanda; /* Only look at packets from the Amanda server */ if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) return NF_ACCEPT; /* increase the UDP timeout of the master connection as replies from * Amanda clients to the server can be quite delayed */ |
3db05fea5 [NETFILTER]: Repl... |
104 |
nf_ct_refresh(ct, skb, master_timeout * HZ); |
169589005 [NETFILTER]: nf_c... |
105 106 107 |
/* No data? */ dataoff = protoff + sizeof(struct udphdr); |
3db05fea5 [NETFILTER]: Repl... |
108 |
if (dataoff >= skb->len) { |
169589005 [NETFILTER]: nf_c... |
109 |
if (net_ratelimit()) |
654d0fbdc netfilter: cleanu... |
110 111 |
printk(KERN_ERR "amanda_help: skblen = %u ", skb->len); |
169589005 [NETFILTER]: nf_c... |
112 113 114 115 |
return NF_ACCEPT; } memset(&ts, 0, sizeof(ts)); |
3db05fea5 [NETFILTER]: Repl... |
116 |
start = skb_find_text(skb, dataoff, skb->len, |
169589005 [NETFILTER]: nf_c... |
117 118 119 120 121 122 |
search[SEARCH_CONNECT].ts, &ts); if (start == UINT_MAX) goto out; start += dataoff + search[SEARCH_CONNECT].len; memset(&ts, 0, sizeof(ts)); |
3db05fea5 [NETFILTER]: Repl... |
123 |
stop = skb_find_text(skb, start, skb->len, |
169589005 [NETFILTER]: nf_c... |
124 125 126 127 128 129 130 |
search[SEARCH_NEWLINE].ts, &ts); if (stop == UINT_MAX) goto out; stop += start; for (i = SEARCH_DATA; i <= SEARCH_INDEX; i++) { memset(&ts, 0, sizeof(ts)); |
3db05fea5 [NETFILTER]: Repl... |
131 |
off = skb_find_text(skb, start, stop, search[i].ts, &ts); |
169589005 [NETFILTER]: nf_c... |
132 133 134 135 136 |
if (off == UINT_MAX) continue; off += start + search[i].len; len = min_t(unsigned int, sizeof(pbuf) - 1, stop - off); |
3db05fea5 [NETFILTER]: Repl... |
137 |
if (skb_copy_bits(skb, off, pbuf, len)) |
169589005 [NETFILTER]: nf_c... |
138 139 140 141 142 143 144 |
break; pbuf[len] = '\0'; port = htons(simple_strtoul(pbuf, &tmp, 10)); len = tmp - pbuf; if (port == 0 || len > 5) break; |
6823645d6 [NETFILTER]: nf_c... |
145 |
exp = nf_ct_expect_alloc(ct); |
169589005 [NETFILTER]: nf_c... |
146 147 148 149 150 |
if (exp == NULL) { ret = NF_DROP; goto out; } tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; |
5e8fbe2ac [NETFILTER]: nf_c... |
151 152 |
nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct), |
6002f266b [NETFILTER]: nf_c... |
153 |
&tuple->src.u3, &tuple->dst.u3, |
6823645d6 [NETFILTER]: nf_c... |
154 |
IPPROTO_TCP, NULL, &port); |
169589005 [NETFILTER]: nf_c... |
155 156 157 |
nf_nat_amanda = rcu_dereference(nf_nat_amanda_hook); if (nf_nat_amanda && ct->status & IPS_NAT_MASK) |
3db05fea5 [NETFILTER]: Repl... |
158 |
ret = nf_nat_amanda(skb, ctinfo, off - dataoff, |
169589005 [NETFILTER]: nf_c... |
159 |
len, exp); |
6823645d6 [NETFILTER]: nf_c... |
160 |
else if (nf_ct_expect_related(exp) != 0) |
169589005 [NETFILTER]: nf_c... |
161 |
ret = NF_DROP; |
6823645d6 [NETFILTER]: nf_c... |
162 |
nf_ct_expect_put(exp); |
169589005 [NETFILTER]: nf_c... |
163 164 165 166 167 |
} out: return ret; } |
6002f266b [NETFILTER]: nf_c... |
168 169 170 171 |
static const struct nf_conntrack_expect_policy amanda_exp_policy = { .max_expected = 3, .timeout = 180, }; |
169589005 [NETFILTER]: nf_c... |
172 173 174 |
static struct nf_conntrack_helper amanda_helper[2] __read_mostly = { { .name = "amanda", |
169589005 [NETFILTER]: nf_c... |
175 176 177 |
.me = THIS_MODULE, .help = amanda_help, .tuple.src.l3num = AF_INET, |
09640e636 net: replace uses... |
178 |
.tuple.src.u.udp.port = cpu_to_be16(10080), |
169589005 [NETFILTER]: nf_c... |
179 |
.tuple.dst.protonum = IPPROTO_UDP, |
6002f266b [NETFILTER]: nf_c... |
180 |
.expect_policy = &amanda_exp_policy, |
169589005 [NETFILTER]: nf_c... |
181 182 183 |
}, { .name = "amanda", |
169589005 [NETFILTER]: nf_c... |
184 185 186 |
.me = THIS_MODULE, .help = amanda_help, .tuple.src.l3num = AF_INET6, |
09640e636 net: replace uses... |
187 |
.tuple.src.u.udp.port = cpu_to_be16(10080), |
169589005 [NETFILTER]: nf_c... |
188 |
.tuple.dst.protonum = IPPROTO_UDP, |
6002f266b [NETFILTER]: nf_c... |
189 |
.expect_policy = &amanda_exp_policy, |
169589005 [NETFILTER]: nf_c... |
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
}, }; static void __exit nf_conntrack_amanda_fini(void) { int i; nf_conntrack_helper_unregister(&amanda_helper[0]); nf_conntrack_helper_unregister(&amanda_helper[1]); for (i = 0; i < ARRAY_SIZE(search); i++) textsearch_destroy(search[i].ts); } static int __init nf_conntrack_amanda_init(void) { int ret, i; |
169589005 [NETFILTER]: nf_c... |
206 207 208 209 |
for (i = 0; i < ARRAY_SIZE(search); i++) { search[i].ts = textsearch_prepare(ts_algo, search[i].string, search[i].len, GFP_KERNEL, TS_AUTOLOAD); |
c764c9ade [NETFILTER]: nf_c... |
210 211 |
if (IS_ERR(search[i].ts)) { ret = PTR_ERR(search[i].ts); |
169589005 [NETFILTER]: nf_c... |
212 |
goto err1; |
c764c9ade [NETFILTER]: nf_c... |
213 |
} |
169589005 [NETFILTER]: nf_c... |
214 215 216 217 218 219 220 221 222 223 224 225 |
} ret = nf_conntrack_helper_register(&amanda_helper[0]); if (ret < 0) goto err1; ret = nf_conntrack_helper_register(&amanda_helper[1]); if (ret < 0) goto err2; return 0; err2: nf_conntrack_helper_unregister(&amanda_helper[0]); err1: |
c764c9ade [NETFILTER]: nf_c... |
226 227 |
while (--i >= 0) textsearch_destroy(search[i].ts); |
169589005 [NETFILTER]: nf_c... |
228 229 230 231 232 |
return ret; } module_init(nf_conntrack_amanda_init); module_exit(nf_conntrack_amanda_fini); |