lwIP TCP/IP 协议栈笔记之十一: ARP协议

本文深入探讨了ARP(地址解析协议)在TCP/IP协议栈中的作用,从链路层概述到MAC地址概念,详细阐述了ARP的工作原理,包括IP地址映射为物理地址、ARP缓存表的管理和超时处理,以及ARP请求和响应的报文结构。此外,还介绍了数据包的接收和发送流程,涉及etharp_output()等相关函数的使用。
摘要由CSDN通过智能技术生成

目录

1. TCP/IP模型及链路层概述

2. MAC地址的概念

3. ARP 概述

4. 以太网帧结构

5. IP 地址映射为物理地址

6.ARP 缓存表

7. ARP 缓存表的超时处理

8. ARP 报文

9. 发送ARP 请求包

10. 数据包接收流程

10.1 以太网之数据包接收

10.2 ARP数据包处理

10.3 更新ARP 缓存表

11. 数据包发送流程

11.1 etharp_output()函数

11.2 etharp_output_to_arp_index()函数

11.3 etharp_query()函数


1. TCP/IP模型及链路层概述

为方便讨论,将运行链路层协议(即第2 层)协议的任何设备均称为结点(node)。结点包括主机、路由器、交换机和WiFi 接入点。我们也把沿着通信路径连接相邻结点的通信信道称为链路(link)。为了将一个数据报从源主机传输到目标主机,数据报必须通过端到端路径上的各段链路才能到达目标主机。在通过特定的链路时,传输结点将数据报封装在链路层帧中,并将该帧传送到链路中 。

链路层的主体部分是网卡中实现的,在发送的数据帧的时候,协议栈取得由高层传递过的数据报(注意,数据帧与数据报不是一个东西,数据帧一般形容链路层的数据,是一帧一帧的,也是链路层的服务——数据成帧),在链路层中封装该数据报,也就是填写数据帧的各个字段,然后遵循链路接入协议将该帧数据进行传输;在接收端,控制器接收了整个数据帧,抽取出网络层的数据报,往上层传递。

不同主机的信息都是必须通过链路层才能传递数据,所有链路层的完整与稳定是传递信息的必要条件。

2. MAC地址的概念

MAC地址(Media Access Control Address)亦称为EHA(Ethernet HardwareAddress)、硬件地址、物理地(Physical Address)。MAC 地址就是在媒体接入层上使用的地址,也叫物理地址、硬件地址或链路地址,其被固化在网卡的ROM中。可见MAC地址实际上就是网卡地址或网卡标识符。

MAC 地址长度为6 字节(48 比特),其前3 个字节表示组织唯一标志符(Organizationally Unique Identifier,即OUI),由IEEE 的注册管理机构给不同厂家分配的代码,以区分不同的厂家,后3 个字节由厂家自行分配,称为扩展标识符。同一个厂家生产的网卡中MAC 地址后24 位是不同的。

厂商OUI分配表:http://standards-oui.ieee.org/oui/oui.txt

注:需要说明,OUI中有执行特殊功能的保留地址,如组播地址(01-00-5E),厂商的OUI 首字节的最低位都是0。

3. ARP 概述

地址解析协议(Address Resolution Protocol,ARP)是通过解析IP 地址得到数据链路层地址的,是一个在网络协议包中极其重要的网络传输协议,它与网卡有着极其密切的关系,在TCP/IP 分层结构中,把ARP 划分为网络层,为什么呢,因为在网络层看来,源主机与目标主机是通过IP 地址进行识别的,而所有的数据传输又依赖网卡底层硬件,即链路层,那么就需要将这些IP 地址转换为链路层可以识别的东西,在所有的链路中都有着自己的一套寻址机制,如在以太网中使用MAC 地址进行寻址,标识不同的主机,那么就需要有一个协议将IP 地址转换为MAC 地址,由此就出现了ARP 协议,ARP 协议在网络层被应用,它是网络层与链路层连接的重要枢纽.

在局域网中,网络中实际传输的是“帧”,帧里面是有目标主机的MAC 地址的。在以太网中,一个主机要和另一个主机进行直接通信,必须要知道目标主机的MAC 地址,那就需要ARP 进行地址解析,所谓“地址解析”就是主机在发送帧前将目标IP 地址转换
成目标MAC 地址的过程。ARP 协议的基本功能就是通过目标设备的IP 地址,查询目标设备的MAC 地址,以保证通信的顺利进行。

4. 以太网帧结构

每个网卡都有唯一一个物理地址,在硬件中进行数据帧传输的时候就必须有正确的目的物理地址,例如以太网的48位MAC 地址就是存储在网卡内部存储器中。

