/** @file
 * @brief Misc network utility functions
 *
 */

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_utils, CONFIG_NET_UTILS_LOG_LEVEL);

#include <zephyr/kernel.h>
#include <stdlib.h>
#include <zephyr/internal/syscall_handler.h>
#include <zephyr/types.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>

#include <zephyr/sys/byteorder.h>
#include <zephyr/net/net_ip.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/net/net_core.h>
#include <zephyr/net/socketcan.h>

char *net_sprint_addr(sa_family_t af, const void *addr)
{
#define NBUFS 3
	static char buf[NBUFS][NET_IPV6_ADDR_LEN];
	static int i;
	char *s = buf[++i % NBUFS];

	return net_addr_ntop(af, addr, s, NET_IPV6_ADDR_LEN);
}

const char *net_proto2str(int family, int proto)
{
	if (family == AF_INET || family == AF_INET6) {
		switch (proto) {
		case IPPROTO_ICMP:
			return "ICMPv4";
		case IPPROTO_TCP:
			return "TCP";
		case IPPROTO_UDP:
			return "UDP";
		case IPPROTO_ICMPV6:
			return "ICMPv6";
		default:
			break;
		}
	} else if (family == AF_CAN) {
		switch (proto) {
		case CAN_RAW:
			return "CAN_RAW";
		default:
			break;
		}
	}

	return "UNK_PROTO";
}

char *net_byte_to_hex(char *ptr, uint8_t byte, char base, bool pad)
{
	int i, val;

	for (i = 0, val = (byte & 0xf0) >> 4; i < 2; i++, val = byte & 0x0f) {
		if (i == 0 && !pad && !val) {
			continue;
		}
		if (val < 10) {
			*ptr++ = (char) (val + '0');
		} else {
			*ptr++ = (char) (val - 10 + base);
		}
	}

	*ptr = '\0';

	return ptr;
}

char *net_sprint_ll_addr_buf(const uint8_t *ll, uint8_t ll_len,
			     char *buf, int buflen)
{
	uint8_t i, len, blen;
	char *ptr = buf;

	if (ll == NULL) {
		return "<unknown>";
	}

	switch (ll_len) {
	case 8:
		len = 8U;
		break;
	case 6:
		len = 6U;
		break;
	case 2:
		len = 2U;
		break;
	default:
		len = 6U;
		break;
	}

	for (i = 0U, blen = buflen; i < len && blen > 0; i++) {
		ptr = net_byte_to_hex(ptr, (char)ll[i], 'A', true);
		*ptr++ = ':';
		blen -= 3U;
	}

	if (!(ptr - buf)) {
		return NULL;
	}

	*(ptr - 1) = '\0';
	return buf;
}

static int net_value_to_udec(char *buf, uint32_t value, int precision)
{
	uint32_t divisor;
	int i;
	int temp;
	char *start = buf;

	divisor = 1000000000U;
	if (precision < 0) {
		precision = 1;
	}

	for (i = 9; i >= 0; i--, divisor /= 10U) {
		temp = value / divisor;
		value = value % divisor;
		if ((precision > i) || (temp != 0)) {
			precision = i;
			*buf++ = (char) (temp + '0');
		}
	}
	*buf = 0;

	return buf - start;
}

