xref: /plan9/sys/src/9/ip/ptclbsum.c (revision 80ee5cbfe36716af62da8896207e9763b8e3d760)
1 #include	"u.h"
2 #include	"../port/lib.h"
3 #include	"mem.h"
4 #include	"dat.h"
5 #include	"fns.h"
6 #include	"../port/error.h"
7 #include	"ip.h"
8 
9 static	short	endian	= 1;
10 static	uchar*	aendian	= (uchar*)&endian;
11 #define	LITTLE	*aendian
12 
13 ushort
ptclbsum(uchar * addr,int len)14 ptclbsum(uchar *addr, int len)
15 {
16 	ulong losum, hisum, mdsum, x;
17 	ulong t1, t2;
18 
19 	losum = 0;
20 	hisum = 0;
21 	mdsum = 0;
22 
23 	x = 0;
24 	if((ulong)addr & 1) {
25 		if(len) {
26 			hisum += addr[0];
27 			len--;
28 			addr++;
29 		}
30 		x = 1;
31 	}
32 	while(len >= 16) {
33 		t1 = *(ushort*)(addr+0);
34 		t2 = *(ushort*)(addr+2);	mdsum += t1;
35 		t1 = *(ushort*)(addr+4);	mdsum += t2;
36 		t2 = *(ushort*)(addr+6);	mdsum += t1;
37 		t1 = *(ushort*)(addr+8);	mdsum += t2;
38 		t2 = *(ushort*)(addr+10);	mdsum += t1;
39 		t1 = *(ushort*)(addr+12);	mdsum += t2;
40 		t2 = *(ushort*)(addr+14);	mdsum += t1;
41 		mdsum += t2;
42 		len -= 16;
43 		addr += 16;
44 	}
45 	while(len >= 2) {
46 		mdsum += *(ushort*)addr;
47 		len -= 2;
48 		addr += 2;
49 	}
50 	if(x) {
51 		if(len)
52 			losum += addr[0];
53 		if(LITTLE)
54 			losum += mdsum;
55 		else
56 			hisum += mdsum;
57 	} else {
58 		if(len)
59 			hisum += addr[0];
60 		if(LITTLE)
61 			hisum += mdsum;
62 		else
63 			losum += mdsum;
64 	}
65 
66 	losum += hisum >> 8;
67 	losum += (hisum & 0xff) << 8;
68 	while(hisum = losum>>16)
69 		losum = hisum + (losum & 0xffff);
70 
71 	return losum & 0xffff;
72 }
73