以太网帧以一个7 字节的前同步码(Preamble)字段开始。该前同步码的值都是10101010(0x55,大端模式);而后紧接着一个字节的帧开始符,其值是10101011(0xD5,大端模式)。前同步码字段的作用是实现物理层帧输入输出的同步,而帧开始符表示着以太网帧的开始,剩下的5 个字段才是真正的以太网数据帧结构。 (注:一般硬件都支持,报头和帧起始数据 (SFD) 在发送路径中插入、在接收路径中删除,因此解析数据帧的时候实际是没有的

目标MAC 地址(6 字节):这个字段包含目标网卡的MAC 地址,当一个网卡收到一个以太网数据帧,如果该数据帧的目标地址是网卡自身的MAC 地址或者是MAC 广播地址,它都将该帧的数据字段的内容传递给网络层;如果它收到了具有任何其他MAC 地址的帧,则将该数据帧丢弃。

源MAC 地址(6 字节):这个字段包含了传输该帧到局域网上的适配器的MAC 地址。

类型字段(2 字节):类型字段允许以太网复用多种网络层协议。为了理解这点,我们需要记住主机能够使用除了IP 以外的其他网络层协议。事实上,一台给定的主机可以支持多种网络层协议,以对不同的应用采用不同的协议。因此,当以太网帧到达网卡中,网卡需要知道它应该将数据字段的内容传递给哪个网络层协议。如IP 协议、ARP 协议等。

(注:Ethernet_II帧类型值大于等于1536(0x0600),以太网数据帧的长度在64-1518字节之间,因此,当类型字段处于相应的范围则表示类型或数据帧长度)

数据字段(46~1500 字节):这个字段承载了IP 数据报。以太网的最大传输单元(MTU)是1500 字节。这意味着如果IP 数据报超过了1500 字节,则主机必须将该数据报分片。数据字段的最小长度是46 字节,这意味着如果IP 数据报小于46 字节,数据报必须被填充到46 字节。当采用填充时,传递到网络层的数据包括IP 数据报和填充部分,网络层使用IP 数据报首部中的长度字段来去除填充部分。

CRC(4 字节):CRC 字段包含了以太网的差错校验信息(除报头和帧SFD)

在以太网帧中,目标MAC 地址可以分成三类,单播地址、多播地址和广播地址。单播地址通常是与某个网卡的MAC 地址对应,它要求以太网第一个字节的bit0(最先发出去的位)必须是0;而多播地址则要求第一个字节的bit0 为1,这样子多播地址就不会与任何网卡的MAC 地址相同,可以被多个网卡同时接收;广播地址的48 位MAC 地址全为1,也就是FF-FF-FF-FF-FF-FF, 同一局域网内的所有网卡都会收到广播的数据包。

所有的以太网计算都向网络层提供不可靠的无连接服务,也就是说在网卡发送数据的时候,不会向目标网卡进行事先的通知(握手),网卡只在以太网帧中封装好来自上层的数据报,然后把数据报发送到局域网上。同样的当一个网卡接收一个以太网数据帧的时候,它也不会进行回复确认,如果当网卡执行CRC 校验不通过的时候,它也不会发送否定确认,这样子当一些以太网帧不通过CRC 校验时,网卡只是将其丢弃,而发送的一方就不会知道它传输的数据是否达到并且通过校验。

5. IP 地址映射为物理地址

TCP/IP 协议有自己的IP 地址,IP 地址(IPv4)是一个32 位的IP 地址,网络层发送数据包只需要知道目标主机IP 地址即可,而以太网发送数据则必须知道对方的硬件MAC 地址,同时IP 地址的分配与硬件MAC 地址是没有关系的,为了让网络层只需要知道IP 地址就可以完成通信工作,那就需要有一个协议将IP 地址映射成为对应的MAC 地址,此外还需要考虑IP 地址可能是动态的,非常灵活,使用静态的映射方法是行不通的,所以ARP协议就提供优质的地址动态解析的机制,让32 位的IP 地址能映射成为48 位的MAC 地址,让上层应用于底层完全分离开,这样子在上层应用就能灵活使用IP 地址作为标识,进行通信。

6.ARP 缓存表

为了实现IP 地址与网卡MAC 地址的查询与转换,ARP 协议引入了ARP 缓存表的概念,每台主机或路由器在其内存中具有一个ARP 缓存表(ARP table),这张表包含IP 地址到MAC 地址的映射关系,表中记录了<IP 地址,MAC 地址>对,它们是主机最近运行时获得关于其他主机的IP 地址到物理地址的映射,当需要发送IP 数据的时候,主机就会根据目标IP 地址到ARP 缓存表中进行查找对应的MAC 地址,然后通过网卡将数据发送出去。ARP 表也包含一个寿命(TTL)值,它指示了从表中删除每个映射的时间。从一个表项放置到某ARP 表中开始,一个表项通常的过期时间是10 分钟。

电脑ARP 缓存表查询 , arp -a

 ARP 协议的核心就是对缓存表的操作,发送数据包的时候,查找ARP 缓存表以得到对应的MAC 地址,必要时进行ARP 缓存表的更新,此外ARP 还需要不断处理其他主机的ARP 请求,在ARP 缓存表中的TTL 即将过期的时候更新缓存表以保证缓存表中的表项有效。

其运作过程大致可以理解为:

1. 如果主机A 想发送数据给主机B,主机A 首先会检查自己的ARP 缓存表,查看是否有主机B 的IP 地址和MAC 地址的对应关系,如果有,则会将主机B 的MAC 地址作为源MAC 地址封装到数据帧中。如果本地ARP 缓存中没有对应关系,主机A 就会向局域网中广播ARP 请求(包括发送方的IP 地址、MAC 地址、接收方的IP 地址),每台主机接收到ARP 请求后都检查自己的IP 地址是否与ARP 请求中的接收方IP 地址相同,若不相同则丢弃ARP 请求包。

2. 当交换机接受到此数据帧之后,发现此数据帧是广播帧,因此,会将此数据帧从非接收的所有接口发送出去。

3. 当主机B 接受到此数据帧后,会校对IP 地址是否是自己的,并将主机A 的IP 地址和MAC 地址的对应关系记录到自己的ARP 缓存表中,同时会发送一个ARP 响应,其中包括自己的MAC 地址。

4. 主机A 在收到这个回应的数据帧之后,在自己的ARP 缓存表中记录主机B 的IP地址和MAC 地址的对应关系。而此时交换机已经学习到了主机A 和主机B 的MAC 地址了。

ARP 协议的核心是ARP 缓存表,ARP 的实质就是对缓存表的建立、更新、查询等操作,ARP 缓存表的核心是表项(entry)。LwIP 使用一个arp_table 数组描述ARP 缓存表,数组的内容是表项的内容.

static struct etharp_entry arp_table[ARP_TABLE_SIZE];

 

每个表项都必须记录一对IP 地址与MAC 地址的映射关系,此外还有一些基本的信息,如表项的状态、生命周期(生存时间)以及对应网卡的基本信息,LwIP 使用一个etharp_entry 结构体对表项进行描述.

编译器预先定义了缓存表的大小,ARP_TABLE_SIZE 默认为10,也就是最大能存放10 个表项,由于这个表很小,LwIP 对表的操作直接采用遍历方式,遍历每个表项并且更改其中的内容。

struct etharp_entry {
#if ARP_QUEUEING
  /** Pointer to queue of pending outgoing packets on this ARP entry. */
  struct etharp_q_entry *q;
#else /* ARP_QUEUEING */
  /** Pointer to a single pending outgoing packet on this ARP entry. */
  struct pbuf *q;
#endif /* ARP_QUEUEING */
  ip4_addr_t ipaddr;            // 记录目标IP 地址
  struct netif *netif;          // 对应网卡信息
  struct eth_addr ethaddr;      // 记录与目标IP 地址对应的MAC 地址
  u16_t ctime;                  // 生存时间
  u8_t state;                   // 表项的状态,LwIP 中用枚举类型定义了不同的状态
};

struct etharp_q_entry {
  struct etharp_q_entry *next;
  struct pbuf *p;
};

 

/** ARP states */
enum etharp_state {
  ETHARP_STATE_EMPTY = 0,
  ETHARP_STATE_PENDING,
  ETHARP_STATE_STABLE,
  ETHARP_STATE_STABLE_REREQUESTING_1,
  ETHARP_STATE_STABLE_REREQUESTING_2
#if ETHARP_SUPPORT_STATIC_ENTRIES
  , ETHARP_STATE_STATIC
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
};

ARP 缓存表在初始化的时候,所有的表项都会被初始化为ETHARP_STATE_EMPTY,也就是空状态,表示这些表项能被使用,在需要添加表项的时候,LwIP 内核就会遍历ARP 缓存表,找到合适的表项,进行添加。

如果ARP 表项处于ETHARP_STATE_PENDING 状态,表示ARP 已经发出了一个ARP 请求包,但是还未收到目标IP 地址主机的应答,处于这个状态的缓存表项是有等待时间的,它通过宏定义ARP_MAXPENDING 指定,默认为5 秒钟,如果从发出ARP 请求包后的5 秒内还没收到应答,那么该表项又会被删除;而如果收到应答后,ARP 就会更新缓存表的信息,记录目标IP 地址与目标MAC 地址的映射关系并且开始记录表项的生存时间,同时该表项的状态会变成ETHARP_STATE_STABLE 状态。

当要发送数据包的时候,而此时表项为ETHARP_STATE_PENDING 状态,那么这些数据包就会暂时被挂载到表项的数据包缓冲队列上,直到表项的状态为ETHARP_STATE_STABLE,才进行发送数据包。

状态ETHARP_STATE_STABLE 的表项,这些表项代表着ARP 记录了IP 地址与MAC 地址的映射关系,能随意通过IP 地址进行数据的发送,但是这些表项是具有生存时间的,通过宏定义ARP_MAXAGE 指定,默认为5 分钟,在这些时间,LwIP 会不断维护这些缓存表以保持缓存表的有效。

当表项是ETHARP_STATE_STABLE 的时候又发送一个ARP 请求包,那么表项状态会暂时被设置为ETHARP_STATE_STABLE_REREQUESTING_1,然后被设置为ETHARP_STATE_STABLE_REREQUESTING_2 状态,这些是一个过渡状态,当收到ARP 应答后,表项又会被设置为ETHARP_ST

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值