Linux 协议处理流程
1. 驱动接收报文处理
skb->protocol = eth_type_trans(skb,dev);
netif_rx(skb);
2.eth_type_trans
首先将报文头的13,14字节进行转换
struct ethhdr
{
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
unsigned short h_proto; /* packet type ID field */
} _ _ATTRIBUTE_ _ ((packed));
focusing on the protocol field, h_proto. Despite its name, it actually can store either the protocol in use or the length of the frame. This is because it is 2 octets (bytes) in size, but the maximum size of an Ethernet frame is 1,500 bytes. (Actually, the size can reach 1,518 if SA, DA, Checksum, and Preamble are included. Frames using 802.1q have four extra bytes of encapsulation and can therefore reach a size of 1,522 bytes.)
To save space, the IEEE decided to use values greater than 1,536 to represent the Ethernet protocol. Some preexisting protocols with identifiers lower than 1,536 (0x600 hexadecimal) were updated to meet the criteria. The 802.2 and 802.3 protocols, however, use the field to store the length of the frame.[*] Values ranging from 1,501 to 1,535 are not legal in this field.
Figure 13-8 shows the variations possible on an Ethernet header. Simple Ethernet is shown in (a). The 802.2 and 802.3 variant is shown in (b). As you can see, a single field serves as the protocol field in the former and the length field in the latter. In addition, the 802 variant can support LLC, as shown in (c) and SNAP, as shown in (d).
3.根据类型进入不同的处理函数
4.局域网协议
Data Link Layer Protocols
The following are sublayers of the Data Link Layer protocol:
LLC-- IEEE 802.2
MAC--Some of these are:
- 802.3--Ethernet
- 802.4--Token Bus
- 802.5--Token Ring
- 802.6--Metropolitan Area Network (MAN)
- 802.11--Wireless
5.802.2处理函数
首先进入前面的llc_rcv处理函数,2.4内核代码在802/p8022.c p8022_rcv
int p8022_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
{
struct datalink_proto *proto;
proto = find_8022_client(*(skb->h.raw));
if (proto != NULL)
{
skb->h.raw += 3;
skb->nh.raw += 3;
skb_pull(skb,3);
return proto->rcvfunc(skb, dev, pt);
}
skb->sk = NULL;
kfree_skb(skb);
return 0;
}
也就是说根据LLC头信息SSAP,DSAP,CTL 的SSAP查找对应的LLC协议。
如果找到了则进入相应的处理。
SNAP 0xAA snap_rcv
IPX 0xE0 ipx_rcv
6.SNAP处理
int snap_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
{
static struct packet_type psnap_packet_type =
{
0,
NULL, /* All Devices */
snap_rcv,
NULL,
NULL,
};
struct datalink_proto *proto;
proto = find_snap_client(skb->h.raw);
if (proto != NULL)
{
/*
* Pass the frame on.
*/
skb->h.raw += 5;
skb->nh.raw += 5;
skb_pull(skb,5);
if (psnap_packet_type.type == 0)
psnap_packet_type.type=htons(ETH_P_SNAP);
return proto->rcvfunc(skb, dev, &psnap_packet_type);
}
skb->sk = NULL;
kfree_skb(skb);
return 0;
}
也就是进一步分析后面信息了,再次进行下一层分析。
Table 13-4. SNAP client
Protocol Snap ID Function handler
AppleTalk Address Resolution Protocol 00:00:00:80:F3 aarp_rcv
AppleTalk Datagram Delivery Protocol 08:00:07:80:9B atalk_rcv
IPX 00:00:00:81:37 ipx_rcv
Given the limitations of the LLC header, the 802 committee generalized the data link header further. To make the protocol domain bigger, they introduced the concept of SNAP. Basically, when the SSAP/DSAP couple is assigned the value 0xAA/0xAA, it has a special meaning: the five bytes following the CTL field of the LLC header represent a protocol identifier. The unicast/multicast and local/global bits are also not used anymore. Thus, the size of the protocol identifier has jumped from 8 bits to 40. The reason the committee decided to use five bytes has to do with how protocol numbers are derived from MAC addresses.[*] Unlike SSAP/DSAP, the use of SNAP codes is pretty common.