← 网络基础学习第 37 / 55 章基础40 分钟

模块五 · 链路层和局域网

ARP:把 IP 地址换成 MAC 地址

你要发一个包给 192.168.31.1,可是帧头里只能填 MAC 地址。你手上只有 IP 地址 —— 这个"翻译"是谁做的?这就是 ARP。本章会在你自己的机器上,抓到 ARP 缓存的五种状态,包括一次失败解析和一次探测的瞬间。

本章要解决的问题:你要发一个包给 192.168.31.1,可是帧头里只能填 MAC 地址。你手上只有 IP 地址 —— 这个"翻译"是谁做的?这就是 ARP。本章会在你自己的机器上,抓到 ARP 缓存的五种状态,包括一次失败解析和一次探测的瞬间。

本章的证据来源:历史实测记录(Get-NetNeighbor 状态机、对不存在主机的 ARP 解析、对 Stale 条目的探测)。报文格式出自 RFC 826。

先从一个例子理解概念

你知道同一条以太网链路上下一步接收者的IP,却还不知道该写哪个MAC。ARP就是用来询问这个对应关系的。

把下一跳IP查成MAC:ARP

ARP(地址解析协议)在本地链路上询问“哪个接口使用这个IPv4地址”。去远方服务器时,常查本地网关的MAC,而不是远端服务器的MAC。

出门先交给谁:网关与下一跳

去其他网络的包通常先交给某个路由器,这个接收者叫下一跳;常用默认出口叫默认网关。它不是DNS服务器这个概念,虽然家用盒子可兼任。

暂存查到的关系:邻居缓存

系统把近期地址映射与确认状态存起来,叫邻居缓存。缓存是暂存记录,不保证目标一直在线,状态也不是设备身份。

怎样读英文状态

Reachable表示近期确认;Stale表示确认已较旧;Incomplete表示尚无完整映射;Probe表示探测中。先记中文含义,再看它们怎样变化,不要把一个状态直接翻译成根因。

下面再用这些概念看原理、命令和结果。规范与官方资料列在本章末尾,类比只帮助理解,不代替协议规则。

为什么需要 ARP

回顾《全景与基础》模块讲过的矛盾:

你手上有的帧头需要的
标识IP 地址 192.168.31.1MAC 地址 A4-39-B3-0B-AB-19

要把数据发出去,必须知道对方的 MAC 地址。可是应用程序和 IP 层只知道 IP 地址。

ARP(Address Resolution Protocol,地址解析协议)就是补上这一环的协议。 它回答的问题只有一个:

注意 ARP 只在本网段内工作。 如果你要访问的是外网地址,ARP 查的不是目标服务器的 MAC,而是默认网关的 MAC —— 因为包要先交给网关。这一点在《网络层》模块讲路由时会再遇到。

ARP 报文长什么样

以太网解析IPv4时,ARP报文为28字节;协议本身支持不同硬件与协议地址长度:

字段长度作用
硬件类型2以太网填 1
协议类型2IPv4 填 0x0800
硬件地址长度1MAC 是 6 字节,填 6
协议地址长度1IPv4 是 4 字节,填 4
操作码21 = 请求,2 = 应答
发送方 MAC6我是谁
发送方 IP4我的 IP
目标 MAC6请求时填全 0(不知道才要问)
目标 IP4我要找谁的

ARP 一问一答的两个包

① 请求:广播
   谁有 192.168.31.1?请告诉 192.168.31.215
   目的 MAC = FF-FF-FF-FF-FF-FF(广播,全网的网卡都收下)

② 应答:单播
   我是 192.168.31.1,我的 MAC 是 A4-39-B3-0B-AB-19
   目的 MAC = 提问方的 MAC(只有它需要知道答案)

为什么首次地址解析通常广播

首次没有映射时通常广播请求;已知缓存映射的可达性探测可以单播,不能说ARP请求一律必须广播。

代价是什么? 同一个网段里所有设备都得收下这个帧、交给 ARP 模块处理一遍,然后发现"不是问我"再丢掉。这就是广播消耗 CPU 的由来。

如果每发一个包都广播一次 ARP,网络很快就被 ARP 报文的噪声淹没了。所以必须有缓存 —— 而这正是本章实测的重点。

实测:ARP 缓存的五种状态

ARP 不是"查一次记一辈子",而是一个带状态机的缓存。历史实测记录到的全部状态:

示例powershell
Get-NetNeighbor -AddressFamily IPv4 | Where-Object { $_.State -ne 'Permanent' }

