diff options
Diffstat (limited to 'net/ipv4/arp.c')
-rw-r--r-- | net/ipv4/arp.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 0937b34c27ca..d54345a06f72 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -653,6 +653,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
653 | unsigned char *arp_ptr; | 653 | unsigned char *arp_ptr; |
654 | struct rtable *rt; | 654 | struct rtable *rt; |
655 | unsigned char *sha; | 655 | unsigned char *sha; |
656 | unsigned char *tha = NULL; | ||
656 | __be32 sip, tip; | 657 | __be32 sip, tip; |
657 | u16 dev_type = dev->type; | 658 | u16 dev_type = dev->type; |
658 | int addr_type; | 659 | int addr_type; |
@@ -724,6 +725,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
724 | break; | 725 | break; |
725 | #endif | 726 | #endif |
726 | default: | 727 | default: |
728 | tha = arp_ptr; | ||
727 | arp_ptr += dev->addr_len; | 729 | arp_ptr += dev->addr_len; |
728 | } | 730 | } |
729 | memcpy(&tip, arp_ptr, 4); | 731 | memcpy(&tip, arp_ptr, 4); |
@@ -842,8 +844,18 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
842 | It is possible, that this option should be enabled for some | 844 | It is possible, that this option should be enabled for some |
843 | devices (strip is candidate) | 845 | devices (strip is candidate) |
844 | */ | 846 | */ |
845 | is_garp = arp->ar_op == htons(ARPOP_REQUEST) && tip == sip && | 847 | is_garp = tip == sip && addr_type == RTN_UNICAST; |
846 | addr_type == RTN_UNICAST; | 848 | |
849 | /* Unsolicited ARP _replies_ also require target hwaddr to be | ||
850 | * the same as source. | ||
851 | */ | ||
852 | if (is_garp && arp->ar_op == htons(ARPOP_REPLY)) | ||
853 | is_garp = | ||
854 | /* IPv4 over IEEE 1394 doesn't provide target | ||
855 | * hardware address field in its ARP payload. | ||
856 | */ | ||
857 | tha && | ||
858 | !memcmp(tha, sha, dev->addr_len); | ||
847 | 859 | ||
848 | if (!n && | 860 | if (!n && |
849 | ((arp->ar_op == htons(ARPOP_REPLY) && | 861 | ((arp->ar_op == htons(ARPOP_REPLY) && |