aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/bridge/netfilter/ebt_arp.c48
1 files changed, 22 insertions, 26 deletions
diff --git a/net/bridge/netfilter/ebt_arp.c b/net/bridge/netfilter/ebt_arp.c
index 9c599800a900..1a46952a56d9 100644
--- a/net/bridge/netfilter/ebt_arp.c
+++ b/net/bridge/netfilter/ebt_arp.c
@@ -35,40 +35,36 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
35 return EBT_NOMATCH; 35 return EBT_NOMATCH;
36 36
37 if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP)) { 37 if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP)) {
38 __be32 _addr, *ap; 38 __be32 saddr, daddr, *sap, *dap;
39 39
40 /* IPv4 addresses are always 4 bytes */ 40 if (ah->ar_pln != sizeof(__be32) || ah->ar_pro != htons(ETH_P_IP))
41 if (ah->ar_pln != sizeof(__be32)) 41 return EBT_NOMATCH;
42 sap = skb_header_pointer(skb, sizeof(struct arphdr) +
43 ah->ar_hln, sizeof(saddr),
44 &saddr);
45 if (sap == NULL)
46 return EBT_NOMATCH;
47 dap = skb_header_pointer(skb, sizeof(struct arphdr) +
48 2*ah->ar_hln+sizeof(saddr),
49 sizeof(daddr), &daddr);
50 if (dap == NULL)
51 return EBT_NOMATCH;
52 if (info->bitmask & EBT_ARP_SRC_IP &&
53 FWINV(info->saddr != (*sap & info->smsk), EBT_ARP_SRC_IP))
54 return EBT_NOMATCH;
55 if (info->bitmask & EBT_ARP_DST_IP &&
56 FWINV(info->daddr != (*dap & info->dmsk), EBT_ARP_DST_IP))
57 return EBT_NOMATCH;
58 if (info->bitmask & EBT_ARP_GRAT &&
59 FWINV(*dap != *sap, EBT_ARP_GRAT))
42 return EBT_NOMATCH; 60 return EBT_NOMATCH;
43 if (info->bitmask & EBT_ARP_SRC_IP) {
44 ap = skb_header_pointer(skb, sizeof(struct arphdr) +
45 ah->ar_hln, sizeof(_addr),
46 &_addr);
47 if (ap == NULL)
48 return EBT_NOMATCH;
49 if (FWINV(info->saddr != (*ap & info->smsk),
50 EBT_ARP_SRC_IP))
51 return EBT_NOMATCH;
52 }
53
54 if (info->bitmask & EBT_ARP_DST_IP) {
55 ap = skb_header_pointer(skb, sizeof(struct arphdr) +
56 2*ah->ar_hln+sizeof(__be32),
57 sizeof(_addr), &_addr);
58 if (ap == NULL)
59 return EBT_NOMATCH;
60 if (FWINV(info->daddr != (*ap & info->dmsk),
61 EBT_ARP_DST_IP))
62 return EBT_NOMATCH;
63 }
64 } 61 }
65 62
66 if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) { 63 if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) {
67 unsigned char _mac[ETH_ALEN], *mp; 64 unsigned char _mac[ETH_ALEN], *mp;
68 uint8_t verdict, i; 65 uint8_t verdict, i;
69 66
70 /* MAC addresses are 6 bytes */ 67 if (ah->ar_hln != ETH_ALEN || ah->ar_hrd != htons(ARPHRD_ETHER))
71 if (ah->ar_hln != ETH_ALEN)
72 return EBT_NOMATCH; 68 return EBT_NOMATCH;
73 if (info->bitmask & EBT_ARP_SRC_MAC) { 69 if (info->bitmask & EBT_ARP_SRC_MAC) {
74 mp = skb_header_pointer(skb, sizeof(struct arphdr), 70 mp = skb_header_pointer(skb, sizeof(struct arphdr),