ipx_cksum.c revision 165899
1139823Simp/*-
211819Sjulian * Copyright (c) 1982, 1992, 1993
311819Sjulian *	The Regents of the University of California.  All rights reserved.
411819Sjulian *
511819Sjulian * Redistribution and use in source and binary forms, with or without
611819Sjulian * modification, are permitted provided that the following conditions
711819Sjulian * are met:
811819Sjulian * 1. Redistributions of source code must retain the above copyright
911819Sjulian *    notice, this list of conditions and the following disclaimer.
1011819Sjulian * 2. Redistributions in binary form must reproduce the above copyright
1111819Sjulian *    notice, this list of conditions and the following disclaimer in the
1211819Sjulian *    documentation and/or other materials provided with the distribution.
13165899Srwatson * 4. Neither the name of the University nor the names of its contributors
14165899Srwatson *    may be used to endorse or promote products derived from this software
15165899Srwatson *    without specific prior written permission.
16165899Srwatson *
17165899Srwatson * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18165899Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19165899Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20165899Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21165899Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22165899Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23165899Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24165899Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25165899Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26165899Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27165899Srwatson * SUCH DAMAGE.
28165899Srwatson *
29165899Srwatson * Copyright (c) 1995, Mike Mitchell
30165899Srwatson *
31165899Srwatson * Redistribution and use in source and binary forms, with or without
32165899Srwatson * modification, are permitted provided that the following conditions
33165899Srwatson * are met:
34165899Srwatson * 1. Redistributions of source code must retain the above copyright
35165899Srwatson *    notice, this list of conditions and the following disclaimer.
36165899Srwatson * 2. Redistributions in binary form must reproduce the above copyright
37165899Srwatson *    notice, this list of conditions and the following disclaimer in the
38165899Srwatson *    documentation and/or other materials provided with the distribution.
3911819Sjulian * 3. All advertising materials mentioning features or use of this software
4011819Sjulian *    must display the following acknowledgement:
4111819Sjulian *	This product includes software developed by the University of
4211819Sjulian *	California, Berkeley and its contributors.
4311819Sjulian * 4. Neither the name of the University nor the names of its contributors
4411819Sjulian *    may be used to endorse or promote products derived from this software
4511819Sjulian *    without specific prior written permission.
4611819Sjulian *
4711819Sjulian * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
4811819Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4911819Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5011819Sjulian * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
5111819Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5211819Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5311819Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5411819Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5511819Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5611819Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5711819Sjulian * SUCH DAMAGE.
5811819Sjulian *
5912057Sjulian *	@(#)ipx_cksum.c
6011819Sjulian */
6111819Sjulian
62116189Sobrien#include <sys/cdefs.h>
63116189Sobrien__FBSDID("$FreeBSD: head/sys/netipx/ipx_cksum.c 165899 2007-01-08 22:14:00Z rwatson $");
64116189Sobrien
6511819Sjulian#include <sys/param.h>
6611819Sjulian#include <sys/mbuf.h>
6750519Sjhay#include <sys/libkern.h>
6811819Sjulian
6950519Sjhay#include <netipx/ipx.h>
7025652Sjhay#include <netipx/ipx_var.h>
7111991Sjulian
7211819Sjulian
7350519Sjhay#define SUMADV	sum += *w++
7411819Sjulian
7511819Sjulianu_short
7650519Sjhayipx_cksum(struct mbuf *m, int len) {
7750519Sjhay	u_int32_t sum = 0;
78132779Skan	u_char *w;
7950519Sjhay	u_char oldtc;
8050519Sjhay	int mlen, words;
8150519Sjhay	struct ipx *ipx;
8211819Sjulian	union {
8350519Sjhay		u_char	b[2];
8450519Sjhay		u_short	w;
8550519Sjhay	} buf;
8611819Sjulian
8750519Sjhay	ipx = mtod(m, struct ipx*);
8850519Sjhay	oldtc = ipx->ipx_tc;
8950519Sjhay	ipx->ipx_tc = 0;
90132779Skan	w = (u_char *)&ipx->ipx_len;
9150519Sjhay	len -= 2;
9250519Sjhay	mlen = 2;
9350519Sjhay
9450519Sjhay	for(;;) {
9550519Sjhay		mlen = imin(m->m_len - mlen, len);
9650519Sjhay		words = mlen / 2;
9750519Sjhay		len -= mlen & ~1;
9850519Sjhay		while (words >= 16) {
9950519Sjhay			SUMADV;	SUMADV;	SUMADV;	SUMADV;
10050519Sjhay			SUMADV;	SUMADV;	SUMADV;	SUMADV;
10150519Sjhay			SUMADV;	SUMADV;	SUMADV;	SUMADV;
10250519Sjhay			SUMADV;	SUMADV;	SUMADV;	SUMADV;
10350519Sjhay			words -= 16;
10411819Sjulian		}
10550519Sjhay		while (words--)
10650519Sjhay			SUMADV;
10750519Sjhay		if (len == 0)
10850519Sjhay			break;
10950519Sjhay		mlen &= 1;
11050519Sjhay		if (mlen) {
111132779Skan			buf.b[0] = *w;
11250519Sjhay			if (--len == 0) {
11350519Sjhay				buf.b[1] = 0;
11450519Sjhay				sum += buf.w;
11550519Sjhay				break;
11650519Sjhay			}
11711819Sjulian		}
11850519Sjhay		m = m->m_next;
11950519Sjhay		if (m == NULL)
12050519Sjhay			break;
121132779Skan		w = mtod(m, u_char *);
12250519Sjhay		if (mlen) {
123132779Skan			buf.b[1] = *w;
12450519Sjhay			sum += buf.w;
125132779Skan			w++;
12650519Sjhay			if (--len == 0)
12750519Sjhay				break;
128139584Srwatson		}
12911819Sjulian	}
13050519Sjhay
13150519Sjhay	ipx->ipx_tc = oldtc;
13250519Sjhay
13350519Sjhay	sum = (sum & 0xffff) + (sum >> 16);
13450519Sjhay	if (sum >= 0x10000)
13550519Sjhay		sum++;
13650519Sjhay	if (sum)
13750519Sjhay		sum = ~sum;
13811819Sjulian	return (sum);
13911819Sjulian}
140