
前面已经讨论了路由器怎样获得路径、怎样转发 IP 数据报。但 IP 提供的是无连接、尽最大努力交付数据报可能因为目的地不可达、TTL 耗尽、首部异常或链路 MTU 不合适而被丢弃。如果网络层只负责“尽力发送”却从不反馈失败原因发送方就很难诊断问题。ICMP 正是 IP 的配套控制协议。它让主机或路由器报告网络层差错、响应诊断请求。我们常用的ping和tracerouteWindows 中通常为tracert都建立在 ICMP 提供的反馈能力之上。一、ICMP 位于哪一层ICMP 是 Internet Control Message Protocol 的缩写中文常译为网际控制报文协议。ICMP 报文被封装在 IP 数据报的数据部分中传输但它服务于 IP 的差错报告和网络控制因此通常归入网络层不能因为它封装在 IP 中就把它当成传输层或应用层协议。链路层帧 └── IP 数据报 └── ICMP 报文ICMP 的作用是报告问题或提供诊断信息而不是修复问题。路由器发出“目的不可达”报文并不会自动替源主机找出新路径收到 ICMP 反馈后源主机或上层程序才能决定重试、减小报文、换目标或提示错误。二、ICMP 报文包含什么不同 ICMP 报文的格式有所区别但都有几个基础字段字段作用类型Type指出这是回送请求、目的不可达、时间超过等哪一大类报文代码Code在同一类型内进一步说明原因校验和检查 ICMP 报文本身是否出错其余首部与数据随具体报文类型变化携带标识、序号或原数据报片段等信息差错报告通常会带回触发错误的原 IPv4 首部及其后至少一部分数据。这样源主机可以结合原数据报的协议、端口等信息判断错误对应哪一次通信而不是只收到一句没有上下文的“失败了”。ICMP 报文大体可分为两类差错报告报文告诉源端数据报在处理或转发时遇到了什么问题询问或信息报文主动请求对端响应用于连通性和状态诊断。三、常见的 ICMP 差错报告1. 目的不可达当路由器或目的主机不能交付数据报时可以向源端返回“目的不可达”。代码字段会进一步区分网络不可达、主机不可达、端口不可达等原因。例如UDP 数据报到达目标主机但目标端口没有程序监听目标主机可以返回“端口不可达”。如果路由器没有可用路由或策略禁止转发也可能产生相应的不可达反馈。2. 时间超过路由器转发 IPv4 数据报前会把 TTL 减 1。若结果变为 0路由器丢弃数据报并通常向源端发送 ICMP“时间超过”报文。这能阻止数据报在路由环路中无限存在也为 Traceroute 提供了逐跳发现路由器的能力。IPv4 分片重组超时也可能触发“时间超过”目的主机在规定时间内没有收齐全部分片就会放弃重组。3. 参数问题若路由器或目的主机发现 IP 首部中的关键字段不合法无法继续正确处理数据报可以丢弃它并返回“参数问题”指出首部存在异常。4. 重定向当路由器发现同一局域网内存在更合适的下一跳时可以向主机发送 ICMP 重定向提示它以后改用另一台路由器。重定向依赖网络环境和安全策略现代系统可能限制或禁用它不能把它当作通用动态路由协议。5. 源点抑制历史机制旧资料中还会看到“源点抑制”用于在拥塞时通知源端降低速率。该机制后来被废弃现代互联网的拥塞控制主要由 TCP 等传输层机制及其他网络信号完成。理解它的历史用途即可不应当把它视为当前网络的常规拥塞控制方法。四、为什么有些情况不发送 ICMP 差错报告ICMP 必须避免在网络异常时制造更多异常流量。典型限制包括对一个 ICMP 差错报告不再生成新的 ICMP 差错报告避免错误套错误对分片后的非首片通常不发送 ICMP 差错报告因为其中未必包含识别上层会话所需的信息对某些多播、广播或特殊源地址的数据报不返回差错报告避免产生大量响应或把报文发给无意义的源地址。因此数据报被丢弃不代表发送方一定能收到 ICMP。链路故障、防火墙过滤、设备限速和返回路径中断都可能让错误反馈本身无法到达。五、Ping怎样测试目标是否可达Ping 主要使用 ICMP回送请求和回送回答源主机向目标发送 ICMP 回送请求目标主机收到后返回 ICMP 回送回答源主机根据标识符和序号匹配请求与回答根据发送与收到回答的时间差计算往返时间 RTT并统计丢包情况。源主机 -- ICMP 回送请求 -- 目标主机 源主机 -- ICMP 回送回答 -- 目标主机Ping 可以帮助回答名称是否已解析为地址、目标是否愿意响应 ICMP、请求和回答是否存在可用路径、当前往返时延和丢包表现如何。但“Ping 不通”等于“服务器宕机”是常见误区。目标主机或中间防火墙可能只屏蔽 ICMP 回送Web、SSH 等业务端口仍然正常反过来Ping 成功也只能证明网络层回送通信可用不能证明应用服务一定健康。RTT 也不是单向时延。请求和回答可能走不同路径排队状况也会变化所以 Ping 的结果更适合作为诊断线索而不是所有业务性能的完整结论。六、Traceroute怎样一跳一跳发现路径Traceroute 的核心思路是主动控制 TTL让探测报文依次在第 1、2、3……跳过期。第一次探测TTL 为 1源主机发送 TTL 为 1 的探测报文。第一台路由器将 TTL 减为 0丢弃数据报并返回 ICMP 时间超过报文。源主机从该 ICMP 报文的源地址得知第一跳路由器并测出一次往返时间。后续探测逐步增大 TTL源主机继续发送 TTL 为 2、3、4……的探测报文。TTL 为 2 时报文在第二台路由器过期TTL 为 3 时在第三台过期。这样就逐步得到路径上的路由器序列。TTL1 - 第 1 跳返回“时间超过” TTL2 - 第 2 跳返回“时间超过” TTL3 - 第 3 跳返回“时间超过” ……怎样判断已经到达终点不同操作系统和工具实现不完全相同经典 Unix/Linux Traceroute 常发送 UDP 数据报到一个通常未监听的高端口到达目标后目标返回 ICMP“端口不可达”表示追踪结束Windowstracert通常使用 ICMP 回送请求目标返回回送回答时结束一些实现也支持 TCP 探测以适应不同网络过滤策略。所以“Traceroute 一定使用 UDP”或“一定使用 ICMP 回送”都不准确。真正共同的机制是逐步增加 TTL并利用中间路由器返回的 ICMP 时间超过报文识别每一跳。七、为什么 Traceroute 会出现星号或路径变化Traceroute 的结果并不是绝对、永久的网络地图。常见现象包括某一跳显示星号路由器没有回复、回复被过滤、ICMP 被限速或返回报文丢失后续跳仍出现某个中间路由器不响应不代表它没有继续转发业务数据多次结果不同网络可能进行等价多路径负载均衡或路由在探测期间发生变化往返时延突然升高可能是该路由器对控制报文处理较慢不一定代表经过它的转发流量同样拥塞显示的地址序列只反映返回 ICMP 的设备和当时路径不一定揭示所有内部隧道或二层设备。因此Traceroute 更适合定位“问题大致从哪一段开始”需要结合 Ping、路由表、接口状态和业务连接测试综合判断。八、ICMPv6 为什么更重要IPv6 使用 ICMPv6。它不仅承担差错报告和回送诊断还支持邻居发现、路由器通告等 IPv6 基础功能。上一篇 IPv6 文章提到中间路由器不对 IPv6 分组进行分片。当分组超过下一跳 MTU 时路由器会丢弃它并返回 ICMPv6“分组太大”报文源主机据此调整发送大小。这是 IPv6 路径 MTU 发现的重要环节。因此在 IPv6 网络中粗暴屏蔽所有 ICMPv6 可能破坏地址配置、邻居发现或正常的数据传输。安全策略应按类型和方向精细控制而不是把 ICMPv6 一律视为无用流量。九、常见误区误区更准确的理解ICMP 是传输层协议ICMP 封装在 IP 中但服务于网络层的控制与差错报告ICMP 能保证数据报可靠到达它只报告部分问题不负责重传也不保证差错报告一定送达Ping 不通就说明主机宕机可能只是 ICMP 被过滤或限速应用服务仍可能可用Ping 通就说明网站正常它只证明回送通信成功不能验证应用服务状态Traceroute 一定使用 UDP不同实现可使用 UDP、ICMP 或 TCP公共核心是递增 TTLTraceroute 某跳星号表示链路断了该设备可能只是不回复 ICMP后续数据仍可正常转发所有 ICMP 都应该被防火墙屏蔽过度屏蔽会妨碍诊断尤其可能破坏 IPv6 的基础机制十、总结ICMP 是 IP 的控制与反馈机制。目的不可达、时间超过、参数问题等报文让主机获知数据报为何失败回送请求和回答为 Ping 提供连通性、RTT 与丢包观测Traceroute 则通过递增 TTL利用沿途路由器的时间超过报文逐跳揭示路径。至此我们已经从地址、数据报、转发、路由选择一路看到网络诊断。下一篇将进入 SDN理解当控制平面从单台路由器中抽离并集中编程后网络的管理与转发方式发生了什么变化。如果这篇文章对你有帮助欢迎点赞、评论、关注、收藏。你们的支持是我前进的动力