From e42433d7127f9a50b5dae57fff331ecfdc9883c4 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Tue, 27 Apr 2010 20:58:44 +0200 Subject: iptv via natting now works at last sometime. alice iptv seems to use destination=ip:port instead of client_port=port, like RFC suggesting it. But destination= is also used by STUN method. As a quick hack I commented out STUN method to avoid crashes. Now at least I can see some tv streams. still not 100% good. --- target/linux/config/Config.in.netfilter | 1 + target/linux/config/Config.in.netfilter.core | 10 +- target/linux/patches/2.6.33/rtsp.patch | 2316 -------------------------- 3 files changed, 6 insertions(+), 2321 deletions(-) delete mode 100644 target/linux/patches/2.6.33/rtsp.patch (limited to 'target/linux') diff --git a/target/linux/config/Config.in.netfilter b/target/linux/config/Config.in.netfilter index cb71b6551..dbc686b0a 100644 --- a/target/linux/config/Config.in.netfilter +++ b/target/linux/config/Config.in.netfilter @@ -156,6 +156,7 @@ endmenu menu "Netfilter Addons" source package/ipset/Config.in.kmod +source package/rtsp/Config.in.kmod endmenu endmenu diff --git a/target/linux/config/Config.in.netfilter.core b/target/linux/config/Config.in.netfilter.core index 0231b2d13..e2e9a2bbb 100644 --- a/target/linux/config/Config.in.netfilter.core +++ b/target/linux/config/Config.in.netfilter.core @@ -82,11 +82,11 @@ config ADK_KPACKAGE_KMOD_NF_CONNTRACK_FTP required for tracking them, and doing masquerading and other forms of Network Address Translation on them. -config ADK_KPACKAGE_KMOD_NF_CONNTRACK_RTSP - tristate 'RTSP protocol support' - depends on ADK_KPACKAGE_KMOD_NF_CONNTRACK - help - Tracking RTSP connections might be required for IPTV. +#config ADK_KPACKAGE_KMOD_NF_CONNTRACK_RTSP +# tristate 'RTSP protocol support' +# depends on ADK_KPACKAGE_KMOD_NF_CONNTRACK +# help +# Tracking RTSP connections might be required for IPTV. config ADK_KPACKAGE_KMOD_NF_CONNTRACK_IRC tristate 'IRC protocol support' diff --git a/target/linux/patches/2.6.33/rtsp.patch b/target/linux/patches/2.6.33/rtsp.patch deleted file mode 100644 index 317c06d8e..000000000 --- a/target/linux/patches/2.6.33/rtsp.patch +++ /dev/null @@ -1,2316 +0,0 @@ -diff -Nur linux-2.6.33.orig/include/linux/netfilter/nf_conntrack_rtsp.h linux-2.6.33/include/linux/netfilter/nf_conntrack_rtsp.h ---- linux-2.6.33.orig/include/linux/netfilter/nf_conntrack_rtsp.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.33/include/linux/netfilter/nf_conntrack_rtsp.h 2010-04-25 01:09:20.000000000 +0200 -@@ -0,0 +1,63 @@ -+/* -+ * RTSP extension for IP connection tracking. -+ * (C) 2003 by Tom Marshall -+ * based on ip_conntrack_irc.h -+ * -+ * 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. -+ */ -+#ifndef _IP_CONNTRACK_RTSP_H -+#define _IP_CONNTRACK_RTSP_H -+ -+//#define IP_NF_RTSP_DEBUG 1 -+#define IP_NF_RTSP_VERSION "0.6.21" -+ -+#ifdef __KERNEL__ -+/* port block types */ -+typedef enum { -+ pb_single, /* client_port=x */ -+ pb_range, /* client_port=x-y */ -+ pb_discon /* client_port=x/y (rtspbis) */ -+} portblock_t; -+ -+/* We record seq number and length of rtsp headers here, all in host order. */ -+ -+/* -+ * This structure is per expected connection. It is a member of struct -+ * ip_conntrack_expect. The TCP SEQ for the conntrack expect is stored -+ * there and we are expected to only store the length of the data which -+ * needs replaced. If a packet contains multiple RTSP messages, we create -+ * one expected connection per message. -+ * -+ * We use these variables to mark the entire header block. This may seem -+ * like overkill, but the nature of RTSP requires it. A header may appear -+ * multiple times in a message. We must treat two Transport headers the -+ * same as one Transport header with two entries. -+ */ -+struct ip_ct_rtsp_expect -+{ -+ u_int32_t len; /* length of header block */ -+ portblock_t pbtype; /* Type of port block that was requested */ -+ u_int16_t loport; /* Port that was requested, low or first */ -+ u_int16_t hiport; /* Port that was requested, high or second */ -+#if 0 -+ uint method; /* RTSP method */ -+ uint cseq; /* CSeq from request */ -+#endif -+}; -+ -+extern unsigned int (*nf_nat_rtsp_hook)(struct sk_buff *skb, -+ enum ip_conntrack_info ctinfo, -+ unsigned int matchoff, unsigned int matchlen, -+ struct ip_ct_rtsp_expect *prtspexp, -+ struct nf_conntrack_expect *exp); -+ -+extern void (*nf_nat_rtsp_hook_expectfn)(struct nf_conn *ct, struct nf_conntrack_expect *exp); -+ -+#define RTSP_PORT 554 -+ -+#endif /* __KERNEL__ */ -+ -+#endif /* _IP_CONNTRACK_RTSP_H */ -diff -Nur linux-2.6.33.orig/include/linux/netfilter_helpers.h linux-2.6.33/include/linux/netfilter_helpers.h ---- linux-2.6.33.orig/include/linux/netfilter_helpers.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.33/include/linux/netfilter_helpers.h 2010-04-25 01:09:20.000000000 +0200 -@@ -0,0 +1,133 @@ -+/* -+ * Helpers for netfiler modules. This file provides implementations for basic -+ * functions such as strncasecmp(), etc. -+ * -+ * gcc will warn for defined but unused functions, so we only include the -+ * functions requested. The following macros are used: -+ * NF_NEED_STRNCASECMP nf_strncasecmp() -+ * NF_NEED_STRTOU16 nf_strtou16() -+ * NF_NEED_STRTOU32 nf_strtou32() -+ */ -+#ifndef _NETFILTER_HELPERS_H -+#define _NETFILTER_HELPERS_H -+ -+/* Only include these functions for kernel code. */ -+#ifdef __KERNEL__ -+ -+#include -+#define iseol(c) ( (c) == '\r' || (c) == '\n' ) -+ -+/* -+ * The standard strncasecmp() -+ */ -+#ifdef NF_NEED_STRNCASECMP -+static int -+nf_strncasecmp(const char* s1, const char* s2, u_int32_t len) -+{ -+ if (s1 == NULL || s2 == NULL) -+ { -+ if (s1 == NULL && s2 == NULL) -+ { -+ return 0; -+ } -+ return (s1 == NULL) ? -1 : 1; -+ } -+ while (len > 0 && tolower(*s1) == tolower(*s2)) -+ { -+ len--; -+ s1++; -+ s2++; -+ } -+ return ( (len == 0) ? 0 : (tolower(*s1) - tolower(*s2)) ); -+} -+#endif /* NF_NEED_STRNCASECMP */ -+ -+/* -+ * Parse a string containing a 16-bit unsigned integer. -+ * Returns the number of chars used, or zero if no number is found. -+ */ -+#ifdef NF_NEED_STRTOU16 -+static int -+nf_strtou16(const char* pbuf, u_int16_t* pval) -+{ -+ int n = 0; -+ -+ *pval = 0; -+ while (isdigit(pbuf[n])) -+ { -+ *pval = (*pval * 10) + (pbuf[n] - '0'); -+ n++; -+ } -+ -+ return n; -+} -+#endif /* NF_NEED_STRTOU16 */ -+ -+/* -+ * Parse a string containing a 32-bit unsigned integer. -+ * Returns the number of chars used, or zero if no number is found. -+ */ -+#ifdef NF_NEED_STRTOU32 -+static int -+nf_strtou32(const char* pbuf, u_int32_t* pval) -+{ -+ int n = 0; -+ -+ *pval = 0; -+ while (pbuf[n] >= '0' && pbuf[n] <= '9') -+ { -+ *pval = (*pval * 10) + (pbuf[n] - '0'); -+ n++; -+ } -+ -+ return n; -+} -+#endif /* NF_NEED_STRTOU32 */ -+ -+/* -+ * Given a buffer and length, advance to the next line and mark the current -+ * line. -+ */ -+#ifdef NF_NEED_NEXTLINE -+static int -+nf_nextline(char* p, uint len, uint* poff, uint* plineoff, uint* plinelen) -+{ -+ uint off = *poff; -+ uint physlen = 0; -+ -+ if (off >= len) -+ { -+ return 0; -+ } -+ -+ while (p[off] != '\n') -+ { -+ if (len-off <= 1) -+ { -+ return 0; -+ } -+ -+ physlen++; -+ off++; -+ } -+ -+ /* if we saw a crlf, physlen needs adjusted */ -+ if (physlen > 0 && p[off] == '\n' && p[off-1] == '\r') -+ { -+ physlen--; -+ } -+ -+ /* advance past the newline */ -+ off++; -+ -+ *plineoff = *poff; -+ *plinelen = physlen; -+ *poff = off; -+ -+ return 1; -+} -+#endif /* NF_NEED_NEXTLINE */ -+ -+#endif /* __KERNEL__ */ -+ -+#endif /* _NETFILTER_HELPERS_H */ -diff -Nur linux-2.6.33.orig/include/linux/netfilter_mime.h linux-2.6.33/include/linux/netfilter_mime.h ---- linux-2.6.33.orig/include/linux/netfilter_mime.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.33/include/linux/netfilter_mime.h 2010-04-25 01:09:20.000000000 +0200 -@@ -0,0 +1,89 @@ -+/* -+ * MIME functions for netfilter modules. This file provides implementations -+ * for basic MIME parsing. MIME headers are used in many protocols, such as -+ * HTTP, RTSP, SIP, etc. -+ * -+ * gcc will warn for defined but unused functions, so we only include the -+ * functions requested. The following macros are used: -+ * NF_NEED_MIME_NEXTLINE nf_mime_nextline() -+ */ -+#ifndef _NETFILTER_MIME_H -+#define _NETFILTER_MIME_H -+ -+/* Only include these functions for kernel code. */ -+#ifdef __KERNEL__ -+ -+#include -+ -+/* -+ * Given a buffer and length, advance to the next line and mark the current -+ * line. If the current line is empty, *plinelen will be set to zero. If -+ * not, it will be set to the actual line length (including CRLF). -+ * -+ * 'line' in this context means logical line (includes LWS continuations). -+ * Returns 1 on success, 0 on failure. -+ */ -+#ifdef NF_NEED_MIME_NEXTLINE -+static int -+nf_mime_nextline(char* p, uint len, uint* poff, uint* plineoff, uint* plinelen) -+{ -+ uint off = *poff; -+ uint physlen = 0; -+ int is_first_line = 1; -+ -+ if (off >= len) -+ { -+ return 0; -+ } -+ -+ do -+ { -+ while (p[off] != '\n') -+ { -+ if (len-off <= 1) -+ { -+ return 0; -+ } -+ -+ physlen++; -+ off++; -+ } -+ -+ /* if we saw a crlf, physlen needs adjusted */ -+ if (physlen > 0 && p[off] == '\n' && p[off-1] == '\r') -+ { -+ physlen--; -+ } -+ -+ /* advance past the newline */ -+ off++; -+ -+ /* check for an empty line */ -+ if (physlen == 0) -+ { -+ break; -+ } -+ -+ /* check for colon on the first physical line */ -+ if (is_first_line) -+ { -+ is_first_line = 0; -+ if (memchr(p+(*poff), ':', physlen) == NULL) -+ { -+ return 0; -+ } -+ } -+ } -+ while (p[off] == ' ' || p[off] == '\t'); -+ -+ *plineoff = *poff; -+ *plinelen = (physlen == 0) ? 0 : (off - *poff); -+ *poff = off; -+ -+ return 1; -+} -+#endif /* NF_NEED_MIME_NEXTLINE */ -+ -+#endif /* __KERNEL__ */ -+ -+#endif /* _NETFILTER_MIME_H */ -diff -Nur linux-2.6.33.orig/net/ipv4/netfilter/Kconfig linux-2.6.33/net/ipv4/netfilter/Kconfig ---- linux-2.6.33.orig/net/ipv4/netfilter/Kconfig 2010-02-24 19:52:17.000000000 +0100 -+++ linux-2.6.33/net/ipv4/netfilter/Kconfig 2010-04-25 01:09:20.000000000 +0200 -@@ -257,6 +257,11 @@ - depends on NF_CONNTRACK && NF_NAT - default NF_NAT && NF_CONNTRACK_IRC - -+config NF_NAT_RTSP -+ tristate -+ depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT -+ default NF_NAT && NF_CONNTRACK_RTSP -+ - config NF_NAT_TFTP - tristate - depends on NF_CONNTRACK && NF_NAT -diff -Nur linux-2.6.33.orig/net/ipv4/netfilter/Makefile linux-2.6.33/net/ipv4/netfilter/Makefile ---- linux-2.6.33.orig/net/ipv4/netfilter/Makefile 2010-02-24 19:52:17.000000000 +0100 -+++ linux-2.6.33/net/ipv4/netfilter/Makefile 2010-04-25 01:09:20.000000000 +0200 -@@ -26,6 +26,7 @@ - obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o - obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o - obj-$(CONFIG_NF_NAT_IRC) += nf_nat_irc.o -+obj-$(CONFIG_NF_NAT_RTSP) += nf_nat_rtsp.o - obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o - obj-$(CONFIG_NF_NAT_SIP) += nf_nat_sip.o - obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o -diff -Nur linux-2.6.33.orig/net/ipv4/netfilter/nf_nat_rtsp.c linux-2.6.33/net/ipv4/netfilter/nf_nat_rtsp.c ---- linux-2.6.33.orig/net/ipv4/netfilter/nf_nat_rtsp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.33/net/ipv4/netfilter/nf_nat_rtsp.c 2010-04-25 01:09:20.000000000 +0200 -@@ -0,0 +1,496 @@ -+/* -+ * RTSP extension for TCP NAT alteration -+ * (C) 2003 by Tom Marshall -+ * based on ip_nat_irc.c -+ * -+ * 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. -+ * -+ * Module load syntax: -+ * insmod nf_nat_rtsp.o ports=port1,port2,...port -+ * stunaddr=
-+ * destaction=[auto|strip|none] -+ * -+ * If no ports are specified, the default will be port 554 only. -+ * -+ * stunaddr specifies the address used to detect that a client is using STUN. -+ * If this address is seen in the destination parameter, it is assumed that -+ * the client has already punched a UDP hole in the firewall, so we don't -+ * mangle the client_port. If none is specified, it is autodetected. It -+ * only needs to be set if you have multiple levels of NAT. It should be -+ * set to the external address that the STUN clients detect. Note that in -+ * this case, it will not be possible for clients to use UDP with servers -+ * between the NATs. -+ * -+ * If no destaction is specified, auto is used. -+ * destaction=auto: strip destination parameter if it is not stunaddr. -+ * destaction=strip: always strip destination parameter (not recommended). -+ * destaction=none: do not touch destination parameter (not recommended). -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#define NF_NEED_STRNCASECMP -+#define NF_NEED_STRTOU16 -+#include -+#define NF_NEED_MIME_NEXTLINE -+#include -+ -+#define INFOP(fmt, args...) printk(KERN_INFO "%s: %s: " fmt, __FILE__, __FUNCTION__ , ## args) -+#if 0 -+#define DEBUGP(fmt, args...) printk(KERN_DEBUG "%s: %s: " fmt, __FILE__, __FUNCTION__ , ## args) -+#else -+#define DEBUGP(fmt, args...) -+#endif -+ -+#define MAX_PORTS 8 -+#define DSTACT_AUTO 0 -+#define DSTACT_STRIP 1 -+#define DSTACT_NONE 2 -+ -+static char* stunaddr = NULL; -+static char* destaction = NULL; -+ -+static u_int32_t extip = 0; -+static int dstact = 0; -+ -+MODULE_AUTHOR("Tom Marshall "); -+MODULE_DESCRIPTION("RTSP network address translation module"); -+MODULE_LICENSE("GPL"); -+module_param(stunaddr, charp, 0644); -+MODULE_PARM_DESC(stunaddr, "Address for detecting STUN"); -+module_param(destaction, charp, 0644); -+MODULE_PARM_DESC(destaction, "Action for destination parameter (auto/strip/none)"); -+ -+#define SKIP_WSPACE(ptr,len,off) while(off < len && isspace(*(ptr+off))) { off++; } -+ -+/*** helper functions ***/ -+ -+static void -+get_skb_tcpdata(struct sk_buff* skb, char** pptcpdata, uint* ptcpdatalen) -+{ -+ struct iphdr* iph = ip_hdr(skb); -+ struct tcphdr* tcph = (void *)iph + ip_hdrlen(skb); -+ -+ *pptcpdata = (char*)tcph + tcph->doff*4; -+ *ptcpdatalen = ((char*)skb_transport_header(skb) + skb->len) - *pptcpdata; -+} -+ -+/*** nat functions ***/ -+ -+/* -+ * Mangle the "Transport:" header: -+ * - Replace all occurences of "client_port=" -+ * - Handle destination parameter -+ * -+ * In: -+ * ct, ctinfo = conntrack context -+ * skb = packet -+ * tranoff = Transport header offset from TCP data -+ * tranlen = Transport header length (incl. CRLF) -+ * rport_lo = replacement low port (host endian) -+ * rport_hi = replacement high port (host endian) -+ * -+ * Returns packet size difference. -+ * -+ * Assumes that a complete transport header is present, ending with CR or LF -+ */ -+static int -+rtsp_mangle_tran(enum ip_conntrack_info ctinfo, -+ struct nf_conntrack_expect* exp, -+ struct ip_ct_rtsp_expect* prtspexp, -+ struct sk_buff* skb, uint tranoff, uint tranlen) -+{ -+ char* ptcp; -+ uint tcplen; -+ char* ptran; -+ char rbuf1[16]; /* Replacement buffer (one port) */ -+ uint rbuf1len; /* Replacement len (one port) */ -+ char rbufa[16]; /* Replacement buffer (all ports) */ -+ uint rbufalen; /* Replacement len (all ports) */ -+ u_int32_t newip; -+ u_int16_t loport, hiport; -+ uint off = 0; -+ uint diff; /* Number of bytes we removed */ -+ -+ struct nf_conn *ct = exp->master; -+ struct nf_conntrack_tuple *t; -+ -+ char szextaddr[15+1]; -+ uint extaddrlen; -+ int is_stun; -+ -+ get_skb_tcpdata(skb, &ptcp, &tcplen); -+ ptran = ptcp+tranoff; -+ -+ if (tranoff+tranlen > tcplen || tcplen-tranoff < tranlen || -+ tranlen < 10 || !iseol(ptran[tranlen-1]) || -+ nf_strncasecmp(ptran, "Transport:", 10) != 0) -+ { -+ INFOP("sanity check failed\n"); -+ return 0; -+ } -+ off += 10; -+ SKIP_WSPACE(ptcp+tranoff, tranlen, off); -+ -+ newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip; -+ t = &exp->tuple; -+ t->dst.u3.ip = newip; -+ -+ extaddrlen = extip ? sprintf(szextaddr, "%u.%u.%u.%u", NIPQUAD(extip)) -+ : sprintf(szextaddr, "%u.%u.%u.%u", NIPQUAD(newip)); -+ DEBUGP("stunaddr=%s (%s)\n", szextaddr, (extip?"forced":"auto")); -+ -+ rbuf1len = rbufalen = 0; -+ switch (prtspexp->pbtype) -+ { -+ case pb_single: -+ for (loport = prtspexp->loport; loport != 0; loport++) /* XXX: improper wrap? */ -+ { -+ t->dst.u.udp.port = htons(loport); -+ if (nf_ct_expect_related(exp) == 0) -+ { -+ DEBUGP("using port %hu\n", loport); -+ break; -+ } -+ } -+ if (loport != 0) -+ { -+ rbuf1len = sprintf(rbuf1, "%hu", loport); -+ rbufalen = sprintf(rbufa, "%hu", loport); -+ } -+ break; -+ case pb_range: -+ for (loport = prtspexp->loport; loport != 0; loport += 2) /* XXX: improper wrap? */ -+ { -+ t->dst.u.udp.port = htons(loport); -+ if (nf_ct_expect_related(exp) == 0) -+ { -+ hiport = loport + ~exp->mask.src.u.udp.port; -+ DEBUGP("using ports %hu-%hu\n", loport, hiport); -+ break; -+ } -+ } -+ if (loport != 0) -+ { -+ rbuf1len = sprintf(rbuf1, "%hu", loport); -+ rbufalen = sprintf(rbufa, "%hu-%hu", loport, loport+1); -+ } -+ break; -+ case pb_discon: -+ for (loport = prtspexp->loport; loport != 0; loport++) /* XXX: improper wrap? */ -+ { -+ t->dst.u.udp.port = htons(loport); -+ if (nf_ct_expect_related(exp) == 0) -+ { -+ DEBUGP("using port %hu (1 of 2)\n", loport); -+ break; -+ } -+ } -+ for (hiport = prtspexp->hiport; hiport != 0; hiport++) /* XXX: improper wrap? */ -+ { -+ t->dst.u.udp.port = htons(hiport); -+ if (nf_ct_expect_related(exp) == 0) -+ { -+ DEBUGP("using port %hu (2 of 2)\n", hiport); -+ break; -+ } -+ } -+ if (loport != 0 && hiport != 0) -+ { -+ rbuf1len = sprintf(rbuf1, "%hu", loport); -+ if (hiport == loport+1) -+ { -+ rbufalen = sprintf(rbufa, "%hu-%hu", loport, hiport); -+ } -+ else -+ { -+ rbufalen = sprintf(rbufa, "%hu/%hu", loport, hiport); -+ } -+ } -+ break; -+ } -+ -+ if (rbuf1len == 0) -+ { -+ return 0; /* cannot get replacement port(s) */ -+ } -+ -+ /* Transport: tran;field;field=val,tran;field;field=val,... */ -+ while (off < tranlen) -+ { -+ uint saveoff; -+ const char* pparamend; -+ uint nextparamoff; -+ -+ pparamend = memchr(ptran+off, ',', tranlen-off); -+ pparamend = (pparamend == NULL) ? ptran+tranlen : pparamend+1; -+ nextparamoff = pparamend-ptcp; -+ -+ /* -+ * We pass over each param twice. On the first pass, we look for a -+ * destination= field. It is handled by the security policy. If it -+ * is present, allowed, and equal to our external address, we assume -+ * that STUN is being used and we leave the client_port= field alone. -+ */ -+ is_stun = 0; -+ saveoff = off; -+ while (off < nextparamoff) -+ { -+ const char* pfieldend; -+ uint nextfieldoff; -+ -+ pfieldend = memchr(ptran+off, ';', nextparamoff-off); -+ nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1; -+ -+ if (dstact != DSTACT_NONE && strncmp(ptran+off, "destination=", 12) == 0) -+ { -+ if (strncmp(ptran+off+12, szextaddr, extaddrlen) == 0) -+ { -+ is_stun = 1; -+ } -+ if (dstact == DSTACT_STRIP || (dstact == DSTACT_AUTO && !is_stun)) -+ { -+ diff = nextfieldoff-off; -+ if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, -+ off, diff, NULL, 0)) -+ { -+ /* mangle failed, all we can do is bail */ -+ nf_ct_unexpect_related(exp); -+ return 0; -+ } -+ get_skb_tcpdata(skb, &ptcp, &tcplen); -+ ptran = ptcp+tranoff; -+ tranlen -= diff; -+ nextparamoff -= diff; -+ nextfieldoff -= diff; -+ } -+ } -+ -+ off = nextfieldoff; -+ } -+ if (is_stun) -+ { -+ continue; -+ } -+ off = saveoff; -+ while (off < nextparamoff) -+ { -+ const char* pfieldend; -+ uint nextfieldoff; -+ -+ pfieldend = memchr(ptran+off, ';', nextparamoff-off); -+ nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1; -+ -+ if (strncmp(ptran+off, "client_port=", 12) == 0) -+ { -+ u_int16_t port; -+ uint numlen; -+ uint origoff; -+ uint origlen; -+ char* rbuf = rbuf1; -+ uint rbuflen = rbuf1len; -+ -+ off += 12; -+ origoff = (ptran-ptcp)+off; -+ origlen = 0; -+ numlen = nf_strtou16(ptran+off, &port); -+ off += numlen; -+ origlen += numlen; -+ if (port != prtspexp->loport) -+ { -+ DEBUGP("multiple ports found, port %hu ignored\n", port); -+ } -+ else -+ { -+ if (ptran[off] == '-' || ptran[off] == '/') -+ { -+ off++; -+ origlen++; -+ numlen = nf_strtou16(ptran+off, &port); -+ off += numlen; -+ origlen += numlen; -+ rbuf = rbufa; -+ rbuflen = rbufalen; -+ } -+ -+ /* -+ * note we cannot just memcpy() if the sizes are the same. -+ * the mangle function does skb resizing, checks for a -+ * cloned skb, and updates the checksums. -+ * -+ * parameter 4 below is offset from start of tcp data. -+ */ -+ diff = origlen-rbuflen; -+ if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, -+ origoff, origlen, rbuf, rbuflen)) -+ { -+ /* mangle failed, all we can do is bail */ -+ nf_ct_unexpect_related(exp); -+ return 0; -+ } -+ get_skb_tcpdata(skb, &ptcp, &tcplen); -+ ptran = ptcp+tranoff; -+ tranlen -= diff; -+ nextparamoff -= diff; -+ nextfieldoff -= diff; -+ } -+ } -+ -+ off = nextfieldoff; -+ } -+ -+ off = nextparamoff; -+ } -+ -+ return 1; -+} -+ -+static uint -+help_out(struct sk_buff *skb, enum ip_conntrack_info ctinfo, -+ unsigned int matchoff, unsigned int matchlen, struct ip_ct_rtsp_expect* prtspexp, -+ struct nf_conntrack_expect* exp) -+{ -+ char* ptcp; -+ uint tcplen; -+ uint hdrsoff; -+ uint hdrslen; -+ uint lineoff; -+ uint linelen; -+ uint off; -+ -+ //struct iphdr* iph = (struct iphdr*)skb->nh.iph; -+ //struct tcphdr* tcph = (struct tcphdr*)((void*)iph + iph->ihl*4); -+ -+ get_skb_tcpdata(skb, &ptcp, &tcplen); -+ hdrsoff = matchoff;//exp->seq - ntohl(tcph->seq); -+ hdrslen = matchlen; -+ off = hdrsoff; -+ DEBUGP("NAT rtsp help_out\n"); -+ -+ while (nf_mime_nextline(ptcp, hdrsoff+hdrslen, &off, &lineoff, &linelen)) -+ { -+ if (linelen == 0) -+ { -+ break; -+ } -+ if (off > hdrsoff+hdrslen) -+ { -+ INFOP("!! overrun !!"); -+ break; -+ } -+ DEBUGP("hdr: len=%u, %.*s", linelen, (int)linelen, ptcp+lineoff); -+ -+ if (nf_strncasecmp(ptcp+lineoff, "Transport:", 10) == 0) -+ { -+ uint oldtcplen = tcplen; -+ DEBUGP("hdr: Transport\n"); -+ if (!rtsp_mangle_tran(ctinfo, exp, prtspexp, skb, lineoff, linelen)) -+ { -+ DEBUGP("hdr: Transport mangle failed"); -+ break; -+ } -+ get_skb_tcpdata(skb, &ptcp, &tcplen); -+ hdrslen -= (oldtcplen-tcplen); -+ off -= (oldtcplen-tcplen); -+ lineoff -= (oldtcplen-tcplen); -+ linelen -= (oldtcplen-tcplen); -+ DEBUGP("rep: len=%u, %.*s", linelen, (int)linelen, ptcp+lineoff); -+ } -+ } -+ -+ return NF_ACCEPT; -+} -+ -+static unsigned int -+help(struct sk_buff *skb, enum ip_conntrack_info ctinfo, -+ unsigned int matchoff, unsigned int matchlen, struct ip_ct_rtsp_expect* prtspexp, -+ struct nf_conntrack_expect* exp) -+{ -+ int dir = CTINFO2DIR(ctinfo); -+ int rc = NF_ACCEPT; -+ -+ switch (dir) -+ { -+ case IP_CT_DIR_ORIGINAL: -+ rc = help_out(skb, ctinfo, matchoff, matchlen, prtspexp, exp); -+ break; -+ case IP_CT_DIR_REPLY: -+ DEBUGP("unmangle ! %u\n", ctinfo); -+ /* XXX: unmangle */ -+ rc = NF_ACCEPT; -+ break; -+ } -+ //UNLOCK_BH(&ip_rtsp_lock); -+ -+ return rc; -+} -+ -+static void expected(struct nf_conn* ct, struct nf_conntrack_expect *exp) -+{ -+ struct nf_nat_multi_range_compat mr; -+ u_int32_t newdstip, newsrcip, newip; -+ -+ struct nf_conn *master = ct->master; -+ -+ newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip; -+ newsrcip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip; -+ //FIXME (how to port that ?) -+ //code from 2.4 : newip = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) ? newsrcip : newdstip; -+ newip = newdstip; -+ -+ DEBUGP("newsrcip=%u.%u.%u.%u, newdstip=%u.%u.%u.%u, newip=%u.%u.%u.%u\n", -+ NIPQUAD(newsrcip), NIPQUAD(newdstip), NIPQUAD(newip)); -+ -+ mr.rangesize = 1; -+ // We don't want to manip the per-protocol, just the IPs. -+ mr.range[0].flags = IP_NAT_RANGE_MAP_IPS; -+ mr.range[0].min_ip = mr.range[0].max_ip = newip; -+ -+ nf_nat_setup_info(ct, &mr.range[0], IP_NAT_MANIP_DST); -+} -+ -+ -+static void __exit fini(void) -+{ -+ nf_nat_rtsp_hook = NULL; -+ nf_nat_rtsp_hook_expectfn = NULL; -+ synchronize_net(); -+} -+ -+static int __init init(void) -+{ -+ printk("nf_nat_rtsp v" IP_NF_RTSP_VERSION " loading\n"); -+ -+ BUG_ON(nf_nat_rtsp_hook); -+ nf_nat_rtsp_hook = help; -+ nf_nat_rtsp_hook_expectfn = &expected; -+ -+ if (stunaddr != NULL) -+ extip = in_aton(stunaddr); -+ -+ if (destaction != NULL) { -+ if (strcmp(destaction, "auto") == 0) -+ dstact = DSTACT_AUTO; -+ -+ if (strcmp(destaction, "strip") == 0) -+ dstact = DSTACT_STRIP; -+ -+ if (strcmp(destaction, "none") == 0) -+ dstact = DSTACT_NONE; -+ } -+ -+ return 0; -+} -+ -+module_init(init); -+module_exit(fini); -diff -Nur linux-2.6.33.orig/net/netfilter/Kconfig linux-2.6.33/net/netfilter/Kconfig ---- linux-2.6.33.orig/net/netfilter/Kconfig 2010-02-24 19:52:17.000000000 +0100 -+++ linux-2.6.33/net/netfilter/Kconfig 2010-04-25 01:09:20.000000000 +0200 -@@ -268,6 +268,16 @@ - - To compile it as a module, choose M here. If unsure, say N. - -+config NF_CONNTRACK_RTSP -+ tristate "RTSP protocol support" -+ depends on NF_CONNTRACK -+ help -+ Support the RTSP protocol. This allows UDP transports to be setup -+ properly, including RTP and RDT. -+ -+ If you want to compile it as a module, say 'M' here and read -+ Documentation/modules.txt. If unsure, say 'Y'. -+ - config NF_CT_NETLINK - tristate 'Connection tracking netlink interface' - select NETFILTER_NETLINK -diff -Nur linux-2.6.33.orig/net/netfilter/Kconfig.orig linux-2.6.33/net/netfilter/Kconfig.orig ---- linux-2.6.33.orig/net/netfilter/Kconfig.orig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.33/net/netfilter/Kconfig.orig 2010-02-24 19:52:17.000000000 +0100 -@@ -0,0 +1,937 @@ -+menu "Core Netfilter Configuration" -+ depends on NET && INET && NETFILTER -+ -+config NETFILTER_NETLINK -+ tristate -+ -+config NETFILTER_NETLINK_QUEUE -+ tristate "Netfilter NFQUEUE over NFNETLINK interface" -+ depends on NETFILTER_ADVANCED -+ select NETFILTER_NETLINK -+ help -+ If this option is enabled, the kernel will include support -+ for queueing packets via NFNETLINK. -+ -+config NETFILTER_NETLINK_LOG -+ tristate "Netfilter LOG over NFNETLINK interface" -+ default m if NETFILTER_ADVANCED=n -+ select NETFILTER_NETLINK -+ help -+ If this option is enabled, the kernel will include support -+ for logging packets via NFNETLINK. -+ -+ This obsoletes the existing ipt_ULOG and ebg_ulog mechanisms, -+ and is also scheduled to replace the old syslog-based ipt_LOG -+ and ip6t_LOG modules. -+ -+config NF_CONNTRACK -+ tristate "Netfilter connection tracking support" -+ default m if NETFILTER_ADVANCED=n -+ help -+ Connection tracking keeps a record of what packets have passed -+ through your machine, in order to figure out how they are related -+ into connections. -+ -+ This is required to do Masquerading or other kinds of Network -+ Address Translation. It can also be used to enhance packet -+ filtering (see `Connection state match support' below). -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+if NF_CONNTRACK -+ -+config NF_CT_ACCT -+ bool "Connection tracking flow accounting" -+ depends on NETFILTER_ADVANCED -+ help -+ If this option is enabled, the connection tracking code will -+ keep per-flow packet and byte counters. -+ -+ Those counters can be used for flow-based accounting or the -+ `connbytes' match. -+ -+ Please note that currently this option only sets a default state. -+ You may change it at boot time with nf_conntrack.acct=0/1 kernel -+ parameter or by loading the nf_conntrack module with acct=0/1. -+ -+ You may also disable/enable it on a running system with: -+ sysctl net.netfilter.nf_conntrack_acct=0/1 -+ -+ This option will be removed in 2.6.29. -+ -+ If unsure, say `N'. -+ -+config NF_CONNTRACK_MARK -+ bool 'Connection mark tracking support' -+ depends on NETFILTER_ADVANCED -+ help -+ This option enables support for connection marks, used by the -+ `CONNMARK' target and `connmark' match. Similar to the mark value -+ of packets, but this mark value is kept in the conntrack session -+ instead of the individual packets. -+ -+config NF_CONNTRACK_SECMARK -+ bool 'Connection tracking security mark support' -+ depends on NETWORK_SECMARK -+ default m if NETFILTER_ADVANCED=n -+ help -+ This option enables security markings to be applied to -+ connections. Typically they are copied to connections from -+ packets using the CONNSECMARK target and copied back from -+ connections to packets with the same target, with the packets -+ being originally labeled via SECMARK. -+ -+ If unsure, say 'N'. -+ -+config NF_CONNTRACK_EVENTS -+ bool "Connection tracking events" -+ depends on NETFILTER_ADVANCED -+ help -+ If this option is enabled, the connection tracking code will -+ provide a notifier chain that can be used by other kernel code -+ to get notified about changes in the connection tracking state. -+ -+ If unsure, say `N'. -+ -+config NF_CT_PROTO_DCCP -+ tristate 'DCCP protocol connection tracking support (EXPERIMENTAL)' -+ depends on EXPERIMENTAL -+ depends on NETFILTER_ADVANCED -+ default IP_DCCP -+ help -+ With this option enabled, the layer 3 independent connection -+ tracking code will be able to do state tracking on DCCP connections. -+ -+ If unsure, say 'N'. -+ -+config NF_CT_PROTO_GRE -+ tristate -+ -+config NF_CT_PROTO_SCTP -+ tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)' -+ depends on EXPERIMENTAL -+ depends on NETFILTER_ADVANCED -+ default IP_SCTP -+ help -+ With this option enabled, the layer 3 independent connection -+ tracking code will be able to do state tracking on SCTP connections. -+ -+ If you want to compile it as a module, say M here and read -+ . If unsure, say `N'. -+ -+config NF_CT_PROTO_UDPLITE -+ tristate 'UDP-Lite protocol connection tracking support' -+ depends on NETFILTER_ADVANCED -+ help -+ With this option enabled, the layer 3 independent connection -+ tracking code will be able to do state tracking on UDP-Lite -+ connections. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NF_CONNTRACK_AMANDA -+ tristate "Amanda backup protocol support" -+ depends on NETFILTER_ADVANCED -+ select TEXTSEARCH -+ select TEXTSEARCH_KMP -+ help -+ If you are running the Amanda backup package -+ on this machine or machines that will be MASQUERADED through this -+ machine, then you may want to enable this feature. This allows the -+ connection tracking and natting code to allow the sub-channels that -+ Amanda requires for communication of the backup data, messages and -+ index. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NF_CONNTRACK_FTP -+ tristate "FTP protocol support" -+ default m if NETFILTER_ADVANCED=n -+ help -+ Tracking FTP connections is problematic: special helpers are -+ required for tracking them, and doing masquerading and other forms -+ of Network Address Translation on them. -+ -+ This is FTP support on Layer 3 independent connection tracking. -+ Layer 3 independent connection tracking is experimental scheme -+ which generalize ip_conntrack to support other layer 3 protocols. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NF_CONNTRACK_H323 -+ tristate "H.323 protocol support" -+ depends on (IPV6 || IPV6=n) -+ depends on NETFILTER_ADVANCED -+ help -+ H.323 is a VoIP signalling protocol from ITU-T. As one of the most -+ important VoIP protocols, it is widely used by voice hardware and -+ software including voice gateways, IP phones, Netmeeting, OpenPhone, -+ Gnomemeeting, etc. -+ -+ With this module you can support H.323 on a connection tracking/NAT -+ firewall. -+ -+ This module supports RAS, Fast Start, H.245 Tunnelling, Call -+ Forwarding, RTP/RTCP and T.120 based audio, video, fax, chat, -+ whiteboard, file transfer, etc. For more information, please -+ visit http://nath323.sourceforge.net/. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NF_CONNTRACK_IRC -+ tristate "IRC protocol support" -+ default m if NETFILTER_ADVANCED=n -+ help -+ There is a commonly-used extension to IRC called -+ Direct Client-to-Client Protocol (DCC). This enables users to send -+ files to each other, and also chat to each other without the need -+ of a server. DCC Sending is used anywhere you send files over IRC, -+ and DCC Chat is most commonly used by Eggdrop bots. If you are -+ using NAT, this extension will enable you to send files and initiate -+ chats. Note that you do NOT need this extension to get files or -+ have others initiate chats, or everything else in IRC. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NF_CONNTRACK_NETBIOS_NS -+ tristate "NetBIOS name service protocol support" -+ depends on NETFILTER_ADVANCED -+ help -+ NetBIOS name service requests are sent as broadcast messages from an -+ unprivileged port and responded to with unicast messages to the -+ same port. This make them hard to firewall properly because connection -+ tracking doesn't deal with broadcasts. This helper tracks locally -+ originating NetBIOS name service requests and the corresponding -+ responses. It relies on correct IP address configuration, specifically -+ netmask and broadcast address. When properly configured, the output -+ of "ip address show" should look similar to this: -+ -+ $ ip -4 address show eth0 -+ 4: eth0: mtu 1500 qdisc pfifo_fast qlen 1000 -+ inet 172.16.2.252/24 brd 172.16.2.255 scope global eth0 -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NF_CONNTRACK_PPTP -+ tristate "PPtP protocol support" -+ depends on NETFILTER_ADVANCED -+ select NF_CT_PROTO_GRE -+ help -+ This module adds support for PPTP (Point to Point Tunnelling -+ Protocol, RFC2637) connection tracking and NAT. -+ -+ If you are running PPTP sessions over a stateful firewall or NAT -+ box, you may want to enable this feature. -+ -+ Please note that not all PPTP modes of operation are supported yet. -+ Specifically these limitations exist: -+ - Blindly assumes that control connections are always established -+ in PNS->PAC direction. This is a violation of RFC2637. -+ - Only supports a single call within each session -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NF_CONNTRACK_SANE -+ tristate "SANE protocol support (EXPERIMENTAL)" -+ depends on EXPERIMENTAL -+ depends on NETFILTER_ADVANCED -+ help -+ SANE is a protocol for remote access to scanners as implemented -+ by the 'saned' daemon. Like FTP, it uses separate control and -+ data connections. -+ -+ With this module you can support SANE on a connection tracking -+ firewall. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NF_CONNTRACK_SIP -+ tristate "SIP protocol support" -+ default m if NETFILTER_ADVANCED=n -+ help -+ SIP is an application-layer control protocol that can establish, -+ modify, and terminate multimedia sessions (conferences) such as -+ Internet telephony calls. With the ip_conntrack_sip and -+ the nf_nat_sip modules you can support the protocol on a connection -+ tracking/NATing firewall. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NF_CONNTRACK_TFTP -+ tristate "TFTP protocol support" -+ depends on NETFILTER_ADVANCED -+ help -+ TFTP connection tracking helper, this is required depending -+ on how restrictive your ruleset is. -+ If you are using a tftp client behind -j SNAT or -j MASQUERADING -+ you will need this. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NF_CT_NETLINK -+ tristate 'Connection tracking netlink interface' -+ select NETFILTER_NETLINK -+ default m if NETFILTER_ADVANCED=n -+ help -+ This option enables support for a netlink-based userspace interface -+ -+endif # NF_CONNTRACK -+ -+# transparent proxy support -+config NETFILTER_TPROXY -+ tristate "Transparent proxying support (EXPERIMENTAL)" -+ depends on EXPERIMENTAL -+ depends on IP_NF_MANGLE -+ depends on NETFILTER_ADVANCED -+ help -+ This option enables transparent proxying support, that is, -+ support for handling non-locally bound IPv4 TCP and UDP sockets. -+ For it to work you will have to configure certain iptables rules -+ and use policy routing. For more information on how to set it up -+ see Documentation/networking/tproxy.txt. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XTABLES -+ tristate "Netfilter Xtables support (required for ip_tables)" -+ default m if NETFILTER_ADVANCED=n -+ help -+ This is required if you intend to use any of ip_tables, -+ ip6_tables or arp_tables. -+ -+if NETFILTER_XTABLES -+ -+# alphabetically ordered list of targets -+ -+config NETFILTER_XT_TARGET_CLASSIFY -+ tristate '"CLASSIFY" target support' -+ depends on NETFILTER_ADVANCED -+ help -+ This option adds a `CLASSIFY' target, which enables the user to set -+ the priority of a packet. Some qdiscs can use this value for -+ classification, among these are: -+ -+ atm, cbq, dsmark, pfifo_fast, htb, prio -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_TARGET_CONNMARK -+ tristate '"CONNMARK" target support' -+ depends on NF_CONNTRACK -+ depends on NETFILTER_ADVANCED -+ select NF_CONNTRACK_MARK -+ help -+ This option adds a `CONNMARK' target, which allows one to manipulate -+ the connection mark value. Similar to the MARK target, but -+ affects the connection mark value rather than the packet mark value. -+ -+ If you want to compile it as a module, say M here and read -+ . The module will be called -+ ipt_CONNMARK. If unsure, say `N'. -+ -+config NETFILTER_XT_TARGET_CONNSECMARK -+ tristate '"CONNSECMARK" target support' -+ depends on NF_CONNTRACK && NF_CONNTRACK_SECMARK -+ default m if NETFILTER_ADVANCED=n -+ help -+ The CONNSECMARK target copies security markings from packets -+ to connections, and restores security markings from connections -+ to packets (if the packets are not already marked). This would -+ normally be used in conjunction with the SECMARK target. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_TARGET_DSCP -+ tristate '"DSCP" and "TOS" target support' -+ depends on IP_NF_MANGLE || IP6_NF_MANGLE -+ depends on NETFILTER_ADVANCED -+ help -+ This option adds a `DSCP' target, which allows you to manipulate -+ the IPv4/IPv6 header DSCP field (differentiated services codepoint). -+ -+ The DSCP field can have any value between 0x0 and 0x3f inclusive. -+ -+ It also adds the "TOS" target, which allows you to create rules in -+ the "mangle" table which alter the Type Of Service field of an IPv4 -+ or the Priority field of an IPv6 packet, prior to routing. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_TARGET_HL -+ tristate '"HL" hoplimit target support' -+ depends on IP_NF_MANGLE || IP6_NF_MANGLE -+ depends on NETFILTER_ADVANCED -+ ---help--- -+ This option adds the "HL" (for IPv6) and "TTL" (for IPv4) -+ targets, which enable the user to change the -+ hoplimit/time-to-live value of the IP header. -+ -+ While it is safe to decrement the hoplimit/TTL value, the -+ modules also allow to increment and set the hoplimit value of -+ the header to arbitrary values. This is EXTREMELY DANGEROUS -+ since you can easily create immortal packets that loop -+ forever on the network. -+ -+config NETFILTER_XT_TARGET_LED -+ tristate '"LED" target support' -+ depends on LEDS_CLASS && LEDS_TRIGGERS -+ depends on NETFILTER_ADVANCED -+ help -+ This option adds a `LED' target, which allows you to blink LEDs in -+ response to particular packets passing through your machine. -+ -+ This can be used to turn a spare LED into a network activity LED, -+ which only flashes in response to FTP transfers, for example. Or -+ you could have an LED which lights up for a minute or two every time -+ somebody connects to your machine via SSH. -+ -+ You will need support for the "led" class to make this work. -+ -+ To create an LED trigger for incoming SSH traffic: -+ iptables -A INPUT -p tcp --dport 22 -j LED --led-trigger-id ssh --led-delay 1000 -+ -+ Then attach the new trigger to an LED on your system: -+ echo netfilter-ssh > /sys/class/leds//trigger -+ -+ For more information on the LEDs available on your system, see -+ Documentation/leds-class.txt -+ -+config NETFILTER_XT_TARGET_MARK -+ tristate '"MARK" target support' -+ default m if NETFILTER_ADVANCED=n -+ help -+ This option adds a `MARK' target, which allows you to create rules -+ in the `mangle' table which alter the netfilter mark (nfmark) field -+ associated with the packet prior to routing. This can change -+ the routing method (see `Use netfilter MARK value as routing -+ key') and can also be used by other subsystems to change their -+ behavior. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_TARGET_NFLOG -+ tristate '"NFLOG" target support' -+ default m if NETFILTER_ADVANCED=n -+ select NETFILTER_NETLINK_LOG -+ help -+ This option enables the NFLOG target, which allows to LOG -+ messages through nfnetlink_log. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_TARGET_NFQUEUE -+ tristate '"NFQUEUE" target Support' -+ depends on NETFILTER_ADVANCED -+ help -+ This target replaced the old obsolete QUEUE target. -+ -+ As opposed to QUEUE, it supports 65535 different queues, -+ not just one. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_TARGET_NOTRACK -+ tristate '"NOTRACK" target support' -+ depends on IP_NF_RAW || IP6_NF_RAW -+ depends on NF_CONNTRACK -+ depends on NETFILTER_ADVANCED -+ help -+ The NOTRACK target allows a select rule to specify -+ which packets *not* to enter the conntrack/NAT -+ subsystem with all the consequences (no ICMP error tracking, -+ no protocol helpers for the selected packets). -+ -+ If you want to compile it as a module, say M here and read -+ . If unsure, say `N'. -+ -+config NETFILTER_XT_TARGET_RATEEST -+ tristate '"RATEEST" target support' -+ depends on NETFILTER_ADVANCED -+ help -+ This option adds a `RATEEST' target, which allows to measure -+ rates similar to TC estimators. The `rateest' match can be -+ used to match on the measured rates. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_TARGET_TPROXY -+ tristate '"TPROXY" target support (EXPERIMENTAL)' -+ depends on EXPERIMENTAL -+ depends on NETFILTER_TPROXY -+ depends on NETFILTER_XTABLES -+ depends on NETFILTER_ADVANCED -+ select NF_DEFRAG_IPV4 -+ help -+ This option adds a `TPROXY' target, which is somewhat similar to -+ REDIRECT. It can only be used in the mangle table and is useful -+ to redirect traffic to a transparent proxy. It does _not_ depend -+ on Netfilter connection tracking and NAT, unlike REDIRECT. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_TARGET_TRACE -+ tristate '"TRACE" target support' -+ depends on IP_NF_RAW || IP6_NF_RAW -+ depends on NETFILTER_ADVANCED -+ help -+ The TRACE target allows you to mark packets so that the kernel -+ will log every rule which match the packets as those traverse -+ the tables, chains, rules. -+ -+ If you want to compile it as a module, say M here and read -+ . If unsure, say `N'. -+ -+config NETFILTER_XT_TARGET_SECMARK -+ tristate '"SECMARK" target support' -+ depends on NETWORK_SECMARK -+ default m if NETFILTER_ADVANCED=n -+ help -+ The SECMARK target allows security marking of network -+ packets, for use with security subsystems. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_TARGET_TCPMSS -+ tristate '"TCPMSS" target support' -+ depends on (IPV6 || IPV6=n) -+ default m if NETFILTER_ADVANCED=n -+ ---help--- -+ This option adds a `TCPMSS' target, which allows you to alter the -+ MSS value of TCP SYN packets, to control the maximum size for that -+ connection (usually limiting it to your outgoing interface's MTU -+ minus 40). -+ -+ This is used to overcome criminally braindead ISPs or servers which -+ block ICMP Fragmentation Needed packets. The symptoms of this -+ problem are that everything works fine from your Linux -+ firewall/router, but machines behind it can never exchange large -+ packets: -+ 1) Web browsers connect, then hang with no data received. -+ 2) Small mail works fine, but large emails hang. -+ 3) ssh works fine, but scp hangs after initial handshaking. -+ -+ Workaround: activate this option and add a rule to your firewall -+ configuration like: -+ -+ iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN \ -+ -j TCPMSS --clamp-mss-to-pmtu -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_TARGET_TCPOPTSTRIP -+ tristate '"TCPOPTSTRIP" target support (EXPERIMENTAL)' -+ depends on EXPERIMENTAL -+ depends on IP_NF_MANGLE || IP6_NF_MANGLE -+ depends on NETFILTER_ADVANCED -+ help -+ This option adds a "TCPOPTSTRIP" target, which allows you to strip -+ TCP options from TCP packets. -+ -+config NETFILTER_XT_MATCH_CLUSTER -+ tristate '"cluster" match support' -+ depends on NF_CONNTRACK -+ depends on NETFILTER_ADVANCED -+ ---help--- -+ This option allows you to build work-load-sharing clusters of -+ network servers/stateful firewalls without having a dedicated -+ load-balancing router/server/switch. Basically, this match returns -+ true when the packet must be handled by this cluster node. Thus, -+ all nodes see all packets and this match decides which node handles -+ what packets. The work-load sharing algorithm is based on source -+ address hashing. -+ -+ If you say Y or M here, try `iptables -m cluster --help` for -+ more information. -+ -+config NETFILTER_XT_MATCH_COMMENT -+ tristate '"comment" match support' -+ depends on NETFILTER_ADVANCED -+ help -+ This option adds a `comment' dummy-match, which allows you to put -+ comments in your iptables ruleset. -+ -+ If you want to compile it as a module, say M here and read -+ . If unsure, say `N'. -+ -+config NETFILTER_XT_MATCH_CONNBYTES -+ tristate '"connbytes" per-connection counter match support' -+ depends on NF_CONNTRACK -+ depends on NETFILTER_ADVANCED -+ select NF_CT_ACCT -+ help -+ This option adds a `connbytes' match, which allows you to match the -+ number of bytes and/or packets for each direction within a connection. -+ -+ If you want to compile it as a module, say M here and read -+ . If unsure, say `N'. -+ -+config NETFILTER_XT_MATCH_CONNLIMIT -+ tristate '"connlimit" match support"' -+ depends on NF_CONNTRACK -+ depends on NETFILTER_ADVANCED -+ ---help--- -+ This match allows you to match against the number of parallel -+ connections to a server per client IP address (or address block). -+ -+config NETFILTER_XT_MATCH_CONNMARK -+ tristate '"connmark" connection mark match support' -+ depends on NF_CONNTRACK -+ depends on NETFILTER_ADVANCED -+ select NF_CONNTRACK_MARK -+ help -+ This option adds a `connmark' match, which allows you to match the -+ connection mark value previously set for the session by `CONNMARK'. -+ -+ If you want to compile it as a module, say M here and read -+ . The module will be called -+ ipt_connmark. If unsure, say `N'. -+ -+config NETFILTER_XT_MATCH_CONNTRACK -+ tristate '"conntrack" connection tracking match support' -+ depends on NF_CONNTRACK -+ default m if NETFILTER_ADVANCED=n -+ help -+ This is a general conntrack match module, a superset of the state match. -+ -+ It allows matching on additional conntrack information, which is -+ useful in complex configurations, such as NAT gateways with multiple -+ internet links or tunnels. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_DCCP -+ tristate '"dccp" protocol match support' -+ depends on NETFILTER_ADVANCED -+ default IP_DCCP -+ help -+ With this option enabled, you will be able to use the iptables -+ `dccp' match in order to match on DCCP source/destination ports -+ and DCCP flags. -+ -+ If you want to compile it as a module, say M here and read -+ . If unsure, say `N'. -+ -+config NETFILTER_XT_MATCH_DSCP -+ tristate '"dscp" and "tos" match support' -+ depends on NETFILTER_ADVANCED -+ help -+ This option adds a `DSCP' match, which allows you to match against -+ the IPv4/IPv6 header DSCP field (differentiated services codepoint). -+ -+ The DSCP field can have any value between 0x0 and 0x3f inclusive. -+ -+ It will also add a "tos" match, which allows you to match packets -+ based on the Type Of Service fields of the IPv4 packet (which share -+ the same bits as DSCP). -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_ESP -+ tristate '"esp" match support' -+ depends on NETFILTER_ADVANCED -+ help -+ This match extension allows you to match a range of SPIs -+ inside ESP header of IPSec packets. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_HASHLIMIT -+ tristate '"hashlimit" match support' -+ depends on (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n) -+ depends on NETFILTER_ADVANCED -+ help -+ This option adds a `hashlimit' match. -+ -+ As opposed to `limit', this match dynamically creates a hash table -+ of limit buckets, based on your selection of source/destination -+ addresses and/or ports. -+ -+ It enables you to express policies like `10kpps for any given -+ destination address' or `500pps from any given source address' -+ with a single rule. -+ -+config NETFILTER_XT_MATCH_HELPER -+ tristate '"helper" match support' -+ depends on NF_CONNTRACK -+ depends on NETFILTER_ADVANCED -+ help -+ Helper matching allows you to match packets in dynamic connections -+ tracked by a conntrack-helper, ie. ip_conntrack_ftp -+ -+ To compile it as a module, choose M here. If unsure, say Y. -+ -+config NETFILTER_XT_MATCH_HL -+ tristate '"hl" hoplimit/TTL match support' -+ depends on NETFILTER_ADVANCED -+ ---help--- -+ HL matching allows you to match packets based on the hoplimit -+ in the IPv6 header, or the time-to-live field in the IPv4 -+ header of the packet. -+ -+config NETFILTER_XT_MATCH_IPRANGE -+ tristate '"iprange" address range match support' -+ depends on NETFILTER_ADVANCED -+ ---help--- -+ This option adds a "iprange" match, which allows you to match based on -+ an IP address range. (Normal iptables only matches on single addresses -+ with an optional mask.) -+ -+ If unsure, say M. -+ -+config NETFILTER_XT_MATCH_LENGTH -+ tristate '"length" match support' -+ depends on NETFILTER_ADVANCED -+ help -+ This option allows you to match the length of a packet against a -+ specific value or range of values. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_LIMIT -+ tristate '"limit" match support' -+ depends on NETFILTER_ADVANCED -+ help -+ limit matching allows you to control the rate at which a rule can be -+ matched: mainly useful in combination with the LOG target ("LOG -+ target support", below) and to avoid some Denial of Service attacks. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_MAC -+ tristate '"mac" address match support' -+ depends on NETFILTER_ADVANCED -+ help -+ MAC matching allows you to match packets based on the source -+ Ethernet address of the packet. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_MARK -+ tristate '"mark" match support' -+ default m if NETFILTER_ADVANCED=n -+ help -+ Netfilter mark matching allows you to match packets based on the -+ `nfmark' value in the packet. This can be set by the MARK target -+ (see below). -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_MULTIPORT -+ tristate '"multiport" Multiple port match support' -+ depends on NETFILTER_ADVANCED -+ help -+ Multiport matching allows you to match TCP or UDP packets based on -+ a series of source or destination ports: normally a rule can only -+ match a single range of ports. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_OWNER -+ tristate '"owner" match support' -+ depends on NETFILTER_ADVANCED -+ ---help--- -+ Socket owner matching allows you to match locally-generated packets -+ based on who created the socket: the user or group. It is also -+ possible to check whether a socket actually exists. -+ -+config NETFILTER_XT_MATCH_POLICY -+ tristate 'IPsec "policy" match support' -+ depends on XFRM -+ default m if NETFILTER_ADVANCED=n -+ help -+ Policy matching allows you to match packets based on the -+ IPsec policy that was used during decapsulation/will -+ be used during encapsulation. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_PHYSDEV -+ tristate '"physdev" match support' -+ depends on BRIDGE && BRIDGE_NETFILTER -+ depends on NETFILTER_ADVANCED -+ help -+ Physdev packet matching matches against the physical bridge ports -+ the IP packet arrived on or will leave by. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_PKTTYPE -+ tristate '"pkttype" packet type match support' -+ depends on NETFILTER_ADVANCED -+ help -+ Packet type matching allows you to match a packet by -+ its "class", eg. BROADCAST, MULTICAST, ... -+ -+ Typical usage: -+ iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_QUOTA -+ tristate '"quota" match support' -+ depends on NETFILTER_ADVANCED -+ help -+ This option adds a `quota' match, which allows to match on a -+ byte counter. -+ -+ If you want to compile it as a module, say M here and read -+ . If unsure, say `N'. -+ -+config NETFILTER_XT_MATCH_RATEEST -+ tristate '"rateest" match support' -+ depends on NETFILTER_ADVANCED -+ select NETFILTER_XT_TARGET_RATEEST -+ help -+ This option adds a `rateest' match, which allows to match on the -+ rate estimated by the RATEEST target. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_REALM -+ tristate '"realm" match support' -+ depends on NETFILTER_ADVANCED -+ select NET_CLS_ROUTE -+ help -+ This option adds a `realm' match, which allows you to use the realm -+ key from the routing subsystem inside iptables. -+ -+ This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option -+ in tc world. -+ -+ If you want to compile it as a module, say M here and read -+ . If unsure, say `N'. -+ -+config NETFILTER_XT_MATCH_RECENT -+ tristate '"recent" match support' -+ depends on NETFILTER_ADVANCED -+ ---help--- -+ This match is used for creating one or many lists of recently -+ used addresses and then matching against that/those list(s). -+ -+ Short options are available by using 'iptables -m recent -h' -+ Official Website: -+ -+config NETFILTER_XT_MATCH_RECENT_PROC_COMPAT -+ bool 'Enable obsolete /proc/net/ipt_recent' -+ depends on NETFILTER_XT_MATCH_RECENT && PROC_FS -+ ---help--- -+ This option enables the old /proc/net/ipt_recent interface, -+ which has been obsoleted by /proc/net/xt_recent. -+ -+config NETFILTER_XT_MATCH_SCTP -+ tristate '"sctp" protocol match support (EXPERIMENTAL)' -+ depends on EXPERIMENTAL -+ depends on NETFILTER_ADVANCED -+ default IP_SCTP -+ help -+ With this option enabled, you will be able to use the -+ `sctp' match in order to match on SCTP source/destination ports -+ and SCTP chunk types. -+ -+ If you want to compile it as a module, say M here and read -+ . If unsure, say `N'. -+ -+config NETFILTER_XT_MATCH_SOCKET -+ tristate '"socket" match support (EXPERIMENTAL)' -+ depends on EXPERIMENTAL -+ depends on NETFILTER_TPROXY -+ depends on NETFILTER_XTABLES -+ depends on NETFILTER_ADVANCED -+ depends on !NF_CONNTRACK || NF_CONNTRACK -+ select NF_DEFRAG_IPV4 -+ help -+ This option adds a `socket' match, which can be used to match -+ packets for which a TCP or UDP socket lookup finds a valid socket. -+ It can be used in combination with the MARK target and policy -+ routing to implement full featured non-locally bound sockets. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_STATE -+ tristate '"state" match support' -+ depends on NF_CONNTRACK -+ default m if NETFILTER_ADVANCED=n -+ help -+ Connection state matching allows you to match packets based on their -+ relationship to a tracked connection (ie. previous packets). This -+ is a powerful tool for packet classification. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_STATISTIC -+ tristate '"statistic" match support' -+ depends on NETFILTER_ADVANCED -+ help -+ This option adds a `statistic' match, which allows you to match -+ on packets periodically or randomly with a given percentage. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_STRING -+ tristate '"string" match support' -+ depends on NETFILTER_ADVANCED -+ select TEXTSEARCH -+ select TEXTSEARCH_KMP -+ select TEXTSEARCH_BM -+ select TEXTSEARCH_FSM -+ help -+ This option adds a `string' match, which allows you to look for -+ pattern matchings in packets. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_TCPMSS -+ tristate '"tcpmss" match support' -+ depends on NETFILTER_ADVANCED -+ help -+ This option adds a `tcpmss' match, which allows you to examine the -+ MSS value of TCP SYN packets, which control the maximum packet size -+ for that connection. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_TIME -+ tristate '"time" match support' -+ depends on NETFILTER_ADVANCED -+ ---help--- -+ This option adds a "time" match, which allows you to match based on -+ the packet arrival time (at the machine which netfilter is running) -+ on) or departure time/date (for locally generated packets). -+ -+ If you say Y here, try `iptables -m time --help` for -+ more information. -+ -+ If you want to compile it as a module, say M here. -+ If unsure, say N. -+ -+config NETFILTER_XT_MATCH_U32 -+ tristate '"u32" match support' -+ depends on NETFILTER_ADVANCED -+ ---help--- -+ u32 allows you to extract quantities of up to 4 bytes from a packet, -+ AND them with specified masks, shift them by specified amounts and -+ test whether the results are in any of a set of specified ranges. -+ The specification of what to extract is general enough to skip over -+ headers with lengths stored in the packet, as in IP or TCP header -+ lengths. -+ -+ Details and examples are in the kernel module source. -+ -+config NETFILTER_XT_MATCH_OSF -+ tristate '"osf" Passive OS fingerprint match' -+ depends on NETFILTER_ADVANCED && NETFILTER_NETLINK -+ help -+ This option selects the Passive OS Fingerprinting match module -+ that allows to passively match the remote operating system by -+ analyzing incoming TCP SYN packets. -+ -+ Rules and loading software can be downloaded from -+ http://www.ioremap.net/projects/osf -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+endif # NETFILTER_XTABLES -+ -+endmenu -+ -+source "net/netfilter/ipvs/Kconfig" -diff -Nur linux-2.6.33.orig/net/netfilter/Makefile linux-2.6.33/net/netfilter/Makefile ---- linux-2.6.33.orig/net/netfilter/Makefile 2010-02-24 19:52:17.000000000 +0100 -+++ linux-2.6.33/net/netfilter/Makefile 2010-04-25 01:09:20.000000000 +0200 -@@ -33,6 +33,7 @@ - obj-$(CONFIG_NF_CONNTRACK_SANE) += nf_conntrack_sane.o - obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o - obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o -+obj-$(CONFIG_NF_CONNTRACK_RTSP) += nf_conntrack_rtsp.o - - # transparent proxy support - obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o -diff -Nur linux-2.6.33.orig/net/netfilter/nf_conntrack_rtsp.c linux-2.6.33/net/netfilter/nf_conntrack_rtsp.c ---- linux-2.6.33.orig/net/netfilter/nf_conntrack_rtsp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.33/net/netfilter/nf_conntrack_rtsp.c 2010-04-25 01:09:20.000000000 +0200 -@@ -0,0 +1,517 @@ -+/* -+ * RTSP extension for IP connection tracking -+ * (C) 2003 by Tom Marshall -+ * based on ip_conntrack_irc.c -+ * -+ * 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. -+ * -+ * Module load syntax: -+ * insmod nf_conntrack_rtsp.o ports=port1,port2,...port -+ * max_outstanding=n setup_timeout=secs -+ * -+ * If no ports are specified, the default will be port 554. -+ * -+ * With max_outstanding you can define the maximum number of not yet -+ * answered SETUP requests per RTSP session (default 8). -+ * With setup_timeout you can specify how long the system waits for -+ * an expected data channel (default 300 seconds). -+ * -+ * 2005-02-13: Harald Welte -+ * - port to 2.6 -+ * - update to recent post-2.6.11 api changes -+ * 2006-09-14: Steven Van Acker -+ * - removed calls to NAT code from conntrack helper: NAT no longer needed to use rtsp-conntrack -+ * 2007-04-18: Michael Guntsche -+ * - Port to new NF API -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#define NF_NEED_STRNCASECMP -+#define NF_NEED_STRTOU16 -+#define NF_NEED_STRTOU32 -+#define NF_NEED_NEXTLINE -+#include -+#define NF_NEED_MIME_NEXTLINE -+#include -+ -+#include -+#define MAX_SIMUL_SETUP 8 /* XXX: use max_outstanding */ -+#define INFOP(fmt, args...) printk(KERN_INFO "%s: %s: " fmt, __FILE__, __FUNCTION__ , ## args) -+#if 0 -+#define DEBUGP(fmt, args...) printk(KERN_DEBUG "%s: %s: " fmt, __FILE__, __FUNCTION__ , ## args) -+#else -+#define DEBUGP(fmt, args...) -+#endif -+ -+#define MAX_PORTS 8 -+static int ports[MAX_PORTS]; -+static int num_ports = 0; -+static int max_outstanding = 8; -+static unsigned int setup_timeout = 300; -+ -+MODULE_AUTHOR("Tom Marshall "); -+MODULE_DESCRIPTION("RTSP connection tracking module"); -+MODULE_LICENSE("GPL"); -+module_param_array(ports, int, &num_ports, 0400); -+MODULE_PARM_DESC(ports, "port numbers of RTSP servers"); -+module_param(max_outstanding, int, 0400); -+MODULE_PARM_DESC(max_outstanding, "max number of outstanding SETUP requests per RTSP session"); -+module_param(setup_timeout, int, 0400); -+MODULE_PARM_DESC(setup_timeout, "timeout on for unestablished data channels"); -+ -+static char *rtsp_buffer; -+static DEFINE_SPINLOCK(rtsp_buffer_lock); -+ -+unsigned int (*nf_nat_rtsp_hook)(struct sk_buff *skb, -+ enum ip_conntrack_info ctinfo, -+ unsigned int matchoff, unsigned int matchlen,struct ip_ct_rtsp_expect* prtspexp, -+ struct nf_conntrack_expect *exp); -+void (*nf_nat_rtsp_hook_expectfn)(struct nf_conn *ct, struct nf_conntrack_expect *exp); -+ -+EXPORT_SYMBOL_GPL(nf_nat_rtsp_hook); -+ -+/* -+ * Max mappings we will allow for one RTSP connection (for RTP, the number -+ * of allocated ports is twice this value). Note that SMIL burns a lot of -+ * ports so keep this reasonably high. If this is too low, you will see a -+ * lot of "no free client map entries" messages. -+ */ -+#define MAX_PORT_MAPS 16 -+ -+/*** default port list was here in the masq code: 554, 3030, 4040 ***/ -+ -+#define SKIP_WSPACE(ptr,len,off) while(off < len && isspace(*(ptr+off))) { off++; } -+ -+/* -+ * Parse an RTSP packet. -+ * -+ * Returns zero if parsing failed. -+ * -+ * Parameters: -+ * IN ptcp tcp data pointer -+ * IN tcplen tcp data len -+ * IN/OUT ptcpoff points to current tcp offset -+ * OUT phdrsoff set to offset of rtsp headers -+ * OUT phdrslen set to length of rtsp headers -+ * OUT pcseqoff set to offset of CSeq header -+ * OUT pcseqlen set to length of CSeq header -+ */ -+static int -+rtsp_parse_message(char* ptcp, uint tcplen, uint* ptcpoff, -+ uint* phdrsoff, uint* phdrslen, -+ uint* pcseqoff, uint* pcseqlen, -+ uint* transoff, uint* translen) -+{ -+ uint entitylen = 0; -+ uint lineoff; -+ uint linelen; -+ -+ if (!nf_nextline(ptcp, tcplen, ptcpoff, &lineoff, &linelen)) -+ return 0; -+ -+ *phdrsoff = *ptcpoff; -+ while (nf_mime_nextline(ptcp, tcplen, ptcpoff, &lineoff, &linelen)) { -+ if (linelen == 0) { -+ if (entitylen > 0) -+ *ptcpoff += min(entitylen, tcplen - *ptcpoff); -+ break; -+ } -+ if (lineoff+linelen > tcplen) { -+ INFOP("!! overrun !!\n"); -+ break; -+ } -+ -+ if (nf_strncasecmp(ptcp+lineoff, "CSeq:", 5) == 0) { -+ *pcseqoff = lineoff; -+ *pcseqlen = linelen; -+ } -+ -+ if (nf_strncasecmp(ptcp+lineoff, "Transport:", 10) == 0) { -+ *transoff = lineoff; -+ *translen = linelen; -+ } -+ -+ if (nf_strncasecmp(ptcp+lineoff, "Content-Length:", 15) == 0) { -+ uint off = lineoff+15; -+ SKIP_WSPACE(ptcp+lineoff, linelen, off); -+ nf_strtou32(ptcp+off, &entitylen); -+ } -+ } -+ *phdrslen = (*ptcpoff) - (*phdrsoff); -+ -+ return 1; -+} -+ -+/* -+ * Find lo/hi client ports (if any) in transport header -+ * In: -+ * ptcp, tcplen = packet -+ * tranoff, tranlen = buffer to search -+ * -+ * Out: -+ * pport_lo, pport_hi = lo/hi ports (host endian) -+ * -+ * Returns nonzero if any client ports found -+ * -+ * Note: it is valid (and expected) for the client to request multiple -+ * transports, so we need to parse the entire line. -+ */ -+static int -+rtsp_parse_transport(char* ptran, uint tranlen, -+ struct ip_ct_rtsp_expect* prtspexp) -+{ -+ int rc = 0; -+ uint off = 0; -+ -+ if (tranlen < 10 || !iseol(ptran[tranlen-1]) || -+ nf_strncasecmp(ptran, "Transport:", 10) != 0) { -+ INFOP("sanity check failed\n"); -+ return 0; -+ } -+ -+ DEBUGP("tran='%.*s'\n", (int)tranlen, ptran); -+ off += 10; -+ SKIP_WSPACE(ptran, tranlen, off); -+ -+ /* Transport: tran;field;field=val,tran;field;field=val,... */ -+ while (off < tranlen) { -+ const char* pparamend; -+ uint nextparamoff; -+ -+ pparamend = memchr(ptran+off, ',', tranlen-off); -+ pparamend = (pparamend == NULL) ? ptran+tranlen : pparamend+1; -+ nextparamoff = pparamend-ptran; -+ -+ while (off < nextparamoff) { -+ const char* pfieldend; -+ uint nextfieldoff; -+ -+ pfieldend = memchr(ptran+off, ';', nextparamoff-off); -+ nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1; -+ -+ if (strncmp(ptran+off, "client_port=", 12) == 0) { -+ u_int16_t port; -+ uint numlen; -+ -+ off += 12; -+ numlen = nf_strtou16(ptran+off, &port); -+ off += numlen; -+ if (prtspexp->loport != 0 && prtspexp->loport != port) -+ DEBUGP("multiple ports found, port %hu ignored\n", port); -+ else { -+ DEBUGP("lo port found : %hu\n", port); -+ prtspexp->loport = prtspexp->hiport = port; -+ if (ptran[off] == '-') { -+ off++; -+ numlen = nf_strtou16(ptran+off, &port); -+ off += numlen; -+ prtspexp->pbtype = pb_range; -+ prtspexp->hiport = port; -+ -+ // If we have a range, assume rtp: -+ // loport must be even, hiport must be loport+1 -+ if ((prtspexp->loport & 0x0001) != 0 || -+ prtspexp->hiport != prtspexp->loport+1) { -+ DEBUGP("incorrect range: %hu-%hu, correcting\n", -+ prtspexp->loport, prtspexp->hiport); -+ prtspexp->loport &= 0xfffe; -+ prtspexp->hiport = prtspexp->loport+1; -+ } -+ } else if (ptran[off] == '/') { -+ off++; -+ numlen = nf_strtou16(ptran+off, &port); -+ off += numlen; -+ prtspexp->pbtype = pb_discon; -+ prtspexp->hiport = port; -+ } -+ rc = 1; -+ } -+ } -+ -+ /* -+ * Note we don't look for the destination parameter here. -+ * If we are using NAT, the NAT module will handle it. If not, -+ * and the client is sending packets elsewhere, the expectation -+ * will quietly time out. -+ */ -+ -+ off = nextfieldoff; -+ } -+ -+ off = nextparamoff; -+ } -+ -+ return rc; -+} -+ -+void expected(struct nf_conn *ct, struct nf_conntrack_expect *exp) -+{ -+ if(nf_nat_rtsp_hook_expectfn) { -+ nf_nat_rtsp_hook_expectfn(ct,exp); -+ } -+} -+ -+/*** conntrack functions ***/ -+ -+/* outbound packet: client->server */ -+ -+static inline int -+help_out(struct sk_buff *skb, unsigned char *rb_ptr, unsigned int datalen, -+ struct nf_conn *ct, enum ip_conntrack_info ctinfo) -+{ -+ struct ip_ct_rtsp_expect expinfo; -+ -+ int dir = CTINFO2DIR(ctinfo); /* = IP_CT_DIR_ORIGINAL */ -+ //struct tcphdr* tcph = (void*)iph + iph->ihl * 4; -+ //uint tcplen = pktlen - iph->ihl * 4; -+ char* pdata = rb_ptr; -+ //uint datalen = tcplen - tcph->doff * 4; -+ uint dataoff = 0; -+ int ret = NF_ACCEPT; -+ -+ struct nf_conntrack_expect *exp; -+ -+ __be16 be_loport; -+ -+ memset(&expinfo, 0, sizeof(expinfo)); -+ -+ while (dataoff < datalen) { -+ uint cmdoff = dataoff; -+ uint hdrsoff = 0; -+ uint hdrslen = 0; -+ uint cseqoff = 0; -+ uint cseqlen = 0; -+ uint transoff = 0; -+ uint translen = 0; -+ uint off; -+ -+ if (!rtsp_parse_message(pdata, datalen, &dataoff, -+ &hdrsoff, &hdrslen, -+ &cseqoff, &cseqlen, -+ &transoff, &translen)) -+ break; /* not a valid message */ -+ -+ if (strncmp(pdata+cmdoff, "SETUP ", 6) != 0) -+ continue; /* not a SETUP message */ -+ DEBUGP("found a setup message\n"); -+ -+ off = 0; -+ if(translen) { -+ rtsp_parse_transport(pdata+transoff, translen, &expinfo); -+ } -+ -+ if (expinfo.loport == 0) { -+ DEBUGP("no udp transports found\n"); -+ continue; /* no udp transports found */ -+ } -+ -+ DEBUGP("udp transport found, ports=(%d,%hu,%hu)\n", -+ (int)expinfo.pbtype, expinfo.loport, expinfo.hiport); -+ -+ exp = nf_ct_expect_alloc(ct); -+ if (!exp) { -+ ret = NF_DROP; -+ goto out; -+ } -+ -+ be_loport = htons(expinfo.loport); -+ -+ nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, -+ ct->tuplehash[!dir].tuple.src.l3num, -+ &ct->tuplehash[!dir].tuple.src.u3, &ct->tuplehash[!dir].tuple.dst.u3, -+ IPPROTO_UDP, NULL, &be_loport); -+ -+ exp->master = ct; -+ -+ exp->expectfn = expected; -+ exp->flags = 0; -+ -+ if (expinfo.pbtype == pb_range) { -+ DEBUGP("Changing expectation mask to handle multiple ports\n"); -+ exp->mask.src.u.udp.port = 0xfffe; -+ } -+ -+ DEBUGP("expect_related %u.%u.%u.%u:%u-%u.%u.%u.%u:%u\n", -+ NIPQUAD(exp->tuple.src.u3.ip), -+ ntohs(exp->tuple.src.u.udp.port), -+ NIPQUAD(exp->tuple.dst.u3.ip), -+ ntohs(exp->tuple.dst.u.udp.port)); -+ -+ if (nf_nat_rtsp_hook) -+ /* pass the request off to the nat helper */ -+ ret = nf_nat_rtsp_hook(skb, ctinfo, hdrsoff, hdrslen, &expinfo, exp); -+ else if (nf_ct_expect_related(exp) != 0) { -+ INFOP("nf_ct_expect_related failed\n"); -+ ret = NF_DROP; -+ } -+ nf_ct_expect_put(exp); -+ goto out; -+ } -+out: -+ -+ return ret; -+} -+ -+ -+static inline int -+help_in(struct sk_buff *skb, size_t pktlen, -+ struct nf_conn* ct, enum ip_conntrack_info ctinfo) -+{ -+ return NF_ACCEPT; -+} -+ -+static int help(struct sk_buff *skb, unsigned int protoff, -+ struct nf_conn *ct, enum ip_conntrack_info ctinfo) -+{ -+ struct tcphdr _tcph, *th; -+ unsigned int dataoff, datalen; -+ char *rb_ptr; -+ int ret = NF_DROP; -+ -+ /* Until there's been traffic both ways, don't look in packets. */ -+ if (ctinfo != IP_CT_ESTABLISHED && -+ ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) { -+ DEBUGP("conntrackinfo = %u\n", ctinfo); -+ return NF_ACCEPT; -+ } -+ -+ /* Not whole TCP header? */ -+ th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); -+ -+ if (!th) -+ return NF_ACCEPT; -+ -+ /* No data ? */ -+ dataoff = protoff + th->doff*4; -+ datalen = skb->len - dataoff; -+ if (dataoff >= skb->len) -+ return NF_ACCEPT; -+ -+ spin_lock_bh(&rtsp_buffer_lock); -+ rb_ptr = skb_header_pointer(skb, dataoff, -+ skb->len - dataoff, rtsp_buffer); -+ BUG_ON(rb_ptr == NULL); -+ -+#if 0 -+ /* Checksum invalid? Ignore. */ -+ /* FIXME: Source route IP option packets --RR */ -+ if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, -+ csum_partial((char*)tcph, tcplen, 0))) -+ { -+ DEBUGP("bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n", -+ tcph, tcplen, NIPQUAD(iph->saddr), NIPQUAD(iph->daddr)); -+ return NF_ACCEPT; -+ } -+#endif -+ -+ switch (CTINFO2DIR(ctinfo)) { -+ case IP_CT_DIR_ORIGINAL: -+ ret = help_out(skb, rb_ptr, datalen, ct, ctinfo); -+ break; -+ case IP_CT_DIR_REPLY: -+ DEBUGP("IP_CT_DIR_REPLY\n"); -+ /* inbound packet: server->client */ -+ ret = NF_ACCEPT; -+ break; -+ } -+ -+ spin_unlock_bh(&rtsp_buffer_lock); -+ -+ return ret; -+} -+ -+static struct nf_conntrack_helper rtsp_helpers[MAX_PORTS]; -+static char rtsp_names[MAX_PORTS][10]; -+static struct nf_conntrack_expect_policy rtsp_expect_policy; -+ -+/* This function is intentionally _NOT_ defined as __exit */ -+static void -+fini(void) -+{ -+ int i; -+ for (i = 0; i < num_ports; i++) { -+ DEBUGP("unregistering port %d\n", ports[i]); -+ nf_conntrack_helper_unregister(&rtsp_helpers[i]); -+ } -+ kfree(rtsp_buffer); -+} -+ -+static int __init -+init(void) -+{ -+ int i, ret; -+ struct nf_conntrack_helper *hlpr; -+ char *tmpname; -+ -+ printk("nf_conntrack_rtsp v" IP_NF_RTSP_VERSION " loading\n"); -+ -+ if (max_outstanding < 1) { -+ printk("nf_conntrack_rtsp: max_outstanding must be a positive integer\n"); -+ return -EBUSY; -+ } -+ if (setup_timeout < 0) { -+ printk("nf_conntrack_rtsp: setup_timeout must be a positive integer\n"); -+ return -EBUSY; -+ } -+ -+ rtsp_expect_policy.max_expected = max_outstanding; -+ rtsp_expect_policy.timeout = setup_timeout; -+ -+ rtsp_buffer = kmalloc(65536, GFP_KERNEL); -+ if (!rtsp_buffer) -+ return -ENOMEM; -+ -+ /* If no port given, default to standard rtsp port */ -+ if (ports[0] == 0) { -+ ports[0] = RTSP_PORT; -+ } -+ -+ for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { -+ hlpr = &rtsp_helpers[i]; -+ memset(hlpr, 0, sizeof(struct nf_conntrack_helper)); -+ hlpr->tuple.src.u.tcp.port = htons(ports[i]); -+ hlpr->tuple.dst.protonum = IPPROTO_TCP; -+ hlpr->expect_policy = &rtsp_expect_policy; -+ hlpr->me = THIS_MODULE; -+ hlpr->help = help; -+ -+ tmpname = &rtsp_names[i][0]; -+ if (ports[i] == RTSP_PORT) { -+ sprintf(tmpname, "rtsp"); -+ } else { -+ sprintf(tmpname, "rtsp-%d", i); -+ } -+ hlpr->name = tmpname; -+ -+ DEBUGP("port #%d: %d\n", i, ports[i]); -+ -+ ret = nf_conntrack_helper_register(hlpr); -+ -+ if (ret) { -+ printk("nf_conntrack_rtsp: ERROR registering port %d\n", ports[i]); -+ fini(); -+ return -EBUSY; -+ } -+ num_ports++; -+ } -+ return 0; -+} -+ -+module_init(init); -+module_exit(fini); -+ -+EXPORT_SYMBOL(nf_nat_rtsp_hook_expectfn); -+ -- cgit v1.2.3