/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1995, 96, 97, 98, 99, 2001 by Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. * Copyright (C) 2001 Thiemo Seufer. * Copyright (C) 2002 Maciej W. Rozycki * Copyright (C) 2014 Imagination Technologies Ltd.
*/ #ifndef _ASM_CHECKSUM_H #define _ASM_CHECKSUM_H
/* * computes the checksum of a memory block at buff, length len, * and adds in "sum" (32-bit) * * returns a 32-bit number suitable for feeding into itself * or csum_tcpudp_magic * * this function must be called with even lengths, except * for the last fragment, which may be odd * * it's best to have buff aligned on a 32-bit boundary
*/
__wsum csum_partial(constvoid *buff, int len, __wsum sum);
__wsum __csum_partial_copy_from_user(constvoid __user *src, void *dst, int len);
__wsum __csum_partial_copy_to_user(constvoid *src, void __user *dst, int len);
/* * Copy and checksum to user
*/ #define HAVE_CSUM_COPY_USER staticinline
__wsum csum_and_copy_to_user(constvoid *src, void __user *dst, int len)
{
might_fault(); if (!access_ok(dst, len)) return 0; return __csum_partial_copy_to_user(src, dst, len);
}
/* * the same as csum_partial, but copies from user space (but on MIPS * we have just one address space, so this is identical to the above)
*/ #define _HAVE_ARCH_CSUM_AND_COPY
__wsum __csum_partial_copy_nocheck(constvoid *src, void *dst, int len); staticinline __wsum csum_partial_copy_nocheck(constvoid *src, void *dst, int len)
{ return __csum_partial_copy_nocheck(src, dst, len);
}
/* * Fold a partial checksum without adding pseudo headers
*/ staticinline __sum16 csum_fold(__wsum csum)
{
u32 sum = (__force u32)csum;
sum += (sum << 16);
csum = (__force __wsum)(sum < (__force u32)csum);
sum >>= 16;
sum += (__force u32)csum;
/* * This is a version of ip_compute_csum() optimized for IP headers, * which always checksum on 4 octet boundaries. * * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by * Arnt Gulbrandsen.
*/ staticinline __sum16 ip_fast_csum(constvoid *iph, unsignedint ihl)
{ constunsignedint *word = iph; constunsignedint *stop = word + ihl; unsignedint csum; int carry;
/* * We know PROTO + LEN has the sign bit clear, so cast to a signed * type to avoid an extraneous zero-extension where TMP is 64-bit.
*/
tmp = (__s32)(proto + len);
tmp <<= IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN) ? 8 : 0;
sum += tmp; if (IS_ENABLED(CONFIG_32BIT))
sum += sum < tmp;
tmp = (__force unsignedlong)isum;
sum += tmp;
if (IS_ENABLED(CONFIG_32BIT)) {
sum += sum < tmp;
osum = sum;
} elseif (IS_ENABLED(CONFIG_64BIT)) {
tmp = sum << sh32;
sum += tmp;
osum = sum < tmp;
osum += sum >> sh32;
} else {
BUILD_BUG();
}
/* * this routine is used for miscellaneous IP-like checksums, mainly * in icmp.c
*/ staticinline __sum16 ip_compute_csum(constvoid *buff, int len)
{ return csum_fold(csum_partial(buff, len, 0));
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.