From fc5c9348494b3da8a90d46d460df9f235dfb3f7a Mon Sep 17 00:00:00 2001 From: Andy Boyett Date: Thu, 10 Sep 2009 10:08:46 +0000 Subject: [PATCH] merge r17552 to 8.09 [generic-2.4] remove nat pptp conntracking patch SVN-Revision: 17555 --- .../patches/603-netfilter_nat_pptp.patch | 2406 ----------------- .../patches/606-netfilter_NETMAP.patch | 34 +- .../patches/610-netfilter_connbytes.patch | 126 +- .../patches/613-netfilter_nat_h323.patch | 69 +- .../patches/625-netfilter_nat_pptp_fix.patch | 53 - 5 files changed, 125 insertions(+), 2563 deletions(-) delete mode 100644 target/linux/generic-2.4/patches/603-netfilter_nat_pptp.patch delete mode 100644 target/linux/generic-2.4/patches/625-netfilter_nat_pptp_fix.patch diff --git a/target/linux/generic-2.4/patches/603-netfilter_nat_pptp.patch b/target/linux/generic-2.4/patches/603-netfilter_nat_pptp.patch deleted file mode 100644 index 7e54a7027f..0000000000 --- a/target/linux/generic-2.4/patches/603-netfilter_nat_pptp.patch +++ /dev/null @@ -1,2406 +0,0 @@ ---- a/include/linux/netfilter_ipv4/ip_conntrack.h -+++ b/include/linux/netfilter_ipv4/ip_conntrack.h -@@ -50,16 +50,19 @@ enum ip_conntrack_status { - - #include - #include -+#include - - /* per conntrack: protocol private data */ - union ip_conntrack_proto { - /* insert conntrack proto private data here */ - struct ip_ct_tcp tcp; - struct ip_ct_icmp icmp; -+ struct ip_ct_gre gre; - }; - - union ip_conntrack_expect_proto { - /* insert expect proto private data here */ -+ struct ip_ct_gre_expect gre; - }; - - /* Add protocol helper include file here */ -@@ -67,6 +70,7 @@ union ip_conntrack_expect_proto { - - #include - #include -+#include - - /* per expectation: application helper private data */ - union ip_conntrack_expect_help { -@@ -74,6 +78,7 @@ union ip_conntrack_expect_help { - struct ip_ct_amanda_expect exp_amanda_info; - struct ip_ct_ftp_expect exp_ftp_info; - struct ip_ct_irc_expect exp_irc_info; -+ struct ip_ct_pptp_expect exp_pptp_info; - - #ifdef CONFIG_IP_NF_NAT_NEEDED - union { -@@ -87,14 +92,17 @@ union ip_conntrack_help { - /* insert conntrack helper private data (master) here */ - struct ip_ct_ftp_master ct_ftp_info; - struct ip_ct_irc_master ct_irc_info; -+ struct ip_ct_pptp_master ct_pptp_info; - }; - - #ifdef CONFIG_IP_NF_NAT_NEEDED - #include -+#include - - /* 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 - ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ip_conntrack_pptp.h -@@ -0,0 +1,313 @@ -+/* 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 -+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 PptpStopSessionRequest *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 */ ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h -@@ -0,0 +1,123 @@ -+#ifndef _CONNTRACK_PROTO_GRE_H -+#define _CONNTRACK_PROTO_GRE_H -+#include -+ -+/* 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 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__ -+struct ip_conntrack_expect; -+ -+/* structure for original <-> reply keymap */ -+struct ip_ct_gre_keymap { -+ struct list_head list; -+ -+ struct ip_conntrack_tuple tuple; -+}; -+ -+ -+/* 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); -+ -+/* delete keymap entries */ -+void ip_ct_gre_keymap_destroy(struct ip_conntrack_expect *exp); -+ -+ -+/* 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 */ ---- a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h -+++ b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h -@@ -14,7 +14,7 @@ - union ip_conntrack_manip_proto - { - /* Add other protocols here. */ -- u_int16_t all; -+ u_int32_t all; - - struct { - u_int16_t port; -@@ -25,6 +25,9 @@ union ip_conntrack_manip_proto - struct { - u_int16_t id; - } icmp; -+ struct { -+ u_int32_t key; -+ } gre; - }; - - /* The manipulable part of the tuple. */ -@@ -44,7 +47,7 @@ struct ip_conntrack_tuple - u_int32_t ip; - union { - /* Add other protocols here. */ -- u_int16_t all; -+ u_int32_t all; - - struct { - u_int16_t port; -@@ -55,6 +58,9 @@ struct ip_conntrack_tuple - struct { - u_int8_t type, code; - } icmp; -+ struct { -+ u_int32_t key; -+ } gre; - } u; - - /* The protocol. */ -@@ -80,10 +86,16 @@ enum ip_conntrack_dir - #ifdef __KERNEL__ - - #define DUMP_TUPLE(tp) \ --DEBUGP("tuple %p: %u %u.%u.%u.%u:%hu -> %u.%u.%u.%u:%hu\n", \ -+DEBUGP("tuple %p: %u %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n", \ - (tp), (tp)->dst.protonum, \ -- NIPQUAD((tp)->src.ip), ntohs((tp)->src.u.all), \ -- NIPQUAD((tp)->dst.ip), ntohs((tp)->dst.u.all)) -+ 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)) - - #define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL) - ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ip_nat_pptp.h -@@ -0,0 +1,11 @@ -+/* 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 */ ---- a/net/ipv4/netfilter/Config.in -+++ b/net/ipv4/netfilter/Config.in -@@ -10,6 +10,8 @@ if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; - dep_tristate ' Amanda protocol support' CONFIG_IP_NF_AMANDA $CONFIG_IP_NF_CONNTRACK - dep_tristate ' TFTP protocol support' CONFIG_IP_NF_TFTP $CONFIG_IP_NF_CONNTRACK - dep_tristate ' IRC protocol support' CONFIG_IP_NF_IRC $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 -@@ -63,6 +65,20 @@ if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; - 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 -+ 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 - if [ "$CONFIG_IP_NF_AMANDA" = "m" ]; then - define_tristate CONFIG_IP_NF_NAT_AMANDA m - else ---- a/net/ipv4/netfilter/ip_conntrack_core.c -+++ b/net/ipv4/netfilter/ip_conntrack_core.c -@@ -143,6 +143,8 @@ ip_ct_get_tuple(const struct iphdr *iph, - 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); -@@ -158,6 +160,8 @@ invert_tuple(struct ip_conntrack_tuple * - 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); - } - -@@ -970,8 +974,8 @@ int ip_conntrack_expect_related(struct i - * so there is no need to use the tuple lock too */ - - DEBUGP("ip_conntrack_expect_related %p\n", related_to); -- DEBUGP("tuple: "); DUMP_TUPLE(&expect->tuple); -- DEBUGP("mask: "); DUMP_TUPLE(&expect->mask); -+ DEBUGP("tuple: "); DUMP_TUPLE_RAW(&expect->tuple); -+ DEBUGP("mask: "); DUMP_TUPLE_RAW(&expect->mask); - - old = LIST_FIND(&ip_conntrack_expect_list, resent_expect, - struct ip_conntrack_expect *, &expect->tuple, -@@ -1089,15 +1093,14 @@ int ip_conntrack_change_expect(struct ip - - MUST_BE_READ_LOCKED(&ip_conntrack_lock); - WRITE_LOCK(&ip_conntrack_expect_tuple_lock); -- - DEBUGP("change_expect:\n"); -- DEBUGP("exp tuple: "); DUMP_TUPLE(&expect->tuple); -- DEBUGP("exp mask: "); DUMP_TUPLE(&expect->mask); -- DEBUGP("newtuple: "); DUMP_TUPLE(newtuple); -+ DEBUGP("exp tuple: "); DUMP_TUPLE_RAW(&expect->tuple); -+ DEBUGP("exp mask: "); DUMP_TUPLE_RAW(&expect->mask); -+ DEBUGP("newtuple: "); DUMP_TUPLE_RAW(newtuple); - if (expect->ct_tuple.dst.protonum == 0) { - /* Never seen before */ - DEBUGP("change expect: never seen before\n"); -- if (!ip_ct_tuple_equal(&expect->tuple, newtuple) -+ if (!ip_ct_tuple_mask_cmp(&expect->tuple, newtuple, &expect->mask) - && LIST_FIND(&ip_conntrack_expect_list, expect_clash, - struct ip_conntrack_expect *, newtuple, &expect->mask)) { - /* Force NAT to find an unused tuple */ ---- /dev/null -+++ b/net/ipv4/netfilter/ip_conntrack_pptp_priv.h -@@ -0,0 +1,24 @@ -+#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 ---- /dev/null -+++ b/net/ipv4/netfilter/ip_conntrack_proto_gre.c -@@ -0,0 +1,333 @@ -+/* -+ * ip_conntrack_proto_gre.c - Version 1.2 -+ * -+ * 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-2003 by Harald Welte -+ * -+ * Development of this code funded by Astaro AG (http://www.astaro.com/) -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+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 -+#include -+#include -+#include -+ -+#include -+#include -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Harald Welte "); -+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) -+ -+#if 0 -+#define DEBUGP(format, args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__ \ -+ ": " format, ## args) -+#define DUMP_TUPLE_GRE(x) printk("%u.%u.%u.%u:0x%x -> %u.%u.%u.%u:0x%x:%u:0x%x\n", \ -+ NIPQUAD((x)->src.ip), ntohl((x)->src.u.gre.key), \ -+ NIPQUAD((x)->dst.ip), ntohl((x)->dst.u.gre.key)) -+#else -+#define DEBUGP(x, args...) -+#define DUMP_TUPLE_GRE(x) -+#endif -+ -+/* 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)); -+ -+ 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); -+} -+ -+/* destroy the keymap entries associated with specified expect */ -+void ip_ct_gre_keymap_destroy(struct ip_conntrack_expect *exp) -+{ -+ DEBUGP("entering for exp %p\n", exp); -+ WRITE_LOCK(&ip_ct_gre_lock); -+ if (exp->proto.gre.keymap_orig) { -+ DEBUGP("removing %p from list\n", exp->proto.gre.keymap_orig); -+ list_del(&exp->proto.gre.keymap_orig->list); -+ kfree(exp->proto.gre.keymap_orig); -+ exp->proto.gre.keymap_orig = NULL; -+ } -+ if (exp->proto.gre.keymap_reply) { -+ DEBUGP("removing %p from list\n", exp->proto.gre.keymap_reply); -+ list_del(&exp->proto.gre.keymap_reply->list); -+ kfree(exp->proto.gre.keymap_reply); -+ exp->proto.gre.keymap_reply = NULL; -+ } -+ 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.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 */ -+ -+ 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", -+ grehdr->version); -+ return 0; -+ } -+ -+ srckey = gre_keymap_lookup(tuple); -+ -+#if 0 -+ DEBUGP("found src key %x for tuple ", ntohl(srckey)); -+ DUMP_TUPLE_GRE(tuple); -+#endif -+ 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, "srckey=0x%x dstkey=0x%x ", -+ 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_acct(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_acct(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; -+ } -+ -+ ip_ct_gre_keymap_destroy(master); -+} -+ -+/* 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 at module unload time\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); -+EXPORT_SYMBOL(ip_ct_gre_keymap_destroy); -+ -+module_init(init); -+module_exit(fini); ---- a/net/ipv4/netfilter/ip_nat_core.c -+++ b/net/ipv4/netfilter/ip_nat_core.c -@@ -424,7 +424,7 @@ get_unique_tuple(struct ip_conntrack_tup - *tuple = *orig_tuple; - while ((rptr = find_best_ips_proto_fast(tuple, mr, conntrack, hooknum)) - != NULL) { -- DEBUGP("Found best for "); DUMP_TUPLE(tuple); -+ DEBUGP("Found best for "); DUMP_TUPLE_RAW(tuple); - /* 3) The per-protocol part of the manip is made to - map into the range to make a unique tuple. */ - -@@ -564,9 +564,9 @@ ip_nat_setup_info(struct ip_conntrack *c - HOOK2MANIP(hooknum)==IP_NAT_MANIP_SRC ? "SRC" : "DST", - conntrack); - DEBUGP("Original: "); -- DUMP_TUPLE(&orig_tp); -+ DUMP_TUPLE_RAW(&orig_tp); - DEBUGP("New: "); -- DUMP_TUPLE(&new_tuple); -+ DUMP_TUPLE_RAW(&new_tuple); - #endif - - /* We now have two tuples (SRCIP/SRCPT/DSTIP/DSTPT): ---- /dev/null -+++ b/net/ipv4/netfilter/ip_nat_pptp.c -@@ -0,0 +1,482 @@ -+/* -+ * ip_nat_pptp.c - Version 1.5 -+ * -+ * 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-2003 by Harald Welte -+ * -+ * 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) -+ * -+ * Changes: -+ * 2002-02-10 - Version 1.3 -+ * - Use ip_nat_mangle_tcp_packet() because of cloned skb's -+ * in local connections (Philip Craig ) -+ * - add checks for magicCookie and pptp version -+ * - make argument list of pptp_{out,in}bound_packet() shorter -+ * - move to C99 style initializers -+ * - print version number at module loadtime -+ * 2003-09-22 - Version 1.5 -+ * - use SNATed tcp sourceport as callid, since we get called before -+ * TCP header is mangled (Philip Craig ) -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define IP_NAT_PPTP_VERSION "1.5" -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Harald Welte "); -+MODULE_DESCRIPTION("Netfilter NAT helper module for PPTP"); -+ -+ -+#if 0 -+#include "ip_conntrack_pptp_priv.h" -+#define DEBUGP(format, args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__ \ -+ ": " format, ## args) -+#else -+#define DEBUGP(format, args...) -+#endif -+ -+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 newip, 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 (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) { -+ 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.dst.u.gre.key = -+ htonl(nat_pptp_info->pns_call_id); -+ newip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip; -+ newcid = htonl(nat_pptp_info->pac_call_id); -+ } else { -+ /* assume PAC->PNS */ -+ 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->pac_call_id); -+ newip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; -+ newcid = htonl(nat_pptp_info->pns_call_id); -+ } -+ } else { -+ if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.gre.key == -+ htonl(ct_pptp_info->pac_call_id)) { -+ /* assume PNS->PAC */ -+ newip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; -+ newcid = htonl(ct_pptp_info->pns_call_id); -+ } -+ else { -+ /* assume PAC->PNS */ -+ newip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; -+ newcid = htonl(ct_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 = newip; -+ mr.range[0].min = mr.range[0].max = -+ ((union ip_conntrack_manip_proto ) { newcid }); -+ DEBUGP("change ip to %u.%u.%u.%u\n", -+ NIPQUAD(newip)); -+ DEBUGP("change 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 sk_buff **pskb, -+ struct ip_conntrack *ct, -+ enum ip_conntrack_info ctinfo, -+ struct ip_conntrack_expect *exp) -+ -+{ -+ struct iphdr *iph = (*pskb)->nh.iph; -+ struct tcphdr *tcph = (void *) iph + iph->ihl*4; -+ struct pptp_pkt_hdr *pptph = (struct pptp_pkt_hdr *) -+ ((void *)tcph + tcph->doff*4); -+ -+ 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; -+ -+ /* FIXME: size checks !!! */ -+ 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; -+ /* FIXME: ideally we would want to reserve a call ID -+ * here. current netfilter NAT core is not able to do -+ * this :( For now we use TCP source port. This breaks -+ * multiple calls within one control session */ -+ -+ /* save original call ID in nat_info */ -+ nat_pptp_info->pns_call_id = ct_pptp_info->pns_call_id; -+ -+ /* don't use tcph->source since we are at a DSTmanip -+ * hook (e.g. PREROUTING) and pkt is not mangled yet */ -+ new_callid = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.tcp.port; -+ -+ /* 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; -+ 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 */ -+ ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, (void *)cid - (void *)pptph, -+ sizeof(new_callid), (char *)&new_callid, -+ sizeof(new_callid)); -+ -+ return NF_ACCEPT; -+} -+ -+/* inbound packets == from PAC to PNS */ -+static inline unsigned int -+pptp_inbound_pkt(struct sk_buff **pskb, -+ struct ip_conntrack *ct, -+ enum ip_conntrack_info ctinfo, -+ struct ip_conntrack_expect *oldexp) -+{ -+ struct iphdr *iph = (*pskb)->nh.iph; -+ struct tcphdr *tcph = (void *) iph + iph->ihl*4; -+ struct pptp_pkt_hdr *pptph = (struct pptp_pkt_hdr *) -+ ((void *)tcph + tcph->doff*4); -+ -+ 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, inv_t; -+ struct ip_conntrack_tuple *orig_t, *reply_t; -+ -+ /* FIXME: size checks !!! */ -+ 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; -+ invert_tuplepr(&inv_t, &t); -+ -+ /* save original PAC call ID in nat_info */ -+ nat_pptp_info->pac_call_id = ct_pptp_info->pac_call_id; -+ -+ /* alter expectation */ -+ orig_t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; -+ reply_t = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; -+ if (t.src.ip == orig_t->src.ip && t.dst.ip == orig_t->dst.ip) { -+ /* expectation for PNS->PAC direction */ -+ t.src.u.gre.key = htonl(nat_pptp_info->pns_call_id); -+ t.dst.u.gre.key = htonl(ct_pptp_info->pac_call_id); -+ inv_t.src.ip = reply_t->src.ip; -+ inv_t.dst.ip = reply_t->dst.ip; -+ inv_t.src.u.gre.key = htonl(nat_pptp_info->pac_call_id); -+ inv_t.dst.u.gre.key = htonl(ct_pptp_info->pns_call_id); -+ } else { -+ /* expectation for PAC->PNS direction */ -+ t.src.u.gre.key = htonl(nat_pptp_info->pac_call_id); -+ t.dst.u.gre.key = htonl(ct_pptp_info->pns_call_id); -+ inv_t.src.ip = orig_t->src.ip; -+ inv_t.dst.ip = orig_t->dst.ip; -+ inv_t.src.u.gre.key = htonl(nat_pptp_info->pns_call_id); -+ inv_t.dst.u.gre.key = htonl(ct_pptp_info->pac_call_id); -+ } -+ -+ if (!ip_conntrack_change_expect(oldexp, &t)) { -+ DEBUGP("successfully changed expect\n"); -+ } else { -+ DEBUGP("can't change expect\n"); -+ } -+ if (oldexp->proto.gre.keymap_orig) -+ ip_ct_gre_keymap_change(oldexp->proto.gre.keymap_orig, -+ &t); -+ if (oldexp->proto.gre.keymap_reply) -+ ip_ct_gre_keymap_change(oldexp->proto.gre.keymap_reply, -+ &inv_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; -+ case PPTP_CALL_DISCONNECT_NOTIFY: -+ pcid = &pptpReq.disc->callID; -+ break; -+ case PPTP_SET_LINK_INFO: -+ pcid = &pptpReq.setlink->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_STOP_SESSION_REPLY: -+ 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)); -+ ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, (void *)pcid - (void *)pptph, -+ sizeof(new_pcid), (char *)&new_pcid, -+ sizeof(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)); -+ ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, -+ (void *)cid - (void *)pptph, -+ sizeof(new_cid), (char *)&new_cid, -+ sizeof(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; -+ -+ int dir; -+ -+ DEBUGP("entering\n"); -+ -+ /* Only mangle things once: DST for original direction -+ and SRC for reply direction. */ -+ dir = CTINFO2DIR(ctinfo); -+ if (!((HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC -+ && dir == IP_CT_DIR_ORIGINAL) -+ || (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST -+ && 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" -+ : hooknum == NF_IP_LOCAL_IN ? "INPUT" : "???"); -+ 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); -+ -+ /* if it's not a control message, we can't handle it */ -+ if (ntohs(pptph->packetType) != PPTP_PACKET_CONTROL || -+ ntohl(pptph->magicCookie) != PPTP_MAGIC_COOKIE) { -+ DEBUGP("not a pptp control packet\n"); -+ return NF_ACCEPT; -+ } -+ -+ LOCK_BH(&ip_pptp_lock); -+ -+ if (dir == IP_CT_DIR_ORIGINAL) { -+ /* reuqests sent by client to server (PNS->PAC) */ -+ pptp_outbound_pkt(pskb, ct, ctinfo, exp); -+ } else { -+ /* response from the server to the client (PAC->PNS) */ -+ pptp_inbound_pkt(pskb, 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 = { -+ .list = { NULL, NULL }, -+ .name = "pptp", -+ .flags = IP_NAT_HELPER_F_ALWAYS, -+ .me = THIS_MODULE, -+ .tuple = { .src = { .ip = 0, -+ .u = { .tcp = { .port = -+ __constant_htons(PPTP_CONTROL_PORT) } -+ } -+ }, -+ .dst = { .ip = 0, -+ .u = { .all = 0 }, -+ .protonum = IPPROTO_TCP -+ } -+ }, -+ -+ .mask = { .src = { .ip = 0, -+ .u = { .tcp = { .port = 0xFFFF } } -+ }, -+ .dst = { .ip = 0, -+ .u = { .all = 0 }, -+ .protonum = 0xFFFF -+ } -+ }, -+ .help = tcp_help, -+ .expect = pptp_nat_expected -+}; -+ -+ -+static int __init init(void) -+{ -+ DEBUGP("%s: registering NAT helper\n", __FILE__); -+ if (ip_nat_helper_register(&pptp_tcp_helper)) { -+ printk(KERN_ERR "Unable to register NAT application helper " -+ "for pptp\n"); -+ return -EIO; -+ } -+ -+ printk("ip_nat_pptp version %s loaded\n", IP_NAT_PPTP_VERSION); -+ return 0; -+} -+ -+static void __exit fini(void) -+{ -+ DEBUGP("cleanup_module\n" ); -+ ip_nat_helper_unregister(&pptp_tcp_helper); -+ printk("ip_nat_pptp version %s unloaded\n", IP_NAT_PPTP_VERSION); -+} -+ -+module_init(init); -+module_exit(fini); ---- /dev/null -+++ b/net/ipv4/netfilter/ip_nat_proto_gre.c -@@ -0,0 +1,202 @@ -+/* -+ * ip_nat_proto_gre.c - Version 1.2 -+ * -+ * 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-2003 by Harald Welte -+ * -+ * Development of this code funded by Astaro AG (http://www.astaro.com/) -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Harald Welte "); -+MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE"); -+ -+#if 0 -+#define DEBUGP(format, args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__ \ -+ ": " format, ## args) -+#else -+#define DEBUGP(x, args...) -+#endif -+ -+/* 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) -+{ -+ u_int32_t key; -+ -+ if (maniptype == IP_NAT_MANIP_SRC) -+ key = tuple->src.u.gre.key; -+ else -+ key = tuple->dst.u.gre.key; -+ -+ return ntohl(key) >= ntohl(min->gre.key) -+ && ntohl(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)) { -+ -+ DEBUGP("%p: NATing GRE PPTP\n", conntrack); -+ min = 1; -+ range_size = 0xffff; -+ -+ } 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) { -+ /* FIXME: Never tested this code... */ -+ *(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->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); ---- a/net/ipv4/netfilter/Makefile -+++ b/net/ipv4/netfilter/Makefile -@@ -36,23 +36,32 @@ obj-$(CONFIG_IP_NF_AMANDA) += ip_conntra - ifdef CONFIG_IP_NF_AMANDA - export-objs += ip_conntrack_amanda.o - endif -- - obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o - obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o - ifdef CONFIG_IP_NF_FTP - export-objs += ip_conntrack_ftp.o - endif -- - obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o - ifdef CONFIG_IP_NF_IRC - export-objs += ip_conntrack_irc.o - endif -+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 -+obj-$(CONFIG_IP_NF_PPTP) += ip_conntrack_pptp.o -+ifdef CONFIG_IP_NF_NAT_PPTP -+ export-objs += ip_conntrack_pptp.o -+endif -+ - - # NAT helpers - obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.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_PROTO_GRE) += ip_nat_proto_gre.o -+obj-$(CONFIG_IP_NF_NAT_PPTP) += ip_nat_pptp.o - - # generic IP tables - obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o ---- /dev/null -+++ b/net/ipv4/netfilter/ip_conntrack_pptp.c -@@ -0,0 +1,635 @@ -+/* -+ * ip_conntrack_pptp.c - Version 1.9 -+ * -+ * 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-2003 by Harald Welte -+ * -+ * 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 -+ * -+ * Changes: -+ * 2002-02-05 - Version 1.3 -+ * - Call ip_conntrack_unexpect_related() from -+ * pptp_timeout_related() to destroy expectations in case -+ * CALL_DISCONNECT_NOTIFY or tcp fin packet was seen -+ * (Philip Craig ) -+ * - Add Version information at module loadtime -+ * 2002-02-10 - Version 1.6 -+ * - move to C99 style initializers -+ * - remove second expectation if first arrives -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#define IP_CT_PPTP_VERSION "1.9" -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Harald Welte "); -+MODULE_DESCRIPTION("Netfilter connection tracking helper module for PPTP"); -+ -+DECLARE_LOCK(ip_pptp_lock); -+ -+#if 0 -+#include "ip_conntrack_pptp_priv.h" -+#define DEBUGP(format, args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__ \ -+ ": " format, ## args) -+#else -+#define DEBUGP(format, args...) -+#endif -+ -+#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 *master; -+ struct ip_conntrack_expect *exp; -+ -+ 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; -+ } -+ -+ exp = ct->master; -+ if (!exp) { -+ DEBUGP("no expectation!!\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.pac_call_id); -+ } -+ -+ /* delete other expectation */ -+ if (exp->expected_list.next != &exp->expected_list) { -+ struct ip_conntrack_expect *other_exp; -+ struct list_head *cur_item, *next; -+ -+ for (cur_item = master->sibling_list.next; -+ cur_item != &master->sibling_list; cur_item = next) { -+ next = cur_item->next; -+ other_exp = list_entry(cur_item, -+ struct ip_conntrack_expect, -+ expected_list); -+ /* remove only if occurred at same sequence number */ -+ if (other_exp != exp && other_exp->seq == exp->seq) { -+ DEBUGP("unexpecting other direction\n"); -+ ip_ct_gre_keymap_destroy(other_exp); -+ ip_conntrack_unexpect_related(other_exp); -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+/* timeout GRE data connections */ -+static int pptp_timeout_related(struct ip_conntrack *ct) -+{ -+ struct list_head *cur_item, *next; -+ struct ip_conntrack_expect *exp; -+ enum ip_conntrack_info ctinfo; -+ struct iphdr *iph; -+ -+ /* FIXME: do we have to lock something ? */ -+ for (cur_item = ct->sibling_list.next; -+ cur_item != &ct->sibling_list; cur_item = next) { -+ next = cur_item->next; -+ exp = list_entry(cur_item, struct ip_conntrack_expect, -+ expected_list); -+ -+ ip_ct_gre_keymap_destroy(exp); -+ if (!exp->sibling) { -+ ip_conntrack_unexpect_related(exp); -+ 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_acct(exp->sibling, ctinfo, iph, 0); -+ } -+ -+ return 0; -+} -+ -+/* expect GRE connections (PNS->PAC and PAC->PNS 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, PNS->PAC */ -+ 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.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.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 */ -+ if (ip_ct_gre_keymap_add(&exp, &exp.tuple, 0) != 0) -+ return 1; -+ -+ invert_tuplepr(&inv_tuple, &exp.tuple); -+ if (ip_ct_gre_keymap_add(&exp, &inv_tuple, 1) != 0) { -+ ip_ct_gre_keymap_destroy(&exp); -+ return 1; -+ } -+ -+ if (ip_conntrack_expect_related(master, &exp) != 0) { -+ ip_ct_gre_keymap_destroy(&exp); -+ DEBUGP("cannot expect_related()\n"); -+ return 1; -+ } -+ -+ /* tuple in reply direction, PAC->PNS */ -+ exp.tuple.src.ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip; -+ exp.tuple.src.u.gre.key = htonl(ntohs(callid)); -+ exp.tuple.dst.ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; -+ exp.tuple.dst.u.gre.key = htonl(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); -+ /* FIXME: cannot handle error correctly, since we need to free -+ * the above keymap :( */ -+ -+ if (ip_conntrack_expect_related(master, &exp) != 0) { -+ /* free the second pair of keypmaps */ -+ ip_ct_gre_keymap_destroy(&exp); -+ DEBUGP("cannot expect_related():\n"); -+ return 1; -+ } -+ -+ 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); -+ if (exp_gre(ct, seq, *cid, *pcid) != 0) -+ printk("ip_conntrack_pptp: error during exp_gre\n"); -+ 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); -+ if (exp_gre(ct, seq, *cid, *pcid) != 0) -+ printk("ip_conntrack_pptp: error during exp_gre\n"); -+ -+ 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); -+ 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"); -+ /* W2K PPTP server sends TCP packets with wrong checksum :(( */ -+ //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); -+ } -+ -+ -+ 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); -+ -+ /* FIXME: We just blindly assume that the control connection is always -+ * established from PNS->PAC. However, RFC makes no guarantee */ -+ 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 = { -+ .list = { NULL, NULL }, -+ .name = "pptp", -+ .flags = IP_CT_HELPER_F_REUSE_EXPECT, -+ .me = THIS_MODULE, -+ .max_expected = 2, -+ .timeout = 0, -+ .tuple = { .src = { .ip = 0, -+ .u = { .tcp = { .port = -+ __constant_htons(PPTP_CONTROL_PORT) } } -+ }, -+ .dst = { .ip = 0, -+ .u = { .all = 0 }, -+ .protonum = IPPROTO_TCP -+ } -+ }, -+ .mask = { .src = { .ip = 0, -+ .u = { .tcp = { .port = 0xffff } } -+ }, -+ .dst = { .ip = 0, -+ .u = { .all = 0 }, -+ .protonum = 0xffff -+ } -+ }, -+ .help = 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; -+ } -+ -+ printk("ip_conntrack_pptp version %s loaded\n", IP_CT_PPTP_VERSION); -+ return 0; -+} -+ -+static void __exit fini(void) -+{ -+ ip_conntrack_helper_unregister(&pptp); -+ printk("ip_conntrack_pptp version %s unloaded\n", IP_CT_PPTP_VERSION); -+} -+ -+module_init(init); -+module_exit(fini); -+ -+EXPORT_SYMBOL(ip_pptp_lock); diff --git a/target/linux/generic-2.4/patches/606-netfilter_NETMAP.patch b/target/linux/generic-2.4/patches/606-netfilter_NETMAP.patch index f7be0727ef..5382ef166c 100644 --- a/target/linux/generic-2.4/patches/606-netfilter_NETMAP.patch +++ b/target/linux/generic-2.4/patches/606-netfilter_NETMAP.patch @@ -1,6 +1,8 @@ ---- a/Documentation/Configure.help -+++ b/Documentation/Configure.help -@@ -3086,6 +3086,17 @@ CONFIG_IP_NF_TARGET_REDIRECT +Index: linux-2.4.35.4/Documentation/Configure.help +=================================================================== +--- linux-2.4.35.4.orig/Documentation/Configure.help 2009-06-06 21:50:40.000000000 +0000 ++++ linux-2.4.35.4/Documentation/Configure.help 2009-06-06 21:59:29.000000000 +0000 +@@ -3086,6 +3086,17 @@ If you want to compile it as a module, say M here and read . If unsure, say `N'. @@ -18,18 +20,22 @@ Packet mangling CONFIG_IP_NF_MANGLE This option adds a `mangle' table to iptables: see the man page for ---- a/net/ipv4/netfilter/Config.in -+++ b/net/ipv4/netfilter/Config.in -@@ -65,6 +65,7 @@ if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; +Index: linux-2.4.35.4/net/ipv4/netfilter/Config.in +=================================================================== +--- linux-2.4.35.4.orig/net/ipv4/netfilter/Config.in 2009-06-06 21:50:40.000000000 +0000 ++++ linux-2.4.35.4/net/ipv4/netfilter/Config.in 2009-06-06 22:04:39.000000000 +0000 +@@ -63,6 +63,7 @@ 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 ' NETMAP target support' CONFIG_IP_NF_TARGET_NETMAP $CONFIG_IP_NF_NAT - if [ "$CONFIG_IP_NF_PPTP" = "m" ]; then - define_tristate CONFIG_IP_NF_NAT_PPTP m + if [ "$CONFIG_IP_NF_AMANDA" = "m" ]; then + define_tristate CONFIG_IP_NF_NAT_AMANDA m else ---- /dev/null -+++ b/net/ipv4/netfilter/ipt_NETMAP.c +Index: linux-2.4.35.4/net/ipv4/netfilter/ipt_NETMAP.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.4.35.4/net/ipv4/netfilter/ipt_NETMAP.c 2009-06-06 21:59:29.000000000 +0000 @@ -0,0 +1,112 @@ +/* NETMAP - static NAT mapping of IP network addresses (1:1). + The mapping can be applied to source (POSTROUTING), @@ -143,9 +149,11 @@ + +module_init(init); +module_exit(fini); ---- a/net/ipv4/netfilter/Makefile -+++ b/net/ipv4/netfilter/Makefile -@@ -107,6 +107,7 @@ obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_D +Index: linux-2.4.35.4/net/ipv4/netfilter/Makefile +=================================================================== +--- linux-2.4.35.4.orig/net/ipv4/netfilter/Makefile 2009-06-06 21:50:40.000000000 +0000 ++++ linux-2.4.35.4/net/ipv4/netfilter/Makefile 2009-06-06 21:59:29.000000000 +0000 +@@ -98,6 +98,7 @@ obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o diff --git a/target/linux/generic-2.4/patches/610-netfilter_connbytes.patch b/target/linux/generic-2.4/patches/610-netfilter_connbytes.patch index 99f81c1665..a0f47bf43c 100644 --- a/target/linux/generic-2.4/patches/610-netfilter_connbytes.patch +++ b/target/linux/generic-2.4/patches/610-netfilter_connbytes.patch @@ -1,17 +1,21 @@ ---- a/net/ipv4/netfilter/Config.in -+++ b/net/ipv4/netfilter/Config.in -@@ -11,6 +11,8 @@ if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; +Index: linux-2.4.35.4/net/ipv4/netfilter/Config.in +=================================================================== +--- linux-2.4.35.4.orig/net/ipv4/netfilter/Config.in 2009-06-06 22:06:27.000000000 +0000 ++++ linux-2.4.35.4/net/ipv4/netfilter/Config.in 2009-06-06 22:09:23.000000000 +0000 +@@ -11,6 +11,8 @@ dep_tristate ' Amanda protocol support' CONFIG_IP_NF_AMANDA $CONFIG_IP_NF_CONNTRACK dep_tristate ' TFTP protocol support' CONFIG_IP_NF_TFTP $CONFIG_IP_NF_CONNTRACK dep_tristate ' IRC protocol support' CONFIG_IP_NF_IRC $CONFIG_IP_NF_CONNTRACK + dep_tristate ' Connection tracking flow accounting' CONFIG_IP_NF_CT_ACCT $CONFIG_IP_NF_CONNTRACK + dep_tristate ' Connection byte counter support' CONFIG_IP_NF_MATCH_CONNBYTES $CONFIG_IP_NF_CT_ACCT $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES - 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 ---- a/net/ipv4/netfilter/Makefile -+++ b/net/ipv4/netfilter/Makefile -@@ -106,6 +106,7 @@ obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_ + + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then +Index: linux-2.4.35.4/net/ipv4/netfilter/Makefile +=================================================================== +--- linux-2.4.35.4.orig/net/ipv4/netfilter/Makefile 2009-06-06 22:06:27.000000000 +0000 ++++ linux-2.4.35.4/net/ipv4/netfilter/Makefile 2009-06-06 22:06:48.000000000 +0000 +@@ -97,6 +97,7 @@ obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o @@ -19,9 +23,11 @@ obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o ---- a/net/ipv4/netfilter/ip_conntrack_amanda.c -+++ b/net/ipv4/netfilter/ip_conntrack_amanda.c -@@ -75,7 +75,7 @@ static int help(const struct iphdr *iph, +Index: linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_amanda.c +=================================================================== +--- linux-2.4.35.4.orig/net/ipv4/netfilter/ip_conntrack_amanda.c 2009-06-06 21:47:31.000000000 +0000 ++++ linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_amanda.c 2009-06-06 22:06:48.000000000 +0000 +@@ -75,7 +75,7 @@ /* increase the UDP timeout of the master connection as replies from * Amanda clients to the server can be quite delayed */ @@ -30,9 +36,11 @@ /* Search for "CONNECT " string */ do { ---- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c -+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c -@@ -211,7 +211,7 @@ static int tcp_packet(struct ip_conntrac +Index: linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +=================================================================== +--- linux-2.4.35.4.orig/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2009-06-06 21:47:31.000000000 +0000 ++++ linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2009-06-06 22:06:48.000000000 +0000 +@@ -211,7 +211,7 @@ set_bit(IPS_ASSURED_BIT, &conntrack->status); WRITE_UNLOCK(&tcp_lock); @@ -41,9 +49,11 @@ } return NF_ACCEPT; ---- a/net/ipv4/netfilter/ip_conntrack_proto_udp.c -+++ b/net/ipv4/netfilter/ip_conntrack_proto_udp.c -@@ -47,16 +47,16 @@ static unsigned int udp_print_conntrack( +Index: linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_udp.c +=================================================================== +--- linux-2.4.35.4.orig/net/ipv4/netfilter/ip_conntrack_proto_udp.c 2009-06-06 21:47:31.000000000 +0000 ++++ linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_udp.c 2009-06-06 22:06:48.000000000 +0000 +@@ -47,16 +47,16 @@ /* Returns verdict for packet, and may modify conntracktype */ static int udp_packet(struct ip_conntrack *conntrack, struct iphdr *iph, size_t len, @@ -63,9 +73,11 @@ return NF_ACCEPT; } ---- a/net/ipv4/netfilter/ip_conntrack_standalone.c -+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c -@@ -79,6 +79,18 @@ print_expect(char *buffer, const struct +Index: linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_standalone.c +=================================================================== +--- linux-2.4.35.4.orig/net/ipv4/netfilter/ip_conntrack_standalone.c 2009-06-06 22:06:24.000000000 +0000 ++++ linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_standalone.c 2009-06-06 22:06:48.000000000 +0000 +@@ -79,6 +79,18 @@ return len; } @@ -84,7 +96,7 @@ static unsigned int print_conntrack(char *buffer, struct ip_conntrack *conntrack) { -@@ -98,11 +110,15 @@ print_conntrack(char *buffer, struct ip_ +@@ -98,11 +110,15 @@ len += print_tuple(buffer + len, &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple, proto); @@ -100,7 +112,7 @@ if (test_bit(IPS_ASSURED_BIT, &conntrack->status)) len += sprintf(buffer + len, "[ASSURED] "); len += sprintf(buffer + len, "use=%u ", -@@ -478,7 +494,7 @@ EXPORT_SYMBOL(ip_conntrack_get); +@@ -478,7 +494,7 @@ EXPORT_SYMBOL(ip_conntrack_helper_register); EXPORT_SYMBOL(ip_conntrack_helper_unregister); EXPORT_SYMBOL(ip_ct_iterate_cleanup); @@ -109,9 +121,11 @@ EXPORT_SYMBOL(ip_ct_find_proto); EXPORT_SYMBOL(__ip_ct_find_proto); EXPORT_SYMBOL(ip_ct_find_helper); ---- a/net/ipv4/netfilter/ip_conntrack_proto_generic.c -+++ b/net/ipv4/netfilter/ip_conntrack_proto_generic.c -@@ -41,9 +41,9 @@ static unsigned int generic_print_conntr +Index: linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_generic.c +=================================================================== +--- linux-2.4.35.4.orig/net/ipv4/netfilter/ip_conntrack_proto_generic.c 2009-06-06 21:47:31.000000000 +0000 ++++ linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_generic.c 2009-06-06 22:06:48.000000000 +0000 +@@ -41,9 +41,9 @@ /* Returns verdict for packet, or -1 for invalid. */ static int established(struct ip_conntrack *conntrack, struct iphdr *iph, size_t len, @@ -123,9 +137,11 @@ return NF_ACCEPT; } ---- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c -+++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c -@@ -82,7 +82,7 @@ static int icmp_packet(struct ip_conntra +Index: linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_icmp.c +=================================================================== +--- linux-2.4.35.4.orig/net/ipv4/netfilter/ip_conntrack_proto_icmp.c 2009-06-06 21:47:31.000000000 +0000 ++++ linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_icmp.c 2009-06-06 22:06:48.000000000 +0000 +@@ -82,7 +82,7 @@ ct->timeout.function((unsigned long)ct); } else { atomic_inc(&ct->proto.icmp.count); @@ -134,9 +150,11 @@ } return NF_ACCEPT; ---- a/net/ipv4/netfilter/ip_conntrack_core.c -+++ b/net/ipv4/netfilter/ip_conntrack_core.c -@@ -1196,22 +1196,40 @@ void ip_conntrack_helper_unregister(stru +Index: linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_core.c +=================================================================== +--- linux-2.4.35.4.orig/net/ipv4/netfilter/ip_conntrack_core.c 2009-06-06 22:06:24.000000000 +0000 ++++ linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_core.c 2009-06-06 22:06:48.000000000 +0000 +@@ -1193,22 +1193,40 @@ MOD_DEC_USE_COUNT; } @@ -180,9 +198,11 @@ } WRITE_UNLOCK(&ip_conntrack_lock); } ---- a/include/linux/netfilter_ipv4/ip_conntrack.h -+++ b/include/linux/netfilter_ipv4/ip_conntrack.h -@@ -164,6 +164,12 @@ struct ip_conntrack_expect +Index: linux-2.4.35.4/include/linux/netfilter_ipv4/ip_conntrack.h +=================================================================== +--- linux-2.4.35.4.orig/include/linux/netfilter_ipv4/ip_conntrack.h 2009-06-06 22:06:24.000000000 +0000 ++++ linux-2.4.35.4/include/linux/netfilter_ipv4/ip_conntrack.h 2009-06-06 22:06:48.000000000 +0000 +@@ -156,6 +156,12 @@ union ip_conntrack_expect_help help; }; @@ -195,7 +215,7 @@ struct ip_conntrack_helper; struct ip_conntrack -@@ -181,6 +187,12 @@ struct ip_conntrack +@@ -173,6 +179,12 @@ /* Timer function; drops refcnt when it goes off. */ struct timer_list timeout; @@ -208,7 +228,7 @@ /* If we're expecting another related connection, this will be in expected linked list */ struct list_head sibling_list; -@@ -264,8 +276,10 @@ extern int invert_tuplepr(struct ip_conn +@@ -256,8 +268,10 @@ const struct ip_conntrack_tuple *orig); /* Refresh conntrack for this many jiffies */ @@ -221,8 +241,10 @@ /* These are for NAT. Icky. */ /* Call me when a conntrack is destroyed. */ ---- /dev/null -+++ b/net/ipv4/netfilter/ipt_connbytes.c +Index: linux-2.4.35.4/net/ipv4/netfilter/ipt_connbytes.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.4.35.4/net/ipv4/netfilter/ipt_connbytes.c 2009-06-06 22:06:48.000000000 +0000 @@ -0,0 +1,163 @@ +/* Kernel module to match connection tracking byte counter. + * GPL (C) 2002 Martin Devera (devik@cdi.cz). @@ -387,8 +409,10 @@ +module_init(init); +module_exit(fini); +MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ipt_connbytes.h +Index: linux-2.4.35.4/include/linux/netfilter_ipv4/ipt_connbytes.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.4.35.4/include/linux/netfilter_ipv4/ipt_connbytes.h 2009-06-06 22:06:48.000000000 +0000 @@ -0,0 +1,25 @@ +#ifndef _IPT_CONNBYTES_H +#define _IPT_CONNBYTES_H @@ -415,25 +439,3 @@ +}; + +#endif ---- a/net/ipv4/netfilter/ip_conntrack_proto_gre.c -+++ b/net/ipv4/netfilter/ip_conntrack_proto_gre.c -@@ -237,16 +237,16 @@ static unsigned int gre_print_conntrack( - /* 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) -+ enum ip_conntrack_info ctinfo) - { - /* If we've seen traffic both ways, this is a GRE connection. - * Extend timeout. */ - if (ct->status & IPS_SEEN_REPLY) { -- ip_ct_refresh_acct(ct, ct->proto.gre.stream_timeout); -+ ip_ct_refresh_acct(ct, ctinfo, iph, 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_acct(ct, ct->proto.gre.timeout); -+ ip_ct_refresh_acct(ct, ctinfo, iph, ct->proto.gre.timeout); - - return NF_ACCEPT; - } diff --git a/target/linux/generic-2.4/patches/613-netfilter_nat_h323.patch b/target/linux/generic-2.4/patches/613-netfilter_nat_h323.patch index cb23abde6d..7793cbcb81 100644 --- a/target/linux/generic-2.4/patches/613-netfilter_nat_h323.patch +++ b/target/linux/generic-2.4/patches/613-netfilter_nat_h323.patch @@ -1,14 +1,16 @@ ---- a/net/ipv4/netfilter/Config.in -+++ b/net/ipv4/netfilter/Config.in -@@ -15,6 +15,7 @@ if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; +Index: linux-2.4.35.4/net/ipv4/netfilter/Config.in +=================================================================== +--- linux-2.4.35.4.orig/net/ipv4/netfilter/Config.in 2009-06-06 22:34:34.000000000 +0000 ++++ linux-2.4.35.4/net/ipv4/netfilter/Config.in 2009-06-06 22:37:34.000000000 +0000 +@@ -13,6 +13,7 @@ + dep_tristate ' IRC protocol support' CONFIG_IP_NF_IRC $CONFIG_IP_NF_CONNTRACK + dep_tristate ' Connection tracking flow accounting' CONFIG_IP_NF_CT_ACCT $CONFIG_IP_NF_CONNTRACK dep_tristate ' Connection byte counter support' CONFIG_IP_NF_MATCH_CONNBYTES $CONFIG_IP_NF_CT_ACCT $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES - 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 + dep_tristate ' H.323 (netmeeting) support' CONFIG_IP_NF_H323 $CONFIG_IP_NF_CONNTRACK fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -@@ -110,6 +111,13 @@ if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; +@@ -94,6 +95,13 @@ define_tristate CONFIG_IP_NF_NAT_AMANDA $CONFIG_IP_NF_NAT fi fi @@ -22,29 +24,32 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then dep_tristate ' Basic SNMP-ALG support (EXPERIMENTAL)' CONFIG_IP_NF_NAT_SNMP_BASIC $CONFIG_IP_NF_NAT fi ---- a/net/ipv4/netfilter/Makefile -+++ b/net/ipv4/netfilter/Makefile -@@ -53,6 +53,10 @@ obj-$(CONFIG_IP_NF_PPTP) += ip_conntrack - ifdef CONFIG_IP_NF_NAT_PPTP - export-objs += ip_conntrack_pptp.o +Index: linux-2.4.35.4/net/ipv4/netfilter/Makefile +=================================================================== +--- linux-2.4.35.4.orig/net/ipv4/netfilter/Makefile 2009-06-06 22:34:34.000000000 +0000 ++++ linux-2.4.35.4/net/ipv4/netfilter/Makefile 2009-06-06 22:46:32.000000000 +0000 +@@ -47,12 +47,17 @@ + ifdef CONFIG_IP_NF_IRC + export-objs += ip_conntrack_irc.o endif +obj-$(CONFIG_IP_NF_H323) += ip_conntrack_h323.o +ifdef CONFIG_IP_NF_NAT_H323 + export-objs += ip_conntrack_h323.o +endif - # NAT helpers -@@ -62,6 +66,7 @@ obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ft + obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.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_PROTO_GRE) += ip_nat_proto_gre.o - obj-$(CONFIG_IP_NF_NAT_PPTP) += ip_nat_pptp.o +obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o # generic IP tables obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o ---- /dev/null -+++ b/net/ipv4/netfilter/ip_conntrack_h323.c +Index: linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_h323.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_h323.c 2009-06-06 22:34:50.000000000 +0000 @@ -0,0 +1,302 @@ +/* + * H.323 'brute force' extension for H.323 connection tracking. @@ -348,8 +353,10 @@ + +module_init(init); +module_exit(fini); ---- /dev/null -+++ b/net/ipv4/netfilter/ip_nat_h323.c +Index: linux-2.4.35.4/net/ipv4/netfilter/ip_nat_h323.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.4.35.4/net/ipv4/netfilter/ip_nat_h323.c 2009-06-06 22:34:50.000000000 +0000 @@ -0,0 +1,403 @@ +/* + * H.323 'brute force' extension for NAT alteration. @@ -754,34 +761,38 @@ + +module_init(init); +module_exit(fini); ---- a/include/linux/netfilter_ipv4/ip_conntrack.h -+++ b/include/linux/netfilter_ipv4/ip_conntrack.h -@@ -71,6 +71,7 @@ union ip_conntrack_expect_proto { +Index: linux-2.4.35.4/include/linux/netfilter_ipv4/ip_conntrack.h +=================================================================== +--- linux-2.4.35.4.orig/include/linux/netfilter_ipv4/ip_conntrack.h 2009-06-06 22:06:48.000000000 +0000 ++++ linux-2.4.35.4/include/linux/netfilter_ipv4/ip_conntrack.h 2009-06-06 22:53:09.000000000 +0000 +@@ -67,6 +67,7 @@ + #include #include - #include +#include /* per expectation: application helper private data */ union ip_conntrack_expect_help { -@@ -79,6 +80,7 @@ union ip_conntrack_expect_help { +@@ -74,6 +75,7 @@ + struct ip_ct_amanda_expect exp_amanda_info; struct ip_ct_ftp_expect exp_ftp_info; struct ip_ct_irc_expect exp_irc_info; - struct ip_ct_pptp_expect exp_pptp_info; + struct ip_ct_h225_expect exp_h225_info; #ifdef CONFIG_IP_NF_NAT_NEEDED union { -@@ -93,6 +95,7 @@ union ip_conntrack_help { +@@ -87,6 +89,7 @@ + /* insert conntrack helper private data (master) here */ struct ip_ct_ftp_master ct_ftp_info; struct ip_ct_irc_master ct_irc_info; - struct ip_ct_pptp_master ct_pptp_info; + struct ip_ct_h225_master ct_h225_info; }; #ifdef CONFIG_IP_NF_NAT_NEEDED ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ip_conntrack_h323.h +Index: linux-2.4.35.4/include/linux/netfilter_ipv4/ip_conntrack_h323.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.4.35.4/include/linux/netfilter_ipv4/ip_conntrack_h323.h 2009-06-06 22:34:50.000000000 +0000 @@ -0,0 +1,30 @@ +#ifndef _IP_CONNTRACK_H323_H +#define _IP_CONNTRACK_H323_H diff --git a/target/linux/generic-2.4/patches/625-netfilter_nat_pptp_fix.patch b/target/linux/generic-2.4/patches/625-netfilter_nat_pptp_fix.patch deleted file mode 100644 index c65c9614d7..0000000000 --- a/target/linux/generic-2.4/patches/625-netfilter_nat_pptp_fix.patch +++ /dev/null @@ -1,53 +0,0 @@ ---- a/net/ipv4/netfilter/ip_conntrack_pptp.c -+++ b/net/ipv4/netfilter/ip_conntrack_pptp.c -@@ -134,12 +134,11 @@ static int pptp_expectfn(struct ip_connt - } - - /* timeout GRE data connections */ --static int pptp_timeout_related(struct ip_conntrack *ct) -+static int pptp_timeout_related(struct ip_conntrack *ct, const struct iphdr *iph) - { - struct list_head *cur_item, *next; - struct ip_conntrack_expect *exp; - enum ip_conntrack_info ctinfo; -- struct iphdr *iph; - - /* FIXME: do we have to lock something ? */ - for (cur_item = ct->sibling_list.next; -@@ -245,7 +244,8 @@ pptp_inbound_pkt(struct tcphdr *tcph, - struct pptp_pkt_hdr *pptph, - size_t datalen, - struct ip_conntrack *ct, -- enum ip_conntrack_info ctinfo) -+ enum ip_conntrack_info ctinfo, -+ const struct iphdr *iph) - { - struct PptpControlHeader *ctlh; - union pptp_ctrl_union pptpReq; -@@ -377,7 +377,7 @@ pptp_inbound_pkt(struct tcphdr *tcph, - info->cstate = PPTP_CALL_NONE; - - /* untrack this call id, unexpect GRE packets */ -- pptp_timeout_related(ct); -+ pptp_timeout_related(ct, iph); - break; - - case PPTP_WAN_ERROR_NOTIFY: -@@ -539,7 +539,7 @@ conntrack_pptp_help(const struct iphdr * - info->cstate = PPTP_CALL_NONE; - - /* untrack this call id, unexpect GRE packets */ -- pptp_timeout_related(ct); -+ pptp_timeout_related(ct, iph); - } - - -@@ -571,7 +571,7 @@ conntrack_pptp_help(const struct iphdr * - ret = pptp_outbound_pkt(tcph, pptph, datalen, ct, ctinfo); - else - /* server -> client (PAC -> PNS) */ -- ret = pptp_inbound_pkt(tcph, pptph, datalen, ct, ctinfo); -+ ret = pptp_inbound_pkt(tcph, pptph, datalen, ct, ctinfo, iph); - DEBUGP("sstate: %d->%d, cstate: %d->%d\n", - oldsstate, info->sstate, oldcstate, info->cstate); - UNLOCK_BH(&ip_pptp_lock); -- 2.30.2