ipx_cksum.c revision 132779
1/* 2 * Copyright (c) 1995, Mike Mitchell 3 * Copyright (c) 1982, 1992, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by the University of 17 * California, Berkeley and its contributors. 18 * 4. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * @(#)ipx_cksum.c 35 */ 36 37#include <sys/cdefs.h> 38__FBSDID("$FreeBSD: head/sys/netipx/ipx_cksum.c 132779 2004-07-28 06:58:23Z kan $"); 39 40#include <sys/param.h> 41#include <sys/mbuf.h> 42#include <sys/libkern.h> 43 44#include <netipx/ipx.h> 45#include <netipx/ipx_var.h> 46 47 48#define SUMADV sum += *w++ 49 50u_short 51ipx_cksum(struct mbuf *m, int len) { 52 u_int32_t sum = 0; 53 u_char *w; 54 u_char oldtc; 55 int mlen, words; 56 struct ipx *ipx; 57 union { 58 u_char b[2]; 59 u_short w; 60 } buf; 61 62 ipx = mtod(m, struct ipx*); 63 oldtc = ipx->ipx_tc; 64 ipx->ipx_tc = 0; 65 w = (u_char *)&ipx->ipx_len; 66 len -= 2; 67 mlen = 2; 68 69 for(;;) { 70 mlen = imin(m->m_len - mlen, len); 71 words = mlen / 2; 72 len -= mlen & ~1; 73 while (words >= 16) { 74 SUMADV; SUMADV; SUMADV; SUMADV; 75 SUMADV; SUMADV; SUMADV; SUMADV; 76 SUMADV; SUMADV; SUMADV; SUMADV; 77 SUMADV; SUMADV; SUMADV; SUMADV; 78 words -= 16; 79 } 80 while (words--) 81 SUMADV; 82 if (len == 0) 83 break; 84 mlen &= 1; 85 if (mlen) { 86 buf.b[0] = *w; 87 if (--len == 0) { 88 buf.b[1] = 0; 89 sum += buf.w; 90 break; 91 } 92 } 93 m = m->m_next; 94 if (m == NULL) 95 break; 96 w = mtod(m, u_char *); 97 if (mlen) { 98 buf.b[1] = *w; 99 sum += buf.w; 100 w++; 101 if (--len == 0) 102 break; 103 } 104 } 105 106 ipx->ipx_tc = oldtc; 107 108 sum = (sum & 0xffff) + (sum >> 16); 109 if (sum >= 0x10000) 110 sum++; 111 if (sum) 112 sum = ~sum; 113 return (sum); 114} 115