实测结果(按状态分组):

状态含义历史实测记录到的条目
Reachable最近确认过,可以直接用192.168.31.1 → A4-39-B3-0B-AB-19;172.30.14.213 → 00-15-5D-FB-2F-0A
Stale曾经确认过,但已有映射但近期可达性确认过期;不等于禁止使用缓存发包192.168.31.248 → FA-AA-FF-92-E6-3F;192.168.31.126 → F6-E3-97-52-2A-56
Probe正在发 ARP 请求验证(过渡状态)192.168.31.51
Incomplete正在解析且尚无可用映射,不证明端点不存在192.168.31.222 → 00-00-00-00-00-00
Unreachable近期解析/探测未确认可达,不证明端点不存在192.168.31.0 → 00-00-00-00-00-00

注意 Stale 那一行:它仍然带着 MAC 地址。 这说明"Stale不等于映射不可用;后续探测与发包关系需查实现和抓包"。这个细节很关键,下一节的实验会用到。

实测一:对不存在的主机做 ARP 解析

ping 一个网段内不存在的地址:

示例powershell
ping -n 1 -w 2000 192.168.31.222

实测结果:

Pinging 192.168.31.222 with 32 bytes of data:
Request timed out.

  → 邻居缓存里出现了:
    192.168.31.222   MAC=00-00-00-00-00-00   State=Incomplete

这说明观察时尚无可用映射。 单凭Incomplete和超时不能证明请求确实发出、网段内没有设备或为何没有应答,仍需抓包和链路证据。

这个状态把两种失败区分开了:

现象缓存状态说明
ping超时且缓存Incomplete尚未取得映射可能是链路、隔离、丢包、端点或配置问题
ping超时且缓存Reachable有近期可达性信息不证明该次Echo一定送达,需检查ICMP路径与策略

实测二:抓到 Stale → Probe 的瞬间

原教程记录某条Stale邻居在ping附近出现Probe状态,并且第一次ping超时。这是时序相近的观察,不证明系统为ARP探测主动丢弃了ICMP,也不能断言第一次超时必然正常。

邻居状态机与发包可能并行。IPv6邻居发现明确规定:可用缓存链路地址继续发送,并在缺少确认时从Stale进入Delay再Probe。Windows IPv4行为须结合实现文档与同次抓包;不能直接把IPv6规范当成所有ARP实现的逐步证据。RFC 4861 §7.3.3、Microsoft ARP缓存行为

正确排查是保存连续探测、邻居状态和抓包时间线,再区分地址解析、ICMP策略、无线省电、丢包与超时设置。重试有助于观察,不代表“只要第二次通就证明第一次被ARP丢弃”。

为什么要有缓存和状态机

每次发包都广播解析会增加负担,永久使用旧映射又会造成错误转发,因此邻居缓存保存映射并按实现进行可达性确认和老化。

缓存是否可用于发送、何时发探测、何时排队或丢弃报文,应按状态与实现判断。 Stale、Incomplete、Reachable不能简单分别翻译成“必须先验证”“对方不存在”“对方永远可达”。

免费 ARP 与 ARP 欺骗

免费 ARP(Gratuitous ARP)

设备开机、或者换了网卡之后,会主动广播一条"我是 X,我的 MAC 是 Y",即使没人问它。用途有两个:

  1. 检测 IP 冲突:如果广播出去之后收到了别人的回应,说明这个 IP 已经有人在用了
  2. 通知大家更新缓存:网卡换了,主动告诉全网"以后发给我用新 MAC"

ARP 欺骗

ARP 协议没有任何认证机制 —— 谁来问都答,谁说自己是网关都信。这带来一个经典攻击方式:

攻击者持续广播:192.168.31.1(网关)的 MAC 是 我的 MAC
  → 全网设备的缓存都被污染
  → 你的所有上网流量都会先经过攻击者的机器
  → 这就是局域网里的「中间人攻击」

防御手段:

方法原理局限
静态 ARP 表手工写死网关的 MAC,不接受动态更新网关换网卡就要人工改
交换机上的动态 ARP 检测(DAI)交换机检查 ARP 报文是否和它记录的对应关系一致需要支持该功能的交换机

实测发现:TUN 接口的 ARP 条目

再回头看那张状态表,有一条很特别:

198.18.0.2       (空)         Reachable    FlClash

它是 Reachable,但 MAC 地址是空的。

