当前位置:文档之家› uIP的ARP协议代码分析之二 ARP应答

uIP的ARP协议代码分析之二 ARP应答

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.}

相关主题