RFC 792
Internet Control Message Protocol —— IP 的差错报告与诊断。它不让 IP 变可靠,只是把坏消息送回去。
ICMP 是 IP 的一部分
The Internet Protocol (IP) [1] is used for host-to-host datagram service in a system of interconnected networks called the Catenet [2]. The network connecting devices are called Gateways. These gateways communicate between themselves for control purposes via a Gateway to Gateway Protocol (GGP) [3,4]. Occasionally a gateway or destination host will communicate with a source host, for example, to report an error in datagram processing. For such purposes this protocol, the Internet Control Message Protocol (ICMP), is used. ICMP, uses the basic support of IP as if it were a higher level protocol, however, ICMP is actually an integral part of IP, and must be implemented by every IP module. ICMP messages are sent in several situations: for example, when a datagram cannot reach its destination, when the gateway does not have the buffering capacity to forward a datagram, and when the gateway can direct the host to send traffic on a shorter route. The Internet Protocol is not designed to be absolutely reliable. The purpose of these control messages is to provide feedback about problems in the communication environment, not to make IP reliable. There are still no guarantees that a datagram will be delivered or a control message will be returned. Some datagrams may still be undelivered without any report of their loss. The higher level protocols that use IP must implement their own reliability procedures if reliable communication is required. The ICMP messages typically report errors in the processing of datagrams. To avoid the infinite regress of messages about messages etc., no ICMP messages are sent about ICMP messages. Also ICMP messages are only sent about errors in handling fragment zero of fragemented datagrams. (Fragment zero has the fragment offeset equal zero).
注解
封装上看 ICMP 像上层(IPv4 Protocol = 1),地位上它是 IP 的强制配件。没有 ICMP 的 IPv4 实现是不完整的。
两道保险丝:不因 ICMP 差错报文再生成 ICMP 差错报文(RFC 1122 §3.2.2、RFC 1812 §4.3.2.7);Echo / Echo Reply 等 query/reply 不在禁令内。分片时只对 offset=0 的那一片报错,因为只有第一片通常带着传输层端口,对端才能把差错对上某个 socket。
易误解:“禁 ping 等于主机不可达”。禁的是 Echo,Destination Unreachable / Time Exceeded 仍可能放行;反之,禁掉所有 ICMP 会弄坏 PMTUD 和 traceroute。
Type 3 与六种 Code
Destination Unreachable Message
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| unused |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Internet Header + 64 bits of Original Data Datagram |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
IP Fields:
Destination Address
The source network and address from the original datagram's data.
ICMP Fields:
Type
3
Code
0 = net unreachable;
1 = host unreachable;
2 = protocol unreachable;
3 = port unreachable;
4 = fragmentation needed and DF set;
5 = source route failed.[……节选 Checksum / 64-bit 字段说明,下接官方 Description]
Description
If, according to the information in the gateway's routing tables,
the network specified in the internet destination field of a
datagram is unreachable, e.g., the distance to the network is
infinity, the gateway may send a destination unreachable message
to the internet source host of the datagram. In addition, in some
networks, the gateway may be able to determine if the internet
destination host is unreachable. Gateways in these networks may
send destination unreachable messages to the source host when the
destination host is unreachable.
If, in the destination host, the IP module cannot deliver the
datagram because the indicated protocol module or process port is
not active, the destination host may send a destination
unreachable message to the source host.
Another case is when a datagram must be fragmented to be forwarded
by a gateway yet the Don't Fragment flag is on. In this case the
gateway must discard the datagram and may return a destination
unreachable message.
Codes 0, 1, 4, and 5 may be received from a gateway. Codes 2 and
3 may be received from a host.
注解
差错报文带回多少原数据:RFC 792 经典格式是原 IP 首部 + 64 bits;RFC 1122 要求至少 8 字节且允许更多;RFC 1812 要求在不超过 576 字节时尽量多带;启用 RFC 4884 扩展时至少 128 字节。不要再记成“永远固定前 8 字节”。
谁会发:网关(路由器)发 0/1/4/5;目的主机发 2(没有这个协议模块)和 3(端口没人听)。看到 Type 3 Code 3,问题在对端传输层,不在路由。
Code 4 是 PMTUD 的核心。RFC 1191 后来在“unused”里放进下一跳 MTU;792 原文那 32 bit 仍标 unused。
Type 11:TTL 耗尽与重组超时
Time Exceeded Message
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| unused |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Internet Header + 64 bits of Original Data Datagram |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
IP Fields:
Destination Address
The source network and address from the original datagram's data.
ICMP Fields:
Type
11
Code
0 = time to live exceeded in transit;
1 = fragment reassembly time exceeded.
Checksum
The checksum is the 16-bit ones's complement of the one's
complement sum of the ICMP message starting with the ICMP Type.
For computing the checksum , the checksum field should be zero.
This checksum may be replaced in the future.
Internet Header + 64 bits of Data Datagram
The internet header plus the first 64 bits of the original
datagram's data. This data is used by the host to match the
message to the appropriate process. If a higher level protocol
uses port numbers, they are assumed to be in the first 64 data
bits of the original datagram's data.
注解
官方 Description:网关发现 TTL 字段为 0 必须丢弃数据报,并可回 Time Exceeded;主机重组超时则丢弃并可以回报。fragment zero 不在就不需要发。Code 0 来自网关,Code 1 来自主机。带回的原数据长度规则与 Type 3 相同:792 为 IP 首部 + 64 bits,后世见 1122 / 1812 / 4884,不是“永远固定前 8 字节”。
Code 0 就是 traceroute 的扳机:从 TTL=1 往上探,沿途网关依次露出自己的源 IP。Code 1 是目的主机等齐分片超时,和“路上跳数用完”不是一回事。
探针本身可以是 UDP(传统 Unix traceroute)、ICMP Echo(Windows tracert)或 TCP SYN。触发的都是这份 Type 11。
Type 8 / 0:ping 的全部内容
Echo or Echo Reply Message
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identifier | Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data ...
+-+-+-+-+-[……节选 Addresses / Checksum / Identifier,下接 Type 与 Description]
Type
8 for echo message;
0 for echo reply message.
Code
0[……节选 Checksum / Identifier / Sequence Number]
Description
The data received in the echo message must be returned in the echo
reply message.
The identifier and sequence number may be used by the echo sender
to aid in matching the replies with the echo requests. For
example, the identifier might be used like a port in TCP or UDP to
identify a session, and the sequence number might be incremented
on each echo request sent. The echoer returns these same values
in the echo reply.
Code 0 may be received from a gateway or a host.
注解
ping 不是独立协议。请求 Type=8,应答 Type=0,Code 都是 0。对端把 Identifier、Sequence Number 和 Data 原样送回,源/目的 IP 对调。
Identifier 常被实现写成进程号,Sequence Number 递增——方便把应答对上发出去的那一次。它们不是 TCP 序号。
校验和从 ICMP Type 字节算到末尾,算法仍是一补码。和 IP 首部校验和不是同一段字节。
抓包对照
Wireshark:Internet Protocol / ICMP。没有端口。过滤器 icmp、icmp.type == 8、icmp.type == 11。
- 直接可见:Type、Code、Checksum;Echo 还能看见 Identifier / Sequence / Data。
- 差错报文里嵌着的原 IP 首部 + 原数据是线上真实字节(792 为 64 bits,后世可更长),Wireshark 会再解码出原四元组。
- 不要用“能不能 ping 通”代替“TCP 443 通不通”。两者走的不是同一条控制路径。
考点与易错点
- ICMP 是 IP 的组成部分(Protocol=1),必须实现;它不提供可靠传输。
- 不因 ICMP 差错报文再生成 ICMP 差错报文;Echo 等 query/reply 不在禁令内。分片只对 fragment zero 报错。
- ping = Echo 8 / Reply 0。traceroute = 递增 TTL 触发 Type 11 Code 0。
- Type 3 Code 4 = 需要分片且 DF=1,是 PMTUD 信号,不是“主机死了”。
- Code 2/3 来自目的主机,Code 0/1/4/5 来自网关(按 792 原文)。
- IPv6 的对应物是 ICMPv6(Next Header 58),NDP 也走它,不是 RFC 792。