ARP应答部分代码为uip_arp.c中的void uip_arp_arpin(void)函数.
这个函数是在设备接收到ARP包时,由驱动程序调用的.
如果收到是ARP包是一个对本地主机上次发送的ARP请求的应答,那么就从包中取得自己想要的主机的MAC地址,加入自己的ARP缓存表中.
如果收到是一个ARP请求,那就把自己的MAC地址打包成一个ARP应答,发送给请求的主机. 看代码uip_arp.c的254行:
1./*-----------------------------------------------------------------
------------------*/
2./**
3.* ARP processing for incoming ARP packets.
4.*对传入的ARP包的处理.
5.* This function should be called by the device driver when an ARP
6.* packet has been received. The function will act differently
7.* depending on the ARP packet type: if it is a reply for a request
8.* that we previously sent out, the ARP cache will be filled in with
9.* the values from the ARP reply. If the incoming ARP packet is an ARP
10.* request for our IP address, an ARP reply packet is created and put
11.* into the uip_buf[] buffer.
12.*此函数在收到ARP包时由设备驱动调用,函数行为会因包类型而有不同.如果
收到的是一个对前先发送的请求的应答
13.*则根据应答的值填充缓存.如果传入的包是对我们的IP的请求,则创建一个
ARP应答,并放入uip_buf[]中.
14.* When the function returns, the value of the global variable uip_len
15.* indicates whether the device driver should send out a packet or
16.* not. If uip_len is zero, no packet should be sent. If uip_len is
17.* non-zero, it contains the length of the outbound packet that is
18.* present in the uip_buf[] buffer.
19.*函数返回时,全局变量uip_len的值指明了设备驱动要不要发送包.若
uip_len为0,则不需发送,若uip_len不是0,
20.* 则其值是uip_buf[]中包含的要传出的包的大小.
21.* This function expects an ARP packet with a prepended Ethernet
22.* header in the uip_buf[] buffer, and the length of the packet in the
23.* global variable uip_len.此函数预期中的uip_buf中有一个带以太网头的
ARP包.其长度存为uip_len中.
24.*/
25./*-----------------------------------------------------------------
------------------*/
26.void
27.uip_arp_arpin(void)
28.{
29.
30.if(uip_len < sizeof(struct arp_hdr)) {
31.uip_len = 0;
32.return;
33.}
34.uip_len = 0;
35.
36.switch(BUF->opcode) {
37.case HTONS(ARP_REQUEST):
38./* ARP request. If it asked for our address, we send out a
39.reply. 如果是一个ARP请求,则发送应答.*/
40.if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
41./* First, we register the one who made the request in our ARP
42.table, since it is likely that we will do more communication
43.with this host in the future.首先,我们将发送请求的主机注册到ARP缓存
表中,因为我们很可能要跟它要有更多的交流 */
44.uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
45.
46./* The reply opcode is 2. 应答的操作码为2*/
47.BUF->opcode = HTONS(2);
48.
49.memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
50.memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
51.memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
52.memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
53.
54.BUF->dipaddr[0] = BUF->sipaddr[0];
55.BUF->dipaddr[1] = BUF->sipaddr[1];
56.BUF->sipaddr[0] = uip_hostaddr[0];
57.BUF->sipaddr[1] = uip_hostaddr[1];
58.
59.BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
60.uip_len = sizeof(struct arp_hdr);
61.}
62.break;
63.case HTONS(ARP_REPLY):
64./* ARP reply. We insert or update the ARP table if it was meant
65.for us. 如果收到的是一个ARP应答,而且也是我们所要的应答的话,就插件并
更新ARP缓存表*/
66.if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
67.uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
68.}
69.break;
70.}
71.
72.return;
73.}