ARP 协议完全图解

地址解析协议 —— 把「IP 地址」翻译成「MAC 地址」的局域网问询机制

二层与三层之间的桥梁 以太类型 0x0806 28 字节定长报文 广播问 · 单播答 缓存 / 免费 ARP / 代理 ARP

①一句话:ARP 是什么

ARP(Address Resolution Protocol,地址解析协议)的作用只有一件事:已知目标设备的 IP 地址,查出它的 MAC 地址。它是一个局域网内的问询协议——在本网段喊一嗓子「谁的 IP 是 192.168.1.1?请告诉我你的 MAC」,拥有该 IP 的设备举手回答。

核心动作

IP → MAC 的地址解析。反向(MAC → IP)叫 RARP,早已被 DHCP 取代。

工作方式

广播请求 + 单播应答。请求发给全网,只有 IP 匹配的那台回应。

作用范围

只在同一个广播域(局域网)内生效,不能跨路由器。跨网段解析的是网关的 MAC。

有无连接

无连接、无状态、无确认、无重传。问了没人答就超时,靠上层或缓存重试。

ARP 的一句话本质 我知道它的 IP 192.168.1.1 ARP 我还需要它的 MAC 才能发包 aa:bb:cc:dd:ee:ff 没有 MAC,以太网帧就封装不起来,数据包根本发不出网卡
图 1 · ARP 的全部使命:补上「IP」到「MAC」这最后一环

②为什么非要 ARP:两套地址的断层

互联网上有两套地址体系,各管一段,中间是断的:

  • IP 地址(三层/网络层):逻辑地址,可以变,用来做跨网络的端到端寻址。就像「收件人姓名 + 城市街道」。
  • MAC 地址(二层/数据链路层):物理地址,烧在网卡里,用来在同一段链路上找下一跳。就像「最后一公里具体是哪栋楼」。

问题来了:应用程序只知道目标的 IP,但网卡发包必须填 MAC。这个翻译工作没人做 —— 于是有了 ARP。

数据包下楼梯:每层都要补全自己那层需要的地址 应用层:我要访问 192.168.1.20(只知道 IP) 网络层:封装 IP 头 —— 源 IP 192.168.1.10 → 目的 IP 192.168.1.20 ✓ 齐了 数据链路层:封装以太头 —— 源 MAC 我知道,目的 MAC 呢?✗ 缺! ↓ 先发一个 ARP 请求把这个洞补上 拿到 MAC 后再重新封装,包才能发上链路
图 2 · 卡在二层:目的 MAC 不填,帧就出不了网卡
为什么不能干脆只用 IP?因为局域网里真正干活的是交换机,交换机看的是 MAC 地址表;而且历史上以太网比 IP 出现更早,二层链路(以太网、令牌环、FDDI…)各有各的地址格式,IP 必须能跑在任意一种之上。ARP 就是让「IP 地址」和「具体链路地址」解耦的那一层胶水。

③ARP 在第几层?一个经典争议题

严格说,ARP 不属于纯二层,也不属于纯三层,它是介于两者之间的协议。判断依据看封装:ARP 报文直接封装在以太网帧里,不经过 IP。

ARP 与 ICMP / TCP 的封装位置对比 以太头 · 类型 = 0x0800(IPv4) IP 头(协议号 6/17/1) TCP / UDP / ICMP 报文 普通数据包:IP 之上 以太头 · 类型 = 0x0806 ARP 报文(28 字节) 没有 IP 头! ARP:直接在二层之上 关键:以太网类型字段 0x0800 = IP 包,0x0806 = ARP 包,0x86DD = IPv6 包
图 3 · ARP 不走 IP,网卡靠「以太类型」字段区分该交给谁处理
对比项ARPICMP
封装位置直接在以太网帧里(无 IP 头)在 IP 数据报里
标识方式以太类型 0x0806IP 协议号 1
能否跨网段不能 只在广播域内能 由 IP 路由
层级归属介于二层与三层之间网络层(IP 的辅助协议)
面试标准答法:「ARP 工作在数据链路层与网络层之间,它为三层 IP 提供二层的地址解析服务。从封装看它不经过 IP,所以不能简单归为三层协议;从服务目的看,它服务于 IP,也不是纯粹的二层协议。」

④ARP 报文格式:定长 28 字节

