计算机网络学习站

kp-013 · 03-网络层与路由

ARP 与 ICMP:地址解析与控制消息

核心 约 25 分钟 ARPICMPpingtraceroute
我的进度:

注:本文基于模型知识整理,建议结合权威教材与 RFC 原文核对细节。

一句话定义

ARP(Address Resolution Protocol,地址解析协议)负责在同一链路内把 IP 地址解析成 MAC 地址;ICMP(Internet Control Message Protocol,网际控制报文协议)承载于 IP 之上,负责传递差错报告与询问消息,ping 与 traceroute 都建立在它之上。

为什么重要

IP 选路只回答「下一跳是谁」,把帧真正送上链路还差「下一跳的 MAC 是多少」——没有 ARP,三层选路在第二层寸步难行。ICMP 则是网络的控制平面:连通性诊断、路径追踪、TTL 超时通知全部由它完成。掌握这两个协议,就能独立完成从「ping 不通」到「哪一跳断了」的系统化排障。

前置知识

建议先读 kp-012《IP 数据报格式、分片与转发》,理解 IP 首部中协议字段与 TTL 字段的含义、路由转发时逐跳更换 MAC 的事实;建议同时具备以太网帧结构的基本认识。

核心概念

  • 一跳一定位:每条链路上的帧都需要链路层地址才能投递。发送方只掌握下一跳的 IP,必须先把它解析成 MAC,帧才能封装发出,这就是 ARP 的存在理由。
  • ARP 工作流程(RFC 826):主机 A 要与同网段的 192.168.1.20 通信但缓存无记录时,广播 ARP 请求(目的 MAC 为 FF:FF:FF:FF:FF:FF),内容为「谁是 192.168.1.20,请告诉 192.168.1.10」;链路上全体主机收到,非目标主机丢弃;目标主机 B 以单播应答自己的 MAC;A 写入 ARP 缓存,B 也顺带记下 A 的映射。
  • ARP 缓存与老化:解析结果存入缓存供后续复用,条目带老化时间,超时删除后需重新解析,以适应地址或网卡的变化。
  • 跨网段解析的对象是网关:主机用自身掩码判断目的地址是否同网段;不同网段时帧的目的 MAC 填默认网关的 MAC,而不是最终目的主机的 MAC,网关收到后在下一链路重复解析过程。
  • 免费 ARP(gratuitous ARP):主机未经请求主动广播「自己的 IP 对应自己的 MAC」,用于让邻居刷新缓存,并辅助检测地址冲突。
  • ARP 欺骗:攻击者伪造 ARP 应答,把他人 IP 映射到自己的 MAC,从而截获或篡改同网段流量(局域网攻击面详见 kp-032)。
  • ICMP 两类报文(RFC 792):差错报告类含终点不可达、超时(TTL 归零或重组超时)、参数问题、改变路由;询问类含 Echo 请求与 Echo 应答。为防报文风暴,规定不针对 ICMP 差错报文再发 ICMP 差错报文。

图示

同一以太网内的 ARP 解析

主机 A 192.168.1.10                           主机 B 192.168.1.20
     |                                               |
     |---- ARP 请求(广播 FF:FF:FF:FF:FF:FF)------->|
     |    "谁是 192.168.1.20?请告诉 192.168.1.10"    |  链路上全体收到,
     |                                               |  非目标主机直接丢弃
     |<--- ARP 应答(单播回 A)----------------------|
     |    "192.168.1.20 的 MAC 是 MAC_B"              |
     |                                               |
 A 写缓存:192.168.1.20 -> MAC_B(开始老化计时)
 B 顺带缓存:192.168.1.10 -> MAC_A

原理与机制

结构上 ICMP 并非「IP 的附属子协议」:ICMP 报文整体作为 IP 数据报的净荷传输,IP 首部协议字段填 1,地位与 TCP、UDP 平级,是承载在 IP 之上的控制协议;而 ARP 连 IP 封装都不经过,直接封装在以太网帧中(帧类型 0x0806),工作在网络层与链路层之间的边界。ping 的原理是发 Echo 请求、收 Echo 应答并计时:输出中的 time 即往返时延 RTT;应答中的 TTL 还能粗略推断距离——常见系统初始 TTL 为 64 或 128,用初始值减去收到值即大约的跳数。traceroute 与 tracert 的原理是把 TTL 从 1 开始递增:TTL 为 n 的探测包会在第 n 台路由器归零,该路由器回送 ICMP 超时报文,其源地址即第 n 跳地址;到达终点的判定方式因实现而异。Linux traceroute 默认发送目的端口为高位随机端口的 UDP 报文,终点主机回 ICMP 终点不可达(端口不可达)表示已到达;Windows tracert 发送 ICMP Echo 请求,终点回 Echo 应答表示已到达。

实例分析

一次典型排障:内网主机 ping 网关通,ping 公网 IP 超时,ping 公网域名报解析失败。逐层判断:ping 网关通说明 ARP 与本链路正常;对公网 IP 的探测超时,说明三层转发受阻或被防火墙拦截;域名解析失败则把矛头指向 DNS 配置。再用 traceroute 定位:输出在前两跳之后全部显示星号且跳数不再增加,说明流量在第三跳附近被丢弃或过滤,结合该跳应属运营商网关的常识,即可向运营商报障并给出断点位置。整个过程里 ARP 解决「本链路找谁」,ICMP 回答「断在哪里」。

常见误区

  • 以为跨网段通信要解析最终目的的 MAC:解析的始终是同一链路上下一跳(通常是网关)的 MAC。
  • 把 ICMP 当成 IP 的一部分或子协议:它是以协议号 1 独立封装的报文,与 TCP、UDP 平级。
  • 以为 ping 通就等于业务可达:很多设备放行 ICMP 却拦截业务端口,反之亦然。
  • 以为 ARP 缓存永久有效:老化时间一到即删除,地址变更后旧映射不可信。

自测题

  1. 主机 A(192.168.1.10/24)访问 8.8.8.8 时,第一个 ARP 请求解析的是谁的地址?

答案要点:默认网关的 MAC。目的地址不在本网段,帧必须先交给网关,而 ARP 只能解析同链路地址。

  1. 免费 ARP 与普通 ARP 请求的区别是什么?

答案要点:免费 ARP 无需触发、主动广播自己的 IP 到自己 MAC 的映射,用于刷新邻居缓存并辅助检测地址冲突。

  1. traceroute 为什么能逐跳列出路由器地址?

答案要点:发送 TTL 依次为 1、2、3 的探测包,第 n 台路由器把 TTL 减到 0 时回 ICMP 超时,其源地址就是第 n 跳。

  1. Linux traceroute 与 Windows tracert 在终点判定上有何差异?

答案要点:Linux 用 UDP 高位端口探测,终点回 ICMP 端口不可达;tracert 用 ICMP Echo 探测,终点回 Echo 应答。

  1. 为什么说 ICMP 不是「IP 的子协议」?

答案要点:ICMP 报文作为完整净荷封装在 IP 数据报中(协议号 1),与 TCP、UDP 同级,是独立的控制消息协议,只是功能上依附 IP。

延伸阅读

  • RFC 826《An Ethernet Address Resolution Protocol》
  • RFC 792《Internet Control Message Protocol》
  • W. Richard Stevens《TCP/IP 详解 卷 1:协议》