Switch dir over to use the new static filesystem dir methods.
[openbios.git] / libopenbios / ipchecksum.c
blob83f39bcea18beb914564c6e69ab8ec42f64908cd
1 /* Taken from Etherboot */
3 #include "libopenbios/ipchecksum.h"
5 unsigned short ipchksum(const void *data, unsigned long length)
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;
15 /* In the most straight forward way possible,
16 * compute an ip style checksum.
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;
26 /* Add the new value */
27 sum += value;
28 /* Wrap around the carry */
29 if (sum > 0xFFFF) {
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;
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.
48 new = (new << 8) | (new >> 8);
50 checksum = sum + new;
51 if (checksum > 0xFFFF) {
52 checksum -= 0xFFFF;
54 return (~checksum) & 0xFFFF;