diff options
| -rw-r--r-- | include/netfilter.mk | 40 | ||||
| -rw-r--r-- | target/linux/au1000/config-2.6.22 | 11 | ||||
| -rw-r--r-- | target/linux/brcm47xx/config-2.6.22 | 4 | ||||
| -rw-r--r-- | target/linux/brcm63xx/config-2.6.22 | 15 | ||||
| -rw-r--r-- | target/linux/generic-2.4/config-default | 4 | ||||
| -rw-r--r-- | target/linux/generic-2.6/config-2.6.22 | 25 | ||||
| -rw-r--r-- | target/linux/generic-2.6/patches-2.6.22/190-netfilter_rtsp.patch | 1370 | ||||
| -rw-r--r-- | target/linux/x86/config-2.6.22 | 1 | 
8 files changed, 1421 insertions, 49 deletions
| diff --git a/include/netfilter.mk b/include/netfilter.mk index 0531a6029..440314dc1 100644 --- a/include/netfilter.mk +++ b/include/netfilter.mk @@ -22,6 +22,10 @@ endef  # conntrack +# kernel only +$(eval $(if $(NF_KMOD),$(call nf_add,IPT_CONNTRACK,CONFIG_NF_CONNTRACK, $(P_XT)nf_conntrack),)) +$(eval $(if $(NF_KMOD),$(call nf_add,IPT_CONNTRACK,CONFIG_NF_CONNTRACK_IPV4, $(P_V4)nf_conntrack_ipv4),)) +  $(eval $(call nf_add,IPT_CONNTRACK,CONFIG_IP_NF_MATCH_CONNBYTES, $(P_V4)ipt_connbytes))  $(eval $(call nf_add,IPT_CONNTRACK,CONFIG_NETFILTER_XT_MATCH_CONNBYTES, $(P_XT)xt_connbytes))  $(eval $(call nf_add,IPT_CONNTRACK,CONFIG_IP_NF_MATCH_CONNMARK, $(P_V4)ipt_connmark)) @@ -43,7 +47,8 @@ $(eval $(call nf_add,IPT_CONNTRACK,CONFIG_NETFILTER_XT_TARGET_NOTRACK, $(P_XT)xt  # extra -$(eval $(if $(NF_KMOD),$(call nf_add,IPT_EXTRA,CONFIG_IP_NF_RAW, $(P_V4)iptable_raw))) +# kernel only +$(eval $(if $(NF_KMOD),$(call nf_add,IPT_EXTRA,CONFIG_IP_NF_RAW, $(P_V4)iptable_raw),))  $(eval $(call nf_add,IPT_EXTRA,CONFIG_IP_NF_MATCH_CONDITION, $(P_V4)ipt_condition))  $(eval $(call nf_add,IPT_EXTRA,CONFIG_IP_NF_MATCH_OWNER, $(P_V4)ipt_owner)) @@ -58,6 +63,7 @@ $(eval $(call nf_add,IPT_EXTRA,CONFIG_NETFILTER_XT_TARGET_CHAOS, $(P_XT)xt_CHAOS  $(eval $(call nf_add,IPT_EXTRA,CONFIG_NETFILTER_XT_TARGET_DELUDE, $(P_XT)xt_DELUDE))  $(eval $(call nf_add,IPT_EXTRA,CONFIG_IP_NF_TARGET_LOG, $(P_V4)ipt_LOG))  $(eval $(call nf_add,IPT_EXTRA,CONFIG_IP_NF_TARGET_REJECT, $(P_V4)ipt_REJECT)) +#$(eval $(call nf_add,IPT_EXTRA,CONFIG_IP_NF_TARGET_ROUTE, $(P_V4)ipt_ROUTE))  # filter @@ -117,6 +123,7 @@ $(eval $(call nf_add,IPT_IPRANGE,CONFIG_IP_NF_MATCH_IPRANGE, $(P_V4)ipt_iprange)  $(eval $(call nf_add,IPT_IPSEC,CONFIG_IP_NF_MATCH_AH_ESP, $(P_V4)ipt_ah $(P_V4)ipt_esp))  $(eval $(call nf_add,IPT_IPSEC,CONFIG_IP_NF_MATCH_AH, $(P_V4)ipt_ah))  $(eval $(call nf_add,IPT_IPSEC,CONFIG_NETFILTER_XT_MATCH_ESP, $(P_XT)xt_esp)) +$(eval $(call nf_add,IPT_IPSEC,CONFIG_NETFILTER_XT_MATCH_POLICY, $(P_XT)xt_policy))  # ipset @@ -137,9 +144,14 @@ $(eval $(call nf_add,IPT_IPSET,CONFIG_IP_NF_TARGET_SET, $(P_V4)ipt_SET))  # nat +# kernel only +$(eval $(if $(NF_KMOD),$(call nf_add,IPT_NAT,CONFIG_IP_NF_NAT, $(P_V4)iptable_nat),)) +$(eval $(if $(NF_KMOD),$(call nf_add,IPT_NAT,CONFIG_NF_NAT,$(P_V4)nf_nat $(P_V4)iptable_nat),)) +# userland only  $(eval $(if $(NF_KMOD),,$(call nf_add,IPT_NAT,CONFIG_IP_NF_NAT, $(P_V4)ipt_SNAT $(P_V4)ipt_DNAT)))  $(eval $(if $(NF_KMOD),,$(call nf_add,IPT_NAT,CONFIG_NF_NAT, $(P_V4)ipt_SNAT $(P_V4)ipt_DNAT))) +  $(eval $(call nf_add,IPT_NAT,CONFIG_IP_NF_TARGET_MASQUERADE, $(P_V4)ipt_MASQUERADE))  $(eval $(call nf_add,IPT_NAT,CONFIG_IP_NF_TARGET_MIRROR, $(P_V4)ipt_MIRROR))  $(eval $(call nf_add,IPT_NAT,CONFIG_IP_NF_TARGET_NETMAP, $(P_V4)ipt_NETMAP)) @@ -150,27 +162,46 @@ $(eval $(call nf_add,IPT_NAT,CONFIG_IP_NF_TARGET_REDIRECT, $(P_V4)ipt_REDIRECT))  $(eval $(call nf_add,IPT_NAT_DEFAULT,CONFIG_IP_NF_FTP, $(P_V4)ip_conntrack_ftp))  $(eval $(call nf_add,IPT_NAT_DEFAULT,CONFIG_IP_NF_NAT_FTP, $(P_V4)ip_nat_ftp)) +$(eval $(call nf_add,IPT_NAT_DEFAULT,CONFIG_NF_CONNTRACK_FTP, $(P_XT)nf_conntrack_ftp)) +$(eval $(call nf_add,IPT_NAT_DEFAULT,CONFIG_NF_NAT_FTP, $(P_V4)nf_nat_ftp))  $(eval $(call nf_add,IPT_NAT_DEFAULT,CONFIG_IP_NF_IRC, $(P_V4)ip_conntrack_irc))  $(eval $(call nf_add,IPT_NAT_DEFAULT,CONFIG_IP_NF_NAT_IRC, $(P_V4)ip_nat_irc)) +$(eval $(call nf_add,IPT_NAT_DEFAULT,CONFIG_NF_CONNTRACK_IRC, $(P_XT)nf_conntrack_irc)) +$(eval $(call nf_add,IPT_NAT_DEFAULT,CONFIG_NF_NAT_IRC, $(P_V4)nf_nat_irc))  $(eval $(call nf_add,IPT_NAT_DEFAULT,CONFIG_IP_NF_TFTP, $(P_V4)ip_conntrack_tftp)) +$(eval $(call nf_add,IPT_NAT_DEFAULT,CONFIG_NF_CONNTRACK_TFTP, $(P_XT)nf_conntrack_tftp)) +$(eval $(call nf_add,IPT_NAT_DEFAULT,CONFIG_NF_NAT_TFTP, $(P_V4)nf_nat_tftp))  # nathelper-extra  $(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_IP_NF_AMANDA, $(P_V4)ip_conntrack_amanda)) +$(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_NF_CONNTRACK_AMANDA, $(P_XT)nf_conntrack_amanda)) +$(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_NF_NAT_AMANDA, $(P_V4)nf_nat_amanda))  $(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_IP_NF_CT_PROTO_GRE, $(P_V4)ip_conntrack_proto_gre))  $(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_IP_NF_NAT_PROTO_GRE, $(P_V4)ip_nat_proto_gre)) +$(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_NF_CT_PROTO_GRE, $(P_XT)nf_conntrack_proto_gre)) +$(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_NF_NAT_PROTO_GRE, $(P_V4)nf_nat_proto_gre))  $(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_IP_NF_H323, $(P_V4)ip_conntrack_h323))  $(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_IP_NF_NAT_H323, $(P_V4)ip_nat_h323)) +$(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_NF_CONNTRACK_H323, $(P_XT)nf_conntrack_h323)) +$(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_NF_NAT_H323, $(P_V4)nf_nat_h323))  $(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_IP_NF_MMS, $(P_V4)ip_conntrack_mms))  $(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_IP_NF_NAT_MMS, $(P_V4)ip_nat_mms))  $(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_IP_NF_PPTP, $(P_V4)ip_conntrack_pptp))  $(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_IP_NF_NAT_PPTP, $(P_V4)ip_nat_pptp)) +$(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_NF_CONNTRACK_PPTP, $(P_XT)nf_conntrack_pptp)) +$(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_NF_NAT_PPTP, $(P_V4)nf_nat_pptp))  $(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_IP_NF_RTSP, $(P_V4)ip_conntrack_rtsp))  $(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_IP_NF_NAT_RTSP, $(P_V4)ip_nat_rtsp)) +$(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_NF_CONNTRACK_RTSP, $(P_XT)nf_conntrack_rtsp)) +$(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_NF_NAT_RTSP, $(P_V4)nf_nat_rtsp))  $(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_IP_NF_SIP, $(P_V4)ip_conntrack_sip))  $(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_IP_NF_NAT_SIP, $(P_V4)ip_nat_sip)) +$(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_NF_CONNTRACK_SIP, $(P_XT)nf_conntrack_sip)) +$(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_NF_NAT_SIP, $(P_V4)nf_nat_sip))  $(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_IP_NF_NAT_SNMP_BASIC, $(P_V4)ip_nat_snmp_basic)) +$(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_NF_NAT_SNMP_BASIC, $(P_V4)nf_nat_snmp_basic))  # queue @@ -183,13 +214,16 @@ $(eval $(call nf_add,IPT_QUEUE,CONFIG_IP_NF_QUEUE, $(P_V4)ip_queue))  $(eval $(call nf_add,IPT_ULOG,CONFIG_IP_NF_TARGET_ULOG, $(P_V4)ipt_ULOG)) -IPT_BUILTIN := $(P_V4)ipt_standard -IPT_BUILTIN += $(P_V4)ipt_icmp $(P_V4)ipt_tcp $(P_V4)ipt_udp +# userland only +IPT_BUILTIN := $(if $(NF_KMOD),,$(P_V4)ipt_standard) +IPT_BUILTIN += $(if $(NF_KMOD),,$(P_V4)ipt_icmp $(P_V4)ipt_tcp $(P_V4)ipt_udp) +  IPT_BUILTIN += $(IPT_CONNTRACK-y)  IPT_BUILTIN += $(IPT_EXTRA-y)  IPT_BUILTIN += $(IPT_FILTER-y)  IPT_BUILTIN += $(IPT_IMQ-y)  IPT_BUILTIN += $(IPT_IPOPT-y) +IPT_BUILTIN += $(IPT_IPRANGE-y)  IPT_BUILTIN += $(IPT_IPSEC-y)  IPT_BUILTIN += $(IPT_IPSET-y)  IPT_BUILTIN += $(IPT_NAT-y) diff --git a/target/linux/au1000/config-2.6.22 b/target/linux/au1000/config-2.6.22 index 2ce3bd3a5..3ae9450de 100644 --- a/target/linux/au1000/config-2.6.22 +++ b/target/linux/au1000/config-2.6.22 @@ -165,17 +165,6 @@ CONFIG_MTX1_WATCHDOG=y  CONFIG_NET_SCH_FIFO=y  # CONFIG_NET_VENDOR_3COM is not set  # CONFIG_NETDEV_1000 is not set -CONFIG_NF_CONNTRACK=y -CONFIG_NF_CONNTRACK_MARK=y -CONFIG_NF_CT_ACCT=y -# CONFIG_NF_NAT_AMANDA is not set -CONFIG_NF_NAT_FTP=m -CONFIG_NF_NAT_H323=m -CONFIG_NF_NAT_IRC=m -CONFIG_NF_NAT_NEEDED=y -# CONFIG_NF_NAT_PPTP is not set -CONFIG_NF_NAT_SIP=m -# CONFIG_NF_NAT_TFTP is not set  # CONFIG_PAGE_SIZE_16KB is not set  CONFIG_PAGE_SIZE_4KB=y  # CONFIG_PAGE_SIZE_64KB is not set diff --git a/target/linux/brcm47xx/config-2.6.22 b/target/linux/brcm47xx/config-2.6.22 index 20f5c3a7a..3399656a9 100644 --- a/target/linux/brcm47xx/config-2.6.22 +++ b/target/linux/brcm47xx/config-2.6.22 @@ -111,10 +111,6 @@ CONFIG_INPUT=m  # CONFIG_IP6_NF_TARGET_HL is not set  CONFIG_IPW2200_QOS=y  # CONFIG_IP_DCCP is not set -# CONFIG_IP_NF_ARPTABLES is not set -# CONFIG_IP_NF_MATCH_ADDRTYPE is not set -# CONFIG_IP_NF_TARGET_NETMAP is not set -# CONFIG_IP_NF_TARGET_SAME is not set  # CONFIG_IP_ROUTE_VERBOSE is not set  CONFIG_IRQ_CPU=y  # CONFIG_LIBCRC32C is not set diff --git a/target/linux/brcm63xx/config-2.6.22 b/target/linux/brcm63xx/config-2.6.22 index f778825a9..95f52f50a 100644 --- a/target/linux/brcm63xx/config-2.6.22 +++ b/target/linux/brcm63xx/config-2.6.22 @@ -132,12 +132,6 @@ CONFIG_IPV6_PRIVACY=y  CONFIG_IPV6_ROUTE_INFO=y  CONFIG_IPV6_TUNNEL=m  CONFIG_IP_MROUTE=y -# CONFIG_IP_NF_ARPTABLES is not set -# CONFIG_IP_NF_MATCH_ADDRTYPE is not set -# CONFIG_IP_NF_TARGET_LOG is not set -# CONFIG_IP_NF_TARGET_NETMAP is not set -CONFIG_IP_NF_TARGET_REJECT=m -# CONFIG_IP_NF_TARGET_SAME is not set  CONFIG_IP_PIMSM_V1=y  CONFIG_IP_PIMSM_V2=y  CONFIG_IP_SCTP=m @@ -254,15 +248,6 @@ CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y  # CONFIG_MTD_SLRAM is not set  # CONFIG_NATSEMI is not set  # CONFIG_NE2K_PCI is not set -CONFIG_NETFILTER_NETLINK=m -CONFIG_NETFILTER_NETLINK_LOG=m -CONFIG_NETFILTER_NETLINK_QUEUE=m -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set -# CONFIG_NETFILTER_XT_TARGET_DSCP is not set -# CONFIG_NET_ACT_IPT is not set -CONFIG_NET_ACT_SIMP=m -CONFIG_NET_KEY=y  CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y  # CONFIG_NET_SCH_CLK_JIFFIES is not set  CONFIG_NET_SCH_FIFO=y diff --git a/target/linux/generic-2.4/config-default b/target/linux/generic-2.4/config-default index 02bb0f2e2..6ae418590 100644 --- a/target/linux/generic-2.4/config-default +++ b/target/linux/generic-2.4/config-default @@ -238,7 +238,7 @@ CONFIG_IP_NF_MATCH_LAYER7=m  CONFIG_IP_NF_MATCH_LENGTH=m  CONFIG_IP_NF_MATCH_LIMIT=y  CONFIG_IP_NF_MATCH_MAC=m -CONFIG_IP_NF_MATCH_MARK=y +CONFIG_IP_NF_MATCH_MARK=m  CONFIG_IP_NF_MATCH_MULTIPORT=y  CONFIG_IP_NF_MATCH_OWNER=m  CONFIG_IP_NF_MATCH_PKTTYPE=m @@ -284,7 +284,7 @@ CONFIG_IP_NF_TARGET_ECN=m  CONFIG_IP_NF_TARGET_CLASSIFY=m  CONFIG_IP_NF_TARGET_IMQ=m  CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_MARK=y +CONFIG_IP_NF_TARGET_MARK=m  CONFIG_IP_NF_TARGET_MASQUERADE=y  CONFIG_IP_NF_TARGET_MIRROR=m  CONFIG_IP_NF_TARGET_NETMAP=m diff --git a/target/linux/generic-2.6/config-2.6.22 b/target/linux/generic-2.6/config-2.6.22 index 2c8e41e37..d9fd908e6 100644 --- a/target/linux/generic-2.6/config-2.6.22 +++ b/target/linux/generic-2.6/config-2.6.22 @@ -534,7 +534,6 @@ CONFIG_IP_NF_ARP_MANGLE=m  CONFIG_IP_NF_CONNTRACK=y  # CONFIG_IP_NF_CONNTRACK_EVENTS is not set  CONFIG_IP_NF_CONNTRACK_MARK=y -# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set  CONFIG_IP_NF_CT_ACCT=y  CONFIG_IP_NF_CT_PROTO_SCTP=m  CONFIG_IP_NF_FILTER=y @@ -588,12 +587,11 @@ CONFIG_IP_NF_TARGET_IMQ=m  CONFIG_IP_NF_TARGET_LOG=m  CONFIG_IP_NF_TARGET_MASQUERADE=y  CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_TARGET_REDIRECT=m  CONFIG_IP_NF_TARGET_REJECT=y  CONFIG_IP_NF_TARGET_ROUTE=m  CONFIG_IP_NF_TARGET_SAME=m  CONFIG_IP_NF_TARGET_SET=m -CONFIG_IP_NF_TARGET_TCPMSS=y  CONFIG_IP_NF_TARGET_TOS=m  CONFIG_IP_NF_TARGET_TTL=m  CONFIG_IP_NF_TARGET_ULOG=m @@ -715,7 +713,7 @@ CONFIG_NETFILTER_XTABLES=y  CONFIG_NETFILTER_XT_MATCH_COMMENT=m  CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m  CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m  CONFIG_NETFILTER_XT_MATCH_DCCP=m  CONFIG_NETFILTER_XT_MATCH_DSCP=m  CONFIG_NETFILTER_XT_MATCH_ESP=m @@ -736,7 +734,7 @@ CONFIG_NETFILTER_XT_MATCH_SCTP=m  CONFIG_NETFILTER_XT_MATCH_STATE=y  # CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set  CONFIG_NETFILTER_XT_MATCH_STRING=m -CONFIG_NETFILTER_XT_MATCH_TCPMSS=y +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m  CONFIG_NETFILTER_XT_TARGET_CHAOS=m  CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m  CONFIG_NETFILTER_XT_TARGET_CONNMARK=m @@ -826,7 +824,7 @@ CONFIG_NFS_V3=y  CONFIG_NFS_V4=y  # CONFIG_NFTL is not set  CONFIG_NF_CONNTRACK=y -# CONFIG_NF_CONNTRACK_AMANDA is not set +CONFIG_NF_CONNTRACK_AMANDA=m  CONFIG_NF_CONNTRACK_ENABLED=y  # CONFIG_NF_CONNTRACK_EVENTS is not set  CONFIG_NF_CONNTRACK_FTP=m @@ -836,24 +834,25 @@ CONFIG_NF_CONNTRACK_IPV4=y  CONFIG_NF_CONNTRACK_IRC=m  CONFIG_NF_CONNTRACK_MARK=y  # CONFIG_NF_CONNTRACK_NETBIOS_NS is not set -# CONFIG_NF_CONNTRACK_PPTP is not set +CONFIG_NF_CONNTRACK_PPTP=m  CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_NF_CONNTRACK_RTSP=m  # CONFIG_NF_CONNTRACK_SANE is not set  CONFIG_NF_CONNTRACK_SIP=m -CONFIG_NF_CONNTRACK_SUPPORT=y -# CONFIG_NF_CONNTRACK_TFTP is not set +CONFIG_NF_CONNTRACK_TFTP=m  CONFIG_NF_CT_ACCT=y  # CONFIG_NF_CT_PROTO_SCTP is not set  CONFIG_NF_NAT=y -# CONFIG_NF_NAT_AMANDA is not set +CONFIG_NF_NAT_AMANDA=m  CONFIG_NF_NAT_FTP=m  CONFIG_NF_NAT_H323=m  CONFIG_NF_NAT_IRC=m  CONFIG_NF_NAT_NEEDED=y -# CONFIG_NF_NAT_PPTP is not set +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_RTSP=m  CONFIG_NF_NAT_SIP=m -# CONFIG_NF_NAT_SNMP_BASIC is not set -# CONFIG_NF_NAT_TFTP is not set +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m  CONFIG_NLS=m  # CONFIG_NLS_ASCII is not set  CONFIG_NLS_CODEPAGE_1250=m diff --git a/target/linux/generic-2.6/patches-2.6.22/190-netfilter_rtsp.patch b/target/linux/generic-2.6/patches-2.6.22/190-netfilter_rtsp.patch new file mode 100644 index 000000000..eac17cf0e --- /dev/null +++ b/target/linux/generic-2.6/patches-2.6.22/190-netfilter_rtsp.patch @@ -0,0 +1,1370 @@ +diff -urN linux-2.6.21-rc7/include/linux/netfilter/nf_conntrack_rtsp.h linux-2.6.21-rc7.rtsp/include/linux/netfilter/nf_conntrack_rtsp.h +--- linux-2.6.21-rc7/include/linux/netfilter/nf_conntrack_rtsp.h	1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21-rc7.rtsp/include/linux/netfilter/nf_conntrack_rtsp.h	2007-04-16 14:07:06.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 **pskb, ++				 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 -urN linux-2.6.21-rc7/include/linux/netfilter_helpers.h linux-2.6.21-rc7.rtsp/include/linux/netfilter_helpers.h +--- linux-2.6.21-rc7/include/linux/netfilter_helpers.h	1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21-rc7.rtsp/include/linux/netfilter_helpers.h	2007-04-15 00:34:57.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 -urN linux-2.6.21-rc7/include/linux/netfilter_mime.h linux-2.6.21-rc7.rtsp/include/linux/netfilter_mime.h +--- linux-2.6.21-rc7/include/linux/netfilter_mime.h	1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21-rc7.rtsp/include/linux/netfilter_mime.h	2007-04-15 00:34:57.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 -urN linux-2.6.21-rc7/net/ipv4/netfilter/Makefile linux-2.6.21-rc7.rtsp/net/ipv4/netfilter/Makefile +--- linux-2.6.21-rc7/net/ipv4/netfilter/Makefile	2007-04-18 23:26:10.000000000 +0200 ++++ linux-2.6.21-rc7.rtsp/net/ipv4/netfilter/Makefile	2007-04-18 21:17:33.000000000 +0200 +@@ -64,6 +66,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 -urN linux-2.6.21-rc7/net/netfilter/Kconfig linux-2.6.21-rc7.rtsp/net/netfilter/Kconfig +--- linux-2.6.21-rc7/net/netfilter/Kconfig	2007-04-18 23:26:10.000000000 +0200 ++++ linux-2.6.21-rc7.rtsp/net/netfilter/Kconfig	2007-04-18 22:25:13.000000000 +0200 +@@ -271,6 +272,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 (EXPERIMENTAL)' + 	depends on EXPERIMENTAL && NF_CONNTRACK && NETFILTER_NETLINK +diff -urN linux-2.6.21-rc7/net/netfilter/Makefile linux-2.6.21-rc7.rtsp/net/netfilter/Makefile +--- linux-2.6.21-rc7/net/netfilter/Makefile	2007-04-18 23:26:10.000000000 +0200 ++++ linux-2.6.21-rc7.rtsp/net/netfilter/Makefile	2007-04-18 21:17:33.000000000 +0200 +@@ -32,6 +32,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 +  + # generic X tables  + obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o +--- linux-2.6.22.1/net/ipv4/netfilter/Kconfig.orig	2007-07-29 23:57:51.000000000 +0200 ++++ linux-2.6.22.1/net/ipv4/netfilter/Kconfig	2007-07-30 00:00:19.000000000 +0200 +@@ -274,6 +274,11 @@ + 	depends on IP_NF_IPTABLES && 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 IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT +--- linux-2.6.22.1/net/netfilter/nf_conntrack_rtsp.c.orig	2007-07-30 17:37:14.000000000 +0200 ++++ linux-2.6.22.1/net/netfilter/nf_conntrack_rtsp.c	2007-07-30 00:03:07.000000000 +0200 +@@ -0,0 +1,515 @@ ++/* ++ * RTSP extension for IP connection tracking ++ * (C) 2003 by Tom Marshall <tmarshall at real.com> ++ * 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_PORTS> ++ *                              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 <laforge at netfilter.org> ++ * 	- port to 2.6 ++ * 	- update to recent post-2.6.11 api changes ++ * 2006-09-14: Steven Van Acker <deepstar at singularity.be> ++ *      - removed calls to NAT code from conntrack helper: NAT no longer needed to use rtsp-conntrack ++ * 2007-04-18: Michael Guntsche <mike at it-loops.com> ++ * 			- Port to new NF API ++ */ ++ ++#include <linux/module.h> ++#include <linux/netfilter.h> ++#include <linux/ip.h> ++#include <linux/inet.h> ++#include <net/tcp.h> ++ ++#include <net/netfilter/nf_conntrack.h> ++#include <net/netfilter/nf_conntrack_expect.h> ++#include <net/netfilter/nf_conntrack_helper.h> ++#include <linux/netfilter/nf_conntrack_rtsp.h> ++ ++#define NF_NEED_STRNCASECMP ++#define NF_NEED_STRTOU16 ++#define NF_NEED_STRTOU32 ++#define NF_NEED_NEXTLINE ++#include <linux/netfilter_helpers.h> ++#define NF_NEED_MIME_NEXTLINE ++#include <linux/netfilter_mime.h> ++ ++#include <linux/ctype.h> ++#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 <tmarshall at real.com>"); ++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 **pskb, ++				 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 **pskb, 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_conntrack_expect_alloc(ct); ++		if (!exp) { ++			ret = NF_DROP; ++			goto out; ++		} ++ ++		be_loport = htons(expinfo.loport); ++ ++		nf_conntrack_expect_init(exp, 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.dst.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(pskb, ctinfo, hdrsoff, hdrslen, &expinfo, exp); ++		else if (nf_conntrack_expect_related(exp) != 0) { ++			INFOP("nf_conntrack_expect_related failed\n"); ++			ret  = NF_DROP; ++		} ++		nf_conntrack_expect_put(exp); ++		goto out; ++	} ++out: ++ ++	return ret; ++} ++ ++ ++static inline int ++help_in(struct sk_buff **pskb, size_t pktlen, ++ struct nf_conn* ct, enum ip_conntrack_info ctinfo) ++{ ++ return NF_ACCEPT; ++} ++ ++static int help(struct sk_buff **pskb, 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(*pskb,protoff, sizeof(_tcph), &_tcph); ++ ++	if (!th) ++		return NF_ACCEPT; ++    ++	/* No data ? */ ++	dataoff = protoff + th->doff*4; ++	datalen = (*pskb)->len - dataoff; ++	if (dataoff >= (*pskb)->len) ++		return NF_ACCEPT; ++ ++	spin_lock_bh(&rtsp_buffer_lock); ++	rb_ptr = skb_header_pointer(*pskb, dataoff, ++				    (*pskb)->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(pskb, 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]; ++ ++/* 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_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->mask.src.u.tcp.port = 0xFFFF; ++		hlpr->mask.dst.protonum = 0xFF; ++		hlpr->max_expected = max_outstanding; ++		hlpr->timeout = setup_timeout; ++		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); ++ +--- linux-2.6.22.1/net/ipv4/netfilter/nf_nat_rtsp.c.orig	2007-07-30 17:35:02.000000000 +0200 ++++ linux-2.6.22.1/net/ipv4/netfilter/nf_nat_rtsp.c	2007-07-30 00:05:28.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 ++ *   pskb       = 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** pskb, 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(*pskb, &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_conntrack_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_conntrack_expect_related(exp) == 0) ++            { ++                hiport = loport + ~exp->mask.dst.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_conntrack_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_conntrack_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(pskb, ct, ctinfo, ++                                                         off, diff, NULL, 0)) ++                    { ++                        /* mangle failed, all we can do is bail */ ++			nf_conntrack_unexpect_related(exp); ++                        return 0; ++                    } ++                    get_skb_tcpdata(*pskb, &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(pskb, ct, ctinfo, ++                                              origoff, origlen, rbuf, rbuflen)) ++                    { ++                        /* mangle failed, all we can do is bail */ ++			nf_conntrack_unexpect_related(exp); ++                        return 0; ++                    } ++                    get_skb_tcpdata(*pskb, &ptcp, &tcplen); ++                    ptran = ptcp+tranoff; ++                    tranlen -= diff; ++                    nextparamoff -= diff; ++                    nextfieldoff -= diff; ++                } ++            } ++ ++            off = nextfieldoff; ++        } ++ ++        off = nextparamoff; ++    } ++ ++    return 1; ++} ++ ++static uint ++help_out(struct sk_buff **pskb, 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*)(*pskb)->nh.iph; ++    //struct tcphdr* tcph = (struct tcphdr*)((void*)iph + iph->ihl*4); ++ ++    get_skb_tcpdata(*pskb, &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, pskb, lineoff, linelen)) ++            { ++		DEBUGP("hdr: Transport mangle failed"); ++                break; ++            } ++            get_skb_tcpdata(*pskb, &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 **pskb, 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(pskb, 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], NF_IP_PRE_ROUTING); ++} ++ ++ ++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 --git a/target/linux/x86/config-2.6.22 b/target/linux/x86/config-2.6.22 index 3df0c5fe7..a848fa96e 100644 --- a/target/linux/x86/config-2.6.22 +++ b/target/linux/x86/config-2.6.22 @@ -151,7 +151,6 @@ CONFIG_INPUT_MOUSEDEV=y  CONFIG_INPUT_MOUSEDEV_PSAUX=y  CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024  CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_IP_NF_SET_IPPORTHASH is not set  CONFIG_IRQBALANCE=y  CONFIG_ISA=y  CONFIG_ISAPNP=y | 
