> For the complete documentation index, see [llms.txt](https://valineliu.gitbook.io/deuterium-wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://valineliu.gitbook.io/deuterium-wiki/reading/cs-jing-dian-shu-ji/tcpv1/ch06-internet-control-message-protocol.md).

# ch06: Internet Control Message Protocol

ICMP

## MindMap

![ICMP: Internet Control Message Protocol](https://tva1.sinaimg.cn/large/007S8ZIlly1gfphltm48wj326m0u0wtd.jpg)

## 简介

ICMP经常被认为是IP层的一个组成部分，用来传递差错报文和其他需要注意的信息。

ICMP报文通常会被IP层或更高的协议（比如TCP或UDP）使用。一些ICMP报文会把差错报文发送给用户进程。

ICMP报文封装在IP报文中：

![image-20200622135728588](https://tva1.sinaimg.cn/large/007S8ZIlly1gg10ze3rovj30ms08w750.jpg)

ICMP报文的格式如下：

![image-20200622135828676](https://tva1.sinaimg.cn/large/007S8ZIlly1gg110e5c96j30wk0csab8.jpg)

所有报文的前四个字节格式一样。

类型（type）可以有15个不同的值，用来描述不同类型的ICMP报文，还可以使用代码（code）来进一步指定不同的类型。

然后是校验和。

接下来是不同的ICMP报文内容，每个类型都不同。

## ICMP报文的类型

![image-20200622140148499](https://tva1.sinaimg.cn/large/007S8ZIlly1gg113upksxj30u00vsws4.jpg)

## ICMP地址掩码请求与应答

ICMP地址掩码请求用于无盘系统在引导过程中获取自己的**子网掩码**。

另一个方式是**BOOTP协议**。

格式如下：

![](https://tva1.sinaimg.cn/large/007S8ZIlly1gg117cd6h1j310e0c00u8.jpg)

identifier和sequence在响应中返回，可以用来匹配请求。

## ICMP时间戳请求与应答

用于查询当前时间，返回的建议值是自午夜开始计算的毫秒数（UTC）。

不过需要知道日期。

格式：

![image-20200622202125468](https://tva1.sinaimg.cn/large/007S8ZIlly1gg1c2u3r78j313k0isac7.jpg)

请求填originate时间戳，响应填receive时间戳和transmit时间戳。

## ICMP端口不可达错误

UDP会使用这个错误，来报告端口不可达错误。

ICMP错误消息必须包含生成这个错误的datagram的IP header，还有IP header后面的8个字节。比如：

![image-20200622202933939](https://tva1.sinaimg.cn/large/007S8ZIlly1gg1cbc68tcj316q0es0v0.jpg)

返回IP header的原因是，可以让ICMP知道后面的八个字节怎么解释。（IP headerVS包含协议的信息）。

格式：

![image-20200622203152628](https://tva1.sinaimg.cn/large/007S8ZIlly1gg1cdpvmljj31000eg764.jpg)

**端口不可达的code是3。**

ICMP端口不可达错误返回时，为什么TFTP仍然发送请求呢？这是因为，BSD系统不把从socket接收到的ICMP报文返回给使用UDP的用户进程，除非这个进程对这个socket使用了connect命令，而标准的BSD TFTP客户程序不发送connect命令。

TFTP每隔五秒重试一次。
