标签:struct inpu enum net 长度 protoc 链路层 static 开始
ARP(Address Resolution Protocol),地址解析协议。ARP协议处于网络层,其主要功能就是通过目标设备的 IP 地址,查询目标设备的 MAC 地址,从而进行网络通信。
网络层中,源主机和目标主机依赖于IP地址进行通信。而链路层又有自己的寻址寻址机制(如,以太网依赖于MAC地址进行通信)。ARP的作用在于将IP地址转换为MAC地址,从而连接网络层与链路层,使得上层可以通过IP地址进行网络通信。
ARP协议的基本运作过程如下:
每台主机或路由器在其内存中都存储着一个ARP缓存表,表中记录着了<IP 地址,MAC 地址>对,反映着目标主机的IP地址与MAC地址的映射关系。
1 /*lwip/src/netif/etharp.c*/ 2 3 enum etharp_state { 4 ETHARP_STATE_EMPTY = 0, //空状态,表示该表项为空 5 ETHARP_STATE_PENDING, //挂起状态,表示该表项还未收到目标主机的ARP应答 6 ETHARP_STATE_STABLE, //可用状态,表示该表项可用 7 ETHARP_STATE_STABLE_REREQUESTING_1,//过渡状态 8 ETHARP_STATE_STABLE_REREQUESTING_2 //过渡状态 9 #if ETHARP_SUPPORT_STATIC_ENTRIES 10 , ETHARP_STATE_STATIC 11 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ 12 }; 13 14 struct etharp_entry { 15 #if ARP_QUEUEING 16 /* 指向此ARP表项上挂起的数据包队列*/ 17 struct etharp_q_entry *q; 18 #else /* ARP_QUEUEING */ 19 /*指向此ARP表项上挂起的单个数据包 */ 20 struct pbuf *q; 21 #endif /* ARP_QUEUEING */ 22 ip_addr_t ipaddr; //目标主机的IP地址 23 struct netif *netif; //目标主机的网卡信息 24 struct eth_addr ethaddr;//目标主机的MAC地址 25 u8_t state; //此表项的状态 26 u8_t ctime; //此表项的生存时间 27 }; 28 29 static struct etharp_entry arp_table[ARP_TABLE_SIZE]; //LWIP协议栈的ARP缓存表
ARP协议的核心就是对缓存表的动态处理。因为IP地址可能是动态的,所以ARP缓存表必须动态更新。
ARP协议中,通过发送ARP请求包、接收ARP应答包、ARP缓存表超时处理来实现缓存表的动态更新。
(1)发送ARP请求包
发送数据时,若不存在目标主机的表项,则新建一个表项,并发送ARP请求包;若存在目标主机的表项,对处于ETHARP_STATE_STABLE的表项,会再次发送ARP请求包,以确认目标主机依然在工作状态。详见4. ARP协议工作流程。
(2)接收ARP应答包
接收到ARP应答包时,将ARP应答包包含的<IP 地址,MAC 地址>对添加到缓存表。详见4. ARP协议工作流程。
(3)ARP缓存表超时处理
缓存表的超时处理。周期性(1S)调用 etharp_tmr()函数,动态更新缓存表项的生存时间,以及它的状态。
在ARP缓存表的动态更新过程中,其表现状态变化过程如下:
ARP协议的请求与应答同时通过ARP报文来实现的。ARP的报文将被封装在以太网帧中进行发送。
(1)MAC地址
MAC Address(Media Access Control Address),亦称为 EHA(Ethernet Hardware Address)、硬件地址、物理地址(Physical Address)、链路地址。MAC的值被固化在网卡的ROM中,以唯一标识该网卡。MAC地址长度为 6字节,其前 3个字节(组 织唯一标志符)表示厂家的代码,后 3个字节(扩展标识符)由厂家自行分配。 目标 MAC地址可以分成三类,单播地址、多播地址和广播地址。
(2)以太网帧结构
在链路层中,数据被封装为以太网帧结构进行发送。以太网帧结构如下:
前同步码:它的作用是实现物理层帧输入输出的同步,其值都是 10101010(0x55,大端模式)。
P.S.:当“类型”字段的值小于 1518时,它表示后面数据字段的数据长度,当大于1518的时候才表示递交给哪个协议。
(1)ARP报文格式如下:
(2)ARP帧格式:
ARP报文将被传输到链路层,加上以太网的帧头,形成ARP帧,再通过链路层发送出去。ARP帧的格式如下:
(3)帧格式的定义
1 /*lwip2.1.2/src/include/lwip/port/ethernet.h*/ 2 #define ETH_HWADDR_LEN 6 //以太网地址长度 3 4 struct eth_addr //以太网地址结构体 5 { 6 PACK_STRUCT_FLD_8(u8_t addr[ETH_HWADDR_LEN]); 7 } PACK_STRUCT_STRUCT; 8 9 struct eth_hdr //以太网首部 9 10 { 11 PACK_STRUCT_FLD_S(struct eth_addr dest); //以太网目标 MAC 地址 12 PACK_STRUCT_FLD_S(struct eth_addr src); //以太网源 MAC 地址 13 PACK_STRUCT_FIELD(u16_t type); //帧类型 14 } PACK_STRUCT_STRUCT; 15 16 17 /*lwip2.1.2/src/include/lwip/port/etharp.h*/ 18 struct etharp_hdr //ARP 报文 19 { 20 PACK_STRUCT_FIELD(u16_t hwtype); //硬件类型 21 PACK_STRUCT_FIELD(u16_t proto); //协议类型 22 PACK_STRUCT_FLD_8(u8_t hwlen); //硬件地址长度 23 PACK_STRUCT_FLD_8(u8_t protolen); //协议地址长度 24 PACK_STRUCT_FIELD(u16_t opcode); //op 字段 25 /* 以上是 ARP 报文首部 */ 26 27 PACK_STRUCT_FLD_S(struct eth_addr shwaddr); //源 MAC 地址 28 PACK_STRUCT_FLD_S(struct ip4_addr_wordaligned sipaddr);//源 ip 地址 29 PACK_STRUCT_FLD_S(struct eth_addr dhwaddr); //目标 MAC 地址 30 PACK_STRUCT_FLD_S(struct ip4_addr_wordaligned dipaddr);//目标 ip 地址 31 } PACK_STRUCT_STRUCT; 32 33 enum etharp_opcode //op 字段操作 34 { 35 ARP_REQUEST = 1, //请求包 33 36 ARP_REPLY = 2 //应答包 34 37 };
(1)数据包接收流程说明:
(2) 数据包接收流程说明:
标签:struct inpu enum net 长度 protoc 链路层 static 开始
原文地址:https://www.cnblogs.com/linfeng-learning/p/12346488.html