ARP 报文结构完全固定(以太网 + IPv4 场景下恒为 28 字节),共 9 个字段,没有任何可选部分。

ARP 报文格式(共 28 字节 = 224 bit) 硬件类型(2 字节) 1 = 以太网 协议类型(2 字节) 0x0800 = IPv4 硬件地址长度 1 字节 · = 6 协议地址长度 1 字节 · = 4 操作码 Opcode(2 字节) 1 = 请求 · 2 = 应答 · 3/4 = RARP 发送方 MAC(6 字节) 谁在问 / 谁在答 发送方 IP(4 字节) 对方的应答要发回这里 目标 MAC(6 字节) 请求时填全 0(未知) 目标 IP(4 字节) 想查谁的 MAC 就填谁 以太头 14 字节 + ARP 28 字节 = 42 字节,不足以太网最小帧长 60 字节 → 需填充 18 字节 Padding(加上 4 字节 FCS 正好 64 字节),这就是抓包里常见的 [18 bytes padding]
图 4 · ARP 报文 28 字节逐字段,无任何可选字段

点开每个字段看说明

硬件类型2B
协议类型2B
硬件地址长1B
协议地址长1B
操作码2B
发送方MAC6B
发送方IP4B
目标MAC6B
目标IP4B
👆 点击上方任意字段,查看它的含义与作用。

请求与应答:只有三个字段不同

字段ARP 请求(Opcode 1)ARP 应答(Opcode 2)
以太网目的 MACFF:FF:FF:FF:FF:FF(广播)请求者的 MAC(单播)
操作码1(Request)2(Reply)
目标 MAC00:00:00:00:00:00(待填)被查询者的真实 MAC
其余字段发送方 MAC / IP、目标 IP 完全相同(应答相当于「把请求里的未知项填上再发回来」)
记忆技巧:ARP 应答就是把请求报文原地填空后单播发回——发送方/目标字段互换位置,目标 MAC 从全 0 补成真值,操作码 1 改 2。理解这一点,后面所有 ARP 变体(免费 ARP、代理 ARP)都只是这个模板的变体。

⑤同网段流程:广播问,单播答

以 192.168.1.10 首次访问 192.168.1.20 为例,完整走一遍:

同网段 ARP 解析四步曲 主机 A 192.168.1.10 MAC: AA:AA 交换机 收到广播 → 泛洪 主机 B 192.168.1.20 MAC: BB:BB ① 查缓存:A 先翻自己的 ARP 缓存表,有 192.168.1.20 的记录就直接用,没有才往下走 ② 广播 ARP 请求(Opcode 1) 「谁是 192.168.1.20?告诉 192.168.1.10」 ③ 非目标主机静默丢弃(IP 不匹配),只有 B 收下并记住 A 的 IP↔MAC ④ B 单播应答(Opcode 2)→ A 收下并写入缓存 → 之后真正的数据包才发出去
图 5 · 同网段:一次广播 + 一次单播,之后走缓存
被忽略的细节:ARP 是「双向学习」的。B 在收到 A 的请求时,就已经从报文里学到了 A 的 IP↔MAC 并写进自己的缓存 —— 所以即使 B 从不主动联系 A,它的缓存表里也会有 A。这也正是 ARP 欺骗能得手的原因之一:主机无条件相信收到的 ARP 报文并更新缓存,不验证真伪。
Q:为什么是「先广播问,再单播答」而不是「也广播答」?
效率。请求时不知道对方是谁,只能广播;应答时已经从请求报文里拿到了对方的 MAC(发送方 MAC 字段),直接单播即可,没必要打扰全网其他主机。

⑥跨网段流程:ARP 只问「下一跳」

核心结论:ARP 永远只解析「同一个广播域内」的地址。跨网段时,主机解析的不是最终目标的 MAC,而是网关(下一跳路由器)的 MAC。

