开发者

How to calculate a packet checksum without sending it?

I'm using scapy, and I wa开发者_如何转开发nt to create a packet and calculate its' checksum without sending it. Is there a way to do it?

Thanks.


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.


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)]
>>>


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.)


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.


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 |>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