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