当发送IP数据报的源主机经过本机数据链路层把IP数据报发送到物理网络后,源主机的工作就基本完成了。至于IP数据报如何在网络中传输,则是由互联网中各路由器来完成的,无需源主机的参与(当然也可以用IP数据报的源路由选项来控制IP数据报经过的路由器)。这样就存在着一个很大的问题,如果由于某种原因(如通信线路错误、传输超时、目的主机关机、线路拥塞、目的网络错误、路由器错误等),IP数据报在传输过程中发生了错误,而IP数据报本身没有任何机制获得有关差错的信息,因此也就没有办法对发生的差错进行相应的控制。为此,在TCP/IP协议族中,专门设计了一个有特殊用途的协议——ICMP(Internet Control Message Protocol),当IP数据报在传输中发生差错时,互联网中的路由器使用ICMP协议把错误或有关控制信息报告给源主机。因此,ICMP协议是一个用于差错报告和报文控制的协议。
8.4.1 ICMP报文的封装与格式
1.ICMP报文的封装
ICMP报文和其他协议的报文一样,也是由ICMP报文头区和数据区两部分组成的。ICMP报文是封装在IP数据报中通过链路层在网络中进行传输的,如图8-14所示。这与其他高层协议(如TCP、UDP等)相似,它在IP数据报头中的协议标识是1(如表8-3)。尽管如此,通常还是把ICMP看成是网络层(IP层)协议,这主要有两个原因:一是ICMP只传送差错与控制报文,不可能在TCP/IP协议族中构成一个单独的层;二是ICMP报文处理与传输的都是有关IP层的信息,收到ICMP报文的主机一般也把报文交给IP层的ICMP模块进行处理,因此从协议逻辑层次来说,ICMP属于网络层协议。
图8-14 ICMP报文及封装格式
2.ICMP报文的格式
ICMP报文的格式如图8-15所示,其中报文头分为三部分:类型、代码和校验和。
图8-15 ICMP报文的格式
类型字段占一个字节,每个取值描述特定类型的ICMP报文,如表8-4所示。代码字段占一个字节,它的值用来对每类字段做进一步的描述。校验和字段提供对整个ICMP报文的校验,使用的算法与IP数据报头部校验和算法相同。数据区随ICMP报文类型的不同而不同。
8.4.2 ICMP请求与应答报文
差错报文和控制报文都是送往源主机的单向报文,并且对源主机来说都是被动接受的。ICMP请求与应答报文可以由源主机主动发出请求报文,为了响应请求,ICMP软件需要发送一个ICMP应答报文。通过这种方法可以获得网络中某些有用的信息,以便进行故障诊断和网络控制。
1.回送请求与应答报文
回送请求报文由源主机发出,目的主机应答,用于测试另一台主机或路由器是否可达。其报文格式如图8-16所示。
图8-16 回送请求与应答ICMP报文格式
回送请求ICMP报文的类型字段为8,应答ICMP报文类型为0,代码字段都为0。一台主机可以同时向多台目的主机发送ICMP请求报文,不同的请求报文标识符和序号不同。应答报文返回时使用的标识符和序号是请求报文的拷贝,因此标识符和序号可用于惟一地匹配一对回送请求与应答报文。数据区的长度可以选择,数据是任意的,但应答报文的数据区必须是回送请求报文数据区内容的复制。
如果发出回送请求的主机收到了目的主机(或路由器)的ICMP应答报文,并且请求与应答报文的数据区完全相同,则说明目的主机是可达的,源主机与目的主机的IP层及其下层协议工作正常。ping命令就是使用回送请求与应答报文来测试网络可达性的。
2.地址掩码请求与应答报文
在划分了子网的网络中,有些主机(如无盘工作站)并不知道自己的子网掩码。ICMP地址掩码请求报文可用于主机在引导过程中获取自己的子网掩码,方法是主机在本网广播ICMP地址掩码请求报文,通常由本网中的路由器向请求主机发送一个ICMP地址掩码应答报文。
地址掩码请求与应答报文的格式与图8-16所示的回送请求与应答ICMP报文格式相似,但数据区是一个4字节的地址掩码。掩码请求报文的类型字段地址为17,地址掩码应答报文为18,代码字段都为0。