ping是基于ICMP协议工作的,所以要明白ping的工作,就要先学习ICMP协议
ICMP 全称是Internet Control Message Protocol,也就是互联网控制报文协议
里面有个关键词:控制,如何控制呢?
网络包在复杂的网络传输环境里,常常会遇到各种问题。当遇到问题的时候,总不能死的不明不白,没头没脑的作风不是计算机网络的风格。所以需要传出消息,报告遇到了什么问题,这样才可以调整传输策略,以此来控制整个局面。
ICMP 主要的功能包括:确认 IP 包是否成功送达目标地址、报告发送过程中 IP 包被废弃的原因和改善网络设置等。
在IP通信中如果某个IP包因为某种原因未能达到目标地址,那么这个具体的原因将由ICMP负责通知
比如上图例子:主机A向主机B发送了数据包,由于某种原因,途中的路由器2未能发现主机B的存在,这时,路由器2就会向主机B发送一个ICMP目标不可达的数据包,说明发往主机B的包未能成功。
ICMP的这种通知消息会使用IP进行发送
因此,从路由器2返回的ICMP包会按照往常的路由控制先经过路由器1再转发给主机A。收到该ICMP包的主机A则分解ICMP的首部和数据域以后得知具体发生问题的原因。
数据包在发送到目标主机的过程中,通常会经过一个或多个路由器。而数据包在通过这些路由进行传输时,可能会遇到各种问题,导致数据包无法发送到目标主机上。为了了解数据包在传输的过程中在哪个环节出现了问题,就需要用到 ICMP 协议。它可以跟踪消息,把问题反馈给源主机。
ICMP报文是封装在IP包里面,它工作在网络层,是IP协议的助手。 ICMP包头的类型字段,大致可以分为两类:
一类是用于诊断的查询信息,即:查询报文信息另一类是通知出错原因的错误信息,即:差错报文类型回送消息 — 类型 0和8
回送消息用于进行通信的主机或者路由器之间,判断所发送的数据包是否已经成功到达对端的一种消息,ping命令就是利用这个消息实现的。 可以向对端主机发送回送请求的消息( ICMP Echo Request Message ,类型 8 ),也可以接收对端主机发回来的回送应答消息( ICMP Echo Reply Message ,类型 0 )。 相比原生的 ICMP,这里多了两个字段:
标识符:用以区分是哪个应用程序发ICMP 包,比如用进程PID 作为标识符;序号:序列号从0 开始,每发送一次新的回送请求就会加1, 可以用来确认网络包是否有丢失。接下来,说明几个常用的 ICMP 差错报文的例子:
目标不可达消息 —— 类型 为 3原点抑制消息 —— 类型 4重定向消息 —— 类型 5超时消息 —— 类型 11IP 路由器无法将 IP 数据包发送给目标地址时,会给发送端主机返回一个目标不可达的 ICMP 消息,并在这个消息中显示不可达的具体原因,原因记录在 ICMP 包头的代码字段。
由此,根据 ICMP 不可达的具体消息,发送端主机也就可以了解此次发送不可达的具体原因。
常见的目标不可达类型的代码:
网络不可达代码为0
外卖版本:小林第一次送外卖时,小区里只有 A 和 B 区两栋楼,但送餐地址写的是 C 区楼,小林表示头上很多问号,压根就没这个地方。正常版本: IP 地址是分为网络号和主机号的,所以当路由器中的路由器表匹配不到接收方 IP 的网络号,就通过ICMP 协议以网络不可达( Network Unreachable )的原因告知主机。自从不再有网络分类以后,网络不可达也渐渐不再使用了。主机不可达代码为1
外卖版本:小林第二次送外卖时,这次小区有 5 层楼高的 C 区楼了,找到地方了,但送餐地址写的是 C 区楼 601号房 ,说明找不到这个房间。正常版本: 当路由表中没有该主机的信息,或者该主机没有连接到网络,那么会通过 ICMP 协议以主机不可达( Host Unreachable )的原因告知主机。协议不可达代码为 2
外卖版本:小林第三次送外卖时,这次小区有 C 区楼,也有 601 号房,找到地方了,也找到房间了,但是一开门人家是外国人说的是英语,我说的是中文!语言不通,外卖送达失败~正常版本:当主机使用 TCP 协议访问对端主机时,能找到对端的主机了,可是对端主机的防火墙已经禁止 TCP 协议访问,那么会通过 ICMP 协议以协议不可达的原因告知主机。端口不可达代码为3
外卖版本:小林第四次送外卖时,这次小区有 C 区楼,也有 601 号房,找到地方了,也找到房间了,房间里的人也是说中文的人了,但是人家说他要的不是外卖,而是快递。。。正常版本:当主机访问对端主机 8080 端口时,这次能找到对端主机了,防火墙也没有限制,可是发现对端主机没有进程监听 8080 端口,那么会通过 ICMP 协议以端口不可达的原因告知主机。需要进行分片但设置了不分片位代码为 4
外卖版本:小林第五次送外卖时,这次是个吃播博主点了 100 份外卖,但是吃播博主要求一次性要把全部外卖送达,小林的一台电动车装不下呀,这样就没办法送达了。正常版本:发送端主机发送 IP 数据报时,将 IP 首部的分片禁止标志位设置为 1 。根据这个标志位,途中的路由器遇到超过 MTU 大小的数据包时,不会进行分片,而是直接抛弃。随后,通过一个 ICMP 的不可达消息**类型,代码为 4的报文,告知发送端主机。如果路由器发现发送端主机使用了「不是最优」的路径发送数据,那么它会返回一个 ICMP 重定向消息给这个主机。
在这个消息中包含了 最合适的路由信息和源数据。这主要发生在路由器持有更好的路由信息的情况下。路由器会通过这样的 ICMP 消息告知发送端,让它下次发给另外一个路由器。
好比,小林本可以过条马路就能到的地方,但小林不知道,所以绕了一圈才到,后面小林知道后,下次小林就不会那么傻再绕一圈了。
此外,有时可以用 TTL 控制包的到达范围,例如设置一个较小的 TTL 值。
接下来,我们重点来看 ping 的发送和接收过程。
同个子网下的主机A 和 主机 B,主机 A 执行 ping 主机 B 后,我们来看看其间发送了什么? ping命令执行的时候,源主机首先会构建一个 ICMP回送请求消息数据包
ICMP数据包中包含多个字段,最重要的是两个:
类型:对于回送请求消息而言该字段为8序号: 主要用于区分连续ping的时候发出的多个数据包每发出一个请求数据包,序号会自动加1。为了能够计算往返时间RTT,它会在报文的数据部分插入发送时间。 然后,由ICMP 协议将这个数据包连同地址 192.168.1.2 一起交给IP 层。IP 层将以 192.168.1.2 作为目的地址,本机 IP 地址作为源地址,协议字段设置为1 表示是 ICMP 协议,再加上一些其他控制信息,构建一个IP 数据包。 接下来,需要加入MAC 头。如果在本地ARP映射表中查找出 IP 地址 192.168.1.2 所对应的 MAC地址,则可以直接使用;如果没有,则需要发送 ARP 协议查询 MAC 地址,获得 MAC 地址后,由数据链路层构建一个数据帧,目的地址是 IP 层传过来的 MAC 地址,源地址则是本机的 MAC 地址;还要 附加上一些控制信息,依据以太网的介质访问规则,将它们传送出去。
主机 B收到这个数据帧后,先检查它的目的 MAC地址,并和本机的 MAC 地址对比,如符合,则接收,否则就丢弃。
接收后检查该数据帧,将IP数据包从帧中提取出来,交给本机的IP 层。
同样,IP层检查后,将有用的信息提取后交给ICMP 协议。
主机B 会构建一个 ICMP 回送响应消息数据包,回送响应数据包的类型字段为 0 ,序号为接收到的请求数据包中的序号,然后再发送出去给主机 A。
在规定的时候间内,源主机如果没有接到 ICMP 的应答包,则说明目标主机不可达;如果接收到了ICMP 回送响应消息,则说明目标主机可达。
此时,源主机会检查,用当前时刻减去该数据包最初从源主机上发出的时刻,就是 ICMP 数据包的时间延迟。
针对上面发送的事情,总结成了如下图:
当然这只是最简单的,同一个局域网里面的情况。如果跨网段的话,还会涉及网关的转发、路由器的转发等等。
但是对于 ICMP 的头来讲,是没什么影响的。会影响的是根据目标 IP 地址,选择路由的下一跳,还有每经过一个路由器到达一个新的局域网,需要换 MAC 头里面的 MAC 地址。
说了这么多,可以看出 ping 这个程序是使用了ICMP 里面的 ECHO REQUEST(类型为 8)和ECHO REPLY(类型为 0)。
http://c.biancheng.net/view/6399.html
tcpdump和wireshark
tcpdump仅仅支持命令行格式使用,常用在Linux服务器中抓包winshark是windows下抓包的,提供了可视化分析网络包的图形界面我们可以在linux下使用tcpdump抓包,在windows上使用winshark分析
1、打开终端,因为ping是icmp协议,因此执行下面命令
tcpdump -i ens33 icmp and host 192.168.0.11 -nn # -i ens33表示抓取ens33网口的数据包 # icmp表示抓取icmp协议的数据包 # host表示主机过滤,抓取对应IP的数据包 # -nn 表示不解析IP地址和端口号的名称2、打开另一个终端,执行ping命令:
ping -I ens33 -c 3 192.168.0.11 # -I ens33表示指定从ens33网口出去 # -c 3 表示发出3个icmp数据包这个时候我们可以在第一个终端中看到下面的界面: 可以看到,tcpdump抓取到icmp数据包之后,输出的格式如下: 从数据包中,我们可以很清楚的看到ICMP echo的交互过程:
首先发送发发起一个ICMP echo request请求报文,接收方收到之后回了一个ICMP echo reply响应报文。每一个ICMP请求对应两个报文,因为我们之前发出了3个ICMP报文,因此整个过程中有六个报文。我们也可以将tcpdump抓取到的数据包保存成pcap后缀的文件,然后用Wireshark来分析:
tcpdump -i ens33 icmp and host 192.168.0.11 -nn -w ping.pcap # -i ens33表示抓取ens33网口的数据包 # icmp表示抓取icmp协议的数据包 # host表示主机过滤,抓取对应IP的数据包 # -nn 表示不解析IP地址和端口号的名称 # -w ping.pcap:表示将抓取到的数据包保存到ping.pcap文件中。接着把 ping.pcap 文件拖到电脑,再用 Wireshark 打开它。打开后,就可以看到下面这个界面: 这里先简单的介绍下Wireshark的控制面板,这个面板包含7个字段,分别是:
NO.编号Time:包的时间戳Source:源地址Destination:目标地址Protocol:协议Length:包长度Info:数据包附加信息在 Wireshark 的页面里,可以更加直观的分析数据包,不仅展示各个网络包的头部信息,还会用不同的颜色来区分不同的协议,由于这次抓包只有 ICMP 协议,所以只有紫色的条目。
从编号可以看出,一共有6帧,每一帧的结构都是类似的,如下:
Frame 1: 物理层的数据帧情况, 对应OSI七层模型中的【物理层】Ethernet II, Src: 数据链路层以太网帧头部信息,对应OSI七层模型中的【数据链路层】Internet Protocol Version 4, Src: 互联网层IP包头信息,对应OSI七层模型中的【网络层】Internet Control Message Protocol: 互联网控制信息协议,即ICMP,对应OSI七层模型中的【网络层】前三层基本上都是一样的,第四层开始就可以出现TCP, UDP 协议,第五层就可能有HTTP 应用层协议等等。
接下来我们来分析各个层的具体情况
第一层 : Frame: 物理层的数据帧概况 Frame 1: 98 bytes on wire (784 bits), 98 bytes captured (784 bits) # 第1帧,线路有98个字节(共784位),实际捕获到98字节 Encapsulation type: Ethernet (1) # 封装类型: 以太网(1) Arrival Time: Oct 22, 2020 10:59:36.412790000 中国标准时间 # 到达时间 [Time shift for this packet: 0.000000000 seconds] # 包偏移时间 Epoch Time: 1603335576.412790000 seconds [Time delta from previous captured frame: 0.000000000 seconds] # 两帧之间的时间间隔 [Time delta from previous displayed frame: 0.000000000 seconds] # 捕获到显示的间隔时间 [Time since reference or first frame: 0.000000000 seconds] # 此包和第一帧的时间间隔 Frame Number: 1 #帧序号 Frame Length: 98 bytes (784 bits) #帧长度 Capture Length: 98 bytes (784 bits) #捕获长度 [Frame is marked: False] #此帧是否做了标记:否 [Frame is ignored: False] #此帧是否被忽略:否 [Protocols in frame: eth:ethertype:ip:icmp:data] #帧内封装的协议层次结构 [Coloring Rule Name: ICMP] #着色标记的协议名称 [Coloring Rule String: icmp || icmpv6] #着色规则显示的字符串 第二层: Ethernet II , Src: 数据链路层以太网帧头部信息。 Ethernet II, Src: VMware_4c:e6:d1 (00:0c:29:4c:e6:d1), Dst: Micro-St_64:86:44 (30:9c:23:64:86:44) Destination: Micro-St_64:86:44 (30:9c:23:64:86:44) #目的MAC地址 Source: VMware_4c:e6:d1 (00:0c:29:4c:e6:d1) #源MAC地址 Type: IPv4 (0x0800) 第三层: Internet Protocol Version 4, Src: 以太网协议层 Internet Protocol Version 4, Src: 192.168.0.12, Dst: 192.168.0.11 # IPv4 协议 源IP:192.168.0.12, 目的IP:192.168.0.11 0100 .... = Version: 4 # 版本4 .... 0101 = Header Length: 20 bytes (5) # 头长度20字节 Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT) #差分服务区域 Total Length: 84 #总长度 Identification: 0x81d9 (33241) #鉴别 Flags: 0x4000, Don't fragment #标志 Fragment offset: 0 #分的偏移量 Time to live: 64 # 生存期 Protocol: ICMP (1) # 协议名称: ICMP(将协议字段设置为1表示是ICMP协议) Header checksum: 0x3768 [validation disabled] # 头部校验和 [Header checksum status: Unverified] # 头部校验和检验状态: Source: 192.168.0.12 # 源IP Destination: 192.168.0.11 #目的地IP 第四层:ICMP层【结构和ICMP协议的数据格式一样】 Internet Control Message Protocol // 因特网控制信息协议 Type: 8 (Echo (ping) request) // 类型,ping 请求 Code: 0 Checksum: 0x4cd3 [correct] // 和校验 [Checksum Status: Good] // 和检验状态 Identifier (BE): 24759 (0x60b7) // 标识符 Identifier (LE): 46944 (0xb760) Sequence number (BE): 1 (0x0001) // BE 序列号 Sequence number (LE): 256 (0x0100) //LE 序列号 [Response frame: 2] Timestamp from icmp data: Oct 22, 2020 10:59:36.000000000 中国标准时间 [Timestamp from icmp data (relative): 0.412790000 seconds] Data (48 bytes) // 数据 Data: 5c4c060000000000101112131415161718191a1b1c1d1e1f… [Length: 48]从第4层往上面看,就和 上文【ping —— 查询报文类型的使用】过程是一样的
Type:标识ICMP消息类型。对于ICMPv6,从0到127的值是错误消息,值128到255是信息性消息。此字段的常用值在ICMP消息类和类型主题的表中给出。 8表示Echo Request , 回送请求报文。0表示Echo Reply , 回送应答报文 Code:标识每个ICMP消息类型值中消息的“子类型”。因此,可以为每个消息类型定义多达256个“子类型”。此字段的值显示在各个ICMP消息类型主题中。 Checksum: 16位校验和字段,其计算方式与IPv4中的IP报头校验和类似。它为整个ICMP消息提供错误检测覆盖范围。请注意,在ICMPv6中,IPv6报头字段的一个伪报头用于校验和计算;这与TCP中的方法类似。 Checksum为0x4cd3 Sequence number (BE): 1 (0x0001) //标识码 Sequence number (LE): 256 (0x0100) //序列码。 5c4c060000000000101112131415161718191a1b1c1d1e1f…为发送的数据Wireshark 用了分层的方式,展示了各个层的包头信息
可以在数据链路层,看到 MAC 包头信息,如源 MAC 地址和目标 MAC 地址等字段;可以在 IP 层,看到 IP 包头信息,如源 IP 地址和目标 IP 地址、TTL、IP 包长度、协议等 IP 协议各个字段的数值和含义;可以在 ICMP 层,看到 ICMP 包头信息,比如 Type、Code 等 ICMP 协议各个字段的数值和含义;从 ping 的例子中,我们可以看到网络分层就像有序的分工,每一层都有自己的责任范围和信息,上层协议完成工作后就交给下一层,最终形成一个完整的网络包。
Wireshark抓包深入分析一下Ping的过程 Wireshark 分析ping报文 Wireshark 分析捕获的数据记录
https://blog.csdn.net/u011416247/article/details/80866725 https://blog.csdn.net/longwang155069/article/details/49990673
执行ARP -a 看看缓存的arp列表: