BSD 4_4 release
[unix-history] / usr / src / sys / i386 / i386 / in_cksum.c
CommitLineData
3da89300 1/*-
ad787160
C
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved.
3da89300 4 *
ad787160
C
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
3da89300
WN
32 *
33 * from tahoe: in_cksum.c 1.2 86/01/05
ad787160 34 * @(#)in_cksum.c 8.1 (Berkeley) 6/11/93
3da89300 35 */
79189150 36
38a01dbe
KB
37#include <sys/param.h>
38#include <sys/mbuf.h>
39
40#include <netinet/in.h>
41#include <netinet/in_systm.h>
79189150
BJ
42
43/*
44 * Checksum routine for Internet Protocol family headers.
45 *
46 * This routine is very heavily used in the network
47 * code and should be modified for each CPU to be as fast as possible.
48 *
3da89300 49 * This implementation is 386 version.
79189150
BJ
50 */
51
52#undef ADDCARRY
53#define ADDCARRY(sum) { \
54 if (sum & 0xffff0000) { \
55 sum &= 0xffff; \
56 sum++; \
57 } \
58 }
59in_cksum(m, len)
60 register struct mbuf *m;
61 register int len;
62{
63 union word {
64 char c[2];
65 u_short s;
66 } u;
67 register u_short *w;
68 register int sum = 0;
69 register int mlen = 0;
70
71 for (;m && len; m = m->m_next) {
72 if (m->m_len == 0)
73 continue;
74 w = mtod(m, u_short *);
75 if (mlen == -1) {
76 /*
77 * The first byte of this mbuf is the continuation
78 * of a word spanning between this mbuf and the
79 * last mbuf.
80 */
81
82 /* u.c[0] is already saved when scanning previous
83 * mbuf.
84 */
85 u.c[1] = *(u_char *)w;
86 sum += u.s;
87 ADDCARRY(sum);
88 w = (u_short *)((char *)w + 1);
89 mlen = m->m_len - 1;
90 len--;
91 } else
92 mlen = m->m_len;
93
94 if (len < mlen)
95 mlen = len;
96 len -= mlen;
97
98 /*
99 * add by words.
100 */
101 while ((mlen -= 2) >= 0) {
102 if ((int)w & 0x1) {
103 /* word is not aligned */
104 u.c[0] = *(char *)w;
105 u.c[1] = *((char *)w+1);
106 sum += u.s;
107 w++;
108 } else
109 sum += *w++;
110 ADDCARRY(sum);
111 }
112 if (mlen == -1)
113 /*
114 * This mbuf has odd number of bytes.
115 * There could be a word split betwen
116 * this mbuf and the next mbuf.
117 * Save the last byte (to prepend to next mbuf).
118 */
119 u.c[0] = *(u_char *)w;
120 }
121 if (len)
122 printf("cksum: out of data\n");
123 if (mlen == -1) {
124 /* The last mbuf has odd # of bytes. Follow the
125 standard (the odd byte is shifted left by 8 bits) */
126 u.c[1] = 0;
127 sum += u.s;
128 ADDCARRY(sum);
129 }
130 return (~sum & 0xffff);
131}