1 /*****************************************************************************\ 2 * compute_ip_checksum.c 3 \*****************************************************************************/ 4 5 #include <stdint.h> 6 #include "ip_checksum.h" 7 8 /* Note: The contents of this file were borrowed from the coreboot source 9 * code which may be obtained from https://www.coreboot.org. 10 * Specifically, this code was obtained from coreboot (LinuxBIOS) 11 * version 1.0.0.8. 12 */ 13 compute_ip_checksum(void * addr,unsigned long length)14unsigned long compute_ip_checksum(void *addr, unsigned long length) 15 { 16 uint8_t *ptr; 17 volatile union { 18 uint8_t byte[2]; 19 uint16_t word; 20 } value; 21 unsigned long sum; 22 unsigned long i; 23 /* In the most straight forward way possible, 24 * compute an ip style checksum. 25 */ 26 sum = 0; 27 ptr = addr; 28 for (i = 0; i < length; i++) { 29 unsigned long value; 30 value = ptr[i]; 31 if (i & 1) { 32 value <<= 8; 33 } 34 /* Add the new value */ 35 sum += value; 36 /* Wrap around the carry */ 37 if (sum > 0xFFFF) { 38 sum = (sum + (sum >> 16)) & 0xFFFF; 39 } 40 } 41 value.byte[0] = sum & 0xff; 42 value.byte[1] = (sum >> 8) & 0xff; 43 return (~value.word) & 0xFFFF; 44 } 45