]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-pom-ng-mms-conntrack-nat.patch
- fix build with glibc 2.10
[packages/kernel.git] / kernel-pom-ng-mms-conntrack-nat.patch
CommitLineData
6890440f 1diff -NurpP --minimal linux-2.6.21.a/include/linux/netfilter/nf_conntrack_mms.h linux-2.6.21.b/include/linux/netfilter/nf_conntrack_mms.h
2--- linux-2.6.21.a/include/linux/netfilter/nf_conntrack_mms.h 1970-01-01 01:00:00.000000000 +0100
3+++ linux-2.6.21.b/include/linux/netfilter/nf_conntrack_mms.h 2007-05-30 11:50:55.000000000 +0200
4@@ -0,0 +1,34 @@
5+#ifndef _IP_CONNTRACK_MMS_H
6+#define _IP_CONNTRACK_MMS_H
7+/* MMS tracking. */
8+
9+#ifdef __KERNEL__
10+
11+#define MMS_PORT 1755
12+#define MMS_SRV_MSG_ID 196610
13+
14+#define MMS_SRV_MSG_OFFSET 36
15+#define MMS_SRV_UNICODE_STRING_OFFSET 60
16+#define MMS_SRV_CHUNKLENLV_OFFSET 16
17+#define MMS_SRV_CHUNKLENLM_OFFSET 32
18+#define MMS_SRV_MESSAGELENGTH_OFFSET 8
19+
20+/* This structure is per expected connection */
21+struct nf_ct_mms_expect {
22+ u_int32_t offset;
23+ u_int32_t len;
24+ u_int32_t padding;
25+ u_int16_t port;
26+};
27+
28+/* This structure exists only once per master */
29+struct nf_ct_mms_master {
30+};
31+
32+struct nf_conntrack_expect;
33+extern unsigned int (*nf_nat_mms_hook)(struct sk_buff **pskb,
34+ enum ip_conntrack_info ctinfo,
35+ const struct nf_ct_mms_expect *exp_mms_info,
36+ struct nf_conntrack_expect *exp);
37+#endif
38+#endif /* _IP_CONNTRACK_MMS_H */
6890440f 39diff -NurpP --minimal linux-2.6.21.a/include/net/netfilter/nf_conntrack.h linux-2.6.21.b/include/net/netfilter/nf_conntrack.h
40--- linux-2.6.21.a/include/net/netfilter/nf_conntrack.h 2007-05-30 11:14:07.000000000 +0200
41+++ linux-2.6.21.b/include/net/netfilter/nf_conntrack.h 2007-05-30 11:50:55.000000000 +0200
42@@ -46,6 +46,7 @@ union nf_conntrack_expect_proto {
6890440f 43 #include <linux/netfilter/nf_conntrack_h323.h>
44 #include <linux/netfilter/nf_conntrack_sane.h>
d76e8f16 45 #include <linux/netfilter/nf_conntrack_sip.h>
6890440f 46+#include <linux/netfilter/nf_conntrack_mms.h>
47
48 /* per conntrack: application helper private data */
49 union nf_conntrack_help {
50@@ -54,6 +55,7 @@ union nf_conntrack_help {
6890440f 51 struct nf_ct_h323_master ct_h323_info;
52 struct nf_ct_sane_master ct_sane_info;
d76e8f16 53 struct nf_ct_sip_master ct_sip_info;
6890440f 54+ struct nf_ct_mms_master ct_mms_info;
55 };
56
57 #include <linux/types.h>
58diff -NurpP --minimal linux-2.6.21.a/include/net/netfilter/nf_conntrack_mms.h linux-2.6.21.b/include/net/netfilter/nf_conntrack_mms.h
59--- linux-2.6.21.a/include/net/netfilter/nf_conntrack_mms.h 1970-01-01 01:00:00.000000000 +0100
60+++ linux-2.6.21.b/include/net/netfilter/nf_conntrack_mms.h 2007-05-30 11:50:55.000000000 +0200
61@@ -0,0 +1,34 @@
62+#ifndef _IP_CONNTRACK_MMS_H
63+#define _IP_CONNTRACK_MMS_H
64+/* MMS tracking. */
65+
66+#ifdef __KERNEL__
67+
68+#define MMS_PORT 1755
69+#define MMS_SRV_MSG_ID 196610
70+
71+#define MMS_SRV_MSG_OFFSET 36
72+#define MMS_SRV_UNICODE_STRING_OFFSET 60
73+#define MMS_SRV_CHUNKLENLV_OFFSET 16
74+#define MMS_SRV_CHUNKLENLM_OFFSET 32
75+#define MMS_SRV_MESSAGELENGTH_OFFSET 8
76+
77+/* This structure is per expected connection */
78+struct nf_ct_mms_expect {
79+ u_int32_t offset;
80+ u_int32_t len;
81+ u_int32_t padding;
82+ u_int16_t port;
83+};
84+
85+/* This structure exists only once per master */
86+struct nf_ct_mms_master {
87+};
88+
89+struct nf_conntrack_expect;
90+extern unsigned int (*nf_nat_mms_hook)(struct sk_buff **pskb,
91+ enum ip_conntrack_info ctinfo,
92+ const struct nf_ct_mms_expect *exp_mms_info,
93+ struct nf_conntrack_expect *exp);
94+#endif
95+#endif /* _IP_CONNTRACK_MMS_H */
96diff -NurpP --minimal linux-2.6.21.a/net/ipv4/netfilter/Kconfig linux-2.6.21.b/net/ipv4/netfilter/Kconfig
97--- linux-2.6.21.a/net/ipv4/netfilter/Kconfig 2007-05-30 11:44:12.000000000 +0200
98+++ linux-2.6.21.b/net/ipv4/netfilter/Kconfig 2007-05-30 11:50:55.000000000 +0200
99@@ -543,6 +543,11 @@ config NF_NAT_H323
100 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
101 default NF_NAT && NF_CONNTRACK_H323
102
103+config NF_NAT_MMS
104+ tristate
105+ depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
106+ default NF_NAT && NF_CONNTRACK_MMS
107+
7f3dddaf 108 config NF_NAT_SIP
6890440f 109 tristate
7f3dddaf 110 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
6890440f 111@@ -847,5 +852,23 @@ config IP_NF_TARGET_TARPIT
112 hardware or IPs. Any TCP port that you would normally DROP or REJECT
113 can instead become a tarpit.
114
115+config IP_NF_NAT_MMS
116+ tristate
117+ depends on IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
118+ default IP_NF_NAT if IP_NF_MMS=y
119+ default m if IP_NF_MMS=m
120+
121+config IP_NF_MMS
122+ tristate 'MMS protocol support'
123+ depends on IP_NF_CONNTRACK
124+ help
125+ Tracking MMS (Microsoft Windows Media Services) connections
126+ could be problematic if random ports are used to send the
127+ streaming content. This option allows users to track streaming
128+ connections over random UDP or TCP ports.
129+
130+ If you want to compile it as a module, say M here and read
131+ <file:Documentation/modules.txt>. If unsure, say `Y'.
132+
133 endmenu
134
135diff -NurpP --minimal linux-2.6.21.a/net/ipv4/netfilter/Makefile linux-2.6.21.b/net/ipv4/netfilter/Makefile
136--- linux-2.6.21.a/net/ipv4/netfilter/Makefile 2007-05-30 11:44:12.000000000 +0200
137+++ linux-2.6.21.b/net/ipv4/netfilter/Makefile 2007-05-30 11:50:55.000000000 +0200
155c0b71 138@@ -0,0 +0,1 @@
6890440f 139+obj-$(CONFIG_NF_NAT_MMS) += nf_nat_mms.o
6890440f 140diff -NurpP --minimal linux-2.6.21.a/net/ipv4/netfilter/nf_nat_mms.c linux-2.6.21.b/net/ipv4/netfilter/nf_nat_mms.c
141--- linux-2.6.21.a/net/ipv4/netfilter/nf_nat_mms.c 1970-01-01 01:00:00.000000000 +0100
142+++ linux-2.6.21.b/net/ipv4/netfilter/nf_nat_mms.c 2007-05-30 11:50:55.000000000 +0200
143@@ -0,0 +1,196 @@
144+/* MMS extension for TCP NAT alteration.
145+ * (C) 2002 by Filip Sneppe <filip.sneppe@cronos.be>
146+ * based on ip_nat_ftp.c and ip_nat_irc.c
147+ *
148+ * ip_nat_mms.c v0.3 2002-09-22
149+ *
150+ * This program is free software; you can redistribute it and/or
151+ * modify it under the terms of the GNU General Public License
152+ * as published by the Free Software Foundation; either version
153+ * 2 of the License, or (at your option) any later version.
154+ *
155+ * Module load syntax:
156+ * insmod ip_nat_mms.o ports=port1,port2,...port<MAX_PORTS>
157+ *
158+ * Please give the ports of all MMS servers You wish to connect to.
159+ * If you don't specify ports, the default will be TCP port 1755.
160+ *
161+ * More info on MMS protocol, firewalls and NAT:
162+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/MMSFirewall.asp
163+ * http://www.microsoft.com/windows/windowsmedia/serve/firewall.asp
164+ *
165+ * The SDP project people are reverse-engineering MMS:
166+ * http://get.to/sdp
167+ *
168+ * 2005-02-13: Harald Welte <laforge@netfilter.org>
169+ * - port to 2.6.x
170+ * - update to work with post 2.6.11 helper API changes
171+ *
172+ * 2007-03-30: Marek Guevara Braun <mguevara@pld-linux.org>
173+ * - port to nf_conntrack
174+ */
175+
176+/* FIXME: issue with UDP & fragmentation with this URL:
177+ http://www.cnn.com/video/world/2002/01/21/jb.shoe.bomb.cafe.cnn.low.asx
178+ may be related to out-of-order first packets:
179+ basically the expectation is set up correctly, then the server sends
180+ a first UDP packet which is fragmented plus arrives out-of-order.
181+ the MASQUERADING firewall with ip_nat_mms loaded responds with
182+ an ICMP unreachable back to the server */
183+
184+#include <linux/module.h>
185+#include <linux/netfilter_ipv4.h>
186+#include <linux/ip.h>
187+#include <linux/tcp.h>
188+#include <net/tcp.h>
189+#include <net/netfilter/nf_nat.h>
190+#include <net/netfilter/nf_nat_helper.h>
191+#include <net/netfilter/nf_nat_rule.h>
192+#include <net/netfilter/nf_conntrack_helper.h>
193+#include <net/netfilter/nf_conntrack_expect.h>
194+#include <linux/netfilter/nf_conntrack_mms.h>
195+
196+#if 0
197+#define DEBUGP printk
198+#define DUMP_BYTES(address, counter) \
199+({ \
200+ int temp_counter; \
201+ for(temp_counter=0; temp_counter<counter; ++temp_counter) { \
202+ DEBUGP("%u ", (u8)*(address+temp_counter)); \
203+ }; \
204+ DEBUGP("\n"); \
205+})
206+#else
207+#define DEBUGP(format, args...)
208+#define DUMP_BYTES(address, counter)
209+#endif
210+
211+MODULE_AUTHOR("Filip Sneppe <filip.sneppe@cronos.be>");
212+MODULE_DESCRIPTION("Microsoft Windows Media Services (MMS) NAT module");
213+MODULE_LICENSE("GPL");
214+
215+static unsigned int mms_data_fixup(struct sk_buff **pskb,
216+ enum ip_conntrack_info ctinfo,
217+ const struct nf_ct_mms_expect *ct_mms_info,
218+ struct nf_conntrack_expect *expect)
219+{
220+ u_int32_t newip;
221+ struct nf_conn *ct = expect->master;
5ce52adc 222+ struct iphdr *iph = ip_hdr(*pskb);
6890440f 223+ struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
224+ char *data = (char *)tcph + tcph->doff * 4;
225+ int i, j, k, port;
226+ u_int16_t mms_proto;
227+
228+ u_int32_t *mms_chunkLenLV = (u_int32_t *)(data + MMS_SRV_CHUNKLENLV_OFFSET);
229+ u_int32_t *mms_chunkLenLM = (u_int32_t *)(data + MMS_SRV_CHUNKLENLM_OFFSET);
230+ u_int32_t *mms_messageLength = (u_int32_t *)(data + MMS_SRV_MESSAGELENGTH_OFFSET);
231+
232+ int zero_padding;
233+
234+ char buffer[28]; /* "\\255.255.255.255\UDP\65635" * 2
235+ (for unicode) */
236+ char unicode_buffer[75]; /* 27*2 (unicode) + 20 + 1 */
237+ char proto_string[6];
238+
239+ /* what was the protocol again ? */
240+ mms_proto = expect->tuple.dst.protonum;
241+ sprintf(proto_string, "%u", mms_proto);
242+
243+ DEBUGP("nf_nat_mms: mms_data_fixup: info (seq %u + %u) "
244+ "in %u, proto %s\n",
245+ expect->seq, ct_mms_info->len, ntohl(tcph->seq),
246+ mms_proto == IPPROTO_UDP ? "UDP"
247+ : mms_proto == IPPROTO_TCP ? "TCP":proto_string);
248+
249+ newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip;
250+ expect->saved_proto.tcp.port = expect->tuple.dst.u.tcp.port;
251+ expect->expectfn = nf_nat_follow_master;
252+
253+ /* Alter conntrack's expectations. */
254+ for (port = ct_mms_info->port; port != 0; port++) {
255+ expect->tuple.dst.u.tcp.port = htons(port);
155c0b71 256+ if (nf_ct_expect_related(expect) == 0) {
6890440f 257+ DEBUGP("nf_nat_mms: mms_data_fixup: using port %d\n",
258+ port);
259+ break;
260+ }
261+ }
262+
263+ if (port == 0)
264+ return NF_DROP;
265+
266+ sprintf(buffer, "\\\\%u.%u.%u.%u\\%s\\%u",
267+ NIPQUAD(newip),
268+ expect->tuple.dst.protonum == IPPROTO_UDP ? "UDP"
269+ : expect->tuple.dst.protonum == IPPROTO_TCP ? "TCP":proto_string,
270+ port);
271+ DEBUGP("nf_nat_mms: new unicode string=%s\n", buffer);
272+
273+ memset(unicode_buffer, 0, sizeof(char)*75);
274+
275+ for (i=0; i<strlen(buffer); ++i)
276+ *(unicode_buffer+i*2)=*(buffer+i);
277+
278+ DEBUGP("nf_nat_mms: mms_data_fixup: padding: %u len: %u\n",
279+ ct_mms_info->padding, ct_mms_info->len);
280+ DEBUGP("nf_nat_mms: mms_data_fixup: offset: %u\n",
281+ MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len);
282+ DUMP_BYTES(data+MMS_SRV_UNICODE_STRING_OFFSET, 60);
283+
284+ /* add end of packet to it */
285+ for (j=0; j<ct_mms_info->padding; ++j) {
286+ DEBUGP("nf_nat_mms: mms_data_fixup: i=%u j=%u byte=%u\n",
287+ i, j, (u8)*(data+MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len+j));
288+ *(unicode_buffer+i*2+j) = *(data+MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len+j);
289+ }
290+
291+ /* pad with zeroes at the end ? see explanation of weird math below */
292+ zero_padding = (8-(strlen(buffer)*2 + ct_mms_info->padding + 4)%8)%8;
293+ for (k=0; k<zero_padding; ++k)
294+ *(unicode_buffer+i*2+j+k)= (char)0;
295+
296+ DEBUGP("nf_nat_mms: mms_data_fixup: zero_padding = %u\n", zero_padding);
297+ DEBUGP("nf_nat_mms: original=> chunkLenLV=%u chunkLenLM=%u "
298+ "messageLength=%u\n", *mms_chunkLenLV, *mms_chunkLenLM,
299+ *mms_messageLength);
300+
301+ /* explanation, before I forget what I did:
302+ strlen(buffer)*2 + ct_mms_info->padding + 4 must be divisable by 8;
303+ divide by 8 and add 3 to compute the mms_chunkLenLM field,
304+ but note that things may have to be padded with zeroes to align by 8
305+ bytes, hence we add 7 and divide by 8 to get the correct length */
306+ *mms_chunkLenLM = (u_int32_t) (3+(strlen(buffer)*2+ct_mms_info->padding+11)/8);
307+ *mms_chunkLenLV = *mms_chunkLenLM+2;
308+ *mms_messageLength = *mms_chunkLenLV*8;
309+
310+ DEBUGP("nf_nat_mms: modified=> chunkLenLV=%u chunkLenLM=%u"
311+ " messageLength=%u\n", *mms_chunkLenLV, *mms_chunkLenLM,
312+ *mms_messageLength);
313+
155c0b71 314+ nf_nat_mangle_tcp_packet(*pskb, ct, ctinfo,
6890440f 315+ ct_mms_info->offset,
316+ ct_mms_info->len + ct_mms_info->padding,
317+ unicode_buffer, strlen(buffer)*2 +
318+ ct_mms_info->padding + zero_padding);
319+ DUMP_BYTES(unicode_buffer, 60);
320+
321+ return NF_ACCEPT;
322+}
323+
324+static void __exit fini(void)
325+{
326+ nf_nat_mms_hook = NULL;
327+ synchronize_net();
328+}
329+
330+static int __init init(void)
331+{
332+ BUG_ON(nf_nat_mms_hook);
333+ nf_nat_mms_hook = &mms_data_fixup;
334+
335+ return 0;
336+}
337+
338+module_init(init);
339+module_exit(fini);
340diff -NurpP --minimal linux-2.6.21.a/net/netfilter/Kconfig linux-2.6.21.b/net/netfilter/Kconfig
341--- linux-2.6.21.a/net/netfilter/Kconfig 2007-05-30 11:13:04.000000000 +0200
342+++ linux-2.6.21.b/net/netfilter/Kconfig 2007-05-30 11:50:55.000000000 +0200
343@@ -271,6 +271,18 @@ config NF_CONNTRACK_TFTP
344
345 To compile it as a module, choose M here. If unsure, say N.
346
347+config NF_CONNTRACK_MMS
348+ tristate 'MMS protocol support'
349+ depends on NF_CONNTRACK
350+ help
351+ Tracking MMS (Microsoft Windows Media Services) connections
352+ could be problematic if random ports are used to send the
353+ streaming content. This option allows users to track streaming
354+ connections over random UDP or TCP ports.
355+
356+ If you want to compile it as a module, say M here and read
357+ <file:Documentation/modules.txt>. If unsure, say `Y'.
358+
359 config NF_CT_NETLINK
360 tristate 'Connection tracking netlink interface (EXPERIMENTAL)'
361 depends on EXPERIMENTAL && NF_CONNTRACK && NETFILTER_NETLINK
362diff -NurpP --minimal linux-2.6.21.a/net/netfilter/Makefile linux-2.6.21.b/net/netfilter/Makefile
363--- linux-2.6.21.a/net/netfilter/Makefile 2007-05-30 11:13:04.000000000 +0200
364+++ linux-2.6.21.b/net/netfilter/Makefile 2007-05-30 11:50:55.000000000 +0200
365@@ -26,6 +26,7 @@ nf_conntrack_h323-objs := nf_conntrack_h
366 obj-$(CONFIG_NF_CONNTRACK_AMANDA) += nf_conntrack_amanda.o
367 obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o
368 obj-$(CONFIG_NF_CONNTRACK_H323) += nf_conntrack_h323.o
369+obj-$(CONFIG_NF_CONNTRACK_MMS) += nf_conntrack_mms.o
370 obj-$(CONFIG_NF_CONNTRACK_IRC) += nf_conntrack_irc.o
371 obj-$(CONFIG_NF_CONNTRACK_NETBIOS_NS) += nf_conntrack_netbios_ns.o
372 obj-$(CONFIG_NF_CONNTRACK_PPTP) += nf_conntrack_pptp.o
373diff -NurpP --minimal linux-2.6.21.a/net/netfilter/nf_conntrack_mms.c linux-2.6.21.b/net/netfilter/nf_conntrack_mms.c
374--- linux-2.6.21.a/net/netfilter/nf_conntrack_mms.c 1970-01-01 01:00:00.000000000 +0100
375+++ linux-2.6.21.b/net/netfilter/nf_conntrack_mms.c 2007-05-30 11:50:55.000000000 +0200
29ef6c7a 376@@ -0,0 +1,374 @@
6890440f 377+/* MMS extension for IP connection tracking
378+ * (C) 2002 by Filip Sneppe <filip.sneppe@cronos.be>
379+ * based on ip_conntrack_ftp.c and ip_conntrack_irc.c
380+ *
381+ * ip_conntrack_mms.c v0.3 2002-09-22
382+ *
383+ * This program is free software; you can redistribute it and/or
384+ * modify it under the terms of the GNU General Public License
385+ * as published by the Free Software Foundation; either version
386+ * 2 of the License, or (at your option) any later version.
387+ *
388+ * Module load syntax:
389+ * insmod nf_conntrack_mms.o ports=port1,port2,...port<MAX_PORTS>
390+ *
391+ * Please give the ports of all MMS servers You wish to connect to.
392+ * If you don't specify ports, the default will be TCP port 1755.
393+ *
394+ * More info on MMS protocol, firewalls and NAT:
395+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/MMSFirewall.asp
396+ * http://www.microsoft.com/windows/windowsmedia/serve/firewall.asp
397+ *
398+ * The SDP project people are reverse-engineering MMS:
399+ * http://get.to/sdp
400+ *
401+ * 2005-02-13: Harald Welte <laforge@netfilter.org>
402+ * - port to 2.6.x
403+ * - update to work with post 2.6.11 helper API changes
404+ *
405+ * 2007-03-30: Marek Guevara Braun <mguevara@pld-linux.org>
406+ * - port to nf_conntrack
407+ */
408+
409+
410+#include <linux/module.h>
411+#include <linux/netfilter.h>
412+#include <linux/ip.h>
413+#include <linux/ctype.h>
414+#include <net/checksum.h>
415+#include <net/tcp.h>
416+
417+#include <net/netfilter/nf_conntrack.h>
418+#include <net/netfilter/nf_conntrack_helper.h>
419+#include <net/netfilter/nf_conntrack_expect.h>
420+#include <linux/netfilter/nf_conntrack_mms.h>
421+
422+#define MAX_PORTS 8
423+static int ports[MAX_PORTS];
424+static int ports_c;
425+module_param_array(ports, int, &ports_c, 0400);
426+MODULE_PARM_DESC(ports, "port numbers of MMS");
427+
428+static char mms_buffer[65536];
429+static DEFINE_SPINLOCK(mms_buffer_lock);
430+
431+unsigned int (*nf_nat_mms_hook)(struct sk_buff **pskb,
432+ enum ip_conntrack_info ctinfo,
433+ const struct nf_ct_mms_expect *exp_mms_info,
434+ struct nf_conntrack_expect *exp);
435+EXPORT_SYMBOL(nf_nat_mms_hook);
436+
437+#if 0
438+#define DEBUGP printk
439+#else
440+#define DEBUGP(format, args...)
441+#endif
442+
443+MODULE_AUTHOR("Filip Sneppe <filip.sneppe@cronos.be>");
444+MODULE_DESCRIPTION("Microsoft Windows Media Services (MMS) connection tracking module");
445+MODULE_LICENSE("GPL");
446+
447+/* #define isdigit(c) (c >= '0' && c <= '9') */
448+
449+/* copied from drivers/usb/serial/io_edgeport.c - not perfect but will do the trick */
450+static void unicode_to_ascii (char *string, short *unicode, int unicode_size)
451+{
452+ int i;
453+ for (i = 0; i < unicode_size; ++i) {
454+ string[i] = (char)(unicode[i]);
455+ }
456+ string[unicode_size] = 0x00;
457+}
458+
459+__inline static int atoi(char *s)
460+{
461+ int i=0;
462+ while (isdigit(*s)) {
463+ i = i*10 + *(s++) - '0';
464+ }
465+ return i;
466+}
467+
468+/* convert ip address string like "192.168.0.10" to unsigned int */
469+__inline static u_int32_t asciiiptoi(char *s)
470+{
471+ unsigned int i, j, k;
472+
473+ for(i=k=0; k<3; ++k, ++s, i<<=8) {
474+ i+=atoi(s);
475+ for(j=0; (*(++s) != '.') && (j<3); ++j)
476+ ;
477+ }
478+ i+=atoi(s);
479+ return ntohl(i);
480+}
481+
482+int parse_mms(const char *data,
483+ const unsigned int datalen,
484+ u_int32_t *mms_ip,
485+ u_int16_t *mms_proto,
486+ u_int16_t *mms_port,
487+ char **mms_string_b,
488+ char **mms_string_e,
489+ char **mms_padding_e)
490+{
491+ int unicode_size, i;
492+ char tempstring[28]; /* "\\255.255.255.255\UDP\65535" */
493+ char getlengthstring[28];
494+
495+ for(unicode_size=0;
496+ (char) *(data+(MMS_SRV_UNICODE_STRING_OFFSET+unicode_size*2)) != (char)0;
497+ unicode_size++)
498+ if ((unicode_size == 28) || (MMS_SRV_UNICODE_STRING_OFFSET+unicode_size*2 >= datalen))
499+ return -1; /* out of bounds - incomplete packet */
500+
501+ unicode_to_ascii(tempstring, (short *)(data+MMS_SRV_UNICODE_STRING_OFFSET), unicode_size);
502+ DEBUGP("nf_conntrack_mms: offset 60: %s\n", (const char *)(tempstring));
503+
504+ /* IP address ? */
505+ *mms_ip = asciiiptoi(tempstring+2);
506+
507+ i=sprintf(getlengthstring, "%u.%u.%u.%u", HIPQUAD(*mms_ip));
508+
509+ /* protocol ? */
510+ if(strncmp(tempstring+3+i, "TCP", 3)==0)
511+ *mms_proto = IPPROTO_TCP;
512+ else if(strncmp(tempstring+3+i, "UDP", 3)==0)
513+ *mms_proto = IPPROTO_UDP;
514+
515+ /* port ? */
516+ *mms_port = atoi(tempstring+7+i);
517+
518+ /* we store a pointer to the beginning of the "\\a.b.c.d\proto\port"
519+ unicode string, one to the end of the string, and one to the end
520+ of the packet, since we must keep track of the number of bytes
521+ between end of the unicode string and the end of packet (padding) */
522+ *mms_string_b = (char *)(data + MMS_SRV_UNICODE_STRING_OFFSET);
523+ *mms_string_e = (char *)(data + MMS_SRV_UNICODE_STRING_OFFSET + unicode_size * 2);
524+ *mms_padding_e = (char *)(data + datalen); /* looks funny, doesn't it */
525+ return 0;
526+}
527+
528+
529+/* FIXME: This should be in userspace. Later. */
530+static int help(struct sk_buff **pskb,
531+ unsigned int protoff,
532+ struct nf_conn *ct,
533+ enum ip_conntrack_info ctinfo)
534+{
535+ int ret = NF_DROP;
536+ struct tcphdr _tcph, *th;
537+ char *data, *mb_ptr;
538+ unsigned int datalen, dataoff;
539+
540+
541+ //struct tcphdr *tcph = (void *)iph + iph->ihl * 4;
542+ //unsigned int tcplen = len - iph->ihl * 4;
543+ //unsigned int datalen = tcplen - tcph->doff * 4;
544+ int dir = CTINFO2DIR(ctinfo);
545+ struct nf_conntrack_expect *exp;
546+ struct nf_conntrack_tuple *tuple;
547+ struct nf_ct_mms_expect _emmi, *exp_mms_info = &_emmi;
548+
549+ u_int32_t mms_ip;
550+ u_int16_t mms_proto;
551+ char mms_proto_string[8];
552+ u_int16_t mms_port;
553+ __be16 port;
554+ char *mms_string_b, *mms_string_e, *mms_padding_e;
555+ typeof(nf_nat_mms_hook) nf_nat_mms;
556+
557+ /* Until there's been traffic both ways, don't look in packets. */
558+ if (ctinfo != IP_CT_ESTABLISHED &&
559+ ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
560+ DEBUGP("nf_conntrack_mms: Conntrackinfo = %u\n", ctinfo);
561+ return NF_ACCEPT;
562+ }
563+
564+ /* Not whole TCP header? */
565+ th = skb_header_pointer(*pskb, protoff, sizeof(_tcph), &_tcph);
566+ if (th == NULL)
567+ return NF_ACCEPT;
568+
569+ /* No data ? */
570+ dataoff = protoff + th->doff*4;
571+ if (dataoff >= (*pskb)->len)
572+ return NF_ACCEPT;
573+
574+ datalen = (*pskb)->len - dataoff;
575+ DEBUGP("nf_conntrack_mms: datalen:%u\n", datalen);
576+
577+ spin_lock_bh(&mms_buffer_lock);
578+ mb_ptr = skb_header_pointer(*pskb, dataoff,
579+ (*pskb)->len - dataoff, mms_buffer);
580+ BUG_ON(mb_ptr == NULL);
581+
582+ data = mb_ptr;
583+
584+#if 0
585+ /* Checksum invalid? Ignore. */
586+ /* FIXME: Source route IP option packets --RR */
587+ if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
588+ csum_partial((char *)tcph, tcplen, 0))) {
589+ DEBUGP("mms_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n",
590+ tcph, tcplen, NIPQUAD(iph->saddr),
591+ NIPQUAD(iph->daddr));
592+ return NF_ACCEPT;
593+ }
594+#endif
595+
596+ /* Only look at packets with 0x00030002/196610 on bytes 36->39 of TCP
597+ * payload */
598+
599+ /* FIXME: There is an issue with only looking at this packet: before
600+ * this packet, the client has already sent a packet to the server with
601+ * the server's hostname according to the client (think of it as the
602+ * "Host: " header in HTTP/1.1). The server will break the connection
603+ * if this doesn't correspond to its own host header. The client can
604+ * also connect to an IP address; if it's the server's IP address, it
605+ * will not break the connection. When doing DNAT on a connection where
606+ * the client uses a server's IP address, the nat module should detect
607+ * this and change this string accordingly to the DNATed address. This
608+ * should probably be done by checking for an IP address, then storing
609+ * it as a member of struct ip_ct_mms_expect and checking for it in
610+ * ip_nat_mms...
611+ */
612+ if ((MMS_SRV_MSG_OFFSET >= datalen) ||
613+ ((*(u32 *)(data+MMS_SRV_MSG_OFFSET)) != MMS_SRV_MSG_ID))
614+ goto out;
615+
616+ DEBUGP("nf_conntrack_mms: offset 37: %u %u %u %u, datalen:%u\n",
617+ (u8)*(data+36), (u8)*(data+37), (u8)*(data+38), (u8)*(data+39),
618+ datalen);
619+ if (parse_mms(data, datalen, &mms_ip, &mms_proto, &mms_port,
620+ &mms_string_b, &mms_string_e, &mms_padding_e))
621+ if (net_ratelimit())
622+ /* FIXME: more verbose debugging ? */
623+ printk(KERN_WARNING
624+ "nf_conntrack_mms: Unable to parse "
625+ "data payload\n");
626+
627+ sprintf(mms_proto_string, "(%u)", mms_proto);
628+ DEBUGP("nf_conntrack_mms: adding %s expectation "
629+ "%u.%u.%u.%u -> %u.%u.%u.%u:%u\n",
630+ mms_proto == IPPROTO_TCP ? "TCP"
631+ : mms_proto == IPPROTO_UDP ? "UDP":mms_proto_string,
632+ NIPQUAD(ct->tuplehash[!dir].tuple.src.ip),
633+ NIPQUAD(mms_ip),
634+ mms_port);
635+
636+ /* it's possible that the client will just ask the server to
637+ * tunnel the stream over the same TCP session (from port
638+ * 1755): there's shouldn't be a need to add an expectation in
639+ * that case, but it makes NAT packet mangling so much easier
640+ * */
641+
642+ DEBUGP("nf_conntrack_mms: tcph->seq = %u\n", tcph->seq);
643+
155c0b71 644+ exp = nf_ct_expect_alloc(ct);
6890440f 645+ if (exp == NULL) {
646+ ret = NF_DROP;
647+ goto out;
648+ }
649+
650+ exp_mms_info->offset = (mms_string_b - data);
651+ exp_mms_info->len = (mms_string_e - mms_string_b);
652+ exp_mms_info->padding = (mms_padding_e - mms_string_e);
653+ exp_mms_info->port = mms_port;
654+
655+ DEBUGP("nf_conntrack_mms: wrote info seq=%u (ofs=%u), "
656+ "len=%d, padding=%u\n", exp->seq, (mms_string_e - data),
657+ exp_mms_info->len, exp_mms_info->padding);
658+
659+ tuple = &ct->tuplehash[!dir].tuple;
660+ port = htons(mms_port);
29ef6c7a 661+ nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, tuple->src.l3num,
6890440f 662+ NULL, &tuple->dst.u3,
663+ IPPROTO_TCP, NULL, &port);
664+
665+ nf_nat_mms = rcu_dereference(nf_nat_mms_hook);
666+ if (nf_nat_mms && ct->status & IPS_NAT_MASK)
667+ ret = nf_nat_mms(pskb, ctinfo, exp_mms_info, exp);
155c0b71 668+ else if (nf_ct_expect_related(exp) != 0)
6890440f 669+ ret = NF_DROP;
155c0b71 670+ nf_ct_expect_put(exp);
6890440f 671+/*
672+ exp->tuple = ((struct nf_conntrack_tuple)
673+ { { ct->tuplehash[!dir].tuple.src.u3.ip, { 0 } },
674+ { mms_ip,
675+ { .tcp = { (__u16) ntohs(mms_port) } },
676+ mms_proto } }
677+ );
678+ exp->mask = ((struct nf_conntrack_tuple)
679+ { { 0xFFFFFFFF, { 0 } },
680+ { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
681+ exp->expectfn = NULL;
682+ exp->master = ct;
683+
684+ if (nf_nat_mms_hook)
685+ ret = nf_nat_mms_hook(pskb, ctinfo, exp_mms_info, exp);
686+ else if (nf_conntrack_expect_related(exp) != 0)
687+ ret = NF_DROP;
688+
689+ nf_conntrack_expect_put(exp);
690+*/
691+out:
692+ spin_unlock_bh(&mms_buffer_lock);
693+ return ret;
694+}
695+
696+static struct nf_conntrack_helper mms[MAX_PORTS];
697+static char mms_names[MAX_PORTS][10];
29ef6c7a 698+static const struct nf_conntrack_expect_policy mms_exp_policy = {
699+ .max_expected = 1,
700+ .timeout = 120,
701+};
6890440f 702+
703+/* Not __exit: called from init() */
704+static void fini(void)
705+{
706+ int i;
707+ for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
708+ DEBUGP("nf_conntrack_mms: unregistering helper for port %d\n",
709+ ports[i]);
710+ nf_conntrack_helper_unregister(&mms[i]);
711+ }
712+}
713+
714+static int __init init(void)
715+{
716+ int i, ret;
717+ char *tmpname;
718+
719+ if (ports[0] == 0)
720+ ports[0] = MMS_PORT;
721+
722+ for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
723+ memset(&mms[i], 0, sizeof(struct nf_conntrack_helper));
724+ mms[i].tuple.src.u.tcp.port = htons(ports[i]);
725+ mms[i].tuple.dst.protonum = IPPROTO_TCP;
6890440f 726+ mms[i].me = THIS_MODULE;
29ef6c7a 727+ mms[i].expect_policy = &mms_exp_policy;
6890440f 728+ mms[i].help = help;
729+
730+ tmpname = &mms_names[i][0];
731+ if (ports[i] == MMS_PORT)
732+ sprintf(tmpname, "mms");
733+ else
734+ sprintf(tmpname, "mms-%d", ports[i]);
735+ mms[i].name = tmpname;
736+
737+ DEBUGP("nf_conntrack_mms: registering helper for port %d\n",
738+ ports[i]);
739+ ret = nf_conntrack_helper_register(&mms[i]);
740+
741+ if (ret) {
742+ fini();
743+ return ret;
744+ }
745+ ports_c++;
746+ }
747+ return 0;
748+}
749+
750+module_init(init);
751+module_exit(fini);
This page took 0.271002 seconds and 4 git commands to generate.