ICMP&ping&traceroute
前言
此文章内容源于计算机网络自顶向下-陈鸣译。
初心是自认为网络上关于计算机网络概念的介绍,没有文章定义看起来舒适。所以权且把一些内容抄写过来。
个人理解以代码段的形式补充在旁边。
ICMP
ICMP:Internet control message protocol 因特网报文控制协议。
由[RFC 792] 定义的因特网控制报文协议(ICMP) , 被主机和路由器用来彼此沟通网络层的信息。ICMP最典型的用途是差错报告。(差错报告只是其中一个用途)
例如, 当运行一个HTTP会话时, 你也许会遇到一些诸如“目的网络不可达”之类的错误报文。这种报文就来源于ICMP。在某个位置, IP路由器不能找到一条通往HTTP请求中所指定的主机的路径, 该路由器就会向你的主机生成并发出一个ICMP报文以指示该错误。
ICMP通常被认为是IP的一部分, 但从体系结构上讲它位于IP之上, 因为ICMP报文是承载在IP分组中的。这就是说, ICMP报文是作为IP有效载荷承载的, 就像TCP与UDP报文段作为IP有效载荷被承载那样。类似地, 当一台主机收到一个指明上层协议为ICMP的IP数据报时(上层协议编码为1)(如下图显示,上层协议编码为1)
, 它分解出该数据报的内容给ICMP, 就像分解出一个数据报的内容给TCP或UDP一样。
ICMP报文有一个类型字段和一个编码字段, 并且包含引起该ICMP报文首次生成的IP数据报的首部和前8个字节(以便发送方能确定引发该差错的数据报)。在图5-19中显示了所选的ICMP报文类型。注意到ICMP报文并不仅是用于通知差错情况。
PING
众所周知的ping程序发送一个ICMP类型8编码0的报文到指定主机。(回显请求包)
看到回显(echo) 请求, 目的主机发回一个类型0编码0的ICMP回显回答。大多数TCP/IP实现直接在操作系统中支持ping服务器, 即该服务器不是一个进程。[Stevens 1990] 的第11章提供了有关ping客户程序的源码。注意到客户程序需要能够指示操作系统产生一个类型8编码0的ICMP报文。
Tracetoute
在第1章中我们介绍了Traceroute程序, 该程序允许我们跟踪从一台主机到世界上任意一台主机之间的路由。有趣的是, Traceroute是用ICMP报文来实现的。为了判断源和目的地之间所有路由器的名字和地址, 源主机中的Traceroute向目的地主机发送一系列普通的IP数据报。这些数据报的每个携带了一个具有不可达UDP端口号的UDP报文段。第一个数据报的TTL为1, 第二个的TTL为2, 第三个的TTL为3, 依次类推。该源主机也为每个数据报启动定时器。(启动计时器是为了方便计算往返时延:RTT值)
当第n个数据报到达第n台路由器时,第n台路由器观察到这个数据报的TTL正好过期。根据IP协议规则, 路由器丢弃该数据报并发送一个ICMP告警报文给源主机(类型11编码0) 。(TTL过期地ICMP报警报文)
该告警报文包含了路由器的名字和它的IP地址。当该ICMP报文返回源主机时, 源主机从定时器得到往返时延, 从ICMP报文中得到第n台路由器的名字与IP地址。
Traceroute源主机是怎样知道何时停止发送UDP报文段的呢?前面讲过源主机为它发送的每个报文段的TTL字段加1。因此, 这些数据报之一将最终沿着这条路到达目的主机。因为该数据报包含了一个具有不可达端口号的UDP报文段, 该目的主机将向源发送一个端口不可达的ICMP报文(类型3编码3) 。当源主机收到这个特别的ICMP报文时,知道它不需要再发送另外的探测分组。(标准的Traceroute程序实际上用相同的TTL发送3个一组的分组, 因此Traceroute输出对每个TTL提供了3个结果。)
以这种方式,源主机知道了位于它与目的主机之间的路由器数量和标识,以及两台主机之间的往返时延。注意到Traceroute客户程序必须能够指令操作系统产生具有特定TTL值的UDP数据报, 当ICMP报文到达时, 也必须能够由它的操作系统进行通知。既然你已明白了Traceroute的工作原理, 你也许想返回去更多地使用它。
在RFC 4443中为IPv6定义了ICMP的新版本。除了重新组织现有的ICMP类型和编码定义外, ICMP还增加了新型IPv6功能所需的新类型和编码。这些包括**“分组太大”类型和一个“未被承认的IPv6选项”差错编码**。
总结与补充
- ICMP和IP同属网络层,位于TCP/UDP之下,ICMP在IP数据报内部传输,此时IP数据报由IP首部和ICMP报文组成。 但就ICMP报文被封装在IP包里这一情况,也可以说他是由IP协议承载的,从这一点来说,他跟TCP协议是一个层级的。这两种理解都各有各的道理。
- ping命令发送端使用的是ICMP类型8编码0的报文
(回显请求包)
,看到回显(echo) 请求,接收方发回一个类型0编码0的ICMP回显回答。Ping 是应用层直接调用IP层的ICMP协议,与TCP,UDP无关。
通过具体的ping报文可以看到ping报文的大小为84字节。其中ICMP报文56个字节(默认大小),再加上20个字节的IP首部和8个字节的ICMP首部。因此IP报文的总长度为84字节。
我们也可以改变ICMP的报文大小,通过-s命令。Ping www.sina.com.cn –s 32. 将ICMP报文大小设置为32字节。加上20字节的IP首部以及8字节的ICMP首部,总共60个字节 - Traceroute命令向目的接收方发送一系列的TTL从1不断增加的IP数据包,其中承载了具有不可达UDP端口的UDP报文。而回显是借助TTL过期警告:TTL过期的所在路由器发送(类型11编码0的)ICMP告警报文给源主机,其中包含了该路由器的名字和IP地址。当最终一个UDP报文段到达目的地时(接收方看到该UDP报文段的目的IP就是自己),它又发现这个UDP端口不存在,所以返回一个(类型3编码3的)端口不可达的ICMP报文。之后源主机就停止发送UDP报文段了,因为已经找到目的主机了。
但是在windows和linux下命令名称不一样,而且实现方式也不太一样
Windows下用的命令是tracert,linux下用的是traceroute
实现方式来说:
Windows下使用的是ICMP报文,而linux下使用的是UDP报文。
但是从对端反馈回的报文都是ICMP报文。且最终目的地址反馈一个port unreachable的报文。这个端口不可达的报文在windows系统中并没有找到。
部分内容参考来源于:
CSDN论坛:ping命令使用的是tcp报文还是udp报文? Icmp属于tcp吗?
博客园:https://www.cnblogs.com/zhanghongfeng/p/7238100.html——一张红枫叶