跨网段:IP 头写最终目标,MAC 头写下一跳 主机 A 192.168.1.10 网关 192.168.1.1 路由器 R1 192.168.1.1 10.0.0.1 主机 C 10.0.0.20 网关 10.0.0.1 ① A 判断:目标 10.0.0.20 不在本网段(子网掩码算出)→ 该包交给网关 ② A 发 ARP 请求:「谁是 192.168.1.1(网关)?」 —— 注意,问的不是 10.0.0.20 ③ A 封装数据帧:目的 IP = 10.0.0.20(全程不变)|目的 MAC = R1 的 MAC ④ R1 收帧 → 剥掉以太头 → 查路由表 → 在 10.0.0.0 段重新发 ARP 问 C 的 MAC → 重新封装发出
图 6 · 跨网段:每一段链路都要重新做一次 ARP
一句话记住:IP 地址端到端不变(写最终收件人),MAC 地址逐跳改变(写当前这段路的下一站)。ARP 负责的永远只是「下一跳的 MAC」。
Q:如果主机没配网关会怎样?
访问外网时,主机算完子网掩码发现目标不在本网段,却找不到网关来转发,直接报「目标主机不可达」或「无可用路由」,连 ARP 都不会发。这是排查「能 ping 通内网、ping 不通外网」时的第一检查项。

⑦ARP 缓存:不可能每次都广播

如果每个包都要先广播问一次,网络会被 ARP 请求淹没。所以每台主机都维护一张 ARP 缓存表,解析一次记下来复用。

Linux 的邻居表状态机(比想象中复杂)

Linux 邻居条目状态流转(简化) INCOMPLETE REACHABLE 可达,直接用 STALE 过期未验证 DELAY 等一会儿 PROBE 单播探活 收到应答 探活成功 → 回到 REACHABLE 探活失败 → 删除条目,重新开始 REACHABLE 超时后不是立刻删,而是先转 STALE(仍可用)→ 有流量时进 DELAY → PROBE 单播确认 这样设计是为了「能不广播就不广播」,把 ARP 流量压到最低
图 7 · Linux 邻居状态机:从 REACHABLE 到 PROBE 的收敛过程
系统 / 设备缓存条目老化时间说明
LinuxREACHABLE 约 30 秒
STALE 后再保留约 60 秒
由 base_reachable_time_ms 与 gc_stale_time 控制,且带有随机抖动避免同步
Windows未使用约 2 分钟
使用中约 10 分钟
可用 netsh 调整
Cisco 路由器默认 4 小时(14400 秒)接口下 arp timeout 可改
表:不同系统的 ARP 老化时间差异很大,数值随版本变化,以实际设备为准
ARP 缓存是运维排障的高频坑。典型场景:换了一块网卡 / 迁移虚拟机 / VIP 漂移之后,其他机器缓存里还是旧的 MAC,导致网络不通。解决办法是等缓存老化,或主动刷新:Linux 用 ip neigh flush dev eth0,Windows 用 arp -d *。更根本的做法是靠免费 ARP 主动通告(见下节)。

⑧免费 ARP(Gratuitous ARP):不请自来的自我介绍

普通 ARP 是「我问你答」。而 免费 ARP 是主机主动、无缘无故地广播一条「我的 IP 是 X,我的 MAC 是 Y」—— 注意它其实是一个 ARP 请求(Opcode 1),只不过发送方 IP 和目标 IP 填的是同一个(自己),且不期待任何人回答。

免费 ARP:目标 IP 填自己,且不期待应答 以太网目的 MAC = FF:FF:FF:FF:FF:FF 操作码 = 1(仍是请求) 发送方 IP = 192.168.1.20 目标 IP = 192.168.1.20(自己!) 目标 MAC = 00:00:00:00:00:00 两大用途 ① IP 地址冲突检测 若有人已占用该 IP,会回一个 ARP 应答 → 屏幕上弹出「IP 地址冲突」警告 ② 主动刷新全网缓存 换网卡 / 虚拟机迁移 / VIP 漂移后广播一次 → 交换机与所有主机立刻更新 MAC,无需等老化
图 8 · 免费 ARP 的报文特征与两大用途
为什么 HA(高可用)切换要靠它?主备切换时 VIP 从 A 机漂到 B 机,如果 B 不主动广播免费 ARP,其他机器和交换机的缓存里 VIP 仍指向 A 的 MAC,流量会继续发给已挂掉的 A —— 这就是所谓的「VIP 漂移后网络不通」。B 开机接管时广播一条免费 ARP,全网缓存瞬间修正。

⑨代理 ARP(Proxy ARP):路由器“替人应答”

正常情况下,ARP 请求不会被路由器转发(广播域隔离)。但如果路由器开启了 代理 ARP,它会用自己的 MAC 地址冒充目标主机应答——让发起方误以为目标就在本网段。

