diff options
author | Eric Biederman <ebiederm@xmission.com> | 2003-04-22 19:02:15 +0000 |
---|---|---|
committer | Eric Biederman <ebiederm@xmission.com> | 2003-04-22 19:02:15 +0000 |
commit | 8ca8d7665d671e10d72b8fcb4d69121d75f7906e (patch) | |
tree | daad2699b4e6b6014bce5a76e82dd9c974801777 /src/lib/compute_ip_checksum.c | |
parent | b138ac83b53da9abf3dc9a87a1cd4b3d3a8150bd (diff) | |
download | coreboot-8ca8d7665d671e10d72b8fcb4d69121d75f7906e.tar.xz |
- Initial checkin of the freebios2 tree
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@784 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/lib/compute_ip_checksum.c')
-rw-r--r-- | src/lib/compute_ip_checksum.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/lib/compute_ip_checksum.c b/src/lib/compute_ip_checksum.c new file mode 100644 index 0000000000..0b8eb90f85 --- /dev/null +++ b/src/lib/compute_ip_checksum.c @@ -0,0 +1,53 @@ +#include <stdint.h> +#include <ip_checksum.h> + +unsigned long compute_ip_checksum(void *addr, unsigned long length) +{ + uint8_t *ptr; + volatile union { + uint8_t byte[2]; + uint16_t word; + } value; + unsigned long sum; + unsigned long i; + /* In the most straight forward way possible, + * compute an ip style checksum. + */ + sum = 0; + ptr = addr; + for(i = 0; i < length; i++) { + unsigned long value; + value = ptr[i]; + if (i & 1) { + value <<= 8; + } + /* Add the new value */ + sum += value; + /* Wrap around the carry */ + if (sum > 0xFFFF) { + sum = (sum + (sum >> 16)) & 0xFFFF; + } + } + value.byte[0] = sum & 0xff; + value.byte[1] = (sum >> 8) & 0xff; + return (~value.word) & 0xFFFF; +} + +unsigned long add_ip_checksums(unsigned long offset, unsigned long sum, unsigned long new) +{ + unsigned long checksum; + sum = ~sum & 0xFFFF; + new = ~new & 0xFFFF; + if (offset & 1) { + /* byte swap the sum if it came from an odd offset + * since the computation is endian independant this + * works. + */ + new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00); + } + checksum = sum + new; + if (checksum > 0xFFFF) { + checksum -= 0xFFFF; + } + return (~checksum) & 0xFFFF; +} |