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 Summe
    

    Ich 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. 🙂


Anmelden zum Antworten