因为 FlClash 是 TUN 虚拟网卡,工作在 IP 层,根本没有二层地址(《MAC 地址》那一章讲过)。Windows 的邻居缓存仍然为它建了条目,但永远填不上 MAC。

同一个命令、同一个系统,"有没有 MAC"这件事完全取决于接口的类型。 这是分层思想在运维层面的又一次体现。

常见误解

误解一:"ARP 是 IP 协议的一部分"

不是。ARP 是独立的协议,它介于链路层和网络层之间 —— 它用链路层的广播来工作,但解析的是网络层的地址。在 TCP/IP 分层模型里它通常被归到网络接口层。

误解二:ping超时能确定端点不存在。

超时可能来自地址解析、过滤、链路丢失或处理延迟;应连续观察并抓包,不能无证据归因为“Stale探测期间必然丢包”。

误解三:"ARP 缓存可以随便清"

实测:Remove-NetNeighbor 需要管理员权限,普通用户会得到 Access is denied。不过缓存自己会老化,日常不需要手动清。

误解四:"ARP 请求只发给目标设备"

请求是广播的,同网段所有设备都会收到并处理一遍。只有目标设备会回应,但所有设备都消耗了一次 CPU。这就是广播的代价。

本章小结

结论性质
以太网IPv4 ARP解析下一跳IP对应的MAC,作用于本链路RFC 826
该地址组合的ARP报文28字节,其他地址长度另算格式条件
首次解析通常广播,已有映射的探测可单播实现范围
缓存状态提供近期信息,不证明端点身份或绝对可达性诊断边界
首次ping超时与Probe相近出现不能单独证明因果证据限制
ARP无内建认证,需额外网络防护安全边界

自测题

7 题 · 先自己答,再展开对照

  1. 你要访问 192.168.31.1,你的机器是怎么知道它的 MAC 地址的?请描述完整的两个包。
    通过 ARP 的一问一答。
    第一个包(广播):目的 MAC 填 FF-FF-FF-FF-FF-FF,内容是「谁是 192.168.31.1?请告诉 192.168.31.215」。同网段所有设备都会收到。
    第二个包(单播):网关收到后回「我是 192.168.31.1,我的 MAC 是 A4-39-B3-0B-AB-19」,直接发给提问方。
    收到之后,本机把它记进邻居缓存(状态 Reachable),下次直接查缓存,不用再广播。
  2. 为什么 ARP 请求必须用广播,而应答可以用单播?
    首次没有目标MAC映射时通常广播;回复可利用请求中的发送者MAC单播。已有映射的探测也可单播,不能将所有ARP请求一律归为广播。
  3. ping 局域网里的一个地址超时了,邻居缓存显示 Incomplete,这说明什么?
    尚未完成映射解析;设备关闭、地址未用、VLAN隔离、链路/无线丢失或过滤都可能导致。不能确认设备不存在。
  4. 同上,但如果邻居缓存显示 Reachable(带正常 MAC),又说明什么?
    缓存有近期可达性信息,但不证明该次Echo已送达或端点仍正常;结合地址、接口、ICMP策略、端口和应用验证。
  5. 为什么 ARP 缓存不能设计成"查到了就永远记住"?
    IP与MAC映射可因换网卡、租约变化或接口移动而变化,缓存要有更新和老化。是否在验证期间继续发包取决于状态与实现,不能概括为每次都先阻塞验证。
  6. 攻击者怎么用 ARP 做中间人攻击?为什么这种攻击能成功?
    持续广播伪造的 ARP 应答,声称"网关的 MAC 是我的 MAC"。局域网上所有设备都会更新缓存,把本该发给网关的流量发到攻击者机器上,攻击者再转发给真正的网关(所以受害者感觉不到异常)。
    能成功的原因:ARP 协议没有任何认证机制 —— 它不验证"这条应答是不是真的来自声称的那台设备",谁来答都信。这是 ARP 设计年代的信任假设造成的。
  7. 你 ping 局域网里的一台设备,第一次超时、第二次通。这是故障吗?
    可能是正常瞬态,也可能是故障征兆。连续探测和状态/抓包时间线才能定位,不能直接说ARP探测必然丢掉首次ICMP。

参考资料与适用范围

修订核对日期:2026-10-13。规则按所列协议与实现范围理解;文中的原始命令输出是历史观察,不表示本次重新实测。跨版本、代理/隧道及不同捕获位置需要另行核对。

正文源自 m5-04-ARP.md · 共 14 节 · 7 道自测题