cyf31头像

第 02 篇:ARP——IP 地址到 MAC 地址的“翻译官“

系列说明:《从 TCP/IP 到 AI 智算网络》每一步都让你动手做一遍。全程 VMware + Ubuntu,不需要专用硬件。

本篇定位:第一部分「TCP/IP 传统协议栈」第 02 篇。讲完最底层的以太网帧(第 01 篇),你自然要问:以太网只认 MAC 地址,那我知道对方 IP 地址,怎么拿到它的 MAC?这就是 ARP 干的事。


一、这个协议有什么用

ARP 全称

ARP = Address Resolution Protocol(地址解析协议)。

为什么需要 ARP?

回忆第 01 篇的比喻:以太网帧是"快递纸箱",纸箱上必须写收件人 MAC 地址(身份证号),快递员(交换机)才认。

但问题是——你在电脑上配的是 IP 地址(工号),应用程序也只知道对方的 IP。比如你敲:

bash

ping 192.168.95.130

系统只知道"我要找 192.168.95.130",但以太网纸箱上不能写 IP,必须写 MAC。

ARP 就是那个"把 IP 翻译成 MAC"的翻译官。

打个比方:

场景

网络对应

你知道同事的工号(IP),但不知道他坐哪

系统知道目标 IP,不知道目标 MAC

你在楼道里喊一嗓子:"工号 130 的同事,报一下你的座位号!"

ARP 广播请求

那个同事举手回答:"我是 130,我坐 A 排 3 号(MAC)"

ARP 单播应答

你记在脑子里,下次直接走过去

系统把 MAC 存入 ARP 缓存表

一句话总结:ARP 解决的是"我知道你 IP,但以太网要 MAC,怎么办"的问题。没有 ARP,局域网里任何两台机器都"说不上一句话"。


二、ARP 协议原理和交互过程

1. ARP 怎么工作(四步走)

纯文本

步骤 1:查缓存 → 系统先翻"小本本"(ARP 表),看之前记没记过

         │

         ├─ 记过 → 直接用,跳过 ARP(你上次抓包"先 ICMP 后 ARP"就是这个原因)

         │

         └─ 没记过 → 进入步骤 2

              │

步骤 2:广播喊话 → 发 ARP 请求(目的 MAC = ff:ff:ff:ff:ff:ff,全楼广播)

              │

步骤 3:目标回答 → 只有 IP 匹配的机器回 ARP 应答(单播,只告诉你)

              │

步骤 4:记小本本 → 系统把"IP ↔ MAC"存进 ARP 缓存,以后直接用

2. ARP 报文长什么样

ARP 报文直接装在 Ethernet II 帧的数据部分(不经过 IP 层!),EtherType = 0x0806。

字段

长度

说明

硬件类型

2 字节

固定 0x0001(以太网)

协议类型

2 字节

0x0800(要解析的是 IPv4)

硬件地址长度

1 字节

6(MAC 地址 6 字节)

协议地址长度

1 字节

4(IPv4 地址 4 字节)

操作码(Opcode)​

2 字节

1 = 请求(Request),2 = 应答(Reply)​

发送方 MAC

6 字节

谁在问 / 谁在答

发送方 IP

4 字节

谁在问 / 谁在答

目标 MAC

6 字节

请求时填 00:00:00:00:00:00(还不知道),应答时填对方的 MAC

目标 IP

4 字节

要查谁的 MAC

3. 请求 vs 应答对照

ARP 请求

ARP 应答

以太网目的 MAC​

ff:ff:ff:ff:ff:ff(广播,所有人收)

请求者的 MAC(单播,只给提问的人)

操作码​

1(Request)

2(Reply)

目标 MAC 字段​

00:00:00:00:00:00(不知道)

填请求者的 MAC

谁发​

想知道 MAC 的那台机器

被问到的那台机器


三、VMware 环境实测

1. 实验拓扑

和上一篇一样,VMnet1 自定义 LAN 段(192.168.95.0/24),两台 Ubuntu 虚拟机直连:

主机

IP

MAC

备注

Host A

192.168.95.128

00:0c:29:48:5d:fa

发起 ping 的一方

Host B

192.168.95.130

00:50:56:37:cb:08

被 ping 的一方

2. 实验步骤(重点:先清缓存!)

为什么要清缓存?​ 因为 Linux 会记住之前解析过的 MAC(缓存),如果不清,系统直接查表就用,你抓不到 ARP 广播过程。清掉缓存,才能看到"从零开始翻译"的完整流程。

终端 1(Host A 上,清缓存):

bash

# 先看看当前 ARP 表

arp -n# 或

ip neigh show

# 清空 ARP 缓存sudo ip neigh flush dev ens33

# 确认已清空

arp -n# 此时应该看不到 192.168.95.130 的条目

