当系统收到一份目的端为本机的ARP请求报文后,它就把硬件地址填进去,然后用两个目的端地址分别替换两个发送端地址,并把操作字段置为2(ARP应答),最后把它发送回去 。
ARP交互报文例子图,wireshark分析:
文章插图
8.4 ARP缓存表8.4.1 ARP缓存表简介每台主机或路由器在其内存中具有一个ARP缓存表(ARP table),这张表包含IP地址到MAC地址的映射关系 。
网络层的IP数据包需要经过链路层转发时,可以直接查询缓存表是否有这个IP映射的MAC 。
如果有,目标链路层数据帧的目标MAC就直接使用这个MAC,就能转发了 。
如果没有,通过ARP协议,往链路层局域网内广播一下,询问下有没有这个IP对应的结点设备,如果有就把这个IP对应的链路层设备的MAC返回到这个主机,然后这个主机的链路层使用这个MAC发送数据帧出去 。而且可以把这个MAC及其对应的IP保存到自己的ARP缓存表中,方便下次直接使用 。当然,这个映射也有过期检查,需要超时机制维护 。
8.4.2 LWIP中的缓存表lwip的缓存表:
static struct etharp_entry arp_table[ARP_TABLE_SIZE];
ARP_TABLE_SIZE
默认为10,即是默认能缓存10条ARP映射记录 。8.4.3 ARP缓存表数据结构
struct etharp_entry
:struct etharp_entry {#if ARP_QUEUEING/* 指向此ARP表项上挂起的数据包队列的指针. */struct etharp_q_entry *q;#else /* ARP_QUEUEING *//* 指向此ARP表项上的单个挂起的数据包队列的指针 */struct pbuf *q;#endif /* ARP_QUEUEING *//* 目标IP地址 */ip4_addr_t ipaddr;/* 当前ARP映射记录对应网卡信息 */struct netif *netif;/* 目标IP对应的MAC地址 */struct eth_addr ethaddr;/* 当前netry的生存时间 */u16_t ctime;/* 当前netry的状态信息 */u8_t state;};
文章插图
8.4.4 ARP缓存表数据缓冲队列
struct etharp_q_entry *q;
:这个字段用于指向缓存表的数据包缓冲队列 。
在IP层发送一个数据包时,会先在ARP映射表中查找与目的IP地址对应的MAC地址,这样才能封装以太网?。?才能在链路层把数据包发送出去 。
但是如果IP层发送一个数据包时 , 在ARP映射表中查不到对应的硬件地址MAC,就发送一个ARP请求包,在请求过程中,把这个IP层的数据包缓存到这个队列
q
先 , 直到请求成功后,获取这个IP层数据包IP对应的MAC地址或请求失败为止 。对于
PBUFF_ERF
、PBUF_POOL
、PBUF_RAM
类型的数据包是不允许直接挂到ARP entry的挂起缓存队列上的,因为内核等待目标主机的ARP应答期间 , 这些数据有可能会被上层改动,所以LwIP需要将这些pbuf数据包拷贝到新的空间,等待发送 。这个队列的数据结构:
- 在memp.h的
MEMP_ARP_QUEUE
内存池中有这个数据结构的内存资源 。共有MEMP_NUM_ARP_QUEUE
个,默认为30个 。
#if ARP_QUEUEINGstruct etharp_q_entry {struct etharp_q_entry *next; /* 下一个节点 */struct pbuf *p; /* pbuf */};#endif /* ARP_QUEUEING */
8.4.5 ARP缓存表entry状态信息u8_t state;
:/** ARP states */enum etharp_state {ETHARP_STATE_EMPTY = 0, /* 空闲态 */ETHARP_STATE_PENDING, /* pending态 */ETHARP_STATE_STABLE, /* 有效态 */ETHARP_STATE_STABLE_REREQUESTING_1, /* 有效过渡态1 */ETHARP_STATE_STABLE_REREQUESTING_2 /* 有效过渡态2 */#if ETHARP_SUPPORT_STATIC_ENTRIES, ETHARP_STATE_STATIC /* 静态entry */#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */};
当前netry的状态信息:ETHARP_STATE_EMPTY
:空状态 。当前entry资源无效,可以被填充使用 。ETHARP_STATE_PENDING
:PENDING态 。当前entry正在ARP请求,但是还没收到ARP响应 。ETHARP_STATE_STABLE
:有效态 。当前entry记录的IP地址与MAC地址映射有效 。ETHARP_STATE_STABLE_REREQUESTING_1
:有效过渡态1 。就是为了防止entry块过期前频繁发起ARP请求 。ETHARP_STATE_STABLE_REREQUESTING_2
:有效过渡态2 。ETHARP_STATE_STATIC
:静态条目 。手动配置的ARP映射,一直有效 。
ETHARP_STATE_STABLE
的时候又发送一个ARP请求包,那么表项状态会暂时被设置为THARP_STATE_STABLE_REREQUESTING_1
, 然后被设置为ETHARP_STATE_STABLE_REREQUESTING_2
状态,这些是一个过渡状态,当收到ARP应答后,表项又会被设置为ETHARP_STATE_STABLE
, 这样能保持表项的有效 。
推荐阅读
- 耳机怎么煲机(关于耳机煲机的三大禁忌)
- 桥牌的玩法及规则介绍(三分钟看懂桥牌)
- 三 Linux--多线程
- 金铲铲之战巨龙之巢龙拳瑟提玩法是什么
- 2022支付宝蚂蚁庄园答案9.2
- 荣耀Magic3和小米12哪个好-荣耀Magic3和小米12哪个值得入手
- 网络非常不稳定怎么办(网络不稳定了怎么解决)
- 我的世界地狱门做法(我的世界特殊地狱门怎么做)
- 幻塔2.2版本上线时间是什么时候
- 我的世界地狱门怎么做(mc七种传送门)