Linux编程之PING的实现

PING(Packet InterNet Groper)中文名为因特网包探索器,是用来查看网络上另一个主机系统的网络连接是否正常的一个工具。ping命令的工作原理是:向网络上的另一个主机系统发送ICMP报文,如果指定系统得到了报文,它将把回复报文传回给发送者,这有点象潜水艇声纳系统中使用的发声装置。所以,我们想知道我这台主机能不能和另一台进行通信,我们首先需要确认的是我们两台主机间的网络是不是通的,也就是我说的话能不能传到你那里,这是双方进行通信的前提。在Linux下使用指令ping的方法和现象如下:

Linux编程之PING的实现

PING的实现看起来并不复杂,我想自己写代码实现这个功能,需要些什么知识储备?我简单罗列了一下:

ICMP协议的理解

RAW套接字

网络封包和解包技能

搭建这么一个ping程序的步骤如下:

ICMP包的封装和解封

创建一个线程用于ICMP包的发送

创建一个线程用于ICMP包的接收

原始套接字编程

 

PING的流程如下:

 

Linux编程之PING的实现

 

一、ICMP包的封装和解封

(1) ICMP协议理解

要进行PING的开发,我们首先需要知道PING的实现是基于ICMP协议来开发的。要进行ICMP包的封装和解封,我们首先需要理解ICMP协议。ICMP位于网络层,允许主机或者路由器报告差错情况和提供有关异常情况的报告。ICMP报文是封装在IP数据报中,作为其中的数据部分。ICMP报文作为IP层数据报的数据,加上数据报头,组成IP数据报发送出去。ICMP报文格式如下:

Linux编程之PING的实现

ICMP报文的种类有两种,即ICMP差错报告报文和ICMP询问报文。PING程序使用的ICMP报文种类为ICMP询问报文。注意一下上面说到的ICMP报文格式中的“类型”字段,我们在组包的时候可以向该字段填写不同的值来标定该ICMP报文的类型。下面列出的是几种常用的ICMP报文类型。

Linux编程之PING的实现

我们的PING程序需要用到的ICMP的类型是回送请求(8)。
因为ICMP报文的具体格式会因为ICMP报文的类型而各不相同,我们ping包的格式是这样的:

Linux编程之PING的实现


(2) ICMP包的组装

  对照上面的ping包格式,我们封装ping包的代码可以这么写:

void icmp_pack(struct icmp* icmphdr, int seq, int length) { int i = 0; icmphdr->icmp_type = ICMP_ECHO; //类型填回送请求 icmphdr->icmp_code = 0; icmphdr->icmp_cksum = 0; //注意,这里先填写0,很重要! icmphdr->icmp_seq = seq; //这里的序列号我们填1,2,3,4.... icmphdr->icmp_id = pid & 0xffff; //我们使用pid作为icmp_id,icmp_id只是2字节,而pid有4字节 for(i=0;i<length;i++) { icmphdr->icmp_data[i] = i; //填充数据段,使ICMP报文大于64B } icmphdr->icmp_cksum = cal_chksum((unsigned short*)icmphdr, length); //校验和计算 }

这里再三提醒一下,icmp_cksum 必须先填写为0再执行校验和算法计算,否则ping时对方主机会因为校验和计算错误而丢弃请求包,导致ping的失败。我一个同事曾经就因为这么一个错误而排查许久,血的教训请铭记。

这里简单介绍一下checksum(校验和)。

计算机网络通信时,为了检验在数据传输过程中数据是否发生了错误,通常在传输数据的时候连同校验和一块传输,当接收端接受数据时候会从新计算校验和,如果与原校验和不同就视为出错,丢弃该数据包,并返回icmp报文。

 

算法基本思路:

IP/ICMP/IGMP/TCP/UDP等协议的校验和算法都是相同的,采用的都是将数据流视为16位整数流进行重复叠加计算。为了计算检验和,首先把检验和字段置为0。然后,对有效数据范围内中每个16位进行二进制反码求和,结果存在检验和字段中,如果数据长度为奇数则补一字节0。当收到数据后,同样对有效数据范围中每个16位数进行二进制反码的求和。由于接收方在计算过程中包含了发送方存在首部中的检验和,因此,如果首部在传输过程中没有发生任何差错,那么接收方计算的结果应该为全0或全1(具体看实现了,本质一样) 。如果结果不是全0或全1,那么表示数据错误。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/f1758934fb4a5bf95095a42c0fa42c83.html