4-8 网际控制报文协议ICMP
ICMP简介
为了更有效的转发 IP 数据报和提高交付成功的机会,在网际层使用了网际控制报文协议ICMP(Internet Control Message Protocol)
主机或路由器使用ICMP协议来发送差错报告报文和询问报文,ICMP报文被封装在 IP 数据报中发送。
ICMP差错报告报文共有以下 5 种,它们分别是
- 终点不可达
- 源点抑制
- 时间超过
- 参数问题
- 改变路由(重定向)
ICMP差错报告报文
终点不可达
终点不可达:当路由器或主机不能交付数据报时,就向源点发送终点不可达报文
具体可再根据ICMP的代码字段细分为
- 目的网络不可达
- 目的主机不可达
- 目的协议不可达
- 目的端口不可达
- 目的网络未知
- 目的主机未知
- ……
等 13 种错误,我们来举例说明。

假设主机 H1 给 H2 发送 IP 数据报, H1 会将 IP 数据报发送给路由器R1,由 R1 帮其转发。若 R1 的路由表中没有网络 N3 的路由记录、默认路由以及主机 H2 的特定主机路由,则R2依旧不知道如何转发该数据报,只能将其丢弃并向发送该数据报的源主机 H1 发送ICMP差错报告报文,其类型为终点不可达。
源点抑制
源点抑制:当路由器或主机由于拥塞而丢弃数据报时,就向源点发送源点抑制报文,使源点知道应当把数据报的发送速率放慢。
例如, H1 给 H2 发送 IP 数据报,当该数据报传输到路由器 R2 时,由于 R2 拥塞,也就是 R2 比较繁忙, R2 根据自己的丢包策略丢弃了该数据报,并向发送该数据报的源主机 H1 发送ICMP差错报告报文,其类型为源点抑制。

又例如, H1 给 H2 发送 IP 数据报,当该数据报传输到 H2 时,由于 H2 拥塞,就丢弃了该数据报,并向发送该数据报的源主机 H1 发送ICMP差错报告报文,其类型为源点抑制。

时间超过
时间超过:当路由器收到一个目的IP地址不是自己的 IP 数据报时,会将其生存时间 TTL 字段的值减1,若结果不为0,则将数据报转发出去。若结果为0,除丢弃该数据报外,还要向源点发送时间超过报文。
例如,某个生存时间等于 2 的 IP 数据报传输到了路由器R1, R1 将其生存时间减 1 后,结果是1,这表明该数据报的生存时间还没有结束, R1 将其转发出去。当该数据报传输到路由器 R2 后, R2 将其生存时间减 1 后,结果是0,这表明该数据报的生存时间结束了。

R2 丢弃该数据报,并向发送该数据报的源主机 H1 发送ICMP差错报告报文,其类型为时间超过。

另外,当终点在预先规定的时间内不能收到一个数据报的全部数据报片时,就把已收到的数据报片都丢弃,也会向源点发送时间超过报文
参数问题
参数问题:当路由器或目的主机收到 IP 数据报后,根据其首部中的检验和字段,发现手部在传输过程中出现了误码,就丢弃该数据报,并向源点发送参数问题报文。
例如,这是 H1 发送给 H2 的 IP 数据报,假设该数据报在传输过程中受到了干扰,其手部出现了误码,当该数据报传输到路由器 R1 后, R1 检测出该数据报的首部出错,于是丢弃该数据报并向发送该数据报的源主机 H1 发送 ICMP 差错报告报文,其类型为参数问题。

改变路由
改变路由:路由器把改变路由报文发送给主机,让主机知道下次应将数据报发送给另外的路由器,这样可以通过更好的路由。
举例说明,假设我们给主机 H1 指定的默认网关是路由器R1,则 H1 要发往网络 N2 的 IP 数据报都会传输给R1,尤其帮忙转发。

当 R1 发现 H1 发往 N2 的数据报的最佳路由不应当经过R1,而是应当经过 R4 时,就用改变路由报文把这个情况告诉主机。

