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