123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #include "u.h"
- #include "../port/lib.h"
- #include "mem.h"
- #include "dat.h"
- #include "fns.h"
- #include "../port/error.h"
- #include "ip.h"
- static short endian = 1;
- static uint8_t* aendian = (uint8_t*)&endian;
- #define LITTLE *aendian
- uint16_t
- ptclbsum(uint8_t *addr, int len)
- {
- uint32_t losum, hisum, mdsum, x;
- uint32_t t1, t2;
- losum = 0;
- hisum = 0;
- mdsum = 0;
- x = 0;
- if(PTR2UINT(addr) & 1) {
- if(len) {
- hisum += addr[0];
- len--;
- addr++;
- }
- x = 1;
- }
- while(len >= 16) {
- t1 = *(uint16_t*)(addr+0);
- t2 = *(uint16_t*)(addr+2); mdsum += t1;
- t1 = *(uint16_t*)(addr+4); mdsum += t2;
- t2 = *(uint16_t*)(addr+6); mdsum += t1;
- t1 = *(uint16_t*)(addr+8); mdsum += t2;
- t2 = *(uint16_t*)(addr+10); mdsum += t1;
- t1 = *(uint16_t*)(addr+12); mdsum += t2;
- t2 = *(uint16_t*)(addr+14); mdsum += t1;
- mdsum += t2;
- len -= 16;
- addr += 16;
- }
- while(len >= 2) {
- mdsum += *(uint16_t*)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;
- }
|