From 6caf621b0d616a03f1b698ed3dab0c5d29348620 Mon Sep 17 00:00:00 2001 From: Bart De Schuymer Date: Thu, 1 May 2003 20:21:52 +0000 Subject: add arp mac address matching --- kernel/linux/net/bridge/netfilter/ebt_arp.c | 45 +++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'kernel/linux/net') diff --git a/kernel/linux/net/bridge/netfilter/ebt_arp.c b/kernel/linux/net/bridge/netfilter/ebt_arp.c index ba2a2ac..0b3ffe1 100644 --- a/kernel/linux/net/bridge/netfilter/ebt_arp.c +++ b/kernel/linux/net/bridge/netfilter/ebt_arp.c @@ -12,6 +12,7 @@ #include #include #include +#include #include static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in, @@ -61,6 +62,50 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in return EBT_NOMATCH; } } + + if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) + { + uint32_t arp_len = sizeof(struct arphdr) + + (2 * (((*skb).nh.arph)->ar_hln)) + + (2 * (((*skb).nh.arph)->ar_pln)); + unsigned char dst[ETH_ALEN]; + unsigned char src[ETH_ALEN]; + + // Make sure the packet is long enough. + if ((((*skb).nh.raw) + arp_len) > (*skb).tail) + return EBT_NOMATCH; + // MAC addresses are 6 bytes. + if (((*skb).nh.arph)->ar_hln != ETH_ALEN) + return EBT_NOMATCH; + if (info->bitmask & EBT_ARP_SRC_MAC) { + uint8_t verdict, i; + memcpy(&src, ((*skb).nh.raw) + + sizeof(struct arphdr), + ETH_ALEN); + verdict = 0; + for (i = 0; i < 6; i++) + verdict |= (src[i] ^ info->smaddr[i]) & + info->smmsk[i]; + if (FWINV(verdict != 0, EBT_ARP_SRC_MAC)) + return EBT_NOMATCH; + } + + if (info->bitmask & EBT_ARP_DST_MAC) { + uint8_t verdict, i; + memcpy(&dst, ((*skb).nh.raw) + + sizeof(struct arphdr) + + (((*skb).nh.arph)->ar_hln) + + (((*skb).nh.arph)->ar_pln), + ETH_ALEN); + verdict = 0; + for (i = 0; i < 6; i++) + verdict |= (dst[i] ^ info->dmaddr[i]) & + info->dmmsk[i]; + if (FWINV(verdict != 0, EBT_ARP_DST_MAC)) + return EBT_NOMATCH; + } + } + return EBT_MATCH; } -- cgit v1.2.3