2.4.2 Ping命令的构造
Ping命令依赖的不是TCP,也不是UDP,它依赖的是ICMP。ICMP是IP层的协议之一,它传递差错报文以及其他需要注意的信息。ICMP报文通常被IP层或高层协议使用。ICMP封装在IP数据报内部,如图2-16所示。
图2-16 ICMP封装在IP数据报内部
ICMP报文的格式如图2-17所示。
图2-17 ICMP报文格式
ICMP协议的类型码与代码根据不同的情况,各自取不同的值。Ping命令类型码用到了2个值,分别是0和8。而代码的取值都是0。当类型码取值为0时,代码的0值表示回显应答;当类型码取值为8时,代码的0值表示请求回显。Ping命令发送一个ICMP数据报时,类型码为8,代码为0,表示向对方主机进行请求回显;当收到对方的ICMP数据报时,类型码为0,代码为0,表示收到了对方主机的回显应答。简单来说,Ping命令发出的数据中,类型是8,代码是0,如果对方有回应,那么对方回应的数据中,类型是0,代码是0。
在自己实现Ping命令时,就是去自己构造一个请求回显的ICMP数据报,然后进行发送。ICMP的数据结构定义如下:
// ICMP协议结构体定义 struct icmp_header { unsigned char icmp_type; // 消息类型 unsigned char icmp_code; // 代码 unsigned short icmp_checksum; // 校验和 unsigned short icmp_id; // 用来唯一标识此请求的ID号,通常设置为进程ID unsigned short icmp_sequence; // 序列号 unsigned long icmp_timestamp; // 时间戳 };
提示:ICMP的数据结构在网络开发中会经常用到,请读者将其保存以备后用。
明白了ICMP协议的数据结构,现在用抓包工具(也可以称为协议分析工具)Wireshark来分析一下ICMP结构真实的情况,如图2-18所示。
图2-18 ICMP数据结构分析
在图2-18中,标识1的部分是对协议进行过滤设置的,在该部分输入“ICMP”可以让Wireshark只显示ICMP的数据记录。相应地,可以输入“TCP”、“UDP”、“HTTP”等协议进行筛选过滤。标识2的部分用于显示筛选后的ICMP记录,从这里可以明显看出源IP地址、目的IP地址和协议的类型。标识3的部分用于显示ICMP数据结构的值和附加的数据内容。最下面的部分显示了数据的原始的二进制数据,在熟练掌握协议后,查看原始的二进制数据也并不是不可能的。