Scapy官方文档已经给出了IPv4的UDP校验和的计算方式
- 自动计算IPV4 UDP校验和
# 构建数据包
packet = IP(dst="10.11.12.13", src="10.11.12.14")/UDP()/DNS()
# 把数据包转换成byte,这时候会自动计算校验和
packet = IP(raw(packet))
# 查看校验和
checksum_scapy = packet[UDP].chksum
- 手动计算IPv4 UDP校验和
# 构建数据包,将校验和设置为0
packet = IP(dst="10.11.12.13", src="10.11.12.14")/UDP(chksum=0)/DNS()
# 校验和转化为byte
packet_raw = raw(packet)
# 得到udp部分的byte,也就是IP负载(payload),20是IPv4包头的长度
udp_raw = packet_raw[20:]
# 计算校验和,socket.IPPROTO_UDP是协议号,UDP是17,可以直接写17
chksum = in4_chksum(socket.IPPROTO_UDP, packet[IP], udp_raw)
# 将校验和写回数据包
packet.chksum = chksum
# 下面就可以发包了
两种方式得到的校验和是一样的
3. 手动计算IPv6 UDP 校验和
通过实践发现IPv6 UDP 校验和只能手动计算,按照自动计算IPv4校验和的方式校验和还是不变。手动计算IPv6 UDP 校验和与计算 IPv4 UDP 校验和一致。
# 构建数据包,将校验和设置为0,构建数据包完才能计算校验和,dst,src,sport,dport这些都会影响校验和的计算
packet = IPv6(dst="2001:4860:4860::8888")/UDP(chksum=0, dport = 33434)
# 校验和转化为byte
packet_raw = raw(packet)
# 得到udp部分的byte,也就是IPv6负载(payload),40是IPv6包头的长度
udp_raw = packet_raw[40:]
# 计算校验和
chksum = in6_chksum(socket.IPPROTO_UDP, packet[IP], udp_raw)
# 将校验和写回数据包
packet.chksum = chksum
==在Scapy发包时不用设定校验和,在调用发包函数发包后,校验和会自动填上。==在构造数据包后查看数据包chksum字段是0,但是发包时Scapy会自动计算。可以通过抓包查看校验和。使用命令
sniff(filter='ip6 dst xxxx', prn=lambda x:x.show(),count=1)
上面的代码会收到目的地址为xxxx发送的包,就是自己构造的包,如果是ipv4则把ip6换成ip即可。可以查看chksum字段。count=1为收到一个包就停止监听的意思。
本文介绍了如何使用Scapy进行IPv4和IPv6 UDP校验和的计算。Scapy官方文档详细说明了IPv4 UDP自动计算校验和的方法,同时手动计算与自动计算结果一致。对于IPv6 UDP,由于其特殊性,只能手动计算校验和,步骤与IPv4相同。在Scapy构造并发送数据包时,尽管初始校验和为0,但Scapy会在发送时自动填充正确的校验和,可以通过抓包工具验证这一过程。
411

被折叠的 条评论
为什么被折叠?



