[PATCH 7/8] netfilter: Remove IPCHAINS and IPFWADM compatibility

Rusty Russell rusty at rustcorp.com.au
Fri Dec 31 12:43:16 CET 2004


Name: Remove IPCHAINS and IPFWADM compatibility
Status: Trivial
Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

We've been threatening to do this for ages: remove the backwards
compatibility code.  We can now combine ip_conntrack_core.c and
ip_conntrack_standalone.c, likewise for the NAT code, but that will
come later.

Index: linux-2.6.10-rc3-bk6-Netfilter/include/linux/netfilter_ipv4/ipfwadm_core.h
===================================================================
--- linux-2.6.10-rc3-bk6-Netfilter.orig/include/linux/netfilter_ipv4/ipfwadm_core.h	2004-12-13 12:02:08.078843096 +1100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,256 +0,0 @@
-#ifndef _IPFWADM_CORE_H
-#define _IPFWADM_CORE_H
-/* Minor modifications to fit on compatibility framework:
-   Rusty.Russell at rustcorp.com.au
-*/
-
-/*
- *	IP firewalling code. This is taken from 4.4BSD. Please note the
- *	copyright message below. As per the GPL it must be maintained
- *	and the licenses thus do not conflict. While this port is subject
- *	to the GPL I also place my modifications under the original
- *	license in recognition of the original copyright.
- *
- *	Ported from BSD to Linux,
- *		Alan Cox 22/Nov/1994.
- *	Merged and included the FreeBSD-Current changes at Ugen's request
- *	(but hey it's a lot cleaner now). Ugen would prefer in some ways
- *	we waited for his final product but since Linux 1.2.0 is about to
- *	appear it's not practical - Read: It works, it's not clean but please
- *	don't consider it to be his standard of finished work.
- *		Alan.
- *
- * Fixes:
- *	Pauline Middelink	:	Added masquerading.
- *	Jos Vos			:	Separate input  and output firewall
- *					chains, new "insert" and "append"
- *					commands to replace "add" commands,
- *					add ICMP header to struct ip_fwpkt.
- *	Jos Vos			:	Add support for matching device names.
- *	Willy Konynenberg	:	Add transparent proxying support.
- *	Jos Vos			:	Add options for input/output accounting.
- *
- *	All the real work was done by .....
- */
-
-/*
- * Copyright (c) 1993 Daniel Boulet
- * Copyright (c) 1994 Ugen J.S.Antsilevich
- *
- * Redistribution and use in source forms, with and without modification,
- * are permitted provided that this entire comment appears intact.
- *
- * Redistribution in binary form may occur without any restrictions.
- * Obviously, it would be nice if you gave credit where credit is due
- * but requiring it would be too onerous.
- *
- * This software is provided ``AS IS'' without any warranties of any kind.
- */
-
-/*
- * 	Format of an IP firewall descriptor
- *
- * 	src, dst, src_mask, dst_mask are always stored in network byte order.
- * 	flags and num_*_ports are stored in host byte order (of course).
- * 	Port numbers are stored in HOST byte order.
- */
-
-#ifdef __KERNEL__
-#include <linux/icmp.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#include <linux/udp.h>
-#endif
-
-struct ip_fw
-{
-	struct ip_fw  *fw_next;			/* Next firewall on chain */
-	struct in_addr fw_src, fw_dst;		/* Source and destination IP addr */
-	struct in_addr fw_smsk, fw_dmsk;	/* Mask for src and dest IP addr */
-	struct in_addr fw_via;			/* IP address of interface "via" */
-	struct net_device *fw_viadev;		/* device of interface "via" */
-	__u16	fw_flg;				/* Flags word */
-	__u16 	fw_nsp, fw_ndp;			/* N'of src ports and # of dst ports */
-						/* in ports array (dst ports follow */
-    						/* src ports; max of 10 ports in all; */
-    						/* count of 0 means match all ports) */
-#define IP_FW_MAX_PORTS	10      		/* A reasonable maximum */
-	__u16	fw_pts[IP_FW_MAX_PORTS];	/* Array of port numbers to match */
-	unsigned long  fw_pcnt,fw_bcnt;		/* Packet and byte counters */
-	__u8	fw_tosand, fw_tosxor;		/* Revised packet priority */
-	char           fw_vianame[IFNAMSIZ];	/* name of interface "via" */
-};
-
-/*
- *	Values for "flags" field .
- */
-
-#define IP_FW_F_ALL	0x0000	/* This is a universal packet firewall*/
-#define IP_FW_F_TCP	0x0001	/* This is a TCP packet firewall      */
-#define IP_FW_F_UDP	0x0002	/* This is a UDP packet firewall      */
-#define IP_FW_F_ICMP	0x0003	/* This is a ICMP packet firewall     */
-#define IP_FW_F_KIND	0x0003	/* Mask to isolate firewall kind      */
-#define IP_FW_F_ACCEPT	0x0004	/* This is an accept firewall (as     *
-				 *         opposed to a deny firewall)*
-				 *                                    */
-#define IP_FW_F_SRNG	0x0008	/* The first two src ports are a min  *
-				 * and max range (stored in host byte *
-				 * order).                            *
-				 *                                    */
-#define IP_FW_F_DRNG	0x0010	/* The first two dst ports are a min  *
-				 * and max range (stored in host byte *
-				 * order).                            *
-				 * (ports[0] <= port <= ports[1])     *
-				 *                                    */
-#define IP_FW_F_PRN	0x0020	/* In verbose mode print this firewall*/
-#define IP_FW_F_BIDIR	0x0040	/* For bidirectional firewalls        */
-#define IP_FW_F_TCPSYN	0x0080	/* For tcp packets-check SYN only     */
-#define IP_FW_F_ICMPRPL 0x0100	/* Send back icmp unreachable packet  */
-#define IP_FW_F_MASQ	0x0200	/* Masquerading			      */
-#define IP_FW_F_TCPACK	0x0400	/* For tcp-packets match if ACK is set*/
-#define IP_FW_F_REDIR	0x0800	/* Redirect to local port fw_pts[n]   */
-#define IP_FW_F_ACCTIN  0x1000	/* Account incoming packets only.     */
-#define IP_FW_F_ACCTOUT 0x2000	/* Account outgoing packets only.     */
-
-#define IP_FW_F_MASK	0x3FFF	/* All possible flag bits mask        */
-
-/*
- *	New IP firewall options for [gs]etsockopt at the RAW IP level.
- *	Unlike BSD Linux inherits IP options so you don't have to use
- *	a raw socket for this. Instead we check rights in the calls.
- */
-
-#define IP_FW_BASE_CTL  	64	/* base for firewall socket options */
-
-#define IP_FW_COMMAND		0x00FF	/* mask for command without chain */
-#define IP_FW_TYPE		0x0300	/* mask for type (chain) */
-#define IP_FW_SHIFT		8	/* shift count for type (chain) */
-
-#define IP_FW_FWD		0
-#define IP_FW_IN		1
-#define IP_FW_OUT		2
-#define IP_FW_ACCT		3
-#define IP_FW_CHAINS		4	/* total number of ip_fw chains */
-#define IP_FW_MASQ		5
-
-#define IP_FW_INSERT		(IP_FW_BASE_CTL)
-#define IP_FW_APPEND		(IP_FW_BASE_CTL+1)
-#define IP_FW_DELETE		(IP_FW_BASE_CTL+2)
-#define IP_FW_FLUSH		(IP_FW_BASE_CTL+3)
-#define IP_FW_ZERO		(IP_FW_BASE_CTL+4)
-#define IP_FW_POLICY		(IP_FW_BASE_CTL+5)
-#define IP_FW_CHECK		(IP_FW_BASE_CTL+6)
-#define IP_FW_MASQ_TIMEOUTS	(IP_FW_BASE_CTL+7)
-
-#define IP_FW_INSERT_FWD	(IP_FW_INSERT | (IP_FW_FWD << IP_FW_SHIFT))
-#define IP_FW_APPEND_FWD	(IP_FW_APPEND | (IP_FW_FWD << IP_FW_SHIFT))
-#define IP_FW_DELETE_FWD	(IP_FW_DELETE | (IP_FW_FWD << IP_FW_SHIFT))
-#define IP_FW_FLUSH_FWD		(IP_FW_FLUSH  | (IP_FW_FWD << IP_FW_SHIFT))
-#define IP_FW_ZERO_FWD		(IP_FW_ZERO   | (IP_FW_FWD << IP_FW_SHIFT))
-#define IP_FW_POLICY_FWD	(IP_FW_POLICY | (IP_FW_FWD << IP_FW_SHIFT))
-#define IP_FW_CHECK_FWD		(IP_FW_CHECK  | (IP_FW_FWD << IP_FW_SHIFT))
-
-#define IP_FW_INSERT_IN		(IP_FW_INSERT | (IP_FW_IN << IP_FW_SHIFT))
-#define IP_FW_APPEND_IN		(IP_FW_APPEND | (IP_FW_IN << IP_FW_SHIFT))
-#define IP_FW_DELETE_IN		(IP_FW_DELETE | (IP_FW_IN << IP_FW_SHIFT))
-#define IP_FW_FLUSH_IN		(IP_FW_FLUSH  | (IP_FW_IN << IP_FW_SHIFT))
-#define IP_FW_ZERO_IN		(IP_FW_ZERO   | (IP_FW_IN << IP_FW_SHIFT))
-#define IP_FW_POLICY_IN		(IP_FW_POLICY | (IP_FW_IN << IP_FW_SHIFT))
-#define IP_FW_CHECK_IN		(IP_FW_CHECK  | (IP_FW_IN << IP_FW_SHIFT))
-
-#define IP_FW_INSERT_OUT	(IP_FW_INSERT | (IP_FW_OUT << IP_FW_SHIFT))
-#define IP_FW_APPEND_OUT	(IP_FW_APPEND | (IP_FW_OUT << IP_FW_SHIFT))
-#define IP_FW_DELETE_OUT	(IP_FW_DELETE | (IP_FW_OUT << IP_FW_SHIFT))
-#define IP_FW_FLUSH_OUT		(IP_FW_FLUSH  | (IP_FW_OUT << IP_FW_SHIFT))
-#define IP_FW_ZERO_OUT		(IP_FW_ZERO   | (IP_FW_OUT << IP_FW_SHIFT))
-#define IP_FW_POLICY_OUT	(IP_FW_POLICY | (IP_FW_OUT << IP_FW_SHIFT))
-#define IP_FW_CHECK_OUT		(IP_FW_CHECK  | (IP_FW_OUT << IP_FW_SHIFT))
-
-#define IP_ACCT_INSERT		(IP_FW_INSERT | (IP_FW_ACCT << IP_FW_SHIFT))
-#define IP_ACCT_APPEND		(IP_FW_APPEND | (IP_FW_ACCT << IP_FW_SHIFT))
-#define IP_ACCT_DELETE		(IP_FW_DELETE | (IP_FW_ACCT << IP_FW_SHIFT))
-#define IP_ACCT_FLUSH		(IP_FW_FLUSH  | (IP_FW_ACCT << IP_FW_SHIFT))
-#define IP_ACCT_ZERO		(IP_FW_ZERO   | (IP_FW_ACCT << IP_FW_SHIFT))
-
-#define IP_FW_MASQ_INSERT	(IP_FW_INSERT | (IP_FW_MASQ << IP_FW_SHIFT))
-#define IP_FW_MASQ_ADD		(IP_FW_APPEND | (IP_FW_MASQ << IP_FW_SHIFT))
-#define IP_FW_MASQ_DEL		(IP_FW_DELETE | (IP_FW_MASQ << IP_FW_SHIFT))
-#define IP_FW_MASQ_FLUSH  	(IP_FW_FLUSH  | (IP_FW_MASQ << IP_FW_SHIFT))
-
-#define IP_FW_MASQ_INSERT	(IP_FW_INSERT | (IP_FW_MASQ << IP_FW_SHIFT))
-#define IP_FW_MASQ_ADD		(IP_FW_APPEND | (IP_FW_MASQ << IP_FW_SHIFT))
-#define IP_FW_MASQ_DEL		(IP_FW_DELETE | (IP_FW_MASQ << IP_FW_SHIFT))
-#define IP_FW_MASQ_FLUSH  	(IP_FW_FLUSH  | (IP_FW_MASQ << IP_FW_SHIFT))
-
-struct ip_fwpkt
-{
-	struct iphdr fwp_iph;			/* IP header */
-	union {
-		struct tcphdr fwp_tcph;		/* TCP header or */
-		struct udphdr fwp_udph;		/* UDP header */
-		struct icmphdr fwp_icmph;	/* ICMP header */
-	} fwp_protoh;
-	struct in_addr fwp_via;			/* interface address */
-	char           fwp_vianame[IFNAMSIZ];	/* interface name */
-};
-
-#define IP_FW_MASQCTL_MAX 256
-#define IP_MASQ_MOD_NMAX  32
-
-struct ip_fw_masqctl
-{
-	int mctl_action;
-	union {
-		struct {
-			char name[IP_MASQ_MOD_NMAX];
-			char data[1];
-		} mod;
-	} u;
-};
-
-/*
- * timeouts for ip masquerading
- */
-
-struct ip_fw_masq;
-
-/*
- *	Main firewall chains definitions and global var's definitions.
- */
-
-#ifdef __KERNEL__
-
-/* Modes used in the ip_fw_chk() routine. */
-#define IP_FW_MODE_FW		0x00	/* kernel firewall check */
-#define IP_FW_MODE_ACCT_IN	0x01	/* accounting (incoming) */
-#define IP_FW_MODE_ACCT_OUT	0x02	/* accounting (outgoing) */
-#define IP_FW_MODE_CHK		0x04	/* check requested by user */
-
-#include <linux/config.h>
-#ifdef CONFIG_IP_FIREWALL
-extern struct ip_fw *ip_fw_in_chain;
-extern struct ip_fw *ip_fw_out_chain;
-extern struct ip_fw *ip_fw_fwd_chain;
-extern int ip_fw_in_policy;
-extern int ip_fw_out_policy;
-extern int ip_fw_fwd_policy;
-extern int ip_fw_ctl(int, void *, int);
-#endif
-#ifdef CONFIG_IP_ACCT
-extern struct ip_fw *ip_acct_chain;
-extern int ip_acct_ctl(int, void *, int);
-#endif
-#ifdef CONFIG_IP_MASQUERADE
-extern int ip_masq_ctl(int, void *, int);
-#endif
-#ifdef CONFIG_IP_MASQUERADE
-extern int ip_masq_ctl(int, void *, int);
-#endif
-
-extern int ip_fw_masq_timeouts(void *user, int len);
-
-extern int ip_fw_chk(struct sk_buff **, struct net_device *, __u16 *,
-		     struct ip_fw *, int, int);
-#endif /* KERNEL */
-#endif /* _IP_FW_H */
Index: linux-2.6.10-rc3-bk6-Netfilter/include/linux/netfilter_ipv4/ipchains_core.h
===================================================================
--- linux-2.6.10-rc3-bk6-Netfilter.orig/include/linux/netfilter_ipv4/ipchains_core.h	2004-12-13 12:02:08.078843096 +1100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,189 +0,0 @@
-/*
- * This code is heavily based on the code in ip_fw.h; see that file for
- * copyrights and attributions.  This code is basically GPL.
- *
- * 15-Feb-1997: Major changes to allow graphs for firewall rules.
- *              Paul Russell <Paul.Russell at rustcorp.com.au> and
- *		Michael Neuling <Michael.Neuling at rustcorp.com.au>
- * 2-Nov-1997: Changed types to __u16, etc.
- *             Removed IP_FW_F_TCPACK & IP_FW_F_BIDIR.
- *             Added inverse flags field.
- *             Removed multiple port specs.
- */
-
-/*
- * 	Format of an IP firewall descriptor
- *
- * 	src, dst, src_mask, dst_mask are always stored in network byte order.
- * 	flags are stored in host byte order (of course).
- * 	Port numbers are stored in HOST byte order.
- */
-
-#ifndef _IP_FWCHAINS_H
-#define _IP_FWCHAINS_H
-
-#ifdef __KERNEL__
-#include <linux/icmp.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#include <linux/udp.h>
-#endif /* __KERNEL__ */
-#define IP_FW_MAX_LABEL_LENGTH 8
-typedef char ip_chainlabel[IP_FW_MAX_LABEL_LENGTH+1];
-
-struct ip_fw
-{
-	struct in_addr fw_src, fw_dst;		/* Source and destination IP addr */
-	struct in_addr fw_smsk, fw_dmsk;	/* Mask for src and dest IP addr */
-	__u32 fw_mark;                          /* ID to stamp on packet */
-	__u16 fw_proto;                         /* Protocol, 0 = ANY */
-	__u16 fw_flg;			        /* Flags word */
-        __u16 fw_invflg;                        /* Inverse flags */
-	__u16 fw_spts[2];                       /* Source port range. */
-        __u16 fw_dpts[2];                       /* Destination port range. */
-	__u16 fw_redirpt;                       /* Port to redirect to. */
-	__u16 fw_outputsize;                    /* Max amount to output to
-						   NETLINK */
-	char           fw_vianame[IFNAMSIZ];	/* name of interface "via" */
-	__u8           fw_tosand, fw_tosxor;	/* Revised packet priority */
-};
-
-struct ip_fwuser
-{
-	struct ip_fw ipfw;
-	ip_chainlabel label;
-};
-
-/* Values for "fw_flg" field .  */
-#define IP_FW_F_PRN	0x0001	/* Print packet if it matches */
-#define IP_FW_F_TCPSYN	0x0002	/* For tcp packets-check SYN only */
-#define IP_FW_F_FRAG	0x0004  /* Set if rule is a fragment rule */
-#define IP_FW_F_MARKABS	0x0008  /* Set the mark to fw_mark, not add. */
-#define IP_FW_F_WILDIF	0x0010  /* Need only match start of interface name. */
-#define IP_FW_F_NETLINK 0x0020  /* Redirect to netlink: 2.1.x only */
-#define IP_FW_F_MASK	0x003F	/* All possible flag bits mask   */
-
-/* Values for "fw_invflg" field. */
-#define IP_FW_INV_SRCIP 0x0001  /* Invert the sense of fw_src. */
-#define IP_FW_INV_DSTIP 0x0002  /* Invert the sense of fw_dst. */
-#define IP_FW_INV_PROTO 0x0004  /* Invert the sense of fw_proto. */
-#define IP_FW_INV_SRCPT 0x0008  /* Invert the sense of source ports. */
-#define IP_FW_INV_DSTPT 0x0010  /* Invert the sense of destination ports. */
-#define IP_FW_INV_VIA   0x0020  /* Invert the sense of fw_vianame. */
-#define IP_FW_INV_SYN   0x0040  /* Invert the sense of IP_FW_F_TCPSYN. */
-#define IP_FW_INV_FRAG  0x0080  /* Invert the sense of IP_FW_F_FRAG. */
-
-/*
- *	New IP firewall options for [gs]etsockopt at the RAW IP level.
- *	Unlike BSD Linux inherits IP options so you don't have to use
- * a raw socket for this. Instead we check rights in the calls.  */
-
-#define IP_FW_BASE_CTL  	64	/* base for firewall socket options */
-
-#define IP_FW_APPEND		(IP_FW_BASE_CTL)    /* Takes ip_fwchange */
-#define IP_FW_REPLACE		(IP_FW_BASE_CTL+1)  /* Takes ip_fwnew */
-#define IP_FW_DELETE_NUM	(IP_FW_BASE_CTL+2)  /* Takes ip_fwdelnum */
-#define IP_FW_DELETE		(IP_FW_BASE_CTL+3)  /* Takes ip_fwchange */
-#define IP_FW_INSERT		(IP_FW_BASE_CTL+4)  /* Takes ip_fwnew */
-#define IP_FW_FLUSH		(IP_FW_BASE_CTL+5)  /* Takes ip_chainlabel */
-#define IP_FW_ZERO		(IP_FW_BASE_CTL+6)  /* Takes ip_chainlabel */
-#define IP_FW_CHECK		(IP_FW_BASE_CTL+7)  /* Takes ip_fwtest */
-#define IP_FW_MASQ_TIMEOUTS	(IP_FW_BASE_CTL+8)  /* Takes 3 ints */
-#define IP_FW_CREATECHAIN	(IP_FW_BASE_CTL+9)  /* Takes ip_chainlabel */
-#define IP_FW_DELETECHAIN	(IP_FW_BASE_CTL+10) /* Takes ip_chainlabel */
-#define IP_FW_POLICY		(IP_FW_BASE_CTL+11) /* Takes ip_fwpolicy */
-/* Masquerade control, only 1 optname */
-
-#define IP_FW_MASQ_CTL  	(IP_FW_BASE_CTL+12) /* General ip_masq ctl */
-
-/* Builtin chain labels */
-#define IP_FW_LABEL_FORWARD	"forward"
-#define IP_FW_LABEL_INPUT	"input"
-#define IP_FW_LABEL_OUTPUT	"output"
-
-/* Special targets */
-#define IP_FW_LABEL_MASQUERADE  "MASQ"
-#define IP_FW_LABEL_REDIRECT    "REDIRECT"
-#define IP_FW_LABEL_ACCEPT	"ACCEPT"
-#define IP_FW_LABEL_BLOCK	"DENY"
-#define IP_FW_LABEL_REJECT	"REJECT"
-#define IP_FW_LABEL_RETURN	"RETURN"
-#define IP_FW_LABEL_QUEUE       "QUEUE"
-
-/* Files in /proc/net */
-#define IP_FW_PROC_CHAINS	"ip_fwchains"
-#define IP_FW_PROC_CHAIN_NAMES	"ip_fwnames"
-
-
-struct ip_fwpkt
-{
-	struct iphdr fwp_iph;			/* IP header */
-	union {
-		struct tcphdr fwp_tcph;		/* TCP header or */
-		struct udphdr fwp_udph;		/* UDP header */
-		struct icmphdr fwp_icmph;	/* ICMP header */
-	} fwp_protoh;
-	struct in_addr fwp_via;			/* interface address */
-	char           fwp_vianame[IFNAMSIZ];	/* interface name */
-};
-
-/* The argument to IP_FW_DELETE and IP_FW_APPEND */
-struct ip_fwchange
-{
-	struct ip_fwuser fwc_rule;
-	ip_chainlabel fwc_label;
-};	
-
-/* The argument to IP_FW_CHECK. */
-struct ip_fwtest
-{
-	struct ip_fwpkt fwt_packet; /* Packet to be tested */
-	ip_chainlabel fwt_label;   /* Block to start test in */
-};
-						
-/* The argument to IP_FW_DELETE_NUM */
-struct ip_fwdelnum
-{
-	__u32 fwd_rulenum;
-	ip_chainlabel fwd_label;
-};
-
-/* The argument to IP_FW_REPLACE and IP_FW_INSERT */
-struct ip_fwnew
-{
-	__u32 fwn_rulenum;
-	struct ip_fwuser fwn_rule;
-	ip_chainlabel fwn_label;
-};
-
-/* The argument to IP_FW_POLICY */
-struct ip_fwpolicy
-{
-	ip_chainlabel fwp_policy;
-	ip_chainlabel fwp_label;
-};
-/*
- * timeouts for ip masquerading
- */
-
-extern int ip_fw_masq_timeouts(void *, int);
-
-
-/*
- *	Main firewall chains definitions and global var's definitions.
- */
-
-#ifdef __KERNEL__
-
-#include <linux/config.h>
-#include <linux/version.h>
-#include <linux/init.h>
-extern void ip_fw_init(void) __init;
-extern int ip_fw_ctl(int, void *, int);
-#ifdef CONFIG_IP_MASQUERADE
-extern int ip_masq_uctl(int, char *, int);
-#endif
-#endif /* KERNEL */
-
-#endif /* _IP_FWCHAINS_H */
Index: linux-2.6.10-rc3-bk6-Netfilter/net/ipv4/netfilter/ipchains_core.c
===================================================================
--- linux-2.6.10-rc3-bk6-Netfilter.orig/net/ipv4/netfilter/ipchains_core.c	2004-12-13 12:02:08.077843248 +1100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,1854 +0,0 @@
-#warning ipchains is obsolete, and will be removed soon.
-
-/* Minor modifications to fit on compatibility framework:
-   Rusty.Russell at rustcorp.com.au
-*/
-
-/*
- * This code is heavily based on the code on the old ip_fw.c code; see below for
- * copyrights and attributions of the old code.  This code is basically GPL.
- *
- * 15-Aug-1997: Major changes to allow graphs for firewall rules.
- *              Paul Russell <Paul.Russell at rustcorp.com.au> and
- *		Michael Neuling <Michael.Neuling at rustcorp.com.au>
- * 24-Aug-1997: Generalised protocol handling (not just TCP/UDP/ICMP).
- *              Added explicit RETURN from chains.
- *              Removed TOS mangling (done in ipchains 1.0.1).
- *              Fixed read & reset bug by reworking proc handling.
- *              Paul Russell <Paul.Russell at rustcorp.com.au>
- * 28-Sep-1997: Added packet marking for net sched code.
- *              Removed fw_via comparisons: all done on device name now,
- *              similar to changes in ip_fw.c in DaveM's CVS970924 tree.
- *              Paul Russell <Paul.Russell at rustcorp.com.au>
- * 2-Nov-1997:  Moved types across to __u16, etc.
- *              Added inverse flags.
- *              Fixed fragment bug (in args to port_match).
- *              Changed mark to only one flag (MARKABS).
- * 21-Nov-1997: Added ability to test ICMP code.
- * 19-Jan-1998: Added wildcard interfaces.
- * 6-Feb-1998:  Merged 2.0 and 2.1 versions.
- *              Initialised ip_masq for 2.0.x version.
- *              Added explicit NETLINK option for 2.1.x version.
- *              Added packet and byte counters for policy matches.
- * 26-Feb-1998: Fixed race conditions, added SMP support.
- * 18-Mar-1998: Fix SMP, fix race condition fix.
- * 1-May-1998:  Remove caching of device pointer.
- * 12-May-1998: Allow tiny fragment case for TCP/UDP.
- * 15-May-1998: Treat short packets as fragments, don't just block.
- * 3-Jan-1999:  Fixed serious procfs security hole -- users should never
- *              be allowed to view the chains!
- *              Marc Santoro <ultima at snicker.emoti.com>
- * 29-Jan-1999: Locally generated bogus IPs dealt with, rather than crash
- *              during dump_packet. --RR.
- * 19-May-1999: Star Wars: The Phantom Menace opened.  Rule num
- *		printed in log (modified from Michael Hasenstein's patch).
- *		Added SYN in log message. --RR
- * 23-Jul-1999: Fixed small fragment security exposure opened on 15-May-1998.
- *              John McDonald <jm at dataprotect.com>
- *              Thomas Lopatic <tl at dataprotect.com>
- */
-
-/*
- *
- * The origina Linux port was done Alan Cox, with changes/fixes from
- * Pauline Middlelink, Jos Vos, Thomas Quinot, Wouter Gadeyne, Juan
- * Jose Ciarlante, Bernd Eckenfels, Keith Owens and others.
- *
- * Copyright from the original FreeBSD version follows:
- *
- * Copyright (c) 1993 Daniel Boulet
- * Copyright (c) 1994 Ugen J.S.Antsilevich
- *
- * Redistribution and use in source forms, with and without modification,
- * are permitted provided that this entire comment appears intact.
- *
- * Redistribution in binary form may occur without any restrictions.
- * Obviously, it would be nice if you gave credit where credit is due
- * but requiring it would be too onerous.
- *
- * This software is provided ``AS IS'' without any warranties of any kind.  */
-
-#include <linux/config.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/icmp.h>
-#include <linux/udp.h>
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <net/route.h>
-#include <net/tcp.h>
-#include <net/udp.h>
-#include <net/sock.h>
-#include <net/icmp.h>
-#include <linux/netlink.h>
-#include <linux/netfilter.h>
-#include <linux/netfilter_ipv4/compat_firewall.h>
-#include <linux/netfilter_ipv4/ipchains_core.h>
-#include <linux/netfilter_ipv4/ip_nat_core.h>
-
-#include <net/checksum.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_AUTHOR("Rusty Russell <rusty at rustcorp.com.au>");
-MODULE_DESCRIPTION("ipchains backwards compatibility layer");
-
-/* Understanding locking in this code: (thanks to Alan Cox for using
- * little words to explain this to me). -- PR
- *
- * In UP, there can be two packets traversing the chains:
- * 1) A packet from the current userspace context
- * 2) A packet off the bh handlers (timer or net).
- *
- * For SMP (kernel v2.1+), multiply this by # CPUs.
- *
- * [Note that this in not correct for 2.2 - because the socket code always
- *  uses lock_kernel() to serialize, and bottom halves (timers and net_bhs)
- *  only run on one CPU at a time.  This will probably change for 2.3.
- *  It is still good to use spinlocks because that avoids the global cli()
- *  for updating the tables, which is rather costly in SMP kernels -AK]
- *
- * This means counters and backchains can get corrupted if no precautions
- * are taken.
- *
- * To actually alter a chain on UP, we need only do a cli(), as this will
- * stop a bh handler firing, as we are in the current userspace context
- * (coming from a setsockopt()).
- *
- * On SMP, we need a write_lock_irqsave(), which is a simple cli() in
- * UP.
- *
- * For backchains and counters, we use an array, indexed by
- * [smp_processor_id()*2 + !in_interrupt()]; the array is of
- * size [NR_CPUS*2].  For v2.0, NR_CPUS is effectively 1.  So,
- * confident of uniqueness, we modify counters even though we only
- * have a read lock (to read the counters, you need a write lock,
- * though).  */
-
-/* Why I didn't use straight locking... -- PR
- *
- * The backchains can be separated out of the ip_chains structure, and
- * allocated as needed inside ip_fw_check().
- *
- * The counters, however, can't.  Trying to lock these means blocking
- * interrupts every time we want to access them.  This would suck HARD
- * performance-wise.  Not locking them leads to possible corruption,
- * made worse on 32-bit machines (counters are 64-bit).  */
-
-/*#define DEBUG_IP_FIREWALL*/
-/*#define DEBUG_ALLOW_ALL*/ /* Useful for remote debugging */
-/*#define DEBUG_IP_FIREWALL_USER*/
-/*#define DEBUG_IP_FIREWALL_LOCKING*/
-
-#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
-static struct sock *ipfwsk;
-#endif
-
-#ifdef CONFIG_SMP
-#define SLOT_NUMBER() (smp_processor_id()*2 + !in_interrupt())
-#else /* !SMP */
-#define SLOT_NUMBER() (!in_interrupt())
-#endif /* CONFIG_SMP */
-#define NUM_SLOTS (NR_CPUS*2)
-
-#define SIZEOF_STRUCT_IP_CHAIN (sizeof(struct ip_chain) \
-				+ NUM_SLOTS*sizeof(struct ip_reent))
-#define SIZEOF_STRUCT_IP_FW_KERNEL (sizeof(struct ip_fwkernel) \
-				    + NUM_SLOTS*sizeof(struct ip_counters))
-
-#ifdef DEBUG_IP_FIREWALL_LOCKING
-static unsigned int fwc_rlocks, fwc_wlocks;
-#define FWC_DEBUG_LOCK(d)			\
-do {						\
-	FWC_DONT_HAVE_LOCK(d);			\
-	d |= (1 << SLOT_NUMBER());		\
-} while (0)
-
-#define FWC_DEBUG_UNLOCK(d)			\
-do {						\
-	FWC_HAVE_LOCK(d);			\
-	d &= ~(1 << SLOT_NUMBER());		\
-} while (0)
-
-#define FWC_DONT_HAVE_LOCK(d)					\
-do {								\
-	if ((d) & (1 << SLOT_NUMBER()))				\
-		printk("%s:%i: Got lock on %i already!\n", 	\
-		       __FILE__, __LINE__, SLOT_NUMBER());	\
-} while(0)
-
-#define FWC_HAVE_LOCK(d)				\
-do {							\
-	if (!((d) & (1 << SLOT_NUMBER())))		\
-	printk("%s:%i:No lock on %i!\n", 		\
-	       __FILE__, __LINE__, SLOT_NUMBER());	\
-} while (0)
-
-#else
-#define FWC_DEBUG_LOCK(d) do { } while(0)
-#define FWC_DEBUG_UNLOCK(d) do { } while(0)
-#define FWC_DONT_HAVE_LOCK(d) do { } while(0)
-#define FWC_HAVE_LOCK(d) do { } while(0)
-#endif /*DEBUG_IP_FIRWALL_LOCKING*/
-
-#define FWC_READ_LOCK(l) do { FWC_DEBUG_LOCK(fwc_rlocks); read_lock(l); } while (0)
-#define FWC_WRITE_LOCK(l) do { FWC_DEBUG_LOCK(fwc_wlocks); write_lock(l); } while (0)
-#define FWC_READ_LOCK_IRQ(l,f) do { FWC_DEBUG_LOCK(fwc_rlocks); read_lock_irqsave(l,f); } while (0)
-#define FWC_WRITE_LOCK_IRQ(l,f) do { FWC_DEBUG_LOCK(fwc_wlocks); write_lock_irqsave(l,f); } while (0)
-#define FWC_READ_UNLOCK(l) do { FWC_DEBUG_UNLOCK(fwc_rlocks); read_unlock(l); } while (0)
-#define FWC_WRITE_UNLOCK(l) do { FWC_DEBUG_UNLOCK(fwc_wlocks); write_unlock(l); } while (0)
-#define FWC_READ_UNLOCK_IRQ(l,f) do { FWC_DEBUG_UNLOCK(fwc_rlocks); read_unlock_irqrestore(l,f); } while (0)
-#define FWC_WRITE_UNLOCK_IRQ(l,f) do { FWC_DEBUG_UNLOCK(fwc_wlocks); write_unlock_irqrestore(l,f); } while (0)
-
-struct ip_chain;
-
-struct ip_counters
-{
-	__u64 pcnt, bcnt;			/* Packet and byte counters */
-};
-
-struct ip_fwkernel
-{
-	struct ip_fw ipfw;
-	struct ip_fwkernel *next;	/* where to go next if current
-					 * rule doesn't match */
-	struct ip_chain *branch;	/* which branch to jump to if
-					 * current rule matches */
-	int simplebranch;		/* Use this if branch == NULL */
-	struct ip_counters counters[0]; /* Actually several of these */
-};
-
-struct ip_reent
-{
-	struct ip_chain *prevchain;	/* Pointer to referencing chain */
-	struct ip_fwkernel *prevrule;	/* Pointer to referencing rule */
-	struct ip_counters counters;
-};
-
-struct ip_chain
-{
-	ip_chainlabel label;	    /* Defines the label for each block */
- 	struct ip_chain *next;	    /* Pointer to next block */
-	struct ip_fwkernel *chain;  /* Pointer to first rule in block */
-	__u32 refcount; 	    /* Number of refernces to block */
-	int policy;		    /* Default rule for chain.  Only *
-				     * used in built in chains */
-	struct ip_reent reent[0];   /* Actually several of these */
-};
-
-/*
- *	Implement IP packet firewall
- */
-
-#ifdef DEBUG_IP_FIREWALL
-#define dprintf(format, args...)  printk(format , ## args)
-#else
-#define dprintf(format, args...)
-#endif
-
-#ifdef DEBUG_IP_FIREWALL_USER
-#define duprintf(format, args...) printk(format , ## args)
-#else
-#define duprintf(format, args...)
-#endif
-
-/* Lock around ip_fw_chains linked list structure */
-rwlock_t ip_fw_lock = RW_LOCK_UNLOCKED;
-
-/* Head of linked list of fw rules */
-static struct ip_chain *ip_fw_chains;
-
-#define IP_FW_INPUT_CHAIN ip_fw_chains
-#define IP_FW_FORWARD_CHAIN (ip_fw_chains->next)
-#define IP_FW_OUTPUT_CHAIN (ip_fw_chains->next->next)
-
-/* Returns 1 if the port is matched by the range, 0 otherwise */
-extern inline int port_match(__u16 min, __u16 max, __u16 port,
-			     int frag, int invert)
-{
-	if (frag) /* Fragments fail ANY port test. */
-		return (min == 0 && max == 0xFFFF);
-	else return (port >= min && port <= max) ^ invert;
-}
-
-/* Returns whether matches rule or not. */
-static int ip_rule_match(struct ip_fwkernel *f,
-			 const char *ifname,
-			 struct sk_buff **pskb,
-			 char tcpsyn,
-			 __u16 src_port, __u16 dst_port,
-			 char isfrag)
-{
-	struct iphdr *ip = (*pskb)->nh.iph;
-
-#define FWINV(bool,invflg) ((bool) ^ !!(f->ipfw.fw_invflg & invflg))
-	/*
-	 *	This is a bit simpler as we don't have to walk
-	 *	an interface chain as you do in BSD - same logic
-	 *	however.
-	 */
-
-	if (FWINV((ip->saddr&f->ipfw.fw_smsk.s_addr) != f->ipfw.fw_src.s_addr,
-		  IP_FW_INV_SRCIP)
-	    || FWINV((ip->daddr&f->ipfw.fw_dmsk.s_addr)!=f->ipfw.fw_dst.s_addr,
-		     IP_FW_INV_DSTIP)) {
-		dprintf("Source or dest mismatch.\n");
-
-		dprintf("SRC: %u. Mask: %u. Target: %u.%s\n", ip->saddr,
-			f->ipfw.fw_smsk.s_addr, f->ipfw.fw_src.s_addr,
-			f->ipfw.fw_invflg & IP_FW_INV_SRCIP ? " (INV)" : "");
-		dprintf("DST: %u. Mask: %u. Target: %u.%s\n", ip->daddr,
-			f->ipfw.fw_dmsk.s_addr, f->ipfw.fw_dst.s_addr,
-			f->ipfw.fw_invflg & IP_FW_INV_DSTIP ? " (INV)" : "");
-		return 0;
-	}
-
-	/*
-	 *	Look for a VIA device match
-	 */
-	if (f->ipfw.fw_flg & IP_FW_F_WILDIF) {
-	    if (FWINV(strncmp(ifname, f->ipfw.fw_vianame,
-			      strlen(f->ipfw.fw_vianame)) != 0,
-		      IP_FW_INV_VIA)) {
-		dprintf("Wildcard interface mismatch.%s\n",
-			f->ipfw.fw_invflg & IP_FW_INV_VIA ? " (INV)" : "");
-		return 0;	/* Mismatch */
-	    }
-	}
-	else if (FWINV(strcmp(ifname, f->ipfw.fw_vianame) != 0,
-		       IP_FW_INV_VIA)) {
-	    dprintf("Interface name does not match.%s\n",
-		    f->ipfw.fw_invflg & IP_FW_INV_VIA
-		    ? " (INV)" : "");
-	    return 0;	/* Mismatch */
-	}
-
-	/*
-	 *	Ok the chain addresses match.
-	 */
-
-	/* If we have a fragment rule but the packet is not a fragment
-	 * the we return zero */
-	if (FWINV((f->ipfw.fw_flg&IP_FW_F_FRAG) && !isfrag, IP_FW_INV_FRAG)) {
-		dprintf("Fragment rule but not fragment.%s\n",
-			f->ipfw.fw_invflg & IP_FW_INV_FRAG ? " (INV)" : "");
-		return 0;
-	}
-
-	/* Fragment NEVER passes a SYN test, even an inverted one. */
-	if (FWINV((f->ipfw.fw_flg&IP_FW_F_TCPSYN) && !tcpsyn, IP_FW_INV_SYN)
-	    || (isfrag && (f->ipfw.fw_flg&IP_FW_F_TCPSYN))) {
-		dprintf("Rule requires SYN and packet has no SYN.%s\n",
-			f->ipfw.fw_invflg & IP_FW_INV_SYN ? " (INV)" : "");
-		return 0;
-	}
-
-	if (f->ipfw.fw_proto) {
-		/*
-		 *	Specific firewall - packet's protocol
-		 *	must match firewall's.
-		 */
-
-		if (FWINV(ip->protocol!=f->ipfw.fw_proto, IP_FW_INV_PROTO)) {
-			dprintf("Packet protocol %hi does not match %hi.%s\n",
-				ip->protocol, f->ipfw.fw_proto,
-				f->ipfw.fw_invflg&IP_FW_INV_PROTO ? " (INV)":"");
-			return 0;
-		}
-
-		/* For non TCP/UDP/ICMP, port range is max anyway. */
-		if (!port_match(f->ipfw.fw_spts[0],
-				f->ipfw.fw_spts[1],
-				src_port, isfrag,
-				!!(f->ipfw.fw_invflg&IP_FW_INV_SRCPT))
-		    || !port_match(f->ipfw.fw_dpts[0],
-				   f->ipfw.fw_dpts[1],
-				   dst_port, isfrag,
-				   !!(f->ipfw.fw_invflg
-				      &IP_FW_INV_DSTPT))) {
-		    dprintf("Port match failed.\n");
-		    return 0;
-		}
-	}
-
-	dprintf("Match succeeded.\n");
-	return 1;
-}
-
-static const char *branchname(struct ip_chain *branch,int simplebranch)
-{
-	if (branch)
-		return branch->label;
-	switch (simplebranch)
-	{
-	case FW_BLOCK: return IP_FW_LABEL_BLOCK;
-	case FW_ACCEPT: return IP_FW_LABEL_ACCEPT;
-	case FW_REJECT: return IP_FW_LABEL_REJECT;
-	case FW_REDIRECT: return IP_FW_LABEL_REDIRECT;
-	case FW_MASQUERADE: return IP_FW_LABEL_MASQUERADE;
-	case FW_SKIP: return "-";
-	case FW_SKIP+1: return IP_FW_LABEL_RETURN;
-	default:
-		return "UNKNOWN";
-	}
-}
-
-/*
- * VERY ugly piece of code which actually
- * makes kernel printf for matching packets...
- */
-static void dump_packet(struct sk_buff **pskb,
-			const char *ifname,
-			struct ip_fwkernel *f,
-			const ip_chainlabel chainlabel,
-			__u16 src_port,
-			__u16 dst_port,
-			unsigned int count,
-			int syn)
-{
-	__u32 *opt = (__u32 *) ((*pskb)->nh.iph + 1);
-	int opti;
-
-	if (f) {
-		printk(KERN_INFO "Packet log: %s ",chainlabel);
-		printk("%s ",branchname(f->branch,f->simplebranch));
-		if (f->simplebranch==FW_REDIRECT)
-			printk("%d ",f->ipfw.fw_redirpt);
-	}
-
-	printk("%s PROTO=%d %u.%u.%u.%u:%hu %u.%u.%u.%u:%hu"
-	       " L=%hu S=0x%2.2hX I=%hu F=0x%4.4hX T=%hu",
-	       ifname, (*pskb)->nh.iph->protocol,
-	       NIPQUAD((*pskb)->nh.iph->saddr),
-	       src_port,
-	       NIPQUAD((*pskb)->nh.iph->daddr),
-	       dst_port,
-	       ntohs((*pskb)->nh.iph->tot_len),
-	       (*pskb)->nh.iph->tos,
-	       ntohs((*pskb)->nh.iph->id),
-	       ntohs((*pskb)->nh.iph->frag_off),
-	       (*pskb)->nh.iph->ttl);
-
-	for (opti = 0; opti < ((*pskb)->nh.iph->ihl - sizeof(struct iphdr) / 4); opti++)
-		printk(" O=0x%8.8X", *opt++);
-	printk(" %s(#%d)\n", syn ? "SYN " : /* "PENANCE" */ "", count);
-}
-
-/* function for checking chain labels for user space. */
-static int check_label(ip_chainlabel label)
-{
-	unsigned int i;
-	/* strlen must be < IP_FW_MAX_LABEL_LENGTH. */
-	for (i = 0; i < IP_FW_MAX_LABEL_LENGTH + 1; i++)
-		if (label[i] == '\0') return 1;
-
-	return 0;
-}
-
-/*	This function returns a pointer to the first chain with a label
- *	that matches the one given. */
-static struct ip_chain *find_label(ip_chainlabel label)
-{
-	struct ip_chain *tmp;
-	FWC_HAVE_LOCK(fwc_rlocks | fwc_wlocks);
-	for (tmp = ip_fw_chains; tmp; tmp = tmp->next)
-		if (strcmp(tmp->label,label) == 0)
-			break;
-	return tmp;
-}
-
-/* This function returns a boolean which when true sets answer to one
-   of the FW_*. */
-static int find_special(ip_chainlabel label, int *answer)
-{
-	if (label[0] == '\0') {
-		*answer = FW_SKIP; /* => pass-through rule */
-		return 1;
-	} else if (strcmp(label,IP_FW_LABEL_ACCEPT) == 0) {
-		*answer = FW_ACCEPT;
-		return 1;
-	} else if (strcmp(label,IP_FW_LABEL_BLOCK) == 0) {
-		*answer = FW_BLOCK;
-		return 1;
-	} else if (strcmp(label,IP_FW_LABEL_REJECT) == 0) {
-		*answer = FW_REJECT;
-		return 1;
-	} else if (strcmp(label,IP_FW_LABEL_REDIRECT) == 0) {
-		*answer = FW_REDIRECT;
-		return 1;
-	} else if (strcmp(label,IP_FW_LABEL_MASQUERADE) == 0) {
-		*answer = FW_MASQUERADE;
-		return 1;
-	} else if (strcmp(label, IP_FW_LABEL_RETURN) == 0) {
-		*answer = FW_SKIP+1;
-		return 1;
-	} else {
-		return 0;
-	}
-}
-
-/* This function cleans up the prevchain and prevrule.  If the verbose
- * flag is set then he names of the chains will be printed as it
- * cleans up.  */
-static void cleanup(struct ip_chain *chain,
-		    const int verbose,
-		    unsigned int slot)
-{
-	struct ip_chain *tmpchain = chain->reent[slot].prevchain;
-	if (verbose)
-		printk(KERN_ERR "Chain backtrace: ");
-	while (tmpchain) {
-		if (verbose)
-			printk("%s<-",chain->label);
-		chain->reent[slot].prevchain = NULL;
-		chain = tmpchain;
-		tmpchain = chain->reent[slot].prevchain;
-	}
-	if (verbose)
-		printk("%s\n",chain->label);
-}
-
-static inline int
-ip_fw_domatch(struct ip_fwkernel *f,
-	      const char *rif,
-	      const ip_chainlabel label,
-	      struct sk_buff **pskb,
-	      unsigned int slot,
-	      __u16 src_port, __u16 dst_port,
-	      unsigned int count,
-	      int tcpsyn,
-	      unsigned char *tos)
-{
-	f->counters[slot].bcnt+=ntohs((*pskb)->nh.iph->tot_len);
-	f->counters[slot].pcnt++;
-	if (f->ipfw.fw_flg & IP_FW_F_PRN) {
-		dump_packet(pskb,rif,f,label,src_port,dst_port,count,tcpsyn);
-	}
-
-	*tos = (*tos & f->ipfw.fw_tosand) ^ f->ipfw.fw_tosxor;
-
-/* This functionality is useless in stock 2.0.x series, but we don't
- * discard the mark thing altogether, to avoid breaking ipchains (and,
- * more importantly, the ipfwadm wrapper) --PR */
-	if (f->ipfw.fw_flg & IP_FW_F_MARKABS) {
-		(*pskb)->nfmark = f->ipfw.fw_mark;
-	} else {
-		(*pskb)->nfmark += f->ipfw.fw_mark;
-	}
-	if (f->ipfw.fw_flg & IP_FW_F_NETLINK) {
-#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
-		size_t len = min_t(unsigned int, f->ipfw.fw_outputsize, ntohs((*pskb)->nh.iph->tot_len))
-			+ sizeof(__u32) + sizeof((*pskb)->nfmark) + IFNAMSIZ;
-		struct sk_buff *outskb=alloc_skb(len, GFP_ATOMIC);
-
-		duprintf("Sending packet out NETLINK (length = %u).\n",
-			 (unsigned int)len);
-		if (outskb) {
-			/* Prepend length, mark & interface */
-			skb_put(outskb, len);
-			*((__u32 *)outskb->data) = (__u32)len;
-			*((__u32 *)(outskb->data+sizeof(__u32))) =
-				(*pskb)->nfmark;
-			strcpy(outskb->data+sizeof(__u32)*2, rif);
-			skb_copy_bits(*pskb,
-				((char *)(*pskb)->nh.iph - (char *)(*pskb)->data),
-				outskb->data+sizeof(__u32)*2+IFNAMSIZ,
-				len-(sizeof(__u32)*2+IFNAMSIZ));
-			netlink_broadcast(ipfwsk, outskb, 0, ~0, GFP_ATOMIC);
-		}
-		else {
-#endif
-			if (net_ratelimit())
-				printk(KERN_WARNING "ip_fw: packet drop due to "
-				       "netlink failure\n");
-			return 0;
-#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
-		}
-#endif
-	}
-	return 1;
-}
-
-/*
- *	Returns one of the generic firewall policies, like FW_ACCEPT.
- *
- *	The testing is either false for normal firewall mode or true for
- *	user checking mode (counters are not updated, TOS & mark not done).
- */
-static int
-ip_fw_check(const char *rif,
-	    __u16 *redirport,
-	    struct ip_chain *chain,
-	    struct sk_buff **pskb,
-	    unsigned int slot,
-	    int testing)
-{
-	__u32			src, dst;
-	__u16			src_port = 0xFFFF, dst_port = 0xFFFF;
-	char			tcpsyn=0;
-	__u16			offset;
-	unsigned char		tos;
-	struct ip_fwkernel	*f;
-	int			ret = FW_SKIP+2;
-	unsigned int		count;
-
-	/* We handle fragments by dealing with the first fragment as
-	 * if it was a normal packet.  All other fragments are treated
-	 * normally, except that they will NEVER match rules that ask
-	 * things we don't know, ie. tcp syn flag or ports).  If the
-	 * rule is also a fragment-specific rule, non-fragments won't
-	 * match it. */
-
-	offset = ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET;
-
-	/*
-	 *	Don't allow a fragment of TCP 8 bytes in. Nobody
-	 *	normal causes this. Its a cracker trying to break
-	 *	in by doing a flag overwrite to pass the direction
-	 *	checks.
-	 */
-	if (offset == 1 && (*pskb)->nh.iph->protocol == IPPROTO_TCP) {
-		if (!testing && net_ratelimit()) {
-			printk("Suspect TCP fragment.\n");
-			dump_packet(pskb,rif,NULL,NULL,0,0,0,0);
-		}
-		return FW_BLOCK;
-	}
-
-	/* If we can't investigate ports, treat as fragment.  It's
-	 * either a trucated whole packet, or a truncated first
-	 * fragment, or a TCP first fragment of length 8-15, in which
-	 * case the above rule stops reassembly.
-	 */
-	if (offset == 0) {
-		unsigned int size_req;
-		switch ((*pskb)->nh.iph->protocol) {
-		case IPPROTO_TCP:
-			/* Don't care about things past flags word */
-			size_req = 16;
-			break;
-
-		case IPPROTO_UDP:
-		case IPPROTO_ICMP:
-			size_req = 8;
-			break;
-
-		default:
-			size_req = 0;
-		}
-
-		/* If it is a truncated first fragment then it can be
-		 * used to rewrite port information, and thus should
-		 * be blocked.
-		 */
-		if (ntohs((*pskb)->nh.iph->tot_len) <
-		    ((*pskb)->nh.iph->ihl<<2)+size_req) {
-			if (!testing && net_ratelimit()) {
-				printk("Suspect short first fragment.\n");
-				dump_packet(pskb,rif,NULL,NULL,0,0,0,0);
-			}
-			return FW_BLOCK;
-		}
-	}
-
-	src = (*pskb)->nh.iph->saddr;
-	dst = (*pskb)->nh.iph->daddr;
-	tos = (*pskb)->nh.iph->tos;
-
-	/*
-	 *	If we got interface from which packet came
-	 *	we can use the address directly. Linux 2.1 now uses address
-	 *	chains per device too, but unlike BSD we first check if the
-	 *	incoming packet matches a device address and the routing
-	 *	table before calling the firewall.
-	 */
-
-	dprintf("Packet ");
-	switch ((*pskb)->nh.iph->protocol) {
-		case IPPROTO_TCP:
-			dprintf("TCP ");
-			if (!offset) {
-				struct tcphdr _tcph, *th;
-
-				th = skb_header_pointer(*pskb,
-							(*pskb)->nh.iph->ihl*4,
-							sizeof(_tcph), &_tcph);
-				if (th == NULL)
-					return FW_BLOCK;
-
-				src_port = ntohs(th->source);
-				dst_port = ntohs(th->dest);
-
-				/* Connection initilisation can only
-				 * be made when the syn bit is set and
-				 * neither of the ack or reset is
-				 * set. */
-				if (th->syn && !(th->ack || th->rst))
-					tcpsyn = 1;
-			}
-			break;
-		case IPPROTO_UDP:
-			dprintf("UDP ");
-			if (!offset) {
-				struct udphdr _udph, *uh;
-
-				uh = skb_header_pointer(*pskb,
-							(*pskb)->nh.iph->ihl*4,
-							sizeof(_udph), &_udph);
-				if (uh == NULL)
-					return FW_BLOCK;
-
-				src_port = ntohs(uh->source);
-				dst_port = ntohs(uh->dest);
-			}
-			break;
-		case IPPROTO_ICMP:
-			if (!offset) {
-				struct icmphdr _icmph, *ic;
-
-				ic = skb_header_pointer(*pskb,
-							(*pskb)->nh.iph->ihl*4,
-							sizeof(_icmph),
-							&_icmph);
-				if (ic == NULL)
-					return FW_BLOCK;
-
-				src_port = (__u16) ic->type;
-				dst_port = (__u16) ic->code;
-			}
-			dprintf("ICMP ");
-			break;
-		default:
-			dprintf("p=%d ", (*pskb)->nh.iph->protocol);
-			break;
-	}
-#ifdef DEBUG_IP_FIREWALL
-	print_ip((*pskb)->nh.iph->saddr);
-
-	if (offset)
-		dprintf(":fragment (%i) ", ((int)offset)<<2);
-	else if ((*pskb)->nh.iph->protocol == IPPROTO_TCP ||
-		 (*pskb)->nh.iph->protocol == IPPROTO_UDP ||
-		 (*pskb)->nh.iph->protocol == IPPROTO_ICMP)
-		dprintf(":%hu:%hu", src_port, dst_port);
-	dprintf("\n");
-#endif
-
-	if (!testing) FWC_READ_LOCK(&ip_fw_lock);
-	else FWC_HAVE_LOCK(fwc_rlocks);
-
-	f = chain->chain;
-	do {
-		count = 0;
-		for (; f; f = f->next) {
-			count++;
-			if (ip_rule_match(f, rif, pskb,
-					  tcpsyn, src_port, dst_port,
-					  offset)) {
-				if (!testing
-				    && !ip_fw_domatch(f, rif, chain->label,
-						      pskb, slot,
-						      src_port, dst_port,
-						      count, tcpsyn, &tos)) {
-					ret = FW_BLOCK;
-					cleanup(chain, 0, slot);
-					goto out;
-				}
-				break;
-			}
-		}
-		if (f) {
-			if (f->branch) {
-				/* Do sanity check to see if we have
-                                 * already set prevchain and if so we
-                                 * must be in a loop */
-				if (f->branch->reent[slot].prevchain) {
-					if (!testing) {
-						printk(KERN_ERR
-						       "IP firewall: "
-						       "Loop detected "
-						       "at `%s'.\n",
-						       f->branch->label);
-						cleanup(chain, 1, slot);
-						ret = FW_BLOCK;
-					} else {
-						cleanup(chain, 0, slot);
-						ret = FW_SKIP+1;
-					}
-				}
-				else {
-					f->branch->reent[slot].prevchain
-						= chain;
-					f->branch->reent[slot].prevrule
-						= f->next;
-					chain = f->branch;
-					f = chain->chain;
-				}
-			}
-			else if (f->simplebranch == FW_SKIP)
-				f = f->next;
-			else if (f->simplebranch == FW_SKIP+1) {
-				/* Just like falling off the chain */
-				goto fall_off_chain;
-			} else {
-				cleanup(chain, 0, slot);
-				ret = f->simplebranch;
-			}
-		} /* f == NULL */
-		else {
-		fall_off_chain:
-			if (chain->reent[slot].prevchain) {
-				struct ip_chain *tmp = chain;
-				f = chain->reent[slot].prevrule;
-				chain = chain->reent[slot].prevchain;
-				tmp->reent[slot].prevchain = NULL;
-			}
-			else {
-				ret = chain->policy;
-				if (!testing) {
-					chain->reent[slot].counters.pcnt++;
-					chain->reent[slot].counters.bcnt
-						+= ntohs((*pskb)->nh.iph->tot_len);
-				}
-			}
-		}
-	} while (ret == FW_SKIP+2);
-
- out:
-	if (!testing) FWC_READ_UNLOCK(&ip_fw_lock);
-
-	/* Recalculate checksum if not going to reject, and TOS changed. */
-	if ((*pskb)->nh.iph->tos != tos
-	    && ret != FW_REJECT && ret != FW_BLOCK
-	    && !testing) {
-		if (!skb_ip_make_writable(pskb, offsetof(struct iphdr, tos)+1))
-			ret = FW_BLOCK;
-		else {
-			(*pskb)->nh.iph->tos = tos;
-			ip_send_check((*pskb)->nh.iph);
-		}
-	}
-
-	if (ret == FW_REDIRECT && redirport) {
-		if ((*redirport = htons(f->ipfw.fw_redirpt)) == 0) {
-			/* Wildcard redirection.
-			 * Note that redirport will become
-			 * 0xFFFF for non-TCP/UDP packets.
-			 */
-			*redirport = htons(dst_port);
-		}
-	}
-
-#ifdef DEBUG_ALLOW_ALL
-	return (testing ? ret : FW_ACCEPT);
-#else
-	return ret;
-#endif
-}
-
-/* Must have write lock & interrupts off for any of these */
-
-/* This function sets all the byte counters in a chain to zero.  The
- * input is a pointer to the chain required for zeroing */
-static int zero_fw_chain(struct ip_chain *chainptr)
-{
-	struct ip_fwkernel *i;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-	for (i = chainptr->chain; i; i = i->next)
-		memset(i->counters, 0, sizeof(struct ip_counters)*NUM_SLOTS);
-	return 0;
-}
-
-static int clear_fw_chain(struct ip_chain *chainptr)
-{
-	struct ip_fwkernel *i= chainptr->chain;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-	chainptr->chain=NULL;
-
-	while (i) {
-		struct ip_fwkernel *tmp = i->next;
-		if (i->branch)
-			i->branch->refcount--;
-		kfree(i);
-		i = tmp;
-		/* We will block in cleanup's unregister sockopt if unloaded,
-		   so this is safe. */
-		module_put(THIS_MODULE);
-	}
-	return 0;
-}
-
-static int replace_in_chain(struct ip_chain *chainptr,
-			    struct ip_fwkernel *frwl,
-			    __u32 position)
-{
-	struct ip_fwkernel *f = chainptr->chain;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-
-	while (--position && f != NULL) f = f->next;
-	if (f == NULL)
-		return EINVAL;
-
-	if (f->branch) f->branch->refcount--;
-	if (frwl->branch) frwl->branch->refcount++;
-
-	frwl->next = f->next;
-	memcpy(f,frwl,sizeof(struct ip_fwkernel));
-	kfree(frwl);
-	return 0;
-}
-
-static int append_to_chain(struct ip_chain *chainptr, struct ip_fwkernel *rule)
-{
-	struct ip_fwkernel *i;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-
-	/* Are we unloading now?  We will block on nf_unregister_sockopt */
-	if (!try_module_get(THIS_MODULE))
-		return ENOPROTOOPT;
-
-	/* Special case if no rules already present */
-	if (chainptr->chain == NULL) {
-
-		/* If pointer writes are atomic then turning off
-		 * interrupts is not necessary. */
-		chainptr->chain = rule;
-		if (rule->branch) rule->branch->refcount++;
-		goto append_successful;
-	}
-
-	/* Find the rule before the end of the chain */
-	for (i = chainptr->chain; i->next; i = i->next);
-	i->next = rule;
-	if (rule->branch) rule->branch->refcount++;
-
-append_successful:
-	return 0;
-}
-
-/* This function inserts a rule at the position of position in the
- * chain refenced by chainptr.  If position is 1 then this rule will
- * become the new rule one. */
-static int insert_in_chain(struct ip_chain *chainptr,
-			   struct ip_fwkernel *frwl,
-			   __u32 position)
-{
-	struct ip_fwkernel *f = chainptr->chain;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-
-	/* Are we unloading now?  We will block on nf_unregister_sockopt */
-	if (!try_module_get(THIS_MODULE))
-		return ENOPROTOOPT;
-
-	/* special case if the position is number 1 */
-	if (position == 1) {
-		frwl->next = chainptr->chain;
-		if (frwl->branch) frwl->branch->refcount++;
-		chainptr->chain = frwl;
-		goto insert_successful;
-	}
-	position--;
-	while (--position && f != NULL) f = f->next;
-	if (f == NULL)
-		return EINVAL;
-	if (frwl->branch) frwl->branch->refcount++;
-	frwl->next = f->next;
-
-	f->next = frwl;
-
-insert_successful:
-	return 0;
-}
-
-/* This function deletes the a rule from a given rulenum and chain.
- * With rulenum = 1 is the first rule is deleted. */
-
-static int del_num_from_chain(struct ip_chain *chainptr, __u32 rulenum)
-{
-	struct ip_fwkernel *i=chainptr->chain,*tmp;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-
-	if (!chainptr->chain)
-		return ENOENT;
-
-	/* Need a special case for the first rule */
-	if (rulenum == 1) {
-		/* store temp to allow for freeing up of memory */
-		tmp = chainptr->chain;
-	        if (chainptr->chain->branch) chainptr->chain->branch->refcount--;
-		chainptr->chain = chainptr->chain->next;
-		kfree(tmp); /* free memory that is now unused */
-	} else {
-		rulenum--;
-		while (--rulenum && i->next ) i = i->next;
-		if (!i->next)
-			return ENOENT;
-		tmp = i->next;
-		if (i->next->branch)
-			i->next->branch->refcount--;
-		i->next = i->next->next;
-		kfree(tmp);
-	}
-
-	/* We will block in cleanup's unregister sockopt if unloaded,
-	   so this is safe. */
-	module_put(THIS_MODULE);
-	return 0;
-}
-
-
-/* This function deletes the a rule from a given rule and chain.
- * The rule that is deleted is the first occursance of that rule. */
-static int del_rule_from_chain(struct ip_chain *chainptr,
-			       struct ip_fwkernel *frwl)
-{
-	struct ip_fwkernel *ltmp,*ftmp = chainptr->chain ;
-	int was_found;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-
-	/* Sure, we should compare marks, but since the `ipfwadm'
-	 * script uses it for an unholy hack... well, life is easier
-	 * this way.  We also mask it out of the flags word. --PR */
-	for (ltmp=NULL, was_found=0;
-	     !was_found && ftmp != NULL;
-	     ltmp = ftmp,ftmp = ftmp->next) {
-		if (ftmp->ipfw.fw_src.s_addr!=frwl->ipfw.fw_src.s_addr
-		    || 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]
-		    || ftmp->ipfw.fw_dpts[0]!=frwl->ipfw.fw_dpts[0]
-		    || ftmp->ipfw.fw_dpts[1]!=frwl->ipfw.fw_dpts[1]
-		    || ftmp->ipfw.fw_outputsize!=frwl->ipfw.fw_outputsize) {
-			duprintf("del_rule_from_chain: mismatch:"
-				 "src:%u/%u dst:%u/%u smsk:%u/%u dmsk:%u/%u "
-				 "flg:%hX/%hX invflg:%hX/%hX proto:%u/%u "
-				 "mark:%u/%u "
-				 "ports:%hu-%hu/%hu-%hu %hu-%hu/%hu-%hu "
-				 "outputsize:%hu-%hu\n",
-				 ftmp->ipfw.fw_src.s_addr,
-				 frwl->ipfw.fw_src.s_addr,
-				 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,
-				 ftmp->ipfw.fw_flg,
-				 frwl->ipfw.fw_flg,
-				 ftmp->ipfw.fw_invflg,
-				 frwl->ipfw.fw_invflg,
-				 ftmp->ipfw.fw_proto,
-				 frwl->ipfw.fw_proto,
-				 ftmp->ipfw.fw_mark,
-				 frwl->ipfw.fw_mark,
-				 ftmp->ipfw.fw_spts[0],
-				 frwl->ipfw.fw_spts[0],
-				 ftmp->ipfw.fw_spts[1],
-				 frwl->ipfw.fw_spts[1],
-				 ftmp->ipfw.fw_dpts[0],
-				 frwl->ipfw.fw_dpts[0],
-				 ftmp->ipfw.fw_dpts[1],
-				 frwl->ipfw.fw_dpts[1],
-				 ftmp->ipfw.fw_outputsize,
-				 frwl->ipfw.fw_outputsize);
-			continue;
-		}
-
-		if (strncmp(ftmp->ipfw.fw_vianame,
-			    frwl->ipfw.fw_vianame,
-			    IFNAMSIZ)) {
-			duprintf("del_rule_from_chain: if mismatch: %s/%s\n",
-				 ftmp->ipfw.fw_vianame,
-				 frwl->ipfw.fw_vianame);
-		        continue;
-		}
-		if (ftmp->branch != frwl->branch) {
-			duprintf("del_rule_from_chain: branch mismatch: "
-				 "%s/%s\n",
-				 ftmp->branch?ftmp->branch->label:"(null)",
-				 frwl->branch?frwl->branch->label:"(null)");
-			continue;
-		}
-		if (ftmp->branch == NULL
-		    && ftmp->simplebranch != frwl->simplebranch) {
-			duprintf("del_rule_from_chain: simplebranch mismatch: "
-				 "%i/%i\n",
-				 ftmp->simplebranch, frwl->simplebranch);
-			continue;
-		}
-		was_found = 1;
-		if (ftmp->branch)
-			ftmp->branch->refcount--;
-		if (ltmp)
-			ltmp->next = ftmp->next;
-		else
-			chainptr->chain = ftmp->next;
-		kfree(ftmp);
-		/* We will block in cleanup's unregister sockopt if unloaded,
-		   so this is safe. */
-		module_put(THIS_MODULE);
-		break;
-	}
-
-	if (was_found)
-		return 0;
-	else {
-		duprintf("del_rule_from_chain: no matching rule found\n");
-		return EINVAL;
-	}
-}
-
-/* This function takes the label of a chain and deletes the first
- * chain with that name.  No special cases required for the built in
- * chains as they have their refcount initilised to 1 so that they are
- * never deleted.  */
-static int del_chain(ip_chainlabel label)
-{
-	struct ip_chain *tmp,*tmp2;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-	/* Corner case: return EBUSY not ENOENT for first elem ("input") */
-	if (strcmp(label, ip_fw_chains->label) == 0)
-		return EBUSY;
-
-	for (tmp = ip_fw_chains; tmp->next; tmp = tmp->next)
-		if(strcmp(tmp->next->label,label) == 0)
-			break;
-
-	tmp2 = tmp->next;
-	if (!tmp2)
-		return ENOENT;
-
-	if (tmp2->refcount)
-		return EBUSY;
-
-	if (tmp2->chain)
-		return ENOTEMPTY;
-
-	tmp->next = tmp2->next;
-	kfree(tmp2);
-
-	/* We will block in cleanup's unregister sockopt if unloaded,
-	   so this is safe. */
-	module_put(THIS_MODULE);
-	return 0;
-}
-
-/* This is a function to initilise a chain.  Built in rules start with
- * refcount = 1 so that they cannot be deleted.  User defined rules
- * start with refcount = 0 so they can be deleted. */
-static struct ip_chain *ip_init_chain(ip_chainlabel name,
-				      __u32 ref,
-				      int policy)
-{
-	unsigned int i;
-	struct ip_chain *label
-		= kmalloc(SIZEOF_STRUCT_IP_CHAIN, GFP_KERNEL);
-	if (label == NULL)
-		panic("Can't kmalloc for firewall chains.\n");
-	strcpy(label->label,name);
-	label->next = NULL;
-	label->chain = NULL;
-	label->refcount = ref;
-	label->policy = policy;
-	for (i = 0; i < NUM_SLOTS; i++) {
-		label->reent[i].counters.pcnt = label->reent[i].counters.bcnt
-			= 0;
-		label->reent[i].prevchain = NULL;
-		label->reent[i].prevrule = NULL;
-	}
-
-	return label;
-}
-
-/* This is a function for reating a new chain.  The chains is not
- * created if a chain of the same name already exists */
-static int create_chain(ip_chainlabel label)
-{
-	struct ip_chain *tmp;
-
-	if (!check_label(label))
-		return EINVAL;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-	for (tmp = ip_fw_chains; tmp->next; tmp = tmp->next)
-		if (strcmp(tmp->label,label) == 0)
-			return EEXIST;
-
-	if (strcmp(tmp->label,label) == 0)
-		return EEXIST;
-
-	/* Are we unloading now?  We will block on nf_unregister_sockopt */
-	if (!try_module_get(THIS_MODULE))
-		return ENOPROTOOPT;
-
-	tmp->next = ip_init_chain(label, 0, FW_SKIP); /* refcount is
-					      * zero since this is a
-					      * user defined chain *
-					      * and therefore can be
-					      * deleted */
-	return 0;
-}
-
-/* This function simply changes the policy on one of the built in
- * chains.  checking must be done before this is call to ensure that
- * chainptr is pointing to one of the three possible chains */
-static int change_policy(struct ip_chain *chainptr, int policy)
-{
-	FWC_HAVE_LOCK(fwc_wlocks);
-	chainptr->policy = policy;
-	return 0;
-}
-
-/* This function takes an ip_fwuser and converts it to a ip_fwkernel.  It also
- * performs some checks in the structure. */
-static struct ip_fwkernel *convert_ipfw(struct ip_fwuser *fwuser, int *errno)
-{
-	struct ip_fwkernel *fwkern;
-
-	if ( (fwuser->ipfw.fw_flg & ~IP_FW_F_MASK) != 0 ) {
-		duprintf("convert_ipfw: undefined flag bits set (flags=%x)\n",
-			 fwuser->ipfw.fw_flg);
-		*errno = EINVAL;
-		return NULL;
-	}
-
-#ifdef DEBUG_IP_FIREWALL_USER
-	/* These are sanity checks that don't really matter.
-	 * We can get rid of these once testing is complete.
-	 */
-	if ((fwuser->ipfw.fw_flg & IP_FW_F_TCPSYN)
-	    && ((fwuser->ipfw.fw_invflg & IP_FW_INV_PROTO)
-		|| fwuser->ipfw.fw_proto != IPPROTO_TCP)) {
-		duprintf("convert_ipfw: TCP SYN flag set but proto != TCP!\n");
-		*errno = EINVAL;
-		return NULL;
-	}
-
-	if (strcmp(fwuser->label, IP_FW_LABEL_REDIRECT) != 0
-	    && fwuser->ipfw.fw_redirpt != 0) {
-		duprintf("convert_ipfw: Target not REDIR but redirpt != 0!\n");
-		*errno = EINVAL;
-		return NULL;
-	}
-
-	if ((!(fwuser->ipfw.fw_flg & IP_FW_F_FRAG)
-	     && (fwuser->ipfw.fw_invflg & IP_FW_INV_FRAG))
-	    || (!(fwuser->ipfw.fw_flg & IP_FW_F_TCPSYN)
-		&& (fwuser->ipfw.fw_invflg & IP_FW_INV_SYN))) {
-		duprintf("convert_ipfw: Can't have INV flag if flag unset!\n");
-		*errno = EINVAL;
-		return NULL;
-	}
-
-	if (((fwuser->ipfw.fw_invflg & IP_FW_INV_SRCPT)
-	     && fwuser->ipfw.fw_spts[0] == 0
-	     && fwuser->ipfw.fw_spts[1] == 0xFFFF)
-	    || ((fwuser->ipfw.fw_invflg & IP_FW_INV_DSTPT)
-		&& fwuser->ipfw.fw_dpts[0] == 0
-		&& fwuser->ipfw.fw_dpts[1] == 0xFFFF)
-	    || ((fwuser->ipfw.fw_invflg & IP_FW_INV_VIA)
-		&& (fwuser->ipfw.fw_vianame)[0] == '\0')
-	    || ((fwuser->ipfw.fw_invflg & IP_FW_INV_SRCIP)
-		&& fwuser->ipfw.fw_smsk.s_addr == 0)
-	    || ((fwuser->ipfw.fw_invflg & IP_FW_INV_DSTIP)
-		&& fwuser->ipfw.fw_dmsk.s_addr == 0)) {
-		duprintf("convert_ipfw: INV flag makes rule unmatchable!\n");
-		*errno = EINVAL;
-		return NULL;
-	}
-
-	if ((fwuser->ipfw.fw_flg & IP_FW_F_FRAG)
-	    && !(fwuser->ipfw.fw_invflg & IP_FW_INV_FRAG)
-	    && (fwuser->ipfw.fw_spts[0] != 0
-		|| fwuser->ipfw.fw_spts[1] != 0xFFFF
-		|| fwuser->ipfw.fw_dpts[0] != 0
-		|| fwuser->ipfw.fw_dpts[1] != 0xFFFF
-		|| (fwuser->ipfw.fw_flg & IP_FW_F_TCPSYN))) {
-		duprintf("convert_ipfw: Can't test ports or SYN with frag!\n");
-		*errno = EINVAL;
-		return NULL;
-	}
-#endif
-
-	if ((fwuser->ipfw.fw_spts[0] != 0
-	     || fwuser->ipfw.fw_spts[1] != 0xFFFF
-	     || fwuser->ipfw.fw_dpts[0] != 0
-	     || fwuser->ipfw.fw_dpts[1] != 0xFFFF)
-	    && ((fwuser->ipfw.fw_invflg & IP_FW_INV_PROTO)
-		|| (fwuser->ipfw.fw_proto != IPPROTO_TCP
-		    && fwuser->ipfw.fw_proto != IPPROTO_UDP
-		    && fwuser->ipfw.fw_proto != IPPROTO_ICMP))) {
-		duprintf("convert_ipfw: Can only test ports for TCP/UDP/ICMP!\n");
-		*errno = EINVAL;
-		return NULL;
-	}
-
-	fwkern = kmalloc(SIZEOF_STRUCT_IP_FW_KERNEL, GFP_ATOMIC);
-	if (!fwkern) {
-		duprintf("convert_ipfw: kmalloc failed!\n");
-		*errno = ENOMEM;
-		return NULL;
-	}
-	memcpy(&fwkern->ipfw,&fwuser->ipfw,sizeof(struct ip_fw));
-
-	if (!find_special(fwuser->label, &fwkern->simplebranch)) {
-		fwkern->branch = find_label(fwuser->label);
-		if (!fwkern->branch) {
-			duprintf("convert_ipfw: chain doesn't exist `%s'.\n",
-				 fwuser->label);
-			kfree(fwkern);
-			*errno = ENOENT;
-			return NULL;
-		} else if (fwkern->branch == IP_FW_INPUT_CHAIN
-			   || fwkern->branch == IP_FW_FORWARD_CHAIN
-			   || fwkern->branch == IP_FW_OUTPUT_CHAIN) {
-			duprintf("convert_ipfw: Can't branch to builtin chain `%s'.\n",
-				 fwuser->label);
-			kfree(fwkern);
-			*errno = ENOENT;
-			return NULL;
-		}
-	} else
-		fwkern->branch = NULL;
-	memset(fwkern->counters, 0, sizeof(struct ip_counters)*NUM_SLOTS);
-
-	/* Handle empty vianame by making it a wildcard */
-	if ((fwkern->ipfw.fw_vianame)[0] == '\0')
-	    fwkern->ipfw.fw_flg |= IP_FW_F_WILDIF;
-
-	fwkern->next = NULL;
-	return fwkern;
-}
-
-int ip_fw_ctl(int cmd, void *m, int len)
-{
-	int ret;
-	struct ip_chain *chain;
-	unsigned long flags;
-
-	FWC_WRITE_LOCK_IRQ(&ip_fw_lock, flags);
-
-	switch (cmd) {
-	case IP_FW_FLUSH:
-		if (len != sizeof(ip_chainlabel) || !check_label(m))
-			ret = EINVAL;
-		else if ((chain = find_label(m)) == NULL)
-			ret = ENOENT;
-		else ret = clear_fw_chain(chain);
-		break;
-
-	case IP_FW_ZERO:
-		if (len != sizeof(ip_chainlabel) || !check_label(m))
-			ret = EINVAL;
-		else if ((chain = find_label(m)) == NULL)
-			ret = ENOENT;
-		else ret = zero_fw_chain(chain);
-		break;
-
-	case IP_FW_CHECK: {
-		struct ip_fwtest *new = m;
-		struct iphdr *ip;
-
-		/* Don't need write lock. */
-		FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);
-
-		if (len != sizeof(struct ip_fwtest) || !check_label(m))
-			return EINVAL;
-
-		/* Need readlock to do find_label */
-		FWC_READ_LOCK(&ip_fw_lock);
-
-		if ((chain = find_label(new->fwt_label)) == NULL)
-			ret = ENOENT;
-		else {
-			struct sk_buff *tmp_skb;
-			int hdrlen;
-
-			hdrlen = sizeof(struct ip_fwpkt) -
-				sizeof(struct in_addr) -
-				IFNAMSIZ;
-
-			ip = &(new->fwt_packet.fwp_iph);
-
-			/* Fix this one up by hand, who knows how many
-			 * tools will break if we start to barf on this.
-			 */
-			if (ntohs(ip->tot_len) > hdrlen)
-				ip->tot_len = htons(hdrlen);
-
-			if (ip->ihl != sizeof(struct iphdr) / sizeof(u32)) {
-				duprintf("ip_fw_ctl: ip->ihl=%d, want %d\n",
-					 ip->ihl,
-					 sizeof(struct iphdr) / sizeof(u32));
-				ret = EINVAL;
-			} else if ((tmp_skb = alloc_skb(hdrlen,
-							GFP_ATOMIC)) == NULL) {
-				duprintf("ip_fw_ctl: tmp_skb alloc failure\n");
-				ret = EFAULT;
-			} else {
-				skb_reserve(tmp_skb, hdrlen);
-				skb_push(tmp_skb, hdrlen);
-				memcpy(tmp_skb->data, ip, hdrlen);
-				tmp_skb->nh.raw =
-					(unsigned char *) tmp_skb->data;
-				ret = ip_fw_check(new->fwt_packet.fwp_vianame,
-						  NULL, chain,
-						  &tmp_skb, SLOT_NUMBER(), 1);
-				kfree_skb(tmp_skb);
-				switch (ret) {
-				case FW_ACCEPT:
-					ret = 0; break;
-				case FW_REDIRECT:
-					ret = ECONNABORTED; break;
-				case FW_MASQUERADE:
-					ret = ECONNRESET; break;
-				case FW_REJECT:
-					ret = ECONNREFUSED; break;
-					/* Hack to help diag; these only get
-					   returned when testing. */
-				case FW_SKIP+1:
-					ret = ELOOP; break;
-				case FW_SKIP:
-					ret = ENFILE; break;
-				default: /* FW_BLOCK */
-					ret = ETIMEDOUT; break;
-				}
-			}
-		}
-		FWC_READ_UNLOCK(&ip_fw_lock);
-		return ret;
-	}
-
-	case IP_FW_MASQ_TIMEOUTS: {
-		ret = ip_fw_masq_timeouts(m, len);
-	}
-	break;
-
-	case IP_FW_REPLACE: {
-		struct ip_fwkernel *ip_fwkern;
-		struct ip_fwnew *new = m;
-
-		if (len != sizeof(struct ip_fwnew)
-		    || !check_label(new->fwn_label))
-			ret = EINVAL;
-		else if ((chain = find_label(new->fwn_label)) == NULL)
-			ret = ENOENT;
-		else if ((ip_fwkern = convert_ipfw(&new->fwn_rule, &ret))
-			 != NULL)
-			ret = replace_in_chain(chain, ip_fwkern,
-					       new->fwn_rulenum);
-	}
-	break;
-
-	case IP_FW_APPEND: {
-		struct ip_fwchange *new = m;
-		struct ip_fwkernel *ip_fwkern;
-
-		if (len != sizeof(struct ip_fwchange)
-		    || !check_label(new->fwc_label))
-			ret = EINVAL;
-		else if ((chain = find_label(new->fwc_label)) == NULL)
-			ret = ENOENT;
-		else if ((ip_fwkern = convert_ipfw(&new->fwc_rule, &ret))
-			 != NULL)
-			ret = append_to_chain(chain, ip_fwkern);
-	}
-	break;
-
-	case IP_FW_INSERT: {
-		struct ip_fwkernel *ip_fwkern;
-		struct ip_fwnew *new = m;
-
-		if (len != sizeof(struct ip_fwnew)
-		    || !check_label(new->fwn_label))
-			ret = EINVAL;
-		else if ((chain = find_label(new->fwn_label)) == NULL)
-			ret = ENOENT;
-		else if ((ip_fwkern = convert_ipfw(&new->fwn_rule, &ret))
-			 != NULL)
-			ret = insert_in_chain(chain, ip_fwkern,
-					      new->fwn_rulenum);
-	}
-	break;
-
-	case IP_FW_DELETE: {
-		struct ip_fwchange *new = m;
-		struct ip_fwkernel *ip_fwkern;
-
-		if (len != sizeof(struct ip_fwchange)
-		    || !check_label(new->fwc_label))
-			ret = EINVAL;
-		else if ((chain = find_label(new->fwc_label)) == NULL)
-			ret = ENOENT;
-		else if ((ip_fwkern = convert_ipfw(&new->fwc_rule, &ret))
-			 != NULL) {
-			ret = del_rule_from_chain(chain, ip_fwkern);
-			kfree(ip_fwkern);
-		}
-	}
-	break;
-
-	case IP_FW_DELETE_NUM: {
-		struct ip_fwdelnum *new = m;
-
-		if (len != sizeof(struct ip_fwdelnum)
-		    || !check_label(new->fwd_label))
-			ret = EINVAL;
-		else if ((chain = find_label(new->fwd_label)) == NULL)
-			ret = ENOENT;
-		else ret = del_num_from_chain(chain, new->fwd_rulenum);
-	}
-	break;
-
-	case IP_FW_CREATECHAIN: {
-		if (len != sizeof(ip_chainlabel)) {
-			duprintf("create_chain: bad size %i\n", len);
-			ret = EINVAL;
-		}
-		else ret = create_chain(m);
-	}
-	break;
-
-	case IP_FW_DELETECHAIN: {
-		if (len != sizeof(ip_chainlabel)) {
-			duprintf("delete_chain: bad size %i\n", len);
-			ret = EINVAL;
-		}
-		else ret = del_chain(m);
-	}
-	break;
-
-	case IP_FW_POLICY: {
-		struct ip_fwpolicy *new = m;
-
-		if (len != sizeof(struct ip_fwpolicy)
-		    || !check_label(new->fwp_label))
-			ret = EINVAL;
-		else if ((chain = find_label(new->fwp_label)) == NULL)
-			ret = ENOENT;
-		else if (chain != IP_FW_INPUT_CHAIN
-			 && chain != IP_FW_FORWARD_CHAIN
-			 && chain != IP_FW_OUTPUT_CHAIN) {
-			duprintf("change_policy: can't change policy on user"
-				 " defined chain.\n");
-			ret = EINVAL;
-		}
-		else {
-		        int pol = FW_SKIP;
-			find_special(new->fwp_policy, &pol);
-
-			switch(pol) {
-			case FW_MASQUERADE:
-				if (chain != IP_FW_FORWARD_CHAIN) {
-					ret = EINVAL;
-					break;
-				}
-				/* Fall thru... */
-			case FW_BLOCK:
-			case FW_ACCEPT:
-			case FW_REJECT:
-				ret = change_policy(chain, pol);
-				break;
-			default:
-			        duprintf("change_policy: bad policy `%s'\n",
-					 new->fwp_policy);
-				ret = EINVAL;
-			}
-		}
-		break;
-	}
-	default:
-		duprintf("ip_fw_ctl:  unknown request %d\n",cmd);
-		ret = ENOPROTOOPT;
-	}
-
-	FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);
-	return ret;
-}
-
-/* Returns bytes used - doesn't NUL terminate */
-static int dump_rule(char *buffer,
-		     const char *chainlabel,
-		     const struct ip_fwkernel *rule)
-{
-	int len;
-	unsigned int i;
-	__u64 packets = 0, bytes = 0;
-
-	FWC_HAVE_LOCK(fwc_wlocks);
-	for (i = 0; i < NUM_SLOTS; i++) {
-		packets += rule->counters[i].pcnt;
-		bytes += rule->counters[i].bcnt;
-	}
-
-	len=sprintf(buffer,
-		    "%9s "			/* Chain name */
-		    "%08X/%08X->%08X/%08X "	/* Source & Destination IPs */
-		    "%.16s "			/* Interface */
-		    "%X %X "			/* fw_flg and fw_invflg fields */
-		    "%u "			/* Protocol */
-		    "%-9u %-9u %-9u %-9u "	/* Packet & byte counters */
-		    "%u-%u %u-%u "		/* Source & Dest port ranges */
-		    "A%02X X%02X "		/* TOS and and xor masks */
-		    "%08X "			/* Redirection port */
-		    "%u "			/* fw_mark field */
-		    "%u "			/* output size */
-		    "%9s\n",			/* Target */
-		    chainlabel,
-		    ntohl(rule->ipfw.fw_src.s_addr),
-		    ntohl(rule->ipfw.fw_smsk.s_addr),
-		    ntohl(rule->ipfw.fw_dst.s_addr),
-		    ntohl(rule->ipfw.fw_dmsk.s_addr),
-		    (rule->ipfw.fw_vianame)[0] ? rule->ipfw.fw_vianame : "-",
-		    rule->ipfw.fw_flg,
-		    rule->ipfw.fw_invflg,
-		    rule->ipfw.fw_proto,
-		    (__u32)(packets >> 32), (__u32)packets,
-		    (__u32)(bytes >> 32), (__u32)bytes,
-		    rule->ipfw.fw_spts[0], rule->ipfw.fw_spts[1],
-		    rule->ipfw.fw_dpts[0], rule->ipfw.fw_dpts[1],
-		    rule->ipfw.fw_tosand, rule->ipfw.fw_tosxor,
-		    rule->ipfw.fw_redirpt,
-		    rule->ipfw.fw_mark,
-		    rule->ipfw.fw_outputsize,
-		    branchname(rule->branch,rule->simplebranch));
-
-	duprintf("dump_rule: %i bytes done.\n", len);
-	return len;
-}
-
-/* File offset is actually in records, not bytes. */
-static int ip_chain_procinfo(char *buffer, char **start,
-			     off_t offset, int length)
-{
-	struct ip_chain *i;
-	struct ip_fwkernel *j = ip_fw_chains->chain;
-	unsigned long flags;
-	int len = 0;
-	int last_len = 0;
-	off_t upto = 0;
-
-	duprintf("Offset starts at %lu\n", offset);
-	duprintf("ip_fw_chains is 0x%0lX\n", (unsigned long int)ip_fw_chains);
-
-	/* Need a write lock to lock out ``readers'' which update counters. */
-	FWC_WRITE_LOCK_IRQ(&ip_fw_lock, flags);
-
-	for (i = ip_fw_chains; i; i = i->next) {
-	    for (j = i->chain; j; j = j->next) {
-		if (upto == offset) break;
-		duprintf("Skipping rule in chain `%s'\n",
-			 i->label);
-		upto++;
-	    }
-	    if (upto == offset) break;
-	}
-
-	/* Don't init j first time, or once i = NULL */
-	for (; i; (void)((i = i->next) && (j = i->chain))) {
-		duprintf("Dumping chain `%s'\n", i->label);
-		for (; j; j = j->next, upto++, last_len = len)
-		{
-			len += dump_rule(buffer+len, i->label, j);
-			if (len > length) {
-				duprintf("Dumped to %i (past %i).  "
-					 "Moving back to %i.\n",
-					 len, length, last_len);
-				len = last_len;
-				goto outside;
-			}
-		}
-	}
-outside:
-	FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);
-	buffer[len] = '\0';
-
-	duprintf("ip_chain_procinfo: Length = %i (of %i).  Offset = %li.\n",
-		 len, length, upto);
-	/* `start' hack - see fs/proc/generic.c line ~165 */
-	*start=(char *)((unsigned int)upto-offset);
-	return len;
-}
-
-static int ip_chain_name_procinfo(char *buffer, char **start,
-				  off_t offset, int length)
-{
-	struct ip_chain *i;
-	int len = 0,last_len = 0;
-	off_t pos = 0,begin = 0;
-	unsigned long flags;
-
-	/* Need a write lock to lock out ``readers'' which update counters. */
-	FWC_WRITE_LOCK_IRQ(&ip_fw_lock, flags);
-
-	for (i = ip_fw_chains; i; i = i->next)
-	{
-		unsigned int j;
-		__u32 packetsHi = 0, packetsLo = 0, bytesHi = 0, bytesLo = 0;
-
-		for (j = 0; j < NUM_SLOTS; j++) {
-			packetsLo += i->reent[j].counters.pcnt & 0xFFFFFFFF;
-			packetsHi += ((i->reent[j].counters.pcnt >> 32)
-				      & 0xFFFFFFFF);
-			bytesLo += i->reent[j].counters.bcnt & 0xFFFFFFFF;
-			bytesHi += ((i->reent[j].counters.bcnt >> 32)
-				    & 0xFFFFFFFF);
-		}
-
-		/* print the label and the policy */
-		len+=sprintf(buffer+len,"%s %s %i %u %u %u %u\n",
-			     i->label,branchname(NULL, i->policy),i->refcount,
-			     packetsHi, packetsLo, bytesHi, bytesLo);
-		pos=begin+len;
-		if(pos<offset) {
-			len=0;
-			begin=pos;
-		}
-		else if(pos>offset+length) {
-			len = last_len;
-			break;
-		}
-
-		last_len = len;
-	}
-	FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);
-
-	*start = buffer+(offset-begin);
-	len-=(offset-begin);
-	if(len>length)
-		len=length;
-	return len;
-}
-
-/*
- *	Interface to the generic firewall chains.
- */
-int ipfw_input_check(struct firewall_ops *this, int pf,
-		     struct net_device *dev, void *arg,
-		     struct sk_buff **pskb)
-{
-	return ip_fw_check(dev->name,
-			   arg, IP_FW_INPUT_CHAIN, pskb, SLOT_NUMBER(), 0);
-}
-
-int ipfw_output_check(struct firewall_ops *this, int pf,
-		      struct net_device *dev, void *arg,
-		      struct sk_buff **pskb)
-{
-	/* Locally generated bogus packets by root. <SIGH>. */
-	if ((*pskb)->len < sizeof(struct iphdr) ||
-	    (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
-		return FW_ACCEPT;
-	return ip_fw_check(dev->name,
-			   arg, IP_FW_OUTPUT_CHAIN, pskb, SLOT_NUMBER(), 0);
-}
-
-int ipfw_forward_check(struct firewall_ops *this, int pf,
-		       struct net_device *dev, void *arg,
-		       struct sk_buff **pskb)
-{
-	return ip_fw_check(dev->name,
-			   arg, IP_FW_FORWARD_CHAIN, pskb, SLOT_NUMBER(), 0);
-}
-
-struct firewall_ops ipfw_ops = {
-	.fw_forward	=	ipfw_forward_check,
-	.fw_input	=	ipfw_input_check,
-	.fw_output	=	ipfw_output_check,
-};
-
-int ipfw_init_or_cleanup(int init)
-{
-	struct proc_dir_entry *proc;
-	int ret = 0;
-	unsigned long flags;
-
-	if (!init) goto cleanup;
-
-#ifdef DEBUG_IP_FIREWALL_LOCKING
-	fwc_wlocks = fwc_rlocks = 0;
-#endif
-
-#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
-	ipfwsk = netlink_kernel_create(NETLINK_FIREWALL, NULL);
-	if (ipfwsk == NULL)
-		goto cleanup_nothing;
-#endif
-
-	ret = register_firewall(PF_INET, &ipfw_ops);
-	if (ret < 0)
-		goto cleanup_netlink;
-
-	proc = proc_net_create(IP_FW_PROC_CHAINS, S_IFREG | S_IRUSR | S_IWUSR,
-			       ip_chain_procinfo);
-	if (proc) proc->owner = THIS_MODULE;
-	proc = proc_net_create(IP_FW_PROC_CHAIN_NAMES,
-			       S_IFREG | S_IRUSR | S_IWUSR,
-			       ip_chain_name_procinfo);
-	if (proc) proc->owner = THIS_MODULE;
-
-	IP_FW_INPUT_CHAIN = ip_init_chain(IP_FW_LABEL_INPUT, 1, FW_ACCEPT);
-	IP_FW_FORWARD_CHAIN = ip_init_chain(IP_FW_LABEL_FORWARD, 1, FW_ACCEPT);
-	IP_FW_OUTPUT_CHAIN = ip_init_chain(IP_FW_LABEL_OUTPUT, 1, FW_ACCEPT);
-
-	return ret;
-
- cleanup:
-	unregister_firewall(PF_INET, &ipfw_ops);
-
-	FWC_WRITE_LOCK_IRQ(&ip_fw_lock, flags);
-	while (ip_fw_chains) {
-		struct ip_chain *next = ip_fw_chains->next;
-
-		clear_fw_chain(ip_fw_chains);
-		kfree(ip_fw_chains);
-		ip_fw_chains = next;
-	}
-	FWC_WRITE_UNLOCK_IRQ(&ip_fw_lock, flags);
-
-	proc_net_remove(IP_FW_PROC_CHAINS);
-	proc_net_remove(IP_FW_PROC_CHAIN_NAMES);
-
- cleanup_netlink:
-#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
-	sock_release(ipfwsk->sk_socket);
-
- cleanup_nothing:
-#endif
-	return ret;
-}
Index: linux-2.6.10-rc3-bk6-Netfilter/net/ipv4/netfilter/Makefile
===================================================================
--- linux-2.6.10-rc3-bk6-Netfilter.orig/net/ipv4/netfilter/Makefile	2004-12-13 12:02:08.077843248 +1100
+++ linux-2.6.10-rc3-bk6-Netfilter/net/ipv4/netfilter/Makefile	2004-12-13 12:03:15.504592824 +1100
@@ -2,19 +2,9 @@
 # Makefile for the netfilter modules on top of IPv4.
 #
 
-# objects for the conntrack and NAT core (used by standalone and backw. compat)
-ip_nf_conntrack-objs	:= ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o
-ip_nf_nat-objs		:= ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o
-
 # objects for the standalone - connection tracking / NAT
-ip_conntrack-objs	:= ip_conntrack_standalone.o $(ip_nf_conntrack-objs)
-iptable_nat-objs	:= ip_nat_standalone.o ip_nat_rule.o $(ip_nf_nat-objs)
-
-# objects for backwards compatibility mode
-ip_nf_compat-objs	:= ip_fw_compat.o ip_fw_compat_redir.o ip_fw_compat_masq.o $(ip_nf_conntrack-objs) $(ip_nf_nat-objs)
-
-ipfwadm-objs		:= $(ip_nf_compat-objs) ipfwadm_core.o
-ipchains-objs		:= $(ip_nf_compat-objs) ipchains_core.o
+ip_conntrack-objs	:= ip_conntrack_standalone.o ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o
+iptable_nat-objs	:= ip_nat_standalone.o ip_nat_rule.o ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o
 
 # connection tracking
 obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
@@ -96,8 +86,4 @@
 # just filtering instance of ARP tables for now
 obj-$(CONFIG_IP_NF_ARPFILTER) += arptable_filter.o
 
-# backwards compatibility 
-obj-$(CONFIG_IP_NF_COMPAT_IPCHAINS) += ipchains.o
-obj-$(CONFIG_IP_NF_COMPAT_IPFWADM) += ipfwadm.o
-
 obj-$(CONFIG_IP_NF_QUEUE) += ip_queue.o
Index: linux-2.6.10-rc3-bk6-Netfilter/net/ipv4/netfilter/ip_fw_compat.c
===================================================================
--- linux-2.6.10-rc3-bk6-Netfilter.orig/net/ipv4/netfilter/ip_fw_compat.c	2004-12-13 12:02:08.018852216 +1100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,303 +0,0 @@
-/* Compatibility framework for ipchains and ipfwadm support; designed
-   to look as much like the 2.2 infrastructure as possible. */
-
-/* (C) 1999-2001 Paul `Rusty' Russell
- * (C) 2002-2004 Netfilter Core Team <coreteam at netfilter.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-struct notifier_block;
-
-#include <linux/netfilter_ipv4.h>
-#include <linux/ip.h>
-#include <net/icmp.h>
-#include <linux/if.h>
-#include <linux/inetdevice.h>
-#include <linux/netdevice.h>
-#include <linux/module.h>
-#include <asm/uaccess.h>
-#include <net/ip.h>
-#include <net/route.h>
-#include <linux/netfilter_ipv4/compat_firewall.h>
-#include <linux/netfilter_ipv4/ip_conntrack.h>
-#include <linux/netfilter_ipv4/ip_conntrack_core.h>
-#include "ip_fw_compat.h"
-
-static struct firewall_ops *fwops;
-
-#ifdef CONFIG_IP_VS
-/* From ip_vs_core.c */
-extern unsigned int
-check_for_ip_vs_out(struct sk_buff **skb_p, int (*okfn)(struct sk_buff *));
-#endif
-
-/* They call these; we do what they want. */
-int register_firewall(int pf, struct firewall_ops *fw)
-{
-	if (pf != PF_INET) {
-		printk("Attempt to register non-IP firewall module.\n");
-		return -EINVAL;
-	}
-	if (fwops) {
-		printk("Attempt to register multiple firewall modules.\n");
-		return -EBUSY;
-	}
-
-	fwops = fw;
-	return 0;
-}
-
-int unregister_firewall(int pf, struct firewall_ops *fw)
-{
-	fwops = NULL;
-	return 0;
-}
-
-static unsigned int
-fw_in(unsigned int hooknum,
-      struct sk_buff **pskb,
-      const struct net_device *in,
-      const struct net_device *out,
-      int (*okfn)(struct sk_buff *))
-{
-	int ret = FW_BLOCK;
-	u_int16_t redirpt;
-
-	/* Assume worse case: any hook could change packet */
-	(*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED;
-	if ((*pskb)->ip_summed == CHECKSUM_HW)
-		if (skb_checksum_help(*pskb, (out == NULL)))
-			return NF_DROP;
-
-	switch (hooknum) {
-	case NF_IP_PRE_ROUTING:
-		if (fwops->fw_acct_in)
-			fwops->fw_acct_in(fwops, PF_INET,
-					  (struct net_device *)in,
-					  &redirpt, pskb);
-
-		if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
-			*pskb = ip_ct_gather_frags(*pskb);
-
-			if (!*pskb)
-				return NF_STOLEN;
-		}
-
-		ret = fwops->fw_input(fwops, PF_INET, (struct net_device *)in,
-				      &redirpt, pskb);
-		break;
-
-	case NF_IP_FORWARD:
-		/* Connection will only be set if it was
-                   demasqueraded: if so, skip forward chain. */
-		if ((*pskb)->nfct)
-			ret = FW_ACCEPT;
-		else ret = fwops->fw_forward(fwops, PF_INET,
-					     (struct net_device *)out,
-					     &redirpt, pskb);
-		break;
-
-	case NF_IP_POST_ROUTING:
-		ret = fwops->fw_output(fwops, PF_INET,
-				       (struct net_device *)out,
-				       &redirpt, pskb);
-		if (ret == FW_ACCEPT || ret == FW_SKIP) {
-			if (fwops->fw_acct_out)
-				fwops->fw_acct_out(fwops, PF_INET,
-						   (struct net_device *)out,
-						   &redirpt,
-						   pskb);
-
-			/* ip_conntrack_confirm return NF_DROP or NF_ACCEPT */
-			if (ip_conntrack_confirm(*pskb) == NF_DROP)
-				ret = FW_BLOCK;
-		}
-		break;
-	}
-
-	switch (ret) {
-	case FW_REJECT: {
-		/* Alexey says:
-		 *
-		 * Generally, routing is THE FIRST thing to make, when
-		 * packet enters IP stack. Before packet is routed you
-		 * cannot call any service routines from IP stack.  */
-		struct iphdr *iph = (*pskb)->nh.iph;
-
-		if ((*pskb)->dst != NULL
-		    || ip_route_input(*pskb, iph->daddr, iph->saddr, iph->tos,
-				      (struct net_device *)in) == 0)
-			icmp_send(*pskb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH,
-				  0);
-		return NF_DROP;
-	}
-
-	case FW_ACCEPT:
-	case FW_SKIP:
-		if (hooknum == NF_IP_PRE_ROUTING) {
-			check_for_demasq(pskb);
-			check_for_redirect(*pskb);
-		} else if (hooknum == NF_IP_POST_ROUTING) {
-			check_for_unredirect(*pskb);
-			/* Handle ICMP errors from client here */
-			if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP
-			    && (*pskb)->nfct)
-				check_for_masq_error(pskb);
-		}
-		return NF_ACCEPT;
-
-	case FW_MASQUERADE:
-		if (hooknum == NF_IP_FORWARD) {
-#ifdef CONFIG_IP_VS
-			/* check if it is for ip_vs */
-			if (check_for_ip_vs_out(pskb, okfn) == NF_STOLEN)
-				return NF_STOLEN;
-#endif
-			return do_masquerade(pskb, out);
-		}
-		else return NF_ACCEPT;
-
-	case FW_REDIRECT:
-		if (hooknum == NF_IP_PRE_ROUTING)
-			return do_redirect(*pskb, in, redirpt);
-		else return NF_ACCEPT;
-
-	default:
-		/* FW_BLOCK */
-		return NF_DROP;
-	}
-}
-
-static unsigned int fw_confirm(unsigned int hooknum,
-			       struct sk_buff **pskb,
-			       const struct net_device *in,
-			       const struct net_device *out,
-			       int (*okfn)(struct sk_buff *))
-{
-	return ip_conntrack_confirm(*pskb);
-}
-
-extern int ip_fw_ctl(int optval, void *m, unsigned int len);
-
-static int sock_fn(struct sock *sk, int optval, void __user *user, unsigned int len)
-{
-	/* MAX of:
-	   2.2: sizeof(struct ip_fwtest) (~14x4 + 3x4 = 17x4)
-	   2.2: sizeof(struct ip_fwnew) (~1x4 + 15x4 + 3x4 + 3x4 = 22x4)
-	   2.0: sizeof(struct ip_fw) (~25x4)
-
-	   We can't include both 2.0 and 2.2 headers, they conflict.
-	   Hence, 200 is a good number. --RR */
-	char tmp_fw[200];
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-
-	if (len > sizeof(tmp_fw) || len < 1)
-		return -EINVAL;
-
-	if (copy_from_user(&tmp_fw, user, len))
-		return -EFAULT;
-
-	return -ip_fw_ctl(optval, &tmp_fw, len);
-}
-
-static struct nf_hook_ops preroute_ops = {
-	.hook		= fw_in,
-	.owner		= THIS_MODULE,
-	.pf		= PF_INET,
-	.hooknum	= NF_IP_PRE_ROUTING,
-	.priority	= NF_IP_PRI_FILTER,
-};
-
-static struct nf_hook_ops postroute_ops = {
-	.hook		= fw_in,
-	.owner		= THIS_MODULE,
-	.pf		= PF_INET,
-	.hooknum	= NF_IP_POST_ROUTING,
-	.priority	= NF_IP_PRI_FILTER,
-};
-
-static struct nf_hook_ops forward_ops = {
-	.hook		= fw_in,
-	.owner		= THIS_MODULE,
-	.pf		= PF_INET,
-	.hooknum	= NF_IP_FORWARD,
-	.priority	= NF_IP_PRI_FILTER,
-};
-
-static struct nf_hook_ops local_in_ops = {
-	.hook		= fw_confirm,
-	.owner		= THIS_MODULE,
-	.pf		= PF_INET,
-	.hooknum	= NF_IP_LOCAL_IN,
-	.priority	= NF_IP_PRI_LAST - 1,
-};
-
-static struct nf_sockopt_ops sock_ops = {
-	.pf		= PF_INET,
-	.set_optmin	= 64,
-	.set_optmax	= 64 + 1024 + 1,
-	.set		= &sock_fn,
-};
-
-extern int ipfw_init_or_cleanup(int init);
-
-static int init_or_cleanup(int init)
-{
-	int ret = 0;
-
-	if (!init) goto cleanup;
-
-	ret = nf_register_sockopt(&sock_ops);
-
-	if (ret < 0)
-		goto cleanup_nothing;
-
-	ret = ipfw_init_or_cleanup(1);
-	if (ret < 0)
-		goto cleanup_sockopt;
-
-	ret = masq_init();
-	if (ret < 0)
-		goto cleanup_ipfw;
-
-	nf_register_hook(&preroute_ops);
-	nf_register_hook(&postroute_ops);
-	nf_register_hook(&forward_ops);
-	nf_register_hook(&local_in_ops);
-
-	return ret;
-
- cleanup:
-	nf_unregister_hook(&preroute_ops);
-	nf_unregister_hook(&postroute_ops);
-	nf_unregister_hook(&forward_ops);
-	nf_unregister_hook(&local_in_ops);
-
-	masq_cleanup();
-
- cleanup_ipfw:
-	ipfw_init_or_cleanup(0);
-
- cleanup_sockopt:
-	nf_unregister_sockopt(&sock_ops);
-
- cleanup_nothing:
-	return ret;
-}
-
-static int __init init(void)
-{
-	return init_or_cleanup(1);
-}
-
-static void __exit fini(void)
-{
-	init_or_cleanup(0);
-}
-
-module_init(init);
-module_exit(fini);
Index: linux-2.6.10-rc3-bk6-Netfilter/net/ipv4/netfilter/ip_fw_compat_redir.c
===================================================================
--- linux-2.6.10-rc3-bk6-Netfilter.orig/net/ipv4/netfilter/ip_fw_compat_redir.c	2004-12-13 12:02:08.018852216 +1100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,318 +0,0 @@
-/* This is a file to handle the "simple" NAT cases (redirect and
-   masquerade) required for the compatibility layer.
-
-   `bind to foreign address' and `getpeername' hacks are not
-   supported.
-
-   FIXME: Timing is overly simplistic.  If anyone complains, make it
-   use conntrack.
-*/
-
-/* (C) 1999-2001 Paul `Rusty' Russell
- * (C) 2002-2004 Netfilter Core Team <coreteam at netfilter.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/config.h>
-#include <linux/netfilter.h>
-#include <linux/ip.h>
-#include <linux/udp.h>
-#include <linux/tcp.h>
-#include <net/checksum.h>
-#include <net/ip.h>
-#include <linux/timer.h>
-#include <linux/netdevice.h>
-#include <linux/if.h>
-#include <linux/in.h>
-
-#include <linux/netfilter_ipv4/lockhelp.h>
-
-/* Very simple timeout pushed back by each packet */
-#define REDIR_TIMEOUT (240*HZ)
-
-static DECLARE_LOCK(redir_lock);
-#define ASSERT_READ_LOCK(x) MUST_BE_LOCKED(&redir_lock)
-#define ASSERT_WRITE_LOCK(x) MUST_BE_LOCKED(&redir_lock)
-
-#include <linux/netfilter_ipv4/listhelp.h>
-#include "ip_fw_compat.h"
-
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
-#ifdef CONFIG_NETFILTER_DEBUG
-#define IP_NF_ASSERT(x)							 \
-do {									 \
-	if (!(x))							 \
-		/* Wooah!  I'm tripping my conntrack in a frenzy of	 \
-		   netplay... */					 \
-		printk("ASSERT: %s:%i(%s)\n",				 \
-		       __FILE__, __LINE__, __FUNCTION__);		 \
-} while(0)
-#else
-#define IP_NF_ASSERT(x)
-#endif
-
-static u_int16_t
-cheat_check(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
-{
-	u_int32_t diffs[] = { oldvalinv, newval };
-	return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
-				      oldcheck^0xFFFF));
-}
-
-struct redir_core {
-	u_int32_t orig_srcip, orig_dstip;
-	u_int16_t orig_sport, orig_dport;
-
-	u_int32_t new_dstip;
-	u_int16_t new_dport;
-};
-
-struct redir
-{
-	struct list_head list;
-	struct redir_core core;
-	struct timer_list destroyme;
-};
-
-static LIST_HEAD(redirs);
-
-static int
-redir_cmp(const struct redir *i,
-	  u_int32_t orig_srcip, u_int32_t orig_dstip,
-	  u_int16_t orig_sport, u_int16_t orig_dport)
-{
-	return (i->core.orig_srcip == orig_srcip
-		&& i->core.orig_dstip == orig_dstip
-		&& i->core.orig_sport == orig_sport
-		&& i->core.orig_dport == orig_dport);
-}
-
-/* Search for an existing redirection of the TCP packet. */
-static struct redir *
-find_redir(u_int32_t orig_srcip, u_int32_t orig_dstip,
-	   u_int16_t orig_sport, u_int16_t orig_dport)
-{
-	return LIST_FIND(&redirs, redir_cmp, struct redir *,
-			 orig_srcip, orig_dstip, orig_sport, orig_dport);
-}
-
-static void do_tcp_redir(struct sk_buff *skb, struct redir *redir)
-{
-	struct iphdr *iph = skb->nh.iph;
-	struct tcphdr *tcph = (struct tcphdr *)((u_int32_t *)iph
-						+ iph->ihl);
-
-	tcph->check = cheat_check(~redir->core.orig_dstip,
-				  redir->core.new_dstip,
-				  cheat_check(redir->core.orig_dport ^ 0xFFFF,
-					      redir->core.new_dport,
-					      tcph->check));
-	iph->check = cheat_check(~redir->core.orig_dstip,
-				 redir->core.new_dstip, iph->check);
-	tcph->dest = redir->core.new_dport;
-	iph->daddr = redir->core.new_dstip;
-
-	skb->nfcache |= NFC_ALTERED;
-}
-
-static int
-unredir_cmp(const struct redir *i,
-	    u_int32_t new_dstip, u_int32_t orig_srcip,
-	    u_int16_t new_dport, u_int16_t orig_sport)
-{
-	return (i->core.orig_srcip == orig_srcip
-		&& i->core.new_dstip == new_dstip
-		&& i->core.orig_sport == orig_sport
-		&& i->core.new_dport == new_dport);
-}
-
-/* Match reply packet against redir */
-static struct redir *
-find_unredir(u_int32_t new_dstip, u_int32_t orig_srcip,
-	     u_int16_t new_dport, u_int16_t orig_sport)
-{
-	return LIST_FIND(&redirs, unredir_cmp, struct redir *,
-			 new_dstip, orig_srcip, new_dport, orig_sport);
-}
-
-/* `unredir' a reply packet. */
-static void do_tcp_unredir(struct sk_buff *skb, struct redir *redir)
-{
-	struct iphdr *iph = skb->nh.iph;
-	struct tcphdr *tcph = (struct tcphdr *)((u_int32_t *)iph
-						+ iph->ihl);
-
-	tcph->check = cheat_check(~redir->core.new_dstip,
-				  redir->core.orig_dstip,
-				  cheat_check(redir->core.new_dport ^ 0xFFFF,
-					      redir->core.orig_dport,
-					      tcph->check));
-	iph->check = cheat_check(~redir->core.new_dstip,
-				 redir->core.orig_dstip,
-				 iph->check);
-	tcph->source = redir->core.orig_dport;
-	iph->saddr = redir->core.orig_dstip;
-
-	skb->nfcache |= NFC_ALTERED;
-}
-
-static void destroyme(unsigned long me)
-{
-	LOCK_BH(&redir_lock);
-	LIST_DELETE(&redirs, (struct redir *)me);
-	UNLOCK_BH(&redir_lock);
-	kfree((struct redir *)me);
-}
-
-/* REDIRECT a packet. */
-unsigned int
-do_redirect(struct sk_buff *skb,
-	    const struct net_device *dev,
-	    u_int16_t redirpt)
-{
-	struct iphdr *iph = skb->nh.iph;
-	u_int32_t newdst;
-
-	/* Figure out address: not loopback. */
-	if (!dev)
-		return NF_DROP;
-
-	/* Grab first address on interface. */
-	newdst = ((struct in_device *)dev->ip_ptr)->ifa_list->ifa_local;
-
-	switch (iph->protocol) {
-	case IPPROTO_UDP: {
-		/* Simple mangle. */
-		struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph
-							+ iph->ihl);
-
-		/* Must have whole header */
-		if (skb->len < iph->ihl*4 + sizeof(*udph))
-			return NF_DROP;
-
-		if (udph->check) /* 0 is a special case meaning no checksum */
-			udph->check = cheat_check(~iph->daddr, newdst,
-					  cheat_check(udph->dest ^ 0xFFFF,
-						      redirpt,
-						      udph->check));
-		iph->check = cheat_check(~iph->daddr, newdst, iph->check);
-		udph->dest = redirpt;
-		iph->daddr = newdst;
-
-		skb->nfcache |= NFC_ALTERED;
-		return NF_ACCEPT;
-	}
-	case IPPROTO_TCP: {
-		/* Mangle, maybe record. */
-		struct tcphdr *tcph = (struct tcphdr *)((u_int32_t *)iph
-							+ iph->ihl);
-		struct redir *redir;
-		int ret;
-
-		/* Must have whole header */
-		if (skb->len < iph->ihl*4 + sizeof(*tcph))
-			return NF_DROP;
-
-		DEBUGP("Doing tcp redirect. %08X:%u %08X:%u -> %08X:%u\n",
-		       iph->saddr, tcph->source, iph->daddr, tcph->dest,
-		       newdst, redirpt);
-		LOCK_BH(&redir_lock);
-		redir = find_redir(iph->saddr, iph->daddr,
-				   tcph->source, tcph->dest);
-
-		if (!redir) {
-			redir = kmalloc(sizeof(struct redir), GFP_ATOMIC);
-			if (!redir) {
-				ret = NF_DROP;
-				goto out;
-			}
-			list_prepend(&redirs, redir);
-			init_timer(&redir->destroyme);
-			redir->destroyme.function = destroyme;
-			redir->destroyme.data = (unsigned long)redir;
-			redir->destroyme.expires = jiffies + REDIR_TIMEOUT;
-			add_timer(&redir->destroyme);
-		}
-		/* In case mangling has changed, rewrite this part. */
-		redir->core = ((struct redir_core)
-			       { iph->saddr, iph->daddr,
-				 tcph->source, tcph->dest,
-				 newdst, redirpt });
-		do_tcp_redir(skb, redir);
-		ret = NF_ACCEPT;
-
-	out:
-		UNLOCK_BH(&redir_lock);
-		return ret;
-	}
-
-	default: /* give up if not TCP or UDP. */
-		return NF_DROP;
-	}
-}
-
-/* Incoming packet: is it a reply to a masqueraded connection, or
-   part of an already-redirected TCP connection? */
-void
-check_for_redirect(struct sk_buff *skb)
-{
-	struct iphdr *iph = skb->nh.iph;
-	struct tcphdr *tcph = (struct tcphdr *)((u_int32_t *)iph
-						+ iph->ihl);
-	struct redir *redir;
-
-	if (iph->protocol != IPPROTO_TCP)
-		return;
-
-	/* Must have whole header */
-	if (skb->len < iph->ihl*4 + sizeof(*tcph))
-		return;
-
-	LOCK_BH(&redir_lock);
-	redir = find_redir(iph->saddr, iph->daddr, tcph->source, tcph->dest);
-	if (redir) {
-		DEBUGP("Doing tcp redirect again.\n");
-		do_tcp_redir(skb, redir);
-		if (del_timer(&redir->destroyme)) {
-			redir->destroyme.expires = jiffies + REDIR_TIMEOUT;
-			add_timer(&redir->destroyme);
-		}
-	}
-	UNLOCK_BH(&redir_lock);
-}
-
-void
-check_for_unredirect(struct sk_buff *skb)
-{
-	struct iphdr *iph = skb->nh.iph;
-	struct tcphdr *tcph = (struct tcphdr *)((u_int32_t *)iph
-						+ iph->ihl);
-	struct redir *redir;
-
-	if (iph->protocol != IPPROTO_TCP)
-		return;
-
-	/* Must have whole header */
-	if (skb->len < iph->ihl*4 + sizeof(*tcph))
-		return;
-
-	LOCK_BH(&redir_lock);
-	redir = find_unredir(iph->saddr, iph->daddr, tcph->source, tcph->dest);
-	if (redir) {
-		DEBUGP("Doing tcp unredirect.\n");
-		do_tcp_unredir(skb, redir);
-		if (del_timer(&redir->destroyme)) {
-			redir->destroyme.expires = jiffies + REDIR_TIMEOUT;
-			add_timer(&redir->destroyme);
-		}
-	}
-	UNLOCK_BH(&redir_lock);
-}
Index: linux-2.6.10-rc3-bk6-Netfilter/include/linux/netfilter_ipv4/compat_firewall.h
===================================================================
--- linux-2.6.10-rc3-bk6-Netfilter.orig/include/linux/netfilter_ipv4/compat_firewall.h	2004-12-13 12:02:08.078843096 +1100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,45 +0,0 @@
-/* Minor modifications to fit on compatibility framework:
-   Rusty.Russell at rustcorp.com.au
-*/
-
-#ifndef __LINUX_FIREWALL_H
-#define __LINUX_FIREWALL_H
-
-/*
- *	Definitions for loadable firewall modules
- */
-
-#define FW_QUEUE	0
-#define FW_BLOCK	1
-#define FW_ACCEPT	2
-#define FW_REJECT	(-1)
-#define FW_REDIRECT	3
-#define FW_MASQUERADE	4
-#define FW_SKIP		5
-
-struct firewall_ops
-{
-	struct firewall_ops *next;
-	int (*fw_forward)(struct firewall_ops *this, int pf,
-			  struct net_device *dev, void *arg,
-			  struct sk_buff **pskb);
-	int (*fw_input)(struct firewall_ops *this, int pf,
-			struct net_device *dev, void *arg,
-			struct sk_buff **pskb);
-	int (*fw_output)(struct firewall_ops *this, int pf,
-			 struct net_device *dev, void *arg,
-			 struct sk_buff **pskb);
-	/* These may be NULL. */
-	int (*fw_acct_in)(struct firewall_ops *this, int pf,
-			  struct net_device *dev, void *arg,
-			  struct sk_buff **pskb);
-	int (*fw_acct_out)(struct firewall_ops *this, int pf,
-			   struct net_device *dev, void *arg,
-			   struct sk_buff **pskb);
-};
-
-extern int register_firewall(int pf, struct firewall_ops *fw);
-extern int unregister_firewall(int pf, struct firewall_ops *fw);
-
-extern int ip_fw_masq_timeouts(void *user, int len);
-#endif /* __LINUX_FIREWALL_H */
Index: linux-2.6.10-rc3-bk6-Netfilter/net/ipv4/netfilter/ipfwadm_core.c
===================================================================
--- linux-2.6.10-rc3-bk6-Netfilter.orig/net/ipv4/netfilter/ipfwadm_core.c	2004-12-13 12:02:08.077843248 +1100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,1464 +0,0 @@
-#warning ipfwadm is obsolete, and will be removed soon.
-
-/* Minor modifications to fit on compatibility framework:
-   Rusty.Russell at rustcorp.com.au
-*/
-
-#include <linux/config.h>
-#define CONFIG_IP_FIREWALL
-#define CONFIG_IP_FIREWALL_VERBOSE
-#define CONFIG_IP_MASQUERADE
-#define CONFIG_IP_ACCT
-#define CONFIG_IP_TRANSPARENT_PROXY
-#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
-#define CONFIG_IP_FIREWALL_NETLINK
-#endif
-
-/*
- *	IP firewalling code. This is taken from 4.4BSD. Please note the
- *	copyright message below. As per the GPL it must be maintained
- *	and the licenses thus do not conflict. While this port is subject
- *	to the GPL I also place my modifications under the original
- *	license in recognition of the original copyright.
- *				-- Alan Cox.
- *
- *	$Id: ipfwadm_core.c,v 1.11 2002/01/24 15:50:31 davem Exp $
- *
- *	Ported from BSD to Linux,
- *		Alan Cox 22/Nov/1994.
- *	Zeroing /proc and other additions
- *		Jos Vos 4/Feb/1995.
- *	Merged and included the FreeBSD-Current changes at Ugen's request
- *	(but hey it's a lot cleaner now). Ugen would prefer in some ways
- *	we waited for his final product but since Linux 1.2.0 is about to
- *	appear it's not practical - Read: It works, it's not clean but please
- *	don't consider it to be his standard of finished work.
- *		Alan Cox 12/Feb/1995
- *	Porting bidirectional entries from BSD, fixing accounting issues,
- *	adding struct ip_fwpkt for checking packets with interface address
- *		Jos Vos 5/Mar/1995.
- *	Established connections (ACK check), ACK check on bidirectional rules,
- *	ICMP type check.
- *		Wilfred Mollenvanger 7/7/1995.
- *	TCP attack protection.
- *		Alan Cox 25/8/95, based on information from bugtraq.
- *	ICMP type printk, IP_FW_F_APPEND
- *		Bernd Eckenfels 1996-01-31
- *	Split blocking chain into input and output chains, add new "insert" and
- *	"append" commands to replace semi-intelligent "add" command, let "delete".
- *	only delete the first matching entry, use 0xFFFF (0xFF) as ports (ICMP
- *	types) when counting packets being 2nd and further fragments.
- *		Jos Vos <jos at xos.nl> 8/2/1996.
- *	Add support for matching on device names.
- *		Jos Vos <jos at xos.nl> 15/2/1996.
- *	Transparent proxying support.
- *		Willy Konynenberg <willy at xos.nl> 10/5/96.
- *	Make separate accounting on incoming and outgoing packets possible.
- *		Jos Vos <jos at xos.nl> 18/5/1996.
- *	Added trap out of bad frames.
- *		Alan Cox <alan at cymru.net> 17/11/1996
- *
- *
- * Masquerading functionality
- *
- * Copyright (c) 1994 Pauline Middelink
- *
- * The pieces which added masquerading functionality are totally
- * my responsibility and have nothing to with the original authors
- * copyright or doing.
- *
- * Parts distributed under GPL.
- *
- * Fixes:
- *	Pauline Middelink	:	Added masquerading.
- *	Alan Cox		:	Fixed an error in the merge.
- *	Thomas Quinot		:	Fixed port spoofing.
- *	Alan Cox		:	Cleaned up retransmits in spoofing.
- *	Alan Cox		:	Cleaned up length setting.
- *	Wouter Gadeyne		:	Fixed masquerading support of ftp PORT commands
- *
- *	Juan Jose Ciarlante	:	Masquerading code moved to ip_masq.c
- *	Andi Kleen :		Print frag_offsets and the ip flags properly.
- *
- *	All the real work was done by .....
- *
- */
-
-
-/*
- * Copyright (c) 1993 Daniel Boulet
- * Copyright (c) 1994 Ugen J.S.Antsilevich
- *
- * Redistribution and use in source forms, with and without modification,
- * are permitted provided that this entire comment appears intact.
- *
- * Redistribution in binary form may occur without any restrictions.
- * Obviously, it would be nice if you gave credit where credit is due
- * but requiring it would be too onerous.
- *
- * This software is provided ``AS IS'' without any warranties of any kind.
- */
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/icmp.h>
-#include <linux/udp.h>
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <net/route.h>
-#include <net/tcp.h>
-#include <net/udp.h>
-#include <net/sock.h>
-#include <net/icmp.h>
-#include <linux/netlink.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/netfilter_ipv4/ipfwadm_core.h>
-#include <linux/netfilter_ipv4/compat_firewall.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
-#include <linux/netfilter_ipv4/ip_nat_core.h>
-
-#include <net/checksum.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_DESCRIPTION("ipfwadm backwards compatibility layer");
-
-/*
- *	Implement IP packet firewall
- */
-
-#ifdef DEBUG_IP_FIREWALL
-#define dprintf1(a)		printk(a)
-#define dprintf2(a1,a2)		printk(a1,a2)
-#define dprintf3(a1,a2,a3)	printk(a1,a2,a3)
-#define dprintf4(a1,a2,a3,a4)	printk(a1,a2,a3,a4)
-#else
-#define dprintf1(a)
-#define dprintf2(a1,a2)
-#define dprintf3(a1,a2,a3)
-#define dprintf4(a1,a2,a3,a4)
-#endif
-
-#define print_ip(a)	 printk("%u.%u.%u.%u", NIPQUAD(a));
-
-#ifdef DEBUG_IP_FIREWALL
-#define dprint_ip(a)	print_ip(a)
-#else
-#define dprint_ip(a)
-#endif
-
-static DECLARE_RWLOCK(ip_fw_lock);
-
-#if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
-
-struct ip_fw *ip_fw_fwd_chain;
-struct ip_fw *ip_fw_in_chain;
-struct ip_fw *ip_fw_out_chain;
-struct ip_fw *ip_acct_chain;
-struct ip_fw *ip_masq_chain;
-
-static struct ip_fw **chains[] =
-	{&ip_fw_fwd_chain, &ip_fw_in_chain, &ip_fw_out_chain, &ip_acct_chain,
-	 &ip_masq_chain
-	};
-#endif /* CONFIG_IP_ACCT || CONFIG_IP_FIREWALL */
-
-#ifdef CONFIG_IP_FIREWALL
-int ip_fw_fwd_policy=IP_FW_F_ACCEPT;
-int ip_fw_in_policy=IP_FW_F_ACCEPT;
-int ip_fw_out_policy=IP_FW_F_ACCEPT;
-
-static int *policies[] =
-	{&ip_fw_fwd_policy, &ip_fw_in_policy, &ip_fw_out_policy};
-
-#endif
-
-#ifdef CONFIG_IP_FIREWALL_NETLINK
-struct sock *ipfwsk;
-#endif
-
-/*
- *	Returns 1 if the port is matched by the vector, 0 otherwise
- */
-
-extern inline int port_match(unsigned short *portptr,int nports,unsigned short port,int range_flag)
-{
-	if (!nports)
-		return 1;
-	if ( range_flag )
-	{
-		if ( portptr[0] <= port && port <= portptr[1] )
-		{
-			return( 1 );
-		}
-		nports -= 2;
-		portptr += 2;
-	}
-	while ( nports-- > 0 )
-	{
-		if ( *portptr++ == port )
-		{
-			return( 1 );
-		}
-	}
-	return(0);
-}
-
-#if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
-
-#ifdef CONFIG_IP_FIREWALL_VERBOSE
-
-/*
- *	VERY ugly piece of code which actually makes kernel printf for
- * 	matching packets.
- */
-
-static char *chain_name(struct ip_fw *chain, int mode)
-{
-	switch (mode) {
-	case IP_FW_MODE_ACCT_IN: return "acct in";
-	case IP_FW_MODE_ACCT_OUT: return "acct out";
-	default:
-		if (chain == ip_fw_fwd_chain)
-			return "fw-fwd";
-		else if (chain == ip_fw_in_chain)
-			return "fw-in";
-		else
-			return "fw-out";
-	}
-}
-
-static char *rule_name(struct ip_fw *f, int mode, char *buf)
-{
-	if (mode == IP_FW_MODE_ACCT_IN || mode == IP_FW_MODE_ACCT_OUT)
-		return "";
-
-	if(f->fw_flg&IP_FW_F_ACCEPT) {
-		if(f->fw_flg&IP_FW_F_REDIR) {
-			sprintf(buf, "acc/r%d ", f->fw_pts[f->fw_nsp+f->fw_ndp]);
-			return buf;
-		} else if(f->fw_flg&IP_FW_F_MASQ)
-			return "acc/masq ";
-		else
-			return "acc ";
-	} else if(f->fw_flg&IP_FW_F_ICMPRPL) {
-		return "rej ";
-	} else {
-		return "deny ";
-	}
-}
-
-static void print_packet(struct sk_buff **pskb,
-			 u16 src_port, u16 dst_port, u16 icmp_type,
-			 char *chain, char *rule, char *devname)
-{
-	__u32 *opt = (__u32 *) ((*pskb)->nh.iph + 1);
-	int opti;
-	__u16 foff = ntohs((*pskb)->nh.iph->frag_off);
-	int protocol = (*pskb)->nh.iph->protocol;
-
-	printk(KERN_INFO "IP %s %s%s", chain, rule, devname);
-
-	switch (protocol) {
-	case IPPROTO_TCP:
-		printk(" TCP ");
-		break;
-	case IPPROTO_UDP:
-		printk(" UDP ");
-		break;
-	case IPPROTO_ICMP:
-		printk(" ICMP/%d ", icmp_type);
-		break;
-	default:
-		printk(" PROTO=%d ", protocol);
-		break;
-	};
-
-	print_ip((*pskb)->nh.iph->saddr);
-	if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP)
-		printk(":%hu", src_port);
-	printk(" ");
-	print_ip((*pskb)->nh.iph->daddr);
-	if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP)
-		printk(":%hu", dst_port);
-	printk(" L=%hu S=0x%2.2hX I=%hu FO=0x%4.4hX T=%hu",
-	       ntohs((*pskb)->nh.iph->tot_len),
-	       (*pskb)->nh.iph->tos,
-	       ntohs((*pskb)->nh.iph->id),
-	       foff & IP_OFFSET,
-	       (*pskb)->nh.iph->ttl);
-	if (foff & IP_DF)
-		printk(" DF=1");
-	if (foff & IP_MF)
-		printk(" MF=1");
-	for (opti = 0; opti < ((*pskb)->nh.iph->ihl - sizeof(struct iphdr) / 4); opti++)
-		printk(" O=0x%8.8X", *opt++);
-	printk("\n");
-}
-#endif
-
-/*
- *	Returns one of the generic firewall policies, like FW_ACCEPT.
- *	Also does accounting so you can feed it the accounting chain.
- *
- *	The modes is either IP_FW_MODE_FW (normal firewall mode),
- *	IP_FW_MODE_ACCT_IN or IP_FW_MODE_ACCT_OUT (accounting mode,
- *	steps through the entire chain and handles fragments
- *	differently), or IP_FW_MODE_CHK (handles user-level check,
- *	counters are not updated).
- */
-
-
-int ip_fw_chk(struct sk_buff **pskb,
-	      struct net_device *rif, __u16 *redirport,
-	      struct ip_fw *chain, int policy, int mode)
-{
-	struct ip_fw *f;
-	__u32			src, dst;
-	__u16			src_port=0xFFFF, dst_port=0xFFFF, icmp_type=0xFF;
-	unsigned short		f_prt=0, prt;
-	char			notcpsyn=0, notcpack=0, match;
-	unsigned short		offset;
-	int			answer;
-	unsigned char		tosand, tosxor;
-	int			protocol;
-
-	/*
-	 *	If the chain is empty follow policy. The BSD one
-	 *	accepts anything giving you a time window while
-	 *	flushing and rebuilding the tables.
-	 */
-
-	/*
-	 *	This way we handle fragmented packets.
-	 *	we ignore all fragments but the first one
-	 *	so the whole packet can't be reassembled.
-	 *	This way we relay on the full info which
-	 *	stored only in first packet.
-	 *
-	 *	Note that this theoretically allows partial packet
-	 *	spoofing. Not very dangerous but paranoid people may
-	 *	wish to play with this. It also allows the so called
-	 *	"fragment bomb" denial of service attack on some types
-	 *	of system.
-	 */
-
-	offset = ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET;
-	protocol = (*pskb)->nh.iph->protocol;
-
-	/*
-	 *	Don't allow a fragment of TCP 8 bytes in. Nobody
-	 *	normal causes this. Its a cracker trying to break
-	 *	in by doing a flag overwrite to pass the direction
-	 *	checks.
-	 */
-
-	if (offset == 1 && protocol == IPPROTO_TCP)
-		return FW_BLOCK;
-
-	if (offset!=0 && !(mode & (IP_FW_MODE_ACCT_IN|IP_FW_MODE_ACCT_OUT)) &&
-		(protocol == IPPROTO_TCP ||
-		 protocol == IPPROTO_UDP ||
-		 protocol == IPPROTO_ICMP))
-		return FW_ACCEPT;
-
-	/*
-	 *	 Header fragment for TCP is too small to check the bits.
-	 */
-
-	if (protocol == IPPROTO_TCP &&
-	    ((*pskb)->nh.iph->ihl<<2)+16 > ntohs((*pskb)->nh.iph->tot_len))
-		return FW_BLOCK;
-
-	/*
-	 *	Too short.
-	 *
-	 *	But only too short for a packet with ports...
-	 */
-
-	else if ((ntohs((*pskb)->nh.iph->tot_len) <
-		  8 + ((*pskb)->nh.iph->ihl << 2)) &&
-		 (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP))
-		return FW_BLOCK;
-
-	src = (*pskb)->nh.iph->saddr;
-	dst = (*pskb)->nh.iph->daddr;
-
-	/*
-	 *	If we got interface from which packet came
-	 *	we can use the address directly. This is unlike
-	 *	4.4BSD derived systems that have an address chain
-	 *	per device. We have a device per address with dummy
-	 *	devices instead.
-	 */
-
-	dprintf1("Packet ");
-	switch (protocol) {
-		case IPPROTO_TCP:
-			dprintf1("TCP ");
-			/* ports stay 0xFFFF if it is not the first fragment */
-			if (!offset) {
-				struct tcphdr _tcph, *th;
-
-				th = skb_header_pointer(*pskb,
-							(*pskb)->nh.iph->ihl*4,
-							sizeof(_tcph), &_tcph);
-				if (th == NULL)
-					return FW_BLOCK;
-
-				src_port = ntohs(th->source);
-				dst_port = ntohs(th->dest);
-
-				if(!th->ack && !th->rst)
-					/* We do NOT have ACK, value TRUE */
-					notcpack = 1;
-				if(!th->syn || !notcpack)
-					/* We do NOT have SYN, value TRUE */
-					notcpsyn = 1;
-			}
-			prt = IP_FW_F_TCP;
-			break;
-		case IPPROTO_UDP:
-			dprintf1("UDP ");
-			/* ports stay 0xFFFF if it is not the first fragment */
-			if (!offset) {
-				struct udphdr _udph, *uh;
-
-				uh = skb_header_pointer(*pskb,
-							(*pskb)->nh.iph->ihl*4,
-							sizeof(_udph), &_udph);
-				if (uh == NULL)
-					return FW_BLOCK;
-
-				src_port = ntohs(uh->source);
-				dst_port = ntohs(uh->dest);
-			}
-			prt = IP_FW_F_UDP;
-			break;
-		case IPPROTO_ICMP:
-			/* icmp_type stays 255 if it is not the first fragment */
-			if (!offset) {
-				struct icmphdr _icmph, *ic;
-
-				ic = skb_header_pointer(*pskb,
-							(*pskb)->nh.iph->ihl*4,
-							sizeof(_icmph),
-							&_icmph);
-				if (ic == NULL)
-					return FW_BLOCK;
-
-				icmp_type = (__u16) ic->type;
-			}
-			dprintf2("ICMP:%d ", icmp_type);
-			prt = IP_FW_F_ICMP;
-			break;
-		default:
-			dprintf2("p=%d ", protocol);
-			prt = IP_FW_F_ALL;
-			break;
-	}
-#ifdef DEBUG_IP_FIREWALL
-	dprint_ip(src);
-
-	if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP)
-		/* This will print 65535 when it is not the first fragment! */
-		dprintf2(":%d ", src_port);
-	dprint_ip(dst);
-	if (protocol == IPPROTO_TCP || protocol == IPPROTO_UDP)
-		/* This will print 65535 when it is not the first fragment! */
-		dprintf2(":%d ", dst_port);
-	dprintf1("\n");
-#endif
-
-	if (mode == IP_FW_MODE_CHK)
-		READ_LOCK(&ip_fw_lock);
-	else
-		WRITE_LOCK(&ip_fw_lock);
-	
-	for (f = chain; f; f = f->fw_next) {
-		/*
-		 *	This is a bit simpler as we don't have to walk
-		 *	an interface chain as you do in BSD - same logic
-		 *	however.
-		 */
-
-		/*
-		 *	Match can become 0x01 (a "normal" match was found),
-		 *	0x02 (a reverse match was found), and 0x03 (the
-		 *	IP addresses match in both directions).
-		 *	Now we know in which direction(s) we should look
-		 *	for a match for the TCP/UDP ports.  Both directions
-		 *	might match (e.g., when both addresses are on the
-		 *	same network for which an address/mask is given), but
-		 *	the ports might only match in one direction.
-		 *	This was obviously wrong in the original BSD code.
-		 */
-		match = 0x00;
-
-		if ((src & f->fw_smsk.s_addr) == f->fw_src.s_addr &&
-		    (dst & f->fw_dmsk.s_addr) == f->fw_dst.s_addr)
-			/* normal direction */
-			match |= 0x01;
-
-		if ((f->fw_flg & IP_FW_F_BIDIR) &&
-		    (dst & f->fw_smsk.s_addr) == f->fw_src.s_addr &&
-		    (src & f->fw_dmsk.s_addr) == f->fw_dst.s_addr)
-			/* reverse direction */
-			match |= 0x02;
-
-		if (!match)
-			continue;
-
-		/*
-		 *	Look for a VIA device match
-		 */
-		if (f->fw_viadev) {
-			if (rif != f->fw_viadev)
-				continue;	/* Mismatch */
-		}
-
-		/* This looks stupid, because we scan almost static
-		   list, searching for static key. However, this way seems
-		   to be only reasonable way of handling fw_via rules
-		   (btw bsd makes the same thing).
-
-		   It will not affect performance if you will follow
-		   the following simple rules:
-
-		   - if interface is aliased, ALWAYS specify fw_viadev,
-		     so that previous check will guarantee, that we will
-		     not waste time when packet arrive on another interface.
-
-		   - avoid using fw_via.s_addr if fw_via.s_addr is owned
-		     by an aliased interface.
-
-		                                                       --ANK
-		 */
-		if (f->fw_via.s_addr && rif) {
-			struct in_ifaddr *ifa;
-
-			if (rif->ip_ptr == NULL)
-				continue;	/* Mismatch */
-
-			for (ifa = ((struct in_device*)(rif->ip_ptr))->ifa_list;
-			     ifa; ifa = ifa->ifa_next) {
-				if (ifa->ifa_local == f->fw_via.s_addr)
-					goto ifa_ok;
-			}
-			continue;	/* Mismatch */
-
-		ifa_ok:;
-		}
-
-		/*
-		 *	Ok the chain addresses match.
-		 */
-
-#ifdef CONFIG_IP_ACCT
-		/*
-		 *	See if we're in accounting mode and only want to
-		 *	count incoming or outgoing packets.
-		 */
-
-		if (mode & (IP_FW_MODE_ACCT_IN|IP_FW_MODE_ACCT_OUT) &&
-		   ((mode == IP_FW_MODE_ACCT_IN && f->fw_flg&IP_FW_F_ACCTOUT) ||
-		    (mode == IP_FW_MODE_ACCT_OUT && f->fw_flg&IP_FW_F_ACCTIN)))
-			continue;
-
-#endif
-		/*
-		 * For all non-TCP packets and/or non-first fragments,
-		 * notcpsyn and notcpack will always be FALSE,
-		 * so the IP_FW_F_TCPSYN and IP_FW_F_TCPACK flags
-		 * are actually ignored for these packets.
-		 */
-
-		if((f->fw_flg&IP_FW_F_TCPSYN) && notcpsyn)
-		 	continue;
-
-		if((f->fw_flg&IP_FW_F_TCPACK) && notcpack)
-		 	continue;
-
-		f_prt=f->fw_flg&IP_FW_F_KIND;
-		if (f_prt != IP_FW_F_ALL) {
-			/*
-			 *	Specific firewall - packet's protocol
-			 *	must match firewall's.
-			 */
-
-			if (prt != f_prt)
-				continue;
-
-			if((prt==IP_FW_F_ICMP &&
-				! port_match(&f->fw_pts[0], f->fw_nsp,
-					icmp_type,f->fw_flg&IP_FW_F_SRNG)) ||
-			    !(prt==IP_FW_F_ICMP || ((match & 0x01) &&
-				port_match(&f->fw_pts[0], f->fw_nsp, src_port,
-					f->fw_flg&IP_FW_F_SRNG) &&
-				port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp, dst_port,
-					f->fw_flg&IP_FW_F_DRNG)) || ((match & 0x02) &&
-				port_match(&f->fw_pts[0], f->fw_nsp, dst_port,
-					f->fw_flg&IP_FW_F_SRNG) &&
-				port_match(&f->fw_pts[f->fw_nsp], f->fw_ndp, src_port,
-					f->fw_flg&IP_FW_F_DRNG))))
-			{
-				continue;
-			}
-		}
-
-#ifdef CONFIG_IP_FIREWALL_VERBOSE
-		if (f->fw_flg & IP_FW_F_PRN)
-		{
-			char buf[16];
-
-			print_packet(pskb, src_port, dst_port, icmp_type,
-				     chain_name(chain, mode),
-				     rule_name(f, mode, buf),
-				     rif ? rif->name : "-");
-		}
-#endif
-		if (mode != IP_FW_MODE_CHK) {
-			f->fw_bcnt += ntohs((*pskb)->nh.iph->tot_len);
-			f->fw_pcnt++;
-		}
-		if (!(mode & (IP_FW_MODE_ACCT_IN|IP_FW_MODE_ACCT_OUT)))
-			break;
-	} /* Loop */
-
-	if (!(mode & (IP_FW_MODE_ACCT_IN|IP_FW_MODE_ACCT_OUT))) {
-
-		/*
-		 * We rely on policy defined in the rejecting entry or, if no match
-		 * was found, we rely on the general policy variable for this type
-		 * of firewall.
-		 */
-
-		if (f != NULL) {
-			policy = f->fw_flg;
-			tosand = f->fw_tosand;
-			tosxor = f->fw_tosxor;
-		} else {
-			tosand = 0xFF;
-			tosxor = 0x00;
-		}
-
-		if (policy & IP_FW_F_ACCEPT) {
-			/* Adjust priority and recompute checksum */
-			__u8 tos = (*pskb)->nh.iph->tos;
-
-			if (((tos & tosand) ^ tosxor) != tos) {
-				if (!skb_ip_make_writable(pskb,
-					  offsetof(struct iphdr, tos)+1))
-					goto drop_it;
-
-				(*pskb)->nh.iph->tos = (tos & tosand) ^ tosxor;
-		 		ip_send_check((*pskb)->nh.iph);
-			}
-
-#ifdef CONFIG_IP_TRANSPARENT_PROXY
-			if (policy & IP_FW_F_REDIR) {
-				if (redirport)
-					if ((*redirport = htons(f->fw_pts[f->fw_nsp+f->fw_ndp])) == 0) {
-						/* Wildcard redirection.
-						 * Note that redirport will become
-						 * 0xFFFF for non-TCP/UDP packets.
-						 */
-						*redirport = htons(dst_port);
-					}
-				answer = FW_REDIRECT;
-			} else
-#endif
-#ifdef CONFIG_IP_MASQUERADE
-			if (policy & IP_FW_F_MASQ)
-				answer = FW_MASQUERADE;
-			else
-#endif
-				answer = FW_ACCEPT;
-
-		} else if (policy & IP_FW_F_ICMPRPL)
-			answer = FW_REJECT;
-		else {
-		drop_it:
-			answer = FW_BLOCK;
-		}
-
-#ifdef CONFIG_IP_FIREWALL_NETLINK
-		if ((policy & IP_FW_F_PRN) && (answer == FW_REJECT || answer == FW_BLOCK))
-		{
-			struct sk_buff *skb = alloc_skb(128,
-					(mode == IP_FW_MODE_CHK) ?
-					GFP_KERNEL : GFP_ATOMIC);
-			if (skb) {
-				int len = min_t(unsigned int,
-					128,
-					ntohs((*pskb)->nh.iph->tot_len));
-
-				skb_put(skb, len);
-				skb_copy_bits(*pskb,
-					((char *)(*pskb)->nh.iph -
-					 (char *)(*pskb)->data),
-					skb->data, len);
-				if (netlink_post(NETLINK_FIREWALL, skb))
-					kfree_skb(skb);
-			}
-		}
-#endif
-	} else
-		/* we're doing accounting, always ok */
-		answer = 0;
-	
-	if (mode == IP_FW_MODE_CHK)
-		READ_UNLOCK(&ip_fw_lock);
-	else
-		WRITE_UNLOCK(&ip_fw_lock);
-
-	return answer;
-}
-
-
-static void zero_fw_chain(struct ip_fw *chainptr)
-{
-	struct ip_fw *ctmp=chainptr;
-	
-	WRITE_LOCK(&ip_fw_lock);
-	while(ctmp)
-	{
-		ctmp->fw_pcnt=0L;
-		ctmp->fw_bcnt=0L;
-		ctmp=ctmp->fw_next;
-	}
-	WRITE_UNLOCK(&ip_fw_lock);
-}
-
-static void free_fw_chain(struct ip_fw *volatile* chainptr)
-{
-	WRITE_LOCK(&ip_fw_lock);
-	while ( *chainptr != NULL )
-	{
-		struct ip_fw *ftmp;
-		ftmp = *chainptr;
-		*chainptr = ftmp->fw_next;
-		if (ftmp->fw_viadev
-		    && ftmp->fw_viadev != (struct net_device *)-1)
-			dev_put(ftmp->fw_viadev);
-		kfree(ftmp);
-		/* We will block in cleanup's unregister sockopt if unloaded,
-		   so this is safe. */
-		module_put(THIS_MODULE);
-	}
-	WRITE_UNLOCK(&ip_fw_lock);
-}
-
-/* Volatiles to keep some of the compiler versions amused */
-
-static int insert_in_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,int len)
-{
-	struct ip_fw *ftmp;
-
-	/* Are we unloading now?  We will block on nf_unregister_sockopt */
-	if (!try_module_get(THIS_MODULE))
-		return ENOPROTOOPT;
-
-	ftmp = kmalloc( sizeof(struct ip_fw), GFP_KERNEL );
-	if ( ftmp == NULL )
-	{
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl:  malloc said no\n");
-#endif
-		return( ENOMEM );
-	}
-
-	memcpy(ftmp, frwl, len);
-	/*
-	 *	Allow the more recent "minimise cost" flag to be
-	 *	set. [Rob van Nieuwkerk]
-	 */
-	ftmp->fw_tosand |= 0x01;
-	ftmp->fw_tosxor &= 0xFE;
-	ftmp->fw_pcnt=0L;
-	ftmp->fw_bcnt=0L;
-
-	WRITE_LOCK(&ip_fw_lock);
-
-	if ((ftmp->fw_vianame)[0]) {
-		if (!(ftmp->fw_viadev = dev_get_by_name(ftmp->fw_vianame)))
-			ftmp->fw_viadev = (struct net_device *) -1;
-	} else
-		ftmp->fw_viadev = NULL;
-
-	ftmp->fw_next = *chainptr;
-       	*chainptr=ftmp;
-	WRITE_UNLOCK(&ip_fw_lock);
-	return(0);
-}
-
-static int append_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,int len)
-{
-	struct ip_fw *ftmp;
-	struct ip_fw *chtmp=NULL;
-	struct ip_fw *volatile chtmp_prev=NULL;
-
-	/* Are we unloading now?  We will block on nf_unregister_sockopt */
-	if (!try_module_get(THIS_MODULE))
-		return ENOPROTOOPT;
-
-	ftmp = kmalloc( sizeof(struct ip_fw), GFP_KERNEL );
-	if ( ftmp == NULL )
-	{
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl:  malloc said no\n");
-#endif
-		return( ENOMEM );
-	}
-
-	memcpy(ftmp, frwl, len);
-	/*
-	 *	Allow the more recent "minimise cost" flag to be
-	 *	set. [Rob van Nieuwkerk]
-	 */
-	ftmp->fw_tosand |= 0x01;
-	ftmp->fw_tosxor &= 0xFE;
-	ftmp->fw_pcnt=0L;
-	ftmp->fw_bcnt=0L;
-
-	ftmp->fw_next = NULL;
-
-	WRITE_LOCK(&ip_fw_lock);
-
-	if ((ftmp->fw_vianame)[0]) {
-		if (!(ftmp->fw_viadev = dev_get_by_name(ftmp->fw_vianame)))
-			ftmp->fw_viadev = (struct net_device *) -1;
-	} else
-		ftmp->fw_viadev = NULL;
-
-	chtmp_prev=NULL;
-	for (chtmp=*chainptr;chtmp!=NULL;chtmp=chtmp->fw_next)
-		chtmp_prev=chtmp;
-
-	if (chtmp_prev)
-		chtmp_prev->fw_next=ftmp;
-	else
-        	*chainptr=ftmp;
-	WRITE_UNLOCK(&ip_fw_lock);
-	return(0);
-}
-
-static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl)
-{
-	struct ip_fw 	*ftmp,*ltmp;
-	unsigned short	tport1,tport2,tmpnum;
-	char		matches,was_found;
-
-	WRITE_LOCK(&ip_fw_lock);
-
-	ftmp=*chainptr;
-
-	if ( ftmp == NULL )
-	{
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl:  chain is empty\n");
-#endif
-		WRITE_UNLOCK(&ip_fw_lock);
-		return( EINVAL );
-	}
-
-	ltmp=NULL;
-	was_found=0;
-
-	while( !was_found && ftmp != NULL )
-	{
-		matches=1;
-		if (ftmp->fw_src.s_addr!=frwl->fw_src.s_addr
-		     ||  ftmp->fw_dst.s_addr!=frwl->fw_dst.s_addr
-		     ||  ftmp->fw_smsk.s_addr!=frwl->fw_smsk.s_addr
-		     ||  ftmp->fw_dmsk.s_addr!=frwl->fw_dmsk.s_addr
-		     ||  ftmp->fw_via.s_addr!=frwl->fw_via.s_addr
-		     ||  ftmp->fw_flg!=frwl->fw_flg)
-        		matches=0;
-
-		tport1=ftmp->fw_nsp+ftmp->fw_ndp;
-		tport2=frwl->fw_nsp+frwl->fw_ndp;
-		if (tport1!=tport2)
-		        matches=0;
-		else if (tport1!=0)
-		{
-			for (tmpnum=0;tmpnum < tport1 && tmpnum < IP_FW_MAX_PORTS;tmpnum++)
-        		if (ftmp->fw_pts[tmpnum]!=frwl->fw_pts[tmpnum])
-				matches=0;
-		}
-		if (strncmp(ftmp->fw_vianame, frwl->fw_vianame, IFNAMSIZ))
-		        matches=0;
-		if(matches)
-		{
-			was_found=1;
-			if (ftmp->fw_viadev
-			    && ftmp->fw_viadev != (struct net_device *)-1)
-				dev_put(ftmp->fw_viadev);
-			if (ltmp)
-			{
-				ltmp->fw_next=ftmp->fw_next;
-				kfree(ftmp);
-				ftmp=ltmp->fw_next;
-        		}
-      			else
-      			{
-      				*chainptr=ftmp->fw_next;
-	 			kfree(ftmp);
-				ftmp=*chainptr;
-			}
-		}
-		else
-		{
-			ltmp = ftmp;
-			ftmp = ftmp->fw_next;
-		 }
-	}
-	WRITE_UNLOCK(&ip_fw_lock);
-	if (was_found) {
-		/* We will block in cleanup's unregister sockopt if unloaded,
-		   so this is safe. */
-		module_put(THIS_MODULE);
-		return 0;
-	} else
-		return(EINVAL);
-}
-
-#endif  /* CONFIG_IP_ACCT || CONFIG_IP_FIREWALL */
-
-struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
-{
-
-	if ( len != sizeof(struct ip_fw) )
-	{
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl: len=%d, want %d\n",len, sizeof(struct ip_fw));
-#endif
-		return(NULL);
-	}
-
-	if ( (frwl->fw_flg & ~IP_FW_F_MASK) != 0 )
-	{
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl: undefined flag bits set (flags=%x)\n",
-			frwl->fw_flg);
-#endif
-		return(NULL);
-	}
-
-#ifndef CONFIG_IP_TRANSPARENT_PROXY
-	if (frwl->fw_flg & IP_FW_F_REDIR) {
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl: unsupported flag IP_FW_F_REDIR\n");
-#endif
-		return(NULL);
-	}
-#endif
-
-#ifndef CONFIG_IP_MASQUERADE
-	if (frwl->fw_flg & IP_FW_F_MASQ) {
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl: unsupported flag IP_FW_F_MASQ\n");
-#endif
-		return(NULL);
-	}
-#endif
-
-	if ( (frwl->fw_flg & IP_FW_F_SRNG) && frwl->fw_nsp < 2 )
-	{
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl: src range set but fw_nsp=%d\n",
-			frwl->fw_nsp);
-#endif
-		return(NULL);
-	}
-
-	if ( (frwl->fw_flg & IP_FW_F_DRNG) && frwl->fw_ndp < 2 )
-	{
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl: dst range set but fw_ndp=%d\n",
-			frwl->fw_ndp);
-#endif
-		return(NULL);
-	}
-
-	if ( frwl->fw_nsp + frwl->fw_ndp > (frwl->fw_flg & IP_FW_F_REDIR ? IP_FW_MAX_PORTS - 1 : IP_FW_MAX_PORTS) )
-	{
-#ifdef DEBUG_IP_FIREWALL
-		printk("ip_fw_ctl: too many ports (%d+%d)\n",
-			frwl->fw_nsp,frwl->fw_ndp);
-#endif
-		return(NULL);
-	}
-
-	return frwl;
-}
-
-
-
-
-#ifdef CONFIG_IP_ACCT
-
-int ip_acct_ctl(int stage, void *m, int len)
-{
-	if ( stage == IP_ACCT_FLUSH )
-	{
-		free_fw_chain(&ip_acct_chain);
-		return(0);
-	}
-	if ( stage == IP_ACCT_ZERO )
-	{
-		zero_fw_chain(ip_acct_chain);
-		return(0);
-	}
-	if ( stage == IP_ACCT_INSERT || stage == IP_ACCT_APPEND ||
-	  				stage == IP_ACCT_DELETE )
-	{
-		struct ip_fw *frwl;
-
-		if (!(frwl=check_ipfw_struct(m,len)))
-			return (EINVAL);
-
-		switch (stage)
-		{
-			case IP_ACCT_INSERT:
-				return( insert_in_chain(&ip_acct_chain,frwl,len));
-			case IP_ACCT_APPEND:
-				return( append_to_chain(&ip_acct_chain,frwl,len));
-		    	case IP_ACCT_DELETE:
-				return( del_from_chain(&ip_acct_chain,frwl));
-			default:
-				/*
- 				 *	Should be panic but... (Why ??? - AC)
-				 */
-#ifdef DEBUG_IP_FIREWALL
-				printk("ip_acct_ctl:  unknown request %d\n",stage);
-#endif
-				return(EINVAL);
-		}
-	}
-#ifdef DEBUG_IP_FIREWALL
-	printk("ip_acct_ctl:  unknown request %d\n",stage);
-#endif
-	return(EINVAL);
-}
-#endif
-
-#ifdef CONFIG_IP_FIREWALL
-int ip_fw_ctl(int stage, void *m, int len)
-{
-	int cmd, fwtype;
-
-	cmd = stage & IP_FW_COMMAND;
-	fwtype = (stage & IP_FW_TYPE) >> IP_FW_SHIFT;
-
-	if ( cmd == IP_FW_FLUSH )
-	{
-		free_fw_chain(chains[fwtype]);
-		return(0);
-	}
-
-	if ( cmd == IP_FW_ZERO )
-	{
-		zero_fw_chain(*chains[fwtype]);
-		return(0);
-	}
-
-	if ( cmd == IP_FW_POLICY )
-	{
-		int *tmp_policy_ptr;
-		tmp_policy_ptr=(int *)m;
-		*policies[fwtype] = *tmp_policy_ptr;
-		return 0;
-	}
-
-	if ( cmd == IP_FW_CHECK )
-	{
-		struct sk_buff *tmp_skb;
-		struct net_device *viadev;
-		struct ip_fwpkt *ipfwp;
-		struct iphdr *ip;
-		int hdrlen, ret;
-
-		hdrlen = sizeof(struct ip_fwpkt) -
-			sizeof(struct in_addr) -
-			IFNAMSIZ;
-
-		if ( len != sizeof(struct ip_fwpkt) )
-		{
-#ifdef DEBUG_IP_FIREWALL
-			printk("ip_fw_ctl: length=%d, expected %d\n",
-				len, sizeof(struct ip_fwpkt));
-#endif
-			return( EINVAL );
-		}
-
-	 	ipfwp = (struct ip_fwpkt *)m;
-	 	ip = &(ipfwp->fwp_iph);
-
-		if ( !(viadev = dev_get_by_name(ipfwp->fwp_vianame)) ) {
-#ifdef DEBUG_IP_FIREWALL
-			printk("ip_fw_ctl: invalid device \"%s\"\n", ipfwp->fwp_vianame);
-#endif
-			return(EINVAL);
-		} else if ( ip->ihl != sizeof(struct iphdr) / sizeof(int)) {
-#ifdef DEBUG_IP_FIREWALL
-			printk("ip_fw_ctl: ip->ihl=%d, want %d\n",ip->ihl,
-					sizeof(struct iphdr)/sizeof(int));
-#endif
-			dev_put(viadev);
-			return(EINVAL);
-		}
-
-		/* Fix this one up by hand, who knows how many
-		 * tools will break if we start to barf on this.
-		 */
-		if (ntohs(ip->tot_len) > hdrlen)
-			ip->tot_len = htons(hdrlen);
-
-		if ((tmp_skb = alloc_skb(hdrlen, GFP_ATOMIC)) == NULL) {
-#ifdef DEBUG_IP_FIREWALL
-			printk("ip_fw_ctl: tmp_skb alloc failure\n");
-#endif
-			dev_put(viadev);
-			return(EFAULT);
-		}
-		skb_reserve(tmp_skb, hdrlen);
-		skb_push(tmp_skb, hdrlen);
-		memcpy(tmp_skb->data, ip, hdrlen);
-
-		ret = ip_fw_chk(&tmp_skb, viadev, NULL, *chains[fwtype],
-				*policies[fwtype], IP_FW_MODE_CHK);
-
-		kfree_skb(tmp_skb);
-		dev_put(viadev);
-
-		switch (ret) {
-			case FW_ACCEPT:
-				return(0);
-	    		case FW_REDIRECT:
-				return(ECONNABORTED);
-	    		case FW_MASQUERADE:
-				return(ECONNRESET);
-	    		case FW_REJECT:
-				return(ECONNREFUSED);
-			default: /* FW_BLOCK */
-				return(ETIMEDOUT);
-		}
-	}
-
-	if ( cmd == IP_FW_MASQ_TIMEOUTS )
-		return ip_fw_masq_timeouts(m, len);
-
-/*
- *	Here we really working hard-adding new elements
- *	to blocking/forwarding chains or deleting 'em
- */
-
-	if ( cmd == IP_FW_INSERT || cmd == IP_FW_APPEND || cmd == IP_FW_DELETE )
-	{
-		struct ip_fw *frwl;
-		int fwtype;
-
-		frwl=check_ipfw_struct(m,len);
-		if (frwl==NULL)
-			return (EINVAL);
-		fwtype = (stage & IP_FW_TYPE) >> IP_FW_SHIFT;
-
-		switch (cmd)
-		{
-			case IP_FW_INSERT:
-				return(insert_in_chain(chains[fwtype],frwl,len));
-			case IP_FW_APPEND:
-				return(append_to_chain(chains[fwtype],frwl,len));
-			case IP_FW_DELETE:
-				return(del_from_chain(chains[fwtype],frwl));
-			default:
-			/*
-	 		 *	Should be panic but... (Why are BSD people panic obsessed ??)
-			 */
-#ifdef DEBUG_IP_FIREWALL
-				printk("ip_fw_ctl:  unknown request %d\n",stage);
-#endif
-				return(EINVAL);
-		}
-	}
-
-#ifdef DEBUG_IP_FIREWALL
-	printk("ip_fw_ctl:  unknown request %d\n",stage);
-#endif
-	return(ENOPROTOOPT);
-}
-#endif /* CONFIG_IP_FIREWALL */
-
-#if defined(CONFIG_IP_FIREWALL) || defined(CONFIG_IP_ACCT)
-static int ip_chain_procinfo(int stage, char *buffer, char **start,
-			     off_t offset, int length)
-{
-	off_t pos=0, begin=0;
-	struct ip_fw *i;
-	int len, p;
-	int last_len = 0;
-
-
-	switch(stage)
-	{
-#ifdef CONFIG_IP_FIREWALL
-		case IP_FW_IN:
-			i = ip_fw_in_chain;
-			len=sprintf(buffer, "IP firewall input rules, default %d\n",
-				ip_fw_in_policy);
-			break;
-		case IP_FW_OUT:
-			i = ip_fw_out_chain;
-			len=sprintf(buffer, "IP firewall output rules, default %d\n",
-				ip_fw_out_policy);
-			break;
-		case IP_FW_FWD:
-			i = ip_fw_fwd_chain;
-			len=sprintf(buffer, "IP firewall forward rules, default %d\n",
-				ip_fw_fwd_policy);
-			break;
-#endif
-#ifdef CONFIG_IP_ACCT
-		case IP_FW_ACCT:
-			i = ip_acct_chain;
-			len=sprintf(buffer,"IP accounting rules\n");
-			break;
-#endif
-		default:
-			/* this should never be reached, but safety first... */
-			i = NULL;
-			len=0;
-			break;
-	}
-
-	READ_LOCK(&ip_fw_lock);
-
-	while(i!=NULL)
-	{
-		len+=sprintf(buffer+len,"%08X/%08X->%08X/%08X %.16s %08X %X ",
-			ntohl(i->fw_src.s_addr),ntohl(i->fw_smsk.s_addr),
-			ntohl(i->fw_dst.s_addr),ntohl(i->fw_dmsk.s_addr),
-			(i->fw_vianame)[0] ? i->fw_vianame : "-",
-			ntohl(i->fw_via.s_addr), i->fw_flg);
-		/* 10 is enough for a 32 bit box but the counters are 64bit on
-		   the Alpha and Ultrapenguin */
-		len+=sprintf(buffer+len,"%u %u %-20lu %-20lu",
-			i->fw_nsp,i->fw_ndp, i->fw_pcnt,i->fw_bcnt);
-		for (p = 0; p < IP_FW_MAX_PORTS; p++)
-			len+=sprintf(buffer+len, " %u", i->fw_pts[p]);
-		len+=sprintf(buffer+len, " A%02X X%02X", i->fw_tosand, i->fw_tosxor);
-		buffer[len++]='\n';
-		buffer[len]='\0';
-		pos=begin+len;
-		if(pos<offset)
-		{
-			len=0;
-			begin=pos;
-		}
-		else if(pos>offset+length)
-		{
-			len = last_len;
-			break;
-		}
-		last_len = len;
-		i=i->fw_next;
-	}
-	READ_UNLOCK(&ip_fw_lock);
-	*start=buffer+(offset-begin);
-	len-=(offset-begin);
-	if(len>length)
-		len=length;
-	return len;
-}
-#endif
-
-#ifdef CONFIG_IP_ACCT
-static int ip_acct_procinfo(char *buffer, char **start, off_t offset,
-			    int length)
-{
-	return ip_chain_procinfo(IP_FW_ACCT, buffer,start, offset,length);
-}
-#endif
-
-#ifdef CONFIG_IP_FIREWALL
-static int ip_fw_in_procinfo(char *buffer, char **start, off_t offset,
-			      int length)
-{
-	return ip_chain_procinfo(IP_FW_IN, buffer,start,offset,length);
-}
-
-static int ip_fw_out_procinfo(char *buffer, char **start, off_t offset,
-			      int length)
-{
-	return ip_chain_procinfo(IP_FW_OUT, buffer,start,offset,length);
-}
-
-static int ip_fw_fwd_procinfo(char *buffer, char **start, off_t offset,
-			      int length)
-{
-	return ip_chain_procinfo(IP_FW_FWD, buffer,start,offset,length);
-}
-#endif
-
-
-#ifdef CONFIG_IP_FIREWALL
-/*
- *	Interface to the generic firewall chains.
- */
-
-int ipfw_input_check(struct firewall_ops *this, int pf,
-		     struct net_device *dev, void *arg,
-		     struct sk_buff **pskb)
-{
-	return ip_fw_chk(pskb, dev, arg, ip_fw_in_chain, ip_fw_in_policy,
-			 IP_FW_MODE_FW);
-}
-
-int ipfw_output_check(struct firewall_ops *this, int pf,
-		      struct net_device *dev, void *arg,
-		      struct sk_buff **pskb)
-{
-	return ip_fw_chk(pskb, dev, arg, ip_fw_out_chain, ip_fw_out_policy,
-			 IP_FW_MODE_FW);
-}
-
-int ipfw_forward_check(struct firewall_ops *this, int pf,
-		       struct net_device *dev, void *arg,
-		       struct sk_buff **pskb)
-{
-	return ip_fw_chk(pskb, dev, arg, ip_fw_fwd_chain, ip_fw_fwd_policy,
-			 IP_FW_MODE_FW);
-}
-
-#ifdef CONFIG_IP_ACCT
-int ipfw_acct_in(struct firewall_ops *this, int pf, struct net_device *dev,
-		 void *arg, struct sk_buff **pskb)
-{
-	return ip_fw_chk(pskb,dev,NULL,ip_acct_chain,0,IP_FW_MODE_ACCT_IN);
-}
-
-int ipfw_acct_out(struct firewall_ops *this, int pf, struct net_device *dev,
-		  void *arg, struct sk_buff **pskb)
-{
-	return ip_fw_chk(pskb,dev,NULL,ip_acct_chain,0,IP_FW_MODE_ACCT_OUT);
-}
-#endif
-
-struct firewall_ops ipfw_ops = {
-	.fw_forward	=	ipfw_forward_check,
-	.fw_input	=	ipfw_input_check,
-	.fw_output	=	ipfw_output_check,
-#ifdef CONFIG_IP_ACCT
-	.fw_acct_in	=	ipfw_acct_in,
-	.fw_acct_out	=	ipfw_acct_out,
-#endif
-};
-
-#endif
-
-#if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
-
-int ipfw_device_event(struct notifier_block *this, unsigned long event, void *ptr)
-{
-	struct net_device *dev=ptr;
-	char *devname = dev->name;
-	struct ip_fw *fw;
-	int chn;
-
-	WRITE_LOCK(&ip_fw_lock);
-
-	if (event == NETDEV_UP) {
-		for (chn = 0; chn < IP_FW_CHAINS; chn++)
-			for (fw = *chains[chn]; fw; fw = fw->fw_next)
-				if ((fw->fw_vianame)[0] && !strncmp(devname,
-					    fw->fw_vianame, IFNAMSIZ)) {
-					dev_hold(dev);
-					fw->fw_viadev = dev;
-				}
-	} else if (event == NETDEV_DOWN) {
-		for (chn = 0; chn < IP_FW_CHAINS; chn++)
-			for (fw = *chains[chn]; fw; fw = fw->fw_next)
-				/* we could compare just the pointers ... */
-				if ((fw->fw_vianame)[0] && !strncmp(devname,
-						    fw->fw_vianame, IFNAMSIZ)){
-					if (fw->fw_viadev
-					    && fw->fw_viadev != (struct net_device *)-1)
-						dev_put(fw->fw_viadev);
-					fw->fw_viadev = (struct net_device*)-1;
-				}
-	}
-
-	WRITE_UNLOCK(&ip_fw_lock);
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block ipfw_dev_notifier = {
-	.notifier_call	=	ipfw_device_event,
-};
-
-#endif
-
-int ipfw_init_or_cleanup(int init)
-{
-	int ret = 0;
-
-	if (!init)
-		goto cleanup;
-
-	ret = register_firewall(PF_INET, &ipfw_ops);
-	if (ret < 0)
-		goto cleanup_nothing;
-
-#ifdef CONFIG_IP_ACCT
-	proc_net_create("ip_acct", S_IFREG | S_IRUGO | S_IWUSR, ip_acct_procinfo);
-#endif
-	proc_net_create("ip_input", S_IFREG | S_IRUGO | S_IWUSR, ip_fw_in_procinfo);
-	proc_net_create("ip_output", S_IFREG | S_IRUGO | S_IWUSR, ip_fw_out_procinfo);
-	proc_net_create("ip_forward", S_IFREG | S_IRUGO | S_IWUSR, ip_fw_fwd_procinfo);
-
-	/* Register for device up/down reports */
-	register_netdevice_notifier(&ipfw_dev_notifier);
-
-#ifdef CONFIG_IP_FIREWALL_NETLINK
-	ipfwsk = netlink_kernel_create(NETLINK_FIREWALL, NULL);
-#endif
-	return ret;
-
- cleanup:
-#ifdef CONFIG_IP_FIREWALL_NETLINK
-	sock_release(ipfwsk->sk_socket);
-#endif
-	unregister_netdevice_notifier(&ipfw_dev_notifier);
-
-#ifdef CONFIG_IP_ACCT
-	proc_net_remove("ip_acct");
-#endif
-	proc_net_remove("ip_input");
-	proc_net_remove("ip_output");
-	proc_net_remove("ip_forward");
-
-	free_fw_chain(chains[IP_FW_FWD]);
-	free_fw_chain(chains[IP_FW_IN]);
-	free_fw_chain(chains[IP_FW_OUT]);
-	free_fw_chain(chains[IP_FW_ACCT]);
-
-	unregister_firewall(PF_INET, &ipfw_ops);
-
- cleanup_nothing:
-	return ret;
-}
Index: linux-2.6.10-rc3-bk6-Netfilter/net/ipv4/netfilter/Kconfig
===================================================================
--- linux-2.6.10-rc3-bk6-Netfilter.orig/net/ipv4/netfilter/Kconfig	2004-12-13 12:03:12.012123760 +1100
+++ linux-2.6.10-rc3-bk6-Netfilter/net/ipv4/netfilter/Kconfig	2004-12-13 12:03:15.496594040 +1100
@@ -458,7 +458,7 @@
 
 config IP_NF_NAT_NEEDED
 	bool
-	depends on IP_NF_CONNTRACK!=y && IP_NF_IPTABLES!=y && (IP_NF_COMPAT_IPCHAINS!=y && IP_NF_COMPAT_IPFWADM || IP_NF_COMPAT_IPCHAINS) || IP_NF_IPTABLES && IP_NF_CONNTRACK && IP_NF_NAT
+	depends on IP_NF_NAT != n
 	default y
 
 config IP_NF_TARGET_MASQUERADE
@@ -693,30 +693,5 @@
 	  Allows altering the ARP packet payload: source and destination
 	  hardware and network addresses.
 
-# Backwards compatibility modules: only if you don't build in the others.
-config IP_NF_COMPAT_IPCHAINS
-	tristate "ipchains (2.2-style) support"
-	depends on IP_NF_CONNTRACK!=y && IP_NF_IPTABLES!=y
-	help
-	  This option places ipchains (with masquerading and redirection
-	  support) back into the kernel, using the new netfilter
-	  infrastructure.  It is not recommended for new installations (see
-	  `Packet filtering').  With this enabled, you should be able to use
-	  the ipchains tool exactly as in 2.2 kernels.
-
-	  To compile it as a module, choose M here.  If unsure, say N.
-
-config IP_NF_COMPAT_IPFWADM
-	tristate "ipfwadm (2.0-style) support"
-	depends on IP_NF_CONNTRACK!=y && IP_NF_IPTABLES!=y && IP_NF_COMPAT_IPCHAINS!=y
-	help
-	  This option places ipfwadm (with masquerading and redirection
-	  support) back into the kernel, using the new netfilter
-	  infrastructure.  It is not recommended for new installations (see
-	  `Packet filtering').  With this enabled, you should be able to use
-	  the ipfwadm tool exactly as in 2.0 kernels.
-
-	  To compile it as a module, choose M here.  If unsure, say N.
-
 endmenu
 
Index: linux-2.6.10-rc3-bk6-Netfilter/net/ipv4/netfilter/ip_fw_compat.h
===================================================================
--- linux-2.6.10-rc3-bk6-Netfilter.orig/net/ipv4/netfilter/ip_fw_compat.h	2004-12-13 12:02:08.019852064 +1100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,28 +0,0 @@
-#ifndef _LINUX_IP_FW_COMPAT_H
-#define _LINUX_IP_FW_COMPAT_H
-
-/* From ip_fw_compat_redir.c */
-extern unsigned int
-do_redirect(struct sk_buff *skb,
-	    const struct net_device *dev,
-	    u_int16_t redirpt);
-
-extern void
-check_for_redirect(struct sk_buff *skb);
-
-extern void
-check_for_unredirect(struct sk_buff *skb);
-
-/* From ip_fw_compat_masq.c */
-extern unsigned int
-do_masquerade(struct sk_buff **pskb, const struct net_device *dev);
-
-extern void check_for_masq_error(struct sk_buff **pskb);
-
-extern unsigned int
-check_for_demasq(struct sk_buff **pskb);
-
-extern int __init masq_init(void);
-extern void masq_cleanup(void);
-
-#endif /* _LINUX_IP_FW_COMPAT_H */
Index: linux-2.6.10-rc3-bk6-Netfilter/net/ipv4/netfilter/ip_fw_compat_masq.c
===================================================================
--- linux-2.6.10-rc3-bk6-Netfilter.orig/net/ipv4/netfilter/ip_fw_compat_masq.c	2004-12-13 12:02:08.018852216 +1100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,342 +0,0 @@
-/* Masquerading compatibility layer.
-
-   Note that there are no restrictions on other programs binding to
-   ports 61000:65095 (in 2.0 and 2.2 they get EADDRINUSE).  Just DON'T
-   DO IT.
- */
-
-/* (C) 1999-2001 Paul `Rusty' Russell
- * (C) 2002-2004 Netfilter Core Team <coreteam at netfilter.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/skbuff.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/icmp.h>
-#include <linux/udp.h>
-#include <linux/netfilter_ipv4.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/proc_fs.h>
-#include <linux/module.h>
-#include <net/route.h>
-#include <net/ip.h>
-
-#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_conntrack_lock)
-#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_conntrack_lock)
-
-#include <linux/netfilter_ipv4/ip_conntrack.h>
-#include <linux/netfilter_ipv4/ip_conntrack_core.h>
-#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
-#include <linux/netfilter_ipv4/ip_nat.h>
-#include <linux/netfilter_ipv4/ip_nat_core.h>
-#include <linux/netfilter_ipv4/listhelp.h>
-#include "ip_fw_compat.h"
-
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
-unsigned int
-do_masquerade(struct sk_buff **pskb, const struct net_device *dev)
-{
-	struct ip_nat_info *info;
-	enum ip_conntrack_info ctinfo;
-	struct ip_conntrack *ct;
-	unsigned int ret;
-
-	/* Sorry, only ICMP, TCP and UDP. */
-	if ((*pskb)->nh.iph->protocol != IPPROTO_ICMP
-	    && (*pskb)->nh.iph->protocol != IPPROTO_TCP
-	    && (*pskb)->nh.iph->protocol != IPPROTO_UDP)
-		return NF_DROP;
-
-	/* Feed it to connection tracking; in fact we're in NF_IP_FORWARD,
-           but connection tracking doesn't expect that */
-	ret = ip_conntrack_in(NF_IP_POST_ROUTING, pskb, dev, NULL, NULL);
-	if (ret != NF_ACCEPT) {
-		DEBUGP("ip_conntrack_in returned %u.\n", ret);
-		return ret;
-	}
-
-	ct = ip_conntrack_get(*pskb, &ctinfo);
-
-	if (!ct) {
-		DEBUGP("ip_conntrack_in set to invalid conntrack.\n");
-		return NF_DROP;
-	}
-
-	info = &ct->nat.info;
-
-	WRITE_LOCK(&ip_nat_lock);
-	/* Setup the masquerade, if not already */
-	if (!info->initialized) {
-		u_int32_t newsrc;
-		struct flowi fl = { .nl_u = { .ip4_u = { .daddr = (*pskb)->nh.iph->daddr } } };
-		struct rtable *rt;
-		struct ip_nat_multi_range range;
-
-		/* Pass 0 instead of saddr, since it's going to be changed
-		   anyway. */
-		if (ip_route_output_key(&rt, &fl) != 0) {
-			DEBUGP("ipnat_rule_masquerade: Can't reroute.\n");
-			return NF_DROP;
-		}
-		newsrc = inet_select_addr(rt->u.dst.dev, rt->rt_gateway,
-					  RT_SCOPE_UNIVERSE);
-		ip_rt_put(rt);
-		range = ((struct ip_nat_multi_range)
-			 { 1,
-			   {{IP_NAT_RANGE_MAP_IPS|IP_NAT_RANGE_PROTO_SPECIFIED,
-			     newsrc, newsrc,
-			     { htons(61000) }, { htons(65095) } } } });
-
-		ret = ip_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
-		if (ret != NF_ACCEPT) {
-			WRITE_UNLOCK(&ip_nat_lock);
-			return ret;
-		}
-	} else
-		DEBUGP("Masquerading already done on this conn.\n");
-	WRITE_UNLOCK(&ip_nat_lock);
-
-	return do_bindings(ct, ctinfo, info, NF_IP_POST_ROUTING, pskb);
-}
-
-void
-check_for_masq_error(struct sk_buff **pskb)
-{
-	enum ip_conntrack_info ctinfo;
-	struct ip_conntrack *ct;
-
-	ct = ip_conntrack_get(*pskb, &ctinfo);
-	/* Wouldn't be here if not tracked already => masq'ed ICMP
-           ping or error related to masq'd connection */
-	IP_NF_ASSERT(ct);
-	if (ctinfo == IP_CT_RELATED) {
-		icmp_reply_translation(pskb, ct, NF_IP_PRE_ROUTING,
-				       CTINFO2DIR(ctinfo));
-		icmp_reply_translation(pskb, ct, NF_IP_POST_ROUTING,
-				       CTINFO2DIR(ctinfo));
-	}
-}
-
-unsigned int
-check_for_demasq(struct sk_buff **pskb)
-{
-	struct ip_conntrack_tuple tuple;
-	struct ip_conntrack_protocol *protocol;
-	struct ip_conntrack_tuple_hash *h;
-	enum ip_conntrack_info ctinfo;
-	struct ip_conntrack *ct;
-	int ret;
-
-	protocol = ip_ct_find_proto((*pskb)->nh.iph->protocol);
-
-	/* We don't feed packets to conntrack system unless we know
-           they're part of an connection already established by an
-           explicit masq command. */
-	switch ((*pskb)->nh.iph->protocol) {
-	case IPPROTO_ICMP:
-		/* ICMP errors. */
-		protocol->error(*pskb, &ctinfo, NF_IP_PRE_ROUTING);
-		ct = (struct ip_conntrack *)(*pskb)->nfct;
-		if (ct) {
-			/* We only do SNAT in the compatibility layer.
-			   So we can manipulate ICMP errors from
-			   server here (== DNAT).  Do SNAT icmp manips
-			   in POST_ROUTING handling. */
-			if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
-				icmp_reply_translation(pskb, ct,
-						       NF_IP_PRE_ROUTING,
-						       CTINFO2DIR(ctinfo));
-				icmp_reply_translation(pskb, ct,
-						       NF_IP_POST_ROUTING,
-						       CTINFO2DIR(ctinfo));
-			}
-			return NF_ACCEPT;
-		}
-		/* Fall thru... */
-	case IPPROTO_TCP:
-	case IPPROTO_UDP:
-		IP_NF_ASSERT(((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) == 0);
-
-		if (!ip_ct_get_tuple((*pskb)->nh.iph, *pskb,
-				     (*pskb)->nh.iph->ihl*4, &tuple, protocol)) {
-			if (net_ratelimit())
-				printk("ip_fw_compat_masq: Can't get tuple\n");
-			return NF_ACCEPT;
-		}
-		break;
-
-	default:
-		/* Not ours... */
-		return NF_ACCEPT;
-	}
-	h = ip_conntrack_find_get(&tuple, NULL);
-
-	/* MUST be found, and MUST be reply. */
-	if (h && DIRECTION(h) == 1) {
-		ret = ip_conntrack_in(NF_IP_PRE_ROUTING, pskb,
-				      NULL, NULL, NULL);
-
-		/* Put back the reference gained from find_get */
-		nf_conntrack_put(&h->ctrack->ct_general);
-		if (ret == NF_ACCEPT) {
-			struct ip_conntrack *ct;
-			ct = ip_conntrack_get(*pskb, &ctinfo);
-
-			if (ct) {
-				struct ip_nat_info *info = &ct->nat.info;
-
-				do_bindings(ct, ctinfo, info,
-					    NF_IP_PRE_ROUTING,
-					    pskb);
-			} else
-				if (net_ratelimit()) 
-					printk("ip_fw_compat_masq: conntrack"
-					       " didn't like\n");
-		}
-	} else {
-		if (h)
-			/* Put back the reference gained from find_get */
-			nf_conntrack_put(&h->ctrack->ct_general);
-		ret = NF_ACCEPT;
-	}
-
-	return ret;
-}
-
-int ip_fw_masq_timeouts(void *user, int len)
-{
-	printk("Sorry: masquerading timeouts set 5DAYS/2MINS/60SECS\n");
-	return 0;
-}
-
-static const char *masq_proto_name(u_int16_t protonum)
-{
-	switch (protonum) {
-	case IPPROTO_TCP: return "TCP";
-	case IPPROTO_UDP: return "UDP";
-	case IPPROTO_ICMP: return "ICMP";
-	default: return "MORE-CAFFEINE-FOR-RUSTY";
-	}
-}
-
-static unsigned int
-print_masq(char *buffer, const struct ip_conntrack *conntrack)
-{
-	char temp[129];
-
-	/* This is for backwards compatibility, but ick!.
-	   We should never export jiffies to userspace.
-	*/
-	sprintf(temp,"%s %08X:%04X %08X:%04X %04X %08X %6d %6d %7lu",
-		masq_proto_name(conntrack->tuplehash[0].tuple.dst.protonum),
-		ntohl(conntrack->tuplehash[0].tuple.src.ip),
-		ntohs(conntrack->tuplehash[0].tuple.src.u.all),
-		ntohl(conntrack->tuplehash[0].tuple.dst.ip),
-		ntohs(conntrack->tuplehash[0].tuple.dst.u.all),
-		ntohs(conntrack->tuplehash[1].tuple.dst.u.all),
-		/* Sorry, no init_seq, delta or previous_delta (yet). */
-		0, 0, 0,
-		conntrack->timeout.expires - jiffies);
-
-	return sprintf(buffer, "%-127s\n", temp);
-}
-
-/* Returns true when finished. */
-static int
-masq_iterate(const struct ip_conntrack_tuple_hash *hash,
-	     char *buffer, off_t offset, off_t *upto,
-	     unsigned int *len, unsigned int maxlen)
-{
-	unsigned int newlen;
-
-	IP_NF_ASSERT(hash->ctrack);
-
-	/* Only count originals */
-	if (DIRECTION(hash))
-		return 0;
-
-	if ((*upto)++ < offset)
-		return 0;
-
-	newlen = print_masq(buffer + *len, hash->ctrack);
-	if (*len + newlen > maxlen)
-		return 1;
-	else *len += newlen;
-
-	return 0;
-}
-
-/* Everything in the hash is masqueraded. */
-static int
-masq_procinfo(char *buffer, char **start, off_t offset, int length)
-{
-	unsigned int i;
-	int len = 0;
-	off_t upto = 1;
-
-	/* Header: first record */
-	if (offset == 0) {
-		char temp[128];
-
-		sprintf(temp,
-			"Prc FromIP   FPrt ToIP     TPrt Masq Init-seq  Delta PDelta Expires (free=0,0,0)");
-		len = sprintf(buffer, "%-127s\n", temp);
-		offset = 1;
-	}
-
-	READ_LOCK(&ip_conntrack_lock);
-	/* Traverse hash; print originals then reply. */
-	for (i = 0; i < ip_conntrack_htable_size; i++) {
-		if (LIST_FIND(&ip_conntrack_hash[i], masq_iterate,
-			      struct ip_conntrack_tuple_hash *,
-			      buffer, offset, &upto, &len, length))
-			break;
-	}
-	READ_UNLOCK(&ip_conntrack_lock);
-
-	/* `start' hack - see fs/proc/generic.c line ~165 */
-	*start = (char *)((unsigned int)upto - offset);
-	return len;
-}
-
-int __init masq_init(void)
-{
-	int ret;
-	struct proc_dir_entry *proc;
-
-	ret = ip_conntrack_init();
-	if (ret == 0) {
-		ret = ip_nat_init();
-		if (ret == 0) {
-			proc = proc_net_create("ip_masquerade",
-					       0, masq_procinfo);
-			if (proc)
-				proc->owner = THIS_MODULE;
-			else {
-				ip_nat_cleanup();
-				ip_conntrack_cleanup();
-				ret = -ENOMEM;
-			}
-		} else
-			ip_conntrack_cleanup();
-	}
-
-	return ret;
-}
-
-void masq_cleanup(void)
-{
-	ip_nat_cleanup();
-	ip_conntrack_cleanup();
-	proc_net_remove("ip_masquerade");
-}

-- 
A bad analogy is like a leaky screwdriver -- Richard Braakman




More information about the netfilter-devel mailing list