Annotation of qemu/roms/openbios/libopenbios/ipchecksum.c, revision 1.1

1.1     ! root        1: /* Taken from Etherboot */
        !             2: 
        !             3: #include "libopenbios/ipchecksum.h"
        !             4: 
        !             5: unsigned short ipchksum(const void *data, unsigned long length)
        !             6: {
        !             7:        unsigned long sum;
        !             8:        unsigned long i;
        !             9:        const unsigned char *ptr;
        !            10:        union {
        !            11:            unsigned char byte[2];
        !            12:            unsigned short word;
        !            13:        } u;
        !            14: 
        !            15:        /* In the most straight forward way possible,
        !            16:         * compute an ip style checksum.
        !            17:         */
        !            18:        sum = 0;
        !            19:        ptr = data;
        !            20:        for(i = 0; i < length; i++) {
        !            21:                unsigned long value;
        !            22:                value = ptr[i];
        !            23:                if (i & 1) {
        !            24:                        value <<= 8;
        !            25:                }
        !            26:                /* Add the new value */
        !            27:                sum += value;
        !            28:                /* Wrap around the carry */
        !            29:                if (sum > 0xFFFF) {
        !            30:                        sum = (sum + (sum >> 16)) & 0xFFFF;
        !            31:                }
        !            32:        }
        !            33:        u.byte[0] = (unsigned char) sum;
        !            34:        u.byte[1] = (unsigned char) (sum >> 8);
        !            35:        return (unsigned short) ~u.word;
        !            36: }
        !            37: 
        !            38: unsigned short add_ipchksums(unsigned long offset, unsigned short sum, unsigned short new)
        !            39: {
        !            40:        unsigned long checksum;
        !            41:        sum = ~sum & 0xFFFF;
        !            42:        new = ~new & 0xFFFF;
        !            43:        if (offset & 1) {
        !            44:                /* byte swap the sum if it came from an odd offset
        !            45:                 * since the computation is endian independant this
        !            46:                 * works.
        !            47:                 */
        !            48:                new = (new << 8) | (new >> 8);
        !            49:        }
        !            50:        checksum = sum + new;
        !            51:        if (checksum > 0xFFFF) {
        !            52:                checksum -= 0xFFFF;
        !            53:        }
        !            54:        return (~checksum) & 0xFFFF;
        !            55: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.