diff options
author | mbm <mbm@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2004-09-19 07:45:34 +0000 |
---|---|---|
committer | mbm <mbm@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2004-09-19 07:45:34 +0000 |
commit | 33c3023ed7e86ce6b2da12f1b5e6a870d266c17a (patch) | |
tree | 7ad61bf949f43c35fdcd4de3ca14071eb9df3373 /obsolete-buildroot | |
parent | 61e08700383d20ffb5d28f1e4700c9da2aa17f06 (diff) |
moved
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@164 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'obsolete-buildroot')
-rw-r--r-- | obsolete-buildroot/sources/openwrt/kernel/patches/100-revert_netfilter.patch | 5834 |
1 files changed, 0 insertions, 5834 deletions
diff --git a/obsolete-buildroot/sources/openwrt/kernel/patches/100-revert_netfilter.patch b/obsolete-buildroot/sources/openwrt/kernel/patches/100-revert_netfilter.patch deleted file mode 100644 index 611261f2d5..0000000000 --- a/obsolete-buildroot/sources/openwrt/kernel/patches/100-revert_netfilter.patch +++ /dev/null @@ -1,5834 +0,0 @@ -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 $ - */ - - /* |