diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack.h --- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack.h 2003-08-12 07:43:11.000000000 -0400 +++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack.h 2004-05-09 04:13:03.000000000 -0400 @@ -45,39 +45,27 @@ #include #include -#include /* 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 -#include -#include - #include #include -#include /* 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 -#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 @@ -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 src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_h323.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_h323.h --- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_h323.h 2003-07-04 04:12:27.000000000 -0400 +++ src/linux/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 src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_mms.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_mms.h --- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_mms.h 2003-07-04 04:12:27.000000000 -0400 +++ src/linux/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 - -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 src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_pptp.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_pptp.h --- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_pptp.h 2003-07-04 04:12:27.000000000 -0400 +++ src/linux/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 -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 src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h --- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h 2003-07-04 04:12:27.000000000 -0400 +++ src/linux/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 - -/* 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__ - -/* 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 src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_tftp.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_tftp.h --- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_tftp.h 2003-07-04 04:12:27.000000000 -0400 +++ src/linux/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 src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_tuple.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_tuple.h --- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_tuple.h 2003-07-04 04:12:27.000000000 -0400 +++ src/linux/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 src/linux/linux/include/linux/netfilter_ipv4/ip_nat_pptp.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_nat_pptp.h --- src/linux/linux/include/linux/netfilter_ipv4/ip_nat_pptp.h 2003-07-04 04:12:27.000000000 -0400 +++ src/linux/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 src/linux/linux/include/linux/netfilter_ipv4/ip_pool.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_pool.h --- src/linux/linux/include/linux/netfilter_ipv4/ip_pool.h 2003-07-04 04:12:27.000000000 -0400 +++ src/linux/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 src/linux/linux/include/linux/netfilter_ipv4/ipt_pool.h src/linux/linux.stock/include/linux/netfilter_ipv4/ipt_pool.h --- src/linux/linux/include/linux/netfilter_ipv4/ipt_pool.h 2003-07-04 04:12:27.000000000 -0400 +++ src/linux/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 - -#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 src/linux/linux/net/ipv4/netfilter/Config.in src/linux/linux.stock/net/ipv4/netfilter/Config.in --- src/linux/linux/net/ipv4/netfilter/Config.in 2004-02-19 06:04:35.000000000 -0500 +++ src/linux/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 src/linux/linux/net/ipv4/netfilter/Makefile src/linux/linux.stock/net/ipv4/netfilter/Makefile --- src/linux/linux/net/ipv4/netfilter/Makefile 2004-02-19 06:04:35.000000000 -0500 +++ src/linux/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 src/linux/linux/net/ipv4/netfilter/ip_conntrack_core.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_core.c --- src/linux/linux/net/ipv4/netfilter/ip_conntrack_core.c 2003-08-12 07:33:45.000000000 -0400 +++ src/linux/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 src/linux/linux/net/ipv4/netfilter/ip_conntrack_ftp.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_ftp.c --- src/linux/linux/net/ipv4/netfilter/ip_conntrack_ftp.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/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 src/linux/linux/net/ipv4/netfilter/ip_conntrack_h323.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_h323.c --- src/linux/linux/net/ipv4/netfilter/ip_conntrack_h323.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/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 - * - * 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 -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Jozsef Kadlecsik "); -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 src/linux/linux/net/ipv4/netfilter/ip_conntrack_mms.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_mms.c --- src/linux/linux/net/ipv4/netfilter/ip_conntrack_mms.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/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 - * 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 - * - * 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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -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 "); -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 src/linux/linux/net/ipv4/netfilter/ip_conntrack_pptp.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_pptp.c --- src/linux/linux/net/ipv4/netfilter/ip_conntrack_pptp.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/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 , - * - * 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 -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Harald Welte "); -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 src/linux/linux/net/ipv4/netfilter/ip_conntrack_pptp_priv.h src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_pptp_priv.h --- src/linux/linux/net/ipv4/netfilter/ip_conntrack_pptp_priv.h 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/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 src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_gre.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_proto_gre.c --- src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_gre.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/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 - * - * 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) - -#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 src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_proto_tcp.c --- src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2003-08-12 07:33:45.000000000 -0400 +++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2004-05-09 04:13:03.000000000 -0400 @@ -15,11 +15,17 @@ #include #include +#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 src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_udp.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_proto_udp.c --- src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_udp.c 2003-08-12 07:33:45.000000000 -0400 +++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_proto_udp.c 2004-05-09 04:13:03.000000000 -0400 @@ -5,7 +5,9 @@ #include #include #include -#include + +#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 src/linux/linux/net/ipv4/netfilter/ip_conntrack_standalone.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_standalone.c --- src/linux/linux/net/ipv4/netfilter/ip_conntrack_standalone.c 2003-08-12 07:33:45.000000000 -0400 +++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-05-09 04:13:03.000000000 -0400 @@ -27,7 +27,11 @@ #include #include +#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 src/linux/linux/net/ipv4/netfilter/ip_conntrack_tftp.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_tftp.c --- src/linux/linux/net/ipv4/netfilter/ip_conntrack_tftp.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/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 - * Version: 0.0.7 - * - * Thu 21 Mar 2002 Harald Welte - * - port to newnat API - * - */ - -#include -#include -#include - -#include -#include -#include -#include - -MODULE_AUTHOR("Magnus Boden "); -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 src/linux/linux/net/ipv4/netfilter/ip_nat_core.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_core.c --- src/linux/linux/net/ipv4/netfilter/ip_nat_core.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_core.c 2004-05-09 04:13:03.000000000 -0400 @@ -31,7 +31,11 @@ #include #include +#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. */ IP_NF_ASSERT(ip_conntrack_destroyed == NULL); ip_conntrack_destroyed = &ip_nat_cleanup_conntrack; diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_nat_h323.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_h323.c --- src/linux/linux/net/ipv4/netfilter/ip_nat_h323.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/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 - * - * 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 -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Jozsef Kadlecsik "); -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<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 src/linux/linux/net/ipv4/netfilter/ip_nat_helper.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_helper.c --- src/linux/linux/net/ipv4/netfilter/ip_nat_helper.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/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 : * - merge SACK support into newnat API - * 16 Aug 2002 Brian J. Murrell : - * - make ip_nat_resize_packet more generic (TCP and UDP) - * - add ip_nat_mangle_udp_packet */ #include #include @@ -25,7 +22,6 @@ #include #include #include -#include #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 #include +#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 src/linux/linux/net/ipv4/netfilter/ip_nat_mms.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_mms.c --- src/linux/linux/net/ipv4/netfilter/ip_nat_mms.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/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 - * 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 - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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 "); -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; ipadding, 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; jpadding; ++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 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 src/linux/linux/net/ipv4/netfilter/ip_nat_pptp.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_pptp.c --- src/linux/linux/net/ipv4/netfilter/ip_nat_pptp.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/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 - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Harald Welte "); -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 src/linux/linux/net/ipv4/netfilter/ip_nat_proto_gre.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_proto_gre.c --- src/linux/linux/net/ipv4/netfilter/ip_nat_proto_gre.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/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 - * - * 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"); - -#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 src/linux/linux/net/ipv4/netfilter/ip_nat_standalone.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_standalone.c --- src/linux/linux/net/ipv4/netfilter/ip_nat_standalone.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_standalone.c 2004-05-09 04:13:03.000000000 -0400 @@ -37,7 +37,11 @@ #include #include +#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 src/linux/linux/net/ipv4/netfilter/ip_nat_tftp.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_tftp.c --- src/linux/linux/net/ipv4/netfilter/ip_nat_tftp.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/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 - * Version: 0.0.7 - * - * Thu 21 Mar 2002 Harald Welte - * - 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 -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Magnus Boden "); -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 src/linux/linux/net/ipv4/netfilter/ip_pool.c src/linux/linux.stock/net/ipv4/netfilter/ip_pool.c --- src/linux/linux/net/ipv4/netfilter/ip_pool.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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; imembers) - 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 #include +#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 src/linux/linux/net/ipv4/netfilter/ipchains_core.c src/linux/linux.stock/net/ipv4/netfilter/ipchains_core.c --- src/linux/linux/net/ipv4/netfilter/ipchains_core.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/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 src/linux/linux/net/ipv4/netfilter/ipfwadm_core.c src/linux/linux.stock/net/ipv4/netfilter/ipfwadm_core.c --- src/linux/linux/net/ipv4/netfilter/ipfwadm_core.c 2003-10-14 04:09:33.000000000 -0400 +++ src/linux/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 src/linux/linux/net/ipv4/netfilter/ipt_ECN.c src/linux/linux.stock/net/ipv4/netfilter/ipt_ECN.c --- src/linux/linux/net/ipv4/netfilter/ipt_ECN.c 2003-10-14 04:02:57.000000000 -0400 +++ src/linux/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 src/linux/linux/net/ipv4/netfilter/ipt_LOG.c src/linux/linux.stock/net/ipv4/netfilter/ipt_LOG.c --- src/linux/linux/net/ipv4/netfilter/ipt_LOG.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/linux.stock/net/ipv4/netfilter/ipt_LOG.c 2004-05-09 04:13:03.000000000 -0400 @@ -14,11 +14,15 @@ #include #include +#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 src/linux/linux/net/ipv4/netfilter/ipt_REJECT.c src/linux/linux.stock/net/ipv4/netfilter/ipt_REJECT.c --- src/linux/linux/net/ipv4/netfilter/ipt_REJECT.c 2003-07-04 04:12:31.000000000 -0400 +++ src/linux/linux.stock/net/ipv4/netfilter/ipt_REJECT.c 2004-05-09 04:13:03.000000000 -0400 @@ -6,8 +6,6 @@ #include #include #include -#include -#include #include #include #include @@ -16,7 +14,11 @@ #include #include +#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 src/linux/linux/net/ipv4/netfilter/ipt_ULOG.c src/linux/linux.stock/net/ipv4/netfilter/ipt_ULOG.c --- src/linux/linux/net/ipv4/netfilter/ipt_ULOG.c 2003-07-04 04:12:32.000000000 -0400 +++ src/linux/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 - * * 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 @@ -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 src/linux/linux/net/ipv4/netfilter/ipt_multiport.c src/linux/linux.stock/net/ipv4/netfilter/ipt_multiport.c --- src/linux/linux/net/ipv4/netfilter/ipt_multiport.c 2003-07-04 04:12:32.000000000 -0400 +++ src/linux/linux.stock/net/ipv4/netfilter/ipt_multiport.c 2004-05-09 04:13:03.000000000 -0400 @@ -8,7 +8,11 @@ #include #include +#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 src/linux/linux/net/ipv4/netfilter/ipt_pool.c src/linux/linux.stock/net/ipv4/netfilter/ipt_pool.c --- src/linux/linux/net/ipv4/netfilter/ipt_pool.c 2003-07-04 04:12:32.000000000 -0400 +++ src/linux/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 -#include -#include - -#include -#include -#include - -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 src/linux/linux/net/ipv6/mcast.c src/linux/linux.stock/net/ipv6/mcast.c --- src/linux/linux/net/ipv6/mcast.c 2003-10-14 04:09:34.000000000 -0400 +++ src/linux/linux.stock/net/ipv6/mcast.c 2004-05-09 04:13:22.000000000 -0400 @@ -5,7 +5,7 @@ * Authors: * Pedro Roque * - * $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 *