于是 H1 就在自己的路由表中添加一个项目,到达 N2 应经过路由器R4,而不是默认网关 R1 之后, H1 要发往 N2 的 IP 数据报都会传输给R4,尤其帮忙转发。
以下情况不应发送ICMP差错报告报文
需要注意的是,以下情况不应发送ICMP差错报告报文:
对ICMP差错报告报文不再发送ICMP差错报告报文。
对第一个分片的数据报片的所有后续数据报片都不发送ICMP差错报告报文。
对具有多播地址的数据报,都不发送ICMP差错报告报文
对具有特殊地址,例如127.0.0.0或0.0.0.0的数据报,不发送ICMP差错报告报文
习题

ICMP询问报文
接下来我们介绍常见的两种ICMP询问报文,一种是回送请求报文及其回答报文,另一种是时间戳请求报文及其回答报文。
ICMP回送请求报文
ICMP回送请求报文是由主机或路由器向一个特定的目的主机发出的询问。收到此报文的主机必须给源主机或路由器发送ICMP回送回答报文。这种询问报文用来测试目的战是否可达,以及了解其有关状态。
ICMP时间戳请求报文
ICMP时间戳请求报文是请求某个主机或路由器回答当前的日期和时间。
在ICMP时间戳回答报文中有一个 32 位的字段,其中写入的整数代表从 1900 年 1 月 1 日起到当前时刻一共有多少秒,这种询问报文用来进行时钟同步和测量时间。
ICMP协议的两个典型应用
接下来我们介绍利用ICMP协议的两个典型应用,一个是分组网间探测,另一个是跟踪路由。
分组网间探测PING(Packet InterNet Groper)
分组网间探测:该应用用来测试主机或路由器之间的连通性,其应用层直接使用网机层的ICMP协议,而不通过运输层的 TCP 或 UDP 协议,所使用的ICMP报文类型为回送请求和回答。
如下所示,这是在主机的 windows 命令行中,使用拼命令来测试该主机与我校官方网站服务器的连通性。

跟踪路由traceroute
跟踪路由:该应用用来测试 IP 数据报从源主机到达目的主机要经过哪些路由器。
在该应用的 windows 版本中,具体命令为tracert,其应用层直接使用网际层的ICMP协议,所使用的ICMP报文类型有:回送请求和回答报文以及差错报告报文。
在该应用的 Unix 版本中,具体命令为 traceroute,其在运输层使用 UDP 协议,在网际层使用的ICMP报文类型只有差错报告报文
如下所示,这是在我的主机的 windows 命令行中,使用tracert命令来测试该主机与我校官方网站服务器之间要经过哪些路由器

tracert命令实现原理
举例说明,假设主机H1想知道到达主机 H2 要经过哪些路由器, H1 就给 H2 发送ICMP回送请求报文。该报文被封装在 IP 数据报中, IP 数据报首部中生存时间字段 TTL 的值被设置为1,该 IP 数据报到达 R1 后,其生存时间减1,结果为 0 ,R1 丢弃该数据报,并向发送该数据报的源主机 H1 发送ICMP差错报告报文,其类型为时间超过。这样 H1 就知道了到达 H2 的路径中的第一个路由器

H1 继续发送下一个封装有ICMP回送请求报文的 IP 数据报,其首部中生存时间字段 TTL 的值被设置为2。经过 R1 的转发后,该数据报的生存时间减少为1。该 IP 数据报到达 R2 后,其生存时间减1,结果为0, R2 丢弃该数据报,并向发送该数据报的源主机 H1 发送ICMP差错报告报文,其类行为时间超过,这样 H1 就知道了到达 H2 的路径中的第二个路由器

H1 继续发送下一个封装有ICMP回送请求报文的IP数据报,其首部中生存时间字段 TTL 的值被设置为3。经过 R1 和 R2 的转发后,该数据报到达主机H2,其生存时间减少为 1 。H2解析该数据报,发现其内部封装的是ICMP回送请求报文,于是就给 H1 发送封装有ICMP回送请求回答报文的 IP 数据报,这样 H1 就知道已经跟踪到路径中的最后一站,也就是目的主机H2。

本节小结
