19a747e4fSDavid du Colombier #include <u.h> 29a747e4fSDavid du Colombier #include <libc.h> 39a747e4fSDavid du Colombier #include <ip.h> 49a747e4fSDavid du Colombier 59a747e4fSDavid du Colombier static short endian = 1; 69a747e4fSDavid du Colombier static uchar* aendian = (uchar*)&endian; 79a747e4fSDavid du Colombier #define LITTLE *aendian 89a747e4fSDavid du Colombier 99a747e4fSDavid du Colombier ushort ptclbsum(uchar * addr,int len)109a747e4fSDavid du Colombierptclbsum(uchar *addr, int len) 119a747e4fSDavid du Colombier { 129a747e4fSDavid du Colombier ulong losum, hisum, mdsum, x; 139a747e4fSDavid du Colombier ulong t1, t2; 149a747e4fSDavid du Colombier 159a747e4fSDavid du Colombier losum = 0; 169a747e4fSDavid du Colombier hisum = 0; 179a747e4fSDavid du Colombier mdsum = 0; 189a747e4fSDavid du Colombier 199a747e4fSDavid du Colombier x = 0; 20*73e742d7SDavid du Colombier if((uintptr)addr & 1) { 219a747e4fSDavid du Colombier if(len) { 229a747e4fSDavid du Colombier hisum += addr[0]; 239a747e4fSDavid du Colombier len--; 249a747e4fSDavid du Colombier addr++; 259a747e4fSDavid du Colombier } 269a747e4fSDavid du Colombier x = 1; 279a747e4fSDavid du Colombier } 289a747e4fSDavid du Colombier while(len >= 16) { 299a747e4fSDavid du Colombier t1 = *(ushort*)(addr+0); 309a747e4fSDavid du Colombier t2 = *(ushort*)(addr+2); mdsum += t1; 319a747e4fSDavid du Colombier t1 = *(ushort*)(addr+4); mdsum += t2; 329a747e4fSDavid du Colombier t2 = *(ushort*)(addr+6); mdsum += t1; 339a747e4fSDavid du Colombier t1 = *(ushort*)(addr+8); mdsum += t2; 349a747e4fSDavid du Colombier t2 = *(ushort*)(addr+10); mdsum += t1; 359a747e4fSDavid du Colombier t1 = *(ushort*)(addr+12); mdsum += t2; 369a747e4fSDavid du Colombier t2 = *(ushort*)(addr+14); mdsum += t1; 379a747e4fSDavid du Colombier mdsum += t2; 389a747e4fSDavid du Colombier len -= 16; 399a747e4fSDavid du Colombier addr += 16; 409a747e4fSDavid du Colombier } 419a747e4fSDavid du Colombier while(len >= 2) { 429a747e4fSDavid du Colombier mdsum += *(ushort*)addr; 439a747e4fSDavid du Colombier len -= 2; 449a747e4fSDavid du Colombier addr += 2; 459a747e4fSDavid du Colombier } 469a747e4fSDavid du Colombier if(x) { 479a747e4fSDavid du Colombier if(len) 489a747e4fSDavid du Colombier losum += addr[0]; 499a747e4fSDavid du Colombier if(LITTLE) 509a747e4fSDavid du Colombier losum += mdsum; 519a747e4fSDavid du Colombier else 529a747e4fSDavid du Colombier hisum += mdsum; 539a747e4fSDavid du Colombier } else { 549a747e4fSDavid du Colombier if(len) 559a747e4fSDavid du Colombier hisum += addr[0]; 569a747e4fSDavid du Colombier if(LITTLE) 579a747e4fSDavid du Colombier hisum += mdsum; 589a747e4fSDavid du Colombier else 599a747e4fSDavid du Colombier losum += mdsum; 609a747e4fSDavid du Colombier } 619a747e4fSDavid du Colombier 629a747e4fSDavid du Colombier losum += hisum >> 8; 639a747e4fSDavid du Colombier losum += (hisum & 0xff) << 8; 649a747e4fSDavid du Colombier while(hisum = losum>>16) 659a747e4fSDavid du Colombier losum = hisum + (losum & 0xffff); 669a747e4fSDavid du Colombier 679a747e4fSDavid du Colombier return losum & 0xffff; 689a747e4fSDavid du Colombier } 69