Remove advertising clause from all that isn't contrib or userland bin.
[dragonfly.git] / sys / netproto / ipx / ipx_cksum.c
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  * 4. Neither the name of the University nor the names of its contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  *      @(#)ipx_cksum.c
31  *
32  * $FreeBSD: src/sys/netipx/ipx_cksum.c,v 1.9 1999/08/28 18:21:53 jhay Exp $
33  * $DragonFly: src/sys/netproto/ipx/ipx_cksum.c,v 1.4 2005/02/15 18:11:59 joerg Exp $
34  */
35
36 #include <sys/param.h>
37 #include <sys/mbuf.h>
38 #include <sys/libkern.h>
39
40 #include "ipx.h"
41 #include "ipx_var.h"
42
43
44 #define SUMADV  sum += *w++
45
46 u_short
47 ipx_cksum(struct mbuf *m, int len) {
48         u_int32_t sum = 0;
49         u_short *w;
50         u_char oldtc;
51         int mlen, words;
52         struct ipx *ipx;
53         union {
54                 u_char  b[2];
55                 u_short w;
56         } buf;
57
58         ipx = mtod(m, struct ipx*);
59         oldtc = ipx->ipx_tc;
60         ipx->ipx_tc = 0;
61         w = &ipx->ipx_len;
62         len -= 2;
63         mlen = 2;
64
65         for(;;) {
66                 mlen = imin(m->m_len - mlen, len);
67                 words = mlen / 2;
68                 len -= mlen & ~1;
69                 while (words >= 16) {
70                         SUMADV; SUMADV; SUMADV; SUMADV;
71                         SUMADV; SUMADV; SUMADV; SUMADV;
72                         SUMADV; SUMADV; SUMADV; SUMADV;
73                         SUMADV; SUMADV; SUMADV; SUMADV;
74                         words -= 16;
75                 }
76                 while (words--)
77                         SUMADV;
78                 if (len == 0)
79                         break;
80                 mlen &= 1;
81                 if (mlen) {
82                         buf.b[0] = *(u_char*)w;
83                         if (--len == 0) {
84                                 buf.b[1] = 0;
85                                 sum += buf.w;
86                                 break;
87                         }
88                 }
89                 m = m->m_next;
90                 if (m == NULL)
91                         break;
92                 w = mtod(m, u_short*);
93                 if (mlen) {
94                         buf.b[1] = *(u_char*)w;
95                         sum += buf.w;
96                         w = (uint16_t *)((uint8_t *)w + 1);
97                         if (--len == 0)
98                                 break;
99                 } 
100         }
101
102         ipx->ipx_tc = oldtc;
103
104         sum = (sum & 0xffff) + (sum >> 16);
105         if (sum >= 0x10000)
106                 sum++;
107         if (sum)
108                 sum = ~sum;
109         return (sum);
110 }