source: rtems-libbsd/freebsd/contrib/tcpdump/in_cksum.c @ 8440506

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 8440506 was 8440506, checked in by Chris Johns <chrisj@…>, on 06/15/15 at 07:42:23

Add tcpdump and libpcap.

  • Update the file builder generator to handle generator specific cflags and includes. The tcpdump and libpcap have localised headers and need specific headers paths to see them. There are also module specific flags and these need to be passed to the lex and yacc generators.
  • Add the tcpdump support.
  • Property mode set to 100644
File size: 6.5 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3/* in_cksum.c
4 * 4.4-Lite-2 Internet checksum routine, modified to take a vector of
5 * pointers/lengths giving the pieces to be checksummed.  Also using
6 * Tahoe/CGI version of ADDCARRY(x) macro instead of from portable version.
7 */
8
9/*
10 * Copyright (c) 1988, 1992, 1993
11 *      The Regents of the University of California.  All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 *    notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice, this list of conditions and the following disclaimer in the
20 *    documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the University nor the names of its contributors
22 *    may be used to endorse or promote products derived from this software
23 *    without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 *      @(#)in_cksum.c  8.1 (Berkeley) 6/10/93
38 */
39
40#ifdef HAVE_CONFIG_H
41# include "config.h"
42#endif
43
44#include <tcpdump-stdinc.h>
45
46#include "interface.h"
47
48/*
49 * Checksum routine for Internet Protocol family headers (Portable Version).
50 *
51 * This routine is very heavily used in the network
52 * code and should be modified for each CPU to be as fast as possible.
53 */
54
55#define ADDCARRY(x)  {if ((x) > 65535) (x) -= 65535;}
56#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
57
58u_int16_t
59in_cksum(const struct cksum_vec *vec, int veclen)
60{
61        register const u_int16_t *w;
62        register int sum = 0;
63        register int mlen = 0;
64        int byte_swapped = 0;
65
66        union {
67                u_int8_t        c[2];
68                u_int16_t       s;
69        } s_util;
70        union {
71                u_int16_t       s[2];
72                u_int32_t       l;
73        } l_util;
74
75        for (; veclen != 0; vec++, veclen--) {
76                if (vec->len == 0)
77                        continue;
78                w = (const u_int16_t *)(void *)vec->ptr;
79                if (mlen == -1) {
80                        /*
81                         * The first byte of this chunk is the continuation
82                         * of a word spanning between this chunk and the
83                         * last chunk.
84                         *
85                         * s_util.c[0] is already saved when scanning previous
86                         * chunk.
87                         */
88                        s_util.c[1] = *(const u_int8_t *)w;
89                        sum += s_util.s;
90                        w = (const u_int16_t *)(void *)((const u_int8_t *)w + 1);
91                        mlen = vec->len - 1;
92                } else
93                        mlen = vec->len;
94                /*
95                 * Force to even boundary.
96                 */
97                if ((1 & (unsigned long) w) && (mlen > 0)) {
98                        REDUCE;
99                        sum <<= 8;
100                        s_util.c[0] = *(const u_int8_t *)w;
101                        w = (const u_int16_t *)(void *)((const u_int8_t *)w + 1);
102                        mlen--;
103                        byte_swapped = 1;
104                }
105                /*
106                 * Unroll the loop to make overhead from
107                 * branches &c small.
108                 */
109                while ((mlen -= 32) >= 0) {
110                        sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
111                        sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
112                        sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
113                        sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
114                        w += 16;
115                }
116                mlen += 32;
117                while ((mlen -= 8) >= 0) {
118                        sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
119                        w += 4;
120                }
121                mlen += 8;
122                if (mlen == 0 && byte_swapped == 0)
123                        continue;
124                REDUCE;
125                while ((mlen -= 2) >= 0) {
126                        sum += *w++;
127                }
128                if (byte_swapped) {
129                        REDUCE;
130                        sum <<= 8;
131                        byte_swapped = 0;
132                        if (mlen == -1) {
133                                s_util.c[1] = *(const u_int8_t *)w;
134                                sum += s_util.s;
135                                mlen = 0;
136                        } else
137                                mlen = -1;
138                } else if (mlen == -1)
139                        s_util.c[0] = *(const u_int8_t *)w;
140        }
141        if (mlen == -1) {
142                /* The last mbuf has odd # of bytes. Follow the
143                   standard (the odd byte may be shifted left by 8 bits
144                   or not as determined by endian-ness of the machine) */
145                s_util.c[1] = 0;
146                sum += s_util.s;
147        }
148        REDUCE;
149        return (~sum & 0xffff);
150}
151
152/*
153 * Given the host-byte-order value of the checksum field in a packet
154 * header, and the network-byte-order computed checksum of the data
155 * that the checksum covers (including the checksum itself), compute
156 * what the checksum field *should* have been.
157 */
158u_int16_t
159in_cksum_shouldbe(u_int16_t sum, u_int16_t computed_sum)
160{
161        u_int32_t shouldbe;
162
163        /*
164         * The value that should have gone into the checksum field
165         * is the negative of the value gotten by summing up everything
166         * *but* the checksum field.
167         *
168         * We can compute that by subtracting the value of the checksum
169         * field from the sum of all the data in the packet, and then
170         * computing the negative of that value.
171         *
172         * "sum" is the value of the checksum field, and "computed_sum"
173         * is the negative of the sum of all the data in the packets,
174         * so that's -(-computed_sum - sum), or (sum + computed_sum).
175         *
176         * All the arithmetic in question is one's complement, so the
177         * addition must include an end-around carry; we do this by
178         * doing the arithmetic in 32 bits (with no sign-extension),
179         * and then adding the upper 16 bits of the sum, which contain
180         * the carry, to the lower 16 bits of the sum, and then do it
181         * again in case *that* sum produced a carry.
182         *
183         * As RFC 1071 notes, the checksum can be computed without
184         * byte-swapping the 16-bit words; summing 16-bit words
185         * on a big-endian machine gives a big-endian checksum, which
186         * can be directly stuffed into the big-endian checksum fields
187         * in protocol headers, and summing words on a little-endian
188         * machine gives a little-endian checksum, which must be
189         * byte-swapped before being stuffed into a big-endian checksum
190         * field.
191         *
192         * "computed_sum" is a network-byte-order value, so we must put
193         * it in host byte order before subtracting it from the
194         * host-byte-order value from the header; the adjusted checksum
195         * will be in host byte order, which is what we'll return.
196         */
197        shouldbe = sum;
198        shouldbe += ntohs(computed_sum);
199        shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16);
200        shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16);
201        return shouldbe;
202}
Note: See TracBrowser for help on using the repository browser.