Blame view

net/netfilter/nf_conntrack_amanda.c 5.88 KB
169589005   Patrick McHardy   [NETFILTER]: nf_c...
1
2
3
4
  /* 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
f229f6ce4   Patrick McHardy   netfilter: add my...
5
   * (C) 2006 Patrick McHardy <kaber@trash.net>
169589005   Patrick McHardy   [NETFILTER]: nf_c...
6
7
8
9
10
11
12
13
14
15
16
17
18
   *
   * 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   Yasuyuki Kozakai   [NETFILTER]: nf_c...
19
  #include <linux/netfilter.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
20
  #include <linux/gfp.h>
169589005   Patrick McHardy   [NETFILTER]: nf_c...
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  
  #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   Pablo Neira Ayuso   netfilter: nf_con...
35
  MODULE_ALIAS_NFCT_HELPER("amanda");
169589005   Patrick McHardy   [NETFILTER]: nf_c...
36
37
38
39
40
  
  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   Herbert Xu   [NETFILTER]: Repl...
41
  unsigned int (*nf_nat_amanda_hook)(struct sk_buff *skb,
169589005   Patrick McHardy   [NETFILTER]: nf_c...
42
  				   enum ip_conntrack_info ctinfo,
051966c0c   Patrick McHardy   netfilter: nf_nat...
43
  				   unsigned int protoff,
169589005   Patrick McHardy   [NETFILTER]: nf_c...
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
  				   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   Jan Engelhardt   [NETFILTER]: anno...
59
  	const char		*string;
169589005   Patrick McHardy   [NETFILTER]: nf_c...
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
  	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   Herbert Xu   [NETFILTER]: Repl...
85
  static int amanda_help(struct sk_buff *skb,
169589005   Patrick McHardy   [NETFILTER]: nf_c...
86
87
88
89
  		       unsigned int protoff,
  		       struct nf_conn *ct,
  		       enum ip_conntrack_info ctinfo)
  {
169589005   Patrick McHardy   [NETFILTER]: nf_c...
90
91
92
93
94
95
  	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   Patrick McHardy   [NETFILTER]: nf_c...
96
97
98
99
100
101
102
103
104
  	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   Herbert Xu   [NETFILTER]: Repl...
105
  	nf_ct_refresh(ct, skb, master_timeout * HZ);
169589005   Patrick McHardy   [NETFILTER]: nf_c...
106
107
108
  
  	/* No data? */
  	dataoff = protoff + sizeof(struct udphdr);
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
109
  	if (dataoff >= skb->len) {
e87cc4728   Joe Perches   net: Convert net_...
110
111
  		net_err_ratelimited("amanda_help: skblen = %u
  ", skb->len);
169589005   Patrick McHardy   [NETFILTER]: nf_c...
112
113
  		return NF_ACCEPT;
  	}
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
114
  	start = skb_find_text(skb, dataoff, skb->len,
059a2440f   Bojan Prtvar   net: Remove state...
115
  			      search[SEARCH_CONNECT].ts);
169589005   Patrick McHardy   [NETFILTER]: nf_c...
116
117
118
  	if (start == UINT_MAX)
  		goto out;
  	start += dataoff + search[SEARCH_CONNECT].len;
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
119
  	stop = skb_find_text(skb, start, skb->len,
059a2440f   Bojan Prtvar   net: Remove state...
120
  			     search[SEARCH_NEWLINE].ts);
169589005   Patrick McHardy   [NETFILTER]: nf_c...
121
122
123
124
125
  	if (stop == UINT_MAX)
  		goto out;
  	stop += start;
  
  	for (i = SEARCH_DATA; i <= SEARCH_INDEX; i++) {
059a2440f   Bojan Prtvar   net: Remove state...
126
  		off = skb_find_text(skb, start, stop, search[i].ts);
169589005   Patrick McHardy   [NETFILTER]: nf_c...
127
128
129
130
131
  		if (off == UINT_MAX)
  			continue;
  		off += start + search[i].len;
  
  		len = min_t(unsigned int, sizeof(pbuf) - 1, stop - off);
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
132
  		if (skb_copy_bits(skb, off, pbuf, len))
169589005   Patrick McHardy   [NETFILTER]: nf_c...
133
134
135
136
137
138
139
  			break;
  		pbuf[len] = '\0';
  
  		port = htons(simple_strtoul(pbuf, &tmp, 10));
  		len = tmp - pbuf;
  		if (port == 0 || len > 5)
  			break;
6823645d6   Patrick McHardy   [NETFILTER]: nf_c...
140
  		exp = nf_ct_expect_alloc(ct);
169589005   Patrick McHardy   [NETFILTER]: nf_c...
141
  		if (exp == NULL) {
b20ab9cc6   Pablo Neira Ayuso   netfilter: nf_ct_...
142
  			nf_ct_helper_log(skb, ct, "cannot alloc expectation");
169589005   Patrick McHardy   [NETFILTER]: nf_c...
143
144
145
146
  			ret = NF_DROP;
  			goto out;
  		}
  		tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
5e8fbe2ac   Patrick McHardy   [NETFILTER]: nf_c...
147
148
  		nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
  				  nf_ct_l3num(ct),
6002f266b   Patrick McHardy   [NETFILTER]: nf_c...
149
  				  &tuple->src.u3, &tuple->dst.u3,
6823645d6   Patrick McHardy   [NETFILTER]: nf_c...
150
  				  IPPROTO_TCP, NULL, &port);
169589005   Patrick McHardy   [NETFILTER]: nf_c...
151
152
  
  		nf_nat_amanda = rcu_dereference(nf_nat_amanda_hook);
ee6eb9667   Patrick McHardy   netfilter: nf_nat...
153
  		if (nf_nat_amanda && ct->status & IPS_NAT_MASK)
051966c0c   Patrick McHardy   netfilter: nf_nat...
154
155
  			ret = nf_nat_amanda(skb, ctinfo, protoff,
  					    off - dataoff, len, exp);
b20ab9cc6   Pablo Neira Ayuso   netfilter: nf_ct_...
156
157
  		else if (nf_ct_expect_related(exp) != 0) {
  			nf_ct_helper_log(skb, ct, "cannot add expectation");
169589005   Patrick McHardy   [NETFILTER]: nf_c...
158
  			ret = NF_DROP;
b20ab9cc6   Pablo Neira Ayuso   netfilter: nf_ct_...
159
  		}
6823645d6   Patrick McHardy   [NETFILTER]: nf_c...
160
  		nf_ct_expect_put(exp);
169589005   Patrick McHardy   [NETFILTER]: nf_c...
161
162
163
164
165
  	}
  
  out:
  	return ret;
  }
