ICMP(Ping)功能原理及其应用简介
一、 Ping功能简介
1、 原始套接字(Raw Socket)
原始套接字(Raw Socket)是一种特殊的网络编程接口,它允许直接接收和发送网络层的数据包,而不是通过传输层。这种套接字可以接收本机网卡上的数据帧或者数据包,对于监听网络的流量和分析网络数据非常有用。
Ping属于原始套接字的应用。
2 、 ICMP帧简介
① 、帧结构
| 8bit | 8bit | 16bit |
|____________|____________|_____________________|______
| | | | ↑
| Type | Code | Checksum | ICMP首部
| | | | ↓
|____________|____________|_____________________|______
| | ↑
| Data | ICMP数据
| | ↓
|_______________________________________________|______
#ICMP协议报文结构(标准)
| 8bit | 8bit | 16bit |
|____________|____________|_____________________|______
| Type | Code | Checksum | ↑
|____________|____________|_____________________| ICMP首部
| Identifier | Sequence Number | ↓
|_________________________|_____________________|______
| | ↑
| 可选数据区: 请求报文方发送,应答方重复报文内容 | ICMP数据
| | ↓
|_______________________________________________|______
#ICMP协议常用的请求与请求响应结构(ping)
② 、 常用Type、Code 字段含义
Type(类型) | Code (代码) | 内容 |
---|---|---|
0 | 0 | 回送应答(Echo Reply) |
3 | 0 | 网络不可达 |
3 | 1 | 主机不可达 |
3 | 2 | 协议不可达 |
3 | 3 | 端口不可达 |
3 | 4 | 需要进行分片,但设置为不分片 |
3 | 5 | 源站选路失败 |
3 | 6 | 目的网络不认识 |
3 | 7 | 目的主机不认识 |
3 | 9 | 目标网络被强制禁止 |
3 | 10 | 目标主机被强制禁止 |
3 | 11 | 由于TOS,网络不可达 |
3 | 12 | 由于TOS,主机不可达 |
3 | 13 | 由于过滤,通信被强制禁止 |
3 | 14 | 主机越权 |
3 | 15 | 优先权终止生效 |
4 | 0 | 源端被关闭 |
5 | 0 | 对网络重定向 |
5 | 1 | 对主机重定向 |
5 | 2 | 对服务类型和网络重定向 |
5 | 3 | 对服务类型和主机重定向 |
8 | 0 | 请求应答(Ping 请求) |
9 | 0 | 路由器通告 |
10 | 0 | 路由器请求通告 |
11 | 0 | 传输期间生存时间为0 |
12 | 0 | 坏的IP首部 |
12 | 1 | 缺少必要的选项 |
17 | 0 | 地址掩码请求 |
18 | 0 | 地址掩码应答 |
③ 、Checksum校验和
对于ICMP
协议校验和计算方式,参考RFC官方文档给出的说明:
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.
If the total length is odd, the received data is padded with one
octet of zeros for computing the checksum. This checksum may be
replaced in the future.
步骤如下:
一、获取ICMP报文(首部+数据部分)
二、将ICMP报文中的校验和字段置为0。
三、将ICMP协议报文中的每两个字节(16位,需要注意大小端问题)两两相加,得到一个累加和。若报文长度为奇数,则最后一个字节(8-bit) 作为高8位,再用0填充一个字节(低8-bit)扩展到16-bit,之后再和前面的累加和继续相加得到一个新的累加和。
四、(若有溢出)将累加和的高16位和低16位相加,直到最后只剩下16位。
五、将最后得到的16位结果取反(按位取反)作为校验和的值。
ICMP
协议校验和计算代码示例
/**
* icmp_checksum:
* @size: the icmp data packet length
* @icmp_data: icmp protocol packet both header and data
*
* Calc icmp's checksum:
* if we divide the ICMP data packet is 16 bit words and sum each of them up
* then hihg 16bit add low 16bit to sum get a value,
* If the total length is odd,
* the last byte is padded with one octet of zeros for computing the checksum.
* Then hihg 16bit add low 16bit to sum get a value,
* finally do a one's complementing
* then the value generated out of this operation would be the checksum.
*
* Return: unsigned short checksum
*/
unsigned short icmp_checksum(char * icmp_packet, int size)
{
unsigned short * sum = (unsigned short *)icmp_packet;
unsigned int checksum = 0;
while (size > 1)
{
checksum += ntohs(*sum++);
size -=