char *z_impl_net_addr_ntop(sa_family_t family, const void *src,
			   char *dst, size_t size)
{
	struct in_addr *addr = NULL;
	struct in6_addr *addr6 = NULL;
	uint16_t *w = NULL;
	uint8_t i, bl, bh, longest = 1U;
	int8_t pos = -1;
	char delim = ':';
	unsigned char zeros[8] = { 0 };
	char *ptr = dst;
	int len = -1;
	uint16_t value;
	bool needcolon = false;
	bool mapped = false;

	if (family == AF_INET6) {
		addr6 = (struct in6_addr *)src;
		w = (uint16_t *)addr6->s6_addr16;
		len = 8;

		if (net_ipv6_addr_is_v4_mapped(addr6)) {
			mapped = true;
		}

		for (i = 0U; i < 8; i++) {
			uint8_t j;

			for (j = i; j < 8; j++) {
				if (UNALIGNED_GET(&w[j]) != 0) {
					break;
				}

				zeros[i]++;
			}
		}

		for (i = 0U; i < 8; i++) {
			if (zeros[i] > longest) {
				longest = zeros[i];
				pos = i;
			}
		}

		if (longest == 1U) {
			pos = -1;
		}

	} else if (family == AF_INET) {
		addr = (struct in_addr *)src;
		len = 4;
		delim = '.';
	} else {
		return NULL;
	}

print_mapped:
	for (i = 0U; i < len; i++) {
		/* IPv4 address a.b.c.d */
		if (len == 4) {
			uint8_t l;

			value = (uint32_t)addr->s4_addr[i];

			/* net_byte_to_udec() eats 0 */
			if (value == 0U) {
				*ptr++ = '0';
				*ptr++ = delim;
				continue;
			}

			l = net_value_to_udec(ptr, value, 0);

			ptr += l;
			*ptr++ = delim;

			continue;
		}

		if (mapped && (i > 5)) {
			delim = '.';
			len = 4;
			addr = (struct in_addr *)(&addr6->s6_addr32[3]);
			*ptr++ = ':';
			family = AF_INET;
			goto print_mapped;
		}

		/* IPv6 address */
		if (i == pos) {
			if (needcolon || i == 0U) {
				*ptr++ = ':';
			}

			*ptr++ = ':';
			needcolon = false;
			i += longest - 1U;

			continue;
		}

		if (needcolon) {
			*ptr++ = ':';
		}

		value = (uint32_t)sys_be16_to_cpu(UNALIGNED_GET(&w[i]));
		bh = value >> 8;
		bl = value & 0xff;

		if (bh) {
			if (bh > 0x0f) {
				ptr = net_byte_to_hex(ptr, bh, 'a', false);
			} else {
				if (bh < 10) {
					*ptr++ = (char)(bh + '0');
				} else {
					*ptr++ = (char) (bh - 10 + 'a');
				}
			}

			ptr = net_byte_to_hex(ptr, bl, 'a', true);
		} else if (bl > 0x0f) {
			ptr = net_byte_to_hex(ptr, bl, 'a', false);
		} else {
			if (bl < 10) {
				*ptr++ = (char)(bl + '0');
			} else {
				*ptr++ = (char) (bl - 10 + 'a');
			}
		}

		needcolon = true;
	}

	if (!(ptr - dst)) {
		return NULL;
	}

	if (family == AF_INET) {
		*(ptr - 1) = '\0';
	} else {
		*ptr = '\0';
	}

	return dst;
}

#if defined(CONFIG_USERSPACE)
char *z_vrfy_net_addr_ntop(sa_family_t family, const void *src,
			   char *dst, size_t size)
{
	char str[INET6_ADDRSTRLEN];
	struct in6_addr addr6;
	struct in_addr addr4;
	char *out;
	const void *addr;

	K_OOPS(K_SYSCALL_MEMORY_WRITE(dst, size));

	if (family == AF_INET) {
		K_OOPS(k_usermode_from_copy(&addr4, (const void *)src,
					sizeof(addr4)));
		addr = &addr4;
	} else if (family == AF_INET6) {
		K_OOPS(k_usermode_from_copy(&addr6, (const void *)src,
					sizeof(addr6)));
		addr = &addr6;
	} else {
		return 0;
	}

	out = z_impl_net_addr_ntop(family, addr, str, sizeof(str));
	if (!out) {
		return 0;
	}

	K_OOPS(k_usermode_to_copy((void *)dst, str, MIN(size, sizeof(str))));

	return dst;
}
#include <syscalls/net_addr_ntop_mrsh.c>
#endif /* CONFIG_USERSPACE */

