尽管每个ICMP报文都有自己的格式,但它们开始的三个字段都是一样的:一个8位的报文类型(type)用来标识报文,一个8位的代码(code)用来提供有关类型的进一步信息,一个16位的校验和(checksum)。(ICMP采用和IP相同的校验和算法,但ICMP校验和只覆盖ICMP报文)。这里我们给出ICMP报文首部的数据结构:
struct ICMPHEADER
{
BYTEi_type;//类型
BYTEi_code;// 代码
USHORTi_cksum;// 首部校验和
USHORTi_id;// 标识
USHORTi_seq;// 序列号
ULONGtimestamp;// 时间戳(选用)
};
表表示了ICMP的报文类型及其含义:
Type | Code | 类别 | 含义 |
0 | 0 | 查询 | 回送应答 |
3 | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 差错 差错 差错 差错 差错 差错 差错 差错 差错 差错 差错 差错 差错 差错 差错 差错 | 网络不可抵达 主机不可抵达 协议不可抵达 端口不可抵达 需要重新分片但设置了不分片比特 源路由失败 目的网络未知 目的主机未知 源主机被隔离 目的网络被禁止 目的主机被禁止 对所请求的服务类型,网络不可达 对所请求的服务类型,主机不可达 由于过滤,通信被禁止 主机越权 优先级失效 |
4 | 0 | 差错 | 源端被关闭 |
5 | 0 1 2 3 | 差错 差错 差错 差错 | 对网络重定向 对主机重定向 对服务类型和网络重定向 对服务类型和主机重定向 |
8 | 0 | 查询 | 请求回显 |
9 | 0 | 查询 | 路由器通告 |
10 | 0 | 查询 | 陆由器请求 |
11 | 0 1 | 差错 差错 | 传输期间数据报超时 数据报组装期间超时 |
12 | 0 1 | 差错 差错 | IP报头损坏 缺少必要的选项 |
13 | 0 | 查询 | 时间戳请求 |
14 | 0 | 查询 | 时间戳回复 |
15 | 0 | 查询 | 信息请求(已过时) |
16 | 0 | 查询 | 信息回复(已过时) |
17 | 0 | 查询 | 地址掩码请求 |
18 | 0 | 查询 | 地址掩码回复 |
下面给出几种常用的ICMP报文格式
回显请求和应答报文格式:通常用来判断目的主机是否可以通过网络访问到。
类型(8或0) | 代码(0) | 校验和 |
标识符 | 序号 | |
可选项 |
时间戳请求与应答:网络上的主机一般是独立的,每台机器都有自己的当前时间。时间戳请求与应答用来查询目的主机系统当前的时间。返回值是自午夜开始到现在的毫秒数,通过这个数值来协调时间的统一。事实上因为延时,这个值是不准确的,通常采取多次测量求平均值的办法。
类型(13或14) | 代码(0) | 校验和 |
标识符 | 序号 | |
发起时间戳 | ||
接收时间戳 | ||
传送时间戳 |
路由器通告:当主机自举以后必须至少知道本地网络上的一个路由器的地址才能够向其它网络发送报文。ICMP支持路由发现方案(RouterDiscovery),允许主机发现一个路由器地址。
类型(9) | 代码(0) | 校验和 |
地址号 | 地址大小(1) | 寿命 |
路由器地址1 | ||
优先级1 | ||
路由器地址2 | ||
优先级2 | ||
… |
地址掩码请求与应答:主机可以通过向路由器发送一个地址掩码请求,并且接收发回的地址掩码应答报文来获得本地网络所使用的子网掩码。可以直接发送请求,但如果不知道路由器的地址,也可以采用广播的方式来发送报文。
类型(17或18) | 代码(0) | 校验和 |
标识符 | 序号 | |
地址掩码 |