|
发表于 2014-3-21 20:01:52
|
显示全部楼层
那为什么还要分IP帧和ARP帧呢?
我突然觉得应该是这样的,我说一下不对请指正:
首先从网卡驱动读取一帧的数据 line62
然后根据读到数据的帧类型进行不同的判断,
这是uip_arp_ipin();源码的英文注释
/*-----------------------------------------------------------------------------------*/
/**
* ARP processing for incoming IP packets
*
* This function should be called by the device driver when an IP
* packet has been received. The function will check if the address is
* in the ARP cache, and if so the ARP cache entry will be
* refreshed. If no ARP cache entry was found, a new one is created.
*
* This function expects an IP packet with a prepended Ethernet header
* in the uip_buf[] buffer, and the length of the packet in the global
* variable uip_len.
*/
/*-----------------------------------------------------------------------------------*/
if 读到的是IP数据包
uip_arp_ipin();
/* Only insert/update an entry if the source IP address of the
incoming IP packet comes from a host on the local network. */ 这是这个函数源码内部语句的注释。
我是这样理解的,如果读到的是IP数据包,调用这个函数进行IP包ARP部分的处理——插入或更新ARP表。
如果原来的ARP缓存中有源IP的记录那么进行更新,如果没有则创建一个该IP的ARP表,这个函数的源码最后
确实调用了ARP表更新的函数。
更新有这样的好处,ARP表中的记录是有生命周期的假如是A分钟,当进行频繁的通信时,在每包的数据
都更新ARP表,生命周期都重新从零开始记,这样就避免了只是在固定的将A分钟到了之后更新ARP表,发送ARP请求
等待响应目标IP的响应会浪费时间。
进行IP数据包ARP部分处理的时候会把一个带以太网帧头的数据写入堆栈uip_buf 同时使把数据长度赋给uip_len,
然后调用 uip_arp_out(); tapdev_send();
这个是 uip_arp_out(); 函数的源码注释
/*-----------------------------------------------------------------------------------*/
/**
* Prepend Ethernet header to an outbound IP packet and see if we need
* to send out an ARP request.
*
* This function should be called before sending out an IP packet. The
* function checks the destination IP address of the IP packet to see
* what Ethernet MAC address that should be used as a destination MAC
* address on the Ethernet.
*
* If the destination IP address is in the local network (determined
* by logical ANDing of netmask and our IP address), the function
* checks the ARP cache to see if an entry for the destination IP
* address is found. If so, an Ethernet header is prepended and the
* function returns. If no ARP cache entry is found for the
* destination IP address, the packet in the uip_buf[] is replaced by
* an ARP request packet for the IP address. The IP packet is dropped
* and it is assumed that they higher level protocols (e.g., TCP)
* eventually will retransmit the dropped packet.
*
* If the destination IP address is not on the local network, the IP
* address of the default router is used instead.
*
* When the function returns, a packet is present in the uip_buf[]
* buffer, and the length of the packet is in the global variable
* uip_len.
*/
/*-----------------------------------------------------------------------------------*/
这个函数会检查ARP表中是否有目标IP对应的MAC地址的历史记录,如果有填入以太网的帧头然后返回,tapdev_send();
发送数据,我觉得这帧数据应该是IP数据包的确定号。如果没有则会发送ARP请求同时丢弃这帧IP数据。
else 是ARP帧
79.uip_arp_arpin(); 对数据进行ARP部分的处理,如果收到的是本机上次发出ARP请求的回复,那么更新ARP表。
如果是其他主机的ARP请求并且目标IP匹配,那么创建ARP回复帧并把数据填入uip_buf 缓冲,同时把数据长度赋给uip_len
80.if (uip_len > 0)
81.{
82.tapdev_send();
83.}
如果是请求帧响应ARP请求。
这是uip_arp_arpin() 这个函数源码的注释。
/*-----------------------------------------------------------------------------------*/
/**
* ARP processing for incoming ARP packets.
*
* This function should be called by the device driver when an ARP
* packet has been received. The function will act differently
* depending on the ARP packet type: if it is a reply for a request
* that we previously sent out, the ARP cache will be filled in with
* the values from the ARP reply. If the incoming ARP packet is an ARP
* request for our IP address, an ARP reply packet is created and put
* into the uip_buf[] buffer.
*
* When the function returns, the value of the global variable uip_len
* indicates whether the device driver should send out a packet or
* not. If uip_len is zero, no packet should be sent. If uip_len is
* non-zero, it contains the length of the outbound packet that is
* present in the uip_buf[] buffer.
*
* This function expects an ARP packet with a prepended Ethernet
* header in the uip_buf[] buffer, and the length of the packet in the
* global variable uip_len.
*/
/*-----------------------------------------------------------------------------------*/
我不是故意挑刺的,看到楼主的认真,今天下午我突然有了想法索性说一下,说了这么多也不知道对不对,诚惶诚恐,请指点或大家一起再讨论。
|
|