Tcp Checksum Berechnung



  • Du kannst doch mit Ethereal einen Dump von dem Paket mal posten. Da müsste man doch genau sehen, was in dem Paket drinsteht und dann probieren wir es damit mal.



  • tcp.checksum = csum(b, sizeof(forcsum)+sizeof(tcp)+buflen)+buflen;
    

    buffer = "" -> Checksum: 0xeec5 [correct]
    buffer = "a" -> Checksum: 0x8ec5 [incorrect, should be 0x8dc4]
    buffer = "aa" -> Checksum: 0x8f64 [incorrect, should be 0x8f64]
    buffer = "aaa" -> Checksum: 0x2f64 [incorrect, should be 0x2c61]

    Hm ich verstehe das nicht! Obwohl ich buflen dazu addiert habe, stimmt das immer noch nicht :(!



  • Dump mit Buffer = "aa"

    Frame 179 (60 bytes on wire, 60 bytes captured)
    Arrival Time: Sep 13, 2005 21:35:26.134344000
    Time delta from previous packet: 2.572850000 seconds
    Time since reference or first frame: 2.572850000 seconds
    Frame Number: 179
    Packet Length: 60 bytes
    Capture Length: 60 bytes
    Protocols in frame: eth:ip:tcp:data
    Ethernet II, Src: 192.168.2.100 (00:e0:18:b9:13:8f), Dst: 192.168.2.99 (00:a0:cc:d3:c6:c6)
    Destination: 192.168.2.99 (00:a0:cc:d3:c6:c6)
    Source: 192.168.2.100 (00:e0:18:b9:13:8f)
    Type: IP (0x0800)
    Trailer: 61206469
    Internet Protocol, Src: 192.168.2.100 (192.168.2.100), Dst: 192.168.2.99 (192.168.2.99)
    Version: 4
    Header length: 20 bytes
    Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
    Total Length: 42
    Identification: 0x0100 (256)
    Flags: 0x00
    Fragment offset: 0
    Time to live: 128
    Protocol: TCP (0x06)
    Header checksum: 0xb3b6 [correct]
    Source: 192.168.2.100 (192.168.2.100)
    Destination: 192.168.2.99 (192.168.2.99)
    Transmission Control Protocol, Src Port: 1024 (1024), Dst Port: 24 (24), Seq: 0, Ack: 0, Len: 2
    Source port: 1024 (1024)
    Destination port: 24 (24)
    Sequence number: 0 (relative sequence number)
    Next sequence number: 2 (relative sequence number)
    Header length: 20 bytes
    Flags: 0x0002 (SYN)
    Window size: 64240
    Checksum: 0x8f64 [incorrect, should be 0x8d62]
    Data (2 bytes)

    0000 00 a0 cc d3 c6 c6 00 e0 18 b9 13 8f 08 00 45 00 ..............E.
    0010 00 2a 01 00 00 00 80 06 b3 b6 c0 a8 02 64 c0 a8 .*...........d..
    0020 02 63 04 00 00 18 0d 8e 2e 6e 00 00 00 00 50 02 .c.......n....P.
    0030 fa f0 8f 64 00 00 61 61 61 20 64 69 ...d..aaa di



  • Bei der Berechnung ändert sich nur das Hi-Byte (und natürlich subtrahieren anstatt addieren). Müsste also:

    tcp.checksum = csum(b, sizeof(forcsum)+sizeof(tcp)+buflen)- (buflen << 8);
    

    sein.

    Bei dem Paket sehe ich leider zumindest nichts offensichtliches.



  • Weshalb muss ich hier nur das HiByte subtrahieren?



  • Little/Big Endian?
    Wenn Du 1 auf Deinen Checksumme addierst und aus 0x8dc5 jetzt 0x8ec5 wird, heisst dass wohl, dass deine Zahl in Deinem Programm 0xc58d war. Ansonsten ist mir nicht klar, wie aus den Werten die Du vor dem Addieren der Bufferlänge gepostet hast, die Werte nach der Addition werden sollten.

    Bei der Berechnung der Checksumme könntest Du den Buffer mitausgeben. Der sollte mit dem von Ethereal ausgegebenen Paket identisch sein (plus Header). Vielleicht siehst Du ja dort eine Abweichung.



  • was definierst du als zahl in meinem Program? Wie kommst du von 0x8dc5 und 0x8ec5 auf 0xc58d? Verstehe immer noch nicht richtig weshalb ich nur die 8bit des Integerwertes subtrahieren muss?

    Lg Joe



  • Die hexadezimale Zahl 0x8dc5 besteht aus 2 Bytes 0x8d und 0xc5. Je nach Maschine werden diese Bytes entweder zu 0x8dc5 oder zu 0xc58d zusammengesetzt. Wenn Du jetzt die Zahl 0x8dc5 in Ethereal siehst, dieser Zahl vermeintlich eins hinzuaddierst und danach 0x8ec5 siehst, würde ich mal vermuten, dass die Zahl intern in Deinem Programm 0xc58d ist. Ansonsten würde ich nicht verstehen, wie Du auf den angegebenen Wert kommst.

    Wenn obiges stimmt, dann musst Du also um von 0x8dc5 auf 0x8dc4 zu kommen, eins abziehen. Da Deine interne Darstellung offensichtlich 0xc58d ist, bedeutet dass 256 (0x100) abziehen. Das ist gleichbedeutend mit (1 << 8).

    BTW, die Header Checksum ist ja richtig. Die ist auch aus Deinem Programm, oder? Das bedeutet ja auch, dass die Berechnung eigentlich richtig ist. Also musst Ethereal die Checksum über andere Daten berechnen als Du. Hast Du mal den Input an die Checksum Routine in ähnlicher Form ausgegeben wie bei Etherreal? Ist das wirklich alles gleich?



  • Buffer = "a" rückgabewert von csum (int) -> -14963 das entspricht 0x8dc5

    Hmm << verschiebt doch den Wert 1 in bit um 8 Stellen oder?



  • ahja ist klar 🙂

    sizeof(forcsum)+sizeof(tcp)+buflen (int) = 33 bei buffer = "a"

    LG


Anmelden zum Antworten