edisona / dpkt

Automatically exported from code.google.com/p/dpkt
Other
1 stars 0 forks source link

dpkt producing a bad TCP checksum #54

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Is anyone else having this problem?

>>> t = TCP(seq=2857195823, ack=1820174829, flags=16, dport=80, sport=42191)
>>> i = IP(src='\xc0\xa8\x01d', dst='\xd0Rd\xaa', len=40, p=6, data=t)
>>> e = Ethernet( dst = '\x00\x22\x6b\x5f\x71\xbd', src = 
'\x00\x1f\x5b\xc5\x01\xc6', data = i )
>>> e.data.sum
0
>>> e.data.data.sum
0
>>> str(e)
'\x00"k_q\xbd\x00\x1f[\xc5\x01\xc6\x08\x00E\x00\x00(\x00\x00\x00\x00@\x06\x83\xc
7\xc0\xa8\x01d\xd0Rd\xaa\xa4\xcf\x00P\xaaMY/l}\xa9\xedP\x10\xff\xff\xf0\xe7\x00\
x00'
>>> print "%x" % e.data.sum
83c7
>>> print "%x" % e.data.data.sum
f0e7
>>> 

The checksums aren't calculated until you convert the object into a string 
(which is fine).  But after they're calculated, the IP checksum, 83c7 is 
correct and the TCP checksum f0e7 is definitely wrong. It should be f9c3.  I 
don't even get a response from the server I'm sending to unless I manually fix 
the TCP checksum.

Using latest version, 1.7, on Mac OS X 10.6.4 with Python 2.6

Original issue reported on code.google.com by crh0...@gmail.com on 9 Nov 2010 at 8:00

GoogleCodeExporter commented 9 years ago
I think dpkt is neglecting to include a TCP pseudo-header.  Working on a patch 
now...

Original comment by crh0...@gmail.com on 9 Nov 2010 at 8:10

GoogleCodeExporter commented 9 years ago
OK, this was how I got it working correctly:

44,45c44,46
<                 #  Get the checksum of concatenated pseudoheader+TCP packet
<                 self.data.sum = dpkt.in_cksum(s+p)
---
>                 s = dpkt.in_cksum_add(0, s)
>                 s = dpkt.in_cksum_add(s, p)
>                 self.data.sum = dpkt.in_cksum_done(s)

Original comment by crh0...@gmail.com on 9 Nov 2010 at 8:29

GoogleCodeExporter commented 9 years ago
Woops, sorry, here's a real patch.  I didn't really have time to look at 
in_cksum_add() so maybe that is what needs to be patched, but it makes sense to 
me to just use in_cksum() for TCP as it is used for IP.

--- ip.py   2010-03-25 22:53:51.000000000 -0400
+++ ip.py   2010-11-09 15:28:35.000000000 -0500
@@ -41,9 +41,8 @@
                 p = str(self.data)
                 s = dpkt.struct.pack('>4s4sxBH', self.src, self.dst,
                                      self.p, len(p))
-                s = dpkt.in_cksum_add(0, s)
-                s = dpkt.in_cksum_add(s, p)
-                self.data.sum = dpkt.in_cksum_done(s)
+                #  Get the checksum of concatenated pseudoheader+TCP packet
+                self.data.sum = dpkt.in_cksum(s+p)
                 if self.p == 17 and self.data.sum == 0:
                     self.data.sum = 0xffff # RFC 768
                 # XXX - skip transports which don't need the pseudoheader

Original comment by crh0...@gmail.com on 9 Nov 2010 at 8:41