[PATCH] Netfilter hook for ARP

Brad Chapman kakadu@earthlink.net
Fri, 27 Jul 2001 16:33:55 -0400


Mr. Virtanen,

   Due to a buggy e-mail tool, a portion of your patch was cut off. Did your
patch also include new shared library protocol extensions for iptables 
and/or
ip6tables, so that we can actually manipulate traffic in these hooks? AFAIK,
the current protocol matches won't work for this low-level thing. This looks
mildly interesting, but without the new extensions, no one will be able to
do anything with it.

Brad

Tommi Virtanen wrote:

> 	Hi. Here's a patch you might like, as there has been lots of
> 	talk about ARP filtering etc lately. The send hook is just
> 	before dev_queue_xmit(), and arp_rcv() is split in two, with
> 	the hook in between. Please include..
> 
> diff -Naur linux-2.4.6/include/linux/netfilter_arp.h linux/include/linux/netfilter_arp.h
> --- linux-2.4.6/include/linux/netfilter_arp.h	Thu Jan  1 02:00:00 1970
> +++ linux/include/linux/netfilter_arp.h	Tue Jul 10 11:03:33 2001
> @@ -0,0 +1,15 @@
> +#ifndef __LINUX_ARP_NETFILTER_H
> +#define __LINUX_ARP_NETFILTER_H
> +
> +/* ARP-specific defines for netfilter. 
> + * Copyright 2000 Stonesoft Corp.
> + * Licensed under the GNU General Public License.
> + */
> +
> +#include <linux/netfilter.h>
> +
> +#define NF_ARP_IN	0
> +#define NF_ARP_OUT	1
> +#define NF_ARP_NUMHOOKS	2
> +
> +#endif /*__LINUX_ARP_NETFILTER_H*/
> diff -Naur linux-2.4.6/net/ipv4/arp.c linux/net/ipv4/arp.c
> --- linux-2.4.6/net/ipv4/arp.c	Wed May 16 20:21:45 2001
> +++ linux/net/ipv4/arp.c	Tue Jul 10 11:04:16 2001
> @@ -111,6 +111,8 @@
>  
>  #include <asm/system.h>
>  #include <asm/uaccess.h>
> +#include <linux/netfilter.h>
> +#include <linux/netfilter_arp.h>
>  
>  
>  
> @@ -562,7 +564,8 @@
>  	memcpy(arp_ptr, &dest_ip, 4);
>  	skb->dev = dev;
>  
> -	dev_queue_xmit(skb);
> +	NF_HOOK(PF_UNSPEC, NF_ARP_OUT, skb, dev, NULL,
> +                dev_queue_xmit);
>  	return;
>  
>  out:
> @@ -578,17 +581,16 @@
>   *	Receive an arp request by the device layer.
>   */
>  
> +static int arp_rcv2(struct sk_buff *skb);
> +
>  int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
>  {
>  	struct arphdr *arp = skb->nh.arph;
>  	unsigned char *arp_ptr= (unsigned char *)(arp+1);
> -	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
> @@ -739,6 +741,42 @@
>   *  and in the case of requests for us we add the requester to the arp 
>   *  cache.
>   */
> +        
> +	if (in_dev)
> +		in_dev_put(in_dev);
> +	return NF_HOOK(PF_UNSPEC, NF_ARP_IN, skb, dev, NULL,
> +		       arp_rcv2);
> +
> + out:
> +	if (in_dev)
> +		in_dev_put(in_dev);
> + freeskb:
> +	kfree_skb(skb);
> + out_of_mem:
> +	return 0