1 /* 2 * Copyright (c) 1986 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)cksum.tahoe.c 2.4 (Berkeley) 06/01/90"; 10 #endif /* not lint */ 11 12 #include <sys/types.h> 13 14 /* 15 * Checksum routine for Internet Protocol family headers. 16 * 17 * This routine is very heavily used in the network 18 * code and should be modified for each CPU to be as fast as possible. 19 * 20 * This implementation is TAHOE version. 21 */ 22 23 #undef ADDCARRY 24 #define ADDCARRY(sum) { \ 25 if (sum & 0xffff0000) { \ 26 sum &= 0xffff; \ 27 sum++; \ 28 } \ 29 } 30 31 in_cksum(addr, len) 32 register u_short *addr; 33 register int len; 34 { 35 union word { 36 char c[2]; 37 u_short s; 38 } u; 39 register int sum = 0; 40 41 while (len > 0) { 42 /* 43 * add by words. 44 */ 45 while ((len -= 2) >= 0) { 46 if ((int)addr & 0x1) { 47 /* word is not aligned */ 48 u.c[0] = *(char *)addr; 49 u.c[1] = *((char *)addr+1); 50 sum += u.s; 51 addr++; 52 } else 53 sum += *addr++; 54 ADDCARRY(sum); 55 } 56 if (len == -1) 57 /* 58 * Odd number of bytes. 59 */ 60 u.c[0] = *(u_char *)addr; 61 } 62 if (len == -1) { 63 /* The last mbuf has odd # of bytes. Follow the 64 standard (the odd byte is shifted left by 8 bits) */ 65 u.c[1] = 0; 66 sum += u.s; 67 ADDCARRY(sum); 68 } 69 return (~sum & 0xffff); 70 } 71