]>
git.saurik.com Git - apple/xnu.git/blob - bsd/netinet6/in6_cksum.c
2 * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
30 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
31 * All rights reserved.
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. Neither the name of the project nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
45 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * Copyright (c) 1988, 1992, 1993
60 * The Regents of the University of California. All rights reserved.
62 * Redistribution and use in source and binary forms, with or without
63 * modification, are permitted provided that the following conditions
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 * 2. Redistributions in binary form must reproduce the above copyright
68 * notice, this list of conditions and the following disclaimer in the
69 * documentation and/or other materials provided with the distribution.
70 * 3. All advertising materials mentioning features or use of this software
71 * must display the following acknowledgement:
72 * This product includes software developed by the University of
73 * California, Berkeley and its contributors.
74 * 4. Neither the name of the University nor the names of its contributors
75 * may be used to endorse or promote products derived from this software
76 * without specific prior written permission.
78 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
79 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
80 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
81 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
82 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
83 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
84 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
85 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
86 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
87 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
90 * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
94 * Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>.
95 * All rights reserved.
97 * Redistribution and use in source and binary forms, with or without
98 * modification, are permitted provided that the following conditions
101 * 1. Redistributions of source code must retain the above copyright
102 * notice, this list of conditions and the following disclaimer.
103 * 2. Redistributions in binary form must reproduce the above copyright
104 * notice, this list of conditions and the following disclaimer in
105 * the documentation and/or other materials provided with the
108 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
109 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
110 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
111 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
112 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
113 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
114 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
115 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
116 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
117 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
118 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
122 #include <sys/param.h>
123 #include <sys/mbuf.h>
124 #include <sys/systm.h>
125 #include <kern/debug.h>
126 #include <netinet/in.h>
127 #include <netinet/ip6.h>
129 #include <net/net_osdep.h>
131 #include <machine/endian.h>
136 * Checksum routine for Internet Protocol family headers (Portable Version).
138 * This routine is very heavily used in the network
139 * code and should be modified for each CPU to be as fast as possible.
142 #define ADDCARRY(x) do { if (x > 65535) { x -= 65535; } } while (0)
143 #define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
146 * m MUST contain a continuous IP6 header.
147 * off is a offset where TCP/UDP/ICMP6 header starts.
148 * len is a total length of a transport segment.
149 * (e.g. TCP header + TCP payload)
153 inet6_cksum(struct mbuf
*m
, unsigned int nxt
, unsigned int off
,
159 int byte_swapped
= 0;
167 } ph
__attribute__((__packed__
));
179 if ((m
->m_flags
& M_PKTHDR
) && m
->m_pkthdr
.len
< off
+ len
) {
180 panic("inet6_cksum: mbuf len (%d) < off+len (%d+%d)\n",
181 m
->m_pkthdr
.len
, off
, len
);
185 bzero(&uph
, sizeof (uph
));
188 * First create IP6 pseudo header and calculate a summary.
190 ip6
= mtod(m
, struct ip6_hdr
*);
191 w
= (u_int16_t
*)&ip6
->ip6_src
;
192 uph
.ph
.ph_len
= htonl(len
);
195 /* IPv6 source address */
197 if (!IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_src
))
199 sum
+= w
[2]; sum
+= w
[3]; sum
+= w
[4]; sum
+= w
[5];
200 sum
+= w
[6]; sum
+= w
[7];
201 /* IPv6 destination address */
203 if (!IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_dst
))
205 sum
+= w
[10]; sum
+= w
[11]; sum
+= w
[12]; sum
+= w
[13];
206 sum
+= w
[14]; sum
+= w
[15];
207 /* Payload length and upper layer identifier */
208 sum
+= uph
.phs
[0]; sum
+= uph
.phs
[1];
209 sum
+= uph
.phs
[2]; sum
+= uph
.phs
[3];
213 * Secondly calculate a summary of the first mbuf excluding offset.
215 while (m
!= NULL
&& off
> 0) {
222 w
= (u_int16_t
*)(void *)(mtod(m
, u_char
*) + off
);
223 mlen
= m
->m_len
- off
;
228 * Force to even boundary.
230 if ((1 & (intptr_t) w
) && (mlen
> 0)) {
233 s_util
.c
[0] = *(u_char
*)w
;
234 w
= (u_int16_t
*)(void *)((char *)w
+ 1);
239 * Unroll the loop to make overhead from
242 while ((mlen
-= 32) >= 0) {
243 sum
+= w
[0]; sum
+= w
[1]; sum
+= w
[2]; sum
+= w
[3];
244 sum
+= w
[4]; sum
+= w
[5]; sum
+= w
[6]; sum
+= w
[7];
245 sum
+= w
[8]; sum
+= w
[9]; sum
+= w
[10]; sum
+= w
[11];
246 sum
+= w
[12]; sum
+= w
[13]; sum
+= w
[14]; sum
+= w
[15];
250 while ((mlen
-= 8) >= 0) {
251 sum
+= w
[0]; sum
+= w
[1]; sum
+= w
[2]; sum
+= w
[3];
255 if (mlen
== 0 && byte_swapped
== 0)
258 while ((mlen
-= 2) >= 0) {
266 s_util
.c
[1] = *(char *)w
;
271 } else if (mlen
== -1)
272 s_util
.c
[0] = *(char *)w
;
277 * Lastly calculate a summary of the rest of mbufs.
280 for (;m
&& len
; m
= m
->m_next
) {
283 w
= mtod(m
, u_int16_t
*);
286 * The first byte of this mbuf is the continuation
287 * of a word spanning between this mbuf and the
290 * s_util.c[0] is already saved when scanning previous
293 s_util
.c
[1] = *(char *)w
;
295 w
= (u_int16_t
*)(void *)((char *)w
+ 1);
304 * Force to even boundary.
306 if ((1 & (intptr_t) w
) && (mlen
> 0)) {
309 s_util
.c
[0] = *(u_char
*)w
;
310 w
= (u_int16_t
*)(void *)((char *)w
+ 1);
315 * Unroll the loop to make overhead from
318 while ((mlen
-= 32) >= 0) {
319 sum
+= w
[0]; sum
+= w
[1]; sum
+= w
[2]; sum
+= w
[3];
320 sum
+= w
[4]; sum
+= w
[5]; sum
+= w
[6]; sum
+= w
[7];
321 sum
+= w
[8]; sum
+= w
[9]; sum
+= w
[10]; sum
+= w
[11];
322 sum
+= w
[12]; sum
+= w
[13]; sum
+= w
[14]; sum
+= w
[15];
326 while ((mlen
-= 8) >= 0) {
327 sum
+= w
[0]; sum
+= w
[1]; sum
+= w
[2]; sum
+= w
[3];
331 if (mlen
== 0 && byte_swapped
== 0)
334 while ((mlen
-= 2) >= 0) {
342 s_util
.c
[1] = *(char *)w
;
347 } else if (mlen
== -1)
348 s_util
.c
[0] = *(char *)w
;
351 printf("inet6_cksum: out of data by %d\n", len
);
353 /* The last mbuf has odd # of bytes. Follow the
354 standard (the odd byte may be shifted left by 8 bits
355 or not as determined by endian-ness of the machine) */
360 return (~sum
& 0xffff);