Thanks Harald, I have applied both your patches and I
will push them to Marcelo and Linus.

I am also pushing the following change which is Rusty's
ARP netfilter hooks with minor modifications by me.

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#                  ChangeSet    1.184   -> 1.186  
#             net/ipv4/arp.c    1.6     -> 1.8    
#                      (new)            -> 1.1     include/linux/netfilter_arp.h
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/03/14      [EMAIL PROTECTED]    1.185
# Allow ARP packets to be seen by netfilter.
# --------------------------------------------
# 02/03/14      [EMAIL PROTECTED]    1.186
# Include linux/netfilter_arp.h
# --------------------------------------------
#
diff -Nru a/include/linux/netfilter_arp.h b/include/linux/netfilter_arp.h
--- /dev/null   Wed Dec 31 16:00:00 1969
+++ b/include/linux/netfilter_arp.h     Thu Mar 14 16:49:51 2002
@@ -0,0 +1,19 @@
+#ifndef __LINUX_ARP_NETFILTER_H
+#define __LINUX_ARP_NETFILTER_H
+
+/* ARP-specific defines for netfilter.
+ * (C)2002 Rusty Russell IBM -- This code is GPL.
+ */
+
+#include <linux/config.h>
+#include <linux/netfilter.h>
+
+/* There is no PF_ARP. */
+#define NF_ARP         0
+
+/* ARP Hooks */
+/* Coming in. */
+#define NF_ARP_IN      0
+#define NF_ARP_OUT     1
+
+#endif /* __LINUX_ARP_NETFILTER_H */
diff -Nru a/net/ipv4/arp.c b/net/ipv4/arp.c
--- a/net/ipv4/arp.c    Thu Mar 14 16:49:51 2002
+++ b/net/ipv4/arp.c    Thu Mar 14 16:49:51 2002
@@ -112,7 +112,7 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-
+#include <linux/netfilter_arp.h>
 
 /*
  *     Interface to generic neighbour cache.
@@ -561,7 +561,8 @@
        arp_ptr+=dev->addr_len;
        memcpy(arp_ptr, &dest_ip, 4);
 
-       dev_queue_xmit(skb);
+       /* Send it off, maybe filter it using firewalling first.  */
+       NF_HOOK(NF_ARP, NF_ARP_OUT, skb, NULL, dev, dev_queue_xmit);
        return;
 
 out:
@@ -574,45 +575,31 @@
 }
 
 /*
- *     Receive an arp request by the device layer.
+ *     Process an arp request.
  */
 
-int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
+int arp_process(struct sk_buff *skb)
 {
-       struct arphdr *arp = skb->nh.arph;
-       unsigned char *arp_ptr= (unsigned char *)(arp+1);
+       struct net_device *dev = skb->dev;
+       struct in_device *in_dev = in_dev_get(dev);
+       struct arphdr *arp;
+       unsigned char *arp_ptr;
        struct rtable *rt;
        unsigned char *sha, *tha;
        u32 sip, tip;
        u16 dev_type = dev->type;
        int addr_type;
-       struct in_device *in_dev = in_dev_get(dev);
        struct neighbour *n;
 
-/*
- *     The hardware length of the packet should match the hardware length
- *     of the device.  Similarly, the hardware types should match.  The
- *     device should be ARP-able.  Also, if pln is not 4, then the lookup
- *     is not from an IP number.  We can't currently handle this, so toss
- *     it. 
- */  
-       if (in_dev == NULL ||
-           arp->ar_hln != dev->addr_len    || 
-           dev->flags & IFF_NOARP ||
-           skb->pkt_type == PACKET_OTHERHOST ||
-           skb->pkt_type == PACKET_LOOPBACK ||
-           arp->ar_pln != 4)
+       /* arp_rcv below verifies the ARP header, verifies the device
+        * is ARP'able, and linearizes the SKB (if needed).
+        */
+
+       if (in_dev == NULL)
                goto out;
 
-       if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
-               goto out_of_mem;
-
-       if (skb_is_nonlinear(skb)) {
-               if (skb_linearize(skb, GFP_ATOMIC) != 0)
-                       goto freeskb;
-               arp = skb->nh.arph;
-               arp_ptr= (unsigned char *)(arp+1);
-       }
+       arp = skb->nh.arph;
+       arp_ptr= (unsigned char *)(arp+1);
 
        switch (dev_type) {
        default:        
@@ -827,13 +814,41 @@
 out:
        if (in_dev)
                in_dev_put(in_dev);
-freeskb:
        kfree_skb(skb);
-out_of_mem:
        return 0;
 }
 
 
+/*
+ *     Receive an arp request from the device layer.
+ */
+
+int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
+{
+       struct arphdr *arp = skb->nh.arph;
+
+       if (arp->ar_hln != dev->addr_len ||
+           dev->flags & IFF_NOARP ||
+           skb->pkt_type == PACKET_OTHERHOST ||
+           skb->pkt_type == PACKET_LOOPBACK ||
+           arp->ar_pln != 4)
+               goto freeskb;
+
+       if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
+               goto out_of_mem;
+
+       if (skb_is_nonlinear(skb)) {
+               if (skb_linearize(skb, GFP_ATOMIC) != 0)
+                       goto freeskb;
+       }
+
+       return NF_HOOK(NF_ARP, NF_ARP_IN, skb, dev, NULL, arp_process);
+
+freeskb:
+       kfree_skb(skb);
+out_of_mem:
+       return 0;
+}
 
 /*
  *     User level interface (ioctl, /proc)

Reply via email to