1 /* Taken from Etherboot */
3 #include "libopenbios/ipchecksum.h"
5 unsigned short ipchksum(const void *data, unsigned long length)
9 const unsigned char *ptr;
11 unsigned char byte[2];
15 /* In the most straight forward way possible,
16 * compute an ip style checksum.
20 for(i = 0; i < length; i++) {
26 /* Add the new value */
28 /* Wrap around the carry */
30 sum = (sum + (sum >> 16)) & 0xFFFF;
33 u.byte[0] = (unsigned char) sum;
34 u.byte[1] = (unsigned char) (sum >> 8);
35 return (unsigned short) ~u.word;
38 unsigned short add_ipchksums(unsigned long offset, unsigned short sum, unsigned short new)
40 unsigned long checksum;
44 /* byte swap the sum if it came from an odd offset
45 * since the computation is endian independant this
48 new = (new << 8) | (new >> 8);
51 if (checksum > 0xFFFF) {
54 return (~checksum) & 0xFFFF;