From d721001fd6d4162738578ba03c94c1198a5ef462 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 6 Dec 2019 21:41:39 -0700 Subject: net: Move the checksum functions to lib/ These functions are used by code outside the network support, so move them to lib/ to be more accessible. Without this, the functions are only accessible in SPL/TPL only if CONFIG_SPL/TPL_NET are defined. Many boards do not enable those option but still want to do checksums in this format. Fix up a few code-style nits while we are here. Signed-off-by: Simon Glass Acked-by: Joe Hershberger Reviewed-by: Bin Meng --- lib/Makefile | 2 +- lib/net_utils.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/Makefile b/lib/Makefile index 7a713a54dc..6b7b9ce85c 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -78,7 +78,7 @@ endif ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o obj-$(CONFIG_$(SPL_TPL_)HASH_SUPPORT) += crc16.o -obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o +obj-y += net_utils.o endif obj-$(CONFIG_ADDR_MAP) += addr_map.o obj-y += qsort.o diff --git a/lib/net_utils.c b/lib/net_utils.c index ed5044c3de..8af7782970 100644 --- a/lib/net_utils.c +++ b/lib/net_utils.c @@ -56,3 +56,51 @@ void string_to_enetaddr(const char *addr, uint8_t *enetaddr) addr = (*end) ? end + 1 : end; } } + +uint compute_ip_checksum(const void *vptr, uint nbytes) +{ + int sum, oddbyte; + const unsigned short *ptr = vptr; + + sum = 0; + while (nbytes > 1) { + sum += *ptr++; + nbytes -= 2; + } + if (nbytes == 1) { + oddbyte = 0; + ((u8 *)&oddbyte)[0] = *(u8 *)ptr; + ((u8 *)&oddbyte)[1] = 0; + sum += oddbyte; + } + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + sum = ~sum & 0xffff; + + return sum; +} + +uint add_ip_checksums(uint offset, uint sum, uint new) +{ + ulong checksum; + + sum = ~sum & 0xffff; + new = ~new & 0xffff; + if (offset & 1) { + /* + * byte-swap the sum if it came from an odd offset; since the + * computation is endian-independent this works. + */ + new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00); + } + checksum = sum + new; + if (checksum > 0xffff) + checksum -= 0xffff; + + return (~checksum) & 0xffff; +} + +int ip_checksum_ok(const void *addr, uint nbytes) +{ + return !(compute_ip_checksum(addr, nbytes) & 0xfffe); +} -- cgit v1.2.3