助力软件开发企业降本增效 PHP / java源码系统,只需一次付费,代码终身使用! 广告
从前面的章节也知道,ARP是动态处理的,现在总结一下:ARP表项的生存时间是5分钟,而ARP请求的等待时间是5秒钟,当这些时间到达后,就会更新ARP表项,如果在物理链路层无法连通则会删除表项。这就需要ARP层有一个超时处理函数对ARP进行管理,这些操作都是根据ARP表项的ctime字段进行的,它记录着对应表项的生存时间,而超时处理函数是etharp\_tmr(),它是一个周期性的超时处理函数,每隔1秒就调用一次,当ctime的值大于指定的时间,就会删除对应的表项,具体见代码清单 10‑5。 ``` 1 void 2 etharp_tmr(void) 3 { 4 int i; 5 6 LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n")); 7 /* 遍历ARP表,从ARP表中删除过期的表项 */ 8 for (i = 0; i < ARP_TABLE_SIZE; ++i) (1) 9 { 10 u8_t state = arp_table[i].state; 11 if (state != ETHARP_STATE_EMPTY 12 #if ETHARP_SUPPORT_STATIC_ENTRIES 13 && (state != ETHARP_STATE_STATIC) 14 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ 15 ) 16 { 17 arp_table[i].ctime++; (2) 18 if ((arp_table[i].ctime >= ARP_MAXAGE) || 19 ((arp_table[i].state == ETHARP_STATE_PENDING) && 20 (arp_table[i].ctime >= ARP_MAXPENDING))) (3) 21 { 22 /* 等待表项稳定或者表项已经过期*/ 23 LWIP_DEBUGF(ETHARP_DEBUG,("etharp_timer: expired %s entry %d.\n", 24 arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", i)); 25 /*从ARP表中删除过期的表项 */ 26 etharp_free_entry(i); (4) 27 } 28 else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_1) 29 { 30 /* 过渡 */ 31 arp_table[i].state = ETHARP_STATE_STABLE_REREQUESTING_2; 32 } 33 else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_2) 34 { 35 /* 进入ETHARP_STATE_STABLE状态 */ 36 37 arp_table[i].state = ETHARP_STATE_STABLE; 38 } 39 else if (arp_table[i].state == ETHARP_STATE_PENDING) 40 { 41 /*仍然挂起,重新发送ARP请求 */ 42 etharp_request(arp_table[i].netif, &arp_table[i].ipaddr); 43 } 44 } 45 } 46 } ``` (1):由于LwIP的ARP表是比较小的,直接遍历表即可,更新ARP表的内容。 (2):如果ARP表项不是空的,那么就记录表项的时间。 (3)(4):当表项的时间大于表项的生存时间(5分钟),或者表项状态是ETHARP_STATE_PENDING处于等待目标主机回应ARP请求包,并且等待的时间超过ARP_MAXPENDING(5秒),那么LwIP就认为这些表项是无效了,就调用etharp_free_entry()函数删除表项。