Search code examples
pythonlinuxscapychecksum

incorrect udp/tcp checksum values in scapy


I intercepted an udp packet, deleted the checksum, and then recalculated it with scapy. I've observed that scapy generates wrong checksum values. Is this a library problem? Or am I doing something wrong? If it was my fault, please let me know the proper way to obtain it. I'm running Ubuntu as my operating system.

from scapy.all import *
s=conf.L2listen(iface="wlo1",filter="tcp or udp")
pkt = s.sniff(count=1)[0]
pkt

<Ether  dst=a0:9f:7a:0b:83:4e src=44:e5:17:5d:42:b5 type=IPv4 |<IP  version=4 ihl=5 tos=0x0 len=74 id=3847 flags= frag=0 ttl=64 proto=udp chksum=0xe9e5 src=192.168.0.101 dst=192.168.0.1 |<UDP  sport=35375 dport=domain len=54 chksum=0x81fe |<DNS  id=8493 qr=0 opcode=QUERY aa=0 tc=0 rd=1 ra=0 z=0 ad=0 cd=0 rcode=ok qdcount=1 ancount=0 nscount=0 arcount=1 qd=<DNSQR qname='i.sstatic.net.' qtype=A qclass=IN |> an=None ns=None ar=<DNSRROPT rrname='.' type=OPT rclass=1472 extrcode=0 version=0 z=0 rdlen=None |> |>>>>
pkt[UDP].chksum = None
pkt.show2()

###[ Ethernet ]### 
  dst       = a0:9f:7a:0b:83:4e
  src       = 44:e5:17:5d:42:b5
  type      = IPv4
###[ IP ]### 
     version   = 4
     ihl       = 5
     tos       = 0x0
     len       = 74
     id        = 3847
     flags     = 
     frag      = 0
     ttl       = 64
     proto     = udp
     chksum    = 0xe9e5
     src       = 192.168.0.101
     dst       = 192.168.0.1
     \options   \
###[ UDP ]### 
        sport     = 35375
        dport     = domain
        len       = 54
        chksum    = 0x8f92
...

I expected the chksum value to be (0x81fe) instead of (0x8f92)


Solution

  • I used wire-shark to explore the matter. It returned an incorrect checksum flag for every udp/tcp packet that I intercepted with a note says " maybe caused by udp checksum offload". I searched about that on Google and I came across the following information on the wire-shark website.

    Most modern operating systems support some form of network offloading, where some network processing happens on the NIC instead of the CPU. Normally this is a great thing. It can free up resources on the rest of the system and let it handle more connections. If you're trying to capture traffic it can result in false errors and strange or even missing traffic.

    On systems that support checksum offloading, IP, TCP, and UDP checksums are calculated on the NIC just before they're transmitted on the wire. In Wireshark these show up as outgoing packets marked black with red Text and the note [incorrect, should be xxxx (maybe caused by "TCP checksum offload"?)].

    Wireshark captures packets before they are sent to the network adapter. It won't see the correct checksum because it has not been calculated yet. Even worse, most OSes don't bother initialize this data so you're probably seeing little chunks of memory that you shouldn't.

    Once I temporarily disabled the checksum offload feature, the intercepted checksum and the one generated with scapy were identical, as anticipated.