LCOV - code coverage report
Current view: top level - netinet - in4_cksum.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 66 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 1 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: in4_cksum.c,v 1.10 2014/09/08 06:24:13 jsg Exp $      */
       2             : /*      $KAME: in4_cksum.c,v 1.10 2001/11/30 10:06:15 itojun Exp $      */
       3             : /*      $NetBSD: in_cksum.c,v 1.13 1996/10/13 02:03:03 christos Exp $   */
       4             : 
       5             : /*
       6             :  * Copyright (C) 1999 WIDE Project.
       7             :  * All rights reserved.
       8             :  *
       9             :  * Redistribution and use in source and binary forms, with or without
      10             :  * modification, are permitted provided that the following conditions
      11             :  * are met:
      12             :  * 1. Redistributions of source code must retain the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer.
      14             :  * 2. Redistributions in binary form must reproduce the above copyright
      15             :  *    notice, this list of conditions and the following disclaimer in the
      16             :  *    documentation and/or other materials provided with the distribution.
      17             :  * 3. Neither the name of the project nor the names of its contributors
      18             :  *    may be used to endorse or promote products derived from this software
      19             :  *    without specific prior written permission.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
      22             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
      25             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31             :  * SUCH DAMAGE.
      32             :  */
      33             : 
      34             : /*
      35             :  * Copyright (c) 1988, 1992, 1993
      36             :  *      The Regents of the University of California.  All rights reserved.
      37             :  *
      38             :  * Redistribution and use in source and binary forms, with or without
      39             :  * modification, are permitted provided that the following conditions
      40             :  * are met:
      41             :  * 1. Redistributions of source code must retain the above copyright
      42             :  *    notice, this list of conditions and the following disclaimer.
      43             :  * 2. Redistributions in binary form must reproduce the above copyright
      44             :  *    notice, this list of conditions and the following disclaimer in the
      45             :  *    documentation and/or other materials provided with the distribution.
      46             :  * 3. Neither the name of the University nor the names of its contributors
      47             :  *    may be used to endorse or promote products derived from this software
      48             :  *    without specific prior written permission.
      49             :  *
      50             :  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      51             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      52             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      53             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      54             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      55             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      56             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      57             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      58             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      59             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      60             :  * SUCH DAMAGE.
      61             :  *
      62             :  *      @(#)in_cksum.c  8.1 (Berkeley) 6/10/93
      63             :  */
      64             : 
      65             : #include <sys/param.h>
      66             : #include <sys/mbuf.h>
      67             : #include <sys/systm.h>
      68             : #include <sys/socket.h>
      69             : #include <sys/socketvar.h>
      70             : #include <netinet/in.h>
      71             : #include <netinet/ip.h>
      72             : #include <netinet/ip_var.h>
      73             : 
      74             : /*
      75             :  * Checksum routine for Internet Protocol family headers (Portable Version).
      76             :  * This is only for IPv4 pseudo header checksum.
      77             :  * No need to clear non-pseudo-header fields in IPv4 header.
      78             :  * len is for actual payload size, and does not include IPv4 header and
      79             :  * skipped header chain (off + len should be equal to the whole packet).
      80             :  *
      81             :  * This routine is very heavily used in the network
      82             :  * code and should be modified for each CPU to be as fast as possible.
      83             :  */
      84             : 
      85             : #define ADDCARRY(x)  (x > 65535 ? x -= 65535 : x)
      86             : #define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
      87             : 
      88             : int
      89           0 : in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len)
      90             : {
      91             :         u_int16_t *w;
      92             :         int sum = 0;
      93             :         int mlen = 0;
      94             :         int byte_swapped = 0;
      95             :         union {
      96             :                 struct ipovly ipov;
      97             :                 u_int16_t w[10];
      98             :         } u;
      99             :         union {
     100             :                 u_int8_t  c[2];
     101             :                 u_int16_t s;
     102             :         } s_util;
     103             :         union {
     104             :                 u_int16_t s[2];
     105             :                 u_int32_t l;
     106             :         } l_util;
     107             : 
     108           0 :         if (nxt != 0) {
     109             :                 /* pseudo header */
     110           0 :                 if (off < sizeof(struct ipovly))
     111           0 :                         panic("in4_cksum: offset too short");
     112           0 :                 if (m->m_len < sizeof(struct ip))
     113           0 :                         panic("in4_cksum: bad mbuf chain");
     114             :                 bzero(&u.ipov, sizeof(u.ipov));
     115           0 :                 u.ipov.ih_len = htons(len);
     116             :                 u.ipov.ih_pr = nxt;
     117           0 :                 u.ipov.ih_src = mtod(m, struct ip *)->ip_src;
     118           0 :                 u.ipov.ih_dst = mtod(m, struct ip *)->ip_dst;
     119             :                 w = u.w;
     120             :                 /* assumes sizeof(ipov) == 20 */
     121           0 :                 sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; sum += w[4];
     122           0 :                 sum += w[5]; sum += w[6]; sum += w[7]; sum += w[8]; sum += w[9];
     123           0 :         }
     124             : 
     125             :         /* skip unnecessary part */
     126           0 :         while (m && off > 0) {
     127           0 :                 if (m->m_len > off)
     128             :                         break;
     129           0 :                 off -= m->m_len;
     130           0 :                 m = m->m_next;
     131             :         }
     132             : 
     133           0 :         for (;m && len; m = m->m_next) {
     134           0 :                 if (m->m_len == 0)
     135             :                         continue;
     136           0 :                 w = (u_int16_t *)(mtod(m, caddr_t) + off);
     137           0 :                 if (mlen == -1) {
     138             :                         /*
     139             :                          * The first byte of this mbuf is the continuation
     140             :                          * of a word spanning between this mbuf and the
     141             :                          * last mbuf.
     142             :                          *
     143             :                          * s_util.c[0] is already saved when scanning previous
     144             :                          * mbuf.
     145             :                          */
     146           0 :                         s_util.c[1] = *(u_int8_t *)w;
     147           0 :                         sum += s_util.s;
     148           0 :                         w = (u_int16_t *)((u_int8_t *)w + 1);
     149           0 :                         mlen = m->m_len - off - 1;
     150           0 :                         len--;
     151           0 :                 } else
     152           0 :                         mlen = m->m_len - off;
     153             :                 off = 0;
     154           0 :                 if (len < mlen)
     155           0 :                         mlen = len;
     156           0 :                 len -= mlen;
     157             :                 /*
     158             :                  * Force to even boundary.
     159             :                  */
     160           0 :                 if ((1 & (long) w) && (mlen > 0)) {
     161           0 :                         REDUCE;
     162           0 :                         sum <<= 8;
     163           0 :                         s_util.c[0] = *(u_int8_t *)w;
     164           0 :                         w = (u_int16_t *)((int8_t *)w + 1);
     165           0 :                         mlen--;
     166             :                         byte_swapped = 1;
     167           0 :                 }
     168             :                 /*
     169             :                  * Unroll the loop to make overhead from
     170             :                  * branches &c small.
     171             :                  */
     172           0 :                 while ((mlen -= 32) >= 0) {
     173           0 :                         sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
     174           0 :                         sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
     175           0 :                         sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
     176           0 :                         sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
     177           0 :                         w += 16;
     178             :                 }
     179             :                 mlen += 32;
     180           0 :                 while ((mlen -= 8) >= 0) {
     181           0 :                         sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
     182           0 :                         w += 4;
     183             :                 }
     184             :                 mlen += 8;
     185           0 :                 if (mlen == 0 && byte_swapped == 0)
     186             :                         continue;
     187           0 :                 REDUCE;
     188           0 :                 while ((mlen -= 2) >= 0) {
     189           0 :                         sum += *w++;
     190             :                 }
     191           0 :                 if (byte_swapped) {
     192           0 :                         REDUCE;
     193           0 :                         sum <<= 8;
     194             :                         byte_swapped = 0;
     195           0 :                         if (mlen == -1) {
     196           0 :                                 s_util.c[1] = *(u_int8_t *)w;
     197           0 :                                 sum += s_util.s;
     198             :                                 mlen = 0;
     199           0 :                         } else
     200             :                                 mlen = -1;
     201           0 :                 } else if (mlen == -1)
     202           0 :                         s_util.c[0] = *(u_int8_t *)w;
     203             :         }
     204           0 :         if (len)
     205           0 :                 printf("cksum4: out of data\n");
     206           0 :         if (mlen == -1) {
     207             :                 /* The last mbuf has odd # of bytes. Follow the
     208             :                    standard (the odd byte may be shifted left by 8 bits
     209             :                    or not as determined by endian-ness of the machine) */
     210             :                 s_util.c[1] = 0;
     211           0 :                 sum += s_util.s;
     212           0 :         }
     213           0 :         REDUCE;
     214           0 :         return (~sum & 0xffff);
     215             : }

Generated by: LCOV version 1.13