mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-11-11 08:14:05 +02:00
3ac1acb9ea
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@30 3c298f89-4303-0410-b956-a3cf2f4a3e73
5824 lines
177 KiB
Diff
5824 lines
177 KiB
Diff
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 <linux/netfilter_ipv4/ip_conntrack_tcp.h>
|
|
#include <linux/netfilter_ipv4/ip_conntrack_icmp.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
|
|
|
|
/* per conntrack: protocol private data */
|
|
union ip_conntrack_proto {
|
|
/* insert conntrack proto private data here */
|
|
- struct ip_ct_gre gre;
|
|
struct ip_ct_tcp tcp;
|
|
struct ip_ct_icmp icmp;
|
|
};
|
|
|
|
union ip_conntrack_expect_proto {
|
|
/* insert expect proto private data here */
|
|
- struct ip_ct_gre_expect gre;
|
|
};
|
|
|
|
/* Add protocol helper include file here */
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_mms.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
|
|
-
|
|
#include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
|
|
#include <linux/netfilter_ipv4/ip_conntrack_irc.h>
|
|
-#include <linux/netfilter_ipv4/ip_autofw.h>
|
|
|
|
/* per expectation: application helper private data */
|
|
union ip_conntrack_expect_help {
|
|
/* insert conntrack helper private data (expect) here */
|
|
- struct ip_ct_pptp_expect exp_pptp_info;
|
|
- struct ip_ct_mms_expect exp_mms_info;
|
|
- struct ip_ct_h225_expect exp_h225_info;
|
|
struct ip_ct_ftp_expect exp_ftp_info;
|
|
struct ip_ct_irc_expect exp_irc_info;
|
|
- struct ip_autofw_expect exp_autofw_info;
|
|
|
|
#ifdef CONFIG_IP_NF_NAT_NEEDED
|
|
union {
|
|
@@ -89,21 +77,16 @@
|
|
/* per conntrack: application helper private data */
|
|
union ip_conntrack_help {
|
|
/* insert conntrack helper private data (master) here */
|
|
- struct ip_ct_pptp_master ct_pptp_info;
|
|
- struct ip_ct_mms_master ct_mms_info;
|
|
- struct ip_ct_h225_master ct_h225_info;
|
|
struct ip_ct_ftp_master ct_ftp_info;
|
|
struct ip_ct_irc_master ct_irc_info;
|
|
};
|
|
|
|
#ifdef CONFIG_IP_NF_NAT_NEEDED
|
|
#include <linux/netfilter_ipv4/ip_nat.h>
|
|
-#include <linux/netfilter_ipv4/ip_nat_pptp.h>
|
|
|
|
/* per conntrack: nat application helper private data */
|
|
union ip_conntrack_nat_help {
|
|
/* insert nat helper private data here */
|
|
- struct ip_nat_pptp nat_pptp_info;
|
|
};
|
|
#endif
|
|
|
|
@@ -275,9 +258,5 @@
|
|
}
|
|
|
|
extern unsigned int ip_conntrack_htable_size;
|
|
-
|
|
-/* connection tracking time out variables. */
|
|
-extern int sysctl_ip_conntrack_tcp_timeouts[10];
|
|
-extern int sysctl_ip_conntrack_udp_timeouts[2];
|
|
#endif /* __KERNEL__ */
|
|
#endif /* _IP_CONNTRACK_H */
|
|
diff -Nurb 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 <linux/netfilter_ipv4/lockhelp.h>
|
|
-
|
|
-DECLARE_LOCK_EXTERN(ip_mms_lock);
|
|
-
|
|
-#define MMS_PORT 1755
|
|
-#define MMS_SRV_MSG_ID 196610
|
|
-
|
|
-#define MMS_SRV_MSG_OFFSET 36
|
|
-#define MMS_SRV_UNICODE_STRING_OFFSET 60
|
|
-#define MMS_SRV_CHUNKLENLV_OFFSET 16
|
|
-#define MMS_SRV_CHUNKLENLM_OFFSET 32
|
|
-#define MMS_SRV_MESSAGELENGTH_OFFSET 8
|
|
-#endif
|
|
-
|
|
-/* This structure is per expected connection */
|
|
-struct ip_ct_mms_expect {
|
|
- u_int32_t len;
|
|
- u_int32_t padding;
|
|
- u_int16_t port;
|
|
-};
|
|
-
|
|
-/* This structure exists only once per master */
|
|
-struct ip_ct_mms_master {
|
|
-};
|
|
-
|
|
-#endif /* _IP_CONNTRACK_MMS_H */
|
|
diff -Nurb 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 <linux/netfilter_ipv4/lockhelp.h>
|
|
-DECLARE_LOCK_EXTERN(ip_pptp_lock);
|
|
-
|
|
-#define IP_CONNTR_PPTP PPTP_CONTROL_PORT
|
|
-
|
|
-union pptp_ctrl_union {
|
|
- void *rawreq;
|
|
- struct PptpStartSessionRequest *sreq;
|
|
- struct PptpStartSessionReply *srep;
|
|
- struct PptpStopSessionReqest *streq;
|
|
- struct PptpStopSessionReply *strep;
|
|
- struct PptpOutCallRequest *ocreq;
|
|
- struct PptpOutCallReply *ocack;
|
|
- struct PptpInCallRequest *icreq;
|
|
- struct PptpInCallReply *icack;
|
|
- struct PptpInCallConnected *iccon;
|
|
- struct PptpClearCallRequest *clrreq;
|
|
- struct PptpCallDisconnectNotify *disc;
|
|
- struct PptpWanErrorNotify *wanerr;
|
|
- struct PptpSetLinkInfo *setlink;
|
|
-};
|
|
-
|
|
-
|
|
-
|
|
-#define PPTP_CONTROL_PORT 1723
|
|
-
|
|
-#define PPTP_PACKET_CONTROL 1
|
|
-#define PPTP_PACKET_MGMT 2
|
|
-
|
|
-#define PPTP_MAGIC_COOKIE 0x1a2b3c4d
|
|
-
|
|
-struct pptp_pkt_hdr {
|
|
- __u16 packetLength;
|
|
- __u16 packetType;
|
|
- __u32 magicCookie;
|
|
-};
|
|
-
|
|
-/* PptpControlMessageType values */
|
|
-#define PPTP_START_SESSION_REQUEST 1
|
|
-#define PPTP_START_SESSION_REPLY 2
|
|
-#define PPTP_STOP_SESSION_REQUEST 3
|
|
-#define PPTP_STOP_SESSION_REPLY 4
|
|
-#define PPTP_ECHO_REQUEST 5
|
|
-#define PPTP_ECHO_REPLY 6
|
|
-#define PPTP_OUT_CALL_REQUEST 7
|
|
-#define PPTP_OUT_CALL_REPLY 8
|
|
-#define PPTP_IN_CALL_REQUEST 9
|
|
-#define PPTP_IN_CALL_REPLY 10
|
|
-#define PPTP_IN_CALL_CONNECT 11
|
|
-#define PPTP_CALL_CLEAR_REQUEST 12
|
|
-#define PPTP_CALL_DISCONNECT_NOTIFY 13
|
|
-#define PPTP_WAN_ERROR_NOTIFY 14
|
|
-#define PPTP_SET_LINK_INFO 15
|
|
-
|
|
-#define PPTP_MSG_MAX 15
|
|
-
|
|
-/* PptpGeneralError values */
|
|
-#define PPTP_ERROR_CODE_NONE 0
|
|
-#define PPTP_NOT_CONNECTED 1
|
|
-#define PPTP_BAD_FORMAT 2
|
|
-#define PPTP_BAD_VALUE 3
|
|
-#define PPTP_NO_RESOURCE 4
|
|
-#define PPTP_BAD_CALLID 5
|
|
-#define PPTP_REMOVE_DEVICE_ERROR 6
|
|
-
|
|
-struct PptpControlHeader {
|
|
- __u16 messageType;
|
|
- __u16 reserved;
|
|
-};
|
|
-
|
|
-/* FramingCapability Bitmap Values */
|
|
-#define PPTP_FRAME_CAP_ASYNC 0x1
|
|
-#define PPTP_FRAME_CAP_SYNC 0x2
|
|
-
|
|
-/* BearerCapability Bitmap Values */
|
|
-#define PPTP_BEARER_CAP_ANALOG 0x1
|
|
-#define PPTP_BEARER_CAP_DIGITAL 0x2
|
|
-
|
|
-struct PptpStartSessionRequest {
|
|
- __u16 protocolVersion;
|
|
- __u8 reserved1;
|
|
- __u8 reserved2;
|
|
- __u32 framingCapability;
|
|
- __u32 bearerCapability;
|
|
- __u16 maxChannels;
|
|
- __u16 firmwareRevision;
|
|
- __u8 hostName[64];
|
|
- __u8 vendorString[64];
|
|
-};
|
|
-
|
|
-/* PptpStartSessionResultCode Values */
|
|
-#define PPTP_START_OK 1
|
|
-#define PPTP_START_GENERAL_ERROR 2
|
|
-#define PPTP_START_ALREADY_CONNECTED 3
|
|
-#define PPTP_START_NOT_AUTHORIZED 4
|
|
-#define PPTP_START_UNKNOWN_PROTOCOL 5
|
|
-
|
|
-struct PptpStartSessionReply {
|
|
- __u16 protocolVersion;
|
|
- __u8 resultCode;
|
|
- __u8 generalErrorCode;
|
|
- __u32 framingCapability;
|
|
- __u32 bearerCapability;
|
|
- __u16 maxChannels;
|
|
- __u16 firmwareRevision;
|
|
- __u8 hostName[64];
|
|
- __u8 vendorString[64];
|
|
-};
|
|
-
|
|
-/* PptpStopReasons */
|
|
-#define PPTP_STOP_NONE 1
|
|
-#define PPTP_STOP_PROTOCOL 2
|
|
-#define PPTP_STOP_LOCAL_SHUTDOWN 3
|
|
-
|
|
-struct PptpStopSessionRequest {
|
|
- __u8 reason;
|
|
-};
|
|
-
|
|
-/* PptpStopSessionResultCode */
|
|
-#define PPTP_STOP_OK 1
|
|
-#define PPTP_STOP_GENERAL_ERROR 2
|
|
-
|
|
-struct PptpStopSessionReply {
|
|
- __u8 resultCode;
|
|
- __u8 generalErrorCode;
|
|
-};
|
|
-
|
|
-struct PptpEchoRequest {
|
|
- __u32 identNumber;
|
|
-};
|
|
-
|
|
-/* PptpEchoReplyResultCode */
|
|
-#define PPTP_ECHO_OK 1
|
|
-#define PPTP_ECHO_GENERAL_ERROR 2
|
|
-
|
|
-struct PptpEchoReply {
|
|
- __u32 identNumber;
|
|
- __u8 resultCode;
|
|
- __u8 generalErrorCode;
|
|
- __u16 reserved;
|
|
-};
|
|
-
|
|
-/* PptpFramingType */
|
|
-#define PPTP_ASYNC_FRAMING 1
|
|
-#define PPTP_SYNC_FRAMING 2
|
|
-#define PPTP_DONT_CARE_FRAMING 3
|
|
-
|
|
-/* PptpCallBearerType */
|
|
-#define PPTP_ANALOG_TYPE 1
|
|
-#define PPTP_DIGITAL_TYPE 2
|
|
-#define PPTP_DONT_CARE_BEARER_TYPE 3
|
|
-
|
|
-struct PptpOutCallRequest {
|
|
- __u16 callID;
|
|
- __u16 callSerialNumber;
|
|
- __u32 minBPS;
|
|
- __u32 maxBPS;
|
|
- __u32 bearerType;
|
|
- __u32 framingType;
|
|
- __u16 packetWindow;
|
|
- __u16 packetProcDelay;
|
|
- __u16 reserved1;
|
|
- __u16 phoneNumberLength;
|
|
- __u16 reserved2;
|
|
- __u8 phoneNumber[64];
|
|
- __u8 subAddress[64];
|
|
-};
|
|
-
|
|
-/* PptpCallResultCode */
|
|
-#define PPTP_OUTCALL_CONNECT 1
|
|
-#define PPTP_OUTCALL_GENERAL_ERROR 2
|
|
-#define PPTP_OUTCALL_NO_CARRIER 3
|
|
-#define PPTP_OUTCALL_BUSY 4
|
|
-#define PPTP_OUTCALL_NO_DIAL_TONE 5
|
|
-#define PPTP_OUTCALL_TIMEOUT 6
|
|
-#define PPTP_OUTCALL_DONT_ACCEPT 7
|
|
-
|
|
-struct PptpOutCallReply {
|
|
- __u16 callID;
|
|
- __u16 peersCallID;
|
|
- __u8 resultCode;
|
|
- __u8 generalErrorCode;
|
|
- __u16 causeCode;
|
|
- __u32 connectSpeed;
|
|
- __u16 packetWindow;
|
|
- __u16 packetProcDelay;
|
|
- __u32 physChannelID;
|
|
-};
|
|
-
|
|
-struct PptpInCallRequest {
|
|
- __u16 callID;
|
|
- __u16 callSerialNumber;
|
|
- __u32 callBearerType;
|
|
- __u32 physChannelID;
|
|
- __u16 dialedNumberLength;
|
|
- __u16 dialingNumberLength;
|
|
- __u8 dialedNumber[64];
|
|
- __u8 dialingNumber[64];
|
|
- __u8 subAddress[64];
|
|
-};
|
|
-
|
|
-/* PptpInCallResultCode */
|
|
-#define PPTP_INCALL_ACCEPT 1
|
|
-#define PPTP_INCALL_GENERAL_ERROR 2
|
|
-#define PPTP_INCALL_DONT_ACCEPT 3
|
|
-
|
|
-struct PptpInCallReply {
|
|
- __u16 callID;
|
|
- __u16 peersCallID;
|
|
- __u8 resultCode;
|
|
- __u8 generalErrorCode;
|
|
- __u16 packetWindow;
|
|
- __u16 packetProcDelay;
|
|
- __u16 reserved;
|
|
-};
|
|
-
|
|
-struct PptpInCallConnected {
|
|
- __u16 peersCallID;
|
|
- __u16 reserved;
|
|
- __u32 connectSpeed;
|
|
- __u16 packetWindow;
|
|
- __u16 packetProcDelay;
|
|
- __u32 callFramingType;
|
|
-};
|
|
-
|
|
-struct PptpClearCallRequest {
|
|
- __u16 callID;
|
|
- __u16 reserved;
|
|
-};
|
|
-
|
|
-struct PptpCallDisconnectNotify {
|
|
- __u16 callID;
|
|
- __u8 resultCode;
|
|
- __u8 generalErrorCode;
|
|
- __u16 causeCode;
|
|
- __u16 reserved;
|
|
- __u8 callStatistics[128];
|
|
-};
|
|
-
|
|
-struct PptpWanErrorNotify {
|
|
- __u16 peersCallID;
|
|
- __u16 reserved;
|
|
- __u32 crcErrors;
|
|
- __u32 framingErrors;
|
|
- __u32 hardwareOverRuns;
|
|
- __u32 bufferOverRuns;
|
|
- __u32 timeoutErrors;
|
|
- __u32 alignmentErrors;
|
|
-};
|
|
-
|
|
-struct PptpSetLinkInfo {
|
|
- __u16 peersCallID;
|
|
- __u16 reserved;
|
|
- __u32 sendAccm;
|
|
- __u32 recvAccm;
|
|
-};
|
|
-
|
|
-
|
|
-struct pptp_priv_data {
|
|
- __u16 call_id;
|
|
- __u16 mcall_id;
|
|
- __u16 pcall_id;
|
|
-};
|
|
-
|
|
-#endif /* __KERNEL__ */
|
|
-#endif /* _CONNTRACK_PPTP_H */
|
|
diff -Nurb 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 <asm/byteorder.h>
|
|
-
|
|
-/* GRE PROTOCOL HEADER */
|
|
-
|
|
-/* GRE Version field */
|
|
-#define GRE_VERSION_1701 0x0
|
|
-#define GRE_VERSION_PPTP 0x1
|
|
-
|
|
-/* GRE Protocol field */
|
|
-#define GRE_PROTOCOL_PPTP 0x880B
|
|
-
|
|
-/* GRE Flags */
|
|
-#define GRE_FLAG_C 0x80
|
|
-#define GRE_FLAG_R 0x40
|
|
-#define GRE_FLAG_K 0x20
|
|
-#define GRE_FLAG_S 0x10
|
|
-#define GRE_FLAG_A 0x80
|
|
-
|
|
-#define GRE_IS_C(f) ((f)&GRE_FLAG_C)
|
|
-#define GRE_IS_R(f) ((f)&GRE_FLAG_R)
|
|
-#define GRE_IS_K(f) ((f)&GRE_FLAG_K)
|
|
-#define GRE_IS_S(f) ((f)&GRE_FLAG_S)
|
|
-#define GRE_IS_A(f) ((f)&GRE_FLAG_A)
|
|
-
|
|
-/* GRE is a mess: Four different standards */
|
|
-struct gre_hdr {
|
|
-#if defined(__LITTLE_ENDIAN_BITFIELD)
|
|
- __u16 rec:3,
|
|
- srr:1,
|
|
- seq:1,
|
|
- key:1,
|
|
- routing:1,
|
|
- csum:1,
|
|
- version:3,
|
|
- reserved:4,
|
|
- ack:1;
|
|
-#elif defined(__BIG_ENDIAN_BITFIELD)
|
|
- __u16 csum:1,
|
|
- routing:1,
|
|
- key:1,
|
|
- seq:1,
|
|
- srr:1,
|
|
- rec:3,
|
|
- ack:1,
|
|
- reserved:4,
|
|
- version:3;
|
|
-#else
|
|
-#error "Adjust your <asm/byteorder.h> defines"
|
|
-#endif
|
|
- __u16 protocol;
|
|
-};
|
|
-
|
|
-/* modified GRE header for PPTP */
|
|
-struct gre_hdr_pptp {
|
|
- __u8 flags; /* bitfield */
|
|
- __u8 version; /* should be GRE_VERSION_PPTP */
|
|
- __u16 protocol; /* should be GRE_PROTOCOL_PPTP */
|
|
- __u16 payload_len; /* size of ppp payload, not inc. gre header */
|
|
- __u16 call_id; /* peer's call_id for this session */
|
|
- __u32 seq; /* sequence number. Present if S==1 */
|
|
- __u32 ack; /* seq number of highest packet recieved by */
|
|
- /* sender in this session */
|
|
-};
|
|
-
|
|
-
|
|
-/* this is part of ip_conntrack */
|
|
-struct ip_ct_gre {
|
|
- unsigned int stream_timeout;
|
|
- unsigned int timeout;
|
|
-};
|
|
-
|
|
-/* this is part of ip_conntrack_expect */
|
|
-struct ip_ct_gre_expect {
|
|
- struct ip_ct_gre_keymap *keymap_orig, *keymap_reply;
|
|
-};
|
|
-
|
|
-#ifdef __KERNEL__
|
|
-
|
|
-/* structure for original <-> reply keymap */
|
|
-struct ip_ct_gre_keymap {
|
|
- struct list_head list;
|
|
-
|
|
- struct ip_conntrack_tuple tuple;
|
|
- struct ip_conntrack_expect *master;
|
|
-};
|
|
-
|
|
-
|
|
-/* add new tuple->key_reply pair to keymap */
|
|
-int ip_ct_gre_keymap_add(struct ip_conntrack_expect *exp,
|
|
- struct ip_conntrack_tuple *t,
|
|
- int reply);
|
|
-
|
|
-/* change an existing keymap entry */
|
|
-void ip_ct_gre_keymap_change(struct ip_ct_gre_keymap *km,
|
|
- struct ip_conntrack_tuple *t);
|
|
-
|
|
-
|
|
-
|
|
-/* get pointer to gre key, if present */
|
|
-static inline u_int32_t *gre_key(struct gre_hdr *greh)
|
|
-{
|
|
- if (!greh->key)
|
|
- return NULL;
|
|
- if (greh->csum || greh->routing)
|
|
- return (u_int32_t *) (greh+sizeof(*greh)+4);
|
|
- return (u_int32_t *) (greh+sizeof(*greh));
|
|
-}
|
|
-
|
|
-/* get pointer ot gre csum, if present */
|
|
-static inline u_int16_t *gre_csum(struct gre_hdr *greh)
|
|
-{
|
|
- if (!greh->csum)
|
|
- return NULL;
|
|
- return (u_int16_t *) (greh+sizeof(*greh));
|
|
-}
|
|
-
|
|
-#endif /* __KERNEL__ */
|
|
-
|
|
-#endif /* _CONNTRACK_PROTO_GRE_H */
|
|
diff -Nurb 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 <linux/netfilter_ipv4/ip_pool.h>
|
|
-
|
|
-#define IPT_POOL_INV_SRC 0x00000001
|
|
-#define IPT_POOL_INV_DST 0x00000002
|
|
-#define IPT_POOL_DEL_SRC 0x00000004
|
|
-#define IPT_POOL_DEL_DST 0x00000008
|
|
-#define IPT_POOL_INV_MOD_SRC 0x00000010
|
|
-#define IPT_POOL_INV_MOD_DST 0x00000020
|
|
-#define IPT_POOL_MOD_SRC_ACCEPT 0x00000040
|
|
-#define IPT_POOL_MOD_DST_ACCEPT 0x00000080
|
|
-#define IPT_POOL_MOD_SRC_DROP 0x00000100
|
|
-#define IPT_POOL_MOD_DST_DROP 0x00000200
|
|
-
|
|
-/* match info */
|
|
-struct ipt_pool_info
|
|
-{
|
|
- ip_pool_t src;
|
|
- ip_pool_t dst;
|
|
- unsigned flags;
|
|
-};
|
|
-
|
|
-#endif /*_IPT_POOL_H*/
|
|
diff -Nurb 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 <kadlec@blackhole.kfki.hu>
|
|
- *
|
|
- * Based on ip_masq_h323.c for 2.2 kernels from CoRiTel, Sofia project.
|
|
- * (http://www.coritel.it/projects/sofia/nat/)
|
|
- * Uses Sampsa Ranta's excellent idea on using expectfn to 'bind'
|
|
- * the unregistered helpers to the conntrack entries.
|
|
- */
|
|
-
|
|
-
|
|
-#include <linux/module.h>
|
|
-#include <linux/netfilter.h>
|
|
-#include <linux/ip.h>
|
|
-#include <net/checksum.h>
|
|
-#include <net/tcp.h>
|
|
-
|
|
-#include <linux/netfilter_ipv4/lockhelp.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_core.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
|
|
-
|
|
-MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
|
|
-MODULE_DESCRIPTION("H.323 'brute force' connection tracking module");
|
|
-MODULE_LICENSE("GPL");
|
|
-
|
|
-DECLARE_LOCK(ip_h323_lock);
|
|
-struct module *ip_conntrack_h323 = THIS_MODULE;
|
|
-
|
|
-#define DEBUGP(format, args...)
|
|
-
|
|
-static int h245_help(const struct iphdr *iph, size_t len,
|
|
- struct ip_conntrack *ct,
|
|
- enum ip_conntrack_info ctinfo)
|
|
-{
|
|
- struct tcphdr *tcph = (void *)iph + iph->ihl * 4;
|
|
- unsigned char *data = (unsigned char *) tcph + tcph->doff * 4;
|
|
- unsigned char *data_limit;
|
|
- u_int32_t tcplen = len - iph->ihl * 4;
|
|
- u_int32_t datalen = tcplen - tcph->doff * 4;
|
|
- int dir = CTINFO2DIR(ctinfo);
|
|
- struct ip_ct_h225_master *info = &ct->help.ct_h225_info;
|
|
- struct ip_conntrack_expect expect, *exp = &expect;
|
|
- struct ip_ct_h225_expect *exp_info = &exp->help.exp_h225_info;
|
|
- u_int16_t data_port;
|
|
- u_int32_t data_ip;
|
|
- unsigned int i;
|
|
-
|
|
- DEBUGP("ct_h245_help: help entered %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
|
|
- NIPQUAD(iph->saddr), ntohs(tcph->source),
|
|
- NIPQUAD(iph->daddr), ntohs(tcph->dest));
|
|
-
|
|
- /* Can't track connections formed before we registered */
|
|
- if (!info)
|
|
- return NF_ACCEPT;
|
|
-
|
|
- /* Until there's been traffic both ways, don't look in packets. */
|
|
- if (ctinfo != IP_CT_ESTABLISHED
|
|
- && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
|
|
- DEBUGP("ct_h245_help: Conntrackinfo = %u\n", ctinfo);
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- /* Not whole TCP header or too short packet? */
|
|
- if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4 + 5) {
|
|
- DEBUGP("ct_h245_help: tcplen = %u\n", (unsigned)tcplen);
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- /* Checksum invalid? Ignore. */
|
|
- if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
|
|
- csum_partial((char *)tcph, tcplen, 0))) {
|
|
- DEBUGP("ct_h245_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n",
|
|
- tcph, tcplen, NIPQUAD(iph->saddr),
|
|
- NIPQUAD(iph->daddr));
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- data_limit = (unsigned char *) data + datalen;
|
|
- /* bytes: 0123 45
|
|
- ipadrr port */
|
|
- for (i = 0; data < (data_limit - 5); data++, i++) {
|
|
- memcpy(&data_ip, data, sizeof(u_int32_t));
|
|
- if (data_ip == iph->saddr) {
|
|
- memcpy(&data_port, data + 4, sizeof(u_int16_t));
|
|
- memset(&expect, 0, sizeof(expect));
|
|
- /* update the H.225 info */
|
|
- DEBUGP("ct_h245_help: new RTCP/RTP requested %u.%u.%u.%u:->%u.%u.%u.%u:%u\n",
|
|
- NIPQUAD(ct->tuplehash[!dir].tuple.src.ip),
|
|
- NIPQUAD(iph->saddr), ntohs(data_port));
|
|
- LOCK_BH(&ip_h323_lock);
|
|
- info->is_h225 = H225_PORT + 1;
|
|
- exp_info->port = data_port;
|
|
- exp_info->dir = dir;
|
|
- exp_info->offset = i;
|
|
-
|
|
- exp->seq = ntohl(tcph->seq) + i;
|
|
-
|
|
- exp->tuple = ((struct ip_conntrack_tuple)
|
|
- { { ct->tuplehash[!dir].tuple.src.ip,
|
|
- { 0 } },
|
|
- { data_ip,
|
|
- { data_port },
|
|
- IPPROTO_UDP }});
|
|
- exp->mask = ((struct ip_conntrack_tuple)
|
|
- { { 0xFFFFFFFF, { 0 } },
|
|
- { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }});
|
|
-
|
|
- exp->expectfn = NULL;
|
|
-
|
|
- /* Ignore failure; should only happen with NAT */
|
|
- ip_conntrack_expect_related(ct, exp);
|
|
-
|
|
- UNLOCK_BH(&ip_h323_lock);
|
|
- }
|
|
- }
|
|
-
|
|
- return NF_ACCEPT;
|
|
-
|
|
-}
|
|
-
|
|
-/* H.245 helper is not registered! */
|
|
-static struct ip_conntrack_helper h245 =
|
|
- { { NULL, NULL },
|
|
- "H.245", /* name */
|
|
- IP_CT_HELPER_F_REUSE_EXPECT, /* flags */
|
|
- NULL, /* module */
|
|
- 8, /* max_ expected */
|
|
- 240, /* timeout */
|
|
- { { 0, { 0 } }, /* tuple */
|
|
- { 0, { 0 }, IPPROTO_TCP } },
|
|
- { { 0, { 0xFFFF } }, /* mask */
|
|
- { 0, { 0 }, 0xFFFF } },
|
|
- h245_help /* helper */
|
|
- };
|
|
-
|
|
-static int h225_expect(struct ip_conntrack *ct)
|
|
-{
|
|
- WRITE_LOCK(&ip_conntrack_lock);
|
|
- ct->helper = &h245;
|
|
- DEBUGP("h225_expect: helper for %p added\n", ct);
|
|
- WRITE_UNLOCK(&ip_conntrack_lock);
|
|
-
|
|
- return NF_ACCEPT; /* unused */
|
|
-}
|
|
-
|
|
-static int h225_help(const struct iphdr *iph, size_t len,
|
|
- struct ip_conntrack *ct,
|
|
- enum ip_conntrack_info ctinfo)
|
|
-{
|
|
- struct tcphdr *tcph = (void *)iph + iph->ihl * 4;
|
|
- unsigned char *data = (unsigned char *) tcph + tcph->doff * 4;
|
|
- unsigned char *data_limit;
|
|
- u_int32_t tcplen = len - iph->ihl * 4;
|
|
- u_int32_t datalen = tcplen - tcph->doff * 4;
|
|
- int dir = CTINFO2DIR(ctinfo);
|
|
- struct ip_ct_h225_master *info = &ct->help.ct_h225_info;
|
|
- struct ip_conntrack_expect expect, *exp = &expect;
|
|
- struct ip_ct_h225_expect *exp_info = &exp->help.exp_h225_info;
|
|
- u_int16_t data_port;
|
|
- u_int32_t data_ip;
|
|
- unsigned int i;
|
|
-
|
|
- DEBUGP("ct_h225_help: help entered %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n",
|
|
- NIPQUAD(iph->saddr), ntohs(tcph->source),
|
|
- NIPQUAD(iph->daddr), ntohs(tcph->dest));
|
|
-
|
|
- /* Can't track connections formed before we registered */
|
|
- if (!info)
|
|
- return NF_ACCEPT;
|
|
-
|
|
- /* Until there's been traffic both ways, don't look in packets. */
|
|
- if (ctinfo != IP_CT_ESTABLISHED
|
|
- && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
|
|
- DEBUGP("ct_h225_help: Conntrackinfo = %u\n", ctinfo);
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- /* Not whole TCP header or too short packet? */
|
|
- if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4 + 5) {
|
|
- DEBUGP("ct_h225_help: tcplen = %u\n", (unsigned)tcplen);
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- /* Checksum invalid? Ignore. */
|
|
- if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
|
|
- csum_partial((char *)tcph, tcplen, 0))) {
|
|
- DEBUGP("ct_h225_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n",
|
|
- tcph, tcplen, NIPQUAD(iph->saddr),
|
|
- NIPQUAD(iph->daddr));
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- data_limit = (unsigned char *) data + datalen;
|
|
- /* bytes: 0123 45
|
|
- ipadrr port */
|
|
- for (i = 0; data < (data_limit - 5); data++, i++) {
|
|
- memcpy(&data_ip, data, sizeof(u_int32_t));
|
|
- if (data_ip == iph->saddr) {
|
|
- memcpy(&data_port, data + 4, sizeof(u_int16_t));
|
|
- if (data_port == tcph->source) {
|
|
- /* Signal address */
|
|
- DEBUGP("ct_h225_help: sourceCallSignalAddress from %u.%u.%u.%u\n",
|
|
- NIPQUAD(iph->saddr));
|
|
- /* Update the H.225 info so that NAT can mangle the address/port
|
|
- even when we have no expected connection! */
|
|
-#ifdef CONFIG_IP_NF_NAT_NEEDED
|
|
- LOCK_BH(&ip_h323_lock);
|
|
- info->dir = dir;
|
|
- info->seq[IP_CT_DIR_ORIGINAL] = ntohl(tcph->seq) + i;
|
|
- info->offset[IP_CT_DIR_ORIGINAL] = i;
|
|
- UNLOCK_BH(&ip_h323_lock);
|
|
-#endif
|
|
- } else {
|
|
- memset(&expect, 0, sizeof(expect));
|
|
-
|
|
- /* update the H.225 info */
|
|
- LOCK_BH(&ip_h323_lock);
|
|
- info->is_h225 = H225_PORT;
|
|
- exp_info->port = data_port;
|
|
- exp_info->dir = dir;
|
|
- exp_info->offset = i;
|
|
-
|
|
- exp->seq = ntohl(tcph->seq) + i;
|
|
-
|
|
- exp->tuple = ((struct ip_conntrack_tuple)
|
|
- { { ct->tuplehash[!dir].tuple.src.ip,
|
|
- { 0 } },
|
|
- { data_ip,
|
|
- { data_port },
|
|
- IPPROTO_TCP }});
|
|
- exp->mask = ((struct ip_conntrack_tuple)
|
|
- { { 0xFFFFFFFF, { 0 } },
|
|
- { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }});
|
|
-
|
|
- exp->expectfn = h225_expect;
|
|
-
|
|
- /* Ignore failure */
|
|
- ip_conntrack_expect_related(ct, exp);
|
|
-
|
|
- DEBUGP("ct_h225_help: new H.245 requested %u.%u.%u.%u->%u.%u.%u.%u:%u\n",
|
|
- NIPQUAD(ct->tuplehash[!dir].tuple.src.ip),
|
|
- NIPQUAD(iph->saddr), ntohs(data_port));
|
|
-
|
|
- UNLOCK_BH(&ip_h323_lock);
|
|
- }
|
|
-#ifdef CONFIG_IP_NF_NAT_NEEDED
|
|
- } else if (data_ip == iph->daddr) {
|
|
- memcpy(&data_port, data + 4, sizeof(u_int16_t));
|
|
- if (data_port == tcph->dest) {
|
|
- /* Signal address */
|
|
- DEBUGP("ct_h225_help: destCallSignalAddress %u.%u.%u.%u\n",
|
|
- NIPQUAD(iph->daddr));
|
|
- /* Update the H.225 info so that NAT can mangle the address/port
|
|
- even when we have no expected connection! */
|
|
- LOCK_BH(&ip_h323_lock);
|
|
- info->dir = dir;
|
|
- info->seq[IP_CT_DIR_REPLY] = ntohl(tcph->seq) + i;
|
|
- info->offset[IP_CT_DIR_REPLY] = i;
|
|
- UNLOCK_BH(&ip_h323_lock);
|
|
- }
|
|
-#endif
|
|
- }
|
|
- }
|
|
-
|
|
- return NF_ACCEPT;
|
|
-
|
|
-}
|
|
-
|
|
-static struct ip_conntrack_helper h225 =
|
|
- { { NULL, NULL },
|
|
- "H.225", /* name */
|
|
- IP_CT_HELPER_F_REUSE_EXPECT, /* flags */
|
|
- THIS_MODULE, /* module */
|
|
- 2, /* max_expected */
|
|
- 240, /* timeout */
|
|
- { { 0, { __constant_htons(H225_PORT) } }, /* tuple */
|
|
- { 0, { 0 }, IPPROTO_TCP } },
|
|
- { { 0, { 0xFFFF } }, /* mask */
|
|
- { 0, { 0 }, 0xFFFF } },
|
|
- h225_help /* helper */
|
|
- };
|
|
-
|
|
-static int __init init(void)
|
|
-{
|
|
- return ip_conntrack_helper_register(&h225);
|
|
-}
|
|
-
|
|
-static void __exit fini(void)
|
|
-{
|
|
- /* Unregister H.225 helper */
|
|
- ip_conntrack_helper_unregister(&h225);
|
|
-}
|
|
-
|
|
-#ifdef CONFIG_IP_NF_NAT_NEEDED
|
|
-EXPORT_SYMBOL(ip_h323_lock);
|
|
-#endif
|
|
-
|
|
-module_init(init);
|
|
-module_exit(fini);
|
|
diff -Nurb 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 <filip.sneppe@cronos.be>
|
|
- * based on ip_conntrack_ftp.c and ip_conntrack_irc.c
|
|
- *
|
|
- * ip_conntrack_mms.c v0.3 2002-09-22
|
|
- *
|
|
- * This program is free software; you can redistribute it and/or
|
|
- * modify it under the terms of the GNU General Public License
|
|
- * as published by the Free Software Foundation; either version
|
|
- * 2 of the License, or (at your option) any later version.
|
|
- *
|
|
- * Module load syntax:
|
|
- * insmod ip_conntrack_mms.o ports=port1,port2,...port<MAX_PORTS>
|
|
- *
|
|
- * Please give the ports of all MMS servers You wish to connect to.
|
|
- * If you don't specify ports, the default will be TCP port 1755.
|
|
- *
|
|
- * More info on MMS protocol, firewalls and NAT:
|
|
- * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/MMSFirewall.asp
|
|
- * http://www.microsoft.com/windows/windowsmedia/serve/firewall.asp
|
|
- *
|
|
- * The SDP project people are reverse-engineering MMS:
|
|
- * http://get.to/sdp
|
|
- */
|
|
-
|
|
-#include <linux/config.h>
|
|
-#include <linux/module.h>
|
|
-#include <linux/netfilter.h>
|
|
-#include <linux/ip.h>
|
|
-#include <linux/ctype.h>
|
|
-#include <net/checksum.h>
|
|
-#include <net/tcp.h>
|
|
-
|
|
-#include <linux/netfilter_ipv4/lockhelp.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_mms.h>
|
|
-
|
|
-DECLARE_LOCK(ip_mms_lock);
|
|
-struct module *ip_conntrack_mms = THIS_MODULE;
|
|
-
|
|
-#define MAX_PORTS 8
|
|
-static int ports[MAX_PORTS];
|
|
-static int ports_c;
|
|
-#ifdef MODULE_PARM
|
|
-MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
|
|
-#endif
|
|
-
|
|
-#define DEBUGP(format, args...)
|
|
-
|
|
-#ifdef CONFIG_IP_NF_NAT_NEEDED
|
|
-EXPORT_SYMBOL(ip_mms_lock);
|
|
-#endif
|
|
-
|
|
-MODULE_AUTHOR("Filip Sneppe <filip.sneppe@cronos.be>");
|
|
-MODULE_DESCRIPTION("Microsoft Windows Media Services (MMS) connection tracking module");
|
|
-MODULE_LICENSE("GPL");
|
|
-
|
|
-/* #define isdigit(c) (c >= '0' && c <= '9') */
|
|
-
|
|
-/* copied from drivers/usb/serial/io_edgeport.c - not perfect but will do the trick */
|
|
-static void unicode_to_ascii (char *string, short *unicode, int unicode_size)
|
|
-{
|
|
- int i;
|
|
- for (i = 0; i < unicode_size; ++i) {
|
|
- string[i] = (char)(unicode[i]);
|
|
- }
|
|
- string[unicode_size] = 0x00;
|
|
-}
|
|
-
|
|
-__inline static int atoi(char *s)
|
|
-{
|
|
- int i=0;
|
|
- while (isdigit(*s)) {
|
|
- i = i*10 + *(s++) - '0';
|
|
- }
|
|
- return i;
|
|
-}
|
|
-
|
|
-/* convert ip address string like "192.168.0.10" to unsigned int */
|
|
-__inline static u_int32_t asciiiptoi(char *s)
|
|
-{
|
|
- unsigned int i, j, k;
|
|
-
|
|
- for(i=k=0; k<3; ++k, ++s, i<<=8) {
|
|
- i+=atoi(s);
|
|
- for(j=0; (*(++s) != '.') && (j<3); ++j)
|
|
- ;
|
|
- }
|
|
- i+=atoi(s);
|
|
- return ntohl(i);
|
|
-}
|
|
-
|
|
-int parse_mms(const char *data,
|
|
- const unsigned int datalen,
|
|
- u_int32_t *mms_ip,
|
|
- u_int16_t *mms_proto,
|
|
- u_int16_t *mms_port,
|
|
- char **mms_string_b,
|
|
- char **mms_string_e,
|
|
- char **mms_padding_e)
|
|
-{
|
|
- int unicode_size, i;
|
|
- char tempstring[28]; /* "\\255.255.255.255\UDP\65535" */
|
|
- char getlengthstring[28];
|
|
-
|
|
- for(unicode_size=0;
|
|
- (char) *(data+(MMS_SRV_UNICODE_STRING_OFFSET+unicode_size*2)) != (char)0;
|
|
- unicode_size++)
|
|
- if ((unicode_size == 28) || (MMS_SRV_UNICODE_STRING_OFFSET+unicode_size*2 >= datalen))
|
|
- return -1; /* out of bounds - incomplete packet */
|
|
-
|
|
- unicode_to_ascii(tempstring, (short *)(data+MMS_SRV_UNICODE_STRING_OFFSET), unicode_size);
|
|
- DEBUGP("ip_conntrack_mms: offset 60: %s\n", (const char *)(tempstring));
|
|
-
|
|
- /* IP address ? */
|
|
- *mms_ip = asciiiptoi(tempstring+2);
|
|
-
|
|
- i=sprintf(getlengthstring, "%u.%u.%u.%u", HIPQUAD(*mms_ip));
|
|
-
|
|
- /* protocol ? */
|
|
- if(strncmp(tempstring+3+i, "TCP", 3)==0)
|
|
- *mms_proto = IPPROTO_TCP;
|
|
- else if(strncmp(tempstring+3+i, "UDP", 3)==0)
|
|
- *mms_proto = IPPROTO_UDP;
|
|
-
|
|
- /* port ? */
|
|
- *mms_port = atoi(tempstring+7+i);
|
|
-
|
|
- /* we store a pointer to the beginning of the "\\a.b.c.d\proto\port"
|
|
- unicode string, one to the end of the string, and one to the end
|
|
- of the packet, since we must keep track of the number of bytes
|
|
- between end of the unicode string and the end of packet (padding) */
|
|
- *mms_string_b = (char *)(data + MMS_SRV_UNICODE_STRING_OFFSET);
|
|
- *mms_string_e = (char *)(data + MMS_SRV_UNICODE_STRING_OFFSET + unicode_size * 2);
|
|
- *mms_padding_e = (char *)(data + datalen); /* looks funny, doesn't it */
|
|
- return 0;
|
|
-}
|
|
-
|
|
-
|
|
-static int help(const struct iphdr *iph, size_t len,
|
|
- struct ip_conntrack *ct,
|
|
- enum ip_conntrack_info ctinfo)
|
|
-{
|
|
- /* tcplen not negative guaranteed by ip_conntrack_tcp.c */
|
|
- struct tcphdr *tcph = (void *)iph + iph->ihl * 4;
|
|
- const char *data = (const char *)tcph + tcph->doff * 4;
|
|
- unsigned int tcplen = len - iph->ihl * 4;
|
|
- unsigned int datalen = tcplen - tcph->doff * 4;
|
|
- int dir = CTINFO2DIR(ctinfo);
|
|
- struct ip_conntrack_expect expect, *exp = &expect;
|
|
- struct ip_ct_mms_expect *exp_mms_info = &exp->help.exp_mms_info;
|
|
-
|
|
- u_int32_t mms_ip;
|
|
- u_int16_t mms_proto;
|
|
- char mms_proto_string[8];
|
|
- u_int16_t mms_port;
|
|
- char *mms_string_b, *mms_string_e, *mms_padding_e;
|
|
-
|
|
- /* Until there's been traffic both ways, don't look in packets. */
|
|
- if (ctinfo != IP_CT_ESTABLISHED
|
|
- && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) {
|
|
- DEBUGP("ip_conntrack_mms: Conntrackinfo = %u\n", ctinfo);
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- /* Not whole TCP header? */
|
|
- if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff*4) {
|
|
- DEBUGP("ip_conntrack_mms: tcplen = %u\n", (unsigned)tcplen);
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- /* Checksum invalid? Ignore. */
|
|
- if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
|
|
- csum_partial((char *)tcph, tcplen, 0))) {
|
|
- DEBUGP("mms_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n",
|
|
- tcph, tcplen, NIPQUAD(iph->saddr),
|
|
- NIPQUAD(iph->daddr));
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- /* Only look at packets with 0x00030002/196610 on bytes 36->39 of TCP payload */
|
|
- if( (MMS_SRV_MSG_OFFSET < datalen) &&
|
|
- ((*(u32 *)(data+MMS_SRV_MSG_OFFSET)) == MMS_SRV_MSG_ID)) {
|
|
- DEBUGP("ip_conntrack_mms: offset 37: %u %u %u %u, datalen:%u\n",
|
|
- (u8)*(data+36), (u8)*(data+37),
|
|
- (u8)*(data+38), (u8)*(data+39),
|
|
- datalen);
|
|
- if(parse_mms(data, datalen, &mms_ip, &mms_proto, &mms_port,
|
|
- &mms_string_b, &mms_string_e, &mms_padding_e))
|
|
- if(net_ratelimit())
|
|
- printk(KERN_WARNING
|
|
- "ip_conntrack_mms: Unable to parse data payload\n");
|
|
-
|
|
- memset(&expect, 0, sizeof(expect));
|
|
-
|
|
- sprintf(mms_proto_string, "(%u)", mms_proto);
|
|
- DEBUGP("ip_conntrack_mms: adding %s expectation %u.%u.%u.%u -> %u.%u.%u.%u:%u\n",
|
|
- mms_proto == IPPROTO_TCP ? "TCP"
|
|
- : mms_proto == IPPROTO_UDP ? "UDP":mms_proto_string,
|
|
- NIPQUAD(ct->tuplehash[!dir].tuple.src.ip),
|
|
- NIPQUAD(mms_ip),
|
|
- mms_port);
|
|
-
|
|
- /* it's possible that the client will just ask the server to tunnel
|
|
- the stream over the same TCP session (from port 1755): there's
|
|
- shouldn't be a need to add an expectation in that case, but it
|
|
- makes NAT packet mangling so much easier */
|
|
- LOCK_BH(&ip_mms_lock);
|
|
-
|
|
- DEBUGP("ip_conntrack_mms: tcph->seq = %u\n", tcph->seq);
|
|
-
|
|
- exp->seq = ntohl(tcph->seq) + (mms_string_b - data);
|
|
- exp_mms_info->len = (mms_string_e - mms_string_b);
|
|
- exp_mms_info->padding = (mms_padding_e - mms_string_e);
|
|
- exp_mms_info->port = mms_port;
|
|
-
|
|
- DEBUGP("ip_conntrack_mms: wrote info seq=%u (ofs=%u), len=%d, padding=%u\n",
|
|
- exp->seq, (mms_string_e - data), exp_mms_info->len, exp_mms_info->padding);
|
|
-
|
|
- exp->tuple = ((struct ip_conntrack_tuple)
|
|
- { { ct->tuplehash[!dir].tuple.src.ip, { 0 } },
|
|
- { mms_ip,
|
|
- { (__u16) ntohs(mms_port) },
|
|
- mms_proto } }
|
|
- );
|
|
- exp->mask = ((struct ip_conntrack_tuple)
|
|
- { { 0xFFFFFFFF, { 0 } },
|
|
- { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }});
|
|
- exp->expectfn = NULL;
|
|
- ip_conntrack_expect_related(ct, &expect);
|
|
- UNLOCK_BH(&ip_mms_lock);
|
|
- }
|
|
-
|
|
- return NF_ACCEPT;
|
|
-}
|
|
-
|
|
-static struct ip_conntrack_helper mms[MAX_PORTS];
|
|
-static char mms_names[MAX_PORTS][10];
|
|
-
|
|
-/* Not __exit: called from init() */
|
|
-static void fini(void)
|
|
-{
|
|
- int i;
|
|
- for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
|
|
- DEBUGP("ip_conntrack_mms: unregistering helper for port %d\n",
|
|
- ports[i]);
|
|
- ip_conntrack_helper_unregister(&mms[i]);
|
|
- }
|
|
-}
|
|
-
|
|
-static int __init init(void)
|
|
-{
|
|
- int i, ret;
|
|
- char *tmpname;
|
|
-
|
|
- if (ports[0] == 0)
|
|
- ports[0] = MMS_PORT;
|
|
-
|
|
- for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
|
|
- memset(&mms[i], 0, sizeof(struct ip_conntrack_helper));
|
|
- mms[i].tuple.src.u.tcp.port = htons(ports[i]);
|
|
- mms[i].tuple.dst.protonum = IPPROTO_TCP;
|
|
- mms[i].mask.src.u.tcp.port = 0xFFFF;
|
|
- mms[i].mask.dst.protonum = 0xFFFF;
|
|
- mms[i].max_expected = 1;
|
|
- mms[i].timeout = 0;
|
|
- mms[i].flags = IP_CT_HELPER_F_REUSE_EXPECT;
|
|
- mms[i].me = THIS_MODULE;
|
|
- mms[i].help = help;
|
|
-
|
|
- tmpname = &mms_names[i][0];
|
|
- if (ports[i] == MMS_PORT)
|
|
- sprintf(tmpname, "mms");
|
|
- else
|
|
- sprintf(tmpname, "mms-%d", ports[i]);
|
|
- mms[i].name = tmpname;
|
|
-
|
|
- DEBUGP("ip_conntrack_mms: registering helper for port %d\n",
|
|
- ports[i]);
|
|
- ret = ip_conntrack_helper_register(&mms[i]);
|
|
-
|
|
- if (ret) {
|
|
- fini();
|
|
- return ret;
|
|
- }
|
|
- ports_c++;
|
|
- }
|
|
- return 0;
|
|
-}
|
|
-
|
|
-module_init(init);
|
|
-module_exit(fini);
|
|
diff -Nurb 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 <laforge@gnumonks.org>,
|
|
- *
|
|
- * Development of this code funded by Astaro AG (http://www.astaro.com/)
|
|
- *
|
|
- * Limitations:
|
|
- * - We blindly assume that control connections are always
|
|
- * established in PNS->PAC direction. This is a violation
|
|
- * of RFFC2673
|
|
- *
|
|
- * TODO: - finish support for multiple calls within one session
|
|
- * (needs expect reservations in newnat)
|
|
- * - testing of incoming PPTP calls
|
|
- */
|
|
-
|
|
-#include <linux/config.h>
|
|
-#include <linux/module.h>
|
|
-#include <linux/netfilter.h>
|
|
-#include <linux/ip.h>
|
|
-#include <net/checksum.h>
|
|
-#include <net/tcp.h>
|
|
-
|
|
-#include <linux/netfilter_ipv4/lockhelp.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
|
|
-
|
|
-MODULE_LICENSE("GPL");
|
|
-MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
|
|
-MODULE_DESCRIPTION("Netfilter connection tracking helper module for PPTP");
|
|
-
|
|
-DECLARE_LOCK(ip_pptp_lock);
|
|
-
|
|
-#define DEBUGP(format, args...)
|
|
-
|
|
-#define SECS *HZ
|
|
-#define MINS * 60 SECS
|
|
-#define HOURS * 60 MINS
|
|
-#define DAYS * 24 HOURS
|
|
-
|
|
-#define PPTP_GRE_TIMEOUT (10 MINS)
|
|
-#define PPTP_GRE_STREAM_TIMEOUT (5 DAYS)
|
|
-
|
|
-static int pptp_expectfn(struct ip_conntrack *ct)
|
|
-{
|
|
- struct ip_conntrack_expect *exp, *other_exp;
|
|
- struct ip_conntrack *master;
|
|
-
|
|
- DEBUGP("increasing timeouts\n");
|
|
- /* increase timeout of GRE data channel conntrack entry */
|
|
- ct->proto.gre.timeout = PPTP_GRE_TIMEOUT;
|
|
- ct->proto.gre.stream_timeout = PPTP_GRE_STREAM_TIMEOUT;
|
|
-
|
|
- master = master_ct(ct);
|
|
- if (!master) {
|
|
- DEBUGP(" no master!!!\n");
|
|
- return 0;
|
|
- }
|
|
-
|
|
- DEBUGP("completing tuples with ct info\n");
|
|
- /* we can do this, since we're unconfirmed */
|
|
- if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.gre.key ==
|
|
- htonl(master->help.ct_pptp_info.pac_call_id)) {
|
|
- /* assume PNS->PAC */
|
|
- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key =
|
|
- htonl(master->help.ct_pptp_info.pns_call_id);
|
|
- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key =
|
|
- htonl(master->help.ct_pptp_info.pns_call_id);
|
|
- } else {
|
|
- /* assume PAC->PNS */
|
|
- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key =
|
|
- htonl(master->help.ct_pptp_info.pac_call_id);
|
|
- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key =
|
|
- htonl(master->help.ct_pptp_info.pns_call_id);
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-/* timeout GRE data connections */
|
|
-static int pptp_timeout_related(struct ip_conntrack *ct)
|
|
-{
|
|
- struct list_head *cur_item;
|
|
- struct ip_conntrack_expect *exp;
|
|
-
|
|
- list_for_each(cur_item, &ct->sibling_list) {
|
|
- exp = list_entry(cur_item, struct ip_conntrack_expect,
|
|
- expected_list);
|
|
-
|
|
- if (!exp->sibling)
|
|
- continue;
|
|
-
|
|
- DEBUGP("setting timeout of conntrack %p to 0\n",
|
|
- exp->sibling);
|
|
- exp->sibling->proto.gre.timeout = 0;
|
|
- exp->sibling->proto.gre.stream_timeout = 0;
|
|
- ip_ct_refresh(exp->sibling, 0);
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-/* expect GRE connection in PNS->PAC direction */
|
|
-static inline int
|
|
-exp_gre(struct ip_conntrack *master,
|
|
- u_int32_t seq,
|
|
- u_int16_t callid,
|
|
- u_int16_t peer_callid)
|
|
-{
|
|
- struct ip_conntrack_expect exp;
|
|
- struct ip_conntrack_tuple inv_tuple;
|
|
-
|
|
- memset(&exp, 0, sizeof(exp));
|
|
- /* tuple in original direction, PAC->PNS */
|
|
- exp.tuple.src.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
|
|
- exp.tuple.src.u.gre.key = htonl(ntohs(peer_callid));
|
|
- exp.tuple.dst.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
|
|
- exp.tuple.dst.u.gre.key = htonl(ntohs(callid));
|
|
- exp.tuple.dst.u.gre.protocol = __constant_htons(GRE_PROTOCOL_PPTP);
|
|
- exp.tuple.dst.u.gre.version = GRE_VERSION_PPTP;
|
|
- exp.tuple.dst.protonum = IPPROTO_GRE;
|
|
-
|
|
- exp.mask.src.ip = 0xffffffff;
|
|
- exp.mask.src.u.all = 0;
|
|
- exp.mask.dst.u.all = 0;
|
|
- exp.mask.dst.u.gre.key = 0xffffffff;
|
|
- exp.mask.dst.u.gre.version = 0xff;
|
|
- exp.mask.dst.u.gre.protocol = 0xffff;
|
|
- exp.mask.dst.ip = 0xffffffff;
|
|
- exp.mask.dst.protonum = 0xffff;
|
|
-
|
|
- exp.seq = seq;
|
|
- exp.expectfn = pptp_expectfn;
|
|
-
|
|
- exp.help.exp_pptp_info.pac_call_id = ntohs(callid);
|
|
- exp.help.exp_pptp_info.pns_call_id = ntohs(peer_callid);
|
|
-
|
|
- DEBUGP("calling expect_related ");
|
|
- DUMP_TUPLE_RAW(&exp.tuple);
|
|
-
|
|
- /* Add GRE keymap entries */
|
|
- ip_ct_gre_keymap_add(&exp, &exp.tuple, 0);
|
|
- invert_tuplepr(&inv_tuple, &exp.tuple);
|
|
- ip_ct_gre_keymap_add(&exp, &inv_tuple, 1);
|
|
-
|
|
- ip_conntrack_expect_related(master, &exp);
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-static inline int
|
|
-pptp_inbound_pkt(struct tcphdr *tcph,
|
|
- struct pptp_pkt_hdr *pptph,
|
|
- size_t datalen,
|
|
- struct ip_conntrack *ct,
|
|
- enum ip_conntrack_info ctinfo)
|
|
-{
|
|
- struct PptpControlHeader *ctlh;
|
|
- union pptp_ctrl_union pptpReq;
|
|
-
|
|
- struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
|
|
- u_int16_t msg, *cid, *pcid;
|
|
- u_int32_t seq;
|
|
-
|
|
- ctlh = (struct PptpControlHeader *)
|
|
- ((char *) pptph + sizeof(struct pptp_pkt_hdr));
|
|
- pptpReq.rawreq = (void *)
|
|
- ((char *) ctlh + sizeof(struct PptpControlHeader));
|
|
-
|
|
- msg = ntohs(ctlh->messageType);
|
|
- DEBUGP("inbound control message %s\n", strMName[msg]);
|
|
-
|
|
- switch (msg) {
|
|
- case PPTP_START_SESSION_REPLY:
|
|
- /* server confirms new control session */
|
|
- if (info->sstate < PPTP_SESSION_REQUESTED) {
|
|
- DEBUGP("%s without START_SESS_REQUEST\n",
|
|
- strMName[msg]);
|
|
- break;
|
|
- }
|
|
- if (pptpReq.srep->resultCode == PPTP_START_OK)
|
|
- info->sstate = PPTP_SESSION_CONFIRMED;
|
|
- else
|
|
- info->sstate = PPTP_SESSION_ERROR;
|
|
- break;
|
|
-
|
|
- case PPTP_STOP_SESSION_REPLY:
|
|
- /* server confirms end of control session */
|
|
- if (info->sstate > PPTP_SESSION_STOPREQ) {
|
|
- DEBUGP("%s without STOP_SESS_REQUEST\n",
|
|
- strMName[msg]);
|
|
- break;
|
|
- }
|
|
- if (pptpReq.strep->resultCode == PPTP_STOP_OK)
|
|
- info->sstate = PPTP_SESSION_NONE;
|
|
- else
|
|
- info->sstate = PPTP_SESSION_ERROR;
|
|
- break;
|
|
-
|
|
- case PPTP_OUT_CALL_REPLY:
|
|
- /* server accepted call, we now expect GRE frames */
|
|
- if (info->sstate != PPTP_SESSION_CONFIRMED) {
|
|
- DEBUGP("%s but no session\n", strMName[msg]);
|
|
- break;
|
|
- }
|
|
- if (info->cstate != PPTP_CALL_OUT_REQ &&
|
|
- info->cstate != PPTP_CALL_OUT_CONF) {
|
|
- DEBUGP("%s without OUTCALL_REQ\n", strMName[msg]);
|
|
- break;
|
|
- }
|
|
- if (pptpReq.ocack->resultCode != PPTP_OUTCALL_CONNECT) {
|
|
- info->cstate = PPTP_CALL_NONE;
|
|
- break;
|
|
- }
|
|
-
|
|
- cid = &pptpReq.ocack->callID;
|
|
- pcid = &pptpReq.ocack->peersCallID;
|
|
-
|
|
- info->pac_call_id = ntohs(*cid);
|
|
-
|
|
- if (htons(info->pns_call_id) != *pcid) {
|
|
- DEBUGP("%s for unknown callid %u\n",
|
|
- strMName[msg], ntohs(*pcid));
|
|
- break;
|
|
- }
|
|
-
|
|
- DEBUGP("%s, CID=%X, PCID=%X\n", strMName[msg],
|
|
- ntohs(*cid), ntohs(*pcid));
|
|
-
|
|
- info->cstate = PPTP_CALL_OUT_CONF;
|
|
-
|
|
- seq = ntohl(tcph->seq) + ((void *)pcid - (void *)pptph);
|
|
- exp_gre(ct, seq, *cid, *pcid);
|
|
- break;
|
|
-
|
|
- case PPTP_IN_CALL_REQUEST:
|
|
- /* server tells us about incoming call request */
|
|
- if (info->sstate != PPTP_SESSION_CONFIRMED) {
|
|
- DEBUGP("%s but no session\n", strMName[msg]);
|
|
- break;
|
|
- }
|
|
- pcid = &pptpReq.icack->peersCallID;
|
|
- DEBUGP("%s, PCID=%X\n", strMName[msg], ntohs(*pcid));
|
|
- info->cstate = PPTP_CALL_IN_REQ;
|
|
- info->pac_call_id= ntohs(*pcid);
|
|
- break;
|
|
-
|
|
- case PPTP_IN_CALL_CONNECT:
|
|
- /* server tells us about incoming call established */
|
|
- if (info->sstate != PPTP_SESSION_CONFIRMED) {
|
|
- DEBUGP("%s but no session\n", strMName[msg]);
|
|
- break;
|
|
- }
|
|
- if (info->sstate != PPTP_CALL_IN_REP
|
|
- && info->sstate != PPTP_CALL_IN_CONF) {
|
|
- DEBUGP("%s but never sent IN_CALL_REPLY\n",
|
|
- strMName[msg]);
|
|
- break;
|
|
- }
|
|
-
|
|
- pcid = &pptpReq.iccon->peersCallID;
|
|
- cid = &info->pac_call_id;
|
|
-
|
|
- if (info->pns_call_id != ntohs(*pcid)) {
|
|
- DEBUGP("%s for unknown CallID %u\n",
|
|
- strMName[msg], ntohs(*cid));
|
|
- break;
|
|
- }
|
|
-
|
|
- DEBUGP("%s, PCID=%X\n", strMName[msg], ntohs(*pcid));
|
|
- info->cstate = PPTP_CALL_IN_CONF;
|
|
-
|
|
- /* we expect a GRE connection from PAC to PNS */
|
|
- seq = ntohl(tcph->seq) + ((void *)pcid - (void *)pptph);
|
|
- exp_gre(ct, seq, *cid, *pcid);
|
|
-
|
|
- break;
|
|
-
|
|
- case PPTP_CALL_DISCONNECT_NOTIFY:
|
|
- /* server confirms disconnect */
|
|
- cid = &pptpReq.disc->callID;
|
|
- DEBUGP("%s, CID=%X\n", strMName[msg], ntohs(*cid));
|
|
- info->cstate = PPTP_CALL_NONE;
|
|
-
|
|
- /* untrack this call id, unexpect GRE packets */
|
|
- pptp_timeout_related(ct);
|
|
- /* NEWNAT: look up exp for call id and unexpct_related */
|
|
- break;
|
|
-
|
|
- case PPTP_WAN_ERROR_NOTIFY:
|
|
- break;
|
|
-
|
|
- case PPTP_ECHO_REQUEST:
|
|
- case PPTP_ECHO_REPLY:
|
|
- /* I don't have to explain these ;) */
|
|
- break;
|
|
- default:
|
|
- DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX)
|
|
- ? strMName[msg]:strMName[0], msg);
|
|
- break;
|
|
- }
|
|
-
|
|
- return NF_ACCEPT;
|
|
-
|
|
-}
|
|
-
|
|
-static inline int
|
|
-pptp_outbound_pkt(struct tcphdr *tcph,
|
|
- struct pptp_pkt_hdr *pptph,
|
|
- size_t datalen,
|
|
- struct ip_conntrack *ct,
|
|
- enum ip_conntrack_info ctinfo)
|
|
-{
|
|
- struct PptpControlHeader *ctlh;
|
|
- union pptp_ctrl_union pptpReq;
|
|
- struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
|
|
- u_int16_t msg, *cid, *pcid;
|
|
-
|
|
- ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph));
|
|
- pptpReq.rawreq = (void *) ((void *) ctlh + sizeof(*ctlh));
|
|
-
|
|
- msg = ntohs(ctlh->messageType);
|
|
- DEBUGP("outbound control message %s\n", strMName[msg]);
|
|
-
|
|
- switch (msg) {
|
|
- case PPTP_START_SESSION_REQUEST:
|
|
- /* client requests for new control session */
|
|
- if (info->sstate != PPTP_SESSION_NONE) {
|
|
- DEBUGP("%s but we already have one",
|
|
- strMName[msg]);
|
|
- }
|
|
- info->sstate = PPTP_SESSION_REQUESTED;
|
|
- break;
|
|
- case PPTP_STOP_SESSION_REQUEST:
|
|
- /* client requests end of control session */
|
|
- info->sstate = PPTP_SESSION_STOPREQ;
|
|
- break;
|
|
-
|
|
- case PPTP_OUT_CALL_REQUEST:
|
|
- /* client initiating connection to server */
|
|
- if (info->sstate != PPTP_SESSION_CONFIRMED) {
|
|
- DEBUGP("%s but no session\n",
|
|
- strMName[msg]);
|
|
- break;
|
|
- }
|
|
- info->cstate = PPTP_CALL_OUT_REQ;
|
|
- /* track PNS call id */
|
|
- cid = &pptpReq.ocreq->callID;
|
|
- DEBUGP("%s, CID=%X\n", strMName[msg], ntohs(*cid));
|
|
- info->pns_call_id = ntohs(*cid);
|
|
- break;
|
|
- case PPTP_IN_CALL_REPLY:
|
|
- /* client answers incoming call */
|
|
- if (info->cstate != PPTP_CALL_IN_REQ
|
|
- && info->cstate != PPTP_CALL_IN_REP) {
|
|
- DEBUGP("%s without incall_req\n",
|
|
- strMName[msg]);
|
|
- break;
|
|
- }
|
|
- if (pptpReq.icack->resultCode != PPTP_INCALL_ACCEPT) {
|
|
- info->cstate = PPTP_CALL_NONE;
|
|
- break;
|
|
- }
|
|
- pcid = &pptpReq.icack->peersCallID;
|
|
- if (info->pac_call_id != ntohs(*pcid)) {
|
|
- DEBUGP("%s for unknown call %u\n",
|
|
- strMName[msg], ntohs(*pcid));
|
|
- break;
|
|
- }
|
|
- DEBUGP("%s, CID=%X\n", strMName[msg], ntohs(*pcid));
|
|
- /* part two of the three-way handshake */
|
|
- info->cstate = PPTP_CALL_IN_REP;
|
|
- info->pns_call_id = ntohs(pptpReq.icack->callID);
|
|
- break;
|
|
-
|
|
- case PPTP_CALL_CLEAR_REQUEST:
|
|
- /* client requests hangup of call */
|
|
- if (info->sstate != PPTP_SESSION_CONFIRMED) {
|
|
- DEBUGP("CLEAR_CALL but no session\n");
|
|
- break;
|
|
- }
|
|
- /* FUTURE: iterate over all calls and check if
|
|
- * call ID is valid. We don't do this without newnat,
|
|
- * because we only know about last call */
|
|
- info->cstate = PPTP_CALL_CLEAR_REQ;
|
|
- break;
|
|
- case PPTP_SET_LINK_INFO:
|
|
- break;
|
|
- case PPTP_ECHO_REQUEST:
|
|
- case PPTP_ECHO_REPLY:
|
|
- /* I don't have to explain these ;) */
|
|
- break;
|
|
- default:
|
|
- DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX)?
|
|
- strMName[msg]:strMName[0], msg);
|
|
- /* unknown: no need to create GRE masq table entry */
|
|
- break;
|
|
- }
|
|
-
|
|
- return NF_ACCEPT;
|
|
-}
|
|
-
|
|
-
|
|
-/* track caller id inside control connection, call expect_related */
|
|
-static int
|
|
-conntrack_pptp_help(const struct iphdr *iph, size_t len,
|
|
- struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
|
|
-
|
|
-{
|
|
- struct pptp_pkt_hdr *pptph;
|
|
-
|
|
- struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
|
|
- u_int32_t tcplen = len - iph->ihl * 4;
|
|
- u_int32_t datalen = tcplen - tcph->doff * 4;
|
|
- void *datalimit;
|
|
- int dir = CTINFO2DIR(ctinfo);
|
|
- struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
|
|
-
|
|
- int oldsstate, oldcstate;
|
|
- int ret;
|
|
-
|
|
- /* don't do any tracking before tcp handshake complete */
|
|
- if (ctinfo != IP_CT_ESTABLISHED
|
|
- && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) {
|
|
- DEBUGP("ctinfo = %u, skipping\n", ctinfo);
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- /* not a complete TCP header? */
|
|
- if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4) {
|
|
- DEBUGP("tcplen = %u\n", tcplen);
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- /* checksum invalid? */
|
|
- if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr,
|
|
- csum_partial((char *) tcph, tcplen, 0))) {
|
|
- printk(KERN_NOTICE __FILE__ ": bad csum\n");
|
|
-// return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- if (tcph->fin || tcph->rst) {
|
|
- DEBUGP("RST/FIN received, timeouting GRE\n");
|
|
- /* can't do this after real newnat */
|
|
- info->cstate = PPTP_CALL_NONE;
|
|
-
|
|
- /* untrack this call id, unexpect GRE packets */
|
|
- pptp_timeout_related(ct);
|
|
- /* no need to call unexpect_related since master conn
|
|
- * dies anyway */
|
|
- }
|
|
-
|
|
-
|
|
- pptph = (struct pptp_pkt_hdr *) ((void *) tcph + tcph->doff * 4);
|
|
- datalimit = (void *) pptph + datalen;
|
|
-
|
|
- /* not a full pptp packet header? */
|
|
- if ((void *) pptph+sizeof(*pptph) >= datalimit) {
|
|
- DEBUGP("no full PPTP header, can't track\n");
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- /* if it's not a control message we can't do anything with it */
|
|
- if (ntohs(pptph->packetType) != PPTP_PACKET_CONTROL ||
|
|
- ntohl(pptph->magicCookie) != PPTP_MAGIC_COOKIE) {
|
|
- DEBUGP("not a control packet\n");
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- oldsstate = info->sstate;
|
|
- oldcstate = info->cstate;
|
|
-
|
|
- LOCK_BH(&ip_pptp_lock);
|
|
-
|
|
- if (dir == IP_CT_DIR_ORIGINAL)
|
|
- /* client -> server (PNS -> PAC) */
|
|
- ret = pptp_outbound_pkt(tcph, pptph, datalen, ct, ctinfo);
|
|
- else
|
|
- /* server -> client (PAC -> PNS) */
|
|
- ret = pptp_inbound_pkt(tcph, pptph, datalen, ct, ctinfo);
|
|
- DEBUGP("sstate: %d->%d, cstate: %d->%d\n",
|
|
- oldsstate, info->sstate, oldcstate, info->cstate);
|
|
- UNLOCK_BH(&ip_pptp_lock);
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-/* control protocol helper */
|
|
-static struct ip_conntrack_helper pptp = {
|
|
- { NULL, NULL },
|
|
- "pptp", IP_CT_HELPER_F_REUSE_EXPECT, THIS_MODULE, 2, 0,
|
|
- { { 0, { tcp: { port: __constant_htons(PPTP_CONTROL_PORT) } } },
|
|
- { 0, { 0 }, IPPROTO_TCP } },
|
|
- { { 0, { tcp: { port: 0xffff } } },
|
|
- { 0, { 0 }, 0xffff } },
|
|
- conntrack_pptp_help };
|
|
-
|
|
-/* ip_conntrack_pptp initialization */
|
|
-static int __init init(void)
|
|
-{
|
|
- int retcode;
|
|
-
|
|
- DEBUGP(__FILE__ ": registering helper\n");
|
|
- if ((retcode = ip_conntrack_helper_register(&pptp))) {
|
|
- printk(KERN_ERR "Unable to register conntrack application "
|
|
- "helper for pptp: %d\n", retcode);
|
|
- return -EIO;
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-static void __exit fini(void)
|
|
-{
|
|
- ip_conntrack_helper_unregister(&pptp);
|
|
-}
|
|
-
|
|
-module_init(init);
|
|
-module_exit(fini);
|
|
-
|
|
-EXPORT_SYMBOL(ip_pptp_lock);
|
|
diff -Nurb 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 <laforge@gnumonks.org>
|
|
- *
|
|
- * Development of this code funded by Astaro AG (http://www.astaro.com/)
|
|
- *
|
|
- */
|
|
-
|
|
-#include <linux/config.h>
|
|
-#include <linux/module.h>
|
|
-#include <linux/types.h>
|
|
-#include <linux/timer.h>
|
|
-#include <linux/netfilter.h>
|
|
-#include <linux/ip.h>
|
|
-#include <linux/in.h>
|
|
-#include <linux/list.h>
|
|
-
|
|
-#include <linux/netfilter_ipv4/lockhelp.h>
|
|
-
|
|
-DECLARE_RWLOCK(ip_ct_gre_lock);
|
|
-#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_ct_gre_lock)
|
|
-#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_ct_gre_lock)
|
|
-
|
|
-#include <linux/netfilter_ipv4/listhelp.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_core.h>
|
|
-
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
|
|
-
|
|
-MODULE_LICENSE("GPL");
|
|
-MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
|
|
-MODULE_DESCRIPTION("netfilter connection tracking protocol helper for GRE");
|
|
-
|
|
-/* shamelessly stolen from ip_conntrack_proto_udp.c */
|
|
-#define GRE_TIMEOUT (30*HZ)
|
|
-#define GRE_STREAM_TIMEOUT (180*HZ)
|
|
-
|
|
-#define DEBUGP(x, args...)
|
|
-#define DUMP_TUPLE_GRE(x)
|
|
-
|
|
-/* GRE KEYMAP HANDLING FUNCTIONS */
|
|
-static LIST_HEAD(gre_keymap_list);
|
|
-
|
|
-static inline int gre_key_cmpfn(const struct ip_ct_gre_keymap *km,
|
|
- const struct ip_conntrack_tuple *t)
|
|
-{
|
|
- return ((km->tuple.src.ip == t->src.ip) &&
|
|
- (km->tuple.dst.ip == t->dst.ip) &&
|
|
- (km->tuple.dst.protonum == t->dst.protonum) &&
|
|
- (km->tuple.dst.u.all == t->dst.u.all));
|
|
-}
|
|
-
|
|
-/* look up the source key for a given tuple */
|
|
-static u_int32_t gre_keymap_lookup(struct ip_conntrack_tuple *t)
|
|
-{
|
|
- struct ip_ct_gre_keymap *km;
|
|
- u_int32_t key;
|
|
-
|
|
- READ_LOCK(&ip_ct_gre_lock);
|
|
- km = LIST_FIND(&gre_keymap_list, gre_key_cmpfn,
|
|
- struct ip_ct_gre_keymap *, t);
|
|
- if (!km) {
|
|
- READ_UNLOCK(&ip_ct_gre_lock);
|
|
- return 0;
|
|
- }
|
|
-
|
|
- key = km->tuple.src.u.gre.key;
|
|
- READ_UNLOCK(&ip_ct_gre_lock);
|
|
-
|
|
- return key;
|
|
-}
|
|
-
|
|
-/* add a single keymap entry, associate with specified expect */
|
|
-int ip_ct_gre_keymap_add(struct ip_conntrack_expect *exp,
|
|
- struct ip_conntrack_tuple *t, int reply)
|
|
-{
|
|
- struct ip_ct_gre_keymap *km;
|
|
-
|
|
- km = kmalloc(sizeof(*km), GFP_ATOMIC);
|
|
- if (!km)
|
|
- return -1;
|
|
-
|
|
- /* initializing list head should be sufficient */
|
|
- memset(km, 0, sizeof(*km));
|
|
-
|
|
- memcpy(&km->tuple, t, sizeof(*t));
|
|
- km->master = exp;
|
|
-
|
|
- if (!reply)
|
|
- exp->proto.gre.keymap_orig = km;
|
|
- else
|
|
- exp->proto.gre.keymap_reply = km;
|
|
-
|
|
- DEBUGP("adding new entry %p: ", km);
|
|
- DUMP_TUPLE_GRE(&km->tuple);
|
|
-
|
|
- WRITE_LOCK(&ip_ct_gre_lock);
|
|
- list_append(&gre_keymap_list, km);
|
|
- WRITE_UNLOCK(&ip_ct_gre_lock);
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-/* change the tuple of a keymap entry (used by nat helper) */
|
|
-void ip_ct_gre_keymap_change(struct ip_ct_gre_keymap *km,
|
|
- struct ip_conntrack_tuple *t)
|
|
-{
|
|
- DEBUGP("changing entry %p to: ", km);
|
|
- DUMP_TUPLE_GRE(t);
|
|
-
|
|
- WRITE_LOCK(&ip_ct_gre_lock);
|
|
- memcpy(&km->tuple, t, sizeof(km->tuple));
|
|
- WRITE_UNLOCK(&ip_ct_gre_lock);
|
|
-}
|
|
-
|
|
-
|
|
-/* PUBLIC CONNTRACK PROTO HELPER FUNCTIONS */
|
|
-
|
|
-/* invert gre part of tuple */
|
|
-static int gre_invert_tuple(struct ip_conntrack_tuple *tuple,
|
|
- const struct ip_conntrack_tuple *orig)
|
|
-{
|
|
- tuple->dst.u.gre.protocol = orig->dst.u.gre.protocol;
|
|
- tuple->dst.u.gre.version = orig->dst.u.gre.version;
|
|
-
|
|
- tuple->dst.u.gre.key = orig->src.u.gre.key;
|
|
- tuple->src.u.gre.key = orig->dst.u.gre.key;
|
|
-
|
|
- return 1;
|
|
-}
|
|
-
|
|
-/* gre hdr info to tuple */
|
|
-static int gre_pkt_to_tuple(const void *datah, size_t datalen,
|
|
- struct ip_conntrack_tuple *tuple)
|
|
-{
|
|
- struct gre_hdr *grehdr = (struct gre_hdr *) datah;
|
|
- struct gre_hdr_pptp *pgrehdr = (struct gre_hdr_pptp *) datah;
|
|
- u_int32_t srckey;
|
|
-
|
|
- /* core guarantees 8 protocol bytes, no need for size check */
|
|
-
|
|
- tuple->dst.u.gre.version = grehdr->version;
|
|
- tuple->dst.u.gre.protocol = grehdr->protocol;
|
|
-
|
|
- switch (grehdr->version) {
|
|
- case GRE_VERSION_1701:
|
|
- if (!grehdr->key) {
|
|
- DEBUGP("Can't track GRE without key\n");
|
|
- return 0;
|
|
- }
|
|
- tuple->dst.u.gre.key = *(gre_key(grehdr));
|
|
- break;
|
|
-
|
|
- case GRE_VERSION_PPTP:
|
|
- if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) {
|
|
- DEBUGP("GRE_VERSION_PPTP but unknown proto\n");
|
|
- return 0;
|
|
- }
|
|
- tuple->dst.u.gre.key = htonl(ntohs(pgrehdr->call_id));
|
|
- break;
|
|
-
|
|
- default:
|
|
- printk(KERN_WARNING "unknown GRE version %hu\n",
|
|
- tuple->dst.u.gre.version);
|
|
- return 0;
|
|
- }
|
|
-
|
|
- srckey = gre_keymap_lookup(tuple);
|
|
-
|
|
- tuple->src.u.gre.key = srckey;
|
|
-
|
|
- return 1;
|
|
-}
|
|
-
|
|
-/* print gre part of tuple */
|
|
-static unsigned int gre_print_tuple(char *buffer,
|
|
- const struct ip_conntrack_tuple *tuple)
|
|
-{
|
|
- return sprintf(buffer, "version=%d protocol=0x%04x srckey=0x%x dstkey=0x%x ",
|
|
- tuple->dst.u.gre.version,
|
|
- ntohs(tuple->dst.u.gre.protocol),
|
|
- ntohl(tuple->src.u.gre.key),
|
|
- ntohl(tuple->dst.u.gre.key));
|
|
-}
|
|
-
|
|
-/* print private data for conntrack */
|
|
-static unsigned int gre_print_conntrack(char *buffer,
|
|
- const struct ip_conntrack *ct)
|
|
-{
|
|
- return sprintf(buffer, "timeout=%u, stream_timeout=%u ",
|
|
- (ct->proto.gre.timeout / HZ),
|
|
- (ct->proto.gre.stream_timeout / HZ));
|
|
-}
|
|
-
|
|
-/* Returns verdict for packet, and may modify conntrack */
|
|
-static int gre_packet(struct ip_conntrack *ct,
|
|
- struct iphdr *iph, size_t len,
|
|
- enum ip_conntrack_info conntrackinfo)
|
|
-{
|
|
- /* If we've seen traffic both ways, this is a GRE connection.
|
|
- * Extend timeout. */
|
|
- if (ct->status & IPS_SEEN_REPLY) {
|
|
- ip_ct_refresh(ct, ct->proto.gre.stream_timeout);
|
|
- /* Also, more likely to be important, and not a probe. */
|
|
- set_bit(IPS_ASSURED_BIT, &ct->status);
|
|
- } else
|
|
- ip_ct_refresh(ct, ct->proto.gre.timeout);
|
|
-
|
|
- return NF_ACCEPT;
|
|
-}
|
|
-
|
|
-/* Called when a new connection for this protocol found. */
|
|
-static int gre_new(struct ip_conntrack *ct,
|
|
- struct iphdr *iph, size_t len)
|
|
-{
|
|
- DEBUGP(": ");
|
|
- DUMP_TUPLE_GRE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
|
-
|
|
- /* initialize to sane value. Ideally a conntrack helper
|
|
- * (e.g. in case of pptp) is increasing them */
|
|
- ct->proto.gre.stream_timeout = GRE_STREAM_TIMEOUT;
|
|
- ct->proto.gre.timeout = GRE_TIMEOUT;
|
|
-
|
|
- return 1;
|
|
-}
|
|
-
|
|
-/* Called when a conntrack entry has already been removed from the hashes
|
|
- * and is about to be deleted from memory */
|
|
-static void gre_destroy(struct ip_conntrack *ct)
|
|
-{
|
|
- struct ip_conntrack_expect *master = ct->master;
|
|
-
|
|
- DEBUGP(" entering\n");
|
|
-
|
|
- if (!master) {
|
|
- DEBUGP("no master exp for ct %p\n", ct);
|
|
- return;
|
|
- }
|
|
-
|
|
- WRITE_LOCK(&ip_ct_gre_lock);
|
|
- if (master->proto.gre.keymap_orig) {
|
|
- DEBUGP("removing %p from list\n", master->proto.gre.keymap_orig);
|
|
- list_del(&master->proto.gre.keymap_orig->list);
|
|
- kfree(master->proto.gre.keymap_orig);
|
|
- }
|
|
- if (master->proto.gre.keymap_reply) {
|
|
- DEBUGP("removing %p from list\n", master->proto.gre.keymap_reply);
|
|
- list_del(&master->proto.gre.keymap_reply->list);
|
|
- kfree(master->proto.gre.keymap_reply);
|
|
- }
|
|
- WRITE_UNLOCK(&ip_ct_gre_lock);
|
|
-}
|
|
-
|
|
-/* protocol helper struct */
|
|
-static struct ip_conntrack_protocol gre = { { NULL, NULL }, IPPROTO_GRE,
|
|
- "gre",
|
|
- gre_pkt_to_tuple,
|
|
- gre_invert_tuple,
|
|
- gre_print_tuple,
|
|
- gre_print_conntrack,
|
|
- gre_packet,
|
|
- gre_new,
|
|
- gre_destroy,
|
|
- NULL,
|
|
- THIS_MODULE };
|
|
-
|
|
-/* ip_conntrack_proto_gre initialization */
|
|
-static int __init init(void)
|
|
-{
|
|
- int retcode;
|
|
-
|
|
- if ((retcode = ip_conntrack_protocol_register(&gre))) {
|
|
- printk(KERN_ERR "Unable to register conntrack protocol "
|
|
- "helper for gre: %d\n", retcode);
|
|
- return -EIO;
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-static void __exit fini(void)
|
|
-{
|
|
- struct list_head *pos, *n;
|
|
-
|
|
- /* delete all keymap entries */
|
|
- WRITE_LOCK(&ip_ct_gre_lock);
|
|
- list_for_each_safe(pos, n, &gre_keymap_list) {
|
|
- DEBUGP("deleting keymap %p\n", pos);
|
|
- list_del(pos);
|
|
- kfree(pos);
|
|
- }
|
|
- WRITE_UNLOCK(&ip_ct_gre_lock);
|
|
-
|
|
- ip_conntrack_protocol_unregister(&gre);
|
|
-}
|
|
-
|
|
-EXPORT_SYMBOL(ip_ct_gre_keymap_add);
|
|
-EXPORT_SYMBOL(ip_ct_gre_keymap_change);
|
|
-
|
|
-module_init(init);
|
|
-module_exit(fini);
|
|
diff -Nurb 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 <linux/netfilter_ipv4/ip_conntrack_protocol.h>
|
|
#include <linux/netfilter_ipv4/lockhelp.h>
|
|
|
|
+#if 0
|
|
+#define DEBUGP printk
|
|
+#else
|
|
#define DEBUGP(format, args...)
|
|
+#endif
|
|
|
|
/* Protects conntrack->proto.tcp */
|
|
static DECLARE_RWLOCK(tcp_lock);
|
|
|
|
+/* FIXME: Examine ipfilter's timeouts and conntrack transitions more
|
|
+ closely. They're more complex. --RR */
|
|
|
|
/* Actually, I believe that neither ipmasq (where this code is stolen
|
|
from) nor ipfilter do it exactly right. A new conntrack machine taking
|
|
@@ -39,6 +45,25 @@
|
|
"LISTEN"
|
|
};
|
|
|
|
+#define SECS *HZ
|
|
+#define MINS * 60 SECS
|
|
+#define HOURS * 60 MINS
|
|
+#define DAYS * 24 HOURS
|
|
+
|
|
+
|
|
+static unsigned long tcp_timeouts[]
|
|
+= { 30 MINS, /* TCP_CONNTRACK_NONE, */
|
|
+ 5 DAYS, /* TCP_CONNTRACK_ESTABLISHED, */
|
|
+ 2 MINS, /* TCP_CONNTRACK_SYN_SENT, */
|
|
+ 60 SECS, /* TCP_CONNTRACK_SYN_RECV, */
|
|
+ 2 MINS, /* TCP_CONNTRACK_FIN_WAIT, */
|
|
+ 2 MINS, /* TCP_CONNTRACK_TIME_WAIT, */
|
|
+ 10 SECS, /* TCP_CONNTRACK_CLOSE, */
|
|
+ 60 SECS, /* TCP_CONNTRACK_CLOSE_WAIT, */
|
|
+ 30 SECS, /* TCP_CONNTRACK_LAST_ACK, */
|
|
+ 2 MINS, /* TCP_CONNTRACK_LISTEN, */
|
|
+};
|
|
+
|
|
#define sNO TCP_CONNTRACK_NONE
|
|
#define sES TCP_CONNTRACK_ESTABLISHED
|
|
#define sSS TCP_CONNTRACK_SYN_SENT
|
|
@@ -161,13 +186,13 @@
|
|
&& tcph->syn && tcph->ack)
|
|
conntrack->proto.tcp.handshake_ack
|
|
= htonl(ntohl(tcph->seq) + 1);
|
|
+ WRITE_UNLOCK(&tcp_lock);
|
|
|
|
/* If only reply is a RST, we can consider ourselves not to
|
|
have an established connection: this is a fairly common
|
|
problem case, so we can delete the conntrack
|
|
immediately. --RR */
|
|
if (!(conntrack->status & IPS_SEEN_REPLY) && tcph->rst) {
|
|
- WRITE_UNLOCK(&tcp_lock);
|
|
if (del_timer(&conntrack->timeout))
|
|
conntrack->timeout.function((unsigned long)conntrack);
|
|
} else {
|
|
@@ -178,9 +203,7 @@
|
|
&& tcph->ack_seq == conntrack->proto.tcp.handshake_ack)
|
|
set_bit(IPS_ASSURED_BIT, &conntrack->status);
|
|
|
|
- WRITE_UNLOCK(&tcp_lock);
|
|
- ip_ct_refresh(conntrack,
|
|
- sysctl_ip_conntrack_tcp_timeouts[newconntrack]);
|
|
+ ip_ct_refresh(conntrack, tcp_timeouts[newconntrack]);
|
|
}
|
|
|
|
return NF_ACCEPT;
|
|
diff -Nurb 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 <linux/in.h>
|
|
#include <linux/udp.h>
|
|
#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_udp.h>
|
|
+
|
|
+#define UDP_TIMEOUT (30*HZ)
|
|
+#define UDP_STREAM_TIMEOUT (180*HZ)
|
|
|
|
static int udp_pkt_to_tuple(const void *datah, size_t datalen,
|
|
struct ip_conntrack_tuple *tuple)
|
|
@@ -50,13 +52,11 @@
|
|
/* If we've seen traffic both ways, this is some kind of UDP
|
|
stream. Extend timeout. */
|
|
if (conntrack->status & IPS_SEEN_REPLY) {
|
|
- ip_ct_refresh(conntrack,
|
|
- sysctl_ip_conntrack_udp_timeouts[UDP_STREAM_TIMEOUT]);
|
|
+ ip_ct_refresh(conntrack, UDP_STREAM_TIMEOUT);
|
|
/* Also, more likely to be important, and not a probe */
|
|
set_bit(IPS_ASSURED_BIT, &conntrack->status);
|
|
} else
|
|
- ip_ct_refresh(conntrack,
|
|
- sysctl_ip_conntrack_udp_timeouts[UDP_TIMEOUT]);
|
|
+ ip_ct_refresh(conntrack, UDP_TIMEOUT);
|
|
|
|
return NF_ACCEPT;
|
|
}
|
|
diff -Nurb 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 <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
|
#include <linux/netfilter_ipv4/listhelp.h>
|
|
|
|
+#if 0
|
|
+#define DEBUGP printk
|
|
+#else
|
|
#define DEBUGP(format, args...)
|
|
+#endif
|
|
|
|
struct module *ip_conntrack_module = THIS_MODULE;
|
|
MODULE_LICENSE("GPL");
|
|
@@ -52,17 +56,12 @@
|
|
return len;
|
|
}
|
|
|
|
+/* FIXME: Don't print source proto part. --RR */
|
|
static unsigned int
|
|
print_expect(char *buffer, const struct ip_conntrack_expect *expect)
|
|
{
|
|
unsigned int len;
|
|
|
|
- if (!expect || !expect->expectant || !expect->expectant->helper) {
|
|
- DEBUGP("expect %x expect->expectant %x expect->expectant->helper %x\n",
|
|
- expect, expect->expectant, expect->expectant->helper);
|
|
- return 0;
|
|
- }
|
|
-
|
|
if (expect->expectant->helper->timeout)
|
|
len = sprintf(buffer, "EXPECTING: %lu ",
|
|
timer_pending(&expect->timeout)
|
|
@@ -294,6 +293,8 @@
|
|
return ret;
|
|
}
|
|
|
|
+/* FIXME: Allow NULL functions and sub in pointers to generic for
|
|
+ them. --RR */
|
|
int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto)
|
|
{
|
|
int ret = 0;
|
|
@@ -362,8 +363,6 @@
|
|
EXPORT_SYMBOL(ip_ct_find_proto);
|
|
EXPORT_SYMBOL(__ip_ct_find_proto);
|
|
EXPORT_SYMBOL(ip_ct_find_helper);
|
|
-EXPORT_SYMBOL(sysctl_ip_conntrack_tcp_timeouts);
|
|
-EXPORT_SYMBOL(sysctl_ip_conntrack_udp_timeouts);
|
|
EXPORT_SYMBOL(ip_conntrack_expect_related);
|
|
EXPORT_SYMBOL(ip_conntrack_change_expect);
|
|
EXPORT_SYMBOL(ip_conntrack_unexpect_related);
|
|
diff -Nurb 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 <mb@ozaba.mine.nu>
|
|
- * Version: 0.0.7
|
|
- *
|
|
- * Thu 21 Mar 2002 Harald Welte <laforge@gnumonks.org>
|
|
- * - port to newnat API
|
|
- *
|
|
- */
|
|
-
|
|
-#include <linux/module.h>
|
|
-#include <linux/ip.h>
|
|
-#include <linux/udp.h>
|
|
-
|
|
-#include <linux/netfilter.h>
|
|
-#include <linux/netfilter_ipv4/ip_tables.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_tftp.h>
|
|
-
|
|
-MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>");
|
|
-MODULE_DESCRIPTION("Netfilter connection tracking module for tftp");
|
|
-MODULE_LICENSE("GPL");
|
|
-
|
|
-#define MAX_PORTS 8
|
|
-static int ports[MAX_PORTS];
|
|
-static int ports_c = 0;
|
|
-#ifdef MODULE_PARM
|
|
-MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
|
|
-MODULE_PARM_DESC(ports, "port numbers of tftp servers");
|
|
-#endif
|
|
-
|
|
-#define DEBUGP(format, args...)
|
|
-
|
|
-static int tftp_help(const struct iphdr *iph, size_t len,
|
|
- struct ip_conntrack *ct,
|
|
- enum ip_conntrack_info ctinfo)
|
|
-{
|
|
- struct udphdr *udph = (void *)iph + iph->ihl * 4;
|
|
- struct tftphdr *tftph = (void *)udph + 8;
|
|
- struct ip_conntrack_expect exp;
|
|
-
|
|
- switch (ntohs(tftph->opcode)) {
|
|
- /* RRQ and WRQ works the same way */
|
|
- case TFTP_OPCODE_READ:
|
|
- case TFTP_OPCODE_WRITE:
|
|
- DEBUGP("");
|
|
- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
|
- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
|
|
- memset(&exp, 0, sizeof(exp));
|
|
-
|
|
- exp.tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
|
|
- exp.mask.src.ip = 0xffffffff;
|
|
- exp.mask.dst.ip = 0xffffffff;
|
|
- exp.mask.dst.u.udp.port = 0xffff;
|
|
- exp.mask.dst.protonum = 0xffff;
|
|
- exp.expectfn = NULL;
|
|
-
|
|
- DEBUGP("expect: ");
|
|
- DUMP_TUPLE(&exp.tuple);
|
|
- DUMP_TUPLE(&exp.mask);
|
|
- ip_conntrack_expect_related(ct, &exp);
|
|
- break;
|
|
- default:
|
|
- DEBUGP("Unknown opcode\n");
|
|
- }
|
|
- return NF_ACCEPT;
|
|
-}
|
|
-
|
|
-static struct ip_conntrack_helper tftp[MAX_PORTS];
|
|
-static char tftp_names[MAX_PORTS][10];
|
|
-
|
|
-static void fini(void)
|
|
-{
|
|
- int i;
|
|
-
|
|
- for (i = 0 ; i < ports_c; i++) {
|
|
- DEBUGP("unregistering helper for port %d\n",
|
|
- ports[i]);
|
|
- ip_conntrack_helper_unregister(&tftp[i]);
|
|
- }
|
|
-}
|
|
-
|
|
-static int __init init(void)
|
|
-{
|
|
- int i, ret;
|
|
- char *tmpname;
|
|
-
|
|
- if (!ports[0])
|
|
- ports[0]=TFTP_PORT;
|
|
-
|
|
- for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) {
|
|
- /* Create helper structure */
|
|
- memset(&tftp[i], 0, sizeof(struct ip_conntrack_helper));
|
|
-
|
|
- tftp[i].tuple.dst.protonum = IPPROTO_UDP;
|
|
- tftp[i].tuple.src.u.udp.port = htons(ports[i]);
|
|
- tftp[i].mask.dst.protonum = 0xFFFF;
|
|
- tftp[i].mask.src.u.udp.port = 0xFFFF;
|
|
- tftp[i].max_expected = 1;
|
|
- tftp[i].timeout = 0;
|
|
- tftp[i].flags = IP_CT_HELPER_F_REUSE_EXPECT;
|
|
- tftp[i].me = THIS_MODULE;
|
|
- tftp[i].help = tftp_help;
|
|
-
|
|
- tmpname = &tftp_names[i][0];
|
|
- if (ports[i] == TFTP_PORT)
|
|
- sprintf(tmpname, "tftp");
|
|
- else
|
|
- sprintf(tmpname, "tftp-%d", i);
|
|
- tftp[i].name = tmpname;
|
|
-
|
|
- DEBUGP("port #%d: %d\n", i, ports[i]);
|
|
-
|
|
- ret=ip_conntrack_helper_register(&tftp[i]);
|
|
- if (ret) {
|
|
- printk("ERROR registering helper for port %d\n",
|
|
- ports[i]);
|
|
- fini();
|
|
- return(ret);
|
|
- }
|
|
- ports_c++;
|
|
- }
|
|
- return(0);
|
|
-}
|
|
-
|
|
-module_init(init);
|
|
-module_exit(fini);
|
|
diff -Nurb 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 <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
|
#include <linux/netfilter_ipv4/listhelp.h>
|
|
|
|
+#if 0
|
|
+#define DEBUGP printk
|
|
+#else
|
|
#define DEBUGP(format, args...)
|
|
+#endif
|
|
|
|
DECLARE_RWLOCK(ip_nat_lock);
|
|
DECLARE_RWLOCK_EXTERN(ip_conntrack_lock);
|
|
@@ -207,6 +211,7 @@
|
|
{
|
|
struct rtable *rt;
|
|
|
|
+ /* FIXME: IPTOS_TOS(iph->tos) --RR */
|
|
if (ip_route_output(&rt, var_ip, 0, 0, 0) != 0) {
|
|
DEBUGP("do_extra_mangle: Can't get route to %u.%u.%u.%u\n",
|
|
NIPQUAD(var_ip));
|
|
@@ -429,7 +434,7 @@
|
|
*tuple = *orig_tuple;
|
|
while ((rptr = find_best_ips_proto_fast(tuple, mr, conntrack, hooknum))
|
|
!= NULL) {
|
|
- DEBUGP("Found best for "); DUMP_TUPLE_RAW(tuple);
|
|
+ DEBUGP("Found best for "); DUMP_TUPLE(tuple);
|
|
/* 3) The per-protocol part of the manip is made to
|
|
map into the range to make a unique tuple. */
|
|
|
|
@@ -529,6 +534,31 @@
|
|
invert_tuplepr(&orig_tp,
|
|
&conntrack->tuplehash[IP_CT_DIR_REPLY].tuple);
|
|
|
|
+#if 0
|
|
+ {
|
|
+ unsigned int i;
|
|
+
|
|
+ DEBUGP("Hook %u (%s), ", hooknum,
|
|
+ HOOK2MANIP(hooknum)==IP_NAT_MANIP_SRC ? "SRC" : "DST");
|
|
+ DUMP_TUPLE(&orig_tp);
|
|
+ DEBUGP("Range %p: ", mr);
|
|
+ for (i = 0; i < mr->rangesize; i++) {
|
|
+ DEBUGP("%u:%s%s%s %u.%u.%u.%u - %u.%u.%u.%u %u - %u\n",
|
|
+ i,
|
|
+ (mr->range[i].flags & IP_NAT_RANGE_MAP_IPS)
|
|
+ ? " MAP_IPS" : "",
|
|
+ (mr->range[i].flags
|
|
+ & IP_NAT_RANGE_PROTO_SPECIFIED)
|
|
+ ? " PROTO_SPECIFIED" : "",
|
|
+ (mr->range[i].flags & IP_NAT_RANGE_FULL)
|
|
+ ? " FULL" : "",
|
|
+ NIPQUAD(mr->range[i].min_ip),
|
|
+ NIPQUAD(mr->range[i].max_ip),
|
|
+ mr->range[i].min.all,
|
|
+ mr->range[i].max.all);
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
|
|
do {
|
|
if (!get_unique_tuple(&new_tuple, &orig_tp, mr, conntrack,
|
|
@@ -538,6 +568,15 @@
|
|
return NF_DROP;
|
|
}
|
|
|
|
+#if 0
|
|
+ DEBUGP("Hook %u (%s) %p\n", hooknum,
|
|
+ HOOK2MANIP(hooknum)==IP_NAT_MANIP_SRC ? "SRC" : "DST",
|
|
+ conntrack);
|
|
+ DEBUGP("Original: ");
|
|
+ DUMP_TUPLE(&orig_tp);
|
|
+ DEBUGP("New: ");
|
|
+ DUMP_TUPLE(&new_tuple);
|
|
+#endif
|
|
|
|
/* We now have two tuples (SRCIP/SRCPT/DSTIP/DSTPT):
|
|
the original (A/B/C/D') and the mangled one (E/F/G/H').
|
|
@@ -554,6 +593,8 @@
|
|
If fail this race (reply tuple now used), repeat. */
|
|
} while (!ip_conntrack_alter_reply(conntrack, &reply));
|
|
|
|
+ /* FIXME: We can simply used existing conntrack reply tuple
|
|
+ here --RR */
|
|
/* Create inverse of original: C/D/A/B' */
|
|
invert_tuplepr(&inv_tuple, &orig_tp);
|
|
|
|
@@ -678,6 +719,17 @@
|
|
iph->check);
|
|
iph->daddr = manip->ip;
|
|
}
|
|
+#if 0
|
|
+ if (ip_fast_csum((u8 *)iph, iph->ihl) != 0)
|
|
+ DEBUGP("IP: checksum on packet bad.\n");
|
|
+
|
|
+ if (proto == IPPROTO_TCP) {
|
|
+ void *th = (u_int32_t *)iph + iph->ihl;
|
|
+ if (tcp_v4_check(th, len - 4*iph->ihl, iph->saddr, iph->daddr,
|
|
+ csum_partial((char *)th, len-4*iph->ihl, 0)))
|
|
+ DEBUGP("TCP: checksum on packet bad\n");
|
|
+ }
|
|
+#endif
|
|
}
|
|
|
|
static inline int exp_for_packet(struct ip_conntrack_expect *exp,
|
|
@@ -765,6 +817,7 @@
|
|
continue;
|
|
|
|
if (exp_for_packet(exp, pskb)) {
|
|
+ /* FIXME: May be true multiple times in the case of UDP!! */
|
|
DEBUGP("calling nat helper (exp=%p) for packet\n",
|
|
exp);
|
|
ret = helper->help(ct, exp, info, ctinfo,
|
|
@@ -926,6 +979,7 @@
|
|
INIT_LIST_HEAD(&byipsproto[i]);
|
|
}
|
|
|
|
+ /* FIXME: Man, this is a hack. <SIGH> */
|
|
IP_NF_ASSERT(ip_conntrack_destroyed == NULL);
|
|
ip_conntrack_destroyed = &ip_nat_cleanup_conntrack;
|
|
|
|
diff -Nurb 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 <kadlec@blackhole.kfki.hu>
|
|
- *
|
|
- * Based on ip_masq_h323.c for 2.2 kernels from CoRiTel, Sofia project.
|
|
- * (http://www.coritel.it/projects/sofia/nat.html)
|
|
- * Uses Sampsa Ranta's excellent idea on using expectfn to 'bind'
|
|
- * the unregistered helpers to the conntrack entries.
|
|
- */
|
|
-
|
|
-
|
|
-#include <linux/module.h>
|
|
-#include <linux/netfilter.h>
|
|
-#include <linux/ip.h>
|
|
-#include <net/checksum.h>
|
|
-#include <net/tcp.h>
|
|
-
|
|
-#include <linux/netfilter_ipv4/lockhelp.h>
|
|
-#include <linux/netfilter_ipv4/ip_nat.h>
|
|
-#include <linux/netfilter_ipv4/ip_nat_helper.h>
|
|
-#include <linux/netfilter_ipv4/ip_nat_rule.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
|
|
-
|
|
-MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
|
|
-MODULE_DESCRIPTION("H.323 'brute force' connection tracking module");
|
|
-MODULE_LICENSE("GPL");
|
|
-
|
|
-DECLARE_LOCK_EXTERN(ip_h323_lock);
|
|
-struct module *ip_nat_h323 = THIS_MODULE;
|
|
-
|
|
-#define DEBUGP(format, args...)
|
|
-
|
|
-
|
|
-static unsigned int
|
|
-h225_nat_expected(struct sk_buff **pskb,
|
|
- unsigned int hooknum,
|
|
- struct ip_conntrack *ct,
|
|
- struct ip_nat_info *info);
|
|
-
|
|
-static unsigned int h225_nat_help(struct ip_conntrack *ct,
|
|
- struct ip_conntrack_expect *exp,
|
|
- struct ip_nat_info *info,
|
|
- enum ip_conntrack_info ctinfo,
|
|
- unsigned int hooknum,
|
|
- struct sk_buff **pskb);
|
|
-
|
|
-static struct ip_nat_helper h245 =
|
|
- { { NULL, NULL },
|
|
- "H.245", /* name */
|
|
- 0, /* flags */
|
|
- NULL, /* module */
|
|
- { { 0, { 0 } }, /* tuple */
|
|
- { 0, { 0 }, IPPROTO_TCP } },
|
|
- { { 0, { 0xFFFF } }, /* mask */
|
|
- { 0, { 0 }, 0xFFFF } },
|
|
- h225_nat_help, /* helper */
|
|
- h225_nat_expected /* expectfn */
|
|
- };
|
|
-
|
|
-static unsigned int
|
|
-h225_nat_expected(struct sk_buff **pskb,
|
|
- unsigned int hooknum,
|
|
- struct ip_conntrack *ct,
|
|
- struct ip_nat_info *info)
|
|
-{
|
|
- struct ip_nat_multi_range mr;
|
|
- u_int32_t newdstip, newsrcip, newip;
|
|
- u_int16_t port;
|
|
- struct ip_ct_h225_expect *exp_info;
|
|
- struct ip_ct_h225_master *master_info;
|
|
- struct ip_conntrack *master = master_ct(ct);
|
|
- unsigned int is_h225, ret;
|
|
-
|
|
- IP_NF_ASSERT(info);
|
|
- IP_NF_ASSERT(master);
|
|
-
|
|
- IP_NF_ASSERT(!(info->initialized & (1<<HOOK2MANIP(hooknum))));
|
|
-
|
|
- DEBUGP("h225_nat_expected: We have a connection!\n");
|
|
- master_info = &ct->master->expectant->help.ct_h225_info;
|
|
- exp_info = &ct->master->help.exp_h225_info;
|
|
-
|
|
- LOCK_BH(&ip_h323_lock);
|
|
-
|
|
- DEBUGP("master: ");
|
|
- DUMP_TUPLE(&master->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
|
- DUMP_TUPLE(&master->tuplehash[IP_CT_DIR_REPLY].tuple);
|
|
- DEBUGP("conntrack: ");
|
|
- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
|
- if (exp_info->dir == IP_CT_DIR_ORIGINAL) {
|
|
- /* Make connection go to the client. */
|
|
- newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
|
|
- newsrcip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
|
|
- DEBUGP("h225_nat_expected: %u.%u.%u.%u->%u.%u.%u.%u (to client)\n",
|
|
- NIPQUAD(newsrcip), NIPQUAD(newdstip));
|
|
- } else {
|
|
- /* Make the connection go to the server */
|
|
- newdstip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
|
|
- newsrcip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
|
|
- DEBUGP("h225_nat_expected: %u.%u.%u.%u->%u.%u.%u.%u (to server)\n",
|
|
- NIPQUAD(newsrcip), NIPQUAD(newdstip));
|
|
- }
|
|
- port = exp_info->port;
|
|
- is_h225 = master_info->is_h225 == H225_PORT;
|
|
- UNLOCK_BH(&ip_h323_lock);
|
|
-
|
|
- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC)
|
|
- newip = newsrcip;
|
|
- else
|
|
- newip = newdstip;
|
|
-
|
|
- DEBUGP("h225_nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip));
|
|
-
|
|
- mr.rangesize = 1;
|
|
- /* We don't want to manip the per-protocol, just the IPs... */
|
|
- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS;
|
|
- mr.range[0].min_ip = mr.range[0].max_ip = newip;
|
|
-
|
|
- /* ... unless we're doing a MANIP_DST, in which case, make
|
|
- sure we map to the correct port */
|
|
- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) {
|
|
- mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
|
|
- mr.range[0].min = mr.range[0].max
|
|
- = ((union ip_conntrack_manip_proto)
|
|
- { port });
|
|
- }
|
|
-
|
|
- ret = ip_nat_setup_info(ct, &mr, hooknum);
|
|
-
|
|
- if (is_h225) {
|
|
- DEBUGP("h225_nat_expected: H.225, setting NAT helper for %p\n", ct);
|
|
- /* NAT expectfn called with ip_nat_lock write-locked */
|
|
- info->helper = &h245;
|
|
- }
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static int h323_signal_address_fixup(struct ip_conntrack *ct,
|
|
- struct sk_buff **pskb,
|
|
- enum ip_conntrack_info ctinfo)
|
|
-{
|
|
- struct iphdr *iph = (*pskb)->nh.iph;
|
|
- struct tcphdr *tcph = (void *)iph + iph->ihl*4;
|
|
- unsigned char *data;
|
|
- u_int32_t tcplen = (*pskb)->len - iph->ihl*4;
|
|
- u_int32_t datalen = tcplen - tcph->doff*4;
|
|
- struct ip_ct_h225_master *info = &ct->help.ct_h225_info;
|
|
- u_int32_t newip;
|
|
- u_int16_t port;
|
|
- u_int8_t buffer[6];
|
|
- int i;
|
|
-
|
|
- MUST_BE_LOCKED(&ip_h323_lock);
|
|
-
|
|
- DEBUGP("h323_signal_address_fixup: %s %s\n",
|
|
- between(info->seq[IP_CT_DIR_ORIGINAL], ntohl(tcph->seq), ntohl(tcph->seq) + datalen)
|
|
- ? "yes" : "no",
|
|
- between(info->seq[IP_CT_DIR_REPLY], ntohl(tcph->seq), ntohl(tcph->seq) + datalen)
|
|
- ? "yes" : "no");
|
|
- if (!(between(info->seq[IP_CT_DIR_ORIGINAL], ntohl(tcph->seq), ntohl(tcph->seq) + datalen)
|
|
- || between(info->seq[IP_CT_DIR_REPLY], ntohl(tcph->seq), ntohl(tcph->seq) + datalen)))
|
|
- return 1;
|
|
-
|
|
- DEBUGP("h323_signal_address_fixup: offsets %u + 6 and %u + 6 in %u\n",
|
|
- info->offset[IP_CT_DIR_ORIGINAL],
|
|
- info->offset[IP_CT_DIR_REPLY],
|
|
- tcplen);
|
|
- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
|
- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
|
|
-
|
|
- for (i = 0; i < IP_CT_DIR_MAX; i++) {
|
|
- DEBUGP("h323_signal_address_fixup: %s %s\n",
|
|
- info->dir == IP_CT_DIR_ORIGINAL ? "original" : "reply",
|
|
- i == IP_CT_DIR_ORIGINAL ? "caller" : "callee");
|
|
- if (!between(info->seq[i], ntohl(tcph->seq),
|
|
- ntohl(tcph->seq) + datalen))
|
|
- continue;
|
|
- if (!between(info->seq[i] + 6, ntohl(tcph->seq),
|
|
- ntohl(tcph->seq) + datalen)) {
|
|
- /* Partial retransmisison. It's a cracker being funky. */
|
|
- if (net_ratelimit()) {
|
|
- printk("H.323_NAT: partial packet %u/6 in %u/%u\n",
|
|
- info->seq[i],
|
|
- ntohl(tcph->seq),
|
|
- ntohl(tcph->seq) + datalen);
|
|
- }
|
|
- return 0;
|
|
- }
|
|
-
|
|
- /* Change address inside packet to match way we're mapping
|
|
- this connection. */
|
|
- if (i == IP_CT_DIR_ORIGINAL) {
|
|
- newip = ct->tuplehash[!info->dir].tuple.dst.ip;
|
|
- port = ct->tuplehash[!info->dir].tuple.dst.u.tcp.port;
|
|
- } else {
|
|
- newip = ct->tuplehash[!info->dir].tuple.src.ip;
|
|
- port = ct->tuplehash[!info->dir].tuple.src.u.tcp.port;
|
|
- }
|
|
-
|
|
- data = (char *) tcph + tcph->doff * 4 + info->offset[i];
|
|
-
|
|
- DEBUGP("h323_signal_address_fixup: orig %s IP:port %u.%u.%u.%u:%u\n",
|
|
- i == IP_CT_DIR_ORIGINAL ? "source" : "dest ",
|
|
- data[0], data[1], data[2], data[3],
|
|
- (data[4] << 8 | data[5]));
|
|
-
|
|
- /* Modify the packet */
|
|
- memcpy(buffer, &newip, 4);
|
|
- memcpy(buffer + 4, &port, 2);
|
|
- if (!ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, info->offset[i],
|
|
- 6, buffer, 6))
|
|
- return 0;
|
|
-
|
|
- DEBUGP("h323_signal_address_fixup: new %s IP:port %u.%u.%u.%u:%u\n",
|
|
- i == IP_CT_DIR_ORIGINAL ? "source" : "dest ",
|
|
- data[0], data[1], data[2], data[3],
|
|
- (data[4] << 8 | data[5]));
|
|
- }
|
|
-
|
|
- return 1;
|
|
-}
|
|
-
|
|
-static int h323_data_fixup(struct ip_ct_h225_expect *info,
|
|
- struct ip_conntrack *ct,
|
|
- struct sk_buff **pskb,
|
|
- enum ip_conntrack_info ctinfo,
|
|
- struct ip_conntrack_expect *expect)
|
|
-{
|
|
- u_int32_t newip;
|
|
- u_int16_t port;
|
|
- u_int8_t buffer[6];
|
|
- struct ip_conntrack_tuple newtuple;
|
|
- struct iphdr *iph = (*pskb)->nh.iph;
|
|
- struct tcphdr *tcph = (void *)iph + iph->ihl*4;
|
|
- unsigned char *data;
|
|
- u_int32_t tcplen = (*pskb)->len - iph->ihl*4;
|
|
- struct ip_ct_h225_master *master_info = &ct->help.ct_h225_info;
|
|
- int is_h225;
|
|
-
|
|
- MUST_BE_LOCKED(&ip_h323_lock);
|
|
- DEBUGP("h323_data_fixup: offset %u + 6 in %u\n", info->offset, tcplen);
|
|
- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
|
- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
|
|
-
|
|
- if (!between(expect->seq + 6, ntohl(tcph->seq),
|
|
- ntohl(tcph->seq) + tcplen - tcph->doff * 4)) {
|
|
- /* Partial retransmisison. It's a cracker being funky. */
|
|
- if (net_ratelimit()) {
|
|
- printk("H.323_NAT: partial packet %u/6 in %u/%u\n",
|
|
- expect->seq,
|
|
- ntohl(tcph->seq),
|
|
- ntohl(tcph->seq) + tcplen - tcph->doff * 4);
|
|
- }
|
|
- return 0;
|
|
- }
|
|
-
|
|
- /* Change address inside packet to match way we're mapping
|
|
- this connection. */
|
|
- if (info->dir == IP_CT_DIR_REPLY) {
|
|
- /* Must be where client thinks server is */
|
|
- newip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
|
|
- /* Expect something from client->server */
|
|
- newtuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
|
|
- newtuple.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
|
|
- } else {
|
|
- /* Must be where server thinks client is */
|
|
- newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
|
|
- /* Expect something from server->client */
|
|
- newtuple.src.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
|
|
- newtuple.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
|
|
- }
|
|
-
|
|
- is_h225 = (master_info->is_h225 == H225_PORT);
|
|
-
|
|
- if (is_h225) {
|
|
- newtuple.dst.protonum = IPPROTO_TCP;
|
|
- newtuple.src.u.tcp.port = expect->tuple.src.u.tcp.port;
|
|
- } else {
|
|
- newtuple.dst.protonum = IPPROTO_UDP;
|
|
- newtuple.src.u.udp.port = expect->tuple.src.u.udp.port;
|
|
- }
|
|
-
|
|
- /* Try to get same port: if not, try to change it. */
|
|
- for (port = ntohs(info->port); port != 0; port++) {
|
|
- if (is_h225)
|
|
- newtuple.dst.u.tcp.port = htons(port);
|
|
- else
|
|
- newtuple.dst.u.udp.port = htons(port);
|
|
-
|
|
- if (ip_conntrack_change_expect(expect, &newtuple) == 0)
|
|
- break;
|
|
- }
|
|
- if (port == 0) {
|
|
- DEBUGP("h323_data_fixup: no free port found!\n");
|
|
- return 0;
|
|
- }
|
|
-
|
|
- port = htons(port);
|
|
-
|
|
- data = (char *) tcph + tcph->doff * 4 + info->offset;
|
|
-
|
|
- DEBUGP("h323_data_fixup: orig IP:port %u.%u.%u.%u:%u\n",
|
|
- data[0], data[1], data[2], data[3],
|
|
- (data[4] << 8 | data[5]));
|
|
-
|
|
- /* Modify the packet */
|
|
- memcpy(buffer, &newip, 4);
|
|
- memcpy(buffer + 4, &port, 2);
|
|
- if (!ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, info->offset,
|
|
- 6, buffer, 6))
|
|
- return 0;
|
|
-
|
|
- DEBUGP("h323_data_fixup: new IP:port %u.%u.%u.%u:%u\n",
|
|
- data[0], data[1], data[2], data[3],
|
|
- (data[4] << 8 | data[5]));
|
|
-
|
|
- return 1;
|
|
-}
|
|
-
|
|
-static unsigned int h225_nat_help(struct ip_conntrack *ct,
|
|
- struct ip_conntrack_expect *exp,
|
|
- struct ip_nat_info *info,
|
|
- enum ip_conntrack_info ctinfo,
|
|
- unsigned int hooknum,
|
|
- struct sk_buff **pskb)
|
|
-{
|
|
- int dir;
|
|
- struct ip_ct_h225_expect *exp_info;
|
|
-
|
|
- /* Only mangle things once: original direction in POST_ROUTING
|
|
- and reply direction on PRE_ROUTING. */
|
|
- dir = CTINFO2DIR(ctinfo);
|
|
- DEBUGP("nat_h323: dir %s at hook %s\n",
|
|
- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
|
|
- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
|
|
- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
|
|
- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???");
|
|
- if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL)
|
|
- || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) {
|
|
- DEBUGP("nat_h323: Not touching dir %s at hook %s\n",
|
|
- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
|
|
- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
|
|
- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
|
|
- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???");
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- if (!exp) {
|
|
- LOCK_BH(&ip_h323_lock);
|
|
- if (!h323_signal_address_fixup(ct, pskb, ctinfo)) {
|
|
- UNLOCK_BH(&ip_h323_lock);
|
|
- return NF_DROP;
|
|
- }
|
|
- UNLOCK_BH(&ip_h323_lock);
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- exp_info = &exp->help.exp_h225_info;
|
|
-
|
|
- LOCK_BH(&ip_h323_lock);
|
|
- if (!h323_data_fixup(exp_info, ct, pskb, ctinfo, exp)) {
|
|
- UNLOCK_BH(&ip_h323_lock);
|
|
- return NF_DROP;
|
|
- }
|
|
- UNLOCK_BH(&ip_h323_lock);
|
|
-
|
|
- return NF_ACCEPT;
|
|
-}
|
|
-
|
|
-static struct ip_nat_helper h225 =
|
|
- { { NULL, NULL },
|
|
- "H.225", /* name */
|
|
- IP_NAT_HELPER_F_ALWAYS, /* flags */
|
|
- THIS_MODULE, /* module */
|
|
- { { 0, { __constant_htons(H225_PORT) } }, /* tuple */
|
|
- { 0, { 0 }, IPPROTO_TCP } },
|
|
- { { 0, { 0xFFFF } }, /* mask */
|
|
- { 0, { 0 }, 0xFFFF } },
|
|
- h225_nat_help, /* helper */
|
|
- h225_nat_expected /* expectfn */
|
|
- };
|
|
-
|
|
-static int __init init(void)
|
|
-{
|
|
- int ret;
|
|
-
|
|
- ret = ip_nat_helper_register(&h225);
|
|
-
|
|
- if (ret != 0)
|
|
- printk("ip_nat_h323: cannot initialize the module!\n");
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static void __exit fini(void)
|
|
-{
|
|
- ip_nat_helper_unregister(&h225);
|
|
-}
|
|
-
|
|
-module_init(init);
|
|
-module_exit(fini);
|
|
diff -Nurb 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 <laforge@gnumonks.org>:
|
|
* - merge SACK support into newnat API
|
|
- * 16 Aug 2002 Brian J. Murrell <netfilter@interlinx.bc.ca>:
|
|
- * - make ip_nat_resize_packet more generic (TCP and UDP)
|
|
- * - add ip_nat_mangle_udp_packet
|
|
*/
|
|
#include <linux/version.h>
|
|
#include <linux/config.h>
|
|
@@ -25,7 +22,6 @@
|
|
#include <net/icmp.h>
|
|
#include <net/ip.h>
|
|
#include <net/tcp.h>
|
|
-#include <net/udp.h>
|
|
|
|
#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock)
|
|
#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock)
|
|
@@ -38,8 +34,13 @@
|
|
#include <linux/netfilter_ipv4/ip_nat_helper.h>
|
|
#include <linux/netfilter_ipv4/listhelp.h>
|
|
|
|
+#if 0
|
|
+#define DEBUGP printk
|
|
+#define DUMP_OFFSET(x) printk("offset_before=%d, offset_after=%d, correction_pos=%u\n", x->offset_before, x->offset_after, x->correction_pos);
|
|
+#else
|
|
#define DEBUGP(format, args...)
|
|
#define DUMP_OFFSET(x)
|
|
+#endif
|
|
|
|
DECLARE_LOCK(ip_nat_seqofs_lock);
|
|
|
|
@@ -50,12 +51,18 @@
|
|
int new_size)
|
|
{
|
|
struct iphdr *iph;
|
|
+ struct tcphdr *tcph;
|
|
+ void *data;
|
|
int dir;
|
|
struct ip_nat_seq *this_way, *other_way;
|
|
|
|
DEBUGP("ip_nat_resize_packet: old_size = %u, new_size = %u\n",
|
|
(*skb)->len, new_size);
|
|
|
|
+ iph = (*skb)->nh.iph;
|
|
+ tcph = (void *)iph + iph->ihl*4;
|
|
+ data = (void *)tcph + tcph->doff*4;
|
|
+
|
|
dir = CTINFO2DIR(ctinfo);
|
|
|
|
this_way = &ct->nat.info.seq[dir];
|
|
@@ -77,9 +84,8 @@
|
|
}
|
|
|
|
iph = (*skb)->nh.iph;
|
|
- if (iph->protocol == IPPROTO_TCP) {
|
|
- struct tcphdr *tcph = (void *)iph + iph->ihl*4;
|
|
- void *data = (void *)tcph + tcph->doff*4;
|
|
+ tcph = (void *)iph + iph->ihl*4;
|
|
+ data = (void *)tcph + tcph->doff*4;
|
|
|
|
DEBUGP("ip_nat_resize_packet: Seq_offset before: ");
|
|
DUMP_OFFSET(this_way);
|
|
@@ -95,20 +101,25 @@
|
|
this_way->correction_pos = ntohl(tcph->seq);
|
|
this_way->offset_before = this_way->offset_after;
|
|
this_way->offset_after = (int32_t)
|
|
- this_way->offset_before + new_size -
|
|
- (*skb)->len;
|
|
+ this_way->offset_before + new_size - (*skb)->len;
|
|
}
|
|
|
|
UNLOCK_BH(&ip_nat_seqofs_lock);
|
|
|
|
DEBUGP("ip_nat_resize_packet: Seq_offset after: ");
|
|
DUMP_OFFSET(this_way);
|
|
- }
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
+/* Generic function for mangling variable-length address changes inside
|
|
+ * NATed connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX command in FTP).
|
|
+ *
|
|
+ * Takes care about all the nasty sequence number changes, checksumming,
|
|
+ * skb enlargement, ...
|
|
+ *
|
|
+ * */
|
|
int
|
|
ip_nat_mangle_tcp_packet(struct sk_buff **skb,
|
|
struct ip_conntrack *ct,
|
|
@@ -163,7 +174,6 @@
|
|
tcph = (void *)iph + iph->ihl*4;
|
|
data = (void *)tcph + tcph->doff*4;
|
|
|
|
- if (rep_len != match_len)
|
|
/* move post-replacement */
|
|
memmove(data + match_offset + rep_len,
|
|
data + match_offset + match_len,
|
|
@@ -198,104 +208,6 @@
|
|
return 1;
|
|
}
|
|
|
|
-int
|
|
-ip_nat_mangle_udp_packet(struct sk_buff **skb,
|
|
- struct ip_conntrack *ct,
|
|
- enum ip_conntrack_info ctinfo,
|
|
- unsigned int match_offset,
|
|
- unsigned int match_len,
|
|
- char *rep_buffer,
|
|
- unsigned int rep_len)
|
|
-{
|
|
- struct iphdr *iph = (*skb)->nh.iph;
|
|
- struct udphdr *udph = (void *)iph + iph->ihl * 4;
|
|
- unsigned char *data;
|
|
- u_int32_t udplen, newlen, newudplen;
|
|
-
|
|
- udplen = (*skb)->len - iph->ihl*4;
|
|
- newudplen = udplen - match_len + rep_len;
|
|
- newlen = iph->ihl*4 + newudplen;
|
|
-
|
|
- if (newlen > 65535) {
|
|
- if (net_ratelimit())
|
|
- printk("ip_nat_mangle_udp_packet: nat'ed packet "
|
|
- "exceeds maximum packet size\n");
|
|
- return 0;
|
|
- }
|
|
-
|
|
- if ((*skb)->len != newlen) {
|
|
- if (!ip_nat_resize_packet(skb, ct, ctinfo, newlen)) {
|
|
- printk("resize_packet failed!!\n");
|
|
- return 0;
|
|
- }
|
|
- }
|
|
-
|
|
- /* Alexey says: if a hook changes _data_ ... it can break
|
|
- original packet sitting in tcp queue and this is fatal */
|
|
- if (skb_cloned(*skb)) {
|
|
- struct sk_buff *nskb = skb_copy(*skb, GFP_ATOMIC);
|
|
- if (!nskb) {
|
|
- if (net_ratelimit())
|
|
- printk("Out of memory cloning TCP packet\n");
|
|
- return 0;
|
|
- }
|
|
- /* Rest of kernel will get very unhappy if we pass it
|
|
- a suddenly-orphaned skbuff */
|
|
- if ((*skb)->sk)
|
|
- skb_set_owner_w(nskb, (*skb)->sk);
|
|
- kfree_skb(*skb);
|
|
- *skb = nskb;
|
|
- }
|
|
-
|
|
- /* skb may be copied !! */
|
|
- iph = (*skb)->nh.iph;
|
|
- udph = (void *)iph + iph->ihl*4;
|
|
- data = (void *)udph + sizeof(struct udphdr);
|
|
-
|
|
- if (rep_len != match_len)
|
|
- /* move post-replacement */
|
|
- memmove(data + match_offset + rep_len,
|
|
- data + match_offset + match_len,
|
|
- (*skb)->tail - (data + match_offset + match_len));
|
|
-
|
|
- /* insert data from buffer */
|
|
- memcpy(data + match_offset, rep_buffer, rep_len);
|
|
-
|
|
- /* update skb info */
|
|
- if (newlen > (*skb)->len) {
|
|
- DEBUGP("ip_nat_mangle_udp_packet: Extending packet by "
|
|
- "%u to %u bytes\n", newlen - (*skb)->len, newlen);
|
|
- skb_put(*skb, newlen - (*skb)->len);
|
|
- } else {
|
|
- DEBUGP("ip_nat_mangle_udp_packet: Shrinking packet from "
|
|
- "%u to %u bytes\n", (*skb)->len, newlen);
|
|
- skb_trim(*skb, newlen);
|
|
- }
|
|
-
|
|
- /* update the length of the UDP and IP packets to the new values*/
|
|
- udph->len = htons((*skb)->len - iph->ihl*4);
|
|
- iph->tot_len = htons(newlen);
|
|
-
|
|
- /* fix udp checksum if udp checksum was previously calculated */
|
|
- if ((*skb)->csum != 0) {
|
|
- (*skb)->csum = csum_partial((char *)udph +
|
|
- sizeof(struct udphdr),
|
|
- newudplen - sizeof(struct udphdr),
|
|
- 0);
|
|
-
|
|
- udph->check = 0;
|
|
- udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
|
|
- newudplen, IPPROTO_UDP,
|
|
- csum_partial((char *)udph,
|
|
- sizeof(struct udphdr),
|
|
- (*skb)->csum));
|
|
- }
|
|
-
|
|
- ip_send_check(iph);
|
|
-
|
|
- return 1;
|
|
-}
|
|
-
|
|
/* Adjust one found SACK option including checksum correction */
|
|
static void
|
|
sack_adjust(struct tcphdr *tcph,
|
|
diff -Nurb 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 <filip.sneppe@cronos.be>
|
|
- * based on ip_nat_ftp.c and ip_nat_irc.c
|
|
- *
|
|
- * ip_nat_mms.c v0.3 2002-09-22
|
|
- *
|
|
- * This program is free software; you can redistribute it and/or
|
|
- * modify it under the terms of the GNU General Public License
|
|
- * as published by the Free Software Foundation; either version
|
|
- * 2 of the License, or (at your option) any later version.
|
|
- *
|
|
- * Module load syntax:
|
|
- * insmod ip_nat_mms.o ports=port1,port2,...port<MAX_PORTS>
|
|
- *
|
|
- * Please give the ports of all MMS servers You wish to connect to.
|
|
- * If you don't specify ports, the default will be TCP port 1755.
|
|
- *
|
|
- * More info on MMS protocol, firewalls and NAT:
|
|
- * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/MMSFirewall.asp
|
|
- * http://www.microsoft.com/windows/windowsmedia/serve/firewall.asp
|
|
- *
|
|
- * The SDP project people are reverse-engineering MMS:
|
|
- * http://get.to/sdp
|
|
- */
|
|
-
|
|
-
|
|
-#include <linux/module.h>
|
|
-#include <linux/netfilter_ipv4.h>
|
|
-#include <linux/ip.h>
|
|
-#include <linux/tcp.h>
|
|
-#include <net/tcp.h>
|
|
-#include <linux/netfilter_ipv4/ip_nat.h>
|
|
-#include <linux/netfilter_ipv4/ip_nat_helper.h>
|
|
-#include <linux/netfilter_ipv4/ip_nat_rule.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_mms.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
|
-
|
|
-#define DEBUGP(format, args...)
|
|
-#define DUMP_BYTES(address, counter)
|
|
-
|
|
-#define MAX_PORTS 8
|
|
-static int ports[MAX_PORTS];
|
|
-static int ports_c = 0;
|
|
-
|
|
-#ifdef MODULE_PARM
|
|
-MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
|
|
-#endif
|
|
-
|
|
-MODULE_AUTHOR("Filip Sneppe <filip.sneppe@cronos.be>");
|
|
-MODULE_DESCRIPTION("Microsoft Windows Media Services (MMS) NAT module");
|
|
-MODULE_LICENSE("GPL");
|
|
-
|
|
-DECLARE_LOCK_EXTERN(ip_mms_lock);
|
|
-
|
|
-
|
|
-static int mms_data_fixup(const struct ip_ct_mms_expect *ct_mms_info,
|
|
- struct ip_conntrack *ct,
|
|
- struct sk_buff **pskb,
|
|
- enum ip_conntrack_info ctinfo,
|
|
- struct ip_conntrack_expect *expect)
|
|
-{
|
|
- u_int32_t newip;
|
|
- struct ip_conntrack_tuple t;
|
|
- struct iphdr *iph = (*pskb)->nh.iph;
|
|
- struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
|
|
- char *data = (char *)tcph + tcph->doff * 4;
|
|
- int i, j, k, port;
|
|
- u_int16_t mms_proto;
|
|
-
|
|
- u_int32_t *mms_chunkLenLV = (u_int32_t *)(data + MMS_SRV_CHUNKLENLV_OFFSET);
|
|
- u_int32_t *mms_chunkLenLM = (u_int32_t *)(data + MMS_SRV_CHUNKLENLM_OFFSET);
|
|
- u_int32_t *mms_messageLength = (u_int32_t *)(data + MMS_SRV_MESSAGELENGTH_OFFSET);
|
|
-
|
|
- int zero_padding;
|
|
-
|
|
- char buffer[28]; /* "\\255.255.255.255\UDP\65635" * 2 (for unicode) */
|
|
- char unicode_buffer[75]; /* 27*2 (unicode) + 20 + 1 */
|
|
- char proto_string[6];
|
|
-
|
|
- MUST_BE_LOCKED(&ip_mms_lock);
|
|
-
|
|
- /* what was the protocol again ? */
|
|
- mms_proto = expect->tuple.dst.protonum;
|
|
- sprintf(proto_string, "%u", mms_proto);
|
|
-
|
|
- DEBUGP("ip_nat_mms: mms_data_fixup: info (seq %u + %u) in %u, proto %s\n",
|
|
- expect->seq, ct_mms_info->len, ntohl(tcph->seq),
|
|
- mms_proto == IPPROTO_UDP ? "UDP"
|
|
- : mms_proto == IPPROTO_TCP ? "TCP":proto_string);
|
|
-
|
|
- newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
|
|
-
|
|
- /* Alter conntrack's expectations. */
|
|
- t = expect->tuple;
|
|
- t.dst.ip = newip;
|
|
- for (port = ct_mms_info->port; port != 0; port++) {
|
|
- t.dst.u.tcp.port = htons(port);
|
|
- if (ip_conntrack_change_expect(expect, &t) == 0) {
|
|
- DEBUGP("ip_nat_mms: mms_data_fixup: using port %d\n", port);
|
|
- break;
|
|
- }
|
|
- }
|
|
-
|
|
- if(port == 0)
|
|
- return 0;
|
|
-
|
|
- sprintf(buffer, "\\\\%u.%u.%u.%u\\%s\\%u",
|
|
- NIPQUAD(newip),
|
|
- expect->tuple.dst.protonum == IPPROTO_UDP ? "UDP"
|
|
- : expect->tuple.dst.protonum == IPPROTO_TCP ? "TCP":proto_string,
|
|
- port);
|
|
- DEBUGP("ip_nat_mms: new unicode string=%s\n", buffer);
|
|
-
|
|
- memset(unicode_buffer, 0, sizeof(char)*75);
|
|
-
|
|
- for (i=0; i<strlen(buffer); ++i)
|
|
- *(unicode_buffer+i*2)=*(buffer+i);
|
|
-
|
|
- DEBUGP("ip_nat_mms: mms_data_fixup: padding: %u len: %u\n", ct_mms_info->padding, ct_mms_info->len);
|
|
- DEBUGP("ip_nat_mms: mms_data_fixup: offset: %u\n", MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len);
|
|
- DUMP_BYTES(data+MMS_SRV_UNICODE_STRING_OFFSET, 60);
|
|
-
|
|
- /* add end of packet to it */
|
|
- for (j=0; j<ct_mms_info->padding; ++j) {
|
|
- DEBUGP("ip_nat_mms: mms_data_fixup: i=%u j=%u byte=%u\n",
|
|
- i, j, (u8)*(data+MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len+j));
|
|
- *(unicode_buffer+i*2+j) = *(data+MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len+j);
|
|
- }
|
|
-
|
|
- /* pad with zeroes at the end ? see explanation of weird math below */
|
|
- zero_padding = (8-(strlen(buffer)*2 + ct_mms_info->padding + 4)%8)%8;
|
|
- for (k=0; k<zero_padding; ++k)
|
|
- *(unicode_buffer+i*2+j+k)= (char)0;
|
|
-
|
|
- DEBUGP("ip_nat_mms: mms_data_fixup: zero_padding = %u\n", zero_padding);
|
|
- DEBUGP("ip_nat_mms: original=> chunkLenLV=%u chunkLenLM=%u messageLength=%u\n",
|
|
- *mms_chunkLenLV, *mms_chunkLenLM, *mms_messageLength);
|
|
-
|
|
- /* explanation, before I forget what I did:
|
|
- strlen(buffer)*2 + ct_mms_info->padding + 4 must be divisable by 8;
|
|
- divide by 8 and add 3 to compute the mms_chunkLenLM field,
|
|
- but note that things may have to be padded with zeroes to align by 8
|
|
- bytes, hence we add 7 and divide by 8 to get the correct length */
|
|
- *mms_chunkLenLM = (u_int32_t) (3+(strlen(buffer)*2+ct_mms_info->padding+11)/8);
|
|
- *mms_chunkLenLV = *mms_chunkLenLM+2;
|
|
- *mms_messageLength = *mms_chunkLenLV*8;
|
|
-
|
|
- DEBUGP("ip_nat_mms: modified=> chunkLenLV=%u chunkLenLM=%u messageLength=%u\n",
|
|
- *mms_chunkLenLV, *mms_chunkLenLM, *mms_messageLength);
|
|
-
|
|
- ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
|
|
- expect->seq - ntohl(tcph->seq),
|
|
- ct_mms_info->len + ct_mms_info->padding, unicode_buffer,
|
|
- strlen(buffer)*2 + ct_mms_info->padding + zero_padding);
|
|
- DUMP_BYTES(unicode_buffer, 60);
|
|
-
|
|
- return 1;
|
|
-}
|
|
-
|
|
-static unsigned int
|
|
-mms_nat_expected(struct sk_buff **pskb,
|
|
- unsigned int hooknum,
|
|
- struct ip_conntrack *ct,
|
|
- struct ip_nat_info *info)
|
|
-{
|
|
- struct ip_nat_multi_range mr;
|
|
- u_int32_t newdstip, newsrcip, newip;
|
|
-
|
|
- struct ip_conntrack *master = master_ct(ct);
|
|
-
|
|
- IP_NF_ASSERT(info);
|
|
- IP_NF_ASSERT(master);
|
|
-
|
|
- IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
|
|
-
|
|
- DEBUGP("ip_nat_mms: mms_nat_expected: We have a connection!\n");
|
|
-
|
|
- newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
|
|
- newsrcip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
|
|
- DEBUGP("ip_nat_mms: mms_nat_expected: hook %s: newsrc->newdst %u.%u.%u.%u->%u.%u.%u.%u\n",
|
|
- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
|
|
- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
|
|
- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???",
|
|
- NIPQUAD(newsrcip), NIPQUAD(newdstip));
|
|
-
|
|
- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC)
|
|
- newip = newsrcip;
|
|
- else
|
|
- newip = newdstip;
|
|
-
|
|
- DEBUGP("ip_nat_mms: mms_nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip));
|
|
-
|
|
- mr.rangesize = 1;
|
|
- /* We don't want to manip the per-protocol, just the IPs. */
|
|
- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS;
|
|
- mr.range[0].min_ip = mr.range[0].max_ip = newip;
|
|
-
|
|
- return ip_nat_setup_info(ct, &mr, hooknum);
|
|
-}
|
|
-
|
|
-
|
|
-static unsigned int mms_nat_help(struct ip_conntrack *ct,
|
|
- struct ip_conntrack_expect *exp,
|
|
- struct ip_nat_info *info,
|
|
- enum ip_conntrack_info ctinfo,
|
|
- unsigned int hooknum,
|
|
- struct sk_buff **pskb)
|
|
-{
|
|
- struct iphdr *iph = (*pskb)->nh.iph;
|
|
- struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
|
|
- unsigned int datalen;
|
|
- int dir;
|
|
- struct ip_ct_mms_expect *ct_mms_info;
|
|
-
|
|
- if (!exp)
|
|
- DEBUGP("ip_nat_mms: no exp!!");
|
|
-
|
|
- ct_mms_info = &exp->help.exp_mms_info;
|
|
-
|
|
- /* Only mangle things once: original direction in POST_ROUTING
|
|
- and reply direction on PRE_ROUTING. */
|
|
- dir = CTINFO2DIR(ctinfo);
|
|
- if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL)
|
|
- ||(hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) {
|
|
- DEBUGP("ip_nat_mms: mms_nat_help: not touching dir %s at hook %s\n",
|
|
- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
|
|
- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
|
|
- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
|
|
- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???");
|
|
- return NF_ACCEPT;
|
|
- }
|
|
- DEBUGP("ip_nat_mms: mms_nat_help: beyond not touching (dir %s at hook %s)\n",
|
|
- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
|
|
- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
|
|
- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
|
|
- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???");
|
|
-
|
|
- datalen = (*pskb)->len - iph->ihl * 4 - tcph->doff * 4;
|
|
-
|
|
- DEBUGP("ip_nat_mms: mms_nat_help: %u+%u=%u %u %u\n", exp->seq, ct_mms_info->len,
|
|
- exp->seq + ct_mms_info->len,
|
|
- ntohl(tcph->seq),
|
|
- ntohl(tcph->seq) + datalen);
|
|
-
|
|
- LOCK_BH(&ip_mms_lock);
|
|
- /* Check wether the whole IP/proto/port pattern is carried in the payload */
|
|
- if (between(exp->seq + ct_mms_info->len,
|
|
- ntohl(tcph->seq),
|
|
- ntohl(tcph->seq) + datalen)) {
|
|
- if (!mms_data_fixup(ct_mms_info, ct, pskb, ctinfo, exp)) {
|
|
- UNLOCK_BH(&ip_mms_lock);
|
|
- return NF_DROP;
|
|
- }
|
|
- } else {
|
|
- /* Half a match? This means a partial retransmisison.
|
|
- It's a cracker being funky. */
|
|
- if (net_ratelimit()) {
|
|
- printk("ip_nat_mms: partial packet %u/%u in %u/%u\n",
|
|
- exp->seq, ct_mms_info->len,
|
|
- ntohl(tcph->seq),
|
|
- ntohl(tcph->seq) + datalen);
|
|
- }
|
|
- UNLOCK_BH(&ip_mms_lock);
|
|
- return NF_DROP;
|
|
- }
|
|
- UNLOCK_BH(&ip_mms_lock);
|
|
-
|
|
- return NF_ACCEPT;
|
|
-}
|
|
-
|
|
-static struct ip_nat_helper mms[MAX_PORTS];
|
|
-static char mms_names[MAX_PORTS][10];
|
|
-
|
|
-/* Not __exit: called from init() */
|
|
-static void fini(void)
|
|
-{
|
|
- int i;
|
|
-
|
|
- for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
|
|
- DEBUGP("ip_nat_mms: unregistering helper for port %d\n", ports[i]);
|
|
- ip_nat_helper_unregister(&mms[i]);
|
|
- }
|
|
-}
|
|
-
|
|
-static int __init init(void)
|
|
-{
|
|
- int i, ret = 0;
|
|
- char *tmpname;
|
|
-
|
|
- if (ports[0] == 0)
|
|
- ports[0] = MMS_PORT;
|
|
-
|
|
- for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
|
|
-
|
|
- memset(&mms[i], 0, sizeof(struct ip_nat_helper));
|
|
-
|
|
- mms[i].tuple.dst.protonum = IPPROTO_TCP;
|
|
- mms[i].tuple.src.u.tcp.port = htons(ports[i]);
|
|
- mms[i].mask.dst.protonum = 0xFFFF;
|
|
- mms[i].mask.src.u.tcp.port = 0xFFFF;
|
|
- mms[i].help = mms_nat_help;
|
|
- mms[i].me = THIS_MODULE;
|
|
- mms[i].flags = 0;
|
|
- mms[i].expect = mms_nat_expected;
|
|
-
|
|
- tmpname = &mms_names[i][0];
|
|
- if (ports[i] == MMS_PORT)
|
|
- sprintf(tmpname, "mms");
|
|
- else
|
|
- sprintf(tmpname, "mms-%d", i);
|
|
- mms[i].name = tmpname;
|
|
-
|
|
- DEBUGP("ip_nat_mms: register helper for port %d\n",
|
|
- ports[i]);
|
|
- ret = ip_nat_helper_register(&mms[i]);
|
|
-
|
|
- if (ret) {
|
|
- printk("ip_nat_mms: error registering "
|
|
- "helper for port %d\n", ports[i]);
|
|
- fini();
|
|
- return ret;
|
|
- }
|
|
- ports_c++;
|
|
- }
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
-module_init(init);
|
|
-module_exit(fini);
|
|
diff -Nurb 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 <laforge@gnumonks.org>
|
|
- *
|
|
- * Development of this code funded by Astaro AG (http://www.astaro.com/)
|
|
- *
|
|
- * TODO: - Support for multiple calls within one session
|
|
- * (needs netfilter newnat code)
|
|
- * - NAT to a unique tuple, not to TCP source port
|
|
- * (needs netfilter tuple reservation)
|
|
- * - Support other NAT scenarios than SNAT of PNS
|
|
- *
|
|
- */
|
|
-
|
|
-#include <linux/config.h>
|
|
-#include <linux/module.h>
|
|
-#include <linux/ip.h>
|
|
-#include <linux/tcp.h>
|
|
-#include <net/tcp.h>
|
|
-#include <linux/netfilter_ipv4/ip_nat.h>
|
|
-#include <linux/netfilter_ipv4/ip_nat_rule.h>
|
|
-#include <linux/netfilter_ipv4/ip_nat_helper.h>
|
|
-#include <linux/netfilter_ipv4/ip_nat_pptp.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
|
|
-
|
|
-MODULE_LICENSE("GPL");
|
|
-MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
|
|
-MODULE_DESCRIPTION("Netfilter NAT helper module for PPTP");
|
|
-
|
|
-
|
|
-#define DEBUGP(format, args...)
|
|
-
|
|
-static unsigned int
|
|
-pptp_nat_expected(struct sk_buff **pskb,
|
|
- unsigned int hooknum,
|
|
- struct ip_conntrack *ct,
|
|
- struct ip_nat_info *info)
|
|
-{
|
|
- struct ip_conntrack *master = master_ct(ct);
|
|
- struct ip_nat_multi_range mr;
|
|
- struct ip_ct_pptp_master *ct_pptp_info;
|
|
- struct ip_nat_pptp *nat_pptp_info;
|
|
- u_int32_t newsrcip, newdstip, newcid;
|
|
- int ret;
|
|
-
|
|
- IP_NF_ASSERT(info);
|
|
- IP_NF_ASSERT(master);
|
|
- IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
|
|
-
|
|
- DEBUGP("we have a connection!\n");
|
|
-
|
|
- LOCK_BH(&ip_pptp_lock);
|
|
- ct_pptp_info = &master->help.ct_pptp_info;
|
|
- nat_pptp_info = &master->nat.help.nat_pptp_info;
|
|
-
|
|
- /* need to alter GRE tuple because conntrack expectfn() used 'wrong'
|
|
- * (unmanipulated) values */
|
|
- if (hooknum == NF_IP_PRE_ROUTING) {
|
|
- DEBUGP("completing tuples with NAT info \n");
|
|
- /* we can do this, since we're unconfirmed */
|
|
- if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.gre.key ==
|
|
- htonl(ct_pptp_info->pac_call_id)) {
|
|
- /* assume PNS->PAC */
|
|
- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key =
|
|
- htonl(nat_pptp_info->pns_call_id);
|
|
-// ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.gre.key =
|
|
-// htonl(nat_pptp_info->pac_call_id);
|
|
- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key =
|
|
- htonl(nat_pptp_info->pns_call_id);
|
|
- } else {
|
|
- /* assume PAC->PNS */
|
|
- DEBUGP("WRONG DIRECTION\n");
|
|
- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key =
|
|
- htonl(nat_pptp_info->pac_call_id);
|
|
- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key =
|
|
- htonl(nat_pptp_info->pns_call_id);
|
|
- }
|
|
- }
|
|
-
|
|
- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) {
|
|
- newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
|
|
- newcid = htonl(master->nat.help.nat_pptp_info.pac_call_id);
|
|
-
|
|
- mr.rangesize = 1;
|
|
- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED;
|
|
- mr.range[0].min_ip = mr.range[0].max_ip = newdstip;
|
|
- mr.range[0].min = mr.range[0].max =
|
|
- ((union ip_conntrack_manip_proto ) { newcid });
|
|
- DEBUGP("change dest ip to %u.%u.%u.%u\n",
|
|
- NIPQUAD(newdstip));
|
|
- DEBUGP("change dest key to 0x%x\n", ntohl(newcid));
|
|
- ret = ip_nat_setup_info(ct, &mr, hooknum);
|
|
- } else {
|
|
- newsrcip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
|
|
- /* nat_multi_range is in network byte order, and GRE tuple
|
|
- * is 32 bits, not 16 like callID */
|
|
- newcid = htonl(master->help.ct_pptp_info.pns_call_id);
|
|
-
|
|
- mr.rangesize = 1;
|
|
- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS
|
|
- |IP_NAT_RANGE_PROTO_SPECIFIED;
|
|
- mr.range[0].min_ip = mr.range[0].max_ip = newsrcip;
|
|
- mr.range[0].min = mr.range[0].max =
|
|
- ((union ip_conntrack_manip_proto ) { newcid });
|
|
- DEBUGP("change src ip to %u.%u.%u.%u\n",
|
|
- NIPQUAD(newsrcip));
|
|
- DEBUGP("change 'src' key to 0x%x\n", ntohl(newcid));
|
|
- ret = ip_nat_setup_info(ct, &mr, hooknum);
|
|
- }
|
|
-
|
|
- UNLOCK_BH(&ip_pptp_lock);
|
|
-
|
|
- return ret;
|
|
-
|
|
-}
|
|
-
|
|
-/* outbound packets == from PNS to PAC */
|
|
-static inline unsigned int
|
|
-pptp_outbound_pkt(struct tcphdr *tcph, struct pptp_pkt_hdr *pptph,
|
|
- size_t datalen,
|
|
- struct ip_conntrack *ct,
|
|
- enum ip_conntrack_info ctinfo,
|
|
- struct ip_conntrack_expect *exp)
|
|
-
|
|
-{
|
|
- struct PptpControlHeader *ctlh;
|
|
- union pptp_ctrl_union pptpReq;
|
|
- struct ip_ct_pptp_master *ct_pptp_info = &ct->help.ct_pptp_info;
|
|
- struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info;
|
|
-
|
|
- u_int16_t msg, *cid = NULL, new_callid;
|
|
-
|
|
- ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph));
|
|
- pptpReq.rawreq = (void *) ((void *) ctlh + sizeof(*ctlh));
|
|
-
|
|
- new_callid = htons(ct_pptp_info->pns_call_id);
|
|
-
|
|
- switch (msg = ntohs(ctlh->messageType)) {
|
|
- case PPTP_OUT_CALL_REQUEST:
|
|
- cid = &pptpReq.ocreq->callID;
|
|
-
|
|
- /* save original call ID in nat_info */
|
|
- nat_pptp_info->pns_call_id = ct_pptp_info->pns_call_id;
|
|
-
|
|
- new_callid = tcph->source;
|
|
- /* save new call ID in ct info */
|
|
- ct_pptp_info->pns_call_id = ntohs(new_callid);
|
|
- break;
|
|
- case PPTP_IN_CALL_REPLY:
|
|
- cid = &pptpReq.icreq->callID;
|
|
- break;
|
|
- case PPTP_CALL_CLEAR_REQUEST:
|
|
- cid = &pptpReq.clrreq->callID;
|
|
- break;
|
|
- case PPTP_CALL_DISCONNECT_NOTIFY:
|
|
- cid = &pptpReq.disc->callID;
|
|
- break;
|
|
-
|
|
- default:
|
|
- DEBUGP("unknown outbound packet 0x%04x:%s\n", msg,
|
|
- (msg <= PPTP_MSG_MAX)? strMName[msg]:strMName[0]);
|
|
- /* fall through */
|
|
-
|
|
- case PPTP_SET_LINK_INFO:
|
|
- /* only need to NAT in case PAC is behind NAT box */
|
|
- case PPTP_START_SESSION_REQUEST:
|
|
- case PPTP_START_SESSION_REPLY:
|
|
- case PPTP_STOP_SESSION_REQUEST:
|
|
- case PPTP_STOP_SESSION_REPLY:
|
|
- case PPTP_ECHO_REQUEST:
|
|
- case PPTP_ECHO_REPLY:
|
|
- /* no need to alter packet */
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- IP_NF_ASSERT(cid);
|
|
-
|
|
- DEBUGP("altering call id from 0x%04x to 0x%04x\n",
|
|
- ntohs(*cid), ntohs(new_callid));
|
|
- /* mangle packet */
|
|
- tcph->check = ip_nat_cheat_check(*cid^0xFFFF,
|
|
- new_callid, tcph->check);
|
|
- *cid = new_callid;
|
|
-
|
|
- return NF_ACCEPT;
|
|
-}
|
|
-
|
|
-/* inbound packets == from PAC to PNS */
|
|
-static inline unsigned int
|
|
-pptp_inbound_pkt(struct tcphdr *tcph, struct pptp_pkt_hdr *pptph,
|
|
- size_t datalen,
|
|
- struct ip_conntrack *ct,
|
|
- enum ip_conntrack_info ctinfo,
|
|
- struct ip_conntrack_expect *oldexp)
|
|
-{
|
|
- struct PptpControlHeader *ctlh;
|
|
- union pptp_ctrl_union pptpReq;
|
|
- struct ip_ct_pptp_master *ct_pptp_info = &ct->help.ct_pptp_info;
|
|
- struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info;
|
|
-
|
|
- u_int16_t msg, new_cid = 0, new_pcid, *pcid = NULL, *cid = NULL;
|
|
- u_int32_t old_dst_ip;
|
|
-
|
|
- struct ip_conntrack_tuple t;
|
|
-
|
|
- ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph));
|
|
- pptpReq.rawreq = (void *) ((void *) ctlh + sizeof(*ctlh));
|
|
-
|
|
- new_pcid = htons(nat_pptp_info->pns_call_id);
|
|
-
|
|
- switch (msg = ntohs(ctlh->messageType)) {
|
|
- case PPTP_OUT_CALL_REPLY:
|
|
- pcid = &pptpReq.ocack->peersCallID;
|
|
- cid = &pptpReq.ocack->callID;
|
|
- if (!oldexp) {
|
|
- DEBUGP("outcall but no expectation\n");
|
|
- break;
|
|
- }
|
|
- old_dst_ip = oldexp->tuple.dst.ip;
|
|
- t = oldexp->tuple;
|
|
-
|
|
- /* save original PAC call ID in nat_info */
|
|
- nat_pptp_info->pac_call_id = ct_pptp_info->pac_call_id;
|
|
-
|
|
- /* store new callID in ct_info, so conntrack works */
|
|
- //ct_pptp_info->pac_call_id = ntohs(tcph->source);
|
|
- //new_cid = htons(ct_pptp_info->pac_call_id);
|
|
-
|
|
- /* alter expectation */
|
|
- if (t.dst.ip == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip) {
|
|
- /* expectation for PNS->PAC direction */
|
|
- t.dst.u.gre.key = htonl(ct_pptp_info->pac_call_id);
|
|
- t.src.u.gre.key = htonl(nat_pptp_info->pns_call_id);
|
|
- } else {
|
|
- /* expectation for PAC->PNS direction */
|
|
- t.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
|
|
- DEBUGP("EXPECTATION IN WRONG DIRECTION!!!\n");
|
|
- }
|
|
-
|
|
- if (!ip_conntrack_change_expect(oldexp, &t)) {
|
|
- DEBUGP("successfully changed expect\n");
|
|
- } else {
|
|
- DEBUGP("can't change expect\n");
|
|
- }
|
|
- ip_ct_gre_keymap_change(oldexp->proto.gre.keymap_orig, &t);
|
|
- /* reply keymap */
|
|
- t.src.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
|
|
- t.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
|
|
- t.src.u.gre.key = htonl(nat_pptp_info->pac_call_id);
|
|
- t.dst.u.gre.key = htonl(ct_pptp_info->pns_call_id);
|
|
- ip_ct_gre_keymap_change(oldexp->proto.gre.keymap_reply, &t);
|
|
-
|
|
- break;
|
|
- case PPTP_IN_CALL_CONNECT:
|
|
- pcid = &pptpReq.iccon->peersCallID;
|
|
- if (!oldexp)
|
|
- break;
|
|
- old_dst_ip = oldexp->tuple.dst.ip;
|
|
- t = oldexp->tuple;
|
|
-
|
|
- /* alter expectation, no need for callID */
|
|
- if (t.dst.ip == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip) {
|
|
- /* expectation for PNS->PAC direction */
|
|
- t.src.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
|
|
- } else {
|
|
- /* expectation for PAC->PNS direction */
|
|
- t.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
|
|
- }
|
|
-
|
|
- if (!ip_conntrack_change_expect(oldexp, &t)) {
|
|
- DEBUGP("successfully changed expect\n");
|
|
- } else {
|
|
- DEBUGP("can't change expect\n");
|
|
- }
|
|
- break;
|
|
- case PPTP_IN_CALL_REQUEST:
|
|
- /* only need to nat in case PAC is behind NAT box */
|
|
- break;
|
|
- case PPTP_WAN_ERROR_NOTIFY:
|
|
- pcid = &pptpReq.wanerr->peersCallID;
|
|
- break;
|
|
- default:
|
|
- DEBUGP("unknown inbound packet %s\n",
|
|
- (msg <= PPTP_MSG_MAX)? strMName[msg]:strMName[0]);
|
|
- /* fall through */
|
|
-
|
|
- case PPTP_START_SESSION_REQUEST:
|
|
- case PPTP_START_SESSION_REPLY:
|
|
- case PPTP_STOP_SESSION_REQUEST:
|
|
- case PPTP_ECHO_REQUEST:
|
|
- case PPTP_ECHO_REPLY:
|
|
- /* no need to alter packet */
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- /* mangle packet */
|
|
- IP_NF_ASSERT(pcid);
|
|
- DEBUGP("altering peer call id from 0x%04x to 0x%04x\n",
|
|
- ntohs(*pcid), ntohs(new_pcid));
|
|
- tcph->check = ip_nat_cheat_check(*pcid^0xFFFF,
|
|
- new_pcid, tcph->check);
|
|
- *pcid = new_pcid;
|
|
-
|
|
- if (new_cid) {
|
|
- IP_NF_ASSERT(cid);
|
|
- DEBUGP("altering call id from 0x%04x to 0x%04x\n",
|
|
- ntohs(*cid), ntohs(new_cid));
|
|
- tcph->check = ip_nat_cheat_check(*cid^0xFFFF,
|
|
- new_cid, tcph->check);
|
|
- *cid = new_cid;
|
|
- }
|
|
-
|
|
- /* great, at least we don't need to resize packets */
|
|
- return NF_ACCEPT;
|
|
-}
|
|
-
|
|
-
|
|
-static unsigned int tcp_help(struct ip_conntrack *ct,
|
|
- struct ip_conntrack_expect *exp,
|
|
- struct ip_nat_info *info,
|
|
- enum ip_conntrack_info ctinfo,
|
|
- unsigned int hooknum, struct sk_buff **pskb)
|
|
-{
|
|
- struct iphdr *iph = (*pskb)->nh.iph;
|
|
- struct tcphdr *tcph = (void *) iph + iph->ihl*4;
|
|
- unsigned int datalen = (*pskb)->len - iph->ihl*4 - tcph->doff*4;
|
|
- struct pptp_pkt_hdr *pptph;
|
|
- void *datalimit;
|
|
-
|
|
- int dir;
|
|
-
|
|
- DEBUGP("entering\n");
|
|
-
|
|
- /* Only mangle things once: original direction in POST_ROUTING
|
|
- and reply direction on PRE_ROUTING. */
|
|
- dir = CTINFO2DIR(ctinfo);
|
|
- if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL)
|
|
- || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) {
|
|
- DEBUGP("Not touching dir %s at hook %s\n",
|
|
- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY",
|
|
- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING"
|
|
- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING"
|
|
- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???");
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- /* if packet is too small, just skip it */
|
|
- if (datalen < sizeof(struct pptp_pkt_hdr)+
|
|
- sizeof(struct PptpControlHeader)) {
|
|
- DEBUGP("pptp packet too short\n");
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
-
|
|
- pptph = (struct pptp_pkt_hdr *) ((void *)tcph + tcph->doff*4);
|
|
- datalimit = (void *) pptph + datalen;
|
|
-
|
|
- LOCK_BH(&ip_pptp_lock);
|
|
-
|
|
- if (dir == IP_CT_DIR_ORIGINAL) {
|
|
- /* reuqests sent by client to server (PNS->PAC) */
|
|
- pptp_outbound_pkt(tcph, pptph, datalen, ct, ctinfo, exp);
|
|
- } else {
|
|
- /* response from the server to the client (PAC->PNS) */
|
|
- pptp_inbound_pkt(tcph, pptph, datalen, ct, ctinfo, exp);
|
|
- }
|
|
-
|
|
- UNLOCK_BH(&ip_pptp_lock);
|
|
-
|
|
- return NF_ACCEPT;
|
|
-}
|
|
-
|
|
-/* nat helper struct for control connection */
|
|
-static struct ip_nat_helper pptp_tcp_helper = {
|
|
- { NULL, NULL },
|
|
- "pptp", IP_NAT_HELPER_F_ALWAYS, THIS_MODULE,
|
|
- { { 0, { tcp: { port: __constant_htons(PPTP_CONTROL_PORT) } } },
|
|
- { 0, { 0 }, IPPROTO_TCP } },
|
|
- { { 0, { tcp: { port: 0xFFFF } } },
|
|
- { 0, { 0 }, 0xFFFF } },
|
|
- tcp_help, pptp_nat_expected };
|
|
-
|
|
-
|
|
-static int __init init(void)
|
|
-{
|
|
- DEBUGP("init_module\n" );
|
|
-
|
|
- if (ip_nat_helper_register(&pptp_tcp_helper))
|
|
- return -EIO;
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-static void __exit fini(void)
|
|
-{
|
|
- DEBUGP("cleanup_module\n" );
|
|
- ip_nat_helper_unregister(&pptp_tcp_helper);
|
|
-}
|
|
-
|
|
-module_init(init);
|
|
-module_exit(fini);
|
|
diff -Nurb 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 <laforge@gnumonks.org>
|
|
- *
|
|
- * Development of this code funded by Astaro AG (http://www.astaro.com/)
|
|
- *
|
|
- */
|
|
-
|
|
-#include <linux/config.h>
|
|
-#include <linux/module.h>
|
|
-#include <linux/ip.h>
|
|
-#include <linux/netfilter_ipv4/ip_nat.h>
|
|
-#include <linux/netfilter_ipv4/ip_nat_rule.h>
|
|
-#include <linux/netfilter_ipv4/ip_nat_protocol.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
|
|
-
|
|
-MODULE_LICENSE("GPL");
|
|
-MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
|
|
-MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE");
|
|
-
|
|
-#define DEBUGP(x, args...)
|
|
-
|
|
-/* is key in given range between min and max */
|
|
-static int
|
|
-gre_in_range(const struct ip_conntrack_tuple *tuple,
|
|
- enum ip_nat_manip_type maniptype,
|
|
- const union ip_conntrack_manip_proto *min,
|
|
- const union ip_conntrack_manip_proto *max)
|
|
-{
|
|
- return ntohl(tuple->src.u.gre.key) >= ntohl(min->gre.key)
|
|
- && ntohl(tuple->src.u.gre.key) <= ntohl(max->gre.key);
|
|
-}
|
|
-
|
|
-/* generate unique tuple ... */
|
|
-static int
|
|
-gre_unique_tuple(struct ip_conntrack_tuple *tuple,
|
|
- const struct ip_nat_range *range,
|
|
- enum ip_nat_manip_type maniptype,
|
|
- const struct ip_conntrack *conntrack)
|
|
-{
|
|
- u_int32_t min, i, range_size;
|
|
- u_int32_t key = 0, *keyptr;
|
|
-
|
|
- if (maniptype == IP_NAT_MANIP_SRC)
|
|
- keyptr = &tuple->src.u.gre.key;
|
|
- else
|
|
- keyptr = &tuple->dst.u.gre.key;
|
|
-
|
|
- if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
|
|
-
|
|
- switch (tuple->dst.u.gre.version) {
|
|
- case 0:
|
|
- DEBUGP("NATing GRE version 0 (ct=%p)\n",
|
|
- conntrack);
|
|
- min = 1;
|
|
- range_size = 0xffffffff;
|
|
- break;
|
|
- case GRE_VERSION_PPTP:
|
|
- DEBUGP("%p: NATing GRE PPTP\n",
|
|
- conntrack);
|
|
- min = 1;
|
|
- range_size = 0xffff;
|
|
- break;
|
|
- default:
|
|
- printk(KERN_WARNING "nat_gre: unknown GRE version\n");
|
|
- return 0;
|
|
- break;
|
|
- }
|
|
-
|
|
- } else {
|
|
- min = ntohl(range->min.gre.key);
|
|
- range_size = ntohl(range->max.gre.key) - min + 1;
|
|
- }
|
|
-
|
|
- DEBUGP("min = %u, range_size = %u\n", min, range_size);
|
|
-
|
|
- for (i = 0; i < range_size; i++, key++) {
|
|
- *keyptr = htonl(min + key % range_size);
|
|
- if (!ip_nat_used_tuple(tuple, conntrack))
|
|
- return 1;
|
|
- }
|
|
-
|
|
- DEBUGP("%p: no NAT mapping\n", conntrack);
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-/* manipulate a GRE packet according to maniptype */
|
|
-static void
|
|
-gre_manip_pkt(struct iphdr *iph, size_t len,
|
|
- const struct ip_conntrack_manip *manip,
|
|
- enum ip_nat_manip_type maniptype)
|
|
-{
|
|
- struct gre_hdr *greh = (struct gre_hdr *)((u_int32_t *)iph+iph->ihl);
|
|
- struct gre_hdr_pptp *pgreh = (struct gre_hdr_pptp *) greh;
|
|
-
|
|
- /* we only have destination manip of a packet, since 'source key'
|
|
- * is not present in the packet itself */
|
|
- if (maniptype == IP_NAT_MANIP_DST) {
|
|
- /* key manipulation is always dest */
|
|
- switch (greh->version) {
|
|
- case 0:
|
|
- if (!greh->key) {
|
|
- DEBUGP("can't nat GRE w/o key\n");
|
|
- break;
|
|
- }
|
|
- if (greh->csum) {
|
|
- *(gre_csum(greh)) =
|
|
- ip_nat_cheat_check(~*(gre_key(greh)),
|
|
- manip->u.gre.key,
|
|
- *(gre_csum(greh)));
|
|
- }
|
|
- *(gre_key(greh)) = manip->u.gre.key;
|
|
- break;
|
|
- case GRE_VERSION_PPTP:
|
|
- DEBUGP("call_id -> 0x%04x\n",
|
|
- ntohl(manip->u.gre.key));
|
|
- pgreh->call_id = htons(ntohl(manip->u.gre.key));
|
|
- break;
|
|
- default:
|
|
- DEBUGP("can't nat unknown GRE version\n");
|
|
- break;
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-/* print out a nat tuple */
|
|
-static unsigned int
|
|
-gre_print(char *buffer,
|
|
- const struct ip_conntrack_tuple *match,
|
|
- const struct ip_conntrack_tuple *mask)
|
|
-{
|
|
- unsigned int len = 0;
|
|
-
|
|
- if (mask->dst.u.gre.version)
|
|
- len += sprintf(buffer + len, "version=%d ",
|
|
- ntohs(match->dst.u.gre.version));
|
|
-
|
|
- if (mask->dst.u.gre.protocol)
|
|
- len += sprintf(buffer + len, "protocol=0x%x ",
|
|
- ntohs(match->dst.u.gre.protocol));
|
|
-
|
|
- if (mask->src.u.gre.key)
|
|
- len += sprintf(buffer + len, "srckey=0x%x ",
|
|
- ntohl(match->src.u.gre.key));
|
|
-
|
|
- if (mask->dst.u.gre.key)
|
|
- len += sprintf(buffer + len, "dstkey=0x%x ",
|
|
- ntohl(match->src.u.gre.key));
|
|
-
|
|
- return len;
|
|
-}
|
|
-
|
|
-/* print a range of keys */
|
|
-static unsigned int
|
|
-gre_print_range(char *buffer, const struct ip_nat_range *range)
|
|
-{
|
|
- if (range->min.gre.key != 0
|
|
- || range->max.gre.key != 0xFFFF) {
|
|
- if (range->min.gre.key == range->max.gre.key)
|
|
- return sprintf(buffer, "key 0x%x ",
|
|
- ntohl(range->min.gre.key));
|
|
- else
|
|
- return sprintf(buffer, "keys 0x%u-0x%u ",
|
|
- ntohl(range->min.gre.key),
|
|
- ntohl(range->max.gre.key));
|
|
- } else
|
|
- return 0;
|
|
-}
|
|
-
|
|
-/* nat helper struct */
|
|
-static struct ip_nat_protocol gre =
|
|
- { { NULL, NULL }, "GRE", IPPROTO_GRE,
|
|
- gre_manip_pkt,
|
|
- gre_in_range,
|
|
- gre_unique_tuple,
|
|
- gre_print,
|
|
- gre_print_range
|
|
- };
|
|
-
|
|
-static int __init init(void)
|
|
-{
|
|
- if (ip_nat_protocol_register(&gre))
|
|
- return -EIO;
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-static void __exit fini(void)
|
|
-{
|
|
- ip_nat_protocol_unregister(&gre);
|
|
-}
|
|
-
|
|
-module_init(init);
|
|
-module_exit(fini);
|
|
diff -Nurb 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 <linux/netfilter_ipv4/ip_conntrack_core.h>
|
|
#include <linux/netfilter_ipv4/listhelp.h>
|
|
|
|
+#if 0
|
|
+#define DEBUGP printk
|
|
+#else
|
|
#define DEBUGP(format, args...)
|
|
+#endif
|
|
|
|
#define HOOKNAME(hooknum) ((hooknum) == NF_IP_POST_ROUTING ? "POST_ROUTING" \
|
|
: ((hooknum) == NF_IP_PRE_ROUTING ? "PRE_ROUTING" \
|
|
@@ -354,6 +358,5 @@
|
|
EXPORT_SYMBOL(ip_nat_helper_unregister);
|
|
EXPORT_SYMBOL(ip_nat_cheat_check);
|
|
EXPORT_SYMBOL(ip_nat_mangle_tcp_packet);
|
|
-EXPORT_SYMBOL(ip_nat_mangle_udp_packet);
|
|
EXPORT_SYMBOL(ip_nat_used_tuple);
|
|
MODULE_LICENSE("GPL");
|
|
diff -Nurb 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 <mb@ozaba.mine.nu>
|
|
- * Version: 0.0.7
|
|
- *
|
|
- * Thu 21 Mar 2002 Harald Welte <laforge@gnumonks.org>
|
|
- * - Port to newnat API
|
|
- *
|
|
- * This module currently supports DNAT:
|
|
- * iptables -t nat -A PREROUTING -d x.x.x.x -j DNAT --to-dest x.x.x.y
|
|
- *
|
|
- * and SNAT:
|
|
- * iptables -t nat -A POSTROUTING { -j MASQUERADE , -j SNAT --to-source x.x.x.x }
|
|
- *
|
|
- * It has not been tested with
|
|
- * -j SNAT --to-source x.x.x.x-x.x.x.y since I only have one external ip
|
|
- * If you do test this please let me know if it works or not.
|
|
- *
|
|
- */
|
|
-
|
|
-#include <linux/module.h>
|
|
-#include <linux/netfilter_ipv4.h>
|
|
-#include <linux/ip.h>
|
|
-#include <linux/udp.h>
|
|
-
|
|
-#include <linux/netfilter.h>
|
|
-#include <linux/netfilter_ipv4/ip_tables.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
|
|
-#include <linux/netfilter_ipv4/ip_conntrack_tftp.h>
|
|
-#include <linux/netfilter_ipv4/ip_nat_helper.h>
|
|
-#include <linux/netfilter_ipv4/ip_nat_rule.h>
|
|
-
|
|
-MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>");
|
|
-MODULE_DESCRIPTION("Netfilter NAT helper for tftp");
|
|
-MODULE_LICENSE("GPL");
|
|
-
|
|
-#define MAX_PORTS 8
|
|
-
|
|
-static int ports[MAX_PORTS];
|
|
-static int ports_c = 0;
|
|
-#ifdef MODULE_PARM
|
|
-MODULE_PARM(ports,"1-" __MODULE_STRING(MAX_PORTS) "i");
|
|
-MODULE_PARM_DESC(ports, "port numbers of tftp servers");
|
|
-#endif
|
|
-
|
|
-#define DEBUGP(format, args...)
|
|
-static unsigned int
|
|
-tftp_nat_help(struct ip_conntrack *ct,
|
|
- struct ip_conntrack_expect *exp,
|
|
- struct ip_nat_info *info,
|
|
- enum ip_conntrack_info ctinfo,
|
|
- unsigned int hooknum,
|
|
- struct sk_buff **pskb)
|
|
-{
|
|
- int dir = CTINFO2DIR(ctinfo);
|
|
- struct iphdr *iph = (*pskb)->nh.iph;
|
|
- struct udphdr *udph = (void *)iph + iph->ihl * 4;
|
|
- struct tftphdr *tftph = (void *)udph + 8;
|
|
- struct ip_conntrack_tuple repl;
|
|
-
|
|
- if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL)
|
|
- || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY)))
|
|
- return NF_ACCEPT;
|
|
-
|
|
- if (!exp) {
|
|
- DEBUGP("no conntrack expectation to modify\n");
|
|
- return NF_ACCEPT;
|
|
- }
|
|
-
|
|
- switch (ntohs(tftph->opcode)) {
|
|
- /* RRQ and WRQ works the same way */
|
|
- case TFTP_OPCODE_READ:
|
|
- case TFTP_OPCODE_WRITE:
|
|
- repl = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
|
|
- DEBUGP("");
|
|
- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
|
- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
|
|
- DEBUGP("expecting: ");
|
|
- DUMP_TUPLE_RAW(&repl);
|
|
- DUMP_TUPLE_RAW(&exp->mask);
|
|
- ip_conntrack_change_expect(exp, &repl);
|
|
- break;
|
|
- default:
|
|
- DEBUGP("Unknown opcode\n");
|
|
- }
|
|
-
|
|
- return NF_ACCEPT;
|
|
-}
|
|
-
|
|
-static unsigned int
|
|
-tftp_nat_expected(struct sk_buff **pskb,
|
|
- unsigned int hooknum,
|
|
- struct ip_conntrack *ct,
|
|
- struct ip_nat_info *info)
|
|
-{
|
|
- const struct ip_conntrack *master = ct->master->expectant;
|
|
- const struct ip_conntrack_tuple *orig =
|
|
- &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
|
|
- struct ip_nat_multi_range mr;
|
|
-
|
|
- IP_NF_ASSERT(info);
|
|
- IP_NF_ASSERT(master);
|
|
- IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
|
|
-
|
|
- mr.rangesize = 1;
|
|
- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS;
|
|
-
|
|
- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) {
|
|
- mr.range[0].min_ip = mr.range[0].max_ip = orig->dst.ip;
|
|
- DEBUGP("orig: %u.%u.%u.%u:%u <-> %u.%u.%u.%u:%u "
|
|
- "newsrc: %u.%u.%u.%u\n",
|
|
- NIPQUAD((*pskb)->nh.iph->saddr), ntohs(udph->source),
|
|
- NIPQUAD((*pskb)->nh.iph->daddr), ntohs(udph->dest),
|
|
- NIPQUAD(orig->dst.ip));
|
|
- } else {
|
|
- mr.range[0].min_ip = mr.range[0].max_ip = orig->src.ip;
|
|
- mr.range[0].min.udp.port = mr.range[0].max.udp.port =
|
|
- orig->src.u.udp.port;
|
|
- mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
|
|
-
|
|
- DEBUGP("orig: %u.%u.%u.%u:%u <-> %u.%u.%u.%u:%u "
|
|
- "newdst: %u.%u.%u.%u:%u\n",
|
|
- NIPQUAD((*pskb)->nh.iph->saddr), ntohs(udph->source),
|
|
- NIPQUAD((*pskb)->nh.iph->daddr), ntohs(udph->dest),
|
|
- NIPQUAD(orig->src.ip), ntohs(orig->src.u.udp.port));
|
|
- }
|
|
-
|
|
- return ip_nat_setup_info(ct,&mr,hooknum);
|
|
-}
|
|
-
|
|
-static struct ip_nat_helper tftp[MAX_PORTS];
|
|
-static char tftp_names[MAX_PORTS][10];
|
|
-
|
|
-static void fini(void)
|
|
-{
|
|
- int i;
|
|
-
|
|
- for (i = 0 ; i < ports_c; i++) {
|
|
- DEBUGP("unregistering helper for port %d\n", ports[i]);
|
|
- ip_nat_helper_unregister(&tftp[i]);
|
|
- }
|
|
-}
|
|
-
|
|
-static int __init init(void)
|
|
-{
|
|
- int i, ret;
|
|
- char *tmpname;
|
|
-
|
|
- if (!ports[0])
|
|
- ports[0] = TFTP_PORT;
|
|
-
|
|
- for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) {
|
|
- memset(&tftp[i], 0, sizeof(struct ip_nat_helper));
|
|
-
|
|
- tftp[i].tuple.dst.protonum = IPPROTO_UDP;
|
|
- tftp[i].tuple.src.u.udp.port = htons(ports[i]);
|
|
- tftp[i].mask.dst.protonum = 0xFFFF;
|
|
- tftp[i].mask.src.u.udp.port = 0xFFFF;
|
|
- tftp[i].help = tftp_nat_help;
|
|
- tftp[i].flags = 0;
|
|
- tftp[i].me = THIS_MODULE;
|
|
- tftp[i].expect = tftp_nat_expected;
|
|
-
|
|
- tmpname = &tftp_names[i][0];
|
|
- if (ports[i] == TFTP_PORT)
|
|
- sprintf(tmpname, "tftp");
|
|
- else
|
|
- sprintf(tmpname, "tftp-%d", i);
|
|
- tftp[i].name = tmpname;
|
|
-
|
|
- DEBUGP("ip_nat_tftp: registering for port %d: name %s\n",
|
|
- ports[i], tftp[i].name);
|
|
- ret = ip_nat_helper_register(&tftp[i]);
|
|
-
|
|
- if (ret) {
|
|
- printk("ip_nat_tftp: unable to register for port %d\n",
|
|
- ports[i]);
|
|
- fini();
|
|
- return ret;
|
|
- }
|
|
- ports_c++;
|
|
- }
|
|
- return ret;
|
|
-}
|
|
-
|
|
-module_init(init);
|
|
-module_exit(fini);
|
|
diff -Nurb 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 <linux/module.h>
|
|
-#include <linux/ip.h>
|
|
-#include <linux/skbuff.h>
|
|
-#include <linux/netfilter_ipv4/ip_tables.h>
|
|
-#include <linux/netfilter_ipv4/ip_pool.h>
|
|
-#include <linux/errno.h>
|
|
-#include <asm/uaccess.h>
|
|
-#include <asm/bitops.h>
|
|
-#include <linux/interrupt.h>
|
|
-#include <linux/spinlock.h>
|
|
-
|
|
-#define DP(format, args...)
|
|
-
|
|
-MODULE_LICENSE("GPL");
|
|
-
|
|
-#define NR_POOL 16
|
|
-static int nr_pool = NR_POOL;/* overwrite this when loading module */
|
|
-
|
|
-struct ip_pool {
|
|
- u_int32_t first_ip; /* host byte order, included in range */
|
|
- u_int32_t last_ip; /* host byte order, included in range */
|
|
- void *members; /* the bitmap proper */
|
|
- int nr_use; /* total nr. of tests through this */
|
|
- int nr_match; /* total nr. of matches through this */
|
|
- rwlock_t lock;
|
|
-};
|
|
-
|
|
-static struct ip_pool *POOL;
|
|
-
|
|
-static inline struct ip_pool *lookup(ip_pool_t index)
|
|
-{
|
|
- if (index < 0 || index >= nr_pool) {
|
|
- DP("ip_pool:lookup: bad index %d\n", index);
|
|
- return 0;
|
|
- }
|
|
- return POOL+index;
|
|
-}
|
|
-
|
|
-int ip_pool_match(ip_pool_t index, u_int32_t addr)
|
|
-{
|
|
- struct ip_pool *pool = lookup(index);
|
|
- int res = 0;
|
|
-
|
|
- if (!pool || !pool->members)
|
|
- return 0;
|
|
- read_lock_bh(&pool->lock);
|
|
- if (pool->members) {
|
|
- if (addr >= pool->first_ip && addr <= pool->last_ip) {
|
|
- addr -= pool->first_ip;
|
|
- if (test_bit(addr, pool->members)) {
|
|
- res = 1;
|
|
-#ifdef CONFIG_IP_POOL_STATISTICS
|
|
- pool->nr_match++;
|
|
-#endif
|
|
- }
|
|
- }
|
|
-#ifdef CONFIG_IP_POOL_STATISTICS
|
|
- pool->nr_use++;
|
|
-#endif
|
|
- }
|
|
- read_unlock_bh(&pool->lock);
|
|
- return res;
|
|
-}
|
|
-
|
|
-static int pool_change(ip_pool_t index, u_int32_t addr, int isdel)
|
|
-{
|
|
- struct ip_pool *pool;
|
|
- int res = -1;
|
|
-
|
|
- pool = lookup(index);
|
|
- if ( !pool || !pool->members
|
|
- || addr < pool->first_ip || addr > pool->last_ip)
|
|
- return -1;
|
|
- read_lock_bh(&pool->lock);
|
|
- if (pool->members && addr >= pool->first_ip && addr <= pool->last_ip) {
|
|
- addr -= pool->first_ip;
|
|
- res = isdel
|
|
- ? (0 != test_and_clear_bit(addr, pool->members))
|
|
- : (0 != test_and_set_bit(addr, pool->members));
|
|
- }
|
|
- read_unlock_bh(&pool->lock);
|
|
- return res;
|
|
-}
|
|
-
|
|
-int ip_pool_mod(ip_pool_t index, u_int32_t addr, int isdel)
|
|
-{
|
|
- int res = pool_change(index,addr,isdel);
|
|
-
|
|
- if (!isdel) res = !res;
|
|
- return res;
|
|
-}
|
|
-
|
|
-static inline int bitmap_bytes(u_int32_t a, u_int32_t b)
|
|
-{
|
|
- return 4*((((b-a+8)/8)+3)/4);
|
|
-}
|
|
-
|
|
-static inline int poolbytes(ip_pool_t index)
|
|
-{
|
|
- struct ip_pool *pool = lookup(index);
|
|
-
|
|
- return pool ? bitmap_bytes(pool->first_ip, pool->last_ip) : 0;
|
|
-}
|
|
-
|
|
-static int setpool(
|
|
- struct sock *sk,
|
|
- int optval,
|
|
- void *user,
|
|
- unsigned int len
|
|
-) {
|
|
- struct ip_pool_request req;
|
|
-
|
|
- DP("ip_pool:setpool: optval=%d, user=%p, len=%d\n", optval, user, len);
|
|
- if (!capable(CAP_NET_ADMIN))
|
|
- return -EPERM;
|
|
- if (optval != SO_IP_POOL)
|
|
- return -EBADF;
|
|
- if (len != sizeof(req))
|
|
- return -EINVAL;
|
|
- if (copy_from_user(&req, user, sizeof(req)) != 0)
|
|
- return -EFAULT;
|
|
- printk("obsolete op - upgrade your ippool(8) utility.\n");
|
|
- return -EINVAL;
|
|
-}
|
|
-
|
|
-static int getpool(
|
|
- struct sock *sk,
|
|
- int optval,
|
|
- void *user,
|
|
- int *len
|
|
-) {
|
|
- struct ip_pool_request req;
|
|
- struct ip_pool *pool;
|
|
- ip_pool_t i;
|
|
- int newbytes;
|
|
- void *newmembers;
|
|
- int res;
|
|
-
|
|
- DP("ip_pool:getpool: optval=%d, user=%p\n", optval, user);
|
|
- if (!capable(CAP_NET_ADMIN))
|
|
- return -EINVAL;
|
|
- if (optval != SO_IP_POOL)
|
|
- return -EINVAL;
|
|
- if (*len != sizeof(req)) {
|
|
- return -EFAULT;
|
|
- }
|
|
- if (copy_from_user(&req, user, sizeof(req)) != 0)
|
|
- return -EFAULT;
|
|
- DP("ip_pool:getpool op=%d, index=%d\n", req.op, req.index);
|
|
- if (req.op < IP_POOL_BAD001) {
|
|
- printk("obsolete op - upgrade your ippool(8) utility.\n");
|
|
- return -EFAULT;
|
|
- }
|
|
- switch(req.op) {
|
|
- case IP_POOL_HIGH_NR:
|
|
- DP("ip_pool HIGH_NR\n");
|
|
- req.index = IP_POOL_NONE;
|
|
- for (i=0; i<nr_pool; i++)
|
|
- if (POOL[i].members)
|
|
- req.index = i;
|
|
- return copy_to_user(user, &req, sizeof(req));
|
|
- case IP_POOL_LOOKUP:
|
|
- DP("ip_pool LOOKUP\n");
|
|
- pool = lookup(req.index);
|
|
- if (!pool)
|
|
- return -EINVAL;
|
|
- if (!pool->members)
|
|
- return -EBADF;
|
|
- req.addr = htonl(pool->first_ip);
|
|
- req.addr2 = htonl(pool->last_ip);
|
|
- return copy_to_user(user, &req, sizeof(req));
|
|
- case IP_POOL_USAGE:
|
|
- DP("ip_pool USE\n");
|
|
- pool = lookup(req.index);
|
|
- if (!pool)
|
|
- return -EINVAL;
|
|
- if (!pool->members)
|
|
- return -EBADF;
|
|
- req.addr = pool->nr_use;
|
|
- req.addr2 = pool->nr_match;
|
|
- return copy_to_user(user, &req, sizeof(req));
|
|
- case IP_POOL_TEST_ADDR:
|
|
- DP("ip_pool TEST 0x%08x\n", req.addr);
|
|
- pool = lookup(req.index);
|
|
- if (!pool)
|
|
- return -EINVAL;
|
|
- res = 0;
|
|
- read_lock_bh(&pool->lock);
|
|
- if (!pool->members) {
|
|
- DP("ip_pool TEST_ADDR no members in pool\n");
|
|
- res = -EBADF;
|
|
- goto unlock_and_return_res;
|
|
- }
|
|
- req.addr = ntohl(req.addr);
|
|
- if (req.addr < pool->first_ip) {
|
|
- DP("ip_pool TEST_ADDR address < pool bounds\n");
|
|
- res = -ERANGE;
|
|
- goto unlock_and_return_res;
|
|
- }
|
|
- if (req.addr > pool->last_ip) {
|
|
- DP("ip_pool TEST_ADDR address > pool bounds\n");
|
|
- res = -ERANGE;
|
|
- goto unlock_and_return_res;
|
|
- }
|
|
- req.addr = (0 != test_bit((req.addr - pool->first_ip),
|
|
- pool->members));
|
|
- read_unlock_bh(&pool->lock);
|
|
- return copy_to_user(user, &req, sizeof(req));
|
|
- case IP_POOL_FLUSH:
|
|
- DP("ip_pool FLUSH not yet implemented.\n");
|
|
- return -EBUSY;
|
|
- case IP_POOL_DESTROY:
|
|
- DP("ip_pool DESTROY not yet implemented.\n");
|
|
- return -EBUSY;
|
|
- case IP_POOL_INIT:
|
|
- DP("ip_pool INIT 0x%08x-0x%08x\n", req.addr, req.addr2);
|
|
- pool = lookup(req.index);
|
|
- if (!pool)
|
|
- return -EINVAL;
|
|
- req.addr = ntohl(req.addr);
|
|
- req.addr2 = ntohl(req.addr2);
|
|
- if (req.addr > req.addr2) {
|
|
- DP("ip_pool INIT bad ip range\n");
|
|
- return -EINVAL;
|
|
- }
|
|
- newbytes = bitmap_bytes(req.addr, req.addr2);
|
|
- newmembers = kmalloc(newbytes, GFP_KERNEL);
|
|
- if (!newmembers) {
|
|
- DP("ip_pool INIT out of mem for %d bytes\n", newbytes);
|
|
- return -ENOMEM;
|
|
- }
|
|
- memset(newmembers, 0, newbytes);
|
|
- write_lock_bh(&pool->lock);
|
|
- if (pool->members) {
|
|
- DP("ip_pool INIT pool %d exists\n", req.index);
|
|
- kfree(newmembers);
|
|
- res = -EBUSY;
|
|
- goto unlock_and_return_res;
|
|
- }
|
|
- pool->first_ip = req.addr;
|
|
- pool->last_ip = req.addr2;
|
|
- pool->nr_use = 0;
|
|
- pool->nr_match = 0;
|
|
- pool->members = newmembers;
|
|
- write_unlock_bh(&pool->lock);
|
|
- return 0;
|
|
- case IP_POOL_ADD_ADDR:
|
|
- DP("ip_pool ADD_ADDR 0x%08x\n", req.addr);
|
|
- req.addr = pool_change(req.index, ntohl(req.addr), 0);
|
|
- return copy_to_user(user, &req, sizeof(req));
|
|
- case IP_POOL_DEL_ADDR:
|
|
- DP("ip_pool DEL_ADDR 0x%08x\n", req.addr);
|
|
- req.addr = pool_change(req.index, ntohl(req.addr), 1);
|
|
- return copy_to_user(user, &req, sizeof(req));
|
|
- default:
|
|
- DP("ip_pool:getpool bad op %d\n", req.op);
|
|
- return -EINVAL;
|
|
- }
|
|
- return -EINVAL;
|
|
-
|
|
-unlock_and_return_res:
|
|
- if (pool)
|
|
- read_unlock_bh(&pool->lock);
|
|
- return res;
|
|
-}
|
|
-
|
|
-static struct nf_sockopt_ops so_pool
|
|
-= { { NULL, NULL }, PF_INET,
|
|
- SO_IP_POOL, SO_IP_POOL+1, &setpool,
|
|
- SO_IP_POOL, SO_IP_POOL+1, &getpool,
|
|
- 0, NULL };
|
|
-
|
|
-MODULE_PARM(nr_pool, "i");
|
|
-
|
|
-static int __init init(void)
|
|
-{
|
|
- ip_pool_t i;
|
|
- int res;
|
|
-
|
|
- if (nr_pool < 1) {
|
|
- printk("ip_pool module init: bad nr_pool %d\n", nr_pool);
|
|
- return -EINVAL;
|
|
- }
|
|
- POOL = kmalloc(nr_pool * sizeof(*POOL), GFP_KERNEL);
|
|
- if (!POOL) {
|
|
- printk("ip_pool module init: out of memory for nr_pool %d\n",
|
|
- nr_pool);
|
|
- return -ENOMEM;
|
|
- }
|
|
- for (i=0; i<nr_pool; i++) {
|
|
- POOL[i].first_ip = 0;
|
|
- POOL[i].last_ip = 0;
|
|
- POOL[i].members = 0;
|
|
- POOL[i].nr_use = 0;
|
|
- POOL[i].nr_match = 0;
|
|
- POOL[i].lock = RW_LOCK_UNLOCKED;
|
|
- }
|
|
- res = nf_register_sockopt(&so_pool);
|
|
- DP("ip_pool:init %d pools, result %d\n", nr_pool, res);
|
|
- if (res != 0) {
|
|
- kfree(POOL);
|
|
- POOL = 0;
|
|
- }
|
|
- return res;
|
|
-}
|
|
-
|
|
-static void __exit fini(void)
|
|
-{
|
|
- ip_pool_t i;
|
|
-
|
|
- DP("ip_pool:fini BYEBYE\n");
|
|
- nf_unregister_sockopt(&so_pool);
|
|
- for (i=0; i<nr_pool; i++) {
|
|
- if (POOL[i].members) {
|
|
- kfree(POOL[i].members);
|
|
- POOL[i].members = 0;
|
|
- }
|
|
- }
|
|
- kfree(POOL);
|
|
- POOL = 0;
|
|
- DP("ip_pool:fini these are the famous last words\n");
|
|
- return;
|
|
-}
|
|
-
|
|
-module_init(init);
|
|
-module_exit(fini);
|
|
diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_tables.c src/linux/linux.stock/net/ipv4/netfilter/ip_tables.c
|
|
--- src/linux/linux/net/ipv4/netfilter/ip_tables.c 2003-07-04 04:12:31.000000000 -0400
|
|
+++ src/linux/linux.stock/net/ipv4/netfilter/ip_tables.c 2004-05-09 04:13:03.000000000 -0400
|
|
@@ -62,6 +62,11 @@
|
|
#include <linux/netfilter_ipv4/lockhelp.h>
|
|
#include <linux/netfilter_ipv4/listhelp.h>
|
|
|
|
+#if 0
|
|
+/* All the better to debug you with... */
|
|
+#define static
|
|
+#define inline
|
|
+#endif
|
|
|
|
/* Locking is simple: we assume at worst case there will be one packet
|
|
in user context and one from bottom halves (or soft irq if Alexey's
|
|
@@ -83,6 +88,7 @@
|
|
{
|
|
/* Size per table */
|
|
unsigned int size;
|
|
+ /* Number of entries: FIXME. --RR */
|
|
unsigned int number;
|
|
/* Initial number of entries. Needed for module usage count */
|
|
unsigned int initial_entries;
|
|
@@ -106,6 +112,11 @@
|
|
#define TABLE_OFFSET(t,p) 0
|
|
#endif
|
|
|
|
+#if 0
|
|
+#define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0)
|
|
+#define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; })
|
|
+#define up(x) do { printk("UP:%u:" #x "\n", __LINE__); up(x); } while(0)
|
|
+#endif
|
|
|
|
/* Returns whether matches rule or not. */
|
|
static inline int
|
|
@@ -408,6 +419,12 @@
|
|
{
|
|
void *ret;
|
|
|
|
+#if 0
|
|
+ duprintf("find_inlist: searching for `%s' in %s.\n",
|
|
+ name, head == &ipt_target ? "ipt_target"
|
|
+ : head == &ipt_match ? "ipt_match"
|
|
+ : head == &ipt_tables ? "ipt_tables" : "UNKNOWN");
|
|
+#endif
|
|
|
|
*error = down_interruptible(mutex);
|
|
if (*error != 0)
|
|
@@ -745,6 +762,8 @@
|
|
newinfo->underflow[h] = underflows[h];
|
|
}
|
|
|
|
+ /* FIXME: underflows must be unconditional, standard verdicts
|
|
+ < 0 (not IPT_RETURN). --RR */
|
|
|
|
/* Clear counters and comefrom */
|
|
e->counters = ((struct ipt_counters) { 0, 0 });
|
|
@@ -957,6 +976,7 @@
|
|
goto free_counters;
|
|
}
|
|
|
|
+ /* FIXME: use iterator macros --RR */
|
|
/* ... then go back and fix counters and names */
|
|
for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){
|
|
unsigned int i;
|
|
@@ -1134,6 +1154,14 @@
|
|
const struct ipt_counters addme[],
|
|
unsigned int *i)
|
|
{
|
|
+#if 0
|
|
+ duprintf("add_counter: Entry %u %lu/%lu + %lu/%lu\n",
|
|
+ *i,
|
|
+ (long unsigned int)e->counters.pcnt,
|
|
+ (long unsigned int)e->counters.bcnt,
|
|
+ (long unsigned int)addme[*i].pcnt,
|
|
+ (long unsigned int)addme[*i].bcnt);
|
|
+#endif
|
|
|
|
ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt);
|
|
|
|
@@ -1495,6 +1523,7 @@
|
|
return 0;
|
|
}
|
|
|
|
+ /* FIXME: Try tcp doff >> packet len against various stacks --RR */
|
|
|
|
#define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg))
|
|
|
|
@@ -1670,15 +1699,14 @@
|
|
= { { NULL, NULL }, "icmp", &icmp_match, &icmp_checkentry, NULL };
|
|
|
|
#ifdef CONFIG_PROC_FS
|
|
-static inline int print_name(const char *i,
|
|
+static inline int print_name(const struct ipt_table *t,
|
|
off_t start_offset, char *buffer, int length,
|
|
off_t *pos, unsigned int *count)
|
|
{
|
|
if ((*count)++ >= start_offset) {
|
|
unsigned int namelen;
|
|
|
|
- namelen = sprintf(buffer + *pos, "%s\n",
|
|
- i + sizeof(struct list_head));
|
|
+ namelen = sprintf(buffer + *pos, "%s\n", t->name);
|
|
if (*pos + namelen > length) {
|
|
/* Stop iterating */
|
|
return 1;
|
|
@@ -1696,7 +1724,7 @@
|
|
if (down_interruptible(&ipt_mutex) != 0)
|
|
return 0;
|
|
|
|
- LIST_FIND(&ipt_tables, print_name, void *,
|
|
+ LIST_FIND(&ipt_tables, print_name, struct ipt_table *,
|
|
offset, buffer, length, &pos, &count);
|
|
|
|
up(&ipt_mutex);
|
|
@@ -1705,46 +1733,6 @@
|
|
*start=(char *)((unsigned long)count-offset);
|
|
return pos;
|
|
}
|
|
-
|
|
-static int ipt_get_targets(char *buffer, char **start, off_t offset, int length)
|
|
-{
|
|
- off_t pos = 0;
|
|
- unsigned int count = 0;
|
|
-
|
|
- if (down_interruptible(&ipt_mutex) != 0)
|
|
- return 0;
|
|
-
|
|
- LIST_FIND(&ipt_target, print_name, void *,
|
|
- offset, buffer, length, &pos, &count);
|
|
-
|
|
- up(&ipt_mutex);
|
|
-
|
|
- *start = (char *)((unsigned long)count - offset);
|
|
- return pos;
|
|
-}
|
|
-
|
|
-static int ipt_get_matches(char *buffer, char **start, off_t offset, int length)
|
|
-{
|
|
- off_t pos = 0;
|
|
- unsigned int count = 0;
|
|
-
|
|
- if (down_interruptible(&ipt_mutex) != 0)
|
|
- return 0;
|
|
-
|
|
- LIST_FIND(&ipt_match, print_name, void *,
|
|
- offset, buffer, length, &pos, &count);
|
|
-
|
|
- up(&ipt_mutex);
|
|
-
|
|
- *start = (char *)((unsigned long)count - offset);
|
|
- return pos;
|
|
-}
|
|
-
|
|
-static struct { char *name; get_info_t *get_info; } ipt_proc_entry[] =
|
|
-{ { "ip_tables_names", ipt_get_tables },
|
|
- { "ip_tables_targets", ipt_get_targets },
|
|
- { "ip_tables_matches", ipt_get_matches },
|
|
- { NULL, NULL} };
|
|
#endif /*CONFIG_PROC_FS*/
|
|
|
|
static int __init init(void)
|
|
@@ -1770,20 +1758,14 @@
|
|
#ifdef CONFIG_PROC_FS
|
|
{
|
|
struct proc_dir_entry *proc;
|
|
- int i;
|
|
|
|
- for (i = 0; ipt_proc_entry[i].name; i++) {
|
|
- proc = proc_net_create(ipt_proc_entry[i].name, 0,
|
|
- ipt_proc_entry[i].get_info);
|
|
+ proc = proc_net_create("ip_tables_names", 0, ipt_get_tables);
|
|
if (!proc) {
|
|
- while (--i >= 0)
|
|
- proc_net_remove(ipt_proc_entry[i].name);
|
|
nf_unregister_sockopt(&ipt_sockopts);
|
|
return -ENOMEM;
|
|
}
|
|
proc->owner = THIS_MODULE;
|
|
}
|
|
- }
|
|
#endif
|
|
|
|
printk("ip_tables: (C) 2000-2002 Netfilter core team\n");
|
|
@@ -1794,11 +1776,7 @@
|
|
{
|
|
nf_unregister_sockopt(&ipt_sockopts);
|
|
#ifdef CONFIG_PROC_FS
|
|
- {
|
|
- int i;
|
|
- for (i = 0; ipt_proc_entry[i].name; i++)
|
|
- proc_net_remove(ipt_proc_entry[i].name);
|
|
- }
|
|
+ proc_net_remove("ip_tables_names");
|
|
#endif
|
|
}
|
|
|
|
diff -Nurb 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 <net/route.h>
|
|
#include <linux/netfilter_ipv4/ipt_LOG.h>
|
|
|
|
+#if 0
|
|
+#define DEBUGP printk
|
|
+#else
|
|
#define DEBUGP(format, args...)
|
|
+#endif
|
|
|
|
struct esphdr {
|
|
__u32 spi;
|
|
-};
|
|
+}; /* FIXME evil kludge */
|
|
|
|
/* Use lock to serialize, so printks don't overlap */
|
|
static spinlock_t log_lock = SPIN_LOCK_UNLOCKED;
|
|
diff -Nurb 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 <linux/module.h>
|
|
#include <linux/skbuff.h>
|
|
#include <linux/ip.h>
|
|
-#include <linux/udp.h>
|
|
-#include <linux/icmp.h>
|
|
#include <net/icmp.h>
|
|
#include <net/ip.h>
|
|
#include <net/tcp.h>
|
|
@@ -16,7 +14,11 @@
|
|
#include <linux/netfilter_ipv4/ip_tables.h>
|
|
#include <linux/netfilter_ipv4/ipt_REJECT.h>
|
|
|
|
+#if 0
|
|
+#define DEBUGP printk
|
|
+#else
|
|
#define DEBUGP(format, args...)
|
|
+#endif
|
|
|
|
/* If the original packet is part of a connection, but the connection
|
|
is not confirmed, our manufactured reply will not be associated
|
|
@@ -155,7 +157,6 @@
|
|
static void send_unreach(struct sk_buff *skb_in, int code)
|
|
{
|
|
struct iphdr *iph;
|
|
- struct udphdr *udph;
|
|
struct icmphdr *icmph;
|
|
struct sk_buff *nskb;
|
|
u32 saddr;
|
|
@@ -167,6 +168,7 @@
|
|
if (!rt)
|
|
return;
|
|
|
|
+ /* FIXME: Use sysctl number. --RR */
|
|
if (!xrlim_allow(&rt->u.dst, 1*HZ))
|
|
return;
|
|
|
|
@@ -184,19 +186,6 @@
|
|
if (iph->frag_off&htons(IP_OFFSET))
|
|
return;
|
|
|
|
- /* if UDP checksum is set, verify it's correct */
|
|
- if (iph->protocol == IPPROTO_UDP
|
|
- && skb_in->tail-(u8*)iph >= sizeof(struct udphdr)) {
|
|
- int datalen = skb_in->len - (iph->ihl<<2);
|
|
- udph = (struct udphdr *)((char *)iph + (iph->ihl<<2));
|
|
- if (udph->check
|
|
- && csum_tcpudp_magic(iph->saddr, iph->daddr,
|
|
- datalen, IPPROTO_UDP,
|
|
- csum_partial((char *)udph, datalen,
|
|
- 0)) != 0)
|
|
- return;
|
|
- }
|
|
-
|
|
/* If we send an ICMP error to an ICMP error a mess would result.. */
|
|
if (iph->protocol == IPPROTO_ICMP
|
|
&& skb_in->tail-(u8*)iph >= sizeof(struct icmphdr)) {
|
|
@@ -271,6 +260,7 @@
|
|
/* Copy as much of original packet as will fit */
|
|
data = skb_put(nskb,
|
|
length - sizeof(struct iphdr) - sizeof(struct icmphdr));
|
|
+ /* FIXME: won't work with nonlinear skbs --RR */
|
|
memcpy(data, skb_in->nh.iph,
|
|
length - sizeof(struct iphdr) - sizeof(struct icmphdr));
|
|
icmph->checksum = ip_compute_csum((unsigned char *)icmph,
|
|
diff -Nurb 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 - <Anders K. Pedersen>
|
|
*
|
|
* Released under the terms of the GPL
|
|
*
|
|
@@ -32,7 +31,7 @@
|
|
* Specify, after how many clock ticks (intel: 100 per second) the queue
|
|
* should be flushed even if it is not full yet.
|
|
*
|
|
- * ipt_ULOG.c,v 1.22 2002/10/30 09:07:31 laforge Exp
|
|
+ * ipt_ULOG.c,v 1.21 2002/08/29 10:54:34 laforge Exp
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
@@ -60,7 +59,12 @@
|
|
#define ULOG_NL_EVENT 111 /* Harald's favorite number */
|
|
#define ULOG_MAXNLGROUPS 32 /* numer of nlgroups */
|
|
|
|
+#if 0
|
|
+#define DEBUGP(format, args...) printk(__FILE__ ":" __FUNCTION__ ":" \
|
|
+ format, ## args)
|
|
+#else
|
|
#define DEBUGP(format, args...)
|
|
+#endif
|
|
|
|
#define PRINTR(format, args...) do { if (net_ratelimit()) printk(format, ## args); } while (0)
|
|
|
|
@@ -220,8 +224,7 @@
|
|
&& in->hard_header_len <= ULOG_MAC_LEN) {
|
|
memcpy(pm->mac, (*pskb)->mac.raw, in->hard_header_len);
|
|
pm->mac_len = in->hard_header_len;
|
|
- } else
|
|
- pm->mac_len = 0;
|
|
+ }
|
|
|
|
if (in)
|
|
strncpy(pm->indev_name, in->name, sizeof(pm->indev_name));
|
|
diff -Nurb 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 <linux/netfilter_ipv4/ipt_multiport.h>
|
|
#include <linux/netfilter_ipv4/ip_tables.h>
|
|
|
|
+#if 0
|
|
+#define duprintf(format, args...) printk(format , ## args)
|
|
+#else
|
|
#define duprintf(format, args...)
|
|
+#endif
|
|
|
|
/* Returns 1 if the port is matched by the test, 0 otherwise. */
|
|
static inline int
|
|
@@ -74,7 +78,7 @@
|
|
|
|
/* Must specify proto == TCP/UDP, no unknown flags or bad count */
|
|
return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
|
|
- && !(ip->invflags & IPT_INV_PROTO)
|
|
+ && !(ip->flags & IPT_INV_PROTO)
|
|
&& matchsize == IPT_ALIGN(sizeof(struct ipt_multiport))
|
|
&& (multiinfo->flags == IPT_MULTIPORT_SOURCE
|
|
|| multiinfo->flags == IPT_MULTIPORT_DESTINATION
|
|
diff -Nurb 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 <linux/module.h>
|
|
-#include <linux/ip.h>
|
|
-#include <linux/skbuff.h>
|
|
-
|
|
-#include <linux/netfilter_ipv4/ip_tables.h>
|
|
-#include <linux/netfilter_ipv4/ip_pool.h>
|
|
-#include <linux/netfilter_ipv4/ipt_pool.h>
|
|
-
|
|
-static inline int match_pool(
|
|
- ip_pool_t index,
|
|
- __u32 addr,
|
|
- int inv
|
|
-) {
|
|
- if (ip_pool_match(index, ntohl(addr)))
|
|
- inv = !inv;
|
|
- return inv;
|
|
-}
|
|
-
|
|
-static int match(
|
|
- const struct sk_buff *skb,
|
|
- const struct net_device *in,
|
|
- const struct net_device *out,
|
|
- const void *matchinfo,
|
|
- int offset,
|
|
- const void *hdr,
|
|
- u_int16_t datalen,
|
|
- int *hotdrop
|
|
-) {
|
|
- const struct ipt_pool_info *info = matchinfo;
|
|
- const struct iphdr *iph = skb->nh.iph;
|
|
-
|
|
- if (info->src != IP_POOL_NONE && !match_pool(info->src, iph->saddr,
|
|
- info->flags&IPT_POOL_INV_SRC))
|
|
- return 0;
|
|
-
|
|
- if (info->dst != IP_POOL_NONE && !match_pool(info->dst, iph->daddr,
|
|
- info->flags&IPT_POOL_INV_DST))
|
|
- return 0;
|
|
-
|
|
- return 1;
|
|
-}
|
|
-
|
|
-static int checkentry(
|
|
- const char *tablename,
|
|
- const struct ipt_ip *ip,
|
|
- void *matchinfo,
|
|
- unsigned int matchsize,
|
|
- unsigned int hook_mask
|
|
-) {
|
|
- if (matchsize != IPT_ALIGN(sizeof(struct ipt_pool_info)))
|
|
- return 0;
|
|
- return 1;
|
|
-}
|
|
-
|
|
-static struct ipt_match pool_match
|
|
-= { { NULL, NULL }, "pool", &match, &checkentry, NULL, THIS_MODULE };
|
|
-
|
|
-static int __init init(void)
|
|
-{
|
|
- return ipt_register_match(&pool_match);
|
|
-}
|
|
-
|
|
-static void __exit fini(void)
|
|
-{
|
|
- ipt_unregister_match(&pool_match);
|
|
-}
|
|
-
|
|
-module_init(init);
|
|
-module_exit(fini);
|
|
diff -Nurb 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 <roque@di.fc.ul.pt>
|
|
*
|
|
- * $Id: mcast.c,v 1.1.1.4 2003/10/14 08:09:34 sparq Exp $
|
|
+ * $Id: mcast.c,v 1.38 2001/08/15 07:36:31 davem Exp $
|
|
*
|
|
* Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c
|
|
*
|