libnet creates UDP packets with invalid checksums
Question: I'm using pylibnet to construct and send UDP packets. The UDP packets I
construct in this way all seem to have invalid checksums. Example:

    
    
    # python
    Python 2.4.3 (#1, Sep  3 2009, 15:37:12)
    [GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 
    >>> import libnet
    >>> from libnet.constants import *
    >>> 
    >>> net = libnet.context(RAW4, 'venet0:0')
    >>> ip = net.name2addr4('www.stackoverflow.com', RESOLVE)
    >>> data = 'This is my payload.'
    >>> udptag = net.build_udp(sp=54321, dp=54321, payload=data)
    >>> packetlen = IPV4_H + UDP_H + len(data)
    >>> iptag = net.autobuild_ipv4(len=packetlen, prot=IPPROTO_UDP, dst=ip)
    >>> 
    >>> net.write()
    

Capturing the above packet on the sending host reveals an invalid checksum:

    
    
    # tcpdump -i venet0:0 -n -v -v port 54321
    tcpdump: WARNING: arptype 65535 not supported by libpcap - falling back to cooked socket
    tcpdump: listening on venet0:0, link-type LINUX_SLL (Linux cooked), capture size 96 bytes
    08:16:10.303719 IP (tos 0x0, ttl  64, id 1, offset 0, flags [none], proto: UDP (17), length: 47) 192.168.55.10.54321 > 69.59.196.211.54321: [bad udp cksum 50c3!] UDP, length 0
    

Am I doing something wrong here?


Answer: It's nothing to do with tcpdump bugs or checksum offloading. Libnet calculates
the checksum in user mode as well (FYI). The problem has to do with the fact
that you did not specify a length for the UDP header. This is not
automagically calculated in pylibnet or libnet so you have to specify it for
the time being. Below is the corrected version of your code. I will apply a
patch to pylibnet to automagically detect the header length in rc6. Stay tuned
to <http://sourceforge.net/projects/pylibnet> for updates. I will be pushing a
new release fixing this issue. By the way, please feel free to contact me via
sourceforge's pylibnet page if you have bug or feature requests. I love to
hear from developers using my software :)

* * *
    
    
    import libnet
    from libnet.constants import *
    
    net = libnet.context(RAW4, 'venet0:0')
    ip = net.name2addr4('www.stackoverflow.com', RESOLVE)
    data = 'This is my payload.'
    udptag = net.build_udp(len=UDP_H+len(data), sp=54321, dp=54321, payload=data)
    packetlen = IPV4_H + UDP_H + len(data)
    iptag = net.autobuild_ipv4(len=packetlen, prot=IPPROTO_UDP, dst=ip)
    
    net.write()
    

