|
@@ -146,6 +146,19 @@ int eth_rebuild_header(struct sk_buff *skb)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static inline unsigned int compare_eth_addr(const unsigned char *__a, const unsigned char *__b)
|
|
|
+{
|
|
|
+ const unsigned short *dest = (unsigned short *) __a;
|
|
|
+ const unsigned short *devaddr = (unsigned short *) __b;
|
|
|
+ unsigned int res;
|
|
|
+
|
|
|
+ BUILD_BUG_ON(ETH_ALEN != 6);
|
|
|
+ res = ((dest[0] ^ devaddr[0]) |
|
|
|
+ (dest[1] ^ devaddr[1]) |
|
|
|
+ (dest[2] ^ devaddr[2])) != 0;
|
|
|
+
|
|
|
+ return res;
|
|
|
+}
|
|
|
|
|
|
/*
|
|
|
* Determine the packet's protocol ID. The rule here is that we
|
|
@@ -158,16 +171,15 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
|
|
|
struct ethhdr *eth;
|
|
|
unsigned char *rawp;
|
|
|
|
|
|
- skb->mac.raw=skb->data;
|
|
|
+ skb->mac.raw = skb->data;
|
|
|
skb_pull(skb,ETH_HLEN);
|
|
|
eth = eth_hdr(skb);
|
|
|
|
|
|
- if(*eth->h_dest&1)
|
|
|
- {
|
|
|
- if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
|
|
|
- skb->pkt_type=PACKET_BROADCAST;
|
|
|
+ if (*eth->h_dest&1) {
|
|
|
+ if (!compare_eth_addr(eth->h_dest, dev->broadcast))
|
|
|
+ skb->pkt_type = PACKET_BROADCAST;
|
|
|
else
|
|
|
- skb->pkt_type=PACKET_MULTICAST;
|
|
|
+ skb->pkt_type = PACKET_MULTICAST;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -178,10 +190,9 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
|
|
|
* seems to set IFF_PROMISC.
|
|
|
*/
|
|
|
|
|
|
- else if(1 /*dev->flags&IFF_PROMISC*/)
|
|
|
- {
|
|
|
- if(memcmp(eth->h_dest,dev->dev_addr, ETH_ALEN))
|
|
|
- skb->pkt_type=PACKET_OTHERHOST;
|
|
|
+ else if(1 /*dev->flags&IFF_PROMISC*/) {
|
|
|
+ if (unlikely(!compare_eth_addr(eth->h_dest, dev->dev_addr)))
|
|
|
+ skb->pkt_type = PACKET_OTHERHOST;
|
|
|
}
|
|
|
|
|
|
if (ntohs(eth->h_proto) >= 1536)
|