struct etharp_entry {
#if ARP_QUEUEING/* 数据包缓存队列指针*/
struct etharp_q_entry *q;
#else /* ARP_QUEUEING *//* 指向此ARP表项上的单个挂起数据包的指针*/
struct pbuf *q;
#endif /* ARP_QUEUEING */
ip4_addr_t ipaddr; /* 目标IP 地址*/
struct netif *netif; /* 对应网卡信息*/
struct eth_addr ethaddr; /* 对应的MAC 地址*/
u16_t ctime; /* 生存时间信息*/
u8_t state; /* 表项的状态*/
};
static struct etharp_entry arp_table[ARP_TABLE_SIZE];
?通过这个表可以查询arp信息。
每一个表项从创建、请求等都设置了一个状态,不同状态的表项都需要特殊的处理,这些
状态如下所示:
(1) ETHARP_STATE_EMPTY 状态
这个状态表示ARP 缓存表处于初始化的状态,所有表项初始化之后才可以被使用,如果
需要添加表项,lwIP 内核就会遍历ARP 缓存表并找到合适的表项进行添加。
(2) ETHARP_STATE_PENDING 状态
该状态表示该表项处于不稳定状态,此时该表项只记录到了IP 地址,但是还未记录到对
应的MAC 地址。很可能的情况是:lwIP 内核已经发出一个关于该IP 地址的ARP 请求到数据
链路上且lwIP 内核还未收到ARP 应答,此时ETHARP_STATE_PENDING 状态下会设定超时
时间(5 秒),当计数超时后,对应的表项将被删除,超时时间需要宏定义
ARP_MAXPENDING 来指定,默认为5 秒,如果在5 秒之前收到应答数据包,那么系统会更
新缓存表的信息,记录目标IP 地址与目标MAC 地址的映射关系并且开始记录表项的生存时
间,同时该表项的状态会变成ETHARP_STATE_STABLE 状态。
(3) ETHARP_STATE_STABLE 状态
当收到应答之前,这些数据包会暂时挂载到表项的数据包缓冲队列上,收到应答之后,系
统已经更新ARP 缓存表,那么系统发送数据就会进入该状态
(4)ETHARP_STATE_STABLE_REREQUESTING_1&ÐARP_STATE_STABLE_REREQUESTING_2 状态
? 如果系统再一次发送ARP 请求数据包,则表项状态会暂时被设置为ETHARP_STATE_ST
ABLE_REREQUESTING_1,之后设置为ETHARP_STATE_STABLE_REREQUESTING_2 状态,
其实这两个状态为过渡状态,如果5 秒之前收到ARP 应答后,表项又会被设置为ETHARP_S
TATE_STABLE 状态,这样子能保持表项的有效性。
这些状态也是和超时处理相关,在ARP 超时事件中,需要定时遍历ARP 缓存表各个表项
的状态和检测各个表项的生存时间
我们在应用层发送数据时:
? ? ?第一步就是需要检测ARP 中是否有对方主机的MAC :
????????如果没有,肯定发送不成功啊,所以此时会在ARP 缓存表上创建一个表项,并且构建一个ARP 请求包,发送完成之后lwIP 内核把要发送的数据包挂载到新创建的表项当中。
? ? ? ?在表项中包含了etharp_q_entry 结构体和pbuf 结构体指针,这两个都是用来挂载数据包的,一般来说,lwIP 内核不使用etharp_q_entry 结构体挂载数据包,而是直接使用指针指向pbuf 数据
包。
? ? 这个函数被周期调用,来清除arp表,防止超时:系统以周期的形式调用函数etharp_trm
-------------------------------------------------------------------------------------------------------------------------------
一般我们用arp用这几个功能吧:
1、查看arp表
??
2、清除arp表
??
3、添加/删除arp表,静态添加后,一般系统应该不会删除,
??
4、刷新arp表
??
回头找找这些功能在哪里,先放一张这个arp函数处理流程表
后面慢慢更新,,,,