diff -urN linux/include/linux/netfilter_ipv4.h devlinux/include/linux/netfilter_ipv4.h
--- linux/include/linux/netfilter_ipv4.h	Tue Jan 30 07:25:54 2001
+++ devlinux/include/linux/netfilter_ipv4.h	Fri Feb  9 14:43:05 2001
@@ -47,7 +47,8 @@
 #define NF_IP_LOCAL_OUT		3
 /* Packets about to hit the wire. */
 #define NF_IP_POST_ROUTING	4
-#define NF_IP_NUMHOOKS		5
+#define NF_IP_PROMISC		6
+#define NF_IP_NUMHOOKS		7
 
 enum nf_ip_hook_priorities {
 	NF_IP_PRI_FIRST = INT_MIN,
diff -urN linux/net/ipv4/ip_input.c devlinux/net/ipv4/ip_input.c
--- linux/net/ipv4/ip_input.c	Mon Dec 11 20:37:04 2000
+++ devlinux/net/ipv4/ip_input.c	Fri Feb  9 14:19:40 2001
@@ -297,6 +297,12 @@
 		       ip_local_deliver_finish);
 }
 
+static inline int ip_prcv_finish(struct sk_buff *skb)
+{
+	kfree_skb(skb);
+	return NET_RX_DROP;
+}
+
 static inline int ip_rcv_finish(struct sk_buff *skb)
 {
 	struct net_device *dev = skb->dev;
@@ -379,13 +385,11 @@
 	/* When the interface is in promisc. mode, drop all the crap
 	 * that it receives, do not try to analyse it.
 	 */
-	if (skb->pkt_type == PACKET_OTHERHOST)
-		goto drop;
-
-	IP_INC_STATS_BH(IpInReceives);
-
-	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
-		goto out;
+	if (skb->pkt_type != PACKET_OTHERHOST) {
+		IP_INC_STATS_BH(IpInReceives);
+		if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
+			goto out;
+	}
 
 	/*
 	 *	RFC1122: 3.1.2.2 MUST silently discard any IP frame that fails the checksum.
@@ -400,7 +404,12 @@
 
 	if (skb->len < sizeof(struct iphdr) || skb->len < (iph->ihl<<2))
 		goto inhdr_error; 
-	if (iph->ihl < 5 || iph->version != 4 || ip_fast_csum((u8 *)iph, iph->ihl) != 0)
+	
+	if (iph->ihl < 5 || iph->version != 4)
+		goto inhdr_error;
+	
+	if ( (skb->pkt_type != PACKET_OTHERHOST) && 
+		(ip_fast_csum((u8 *)iph, iph->ihl) != 0) )
 		goto inhdr_error; 
 
 	{
@@ -415,13 +424,18 @@
 		__skb_trim(skb, len);
 	}
 
-	return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,
+	if ( skb->pkt_type == PACKET_OTHERHOST ) {
+		return NF_HOOK(PF_INET, NF_IP_PROMISC, skb, dev, NULL,
+			ip_prcv_finish);
+	}else{
+		return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,
 		       ip_rcv_finish);
+	}
 
 inhdr_error:
 	IP_INC_STATS_BH(IpInHdrErrors);
-drop:
-        kfree_skb(skb);
+//drop:
+//	kfree_skb(skb);
 out:
         return NET_RX_DROP;
 }
diff -urN linux/net/ipv4/netfilter/iptable_filter.c devlinux/net/ipv4/netfilter/iptable_filter.c
--- linux/net/ipv4/netfilter/iptable_filter.c	Fri May 12 18:45:26 2000
+++ devlinux/net/ipv4/netfilter/iptable_filter.c	Fri Feb  9 14:55:38 2001
@@ -6,7 +6,8 @@
 #include <linux/module.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
 
-#define FILTER_VALID_HOOKS ((1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT))
+#define FILTER_VALID_HOOKS ((1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | \
+(1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_PROMISC) )
 
 /* Standard entry. */
 struct ipt_standard
@@ -30,17 +31,19 @@
 static struct
 {
 	struct ipt_replace repl;
-	struct ipt_standard entries[3];
+	struct ipt_standard entries[4];
 	struct ipt_error term;
 } initial_table __initdata
-= { { "filter", FILTER_VALID_HOOKS, 4,
-      sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),
+= { { "filter", FILTER_VALID_HOOKS, 5,
+      sizeof(struct ipt_standard) * 4 + sizeof(struct ipt_error),
       { [NF_IP_LOCAL_IN] 0,
 	[NF_IP_FORWARD] sizeof(struct ipt_standard),
-	[NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) * 2 },
+	[NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) * 2,
+	[NF_IP_PROMISC] sizeof(struct ipt_standard) * 3},
       { [NF_IP_LOCAL_IN] 0,
 	[NF_IP_FORWARD] sizeof(struct ipt_standard),
-	[NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) * 2 },
+	[NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) * 2,
+	[NF_IP_PROMISC] sizeof(struct ipt_standard) * 3},
       0, NULL, { } },
     {
 	    /* LOCAL_IN */
@@ -66,6 +69,14 @@
 		sizeof(struct ipt_standard),
 		0, { 0, 0 }, { } },
 	      { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
+		-NF_ACCEPT - 1 } },
+	    /* PROMISC */
+	    { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
+		0,
+		sizeof(struct ipt_entry),
+		sizeof(struct ipt_standard),
+		0, { 0, 0 }, { } },
+	      { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
 		-NF_ACCEPT - 1 } }
     },
     /* ERROR */
@@ -118,7 +129,8 @@
 = { { { NULL, NULL }, ipt_hook, PF_INET, NF_IP_LOCAL_IN, NF_IP_PRI_FILTER },
     { { NULL, NULL }, ipt_hook, PF_INET, NF_IP_FORWARD, NF_IP_PRI_FILTER },
     { { NULL, NULL }, ipt_local_out_hook, PF_INET, NF_IP_LOCAL_OUT,
-		NF_IP_PRI_FILTER }
+		NF_IP_PRI_FILTER },
+    { { NULL, NULL }, ipt_hook, PF_INET, NF_IP_PROMISC, NF_IP_PRI_FILTER }
 };
 
 /* Default to forward because I got too much mail already. */
@@ -155,8 +167,14 @@
 	if (ret < 0)
 		goto cleanup_hook1;
 
+	ret = nf_register_hook(&ipt_ops[3]);
+	if (ret < 0)
+		goto cleanup_hook2;
+
 	return ret;
 
+ cleanup_hook2:
+	nf_unregister_hook(&ipt_ops[2]);
  cleanup_hook1:
 	nf_unregister_hook(&ipt_ops[1]);
  cleanup_hook0:
