Entwickler-Ecke

Algorithmen, Optimierung und Assembler - TCP Prüfsumme


der_zaehe - So 15.10.06 15:17
Titel: TCP Prüfsumme
Heho,

ich arbeite momentan an der Implementierung eines Algorithmus zur Herstellung von P2P-TCP-Verbindungen durch NATs wie Router oder Firewalls. Das läuft bis jetzt auch ganz gut und ich habe fast alle Probleme irgendwie überwunden, aber gerade hänge ich echt fest. Ich muss an einer Stelle im Ablauf des Verbindungsaufbaus ein "hausgemachtes", gefälschtes TCP-Packet versenden. Dieses Packet habe ich mir bis jetzt auch ganz gut zusammenbauen können, aber nun habe ich keine Ahnung, wie genau die Prüfsumme berechnet wird. Ich habe mir in erster Linie den entsprechenden Artikel in der Wikipedia [http://de.wikipedia.org/wiki/TCP-Header#Aufbau_und_Funktion_des_TCP_Pseudo-Headers] durchgelesen und auch lange gegoogelt, aber keine anschauliche Beschreibung oder Erläuterung des Verfahrens gefunden. Wie funktioniert das? Oder, um genau zu sein: Was bedeutet "Addition von 16 Bit-Werten im Einerkomplement"?

Schon mal danke im voraus für eure Hilfe,
Der Zaehe


BenBE - Mo 16.10.06 14:34

Einfach alle Words des TCP-Pakets hintereinander schreiben, jedes Word addieren und am Ende jedes Bit umkeehren ...


Quelltext
1:
01 23 45 67 89 AB CD EF                    


Wird also zu


Quelltext
1:
0123 + 4567 + 89AB + CDEF = 19E24 --> 9E24                    


Und dann einfach das Einerkomplement dieser Summe: 9E24 --> 61DC ...

Steht doch eigentlich im entsprechenden RFC\STD für TCP drin ...


der_zaehe - Mo 16.10.06 22:53

Ah, also einfach aufaddieren. Danke!

Edit: Moment, gerade habe ich die RFC nochmal studiert. Da steht:
Zitat:

The checksum field is the 16 bit one's complement of the one's complement sum of all 16 bit words in the header and text.

Heißt das nicht, das ich aus den Wörtern vor dem Addieren nicht auch das Einserkomplement bilden muss?


der_zaehe - Fr 20.10.06 00:44

Öh, hat doch gestimmt, so wie dus gesagt hast. :oops:
Hier ist der Code. Stimmt das so?

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
int intChecksum = 0;
ushort word = 0;
for (int i = 0; i < 6; i++)
{
    word = BitConverter.ToUInt16(tcpPseudoHeader, i * 2);
    intChecksum += word;
}
for (int i = 0; i < 10; i++)
{
    word = BitConverter.ToUInt16(tcpHeader, i * 2);
    intChecksum += word;
}
intChecksum = intChecksum + (intChecksum >> 16);
ushort ushortChecksum = BitConverter.ToUInt16(BitConverter.GetBytes(intChecksum), 2);
ushortChecksum = ~ushortChecksum;