ICMP 协议

ICMP协议,全称Internet Control Message Protocol,也叫互联网控制报文协议。

0x00 简介

ICMP 常用的有两种类型的报文,一种是查询类型的,另一种是差错类型的。

查询类型的报文,它可以用来主动查询网络数据包是否可以到达目标主机;至于差错类型的报文,你可以把它理解成是报信的,它可以用来通报源主机,你发送的数据包出错了,到不了你指定的网络、主机或者端口,等等。

0x01 展开

查询类型报文

我们常用的 ping 程序,使用的就是查询类型的 ICMP 报文,它是一种主动请求,并且获得主动应答的 ICMP 协议。

对于主动请求的报文,称为 ICMP ECHO REQUEST,而主动请求的回复,称为ICMP ECHO REPLY。对 ping 程序的网络数据进行抓包,你就会看到这两个类型的数据包了。

ICPM 查询类型报文:

22:43:14.678840 IP 192.168.1.5 > blog.chenishr.com: ICMP echo request, id 59234, seq 0, length 64
22:43:14.689983 IP blog.chenishr.com > 192.168.1.5: ICMP echo reply, id 59234, seq 0, length 64

差错类型报文

前面说过,差错类型的报文是用来给源主机报信的,当互联网协议在传输过程中发生错误时,会给源主机发送一个ICMP的差错报文。常见的差错报文有以下几种:

第一种是终点不可达。很明显就是说数据包到达不了它指定的目标,如到达不了网络、主机等等。

具体的有以下几种场景:

  • 网络不可达
  • 主机不可达
  • 协议不可达
  • 端口不可达
  • 需要进行分片但设置了不分片位

那些不可达的目标很好理解,就是到达不了具体的网络、主机、端口等等。需要进行分片但设置了不分片位,这一点可能不好理解。这个场景的意思是这样子的,当数据包在传输路径中碰到一个 MTU 比较小的网卡,而且数据包的大小比那个 MTU 大时,必须要对数据进行分片,但是数据包设置了不可分片位,这时就会返回一个这样的差错报文。

第二种是源站抑制。源主机发送数据包的速度太快了,目标主机处理不过来,也就是让源主机放慢发送速度。

第三种是时间超时。IP数据报有个 TTL 的生存时间,每次经过一个路由节点就会减一,点到零还没到目标主机的话,就会发送一个时间超时的差错报文。

第四种是路由重定向。也就是让下次发给另一个路由器。

0x02 运用

ping 程序

ICMP 协议查询报文类型的典型运用是 ping 程序。ping 是我们日常工作中经常用到的,想要知道某个主机的网络通不通,ping 一下就知道了。

ping 程序执行的输出:

PING blog.chenishr.com (120.77.213.253) 56(84) bytes of data.
64 bytes from 120.77.213.253: icmp_seq=1 ttl=51 time=6.55 ms
64 bytes from 120.77.213.253: icmp_seq=2 ttl=51 time=65.9 ms
64 bytes from 120.77.213.253: icmp_seq=3 ttl=51 time=7.93 ms
64 bytes from 120.77.213.253: icmp_seq=4 ttl=51 time=30.4 ms
^C
--- blog.chenishr.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 6.552/27.717/65.967/24.030 ms

从输出可以看出,ping 程序发送了四个报文,都能正常收到回复,没有丢包,而且最后还有相应的统计信息。

工作原理

源主机首先会构建一个 ICMP 请求数据包,ICMP 数据包内包含三个重要的内容。第一个是类型字段,对于请求数据包而言该字段为 8;另外一个是顺序号,主要用于区分连续 ping 的时候发出的多个数据包,每发出一个请求数据包,顺序号会自动加 1;最后是发送时间,它被添加到报文的数据部分,为了能够计算往返时间 RTT。

