uip源码剖析【一】——【网络层】ARP解读

===================转载请保留头部====================

作者:souroot   来源:WEB DNA

连接:http://www.cnblogs.com/souroot/archive/2013/04/21/3033856.html

关键词:TCPIP UIP 51单片机 计算机网络 网络工程专业 手把手教你写tcpip协议栈

版权:  Q college 版权所有

=====================以下为正文=====================

uip对TCPIP协议栈做了最大的精简,最最基本的TCPIP协议栈,最起码要有4个协议:ARP、IP、ICMP、TCP,

为什么ARP很重要呢?因为报文在网络上传递,最终还是需要二层地址,即MAC地址的,而运行uip的主机只知道报文的目的ip地址,而对MAC地址是不了解的。

这时候就需要ARP了。

====ARP流程=====

ARP是已知对端的IP地址,想要获取对端的MAC地址,就会发送一个ARP请求,对端收到ARP请求后,会发送一个ARP应答给源主机。这是个大概的流程。下面讲一下详细的流程:

 ====详细流程=====

【ARP请求的发送】

主机首先检查要发送的报文的目的IP是否和自己在同一网段,如果在同一网段,就请求目的主机的MAC地址;如果不是同一网段的,就请求网关的MAC地址。

【接收到ARP请求】

如果设备收到个ARP请求,发现请求的就是自己的MAC,首先把对方的IP和MAC映射放到自己的ARP表项中,然后填好ARP应答后,单播给发送ARP请求的

设备。

【接收到ARP应答】

这个很简单了,收到了ARP应答就把对方的IP和MAC地址映射表存入自己的ARP表项即可 

 

====ARP帧格式====

下面讲一下ARP的帧格式:

ARP帧由14字节的以太网首部和28字节的ARP头组成。

----以太网头部解释----

这个比较简单,就是目的MAC,源MAC,以及以太帧中封装的三层报文类型,如果是ip报文,就是0x0800, ARP报文的话,就是0x0806

----ARP头部解释----

 硬件类型:以太网地址用1表示;

 协议类型:字段表示要映射的协议地址类型它的值为 0 x 0 8 0 0即表示I P地址;

 下面两个字节是硬件地址长度和协议地址长度,分别为6字节和4字节;

OP为操作类型,1表示ARP请求,2表示ARP应答;

 对于ARP请求来说,除了目的以太网地址,其他的信息都要填充(因为ARP请求就是要获取目的MAC地址)。当目的端收到ARP请求后,目的端把自己的MAC地址填入此报文中,然后把发送地址换成自己的地址(包括MAC和IP),并把OP位置为2(即表示ARP应答),然后发送出去。

====uip中ARP报文的结构体====

 

uip中的arp基本都放在uip_arp.h和uip_arp.c中

主要包含以下函数接口:

/*-----------------------------------------------------------------------------------*/
/**
* Periodic ARP processing function.
*
* This function performs periodic timer processing in the ARP module
* and should be called at regular intervals. The recommended interval
* is 10 seconds between the calls.
* 每10s就需要被main函数调用一次,在ARP老化后把表项清零
*/
/*-----------------------------------------------------------------------------------*/
void uip_arp_timer(void);

 

/* 收到ip报文或者ARP报文就可能调用此函数,更新ARP表项*/
static void
uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)

 

/*-----------------------------------------------------------------------------------*/
/**
* 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.
*
* 收到IP报文也需要更新ARP表项
*/
/*-----------------------------------------------------------------------------------*/
void uip_arp_ipin(void)

 

/*-----------------------------------------------------------------------------------*/
/**
* 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.
*
* 收到ARP报文,不管是请求报文还是应答报文,做出相应的处理
*/
/*-----------------------------------------------------------------------------------*/
void uip_arp_arpin(void)

 

/*-----------------------------------------------------------------------------------*/
/**
* 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请求
*/
/*-----------------------------------------------------------------------------------*/
void uip_arp_out(void)

posted @ 2013-04-21 13:54  souroot  阅读(1993)  评论(0编辑  收藏  举报