6002f266b   Patrick McHardy   [NETFILTER]: nf_c...
166
167
168
169
  static const struct nf_conntrack_expect_policy amanda_exp_policy = {
  	.max_expected		= 3,
  	.timeout		= 180,
  };
169589005   Patrick McHardy   [NETFILTER]: nf_c...
170
171
172
  static struct nf_conntrack_helper amanda_helper[2] __read_mostly = {
  	{
  		.name			= "amanda",
169589005   Patrick McHardy   [NETFILTER]: nf_c...
173
174
175
  		.me			= THIS_MODULE,
  		.help			= amanda_help,
  		.tuple.src.l3num	= AF_INET,
09640e636   Harvey Harrison   net: replace uses...
176
  		.tuple.src.u.udp.port	= cpu_to_be16(10080),
169589005   Patrick McHardy   [NETFILTER]: nf_c...
177
  		.tuple.dst.protonum	= IPPROTO_UDP,
6002f266b   Patrick McHardy   [NETFILTER]: nf_c...
178
  		.expect_policy		= &amanda_exp_policy,
169589005   Patrick McHardy   [NETFILTER]: nf_c...
179
180
181
  	},
  	{
  		.name			= "amanda",
169589005   Patrick McHardy   [NETFILTER]: nf_c...
182
183
184
  		.me			= THIS_MODULE,
  		.help			= amanda_help,
  		.tuple.src.l3num	= AF_INET6,
09640e636   Harvey Harrison   net: replace uses...
185
  		.tuple.src.u.udp.port	= cpu_to_be16(10080),
169589005   Patrick McHardy   [NETFILTER]: nf_c...
186
  		.tuple.dst.protonum	= IPPROTO_UDP,
6002f266b   Patrick McHardy   [NETFILTER]: nf_c...
187
  		.expect_policy		= &amanda_exp_policy,
169589005   Patrick McHardy   [NETFILTER]: nf_c...
188
189
190
191
192
193
  	},
  };
  
  static void __exit nf_conntrack_amanda_fini(void)
  {
  	int i;
d53e3fc39   Liping Zhang   netfilter: use nf...
194
195
  	nf_conntrack_helpers_unregister(amanda_helper,
  					ARRAY_SIZE(amanda_helper));
169589005   Patrick McHardy   [NETFILTER]: nf_c...
196
197
198
199
200
201
202
  	for (i = 0; i < ARRAY_SIZE(search); i++)
  		textsearch_destroy(search[i].ts);
  }
  
  static int __init nf_conntrack_amanda_init(void)
  {
  	int ret, i;
dcf67740f   Florian Westphal   netfilter: helper...
203
  	NF_CT_HELPER_BUILD_BUG_ON(0);
169589005   Patrick McHardy   [NETFILTER]: nf_c...
204
205
206
207
  	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   Akinobu Mita   [NETFILTER]: nf_c...
208
209
  		if (IS_ERR(search[i].ts)) {
  			ret = PTR_ERR(search[i].ts);
169589005   Patrick McHardy   [NETFILTER]: nf_c...
210
  			goto err1;
c764c9ade   Akinobu Mita   [NETFILTER]: nf_c...
211
  		}
169589005   Patrick McHardy   [NETFILTER]: nf_c...
212
  	}
d53e3fc39   Liping Zhang   netfilter: use nf...
213
214
  	ret = nf_conntrack_helpers_register(amanda_helper,
  					    ARRAY_SIZE(amanda_helper));
169589005   Patrick McHardy   [NETFILTER]: nf_c...
215
216
  	if (ret < 0)
  		goto err1;
169589005   Patrick McHardy   [NETFILTER]: nf_c...
217
  	return 0;
169589005   Patrick McHardy   [NETFILTER]: nf_c...
218
  err1:
c764c9ade   Akinobu Mita   [NETFILTER]: nf_c...
219
220
  	while (--i >= 0)
  		textsearch_destroy(search[i].ts);
169589005   Patrick McHardy   [NETFILTER]: nf_c...
221
222
223
224
225
  	return ret;
  }
  
  module_init(nf_conntrack_amanda_init);
  module_exit(nf_conntrack_amanda_fini);