1*23271Smckusick /* 2*23271Smckusick * Copyright (c) 1982 Regents of the University of California. 3*23271Smckusick * All rights reserved. The Berkeley software License Agreement 4*23271Smckusick * specifies the terms and conditions for redistribution. 5*23271Smckusick * 6*23271Smckusick * @(#)pup_cksum.c 6.3 (Berkeley) 06/08/85 7*23271Smckusick */ 812827Ssam 917043Sbloom #include "types.h" 1017043Sbloom #include "mbuf.h" 1112827Ssam 1212827Ssam /* 1312827Ssam * Checksum routine for PUP-I Protocol family (VAX Version). 1412827Ssam */ pup_cksum(m,len)1512827Ssampup_cksum(m, len) 1612827Ssam register struct mbuf *m; 1712827Ssam register int len; 1812827Ssam { 1912827Ssam register u_short *w; 2012827Ssam register int sum = 0; /* known to be r8 */ 2112827Ssam register int mlen = 0; 2212827Ssam 2312827Ssam for (;;) { 2412827Ssam /* 2512827Ssam * Each trip around loop adds in 2612827Ssam * words from one mbuf segment. 2712827Ssam */ 2812827Ssam w = mtod(m, u_short *); 2912827Ssam if (mlen == -1) { 3012827Ssam /* 3112827Ssam * There is a byte left from the last segment; 3212827Ssam * add it into the checksum. 3312827Ssam */ 3412827Ssam sum += *(u_char *)w << 8; 3512827Ssam asm("rotl $1,r8,r8"); 3612827Ssam w = (u_short *)((char *)w + 1); 3712827Ssam mlen = m->m_len - 1; 3812827Ssam len--; 3912827Ssam } else 4012827Ssam mlen = m->m_len; 4112827Ssam m = m->m_next; 4212827Ssam if (len < mlen) 4312827Ssam mlen = len; 4412827Ssam len -= mlen; 4512827Ssam while ((mlen -= 2) >= 0) { 4612827Ssam asm("addw2 (r9)+,r8; rotl $1,r8,r8;"); 4712827Ssam } 4812827Ssam if (mlen == -1) 4912827Ssam sum += *(u_char *)w; 5012827Ssam if (len == 0) 5112827Ssam break; 5212827Ssam /* 5312827Ssam * Locate the next block with some data. 5412827Ssam * If there is a word split across a boundary we 5512827Ssam * will wrap to the top with mlen == -1 and 5612827Ssam * then add it in shifted appropriately. 5712827Ssam */ 5812827Ssam for (;;) { 5912827Ssam if (m == 0) { 6012827Ssam printf("pup_cksum: out of data\n"); 6112827Ssam goto done; 6212827Ssam } 6312827Ssam if (m->m_len) 6412827Ssam break; 6512827Ssam m = m->m_next; 6612827Ssam } 6712827Ssam } 6812827Ssam done: 6912827Ssam return (sum); 7012827Ssam } 71