icmp header Prüfsumme berechnen



  • Hallo,

    ich zitiere hier mal das RFC 792

    The 16 bit one's complement of the one's complement sum of all 16
    bit words in the header. For computing the checksum, the checksum
    field should be zero.

    Wie soll ich das jetzt genau verstehen?

    Ok, ich fass den Header zu 16 Bit Stücken zusammen,
    mach von jedem 16Bit Teil das Einerkomplement (~ -Operator ?)
    und addiere alles zusammen.

    Und dann?

    Die Summe kann ja durchaus grösser als 16 Bit sein.
    Wie mach ich dann ein 16 Bit komplement davon?

    Habs einfach mal ignoriert, aber leider stimmt die Checksumme (laut Ethereal) nie...

    hier noch a bissl Code:

    struct icmpHeader
    {
    unsigned char type;
    unsigned char code;
    unsigned short checkSum;
    unsigned short id;
    unsigned short sequence;
    unsigned long timeStamp;
    };
    
    ////////////////////////////////////////////////////
    
    unsigned short my::icmpClient::m_calcCheckSum(icmpHeader & Header)
    {
    unsigned long checkSum = 0;
    
    // type und code haben jeweils 8 Bit => zu 16 Bit zusammenfassen
    unsigned short typeCode = Header.type;
    typeCode <<= 8;
    typeCode += Header.code;
    
    // timeStamp hat 32 Bit => aufteilen auf jeweils 16 Bit
    unsigned short timeStamp1 = Header.timeStamp >> 16;
    unsigned short timeStamp2 = static_cast<unsigned short>(Header.timeStamp);
    
    // Summe aller Einerkomplemente berechnen
    checkSum = ~typeCode;
    checkSum += ~0;	// Prüfsumme ist Bestandteil des Headers und mit 0 vorinitialisiert
    checkSum += ~ Header.id;
    checkSum += ~ Header.sequence;
    checkSum += ~timeStamp1;
    checkSum += ~timeStamp2;
    
    // Einerkomplement der Summe aller Einerkomplemente
    return static_cast<unsigned short>(~checkSum);
    }
    


  • Hier mal eine Klasse die ich dafür geschrieben habe. Ist zwar für 8 Bit Checksummen, aber das Prinzip ist das selbe.

    #ifndef BYTE_ARRAY_HPP
    #define BYTE_ARRAY_HPP
    #include <vector>
    typedef unsigned char Byte;
    
    class ByteArray : public std::vector<Byte>{
    public:
      typedef std::vector<Byte> Base;
    
      Byte getCheckSum() const{
        const Base &base = *dynamic_cast<const Base*>(this);
    
        union{
          unsigned long lSum;
          Byte cSum[4];
        }sum;
    
        Base::const_iterator it = base.begin(), end = base.end();
    
        for (;it!=end;++it){
          sum.lSum += *it;
        }
    
        while (sum.lSum > 0xFF){
          sum.lSum = sum.cSum[0] + sum.cSum[1] + sum.cSum[2] + sum.cSum[3];
        }
        return ~sum.cSum[0];
      };
    
      bool checkSumCorrect() const{
        return getCheckSum() == 0xff;
      };
    
      void setCheckSumAt(size_t position){
        Base &base = *dynamic_cast<Base*>(this);
    
        base[position] = 0x00;
        base[position] = getCheckSum();
        assert(checkSumCorrect());
      };
    };
    #endif
    

Anmelden zum Antworten