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)1512827Ssam pup_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