-
__be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
-
{
-
struct ethhdr *eth;
-
-
skb->dev = dev;
-
skb_reset_mac_header(skb);
-
skb_pull_inline(skb, ETH_HLEN);
-
eth = eth_hdr(skb);
-
-
if (unlikely(is_multicast_ether_addr(eth->h_dest))) {
-
/* 如果是多播地址,即bit0为1*/
-
if (!compare_ether_addr_64bits(eth->h_dest, dev->broadcast))
-
skb->pkt_type = PACKET_BROADCAST; //与设备的广播地址相同,则帧为广播帧
-
else
-
skb->pkt_type = PACKET_MULTICAST; //与设备的广播地址不同,则帧为多播帧
-
}
-
-
/*
-
* This ALLMULTI check should be redundant by 1.4
-
* so don't forget to remove it.
-
*
-
* Seems, you forgot to remove it. All silly devices
-
* seems to set IFF_PROMISC.
-
*/
/*
这里为什么不检测IFF_PROMISC标志呢?
我怀疑是因为有的网卡不设置这个标志,依然可以收到不属于自己地址的数据包
*/
-
else if (1 /*dev->flags&IFF_PROMISC */ ) {
/* 如果数据帧的目的地址不是网卡的地址,那么数据帧的类型为PACKET_OTHERHOST */
-
if (unlikely(compare_ether_addr_64bits(eth->h_dest, dev->dev_addr)))
-
skb->pkt_type = PACKET_OTHERHOST;
/* 默认情况,skb->pkt_type为0,即PACKET_HOST,即数据帧是发给本主机的 */
-
}
/* 下面开始判断L2协议 */
-
-
/*
-
* Some variants of DSA tagging don't have an ethertype field
-
* at all, so we check here whether one of those tagging
-
* variants has been configured on the receiving interface,
-
* and if so, set skb->protocol without looking at the packet.
-
*/
/*
如上面的注释所说,当设备指定了DSA或者TRAILER,那么就不需要检查包,直接返回DSA或者TRAILER
*/
-
if (netdev_uses_dsa_tags(dev))
-
return htons(ETH_P_DSA);
-
if (netdev_uses_trailer_tags(dev))
-
return htons(ETH_P_TRAILER);
/*
当协议值大于136时,那么这个数据帧一定为ethernet frame
因为802.2和802.3的对应域为帧长,均要小于或等于1500,而ethernet frame的协议类型都大于等于1536.
*/
-
if (ntohs(eth->h_proto) >= 1536)
-
return eth->h_proto;
-
-
/*
-
* This is a magic hack to spot IPX packets. Older Novell breaks
-
* the protocol design and runs IPX over 802.3 without an 802.2 LLC
-
* layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
-
* won't work for fault tolerant netware but does for the rest.
-
*/
/*
当IPX使用原始的802.3作为载体时,其头两个字节作为checksum,但是一般都设为0xffff。
*/
-
if (skb->len >= 2 && *(unsigned short *)(skb->data) == 0xFFFF)
-
return htons(ETH_P_802_3);
-
-
/*
-
* Real 802.2 LLC
-
*/
-
/* ok, 那么类型为802.2*/
-
return htons(ETH_P_802_2);
-
}