终端 2(Host A 上,开 Wireshark 抓包):

打开 Wireshark,选择 ens33 接口,设置过滤条件:

纯文本

arp || icmp

这样只显示 ARP 和 ICMP 报文,排除 NTP、DNS、IPv6 等干扰。

终端 1(Host A 上,触发流量):

bash

ping -c 1 192.168.95.130

3. 抓包结果解读

清完缓存后 ping 一次,Wireshark 里你会看到类似这样的报文序列:

No.

协议

源

目的

信息

1

ARP

192.168.95.128

Broadcast

Who has 192.168.95.130? Tell 192.168.95.128

2

ARP

192.168.95.130

192.168.95.128

192.168.95.130 is at 00:50:56:37:cb:08

3

ICMP

192.168.95.128

192.168.95.130

Echo request

4

ICMP

192.168.95.130

192.168.95.128

Echo reply

5

ARP

192.168.95.130

Broadcast

Who has 192.168.95.128? Tell 192.168.95.130

6

ARP

192.168.95.128

192.168.95.130

192.168.95.128 is at 00:0c:29:48:5d:fa

逐包拆解:

No.1(ARP 请求):

  • 以太网头:目的 MAC = ff:ff:ff:ff:ff:ff(广播),源 MAC = 00:0c:29:48:5d:fa(Host A),类型 = 0x0806(ARP)
  • ARP 内容:发送方 IP = .128,发送方 MAC = 48:5d:fa;目标 IP = .130,目标 MAC = 00:00:00:00:00:00(还不知道)
  • 操作码 = 1(Request)
  • 大白话:Host A 在楼道喊:"工号 130 的同事,我是 128,我的 MAC 是 48:5d:fa,你的 MAC 是多少?所有人都听着!"

No.2(ARP 应答):

  • 以太网头:目的 MAC = 00:0c:29:48:5d:fa(单播回给 Host A),源 MAC = 00:50:56:37:cb:08(Host B),类型 = 0x0806 
  • ARP 内容:发送方 IP = .130,发送方 MAC = 37:cb:08;目标 IP = .128,目标 MAC = 48:5d:fa 
  • 操作码 = 2(Reply)
  • 大白话:Host B 举手:"我是 130,我的 MAC 是 37:cb:08,只有 128 你听好了!"

No.3~4(ICMP):

  • ARP 表建好了,MAC 地址已知,直接封装以太网帧发 ICMP即ping报文(这就是第 01 篇拆的那个 98 字节包的来源)。

No.5~6(反向 ARP):

  • Ping 通后,Host B 也顺便查了 Host A 的 MAC(如果之前没缓存的话),完成双向映射。
  • 即这2个反向ARP报文:
  • 具体报文内容如下:

5. 验证 ARP 缓存

Flags Mask 列的 C 表示 Complete(已解析完成,缓存有效)。


四、ARP 缓存的生命周期

初学者最容易困惑的问题:"为什么我第二次 ping 就不发 ARP 了?"

因为 ARP 缓存有"保质期":

状态

含义

持续时间

REACHABLE​

刚解析完,确定可达

约 30~60 秒

STALE​

过期了,不确定对方还在不在

之后每次发包前会发单播 ARP 刷新

DELAY / PROBE​

正在重新探测

几秒内

FAILED​

探测失败,从表里删除

—

用命令查看详细状态:

bash

ip neigh show# 输出类似:# 192.168.95.130 dev ens33 lladdr 00:50:56:37:cb:08 REACHABLE

这就是为什么你上次抓包"先 ICMP 后 ARP"——那不是广播解析,是缓存变成 STALE 后的单播刷新。


五、ARP 故障排查速查

1. 常见问题一:ping 不通,Wireshark 里只有 ARP 请求,没有应答

可能原因:

  • 目标机器没开机 / 网卡没 up
  • 两台虚拟机不在同一个 VMnet(网段不同)
  • 防火墙拦截(少见,但 Ubuntu 默认不拦 ARP)

排查命令:

bash

# 确认 IP 在同一网段

ip addr show ens33

# 确认接口是 UP

ip link show ens33

# 手动发 ARP 请求测试

arping -I ens33 192.168.95.130

# 看有没有应答

arp -n

2. 常见问题二:ARP 表里有条目,但还是 ping 不通

可能原因:

  • MAC 地址缓存了旧的(比如虚拟机克隆后 MAC 变了)
  • IP 冲突(两台机器配了同一个 IP)
  • 虚拟机配置不对

排查命令:

bash

# 删除错误条目sudo ip neigh del 192.168.95.130 dev ens33

# 重新 ping 触发解析

ping -c 1 192.168.95.130

# 查看是否有 IP 冲突(看同一个 IP 对应多个 MAC)

