LwIP的ARP协议实现系列文章
LwIP中的ARP实现(1)之 ARP缓存表的数据结构
LwIP中的ARP实现(2)之 ARP缓存表的超时处理
LwIP中的ARP实现(3)之 发送ARP请求包
LwIP中的ARP实现(4)之 ARP数据包接收
LwIP中的ARP实现(5)之 ARP数据包发送
ARP缓存表的超时处理
ARP表项的生存时间是5分钟,而ARP请求的等待时间是5秒钟,当这些时间到达后,就会更新ARP表项,如果在物理链路层无法连通则会删除表项。这就需要ARP层有一个超时处理函数对ARP进行管理,这些操作都是根据ARP表项的ctime字段进行的,它记录着对应表项的生存时间,而超时处理函数是etharp_tmr(),它是一个周期性的超时处理函数,每隔1秒就调用一次,当ctime的值大于指定的时间,就会删除对应的表项。
LwIP中实现的函数是:etharp_tmr(void)。
由于LwIP的ARP表是比较小的,LwIP采用直接遍历ARP缓存表,更新ARP表的内容,而当表项的时间大于表项的生存时间(5分钟),或者表项状态是ETHARP_STATE_PENDING处于等待目标主机回应ARP请求包,并且等待的时间超过ARP_MAXPENDING(5秒),那么LwIP就认为这些表项是无效了,就调用etharp_free_entry()函数删除表项。
void
etharp_tmr(void)
{
int i;
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
/* 遍历ARP表,从ARP表中删除过期的表项 */
for (i = 0; i < ARP_TABLE_SIZE; ++i) {
u8_t state = arp_table[i].state;
if (state != ETHARP_STATE_EMPTY
#if ETHARP_SUPPORT_STATIC_ENTRIES
&& (state != ETHARP_STATE_STATIC)
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
) {
arp_table[i].ctime++;
/* 等待表项稳定或者表项已经过期*/
if ((arp_table[i].ctime >= ARP_MAXAGE) ||
((arp_table[i].state == ETHARP_STATE_PENDING) &&
(arp_table[i].ctime >= ARP_MAXPENDING)))
{
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %d.\n",
arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", i));
/* clean up entries that have just been expired */
etharp_free_entry(i);
}
else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_1)
{
/* 过渡阶段 */
arp_table[i].state = ETHARP_STATE_STABLE_REREQUESTING_2;
}
else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_2)
{
/* 进入ETHARP_STATE_STABLE状态 */
arp_table[i].state = ETHARP_STATE_STABLE;
}
else if (arp_table[i].state == ETHARP_STATE_PENDING)
{
/*仍然挂起,重新发送ARP请求 */
etharp_request(arp_table[i].netif, &arp_table[i].ipaddr);
}
}
}
}
欢迎关注杰杰个人公众号,更多干货等着你!