从0到1用java再造tcpip协议栈:ICMP协议的原理和实现

绝大多数TCPIP传输协议基于IP寻址协议,然后建造在IP之上的TCP和UDP两种协议用于控制数据包的传输。问题在于这些协议只关注数据传输,在传输过程中如果出现错误信息,或者是网络出现某种异常情况需要数据发送双方做一些控制操作时,我们就需要在这些协议的控制范围之外传递一些有关数据发送的控制信息,这些数据的发送就必须依赖于控制数据报协议,也就是ICMP协议。

ICMP协议在保证数据的准确发送上发挥了巨大作用,但人们往往忽略它的作用,就连专业从事信息技术开发的工程师对它了解也很少。它经常被使用,当你感觉网络出问题时,你会执行ping命令,看数据包的发送是否顺畅,ping命令正是基于ICMP协议实现的。

ICMP协议的主要目标是汇报数据发送过程中出现的错误信息,如果把IP协议看做强力首席执行官,那么ICMP就是辅助执行官工作的总裁助理。ICMP主要任务是辅助IP层把数据包有效的发送给目的地,一旦发送过程中出现问题时,相关信息就通过ICMP协议进行传输,如下图:


从0到1用java再造tcpip协议栈:ICMP协议的原理和实现_第1张图片
屏幕快照 2018-12-21 上午11.09.03.png

假设设备A要把消息发送给左边设备B,数据包要经过路由器R3,但R3出现了问题,于是R3就会使用ICMP协议把问题信息传递给设备A。ICMP存在一个问题是,它只能把错误信息传递给数据包发送者,假设R3发现问题是R2引起的,但它不能通过ICMP把信息发送给R2,让其进行纠正,而只能把消息回传给A.

ICMP协议主要发送两类消息。第一类是错误消息,如果数据发送过程中产生错误,那么有关错误的信息会封装在ICMP协议数据包中返回给发送者;第二类是控制信息消息,这类信息主要用于把当前网络状况传递给发送者,让发送者根据情况调整数据包的发送控制。

我们先看看ICMP协议数据报的格式。ICMP数据报首先以数据链路层包头开始,我们前面章节提到过,包头2字节使用0x0800表示发送的是IP数据包。ICMP数据包有意思的一点是,它使用IP包头寻址,但又不包含在IP数据包里。因此跟在数据链路层包头后面的是IP4包头,其格式如下:

从0到1用java再造tcpip协议栈:ICMP协议的原理和实现_第2张图片
屏幕快照 2018-12-21 下午5.37.41.png

后面我们研究IP协议时在详细讲解这个包头,ICMP使用IP包头主要是确定发送者和接收者的IP地址而已,ICMP使用的IP包头中,options部分一般没有,因此包头总长度是20字节,过了IP包头后接下来才是ICMP数据包部分,其格式如下:

从0到1用java再造tcpip协议栈:ICMP协议的原理和实现_第3张图片
屏幕快照 2018-12-21 下午5.44.02.png

其中的type用来标志消息类型,0-127表示错误消息,128-255表示控制信息。code用来表示消息分类,如果是错误消息,那么它用来表示不同的错误情况,checksum用来表示校验值,用来判断数据包是否出错。接下来的部分是消息的主要内容,它的结构根据type和code的不同组合而不同。

我们看一个ICMP数据的具体实例,假设你在浏览器中登陆www.chenyi.com,这是一个不存在的网站,此时就会有一个ICMP数据包包含着错误信息回传到你电脑上,这个错误类型叫Destination Unreachable Message,使用wireshark抓包就会看到如下内容:

从0到1用java再造tcpip协议栈:ICMP协议的原理和实现_第4张图片
屏幕快照 2018-12-22 下午4.19.40.png

当上述类型错误产生时,type取值为1,code有多种取值,0表示找不到给的IP对应的网络,1表示IP对应网络找到了,但网络中不存在接收该消息的设备;2表示发送数据包的协议无效;3表示端口不可达;4表示数据量太大却不分割;5表示数据包发送路径出错;其他数值表示的含义我们今后用到时才讲解。此时数据报的消息主体是导致这个错误的数据包它的IP包头加8个字节的数据内容,其格式如下:

从0到1用java再造tcpip协议栈:ICMP协议的原理和实现_第5张图片
屏幕快照 2018-12-22 下午4.43.55.png

其中前4字节留着没用任何用处。我们分析一个具体例子,当你在浏览器里输入www.chenyi.com后,wireshark会抓到消息类型为Destination Unreachable 的ICMP数据报,它以14个字节的数据链路层包头开始,然后接着是20字节的IP包头,该包头是用来发送该数据包的IP包头,由此可见ICMP的传输依赖于IP层协议,但记住,它是与IP协议并列同一层的协议。

从0到1用java再造tcpip协议栈:ICMP协议的原理和实现_第6张图片
下来

然后我们往下拉,进入ICMP数据报部分,然后点击它的消息体,我们可以看到消息主体首先包含了IP数据包头,这个数据包头市产生这个ICMP错误消息的那个数据包,也就是当我们在浏览器输入www.chenyi.com,按回车后浏览器发送出去的数据包的IP包头:

从0到1用java再造tcpip协议栈:ICMP协议的原理和实现_第7张图片
屏幕快照 2018-12-22 下午4.59.24.png

最后是导致出错数据包的内容中前8个字节,从这里看是UDP数据包前8个字节,该协议我们在后续课程中再详细分析:

从0到1用java再造tcpip协议栈:ICMP协议的原理和实现_第8张图片
屏幕快照 2018-12-22 下午5.06.05.png

在下一节课,我们将使用代码实现该ICMP数据包的解析。

更详细的讲解和代码调试演示过程,请点击链接

更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号:


这里写图片描述

你可能感兴趣的:(从0到1用java再造tcpip协议栈:ICMP协议的原理和实现)