17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <ip.h>
49a747e4fSDavid du Colombier #include <auth.h>
57dd7cddfSDavid du Colombier #include "ppp.h"
67dd7cddfSDavid du Colombier
77dd7cddfSDavid du Colombier static ushort endian = 1;
87dd7cddfSDavid du Colombier static uchar* aendian = (uchar*)&endian;
97dd7cddfSDavid du Colombier #define LITTLE *aendian
107dd7cddfSDavid du Colombier
117dd7cddfSDavid du Colombier ushort
ptclbsum(uchar * addr,int len)127dd7cddfSDavid du Colombier ptclbsum(uchar *addr, int len)
137dd7cddfSDavid du Colombier {
147dd7cddfSDavid du Colombier ulong losum, hisum, mdsum, x;
157dd7cddfSDavid du Colombier ulong t1, t2;
167dd7cddfSDavid du Colombier
177dd7cddfSDavid du Colombier losum = 0;
187dd7cddfSDavid du Colombier hisum = 0;
197dd7cddfSDavid du Colombier mdsum = 0;
207dd7cddfSDavid du Colombier
217dd7cddfSDavid du Colombier x = 0;
22*312a1df1SDavid du Colombier if((uintptr)addr & 1) {
237dd7cddfSDavid du Colombier if(len) {
247dd7cddfSDavid du Colombier hisum += addr[0];
257dd7cddfSDavid du Colombier len--;
267dd7cddfSDavid du Colombier addr++;
277dd7cddfSDavid du Colombier }
287dd7cddfSDavid du Colombier x = 1;
297dd7cddfSDavid du Colombier }
307dd7cddfSDavid du Colombier while(len >= 16) {
317dd7cddfSDavid du Colombier t1 = *(ushort*)(addr+0);
327dd7cddfSDavid du Colombier t2 = *(ushort*)(addr+2); mdsum += t1;
337dd7cddfSDavid du Colombier t1 = *(ushort*)(addr+4); mdsum += t2;
347dd7cddfSDavid du Colombier t2 = *(ushort*)(addr+6); mdsum += t1;
357dd7cddfSDavid du Colombier t1 = *(ushort*)(addr+8); mdsum += t2;
367dd7cddfSDavid du Colombier t2 = *(ushort*)(addr+10); mdsum += t1;
377dd7cddfSDavid du Colombier t1 = *(ushort*)(addr+12); mdsum += t2;
387dd7cddfSDavid du Colombier t2 = *(ushort*)(addr+14); mdsum += t1;
397dd7cddfSDavid du Colombier mdsum += t2;
407dd7cddfSDavid du Colombier len -= 16;
417dd7cddfSDavid du Colombier addr += 16;
427dd7cddfSDavid du Colombier }
437dd7cddfSDavid du Colombier while(len >= 2) {
447dd7cddfSDavid du Colombier mdsum += *(ushort*)addr;
457dd7cddfSDavid du Colombier len -= 2;
467dd7cddfSDavid du Colombier addr += 2;
477dd7cddfSDavid du Colombier }
487dd7cddfSDavid du Colombier if(x) {
497dd7cddfSDavid du Colombier if(len)
507dd7cddfSDavid du Colombier losum += addr[0];
517dd7cddfSDavid du Colombier if(LITTLE)
527dd7cddfSDavid du Colombier losum += mdsum;
537dd7cddfSDavid du Colombier else
547dd7cddfSDavid du Colombier hisum += mdsum;
557dd7cddfSDavid du Colombier } else {
567dd7cddfSDavid du Colombier if(len)
577dd7cddfSDavid du Colombier hisum += addr[0];
587dd7cddfSDavid du Colombier if(LITTLE)
597dd7cddfSDavid du Colombier hisum += mdsum;
607dd7cddfSDavid du Colombier else
617dd7cddfSDavid du Colombier losum += mdsum;
627dd7cddfSDavid du Colombier }
637dd7cddfSDavid du Colombier
647dd7cddfSDavid du Colombier losum += hisum >> 8;
657dd7cddfSDavid du Colombier losum += (hisum & 0xff) << 8;
667dd7cddfSDavid du Colombier while(hisum = losum>>16)
677dd7cddfSDavid du Colombier losum = hisum + (losum & 0xffff);
687dd7cddfSDavid du Colombier
697dd7cddfSDavid du Colombier return losum & 0xffff;
707dd7cddfSDavid du Colombier }
717dd7cddfSDavid du Colombier
727dd7cddfSDavid du Colombier ushort
ptclcsum(Block * bp,int offset,int len)737dd7cddfSDavid du Colombier ptclcsum(Block *bp, int offset, int len)
747dd7cddfSDavid du Colombier {
757dd7cddfSDavid du Colombier uchar *addr;
767dd7cddfSDavid du Colombier ulong losum, hisum;
777dd7cddfSDavid du Colombier ushort csum;
787dd7cddfSDavid du Colombier int odd, blen, x;
797dd7cddfSDavid du Colombier
807dd7cddfSDavid du Colombier /* Correct to front of data area */
817dd7cddfSDavid du Colombier while(bp != nil && offset && offset >= BLEN(bp)) {
827dd7cddfSDavid du Colombier offset -= BLEN(bp);
837dd7cddfSDavid du Colombier bp = bp->next;
847dd7cddfSDavid du Colombier }
857dd7cddfSDavid du Colombier if(bp == nil)
867dd7cddfSDavid du Colombier return 0;
877dd7cddfSDavid du Colombier
887dd7cddfSDavid du Colombier addr = bp->rptr + offset;
897dd7cddfSDavid du Colombier blen = BLEN(bp) - offset;
907dd7cddfSDavid du Colombier
917dd7cddfSDavid du Colombier if(bp->next == nil) {
927dd7cddfSDavid du Colombier if(blen < len)
937dd7cddfSDavid du Colombier len = blen;
947dd7cddfSDavid du Colombier return ~ptclbsum(addr, len) & 0xffff;
957dd7cddfSDavid du Colombier }
967dd7cddfSDavid du Colombier
977dd7cddfSDavid du Colombier losum = 0;
987dd7cddfSDavid du Colombier hisum = 0;
997dd7cddfSDavid du Colombier
1007dd7cddfSDavid du Colombier odd = 0;
1017dd7cddfSDavid du Colombier while(len) {
1027dd7cddfSDavid du Colombier x = blen;
1037dd7cddfSDavid du Colombier if(len < x)
1047dd7cddfSDavid du Colombier x = len;
1057dd7cddfSDavid du Colombier
1067dd7cddfSDavid du Colombier csum = ptclbsum(addr, x);
1077dd7cddfSDavid du Colombier if(odd)
1087dd7cddfSDavid du Colombier hisum += csum;
1097dd7cddfSDavid du Colombier else
1107dd7cddfSDavid du Colombier losum += csum;
1117dd7cddfSDavid du Colombier odd = (odd+x) & 1;
1127dd7cddfSDavid du Colombier len -= x;
1137dd7cddfSDavid du Colombier
1147dd7cddfSDavid du Colombier bp = bp->next;
1157dd7cddfSDavid du Colombier if(bp == nil)
1167dd7cddfSDavid du Colombier break;
1177dd7cddfSDavid du Colombier blen = BLEN(bp);
1187dd7cddfSDavid du Colombier addr = bp->rptr;
1197dd7cddfSDavid du Colombier }
1207dd7cddfSDavid du Colombier
1217dd7cddfSDavid du Colombier losum += hisum>>8;
1227dd7cddfSDavid du Colombier losum += (hisum&0xff)<<8;
1237dd7cddfSDavid du Colombier while((csum = losum>>16) != 0)
1247dd7cddfSDavid du Colombier losum = csum + (losum & 0xffff);
1257dd7cddfSDavid du Colombier
1267dd7cddfSDavid du Colombier return ~losum & 0xffff;
1277dd7cddfSDavid du Colombier }
1287dd7cddfSDavid du Colombier
1297dd7cddfSDavid du Colombier ushort
ipcsum(uchar * addr)1307dd7cddfSDavid du Colombier ipcsum(uchar *addr)
1317dd7cddfSDavid du Colombier {
1327dd7cddfSDavid du Colombier int len;
1337dd7cddfSDavid du Colombier ulong sum;
1347dd7cddfSDavid du Colombier
1357dd7cddfSDavid du Colombier sum = 0;
1367dd7cddfSDavid du Colombier len = (addr[0]&0xf)<<2;
1377dd7cddfSDavid du Colombier
1387dd7cddfSDavid du Colombier while(len > 0) {
1397dd7cddfSDavid du Colombier sum += (addr[0]<<8) | addr[1] ;
1407dd7cddfSDavid du Colombier len -= 2;
1417dd7cddfSDavid du Colombier addr += 2;
1427dd7cddfSDavid du Colombier }
1437dd7cddfSDavid du Colombier
1447dd7cddfSDavid du Colombier sum = (sum & 0xffff) + (sum >> 16);
1457dd7cddfSDavid du Colombier sum = (sum & 0xffff) + (sum >> 16);
1467dd7cddfSDavid du Colombier
1477dd7cddfSDavid du Colombier return (sum^0xffff);
1487dd7cddfSDavid du Colombier }
149