199029Speter/* $NetBSD: in_cksum.c,v 1.6 2000/03/31 19:55:09 castor Exp $ */ 238451Smsmith 338451Smsmith/* 438451Smsmith * Copyright (c) 1992 Regents of the University of California. 538451Smsmith * All rights reserved. 638451Smsmith * 738451Smsmith * This software was developed by the Computer Systems Engineering group 838451Smsmith * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 938451Smsmith * contributed to Berkeley. 1038451Smsmith * 1138451Smsmith * Redistribution and use in source and binary forms, with or without 1238451Smsmith * modification, are permitted provided that the following conditions 1338451Smsmith * are met: 1438451Smsmith * 1. Redistributions of source code must retain the above copyright 1538451Smsmith * notice, this list of conditions and the following disclaimer. 1638451Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1738451Smsmith * notice, this list of conditions and the following disclaimer in the 1838451Smsmith * documentation and/or other materials provided with the distribution. 1938451Smsmith * 4. Neither the name of the University nor the names of its contributors 2038451Smsmith * may be used to endorse or promote products derived from this software 2138451Smsmith * without specific prior written permission. 2238451Smsmith * 2338451Smsmith * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2438451Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2538451Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2638451Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2738451Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2838451Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2938451Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3038451Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3138451Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3238451Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3338451Smsmith * SUCH DAMAGE. 3438451Smsmith * 3538451Smsmith * @(#) Header: in_cksum.c,v 1.1 92/09/11 01:15:55 leres Exp (LBL) 3638451Smsmith */ 3738451Smsmith 3884221Sdillon#include <sys/cdefs.h> 3984221Sdillon__FBSDID("$FreeBSD: stable/11/stand/libsa/in_cksum.c 329132 2018-02-11 19:51:29Z kevans $"); 4084221Sdillon 4138451Smsmith#include <sys/types.h> 4299029Speter#include <machine/endian.h> 4338451Smsmith 4499029Speter#include "stand.h" 4599029Speter 4638451Smsmith/* 4738451Smsmith * Checksum routine for Internet Protocol family headers. 4838451Smsmith * This routine is very heavily used in the network 4938451Smsmith * code and should be modified for each CPU to be as fast as possible. 5038451Smsmith * In particular, it should not be this one. 5138451Smsmith */ 5238451Smsmithint 5338451Smsmithin_cksum(p, len) 5492913Sobrien void *p; 5592913Sobrien int len; 5638451Smsmith{ 5792913Sobrien int sum = 0, oddbyte = 0, v = 0; 5892913Sobrien u_char *cp = p; 5938451Smsmith 6038451Smsmith /* we assume < 2^16 bytes being summed */ 6138451Smsmith while (len > 0) { 6238451Smsmith if (oddbyte) { 6338451Smsmith sum += v + *cp++; 6438451Smsmith len--; 6538451Smsmith } 6638451Smsmith if (((long)cp & 1) == 0) { 6738451Smsmith while ((len -= 2) >= 0) { 6838451Smsmith sum += *(u_short *)cp; 6938451Smsmith cp += 2; 7038451Smsmith } 7138451Smsmith } else { 7238451Smsmith while ((len -= 2) >= 0) { 7399029Speter#if BYTE_ORDER == BIG_ENDIAN 7438451Smsmith sum += *cp++ << 8; 7538451Smsmith sum += *cp++; 7699029Speter#else 7799029Speter sum += *cp++; 7899029Speter sum += *cp++ << 8; 7999029Speter#endif 8038451Smsmith } 8138451Smsmith } 8238451Smsmith if ((oddbyte = len & 1) != 0) 8399029Speter#if BYTE_ORDER == BIG_ENDIAN 8438451Smsmith v = *cp << 8; 8599029Speter#else 8699029Speter v = *cp; 8799029Speter#endif 8838451Smsmith } 8938451Smsmith if (oddbyte) 9038451Smsmith sum += v; 9138451Smsmith sum = (sum >> 16) + (sum & 0xffff); /* add in accumulated carries */ 9238451Smsmith sum += sum >> 16; /* add potential last carry */ 9338451Smsmith return (0xffff & ~sum); 9438451Smsmith} 95