ipx_cksum.c revision 139823
1139823Simp/*- 211819Sjulian * Copyright (c) 1995, Mike Mitchell 311819Sjulian * Copyright (c) 1982, 1992, 1993 411819Sjulian * The Regents of the University of California. All rights reserved. 511819Sjulian * 611819Sjulian * Redistribution and use in source and binary forms, with or without 711819Sjulian * modification, are permitted provided that the following conditions 811819Sjulian * are met: 911819Sjulian * 1. Redistributions of source code must retain the above copyright 1011819Sjulian * notice, this list of conditions and the following disclaimer. 1111819Sjulian * 2. Redistributions in binary form must reproduce the above copyright 1211819Sjulian * notice, this list of conditions and the following disclaimer in the 1311819Sjulian * documentation and/or other materials provided with the distribution. 1411819Sjulian * 3. All advertising materials mentioning features or use of this software 1511819Sjulian * must display the following acknowledgement: 1611819Sjulian * This product includes software developed by the University of 1711819Sjulian * California, Berkeley and its contributors. 1811819Sjulian * 4. Neither the name of the University nor the names of its contributors 1911819Sjulian * may be used to endorse or promote products derived from this software 2011819Sjulian * without specific prior written permission. 2111819Sjulian * 2211819Sjulian * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2311819Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2411819Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2511819Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2611819Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2711819Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2811819Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2911819Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3011819Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3111819Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3211819Sjulian * SUCH DAMAGE. 3311819Sjulian * 3412057Sjulian * @(#)ipx_cksum.c 3511819Sjulian */ 3611819Sjulian 37116189Sobrien#include <sys/cdefs.h> 38116189Sobrien__FBSDID("$FreeBSD: head/sys/netipx/ipx_cksum.c 139823 2005-01-07 01:45:51Z imp $"); 39116189Sobrien 4011819Sjulian#include <sys/param.h> 4111819Sjulian#include <sys/mbuf.h> 4250519Sjhay#include <sys/libkern.h> 4311819Sjulian 4450519Sjhay#include <netipx/ipx.h> 4525652Sjhay#include <netipx/ipx_var.h> 4611991Sjulian 4711819Sjulian 4850519Sjhay#define SUMADV sum += *w++ 4911819Sjulian 5011819Sjulianu_short 5150519Sjhayipx_cksum(struct mbuf *m, int len) { 5250519Sjhay u_int32_t sum = 0; 53132779Skan u_char *w; 5450519Sjhay u_char oldtc; 5550519Sjhay int mlen, words; 5650519Sjhay struct ipx *ipx; 5711819Sjulian union { 5850519Sjhay u_char b[2]; 5950519Sjhay u_short w; 6050519Sjhay } buf; 6111819Sjulian 6250519Sjhay ipx = mtod(m, struct ipx*); 6350519Sjhay oldtc = ipx->ipx_tc; 6450519Sjhay ipx->ipx_tc = 0; 65132779Skan w = (u_char *)&ipx->ipx_len; 6650519Sjhay len -= 2; 6750519Sjhay mlen = 2; 6850519Sjhay 6950519Sjhay for(;;) { 7050519Sjhay mlen = imin(m->m_len - mlen, len); 7150519Sjhay words = mlen / 2; 7250519Sjhay len -= mlen & ~1; 7350519Sjhay while (words >= 16) { 7450519Sjhay SUMADV; SUMADV; SUMADV; SUMADV; 7550519Sjhay SUMADV; SUMADV; SUMADV; SUMADV; 7650519Sjhay SUMADV; SUMADV; SUMADV; SUMADV; 7750519Sjhay SUMADV; SUMADV; SUMADV; SUMADV; 7850519Sjhay words -= 16; 7911819Sjulian } 8050519Sjhay while (words--) 8150519Sjhay SUMADV; 8250519Sjhay if (len == 0) 8350519Sjhay break; 8450519Sjhay mlen &= 1; 8550519Sjhay if (mlen) { 86132779Skan buf.b[0] = *w; 8750519Sjhay if (--len == 0) { 8850519Sjhay buf.b[1] = 0; 8950519Sjhay sum += buf.w; 9050519Sjhay break; 9150519Sjhay } 9211819Sjulian } 9350519Sjhay m = m->m_next; 9450519Sjhay if (m == NULL) 9550519Sjhay break; 96132779Skan w = mtod(m, u_char *); 9750519Sjhay if (mlen) { 98132779Skan buf.b[1] = *w; 9950519Sjhay sum += buf.w; 100132779Skan w++; 10150519Sjhay if (--len == 0) 10250519Sjhay break; 103139584Srwatson } 10411819Sjulian } 10550519Sjhay 10650519Sjhay ipx->ipx_tc = oldtc; 10750519Sjhay 10850519Sjhay sum = (sum & 0xffff) + (sum >> 16); 10950519Sjhay if (sum >= 0x10000) 11050519Sjhay sum++; 11150519Sjhay if (sum) 11250519Sjhay sum = ~sum; 11311819Sjulian return (sum); 11411819Sjulian} 115