int z_impl_net_addr_pton(sa_family_t family, const char *src,
			 void *dst)
{
	if (family == AF_INET) {
		struct in_addr *addr = (struct in_addr *)dst;
		size_t i, len;

		len = strlen(src);
		for (i = 0; i < len; i++) {
			if (!(src[i] >= '0' && src[i] <= '9') &&
			    src[i] != '.') {
				return -EINVAL;
			}
		}

		(void)memset(addr, 0, sizeof(struct in_addr));

		for (i = 0; i < sizeof(struct in_addr); i++) {
			char *endptr;

			addr->s4_addr[i] = strtol(src, &endptr, 10);

			src = ++endptr;
		}

	} else if (family == AF_INET6) {
		/* If the string contains a '.', it means it's of the form
		 * X:X:X:X:X:X:x.x.x.x, and contains only 6 16-bit pieces
		 */
		int expected_groups = strchr(src, '.') ? 6 : 8;
		struct in6_addr *addr = (struct in6_addr *)dst;
		int i, len;

		if (*src == ':') {
			/* Ignore a leading colon, makes parsing neater */
			src++;
		}

		len = strlen(src);
		for (i = 0; i < len; i++) {
			if (!(src[i] >= '0' && src[i] <= '9') &&
			    !(src[i] >= 'A' && src[i] <= 'F') &&
			    !(src[i] >= 'a' && src[i] <= 'f') &&
			    src[i] != '.' && src[i] != ':') {
				return -EINVAL;
			}
		}

		for (i = 0; i < expected_groups; i++) {
			char *tmp;

			if (!src || *src == '\0') {
				return -EINVAL;
			}

			if (*src != ':') {
				/* Normal IPv6 16-bit piece */
				UNALIGNED_PUT(htons(strtol(src, NULL, 16)),
					      &addr->s6_addr16[i]);
				src = strchr(src, ':');
				if (src) {
					src++;
				} else {
					if (i < expected_groups - 1) {
						return -EINVAL;
					}
				}

				continue;
			}

			/* Two colons in a row */

			for (; i < expected_groups; i++) {
				UNALIGNED_PUT(0, &addr->s6_addr16[i]);
			}

			tmp = strrchr(src, ':');
			if (src == tmp && (expected_groups == 6 || !src[1])) {
				src++;
				break;
			}

			if (expected_groups == 6) {
				/* we need to drop the trailing
				 * colon since it's between the
				 * ipv6 and ipv4 addresses, rather than being
				 * a part of the ipv6 address
				 */
				tmp--;
			}

			/* Calculate the amount of skipped zeros */
			i = expected_groups - 1;
			do {
				if (*tmp == ':') {
					i--;
				}

				if (i < 0) {
					return -EINVAL;
				}
			} while (tmp-- != src);

			src++;
		}

		if (expected_groups == 6) {
			/* Parse the IPv4 part */
			for (i = 0; i < 4; i++) {
				if (!src || !*src) {
					return -EINVAL;
				}

				addr->s6_addr[12 + i] = strtol(src, NULL, 10);

				src = strchr(src, '.');
				if (src) {
					src++;
				} else {
					if (i < 3) {
						return -EINVAL;
					}
				}
			}
		}
	} else {
		return -EINVAL;
	}

	return 0;
}

#if defined(CONFIG_USERSPACE)
int z_vrfy_net_addr_pton(sa_family_t family, const char *src,
			 void *dst)
{
	char str[MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)] = {};
	struct in6_addr addr6;
	struct in_addr addr4;
	void *addr;
	size_t size;
	int err;

	if (family == AF_INET) {
		size = sizeof(struct in_addr);
		addr = &addr4;
	} else if (family == AF_INET6) {
		size = sizeof(struct in6_addr);
		addr = &addr6;
	} else {
		return -EINVAL;
	}

	if (k_usermode_string_copy(str, (char *)src, sizeof(str)) != 0) {
		return -EINVAL;
	}

	K_OOPS(K_SYSCALL_MEMORY_WRITE(dst, size));

	err = z_impl_net_addr_pton(family, str, addr);
	if (err) {
		return err;
	}

	K_OOPS(k_usermode_to_copy((void *)dst, addr, size));

	return 0;
}
#include <syscalls/net_addr_pton_mrsh.c>
#endif /* CONFIG_USERSPACE */


#ifdef CONFIG_LITTLE_ENDIAN
#define CHECKSUM_BIG_ENDIAN 0
#else
#define CHECKSUM_BIG_ENDIAN 1
#endif

static uint16_t offset_based_swap8(const uint8_t *data)
{
	uint16_t data16 = (uint16_t)*data;

	if (((uintptr_t)(data) & 1) == CHECKSUM_BIG_ENDIAN) {
		return data16;
	} else {
		return data16 << 8;
	}
}

/* Word based checksum calculation based on:
 * https://blogs.igalia.com/dpino/2018/06/14/fast-checksum-computation/
 * It’s not necessary to add octets as 16-bit words. Due to the associative property of addition,
 * it is possible to do parallel addition using larger word sizes such as 32-bit or 64-bit words.
 * In those cases the variable that stores the accumulative sum has to be bigger too.
 * Once the sum is computed a final step folds the sum to a 16-bit word (adding carry if any).
 */
