计算机网络(TCP/IP原理)|34、ICMP协议
本节要学习的内容是关于ICMP协议的,通过ICMP协议了解网络层的IP数据包在传输过程中出了差错的情况下,如何把差错情况报告给数据发送的源主机。学习ICMP报文的格式,以及ICMP的两种类型。
ICMP报文 ICMP,全称“Internet Control Message Protocol”,意思是“网络控制报文协议”。这个协议是属于网络层的协议。当然,您可能注意到,我在这里使用了“ICMP报文”这个名词,而报文是传输层和应用层的PDU,这就是ICMP协议比较特殊的一点,协议本身并不是高层的协议,但是却使用了“报文”这个名词。
那么为什么会这样呢,是因为ICMP这个协议本身带有一点特殊性,ICMP的数据是要放在IP数据包的数据部分里面传输的。这样在逻辑上来说,ICMP就要比IP高一层,但我们要知道在事实上ICMP其实也属于网络层,所以在这里会用到比数据包在逻辑上更高一层的报文的概念。
下图为ICMP报文与IP数据包的承载关系:
文章图片
通过上图,我们可以看到,ICMP报文的结构组成和IP数据包是类似的,也是分为首部和数据部分,我们关注的重点仍然是首部的格式,见下图:
文章图片
首先第一个字段,类型。这个字段可以说是ICMP报文最重要的一个字段了,因为类型字段的值不仅指明了某个ICMP报文的类型,而且还会影响到首部剩余部分的格式,还会影响到整个ICMP报文的数据部分的长度。
第二个字段是代码。在某一类的ICMP报文中又会有几种不同的情况,代码字段的值就是指明具体的情况。
第三个字段是校验和,ICMP的校验和字段用来检验整个ICMP报文(包括首部和数据部分)。要注意和IP数据包首部的校验和区分开,IP首部的校验和之检验IP首部,不管数据部分。
ICMP报文类型 要了解ICMP的类型,首先还是要从根本上进行把握,ICMP协议的作用就是传递控制信息,比如说当源主机给目的主机发送出去的数据由于一些原因没到达目的端,这其中是哪个环节除了差错,就需要把差错信息报告给源主机,或者说测试两个主机之间的路由是否可达等网络状态的信息,这些都属于网络控制信息,需要用ICMP报文来传递。
所以说,ICMP报文从大的方面也就分为了两种类型,一种是“ICMP差错报告报文”来报告数据传输中的差错问题,另一种是“ICMP询问报文”可以描述出网络连通状态。(当然还有这两种大的类型内部又分为好多小的具体的类型,下面我们会介绍几种常用的以及考试常考的)。
不同类型的报文,是通过ICMP首部的类型字段的值来表现的,不同值代表不同类型,如下表:
差错报告报文:
类型值 | 代码值 | 类型描述 |
3 | 0、1、2、3 | 终点不可达 |
5 | 0 | 路由重定向 |
11 | 0 | 时间超过 |
12 | 0 | 参数问题 |
差错报告类型 当ICMP报文首部的类型字段值为3时,表示此报文属于差错报告报文这一类,具体的出错原因是终点不可达。终点不可达的意思是:主机或路由器不能交付数据包。比如说目的主机不存在或者处于关机状态,或者路由器不能为该数据包找到合适的路由,都会出现终点不可达。
但是只凭终点不可达,还是不能判断出具体是怎么不可达的情况,这时候借助代码的值可以帮助进一步说明情况:
类型值 | 代码值 | 类型描述 |
---|---|---|
3 | 0 | 网络不可达 |
3 | 1 | 主机不可达 |
3 | 2 | 协议不可达 |
3 | 3 | 端口不可达 |
文章图片
当一个主机A要访问另一台主机B,发送出去的数据包要经过路由器RA,再经过路由器RB,RB通过查询自己的路由表发现,不用再转发到别的路由器了,直接交付到目的主机即可了。但是现在新加了一台路由器RC,我们假设数据从主机A到主机B如果走经过RC的这条路的话,不管从跳数还是从链路状态来讲都更优,那么当RA收到主机A要发往主机B的数据包时,就会给主机A发送一个路由重定向的ICMP报文,告知主机A以后走RC那条路会更优。
当类型字段值为11时,表示IP数据包时间超过的差错。(如果理解不了时间超过,请复习IP首部中TTL字段的含义),在这里,当路由器收到一个TTL值为0的数据包,就会丢弃此数据包,并向源主机发送一个时间超过的ICMP差错报告。还有一种情况,就是如果IP数据包被分片传输了,在规定时间内,目的主机没有收到所有的分片,那就不能进行重新组合,所以目的主机只能把已收到的分片全部丢弃,并向源主机发送ICMP的时间超过报告。
当类型字段值为12时,表示IP数据包的参数出了问题,当路由器或目的主机收到的IP数据包的首部中有的字段值不正确时,就会丢弃此数据包,并向源主机发送一个ICMP的参数问题报告。
差错报告的传输问题 现在各种差错报告类型,我们介绍完了,那么差错报告报文的数据部分,到底包含着什么呢?
其实,所有的差错报告报文的数据字段都是相同的格式:把需要进行差错报告的IP数据包的首部和数据字段的前8个字节提取出来,作为数据部分,然后在前面加上ICMP的首部,就构成了ICMP的差错报告报文。
在这要说明的是,为什么要把需要进行差错报告的IP数据包的数据部分的前8个字节提取出来,原因是数据部分的前8个字节包含着传输层的端口号,这个信息对源主机是有用的。
如果现有一个IP数据包传输中出了问题,需要向源主机进行差错报告,在封装好了ICMP差错报告报文之后是直接发送给源主机吗?
当然不是,因为ICMP的报文不直接在网络是传输,还要把它再加上一个IP首部,封装成一个IP数据包发送出去。
可是这样的话,又会产生问题,因为网络层的IP协议只是尽最大努力交付数据包,并没有可靠的保障机制,如果一个承载着ICMP差错报告报文的IP数据包在传输途中又出差错了,那么再对这个IP包再进行差错报告,这样的话,有可能就会陷入一个无尽循环的境地。
所以我们约定,出现以下四种情况是不应该进行差错报告的:
1、对于本身就是ICMP差错报告报文的,就不再发送ICMP差错报告报文。
2、对于被分片的数据包,第一个分片的所有后续分片,都不发送ICMP差错报告。
3、对于组播地址的数据包,不发送ICMP差错报告。
4、对具有特殊IP的数据包(比如0.0.0.0或127.0.0.0)都不发送ICMP差错报告。
本节关于ICMP差错报告的内容就是这些, 一定要重视ICMP工作原理的学习,很重要。下一节,我们将结合ping命令与tracert命令学习ICMP的询问报文的相关内容。
【计算机网络(TCP/IP原理)|34、ICMP协议】参考教材:谢希仁《计算机网络》第七版
推荐阅读
- CVE-2020-16898|CVE-2020-16898 TCP/IP远程代码执行漏洞
- 做一件事情的基本原理是什么()
- 【读书笔记】贝叶斯原理
- SG平滑轨迹算法的原理和实现
- “写作宝典”《金字塔原理》之读书笔记
- Spring|Spring 框架之 AOP 原理剖析已经出炉!!!预定的童鞋可以识别下发二维码去看了
- Spring|Spring Boot 自动配置的原理、核心注解以及利用自动配置实现了自定义 Starter 组件
- Vue源码分析—响应式原理(二)
- MYSQL主从同步的实现
- (1)redis集群原理及搭建与使用(1)