🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
ARP的请求与应答都是依赖ARP报文结构进行的,ARP报文是放在以太网数据帧中进行发送的,所以下图会将以太网首部一同画出来,具体见图 10‑5。 ![](https://box.kancloud.cn/89188704ea640dcd055e66600299866c_927x372.png) 在ARP表建立前,主机并不知道目标MAC地址,所以在一开始的时候只能通过广播的方式将ARP请求包发送出去,处于同一局域网的主机都能接收到广播的数据包。所以一开始目标MAC地址是FF-FF-FF-FF-FF-FF,而以太网首部的帧类型是有多种,对于ARP数据包来说,其值为0x0806,对于IP数据报来说,其值为0x0800,此处我们只需简单了解一下即可,无需记住。 接下来就是ARP报文部分,ARP也是一种协议,也有ARP首部,在ARP首部一开始的2个字节存储的是硬件类型,表示要知道目标网卡的硬件类型,其中,值为1表示以太网地址,其他还可能表示令牌环地址;接下来还有2字节的协议类型,其中,0x0800表示IP地址,其他还可能是ICMP/IGMP等;接下来有1个字节表示硬件地址长度,指出该报文中硬件地址的长度,对于以太网,它的值为6;还有1字节的协议地址长度,对于ARP请求或应答来说,该值为4;ARP首部最后的op字段用于记录ARP操作的类型,分别是:  ARP请求,其值为1。  ARP应答,其值为2。  RARP请求,其值为3。  RARP应答,其值为4。 我们只关心ARP的请求与应答即可,RARP是逆地址解析协议,在这里我们就不用去了解,它在网络中基本已经被淘汰,用于主机在启动的时候获得自己的IP地址。 对于ARP首部后面的四个字段分别是源MAC地址、源IP地址、目标MAC地址、目标IP地址,这些就是比较简单的了。 在ARP请求包中,除了目标MAC地址是未知以为,其他地址3个字段都应该填写正确,然后通过广播的形式将该ARP请求包发送出去,目标主机接收到该请求包后判断目标IP地址与自身IP地址是否一致,如果一致则返回ARP应答;对应ARP应答包,只需要把自己的MAC地址填充进去,并且请求包的源主机信息与目标主机信息进行交换位置,然后把op字段设置为2,就返回ARP应答包即可。 注意,在发送ARP请求包的时候,以太网首部的目标MAC地址是FF-FF-FF-FF-FF-FF,而ARP首部目标MAC地址为00-00-00-00-00-00-00,这里千万不要混淆。 在LwIP中,使用了大量的数据结构对ARP进行描述,比较麻烦,我们暂时不用去学它,只要知道原理是这样子的即可,关于这些数据结构的定义位于etharp.h 、ethernet.h等头文件中,具体见代码清单 10-6。 ``` 1 #define ETH_HWADDR_LEN 6 //以太网地址长度 2 3 truct eth_addr //以太网地址结构体 4 { 5 PACK_STRUCT_FLD_8(u8_t addr[ETH_HWADDR_LEN]); 6 } PACK_STRUCT_STRUCT; 7 8 struct eth_hdr //以太网首部 9 { 10 PACK_STRUCT_FLD_S(struct eth_addr dest); //以太网目标MAC地址 11 PACK_STRUCT_FLD_S(struct eth_addr src); //以太网源MAC地址 12 PACK_STRUCT_FIELD(u16_t type); //帧类型 13 } PACK_STRUCT_STRUCT; 14 15 struct etharp_hdr //ARP报文 16 { 17 PACK_STRUCT_FIELD(u16_t hwtype); //硬件类型 18 PACK_STRUCT_FIELD(u16_t proto); //协议类型 19 PACK_STRUCT_FLD_8(u8_t hwlen); //硬件地址长度 20 PACK_STRUCT_FLD_8(u8_t protolen); //协议地址长度 21 PACK_STRUCT_FIELD(u16_t opcode); //op字段 22 /* 以上是ARP报文首部 */ 23 24 PACK_STRUCT_FLD_S(struct eth_addr shwaddr); //源MAC地址 25 PACK_STRUCT_FLD_S(struct ip4_addr_wordaligned sipaddr);//源ip地址 26 PACK_STRUCT_FLD_S(struct eth_addr dhwaddr); //目标MAC地址 27 PACK_STRUCT_FLD_S(struct ip4_addr_wordaligned dipaddr);//目标ip地址 28 } PACK_STRUCT_STRUCT; 29 30 enum etharp_opcode //op字段操作 31 { 32 ARP_REQUEST = 1, //请求包 33 ARP_REPLY = 2 //应答包 34 }; ``` 为了加深理解,我们使用wireshark网络抓包工具形象地讲解报文格式与内容,关于wireshark网络抓包工具的使用方式我们就不做过多讲解,打开工具,然后抓取电脑网络中的数据包,具体见图 10‑6。 ![](https://box.kancloud.cn/a71e9bfabdc65be0e4708b7a9a48de2c_1425x800.png) 然后我们找到ARP协议,双击进行查看ARP协议中的数据包,然后我们可以看到第一个ARP协议是一个请求包,而第二个ARP协议是一个应答包,具体见图 10‑7与图 10‑8 。 ![](https://box.kancloud.cn/ea388ea8e5b36ff3baa7d2441cde8ad4_868x531.png) ![](https://box.kancloud.cn/66e2cdccc3aaf78cd1f733b99d8b5dab_868x506.png)