ICMP 协议

别有洞天
• 阅读 2730

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 协议的功能来工作。

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
皕杰报表(关于日期时间时分秒显示不出来)
在使用皕杰报表设计器时,数据据里面是日期型,但当你web预览时候,发现有日期时间类型的数据时分秒显示不出来,只有年月日能显示出来,时分秒显示为0:00:00。1.可以使用tochar解决,数据集用selecttochar(flowdate,"yyyyMMddHH:mm:ss")fromtablename2.也可以把数据库日期类型date改成timestamp
Easter79 Easter79
4年前
typeScript数据类型
//布尔类型letisDone:booleanfalse;//数字类型所有数字都是浮点数numberletdecLiteral:number6;lethexLiteral:number0xf00d;letbinaryLiteral:number0b101
Wesley13 Wesley13
4年前
DHCP协议报文
DICP协议采用客户端服务器方式进行交互,其报文格式共有8种,由报文中“DHCPmessage0pe”字段的值来确定,后面括号中的值即为相应类型的值,具体含义如下1、DHCPDiscover报文,是客户端开始DHCP过程的第一个报文。2\.DHCPOfer报文,是服务器对DHCP\_Discover报文的响应3\.D
Wesley13 Wesley13
4年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
4年前
mysql中时间比较的实现
MySql中时间比较的实现unix\_timestamp()unix\_timestamp函数可以接受一个参数,也可以不使用参数。它的返回值是一个无符号的整数。不使用参数,它返回自1970年1月1日0时0分0秒到现在所经过的秒数,如果使用参数,参数的类型为时间类型或者时间类型的字符串表示,则是从1970010100:00:0
Wesley13 Wesley13
4年前
NEO从源码分析看UTXO交易
_0x00前言_社区大佬:“交易是操作区块链的唯一方式。”_0x01交易类型_在NEO中,几乎除了共识之外的所有的对区块链的操作都是一种“交易”,甚至在“交易”面前,合约都只是一个小弟。交易类型的定义在Core中的TransactionType中:源码位置:neo/Core/TransactionType
Wesley13 Wesley13
4年前
ThinkPHP 根据关联数据查询 hasWhere 的使用实例
很多时候,模型关联后需要根据关联的模型做查询。场景:广告表(ad),广告类型表(ad\_type),现在需要筛选出广告类型表中id字段为1且广告表中status为1的列表先看关联的设置部分 publicfunctionadType(){return$thisbelongsTo('A
ping命令使用及其常用参数
PING(PacketInternetGroper),因特网包探索器,用于测试网络连接量检查网络是否连通,可以很好地帮助我们分析和判定网络故障。Ping发送一个ICMP(InternetControlMessagesProtocol)即因特网信报控制协议;回声请求消息给目的地并报告是否收到所希望的ICMP echo(ICMP回声应答)。它是用来检查网络是否通畅或者网络连接速度的命令。