aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2006-12-03 01:08:26 -0500
committerDavid S. Miller <davem@davemloft.net>2006-12-03 01:08:26 -0500
commit16958900578b94585c2ab9a2d20d837b4d5e3ba6 (patch)
tree91d198f1287535821ccc4d2f4dcdf9d8aa3b8483
parentd6a9b6500a8941599bcef98e7de49e1260d104ed (diff)
[NETFILTER]: nf_conntrack/nf_nat: add amanda helper port
Add IPv4 and IPv6 capable nf_conntrack port of the Amanda conntrack/NAT helper. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/netfilter/nf_conntrack_amanda.h10
-rw-r--r--net/ipv4/netfilter/Kconfig5
-rw-r--r--net/ipv4/netfilter/Makefile1
-rw-r--r--net/ipv4/netfilter/nf_nat_amanda.c78
-rw-r--r--net/netfilter/Kconfig15
-rw-r--r--net/netfilter/Makefile1
-rw-r--r--net/netfilter/nf_conntrack_amanda.c237
7 files changed, 347 insertions, 0 deletions
diff --git a/include/linux/netfilter/nf_conntrack_amanda.h b/include/linux/netfilter/nf_conntrack_amanda.h
new file mode 100644
index 000000000000..26c223544ae8
--- /dev/null
+++ b/include/linux/netfilter/nf_conntrack_amanda.h
@@ -0,0 +1,10 @@
1#ifndef _NF_CONNTRACK_AMANDA_H
2#define _NF_CONNTRACK_AMANDA_H
3/* AMANDA tracking. */
4
5extern unsigned int (*nf_nat_amanda_hook)(struct sk_buff **pskb,
6 enum ip_conntrack_info ctinfo,
7 unsigned int matchoff,
8 unsigned int matchlen,
9 struct nf_conntrack_expect *exp);
10#endif /* _NF_CONNTRACK_AMANDA_H */
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 52f876db68f4..6993ec53dc06 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -512,6 +512,11 @@ config IP_NF_NAT_AMANDA
512 default IP_NF_NAT if IP_NF_AMANDA=y 512 default IP_NF_NAT if IP_NF_AMANDA=y
513 default m if IP_NF_AMANDA=m 513 default m if IP_NF_AMANDA=m
514 514
515config NF_NAT_AMANDA
516 tristate
517 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
518 default NF_NAT && NF_CONNTRACK_AMANDA
519
515config IP_NF_NAT_PPTP 520config IP_NF_NAT_PPTP
516 tristate 521 tristate
517 depends on IP_NF_NAT!=n && IP_NF_PPTP!=n 522 depends on IP_NF_NAT!=n && IP_NF_PPTP!=n
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index c0c6194bb275..8893249bbe98 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_IP_NF_NAT_IRC) += ip_nat_irc.o
50obj-$(CONFIG_IP_NF_NAT_SIP) += ip_nat_sip.o 50obj-$(CONFIG_IP_NF_NAT_SIP) += ip_nat_sip.o
51 51
52# NAT helpers (nf_conntrack) 52# NAT helpers (nf_conntrack)
53obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
53obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o 54obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
54 55
55# generic IP tables 56# generic IP tables
diff --git a/net/ipv4/netfilter/nf_nat_amanda.c b/net/ipv4/netfilter/nf_nat_amanda.c
new file mode 100644
index 000000000000..0f17098917bc
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_amanda.c
@@ -0,0 +1,78 @@
1/* Amanda extension for TCP NAT alteration.
2 * (C) 2002 by Brian J. Murrell <netfilter@interlinx.bc.ca>
3 * based on a copy of HW's ip_nat_irc.c as well as other modules
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 */
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/skbuff.h>
14#include <linux/udp.h>
15
16#include <net/netfilter/nf_nat_helper.h>
17#include <net/netfilter/nf_nat_rule.h>
18#include <net/netfilter/nf_conntrack_helper.h>
19#include <net/netfilter/nf_conntrack_expect.h>
20#include <linux/netfilter/nf_conntrack_amanda.h>
21
22MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
23MODULE_DESCRIPTION("Amanda NAT helper");
24MODULE_LICENSE("GPL");
25MODULE_ALIAS("ip_nat_amanda");
26
27static unsigned int help(struct sk_buff **pskb,
28 enum ip_conntrack_info ctinfo,
29 unsigned int matchoff,
30 unsigned int matchlen,
31 struct nf_conntrack_expect *exp)
32{
33 char buffer[sizeof("65535")];
34 u_int16_t port;
35 unsigned int ret;
36
37 /* Connection comes from client. */
38 exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
39 exp->dir = IP_CT_DIR_ORIGINAL;
40
41 /* When you see the packet, we need to NAT it the same as the
42 * this one (ie. same IP: it will be TCP and master is UDP). */
43 exp->expectfn = nf_nat_follow_master;
44
45 /* Try to get same port: if not, try to change it. */
46 for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
47 exp->tuple.dst.u.tcp.port = htons(port);
48 if (nf_conntrack_expect_related(exp) == 0)
49 break;
50 }
51
52 if (port == 0)
53 return NF_DROP;
54
55 sprintf(buffer, "%u", port);
56 ret = nf_nat_mangle_udp_packet(pskb, exp->master, ctinfo,
57 matchoff, matchlen,
58 buffer, strlen(buffer));
59 if (ret != NF_ACCEPT)
60 nf_conntrack_unexpect_related(exp);
61 return ret;
62}
63
64static void __exit nf_nat_amanda_fini(void)
65{
66 rcu_assign_pointer(nf_nat_amanda_hook, NULL);
67 synchronize_rcu();
68}
69
70static int __init nf_nat_amanda_init(void)
71{
72 BUG_ON(rcu_dereference(nf_nat_amanda_hook));
73 rcu_assign_pointer(nf_nat_amanda_hook, help);
74 return 0;
75}
76
77module_init(nf_nat_amanda_init);
78module_exit(nf_nat_amanda_fini);
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index efe56f768f34..f85fd43b344b 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -131,6 +131,21 @@ config NF_CT_PROTO_SCTP
131 If you want to compile it as a module, say M here and read 131 If you want to compile it as a module, say M here and read
132 Documentation/modules.txt. If unsure, say `N'. 132 Documentation/modules.txt. If unsure, say `N'.
133 133
134config NF_CONNTRACK_AMANDA
135 tristate "Amanda backup protocol support (EXPERIMENTAL)"
136 depends on EXPERIMENTAL && NF_CONNTRACK
137 select TEXTSEARCH
138 select TEXTSEARCH_KMP
139 help
140 If you are running the Amanda backup package <http://www.amanda.org/>
141 on this machine or machines that will be MASQUERADED through this
142 machine, then you may want to enable this feature. This allows the
143 connection tracking and natting code to allow the sub-channels that
144 Amanda requires for communication of the backup data, messages and
145 index.
146
147 To compile it as a module, choose M here. If unsure, say N.
148
134config NF_CONNTRACK_FTP 149config NF_CONNTRACK_FTP
135 tristate "FTP support on new connection tracking (EXPERIMENTAL)" 150 tristate "FTP support on new connection tracking (EXPERIMENTAL)"
136 depends on EXPERIMENTAL && NF_CONNTRACK 151 depends on EXPERIMENTAL && NF_CONNTRACK
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 7f0089c584bf..a5ee93817427 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o
20obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o 20obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o
21 21
22# connection tracking helpers 22# connection tracking helpers
23obj-$(CONFIG_NF_CONNTRACK_AMANDA) += nf_conntrack_amanda.o
23obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o 24obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o
24 25
25# generic X tables 26# generic X tables
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c
new file mode 100644
index 000000000000..5c495dc9d942
--- /dev/null
+++ b/net/netfilter/nf_conntrack_amanda.c
@@ -0,0 +1,237 @@
1/* Amanda extension for IP connection tracking
2 *
3 * (C) 2002 by Brian J. Murrell <netfilter@interlinx.bc.ca>
4 * based on HW's ip_conntrack_irc.c as well as other modules
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/textsearch.h>
15#include <linux/skbuff.h>
16#include <linux/in.h>
17#include <linux/udp.h>
18
19#include <net/netfilter/nf_conntrack.h>
20#include <net/netfilter/nf_conntrack_expect.h>
21#include <net/netfilter/nf_conntrack_ecache.h>
22#include <net/netfilter/nf_conntrack_helper.h>
23#include <linux/netfilter/nf_conntrack_amanda.h>
24
25static unsigned int master_timeout __read_mostly = 300;
26static char *ts_algo = "kmp";
27
28MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
29MODULE_DESCRIPTION("Amanda connection tracking module");
30MODULE_LICENSE("GPL");
31MODULE_ALIAS("ip_conntrack_amanda");
32
33module_param(master_timeout, uint, 0600);
34MODULE_PARM_DESC(master_timeout, "timeout for the master connection");
35module_param(ts_algo, charp, 0400);
36MODULE_PARM_DESC(ts_algo, "textsearch algorithm to use (default kmp)");
37
38unsigned int (*nf_nat_amanda_hook)(struct sk_buff **pskb,
39 enum ip_conntrack_info ctinfo,
40 unsigned int matchoff,
41 unsigned int matchlen,
42 struct nf_conntrack_expect *exp)
43 __read_mostly;
44EXPORT_SYMBOL_GPL(nf_nat_amanda_hook);
45
46enum amanda_strings {
47 SEARCH_CONNECT,
48 SEARCH_NEWLINE,
49 SEARCH_DATA,
50 SEARCH_MESG,
51 SEARCH_INDEX,
52};
53
54static struct {
55 char *string;
56 size_t len;
57 struct ts_config *ts;
58} search[] __read_mostly = {
59 [SEARCH_CONNECT] = {
60 .string = "CONNECT ",
61 .len = 8,
62 },
63 [SEARCH_NEWLINE] = {
64 .string = "\n",
65 .len = 1,
66 },
67 [SEARCH_DATA] = {
68 .string = "DATA ",
69 .len = 5,
70 },
71 [SEARCH_MESG] = {
72 .string = "MESG ",
73 .len = 5,
74 },
75 [SEARCH_INDEX] = {
76 .string = "INDEX ",
77 .len = 6,
78 },
79};
80
81static int amanda_help(struct sk_buff **pskb,
82 unsigned int protoff,
83 struct nf_conn *ct,
84 enum ip_conntrack_info ctinfo)
85{
86 struct ts_state ts;
87 struct nf_conntrack_expect *exp;
88 struct nf_conntrack_tuple *tuple;
89 unsigned int dataoff, start, stop, off, i;
90 char pbuf[sizeof("65535")], *tmp;
91 u_int16_t len;
92 __be16 port;
93 int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
94 int ret = NF_ACCEPT;
95 typeof(nf_nat_amanda_hook) nf_nat_amanda;
96
97 /* Only look at packets from the Amanda server */
98 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
99 return NF_ACCEPT;
100
101 /* increase the UDP timeout of the master connection as replies from
102 * Amanda clients to the server can be quite delayed */
103 nf_ct_refresh(ct, *pskb, master_timeout * HZ);
104
105 /* No data? */
106 dataoff = protoff + sizeof(struct udphdr);
107 if (dataoff >= (*pskb)->len) {
108 if (net_ratelimit())
109 printk("amanda_help: skblen = %u\n", (*pskb)->len);
110 return NF_ACCEPT;
111 }
112
113 memset(&ts, 0, sizeof(ts));
114 start = skb_find_text(*pskb, dataoff, (*pskb)->len,
115 search[SEARCH_CONNECT].ts, &ts);
116 if (start == UINT_MAX)
117 goto out;
118 start += dataoff + search[SEARCH_CONNECT].len;
119
120 memset(&ts, 0, sizeof(ts));
121 stop = skb_find_text(*pskb, start, (*pskb)->len,
122 search[SEARCH_NEWLINE].ts, &ts);
123 if (stop == UINT_MAX)
124 goto out;
125 stop += start;
126
127 for (i = SEARCH_DATA; i <= SEARCH_INDEX; i++) {
128 memset(&ts, 0, sizeof(ts));
129 off = skb_find_text(*pskb, start, stop, search[i].ts, &ts);
130 if (off == UINT_MAX)
131 continue;
132 off += start + search[i].len;
133
134 len = min_t(unsigned int, sizeof(pbuf) - 1, stop - off);
135 if (skb_copy_bits(*pskb, off, pbuf, len))
136 break;
137 pbuf[len] = '\0';
138
139 port = htons(simple_strtoul(pbuf, &tmp, 10));
140 len = tmp - pbuf;
141 if (port == 0 || len > 5)
142 break;
143
144 exp = nf_conntrack_expect_alloc(ct);
145 if (exp == NULL) {
146 ret = NF_DROP;
147 goto out;
148 }
149 tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
150 nf_conntrack_expect_init(exp, family,
151 &tuple->src.u3, &tuple->dst.u3,
152 IPPROTO_TCP, NULL, &port);
153
154 nf_nat_amanda = rcu_dereference(nf_nat_amanda_hook);
155 if (nf_nat_amanda && ct->status & IPS_NAT_MASK)
156 ret = nf_nat_amanda(pskb, ctinfo, off - dataoff,
157 len, exp);
158 else if (nf_conntrack_expect_related(exp) != 0)
159 ret = NF_DROP;
160 nf_conntrack_expect_put(exp);
161 }
162
163out:
164 return ret;
165}
166
167static struct nf_conntrack_helper amanda_helper[2] __read_mostly = {
168 {
169 .name = "amanda",
170 .max_expected = 3,
171 .timeout = 180,
172 .me = THIS_MODULE,
173 .help = amanda_help,
174 .tuple.src.l3num = AF_INET,
175 .tuple.src.u.udp.port = __constant_htons(10080),
176 .tuple.dst.protonum = IPPROTO_UDP,
177 .mask.src.l3num = 0xFFFF,
178 .mask.src.u.udp.port = __constant_htons(0xFFFF),
179 .mask.dst.protonum = 0xFF,
180 },
181 {
182 .name = "amanda",
183 .max_expected = 3,
184 .timeout = 180,
185 .me = THIS_MODULE,
186 .help = amanda_help,
187 .tuple.src.l3num = AF_INET6,
188 .tuple.src.u.udp.port = __constant_htons(10080),
189 .tuple.dst.protonum = IPPROTO_UDP,
190 .mask.src.l3num = 0xFFFF,
191 .mask.src.u.udp.port = __constant_htons(0xFFFF),
192 .mask.dst.protonum = 0xFF,
193 },
194};
195
196static void __exit nf_conntrack_amanda_fini(void)
197{
198 int i;
199
200 nf_conntrack_helper_unregister(&amanda_helper[0]);
201 nf_conntrack_helper_unregister(&amanda_helper[1]);
202 for (i = 0; i < ARRAY_SIZE(search); i++)
203 textsearch_destroy(search[i].ts);
204}
205
206static int __init nf_conntrack_amanda_init(void)
207{
208 int ret, i;
209
210 ret = -ENOMEM;
211 for (i = 0; i < ARRAY_SIZE(search); i++) {
212 search[i].ts = textsearch_prepare(ts_algo, search[i].string,
213 search[i].len,
214 GFP_KERNEL, TS_AUTOLOAD);
215 if (search[i].ts == NULL)
216 goto err1;
217 }
218 ret = nf_conntrack_helper_register(&amanda_helper[0]);
219 if (ret < 0)
220 goto err1;
221 ret = nf_conntrack_helper_register(&amanda_helper[1]);
222 if (ret < 0)
223 goto err2;
224 return 0;
225
226err2:
227 nf_conntrack_helper_unregister(&amanda_helper[0]);
228err1:
229 for (; i >= 0; i--) {
230 if (search[i].ts)
231 textsearch_destroy(search[i].ts);
232 }
233 return ret;
234}
235
236module_init(nf_conntrack_amanda_init);
237module_exit(nf_conntrack_amanda_fini);