1
2
3
4
5
6
7
8
9
10
11#include <common.h>
12#include <net.h>
13
14unsigned compute_ip_checksum(const void *vptr, unsigned nbytes)
15{
16 int sum, oddbyte;
17 const unsigned short *ptr = vptr;
18
19 sum = 0;
20 while (nbytes > 1) {
21 sum += *ptr++;
22 nbytes -= 2;
23 }
24 if (nbytes == 1) {
25 oddbyte = 0;
26 ((u8 *)&oddbyte)[0] = *(u8 *)ptr;
27 ((u8 *)&oddbyte)[1] = 0;
28 sum += oddbyte;
29 }
30 sum = (sum >> 16) + (sum & 0xffff);
31 sum += (sum >> 16);
32 sum = ~sum & 0xffff;
33
34 return sum;
35}
36
37unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned new)
38{
39 unsigned long checksum;
40
41 sum = ~sum & 0xffff;
42 new = ~new & 0xffff;
43 if (offset & 1) {
44
45
46
47
48 new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00);
49 }
50 checksum = sum + new;
51 if (checksum > 0xffff)
52 checksum -= 0xffff;
53
54 return (~checksum) & 0xffff;
55}
56
57int ip_checksum_ok(const void *addr, unsigned nbytes)
58{
59 return !(compute_ip_checksum(addr, nbytes) & 0xfffe);
60}
61