File:
[Qemu by Fabrice Bellard] /
qemu /
slirp /
cksum.c
Revision
1.1.1.3 (vendor branch):
download - view:
text,
annotated -
select for diffs
Tue Apr 24 16:54:50 2018 UTC (2 years, 11 months ago) by
root
Branches:
qemu,
MAIN
CVS tags:
qemu0125,
qemu0124,
qemu0123,
qemu0122,
qemu0121,
qemu0120,
qemu0111,
qemu0110,
qemu0105,
qemu0104,
qemu0103,
qemu0102,
qemu0101,
qemu0100,
HEAD
qemu 0.10.0
1: /*
2: * Copyright (c) 1988, 1992, 1993
3: * The Regents of the University of California. All rights reserved.
4: *
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. Neither the name of the University nor the names of its contributors
14: * may be used to endorse or promote products derived from this software
15: * without specific prior written permission.
16: *
17: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27: * SUCH DAMAGE.
28: *
29: * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
30: * in_cksum.c,v 1.2 1994/08/02 07:48:16 davidg Exp
31: */
32:
33: #include <slirp.h>
34:
35: /*
36: * Checksum routine for Internet Protocol family headers (Portable Version).
37: *
38: * This routine is very heavily used in the network
39: * code and should be modified for each CPU to be as fast as possible.
40: *
41: * XXX Since we will never span more than 1 mbuf, we can optimise this
42: */
43:
44: #define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
45: #define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
46:
47: int cksum(struct mbuf *m, int len)
48: {
49: register u_int16_t *w;
50: register int sum = 0;
51: register int mlen = 0;
52: int byte_swapped = 0;
53:
54: union {
55: u_int8_t c[2];
56: u_int16_t s;
57: } s_util;
58: union {
59: u_int16_t s[2];
60: u_int32_t l;
61: } l_util;
62:
63: if (m->m_len == 0)
64: goto cont;
65: w = mtod(m, u_int16_t *);
66:
67: mlen = m->m_len;
68:
69: if (len < mlen)
70: mlen = len;
71: len -= mlen;
72: /*
73: * Force to even boundary.
74: */
75: if ((1 & (long) w) && (mlen > 0)) {
76: REDUCE;
77: sum <<= 8;
78: s_util.c[0] = *(u_int8_t *)w;
79: w = (u_int16_t *)((int8_t *)w + 1);
80: mlen--;
81: byte_swapped = 1;
82: }
83: /*
84: * Unroll the loop to make overhead from
85: * branches &c small.
86: */
87: while ((mlen -= 32) >= 0) {
88: sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
89: sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
90: sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
91: sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
92: w += 16;
93: }
94: mlen += 32;
95: while ((mlen -= 8) >= 0) {
96: sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
97: w += 4;
98: }
99: mlen += 8;
100: if (mlen == 0 && byte_swapped == 0)
101: goto cont;
102: REDUCE;
103: while ((mlen -= 2) >= 0) {
104: sum += *w++;
105: }
106:
107: if (byte_swapped) {
108: REDUCE;
109: sum <<= 8;
110: byte_swapped = 0;
111: if (mlen == -1) {
112: s_util.c[1] = *(u_int8_t *)w;
113: sum += s_util.s;
114: mlen = 0;
115: } else
116:
117: mlen = -1;
118: } else if (mlen == -1)
119: s_util.c[0] = *(u_int8_t *)w;
120:
121: cont:
122: #ifdef DEBUG
123: if (len) {
124: DEBUG_ERROR((dfd, "cksum: out of data\n"));
125: DEBUG_ERROR((dfd, " len = %d\n", len));
126: }
127: #endif
128: if (mlen == -1) {
129: /* The last mbuf has odd # of bytes. Follow the
130: standard (the odd byte may be shifted left by 8 bits
131: or not as determined by endian-ness of the machine) */
132: s_util.c[1] = 0;
133: sum += s_util.s;
134: }
135: REDUCE;
136: return (~sum & 0xffff);
137: }
unix.superglobalmegacorp.com