哈工大计算机网络课程网络层协议详解之:互联网控制报文协议(ICMP)
在互联网中,IP数据报的传输很容易出现差错,当出现差错时,最简单的处理办法就是对该IP数据报进行丢弃。但是,并不是直接丢弃就完了,为了让源主机感知到数据报出现差错,当数据报被丢弃时,IP网络会借助于ICMP协议,向发送数据报的源主机发送一个ICMP差错报文。本节详细介绍ICMP协议的原理和报文格式、以及用途。
互联网控制报文协议ICMP
ICMP协议支持主机或路由器:
- 差错(或异常)报告。
- 主动发送一些特殊的ICMP报文对网络进行探询。
实现上述功能的原理,主要是借助于发送一些特定的ICMP报文。根据ICMP协议所实现的功能,发送的ICMP报文可以主要分为以下两大类:
-
差错报告报文(5种)
- 目的不可达。 当IP数据报已经到达目的主机,但无法实现成功交付的场景(比如目的端口有异常),此时IP数据报会被丢弃,并向源主机发送这种“目的不可达”的ICMP报文。
- 源抑制(Source Quench)。 该报文与网络中的拥塞控制相关。当路由器发现自己缓存已满,导致新到的IP数据报会被丢弃时,会主动向源主机发送“源抑制”报文,希望源主机在收到该ICMP报文后,降低其自身数据发送速率。
- 超时/超期。 与IP数据报格式种的TTL字段相关。IP数据报中的TTL字段定义了该报文能够被路由器转发的次数,每转发一次,则TTL减一。当减为0时,会被路由器丢弃,并向源主机发送一个“超时/超期”ICMP报文,报告此类差错。
- 参数问题。 当路由器在转发一个IP数据报时,如果发现IP数据报中存在参数异常,则可以选择丢弃,并向源主机发送一个“参数问题”报文,报告此类差错。
- 重定向(redirect)。 当路由器收到一个IP数据报,而这个IP数据报所要到达的目的网络不应该由这个路由器进行转发,而应该由这个网络连接的另一个路由器进行转发的话。此时,路由器可以向源主机发送一个“重定向”报文,让源主机将到达这个网络的IP数据报重定向到另一个网关上去。
-
网络探询报文(2种)。 由主机或路由器主动发送探询网络状态。
-
回声(Echo)请求与应答报文(Reply)。
当主机向探询到另一个主机之间的网络是否通达,可以发送回声请求报文,通过接收回声报文的响应,来探测网络是否可达。此类报文最典型的,也就最经常使用的就是
Ping
工具。 -
时间戳请求与应答报文。
-
典型ICMP报文
典型ICMP报文示例如所示:
图中可以看出,ICMP报文是通过一个类型+编码的形式来标识不同类型报文,不同类型的报文对应了各自表示的含义。
ICMP例外情况
并不是所有IP数据报的出错,都会发送ICMP报文,下面是几种不发送ICMP差错报文的特殊情况:
-
对ICMP差错报告报文不再发送ICMP差错报告报文。
ICMP报文实际上是要封装到IP数据报中进行传输的,当一个IP数据报在传输过程中出错了,就会向源主机发送一个ICMP差错报文。这个差错报文会再次封装到另外一个IP数据报中,如果这个数据报出错了,就不再发送这个数据报的ICMP差错报文。
-
除第1个IP数据报分片外,对所有后续分片均不发送ICMP差错报告报文。
-
对所有多播IP数据报均不发送ICMP差错报告报文。
-
对具有特殊地址(如127.0.0.0或0.0.0.0)的IP数据报不发送ICMP差错报告报文。
其次,还有一些原始的ICMP报文,在现在的互联网中已经不再使用了:
- 信息请求与应答报文
- 子网掩码请求和应答报文
- 路由器询问和通告报文
ICMP报文格式
前面我们提到,ICMP报文是需要封装到IP数据报中进行传输的。因此,ICMP报文也是由首部和数据部分进行传输的。首部的前4个字节都是一样的,包括了类型、代码、校验和等信息。数据部分的长度取决于不同的ICMP报文类型。
下面以ICMP差错报告报文的报文格式来说明:
我们知道,ICMP差错报告报文是由于一个IP数据报在传输过程中差错或异常,此时该IP数据报会被丢弃,并向源主机发送ICMP差错报告报文。
在差错报告报文中,实际上,需要封装出差错的这个IP数据报的完整的IP首部,以及前8个字节的数据。为什么要这样做呢?
假设这个出差错的IP数据报封装的是一个UDP数据段,而对于UDP数据段来说,前8个字节包含了完整的UDP首部。 此时,对应构造的ICMP差错报文就会把完整的IP首部+UDP首部一起封装,返回给源主机。源主机就非常清晰地知道源和目的IP地址,端口号等重要信息。
假设这个出差错地IP数据报封装地是一个TCP数据段,对于TCP数据段来说,前8个字节不是完整地TCP首部(TCP首部完整应该是20个字节)。但是,TCP段首部前8个字节包含了重要的源端口号,目的端口号信息,有了这些信息,仍然能很好的还原出差错的IP数据报访问的是什么应用。
因此,综上所示,ICMP报文封装差错信息时,数据字段只封装了差错IP数据部分的前8个字节的数据。
进一步的,这些差错信息也要封装到IP数据报中,因此,上述差错IP数据报的首部,以及数据部分前8个字节,再加上ICMP协议定义的前8字节,共同构成了ICMP差错报文IP数据报的数据部分,最后添加上IP首部,即构成了最终封装好ICMP差错报文的IP数据报格式。
ICMP的应用举例:Traceroute
Traceroute工具主要是用来进行网络路径跟踪的,比如从源主机出发到达目的主机,经过哪些路由器等信息。
百度百科
traceroute (Windows 系统下是tracert) 命令利用ICMP 协议定位您的计算机和目标计算机之间的所有路由器。TTL 值可以反映数据包经过的路由器或网关的数量,通过操纵独立ICMP 呼叫报文的TTL 值和观察该报文被抛弃的返回信息,traceroute命令能够遍历到数据包传输路径上的所有路由器。
Traceroute实现的基本原理大概如下所示:
- 源主机向目的主机发送一系列UDP数据报。
- 在UDP数据报封装到IP数据报时,设置第一组IP数据报的TTL=1
- 发送第二组IP数据报时设置TTL=2,以此类推。
- 同时,确保目的端口号为目的主机不可能使用的端口号。目的是为了出差错,从而获取ICMP报文返回的信息。
- 当第n组数据报(TTL=n)到达第n个路由器时:
- 此时TTL=n-n=0,路由器会将该数据报丢弃
- 向源主机发送ICMP报文(type=11, code=0)
- ICMP报文携带路由器名称和IP地址信息
- 此时,源主机就探测到了第n个路由器的信息。
- 当ICMP报文返回源数据时,记录RTT
- 停止准则:
- UDP数据报最终到达目的主机
- 因为设置的目的端口是目的主机不可用的,势必目的主机会返回“目的端口不可达”类型的ICMP报文(type=3,code=3)
- 当源主机收到这样的ICMP报文时,就知道已经探测到了最终的目的主机,探测路径结束,并获取了整个链路的信息