Python 如何在不发送数据包校验和的情况下计算数据包校验和?

Python 如何在不发送数据包校验和的情况下计算数据包校验和?,python,scapy,Python,Scapy,我正在使用scapy,我想创建一个数据包并计算它的校验和,而不发送它。有办法吗 谢谢。创建数据包后,您需要从数据包中删除.chksum值;然后调用.show2() 我还试图避免show2(),因为它会打印数据包。 我在源代码中找到了一个更好的解决方案: del packet.chksum packet = packet.__class__(bytes(packet)) 此代码使用正确的校验和重新生成数据包,无需任何打印,实际上是show2()在打印前在后台运行的代码。将此修补程序添加到scap

我正在使用scapy,我想创建一个数据包并计算它的校验和,而不发送它。有办法吗


谢谢。

创建数据包后,您需要从数据包中删除
.chksum
值;然后调用
.show2()


我还试图避免show2(),因为它会打印数据包。 我在源代码中找到了一个更好的解决方案:

del packet.chksum
packet = packet.__class__(bytes(packet))

此代码使用正确的校验和重新生成数据包,无需任何打印,实际上是show2()在打印前在后台运行的代码。

将此修补程序添加到scapy/packet.py:

+    def checksum_silent(self):
+        """
+        Internal method that recalcs checksum without the annoying prints
+        **AFTER old checksums are deleted.**
+        """
+
+        for f in self.fields_desc:
+            if isinstance(f, ConditionalField) and not f._evalcond(self):
+                continue
+            fvalue = self.getfieldval(f.name)
+            if isinstance(fvalue, Packet) or (f.islist and f.holds_packets and type(fvalue) is list):
+                fvalue_gen = SetGen(fvalue,_iterpacket=0)
+                for fvalue in fvalue_gen:
+                    fvalue.checksum_silent()
+        if self.payload:
+            self.payload.checksum_silent()
然后,不要调用
pkt.show2()
,只需调用此函数即可
pkt.checksum\u silent()
(记得先做
del-pkt[IP].chksum
del-pkt[UDP].chksum
,等等)
,如前面的答案所示

此功能应该更快,并且是静默的。(可能还有其他需要修剪的地方;我把这段代码拼凑在一起,测试的目的只是确保它没有使用正确的校验和。)

事实上,
show2()
函数会为您计算校验和,但它也会在完成工作后打印数据包的内容。但是,
show2()
有一个有用的小参数,名为
dump
。消息来源这样描述:

:param dump:确定它是否打印或返回字符串值


因此,通过设置
dump=True
,您可以避免函数默认提供的讨厌的输出,并且仍然可以获得所需的计算。

您还可以使用
packet.build()
,它返回具有正确校验和的原始字节。然后将字节转换为数据包

>>> import scapy.all as sp
>>> packet = sp.IP(src='127.0.0.1', dst='8.8.8.8')
>>> packet
<IP  src=127.0.0.1 dst=8.8.8.8 |>
>>> sp.IP(packet.build())
<IP  version=4 ihl=5 tos=0x0 len=20 id=1 flags= frag=0 ttl=64 
proto=hopopt chksum=0xebd8 src=127.0.0.1 dst=8.8.8.8 |>
>>将scapy.all作为sp导入
>>>数据包=sp.IP(src='127.0.0.1',dst='8.8.8.8')
>>>小包
>>>sp.IP(packet.build())

谢谢。我找到了另一个选项-将数据包转换为字符串,然后使用该字符串重新创建它。@Dima,谢谢你的建议。我想避免
show2()
,因为所有的输出都是不必要的。也许应该有一个
recalc
packet函数。@Shickadance先生,你可以通过重新分配
stdout
来轻松地让它安静一会儿。。。i、 e.
stdout,null=sys.stdout,打开('/dev/null','w');sys.stdout=null
。当您使用
sys.stdout=stdout
再次完成重新分配时,似乎我实际上使用了非常类似的解决方案进行了注释。没有静默或任何东西……有没有办法只获取新的chksum字段,而不是整个
show2()
输出?到目前为止,这是真正的最佳答案。不要试图从印刷品中提取数据,这可能会随着时间的推移而改变回答得很好,谢谢!只是加上第二行对我造成了一个重大的、无法解释的延迟,但因为我想发送数据包,我只是删除了它,并在发送过程中重新计算了校验和本身。因此我使用了
del ret_packet.chksum
del ret_packet[UDP]。chksum
用于UDP不要试图从打印中提取数据:它根本不是一个稳定的API,可能会在不另行通知的情况下进行更改
>>> import scapy.all as sp
>>> packet = sp.IP(src='127.0.0.1', dst='8.8.8.8')
>>> packet
<IP  src=127.0.0.1 dst=8.8.8.8 |>
>>> sp.IP(packet.build())
<IP  version=4 ihl=5 tos=0x0 len=20 id=1 flags= frag=0 ttl=64 
proto=hopopt chksum=0xebd8 src=127.0.0.1 dst=8.8.8.8 |>