Rawsock library  v0.3.4
Library to make the use of raw sockets easier, under Linux. Currently supporting IPv4, UDP and a custom latency measurement protocol (LaMP - supported both in raw and non-raw sockets).
ipcsum_alth.c
1 // Rawsock library, licensed under GPLv2
2 // Version 0.3.4
3 #include "ipcsum_alth.h"
4 
5 // This is all taken from Linux kernel 4.19.1 (this is not original work)
6 static inline unsigned short from32to16(unsigned int x) {
7  /* add up 16-bit and 16-bit for 16+c bit */
8  x = (x & 0xffff) + (x >> 16);
9  /* add up carry.. */
10  x = (x & 0xffff) + (x >> 16);
11  return x;
12 }
13 
14 // This is all taken from Linux kernel 4.19.1 (this is not original work)
15 static unsigned int do_csum(const unsigned char *buff, int len) {
16  int odd;
17  unsigned int result = 0;
18 
19  if (len <= 0)
20  goto out;
21  odd = 1 & (unsigned long) buff;
22  if (odd) {
23 #ifdef __LITTLE_ENDIAN
24  result += (*buff << 8);
25 #else
26  result = *buff;
27 #endif
28  len--;
29  buff++;
30  }
31  if (len >= 2) {
32  if (2 & (unsigned long) buff) {
33  result += *(unsigned short *) buff;
34  len -= 2;
35  buff += 2;
36  }
37  if (len >= 4) {
38  const unsigned char *end = buff + ((unsigned)len & ~3);
39  unsigned int carry = 0;
40  do {
41  unsigned int w = *(unsigned int *) buff;
42  buff += 4;
43  result += carry;
44  result += w;
45  carry = (w > result);
46  } while (buff < end);
47  result += carry;
48  result = (result & 0xffff) + (result >> 16);
49  }
50  if (len & 2) {
51  result += *(unsigned short *) buff;
52  buff += 2;
53  }
54  }
55  if (len & 1)
56 #ifdef __LITTLE_ENDIAN
57  result += *buff;
58 #else
59  result += (*buff << 8);
60 #endif
61  result = from32to16(result);
62  if (odd)
63  result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
64 out:
65  return result;
66 }
67 
84 __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
85 {
86  return (__sum16)~do_csum(iph,ihl*4);
87 }
__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
Calculate the IPv4 checksum (optimized for IP headers, which always checksum on 4 octet boundaries) ...
Definition: ipcsum_alth.c:84