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

发布于 2024-11-06 19:19:32 字数 60 浏览 6 评论 0原文

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

谢谢。

I'm using scapy, and I want to create a packet and calculate its' checksum without sending it. Is there a way to do it?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

李不 2024-11-13 19:19:32

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

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

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

I've also tried to avoid show2() because it print the packet.
I've found in the source a better solution:

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

This code regenerate the packet with the correct checksum without any print and actually is what show2() run in the background before printing.

墨小墨 2024-11-13 19:19:32

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

>>> from scapy.layers.inet import IP
>>> from scapy.layers.inet import ICMP
>>> from scapy.layers.inet import TCP
>>> target = "10.9.8.7"
>>> ttl = 64
>>> id = 32711
>>> sport = 2927
>>> dport = 80
>>> pak = IP(dst=target, src = "100.99.98.97", ttl=ttl, flags="DF", id=id, len=1200, chksum = 0)/TCP(flags="S", sport=sport, dport=int(dport), options=[('Timestamp',(0,0))], chksum = 0)
>>> del pak[IP].chksum
>>> del pak[TCP].chksum
>>> pak.show2()
###[ IP ]###
  version   = 4L
  ihl       = 5L
  tos       = 0x0
  len       = 1200
  id        = 32711
  flags     = DF
  frag      = 0L
  ttl       = 64
  proto     = tcp
  chksum    = 0x9afd
  src       = 100.99.98.97
  dst       = 10.9.8.7
  \options   \
###[ TCP ]###
     sport     = 2927
     dport     = www
     seq       = 0
     ack       = 0
     dataofs   = 8L
     reserved  = 0L
     flags     = S
     window    = 8192
     chksum    = 0x2c0e
     urgptr    = 0
     options   = [('Timestamp', (0, 0)), ('EOL', None)]
>>>

You need to delete the .chksum value from the packet after you create it; then call .show2()

>>> from scapy.layers.inet import IP
>>> from scapy.layers.inet import ICMP
>>> from scapy.layers.inet import TCP
>>> target = "10.9.8.7"
>>> ttl = 64
>>> id = 32711
>>> sport = 2927
>>> dport = 80
>>> pak = IP(dst=target, src = "100.99.98.97", ttl=ttl, flags="DF", id=id, len=1200, chksum = 0)/TCP(flags="S", sport=sport, dport=int(dport), options=[('Timestamp',(0,0))], chksum = 0)
>>> del pak[IP].chksum
>>> del pak[TCP].chksum
>>> pak.show2()
###[ IP ]###
  version   = 4L
  ihl       = 5L
  tos       = 0x0
  len       = 1200
  id        = 32711
  flags     = DF
  frag      = 0L
  ttl       = 64
  proto     = tcp
  chksum    = 0x9afd
  src       = 100.99.98.97
  dst       = 10.9.8.7
  \options   \
###[ TCP ]###
     sport     = 2927
     dport     = www
     seq       = 0
     ack       = 0
     dataofs   = 8L
     reserved  = 0L
     flags     = S
     window    = 8192
     chksum    = 0x2c0e
     urgptr    = 0
     options   = [('Timestamp', (0, 0)), ('EOL', None)]
>>>
蓦然回首 2024-11-13 19:19:32

将此补丁添加到 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_silent()(记得先做del pkt[IP].chksumdel pkt[UDP].chksum等)如上图所示回答。

这个功能应该更快并且安静。 (可能还有其他东西需要修剪;我将这段代码拼凑在一起,仅进行测试以确保它在正确的校验和下保持沉默。)

Add this patch to 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()

Then instead of calling pkt.show2(), just call this function
pkt.checksum_silent(). (Remember to first do del pkt[IP].chksum and del pkt[UDP].chksum, etc.) as shown in the previous answer.

This function should be faster and be silent. (There may be additional things to trim as well; I hacked this code together and only tested to make sure it was silent with correct checksum.)

陌路黄昏 2024-11-13 19:19:32

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

:param dump:判断是打印还是返回字符串值

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

Indeed, the show2() function calculates the checksum for you, but it also prints the contents of the packet once it is finished with its work. However, show2() has a helpful little parameter named dump. The source describes it as such:

:param dump: determine if it prints or returns the string value

So by setting dump=True, you can avoid the pesky output that the function provides by default, and still get the calculations that you want.

白衬杉格子梦 2024-11-13 19:19:32

您还可以使用 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 |>

You can also use packet.build() which returns raw bytes with correct checksum. Then convert the bytes to a packet.

>>> 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 |>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文