123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- #include <u.h>
- #include <libc.h>
- #include <ip.h>
- #include <auth.h>
- #include "ppp.h"
- static ushort 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((uintptr)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;
- }
- ushort
- ptclcsum(Block *bp, int offset, int len)
- {
- uchar *addr;
- ulong losum, hisum;
- ushort csum;
- int odd, blen, x;
- /* Correct to front of data area */
- while(bp != nil && offset && offset >= BLEN(bp)) {
- offset -= BLEN(bp);
- bp = bp->next;
- }
- if(bp == nil)
- return 0;
- addr = bp->rptr + offset;
- blen = BLEN(bp) - offset;
- if(bp->next == nil) {
- if(blen < len)
- len = blen;
- return ~ptclbsum(addr, len) & 0xffff;
- }
- losum = 0;
- hisum = 0;
- odd = 0;
- while(len) {
- x = blen;
- if(len < x)
- x = len;
- csum = ptclbsum(addr, x);
- if(odd)
- hisum += csum;
- else
- losum += csum;
- odd = (odd+x) & 1;
- len -= x;
- bp = bp->next;
- if(bp == nil)
- break;
- blen = BLEN(bp);
- addr = bp->rptr;
- }
- losum += hisum>>8;
- losum += (hisum&0xff)<<8;
- while((csum = losum>>16) != 0)
- losum = csum + (losum & 0xffff);
- return ~losum & 0xffff;
- }
- ushort
- ipcsum(uchar *addr)
- {
- int len;
- ulong sum;
- sum = 0;
- len = (addr[0]&0xf)<<2;
- while(len > 0) {
- sum += (addr[0]<<8) | addr[1] ;
- len -= 2;
- addr += 2;
- }
- sum = (sum & 0xffff) + (sum >> 16);
- sum = (sum & 0xffff) + (sum >> 16);
- return (sum^0xffff);
- }
|