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$");
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
76169463Srwatsonipx_cksum(struct mbuf *m, int len)
77169463Srwatson{
7850519Sjhay	u_int32_t sum = 0;
79132779Skan	u_char *w;
8050519Sjhay	u_char oldtc;
8150519Sjhay	int mlen, words;
8250519Sjhay	struct ipx *ipx;
8311819Sjulian	union {
8450519Sjhay		u_char	b[2];
8550519Sjhay		u_short	w;
8650519Sjhay	} buf;
8711819Sjulian
8850519Sjhay	ipx = mtod(m, struct ipx*);
8950519Sjhay	oldtc = ipx->ipx_tc;
9050519Sjhay	ipx->ipx_tc = 0;
91132779Skan	w = (u_char *)&ipx->ipx_len;
9250519Sjhay	len -= 2;
9350519Sjhay	mlen = 2;
9450519Sjhay
9550519Sjhay	for(;;) {
9650519Sjhay		mlen = imin(m->m_len - mlen, len);
9750519Sjhay		words = mlen / 2;
9850519Sjhay		len -= mlen & ~1;
9950519Sjhay		while (words >= 16) {
10050519Sjhay			SUMADV;	SUMADV;	SUMADV;	SUMADV;
10150519Sjhay			SUMADV;	SUMADV;	SUMADV;	SUMADV;
10250519Sjhay			SUMADV;	SUMADV;	SUMADV;	SUMADV;
10350519Sjhay			SUMADV;	SUMADV;	SUMADV;	SUMADV;
10450519Sjhay			words -= 16;
10511819Sjulian		}
10650519Sjhay		while (words--)
10750519Sjhay			SUMADV;
10850519Sjhay		if (len == 0)
10950519Sjhay			break;
11050519Sjhay		mlen &= 1;
11150519Sjhay		if (mlen) {
112132779Skan			buf.b[0] = *w;
11350519Sjhay			if (--len == 0) {
11450519Sjhay				buf.b[1] = 0;
11550519Sjhay				sum += buf.w;
11650519Sjhay				break;
11750519Sjhay			}
11811819Sjulian		}
11950519Sjhay		m = m->m_next;
12050519Sjhay		if (m == NULL)
12150519Sjhay			break;
122132779Skan		w = mtod(m, u_char *);
12350519Sjhay		if (mlen) {
124132779Skan			buf.b[1] = *w;
12550519Sjhay			sum += buf.w;
126132779Skan			w++;
12750519Sjhay			if (--len == 0)
12850519Sjhay				break;
129139584Srwatson		}
13011819Sjulian	}
13150519Sjhay
13250519Sjhay	ipx->ipx_tc = oldtc;
13350519Sjhay
13450519Sjhay	sum = (sum & 0xffff) + (sum >> 16);
13550519Sjhay	if (sum >= 0x10000)
13650519Sjhay		sum++;
13750519Sjhay	if (sum)
13850519Sjhay		sum = ~sum;
13911819Sjulian	return (sum);
14011819Sjulian}
141