ping命令和ICMP协议

ICMP全称Internet Control Message Protocol,就是互联网控制报文协议
ICMP 报文是封装在 IP 包里面的。因为传输指令的时候,肯定需要源地址目标地址。它本身非常简单。因为作为侦查兵,要轻装上阵,不能携带大量的包袱。
在这里插入图片描述
ICMP 报文有很多的类型,不同的类型有不同的代码。最常用的类型是主动请求为 8,主动请求的应答为0。

查询报文类型

我们经常在电视剧里听到这样的话:主帅说,来人哪!前方战事如何,快去派人打探,一有情况,立即通报!
这种是主帅发起的,主动查看敌情,对应 ICMP 的查询报文类型。例如,常用的ping 就是查询报文,是一种主动请求,并且获得主动应答的 ICMP 协议。所以,ping 发的包也是符合 ICMP 协议格式的,只不过它在后面增加了自己的格式。
对 ping 的主动请求,进行网络抓包,称为ICMP ECHO REQUEST。同理主动请求的回复,称为ICMP ECHO REPLY。比起原生的 ICMP,这里面多了两个字段,一个是标识符。这个很好理解,你派出去两队侦查兵,一队是侦查战况的,一队是去查找水源的,要有个标识才能区分。另一个是序号,你派出去的侦查兵,都要编个号。如果派出去 10 个,回来 10 个,就说明前方战况不错;如果派出去 10 个,回来 2 个,说明情况可能不妙。
在选项数据中,ping 还会存放发送请求的时间值,来计算往返时间,说明路程的长短。

差错报文类型

当然也有另外一种方式,就是差错报文。
主帅骑马走着走着,突然来了一匹快马,上面的小兵气喘吁吁的:报告主公,不好啦!张将军遭遇埋伏,全军覆没啦!这种是异常情况发起的,来报告发生了不好的事情,对应 ICMP 的差错报文类型。
我举几个 ICMP 差错报文的例子:终点不可达为 3,源抑制为 4,超时为 11,重定向为 5。这些都是什么意思呢?我给你具体解释一下。

第一种是终点不可达。小兵:报告主公,您让把粮草送到张将军那里,结果没有送到。
如果你是主公,你肯定会问,为啥送不到?具体的原因在代码中表示就是,网络不可达代码为 0,主机不可达代码为 1,协议不可达代码为 2,端口不可达代码为 3,需要进行分片但设置了不分片位代码为4。
第二种是源站抑制,也就是让源站放慢发送速度。小兵:报告主公,您粮草送的太多了吃不完。
第三种是时间超时,也就是超过网络包的生存时间还是没到。小兵:报告主公,送粮草的人,自己把粮草吃完了,还没找到地方,已经饿死啦。
第四种是路由重定向,也就是让下次发给另一个路由器。小兵:报告主公,上次送粮草的人本来只要走一站地铁,非得从五环绕,下次别这样了啊。

差错报文的结构相对复杂一些。除了前面还是 IP,ICMP 的前 8 字节不变,后面则跟上出错的那个 IP 包的 IP 头IP 正文的前 8 个字节

### Ping命令的工作原理 Ping命令用于测试网络连接状态及其质量。通过发送ICMP回显请求消息给目标主机并等待接收来自该主机的ICMP回显应答消息来验证通信路径是否可达[^1]。 当发起一次Ping操作时,源设备会构建一个ICMP Echo Request(类型8)报文,并将其封装在一个IP包里发出;一旦目的端收到这个Echo Request之后就会回复一个对应的ICMP Echo Reply(类型0),同样也是被嵌入到另一个IP分组之中返回给原发者。整个过程可以简单描述如下: 1. 发送方构造ICMP Echo Request数据包; 2. 将其作为上层负载打包成IPv4/IPv6格式的数据帧传输至接收节点; 3. 接收方解析出ICMP部分的信息后作出回应——即创建相应的Reply响应; 4. 这个答复再次经过相同的流程逆向传回到最初的询问者那里完成一轮交互循环。 这种机制不仅能够确认两台机器间的连通状况如何,还可以测量往返时间(RTT),从而评估链路性能的好坏程度。 #### ICMP协议详解 Internet控制消息协议(ICMP)属于TCP/IP模型中的网际层组件之一,主要负责传递有关路由选择错误、拥塞情况以及其他异常事件的通知信息给应用程序或者操作系统本身处理[^2]。除了支持像Ping这样的诊断工具外,在其他方面也有广泛应用场景比如Traceroute用来发现到达远程位置所经过的所有中间跳数等。 ICMP报文通常由三部分组成:固定长度为四个字节的首部字段加上可变大小的内容区域再加上校验计算范围覆盖整个PDU(Protocol Data Unit)[^3]。具体来说, - **Type**: 表明当前消息种类,如上述提到过的Request (8)/Reply (0); - **Code**: 对type做进一步补充说明,默认情况下设为零表示无特殊含义; - **Checksum**: 保障数据完整性的一种手段,通过对全部有效载荷实施CRC算法得出的结果值; ```python import struct def calculate_checksum(data): """Calculate checksum of data""" sum = 0 for i in range(0, len(data), 2): if i + 1 >= len(data): sum += ord(data[i]) & 0xFF else: w = ((ord(data[i]) << 8) & 0xFF00) + (ord(data[i+1]) & 0xFF) sum += w while (sum >> 16) > 0: sum = (sum & 0xFFFF) + (sum >> 16) return ~sum & 0xFFFF # Example usage with an echo request packet creation echo_request_type = 8 # Type field value for Echo Requests code_value_zero = 0 # Code set to zero as per standard practice identifier_field = b'\x1a\x2b' # Identifier can be any two-byte sequence; here we use arbitrary values. sequence_number = b'\xc8\x7d' # Sequence number also takes up exactly two bytes. pseudo_header = struct.pack('!BBHHH', echo_request_type, code_value_zero, 0, int.from_bytes(identifier_field,'big'), int.from_bytes(sequence_number,'big')) checksum_result = calculate_checksum(pseudo_header+b'data') # Replace 'data' with actual payload content when implementing fully functional ping utility. print(f"Calculated Checksum Value: {hex(checksum_result)}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值