diff -Nru linux-2.4.20/Documentation/Configure.help linux-2.4.20-pom2patch/Documentation/Configure.help
--- linux-2.4.20/Documentation/Configure.help	2003-05-02 12:55:07.000000000 -0500
+++ linux-2.4.20-pom2patch/Documentation/Configure.help	2003-05-02 12:55:10.000000000 -0500
@@ -2704,6 +2704,15 @@
   Documentation/modules.txt.  If unsure, say `N'.
 
 
+NETLINK target support
+CONFIG_IP_NF_TARGET_NETLINK
+  The NETLINK target allows you to recieve packets in userspace via
+  the kernel firewall netlink socket. Apps such as fwmon
+  (http://firestorm.geek-ware.co.uk) can then recieve and dislpay
+  these packets. This option is basically a re-implementation of the
+  ipchains -o option.
+
+
 REJECT target support
 CONFIG_IP_NF_TARGET_REJECT
   The REJECT target allows a filtering rule to specify that an ICMP
diff -Nru linux-2.4.20/include/linux/netfilter_ipv4/ipt_NETLINK.h linux-2.4.20-pom2patch/include/linux/netfilter_ipv4/ipt_NETLINK.h
--- linux-2.4.20/include/linux/netfilter_ipv4/ipt_NETLINK.h	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.4.20-pom2patch/include/linux/netfilter_ipv4/ipt_NETLINK.h	2003-05-02 12:55:10.000000000 -0500
@@ -0,0 +1,27 @@
+#ifndef _IPT_FWMON_H
+#define _IPT_FWMON_H
+
+/* Bitmask macros */
+#define MASK(x,y) (x & y)
+#define MASK_SET(x,y) x |= y
+#define MASK_UNSET(x,y) x &= ~y
+
+#define USE_MARK	0x00000001
+#define USE_DROP	0x00000002
+#define USE_SIZE	0x00000004
+
+struct ipt_nldata
+{	
+	unsigned int flags;
+	unsigned int mark;
+	unsigned int size;
+};
+
+/* Old header */
+struct netlink_t {
+	unsigned int len;
+	unsigned int mark;
+	char iface[IFNAMSIZ];
+};
+
+#endif /*_IPT_FWMON_H*/
diff -Nru linux-2.4.20/net/ipv4/netfilter/Config.in linux-2.4.20-pom2patch/net/ipv4/netfilter/Config.in
--- linux-2.4.20/net/ipv4/netfilter/Config.in	2003-05-02 12:55:07.000000000 -0500
+++ linux-2.4.20-pom2patch/net/ipv4/netfilter/Config.in	2003-05-02 12:55:10.000000000 -0500
@@ -45,6 +45,7 @@
   dep_tristate '  Packet filtering' CONFIG_IP_NF_FILTER $CONFIG_IP_NF_IPTABLES 
   if [ "$CONFIG_IP_NF_FILTER" != "n" ]; then
     dep_tristate '    REJECT target support' CONFIG_IP_NF_TARGET_REJECT $CONFIG_IP_NF_FILTER
+dep_tristate '    NETLINK target support' CONFIG_IP_NF_TARGET_NETLINK $CONFIG_IP_NF_FILTER
     dep_tristate '    IPV4OPTSSTRIP target support' CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP $CONFIG_IP_NF_FILTER
     if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
       dep_tristate '    MIRROR target support (EXPERIMENTAL)' CONFIG_IP_NF_TARGET_MIRROR $CONFIG_IP_NF_FILTER
diff -Nru linux-2.4.20/net/ipv4/netfilter/Makefile linux-2.4.20-pom2patch/net/ipv4/netfilter/Makefile
--- linux-2.4.20/net/ipv4/netfilter/Makefile	2003-05-02 12:55:07.000000000 -0500
+++ linux-2.4.20-pom2patch/net/ipv4/netfilter/Makefile	2003-05-02 12:55:10.000000000 -0500
@@ -88,6 +88,8 @@
 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
 
+obj-$(CONFIG_IP_NF_TARGET_NETLINK) += ipt_NETLINK.o
+
 obj-$(CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP) += ipt_IPV4OPTSSTRIP.o
 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
diff -Nru linux-2.4.20/net/ipv4/netfilter/ipt_NETLINK.c linux-2.4.20-pom2patch/net/ipv4/netfilter/ipt_NETLINK.c
--- linux-2.4.20/net/ipv4/netfilter/ipt_NETLINK.c	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.4.20-pom2patch/net/ipv4/netfilter/ipt_NETLINK.c	2003-05-02 12:55:10.000000000 -0500
@@ -0,0 +1,119 @@
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/socket.h>
+#include <linux/skbuff.h>
+#include <linux/kernel.h>
+#include <linux/netlink.h>
+#include <linux/netdevice.h>
+#include <linux/mm.h>
+#include <linux/socket.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_NETLINK.h>
+#include <net/sock.h>
+
+MODULE_AUTHOR("Gianni Tedesco <gianni@ecsc.co.uk>");
+MODULE_DESCRIPTION("Provides iptables NETLINK target similar to ipchains -o");
+MODULE_LICENSE("GPL");
+
+#if 0
+#define DEBUGP	printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+static struct sock *ipfwsk;
+
+static unsigned int ipt_netlink_target(struct sk_buff **pskb,
+				    unsigned int hooknum,
+				    const struct net_device *in,
+				    const struct net_device *out,
+				    const void *targinfo, void *userinfo)
+{
+	struct ipt_nldata *nld = (struct ipt_nldata *)targinfo;
+	struct iphdr *ip = (*pskb)->nh.iph;
+	struct sk_buff *outskb;
+	struct netlink_t nlhdr;
+	size_t len=0;
+
+	/* Allocate a socket buffer */
+	if ( MASK(nld->flags, USE_SIZE) )
+		len = nld->size+sizeof(nlhdr);
+	else
+		len = ntohs(ip->tot_len)+sizeof(nlhdr);	
+
+	outskb=alloc_skb(len, GFP_ATOMIC);
+
+	if (outskb) {
+		nlhdr.len=len;
+		
+		if ( MASK(nld->flags, USE_MARK) )
+			nlhdr.mark=(*pskb)->nfmark=nld->mark;
+		else
+			nlhdr.mark=(*pskb)->nfmark;
+		
+		if ( in && in->name ) {
+			strncpy((char *)&nlhdr.iface, in->name, IFNAMSIZ);
+		}else if ( out && out->name ){
+			strncpy((char *)&nlhdr.iface, out->name, IFNAMSIZ);
+		}
+
+		skb_put(outskb, len);
+		memcpy(outskb->data, &nlhdr, sizeof(nlhdr));
+		memcpy((outskb->data)+sizeof(nlhdr), ip, len-sizeof(nlhdr));
+		netlink_broadcast(ipfwsk, outskb, 0, ~0, GFP_ATOMIC);
+	}else{
+		if (net_ratelimit())
+			printk(KERN_WARNING "ipt_NETLINK: packet drop due to netlink failure\n");
+	}
+
+	if ( MASK(nld->flags, USE_DROP) )
+		return NF_DROP;
+
+	return IPT_CONTINUE;
+}
+
+static int ipt_netlink_checkentry(const char *tablename,
+			       const struct ipt_entry *e,
+			       void *targinfo,
+			       unsigned int targinfosize,
+			       unsigned int hookmask)
+{
+	//struct ipt_nldata *nld = (struct ipt_nldata *)targinfo;
+
+	return 1;
+}
+
+static struct ipt_target ipt_netlink_reg = { 
+	{NULL, NULL},
+	"NETLINK",
+	ipt_netlink_target,
+	ipt_netlink_checkentry,
+	NULL,
+	THIS_MODULE
+};
+
+static int __init init(void)
+{
+	DEBUGP("ipt_NETLINK: init module\n");	
+
+	if (ipt_register_target(&ipt_netlink_reg) != 0) {
+		return -EINVAL;
+	}
+
+	if ( !(ipfwsk=netlink_kernel_create(NETLINK_FIREWALL, NULL)) ){
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void __exit fini(void)
+{
+	DEBUGP("ipt_NETLINK: cleanup_module\n");
+	ipt_unregister_target(&ipt_netlink_reg);
+	if(ipfwsk->socket) sock_release(ipfwsk->socket);
+}
+
+module_init(init);
+module_exit(fini);
