diff options
author | Waldemar Brodkorb <wbx@openadk.org> | 2010-04-25 03:14:44 +0200 |
---|---|---|
committer | Waldemar Brodkorb <wbx@openadk.org> | 2010-04-25 03:14:44 +0200 |
commit | ab0fccc6bc1991aa1a9e37fde4b6e27361b7ff44 (patch) | |
tree | b9f6af73a541cff06e8b19e533aec19f3f442c4f /target/linux/patches | |
parent | 201380b2d06fef0ede1fd9777b7874950c220a2a (diff) |
fix nat helpers for ipv4, add rtsp nat helper
Diffstat (limited to 'target/linux/patches')
-rw-r--r-- | target/linux/patches/2.6.33/rtsp.patch | 2316 |
1 files changed, 2316 insertions, 0 deletions
diff --git a/target/linux/patches/2.6.33/rtsp.patch b/target/linux/patches/2.6.33/rtsp.patch new file mode 100644 index 000000000..317c06d8e --- /dev/null +++ b/target/linux/patches/2.6.33/rtsp.patch @@ -0,0 +1,2316 @@ +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 <tmarshall at real.com> ++ * 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 <linux/ctype.h> ++#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 <linux/ctype.h> ++ ++/* ++ * 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 <tmarshall at real.com> ++ * 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<MAX_PORTS> ++ * stunaddr=<address> ++ * 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 <linux/module.h> ++#include <net/tcp.h> ++#include <net/netfilter/nf_nat_helper.h> ++#include <net/netfilter/nf_nat_rule.h> ++#include <linux/netfilter/nf_conntrack_rtsp.h> ++#include <net/netfilter/nf_conntrack_expect.h> ++ ++#include <linux/inet.h> ++#include <linux/ctype.h> ++#define NF_NEED_STRNCASECMP ++#define NF_NEED_STRTOU16 ++#include <linux/netfilter_helpers.h> ++#define NF_NEED_MIME_NEXTLINE ++#include <linux/netfilter_mime.h> ++ ++#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 <tmarshall at real.com>"); ++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=<spec>" ++ * - 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 ++ <file:Documentation/kbuild/modules.txt>. 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 <http://www.amanda.org/> ++ 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. |