__be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)

来源:互联网 发布:轻便婴儿车推荐 知乎 编辑:程序博客网 时间:2024/05/16 00:53

参考一下博客:

http://yaoyang.blog.51cto.com/7657153/1269713

http://blog.csdn.net/eric_liufeng/article/details/10475583

网络驱动接收到报文后,会初始化skb->protocol字段,再通过netif_rx(skb);传输给3层协议,3层协议根据skb->protocol字段决定使用哪个协议实例处理。

某一mac协议类型的全部网络设备都是使用相同的xx_type_trans()函数来获取protocol的:以太网设备驱动调用eth_type_trans(), FDDI网络设备驱动调用fddi_type_trans().

/** * eth_type_trans - determine the packet's protocol ID. * @skb: received socket data * @dev: receiving network device * * The rule here is that we * assume 802.3 if the type field is short enough to be a length. * This is normal practice and works for any 'now in use' protocol. */__be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev){unsigned short _service_access_point;const unsigned short *sap;const struct ethhdr *eth;skb->dev = dev;skb_reset_mac_header(skb);//获取第二层数据包的报头skb_pull_inline(skb, ETH_HLEN);eth = eth_hdr(skb);/** 在skb->pkt_type中得到识别和注册* PACKET_BROADCAST:广播包 * PACKET_MULTICAST:2层组播地址 * PACKET_HOST:发送给本机的报文 * PACKET_OTHERHOST: 发送给其他主机的报文,这里主机应该处于混杂模式中 */if (unlikely(is_multicast_ether_addr(eth->h_dest))) {if (ether_addr_equal_64bits(eth->h_dest, dev->broadcast))skb->pkt_type = PACKET_BROADCAST;elseskb->pkt_type = PACKET_MULTICAST;}else if (unlikely(!ether_addr_equal_64bits(eth->h_dest,   dev->dev_addr)))skb->pkt_type = PACKET_OTHERHOST;/* * 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. */if (unlikely(netdev_uses_dsa(dev)))return htons(ETH_P_XDSA);/*如果长度大于1536(最大帧长度ETH_P_802_3_MIN),那么他是802.3兼容以太网卡,协议字段在eth->h_proto中标识*/  if (likely(ntohs(eth->h_proto) >= ETH_P_802_3_MIN))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. */sap = skb_header_pointer(skb, 0, sizeof(*sap), &_service_access_point);if (sap && *sap == 0xFFFF)return htons(ETH_P_802_3);/* *      Real 802.2 LLC         * 802.2的协议头返回后,被当做三层报文处理,          * 协议处理被散列在ptype_base中,协议处理函数为p8022_rcv()          * 对应的三层协议可以通过 register_8022_client() 将自己的处理函数注册到p8022_rcv()中          * 如果 register_8022_client(0xAA, snap_rcv)就将SNAP的三层处理函数注册进去了 */return htons(ETH_P_802_2);}


0 0
原创粉丝点击