1 /* pup_cksum.c 4.1 83/05/30 */ 2 3 #include "../h/types.h" 4 #include "../h/mbuf.h" 5 6 /* 7 * Checksum routine for PUP-I Protocol family (VAX Version). 8 */ 9 pup_cksum(m, len) 10 register struct mbuf *m; 11 register int len; 12 { 13 register u_short *w; 14 register int sum = 0; /* known to be r8 */ 15 register int mlen = 0; 16 17 for (;;) { 18 /* 19 * Each trip around loop adds in 20 * words from one mbuf segment. 21 */ 22 w = mtod(m, u_short *); 23 if (mlen == -1) { 24 /* 25 * There is a byte left from the last segment; 26 * add it into the checksum. 27 */ 28 sum += *(u_char *)w << 8; 29 asm("rotl $1,r8,r8"); 30 w = (u_short *)((char *)w + 1); 31 mlen = m->m_len - 1; 32 len--; 33 } else 34 mlen = m->m_len; 35 m = m->m_next; 36 if (len < mlen) 37 mlen = len; 38 len -= mlen; 39 while ((mlen -= 2) >= 0) { 40 asm("addw2 (r9)+,r8; rotl $1,r8,r8;"); 41 } 42 if (mlen == -1) 43 sum += *(u_char *)w; 44 if (len == 0) 45 break; 46 /* 47 * Locate the next block with some data. 48 * If there is a word split across a boundary we 49 * will wrap to the top with mlen == -1 and 50 * then add it in shifted appropriately. 51 */ 52 for (;;) { 53 if (m == 0) { 54 printf("pup_cksum: out of data\n"); 55 goto done; 56 } 57 if (m->m_len) 58 break; 59 m = m->m_next; 60 } 61 } 62 done: 63 return (sum); 64 } 65