uint16_t calc_chksum(uint16_t sum_in, const uint8_t *data, size_t len)
{
	uint64_t sum;
	uint32_t *p;
	size_t i = 0;
	size_t pending = len;
	int odd_start = ((uintptr_t)data & 0x01);

	/* Sum in is in host endiannes, working order endiannes is both dependent on endianness
	 * and the offset of starting
	 */
	if (odd_start == CHECKSUM_BIG_ENDIAN) {
		sum = BSWAP_16(sum_in);
	} else {
		sum = sum_in;
	}

	/* Process up to 3 data elements up front, so the data is aligned further down the line */
	if ((((uintptr_t)data & 0x01) != 0) && (pending >= 1)) {
		sum += offset_based_swap8(data);
		data++;
		pending--;
	}
	if ((((uintptr_t)data & 0x02) != 0) && (pending >= sizeof(uint16_t))) {
		pending -= sizeof(uint16_t);
		sum = sum + *((uint16_t *)data);
		data += sizeof(uint16_t);
	}
	p = (uint32_t *)data;

	/* Do loop unrolling for the very large data sets */
	while (pending >= sizeof(uint32_t) * 4) {
		uint64_t sum_a = p[i];
		uint64_t sum_b = p[i + 1];

		pending -= sizeof(uint32_t) * 4;
		sum_a += p[i + 2];
		sum_b += p[i + 3];
		i += 4;
		sum += sum_a + sum_b;
	}
	while (pending >= sizeof(uint32_t)) {
		pending -= sizeof(uint32_t);
		sum = sum + p[i++];
	}
	data = (uint8_t *)(p + i);
	if (pending >= 2) {
		pending -= sizeof(uint16_t);
		sum = sum + *((uint16_t *)data);
		data += sizeof(uint16_t);
	}
	if (pending == 1) {
		sum += offset_based_swap8(data);
	}

	/* Fold sum into 16-bit word. */
	while (sum >> 16) {
		sum = (sum & 0xffff) + (sum >> 16);
	}

	/* Sum in is in host endiannes, working order endiannes is both dependent on endianness
	 * and the offset of starting
	 */
	if (odd_start == CHECKSUM_BIG_ENDIAN) {
		return BSWAP_16((uint16_t)sum);
	} else {
		return sum;
	}
}

static inline uint16_t pkt_calc_chksum(struct net_pkt *pkt, uint16_t sum)
{
	struct net_pkt_cursor *cur = &pkt->cursor;
	size_t len;

	if (!cur->buf || !cur->pos) {
		return sum;
	}

	len = cur->buf->len - (cur->pos - cur->buf->data);

	while (cur->buf) {
		sum = calc_chksum(sum, cur->pos, len);

		cur->buf = cur->buf->frags;
		if (!cur->buf || !cur->buf->len) {
			break;
		}

		cur->pos = cur->buf->data;

		if (len % 2) {
			sum += *cur->pos;
			if (sum < *cur->pos) {
				sum++;
			}

			cur->pos++;
			len = cur->buf->len - 1;
		} else {
			len = cur->buf->len;
		}
	}

	return sum;
}

#if defined(CONFIG_NET_IP)
uint16_t net_calc_chksum(struct net_pkt *pkt, uint8_t proto)
{
	size_t len = 0U;
	uint16_t sum = 0U;
	struct net_pkt_cursor backup;
	bool ow;

	if (IS_ENABLED(CONFIG_NET_IPV4) &&
	    net_pkt_family(pkt) == AF_INET) {
		if (proto != IPPROTO_ICMP && proto != IPPROTO_IGMP) {
			len = 2 * sizeof(struct in_addr);
			sum = net_pkt_get_len(pkt) -
				net_pkt_ip_hdr_len(pkt) -
				net_pkt_ipv4_opts_len(pkt) + proto;
		}
	} else if (IS_ENABLED(CONFIG_NET_IPV6) &&
		   net_pkt_family(pkt) == AF_INET6) {
		len = 2 * sizeof(struct in6_addr);
		sum =  net_pkt_get_len(pkt) -
			net_pkt_ip_hdr_len(pkt) -
			net_pkt_ipv6_ext_len(pkt) + proto;
	} else {
		NET_DBG("Unknown protocol family %d", net_pkt_family(pkt));
		return 0;
	}

	net_pkt_cursor_backup(pkt, &backup);
	net_pkt_cursor_init(pkt);

	ow = net_pkt_is_being_overwritten(pkt);
	net_pkt_set_overwrite(pkt, true);

	net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) - len);

	sum = calc_chksum(sum, pkt->cursor.pos, len);
	net_pkt_skip(pkt, len + net_pkt_ip_opts_len(pkt));

	sum = pkt_calc_chksum(pkt, sum);

	sum = (sum == 0U) ? 0xffff : htons(sum);

	net_pkt_cursor_restore(pkt, &backup);

	net_pkt_set_overwrite(pkt, ow);

	return ~sum;
}
#endif

