diff options
author | mbm <mbm@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2004-09-19 07:44:57 +0000 |
---|---|---|
committer | mbm <mbm@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2004-09-19 07:44:57 +0000 |
commit | 61e08700383d20ffb5d28f1e4700c9da2aa17f06 (patch) | |
tree | bc267a68bac7c67c7f638b06d4b1bc2f46ff62a6 /obsolete-buildroot/sources/openwrt | |
parent | 2721db4a989f3c55fd0e3ec5d784afea3834f537 (diff) |
netfilter patches must be applied before other kernel patches to avoid breaking patch-o-matic
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@163 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'obsolete-buildroot/sources/openwrt')
-rw-r--r-- | obsolete-buildroot/sources/openwrt/kernel/netfilter/patches/100-revert_netfilter.patch | 5834 |
1 files changed, 5834 insertions, 0 deletions
diff --git a/obsolete-buildroot/sources/openwrt/kernel/netfilter/patches/100-revert_netfilter.patch b/obsolete-buildroot/sources/openwrt/kernel/netfilter/patches/100-revert_netfilter.patch new file mode 100644 index 000000000..611261f2d --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/kernel/netfilter/patches/100-revert_netfilter.patch @@ -0,0 +1,5834 @@ +diff -Nurb linux/include/linux/netfilter_ipv4/ip_conntrack.h linux.stock/include/linux/netfilter_ipv4/ip_conntrack.h +--- linux/include/linux/netfilter_ipv4/ip_conntrack.h 2003-08-12 07:43:11.000000000 -0400 ++++ linux.stock/include/linux/netfilter_ipv4/ip_conntrack.h 2004-05-09 04:13:03.000000000 -0400 +@@ -45,39 +45,27 @@ + + #include <linux/netfilter_ipv4/ip_conntrack_tcp.h> + #include <linux/netfilter_ipv4/ip_conntrack_icmp.h> +-#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h> + + /* per conntrack: protocol private data */ + union ip_conntrack_proto { + /* insert conntrack proto private data here */ +- struct ip_ct_gre gre; + struct ip_ct_tcp tcp; + struct ip_ct_icmp icmp; + }; + + union ip_conntrack_expect_proto { + /* insert expect proto private data here */ +- struct ip_ct_gre_expect gre; + }; + + /* Add protocol helper include file here */ +-#include <linux/netfilter_ipv4/ip_conntrack_pptp.h> +-#include <linux/netfilter_ipv4/ip_conntrack_mms.h> +-#include <linux/netfilter_ipv4/ip_conntrack_h323.h> +- + #include <linux/netfilter_ipv4/ip_conntrack_ftp.h> + #include <linux/netfilter_ipv4/ip_conntrack_irc.h> +-#include <linux/netfilter_ipv4/ip_autofw.h> + + /* per expectation: application helper private data */ + union ip_conntrack_expect_help { + /* insert conntrack helper private data (expect) here */ +- struct ip_ct_pptp_expect exp_pptp_info; +- struct ip_ct_mms_expect exp_mms_info; +- struct ip_ct_h225_expect exp_h225_info; + struct ip_ct_ftp_expect exp_ftp_info; + struct ip_ct_irc_expect exp_irc_info; +- struct ip_autofw_expect exp_autofw_info; + + #ifdef CONFIG_IP_NF_NAT_NEEDED + union { +@@ -89,21 +77,16 @@ + /* per conntrack: application helper private data */ + union ip_conntrack_help { + /* insert conntrack helper private data (master) here */ +- struct ip_ct_pptp_master ct_pptp_info; +- struct ip_ct_mms_master ct_mms_info; +- struct ip_ct_h225_master ct_h225_info; + struct ip_ct_ftp_master ct_ftp_info; + struct ip_ct_irc_master ct_irc_info; + }; + + #ifdef CONFIG_IP_NF_NAT_NEEDED + #include <linux/netfilter_ipv4/ip_nat.h> +-#include <linux/netfilter_ipv4/ip_nat_pptp.h> + + /* per conntrack: nat application helper private data */ + union ip_conntrack_nat_help { + /* insert nat helper private data here */ +- struct ip_nat_pptp nat_pptp_info; + }; + #endif + +@@ -275,9 +258,5 @@ + } + + extern unsigned int ip_conntrack_htable_size; +- +-/* connection tracking time out variables. */ +-extern int sysctl_ip_conntrack_tcp_timeouts[10]; +-extern int sysctl_ip_conntrack_udp_timeouts[2]; + #endif /* __KERNEL__ */ + #endif /* _IP_CONNTRACK_H */ +diff -Nurb linux/include/linux/netfilter_ipv4/ip_conntrack_h323.h linux.stock/include/linux/netfilter_ipv4/ip_conntrack_h323.h +--- linux/include/linux/netfilter_ipv4/ip_conntrack_h323.h 2003-07-04 04:12:27.000000000 -0400 ++++ linux.stock/include/linux/netfilter_ipv4/ip_conntrack_h323.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,30 +0,0 @@ +-#ifndef _IP_CONNTRACK_H323_H +-#define _IP_CONNTRACK_H323_H +-/* H.323 connection tracking. */ +- +-#ifdef __KERNEL__ +-/* Protects H.323 related data */ +-DECLARE_LOCK_EXTERN(ip_h323_lock); +-#endif +- +-/* Default H.225 port */ +-#define H225_PORT 1720 +- +-/* This structure is per expected connection */ +-struct ip_ct_h225_expect { +- u_int16_t port; /* Port of the H.225 helper/RTCP/RTP channel */ +- enum ip_conntrack_dir dir; /* Direction of the original connection */ +- unsigned int offset; /* offset of the address in the payload */ +-}; +- +-/* This structure exists only once per master */ +-struct ip_ct_h225_master { +- int is_h225; /* H.225 or H.245 connection */ +-#ifdef CONFIG_IP_NF_NAT_NEEDED +- enum ip_conntrack_dir dir; /* Direction of the original connection */ +- u_int32_t seq[IP_CT_DIR_MAX]; /* Exceptional packet mangling for signal addressess... */ +- unsigned int offset[IP_CT_DIR_MAX]; /* ...and the offset of the addresses in the payload */ +-#endif +-}; +- +-#endif /* _IP_CONNTRACK_H323_H */ +diff -Nurb linux/include/linux/netfilter_ipv4/ip_conntrack_mms.h linux.stock/include/linux/netfilter_ipv4/ip_conntrack_mms.h +--- linux/include/linux/netfilter_ipv4/ip_conntrack_mms.h 2003-07-04 04:12:27.000000000 -0400 ++++ linux.stock/include/linux/netfilter_ipv4/ip_conntrack_mms.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,31 +0,0 @@ +-#ifndef _IP_CONNTRACK_MMS_H +-#define _IP_CONNTRACK_MMS_H +-/* MMS tracking. */ +- +-#ifdef __KERNEL__ +-#include <linux/netfilter_ipv4/lockhelp.h> +- +-DECLARE_LOCK_EXTERN(ip_mms_lock); +- +-#define MMS_PORT 1755 +-#define MMS_SRV_MSG_ID 196610 +- +-#define MMS_SRV_MSG_OFFSET 36 +-#define MMS_SRV_UNICODE_STRING_OFFSET 60 +-#define MMS_SRV_CHUNKLENLV_OFFSET 16 +-#define MMS_SRV_CHUNKLENLM_OFFSET 32 +-#define MMS_SRV_MESSAGELENGTH_OFFSET 8 +-#endif +- +-/* This structure is per expected connection */ +-struct ip_ct_mms_expect { +- u_int32_t len; +- u_int32_t padding; +- u_int16_t port; +-}; +- +-/* This structure exists only once per master */ +-struct ip_ct_mms_master { +-}; +- +-#endif /* _IP_CONNTRACK_MMS_H */ +diff -Nurb linux/include/linux/netfilter_ipv4/ip_conntrack_pptp.h linux.stock/include/linux/netfilter_ipv4/ip_conntrack_pptp.h +--- linux/include/linux/netfilter_ipv4/ip_conntrack_pptp.h 2003-07-04 04:12:27.000000000 -0400 ++++ linux.stock/include/linux/netfilter_ipv4/ip_conntrack_pptp.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,313 +0,0 @@ +-/* PPTP constants and structs */ +-#ifndef _CONNTRACK_PPTP_H +-#define _CONNTRACK_PPTP_H +- +-/* state of the control session */ +-enum pptp_ctrlsess_state { +- PPTP_SESSION_NONE, /* no session present */ +- PPTP_SESSION_ERROR, /* some session error */ +- PPTP_SESSION_STOPREQ, /* stop_sess request seen */ +- PPTP_SESSION_REQUESTED, /* start_sess request seen */ +- PPTP_SESSION_CONFIRMED, /* session established */ +-}; +- +-/* state of the call inside the control session */ +-enum pptp_ctrlcall_state { +- PPTP_CALL_NONE, +- PPTP_CALL_ERROR, +- PPTP_CALL_OUT_REQ, +- PPTP_CALL_OUT_CONF, +- PPTP_CALL_IN_REQ, +- PPTP_CALL_IN_REP, +- PPTP_CALL_IN_CONF, +- PPTP_CALL_CLEAR_REQ, +-}; +- +- +-/* conntrack private data */ +-struct ip_ct_pptp_master { +- enum pptp_ctrlsess_state sstate; /* session state */ +- +- /* everything below is going to be per-expectation in newnat, +- * since there could be more than one call within one session */ +- enum pptp_ctrlcall_state cstate; /* call state */ +- u_int16_t pac_call_id; /* call id of PAC, host byte order */ +- u_int16_t pns_call_id; /* call id of PNS, host byte order */ +-}; +- +-/* conntrack_expect private member */ +-struct ip_ct_pptp_expect { +- enum pptp_ctrlcall_state cstate; /* call state */ +- u_int16_t pac_call_id; /* call id of PAC */ +- u_int16_t pns_call_id; /* call id of PNS */ +-}; +- +- +-#ifdef __KERNEL__ +- +-#include <linux/netfilter_ipv4/lockhelp.h> +-DECLARE_LOCK_EXTERN(ip_pptp_lock); +- +-#define IP_CONNTR_PPTP PPTP_CONTROL_PORT +- +-union pptp_ctrl_union { +- void *rawreq; +- struct PptpStartSessionRequest *sreq; +- struct PptpStartSessionReply *srep; +- struct PptpStopSessionReqest *streq; +- struct PptpStopSessionReply *strep; +- struct PptpOutCallRequest *ocreq; +- struct PptpOutCallReply *ocack; +- struct PptpInCallRequest *icreq; +- struct PptpInCallReply *icack; +- struct PptpInCallConnected *iccon; +- struct PptpClearCallRequest *clrreq; +- struct PptpCallDisconnectNotify *disc; +- struct PptpWanErrorNotify *wanerr; +- struct PptpSetLinkInfo *setlink; +-}; +- +- +- +-#define PPTP_CONTROL_PORT 1723 +- +-#define PPTP_PACKET_CONTROL 1 +-#define PPTP_PACKET_MGMT 2 +- +-#define PPTP_MAGIC_COOKIE 0x1a2b3c4d +- +-struct pptp_pkt_hdr { +- __u16 packetLength; +- __u16 packetType; +- __u32 magicCookie; +-}; +- +-/* PptpControlMessageType values */ +-#define PPTP_START_SESSION_REQUEST 1 +-#define PPTP_START_SESSION_REPLY 2 +-#define PPTP_STOP_SESSION_REQUEST 3 +-#define PPTP_STOP_SESSION_REPLY 4 +-#define PPTP_ECHO_REQUEST 5 +-#define PPTP_ECHO_REPLY 6 +-#define PPTP_OUT_CALL_REQUEST 7 +-#define PPTP_OUT_CALL_REPLY 8 +-#define PPTP_IN_CALL_REQUEST 9 +-#define PPTP_IN_CALL_REPLY 10 +-#define PPTP_IN_CALL_CONNECT 11 +-#define PPTP_CALL_CLEAR_REQUEST 12 +-#define PPTP_CALL_DISCONNECT_NOTIFY 13 +-#define PPTP_WAN_ERROR_NOTIFY 14 +-#define PPTP_SET_LINK_INFO 15 +- +-#define PPTP_MSG_MAX 15 +- +-/* PptpGeneralError values */ +-#define PPTP_ERROR_CODE_NONE 0 +-#define PPTP_NOT_CONNECTED 1 +-#define PPTP_BAD_FORMAT 2 +-#define PPTP_BAD_VALUE 3 +-#define PPTP_NO_RESOURCE 4 +-#define PPTP_BAD_CALLID 5 +-#define PPTP_REMOVE_DEVICE_ERROR 6 +- +-struct PptpControlHeader { +- __u16 messageType; +- __u16 reserved; +-}; +- +-/* FramingCapability Bitmap Values */ +-#define PPTP_FRAME_CAP_ASYNC 0x1 +-#define PPTP_FRAME_CAP_SYNC 0x2 +- +-/* BearerCapability Bitmap Values */ +-#define PPTP_BEARER_CAP_ANALOG 0x1 +-#define PPTP_BEARER_CAP_DIGITAL 0x2 +- +-struct PptpStartSessionRequest { +- __u16 protocolVersion; +- __u8 reserved1; +- __u8 reserved2; +- __u32 framingCapability; +- __u32 bearerCapability; +- __u16 maxChannels; +- __u16 firmwareRevision; +- __u8 hostName[64]; +- __u8 vendorString[64]; +-}; +- +-/* PptpStartSessionResultCode Values */ +-#define PPTP_START_OK 1 +-#define PPTP_START_GENERAL_ERROR 2 +-#define PPTP_START_ALREADY_CONNECTED 3 +-#define PPTP_START_NOT_AUTHORIZED 4 +-#define PPTP_START_UNKNOWN_PROTOCOL 5 +- +-struct PptpStartSessionReply { +- __u16 protocolVersion; +- __u8 resultCode; +- __u8 generalErrorCode; +- __u32 framingCapability; +- __u32 bearerCapability; +- __u16 maxChannels; +- __u16 firmwareRevision; +- __u8 hostName[64]; +- __u8 vendorString[64]; +-}; +- +-/* PptpStopReasons */ +-#define PPTP_STOP_NONE 1 +-#define PPTP_STOP_PROTOCOL 2 +-#define PPTP_STOP_LOCAL_SHUTDOWN 3 +- +-struct PptpStopSessionRequest { +- __u8 reason; +-}; +- +-/* PptpStopSessionResultCode */ +-#define PPTP_STOP_OK 1 +-#define PPTP_STOP_GENERAL_ERROR 2 +- +-struct PptpStopSessionReply { +- __u8 resultCode; +- __u8 generalErrorCode; +-}; +- +-struct PptpEchoRequest { +- __u32 identNumber; +-}; +- +-/* PptpEchoReplyResultCode */ +-#define PPTP_ECHO_OK 1 +-#define PPTP_ECHO_GENERAL_ERROR 2 +- +-struct PptpEchoReply { +- __u32 identNumber; +- __u8 resultCode; +- __u8 generalErrorCode; +- __u16 reserved; +-}; +- +-/* PptpFramingType */ +-#define PPTP_ASYNC_FRAMING 1 +-#define PPTP_SYNC_FRAMING 2 +-#define PPTP_DONT_CARE_FRAMING 3 +- +-/* PptpCallBearerType */ +-#define PPTP_ANALOG_TYPE 1 +-#define PPTP_DIGITAL_TYPE 2 +-#define PPTP_DONT_CARE_BEARER_TYPE 3 +- +-struct PptpOutCallRequest { +- __u16 callID; +- __u16 callSerialNumber; +- __u32 minBPS; +- __u32 maxBPS; +- __u32 bearerType; +- __u32 framingType; +- __u16 packetWindow; +- __u16 packetProcDelay; +- __u16 reserved1; +- __u16 phoneNumberLength; +- __u16 reserved2; +- __u8 phoneNumber[64]; +- __u8 subAddress[64]; +-}; +- +-/* PptpCallResultCode */ +-#define PPTP_OUTCALL_CONNECT 1 +-#define PPTP_OUTCALL_GENERAL_ERROR 2 +-#define PPTP_OUTCALL_NO_CARRIER 3 +-#define PPTP_OUTCALL_BUSY 4 +-#define PPTP_OUTCALL_NO_DIAL_TONE 5 +-#define PPTP_OUTCALL_TIMEOUT 6 +-#define PPTP_OUTCALL_DONT_ACCEPT 7 +- +-struct PptpOutCallReply { +- __u16 callID; +- __u16 peersCallID; +- __u8 resultCode; +- __u8 generalErrorCode; +- __u16 causeCode; +- __u32 connectSpeed; +- __u16 packetWindow; +- __u16 packetProcDelay; +- __u32 physChannelID; +-}; +- +-struct PptpInCallRequest { +- __u16 callID; +- __u16 callSerialNumber; +- __u32 callBearerType; +- __u32 physChannelID; +- __u16 dialedNumberLength; +- __u16 dialingNumberLength; +- __u8 dialedNumber[64]; +- __u8 dialingNumber[64]; +- __u8 subAddress[64]; +-}; +- +-/* PptpInCallResultCode */ +-#define PPTP_INCALL_ACCEPT 1 +-#define PPTP_INCALL_GENERAL_ERROR 2 +-#define PPTP_INCALL_DONT_ACCEPT 3 +- +-struct PptpInCallReply { +- __u16 callID; +- __u16 peersCallID; +- __u8 resultCode; +- __u8 generalErrorCode; +- __u16 packetWindow; +- __u16 packetProcDelay; +- __u16 reserved; +-}; +- +-struct PptpInCallConnected { +- __u16 peersCallID; +- __u16 reserved; +- __u32 connectSpeed; +- __u16 packetWindow; +- __u16 packetProcDelay; +- __u32 callFramingType; +-}; +- +-struct PptpClearCallRequest { +- __u16 callID; +- __u16 reserved; +-}; +- +-struct PptpCallDisconnectNotify { +- __u16 callID; +- __u8 resultCode; +- __u8 generalErrorCode; +- __u16 causeCode; +- __u16 reserved; +- __u8 callStatistics[128]; +-}; +- +-struct PptpWanErrorNotify { +- __u16 peersCallID; +- __u16 reserved; +- __u32 crcErrors; +- __u32 framingErrors; +- __u32 hardwareOverRuns; +- __u32 bufferOverRuns; +- __u32 timeoutErrors; +- __u32 alignmentErrors; +-}; +- +-struct PptpSetLinkInfo { +- __u16 peersCallID; +- __u16 reserved; +- __u32 sendAccm; +- __u32 recvAccm; +-}; +- +- +-struct pptp_priv_data { +- __u16 call_id; +- __u16 mcall_id; +- __u16 pcall_id; +-}; +- +-#endif /* __KERNEL__ */ +-#endif /* _CONNTRACK_PPTP_H */ +diff -Nurb linux/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h linux.stock/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h +--- linux/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h 2003-07-04 04:12:27.000000000 -0400 ++++ linux.stock/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,121 +0,0 @@ +-#ifndef _CONNTRACK_PROTO_GRE_H +-#define _CONNTRACK_PROTO_GRE_H +-#include <asm/byteorder.h> +- +-/* GRE PROTOCOL HEADER */ +- +-/* GRE Version field */ +-#define GRE_VERSION_1701 0x0 +-#define GRE_VERSION_PPTP 0x1 +- +-/* GRE Protocol field */ +-#define GRE_PROTOCOL_PPTP 0x880B +- +-/* GRE Flags */ +-#define GRE_FLAG_C 0x80 +-#define GRE_FLAG_R 0x40 +-#define GRE_FLAG_K 0x20 +-#define GRE_FLAG_S 0x10 +-#define GRE_FLAG_A 0x80 +- +-#define GRE_IS_C(f) ((f)&GRE_FLAG_C) +-#define GRE_IS_R(f) ((f)&GRE_FLAG_R) +-#define GRE_IS_K(f) ((f)&GRE_FLAG_K) +-#define GRE_IS_S(f) ((f)&GRE_FLAG_S) +-#define GRE_IS_A(f) ((f)&GRE_FLAG_A) +- +-/* GRE is a mess: Four different standards */ +-struct gre_hdr { +-#if defined(__LITTLE_ENDIAN_BITFIELD) +- __u16 rec:3, +- srr:1, +- seq:1, +- key:1, +- routing:1, +- csum:1, +- version:3, +- reserved:4, +- ack:1; +-#elif defined(__BIG_ENDIAN_BITFIELD) +- __u16 csum:1, +- routing:1, +- key:1, +- seq:1, +- srr:1, +- rec:3, +- ack:1, +- reserved:4, +- version:3; +-#else +-#error "Adjust your <asm/byteorder.h> defines" +-#endif +- __u16 protocol; +-}; +- +-/* modified GRE header for PPTP */ +-struct gre_hdr_pptp { +- __u8 flags; /* bitfield */ +- __u8 version; /* should be GRE_VERSION_PPTP */ +- __u16 protocol; /* should be GRE_PROTOCOL_PPTP */ +- __u16 payload_len; /* size of ppp payload, not inc. gre header */ +- __u16 call_id; /* peer's call_id for this session */ +- __u32 seq; /* sequence number. Present if S==1 */ +- __u32 ack; /* seq number of highest packet recieved by */ +- /* sender in this session */ +-}; +- +- +-/* this is part of ip_conntrack */ +-struct ip_ct_gre { +- unsigned int stream_timeout; +- unsigned int timeout; +-}; +- +-/* this is part of ip_conntrack_expect */ +-struct ip_ct_gre_expect { +- struct ip_ct_gre_keymap *keymap_orig, *keymap_reply; +-}; +- +-#ifdef __KERNEL__ +- +-/* structure for original <-> reply keymap */ +-struct ip_ct_gre_keymap { +- struct list_head list; +- +- struct ip_conntrack_tuple tuple; +- struct ip_conntrack_expect *master; +-}; +- +- +-/* add new tuple->key_reply pair to keymap */ +-int ip_ct_gre_keymap_add(struct ip_conntrack_expect *exp, +- struct ip_conntrack_tuple *t, +- int reply); +- +-/* change an existing keymap entry */ +-void ip_ct_gre_keymap_change(struct ip_ct_gre_keymap *km, +- struct ip_conntrack_tuple *t); +- +- +- +-/* get pointer to gre key, if present */ +-static inline u_int32_t *gre_key(struct gre_hdr *greh) +-{ +- if (!greh->key) +- return NULL; +- if (greh->csum || greh->routing) +- return (u_int32_t *) (greh+sizeof(*greh)+4); +- return (u_int32_t *) (greh+sizeof(*greh)); +-} +- +-/* get pointer ot gre csum, if present */ +-static inline u_int16_t *gre_csum(struct gre_hdr *greh) +-{ +- if (!greh->csum) +- return NULL; +- return (u_int16_t *) (greh+sizeof(*greh)); +-} +- +-#endif /* __KERNEL__ */ +- +-#endif /* _CONNTRACK_PROTO_GRE_H */ +diff -Nurb linux/include/linux/netfilter_ipv4/ip_conntrack_tftp.h linux.stock/include/linux/netfilter_ipv4/ip_conntrack_tftp.h +--- linux/include/linux/netfilter_ipv4/ip_conntrack_tftp.h 2003-07-04 04:12:27.000000000 -0400 ++++ linux.stock/include/linux/netfilter_ipv4/ip_conntrack_tftp.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,13 +0,0 @@ +-#ifndef _IP_CT_TFTP +-#define _IP_CT_TFTP +- +-#define TFTP_PORT 69 +- +-struct tftphdr { +- u_int16_t opcode; +-}; +- +-#define TFTP_OPCODE_READ 1 +-#define TFTP_OPCODE_WRITE 2 +- +-#endif /* _IP_CT_TFTP */ +diff -Nurb linux/include/linux/netfilter_ipv4/ip_conntrack_tuple.h linux.stock/include/linux/netfilter_ipv4/ip_conntrack_tuple.h +--- linux/include/linux/netfilter_ipv4/ip_conntrack_tuple.h 2003-07-04 04:12:27.000000000 -0400 ++++ linux.stock/include/linux/netfilter_ipv4/ip_conntrack_tuple.h 2004-05-09 04:13:03.000000000 -0400 +@@ -14,7 +14,7 @@ + union ip_conntrack_manip_proto + { + /* Add other protocols here. */ +- u_int32_t all; ++ u_int16_t all; + + struct { + u_int16_t port; +@@ -25,9 +25,6 @@ + struct { + u_int16_t id; + } icmp; +- struct { +- u_int32_t key; +- } gre; + }; + + /* The manipulable part of the tuple. */ +@@ -47,7 +44,7 @@ + u_int32_t ip; + union { + /* Add other protocols here. */ +- u_int64_t all; ++ u_int16_t all; + + struct { + u_int16_t port; +@@ -58,11 +55,6 @@ + struct { + u_int8_t type, code; + } icmp; +- struct { +- u_int16_t protocol; +- u_int8_t version; +- u_int32_t key; +- } gre; + } u; + + /* The protocol. */ +@@ -80,16 +72,10 @@ + #ifdef __KERNEL__ + + #define DUMP_TUPLE(tp) \ +-DEBUGP("tuple %p: %u %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n", \ ++DEBUGP("tuple %p: %u %u.%u.%u.%u:%hu -> %u.%u.%u.%u:%hu\n", \ + (tp), (tp)->dst.protonum, \ +- NIPQUAD((tp)->src.ip), ntohl((tp)->src.u.all), \ +- NIPQUAD((tp)->dst.ip), ntohl((tp)->dst.u.all)) +- +-#define DUMP_TUPLE_RAW(x) \ +- DEBUGP("tuple %p: %u %u.%u.%u.%u:0x%08x -> %u.%u.%u.%u:0x%08x\n",\ +- (x), (x)->dst.protonum, \ +- NIPQUAD((x)->src.ip), ntohl((x)->src.u.all), \ +- NIPQUAD((x)->dst.ip), ntohl((x)->dst.u.all)) ++ NIPQUAD((tp)->src.ip), ntohs((tp)->src.u.all), \ ++ NIPQUAD((tp)->dst.ip), ntohs((tp)->dst.u.all)) + + #define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL) + +diff -Nurb linux/include/linux/netfilter_ipv4/ip_nat_pptp.h linux.stock/include/linux/netfilter_ipv4/ip_nat_pptp.h +--- linux/include/linux/netfilter_ipv4/ip_nat_pptp.h 2003-07-04 04:12:27.000000000 -0400 ++++ linux.stock/include/linux/netfilter_ipv4/ip_nat_pptp.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,11 +0,0 @@ +-/* PPTP constants and structs */ +-#ifndef _NAT_PPTP_H +-#define _NAT_PPTP_H +- +-/* conntrack private data */ +-struct ip_nat_pptp { +- u_int16_t pns_call_id; /* NAT'ed PNS call id */ +- u_int16_t pac_call_id; /* NAT'ed PAC call id */ +-}; +- +-#endif /* _NAT_PPTP_H */ +diff -Nurb linux/include/linux/netfilter_ipv4/ip_pool.h linux.stock/include/linux/netfilter_ipv4/ip_pool.h +--- linux/include/linux/netfilter_ipv4/ip_pool.h 2003-07-04 04:12:27.000000000 -0400 ++++ linux.stock/include/linux/netfilter_ipv4/ip_pool.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,64 +0,0 @@ +-#ifndef _IP_POOL_H +-#define _IP_POOL_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. */ +-/* */ +-/* This program is distributed in the hope that it will be useful, */ +-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +-/* GNU General Public License for more details. */ +-/* */ +-/* You should have received a copy of the GNU General Public License */ +-/* along with this program; if not, write to the Free Software */ +-/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/ +-/***************************************************************************/ +- +-/* A sockopt of such quality has hardly ever been seen before on the open +- * market! This little beauty, hardly ever used: above 64, so it's +- * traditionally used for firewalling, not touched (even once!) by the +- * 2.0, 2.2 and 2.4 kernels! +- * +- * Comes with its own certificate of authenticity, valid anywhere in the +- * Free world! +- * +- * Rusty, 19.4.2000 +- */ +-#define SO_IP_POOL 81 +- +-typedef int ip_pool_t; /* pool index */ +-#define IP_POOL_NONE ((ip_pool_t)-1) +- +-struct ip_pool_request { +- int op; +- ip_pool_t index; +- u_int32_t addr; +- u_int32_t addr2; +-}; +- +-/* NOTE: I deliberately break the first cut ippool utility. Nobody uses it. */ +- +-#define IP_POOL_BAD001 0x00000010 +- +-#define IP_POOL_FLUSH 0x00000011 /* req.index, no arguments */ +-#define IP_POOL_INIT 0x00000012 /* from addr to addr2 incl. */ +-#define IP_POOL_DESTROY 0x00000013 /* req.index, no arguments */ +-#define IP_POOL_ADD_ADDR 0x00000014 /* add addr to pool */ +-#define IP_POOL_DEL_ADDR 0x00000015 /* del addr from pool */ +-#define IP_POOL_HIGH_NR 0x00000016 /* result in req.index */ +-#define IP_POOL_LOOKUP 0x00000017 /* result in addr and addr2 */ +-#define IP_POOL_USAGE 0x00000018 /* result in addr */ +-#define IP_POOL_TEST_ADDR 0x00000019 /* result (0/1) returned */ +- +-#ifdef __KERNEL__ +- +-/* NOTE: ip_pool_match() and ip_pool_mod() expect ADDR to be host byte order */ +-extern int ip_pool_match(ip_pool_t pool, u_int32_t addr); +-extern int ip_pool_mod(ip_pool_t pool, u_int32_t addr, int isdel); +- +-#endif +- +-#endif /*_IP_POOL_H*/ +diff -Nurb linux/include/linux/netfilter_ipv4/ipt_pool.h linux.stock/include/linux/netfilter_ipv4/ipt_pool.h +--- linux/include/linux/netfilter_ipv4/ipt_pool.h 2003-07-04 04:12:27.000000000 -0400 ++++ linux.stock/include/linux/netfilter_ipv4/ipt_pool.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,25 +0,0 @@ +-#ifndef _IPT_POOL_H +-#define _IPT_POOL_H +- +-#include <linux/netfilter_ipv4/ip_pool.h> +- +-#define IPT_POOL_INV_SRC 0x00000001 +-#define IPT_POOL_INV_DST 0x00000002 +-#define IPT_POOL_DEL_SRC 0x00000004 +-#define IPT_POOL_DEL_DST 0x00000008 +-#define IPT_POOL_INV_MOD_SRC 0x00000010 +-#define IPT_POOL_INV_MOD_DST 0x00000020 +-#define IPT_POOL_MOD_SRC_ACCEPT 0x00000040 +-#define IPT_POOL_MOD_DST_ACCEPT 0x00000080 +-#define IPT_POOL_MOD_SRC_DROP 0x00000100 +-#define IPT_POOL_MOD_DST_DROP 0x00000200 +- +-/* match info */ +-struct ipt_pool_info +-{ +- ip_pool_t src; +- ip_pool_t dst; +- unsigned flags; +-}; +- +-#endif /*_IPT_POOL_H*/ +diff -Nurb linux/net/ipv4/netfilter/Config.in linux.stock/net/ipv4/netfilter/Config.in +--- linux/net/ipv4/netfilter/Config.in 2004-02-19 06:04:35.000000000 -0500 ++++ linux.stock/net/ipv4/netfilter/Config.in 2004-05-09 04:13:03.000000000 -0400 +@@ -7,12 +7,7 @@ + tristate 'Connection tracking (required for masq/NAT)' CONFIG_IP_NF_CONNTRACK + if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then + dep_tristate ' FTP protocol support' CONFIG_IP_NF_FTP $CONFIG_IP_NF_CONNTRACK +- dep_tristate ' TFTP protocol support' CONFIG_IP_NF_TFTP $CONFIG_IP_NF_CONNTRACK +- dep_tristate ' H.323 (netmeeting) support' CONFIG_IP_NF_H323 $CONFIG_IP_NF_CONNTRACK + dep_tristate ' IRC protocol support' CONFIG_IP_NF_IRC $CONFIG_IP_NF_CONNTRACK +- dep_tristate ' MMS protocol support' CONFIG_IP_NF_MMS $CONFIG_IP_NF_CONNTRACK +- dep_tristate ' GRE protocol support' CONFIG_IP_NF_CT_PROTO_GRE $CONFIG_IP_NF_CONNTRACK +- dep_tristate ' PPTP protocol support' CONFIG_IP_NF_PPTP $CONFIG_IP_NF_CT_PROTO_GRE + fi + + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then +@@ -22,19 +17,11 @@ + if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; then + # The simple matches. + dep_tristate ' limit match support' CONFIG_IP_NF_MATCH_LIMIT $CONFIG_IP_NF_IPTABLES +- +- dep_tristate ' IP address pool support' CONFIG_IP_NF_POOL $CONFIG_IP_NF_IPTABLES +- if [ "$CONFIG_IP_NF_POOL" = "y" -o "$CONFIG_IP_NF_POOL" = "m" ]; then +- bool ' enable statistics on pool usage' CONFIG_IP_POOL_STATISTICS n +- fi +- + dep_tristate ' MAC address match support' CONFIG_IP_NF_MATCH_MAC $CONFIG_IP_NF_IPTABLES + dep_tristate ' Packet type match support' CONFIG_IP_NF_MATCH_PKTTYPE $CONFIG_IP_NF_IPTABLES + dep_tristate ' netfilter MARK match support' CONFIG_IP_NF_MATCH_MARK $CONFIG_IP_NF_IPTABLES + dep_tristate ' Multiple port match support' CONFIG_IP_NF_MATCH_MULTIPORT $CONFIG_IP_NF_IPTABLES +- dep_tristate ' Multiple port with ranges match support' CONFIG_IP_NF_MATCH_MPORT $CONFIG_IP_NF_IPTABLES + dep_tristate ' TOS match support' CONFIG_IP_NF_MATCH_TOS $CONFIG_IP_NF_IPTABLES +- dep_tristate ' TIME match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_TIME $CONFIG_IP_NF_IPTABLES + dep_tristate ' ECN match support' CONFIG_IP_NF_MATCH_ECN $CONFIG_IP_NF_IPTABLES + + dep_tristate ' DSCP match support' CONFIG_IP_NF_MATCH_DSCP $CONFIG_IP_NF_IPTABLES +@@ -52,7 +39,6 @@ + fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' Unclean match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_UNCLEAN $CONFIG_IP_NF_IPTABLES +- dep_tristate ' Webstr match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_WEBSTR $CONFIG_IP_NF_IPTABLES + dep_tristate ' Owner match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_OWNER $CONFIG_IP_NF_IPTABLES + fi + # The targets +@@ -70,29 +56,6 @@ + define_bool CONFIG_IP_NF_NAT_NEEDED y + dep_tristate ' MASQUERADE target support' CONFIG_IP_NF_TARGET_MASQUERADE $CONFIG_IP_NF_NAT + dep_tristate ' REDIRECT target support' CONFIG_IP_NF_TARGET_REDIRECT $CONFIG_IP_NF_NAT +- dep_tristate ' Automatic port forwarding (autofw) target support' CONFIG_IP_NF_AUTOFW $CONFIG_IP_NF_NAT +- dep_tristate ' TRIGGER target support (port-trigger)' CONFIG_IP_NF_TARGET_TRIGGER $CONFIG_IP_NF_NAT +- if [ "$CONFIG_IP_NF_H323" = "m" ]; then +- define_tristate CONFIG_IP_NF_NAT_H323 m +- else +- if [ "$CONFIG_IP_NF_H323" = "y" ]; then +- define_tristate CONFIG_IP_NF_NAT_H323 $CONFIG_IP_NF_NAT +- fi +- fi +- if [ "$CONFIG_IP_NF_PPTP" = "m" ]; then +- define_tristate CONFIG_IP_NF_NAT_PPTP m +- else +- if [ "$CONFIG_IP_NF_PPTP" = "y" ]; then +- define_tristate CONFIG_IP_NF_NAT_PPTP $CONFIG_IP_NF_NAT +- fi +- fi +- if [ "$CONFIG_IP_NF_CT_PROTO_GRE" = "m" ]; then +- define_tristate CONFIG_IP_NF_NAT_PROTO_GRE m +- else +- if [ "$CONFIG_IP_NF_CT_PROTO_GRE" = "y" ]; then +- define_tristate CONFIG_IP_NF_NAT_PROTO_GRE $CONFIG_IP_NF_NAT +- fi +- fi + bool ' NAT of local connections (READ HELP)' CONFIG_IP_NF_NAT_LOCAL + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' Basic SNMP-ALG support (EXPERIMENTAL)' CONFIG_IP_NF_NAT_SNMP_BASIC $CONFIG_IP_NF_NAT +@@ -104,13 +67,6 @@ + define_tristate CONFIG_IP_NF_NAT_IRC $CONFIG_IP_NF_NAT + fi + fi +- if [ "$CONFIG_IP_NF_MMS" = "m" ]; then +- define_tristate CONFIG_IP_NF_NAT_MMS m +- else +- if [ "$CONFIG_IP_NF_MMS" = "y" ]; then +- define_tristate CONFIG_IP_NF_NAT_MMS $CONFIG_IP_NF_NAT +- fi +- fi + # If they want FTP, set to $CONFIG_IP_NF_NAT (m or y), + # or $CONFIG_IP_NF_FTP (m or y), whichever is weaker. Argh. + if [ "$CONFIG_IP_NF_FTP" = "m" ]; then +@@ -120,13 +76,6 @@ + define_tristate CONFIG_IP_NF_NAT_FTP $CONFIG_IP_NF_NAT + fi + fi +- if [ "$CONFIG_IP_NF_TFTP" = "m" ]; then +- define_tristate CONFIG_IP_NF_NAT_TFTP m +- else +- if [ "$CONFIG_IP_NF_TFTP" = "y" ]; then +- define_tristate CONFIG_IP_NF_NAT_TFTP $CONFIG_IP_NF_NAT +- fi +- fi + fi + fi + +diff -Nurb linux/net/ipv4/netfilter/Makefile linux.stock/net/ipv4/netfilter/Makefile +--- linux/net/ipv4/netfilter/Makefile 2004-02-19 06:04:35.000000000 -0500 ++++ linux.stock/net/ipv4/netfilter/Makefile 2004-05-09 04:13:03.000000000 -0400 +@@ -31,48 +31,20 @@ + # connection tracking + obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o + +-# H.323 support +-obj-$(CONFIG_IP_NF_H323) += ip_conntrack_h323.o +-obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o +-ifdef CONFIG_IP_NF_NAT_H323 +- export-objs += ip_conntrack_h323.o +-endif +- +- +-# connection tracking protocol helpers +-obj-$(CONFIG_IP_NF_CT_PROTO_GRE) += ip_conntrack_proto_gre.o +-ifdef CONFIG_IP_NF_CT_PROTO_GRE +- export-objs += ip_conntrack_proto_gre.o +-endif +- +-# NAT protocol helpers +-obj-$(CONFIG_IP_NF_NAT_PROTO_GRE) += ip_nat_proto_gre.o +- + # connection tracking helpers +-obj-$(CONFIG_IP_NF_MMS) += ip_conntrack_mms.o +-ifdef CONFIG_IP_NF_NAT_MMS +- export-objs += ip_conntrack_mms.o +-endif +-obj-$(CONFIG_IP_NF_PPTP) += ip_conntrack_pptp.o +-ifdef CONFIG_IP_NF_NAT_PPTP +- export-objs += ip_conntrack_pptp.o +-endif +-obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o + obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o + ifdef CONFIG_IP_NF_NAT_FTP + export-objs += ip_conntrack_ftp.o + endif ++ + obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o + ifdef CONFIG_IP_NF_NAT_IRC + export-objs += ip_conntrack_irc.o + endif + + # NAT helpers +-obj-$(CONFIG_IP_NF_NAT_PPTP) += ip_nat_pptp.o +-obj-$(CONFIG_IP_NF_NAT_TFTP) += ip_nat_tftp.o + obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o + obj-$(CONFIG_IP_NF_NAT_IRC) += ip_nat_irc.o +-obj-$(CONFIG_IP_NF_NAT_MMS) += ip_nat_mms.o + + # generic IP tables + obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o +@@ -86,19 +58,12 @@ + obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o + obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o + obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o +-obj-$(CONFIG_IP_NF_POOL) += ipt_pool.o ip_pool.o + obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o + + obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o + obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o +- +-obj-$(CONFIG_IP_NF_MATCH_MPORT) += ipt_mport.o +- + obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o + obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o +- +-obj-$(CONFIG_IP_NF_MATCH_TIME) += ipt_time.o +- + obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o + obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o + obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o +@@ -109,7 +74,6 @@ + obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o + obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o + obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o +-obj-$(CONFIG_IP_NF_MATCH_WEBSTR) += ipt_webstr.o + obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o + + # targets +@@ -125,8 +89,6 @@ + obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o + obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o + obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o +-obj-$(CONFIG_IP_NF_AUTOFW) += ip_autofw.o +-obj-$(CONFIG_IP_NF_TARGET_TRIGGER) += ipt_TRIGGER.o + + # generic ARP tables + obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o +diff -Nurb linux/net/ipv4/netfilter/ip_conntrack_core.c linux.stock/net/ipv4/netfilter/ip_conntrack_core.c +--- linux/net/ipv4/netfilter/ip_conntrack_core.c 2003-08-12 07:33:45.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_conntrack_core.c 2004-05-09 04:13:03.000000000 -0400 +@@ -47,7 +47,11 @@ + + #define IP_CONNTRACK_VERSION "2.1" + ++#if 0 ++#define DEBUGP printk ++#else + #define DEBUGP(format, args...) ++#endif + + DECLARE_RWLOCK(ip_conntrack_lock); + DECLARE_RWLOCK(ip_conntrack_expect_tuple_lock); +@@ -62,29 +66,6 @@ + struct list_head *ip_conntrack_hash; + static kmem_cache_t *ip_conntrack_cachep; + +-#define SECS * HZ +-#define MINS * 60 SECS +-#define HOURS * 60 MINS +-#define DAYS * 24 HOURS +- +-int sysctl_ip_conntrack_tcp_timeouts[10] = { +- 30 MINS, /* TCP_CONNTRACK_NONE, */ +- 5 DAYS, /* TCP_CONNTRACK_ESTABLISHED, */ +- 2 MINS, /* TCP_CONNTRACK_SYN_SENT, */ +- 60 SECS, /* TCP_CONNTRACK_SYN_RECV, */ +- 2 MINS, /* TCP_CONNTRACK_FIN_WAIT, */ +- 2 MINS, /* TCP_CONNTRACK_TIME_WAIT, */ +- 10 SECS, /* TCP_CONNTRACK_CLOSE, */ +- 60 SECS, /* TCP_CONNTRACK_CLOSE_WAIT, */ +- 30 SECS, /* TCP_CONNTRACK_LAST_ACK, */ +- 2 MINS, /* TCP_CONNTRACK_LISTEN, */ +-}; +- +-int sysctl_ip_conntrack_udp_timeouts[2] = { +- 30 SECS, /* UNREPLIED */ +- 180 SECS /* ASSURED */ +-}; +- + extern struct ip_conntrack_protocol ip_conntrack_generic_protocol; + + static inline int proto_cmpfn(const struct ip_conntrack_protocol *curr, +@@ -129,6 +110,9 @@ + static inline u_int32_t + hash_conntrack(const struct ip_conntrack_tuple *tuple) + { ++#if 0 ++ dump_tuple(tuple); ++#endif + /* ntohl because more differences in low bits. */ + /* To ensure that halves of the same connection don't hash + clash, we add the source per-proto again. */ +@@ -160,8 +144,6 @@ + tuple->dst.ip = iph->daddr; + tuple->dst.protonum = iph->protocol; + +- tuple->src.u.all = tuple->dst.u.all = 0; +- + ret = protocol->pkt_to_tuple((u_int32_t *)iph + iph->ihl, + len - 4*iph->ihl, + tuple); +@@ -177,8 +159,6 @@ + inverse->dst.ip = orig->src.ip; + inverse->dst.protonum = orig->dst.protonum; + +- inverse->src.u.all = inverse->dst.u.all = 0; +- + return protocol->invert_tuple(inverse, orig); + } + +@@ -196,8 +176,8 @@ + static void + destroy_expect(struct ip_conntrack_expect *exp) + { +- DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(&exp->use)); +- IP_NF_ASSERT(atomic_read(&exp->use)); ++ DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(exp->use)); ++ IP_NF_ASSERT(atomic_read(exp->use)); + IP_NF_ASSERT(!timer_pending(&exp->timeout)); + + kfree(exp); +@@ -267,11 +247,11 @@ + static void unexpect_related(struct ip_conntrack_expect *expect) + { + IP_NF_ASSERT(expect->expectant); ++ IP_NF_ASSERT(expect->expectant->helper); + /* if we are supposed to have a timer, but we can't delete + * it: race condition. __unexpect_related will + * be calledd by timeout function */ +- if (expect->expectant->helper +- && expect->expectant->helper->timeout ++ if (expect->expectant->helper->timeout + && !del_timer(&expect->timeout)) + return; + +@@ -580,6 +560,7 @@ + if (!h) { + /* Locally generated ICMPs will match inverted if they + haven't been SNAT'ed yet */ ++ /* FIXME: NAT code has to handle half-done double NAT --RR */ + if (hooknum == NF_IP_LOCAL_OUT) + h = ip_conntrack_find_get(&origtuple, NULL); + +@@ -725,7 +706,6 @@ + + /* If the expectation is dying, then this is a looser. */ + if (expected +- && expected->expectant->helper + && expected->expectant->helper->timeout + && ! del_timer(&expected->timeout)) + expected = NULL; +@@ -744,7 +724,6 @@ + conntrack->master = expected; + expected->sibling = conntrack; + LIST_DELETE(&ip_conntrack_expect_list, expected); +- INIT_LIST_HEAD(&expected->list); + expected->expectant->expecting--; + nf_conntrack_get(&master_ct(conntrack)->infos[0]); + } +@@ -821,9 +800,23 @@ + int set_reply; + int ret; + ++ /* FIXME: Do this right please. --RR */ + (*pskb)->nfcache |= NFC_UNKNOWN; + + /* Doesn't cover locally-generated broadcast, so not worth it. */ ++#if 0 ++ /* Ignore broadcast: no `connection'. */ ++ if ((*pskb)->pkt_type == PACKET_BROADCAST) { ++ printk("Broadcast packet!\n"); ++ return NF_ACCEPT; ++ } else if (((*pskb)->nh.iph->daddr & htonl(0x000000FF)) ++ == htonl(0x000000FF)) { ++ printk("Should bcast: %u.%u.%u.%u->%u.%u.%u.%u (sk=%p, ptype=%u)\n", ++ NIPQUAD((*pskb)->nh.iph->saddr), ++ NIPQUAD((*pskb)->nh.iph->daddr), ++ (*pskb)->sk, (*pskb)->pkt_type); ++ } ++#endif + + /* Previously seen (loopback)? Ignore. Do this before + fragment check. */ +@@ -943,8 +936,8 @@ + * so there is no need to use the tuple lock too */ + + DEBUGP("ip_conntrack_expect_related %p\n", related_to); +- DEBUGP("tuple: "); DUMP_TUPLE_RAW(&expect->tuple); +- DEBUGP("mask: "); DUMP_TUPLE_RAW(&expect->mask); ++ DEBUGP("tuple: "); DUMP_TUPLE(&expect->tuple); ++ DEBUGP("mask: "); DUMP_TUPLE(&expect->mask); + + old = LIST_FIND(&ip_conntrack_expect_list, resent_expect, + struct ip_conntrack_expect *, &expect->tuple, +@@ -954,8 +947,7 @@ + pointing into the payload - otherwise we should have to copy + the data filled out by the helper over the old one */ + DEBUGP("expect_related: resent packet\n"); +- if (related_to->helper && +- related_to->helper->timeout) { ++ if (related_to->helper->timeout) { + if (!del_timer(&old->timeout)) { + /* expectation is dying. Fall through */ + old = NULL; +@@ -970,32 +962,26 @@ + WRITE_UNLOCK(&ip_conntrack_lock); + return -EEXIST; + } +- } else if (related_to->helper && +- related_to->helper->max_expected && ++ } else if (related_to->helper->max_expected && + related_to->expecting >= related_to->helper->max_expected) { + struct list_head *cur_item; + /* old == NULL */ +- if (!(related_to->helper->flags & +- IP_CT_HELPER_F_REUSE_EXPECT)) { +- WRITE_UNLOCK(&ip_conntrack_lock); + if (net_ratelimit()) + printk(KERN_WARNING + "ip_conntrack: max number of expected " + "connections %i of %s reached for " +- "%u.%u.%u.%u->%u.%u.%u.%u\n", ++ "%u.%u.%u.%u->%u.%u.%u.%u%s\n", + related_to->helper->max_expected, + related_to->helper->name, + NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip), +- NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip)); ++ NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip), ++ related_to->helper->flags & IP_CT_HELPER_F_REUSE_EXPECT ? ++ ", reusing" : ""); ++ if (!(related_to->helper->flags & ++ IP_CT_HELPER_F_REUSE_EXPECT)) { ++ WRITE_UNLOCK(&ip_conntrack_lock); + return -EPERM; + } +- DEBUGP("ip_conntrack: max number of expected " +- "connections %i of %s reached for " +- "%u.%u.%u.%u->%u.%u.%u.%u, reusing\n", +- related_to->helper->max_expected, +- related_to->helper->name, +- NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip), +- NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip)); + + /* choose the the oldest expectation to evict */ + list_for_each(cur_item, &related_to->sibling_list) { +@@ -1055,8 +1041,7 @@ + /* add to global list of expectations */ + list_prepend(&ip_conntrack_expect_list, &new->list); + /* add and start timer if required */ +- if (related_to->helper && +- related_to->helper->timeout) { ++ if (related_to->helper->timeout) { + init_timer(&new->timeout); + new->timeout.data = (unsigned long)new; + new->timeout.function = expectation_timed_out; +@@ -1079,10 +1064,11 @@ + + MUST_BE_READ_LOCKED(&ip_conntrack_lock); + WRITE_LOCK(&ip_conntrack_expect_tuple_lock); ++ + DEBUGP("change_expect:\n"); +- DEBUGP("exp tuple: "); DUMP_TUPLE_RAW(&expect->tuple); +- DEBUGP("exp mask: "); DUMP_TUPLE_RAW(&expect->mask); +- DEBUGP("newtuple: "); DUMP_TUPLE_RAW(newtuple); ++ DEBUGP("exp tuple: "); DUMP_TUPLE(&expect->tuple); ++ DEBUGP("exp mask: "); DUMP_TUPLE(&expect->mask); ++ DEBUGP("newtuple: "); DUMP_TUPLE(newtuple); + if (expect->ct_tuple.dst.protonum == 0) { + /* Never seen before */ + DEBUGP("change expect: never seen before\n"); +@@ -1360,8 +1346,6 @@ + 0, NULL }; + + #define NET_IP_CONNTRACK_MAX 2089 +-#define NET_IP_CONNTRACK_TCP_TIMEOUTS 2090 +-#define NET_IP_CONNTRACK_UDP_TIMEOUTS 2091 + #define NET_IP_CONNTRACK_MAX_NAME "ip_conntrack_max" + + #ifdef CONFIG_SYSCTL +@@ -1370,14 +1354,6 @@ + static ctl_table ip_conntrack_table[] = { + { NET_IP_CONNTRACK_MAX, NET_IP_CONNTRACK_MAX_NAME, &ip_conntrack_max, + sizeof(ip_conntrack_max), 0644, NULL, proc_dointvec }, +- { NET_IP_CONNTRACK_TCP_TIMEOUTS, "ip_conntrack_tcp_timeouts", +- &sysctl_ip_conntrack_tcp_timeouts, +- sizeof(sysctl_ip_conntrack_tcp_timeouts), +- 0644, NULL, &proc_dointvec_jiffies, &sysctl_jiffies }, +- { NET_IP_CONNTRACK_UDP_TIMEOUTS, "ip_conntrack_udp_timeouts", +- &sysctl_ip_conntrack_udp_timeouts, +- sizeof(sysctl_ip_conntrack_udp_timeouts), +- 0644, NULL, &proc_dointvec_jiffies, &sysctl_jiffies }, + { 0 } + }; + +diff -Nurb linux/net/ipv4/netfilter/ip_conntrack_ftp.c linux.stock/net/ipv4/netfilter/ip_conntrack_ftp.c +--- linux/net/ipv4/netfilter/ip_conntrack_ftp.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_conntrack_ftp.c 2004-05-09 04:13:03.000000000 -0400 +@@ -24,7 +24,11 @@ + static int loose = 0; + MODULE_PARM(loose, "i"); + ++#if 0 ++#define DEBUGP printk ++#else + #define DEBUGP(format, args...) ++#endif + + static int try_rfc959(const char *, size_t, u_int32_t [], char); + static int try_eprt(const char *, size_t, u_int32_t [], char); +@@ -191,6 +195,16 @@ + } + + if (strnicmp(data, pattern, plen) != 0) { ++#if 0 ++ size_t i; ++ ++ DEBUGP("ftp: string mismatch\n"); ++ for (i = 0; i < plen; i++) { ++ DEBUGFTP("ftp:char %u `%c'(%u) vs `%c'(%u)\n", ++ i, data[i], data[i], ++ pattern[i], pattern[i]); ++ } ++#endif + return 0; + } + +@@ -214,6 +228,7 @@ + return 1; + } + ++/* FIXME: This should be in userspace. Later. */ + static int help(const struct iphdr *iph, size_t len, + struct ip_conntrack *ct, + enum ip_conntrack_info ctinfo) +@@ -249,6 +264,7 @@ + } + + /* 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("ftp_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n", +diff -Nurb linux/net/ipv4/netfilter/ip_conntrack_h323.c linux.stock/net/ipv4/netfilter/ip_conntrack_h323.c +--- linux/net/ipv4/netfilter/ip_conntrack_h323.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_conntrack_h323.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,302 +0,0 @@ +-/* +- * H.323 'brute force' extension for H.323 connection tracking. +- * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> +- * +- * Based on ip_masq_h323.c for 2.2 kernels from CoRiTel, Sofia project. +- * (http://www.coritel.it/projects/sofia/nat/) +- * Uses Sampsa Ranta's excellent idea on using expectfn to 'bind' +- * the unregistered helpers to the conntrack entries. +- */ +- +- +-#include <linux/module.h> +-#include <linux/netfilter.h> +-#include <linux/ip.h> +-#include <net/checksum.h> +-#include <net/tcp.h> +- +-#include <linux/netfilter_ipv4/lockhelp.h> +-#include <linux/netfilter_ipv4/ip_conntrack.h> +-#include <linux/netfilter_ipv4/ip_conntrack_core.h> +-#include <linux/netfilter_ipv4/ip_conntrack_helper.h> +-#include <linux/netfilter_ipv4/ip_conntrack_tuple.h> +-#include <linux/netfilter_ipv4/ip_conntrack_h323.h> +- +-MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); +-MODULE_DESCRIPTION("H.323 'brute force' connection tracking module"); +-MODULE_LICENSE("GPL"); +- +-DECLARE_LOCK(ip_h323_lock); +-struct module *ip_conntrack_h323 = THIS_MODULE; +- +-#define DEBUGP(format, args...) +- +-static int h245_help(const struct iphdr *iph, size_t len, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo) +-{ +- struct tcphdr *tcph = (void *)iph + iph->ihl * 4; +- unsigned char *data = (unsigned char *) tcph + tcph->doff * 4; +- unsigned char *data_limit; +- u_int32_t tcplen = len - iph->ihl * 4; +- u_int32_t datalen = tcplen - tcph->doff * 4; +- int dir = CTINFO2DIR(ctinfo); +- struct ip_ct_h225_master *info = &ct->help.ct_h225_info; +- struct ip_conntrack_expect expect, *exp = &expect; +- struct ip_ct_h225_expect *exp_info = &exp->help.exp_h225_info; +- u_int16_t data_port; +- u_int32_t data_ip; +- unsigned int i; +- +- DEBUGP("ct_h245_help: help entered %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n", +- NIPQUAD(iph->saddr), ntohs(tcph->source), +- NIPQUAD(iph->daddr), ntohs(tcph->dest)); +- +- /* Can't track connections formed before we registered */ +- if (!info) +- return NF_ACCEPT; +- +- /* 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("ct_h245_help: Conntrackinfo = %u\n", ctinfo); +- return NF_ACCEPT; +- } +- +- /* Not whole TCP header or too short packet? */ +- if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4 + 5) { +- DEBUGP("ct_h245_help: tcplen = %u\n", (unsigned)tcplen); +- return NF_ACCEPT; +- } +- +- /* Checksum invalid? Ignore. */ +- if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, +- csum_partial((char *)tcph, tcplen, 0))) { +- DEBUGP("ct_h245_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n", +- tcph, tcplen, NIPQUAD(iph->saddr), +- NIPQUAD(iph->daddr)); +- return NF_ACCEPT; +- } +- +- data_limit = (unsigned char *) data + datalen; +- /* bytes: 0123 45 +- ipadrr port */ +- for (i = 0; data < (data_limit - 5); data++, i++) { +- memcpy(&data_ip, data, sizeof(u_int32_t)); +- if (data_ip == iph->saddr) { +- memcpy(&data_port, data + 4, sizeof(u_int16_t)); +- memset(&expect, 0, sizeof(expect)); +- /* update the H.225 info */ +- DEBUGP("ct_h245_help: new RTCP/RTP requested %u.%u.%u.%u:->%u.%u.%u.%u:%u\n", +- NIPQUAD(ct->tuplehash[!dir].tuple.src.ip), +- NIPQUAD(iph->saddr), ntohs(data_port)); +- LOCK_BH(&ip_h323_lock); +- info->is_h225 = H225_PORT + 1; +- exp_info->port = data_port; +- exp_info->dir = dir; +- exp_info->offset = i; +- +- exp->seq = ntohl(tcph->seq) + i; +- +- exp->tuple = ((struct ip_conntrack_tuple) +- { { ct->tuplehash[!dir].tuple.src.ip, +- { 0 } }, +- { data_ip, +- { data_port }, +- IPPROTO_UDP }}); +- exp->mask = ((struct ip_conntrack_tuple) +- { { 0xFFFFFFFF, { 0 } }, +- { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); +- +- exp->expectfn = NULL; +- +- /* Ignore failure; should only happen with NAT */ +- ip_conntrack_expect_related(ct, exp); +- +- UNLOCK_BH(&ip_h323_lock); +- } +- } +- +- return NF_ACCEPT; +- +-} +- +-/* H.245 helper is not registered! */ +-static struct ip_conntrack_helper h245 = +- { { NULL, NULL }, +- "H.245", /* name */ +- IP_CT_HELPER_F_REUSE_EXPECT, /* flags */ +- NULL, /* module */ +- 8, /* max_ expected */ +- 240, /* timeout */ +- { { 0, { 0 } }, /* tuple */ +- { 0, { 0 }, IPPROTO_TCP } }, +- { { 0, { 0xFFFF } }, /* mask */ +- { 0, { 0 }, 0xFFFF } }, +- h245_help /* helper */ +- }; +- +-static int h225_expect(struct ip_conntrack *ct) +-{ +- WRITE_LOCK(&ip_conntrack_lock); +- ct->helper = &h245; +- DEBUGP("h225_expect: helper for %p added\n", ct); +- WRITE_UNLOCK(&ip_conntrack_lock); +- +- return NF_ACCEPT; /* unused */ +-} +- +-static int h225_help(const struct iphdr *iph, size_t len, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo) +-{ +- struct tcphdr *tcph = (void *)iph + iph->ihl * 4; +- unsigned char *data = (unsigned char *) tcph + tcph->doff * 4; +- unsigned char *data_limit; +- u_int32_t tcplen = len - iph->ihl * 4; +- u_int32_t datalen = tcplen - tcph->doff * 4; +- int dir = CTINFO2DIR(ctinfo); +- struct ip_ct_h225_master *info = &ct->help.ct_h225_info; +- struct ip_conntrack_expect expect, *exp = &expect; +- struct ip_ct_h225_expect *exp_info = &exp->help.exp_h225_info; +- u_int16_t data_port; +- u_int32_t data_ip; +- unsigned int i; +- +- DEBUGP("ct_h225_help: help entered %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n", +- NIPQUAD(iph->saddr), ntohs(tcph->source), +- NIPQUAD(iph->daddr), ntohs(tcph->dest)); +- +- /* Can't track connections formed before we registered */ +- if (!info) +- return NF_ACCEPT; +- +- /* 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("ct_h225_help: Conntrackinfo = %u\n", ctinfo); +- return NF_ACCEPT; +- } +- +- /* Not whole TCP header or too short packet? */ +- if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4 + 5) { +- DEBUGP("ct_h225_help: tcplen = %u\n", (unsigned)tcplen); +- return NF_ACCEPT; +- } +- +- /* Checksum invalid? Ignore. */ +- if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, +- csum_partial((char *)tcph, tcplen, 0))) { +- DEBUGP("ct_h225_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n", +- tcph, tcplen, NIPQUAD(iph->saddr), +- NIPQUAD(iph->daddr)); +- return NF_ACCEPT; +- } +- +- data_limit = (unsigned char *) data + datalen; +- /* bytes: 0123 45 +- ipadrr port */ +- for (i = 0; data < (data_limit - 5); data++, i++) { +- memcpy(&data_ip, data, sizeof(u_int32_t)); +- if (data_ip == iph->saddr) { +- memcpy(&data_port, data + 4, sizeof(u_int16_t)); +- if (data_port == tcph->source) { +- /* Signal address */ +- DEBUGP("ct_h225_help: sourceCallSignalAddress from %u.%u.%u.%u\n", +- NIPQUAD(iph->saddr)); +- /* Update the H.225 info so that NAT can mangle the address/port +- even when we have no expected connection! */ +-#ifdef CONFIG_IP_NF_NAT_NEEDED +- LOCK_BH(&ip_h323_lock); +- info->dir = dir; +- info->seq[IP_CT_DIR_ORIGINAL] = ntohl(tcph->seq) + i; +- info->offset[IP_CT_DIR_ORIGINAL] = i; +- UNLOCK_BH(&ip_h323_lock); +-#endif +- } else { +- memset(&expect, 0, sizeof(expect)); +- +- /* update the H.225 info */ +- LOCK_BH(&ip_h323_lock); +- info->is_h225 = H225_PORT; +- exp_info->port = data_port; +- exp_info->dir = dir; +- exp_info->offset = i; +- +- exp->seq = ntohl(tcph->seq) + i; +- +- exp->tuple = ((struct ip_conntrack_tuple) +- { { ct->tuplehash[!dir].tuple.src.ip, +- { 0 } }, +- { data_ip, +- { data_port }, +- IPPROTO_TCP }}); +- exp->mask = ((struct ip_conntrack_tuple) +- { { 0xFFFFFFFF, { 0 } }, +- { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); +- +- exp->expectfn = h225_expect; +- +- /* Ignore failure */ +- ip_conntrack_expect_related(ct, exp); +- +- DEBUGP("ct_h225_help: new H.245 requested %u.%u.%u.%u->%u.%u.%u.%u:%u\n", +- NIPQUAD(ct->tuplehash[!dir].tuple.src.ip), +- NIPQUAD(iph->saddr), ntohs(data_port)); +- +- UNLOCK_BH(&ip_h323_lock); +- } +-#ifdef CONFIG_IP_NF_NAT_NEEDED +- } else if (data_ip == iph->daddr) { +- memcpy(&data_port, data + 4, sizeof(u_int16_t)); +- if (data_port == tcph->dest) { +- /* Signal address */ +- DEBUGP("ct_h225_help: destCallSignalAddress %u.%u.%u.%u\n", +- NIPQUAD(iph->daddr)); +- /* Update the H.225 info so that NAT can mangle the address/port +- even when we have no expected connection! */ +- LOCK_BH(&ip_h323_lock); +- info->dir = dir; +- info->seq[IP_CT_DIR_REPLY] = ntohl(tcph->seq) + i; +- info->offset[IP_CT_DIR_REPLY] = i; +- UNLOCK_BH(&ip_h323_lock); +- } +-#endif +- } +- } +- +- return NF_ACCEPT; +- +-} +- +-static struct ip_conntrack_helper h225 = +- { { NULL, NULL }, +- "H.225", /* name */ +- IP_CT_HELPER_F_REUSE_EXPECT, /* flags */ +- THIS_MODULE, /* module */ +- 2, /* max_expected */ +- 240, /* timeout */ +- { { 0, { __constant_htons(H225_PORT) } }, /* tuple */ +- { 0, { 0 }, IPPROTO_TCP } }, +- { { 0, { 0xFFFF } }, /* mask */ +- { 0, { 0 }, 0xFFFF } }, +- h225_help /* helper */ +- }; +- +-static int __init init(void) +-{ +- return ip_conntrack_helper_register(&h225); +-} +- +-static void __exit fini(void) +-{ +- /* Unregister H.225 helper */ +- ip_conntrack_helper_unregister(&h225); +-} +- +-#ifdef CONFIG_IP_NF_NAT_NEEDED +-EXPORT_SYMBOL(ip_h323_lock); +-#endif +- +-module_init(init); +-module_exit(fini); +diff -Nurb linux/net/ipv4/netfilter/ip_conntrack_mms.c linux.stock/net/ipv4/netfilter/ip_conntrack_mms.c +--- linux/net/ipv4/netfilter/ip_conntrack_mms.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_conntrack_mms.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,292 +0,0 @@ +-/* MMS extension for IP connection tracking +- * (C) 2002 by Filip Sneppe <filip.sneppe@cronos.be> +- * based on ip_conntrack_ftp.c and ip_conntrack_irc.c +- * +- * ip_conntrack_mms.c v0.3 2002-09-22 +- * +- * 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 ip_conntrack_mms.o ports=port1,port2,...port<MAX_PORTS> +- * +- * Please give the ports of all MMS servers You wish to connect to. +- * If you don't specify ports, the default will be TCP port 1755. +- * +- * More info on MMS protocol, firewalls and NAT: +- * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/MMSFirewall.asp +- * http://www.microsoft.com/windows/windowsmedia/serve/firewall.asp +- * +- * The SDP project people are reverse-engineering MMS: +- * http://get.to/sdp +- */ +- +-#include <linux/config.h> +-#include <linux/module.h> +-#include <linux/netfilter.h> +-#include <linux/ip.h> +-#include <linux/ctype.h> +-#include <net/checksum.h> +-#include <net/tcp.h> +- +-#include <linux/netfilter_ipv4/lockhelp.h> +-#include <linux/netfilter_ipv4/ip_conntrack_helper.h> +-#include <linux/netfilter_ipv4/ip_conntrack_mms.h> +- +-DECLARE_LOCK(ip_mms_lock); +-struct module *ip_conntrack_mms = THIS_MODULE; +- +-#define MAX_PORTS 8 +-static int ports[MAX_PORTS]; +-static int ports_c; +-#ifdef MODULE_PARM +-MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); +-#endif +- +-#define DEBUGP(format, args...) +- +-#ifdef CONFIG_IP_NF_NAT_NEEDED +-EXPORT_SYMBOL(ip_mms_lock); +-#endif +- +-MODULE_AUTHOR("Filip Sneppe <filip.sneppe@cronos.be>"); +-MODULE_DESCRIPTION("Microsoft Windows Media Services (MMS) connection tracking module"); +-MODULE_LICENSE("GPL"); +- +-/* #define isdigit(c) (c >= '0' && c <= '9') */ +- +-/* copied from drivers/usb/serial/io_edgeport.c - not perfect but will do the trick */ +-static void unicode_to_ascii (char *string, short *unicode, int unicode_size) +-{ +- int i; +- for (i = 0; i < unicode_size; ++i) { +- string[i] = (char)(unicode[i]); +- } +- string[unicode_size] = 0x00; +-} +- +-__inline static int atoi(char *s) +-{ +- int i=0; +- while (isdigit(*s)) { +- i = i*10 + *(s++) - '0'; +- } +- return i; +-} +- +-/* convert ip address string like "192.168.0.10" to unsigned int */ +-__inline static u_int32_t asciiiptoi(char *s) +-{ +- unsigned int i, j, k; +- +- for(i=k=0; k<3; ++k, ++s, i<<=8) { +- i+=atoi(s); +- for(j=0; (*(++s) != '.') && (j<3); ++j) +- ; +- } +- i+=atoi(s); +- return ntohl(i); +-} +- +-int parse_mms(const char *data, +- const unsigned int datalen, +- u_int32_t *mms_ip, +- u_int16_t *mms_proto, +- u_int16_t *mms_port, +- char **mms_string_b, +- char **mms_string_e, +- char **mms_padding_e) +-{ +- int unicode_size, i; +- char tempstring[28]; /* "\\255.255.255.255\UDP\65535" */ +- char getlengthstring[28]; +- +- for(unicode_size=0; +- (char) *(data+(MMS_SRV_UNICODE_STRING_OFFSET+unicode_size*2)) != (char)0; +- unicode_size++) +- if ((unicode_size == 28) || (MMS_SRV_UNICODE_STRING_OFFSET+unicode_size*2 >= datalen)) +- return -1; /* out of bounds - incomplete packet */ +- +- unicode_to_ascii(tempstring, (short *)(data+MMS_SRV_UNICODE_STRING_OFFSET), unicode_size); +- DEBUGP("ip_conntrack_mms: offset 60: %s\n", (const char *)(tempstring)); +- +- /* IP address ? */ +- *mms_ip = asciiiptoi(tempstring+2); +- +- i=sprintf(getlengthstring, "%u.%u.%u.%u", HIPQUAD(*mms_ip)); +- +- /* protocol ? */ +- if(strncmp(tempstring+3+i, "TCP", 3)==0) +- *mms_proto = IPPROTO_TCP; +- else if(strncmp(tempstring+3+i, "UDP", 3)==0) +- *mms_proto = IPPROTO_UDP; +- +- /* port ? */ +- *mms_port = atoi(tempstring+7+i); +- +- /* we store a pointer to the beginning of the "\\a.b.c.d\proto\port" +- unicode string, one to the end of the string, and one to the end +- of the packet, since we must keep track of the number of bytes +- between end of the unicode string and the end of packet (padding) */ +- *mms_string_b = (char *)(data + MMS_SRV_UNICODE_STRING_OFFSET); +- *mms_string_e = (char *)(data + MMS_SRV_UNICODE_STRING_OFFSET + unicode_size * 2); +- *mms_padding_e = (char *)(data + datalen); /* looks funny, doesn't it */ +- return 0; +-} +- +- +-static int help(const struct iphdr *iph, size_t len, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo) +-{ +- /* tcplen not negative guaranteed by ip_conntrack_tcp.c */ +- struct tcphdr *tcph = (void *)iph + iph->ihl * 4; +- const char *data = (const char *)tcph + tcph->doff * 4; +- unsigned int tcplen = len - iph->ihl * 4; +- unsigned int datalen = tcplen - tcph->doff * 4; +- int dir = CTINFO2DIR(ctinfo); +- struct ip_conntrack_expect expect, *exp = &expect; +- struct ip_ct_mms_expect *exp_mms_info = &exp->help.exp_mms_info; +- +- u_int32_t mms_ip; +- u_int16_t mms_proto; +- char mms_proto_string[8]; +- u_int16_t mms_port; +- char *mms_string_b, *mms_string_e, *mms_padding_e; +- +- /* 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("ip_conntrack_mms: Conntrackinfo = %u\n", ctinfo); +- return NF_ACCEPT; +- } +- +- /* Not whole TCP header? */ +- if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff*4) { +- DEBUGP("ip_conntrack_mms: tcplen = %u\n", (unsigned)tcplen); +- return NF_ACCEPT; +- } +- +- /* Checksum invalid? Ignore. */ +- if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, +- csum_partial((char *)tcph, tcplen, 0))) { +- DEBUGP("mms_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n", +- tcph, tcplen, NIPQUAD(iph->saddr), +- NIPQUAD(iph->daddr)); +- return NF_ACCEPT; +- } +- +- /* Only look at packets with 0x00030002/196610 on bytes 36->39 of TCP payload */ +- if( (MMS_SRV_MSG_OFFSET < datalen) && +- ((*(u32 *)(data+MMS_SRV_MSG_OFFSET)) == MMS_SRV_MSG_ID)) { +- DEBUGP("ip_conntrack_mms: offset 37: %u %u %u %u, datalen:%u\n", +- (u8)*(data+36), (u8)*(data+37), +- (u8)*(data+38), (u8)*(data+39), +- datalen); +- if(parse_mms(data, datalen, &mms_ip, &mms_proto, &mms_port, +- &mms_string_b, &mms_string_e, &mms_padding_e)) +- if(net_ratelimit()) +- printk(KERN_WARNING +- "ip_conntrack_mms: Unable to parse data payload\n"); +- +- memset(&expect, 0, sizeof(expect)); +- +- sprintf(mms_proto_string, "(%u)", mms_proto); +- DEBUGP("ip_conntrack_mms: adding %s expectation %u.%u.%u.%u -> %u.%u.%u.%u:%u\n", +- mms_proto == IPPROTO_TCP ? "TCP" +- : mms_proto == IPPROTO_UDP ? "UDP":mms_proto_string, +- NIPQUAD(ct->tuplehash[!dir].tuple.src.ip), +- NIPQUAD(mms_ip), +- mms_port); +- +- /* it's possible that the client will just ask the server to tunnel +- the stream over the same TCP session (from port 1755): there's +- shouldn't be a need to add an expectation in that case, but it +- makes NAT packet mangling so much easier */ +- LOCK_BH(&ip_mms_lock); +- +- DEBUGP("ip_conntrack_mms: tcph->seq = %u\n", tcph->seq); +- +- exp->seq = ntohl(tcph->seq) + (mms_string_b - data); +- exp_mms_info->len = (mms_string_e - mms_string_b); +- exp_mms_info->padding = (mms_padding_e - mms_string_e); +- exp_mms_info->port = mms_port; +- +- DEBUGP("ip_conntrack_mms: wrote info seq=%u (ofs=%u), len=%d, padding=%u\n", +- exp->seq, (mms_string_e - data), exp_mms_info->len, exp_mms_info->padding); +- +- exp->tuple = ((struct ip_conntrack_tuple) +- { { ct->tuplehash[!dir].tuple.src.ip, { 0 } }, +- { mms_ip, +- { (__u16) ntohs(mms_port) }, +- mms_proto } } +- ); +- exp->mask = ((struct ip_conntrack_tuple) +- { { 0xFFFFFFFF, { 0 } }, +- { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); +- exp->expectfn = NULL; +- ip_conntrack_expect_related(ct, &expect); +- UNLOCK_BH(&ip_mms_lock); +- } +- +- return NF_ACCEPT; +-} +- +-static struct ip_conntrack_helper mms[MAX_PORTS]; +-static char mms_names[MAX_PORTS][10]; +- +-/* Not __exit: called from init() */ +-static void fini(void) +-{ +- int i; +- for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { +- DEBUGP("ip_conntrack_mms: unregistering helper for port %d\n", +- ports[i]); +- ip_conntrack_helper_unregister(&mms[i]); +- } +-} +- +-static int __init init(void) +-{ +- int i, ret; +- char *tmpname; +- +- if (ports[0] == 0) +- ports[0] = MMS_PORT; +- +- for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { +- memset(&mms[i], 0, sizeof(struct ip_conntrack_helper)); +- mms[i].tuple.src.u.tcp.port = htons(ports[i]); +- mms[i].tuple.dst.protonum = IPPROTO_TCP; +- mms[i].mask.src.u.tcp.port = 0xFFFF; +- mms[i].mask.dst.protonum = 0xFFFF; +- mms[i].max_expected = 1; +- mms[i].timeout = 0; +- mms[i].flags = IP_CT_HELPER_F_REUSE_EXPECT; +- mms[i].me = THIS_MODULE; +- mms[i].help = help; +- +- tmpname = &mms_names[i][0]; +- if (ports[i] == MMS_PORT) +- sprintf(tmpname, "mms"); +- else +- sprintf(tmpname, "mms-%d", ports[i]); +- mms[i].name = tmpname; +- +- DEBUGP("ip_conntrack_mms: registering helper for port %d\n", +- ports[i]); +- ret = ip_conntrack_helper_register(&mms[i]); +- +- if (ret) { +- fini(); +- return ret; +- } +- ports_c++; +- } +- return 0; +-} +- +-module_init(init); +-module_exit(fini); +diff -Nurb linux/net/ipv4/netfilter/ip_conntrack_pptp.c linux.stock/net/ipv4/netfilter/ip_conntrack_pptp.c +--- linux/net/ipv4/netfilter/ip_conntrack_pptp.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_conntrack_pptp.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,531 +0,0 @@ +-/* +- * ip_conntrack_pptp.c - Version 1.11 +- * +- * Connection tracking support for PPTP (Point to Point Tunneling Protocol). +- * PPTP is a a protocol for creating virtual private networks. +- * It is a specification defined by Microsoft and some vendors +- * working with Microsoft. PPTP is built on top of a modified +- * version of the Internet Generic Routing Encapsulation Protocol. +- * GRE is defined in RFC 1701 and RFC 1702. Documentation of +- * PPTP can be found in RFC 2637 +- * +- * (C) 2000-2002 by Harald Welte <laforge@gnumonks.org>, +- * +- * Development of this code funded by Astaro AG (http://www.astaro.com/) +- * +- * Limitations: +- * - We blindly assume that control connections are always +- * established in PNS->PAC direction. This is a violation +- * of RFFC2673 +- * +- * TODO: - finish support for multiple calls within one session +- * (needs expect reservations in newnat) +- * - testing of incoming PPTP calls +- */ +- +-#include <linux/config.h> +-#include <linux/module.h> +-#include <linux/netfilter.h> +-#include <linux/ip.h> +-#include <net/checksum.h> +-#include <net/tcp.h> +- +-#include <linux/netfilter_ipv4/lockhelp.h> +-#include <linux/netfilter_ipv4/ip_conntrack_helper.h> +-#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h> +-#include <linux/netfilter_ipv4/ip_conntrack_pptp.h> +- +-MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); +-MODULE_DESCRIPTION("Netfilter connection tracking helper module for PPTP"); +- +-DECLARE_LOCK(ip_pptp_lock); +- +-#define DEBUGP(format, args...) +- +-#define SECS *HZ +-#define MINS * 60 SECS +-#define HOURS * 60 MINS +-#define DAYS * 24 HOURS +- +-#define PPTP_GRE_TIMEOUT (10 MINS) +-#define PPTP_GRE_STREAM_TIMEOUT (5 DAYS) +- +-static int pptp_expectfn(struct ip_conntrack *ct) +-{ +- struct ip_conntrack_expect *exp, *other_exp; +- struct ip_conntrack *master; +- +- DEBUGP("increasing timeouts\n"); +- /* increase timeout of GRE data channel conntrack entry */ +- ct->proto.gre.timeout = PPTP_GRE_TIMEOUT; +- ct->proto.gre.stream_timeout = PPTP_GRE_STREAM_TIMEOUT; +- +- master = master_ct(ct); +- if (!master) { +- DEBUGP(" no master!!!\n"); +- return 0; +- } +- +- DEBUGP("completing tuples with ct info\n"); +- /* we can do this, since we're unconfirmed */ +- if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.gre.key == +- htonl(master->help.ct_pptp_info.pac_call_id)) { +- /* assume PNS->PAC */ +- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key = +- htonl(master->help.ct_pptp_info.pns_call_id); +- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key = +- htonl(master->help.ct_pptp_info.pns_call_id); +- } else { +- /* assume PAC->PNS */ +- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key = +- htonl(master->help.ct_pptp_info.pac_call_id); +- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key = +- htonl(master->help.ct_pptp_info.pns_call_id); +- } +- +- return 0; +-} +- +-/* timeout GRE data connections */ +-static int pptp_timeout_related(struct ip_conntrack *ct) +-{ +- struct list_head *cur_item; +- struct ip_conntrack_expect *exp; +- +- list_for_each(cur_item, &ct->sibling_list) { +- exp = list_entry(cur_item, struct ip_conntrack_expect, +- expected_list); +- +- if (!exp->sibling) +- continue; +- +- DEBUGP("setting timeout of conntrack %p to 0\n", +- exp->sibling); +- exp->sibling->proto.gre.timeout = 0; +- exp->sibling->proto.gre.stream_timeout = 0; +- ip_ct_refresh(exp->sibling, 0); +- } +- +- return 0; +-} +- +-/* expect GRE connection in PNS->PAC direction */ +-static inline int +-exp_gre(struct ip_conntrack *master, +- u_int32_t seq, +- u_int16_t callid, +- u_int16_t peer_callid) +-{ +- struct ip_conntrack_expect exp; +- struct ip_conntrack_tuple inv_tuple; +- +- memset(&exp, 0, sizeof(exp)); +- /* tuple in original direction, PAC->PNS */ +- exp.tuple.src.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; +- exp.tuple.src.u.gre.key = htonl(ntohs(peer_callid)); +- exp.tuple.dst.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; +- exp.tuple.dst.u.gre.key = htonl(ntohs(callid)); +- exp.tuple.dst.u.gre.protocol = __constant_htons(GRE_PROTOCOL_PPTP); +- exp.tuple.dst.u.gre.version = GRE_VERSION_PPTP; +- exp.tuple.dst.protonum = IPPROTO_GRE; +- +- exp.mask.src.ip = 0xffffffff; +- exp.mask.src.u.all = 0; +- exp.mask.dst.u.all = 0; +- exp.mask.dst.u.gre.key = 0xffffffff; +- exp.mask.dst.u.gre.version = 0xff; +- exp.mask.dst.u.gre.protocol = 0xffff; +- exp.mask.dst.ip = 0xffffffff; +- exp.mask.dst.protonum = 0xffff; +- +- exp.seq = seq; +- exp.expectfn = pptp_expectfn; +- +- exp.help.exp_pptp_info.pac_call_id = ntohs(callid); +- exp.help.exp_pptp_info.pns_call_id = ntohs(peer_callid); +- +- DEBUGP("calling expect_related "); +- DUMP_TUPLE_RAW(&exp.tuple); +- +- /* Add GRE keymap entries */ +- ip_ct_gre_keymap_add(&exp, &exp.tuple, 0); +- invert_tuplepr(&inv_tuple, &exp.tuple); +- ip_ct_gre_keymap_add(&exp, &inv_tuple, 1); +- +- ip_conntrack_expect_related(master, &exp); +- +- return 0; +-} +- +-static inline int +-pptp_inbound_pkt(struct tcphdr *tcph, +- struct pptp_pkt_hdr *pptph, +- size_t datalen, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo) +-{ +- struct PptpControlHeader *ctlh; +- union pptp_ctrl_union pptpReq; +- +- struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info; +- u_int16_t msg, *cid, *pcid; +- u_int32_t seq; +- +- ctlh = (struct PptpControlHeader *) +- ((char *) pptph + sizeof(struct pptp_pkt_hdr)); +- pptpReq.rawreq = (void *) +- ((char *) ctlh + sizeof(struct PptpControlHeader)); +- +- msg = ntohs(ctlh->messageType); +- DEBUGP("inbound control message %s\n", strMName[msg]); +- +- switch (msg) { +- case PPTP_START_SESSION_REPLY: +- /* server confirms new control session */ +- if (info->sstate < PPTP_SESSION_REQUESTED) { +- DEBUGP("%s without START_SESS_REQUEST\n", +- strMName[msg]); +- break; +- } +- if (pptpReq.srep->resultCode == PPTP_START_OK) +- info->sstate = PPTP_SESSION_CONFIRMED; +- else +- info->sstate = PPTP_SESSION_ERROR; +- break; +- +- case PPTP_STOP_SESSION_REPLY: +- /* server confirms end of control session */ +- if (info->sstate > PPTP_SESSION_STOPREQ) { +- DEBUGP("%s without STOP_SESS_REQUEST\n", +- strMName[msg]); +- break; +- } +- if (pptpReq.strep->resultCode == PPTP_STOP_OK) +- info->sstate = PPTP_SESSION_NONE; +- else +- info->sstate = PPTP_SESSION_ERROR; +- break; +- +- case PPTP_OUT_CALL_REPLY: +- /* server accepted call, we now expect GRE frames */ +- if (info->sstate != PPTP_SESSION_CONFIRMED) { +- DEBUGP("%s but no session\n", strMName[msg]); +- break; +- } +- if (info->cstate != PPTP_CALL_OUT_REQ && +- info->cstate != PPTP_CALL_OUT_CONF) { +- DEBUGP("%s without OUTCALL_REQ\n", strMName[msg]); +- break; +- } +- if (pptpReq.ocack->resultCode != PPTP_OUTCALL_CONNECT) { +- info->cstate = PPTP_CALL_NONE; +- break; +- } +- +- cid = &pptpReq.ocack->callID; +- pcid = &pptpReq.ocack->peersCallID; +- +- info->pac_call_id = ntohs(*cid); +- +- if (htons(info->pns_call_id) != *pcid) { +- DEBUGP("%s for unknown callid %u\n", +- strMName[msg], ntohs(*pcid)); +- break; +- } +- +- DEBUGP("%s, CID=%X, PCID=%X\n", strMName[msg], +- ntohs(*cid), ntohs(*pcid)); +- +- info->cstate = PPTP_CALL_OUT_CONF; +- +- seq = ntohl(tcph->seq) + ((void *)pcid - (void *)pptph); +- exp_gre(ct, seq, *cid, *pcid); +- break; +- +- case PPTP_IN_CALL_REQUEST: +- /* server tells us about incoming call request */ +- if (info->sstate != PPTP_SESSION_CONFIRMED) { +- DEBUGP("%s but no session\n", strMName[msg]); +- break; +- } +- pcid = &pptpReq.icack->peersCallID; +- DEBUGP("%s, PCID=%X\n", strMName[msg], ntohs(*pcid)); +- info->cstate = PPTP_CALL_IN_REQ; +- info->pac_call_id= ntohs(*pcid); +- break; +- +- case PPTP_IN_CALL_CONNECT: +- /* server tells us about incoming call established */ +- if (info->sstate != PPTP_SESSION_CONFIRMED) { +- DEBUGP("%s but no session\n", strMName[msg]); +- break; +- } +- if (info->sstate != PPTP_CALL_IN_REP +- && info->sstate != PPTP_CALL_IN_CONF) { +- DEBUGP("%s but never sent IN_CALL_REPLY\n", +- strMName[msg]); +- break; +- } +- +- pcid = &pptpReq.iccon->peersCallID; +- cid = &info->pac_call_id; +- +- if (info->pns_call_id != ntohs(*pcid)) { +- DEBUGP("%s for unknown CallID %u\n", +- strMName[msg], ntohs(*cid)); +- break; +- } +- +- DEBUGP("%s, PCID=%X\n", strMName[msg], ntohs(*pcid)); +- info->cstate = PPTP_CALL_IN_CONF; +- +- /* we expect a GRE connection from PAC to PNS */ +- seq = ntohl(tcph->seq) + ((void *)pcid - (void *)pptph); +- exp_gre(ct, seq, *cid, *pcid); +- +- break; +- +- case PPTP_CALL_DISCONNECT_NOTIFY: +- /* server confirms disconnect */ +- cid = &pptpReq.disc->callID; +- DEBUGP("%s, CID=%X\n", strMName[msg], ntohs(*cid)); +- info->cstate = PPTP_CALL_NONE; +- +- /* untrack this call id, unexpect GRE packets */ +- pptp_timeout_related(ct); +- /* NEWNAT: look up exp for call id and unexpct_related */ +- break; +- +- case PPTP_WAN_ERROR_NOTIFY: +- break; +- +- case PPTP_ECHO_REQUEST: +- case PPTP_ECHO_REPLY: +- /* I don't have to explain these ;) */ +- break; +- default: +- DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX) +- ? strMName[msg]:strMName[0], msg); +- break; +- } +- +- return NF_ACCEPT; +- +-} +- +-static inline int +-pptp_outbound_pkt(struct tcphdr *tcph, +- struct pptp_pkt_hdr *pptph, +- size_t datalen, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo) +-{ +- struct PptpControlHeader *ctlh; +- union pptp_ctrl_union pptpReq; +- struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info; +- u_int16_t msg, *cid, *pcid; +- +- ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph)); +- pptpReq.rawreq = (void *) ((void *) ctlh + sizeof(*ctlh)); +- +- msg = ntohs(ctlh->messageType); +- DEBUGP("outbound control message %s\n", strMName[msg]); +- +- switch (msg) { +- case PPTP_START_SESSION_REQUEST: +- /* client requests for new control session */ +- if (info->sstate != PPTP_SESSION_NONE) { +- DEBUGP("%s but we already have one", +- strMName[msg]); +- } +- info->sstate = PPTP_SESSION_REQUESTED; +- break; +- case PPTP_STOP_SESSION_REQUEST: +- /* client requests end of control session */ +- info->sstate = PPTP_SESSION_STOPREQ; +- break; +- +- case PPTP_OUT_CALL_REQUEST: +- /* client initiating connection to server */ +- if (info->sstate != PPTP_SESSION_CONFIRMED) { +- DEBUGP("%s but no session\n", +- strMName[msg]); +- break; +- } +- info->cstate = PPTP_CALL_OUT_REQ; +- /* track PNS call id */ +- cid = &pptpReq.ocreq->callID; +- DEBUGP("%s, CID=%X\n", strMName[msg], ntohs(*cid)); +- info->pns_call_id = ntohs(*cid); +- break; +- case PPTP_IN_CALL_REPLY: +- /* client answers incoming call */ +- if (info->cstate != PPTP_CALL_IN_REQ +- && info->cstate != PPTP_CALL_IN_REP) { +- DEBUGP("%s without incall_req\n", +- strMName[msg]); +- break; +- } +- if (pptpReq.icack->resultCode != PPTP_INCALL_ACCEPT) { +- info->cstate = PPTP_CALL_NONE; +- break; +- } +- pcid = &pptpReq.icack->peersCallID; +- if (info->pac_call_id != ntohs(*pcid)) { +- DEBUGP("%s for unknown call %u\n", +- strMName[msg], ntohs(*pcid)); +- break; +- } +- DEBUGP("%s, CID=%X\n", strMName[msg], ntohs(*pcid)); +- /* part two of the three-way handshake */ +- info->cstate = PPTP_CALL_IN_REP; +- info->pns_call_id = ntohs(pptpReq.icack->callID); +- break; +- +- case PPTP_CALL_CLEAR_REQUEST: +- /* client requests hangup of call */ +- if (info->sstate != PPTP_SESSION_CONFIRMED) { +- DEBUGP("CLEAR_CALL but no session\n"); +- break; +- } +- /* FUTURE: iterate over all calls and check if +- * call ID is valid. We don't do this without newnat, +- * because we only know about last call */ +- info->cstate = PPTP_CALL_CLEAR_REQ; +- break; +- case PPTP_SET_LINK_INFO: +- break; +- case PPTP_ECHO_REQUEST: +- case PPTP_ECHO_REPLY: +- /* I don't have to explain these ;) */ +- break; +- default: +- DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX)? +- strMName[msg]:strMName[0], msg); +- /* unknown: no need to create GRE masq table entry */ +- break; +- } +- +- return NF_ACCEPT; +-} +- +- +-/* track caller id inside control connection, call expect_related */ +-static int +-conntrack_pptp_help(const struct iphdr *iph, size_t len, +- struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) +- +-{ +- struct pptp_pkt_hdr *pptph; +- +- struct tcphdr *tcph = (void *) iph + iph->ihl * 4; +- u_int32_t tcplen = len - iph->ihl * 4; +- u_int32_t datalen = tcplen - tcph->doff * 4; +- void *datalimit; +- int dir = CTINFO2DIR(ctinfo); +- struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info; +- +- int oldsstate, oldcstate; +- int ret; +- +- /* don't do any tracking before tcp handshake complete */ +- if (ctinfo != IP_CT_ESTABLISHED +- && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) { +- DEBUGP("ctinfo = %u, skipping\n", ctinfo); +- return NF_ACCEPT; +- } +- +- /* not a complete TCP header? */ +- if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4) { +- DEBUGP("tcplen = %u\n", tcplen); +- return NF_ACCEPT; +- } +- +- /* checksum invalid? */ +- if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, +- csum_partial((char *) tcph, tcplen, 0))) { +- printk(KERN_NOTICE __FILE__ ": bad csum\n"); +-// return NF_ACCEPT; +- } +- +- if (tcph->fin || tcph->rst) { +- DEBUGP("RST/FIN received, timeouting GRE\n"); +- /* can't do this after real newnat */ +- info->cstate = PPTP_CALL_NONE; +- +- /* untrack this call id, unexpect GRE packets */ +- pptp_timeout_related(ct); +- /* no need to call unexpect_related since master conn +- * dies anyway */ +- } +- +- +- pptph = (struct pptp_pkt_hdr *) ((void *) tcph + tcph->doff * 4); +- datalimit = (void *) pptph + datalen; +- +- /* not a full pptp packet header? */ +- if ((void *) pptph+sizeof(*pptph) >= datalimit) { +- DEBUGP("no full PPTP header, can't track\n"); +- return NF_ACCEPT; +- } +- +- /* if it's not a control message we can't do anything with it */ +- if (ntohs(pptph->packetType) != PPTP_PACKET_CONTROL || +- ntohl(pptph->magicCookie) != PPTP_MAGIC_COOKIE) { +- DEBUGP("not a control packet\n"); +- return NF_ACCEPT; +- } +- +- oldsstate = info->sstate; +- oldcstate = info->cstate; +- +- LOCK_BH(&ip_pptp_lock); +- +- if (dir == IP_CT_DIR_ORIGINAL) +- /* client -> server (PNS -> PAC) */ +- ret = pptp_outbound_pkt(tcph, pptph, datalen, ct, ctinfo); +- else +- /* server -> client (PAC -> PNS) */ +- ret = pptp_inbound_pkt(tcph, pptph, datalen, ct, ctinfo); +- DEBUGP("sstate: %d->%d, cstate: %d->%d\n", +- oldsstate, info->sstate, oldcstate, info->cstate); +- UNLOCK_BH(&ip_pptp_lock); +- +- return ret; +-} +- +-/* control protocol helper */ +-static struct ip_conntrack_helper pptp = { +- { NULL, NULL }, +- "pptp", IP_CT_HELPER_F_REUSE_EXPECT, THIS_MODULE, 2, 0, +- { { 0, { tcp: { port: __constant_htons(PPTP_CONTROL_PORT) } } }, +- { 0, { 0 }, IPPROTO_TCP } }, +- { { 0, { tcp: { port: 0xffff } } }, +- { 0, { 0 }, 0xffff } }, +- conntrack_pptp_help }; +- +-/* ip_conntrack_pptp initialization */ +-static int __init init(void) +-{ +- int retcode; +- +- DEBUGP(__FILE__ ": registering helper\n"); +- if ((retcode = ip_conntrack_helper_register(&pptp))) { +- printk(KERN_ERR "Unable to register conntrack application " +- "helper for pptp: %d\n", retcode); +- return -EIO; +- } +- +- return 0; +-} +- +-static void __exit fini(void) +-{ +- ip_conntrack_helper_unregister(&pptp); +-} +- +-module_init(init); +-module_exit(fini); +- +-EXPORT_SYMBOL(ip_pptp_lock); +diff -Nurb linux/net/ipv4/netfilter/ip_conntrack_pptp_priv.h linux.stock/net/ipv4/netfilter/ip_conntrack_pptp_priv.h +--- linux/net/ipv4/netfilter/ip_conntrack_pptp_priv.h 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_conntrack_pptp_priv.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,24 +0,0 @@ +-#ifndef _IP_CT_PPTP_PRIV_H +-#define _IP_CT_PPTP_PRIV_H +- +-/* PptpControlMessageType names */ +-static const char *strMName[] = { +- "UNKNOWN_MESSAGE", +- "START_SESSION_REQUEST", +- "START_SESSION_REPLY", +- "STOP_SESSION_REQUEST", +- "STOP_SESSION_REPLY", +- "ECHO_REQUEST", +- "ECHO_REPLY", +- "OUT_CALL_REQUEST", +- "OUT_CALL_REPLY", +- "IN_CALL_REQUEST", +- "IN_CALL_REPLY", +- "IN_CALL_CONNECT", +- "CALL_CLEAR_REQUEST", +- "CALL_DISCONNECT_NOTIFY", +- "WAN_ERROR_NOTIFY", +- "SET_LINK_INFO" +-}; +- +-#endif +diff -Nurb linux/net/ipv4/netfilter/ip_conntrack_proto_gre.c linux.stock/net/ipv4/netfilter/ip_conntrack_proto_gre.c +--- linux/net/ipv4/netfilter/ip_conntrack_proto_gre.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_conntrack_proto_gre.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,320 +0,0 @@ +-/* +- * ip_conntrack_proto_gre.c - Version 1.11 +- * +- * Connection tracking protocol helper module for GRE. +- * +- * GRE is a generic encapsulation protocol, which is generally not very +- * suited for NAT, as it has no protocol-specific part as port numbers. +- * +- * It has an optional key field, which may help us distinguishing two +- * connections between the same two hosts. +- * +- * GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784 +- * +- * PPTP is built on top of a modified version of GRE, and has a mandatory +- * field called "CallID", which serves us for the same purpose as the key +- * field in plain GRE. +- * +- * Documentation about PPTP can be found in RFC 2637 +- * +- * (C) 2000-2002 by Harald Welte <laforge@gnumonks.org> +- * +- * Development of this code funded by Astaro AG (http://www.astaro.com/) +- * +- */ +- +-#include <linux/config.h> +-#include <linux/module.h> +-#include <linux/types.h> +-#include <linux/timer.h> +-#include <linux/netfilter.h> +-#include <linux/ip.h> +-#include <linux/in.h> +-#include <linux/list.h> +- +-#include <linux/netfilter_ipv4/lockhelp.h> +- +-DECLARE_RWLOCK(ip_ct_gre_lock); +-#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_ct_gre_lock) +-#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_ct_gre_lock) +- +-#include <linux/netfilter_ipv4/listhelp.h> +-#include <linux/netfilter_ipv4/ip_conntrack_protocol.h> +-#include <linux/netfilter_ipv4/ip_conntrack_helper.h> +-#include <linux/netfilter_ipv4/ip_conntrack_core.h> +- +-#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h> +-#include <linux/netfilter_ipv4/ip_conntrack_pptp.h> +- +-MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); +-MODULE_DESCRIPTION("netfilter connection tracking protocol helper for GRE"); +- +-/* shamelessly stolen from ip_conntrack_proto_udp.c */ +-#define GRE_TIMEOUT (30*HZ) +-#define GRE_STREAM_TIMEOUT (180*HZ) +- +-#define DEBUGP(x, args...) +-#define DUMP_TUPLE_GRE(x) +- +-/* GRE KEYMAP HANDLING FUNCTIONS */ +-static LIST_HEAD(gre_keymap_list); +- +-static inline int gre_key_cmpfn(const struct ip_ct_gre_keymap *km, +- const struct ip_conntrack_tuple *t) +-{ +- return ((km->tuple.src.ip == t->src.ip) && +- (km->tuple.dst.ip == t->dst.ip) && +- (km->tuple.dst.protonum == t->dst.protonum) && +- (km->tuple.dst.u.all == t->dst.u.all)); +-} +- +-/* look up the source key for a given tuple */ +-static u_int32_t gre_keymap_lookup(struct ip_conntrack_tuple *t) +-{ +- struct ip_ct_gre_keymap *km; +- u_int32_t key; +- +- READ_LOCK(&ip_ct_gre_lock); +- km = LIST_FIND(&gre_keymap_list, gre_key_cmpfn, +- struct ip_ct_gre_keymap *, t); +- if (!km) { +- READ_UNLOCK(&ip_ct_gre_lock); +- return 0; +- } +- +- key = km->tuple.src.u.gre.key; +- READ_UNLOCK(&ip_ct_gre_lock); +- +- return key; +-} +- +-/* add a single keymap entry, associate with specified expect */ +-int ip_ct_gre_keymap_add(struct ip_conntrack_expect *exp, +- struct ip_conntrack_tuple *t, int reply) +-{ +- struct ip_ct_gre_keymap *km; +- +- km = kmalloc(sizeof(*km), GFP_ATOMIC); +- if (!km) +- return -1; +- +- /* initializing list head should be sufficient */ +- memset(km, 0, sizeof(*km)); +- +- memcpy(&km->tuple, t, sizeof(*t)); +- km->master = exp; +- +- if (!reply) +- exp->proto.gre.keymap_orig = km; +- else +- exp->proto.gre.keymap_reply = km; +- +- DEBUGP("adding new entry %p: ", km); +- DUMP_TUPLE_GRE(&km->tuple); +- +- WRITE_LOCK(&ip_ct_gre_lock); +- list_append(&gre_keymap_list, km); +- WRITE_UNLOCK(&ip_ct_gre_lock); +- +- return 0; +-} +- +-/* change the tuple of a keymap entry (used by nat helper) */ +-void ip_ct_gre_keymap_change(struct ip_ct_gre_keymap *km, +- struct ip_conntrack_tuple *t) +-{ +- DEBUGP("changing entry %p to: ", km); +- DUMP_TUPLE_GRE(t); +- +- WRITE_LOCK(&ip_ct_gre_lock); +- memcpy(&km->tuple, t, sizeof(km->tuple)); +- WRITE_UNLOCK(&ip_ct_gre_lock); +-} +- +- +-/* PUBLIC CONNTRACK PROTO HELPER FUNCTIONS */ +- +-/* invert gre part of tuple */ +-static int gre_invert_tuple(struct ip_conntrack_tuple *tuple, +- const struct ip_conntrack_tuple *orig) +-{ +- tuple->dst.u.gre.protocol = orig->dst.u.gre.protocol; +- tuple->dst.u.gre.version = orig->dst.u.gre.version; +- +- tuple->dst.u.gre.key = orig->src.u.gre.key; +- tuple->src.u.gre.key = orig->dst.u.gre.key; +- +- return 1; +-} +- +-/* gre hdr info to tuple */ +-static int gre_pkt_to_tuple(const void *datah, size_t datalen, +- struct ip_conntrack_tuple *tuple) +-{ +- struct gre_hdr *grehdr = (struct gre_hdr *) datah; +- struct gre_hdr_pptp *pgrehdr = (struct gre_hdr_pptp *) datah; +- u_int32_t srckey; +- +- /* core guarantees 8 protocol bytes, no need for size check */ +- +- tuple->dst.u.gre.version = grehdr->version; +- tuple->dst.u.gre.protocol = grehdr->protocol; +- +- switch (grehdr->version) { +- case GRE_VERSION_1701: +- if (!grehdr->key) { +- DEBUGP("Can't track GRE without key\n"); +- return 0; +- } +- tuple->dst.u.gre.key = *(gre_key(grehdr)); +- break; +- +- case GRE_VERSION_PPTP: +- if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) { +- DEBUGP("GRE_VERSION_PPTP but unknown proto\n"); +- return 0; +- } +- tuple->dst.u.gre.key = htonl(ntohs(pgrehdr->call_id)); +- break; +- +- default: +- printk(KERN_WARNING "unknown GRE version %hu\n", +- tuple->dst.u.gre.version); +- return 0; +- } +- +- srckey = gre_keymap_lookup(tuple); +- +- tuple->src.u.gre.key = srckey; +- +- return 1; +-} +- +-/* print gre part of tuple */ +-static unsigned int gre_print_tuple(char *buffer, +- const struct ip_conntrack_tuple *tuple) +-{ +- return sprintf(buffer, "version=%d protocol=0x%04x srckey=0x%x dstkey=0x%x ", +- tuple->dst.u.gre.version, +- ntohs(tuple->dst.u.gre.protocol), +- ntohl(tuple->src.u.gre.key), +- ntohl(tuple->dst.u.gre.key)); +-} +- +-/* print private data for conntrack */ +-static unsigned int gre_print_conntrack(char *buffer, +- const struct ip_conntrack *ct) +-{ +- return sprintf(buffer, "timeout=%u, stream_timeout=%u ", +- (ct->proto.gre.timeout / HZ), +- (ct->proto.gre.stream_timeout / HZ)); +-} +- +-/* Returns verdict for packet, and may modify conntrack */ +-static int gre_packet(struct ip_conntrack *ct, +- struct iphdr *iph, size_t len, +- enum ip_conntrack_info conntrackinfo) +-{ +- /* If we've seen traffic both ways, this is a GRE connection. +- * Extend timeout. */ +- if (ct->status & IPS_SEEN_REPLY) { +- ip_ct_refresh(ct, ct->proto.gre.stream_timeout); +- /* Also, more likely to be important, and not a probe. */ +- set_bit(IPS_ASSURED_BIT, &ct->status); +- } else +- ip_ct_refresh(ct, ct->proto.gre.timeout); +- +- return NF_ACCEPT; +-} +- +-/* Called when a new connection for this protocol found. */ +-static int gre_new(struct ip_conntrack *ct, +- struct iphdr *iph, size_t len) +-{ +- DEBUGP(": "); +- DUMP_TUPLE_GRE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); +- +- /* initialize to sane value. Ideally a conntrack helper +- * (e.g. in case of pptp) is increasing them */ +- ct->proto.gre.stream_timeout = GRE_STREAM_TIMEOUT; +- ct->proto.gre.timeout = GRE_TIMEOUT; +- +- return 1; +-} +- +-/* Called when a conntrack entry has already been removed from the hashes +- * and is about to be deleted from memory */ +-static void gre_destroy(struct ip_conntrack *ct) +-{ +- struct ip_conntrack_expect *master = ct->master; +- +- DEBUGP(" entering\n"); +- +- if (!master) { +- DEBUGP("no master exp for ct %p\n", ct); +- return; +- } +- +- WRITE_LOCK(&ip_ct_gre_lock); +- if (master->proto.gre.keymap_orig) { +- DEBUGP("removing %p from list\n", master->proto.gre.keymap_orig); +- list_del(&master->proto.gre.keymap_orig->list); +- kfree(master->proto.gre.keymap_orig); +- } +- if (master->proto.gre.keymap_reply) { +- DEBUGP("removing %p from list\n", master->proto.gre.keymap_reply); +- list_del(&master->proto.gre.keymap_reply->list); +- kfree(master->proto.gre.keymap_reply); +- } +- WRITE_UNLOCK(&ip_ct_gre_lock); +-} +- +-/* protocol helper struct */ +-static struct ip_conntrack_protocol gre = { { NULL, NULL }, IPPROTO_GRE, +- "gre", +- gre_pkt_to_tuple, +- gre_invert_tuple, +- gre_print_tuple, +- gre_print_conntrack, +- gre_packet, +- gre_new, +- gre_destroy, +- NULL, +- THIS_MODULE }; +- +-/* ip_conntrack_proto_gre initialization */ +-static int __init init(void) +-{ +- int retcode; +- +- if ((retcode = ip_conntrack_protocol_register(&gre))) { +- printk(KERN_ERR "Unable to register conntrack protocol " +- "helper for gre: %d\n", retcode); +- return -EIO; +- } +- +- return 0; +-} +- +-static void __exit fini(void) +-{ +- struct list_head *pos, *n; +- +- /* delete all keymap entries */ +- WRITE_LOCK(&ip_ct_gre_lock); +- list_for_each_safe(pos, n, &gre_keymap_list) { +- DEBUGP("deleting keymap %p\n", pos); +- list_del(pos); +- kfree(pos); +- } +- WRITE_UNLOCK(&ip_ct_gre_lock); +- +- ip_conntrack_protocol_unregister(&gre); +-} +- +-EXPORT_SYMBOL(ip_ct_gre_keymap_add); +-EXPORT_SYMBOL(ip_ct_gre_keymap_change); +- +-module_init(init); +-module_exit(fini); +diff -Nurb linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c linux.stock/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +--- linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2003-08-12 07:33:45.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2004-05-09 04:13:03.000000000 -0400 +@@ -15,11 +15,17 @@ + #include <linux/netfilter_ipv4/ip_conntrack_protocol.h> + #include <linux/netfilter_ipv4/lockhelp.h> + ++#if 0 ++#define DEBUGP printk ++#else + #define DEBUGP(format, args...) ++#endif + + /* Protects conntrack->proto.tcp */ + static DECLARE_RWLOCK(tcp_lock); + ++/* FIXME: Examine ipfilter's timeouts and conntrack transitions more ++ closely. They're more complex. --RR */ + + /* Actually, I believe that neither ipmasq (where this code is stolen + from) nor ipfilter do it exactly right. A new conntrack machine taking +@@ -39,6 +45,25 @@ + "LISTEN" + }; + ++#define SECS *HZ ++#define MINS * 60 SECS ++#define HOURS * 60 MINS ++#define DAYS * 24 HOURS ++ ++ ++static unsigned long tcp_timeouts[] ++= { 30 MINS, /* TCP_CONNTRACK_NONE, */ ++ 5 DAYS, /* TCP_CONNTRACK_ESTABLISHED, */ ++ 2 MINS, /* TCP_CONNTRACK_SYN_SENT, */ ++ 60 SECS, /* TCP_CONNTRACK_SYN_RECV, */ ++ 2 MINS, /* TCP_CONNTRACK_FIN_WAIT, */ ++ 2 MINS, /* TCP_CONNTRACK_TIME_WAIT, */ ++ 10 SECS, /* TCP_CONNTRACK_CLOSE, */ ++ 60 SECS, /* TCP_CONNTRACK_CLOSE_WAIT, */ ++ 30 SECS, /* TCP_CONNTRACK_LAST_ACK, */ ++ 2 MINS, /* TCP_CONNTRACK_LISTEN, */ ++}; ++ + #define sNO TCP_CONNTRACK_NONE + #define sES TCP_CONNTRACK_ESTABLISHED + #define sSS TCP_CONNTRACK_SYN_SENT +@@ -161,13 +186,13 @@ + && tcph->syn && tcph->ack) + conntrack->proto.tcp.handshake_ack + = htonl(ntohl(tcph->seq) + 1); ++ WRITE_UNLOCK(&tcp_lock); + + /* If only reply is a RST, we can consider ourselves not to + have an established connection: this is a fairly common + problem case, so we can delete the conntrack + immediately. --RR */ + if (!(conntrack->status & IPS_SEEN_REPLY) && tcph->rst) { +- WRITE_UNLOCK(&tcp_lock); + if (del_timer(&conntrack->timeout)) + conntrack->timeout.function((unsigned long)conntrack); + } else { +@@ -178,9 +203,7 @@ + && tcph->ack_seq == conntrack->proto.tcp.handshake_ack) + set_bit(IPS_ASSURED_BIT, &conntrack->status); + +- WRITE_UNLOCK(&tcp_lock); +- ip_ct_refresh(conntrack, +- sysctl_ip_conntrack_tcp_timeouts[newconntrack]); ++ ip_ct_refresh(conntrack, tcp_timeouts[newconntrack]); + } + + return NF_ACCEPT; +diff -Nurb linux/net/ipv4/netfilter/ip_conntrack_proto_udp.c linux.stock/net/ipv4/netfilter/ip_conntrack_proto_udp.c +--- linux/net/ipv4/netfilter/ip_conntrack_proto_udp.c 2003-08-12 07:33:45.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_conntrack_proto_udp.c 2004-05-09 04:13:03.000000000 -0400 +@@ -5,7 +5,9 @@ + #include <linux/in.h> + #include <linux/udp.h> + #include <linux/netfilter_ipv4/ip_conntrack_protocol.h> +-#include <linux/netfilter_ipv4/ip_conntrack_udp.h> ++ ++#define UDP_TIMEOUT (30*HZ) ++#define UDP_STREAM_TIMEOUT (180*HZ) + + static int udp_pkt_to_tuple(const void *datah, size_t datalen, + struct ip_conntrack_tuple *tuple) +@@ -50,13 +52,11 @@ + /* If we've seen traffic both ways, this is some kind of UDP + stream. Extend timeout. */ + if (conntrack->status & IPS_SEEN_REPLY) { +- ip_ct_refresh(conntrack, +- sysctl_ip_conntrack_udp_timeouts[UDP_STREAM_TIMEOUT]); ++ ip_ct_refresh(conntrack, UDP_STREAM_TIMEOUT); + /* Also, more likely to be important, and not a probe */ + set_bit(IPS_ASSURED_BIT, &conntrack->status); + } else +- ip_ct_refresh(conntrack, +- sysctl_ip_conntrack_udp_timeouts[UDP_TIMEOUT]); ++ ip_ct_refresh(conntrack, UDP_TIMEOUT); + + return NF_ACCEPT; + } +diff -Nurb linux/net/ipv4/netfilter/ip_conntrack_standalone.c linux.stock/net/ipv4/netfilter/ip_conntrack_standalone.c +--- linux/net/ipv4/netfilter/ip_conntrack_standalone.c 2003-08-12 07:33:45.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-05-09 04:13:03.000000000 -0400 +@@ -27,7 +27,11 @@ + #include <linux/netfilter_ipv4/ip_conntrack_helper.h> + #include <linux/netfilter_ipv4/listhelp.h> + ++#if 0 ++#define DEBUGP printk ++#else + #define DEBUGP(format, args...) ++#endif + + struct module *ip_conntrack_module = THIS_MODULE; + MODULE_LICENSE("GPL"); +@@ -52,17 +56,12 @@ + return len; + } + ++/* FIXME: Don't print source proto part. --RR */ + static unsigned int + print_expect(char *buffer, const struct ip_conntrack_expect *expect) + { + unsigned int len; + +- if (!expect || !expect->expectant || !expect->expectant->helper) { +- DEBUGP("expect %x expect->expectant %x expect->expectant->helper %x\n", +- expect, expect->expectant, expect->expectant->helper); +- return 0; +- } +- + if (expect->expectant->helper->timeout) + len = sprintf(buffer, "EXPECTING: %lu ", + timer_pending(&expect->timeout) +@@ -294,6 +293,8 @@ + return ret; + } + ++/* FIXME: Allow NULL functions and sub in pointers to generic for ++ them. --RR */ + int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto) + { + int ret = 0; +@@ -362,8 +363,6 @@ + EXPORT_SYMBOL(ip_ct_find_proto); + EXPORT_SYMBOL(__ip_ct_find_proto); + EXPORT_SYMBOL(ip_ct_find_helper); +-EXPORT_SYMBOL(sysctl_ip_conntrack_tcp_timeouts); +-EXPORT_SYMBOL(sysctl_ip_conntrack_udp_timeouts); + EXPORT_SYMBOL(ip_conntrack_expect_related); + EXPORT_SYMBOL(ip_conntrack_change_expect); + EXPORT_SYMBOL(ip_conntrack_unexpect_related); +diff -Nurb linux/net/ipv4/netfilter/ip_conntrack_tftp.c linux.stock/net/ipv4/netfilter/ip_conntrack_tftp.c +--- linux/net/ipv4/netfilter/ip_conntrack_tftp.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_conntrack_tftp.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,126 +0,0 @@ +-/* +- * Licensed under GNU GPL version 2 Copyright Magnus Boden <mb@ozaba.mine.nu> +- * Version: 0.0.7 +- * +- * Thu 21 Mar 2002 Harald Welte <laforge@gnumonks.org> +- * - port to newnat API +- * +- */ +- +-#include <linux/module.h> +-#include <linux/ip.h> +-#include <linux/udp.h> +- +-#include <linux/netfilter.h> +-#include <linux/netfilter_ipv4/ip_tables.h> +-#include <linux/netfilter_ipv4/ip_conntrack_helper.h> +-#include <linux/netfilter_ipv4/ip_conntrack_tftp.h> +- +-MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>"); +-MODULE_DESCRIPTION("Netfilter connection tracking module for tftp"); +-MODULE_LICENSE("GPL"); +- +-#define MAX_PORTS 8 +-static int ports[MAX_PORTS]; +-static int ports_c = 0; +-#ifdef MODULE_PARM +-MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); +-MODULE_PARM_DESC(ports, "port numbers of tftp servers"); +-#endif +- +-#define DEBUGP(format, args...) +- +-static int tftp_help(const struct iphdr *iph, size_t len, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo) +-{ +- struct udphdr *udph = (void *)iph + iph->ihl * 4; +- struct tftphdr *tftph = (void *)udph + 8; +- struct ip_conntrack_expect exp; +- +- switch (ntohs(tftph->opcode)) { +- /* RRQ and WRQ works the same way */ +- case TFTP_OPCODE_READ: +- case TFTP_OPCODE_WRITE: +- DEBUGP(""); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); +- memset(&exp, 0, sizeof(exp)); +- +- exp.tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; +- exp.mask.src.ip = 0xffffffff; +- exp.mask.dst.ip = 0xffffffff; +- exp.mask.dst.u.udp.port = 0xffff; +- exp.mask.dst.protonum = 0xffff; +- exp.expectfn = NULL; +- +- DEBUGP("expect: "); +- DUMP_TUPLE(&exp.tuple); +- DUMP_TUPLE(&exp.mask); +- ip_conntrack_expect_related(ct, &exp); +- break; +- default: +- DEBUGP("Unknown opcode\n"); +- } +- return NF_ACCEPT; +-} +- +-static struct ip_conntrack_helper tftp[MAX_PORTS]; +-static char tftp_names[MAX_PORTS][10]; +- +-static void fini(void) +-{ +- int i; +- +- for (i = 0 ; i < ports_c; i++) { +- DEBUGP("unregistering helper for port %d\n", +- ports[i]); +- ip_conntrack_helper_unregister(&tftp[i]); +- } +-} +- +-static int __init init(void) +-{ +- int i, ret; +- char *tmpname; +- +- if (!ports[0]) +- ports[0]=TFTP_PORT; +- +- for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) { +- /* Create helper structure */ +- memset(&tftp[i], 0, sizeof(struct ip_conntrack_helper)); +- +- tftp[i].tuple.dst.protonum = IPPROTO_UDP; +- tftp[i].tuple.src.u.udp.port = htons(ports[i]); +- tftp[i].mask.dst.protonum = 0xFFFF; +- tftp[i].mask.src.u.udp.port = 0xFFFF; +- tftp[i].max_expected = 1; +- tftp[i].timeout = 0; +- tftp[i].flags = IP_CT_HELPER_F_REUSE_EXPECT; +- tftp[i].me = THIS_MODULE; +- tftp[i].help = tftp_help; +- +- tmpname = &tftp_names[i][0]; +- if (ports[i] == TFTP_PORT) +- sprintf(tmpname, "tftp"); +- else +- sprintf(tmpname, "tftp-%d", i); +- tftp[i].name = tmpname; +- +- DEBUGP("port #%d: %d\n", i, ports[i]); +- +- ret=ip_conntrack_helper_register(&tftp[i]); +- if (ret) { +- printk("ERROR registering helper for port %d\n", +- ports[i]); +- fini(); +- return(ret); +- } +- ports_c++; +- } +- return(0); +-} +- +-module_init(init); +-module_exit(fini); +diff -Nurb linux/net/ipv4/netfilter/ip_nat_core.c linux.stock/net/ipv4/netfilter/ip_nat_core.c +--- linux/net/ipv4/netfilter/ip_nat_core.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_nat_core.c 2004-05-09 04:13:03.000000000 -0400 +@@ -31,7 +31,11 @@ + #include <linux/netfilter_ipv4/ip_conntrack_helper.h> + #include <linux/netfilter_ipv4/listhelp.h> + ++#if 0 ++#define DEBUGP printk ++#else + #define DEBUGP(format, args...) ++#endif + + DECLARE_RWLOCK(ip_nat_lock); + DECLARE_RWLOCK_EXTERN(ip_conntrack_lock); +@@ -207,6 +211,7 @@ + { + struct rtable *rt; + ++ /* FIXME: IPTOS_TOS(iph->tos) --RR */ + if (ip_route_output(&rt, var_ip, 0, 0, 0) != 0) { + DEBUGP("do_extra_mangle: Can't get route to %u.%u.%u.%u\n", + NIPQUAD(var_ip)); +@@ -429,7 +434,7 @@ + *tuple = *orig_tuple; + while ((rptr = find_best_ips_proto_fast(tuple, mr, conntrack, hooknum)) + != NULL) { +- DEBUGP("Found best for "); DUMP_TUPLE_RAW(tuple); ++ DEBUGP("Found best for "); DUMP_TUPLE(tuple); + /* 3) The per-protocol part of the manip is made to + map into the range to make a unique tuple. */ + +@@ -529,6 +534,31 @@ + invert_tuplepr(&orig_tp, + &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple); + ++#if 0 ++ { ++ unsigned int i; ++ ++ DEBUGP("Hook %u (%s), ", hooknum, ++ HOOK2MANIP(hooknum)==IP_NAT_MANIP_SRC ? "SRC" : "DST"); ++ DUMP_TUPLE(&orig_tp); ++ DEBUGP("Range %p: ", mr); ++ for (i = 0; i < mr->rangesize; i++) { ++ DEBUGP("%u:%s%s%s %u.%u.%u.%u - %u.%u.%u.%u %u - %u\n", ++ i, ++ (mr->range[i].flags & IP_NAT_RANGE_MAP_IPS) ++ ? " MAP_IPS" : "", ++ (mr->range[i].flags ++ & IP_NAT_RANGE_PROTO_SPECIFIED) ++ ? " PROTO_SPECIFIED" : "", ++ (mr->range[i].flags & IP_NAT_RANGE_FULL) ++ ? " FULL" : "", ++ NIPQUAD(mr->range[i].min_ip), ++ NIPQUAD(mr->range[i].max_ip), ++ mr->range[i].min.all, ++ mr->range[i].max.all); ++ } ++ } ++#endif + + do { + if (!get_unique_tuple(&new_tuple, &orig_tp, mr, conntrack, +@@ -538,6 +568,15 @@ + return NF_DROP; + } + ++#if 0 ++ DEBUGP("Hook %u (%s) %p\n", hooknum, ++ HOOK2MANIP(hooknum)==IP_NAT_MANIP_SRC ? "SRC" : "DST", ++ conntrack); ++ DEBUGP("Original: "); ++ DUMP_TUPLE(&orig_tp); ++ DEBUGP("New: "); ++ DUMP_TUPLE(&new_tuple); ++#endif + + /* We now have two tuples (SRCIP/SRCPT/DSTIP/DSTPT): + the original (A/B/C/D') and the mangled one (E/F/G/H'). +@@ -554,6 +593,8 @@ + If fail this race (reply tuple now used), repeat. */ + } while (!ip_conntrack_alter_reply(conntrack, &reply)); + ++ /* FIXME: We can simply used existing conntrack reply tuple ++ here --RR */ + /* Create inverse of original: C/D/A/B' */ + invert_tuplepr(&inv_tuple, &orig_tp); + +@@ -678,6 +719,17 @@ + iph->check); + iph->daddr = manip->ip; + } ++#if 0 ++ if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) ++ DEBUGP("IP: checksum on packet bad.\n"); ++ ++ if (proto == IPPROTO_TCP) { ++ void *th = (u_int32_t *)iph + iph->ihl; ++ if (tcp_v4_check(th, len - 4*iph->ihl, iph->saddr, iph->daddr, ++ csum_partial((char *)th, len-4*iph->ihl, 0))) ++ DEBUGP("TCP: checksum on packet bad\n"); ++ } ++#endif + } + + static inline int exp_for_packet(struct ip_conntrack_expect *exp, +@@ -765,6 +817,7 @@ + continue; + + if (exp_for_packet(exp, pskb)) { ++ /* FIXME: May be true multiple times in the case of UDP!! */ + DEBUGP("calling nat helper (exp=%p) for packet\n", + exp); + ret = helper->help(ct, exp, info, ctinfo, +@@ -926,6 +979,7 @@ + INIT_LIST_HEAD(&byipsproto[i]); + } + ++ /* FIXME: Man, this is a hack. <SIGH> */ + IP_NF_ASSERT(ip_conntrack_destroyed == NULL); + ip_conntrack_destroyed = &ip_nat_cleanup_conntrack; + +diff -Nurb linux/net/ipv4/netfilter/ip_nat_h323.c linux.stock/net/ipv4/netfilter/ip_nat_h323.c +--- linux/net/ipv4/netfilter/ip_nat_h323.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_nat_h323.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,403 +0,0 @@ +-/* +- * H.323 'brute force' extension for NAT alteration. +- * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> +- * +- * Based on ip_masq_h323.c for 2.2 kernels from CoRiTel, Sofia project. +- * (http://www.coritel.it/projects/sofia/nat.html) +- * Uses Sampsa Ranta's excellent idea on using expectfn to 'bind' +- * the unregistered helpers to the conntrack entries. +- */ +- +- +-#include <linux/module.h> +-#include <linux/netfilter.h> +-#include <linux/ip.h> +-#include <net/checksum.h> +-#include <net/tcp.h> +- +-#include <linux/netfilter_ipv4/lockhelp.h> +-#include <linux/netfilter_ipv4/ip_nat.h> +-#include <linux/netfilter_ipv4/ip_nat_helper.h> +-#include <linux/netfilter_ipv4/ip_nat_rule.h> +-#include <linux/netfilter_ipv4/ip_conntrack_tuple.h> +-#include <linux/netfilter_ipv4/ip_conntrack_helper.h> +-#include <linux/netfilter_ipv4/ip_conntrack_h323.h> +- +-MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); +-MODULE_DESCRIPTION("H.323 'brute force' connection tracking module"); +-MODULE_LICENSE("GPL"); +- +-DECLARE_LOCK_EXTERN(ip_h323_lock); +-struct module *ip_nat_h323 = THIS_MODULE; +- +-#define DEBUGP(format, args...) +- +- +-static unsigned int +-h225_nat_expected(struct sk_buff **pskb, +- unsigned int hooknum, +- struct ip_conntrack *ct, +- struct ip_nat_info *info); +- +-static unsigned int h225_nat_help(struct ip_conntrack *ct, +- struct ip_conntrack_expect *exp, +- struct ip_nat_info *info, +- enum ip_conntrack_info ctinfo, +- unsigned int hooknum, +- struct sk_buff **pskb); +- +-static struct ip_nat_helper h245 = +- { { NULL, NULL }, +- "H.245", /* name */ +- 0, /* flags */ +- NULL, /* module */ +- { { 0, { 0 } }, /* tuple */ +- { 0, { 0 }, IPPROTO_TCP } }, +- { { 0, { 0xFFFF } }, /* mask */ +- { 0, { 0 }, 0xFFFF } }, +- h225_nat_help, /* helper */ +- h225_nat_expected /* expectfn */ +- }; +- +-static unsigned int +-h225_nat_expected(struct sk_buff **pskb, +- unsigned int hooknum, +- struct ip_conntrack *ct, +- struct ip_nat_info *info) +-{ +- struct ip_nat_multi_range mr; +- u_int32_t newdstip, newsrcip, newip; +- u_int16_t port; +- struct ip_ct_h225_expect *exp_info; +- struct ip_ct_h225_master *master_info; +- struct ip_conntrack *master = master_ct(ct); +- unsigned int is_h225, ret; +- +- IP_NF_ASSERT(info); +- IP_NF_ASSERT(master); +- +- IP_NF_ASSERT(!(info->initialized & (1<<HOOK2MANIP(hooknum)))); +- +- DEBUGP("h225_nat_expected: We have a connection!\n"); +- master_info = &ct->master->expectant->help.ct_h225_info; +- exp_info = &ct->master->help.exp_h225_info; +- +- LOCK_BH(&ip_h323_lock); +- +- DEBUGP("master: "); +- DUMP_TUPLE(&master->tuplehash[IP_CT_DIR_ORIGINAL].tuple); +- DUMP_TUPLE(&master->tuplehash[IP_CT_DIR_REPLY].tuple); +- DEBUGP("conntrack: "); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); +- if (exp_info->dir == IP_CT_DIR_ORIGINAL) { +- /* Make connection go to the client. */ +- newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; +- newsrcip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; +- DEBUGP("h225_nat_expected: %u.%u.%u.%u->%u.%u.%u.%u (to client)\n", +- NIPQUAD(newsrcip), NIPQUAD(newdstip)); +- } else { +- /* Make the connection go to the server */ +- newdstip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip; +- newsrcip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- DEBUGP("h225_nat_expected: %u.%u.%u.%u->%u.%u.%u.%u (to server)\n", +- NIPQUAD(newsrcip), NIPQUAD(newdstip)); +- } +- port = exp_info->port; +- is_h225 = master_info->is_h225 == H225_PORT; +- UNLOCK_BH(&ip_h323_lock); +- +- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) +- newip = newsrcip; +- else +- newip = newdstip; +- +- DEBUGP("h225_nat_expected: IP to %u.%u.%u.%u\n", 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; +- +- /* ... unless we're doing a MANIP_DST, in which case, make +- sure we map to the correct port */ +- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) { +- mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED; +- mr.range[0].min = mr.range[0].max +- = ((union ip_conntrack_manip_proto) +- { port }); +- } +- +- ret = ip_nat_setup_info(ct, &mr, hooknum); +- +- if (is_h225) { +- DEBUGP("h225_nat_expected: H.225, setting NAT helper for %p\n", ct); +- /* NAT expectfn called with ip_nat_lock write-locked */ +- info->helper = &h245; +- } +- return ret; +-} +- +-static int h323_signal_address_fixup(struct ip_conntrack *ct, +- struct sk_buff **pskb, +- enum ip_conntrack_info ctinfo) +-{ +- struct iphdr *iph = (*pskb)->nh.iph; +- struct tcphdr *tcph = (void *)iph + iph->ihl*4; +- unsigned char *data; +- u_int32_t tcplen = (*pskb)->len - iph->ihl*4; +- u_int32_t datalen = tcplen - tcph->doff*4; +- struct ip_ct_h225_master *info = &ct->help.ct_h225_info; +- u_int32_t newip; +- u_int16_t port; +- u_int8_t buffer[6]; +- int i; +- +- MUST_BE_LOCKED(&ip_h323_lock); +- +- DEBUGP("h323_signal_address_fixup: %s %s\n", +- between(info->seq[IP_CT_DIR_ORIGINAL], ntohl(tcph->seq), ntohl(tcph->seq) + datalen) +- ? "yes" : "no", +- between(info->seq[IP_CT_DIR_REPLY], ntohl(tcph->seq), ntohl(tcph->seq) + datalen) +- ? "yes" : "no"); +- if (!(between(info->seq[IP_CT_DIR_ORIGINAL], ntohl(tcph->seq), ntohl(tcph->seq) + datalen) +- || between(info->seq[IP_CT_DIR_REPLY], ntohl(tcph->seq), ntohl(tcph->seq) + datalen))) +- return 1; +- +- DEBUGP("h323_signal_address_fixup: offsets %u + 6 and %u + 6 in %u\n", +- info->offset[IP_CT_DIR_ORIGINAL], +- info->offset[IP_CT_DIR_REPLY], +- tcplen); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); +- +- for (i = 0; i < IP_CT_DIR_MAX; i++) { +- DEBUGP("h323_signal_address_fixup: %s %s\n", +- info->dir == IP_CT_DIR_ORIGINAL ? "original" : "reply", +- i == IP_CT_DIR_ORIGINAL ? "caller" : "callee"); +- if (!between(info->seq[i], ntohl(tcph->seq), +- ntohl(tcph->seq) + datalen)) +- continue; +- if (!between(info->seq[i] + 6, ntohl(tcph->seq), +- ntohl(tcph->seq) + datalen)) { +- /* Partial retransmisison. It's a cracker being funky. */ +- if (net_ratelimit()) { +- printk("H.323_NAT: partial packet %u/6 in %u/%u\n", +- info->seq[i], +- ntohl(tcph->seq), +- ntohl(tcph->seq) + datalen); +- } +- return 0; +- } +- +- /* Change address inside packet to match way we're mapping +- this connection. */ +- if (i == IP_CT_DIR_ORIGINAL) { +- newip = ct->tuplehash[!info->dir].tuple.dst.ip; +- port = ct->tuplehash[!info->dir].tuple.dst.u.tcp.port; +- } else { +- newip = ct->tuplehash[!info->dir].tuple.src.ip; +- port = ct->tuplehash[!info->dir].tuple.src.u.tcp.port; +- } +- +- data = (char *) tcph + tcph->doff * 4 + info->offset[i]; +- +- DEBUGP("h323_signal_address_fixup: orig %s IP:port %u.%u.%u.%u:%u\n", +- i == IP_CT_DIR_ORIGINAL ? "source" : "dest ", +- data[0], data[1], data[2], data[3], +- (data[4] << 8 | data[5])); +- +- /* Modify the packet */ +- memcpy(buffer, &newip, 4); +- memcpy(buffer + 4, &port, 2); +- if (!ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, info->offset[i], +- 6, buffer, 6)) +- return 0; +- +- DEBUGP("h323_signal_address_fixup: new %s IP:port %u.%u.%u.%u:%u\n", +- i == IP_CT_DIR_ORIGINAL ? "source" : "dest ", +- data[0], data[1], data[2], data[3], +- (data[4] << 8 | data[5])); +- } +- +- return 1; +-} +- +-static int h323_data_fixup(struct ip_ct_h225_expect *info, +- struct ip_conntrack *ct, +- struct sk_buff **pskb, +- enum ip_conntrack_info ctinfo, +- struct ip_conntrack_expect *expect) +-{ +- u_int32_t newip; +- u_int16_t port; +- u_int8_t buffer[6]; +- struct ip_conntrack_tuple newtuple; +- struct iphdr *iph = (*pskb)->nh.iph; +- struct tcphdr *tcph = (void *)iph + iph->ihl*4; +- unsigned char *data; +- u_int32_t tcplen = (*pskb)->len - iph->ihl*4; +- struct ip_ct_h225_master *master_info = &ct->help.ct_h225_info; +- int is_h225; +- +- MUST_BE_LOCKED(&ip_h323_lock); +- DEBUGP("h323_data_fixup: offset %u + 6 in %u\n", info->offset, tcplen); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); +- +- if (!between(expect->seq + 6, ntohl(tcph->seq), +- ntohl(tcph->seq) + tcplen - tcph->doff * 4)) { +- /* Partial retransmisison. It's a cracker being funky. */ +- if (net_ratelimit()) { +- printk("H.323_NAT: partial packet %u/6 in %u/%u\n", +- expect->seq, +- ntohl(tcph->seq), +- ntohl(tcph->seq) + tcplen - tcph->doff * 4); +- } +- return 0; +- } +- +- /* Change address inside packet to match way we're mapping +- this connection. */ +- if (info->dir == IP_CT_DIR_REPLY) { +- /* Must be where client thinks server is */ +- newip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; +- /* Expect something from client->server */ +- newtuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; +- newtuple.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; +- } else { +- /* Must be where server thinks client is */ +- newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- /* Expect something from server->client */ +- newtuple.src.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip; +- newtuple.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- } +- +- is_h225 = (master_info->is_h225 == H225_PORT); +- +- if (is_h225) { +- newtuple.dst.protonum = IPPROTO_TCP; +- newtuple.src.u.tcp.port = expect->tuple.src.u.tcp.port; +- } else { +- newtuple.dst.protonum = IPPROTO_UDP; +- newtuple.src.u.udp.port = expect->tuple.src.u.udp.port; +- } +- +- /* Try to get same port: if not, try to change it. */ +- for (port = ntohs(info->port); port != 0; port++) { +- if (is_h225) +- newtuple.dst.u.tcp.port = htons(port); +- else +- newtuple.dst.u.udp.port = htons(port); +- +- if (ip_conntrack_change_expect(expect, &newtuple) == 0) +- break; +- } +- if (port == 0) { +- DEBUGP("h323_data_fixup: no free port found!\n"); +- return 0; +- } +- +- port = htons(port); +- +- data = (char *) tcph + tcph->doff * 4 + info->offset; +- +- DEBUGP("h323_data_fixup: orig IP:port %u.%u.%u.%u:%u\n", +- data[0], data[1], data[2], data[3], +- (data[4] << 8 | data[5])); +- +- /* Modify the packet */ +- memcpy(buffer, &newip, 4); +- memcpy(buffer + 4, &port, 2); +- if (!ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, info->offset, +- 6, buffer, 6)) +- return 0; +- +- DEBUGP("h323_data_fixup: new IP:port %u.%u.%u.%u:%u\n", +- data[0], data[1], data[2], data[3], +- (data[4] << 8 | data[5])); +- +- return 1; +-} +- +-static unsigned int h225_nat_help(struct ip_conntrack *ct, +- struct ip_conntrack_expect *exp, +- struct ip_nat_info *info, +- enum ip_conntrack_info ctinfo, +- unsigned int hooknum, +- struct sk_buff **pskb) +-{ +- int dir; +- struct ip_ct_h225_expect *exp_info; +- +- /* Only mangle things once: original direction in POST_ROUTING +- and reply direction on PRE_ROUTING. */ +- dir = CTINFO2DIR(ctinfo); +- DEBUGP("nat_h323: dir %s at hook %s\n", +- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", +- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" +- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" +- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"); +- if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) +- || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) { +- DEBUGP("nat_h323: Not touching dir %s at hook %s\n", +- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", +- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" +- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" +- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"); +- return NF_ACCEPT; +- } +- +- if (!exp) { +- LOCK_BH(&ip_h323_lock); +- if (!h323_signal_address_fixup(ct, pskb, ctinfo)) { +- UNLOCK_BH(&ip_h323_lock); +- return NF_DROP; +- } +- UNLOCK_BH(&ip_h323_lock); +- return NF_ACCEPT; +- } +- +- exp_info = &exp->help.exp_h225_info; +- +- LOCK_BH(&ip_h323_lock); +- if (!h323_data_fixup(exp_info, ct, pskb, ctinfo, exp)) { +- UNLOCK_BH(&ip_h323_lock); +- return NF_DROP; +- } +- UNLOCK_BH(&ip_h323_lock); +- +- return NF_ACCEPT; +-} +- +-static struct ip_nat_helper h225 = +- { { NULL, NULL }, +- "H.225", /* name */ +- IP_NAT_HELPER_F_ALWAYS, /* flags */ +- THIS_MODULE, /* module */ +- { { 0, { __constant_htons(H225_PORT) } }, /* tuple */ +- { 0, { 0 }, IPPROTO_TCP } }, +- { { 0, { 0xFFFF } }, /* mask */ +- { 0, { 0 }, 0xFFFF } }, +- h225_nat_help, /* helper */ +- h225_nat_expected /* expectfn */ +- }; +- +-static int __init init(void) +-{ +- int ret; +- +- ret = ip_nat_helper_register(&h225); +- +- if (ret != 0) +- printk("ip_nat_h323: cannot initialize the module!\n"); +- +- return ret; +-} +- +-static void __exit fini(void) +-{ +- ip_nat_helper_unregister(&h225); +-} +- +-module_init(init); +-module_exit(fini); +diff -Nurb linux/net/ipv4/netfilter/ip_nat_helper.c linux.stock/net/ipv4/netfilter/ip_nat_helper.c +--- linux/net/ipv4/netfilter/ip_nat_helper.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_nat_helper.c 2004-05-09 04:13:03.000000000 -0400 +@@ -8,9 +8,6 @@ + * - add support for SACK adjustment + * 14 Mar 2002 Harald Welte <laforge@gnumonks.org>: + * - merge SACK support into newnat API +- * 16 Aug 2002 Brian J. Murrell <netfilter@interlinx.bc.ca>: +- * - make ip_nat_resize_packet more generic (TCP and UDP) +- * - add ip_nat_mangle_udp_packet + */ + #include <linux/version.h> + #include <linux/config.h> +@@ -25,7 +22,6 @@ + #include <net/icmp.h> + #include <net/ip.h> + #include <net/tcp.h> +-#include <net/udp.h> + + #define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock) + #define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock) +@@ -38,8 +34,13 @@ + #include <linux/netfilter_ipv4/ip_nat_helper.h> + #include <linux/netfilter_ipv4/listhelp.h> + ++#if 0 ++#define DEBUGP printk ++#define DUMP_OFFSET(x) printk("offset_before=%d, offset_after=%d, correction_pos=%u\n", x->offset_before, x->offset_after, x->correction_pos); ++#else + #define DEBUGP(format, args...) + #define DUMP_OFFSET(x) ++#endif + + DECLARE_LOCK(ip_nat_seqofs_lock); + +@@ -50,12 +51,18 @@ + int new_size) + { + struct iphdr *iph; ++ struct tcphdr *tcph; ++ void *data; + int dir; + struct ip_nat_seq *this_way, *other_way; + + DEBUGP("ip_nat_resize_packet: old_size = %u, new_size = %u\n", + (*skb)->len, new_size); + ++ iph = (*skb)->nh.iph; ++ tcph = (void *)iph + iph->ihl*4; ++ data = (void *)tcph + tcph->doff*4; ++ + dir = CTINFO2DIR(ctinfo); + + this_way = &ct->nat.info.seq[dir]; +@@ -77,9 +84,8 @@ + } + + iph = (*skb)->nh.iph; +- if (iph->protocol == IPPROTO_TCP) { +- struct tcphdr *tcph = (void *)iph + iph->ihl*4; +- void *data = (void *)tcph + tcph->doff*4; ++ tcph = (void *)iph + iph->ihl*4; ++ data = (void *)tcph + tcph->doff*4; + + DEBUGP("ip_nat_resize_packet: Seq_offset before: "); + DUMP_OFFSET(this_way); +@@ -95,20 +101,25 @@ + this_way->correction_pos = ntohl(tcph->seq); + this_way->offset_before = this_way->offset_after; + this_way->offset_after = (int32_t) +- this_way->offset_before + new_size - +- (*skb)->len; ++ this_way->offset_before + new_size - (*skb)->len; + } + + UNLOCK_BH(&ip_nat_seqofs_lock); + + DEBUGP("ip_nat_resize_packet: Seq_offset after: "); + DUMP_OFFSET(this_way); +- } + + return 1; + } + + ++/* Generic function for mangling variable-length address changes inside ++ * NATed connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX command in FTP). ++ * ++ * Takes care about all the nasty sequence number changes, checksumming, ++ * skb enlargement, ... ++ * ++ * */ + int + ip_nat_mangle_tcp_packet(struct sk_buff **skb, + struct ip_conntrack *ct, +@@ -163,7 +174,6 @@ + tcph = (void *)iph + iph->ihl*4; + data = (void *)tcph + tcph->doff*4; + +- if (rep_len != match_len) + /* move post-replacement */ + memmove(data + match_offset + rep_len, + data + match_offset + match_len, +@@ -198,104 +208,6 @@ + return 1; + } + +-int +-ip_nat_mangle_udp_packet(struct sk_buff **skb, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo, +- unsigned int match_offset, +- unsigned int match_len, +- char *rep_buffer, +- unsigned int rep_len) +-{ +- struct iphdr *iph = (*skb)->nh.iph; +- struct udphdr *udph = (void *)iph + iph->ihl * 4; +- unsigned char *data; +- u_int32_t udplen, newlen, newudplen; +- +- udplen = (*skb)->len - iph->ihl*4; +- newudplen = udplen - match_len + rep_len; +- newlen = iph->ihl*4 + newudplen; +- +- if (newlen > 65535) { +- if (net_ratelimit()) +- printk("ip_nat_mangle_udp_packet: nat'ed packet " +- "exceeds maximum packet size\n"); +- return 0; +- } +- +- if ((*skb)->len != newlen) { +- if (!ip_nat_resize_packet(skb, ct, ctinfo, newlen)) { +- printk("resize_packet failed!!\n"); +- return 0; +- } +- } +- +- /* Alexey says: if a hook changes _data_ ... it can break +- original packet sitting in tcp queue and this is fatal */ +- if (skb_cloned(*skb)) { +- struct sk_buff *nskb = skb_copy(*skb, GFP_ATOMIC); +- if (!nskb) { +- if (net_ratelimit()) +- printk("Out of memory cloning TCP packet\n"); +- return 0; +- } +- /* Rest of kernel will get very unhappy if we pass it +- a suddenly-orphaned skbuff */ +- if ((*skb)->sk) +- skb_set_owner_w(nskb, (*skb)->sk); +- kfree_skb(*skb); +- *skb = nskb; +- } +- +- /* skb may be copied !! */ +- iph = (*skb)->nh.iph; +- udph = (void *)iph + iph->ihl*4; +- data = (void *)udph + sizeof(struct udphdr); +- +- if (rep_len != match_len) +- /* move post-replacement */ +- memmove(data + match_offset + rep_len, +- data + match_offset + match_len, +- (*skb)->tail - (data + match_offset + match_len)); +- +- /* insert data from buffer */ +- memcpy(data + match_offset, rep_buffer, rep_len); +- +- /* update skb info */ +- if (newlen > (*skb)->len) { +- DEBUGP("ip_nat_mangle_udp_packet: Extending packet by " +- "%u to %u bytes\n", newlen - (*skb)->len, newlen); +- skb_put(*skb, newlen - (*skb)->len); +- } else { +- DEBUGP("ip_nat_mangle_udp_packet: Shrinking packet from " +- "%u to %u bytes\n", (*skb)->len, newlen); +- skb_trim(*skb, newlen); +- } +- +- /* update the length of the UDP and IP packets to the new values*/ +- udph->len = htons((*skb)->len - iph->ihl*4); +- iph->tot_len = htons(newlen); +- +- /* fix udp checksum if udp checksum was previously calculated */ +- if ((*skb)->csum != 0) { +- (*skb)->csum = csum_partial((char *)udph + +- sizeof(struct udphdr), +- newudplen - sizeof(struct udphdr), +- 0); +- +- udph->check = 0; +- udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, +- newudplen, IPPROTO_UDP, +- csum_partial((char *)udph, +- sizeof(struct udphdr), +- (*skb)->csum)); +- } +- +- ip_send_check(iph); +- +- return 1; +-} +- + /* Adjust one found SACK option including checksum correction */ + static void + sack_adjust(struct tcphdr *tcph, +diff -Nurb linux/net/ipv4/netfilter/ip_nat_mms.c linux.stock/net/ipv4/netfilter/ip_nat_mms.c +--- linux/net/ipv4/netfilter/ip_nat_mms.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_nat_mms.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,330 +0,0 @@ +-/* MMS extension for TCP NAT alteration. +- * (C) 2002 by Filip Sneppe <filip.sneppe@cronos.be> +- * based on ip_nat_ftp.c and ip_nat_irc.c +- * +- * ip_nat_mms.c v0.3 2002-09-22 +- * +- * 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 ip_nat_mms.o ports=port1,port2,...port<MAX_PORTS> +- * +- * Please give the ports of all MMS servers You wish to connect to. +- * If you don't specify ports, the default will be TCP port 1755. +- * +- * More info on MMS protocol, firewalls and NAT: +- * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/MMSFirewall.asp +- * http://www.microsoft.com/windows/windowsmedia/serve/firewall.asp +- * +- * The SDP project people are reverse-engineering MMS: +- * http://get.to/sdp +- */ +- +- +-#include <linux/module.h> +-#include <linux/netfilter_ipv4.h> +-#include <linux/ip.h> +-#include <linux/tcp.h> +-#include <net/tcp.h> +-#include <linux/netfilter_ipv4/ip_nat.h> +-#include <linux/netfilter_ipv4/ip_nat_helper.h> +-#include <linux/netfilter_ipv4/ip_nat_rule.h> +-#include <linux/netfilter_ipv4/ip_conntrack_mms.h> +-#include <linux/netfilter_ipv4/ip_conntrack_helper.h> +- +-#define DEBUGP(format, args...) +-#define DUMP_BYTES(address, counter) +- +-#define MAX_PORTS 8 +-static int ports[MAX_PORTS]; +-static int ports_c = 0; +- +-#ifdef MODULE_PARM +-MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); +-#endif +- +-MODULE_AUTHOR("Filip Sneppe <filip.sneppe@cronos.be>"); +-MODULE_DESCRIPTION("Microsoft Windows Media Services (MMS) NAT module"); +-MODULE_LICENSE("GPL"); +- +-DECLARE_LOCK_EXTERN(ip_mms_lock); +- +- +-static int mms_data_fixup(const struct ip_ct_mms_expect *ct_mms_info, +- struct ip_conntrack *ct, +- struct sk_buff **pskb, +- enum ip_conntrack_info ctinfo, +- struct ip_conntrack_expect *expect) +-{ +- u_int32_t newip; +- struct ip_conntrack_tuple t; +- struct iphdr *iph = (*pskb)->nh.iph; +- struct tcphdr *tcph = (void *) iph + iph->ihl * 4; +- char *data = (char *)tcph + tcph->doff * 4; +- int i, j, k, port; +- u_int16_t mms_proto; +- +- u_int32_t *mms_chunkLenLV = (u_int32_t *)(data + MMS_SRV_CHUNKLENLV_OFFSET); +- u_int32_t *mms_chunkLenLM = (u_int32_t *)(data + MMS_SRV_CHUNKLENLM_OFFSET); +- u_int32_t *mms_messageLength = (u_int32_t *)(data + MMS_SRV_MESSAGELENGTH_OFFSET); +- +- int zero_padding; +- +- char buffer[28]; /* "\\255.255.255.255\UDP\65635" * 2 (for unicode) */ +- char unicode_buffer[75]; /* 27*2 (unicode) + 20 + 1 */ +- char proto_string[6]; +- +- MUST_BE_LOCKED(&ip_mms_lock); +- +- /* what was the protocol again ? */ +- mms_proto = expect->tuple.dst.protonum; +- sprintf(proto_string, "%u", mms_proto); +- +- DEBUGP("ip_nat_mms: mms_data_fixup: info (seq %u + %u) in %u, proto %s\n", +- expect->seq, ct_mms_info->len, ntohl(tcph->seq), +- mms_proto == IPPROTO_UDP ? "UDP" +- : mms_proto == IPPROTO_TCP ? "TCP":proto_string); +- +- newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- +- /* Alter conntrack's expectations. */ +- t = expect->tuple; +- t.dst.ip = newip; +- for (port = ct_mms_info->port; port != 0; port++) { +- t.dst.u.tcp.port = htons(port); +- if (ip_conntrack_change_expect(expect, &t) == 0) { +- DEBUGP("ip_nat_mms: mms_data_fixup: using port %d\n", port); +- break; +- } +- } +- +- if(port == 0) +- return 0; +- +- sprintf(buffer, "\\\\%u.%u.%u.%u\\%s\\%u", +- NIPQUAD(newip), +- expect->tuple.dst.protonum == IPPROTO_UDP ? "UDP" +- : expect->tuple.dst.protonum == IPPROTO_TCP ? "TCP":proto_string, +- port); +- DEBUGP("ip_nat_mms: new unicode string=%s\n", buffer); +- +- memset(unicode_buffer, 0, sizeof(char)*75); +- +- for (i=0; i<strlen(buffer); ++i) +- *(unicode_buffer+i*2)=*(buffer+i); +- +- DEBUGP("ip_nat_mms: mms_data_fixup: padding: %u len: %u\n", ct_mms_info->padding, ct_mms_info->len); +- DEBUGP("ip_nat_mms: mms_data_fixup: offset: %u\n", MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len); +- DUMP_BYTES(data+MMS_SRV_UNICODE_STRING_OFFSET, 60); +- +- /* add end of packet to it */ +- for (j=0; j<ct_mms_info->padding; ++j) { +- DEBUGP("ip_nat_mms: mms_data_fixup: i=%u j=%u byte=%u\n", +- i, j, (u8)*(data+MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len+j)); +- *(unicode_buffer+i*2+j) = *(data+MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len+j); +- } +- +- /* pad with zeroes at the end ? see explanation of weird math below */ +- zero_padding = (8-(strlen(buffer)*2 + ct_mms_info->padding + 4)%8)%8; +- for (k=0; k<zero_padding; ++k) +- *(unicode_buffer+i*2+j+k)= (char)0; +- +- DEBUGP("ip_nat_mms: mms_data_fixup: zero_padding = %u\n", zero_padding); +- DEBUGP("ip_nat_mms: original=> chunkLenLV=%u chunkLenLM=%u messageLength=%u\n", +- *mms_chunkLenLV, *mms_chunkLenLM, *mms_messageLength); +- +- /* explanation, before I forget what I did: +- strlen(buffer)*2 + ct_mms_info->padding + 4 must be divisable by 8; +- divide by 8 and add 3 to compute the mms_chunkLenLM field, +- but note that things may have to be padded with zeroes to align by 8 +- bytes, hence we add 7 and divide by 8 to get the correct length */ +- *mms_chunkLenLM = (u_int32_t) (3+(strlen(buffer)*2+ct_mms_info->padding+11)/8); +- *mms_chunkLenLV = *mms_chunkLenLM+2; +- *mms_messageLength = *mms_chunkLenLV*8; +- +- DEBUGP("ip_nat_mms: modified=> chunkLenLV=%u chunkLenLM=%u messageLength=%u\n", +- *mms_chunkLenLV, *mms_chunkLenLM, *mms_messageLength); +- +- ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, +- expect->seq - ntohl(tcph->seq), +- ct_mms_info->len + ct_mms_info->padding, unicode_buffer, +- strlen(buffer)*2 + ct_mms_info->padding + zero_padding); +- DUMP_BYTES(unicode_buffer, 60); +- +- return 1; +-} +- +-static unsigned int +-mms_nat_expected(struct sk_buff **pskb, +- unsigned int hooknum, +- struct ip_conntrack *ct, +- struct ip_nat_info *info) +-{ +- struct ip_nat_multi_range mr; +- u_int32_t newdstip, newsrcip, newip; +- +- struct ip_conntrack *master = master_ct(ct); +- +- IP_NF_ASSERT(info); +- IP_NF_ASSERT(master); +- +- IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum)))); +- +- DEBUGP("ip_nat_mms: mms_nat_expected: We have a connection!\n"); +- +- newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; +- newsrcip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; +- DEBUGP("ip_nat_mms: mms_nat_expected: hook %s: newsrc->newdst %u.%u.%u.%u->%u.%u.%u.%u\n", +- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" +- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" +- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???", +- NIPQUAD(newsrcip), NIPQUAD(newdstip)); +- +- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) +- newip = newsrcip; +- else +- newip = newdstip; +- +- DEBUGP("ip_nat_mms: mms_nat_expected: IP to %u.%u.%u.%u\n", 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; +- +- return ip_nat_setup_info(ct, &mr, hooknum); +-} +- +- +-static unsigned int mms_nat_help(struct ip_conntrack *ct, +- struct ip_conntrack_expect *exp, +- struct ip_nat_info *info, +- enum ip_conntrack_info ctinfo, +- unsigned int hooknum, +- struct sk_buff **pskb) +-{ +- struct iphdr *iph = (*pskb)->nh.iph; +- struct tcphdr *tcph = (void *) iph + iph->ihl * 4; +- unsigned int datalen; +- int dir; +- struct ip_ct_mms_expect *ct_mms_info; +- +- if (!exp) +- DEBUGP("ip_nat_mms: no exp!!"); +- +- ct_mms_info = &exp->help.exp_mms_info; +- +- /* Only mangle things once: original direction in POST_ROUTING +- and reply direction on PRE_ROUTING. */ +- dir = CTINFO2DIR(ctinfo); +- if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) +- ||(hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) { +- DEBUGP("ip_nat_mms: mms_nat_help: not touching dir %s at hook %s\n", +- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", +- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" +- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" +- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"); +- return NF_ACCEPT; +- } +- DEBUGP("ip_nat_mms: mms_nat_help: beyond not touching (dir %s at hook %s)\n", +- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", +- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" +- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" +- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"); +- +- datalen = (*pskb)->len - iph->ihl * 4 - tcph->doff * 4; +- +- DEBUGP("ip_nat_mms: mms_nat_help: %u+%u=%u %u %u\n", exp->seq, ct_mms_info->len, +- exp->seq + ct_mms_info->len, +- ntohl(tcph->seq), +- ntohl(tcph->seq) + datalen); +- +- LOCK_BH(&ip_mms_lock); +- /* Check wether the whole IP/proto/port pattern is carried in the payload */ +- if (between(exp->seq + ct_mms_info->len, +- ntohl(tcph->seq), +- ntohl(tcph->seq) + datalen)) { +- if (!mms_data_fixup(ct_mms_info, ct, pskb, ctinfo, exp)) { +- UNLOCK_BH(&ip_mms_lock); +- return NF_DROP; +- } +- } else { +- /* Half a match? This means a partial retransmisison. +- It's a cracker being funky. */ +- if (net_ratelimit()) { +- printk("ip_nat_mms: partial packet %u/%u in %u/%u\n", +- exp->seq, ct_mms_info->len, +- ntohl(tcph->seq), +- ntohl(tcph->seq) + datalen); +- } +- UNLOCK_BH(&ip_mms_lock); +- return NF_DROP; +- } +- UNLOCK_BH(&ip_mms_lock); +- +- return NF_ACCEPT; +-} +- +-static struct ip_nat_helper mms[MAX_PORTS]; +-static char mms_names[MAX_PORTS][10]; +- +-/* Not __exit: called from init() */ +-static void fini(void) +-{ +- int i; +- +- for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { +- DEBUGP("ip_nat_mms: unregistering helper for port %d\n", ports[i]); +- ip_nat_helper_unregister(&mms[i]); +- } +-} +- +-static int __init init(void) +-{ +- int i, ret = 0; +- char *tmpname; +- +- if (ports[0] == 0) +- ports[0] = MMS_PORT; +- +- for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { +- +- memset(&mms[i], 0, sizeof(struct ip_nat_helper)); +- +- mms[i].tuple.dst.protonum = IPPROTO_TCP; +- mms[i].tuple.src.u.tcp.port = htons(ports[i]); +- mms[i].mask.dst.protonum = 0xFFFF; +- mms[i].mask.src.u.tcp.port = 0xFFFF; +- mms[i].help = mms_nat_help; +- mms[i].me = THIS_MODULE; +- mms[i].flags = 0; +- mms[i].expect = mms_nat_expected; +- +- tmpname = &mms_names[i][0]; +- if (ports[i] == MMS_PORT) +- sprintf(tmpname, "mms"); +- else +- sprintf(tmpname, "mms-%d", i); +- mms[i].name = tmpname; +- +- DEBUGP("ip_nat_mms: register helper for port %d\n", +- ports[i]); +- ret = ip_nat_helper_register(&mms[i]); +- +- if (ret) { +- printk("ip_nat_mms: error registering " +- "helper for port %d\n", ports[i]); +- fini(); +- return ret; +- } +- ports_c++; +- } +- +- return ret; +-} +- +-module_init(init); +-module_exit(fini); +diff -Nurb linux/net/ipv4/netfilter/ip_nat_pptp.c linux.stock/net/ipv4/netfilter/ip_nat_pptp.c +--- linux/net/ipv4/netfilter/ip_nat_pptp.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_nat_pptp.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,412 +0,0 @@ +-/* +- * ip_nat_pptp.c - Version 1.11 +- * +- * NAT support for PPTP (Point to Point Tunneling Protocol). +- * PPTP is a a protocol for creating virtual private networks. +- * It is a specification defined by Microsoft and some vendors +- * working with Microsoft. PPTP is built on top of a modified +- * version of the Internet Generic Routing Encapsulation Protocol. +- * GRE is defined in RFC 1701 and RFC 1702. Documentation of +- * PPTP can be found in RFC 2637 +- * +- * (C) 2000-2002 by Harald Welte <laforge@gnumonks.org> +- * +- * Development of this code funded by Astaro AG (http://www.astaro.com/) +- * +- * TODO: - Support for multiple calls within one session +- * (needs netfilter newnat code) +- * - NAT to a unique tuple, not to TCP source port +- * (needs netfilter tuple reservation) +- * - Support other NAT scenarios than SNAT of PNS +- * +- */ +- +-#include <linux/config.h> +-#include <linux/module.h> +-#include <linux/ip.h> +-#include <linux/tcp.h> +-#include <net/tcp.h> +-#include <linux/netfilter_ipv4/ip_nat.h> +-#include <linux/netfilter_ipv4/ip_nat_rule.h> +-#include <linux/netfilter_ipv4/ip_nat_helper.h> +-#include <linux/netfilter_ipv4/ip_nat_pptp.h> +-#include <linux/netfilter_ipv4/ip_conntrack_helper.h> +-#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h> +-#include <linux/netfilter_ipv4/ip_conntrack_pptp.h> +- +-MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); +-MODULE_DESCRIPTION("Netfilter NAT helper module for PPTP"); +- +- +-#define DEBUGP(format, args...) +- +-static unsigned int +-pptp_nat_expected(struct sk_buff **pskb, +- unsigned int hooknum, +- struct ip_conntrack *ct, +- struct ip_nat_info *info) +-{ +- struct ip_conntrack *master = master_ct(ct); +- struct ip_nat_multi_range mr; +- struct ip_ct_pptp_master *ct_pptp_info; +- struct ip_nat_pptp *nat_pptp_info; +- u_int32_t newsrcip, newdstip, newcid; +- int ret; +- +- IP_NF_ASSERT(info); +- IP_NF_ASSERT(master); +- IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum)))); +- +- DEBUGP("we have a connection!\n"); +- +- LOCK_BH(&ip_pptp_lock); +- ct_pptp_info = &master->help.ct_pptp_info; +- nat_pptp_info = &master->nat.help.nat_pptp_info; +- +- /* need to alter GRE tuple because conntrack expectfn() used 'wrong' +- * (unmanipulated) values */ +- if (hooknum == NF_IP_PRE_ROUTING) { +- DEBUGP("completing tuples with NAT info \n"); +- /* we can do this, since we're unconfirmed */ +- if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.gre.key == +- htonl(ct_pptp_info->pac_call_id)) { +- /* assume PNS->PAC */ +- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key = +- htonl(nat_pptp_info->pns_call_id); +-// ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.gre.key = +-// htonl(nat_pptp_info->pac_call_id); +- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key = +- htonl(nat_pptp_info->pns_call_id); +- } else { +- /* assume PAC->PNS */ +- DEBUGP("WRONG DIRECTION\n"); +- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key = +- htonl(nat_pptp_info->pac_call_id); +- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key = +- htonl(nat_pptp_info->pns_call_id); +- } +- } +- +- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) { +- newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; +- newcid = htonl(master->nat.help.nat_pptp_info.pac_call_id); +- +- mr.rangesize = 1; +- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED; +- mr.range[0].min_ip = mr.range[0].max_ip = newdstip; +- mr.range[0].min = mr.range[0].max = +- ((union ip_conntrack_manip_proto ) { newcid }); +- DEBUGP("change dest ip to %u.%u.%u.%u\n", +- NIPQUAD(newdstip)); +- DEBUGP("change dest key to 0x%x\n", ntohl(newcid)); +- ret = ip_nat_setup_info(ct, &mr, hooknum); +- } else { +- newsrcip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- /* nat_multi_range is in network byte order, and GRE tuple +- * is 32 bits, not 16 like callID */ +- newcid = htonl(master->help.ct_pptp_info.pns_call_id); +- +- mr.rangesize = 1; +- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS +- |IP_NAT_RANGE_PROTO_SPECIFIED; +- mr.range[0].min_ip = mr.range[0].max_ip = newsrcip; +- mr.range[0].min = mr.range[0].max = +- ((union ip_conntrack_manip_proto ) { newcid }); +- DEBUGP("change src ip to %u.%u.%u.%u\n", +- NIPQUAD(newsrcip)); +- DEBUGP("change 'src' key to 0x%x\n", ntohl(newcid)); +- ret = ip_nat_setup_info(ct, &mr, hooknum); +- } +- +- UNLOCK_BH(&ip_pptp_lock); +- +- return ret; +- +-} +- +-/* outbound packets == from PNS to PAC */ +-static inline unsigned int +-pptp_outbound_pkt(struct tcphdr *tcph, struct pptp_pkt_hdr *pptph, +- size_t datalen, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo, +- struct ip_conntrack_expect *exp) +- +-{ +- struct PptpControlHeader *ctlh; +- union pptp_ctrl_union pptpReq; +- struct ip_ct_pptp_master *ct_pptp_info = &ct->help.ct_pptp_info; +- struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info; +- +- u_int16_t msg, *cid = NULL, new_callid; +- +- ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph)); +- pptpReq.rawreq = (void *) ((void *) ctlh + sizeof(*ctlh)); +- +- new_callid = htons(ct_pptp_info->pns_call_id); +- +- switch (msg = ntohs(ctlh->messageType)) { +- case PPTP_OUT_CALL_REQUEST: +- cid = &pptpReq.ocreq->callID; +- +- /* save original call ID in nat_info */ +- nat_pptp_info->pns_call_id = ct_pptp_info->pns_call_id; +- +- new_callid = tcph->source; +- /* save new call ID in ct info */ +- ct_pptp_info->pns_call_id = ntohs(new_callid); +- break; +- case PPTP_IN_CALL_REPLY: +- cid = &pptpReq.icreq->callID; +- break; +- case PPTP_CALL_CLEAR_REQUEST: +- cid = &pptpReq.clrreq->callID; +- break; +- case PPTP_CALL_DISCONNECT_NOTIFY: +- cid = &pptpReq.disc->callID; +- break; +- +- default: +- DEBUGP("unknown outbound packet 0x%04x:%s\n", msg, +- (msg <= PPTP_MSG_MAX)? strMName[msg]:strMName[0]); +- /* fall through */ +- +- case PPTP_SET_LINK_INFO: +- /* only need to NAT in case PAC is behind NAT box */ +- case PPTP_START_SESSION_REQUEST: +- case PPTP_START_SESSION_REPLY: +- case PPTP_STOP_SESSION_REQUEST: +- case PPTP_STOP_SESSION_REPLY: +- case PPTP_ECHO_REQUEST: +- case PPTP_ECHO_REPLY: +- /* no need to alter packet */ +- return NF_ACCEPT; +- } +- +- IP_NF_ASSERT(cid); +- +- DEBUGP("altering call id from 0x%04x to 0x%04x\n", +- ntohs(*cid), ntohs(new_callid)); +- /* mangle packet */ +- tcph->check = ip_nat_cheat_check(*cid^0xFFFF, +- new_callid, tcph->check); +- *cid = new_callid; +- +- return NF_ACCEPT; +-} +- +-/* inbound packets == from PAC to PNS */ +-static inline unsigned int +-pptp_inbound_pkt(struct tcphdr *tcph, struct pptp_pkt_hdr *pptph, +- size_t datalen, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo, +- struct ip_conntrack_expect *oldexp) +-{ +- struct PptpControlHeader *ctlh; +- union pptp_ctrl_union pptpReq; +- struct ip_ct_pptp_master *ct_pptp_info = &ct->help.ct_pptp_info; +- struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info; +- +- u_int16_t msg, new_cid = 0, new_pcid, *pcid = NULL, *cid = NULL; +- u_int32_t old_dst_ip; +- +- struct ip_conntrack_tuple t; +- +- ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph)); +- pptpReq.rawreq = (void *) ((void *) ctlh + sizeof(*ctlh)); +- +- new_pcid = htons(nat_pptp_info->pns_call_id); +- +- switch (msg = ntohs(ctlh->messageType)) { +- case PPTP_OUT_CALL_REPLY: +- pcid = &pptpReq.ocack->peersCallID; +- cid = &pptpReq.ocack->callID; +- if (!oldexp) { +- DEBUGP("outcall but no expectation\n"); +- break; +- } +- old_dst_ip = oldexp->tuple.dst.ip; +- t = oldexp->tuple; +- +- /* save original PAC call ID in nat_info */ +- nat_pptp_info->pac_call_id = ct_pptp_info->pac_call_id; +- +- /* store new callID in ct_info, so conntrack works */ +- //ct_pptp_info->pac_call_id = ntohs(tcph->source); +- //new_cid = htons(ct_pptp_info->pac_call_id); +- +- /* alter expectation */ +- if (t.dst.ip == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip) { +- /* expectation for PNS->PAC direction */ +- t.dst.u.gre.key = htonl(ct_pptp_info->pac_call_id); +- t.src.u.gre.key = htonl(nat_pptp_info->pns_call_id); +- } else { +- /* expectation for PAC->PNS direction */ +- t.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- DEBUGP("EXPECTATION IN WRONG DIRECTION!!!\n"); +- } +- +- if (!ip_conntrack_change_expect(oldexp, &t)) { +- DEBUGP("successfully changed expect\n"); +- } else { +- DEBUGP("can't change expect\n"); +- } +- ip_ct_gre_keymap_change(oldexp->proto.gre.keymap_orig, &t); +- /* reply keymap */ +- t.src.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip; +- t.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- t.src.u.gre.key = htonl(nat_pptp_info->pac_call_id); +- t.dst.u.gre.key = htonl(ct_pptp_info->pns_call_id); +- ip_ct_gre_keymap_change(oldexp->proto.gre.keymap_reply, &t); +- +- break; +- case PPTP_IN_CALL_CONNECT: +- pcid = &pptpReq.iccon->peersCallID; +- if (!oldexp) +- break; +- old_dst_ip = oldexp->tuple.dst.ip; +- t = oldexp->tuple; +- +- /* alter expectation, no need for callID */ +- if (t.dst.ip == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip) { +- /* expectation for PNS->PAC direction */ +- t.src.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- } else { +- /* expectation for PAC->PNS direction */ +- t.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- } +- +- if (!ip_conntrack_change_expect(oldexp, &t)) { +- DEBUGP("successfully changed expect\n"); +- } else { +- DEBUGP("can't change expect\n"); +- } +- break; +- case PPTP_IN_CALL_REQUEST: +- /* only need to nat in case PAC is behind NAT box */ +- break; +- case PPTP_WAN_ERROR_NOTIFY: +- pcid = &pptpReq.wanerr->peersCallID; +- break; +- default: +- DEBUGP("unknown inbound packet %s\n", +- (msg <= PPTP_MSG_MAX)? strMName[msg]:strMName[0]); +- /* fall through */ +- +- case PPTP_START_SESSION_REQUEST: +- case PPTP_START_SESSION_REPLY: +- case PPTP_STOP_SESSION_REQUEST: +- case PPTP_ECHO_REQUEST: +- case PPTP_ECHO_REPLY: +- /* no need to alter packet */ +- return NF_ACCEPT; +- } +- +- /* mangle packet */ +- IP_NF_ASSERT(pcid); +- DEBUGP("altering peer call id from 0x%04x to 0x%04x\n", +- ntohs(*pcid), ntohs(new_pcid)); +- tcph->check = ip_nat_cheat_check(*pcid^0xFFFF, +- new_pcid, tcph->check); +- *pcid = new_pcid; +- +- if (new_cid) { +- IP_NF_ASSERT(cid); +- DEBUGP("altering call id from 0x%04x to 0x%04x\n", +- ntohs(*cid), ntohs(new_cid)); +- tcph->check = ip_nat_cheat_check(*cid^0xFFFF, +- new_cid, tcph->check); +- *cid = new_cid; +- } +- +- /* great, at least we don't need to resize packets */ +- return NF_ACCEPT; +-} +- +- +-static unsigned int tcp_help(struct ip_conntrack *ct, +- struct ip_conntrack_expect *exp, +- struct ip_nat_info *info, +- enum ip_conntrack_info ctinfo, +- unsigned int hooknum, struct sk_buff **pskb) +-{ +- struct iphdr *iph = (*pskb)->nh.iph; +- struct tcphdr *tcph = (void *) iph + iph->ihl*4; +- unsigned int datalen = (*pskb)->len - iph->ihl*4 - tcph->doff*4; +- struct pptp_pkt_hdr *pptph; +- void *datalimit; +- +- int dir; +- +- DEBUGP("entering\n"); +- +- /* Only mangle things once: original direction in POST_ROUTING +- and reply direction on PRE_ROUTING. */ +- dir = CTINFO2DIR(ctinfo); +- if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) +- || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) { +- DEBUGP("Not touching dir %s at hook %s\n", +- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", +- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" +- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" +- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"); +- return NF_ACCEPT; +- } +- +- /* if packet is too small, just skip it */ +- if (datalen < sizeof(struct pptp_pkt_hdr)+ +- sizeof(struct PptpControlHeader)) { +- DEBUGP("pptp packet too short\n"); +- return NF_ACCEPT; +- } +- +- +- pptph = (struct pptp_pkt_hdr *) ((void *)tcph + tcph->doff*4); +- datalimit = (void *) pptph + datalen; +- +- LOCK_BH(&ip_pptp_lock); +- +- if (dir == IP_CT_DIR_ORIGINAL) { +- /* reuqests sent by client to server (PNS->PAC) */ +- pptp_outbound_pkt(tcph, pptph, datalen, ct, ctinfo, exp); +- } else { +- /* response from the server to the client (PAC->PNS) */ +- pptp_inbound_pkt(tcph, pptph, datalen, ct, ctinfo, exp); +- } +- +- UNLOCK_BH(&ip_pptp_lock); +- +- return NF_ACCEPT; +-} +- +-/* nat helper struct for control connection */ +-static struct ip_nat_helper pptp_tcp_helper = { +- { NULL, NULL }, +- "pptp", IP_NAT_HELPER_F_ALWAYS, THIS_MODULE, +- { { 0, { tcp: { port: __constant_htons(PPTP_CONTROL_PORT) } } }, +- { 0, { 0 }, IPPROTO_TCP } }, +- { { 0, { tcp: { port: 0xFFFF } } }, +- { 0, { 0 }, 0xFFFF } }, +- tcp_help, pptp_nat_expected }; +- +- +-static int __init init(void) +-{ +- DEBUGP("init_module\n" ); +- +- if (ip_nat_helper_register(&pptp_tcp_helper)) +- return -EIO; +- +- return 0; +-} +- +-static void __exit fini(void) +-{ +- DEBUGP("cleanup_module\n" ); +- ip_nat_helper_unregister(&pptp_tcp_helper); +-} +- +-module_init(init); +-module_exit(fini); +diff -Nurb linux/net/ipv4/netfilter/ip_nat_proto_gre.c linux.stock/net/ipv4/netfilter/ip_nat_proto_gre.c +--- linux/net/ipv4/netfilter/ip_nat_proto_gre.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_nat_proto_gre.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,212 +0,0 @@ +-/* +- * ip_nat_proto_gre.c - Version 1.11 +- * +- * NAT protocol helper module for GRE. +- * +- * GRE is a generic encapsulation protocol, which is generally not very +- * suited for NAT, as it has no protocol-specific part as port numbers. +- * +- * It has an optional key field, which may help us distinguishing two +- * connections between the same two hosts. +- * +- * GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784 +- * +- * PPTP is built on top of a modified version of GRE, and has a mandatory +- * field called "CallID", which serves us for the same purpose as the key +- * field in plain GRE. +- * +- * Documentation about PPTP can be found in RFC 2637 +- * +- * (C) 2000-2002 by Harald Welte <laforge@gnumonks.org> +- * +- * Development of this code funded by Astaro AG (http://www.astaro.com/) +- * +- */ +- +-#include <linux/config.h> +-#include <linux/module.h> +-#include <linux/ip.h> +-#include <linux/netfilter_ipv4/ip_nat.h> +-#include <linux/netfilter_ipv4/ip_nat_rule.h> +-#include <linux/netfilter_ipv4/ip_nat_protocol.h> +-#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h> +- +-MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); +-MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE"); +- +-#define DEBUGP(x, args...) +- +-/* is key in given range between min and max */ +-static int +-gre_in_range(const struct ip_conntrack_tuple *tuple, +- enum ip_nat_manip_type maniptype, +- const union ip_conntrack_manip_proto *min, +- const union ip_conntrack_manip_proto *max) +-{ +- return ntohl(tuple->src.u.gre.key) >= ntohl(min->gre.key) +- && ntohl(tuple->src.u.gre.key) <= ntohl(max->gre.key); +-} +- +-/* generate unique tuple ... */ +-static int +-gre_unique_tuple(struct ip_conntrack_tuple *tuple, +- const struct ip_nat_range *range, +- enum ip_nat_manip_type maniptype, +- const struct ip_conntrack *conntrack) +-{ +- u_int32_t min, i, range_size; +- u_int32_t key = 0, *keyptr; +- +- if (maniptype == IP_NAT_MANIP_SRC) +- keyptr = &tuple->src.u.gre.key; +- else +- keyptr = &tuple->dst.u.gre.key; +- +- if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) { +- +- switch (tuple->dst.u.gre.version) { +- case 0: +- DEBUGP("NATing GRE version 0 (ct=%p)\n", +- conntrack); +- min = 1; +- range_size = 0xffffffff; +- break; +- case GRE_VERSION_PPTP: +- DEBUGP("%p: NATing GRE PPTP\n", +- conntrack); +- min = 1; +- range_size = 0xffff; +- break; +- default: +- printk(KERN_WARNING "nat_gre: unknown GRE version\n"); +- return 0; +- break; +- } +- +- } else { +- min = ntohl(range->min.gre.key); +- range_size = ntohl(range->max.gre.key) - min + 1; +- } +- +- DEBUGP("min = %u, range_size = %u\n", min, range_size); +- +- for (i = 0; i < range_size; i++, key++) { +- *keyptr = htonl(min + key % range_size); +- if (!ip_nat_used_tuple(tuple, conntrack)) +- return 1; +- } +- +- DEBUGP("%p: no NAT mapping\n", conntrack); +- +- return 0; +-} +- +-/* manipulate a GRE packet according to maniptype */ +-static void +-gre_manip_pkt(struct iphdr *iph, size_t len, +- const struct ip_conntrack_manip *manip, +- enum ip_nat_manip_type maniptype) +-{ +- struct gre_hdr *greh = (struct gre_hdr *)((u_int32_t *)iph+iph->ihl); +- struct gre_hdr_pptp *pgreh = (struct gre_hdr_pptp *) greh; +- +- /* we only have destination manip of a packet, since 'source key' +- * is not present in the packet itself */ +- if (maniptype == IP_NAT_MANIP_DST) { +- /* key manipulation is always dest */ +- switch (greh->version) { +- case 0: +- if (!greh->key) { +- DEBUGP("can't nat GRE w/o key\n"); +- break; +- } +- if (greh->csum) { +- *(gre_csum(greh)) = +- ip_nat_cheat_check(~*(gre_key(greh)), +- manip->u.gre.key, +- *(gre_csum(greh))); +- } +- *(gre_key(greh)) = manip->u.gre.key; +- break; +- case GRE_VERSION_PPTP: +- DEBUGP("call_id -> 0x%04x\n", +- ntohl(manip->u.gre.key)); +- pgreh->call_id = htons(ntohl(manip->u.gre.key)); +- break; +- default: +- DEBUGP("can't nat unknown GRE version\n"); +- break; +- } +- } +-} +- +-/* print out a nat tuple */ +-static unsigned int +-gre_print(char *buffer, +- const struct ip_conntrack_tuple *match, +- const struct ip_conntrack_tuple *mask) +-{ +- unsigned int len = 0; +- +- if (mask->dst.u.gre.version) +- len += sprintf(buffer + len, "version=%d ", +- ntohs(match->dst.u.gre.version)); +- +- if (mask->dst.u.gre.protocol) +- len += sprintf(buffer + len, "protocol=0x%x ", +- ntohs(match->dst.u.gre.protocol)); +- +- if (mask->src.u.gre.key) +- len += sprintf(buffer + len, "srckey=0x%x ", +- ntohl(match->src.u.gre.key)); +- +- if (mask->dst.u.gre.key) +- len += sprintf(buffer + len, "dstkey=0x%x ", +- ntohl(match->src.u.gre.key)); +- +- return len; +-} +- +-/* print a range of keys */ +-static unsigned int +-gre_print_range(char *buffer, const struct ip_nat_range *range) +-{ +- if (range->min.gre.key != 0 +- || range->max.gre.key != 0xFFFF) { +- if (range->min.gre.key == range->max.gre.key) +- return sprintf(buffer, "key 0x%x ", +- ntohl(range->min.gre.key)); +- else +- return sprintf(buffer, "keys 0x%u-0x%u ", +- ntohl(range->min.gre.key), +- ntohl(range->max.gre.key)); +- } else +- return 0; +-} +- +-/* nat helper struct */ +-static struct ip_nat_protocol gre = +- { { NULL, NULL }, "GRE", IPPROTO_GRE, +- gre_manip_pkt, +- gre_in_range, +- gre_unique_tuple, +- gre_print, +- gre_print_range +- }; +- +-static int __init init(void) +-{ +- if (ip_nat_protocol_register(&gre)) +- return -EIO; +- +- return 0; +-} +- +-static void __exit fini(void) +-{ +- ip_nat_protocol_unregister(&gre); +-} +- +-module_init(init); +-module_exit(fini); +diff -Nurb linux/net/ipv4/netfilter/ip_nat_standalone.c linux.stock/net/ipv4/netfilter/ip_nat_standalone.c +--- linux/net/ipv4/netfilter/ip_nat_standalone.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_nat_standalone.c 2004-05-09 04:13:03.000000000 -0400 +@@ -37,7 +37,11 @@ + #include <linux/netfilter_ipv4/ip_conntrack_core.h> + #include <linux/netfilter_ipv4/listhelp.h> + ++#if 0 ++#define DEBUGP printk ++#else + #define DEBUGP(format, args...) ++#endif + + #define HOOKNAME(hooknum) ((hooknum) == NF_IP_POST_ROUTING ? "POST_ROUTING" \ + : ((hooknum) == NF_IP_PRE_ROUTING ? "PRE_ROUTING" \ +@@ -354,6 +358,5 @@ + EXPORT_SYMBOL(ip_nat_helper_unregister); + EXPORT_SYMBOL(ip_nat_cheat_check); + EXPORT_SYMBOL(ip_nat_mangle_tcp_packet); +-EXPORT_SYMBOL(ip_nat_mangle_udp_packet); + EXPORT_SYMBOL(ip_nat_used_tuple); + MODULE_LICENSE("GPL"); +diff -Nurb linux/net/ipv4/netfilter/ip_nat_tftp.c linux.stock/net/ipv4/netfilter/ip_nat_tftp.c +--- linux/net/ipv4/netfilter/ip_nat_tftp.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_nat_tftp.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,186 +0,0 @@ +-/* +- * Licensed under GNU GPL version 2 Copyright Magnus Boden <mb@ozaba.mine.nu> +- * Version: 0.0.7 +- * +- * Thu 21 Mar 2002 Harald Welte <laforge@gnumonks.org> +- * - Port to newnat API +- * +- * This module currently supports DNAT: +- * iptables -t nat -A PREROUTING -d x.x.x.x -j DNAT --to-dest x.x.x.y +- * +- * and SNAT: +- * iptables -t nat -A POSTROUTING { -j MASQUERADE , -j SNAT --to-source x.x.x.x } +- * +- * It has not been tested with +- * -j SNAT --to-source x.x.x.x-x.x.x.y since I only have one external ip +- * If you do test this please let me know if it works or not. +- * +- */ +- +-#include <linux/module.h> +-#include <linux/netfilter_ipv4.h> +-#include <linux/ip.h> +-#include <linux/udp.h> +- +-#include <linux/netfilter.h> +-#include <linux/netfilter_ipv4/ip_tables.h> +-#include <linux/netfilter_ipv4/ip_conntrack_helper.h> +-#include <linux/netfilter_ipv4/ip_conntrack_tftp.h> +-#include <linux/netfilter_ipv4/ip_nat_helper.h> +-#include <linux/netfilter_ipv4/ip_nat_rule.h> +- +-MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>"); +-MODULE_DESCRIPTION("Netfilter NAT helper for tftp"); +-MODULE_LICENSE("GPL"); +- +-#define MAX_PORTS 8 +- +-static int ports[MAX_PORTS]; +-static int ports_c = 0; +-#ifdef MODULE_PARM +-MODULE_PARM(ports,"1-" __MODULE_STRING(MAX_PORTS) "i"); +-MODULE_PARM_DESC(ports, "port numbers of tftp servers"); +-#endif +- +-#define DEBUGP(format, args...) +-static unsigned int +-tftp_nat_help(struct ip_conntrack *ct, +- struct ip_conntrack_expect *exp, +- struct ip_nat_info *info, +- enum ip_conntrack_info ctinfo, +- unsigned int hooknum, +- struct sk_buff **pskb) +-{ +- int dir = CTINFO2DIR(ctinfo); +- struct iphdr *iph = (*pskb)->nh.iph; +- struct udphdr *udph = (void *)iph + iph->ihl * 4; +- struct tftphdr *tftph = (void *)udph + 8; +- struct ip_conntrack_tuple repl; +- +- if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) +- || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) +- return NF_ACCEPT; +- +- if (!exp) { +- DEBUGP("no conntrack expectation to modify\n"); +- return NF_ACCEPT; +- } +- +- switch (ntohs(tftph->opcode)) { +- /* RRQ and WRQ works the same way */ +- case TFTP_OPCODE_READ: +- case TFTP_OPCODE_WRITE: +- repl = ct->tuplehash[IP_CT_DIR_REPLY].tuple; +- DEBUGP(""); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); +- DEBUGP("expecting: "); +- DUMP_TUPLE_RAW(&repl); +- DUMP_TUPLE_RAW(&exp->mask); +- ip_conntrack_change_expect(exp, &repl); +- break; +- default: +- DEBUGP("Unknown opcode\n"); +- } +- +- return NF_ACCEPT; +-} +- +-static unsigned int +-tftp_nat_expected(struct sk_buff **pskb, +- unsigned int hooknum, +- struct ip_conntrack *ct, +- struct ip_nat_info *info) +-{ +- const struct ip_conntrack *master = ct->master->expectant; +- const struct ip_conntrack_tuple *orig = +- &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple; +- struct ip_nat_multi_range mr; +- +- IP_NF_ASSERT(info); +- IP_NF_ASSERT(master); +- IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum)))); +- +- mr.rangesize = 1; +- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS; +- +- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) { +- mr.range[0].min_ip = mr.range[0].max_ip = orig->dst.ip; +- DEBUGP("orig: %u.%u.%u.%u:%u <-> %u.%u.%u.%u:%u " +- "newsrc: %u.%u.%u.%u\n", +- NIPQUAD((*pskb)->nh.iph->saddr), ntohs(udph->source), +- NIPQUAD((*pskb)->nh.iph->daddr), ntohs(udph->dest), +- NIPQUAD(orig->dst.ip)); +- } else { +- mr.range[0].min_ip = mr.range[0].max_ip = orig->src.ip; +- mr.range[0].min.udp.port = mr.range[0].max.udp.port = +- orig->src.u.udp.port; +- mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED; +- +- DEBUGP("orig: %u.%u.%u.%u:%u <-> %u.%u.%u.%u:%u " +- "newdst: %u.%u.%u.%u:%u\n", +- NIPQUAD((*pskb)->nh.iph->saddr), ntohs(udph->source), +- NIPQUAD((*pskb)->nh.iph->daddr), ntohs(udph->dest), +- NIPQUAD(orig->src.ip), ntohs(orig->src.u.udp.port)); +- } +- +- return ip_nat_setup_info(ct,&mr,hooknum); +-} +- +-static struct ip_nat_helper tftp[MAX_PORTS]; +-static char tftp_names[MAX_PORTS][10]; +- +-static void fini(void) +-{ +- int i; +- +- for (i = 0 ; i < ports_c; i++) { +- DEBUGP("unregistering helper for port %d\n", ports[i]); +- ip_nat_helper_unregister(&tftp[i]); +- } +-} +- +-static int __init init(void) +-{ +- int i, ret; +- char *tmpname; +- +- if (!ports[0]) +- ports[0] = TFTP_PORT; +- +- for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) { +- memset(&tftp[i], 0, sizeof(struct ip_nat_helper)); +- +- tftp[i].tuple.dst.protonum = IPPROTO_UDP; +- tftp[i].tuple.src.u.udp.port = htons(ports[i]); +- tftp[i].mask.dst.protonum = 0xFFFF; +- tftp[i].mask.src.u.udp.port = 0xFFFF; +- tftp[i].help = tftp_nat_help; +- tftp[i].flags = 0; +- tftp[i].me = THIS_MODULE; +- tftp[i].expect = tftp_nat_expected; +- +- tmpname = &tftp_names[i][0]; +- if (ports[i] == TFTP_PORT) +- sprintf(tmpname, "tftp"); +- else +- sprintf(tmpname, "tftp-%d", i); +- tftp[i].name = tmpname; +- +- DEBUGP("ip_nat_tftp: registering for port %d: name %s\n", +- ports[i], tftp[i].name); +- ret = ip_nat_helper_register(&tftp[i]); +- +- if (ret) { +- printk("ip_nat_tftp: unable to register for port %d\n", +- ports[i]); +- fini(); +- return ret; +- } +- ports_c++; +- } +- return ret; +-} +- +-module_init(init); +-module_exit(fini); +diff -Nurb linux/net/ipv4/netfilter/ip_pool.c linux.stock/net/ipv4/netfilter/ip_pool.c +--- linux/net/ipv4/netfilter/ip_pool.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_pool.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,328 +0,0 @@ +-/* Kernel module for IP pool management */ +- +-#include <linux/module.h> +-#include <linux/ip.h> +-#include <linux/skbuff.h> +-#include <linux/netfilter_ipv4/ip_tables.h> +-#include <linux/netfilter_ipv4/ip_pool.h> +-#include <linux/errno.h> +-#include <asm/uaccess.h> +-#include <asm/bitops.h> +-#include <linux/interrupt.h> +-#include <linux/spinlock.h> +- +-#define DP(format, args...) +- +-MODULE_LICENSE("GPL"); +- +-#define NR_POOL 16 +-static int nr_pool = NR_POOL;/* overwrite this when loading module */ +- +-struct ip_pool { +- u_int32_t first_ip; /* host byte order, included in range */ +- u_int32_t last_ip; /* host byte order, included in range */ +- void *members; /* the bitmap proper */ +- int nr_use; /* total nr. of tests through this */ +- int nr_match; /* total nr. of matches through this */ +- rwlock_t lock; +-}; +- +-static struct ip_pool *POOL; +- +-static inline struct ip_pool *lookup(ip_pool_t index) +-{ +- if (index < 0 || index >= nr_pool) { +- DP("ip_pool:lookup: bad index %d\n", index); +- return 0; +- } +- return POOL+index; +-} +- +-int ip_pool_match(ip_pool_t index, u_int32_t addr) +-{ +- struct ip_pool *pool = lookup(index); +- int res = 0; +- +- if (!pool || !pool->members) +- return 0; +- read_lock_bh(&pool->lock); +- if (pool->members) { +- if (addr >= pool->first_ip && addr <= pool->last_ip) { +- addr -= pool->first_ip; +- if (test_bit(addr, pool->members)) { +- res = 1; +-#ifdef CONFIG_IP_POOL_STATISTICS +- pool->nr_match++; +-#endif +- } +- } +-#ifdef CONFIG_IP_POOL_STATISTICS +- pool->nr_use++; +-#endif +- } +- read_unlock_bh(&pool->lock); +- return res; +-} +- +-static int pool_change(ip_pool_t index, u_int32_t addr, int isdel) +-{ +- struct ip_pool *pool; +- int res = -1; +- +- pool = lookup(index); +- if ( !pool || !pool->members +- || addr < pool->first_ip || addr > pool->last_ip) +- return -1; +- read_lock_bh(&pool->lock); +- if (pool->members && addr >= pool->first_ip && addr <= pool->last_ip) { +- addr -= pool->first_ip; +- res = isdel +- ? (0 != test_and_clear_bit(addr, pool->members)) +- : (0 != test_and_set_bit(addr, pool->members)); +- } +- read_unlock_bh(&pool->lock); +- return res; +-} +- +-int ip_pool_mod(ip_pool_t index, u_int32_t addr, int isdel) +-{ +- int res = pool_change(index,addr,isdel); +- +- if (!isdel) res = !res; +- return res; +-} +- +-static inline int bitmap_bytes(u_int32_t a, u_int32_t b) +-{ +- return 4*((((b-a+8)/8)+3)/4); +-} +- +-static inline int poolbytes(ip_pool_t index) +-{ +- struct ip_pool *pool = lookup(index); +- +- return pool ? bitmap_bytes(pool->first_ip, pool->last_ip) : 0; +-} +- +-static int setpool( +- struct sock *sk, +- int optval, +- void *user, +- unsigned int len +-) { +- struct ip_pool_request req; +- +- DP("ip_pool:setpool: optval=%d, user=%p, len=%d\n", optval, user, len); +- if (!capable(CAP_NET_ADMIN)) +- return -EPERM; +- if (optval != SO_IP_POOL) +- return -EBADF; +- if (len != sizeof(req)) +- return -EINVAL; +- if (copy_from_user(&req, user, sizeof(req)) != 0) +- return -EFAULT; +- printk("obsolete op - upgrade your ippool(8) utility.\n"); +- return -EINVAL; +-} +- +-static int getpool( +- struct sock *sk, +- int optval, +- void *user, +- int *len +-) { +- struct ip_pool_request req; +- struct ip_pool *pool; +- ip_pool_t i; +- int newbytes; +- void *newmembers; +- int res; +- +- DP("ip_pool:getpool: optval=%d, user=%p\n", optval, user); +- if (!capable(CAP_NET_ADMIN)) +- return -EINVAL; +- if (optval != SO_IP_POOL) +- return -EINVAL; +- if (*len != sizeof(req)) { +- return -EFAULT; +- } +- if (copy_from_user(&req, user, sizeof(req)) != 0) +- return -EFAULT; +- DP("ip_pool:getpool op=%d, index=%d\n", req.op, req.index); +- if (req.op < IP_POOL_BAD001) { +- printk("obsolete op - upgrade your ippool(8) utility.\n"); +- return -EFAULT; +- } +- switch(req.op) { +- case IP_POOL_HIGH_NR: +- DP("ip_pool HIGH_NR\n"); +- req.index = IP_POOL_NONE; +- for (i=0; i<nr_pool; i++) +- if (POOL[i].members) +- req.index = i; +- return copy_to_user(user, &req, sizeof(req)); +- case IP_POOL_LOOKUP: +- DP("ip_pool LOOKUP\n"); +- pool = lookup(req.index); +- if (!pool) +- return -EINVAL; +- if (!pool->members) +- return -EBADF; +- req.addr = htonl(pool->first_ip); +- req.addr2 = htonl(pool->last_ip); +- return copy_to_user(user, &req, sizeof(req)); +- case IP_POOL_USAGE: +- DP("ip_pool USE\n"); +- pool = lookup(req.index); +- if (!pool) +- return -EINVAL; +- if (!pool->members) +- return -EBADF; +- req.addr = pool->nr_use; +- req.addr2 = pool->nr_match; +- return copy_to_user(user, &req, sizeof(req)); +- case IP_POOL_TEST_ADDR: +- DP("ip_pool TEST 0x%08x\n", req.addr); +- pool = lookup(req.index); +- if (!pool) +- return -EINVAL; +- res = 0; +- read_lock_bh(&pool->lock); +- if (!pool->members) { +- DP("ip_pool TEST_ADDR no members in pool\n"); +- res = -EBADF; +- goto unlock_and_return_res; +- } +- req.addr = ntohl(req.addr); +- if (req.addr < pool->first_ip) { +- DP("ip_pool TEST_ADDR address < pool bounds\n"); +- res = -ERANGE; +- goto unlock_and_return_res; +- } +- if (req.addr > pool->last_ip) { +- DP("ip_pool TEST_ADDR address > pool bounds\n"); +- res = -ERANGE; +- goto unlock_and_return_res; +- } +- req.addr = (0 != test_bit((req.addr - pool->first_ip), +- pool->members)); +- read_unlock_bh(&pool->lock); +- return copy_to_user(user, &req, sizeof(req)); +- case IP_POOL_FLUSH: +- DP("ip_pool FLUSH not yet implemented.\n"); +- return -EBUSY; +- case IP_POOL_DESTROY: +- DP("ip_pool DESTROY not yet implemented.\n"); +- return -EBUSY; +- case IP_POOL_INIT: +- DP("ip_pool INIT 0x%08x-0x%08x\n", req.addr, req.addr2); +- pool = lookup(req.index); +- if (!pool) +- return -EINVAL; +- req.addr = ntohl(req.addr); +- req.addr2 = ntohl(req.addr2); +- if (req.addr > req.addr2) { +- DP("ip_pool INIT bad ip range\n"); +- return -EINVAL; +- } +- newbytes = bitmap_bytes(req.addr, req.addr2); +- newmembers = kmalloc(newbytes, GFP_KERNEL); +- if (!newmembers) { +- DP("ip_pool INIT out of mem for %d bytes\n", newbytes); +- return -ENOMEM; +- } +- memset(newmembers, 0, newbytes); +- write_lock_bh(&pool->lock); +- if (pool->members) { +- DP("ip_pool INIT pool %d exists\n", req.index); +- kfree(newmembers); +- res = -EBUSY; +- goto unlock_and_return_res; +- } +- pool->first_ip = req.addr; +- pool->last_ip = req.addr2; +- pool->nr_use = 0; +- pool->nr_match = 0; +- pool->members = newmembers; +- write_unlock_bh(&pool->lock); +- return 0; +- case IP_POOL_ADD_ADDR: +- DP("ip_pool ADD_ADDR 0x%08x\n", req.addr); +- req.addr = pool_change(req.index, ntohl(req.addr), 0); +- return copy_to_user(user, &req, sizeof(req)); +- case IP_POOL_DEL_ADDR: +- DP("ip_pool DEL_ADDR 0x%08x\n", req.addr); +- req.addr = pool_change(req.index, ntohl(req.addr), 1); +- return copy_to_user(user, &req, sizeof(req)); +- default: +- DP("ip_pool:getpool bad op %d\n", req.op); +- return -EINVAL; +- } +- return -EINVAL; +- +-unlock_and_return_res: +- if (pool) +- read_unlock_bh(&pool->lock); +- return res; +-} +- +-static struct nf_sockopt_ops so_pool +-= { { NULL, NULL }, PF_INET, +- SO_IP_POOL, SO_IP_POOL+1, &setpool, +- SO_IP_POOL, SO_IP_POOL+1, &getpool, +- 0, NULL }; +- +-MODULE_PARM(nr_pool, "i"); +- +-static int __init init(void) +-{ +- ip_pool_t i; +- int res; +- +- if (nr_pool < 1) { +- printk("ip_pool module init: bad nr_pool %d\n", nr_pool); +- return -EINVAL; +- } +- POOL = kmalloc(nr_pool * sizeof(*POOL), GFP_KERNEL); +- if (!POOL) { +- printk("ip_pool module init: out of memory for nr_pool %d\n", +- nr_pool); +- return -ENOMEM; +- } +- for (i=0; i<nr_pool; i++) { +- POOL[i].first_ip = 0; +- POOL[i].last_ip = 0; +- POOL[i].members = 0; +- POOL[i].nr_use = 0; +- POOL[i].nr_match = 0; +- POOL[i].lock = RW_LOCK_UNLOCKED; +- } +- res = nf_register_sockopt(&so_pool); +- DP("ip_pool:init %d pools, result %d\n", nr_pool, res); +- if (res != 0) { +- kfree(POOL); +- POOL = 0; +- } +- return res; +-} +- +-static void __exit fini(void) +-{ +- ip_pool_t i; +- +- DP("ip_pool:fini BYEBYE\n"); +- nf_unregister_sockopt(&so_pool); +- for (i=0; i<nr_pool; i++) { +- if (POOL[i].members) { +- kfree(POOL[i].members); +- POOL[i].members = 0; +- } +- } +- kfree(POOL); +- POOL = 0; +- DP("ip_pool:fini these are the famous last words\n"); +- return; +-} +- +-module_init(init); +-module_exit(fini); +diff -Nurb linux/net/ipv4/netfilter/ip_tables.c linux.stock/net/ipv4/netfilter/ip_tables.c +--- linux/net/ipv4/netfilter/ip_tables.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ip_tables.c 2004-05-09 04:13:03.000000000 -0400 +@@ -62,6 +62,11 @@ + #include <linux/netfilter_ipv4/lockhelp.h> + #include <linux/netfilter_ipv4/listhelp.h> + ++#if 0 ++/* All the better to debug you with... */ ++#define static ++#define inline ++#endif + + /* Locking is simple: we assume at worst case there will be one packet + in user context and one from bottom halves (or soft irq if Alexey's +@@ -83,6 +88,7 @@ + { + /* Size per table */ + unsigned int size; ++ /* Number of entries: FIXME. --RR */ + unsigned int number; + /* Initial number of entries. Needed for module usage count */ + unsigned int initial_entries; +@@ -106,6 +112,11 @@ + #define TABLE_OFFSET(t,p) 0 + #endif + ++#if 0 ++#define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) ++#define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; }) ++#define up(x) do { printk("UP:%u:" #x "\n", __LINE__); up(x); } while(0) ++#endif + + /* Returns whether matches rule or not. */ + static inline int +@@ -408,6 +419,12 @@ + { + void *ret; + ++#if 0 ++ duprintf("find_inlist: searching for `%s' in %s.\n", ++ name, head == &ipt_target ? "ipt_target" ++ : head == &ipt_match ? "ipt_match" ++ : head == &ipt_tables ? "ipt_tables" : "UNKNOWN"); ++#endif + + *error = down_interruptible(mutex); + if (*error != 0) +@@ -745,6 +762,8 @@ + newinfo->underflow[h] = underflows[h]; + } + ++ /* FIXME: underflows must be unconditional, standard verdicts ++ < 0 (not IPT_RETURN). --RR */ + + /* Clear counters and comefrom */ + e->counters = ((struct ipt_counters) { 0, 0 }); +@@ -957,6 +976,7 @@ + goto free_counters; + } + ++ /* FIXME: use iterator macros --RR */ + /* ... then go back and fix counters and names */ + for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ + unsigned int i; +@@ -1134,6 +1154,14 @@ + const struct ipt_counters addme[], + unsigned int *i) + { ++#if 0 ++ duprintf("add_counter: Entry %u %lu/%lu + %lu/%lu\n", ++ *i, ++ (long unsigned int)e->counters.pcnt, ++ (long unsigned int)e->counters.bcnt, ++ (long unsigned int)addme[*i].pcnt, ++ (long unsigned int)addme[*i].bcnt); ++#endif + + ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt); + +@@ -1495,6 +1523,7 @@ + return 0; + } + ++ /* FIXME: Try tcp doff >> packet len against various stacks --RR */ + + #define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) + +@@ -1670,15 +1699,14 @@ + = { { NULL, NULL }, "icmp", &icmp_match, &icmp_checkentry, NULL }; + + #ifdef CONFIG_PROC_FS +-static inline int print_name(const char *i, ++static inline int print_name(const struct ipt_table *t, + off_t start_offset, char *buffer, int length, + off_t *pos, unsigned int *count) + { + if ((*count)++ >= start_offset) { + unsigned int namelen; + +- namelen = sprintf(buffer + *pos, "%s\n", +- i + sizeof(struct list_head)); ++ namelen = sprintf(buffer + *pos, "%s\n", t->name); + if (*pos + namelen > length) { + /* Stop iterating */ + return 1; +@@ -1696,7 +1724,7 @@ + if (down_interruptible(&ipt_mutex) != 0) + return 0; + +- LIST_FIND(&ipt_tables, print_name, void *, ++ LIST_FIND(&ipt_tables, print_name, struct ipt_table *, + offset, buffer, length, &pos, &count); + + up(&ipt_mutex); +@@ -1705,46 +1733,6 @@ + *start=(char *)((unsigned long)count-offset); + return pos; + } +- +-static int ipt_get_targets(char *buffer, char **start, off_t offset, int length) +-{ +- off_t pos = 0; +- unsigned int count = 0; +- +- if (down_interruptible(&ipt_mutex) != 0) +- return 0; +- +- LIST_FIND(&ipt_target, print_name, void *, +- offset, buffer, length, &pos, &count); +- +- up(&ipt_mutex); +- +- *start = (char *)((unsigned long)count - offset); +- return pos; +-} +- +-static int ipt_get_matches(char *buffer, char **start, off_t offset, int length) +-{ +- off_t pos = 0; +- unsigned int count = 0; +- +- if (down_interruptible(&ipt_mutex) != 0) +- return 0; +- +- LIST_FIND(&ipt_match, print_name, void *, +- offset, buffer, length, &pos, &count); +- +- up(&ipt_mutex); +- +- *start = (char *)((unsigned long)count - offset); +- return pos; +-} +- +-static struct { char *name; get_info_t *get_info; } ipt_proc_entry[] = +-{ { "ip_tables_names", ipt_get_tables }, +- { "ip_tables_targets", ipt_get_targets }, +- { "ip_tables_matches", ipt_get_matches }, +- { NULL, NULL} }; + #endif /*CONFIG_PROC_FS*/ + + static int __init init(void) +@@ -1770,20 +1758,14 @@ + #ifdef CONFIG_PROC_FS + { + struct proc_dir_entry *proc; +- int i; + +- for (i = 0; ipt_proc_entry[i].name; i++) { +- proc = proc_net_create(ipt_proc_entry[i].name, 0, +- ipt_proc_entry[i].get_info); ++ proc = proc_net_create("ip_tables_names", 0, ipt_get_tables); + if (!proc) { +- while (--i >= 0) +- proc_net_remove(ipt_proc_entry[i].name); + nf_unregister_sockopt(&ipt_sockopts); + return -ENOMEM; + } + proc->owner = THIS_MODULE; + } +- } + #endif + + printk("ip_tables: (C) 2000-2002 Netfilter core team\n"); +@@ -1794,11 +1776,7 @@ + { + nf_unregister_sockopt(&ipt_sockopts); + #ifdef CONFIG_PROC_FS +- { +- int i; +- for (i = 0; ipt_proc_entry[i].name; i++) +- proc_net_remove(ipt_proc_entry[i].name); +- } ++ proc_net_remove("ip_tables_names"); + #endif + } + +diff -Nurb linux/net/ipv4/netfilter/ipchains_core.c linux.stock/net/ipv4/netfilter/ipchains_core.c +--- linux/net/ipv4/netfilter/ipchains_core.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ipchains_core.c 2004-05-09 04:13:03.000000000 -0400 +@@ -977,10 +977,17 @@ + || ftmp->ipfw.fw_dst.s_addr!=frwl->ipfw.fw_dst.s_addr + || ftmp->ipfw.fw_smsk.s_addr!=frwl->ipfw.fw_smsk.s_addr + || ftmp->ipfw.fw_dmsk.s_addr!=frwl->ipfw.fw_dmsk.s_addr ++#if 0 ++ || ftmp->ipfw.fw_flg!=frwl->ipfw.fw_flg ++#else + || ((ftmp->ipfw.fw_flg & ~IP_FW_F_MARKABS) + != (frwl->ipfw.fw_flg & ~IP_FW_F_MARKABS)) ++#endif + || ftmp->ipfw.fw_invflg!=frwl->ipfw.fw_invflg + || ftmp->ipfw.fw_proto!=frwl->ipfw.fw_proto ++#if 0 ++ || ftmp->ipfw.fw_mark!=frwl->ipfw.fw_mark ++#endif + || ftmp->ipfw.fw_redirpt!=frwl->ipfw.fw_redirpt + || ftmp->ipfw.fw_spts[0]!=frwl->ipfw.fw_spts[0] + || ftmp->ipfw.fw_spts[1]!=frwl->ipfw.fw_spts[1] +@@ -1566,6 +1573,7 @@ + ) + { + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29) ++ /* FIXME: No more `atomic' read and reset. Wonderful 8-( --RR */ + int reset = 0; + #endif + struct ip_chain *i; +diff -Nurb linux/net/ipv4/netfilter/ipfwadm_core.c linux.stock/net/ipv4/netfilter/ipfwadm_core.c +--- linux/net/ipv4/netfilter/ipfwadm_core.c 2003-10-14 04:09:33.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ipfwadm_core.c 2004-05-09 04:13:03.000000000 -0400 +@@ -20,7 +20,7 @@ + * license in recognition of the original copyright. + * -- Alan Cox. + * +- * $Id: ipfwadm_core.c,v 1.1.1.4 2003/10/14 08:09:33 sparq Exp $ ++ * $Id: ipfwadm_core.c,v 1.9.2.2 2002/01/24 15:50:42 davem Exp $ + * + * Ported from BSD to Linux, + * Alan Cox 22/Nov/1994. +@@ -1205,6 +1205,7 @@ + ) + { + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29) ++ /* FIXME: No more `atomic' read and reset. Wonderful 8-( --RR */ + int reset = 0; + #endif + return ip_chain_procinfo(IP_FW_ACCT, buffer,start, offset,length, +@@ -1223,6 +1224,7 @@ + ) + { + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29) ++ /* FIXME: No more `atomic' read and reset. Wonderful 8-( --RR */ + int reset = 0; + #endif + return ip_chain_procinfo(IP_FW_IN, buffer,start,offset,length, +@@ -1237,6 +1239,7 @@ + ) + { + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29) ++ /* FIXME: No more `atomic' read and reset. Wonderful 8-( --RR */ + int reset = 0; + #endif + return ip_chain_procinfo(IP_FW_OUT, buffer,start,offset,length, +@@ -1251,6 +1254,7 @@ + ) + { + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29) ++ /* FIXME: No more `atomic' read and reset. Wonderful 8-( --RR */ + int reset = 0; + #endif + return ip_chain_procinfo(IP_FW_FWD, buffer,start,offset,length, +diff -Nurb linux/net/ipv4/netfilter/ipt_ECN.c linux.stock/net/ipv4/netfilter/ipt_ECN.c +--- linux/net/ipv4/netfilter/ipt_ECN.c 2003-10-14 04:02:57.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ipt_ECN.c 2004-05-09 04:13:03.000000000 -0400 +@@ -87,8 +87,8 @@ + } + + if (diffs[0] != *tcpflags) { +- diffs[0] = diffs[0] ^ 0xFFFF; +- diffs[1] = *tcpflags; ++ diffs[0] = htons(diffs[0]) ^ 0xFFFF; ++ diffs[1] = htons(*tcpflags); + tcph->check = csum_fold(csum_partial((char *)diffs, + sizeof(diffs), + tcph->check^0xFFFF)); +diff -Nurb linux/net/ipv4/netfilter/ipt_LOG.c linux.stock/net/ipv4/netfilter/ipt_LOG.c +--- linux/net/ipv4/netfilter/ipt_LOG.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ipt_LOG.c 2004-05-09 04:13:03.000000000 -0400 +@@ -14,11 +14,15 @@ + #include <net/route.h> + #include <linux/netfilter_ipv4/ipt_LOG.h> + ++#if 0 ++#define DEBUGP printk ++#else + #define DEBUGP(format, args...) ++#endif + + struct esphdr { + __u32 spi; +-}; ++}; /* FIXME evil kludge */ + + /* Use lock to serialize, so printks don't overlap */ + static spinlock_t log_lock = SPIN_LOCK_UNLOCKED; +diff -Nurb linux/net/ipv4/netfilter/ipt_REJECT.c linux.stock/net/ipv4/netfilter/ipt_REJECT.c +--- linux/net/ipv4/netfilter/ipt_REJECT.c 2003-07-04 04:12:31.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ipt_REJECT.c 2004-05-09 04:13:03.000000000 -0400 +@@ -6,8 +6,6 @@ + #include <linux/module.h> + #include <linux/skbuff.h> + #include <linux/ip.h> +-#include <linux/udp.h> +-#include <linux/icmp.h> + #include <net/icmp.h> + #include <net/ip.h> + #include <net/tcp.h> +@@ -16,7 +14,11 @@ + #include <linux/netfilter_ipv4/ip_tables.h> + #include <linux/netfilter_ipv4/ipt_REJECT.h> + ++#if 0 ++#define DEBUGP printk ++#else + #define DEBUGP(format, args...) ++#endif + + /* If the original packet is part of a connection, but the connection + is not confirmed, our manufactured reply will not be associated +@@ -155,7 +157,6 @@ + static void send_unreach(struct sk_buff *skb_in, int code) + { + struct iphdr *iph; +- struct udphdr *udph; + struct icmphdr *icmph; + struct sk_buff *nskb; + u32 saddr; +@@ -167,6 +168,7 @@ + if (!rt) + return; + ++ /* FIXME: Use sysctl number. --RR */ + if (!xrlim_allow(&rt->u.dst, 1*HZ)) + return; + +@@ -184,19 +186,6 @@ + if (iph->frag_off&htons(IP_OFFSET)) + return; + +- /* if UDP checksum is set, verify it's correct */ +- if (iph->protocol == IPPROTO_UDP +- && skb_in->tail-(u8*)iph >= sizeof(struct udphdr)) { +- int datalen = skb_in->len - (iph->ihl<<2); +- udph = (struct udphdr *)((char *)iph + (iph->ihl<<2)); +- if (udph->check +- && csum_tcpudp_magic(iph->saddr, iph->daddr, +- datalen, IPPROTO_UDP, +- csum_partial((char *)udph, datalen, +- 0)) != 0) +- return; +- } +- + /* If we send an ICMP error to an ICMP error a mess would result.. */ + if (iph->protocol == IPPROTO_ICMP + && skb_in->tail-(u8*)iph >= sizeof(struct icmphdr)) { +@@ -271,6 +260,7 @@ + /* Copy as much of original packet as will fit */ + data = skb_put(nskb, + length - sizeof(struct iphdr) - sizeof(struct icmphdr)); ++ /* FIXME: won't work with nonlinear skbs --RR */ + memcpy(data, skb_in->nh.iph, + length - sizeof(struct iphdr) - sizeof(struct icmphdr)); + icmph->checksum = ip_compute_csum((unsigned char *)icmph, +diff -Nurb linux/net/ipv4/netfilter/ipt_ULOG.c linux.stock/net/ipv4/netfilter/ipt_ULOG.c +--- linux/net/ipv4/netfilter/ipt_ULOG.c 2003-07-04 04:12:32.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ipt_ULOG.c 2004-05-09 04:13:03.000000000 -0400 +@@ -12,7 +12,6 @@ + * module loadtime -HW + * 2002/07/07 remove broken nflog_rcv() function -HW + * 2002/08/29 fix shifted/unshifted nlgroup bug -HW +- * 2002/10/30 fix uninitialized mac_len field - <Anders K. Pedersen> + * + * Released under the terms of the GPL + * +@@ -32,7 +31,7 @@ + * Specify, after how many clock ticks (intel: 100 per second) the queue + * should be flushed even if it is not full yet. + * +- * ipt_ULOG.c,v 1.22 2002/10/30 09:07:31 laforge Exp ++ * ipt_ULOG.c,v 1.21 2002/08/29 10:54:34 laforge Exp + */ + + #include <linux/module.h> +@@ -60,7 +59,12 @@ + #define ULOG_NL_EVENT 111 /* Harald's favorite number */ + #define ULOG_MAXNLGROUPS 32 /* numer of nlgroups */ + ++#if 0 ++#define DEBUGP(format, args...) printk(__FILE__ ":" __FUNCTION__ ":" \ ++ format, ## args) ++#else + #define DEBUGP(format, args...) ++#endif + + #define PRINTR(format, args...) do { if (net_ratelimit()) printk(format, ## args); } while (0) + +@@ -220,8 +224,7 @@ + && in->hard_header_len <= ULOG_MAC_LEN) { + memcpy(pm->mac, (*pskb)->mac.raw, in->hard_header_len); + pm->mac_len = in->hard_header_len; +- } else +- pm->mac_len = 0; ++ } + + if (in) + strncpy(pm->indev_name, in->name, sizeof(pm->indev_name)); +diff -Nurb linux/net/ipv4/netfilter/ipt_multiport.c linux.stock/net/ipv4/netfilter/ipt_multiport.c +--- linux/net/ipv4/netfilter/ipt_multiport.c 2003-07-04 04:12:32.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ipt_multiport.c 2004-05-09 04:13:03.000000000 -0400 +@@ -8,7 +8,11 @@ + #include <linux/netfilter_ipv4/ipt_multiport.h> + #include <linux/netfilter_ipv4/ip_tables.h> + ++#if 0 ++#define duprintf(format, args...) printk(format , ## args) ++#else + #define duprintf(format, args...) ++#endif + + /* Returns 1 if the port is matched by the test, 0 otherwise. */ + static inline int +@@ -74,7 +78,7 @@ + + /* Must specify proto == TCP/UDP, no unknown flags or bad count */ + return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP) +- && !(ip->invflags & IPT_INV_PROTO) ++ && !(ip->flags & IPT_INV_PROTO) + && matchsize == IPT_ALIGN(sizeof(struct ipt_multiport)) + && (multiinfo->flags == IPT_MULTIPORT_SOURCE + || multiinfo->flags == IPT_MULTIPORT_DESTINATION +diff -Nurb linux/net/ipv4/netfilter/ipt_pool.c linux.stock/net/ipv4/netfilter/ipt_pool.c +--- linux/net/ipv4/netfilter/ipt_pool.c 2003-07-04 04:12:32.000000000 -0400 ++++ linux.stock/net/ipv4/netfilter/ipt_pool.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,71 +0,0 @@ +-/* Kernel module to match an IP address pool. */ +- +-#include <linux/module.h> +-#include <linux/ip.h> +-#include <linux/skbuff.h> +- +-#include <linux/netfilter_ipv4/ip_tables.h> +-#include <linux/netfilter_ipv4/ip_pool.h> +-#include <linux/netfilter_ipv4/ipt_pool.h> +- +-static inline int match_pool( +- ip_pool_t index, +- __u32 addr, +- int inv +-) { +- if (ip_pool_match(index, ntohl(addr))) +- inv = !inv; +- return inv; +-} +- +-static int match( +- const struct sk_buff *skb, +- const struct net_device *in, +- const struct net_device *out, +- const void *matchinfo, +- int offset, +- const void *hdr, +- u_int16_t datalen, +- int *hotdrop +-) { +- const struct ipt_pool_info *info = matchinfo; +- const struct iphdr *iph = skb->nh.iph; +- +- if (info->src != IP_POOL_NONE && !match_pool(info->src, iph->saddr, +- info->flags&IPT_POOL_INV_SRC)) +- return 0; +- +- if (info->dst != IP_POOL_NONE && !match_pool(info->dst, iph->daddr, +- info->flags&IPT_POOL_INV_DST)) +- return 0; +- +- return 1; +-} +- +-static int checkentry( +- const char *tablename, +- const struct ipt_ip *ip, +- void *matchinfo, +- unsigned int matchsize, +- unsigned int hook_mask +-) { +- if (matchsize != IPT_ALIGN(sizeof(struct ipt_pool_info))) +- return 0; +- return 1; +-} +- +-static struct ipt_match pool_match +-= { { NULL, NULL }, "pool", &match, &checkentry, NULL, THIS_MODULE }; +- +-static int __init init(void) +-{ +- return ipt_register_match(&pool_match); +-} +- +-static void __exit fini(void) +-{ +- ipt_unregister_match(&pool_match); +-} +- +-module_init(init); +-module_exit(fini); +diff -Nurb linux/net/ipv6/mcast.c linux.stock/net/ipv6/mcast.c +--- linux/net/ipv6/mcast.c 2003-10-14 04:09:34.000000000 -0400 ++++ linux.stock/net/ipv6/mcast.c 2004-05-09 04:13:22.000000000 -0400 +@@ -5,7 +5,7 @@ + * Authors: + * Pedro Roque <roque@di.fc.ul.pt> + * +- * $Id: mcast.c,v 1.1.1.4 2003/10/14 08:09:34 sparq Exp $ ++ * $Id: mcast.c,v 1.38 2001/08/15 07:36:31 davem Exp $ + * + * Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c + * +--- linux/include/linux/ppp-comp.h 2004-08-16 20:58:32.089851872 -0400 ++++ linux.stock/include/linux/ppp-comp.h 2004-08-16 20:59:48.217278744 -0400 +@@ -24,7 +24,7 @@ + * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, + * OR MODIFICATIONS. + * +- * $Id: ppp-comp.h,v 1.1.1.4 2003/10/14 08:09:26 sparq Exp $ ++ * $Id: ppp-comp.h,v 1.6 1997/11/27 06:04:44 paulus Exp $ + */ + + /* |