IP Checksum Berechnung
-
Japp, habe ich.
Es muss an etwas größerem liegen. Die Checksume der CDP Daten ist im Musterpaket 46500 (Dezimal). Meine errechnete Checksumme mit meiner Funktion ist weit über 146000.
Zur Zeit prüfe ich nocheinmal sehr aufmerksam die Funktion. Falls ihr Zeit habt, könnt ihr gerne eine Implementation von Euch posten, die ich dann mit meiner vergleichen kann.
-
NeoInferno schrieb:
Japp, habe ich.
Es muss an etwas größerem liegen. Die Checksume der CDP Daten ist im Musterpaket 46500 (Dezimal). Meine errechnete Checksumme mit meiner Funktion ist weit über 146000.
Zur Zeit prüfe ich nocheinmal sehr aufmerksam die Funktion. Falls ihr Zeit habt, könnt ihr gerne eine Implementation von Euch posten, die ich dann mit meiner vergleichen kann.
Da muss dann auch der fehler liegen bei 16 bit kann die checksumme nich grösser als 65535 werden.
K
-
Stimmt, das leuchtet ein. Hier nocheinmal detailierter Pseudocode (nicht wundern, hab einiges recht umständlich gemacht):
Eingabe: Data // Words: Array mit 16-bit Werten Für jedes Zeichen in Data: Füge Zeichen + Nächstes Zeichen zu Words hinzu Wdh. // Komplemente addieren Für jedes Element in Words: Bilde 8-bit des ersten Zeichens Bilde 8-bit des zweiten Zeichens Hänge diese Werte zu einem 16-bit Zeichen zusammen Summe = Summe + (NOT DualzuDezimal(16-bit Zahl)) Wdh. Summe = NOT SummeIch behandle die zwei 8-bit Zeichen getrennt, weil ich nicht weiß, wie ich direkt aus den zwei Zeichen eine Zahl machen kann.
Hoffentlich findet jemand einen Denkfehler im Code.
-
denke das könnte schon so funktionieren aber es fehlt auf jeden fall eine überprüfung auf überlauf. vielleicht so.
// Komplemente addieren Für jedes Element in Words: Bilde 8-bit des ersten Zeichens // verstehe nicht was du hier meinst Bilde 8-bit des zweiten Zeichens Hänge diese Werte zu einem 16-bit Zeichen zusammen Summe = Summe + (NOT DualzuDezimal(16-bit Zahl)) wenn Summe > 65535 Summe = Summe - 65536; Wdh.Kurt
-
ich hab auch noch einen
UINT16 IP_Checksum (UINT16 *data, UINT16 bytecount) { UINT32 sum = 0; while (bytecount > 1) { sum += *data++; bytecount -= 2; } if (bytecount == 1) #ifdef LITTLE_ENDIAN sum += *(UINT8 PTR)data; #else sum += ((UINT16)(*(UINT8 PTR)data))<<8; #endif while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16); return (UINT16)~sum; } /*lint !e818 (Pointer parameter could be declared ptr to const) */-->
'data' zeigt auf den anfang des arrays
'bytecount' anzahl _bytes_ des arrays
-
Hi,
ich verstehe diese Zeile nicht:
while (bytecount > 1) { sum += *data++; bytecount -= 2; }Damit kriegst du doch nur jedes 2te Zeichen zu 'sum' addiert, oder?
Und laut deinem Algo, der mit meinem wenig gemein hat, addierst du also zuerst die ganzen 16-bit WORDs zu sum und bearbeitest sie dann nacher mit Komplementbildung?
Danke,
Neo
-
Hi NeoInferno,
die Berechnung von 'net' stimmt, da dort ein Zeiger auf einen 16Bit-Wert (UINT16) genommen wird.
Aber poste mal deinen Code.
-
Von meinem Code werdet ihr wenig haben - er ist in Visual Basic geschrieben.
Es geht faktisch ums Problem, den Code übersetze ich mir jedes mal in VB (auch wenns mit Zeigern recht schwierig wird
).Wenn es in VB gar nicht funktioniert, werde ich das ganze wohl in C++ schreiben.
-
NeoInferno schrieb:
Von meinem Code werdet ihr wenig haben - er ist in Visual Basic geschrieben.
Es geht faktisch ums Problem, den Code übersetze ich mir jedes mal in VB (auch wenns mit Zeigern recht schwierig wird
).
Wenn es in VB gar nicht funktioniert, werde ich das ganze wohl in C++ schreiben.schreib den code in c# (die syntax ist c-ähnlich), dann saugst du dir sharpdevelop
--> http://www.icsharpcode.net/OpenSource/SD/
und damit machste vb-code draus (der kann das konvertieren)
-
Sorry, dass ich erst jetzt antworte, kann nicht so oft online zur Zeit.
Hier eine Lösung die ich in C++ geschrieben habe, um die Funktion dann als DLL zu exportieren (und in VB zu verwenden). Sie liefert zwar gute Checksummen, wenn ich aber mit z.B. IP vergleiche scheinen sie trotzdem nicht zu stimmen. Findet jemand einen Fehler?
DLLEXPORT uint getipchecksum(string &text, string &checksum) { uint len = text.length()-1; ushort tmp; ushort sum; // Evtl. für gerade Zeichenanzahl Zeichen anhängen if (len % 2 != 0) { text += " "; text[++len] = uchar(0); } // Stückweise Komplemente bilden for (uint i = 0 ; i < len ; i += 2) { tmp = frombytes(text.substr(i,2)); cout<<i<<" + "<<~tmp<<nl; sum += (~tmp); } // Summe als 2 Bytes zurückgeben checksum = tobytes( (~sum),2 ); return 0; }Danke nochmal für eure Hilfe, dieses Problem ist mir wirklich sehr wichtig, da ich es auf zig andere Protokolle übertragen kann.
