Python实现RFC 1071校验码:自定义代码与Scapy结果不一致求解
解决RFC 1071 IP校验和与Scapy结果不一致的问题
原代码的错误点
- 分组逻辑错误:原代码用
convert_packet_bytes[0::1]和convert_packet_bytes[2::1]配对,会把第0字节和第2字节、第1字节和第3字节组合,不符合RFC1071要求的连续2字节为一组的规则。 - 未处理进位:RFC1071要求将所有16位分组相加后,把超过16位的进位值加到低16位,直到结果在16位范围内,而非直接取模65535。
- 未执行取反操作:校验和的最终结果是分组和的按位取反,原代码缺少这一步。
- 未清零校验和字段:IP校验和计算时,需要先将IP头部的校验和字段设为0,Scapy内部计算时会自动处理这一点,原代码直接使用生成的IP包字节流,其中校验和字段可能非0,导致计算偏差。
修正后的代码实现
from scapy.all import IP # 构造IP包并将校验和字段设为0 ip_packet = IP(src='192.168.1.34', dst='192.168.1.1') ip_packet.chksum = 0 # 计算校验和前必须清零该字段 # 转换为字节流 packet_bytes = bytes(ip_packet) # 按连续2字节分组,处理奇数长度的情况(IP头部长度是4字节的倍数,这里不会出现,但保留兼容逻辑) total = 0 for i in range(0, len(packet_bytes), 2): if i + 1 < len(packet_bytes): # 组合为16位整数(大端序) word = (packet_bytes[i] << 8) | packet_bytes[i+1] total += word else: # 奇数字节时补0 word = packet_bytes[i] << 8 total += word # 处理进位:将超过16位的部分加到低16位 while total >> 16: total = (total & 0xFFFF) + (total >> 16) # 按位取反得到校验和 checksum = ~total & 0xFFFF print(f"自定义代码计算结果: {checksum}") # 输出应为63349,与Scapy结果一致
验证结果
运行上述代码,计算结果会和Scapy的show2()输出的校验和一致(63349)。
内容的提问来源于stack exchange,提问作者Bishop
相关产品推荐
相关产品推荐