代理 ARP:路由器代答,主机会把跨网段目标当成同网段 主机 A 192.168.1.10 路由器(开代理 ARP) MAC: RR:RR 主机 C 10.0.0.20(另一网段) 广播问 「谁是 10.0.0.20?」 路由器代答: 「是我,MAC = RR:RR」 A 把包发给 MAC=RR:RR,路由器收到后查路由表再转发给真正的 C —— A 全程不知道 C 在另一个网段
图 9 · 代理 ARP 让主机「看不见」网段的存在

✅ 好处

主机不配网关也能跨网段通信(甚至不配子网掩码也行),对老旧设备、嵌入式设备友好;某些拨号/PPP 场景会用到。

⚠️ 代价

主机 ARP 缓存被污染(多个 IP 映射到同一个路由器 MAC)、隐藏了真实网络拓扑使排障变难、增加 ARP 流量、放大欺骗风险。

现代网络通常关闭代理 ARP(Cisco 上默认开启,但最佳实践是 no ip proxy-arp),因为它的收益在「主机都能正确配置网关」的今天已经不大,而副作用明显。

⑩ARP 家族的其他成员

协议作用现状
ARP已知 IP → 查 MAC(Opcode 1/2)核心,广泛使用
RARP
(反向 ARP)
已知 MAC → 查 IP(Opcode 3/4)已淘汰,被 BOOTP / DHCP 取代。缺点:只能给 IP,不能给掩码、网关、DNS
InARP
(逆向 ARP)
已知对端 DLCI/虚电路 → 查对端 IP帧中继、ATM 时代使用,现已罕见
免费 ARP主动通告自己的 IP↔MAC冲突检测 + 刷新缓存,见第 ⑧ 节
代理 ARP路由器代答见第 ⑨ 节,现代多关闭
NDP(IPv6)IPv6 的地址解析,走 ICMPv6 的 NS/NA取代 ARP,见下表

IPv6 没有 ARP 了:NDP 上位

对比项IPv4 + ARPIPv6 + NDP
承载协议独立协议,直接封装在以太帧(0x0806)ICMPv6 的一部分(NS=135 / NA=136),封装在 IPv6 包里
寻址方式广播给全网(FF:FF:FF:FF:FF:FF)组播给「被请求节点组播组」,只有相关主机处理
额外能力只能解析地址还负责路由器发现(RS/RA)、前缀发现、重复地址检测 DAD、重定向
安全性无任何认证,易被欺骗设计上支持 SEND(安全邻居发现,加密认证),但部署率低
副作用广播打扰所有主机组播 + 二层可达性验证,更精确
表:NDP 不是 ARP 的简单改名,而是把「地址解析 + 邻居发现 + 无状态配置」打包重做

⑪ARP 欺骗:局域网里的“中间人”

ARP 协议的致命假设:所有报文都是可信的,收到就更新缓存,不验证身份。攻击者只要持续发送伪造的 ARP 应答,就能把自己插进通信双方之间。

ARP 欺骗:双向投毒,把自己伪装成双方 主机 A 192.168.1.10 攻击者 M MAC: MM:MM 网关 R 192.168.1.1 毒化 A 毒化 R M 对 A 说:「网关 192.168.1.1 的 MAC 是 MM:MM」→ A 的流量全发给 M M 对 R 说:「主机 192.168.1.10 的 MAC 是 MM:MM」→ R 的回程也全发给 M 结果:M 成为双向中间人,可窃听、篡改、断网(只投毒不转发 = 拒绝服务)
图 10 · ARP 双向欺骗:A↔R 的流量全部经过 M

防御手段

手段做法适用场景
静态 ARP 绑定手工写死 IP↔MAC 映射:arp -s 192.168.1.1 xx:xx:xx:xx:xx:xx主机少、拓扑固定的小网;规模大时不可维护
DHCP Snooping交换机只信任合法 DHCP 端口,建立 IP-MAC-端口绑定表企业网基础,是 DAI 的前置
DAI(动态 ARP 检测)交换机校验每个 ARP 报文是否与绑定表一致,不符即丢弃最有效的企业级方案,需接入层交换机支持
端口安全 Port Security限制每个物理端口允许的 MAC 数量防私接、防 MAC 泛洪
VLAN 细分缩小广播域,限制欺骗影响范围通用最佳实践
加密传输用 HTTPS / SSH / TLS 保证即使被窃听也读不懂兜底手段,无法防断网型攻击
为什么 ARP 欺骗在现代 Wi-Fi 上依然致命?因为 ARP 是二层协议且无认证,只要进了同一个广播域(连上同一个 Wi-Fi)就能发起。公共 Wi-Fi 风险尤其高——这也是「公共 Wi-Fi 不要传敏感信息」的技术根因。企业网的解法是在接入交换机上开 DHCP Snooping + DAI,从源头校验 ARP 报文真伪。

