|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.