#if defined(CONFIG_NET_IPV4)
uint16_t net_calc_chksum_ipv4(struct net_pkt *pkt)
{
	uint16_t sum;

	sum = calc_chksum(0, pkt->buffer->data,
			  net_pkt_ip_hdr_len(pkt) +
			  net_pkt_ipv4_opts_len(pkt));

	sum = (sum == 0U) ? 0xffff : htons(sum);

	return ~sum;
}
#endif /* CONFIG_NET_IPV4 */

#if defined(CONFIG_NET_IPV4_IGMP)
uint16_t net_calc_chksum_igmp(struct net_pkt *pkt)
{
	return net_calc_chksum(pkt, IPPROTO_IGMP);
}
#endif /* CONFIG_NET_IPV4_IGMP */

#if defined(CONFIG_NET_IP)
static bool convert_port(const char *buf, uint16_t *port)
{
	unsigned long tmp;
	char *endptr;

	tmp = strtoul(buf, &endptr, 10);
	if ((endptr == buf && tmp == 0) ||
	    !(*buf != '\0' && *endptr == '\0') ||
	    ((unsigned long)(unsigned short)tmp != tmp)) {
		return false;
	}

	*port = tmp;

	return true;
}
#endif /* CONFIG_NET_IP */

#if defined(CONFIG_NET_IPV6)
static bool parse_ipv6(const char *str, size_t str_len,
		       struct sockaddr *addr, bool has_port)
{
	char *ptr = NULL;
	struct in6_addr *addr6;
	char ipaddr[INET6_ADDRSTRLEN + 1];
	int end, len, ret, i;
	uint16_t port;

	len = MIN(INET6_ADDRSTRLEN, str_len);

	for (i = 0; i < len; i++) {
		if (!str[i]) {
			len = i;
			break;
		}
	}

	if (has_port) {
		/* IPv6 address with port number */
		ptr = memchr(str, ']', len);
		if (!ptr) {
			return false;
		}

		end = MIN(len, ptr - (str + 1));
		memcpy(ipaddr, str + 1, end);
	} else {
		end = len;
		memcpy(ipaddr, str, end);
	}

	ipaddr[end] = '\0';

	addr6 = &net_sin6(addr)->sin6_addr;

	ret = net_addr_pton(AF_INET6, ipaddr, addr6);
	if (ret < 0) {
		return false;
	}

	net_sin6(addr)->sin6_family = AF_INET6;

	if (!has_port) {
		return true;
	}

	if ((ptr + 1) < (str + str_len) && *(ptr + 1) == ':') {
		/* -1 as end does not contain first [
		 * -2 as pointer is advanced by 2, skipping ]:
		 */
		len = str_len - end - 1 - 2;

		ptr += 2;

		for (i = 0; i < len; i++) {
			if (!ptr[i]) {
				len = i;
				break;
			}
		}

		/* Re-use the ipaddr buf for port conversion */
		memcpy(ipaddr, ptr, len);
		ipaddr[len] = '\0';

		ret = convert_port(ipaddr, &port);
		if (!ret) {
			return false;
		}

		net_sin6(addr)->sin6_port = htons(port);

		NET_DBG("IPv6 host %s port %d",
			net_addr_ntop(AF_INET6, addr6, ipaddr, sizeof(ipaddr) - 1),
			port);
	} else {
		NET_DBG("IPv6 host %s",
			net_addr_ntop(AF_INET6, addr6, ipaddr, sizeof(ipaddr) - 1));
	}

	return true;
}
#else
static inline bool parse_ipv6(const char *str, size_t str_len,
			      struct sockaddr *addr, bool has_port)
{
	return false;
}
#endif /* CONFIG_NET_IPV6 */

#if defined(CONFIG_NET_IPV4)
static bool parse_ipv4(const char *str, size_t str_len,
		       struct sockaddr *addr, bool has_port)
{
	char *ptr = NULL;
	char ipaddr[NET_IPV4_ADDR_LEN + 1];
	struct in_addr *addr4;
	int end, len, ret, i;
	uint16_t port;

	len = MIN(NET_IPV4_ADDR_LEN, str_len);

	for (i = 0; i < len; i++) {
		if (!str[i]) {
			len = i;
			break;
		}
	}

	if (has_port) {
		/* IPv4 address with port number */
		ptr = memchr(str, ':', len);
		if (!ptr) {
			return false;
		}

		end = MIN(len, ptr - str);
	} else {
		end = len;
	}

