#include <u.h> | |
#include <libc.h> | |
#include <ip.h> | |
static short endian = 1; | |
static uchar* aendian = (uchar*)&endian; | |
#define LITTLE *aendian | |
ushort | |
ptclbsum(uchar *addr, int len) | |
{ | |
ulong losum, hisum, mdsum, x; | |
ulong t1, t2; | |
losum = 0; | |
hisum = 0; | |
mdsum = 0; | |
x = 0; | |
if((ulong)addr & 1) { | |
if(len) { | |
hisum += addr[0]; | |
len--; | |
addr++; | |
} | |
x = 1; | |
} | |
while(len >= 16) { | |
t1 = *(ushort*)(addr+0); | |
t2 = *(ushort*)(addr+2); mdsum += t1; | |
t1 = *(ushort*)(addr+4); mdsum += t2; | |
t2 = *(ushort*)(addr+6); mdsum += t1; | |
t1 = *(ushort*)(addr+8); mdsum += t2; | |
t2 = *(ushort*)(addr+10); mdsum += t1; | |
t1 = *(ushort*)(addr+12); mdsum += t2; | |
t2 = *(ushort*)(addr+14); mdsum += t1; | |
mdsum += t2; | |
len -= 16; | |
addr += 16; | |
} | |
while(len >= 2) { | |
mdsum += *(ushort*)addr; | |
len -= 2; | |
addr += 2; | |
} | |
if(x) { | |
if(len) | |
losum += addr[0]; | |
if(LITTLE) | |
losum += mdsum; | |
else | |
hisum += mdsum; | |
} else { | |
if(len) | |
hisum += addr[0]; | |
if(LITTLE) | |
hisum += mdsum; | |
else | |
losum += mdsum; | |
} | |
losum += hisum >> 8; | |
losum += (hisum & 0xff) << 8; | |
while(hisum = losum>>16) | |
losum = hisum + (losum & 0xffff); | |
return losum & 0xffff; | |
} |