xref: /original-bsd/sys/sparc/sparc/in_cksum.c (revision 2f29ec0e)
1 /*
2  * Copyright (c) 1992 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This software was developed by the Computer Systems Engineering group
6  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7  * contributed to Berkeley.
8  *
9  * All advertising materials mentioning features or use of this software
10  * must display the following acknowledgement:
11  *	This product includes software developed by the University of
12  *	California, Lawrence Berkeley Laboratory.
13  *
14  * %sccs.include.redist.c%
15  *
16  *	@(#)in_cksum.c	7.4 (Berkeley) 04/20/93
17  *
18  * from: $Header: in_cksum.c,v 1.7 92/11/26 03:04:52 torek Exp $
19  */
20 
21 #include <sys/param.h>
22 #include <sys/mbuf.h>
23 
24 #include <netinet/in.h>
25 #include <netinet/in_systm.h>
26 
27 /*
28  * Checksum routine for Internet Protocol family headers.
29  * This routine is very heavily used in the network
30  * code and should be modified for each CPU to be as fast as possible.
31  * In particular, it should not be this one.
32  */
33 int
34 in_cksum(m, len)
35 	register struct mbuf *m;
36 	register int len;
37 {
38 	register int sum = 0, i, oddbyte = 0, v = 0;
39 	register u_char *cp;
40 
41 	/* we assume < 2^16 bytes being summed */
42 	while (len) {
43 		while ((i = m->m_len) == 0)
44 			m = m->m_next;
45 		if (i > len)
46 			i = len;
47 		len -= i;
48 		cp = mtod(m, u_char *);
49 		if (oddbyte) {
50 			sum += v + *cp++;
51 			i--;
52 		}
53 		if (((int)cp & 1) == 0) {
54 			while ((i -= 2) >= 0) {
55 				sum += *(u_short *)cp;
56 				cp += 2;
57 			}
58 		} else {
59 			while ((i -= 2) >= 0) {
60 				sum += *cp++ << 8;
61 				sum += *cp++;
62 			}
63 		}
64 		if ((oddbyte = i & 1) != 0)
65 			v = *cp << 8;
66 		m = m->m_next;
67 	}
68 	if (oddbyte)
69 		sum += v;
70 	sum = (sum >> 16) + (sum & 0xffff); /* add in accumulated carries */
71 	sum += sum >> 16;		/* add potential last carry */
72 	return (0xffff & ~sum);
73 }
74