arp -n# 如果看到同一个 IP 对应两个不同 MAC → IP 冲突了

# ifconfig显示NO-CARRIER,ping对端ping不通

可以改虚拟机配置,选择仅主机模式,重启虚拟机:

3. 常见问题三:ARP 表满了

排查命令:

bash

# 查看 ARP 表条目数

arp -n | wc -l

# 查看系统 ARP 表大小限制cat /proc/sys/net/ipv4/neigh/default/gc_thresh3

# 手动清空全部sudo ip neigh flush all

4. 排障速查表

现象

先看什么

命令

ping 不通

ARP 表有没有条目

arp -n

只有 ARP 请求没应答

对方是否在线、同网段

ip addr show + ping 对方

ARP 表有但通信失败

MAC 是否过期/错误

ip neigh show + sudo ip neigh flush

网络慢、丢包

是否有 IP 冲突

arping -I ens33 <IP> 看几个 MAC 回

怀疑 ARP 欺骗

同一 IP 对应多个 MAC

arp -n 反复观察


六、ARP 和后续协议的关系

协议

和 ARP 的关系

IP​

IP 包要发出去之前,必须先通过 ARP 拿到下一跳的 MAC

ICMP (Ping)​

Ping 之前先 ARP(你第 01 篇的抓包就是证据)

TCP/UDP​

第一次发包前也要先 ARP

路由转发​

路由器收到包后,查路由表决定从哪个口出,再 ARP 查下一跳 MAC

Gratuitous ARP​

免费 ARP——自己主动广播"我的 IP 是 X,MAC 是 Y",用来检测 IP 冲突 / 通告 MAC 变了(后面讲 VRRP 时会用到)

代理 ARP​

路由器替别人回答 ARP(老技术,了解即可)

IPv6 ND​

IPv6 不用 ARP,用邻居发现协议(NDP),本质干一样的事(下一篇会提)

依赖关系总结:

纯文本

应用层 (HTTP/DNS/...)

    ↓

传输层 (TCP/UDP)

    ↓

网络层 (IP)

    ↓

链路层 (Ethernet II)

    ↑ 发包前先查

ARP(翻译官:IP → MAC)

ARP 不是"装在 IP 里面"的,它是和 IP 平级的——都直接装在以太网帧里。​ 看 EtherType:0x0800 = IP,0x0806 = ARP,各走各的。


七、总结

今天你亲手做了这些事:

你做了什么

学到了什么

ip neigh flush 清空 ARP 缓存

ARP 表是"记忆",清掉才能看到完整解析过程

ping -c 1 触发通信

第一次通信必定先 ARP,后 ICMP

Wireshark 抓到 ARP 广播和单播应答

请求是广播(ff:ff:ff:ff:ff:ff),应答是单播

点开 ARP 包看 Opcode=1/2

请求是"喊话",应答是"私聊回信"

arp -n 查看缓存

MAC 地址被记住了,下次直接复用

ip neigh show 看 REACHABLE/STALE

缓存有生命周期,过期会刷新

arping 手动探测

排障利器,不依赖 IP 层

记住一句话:ARP 是 IP 到 MAC 的"翻译官"——以太网只认 MAC,不认 IP,ARP 负责把 IP 翻译成 MAC。请求广播喊一嗓子,应答单播回一句,翻译完记小本本,下次直接用。


下一篇预告

第 03 篇:VLAN(802.1Q)—— 一台交换机怎么"隔出多个房间"

ARP 解决了"同网段找 MAC"的问题,但如果局域网里机器越来越多,广播风暴、安全隔离、部门之间互串……怎么办?现实中不可能所有设备都挤在同一个广播域里。VLAN 就是给以太网帧"贴标签",把一台物理交换机逻辑上切成多个独立的虚拟局域网。下篇讲 VLAN 标签怎么插进 Ethernet II 帧、VMware 里怎么模拟多 VLAN 环境、以及 trunk/access 端口的区别。


附录:本文命令速查

bash

# 查看 ARP 表

arp -n

ip neigh show

# 清空 ARP 缓存sudo ip neigh flush dev ens33sudo ip neigh flush all

# 手动 ARP 请求(探测)

arping -I ens33 192.168.95.130

# 查看 ARP 缓存详细状态

ip neigh show

# 删除指定 ARP 条目sudo ip neigh del 192.168.95.130 dev ens33

# Wireshark 过滤# arp                    # 只看 ARP# arp.opcode == 1        # 只看请求# arp.opcode == 2        # 只看应答# eth.dst == ff:ff:ff:ff:ff:ff  # 广播帧# arp.src.proto_ipv4 == 192.168.95.128  # 指定源 IP 的 ARP


转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/cyf31/article/details/169651700

文章来源转载

评论

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--