--- kernel-source-2.4.19/include/linux/netfilter_ipv4/ipt_mac.h 2002-10-15 17:16:09.000000000 +0200 +++ kernel-source-2.4.19.new/include/linux/netfilter_ipv4/ipt_mac.h 2002-10-15 18:30:44.000000000 +0200 @@ -2,7 +2,9 @@ #define _IPT_MAC_H struct ipt_mac_info { - unsigned char srcaddr[ETH_ALEN]; - int invert; + unsigned char srcaddr[ETH_ALEN]; + unsigned char mask[ETH_ALEN]; + int is_mask; + int invert; }; #endif /*_IPT_MAC_H*/ --- kernel-source-2.4.19/net/ipv4/netfilter/ipt_mac.c 2002-10-15 20:48:39.000000000 +0200 +++ kernel-source-2.4.19.new/net/ipv4/netfilter/ipt_mac.c 2002-10-15 20:49:02.000000000 +0200 @@ -18,12 +18,30 @@ { const struct ipt_mac_info *info = matchinfo; - /* Is mac pointer valid? */ - return (skb->mac.raw >= skb->head - && (skb->mac.raw + ETH_HLEN) <= skb->data - /* If so, compare... */ - && ((memcmp(skb->mac.ethernet->h_source, info->srcaddr, ETH_ALEN) + if (info->is_mask) { + if (skb->mac.raw >= skb->head && + (skb->mac.raw + ETH_HLEN) <= skb->data) { + int i; + for (i = 0; i < ETH_HLEN; i++) { + if ((skb->mac.ethernet->h_source[i] & + info->mask[i]) != + (info->srcaddr[i] & info->mask[i])) { + return info->invert; + } + } + return !info->invert; + } else { + return 0; + } + } else { + /* Is mac pointer valid? */ + return (skb->mac.raw >= skb->head + && (skb->mac.raw + ETH_HLEN) <= skb->data + /* If so, compare... */ + && ((memcmp(skb->mac.ethernet->h_source, + info->srcaddr, ETH_ALEN) == 0) ^ info->invert)); + } } static int