date | author | title | url | tags | series | categories | toc | draft | ||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
2022-04-09 09:39:00 +0800 |
Rustle Karl |
ICMP 协议详解 |
posts/protocols/docs/net/ip/icmp |
|
|
|
true |
false |
https://zh.wikipedia.org/wiki/%E4%BA%92%E8%81%94%E7%BD%91%E6%8E%A7%E5%88%B6%E6%B6%88%E6%81%AF%E5%8D%8F%E8%AE%AE
Internet 控制消息协议 ICMP(Internet Control Message Protocol): ICMP 它是 TCP/IP 协议簇的一个子协议,与 IP 协议、ARP 协议、RARP 协议及 IGMP 协议共同构成 TCP/IP 模型中的网络层。
主要用于在主机与路由器之间传递控制信息,包括报告错误、交换受限控制和状态信息等。当遇到 IP 数据无法访问目标、IP 路由器无法按当前的传输速率转发数据包等情况时,会自动发送 ICMP 消息。
控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。
ICMP 就是一个“错误侦测与回报机制”,其目的就是让我们能够检测网路的连线状况,也能确保连线的准确性。当路由器在处理一个数据包的过程中发生了意外,可以通过 ICMP 向数据包的源端报告有关事件。
- 侦测远端主机是否存在。
- 建立及维护路由资料。
- 重导资料传送路径(ICMP重定向)。
- 资料流量控制。
透过不同的类别 (Type) 与代码 (Code) 让机器来识别不同的连线状况。
ICMP 协议主要用来检测网络通信故障和实现链路追踪,最典型的应用就是 ping 和 traceroute。
通过发送回送请求报文和回送回答报文来检测源主机到目的主机的链路是否有问题,目的地是否可达,以及通信的延迟情况。Ping 用到的是 ICMP 协议,无端口的概念。
发送 ICMP 回显请求 (ICMP_ECHO) 给主机,等待主机返回回显应答 (ICMP_ECHOREPLY),来测试另一台主机是否可达。可以根据 ping 出的往返时间来确定主机离我们有多远。它只利用了 ICMP 的回显请求和回显应答报文,而不用经过传输层。
在 UNIX 中 ICMP 报文中的会把标识符字段设置为发送进程的 id 号,这样的话可以在同一台主机上同时运行多个 ping 程序。
客户程序在应答和请求之间进行匹配是通过序列号字段实现的。序列号从 0 开始,每法送一次新的回显请求就加 1。我们可以通过 ping 打印的序列号来确定分组是否有丢失、失序或者重复。
通过 IP 记录路由选项。ping 提供了一个 -R 选项,来记录路由的功能。每个路由处理数据报的时候都会都会把它的地址放入选项清单中。当数据报到达目的端时,IP 地址清单都会被复制到 ICMP 回显应答中,这样用户就可以通过 ping 的输出信息查看目的主机的 IP 了。
输出字节数,是 64 ;输出目的主机的 IP 地址,是通过 DNS 协议解析来的;输出 icmp_seq,是序列号,ttl,是 生存时间,time 是往返时间,如果是 0 是因为系统的计时器分辨率低。
- ping命令会先发送一个 ICMP Echo Request 给对端
- 对端接收到之后, 会返回一个 ICMP Echo Reply
- 若没有返回,就是超时了,会认为指定的网络地址不存在
通过发送探测报文来获取链路地址信息。第一个探测报文 TTL 为 1,到达第一个路由器时,TTL 减 1 为 0 所以丢掉这个探测包,同时向源主机发回 ICMP 时间超过报文,这时源主机就获得了第一个路由器的 IP 地址;接着源主机发送第二个探测报文,TTL 增 1 为 2,到达第一个路由器 TTL 减 1 为 1 并转发探测包到第二个路由器,这时 TTL 减 1 为 0,丢掉这个探测包并向源主机发回 ICMP 时间超过报文,源主机就获得了第二个路由器的 IP 地址;以此类推,直到探测报文到达 traceroute 的目的地,这时源主机就获得了到目的地的每一跳路由的 IP 地址。
ICMP 提供一致易懂的出错报告信息。发送的出错报文返回到发送原数据的设备,因为只有发送设备才是出错报文的逻辑接受者。发送设备随后可根据 ICMP 报文确定发生错误的类型,并确定如何才能更好地重发失败的数据包。但是 ICMP 唯一的功能是报告问题而不是纠正错误,纠正错误的任务由发送方完成。
我们在网络中经常会使用到 ICMP 协议,比如我们经常使用的用于检查网络通不通的 Ping 命令(Linux 和 Windows 中均有),这个“Ping”的过程实际上就是 ICMP 协议工作的过程。还有其他的网络命令如跟踪路由的 Tracert 命令也是基于 ICMP 协议的。
ICMP 报文包含在 IP 数据报中,IP 报头在 ICMP 报文的最前面。一个 ICMP 报文包括 IP 报头(至少 20 字节)、ICMP 报头(至少八字节)和 ICMP 报文(属于 ICMP 报文的数据部分)。当 IP 报头中的协议字段值为 1 时,就说明这是一个 ICMP 报文。
字段 | 说明 |
---|---|
类型 | 占一字节,标识 ICMP 报文的类型,从类型值来看 ICMP 报文可以分为两大类。第一类是取值为 1 ~ 127 的差错报文,第 2 类是取值 128 以上的信息报文 |
代码 | 占一字节,标识对应 ICMP 报文的代码。它与类型字段一起共同标识了 ICMP 报文的详细类型 |
校验和 | 这是对包括 ICMP 报文数据部分在内的整个 ICMP 数据报的校验和,以检验报文在传输过程中是否出现了差错(其计算方法与在我们介绍 IP 报头中的校验和计算方法是一样的) |
标识 | 占两字节,用于标识本 ICMP 进程,但仅适用于回显请求和应答 ICMP 报文,对于目标不可达 ICMP 报文和超时 ICMP 报文等,该字段的值为 0。 |
ICMP 报文的中来有两种:即 ICMP 差错报告报文和 ICMP 询问报文。
从 ICMP 的报文格式来说,ICMP 是 IP 的上层协议。但是 ICMP 是分担了 IP 的一部分功能。所以,他也被认为是与 IP 同层的协议。
ICMP 差错报文:即端口不可达报文。它是 ICMP 目的不可达报文的一种,这种差错报文是立刻返回的。
UDP 的规则之一是,如果收到一份 UDP 数据报,而目的端口与某个正在使用的进程不符,那么 UDP 返回一个 ICMP 不可达报文。(ICMP 报文是在主机之间进行交换的,不是目的端口号。UDP 是从一个端口号发给另一个端口号。)
ICMP 的一个规则是,ICMP 差错报文,必须包括生产该差错报文的数据报 IP 首部,还必须至少包括 IP 首部后面的前 8 个字节。IP 数据报= IP 首部 +ICMP 报文。
IP 数据报= IP 首部 +ICMP 首部 +ICMP 报文数据部分。
IP 数据报= IP 首部 +ICMP 首部 + 产生差错的数据报 IP 首部 + 原始 IP 数据报中数据的前 8 个字节。
常见的 ICMP 差错报文格式有 4 种:
类型的值 | ICMP 报文类型 | 描述 |
---|---|---|
3 | 终点不可达 | 当路由器或者主机不能交付数据时就向源主机发送终点不可达报文 |
11 | 时间超过 | 当路由器收到的 TTL 为 0 或者终点不能再预定的时间内收到一个数据报的全部数据时,丢弃该数据包外,还要向源点发送时间超过报文 |
12 | 参数问题 | 当路由器或者目的主机收到的数据报的首部中有的字段值不正确时就丢弃该数据报,并向源点发送数据报文 |
5 | 改变路由(重定向) | 路由器把改变路由报文发送给主机,让主机知道下次应将数据报发送给另外的路由器(可通过更好的路由) |
不再发送ICMP差错报告报文的几种情况:
- 对于ICMP差错报告报文,不再发送ICMP差错报告报文
- 对第一个分片的数据报片的所有后续数据报片,都不发送ICMP差错报告报文 。
- 对具有多播地址的数据报,都不发送ICMP差错报告报文
- 对具有特殊地址(如127.0.0.0或0.0.0.0.0)的数据报,不发送ICMP差错报告报文。
不产生ICMP差错报文的情况:
- ICMP差错报文(但是,ICMP查询报文可能会产生)
- 目的地址是广播地址或多播地址的IP数据报。
- 作为链路层广播的数据报。
- 不是IP分片的第一片。
- 源地址不是单个主机的数据报。 目的是为了不产生广播风暴。
ICMP 询问报文:主要有两种回送请求和回答和时间戳请求和回答。
第一种回送请求和回答:ICMP 回送请求报文是由主机或路由器向一个特定的目的主机发出的询问。收到此报文的主机必须给源主机发送一个 ICMP 回送回答报文。这种询问报文用来测试目的站是否可达以及了解其有关状态。
我们日常使用最多的 ping,就是响应请求(Type = 8)和应答(Type = 0),一台主机向一个节点发送一个 Type = 8 的 ICMP 报文,如果途中没有异常(例如被路由器丢弃、目标不回应 ICMP 或传输失败),则目标返回 Type = 0 的 ICMP 报文,说明这台主机存在,更详细的 tracert 通过计算 ICMP 报文通过的节点来确定主机与目标之间的网络距离。
第二种时间戳请求和回答:ICMP时间戳请求报文是请某台主机或路由器回答当前的日期和时间。时间戳请求和回答可用于时钟同步和时间测量(时间从1990年1月1日算起到当前时刻一共有多少秒)
时间戳请求报文(Type=13)和时间戳应答报文(Type=14)用于测试两台主机之间数据报来回一次的传输时间。传输时,主机填充原始时间戳,接收方收到请求后填充接收时间戳后以Type=14的报文格式返回,发送方计算这个时间差。一些系统不响应这种报文。