UIP协议栈笔记·三

转载地址:http://blog.chinaunix.net/uid-23247944-id-2975088.html

网卡如何与UIP协议交互(包括arp, icmp等) 接上文
    接下来看看UIP如何处理ARP应答的情况,在主循环中一段代码:

  1. else if(BUF->type == htons(UIP_ETHTYPE_ARP)) 
  2. {   
  3.     uip_arp_arpin();  // 处理ARP应答
  4.     /* If the above function invocation resulted in data that
  5.        should be sent out on the network, the global variable
  6.        uip_len is set to a value > 0. */
  7.    // 如果上面的函数返回的结果需要发送到网络上,那么uip_len就必须设置 > 0
  8.     if(uip_len > 0) 
  9.     {
  10.         network_device_send(); // 回应ARP包
  11.     }
  12. }
  13.  

在uip_arp_arpin()函数中主要是处理ARP应答。
    这个函数是在设备接收到ARP包时,由驱动程序调用的.如果收到是ARP包是一个对本地主机上次发送的ARP请求的应答,那么就从包中取得自己想要的主机的MAC地址,加入自己的ARP缓存表中.如果收到是一个ARP请求,那就把自己的MAC地址打包成一个ARP应答,发送给请求的主机.看代码uip_arp.c的254行:

  1. void uip_arp_arpin(void)
  2. {
  3.   if(uip_len < sizeof(struct arp_hdr))
  4.   {
  5.     uip_len = 0;
  6.     return;
  7.   }
  8.   uip_len = 0;
  9.   
  10.   switch(BUF->opcode)  // 操作码
  11.   {
  12.       case HTONS(ARP_REQUEST):
  13.       // 如果是一个ARP请求,则发送应答
  14.       if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr))
  15.       {
  16.           // 首先,我们将发送请求的主机注册到ARP缓存表中,因为我们很
  17.           // 可能要跟它要有更多的交流
  18.           uip_arp_update(BUF->sipaddr, &BUF->shwaddr);  
  19.       
  20.           // 回应的操作码是 2.
  21.           BUF->opcode = HTONS(2);
  22.           // 将收到的ARP包的发送端以太网地址,变为目的以太网地址
  23.           memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
  24.           // 将自己的以太网地址,赋值给ARP包的发送端以太网地址
  25.           memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
  26.           // 对应以太网源地址
  27.           memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
  28.           // 对应以太网目的地址
  29.           memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
  30.       
  31.           BUF->dipaddr[0] = BUF->sipaddr[0];
  32.           BUF->dipaddr[1] = BUF->sipaddr[1];
  33.           BUF->sipaddr[0] = uip_hostaddr[0];
  34.           BUF->sipaddr[1] = uip_hostaddr[1];
  35.  
  36.           BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
  37.           uip_len = sizeof(struct arp_hdr);
  38.      }
  39.      break;
  40.     // 如果收到的是一个ARP应答,而且也是我们所要的应答的话,就插件
  41.     // 并更新ARP缓存表
  42.     case HTONS(ARP_REPLY):  
  43.     if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr))
  44.     {
  45.       uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
  46.     }
  47.     break;
  48.   }
  49.  
  50.   return;
  51. }

还有一个是ARP周期处理函数,在主循环中代码如下:

// 每10秒运行一次
if(timer_expired(&arp_timer)) 
{
    timer_reset(&arp_timer); 
    uip_arp_timer();
}

具体的代码:

  1. void uip_arp_timer(void)
  2. {
  3.   struct arp_entry *tabptr;
  4.   ++arptime;    // 这个是个全局变量,结合uip_arp_update来更新缓存表
  5.   for(= 0; i < UIP_ARPTAB_SIZE; ++i)
  6.   {
  7.     tabptr = &arp_table[i];
  8.     // 把超过20分钟都没有更新的项扔掉
  9.     if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
  10.        arptime - tabptr->time >= UIP_ARP_MAXAGE)
  11.     {
  12.       memset(tabptr->ipaddr, 0, 4);
  13.     }
  14.   }
  15. }

 (以上翻译摘自:USR嵌入式技术社区>群组>联盟直属>资料翻译组>UIP文档中文翻译组>uIP的ARP协议代码分析之一 ARP请求 )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值