目标主机收到请求后会构建一个 ICMP 应答包,应答数据包的类型字段为 0,顺序号为接收到的请求数据包中的顺序号,然后再发送出去给源主机。需要注意的是,目标主机可能会关闭响应 ICMP 请求。

源主机如果在规定的时候间内没有接到 ICMP 的应答包,则说明目标主机不可达;如果接收到了ICMP 应答包,则说明目标主机可达。此时,源主机会检查,用当前时刻减去该数据包最初从源主机上发出的时刻,就是 ICMP 数据包的时间延迟。

Traceroute 程序

Traceroute 程序是对 ICMP 差错报文类型的一个经典运用。我们主要用它来追踪网络数据包的路由途径。

Traceroute 程序执行输出:

traceroute to blog.chenishr.com (120.77.213.253), 30 hops max, 60 byte packets
 1  172.17.0.1 (172.17.0.1)  1.168 ms  1.091 ms  1.033 ms
 2  192.168.5.1 (192.168.5.1)  15.025 ms  15.352 ms  15.948 ms
 3  192.168.0.2 (192.168.0.2)  14.760 ms  14.683 ms  14.621 ms
 4  * * *
 5  113.106.40.50 (113.106.40.50)  208.131 ms 202.105.155.205 (202.105.155.205)  208.044 ms 61.146.241.233 (61.146.241.233)  208.000 ms
 6  183.56.65.6 (183.56.65.6)  208.619 ms 183.56.65.14 (183.56.65.14)  91.293 ms 183.56.65.86 (183.56.65.86)  91.100 ms
 7  119.147.223.110 (119.147.223.110)  90.981 ms  92.300 ms *
 8  183.2.182.130 (183.2.182.130)  92.160 ms 58.61.162.134 (58.61.162.134)  92.146 ms  92.076 ms
 9  183.61.45.10 (183.61.45.10)  92.041 ms 183.2.184.134 (183.2.184.134)  91.943 ms 183.61.45.10 (183.61.45.10)  91.948 ms
10  116.251.113.142 (116.251.113.142)  91.867 ms * 42.120.242.218 (42.120.242.218)  91.772 ms
11  42.120.253.2 (42.120.253.2)  91.730 ms 42.120.253.6 (42.120.253.6)  91.687 ms 116.251.117.153 (116.251.117.153)  103.880 ms
12  * * *
13  * * *
14  120.77.213.253 (120.77.213.253)  103.499 ms  103.443 ms  103.401 ms

其中前面的序号表示经过的第几个路由,序号后面是一个 IP 地址,即该路由的 IP。接下来是三个时间,Traceroute默认会向每个网关发送三个探测数据包,那三个数值是网关响应后返回的时间。还有出现星号的情况,那表示网关没有返回数据。

工作原理

程序使用了 IP 首部中的 TTL (生存周期)字段和 ICMP 的差错类型报文。

首先将 TTL 设为 1 ,当它到达第一个路由时就超时了,这样它就可以收到该路由返回的 ICMP 的时间超时差错报文;然后程序再将 TTL 设为 2,这样就可以拿到第二个路由的信息;以此类推,直到到达目标主机。

Traceroute 程序给目的主机发送的是一份 UDP 数据报,但它选择一个不可能的值作为 UDP 端口号(大于30000),使目的主机的任何一个应用程序都不可能使用该端口。这样目的主机就会给程序返回一个端口不可达的差错报文,程序就知道数据包已经到达目的主机了,不用再发送探测包了。

有了以上收集的信息,Traceroute 程序既可以将网络数据包的路由途径绘制出来了。

0x03 最后

本文主要介绍了 ICMP 协议查询类型和差错类型的报文,然后介绍了 ping 和 traceroute 程序是如果利用 ICMP 协议的功能来工作。

本文作者: chenishr

本文标题:《ICMP 协议》

本文地址: https://blog.chenishr.com/?p=822

©版权所有,除非注明, 永在路上文章均为原创,转载请以链接形式注明出处和作者细信息。