Annotation of sys/arch/vax/vax/in4_cksum.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: in4_cksum.c,v 1.2 2005/05/24 20:35:29 miod Exp $ */
2: /* $NetBSD: in4_cksum.c,v 1.8 2003/09/29 22:54:28 matt Exp $ */
3:
4: /*
5: * Copyright (C) 1999 WIDE Project.
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. Neither the name of the project nor the names of its contributors
17: * may be used to endorse or promote products derived from this software
18: * without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23: * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30: * SUCH DAMAGE.
31: */
32:
33: /*
34: * Copyright (c) 1988, 1992, 1993
35: * The Regents of the University of California. All rights reserved.
36: *
37: * Redistribution and use in source and binary forms, with or without
38: * modification, are permitted provided that the following conditions
39: * are met:
40: * 1. Redistributions of source code must retain the above copyright
41: * notice, this list of conditions and the following disclaimer.
42: * 2. Redistributions in binary form must reproduce the above copyright
43: * notice, this list of conditions and the following disclaimer in the
44: * documentation and/or other materials provided with the distribution.
45: * 3. Neither the name of the University nor the names of its contributors
46: * may be used to endorse or promote products derived from this software
47: * without specific prior written permission.
48: *
49: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59: * SUCH DAMAGE.
60: *
61: * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
62: */
63:
64: #if 0
65: #include <sys/cdefs.h>
66: __KERNEL_RCSID(0, "$NetBSD: in4_cksum.c,v 1.8 2003/09/29 22:54:28 matt Exp $");
67: #endif
68:
69: #include <sys/param.h>
70: #include <sys/systm.h>
71: #include <sys/mbuf.h>
72: #include <sys/socketvar.h>
73: #include <netinet/in.h>
74: #include <netinet/in_systm.h>
75: #include <netinet/ip.h>
76: #include <netinet/ip_var.h>
77:
78: #ifdef CKSUMDEBUG
79: int in4_cksum_md_debug(struct mbuf *m, u_int8_t nxt, int off, int len);
80: #define in4_cksum in4_cksum_md_debug
81: #include <netinet/in4_cksum.c>
82: #undef in4_cksum
83: #undef ADDCARRY
84: #undef REDUCE
85: #endif
86:
87: /*
88: * Checksum routine for Internet Protocol family headers.
89: * This is only for IPv4 pseudo header checksum.
90: * No need to clear non-pseudo-header fields in IPv4 header.
91: * len is for actual payload size, and does not include IPv4 header and
92: * skipped header chain (off + len should be equal to the whole packet).
93: *
94: * This implementation is VAX version.
95: */
96:
97:
98: #define REDUCE {sum = (sum & 0xffff) + (sum >> 16);}
99: #define ADDCARRY {if (sum > 0xffff) sum -= 0xffff;}
100: #define ADVANCE(n) {w += n; mlen -= n;}
101: #define SWAP {sum <<= 8;} /* depends on recent REDUCE */
102:
103: #define Asm __asm __volatile
104: #define ADDL Asm("addl2 (%2)+,%0" : "=r" (sum) : "0" (sum), "r" (w))
105: #define ADWC Asm("adwc (%2)+,%0" : "=r" (sum) : "0" (sum), "r" (w))
106: #define ADDC Asm("adwc $0,%0" : "=r" (sum) : "0" (sum))
107: #define UNSWAP Asm("rotl $8,%0,%0" : "=r" (sum) : "0" (sum))
108: #define ADDBYTE {sum += *w; SWAP; byte_swapped ^= 1;}
109: #define ADDWORD {sum += *(u_short *)w;}
110:
111: int
112: in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len)
113: {
114: u_int8_t *w;
115: u_int32_t sum = 0;
116: int mlen = 0;
117: int byte_swapped = 0;
118: #ifdef CKSUMDEBUG
119: int debugrv = in4_cksum_md_debug(m, nxt, off, len);
120: #endif
121:
122: if (nxt != 0) {
123: #ifdef DIAGNOSTIC
124: if (off < sizeof(struct ipovly))
125: panic("in4_cksum: offset too short");
126: if (m->m_len < sizeof(struct ip))
127: panic("in4_cksum: bad mbuf chain");
128: #endif
129:
130: __asm __volatile(
131: "movzwl %3,%0;" /* mov len to sum */
132: "addb2 %4,%0;" /* add proto to sum */
133: "rotl $8,%0,%0;" /* htons, carry is preserved */
134: "adwc 12(%2),%0;" /* add src ip */
135: "adwc 16(%2),%0;" /* add dst ip */
136: "adwc $0,%0;" /* clean up carry */
137: : "=r" (sum)
138: : "0" (sum), "r" (mtod(m, void *)), "r" (len), "r"(nxt));
139: }
140:
141: /* skip unnecessary part */
142: while (m && off > 0) {
143: if (m->m_len > off)
144: break;
145: off -= m->m_len;
146: m = m->m_next;
147: }
148:
149: for (;m && len; m = m->m_next) {
150: if ((mlen = m->m_len) == 0)
151: continue;
152: w = mtod(m, u_int8_t *);
153: if (off) {
154: w += off;
155: mlen -= off;
156: off = 0;
157: }
158: if (len < mlen)
159: mlen = len;
160: len -= mlen;
161: if (mlen < 16)
162: goto short_mbuf;
163: /*
164: * Ensure that we're aligned on a word boundary here so
165: * that we can do 32 bit operations below.
166: */
167: if ((3 & (u_long) w) != 0) {
168: REDUCE;
169: if ((1 & (u_long) w) != 0) {
170: ADDBYTE;
171: ADVANCE(1);
172: }
173: if ((2 & (u_long) w) != 0) {
174: ADDWORD;
175: ADVANCE(2);
176: }
177: }
178: /*
179: * Do as much of the checksum as possible 32 bits at at time.
180: * In fact, this loop is unrolled to make overhead from
181: * branches &c small.
182: */
183: while ((mlen -= 32) >= 0) {
184: /*
185: * Add with carry 16 words and fold in the last carry
186: * by adding a 0 with carry.
187: */
188: ADDL; ADWC; ADWC; ADWC;
189: ADWC; ADWC; ADWC; ADWC;
190: ADDC;
191: }
192: mlen += 32;
193: if (mlen >= 16) {
194: ADDL; ADWC; ADWC; ADWC;
195: ADDC;
196: mlen -= 16;
197: }
198: short_mbuf:
199: if (mlen >= 8) {
200: ADDL; ADWC;
201: ADDC;
202: mlen -= 8;
203: }
204: if (mlen >= 4) {
205: ADDL;
206: ADDC;
207: mlen -= 4;
208: }
209: if (mlen > 0) {
210: REDUCE;
211: if (mlen >= 2) {
212: ADDWORD;
213: ADVANCE(2);
214: }
215: if (mlen >= 1) {
216: ADDBYTE;
217: }
218: }
219: }
220:
221: if (len)
222: printf("cksum4: out of data\n");
223: if (byte_swapped) {
224: UNSWAP;
225: }
226: REDUCE;
227: ADDCARRY;
228: #ifdef CKSUMDEBUG
229: if ((sum ^ 0xffff) != debugrv)
230: printf("in4_cksum: rv != debugrv (rv %x debugrv %x)\n",
231: (sum ^ 0xffff), debugrv);
232: #endif
233: return (sum ^ 0xffff);
234: }
CVSweb