- 新增原理解释文档,详细说明了 ICMP、UDP 和 TCP 报文的构建与发送原理 - 新增校验和计算文档,提供了正确的 ICMP 校验和计算方法 - 这些文档有助于开发者更好地理解网络报文的构建和发送过程
1.7 KiB
1.7 KiB
为了正确地计算 ICMP 报文的校验和 (checksum),我们需要遵循以下步骤:
- 填充报文头部的校验和字段为
0
。 - 将报文数据划分为 16 位块并求和。
- 如果报文长度为奇数,在末尾补零。
- 对总和取反,并将其结果存入校验和字段。
以下是修改后的代码,增加了正确的 ICMP 校验和计算:
# 计算校验和
def calculate_checksum(data):
checksum = 0
n = len(data)
# 按 16 位块划分
for i in range(0, n - 1, 2):
chunk = (data[i] << 8) + data[i + 1]
checksum += chunk
# 如果长度为奇数,补零
if n % 2 == 1:
checksum += data[-1] << 8
# 将 32 位总和折叠为 16 位
checksum = (checksum >> 16) + (checksum & 0xFFFF)
checksum += (checksum >> 16)
# 对总和取反
return ~checksum & 0xFFFF
# 构造 ICMP 报文
def construct_icmp():
# ICMP 报文头部: 类型(8), 代码(0), 校验和(0), 标识符(1), 序列号(1)
icmp_header = struct.pack('!BBHHH', 8, 0, 0, 1, 1)
data = b'Ping'
# 计算校验和
checksum = calculate_checksum(icmp_header + data)
# 填充校验和字段
icmp_header = struct.pack('!BBHHH', 8, 0, checksum, 1, 1)
return icmp_header + data
说明
calculate_checksum
函数负责按 ICMP 的要求计算校验和。- 数据部分(例如
"Ping"
)被添加到报文头后计算校验和。 - 构造的 ICMP 报文将包含报文头和数据部分。
使用方法
使用这个改进后的 construct_icmp
函数可以确保生成的 ICMP 报文具有正确的校验和,从而能够在网络中正常解析和传输。