2.5. 互联网控制消息协议

IP 还有一个我们尚未讨论的配套协议。这就是互联网控制消息协议 (ICMP),内核网络代码使用它来向其他主机传递错误消息。例如,假设您再次位于 erdos 上,并且想要 telnetquark 上的端口 12345,但是该端口上没有进程在监听。当针对此端口的第一个 TCP 数据包到达 quark 时,网络层将识别出此到达,并立即向 erdos 返回一条 ICMP 消息,声明“端口不可达”。

ICMP 协议提供了几种不同的消息,其中许多消息处理错误情况。但是,有一种非常有趣的消息称为重定向消息。当路由模块检测到另一个主机将其用作网关时(即使存在更短的路由),它也会生成此消息。例如,启动后,sophus 的路由表可能不完整。它可能包含到数学网络、FDDI 主干以及指向 Groucho 计算中心网关 (gcc1) 的默认路由的路由。因此,发往 quark 的数据包将被发送到 gcc1 而不是物理系的网关 niels。当接收到这样的数据报时,gcc1 将注意到这是一个糟糕的路由选择,并将数据包转发到 niels,同时向 sophus 返回一条 ICMP 重定向消息,告知其更优的路由。

这似乎是一种非常聪明的方法,可以避免手动设置任何路由,但最基本的路由除外。但是,请注意,依赖动态路由方案(无论是 RIP 还是 ICMP 重定向消息)并不总是一个好主意。ICMP 重定向和 RIP 在验证某些路由信息是否确实真实方面几乎没有或根本没有给您选择。这种情况使得恶意的无赖能够破坏您的整个网络流量,甚至更糟。因此,Linux 网络代码将网络重定向消息视为它们是主机重定向。这通过将其限制为仅一台主机,而不是整个网络,来最大限度地减少攻击的损害。另一方面,这意味着在合法情况下会产生更多的流量,因为每台主机都会导致生成 ICMP 重定向消息。通常认为,在当今的任何情况下,依赖 ICMP 重定向都是一种不良做法。