⑫实战命令与抓包

# ===== 查看 ARP 缓存 =====
$ arp -a                     # macOS / Windows 通用
$ ip neigh show              # Linux 推荐(显示状态:REACHABLE / STALE 等)
$ ip neigh show dev eth0

# ===== 清空 / 删除缓存(排障常用)=====
$ sudo ip neigh flush dev eth0     # Linux 清空某网卡的邻居表
$ arp -d 192.168.1.1               # 删除单条
C:\> arp -d *                       # Windows 清空全部(需管理员)

# ===== 主动发 ARP 请求探测(比 ping 更底层,不受禁 ICMP 影响)=====
$ arping -I eth0 192.168.1.1       # 看是否有 MAC 回应、是否多个 MAC 冲突

# ===== 抓 ARP 包 =====
$ sudo tcpdump -nn -i eth0 arp
# tcpdump 输出实例:一次完整的请求 + 应答
ARP, Request  who-has 192.168.1.20 tell 192.168.1.10, length 28
ARP, Reply    192.168.1.20 is-at bb:bb:cc:dd:ee:ff, length 28

# 免费 ARP(gratuitous):注意目标 IP 就是自己
ARP, Request  who-has 192.168.1.20 tell 192.168.1.20, length 28

# IP 冲突的表现:同一个 IP 被两个不同 MAC 应答
ARP, Reply    192.168.1.20 is-at bb:bb:cc:dd:ee:ff
ARP, Reply    192.168.1.20 is-at 11:22:33:44:55:66   # ← 冲突!
排障口诀:网络不通先分层
① ping 127.0.0.1 → 本机协议栈;② ping 网关 IP → 本网段链路与 ARP;③ arp -a 看网关 MAC 是否正确(错的 MAC = ARP 被欺骗或缓存过期);④ ping 外网 IP → 出网关的路由;⑤ ping 域名 → DNS。 ARP 问题通常暴露在第 ②③ 步。

⑬常见误区与一句话速记

误区一:ARP 是三层协议
不准确。它不经过 IP 封装(以太类型 0x0806),所以不是纯三层;它又服务于 IP 地址解析,也不是纯二层。标准说法是工作在数据链路层与网络层之间。
误区二:ARP 能跨网段解析目标主机
不能。ARP 只在同一个广播域内有效,跨网段时解析的是网关的 MAC,最终目标的 MAC 由最后一跳的路由器去解析。
误区三:ping 不通就是 ARP 问题
不一定。ARP 只负责「拿到 MAC」这一步。拿到 MAC 后还有 IP 路由、防火墙、ICMP 过滤、端口未监听等多种可能。反过来,arping 通而 ping 不通恰好说明二层没问题,问题在三层的 ICMP 被拦了。
误区四:ARP 有重传机制
没有。ARP 无连接、无确认、无重传。请求发出后没收到应答就超时丢弃,由上层协议(或应用重试)触发下一次解析。
误区五:IPv6 里也有 ARP
没有。IPv6 用 NDP(ICMPv6 的 NS/NA)取代 ARP,并且顺带把路由器发现、前缀通告、重复地址检测一起做了。

一句话速记

ARP = IP → MAC 的局域网问询协议:以太类型 0x0806、不走 IP、28 字节定长报文、广播请求 + 单播应答;
只在广播域内有效,跨网段解析的是网关(下一跳)——IP 端到端不变,MAC 逐跳改变;
缓存避免每次广播(REACHABLE → STALE → DELAY → PROBE);
免费 ARP 主动通告(冲突检测 + VIP 漂移刷新),代理 ARP 让路由器代答(现代多关闭);
无认证 = 可被欺骗,靠 DHCP Snooping + DAI 防御;IPv6 已用 NDP 取代它。