xref: /original-bsd/sys/sparc/sparc/in_cksum.c (revision 860e07fc)
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 Laboratories.
13  *
14  * %sccs.include.redist.c%
15  *
16  *	@(#)in_cksum.c	7.2 (Berkeley) 07/21/92
17  *
18  * from: $Header: in_cksum.c,v 1.6 92/06/17 05:22:04 torek Exp $
19  */
20 
21 #include "param.h"
22 #include "mbuf.h"
23 #include "netinet/in.h"
24 #include "netinet/in_systm.h"
25 
26 /*
27  * Checksum routine for Internet Protocol family headers.
28  * This routine is very heavily used in the network
29  * code and should be modified for each CPU to be as fast as possible.
30  * In particular, it should not be this one.
31  */
32 int
33 in_cksum(m, len)
34 	register struct mbuf *m;
35 	register int len;
36 {
37 	register int sum = 0, i, oddbyte = 0, v = 0;
38 	register u_char *cp;
39 
40 	/* we assume < 2^16 bytes being summed */
41 	while (len) {
42 		while ((i = m->m_len) == 0)
43 			m = m->m_next;
44 		if (i > len)
45 			i = len;
46 		len -= i;
47 		cp = mtod(m, u_char *);
48 		if (oddbyte) {
49 			sum += v + *cp++;
50 			i--;
51 		}
52 		if (((int)cp & 1) == 0) {
53 			while ((i -= 2) >= 0) {
54 				sum += *(u_short *)cp;
55 				cp += 2;
56 			}
57 		} else {
58 			while ((i -= 2) >= 0) {
59 				sum += *cp++ << 8;
60 				sum += *cp++;
61 			}
62 		}
63 		if ((oddbyte = i & 1) != 0)
64 			v = *cp << 8;
65 		m = m->m_next;
66 	}
67 	if (oddbyte)
68 		sum += v;
69 	sum = (sum >> 16) + (sum & 0xffff); /* add in accumulated carries */
70 	sum += sum >> 16;		/* add potential last carry */
71 	return (0xffff & ~sum);
72 }
73