1*25949Ssam /* ns_cksum.c 1.1 86/01/23 */ 2*25949Ssam 3*25949Ssam /* 4*25949Ssam * ns_cksum.c - Xerox Internet Datagram protocol checksum 5*25949Ssam */ 6*25949Ssam #include "types.h" 7*25949Ssam #include "mbuf.h" 8*25949Ssam 9*25949Ssam /* 10*25949Ssam * Perform (slowly) the Xerox Internet checksum algorithm on a 11*25949Ssam * chain of mbufs. This means we add all the 16-bits words, 12*25949Ssam * shifting the sum after each 16-bit add. Ones-complement 13*25949Ssam * arithmetic is required, so we fold the carry bits after 14*25949Ssam * each 16-bit add as well. 15*25949Ssam * If the result is the *no-checksum* value 0xffff, return zero instead. 16*25949Ssam * 17*25949Ssam * Chris Torek <chris@maryland> 18*25949Ssam * James O'Toole <james@maryland> 19*25949Ssam */ 20*25949Ssam u_short 21*25949Ssam ns_cksum(m, len) 22*25949Ssam register struct mbuf *m; 23*25949Ssam register int len; 24*25949Ssam { 25*25949Ssam register int cksum = 0; 26*25949Ssam register int shift = 8; 27*25949Ssam register u_char *p; 28*25949Ssam register int mlen; 29*25949Ssam 30*25949Ssam if (len & 1) 31*25949Ssam printf("ns_cksum: odd length\n"); 32*25949Ssam while (m && len) { 33*25949Ssam p = mtod(m, u_char *); 34*25949Ssam mlen = m->m_len; 35*25949Ssam if ((len -= mlen) < 0) 36*25949Ssam mlen += len, len = 0; 37*25949Ssam while (--mlen >= 0) { 38*25949Ssam cksum += *p++ << shift; 39*25949Ssam if ((shift = 8 - shift) != 0) { 40*25949Ssam cksum <<= 1; 41*25949Ssam cksum = (cksum & 0xffff) + (cksum >> 16); 42*25949Ssam } 43*25949Ssam } 44*25949Ssam m = m->m_next; 45*25949Ssam } 46*25949Ssam #ifdef notdef 47*25949Ssam if (len) 48*25949Ssam printf("ns_cksum: out of data\n"); 49*25949Ssam #endif 50*25949Ssam return (cksum == 0xffff ? 0 : cksum); 51*25949Ssam } 52