	memcpy(ipaddr, str, end);
	ipaddr[end] = '\0';

	addr4 = &net_sin(addr)->sin_addr;

	ret = net_addr_pton(AF_INET, ipaddr, addr4);
	if (ret < 0) {
		return false;
	}

	net_sin(addr)->sin_family = AF_INET;

	if (!has_port) {
		return true;
	}

	memcpy(ipaddr, ptr + 1, str_len - end);
	ipaddr[str_len - end] = '\0';

	ret = convert_port(ipaddr, &port);
	if (!ret) {
		return false;
	}

	net_sin(addr)->sin_port = htons(port);

	NET_DBG("IPv4 host %s port %d",
		net_addr_ntop(AF_INET, addr4, ipaddr, sizeof(ipaddr) - 1),
		port);
	return true;
}
#else
static inline bool parse_ipv4(const char *str, size_t str_len,
			      struct sockaddr *addr, bool has_port)
{
	return false;
}
#endif /* CONFIG_NET_IPV4 */

bool net_ipaddr_parse(const char *str, size_t str_len, struct sockaddr *addr)
{
	int i, count;

	if (!str || str_len == 0) {
		return false;
	}

	/* We cannot accept empty string here */
	if (*str == '\0') {
		return false;
	}

	if (*str == '[') {
		return parse_ipv6(str, str_len, addr, true);
	}

	for (count = i = 0; i < str_len && str[i]; i++) {
		if (str[i] == ':') {
			count++;
		}
	}

	if (count == 1) {
		return parse_ipv4(str, str_len, addr, true);
	}

#if defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_IPV6)
	if (!parse_ipv4(str, str_len, addr, false)) {
		return parse_ipv6(str, str_len, addr, false);
	}

	return true;
#endif

#if defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_IPV6)
	return parse_ipv4(str, str_len, addr, false);
#endif

#if defined(CONFIG_NET_IPV6) && !defined(CONFIG_NET_IPV4)
	return parse_ipv6(str, str_len, addr, false);
#endif
	return false;
}

int net_port_set_default(struct sockaddr *addr, uint16_t default_port)
{
	if (IS_ENABLED(CONFIG_NET_IPV4) && addr->sa_family == AF_INET &&
	    net_sin(addr)->sin_port == 0) {
		net_sin(addr)->sin_port = htons(default_port);
	} else if (IS_ENABLED(CONFIG_NET_IPV6) && addr->sa_family == AF_INET6 &&
		   net_sin6(addr)->sin6_port == 0) {
		net_sin6(addr)->sin6_port = htons(default_port);
	} else if ((IS_ENABLED(CONFIG_NET_IPV4) && addr->sa_family == AF_INET) ||
		   (IS_ENABLED(CONFIG_NET_IPV6) && addr->sa_family == AF_INET6)) {
		; /* Port is already set */
	} else {
		LOG_ERR("Unknown address family");
		return -EINVAL;
	}

	return 0;
}

int net_bytes_from_str(uint8_t *buf, int buf_len, const char *src)
{
	unsigned int i;
	char *endptr;

	for (i = 0U; i < strlen(src); i++) {
		if (!(src[i] >= '0' && src[i] <= '9') &&
		    !(src[i] >= 'A' && src[i] <= 'F') &&
		    !(src[i] >= 'a' && src[i] <= 'f') &&
		    src[i] != ':') {
			return -EINVAL;
		}
	}

	(void)memset(buf, 0, buf_len);

	for (i = 0U; i < buf_len; i++) {
		buf[i] = strtol(src, &endptr, 16);
		src = ++endptr;
	}

	return 0;
}

const char *net_family2str(sa_family_t family)
{
	switch (family) {
	case AF_UNSPEC:
		return "AF_UNSPEC";
	case AF_INET:
		return "AF_INET";
	case AF_INET6:
		return "AF_INET6";
	case AF_PACKET:
		return "AF_PACKET";
	case AF_CAN:
		return "AF_CAN";
	}

	return NULL;
}

const struct in_addr *net_ipv4_unspecified_address(void)
{
	static const struct in_addr addr;

	return &addr;
}

const struct in_addr *net_ipv4_broadcast_address(void)
{
	static const struct in_addr addr = { { { 255, 255, 255, 255 } } };

	return &addr;
}

/* IPv6 wildcard and loopback address defined by RFC2553 */
const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;

const struct in6_addr *net_ipv6_unspecified_address(void)
{
	return &in6addr_any;
}
