ARP
ARP(Address Resolution Protocol,地址解析协议)用于查询协议地址对应的链路地址。以太网中的 IPv4 通信使用它,把当前链路上下一跳的 IP 地址解析为 MAC 地址,让主机能够填写以太网帧的目标地址。
这里最容易影响推导的是「下一跳」:访问同一网段的主机,通常解析对方的 MAC;访问远端服务器,通常解析网关的 MAC。IP 决定数据报要送往哪里,ARP 补上当前这一跳实际交付需要的地址。路由选择过程见 IP 的地址与逐跳转发,本文讨论普通以太网中的 IPv4 单播通信。
1. 面试核心
先记住这几条,再读正文- IP 地址参与跨网络寻址与路由选择,MAC 地址用于当前以太网链路上的帧交付。一个接口可以配置多个 IP,不能把两种地址理解为一一对应的设备编号。卡 · IP 地址与 MAC 地址
- 发送端先查路由、确定出口和下一跳,再查邻居缓存。缺少可用映射时,典型首次解析发送广播 ARP 请求,目标通常单播回复;ARP 直接封装在以太网帧里,不经过 TCP 或 UDP。卡 · 请求、应答与报文字段
- 目标不在直连网络时,主机解析的是匹配路由指定的网关。路由器在下一条链路重新解析、重新封装,原来的 ARP 广播不会被普通 IP 转发直接带到远端。卡 · 同链路通信与跨网段转发
- ARP 缓存保存 IP 与 MAC 的映射,并结合接口、有效性状态使用。有映射不等于永远可达,也不意味着每次发送都要重新广播;刷新和失效策略取决于系统实现。卡 · 缓存项可以继续使用,也需要验证
- 排查解析失败,要沿着路由选择、邻居状态、请求与应答检查。能解析到网关的 MAC,只能说明这一跳取得了映射,不能证明远端服务可用。卡 · 从路由走到报文
- ARP 本身没有验证地址声明者身份的认证机制。地址冲突检测和公告可以帮助发现冲突、更新映射,但不能建立可信身份;IPv6 的相应功能由邻居发现承担。卡 · 地址声明与协议边界
2. IP 地址与 MAC 地址
MAC 地址是在以太网帧中标识发送方和接收方的链路地址。交换机根据目标 MAC 在当前二层网络内转发帧;IP 路由器根据目标 IP 决定下一跳,两者处理的对象和范围不同。
例如,主机 A 要访问另一个网络中的服务器 C。A 的 IP 数据报仍然写着 C 的目标 IP,但包在第一条以太网上要先交给网关 R,外层帧就写 R 在这条链路上的 MAC。R 收到后去掉这一跳的链路封装,作出路由决定,再填写下一条链路上的 MAC 地址。各层的封装关系见网络分层的逐跳处理与设备分工。
IP 地址由系统配置在网络接口上,不要求烧录到物理网卡中;接口也可以是虚拟接口。一个以太网接口可以有多个 IP,这些 IP 可能对应同一个 MAC。MAC 可以使用厂商分配的地址,也可以按系统和网络配置使用本地管理地址,因此它不是不可改变、全球可信的身份标识。
3. 请求、应答与报文字段
3.1 先确定下一跳,再解析地址
ARP 缓存是主机保存已知 IP 与链路地址映射的地方。在 Linux 中,可以通过邻居表查看这些映射;同一个 IP 出现在不同接口上时,不能脱离出口接口判断该用哪一项。
设 A 的地址为 192.0.2.10/24,B 为 192.0.2.20/24,二者连接在同一条以太网链路上。A 没有 B 的可用缓存项时,发送过程是:
- A 查路由,确认
192.0.2.20可以通过当前接口直接到达,下一跳就是 B。 - A 广播 ARP 请求,询问「谁使用
192.0.2.20」,并携带自己的 IP 和 MAC。 - 同一广播域中的节点可以收到请求。使用目标地址的 B 识别到请求,通常向 A 的 MAC 单播 ARP 应答,告知自己的映射。
- A 更新邻居项,用 B 的 MAC 封装之前准备发送的 IP 数据报。实现可以暂存等待解析的数据报,但队列容量和解析失败处理都有边界。
B 也可以从发给自己的请求中学习 A 的地址映射,因此不一定要为了回复 A 再广播查询一次。是否新增或更新某个缓存项,还受到协议处理规则与系统配置约束,不能概括为「收到任何 ARP 包都无条件覆盖所有映射」。
3.2 外层帧与 ARP 内容分别表示什么
ARP 报文直接放在以太网帧中,外层 EtherType 为 0x0806。它有自己的协议字段,但没有 IP 头,也没有 TCP 或 UDP 端口。以太网中的 IPv4 ARP 报文包含以下主要信息:
| 字段 | 作用或取值 |
|---|---|
| 硬件类型、硬件地址长度 | 以太网类型为 1,MAC 地址长度为 6 字节 |
| 协议类型、协议地址长度 | IPv4 类型为 0x0800,IPv4 地址长度为 4 字节 |
| 操作码 | 1 表示请求,2 表示应答 |
| 发送方 MAC、发送方 IP | 声明发送方的地址映射 |
| 目标 MAC、目标 IP | 标明被查询或接收应答的一方 |
注意两处「类型」不一样:帧的 0x0806 表示里面装着 ARP;ARP 内容中的 0x0800 表示正在解析 IPv4 地址,不能据此认为 ARP 被封装在 IPv4 内。
典型首次请求的外层目标 MAC 是广播地址 ff:ff:ff:ff:ff:ff。请求内部的目标 MAC 字段则是正在查询的未知值;Linux 的这种请求会填全零,但 RFC 826 并没有要求普通请求必须填全零。看到两者不同并不矛盾。
4. 同链路通信与跨网段转发
ARP 只解决当前链路的交付,跨网段通信由路由器把这些逐跳交付串起来。以下地址用于说明机制,不代表公网服务地址:
| 节点与接口 | IPv4 地址 | MAC 地址 |
|---|---|---|
| A | 192.0.2.10/24 | 02:00:00:00:00:0a |
| B | 192.0.2.20/24 | 02:00:00:00:00:0b |
| R 左侧接口 | 192.0.2.1/24 | 02:00:00:00:00:01 |
| R 右侧接口 | 198.51.100.1/24 | 02:00:00:00:01:01 |
| C | 198.51.100.20/24 | 02:00:00:00:01:14 |
A、B 和 R 的左侧接口在同一广播域,C 与 R 的右侧接口在另一条链路。A 的默认网关为 192.0.2.1,C 的默认网关为 198.51.100.1。这里没有配置 NAT,也没有更具体的额外路由。
4.1 访问同链路的 B
A 访问 B 时,解析目标就是 192.0.2.20。本例在隔离 Linux 网络命名空间和 veth 链路上实际抓到的关键字段如下;表中省略了时间戳、填充和与说明无关的字段:
| 顺序 | 以太网源 → 目标 | 报文内容 |
|---|---|---|
| 1 | A 的 MAC → ff:ff:ff:ff:ff:ff | ARP 请求:发送方 192.0.2.10,查询 192.0.2.20 |
| 2 | B 的 MAC → A 的 MAC | ARP 应答:192.0.2.20 对应 B 的 MAC |
| 3 | A 的 MAC → B 的 MAC | IPv4:192.0.2.10 → 192.0.2.20,其中承载 ICMP 回显请求 |
第 1、2 个帧承载 ARP,第 3 个帧才承载 IPv4。紧接着再次发送一个 ping,抓包中只有 ICMP 请求与响应,没有新的 ARP 请求,因为这次发送使用了刚取得的缓存项。这个结果只说明本次缓存复用,不代表系统之后永远不再验证 B。
4.2 访问跨网段的 C
A 访问 198.51.100.20 时,匹配默认路由,下一跳为 192.0.2.1。清空实验节点的动态邻居项后,两侧实际抓到的过程是:
| 位置 | ARP 查询的 IP | 随后 IPv4 帧的目标 MAC | IP 数据报的源 → 目标 |
|---|---|---|---|
| A 所在链路 | 192.0.2.1 | R 左侧接口的 MAC | 192.0.2.10 → 198.51.100.20 |
| R 到 C 的链路 | 198.51.100.20 | C 的 MAC | 192.0.2.10 → 198.51.100.20 |
A 并没有查询 C 的 MAC。R 的右侧重新发出一次 ARP 请求,发送方 IP 为 198.51.100.1;这不是把 A 的广播转发过去。两侧 IP 源、目标保持不变,经过 R 后 TTL 减 1,以太网的源、目标 MAC 则按当前链路重新填写。
因此,「跨网段发给默认网关」也需要条件:最终使用的是匹配路由指定的下一跳,有更具体路由时不一定走默认网关。若子网掩码或路由配错,主机可能误以为远端地址就在本链路,从而直接广播查询那个地址,却得不到预期应答。
5. 缓存、失效与排查
5.1 缓存项可以继续使用,也需要验证
缓存减少了重复广播,但地址迁移、接口替换或节点离线后,旧映射可能失效。RFC 1122 要求实现能够清理过时项,并抑制对同一目标的高频重复请求;它没有给所有系统规定一个统一的缓存寿命。
Linux 的邻居项还带有可达性状态。例如 REACHABLE 表示近期确认过可达,STALE 表示映射仍在,但可达性需要再确认。**STALE 不等于删除,也不等于发送前必须重新广播。**本例把 B 的实验邻居项改为 STALE 后发送 ping,最初的请求仍然直接使用已有 MAC,之后再按邻居状态机验证可达性。具体计时与探测次数取决于系统和配置,不能作为 ARP 协议常量背诵。
缓存项与交换机的 MAC 转发表也不是同一张表:前者帮助主机取得「某接口上的下一跳 IP → MAC」;后者帮助交换机判断「某 VLAN 内的目标 MAC → 出口端口」。主机缓存正确,不等于交换机一定有相应转发表项;交换机没有目标项时的未知单播泛洪,也不等于主机发起了 ARP 广播。
5.2 从路由走到报文
排查时,先确认系统要交给谁,再看它是否解析成功。Linux 中以下查询不会修改接口或路由:
ip route get 198.51.100.20
ip neigh show dev eth0
在上述 A 节点中,第一条查询给出的下一跳为 192.0.2.1、出口为 eth0;成功发送后,邻居表里对应的是网关的 MAC,不需要出现 198.51.100.20 的映射。实际机器的接口名称和路由可能不同,应按查询结果继续定位。
| 观察 | 下一步需要判断什么 |
|---|---|
| 路由选错出口或下一跳 | 先检查地址、前缀和路由;ARP 不负责纠正错误的选路 |
邻居项处于 INCOMPLETE,有请求却没有应答 | 请求是否到达正确链路,对端是否拥有该地址,接口、VLAN、过滤或代理配置是否符合预期 |
邻居项最终为 FAILED | 本次邻居解析或可达性验证失败;不能仅据此推断远端应用进程崩溃 |
| 已取得网关 MAC,远端访问仍失败 | 继续检查后续路由、回程、过滤和服务,不能停在 ARP 成功 |
隔离实验还访问了无人使用的同链路地址 192.0.2.99:只抓到针对该地址的 ARP 请求,没有向它发出承载 IPv4 的以太网帧,最后邻居项进入 FAILED。这说明本例连当前链路的交付地址都没有取得,与「数据报已到达服务器,但服务器拒绝端口」属于不同阶段。
6. 地址声明与协议边界
6.1 地址探测和公告分别做什么?
ARP Probe 是使用地址前的冲突探测。按 RFC 5227,它是广播 ARP 请求,发送方 IP 填 0.0.0.0,目标 IP 填准备使用的地址;这样可以询问地址是否被占用,又不提前声明自己已使用它。
ARP Announcement 是对本机开始使用某地址的公告。RFC 5227 定义的形式也是广播请求,但发送方 IP 与目标 IP 都填该地址,用于帮助同链路节点更新旧映射。实践中「免费 ARP」通常指这类主动地址声明,不能由这个名称断定所有实现都使用同一种操作码,也不能保证所有接收方都无条件更新缓存。
探测没有发现冲突,不等于取得永久排他权;之后仍可能出现另一个节点使用同样的地址。上述字段按 RFC 核验,本实验没有运行完整的地址冲突检测状态机。
6.2 ARP 广播、代理与安全有什么限制?
普通 IP 路由不会把收到的二层广播 ARP 请求跨接口转发。代理 ARP 是设备代替另一个 IP 回答请求,通常返回自己的 MAC,再由它接收并转发后续流量。它改变了「谁回答」,并没有让原来的广播跨过路由器。
ARP 没有内置的身份认证。错误或伪造的地址声明可能使节点采用错误映射,造成流量被错误转发或中断。受控网络可以结合地址绑定、交换设备的 ARP 检查等措施约束声明;端到端 TLS 则验证应用连接对端并保护传输内容,但不能保证底层链路仍然可达。
IPv6 使用基于 ICMPv6 的邻居发现完成邻居地址解析和可达性检测等任务,不使用 ARP。两者解决的问题有交集,不能把 IPv4 的 ARP 报文字段直接套到 IPv6 上。
7 · 面试题卡片
本页题目与参考回答
7.1 IP 地址与 MAC 地址各有什么作用?它们是否一一对应?
考察重点:跨网络寻址、链路交付、接口地址与设备身份的区别。
相关内容:IP 地址与 MAC 地址。
参考回答
**IP 地址用于网络层寻址和路由,MAC 地址用于当前以太网链路的帧交付,两者不是一一对应。**路由器根据目标 IP 选下一跳,再填写当前链路上的 MAC,因此经过路由器时链路封装会变化。
一个接口可以配置多个 IP,也可以是虚拟接口;MAC 也可能由系统配置,不能把它当作不可变的可信身份。普通 IP 转发中,源、目标 IP 保持不变,经过 NAT 等转换时例外。
7.2 ARP 如何取得下一跳的 MAC 地址?请求和应答怎样封装?
考察重点:选路、邻居缓存、广播请求、应答及 ARP 的封装位置。
相关内容:请求、应答与报文字段。
参考回答
**先根据路由选出出口接口和下一跳,再查对应的邻居映射;缺少可用映射时发起 ARP 解析。**典型首次解析广播询问下一跳 IP,由拥有该地址的节点通常单播回复其 MAC。发送方缓存映射,随后以这个 MAC 封装 IP 数据报;代理 ARP 等配置可能由其他设备代答。
ARP 直接承载在 EtherType 为 0x0806 的以太网帧中,没有 TCP、UDP 端口。请求和应答包含操作码以及发送方、目标的 IP 与 MAC;请求外层帧的广播 MAC 与内部尚未知的目标 MAC 字段要分开理解。
7.3 A 访问另一个网段的 C,为什么查询网关的 MAC?
考察重点:下一跳和最终目标的区别、路由器重新封装与广播范围。
相关内容:同链路通信与跨网段转发。
参考回答
**因为路由决定先把数据报交给本链路的网关,ARP 需要解析的是这一步的接收者。**A 的 IP 数据报仍以 C 为目标,外层帧却以网关接口的 MAC 为目标。
网关再查路由,在自己的出口链路解析下一跳并重新封装。没有 NAT 等转换时 IP 两端保持不变,MAC 随链路变化;原来的 ARP 广播不会被普通 IP 转发带到 C。所选网关取决于匹配路由,不一定总是默认网关。
7.4 每发送一个 IP 数据报都需要广播 ARP 吗?STALE 项能否使用?
考察重点:缓存复用、映射与可达性的区别、实现相关的验证策略。
相关内容:缓存项可以继续使用,也需要验证。
参考回答
**不需要。已有可用邻居映射时可以直接封装帧,系统另行维护映射和可达性状态。**Linux 的 STALE 项仍带有 MAC,发送可以先使用它,再按状态机验证,不等于立即删除后广播重查。
节点迁移或离线会让缓存过时,实现必须处理更新与失效。缓存寿命、探测方式和重试参数依赖系统,不能把某台机器的观察当作统一协议规定。
7.5 访问服务器超时,如何判断问题是否发生在 ARP 阶段?
考察重点:选路、邻居状态和报文证据的对应关系。
相关内容:从路由走到报文。
参考回答
**先查实际路由确定下一跳,再检查该接口上的邻居项和 ARP 请求、应答。**跨网段访问时应关注网关的映射,不能因为邻居表里没有远端服务器就判断异常。
如果请求持续没有应答、邻居项最终失败,检查当前链路、目标地址归属、VLAN、过滤或代理配置。如果已取得网关 MAC,则继续检查后续路由、回程和服务;ARP 成功并不能证明远端应用能正常响应。
7.6 ARP 公告是否能证明地址归属?代理 ARP 是否会转发广播?
考察重点:地址声明、认证、代理应答与转发范围的区别。
相关内容:地址声明与协议边界。
参考回答
**ARP 公告是映射声明,不是身份认证;代理 ARP 是代答请求,不是跨网段转发原广播。**接收方需要按自身规则处理公告,不能仅凭报文就证明发送方有权使用该 IP。
代理设备通常以自己的 MAC 回答另一个 IP 的查询,然后处理收到的后续数据流量。它仍依赖路由和链路条件,也不消除 ARP 缺少认证的边界。
8. 参考资料
- RFC 826:ARP 报文、发送与接收处理
- RFC 1122 §2.3.2:ARP 缓存维护与等待解析的报文
- RFC 5227 §2、§5:IPv4 地址冲突检测、公告与安全边界
- Linux 内核 6.6 文档:邻居参数、代理 ARP 与 ARP 应答配置
- iproute2 6.1.0:邻居表及其状态
- RFC 4861:IPv6 邻居发现
来源:Coding 101 原文 · 免费阅读,引用请保留出处。内容使用说明