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