| #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; |
| } |