xref: /original-bsd/sys/sparc/sparc/in_cksum.c (revision 304a8d6d)
191449f87Storek /*
2*304a8d6dSbostic  * Copyright (c) 1992, 1993
3*304a8d6dSbostic  *	The Regents of the University of California.  All rights reserved.
491449f87Storek  *
591449f87Storek  * This software was developed by the Computer Systems Engineering group
691449f87Storek  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
791449f87Storek  * contributed to Berkeley.
891449f87Storek  *
983548bb1Sbostic  * All advertising materials mentioning features or use of this software
1083548bb1Sbostic  * must display the following acknowledgement:
1183548bb1Sbostic  *	This product includes software developed by the University of
12bf37ff33Storek  *	California, Lawrence Berkeley Laboratory.
1383548bb1Sbostic  *
1491449f87Storek  * %sccs.include.redist.c%
1591449f87Storek  *
16*304a8d6dSbostic  *	@(#)in_cksum.c	8.1 (Berkeley) 06/11/93
1791449f87Storek  *
18bf37ff33Storek  * from: $Header: in_cksum.c,v 1.7 92/11/26 03:04:52 torek Exp $
1991449f87Storek  */
2091449f87Storek 
21a159b5e1Sbostic #include <sys/param.h>
22a159b5e1Sbostic #include <sys/mbuf.h>
23a159b5e1Sbostic 
24a159b5e1Sbostic #include <netinet/in.h>
25a159b5e1Sbostic #include <netinet/in_systm.h>
2691449f87Storek 
2791449f87Storek /*
2891449f87Storek  * Checksum routine for Internet Protocol family headers.
2991449f87Storek  * This routine is very heavily used in the network
3091449f87Storek  * code and should be modified for each CPU to be as fast as possible.
3191449f87Storek  * In particular, it should not be this one.
3291449f87Storek  */
3391449f87Storek int
in_cksum(m,len)3491449f87Storek in_cksum(m, len)
3591449f87Storek 	register struct mbuf *m;
3691449f87Storek 	register int len;
3791449f87Storek {
3891449f87Storek 	register int sum = 0, i, oddbyte = 0, v = 0;
3991449f87Storek 	register u_char *cp;
4091449f87Storek 
4191449f87Storek 	/* we assume < 2^16 bytes being summed */
4291449f87Storek 	while (len) {
4391449f87Storek 		while ((i = m->m_len) == 0)
4491449f87Storek 			m = m->m_next;
4591449f87Storek 		if (i > len)
4691449f87Storek 			i = len;
4791449f87Storek 		len -= i;
4891449f87Storek 		cp = mtod(m, u_char *);
4991449f87Storek 		if (oddbyte) {
5091449f87Storek 			sum += v + *cp++;
5191449f87Storek 			i--;
5291449f87Storek 		}
5391449f87Storek 		if (((int)cp & 1) == 0) {
5491449f87Storek 			while ((i -= 2) >= 0) {
5591449f87Storek 				sum += *(u_short *)cp;
5691449f87Storek 				cp += 2;
5791449f87Storek 			}
5891449f87Storek 		} else {
5991449f87Storek 			while ((i -= 2) >= 0) {
6091449f87Storek 				sum += *cp++ << 8;
6191449f87Storek 				sum += *cp++;
6291449f87Storek 			}
6391449f87Storek 		}
6491449f87Storek 		if ((oddbyte = i & 1) != 0)
6591449f87Storek 			v = *cp << 8;
6691449f87Storek 		m = m->m_next;
6791449f87Storek 	}
6891449f87Storek 	if (oddbyte)
6991449f87Storek 		sum += v;
7091449f87Storek 	sum = (sum >> 16) + (sum & 0xffff); /* add in accumulated carries */
7191449f87Storek 	sum += sum >> 16;		/* add potential last carry */
7291449f87Storek 	return (0xffff & ~sum);
7391449f87Storek }
74