coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
compute_ip_checksum.c
Go to the documentation of this file.
1 #include <stdint.h>
2 #include <ip_checksum.h>
3 
4 unsigned long compute_ip_checksum(const void *addr, unsigned long length)
5 {
6  const uint8_t *ptr;
7  volatile union {
8  uint8_t byte[2];
10  } value;
11  unsigned long sum;
12  unsigned long i;
13  /* In the most straight forward way possible,
14  * compute an ip style checksum.
15  */
16  sum = 0;
17  ptr = addr;
18  for (i = 0; i < length; i++) {
19  unsigned long v;
20  v = ptr[i];
21  if (i & 1)
22  v <<= 8;
23  /* Add the new value */
24  sum += v;
25  /* Wrap around the carry */
26  if (sum > 0xFFFF)
27  sum = (sum + (sum >> 16)) & 0xFFFF;
28  }
29  value.byte[0] = sum & 0xff;
30  value.byte[1] = (sum >> 8) & 0xff;
31  return (~value.word) & 0xFFFF;
32 }
33 
34 unsigned long add_ip_checksums(unsigned long offset, unsigned long sum,
35  unsigned long new)
36 {
37  unsigned long checksum;
38  sum = ~sum & 0xFFFF;
39  new = ~new & 0xFFFF;
40  if (offset & 1) {
41  /* byte swap the sum if it came from an odd offset
42  * since the computation is endian independent this
43  * works.
44  */
45  new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00);
46  }
47  checksum = sum + new;
48  if (checksum > 0xFFFF)
49  checksum -= 0xFFFF;
50  return (~checksum) & 0xFFFF;
51 }
pte_t value
Definition: mmu.c:91
static u32 addr
Definition: cirrus.c:14
unsigned long compute_ip_checksum(const void *addr, unsigned long length)
unsigned long add_ip_checksums(unsigned long offset, unsigned long sum, unsigned long new)
static size_t offset
Definition: flashconsole.c:16
uint64_t length
Definition: fw_cfg_if.h:1
static uint8_t checksum(uint8_t *data, int offset)
Definition: ipmi_fru.c:70
static unsigned int word
Definition: uart.c:88
unsigned short uint16_t
Definition: stdint.h:11
unsigned char uint8_t
Definition: stdint.h:8