/** @file
 * @brief Generic connection related functions
 */

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

#if defined(CONFIG_NET_DEBUG_CONN)
#define SYS_LOG_DOMAIN "net/conn"
#define NET_LOG_ENABLED 1
#endif

#include <errno.h>
#include <misc/util.h>

#include <net/net_core.h>
#include <net/net_pkt.h>
#include <net/udp.h>

#include "net_private.h"
#include "icmpv6.h"
#include "icmpv4.h"
#include "udp_internal.h"
#include "tcp.h"
#include "connection.h"
#include "net_stats.h"

/** Is this connection used or not */
#define NET_CONN_IN_USE BIT(0)

/** Remote address set */
#define NET_CONN_REMOTE_ADDR_SET BIT(1)

/** Local address set */
#define NET_CONN_LOCAL_ADDR_SET BIT(2)

/** Rank bits */
#define NET_RANK_LOCAL_PORT         BIT(0)
#define NET_RANK_REMOTE_PORT        BIT(1)
#define NET_RANK_LOCAL_UNSPEC_ADDR  BIT(2)
#define NET_RANK_REMOTE_UNSPEC_ADDR BIT(3)
#define NET_RANK_LOCAL_SPEC_ADDR    BIT(4)
#define NET_RANK_REMOTE_SPEC_ADDR   BIT(5)

static struct net_conn conns[CONFIG_NET_MAX_CONN];

#if defined(CONFIG_NET_CONN_CACHE)

/* Cache the connection so that we do not have to go
 * through the full list of connections when receiving
 * a network packet. The cache contains an index to
 * corresponding entry in conns array.
 *
 * Hash value is constructed like this:
 *
 *   bit      description
 *   0  - 3   bits from remote port
 *   4  - 7   bits from local port
 *   8  - 18  bits from remote address
 *   19 - 29  bits from local address
 *   30       family
 *   31       protocol
 */
struct conn_hash {
	u32_t value;
	s32_t idx;
};

struct conn_hash_neg {
	u32_t value;
};

/** Connection cache */
static struct conn_hash conn_cache[CONFIG_NET_MAX_CONN];

/** Negative cache, we definitely do not have a connection
 * to these hosts.
 */
static struct conn_hash_neg conn_cache_neg[CONFIG_NET_MAX_CONN];

#define TAKE_BIT(val, bit, max, used)				\
	(((val & BIT(bit)) >> bit) << (max - used))

static inline u8_t ports_to_hash(u16_t remote_port,
				    u16_t local_port)
{
	/* Note that we do not convert port value to network byte order */
	return (remote_port & BIT(0)) |
		((remote_port & BIT(4)) >> 3) |
		((remote_port & BIT(8)) >> 6) |
		((remote_port & BIT(15)) >> 12) |
		(((local_port & BIT(0)) |
		  ((local_port & BIT(4)) >> 3) |
		  ((local_port & BIT(8)) >> 6) |
		  ((local_port & BIT(15)) >> 12)) << 4);
}

static inline u16_t ipv6_to_hash(struct in6_addr *addr)
{
	/* There is 11 bits available for IPv6 address */
	/* Use more bits from the lower part of address space */
	return
		/* Take 3 bits from higher values */
		TAKE_BIT(UNALIGNED_GET(&addr->s6_addr32[0]), 31, 11, 1) |
		TAKE_BIT(UNALIGNED_GET(&addr->s6_addr32[0]), 15, 11, 2) |
		TAKE_BIT(UNALIGNED_GET(&addr->s6_addr32[0]), 7, 11, 3) |

		/* Take 2 bits from higher middle values */
		TAKE_BIT(UNALIGNED_GET(&addr->s6_addr32[1]), 31, 11, 4) |
		TAKE_BIT(UNALIGNED_GET(&addr->s6_addr32[1]), 15, 11, 5) |

		/* Take 2 bits from lower middle values */
		TAKE_BIT(UNALIGNED_GET(&addr->s6_addr32[2]), 31, 11, 6) |
		TAKE_BIT(UNALIGNED_GET(&addr->s6_addr32[2]), 15, 11, 7) |

		/* Take 4 bits from lower values */
		TAKE_BIT(UNALIGNED_GET(&addr->s6_addr32[3]), 31, 11, 8) |
		TAKE_BIT(UNALIGNED_GET(&addr->s6_addr32[3]), 15, 11, 9) |
		TAKE_BIT(UNALIGNED_GET(&addr->s6_addr32[3]), 7, 11, 10) |
		TAKE_BIT(UNALIGNED_GET(&addr->s6_addr32[3]), 0, 11, 11);
}

static inline u16_t ipv4_to_hash(struct in_addr *addr)
{
	/* There is 11 bits available for IPv4 address */
	/* Use more bits from the lower part of address space */
	return
		TAKE_BIT(addr->s_addr, 31, 11, 1) |
		TAKE_BIT(addr->s_addr, 27, 11, 2) |
		TAKE_BIT(addr->s_addr, 21, 11, 3) |
		TAKE_BIT(addr->s_addr, 17, 11, 4) |
		TAKE_BIT(addr->s_addr, 14, 11, 5) |
		TAKE_BIT(addr->s_addr, 11, 11, 6) |
		TAKE_BIT(addr->s_addr, 8, 11, 7) |
		TAKE_BIT(addr->s_addr, 5, 11, 8) |
		TAKE_BIT(addr->s_addr, 3, 11, 9) |
		TAKE_BIT(addr->s_addr, 2, 11, 10) |
		TAKE_BIT(addr->s_addr, 0, 11, 11);
}

/* Return either the first free position in the cache (idx < 0) or
 * the existing cached position (idx >= 0)
 */
static s32_t check_hash(enum net_ip_protocol proto,
			  sa_family_t family,
			  void *remote_addr,
			  void *local_addr,
			  u16_t remote_port,
			  u16_t local_port,
			  u32_t *cache_value)
{
	int i, free_pos = -1;
	u32_t value = 0;

	value = ports_to_hash(remote_port, local_port);

#if defined(CONFIG_NET_UDP)
	if (proto == IPPROTO_UDP) {
		value |= BIT(31);
	}
#endif

#if defined(CONFIG_NET_TCP)
	if (proto == IPPROTO_TCP) {
		value &= ~BIT(31);
	}
#endif

#if defined(CONFIG_NET_IPV6)
	if (family == AF_INET6) {
		value |= BIT(30);
		value |= ipv6_to_hash((struct in6_addr *)remote_addr) << 8;
		value |= ipv6_to_hash((struct in6_addr *)local_addr) << 19;
	}
#endif

#if defined(CONFIG_NET_IPV4)
	if (family == AF_INET) {
		value &= ~BIT(30);
		value |= ipv4_to_hash((struct in_addr *)remote_addr) << 8;
		value |= ipv4_to_hash((struct in_addr *)local_addr) << 19;
	}
#endif

	for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
		if (conn_cache[i].value == value) {
			return i;
		}

		if (conn_cache[i].idx < 0 && free_pos < 0) {
			free_pos = i;
		}
	}

	if (free_pos >= 0) {
		conn_cache[free_pos].value = value;
		return free_pos;
	}

	*cache_value = value;

	return -ENOENT;
}

static inline s32_t get_conn(enum net_ip_protocol proto,
			     sa_family_t family,
			     struct net_pkt *pkt,
			     u32_t *cache_value)
{
	struct net_udp_hdr hdr, *udp_hdr;

	udp_hdr = net_udp_get_hdr(pkt, &hdr);
	if (!udp_hdr) {
		return NET_DROP;
	}

#if defined(CONFIG_NET_IPV4)
	if (family == AF_INET) {
		return check_hash(proto, family,
				  &NET_IPV4_HDR(pkt)->src,
				  &NET_IPV4_HDR(pkt)->dst,
				  udp_hdr->src_port,
				  udp_hdr->dst_port,
				  cache_value);
	}
#endif

#if defined(CONFIG_NET_IPV6)
	if (family == AF_INET6) {
		return check_hash(proto, family,
				  &NET_IPV6_HDR(pkt)->src,
				  &NET_IPV6_HDR(pkt)->dst,
				  udp_hdr->src_port,
				  udp_hdr->dst_port,
				  cache_value);
	}
#endif

	return -1;
}

static inline void cache_add_neg(u32_t cache_value)
{
	int i;

	for (i = 0; i < CONFIG_NET_MAX_CONN && cache_value > 0; i++) {
		if (conn_cache_neg[i].value) {
			continue;
		}

		NET_DBG("Add to neg cache value 0x%x", cache_value);

		conn_cache_neg[i].value = cache_value;
		break;
	}
}

static inline bool cache_check_neg(u32_t cache_value)
{
	int i;

	for (i = 0; i < CONFIG_NET_MAX_CONN && cache_value > 0; i++) {
		if (conn_cache_neg[i].value == cache_value) {
			NET_DBG("Cache neg [%d] value 0x%x found",
				i, cache_value);
			return true;
		}
	}

	return false;
}

static void cache_clear(void)
{
	int i;

	for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
		conn_cache[i].idx = -1;
		conn_cache_neg[i].value = 0;
	}
}

static inline enum net_verdict cache_check(enum net_ip_protocol proto,
					   struct net_pkt *pkt,
					   u32_t *cache_value,
					   s32_t *pos)
{
	*pos = get_conn(proto, net_pkt_family(pkt), pkt, cache_value);
	if (*pos >= 0) {
		if (conn_cache[*pos].idx >= 0) {
			/* Connection is in the cache */
			struct net_conn *conn;
			struct net_udp_hdr hdr, *udp_hdr;

			udp_hdr = net_udp_get_hdr(pkt, &hdr);
			if (!udp_hdr) {
				return NET_CONTINUE;
			}

			conn = &conns[conn_cache[*pos].idx];

			NET_DBG("Cache %s listener for pkt %p src port %u "
				"dst port %u family %d cache[%d] 0x%x",
				net_proto2str(proto), pkt,
				ntohs(udp_hdr->src_port),
				ntohs(udp_hdr->dst_port),
				net_pkt_family(pkt), *pos,
				conn_cache[*pos].value);

			return conn->cb(conn, pkt, conn->user_data);
		}
	} else if (*cache_value > 0) {
		if (cache_check_neg(*cache_value)) {
			NET_DBG("Drop by cache");
			return NET_DROP;
		}
	}

	return NET_CONTINUE;
}

static inline void cache_remove(struct net_conn *conn)
{
	int i;

	for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
		if (conn_cache[i].idx < 0 ||
		    conn_cache[i].idx >= CONFIG_NET_MAX_CONN) {
			continue;
		}

		if (&conns[conn_cache[i].idx] == conn) {
			conn_cache[i].idx = -1;
			break;
		}
	}
}
#else
#define cache_clear(...)
#define cache_add_neg(...)
#define cache_check(...) NET_CONTINUE
#define cache_remove(...)
#endif /* CONFIG_NET_CONN_CACHE */

int net_conn_unregister(struct net_conn_handle *handle)
{
	struct net_conn *conn = (struct net_conn *)handle;

	if (conn < &conns[0] || conn > &conns[CONFIG_NET_MAX_CONN]) {
		return -EINVAL;
	}

	if (!(conn->flags & NET_CONN_IN_USE)) {
		return -ENOENT;
	}

	cache_remove(conn);

	NET_DBG("[%zu] connection handler %p removed",
		(conn - conns) / sizeof(*conn), conn);

	memset(conn, 0, sizeof(*conn));

	return 0;
}

int net_conn_change_callback(struct net_conn_handle *handle,
			     net_conn_cb_t cb, void *user_data)
{
	struct net_conn *conn = (struct net_conn *)handle;

	if (conn < &conns[0] || conn > &conns[CONFIG_NET_MAX_CONN]) {
		return -EINVAL;
	}

	if (!(conn->flags & NET_CONN_IN_USE)) {
		return -ENOENT;
	}

	NET_DBG("[%zu] connection handler %p changed callback",
		(conn - conns) / sizeof(*conn), conn);

	conn->cb = cb;
	conn->user_data = user_data;

	return 0;
}

#if defined(CONFIG_NET_DEBUG_CONN)
static inline
void prepare_register_debug_print(char *dst, int dst_len,
				  char *src, int src_len,
				  const struct sockaddr *remote_addr,
				  const struct sockaddr *local_addr)
{
	if (remote_addr && remote_addr->sa_family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
		snprintk(dst, dst_len, "%s",
			 net_sprint_ipv6_addr(&net_sin6(remote_addr)->
							sin6_addr));
#else
		snprintk(dst, dst_len, "%s", "?");
#endif

	} else if (remote_addr && remote_addr->sa_family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
		snprintk(dst, dst_len, "%s",
			 net_sprint_ipv4_addr(&net_sin(remote_addr)->
							sin_addr));
#else
		snprintk(dst, dst_len, "%s", "?");
#endif

	} else {
		snprintk(dst, dst_len, "%s", "-");
	}

	if (local_addr && local_addr->sa_family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
		snprintk(src, src_len, "%s",
			 net_sprint_ipv6_addr(&net_sin6(local_addr)->
							sin6_addr));
#else
		snprintk(src, src_len, "%s", "?");
#endif

	} else if (local_addr && local_addr->sa_family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
		snprintk(src, src_len, "%s",
			 net_sprint_ipv4_addr(&net_sin(local_addr)->
							sin_addr));
#else
		snprintk(src, src_len, "%s", "?");
#endif

	} else {
		snprintk(src, src_len, "%s", "-");
	}
}
#endif /* CONFIG_NET_DEBUG_CONN */

/* Check if we already have identical connection handler installed. */
static int find_conn_handler(enum net_ip_protocol proto,
			     const struct sockaddr *remote_addr,
			     const struct sockaddr *local_addr,
			     u16_t remote_port,
			     u16_t local_port)
{
	int i;

	for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
		if (!(conns[i].flags & NET_CONN_IN_USE)) {
			continue;
		}

		if (conns[i].proto != proto) {
			continue;
		}

		if (remote_addr) {
			if (!(conns[i].flags & NET_CONN_REMOTE_ADDR_SET)) {
				continue;
			}

#if defined(CONFIG_NET_IPV6)
			if (remote_addr->sa_family == AF_INET6 &&
			    remote_addr->sa_family ==
			    conns[i].remote_addr.sa_family) {
				if (!net_ipv6_addr_cmp(
					    &net_sin6(remote_addr)->sin6_addr,
					    &net_sin6(&conns[i].remote_addr)->
								sin6_addr)) {
					continue;
				}
			} else
#endif
#if defined(CONFIG_NET_IPV4)
			if (remote_addr->sa_family == AF_INET &&
			    remote_addr->sa_family ==
			    conns[i].remote_addr.sa_family) {
				if (!net_ipv4_addr_cmp(
					    &net_sin(remote_addr)->sin_addr,
					    &net_sin(&conns[i].remote_addr)->
								sin_addr)) {
					continue;
				}
			} else
#endif
			{
				continue;
			}
		} else {
			if (conns[i].flags & NET_CONN_REMOTE_ADDR_SET) {
				continue;
			}
		}

		if (local_addr) {
			if (!(conns[i].flags & NET_CONN_LOCAL_ADDR_SET)) {
				continue;
			}

#if defined(CONFIG_NET_IPV6)
			if (local_addr->sa_family == AF_INET6 &&
			    local_addr->sa_family ==
			    conns[i].local_addr.sa_family) {
				if (!net_ipv6_addr_cmp(
					    &net_sin6(local_addr)->sin6_addr,
					    &net_sin6(&conns[i].local_addr)->
								sin6_addr)) {
					continue;
				}
			} else
#endif
#if defined(CONFIG_NET_IPV4)
			if (local_addr->sa_family == AF_INET &&
			    local_addr->sa_family ==
			    conns[i].local_addr.sa_family) {
				if (!net_ipv4_addr_cmp(
					    &net_sin(local_addr)->sin_addr,
					    &net_sin(&conns[i].local_addr)->
								sin_addr)) {
					continue;
				}
			} else
#endif
			{
				continue;
			}
		} else {
			if (conns[i].flags & NET_CONN_LOCAL_ADDR_SET) {
				continue;
			}
		}

		if (net_sin(&conns[i].remote_addr)->sin_port !=
		    htons(remote_port)) {
			continue;
		}

		if (net_sin(&conns[i].local_addr)->sin_port !=
		    htons(local_port)) {
			continue;
		}

		return i;
	}

	return -ENOENT;
}

int net_conn_register(enum net_ip_protocol proto,
		      const struct sockaddr *remote_addr,
		      const struct sockaddr *local_addr,
		      u16_t remote_port,
		      u16_t local_port,
		      net_conn_cb_t cb,
		      void *user_data,
		      struct net_conn_handle **handle)
{
	int i;
	u8_t rank = 0;

	i = find_conn_handler(proto, remote_addr, local_addr, remote_port,
			      local_port);
	if (i != -ENOENT) {
		NET_ERR("Identical connection handler %p already found.",
			&conns[i]);
		return -EALREADY;
	}

	for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
		if (conns[i].flags & NET_CONN_IN_USE) {
			continue;
		}

		if (remote_addr) {
#if defined(CONFIG_NET_IPV6)
			if (remote_addr->sa_family == AF_INET6) {
				memcpy(&conns[i].remote_addr, remote_addr,
				       sizeof(struct sockaddr_in6));

				if (net_is_ipv6_addr_unspecified(
					    &net_sin6(remote_addr)->
							sin6_addr)) {
					rank |= NET_RANK_REMOTE_UNSPEC_ADDR;
				} else {
					rank |= NET_RANK_REMOTE_SPEC_ADDR;
				}
			} else
#endif

#if defined(CONFIG_NET_IPV4)
			if (remote_addr->sa_family == AF_INET) {
				memcpy(&conns[i].remote_addr, remote_addr,
				       sizeof(struct sockaddr_in));

				if (!net_sin(remote_addr)->
							sin_addr.s_addr) {
					rank |= NET_RANK_REMOTE_UNSPEC_ADDR;
				} else {
					rank |= NET_RANK_REMOTE_SPEC_ADDR;
				}
			} else
#endif
			{
				NET_ERR("Remote address family not set");
				return -EINVAL;
			}

			conns[i].flags |= NET_CONN_REMOTE_ADDR_SET;
		}

		if (local_addr) {
#if defined(CONFIG_NET_IPV6)
			if (local_addr->sa_family == AF_INET6) {
				memcpy(&conns[i].local_addr, local_addr,
				       sizeof(struct sockaddr_in6));

				if (net_is_ipv6_addr_unspecified(
					    &net_sin6(local_addr)->
							sin6_addr)) {
					rank |= NET_RANK_LOCAL_UNSPEC_ADDR;
				} else {
					rank |= NET_RANK_LOCAL_SPEC_ADDR;
				}
			} else
#endif

#if defined(CONFIG_NET_IPV4)
			if (local_addr->sa_family == AF_INET) {
				memcpy(&conns[i].local_addr, local_addr,
				       sizeof(struct sockaddr_in));

				if (!net_sin(local_addr)->sin_addr.s_addr) {
					rank |= NET_RANK_LOCAL_UNSPEC_ADDR;
				} else {
					rank |= NET_RANK_LOCAL_SPEC_ADDR;
				}
			} else
#endif
			{
				NET_ERR("Local address family not set");
				return -EINVAL;
			}

			conns[i].flags |= NET_CONN_LOCAL_ADDR_SET;
		}

		if (remote_addr && local_addr) {
			if (remote_addr->sa_family != local_addr->sa_family) {
				NET_ERR("Address families different");
				return -EINVAL;
			}
		}

		if (remote_port) {
			rank |= NET_RANK_REMOTE_PORT;
			net_sin(&conns[i].remote_addr)->sin_port =
				htons(remote_port);
		}

		if (local_port) {
			rank |= NET_RANK_LOCAL_PORT;
			net_sin(&conns[i].local_addr)->sin_port =
				htons(local_port);
		}

		conns[i].flags |= NET_CONN_IN_USE;
		conns[i].cb = cb;
		conns[i].user_data = user_data;
		conns[i].rank = rank;
		conns[i].proto = proto;

		/* Cache needs to be cleared if new entries are added. */
		cache_clear();

#if defined(CONFIG_NET_DEBUG_CONN)
		do {
			char dst[NET_IPV6_ADDR_LEN];
			char src[NET_IPV6_ADDR_LEN];

			prepare_register_debug_print(dst, sizeof(dst),
						     src, sizeof(src),
						     remote_addr,
						     local_addr);

			NET_DBG("[%d/%d/%u/0x%02x] remote %p/%s/%u "
				"local %p/%s/%u cb %p ud %p",
				i, local_addr ? local_addr->sa_family : AF_UNSPEC,
				proto, rank, remote_addr, dst, remote_port,
				local_addr, src, local_port,
				cb, user_data);
		} while (0);
#endif /* CONFIG_NET_DEBUG_CONN */

		if (handle) {
			*handle = (struct net_conn_handle *)&conns[i];
		}

		return 0;
	}

	return -ENOENT;
}

static bool check_addr(struct net_pkt *pkt,
		       struct sockaddr *addr,
		       bool is_remote)
{
	if (addr->sa_family != net_pkt_family(pkt)) {
		return false;
	}

#if defined(CONFIG_NET_IPV6)
	if (net_pkt_family(pkt) == AF_INET6 && addr->sa_family == AF_INET6) {
		struct in6_addr *addr6;

		if (is_remote) {
			addr6 = &NET_IPV6_HDR(pkt)->src;
		} else {
			addr6 = &NET_IPV6_HDR(pkt)->dst;
		}

		if (!net_is_ipv6_addr_unspecified(
			    &net_sin6(addr)->sin6_addr)) {
			if (!net_ipv6_addr_cmp(&net_sin6(addr)->sin6_addr,
					       addr6)) {
				return false;
			}
		}

		return true;
	}
#endif /* CONFIG_NET_IPV6 */

#if defined(CONFIG_NET_IPV4)
	if (net_pkt_family(pkt) == AF_INET && addr->sa_family == AF_INET) {
		struct in_addr *addr4;

		if (is_remote) {
			addr4 = &NET_IPV4_HDR(pkt)->src;
		} else {
			addr4 = &NET_IPV4_HDR(pkt)->dst;
		}

		if (net_sin(addr)->sin_addr.s_addr) {
			if (!net_ipv4_addr_cmp(&net_sin(addr)->sin_addr,
					       addr4)) {
				return false;
			}
		}
	}
#endif /* CONFIG_NET_IPV4 */

	return true;
}

static inline void send_icmp_error(struct net_pkt *pkt)
{
	if (net_pkt_family(pkt) == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
		net_icmpv6_send_error(pkt, NET_ICMPV6_DST_UNREACH,
				      NET_ICMPV6_DST_UNREACH_NO_PORT, 0);
#endif /* CONFIG_NET_IPV6 */

	} else {

#if defined(CONFIG_NET_IPV4)
		net_icmpv4_send_error(pkt, NET_ICMPV4_DST_UNREACH,
				      NET_ICMPV4_DST_UNREACH_NO_PORT);
#endif /* CONFIG_NET_IPV4 */
	}
}

enum net_verdict net_conn_input(enum net_ip_protocol proto, struct net_pkt *pkt)
{
	int i, best_match = -1;
	s16_t best_rank = -1;
	u16_t src_port, dst_port;
	u16_t chksum;

#if defined(CONFIG_NET_CONN_CACHE)
	enum net_verdict verdict;
	u32_t cache_value = 0;
	s32_t pos;

	verdict = cache_check(proto, pkt, &cache_value, &pos);
	if (verdict != NET_CONTINUE) {
		return verdict;
	}
#endif

	/* This is only used for getting source and destination ports.
	 * Because both TCP and UDP header have these in the same
	 * location, we can check them both using the UDP struct.
	 */
	if (IS_ENABLED(CONFIG_NET_UDP) && proto == IPPROTO_UDP) {
		struct net_udp_hdr hdr, *udp_hdr;

		ARG_UNUSED(hdr);

		udp_hdr = net_udp_get_hdr(pkt, &hdr);
		if (!udp_hdr) {
			return NET_DROP;
		}

		src_port = udp_hdr->src_port;
		dst_port = udp_hdr->dst_port;
		chksum = udp_hdr->chksum;
	} else if (IS_ENABLED(CONFIG_NET_TCP) && proto == IPPROTO_TCP) {
		struct net_tcp_hdr hdr, *tcp_hdr;

		ARG_UNUSED(hdr);

		tcp_hdr = net_tcp_get_hdr(pkt, &hdr);
		if (!tcp_hdr) {
			return NET_DROP;
		}

		src_port = tcp_hdr->src_port;
		dst_port = tcp_hdr->dst_port;
		chksum = tcp_hdr->chksum;
	} else {
		NET_DBG("No UDP or TCP configured, dropping packet.");
		return NET_DROP;
	}

	if (IS_ENABLED(CONFIG_NET_DEBUG_CONN)) {
		int data_len = -1;

		if (IS_ENABLED(CONFIG_NET_IPV4) &&
		    net_pkt_family(pkt) == AF_INET) {
			data_len = NET_IPV4_HDR(pkt)->len[0] * 256 +
				NET_IPV4_HDR(pkt)->len[1];
		} else if (IS_ENABLED(CONFIG_NET_IPV6) &&
			   net_pkt_family(pkt) == AF_INET6) {
			data_len = NET_IPV6_HDR(pkt)->len[0] * 256 +
				NET_IPV6_HDR(pkt)->len[1];
		}

		NET_DBG("Check %s listener for pkt %p src port %u dst port %u "
			"family %d chksum 0x%04x len %d", net_proto2str(proto),
			pkt,
			ntohs(src_port),
			ntohs(dst_port),
			net_pkt_family(pkt), ntohs(chksum), data_len);
	}

	for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
		if (!(conns[i].flags & NET_CONN_IN_USE)) {
			continue;
		}

		if (conns[i].proto != proto) {
			continue;
		}

		if (net_sin(&conns[i].remote_addr)->sin_port) {
			if (net_sin(&conns[i].remote_addr)->sin_port !=
			    src_port) {
				continue;
			}
		}

		if (net_sin(&conns[i].local_addr)->sin_port) {
			if (net_sin(&conns[i].local_addr)->sin_port !=
			    dst_port) {
				continue;
			}
		}

		if (conns[i].flags & NET_CONN_REMOTE_ADDR_SET) {
			if (!check_addr(pkt, &conns[i].remote_addr, true)) {
				continue;
			}
		}

		if (conns[i].flags & NET_CONN_LOCAL_ADDR_SET) {
			if (!check_addr(pkt, &conns[i].local_addr, false)) {
				continue;
			}
		}

		/* If we have an existing best_match, and that one
		 * specifies a remote port, then we've matched to a
		 * LISTENING connection that should not override.
		 */
		if (best_match >= 0 &&
		    net_sin(&conns[best_match].remote_addr)->sin_port) {
			continue;
		}

		if (best_rank < conns[i].rank) {
			best_rank = conns[i].rank;
			best_match = i;
		}
	}

	if (best_match >= 0) {

		/* If packet has a listener configured, then check also the
		 * protocol checksum if that checking is enabled.
		 * If the checksum calculation fails, then discard the message.
		 */
		if (IS_ENABLED(CONFIG_NET_UDP_CHECKSUM) &&
		    proto == IPPROTO_UDP) {
			u16_t chksum_calc;

			net_udp_set_chksum(pkt, pkt->frags);
			chksum_calc = net_udp_get_chksum(pkt, pkt->frags);

			if (chksum != chksum_calc) {
				net_stats_update_udp_chkerr();
				NET_DBG("UDP checksum mismatch "
					"expected 0x%04x got 0x%04x, dropping packet.",
					ntohs(chksum_calc), ntohs(chksum));
				goto drop;
			}

		} else if (IS_ENABLED(CONFIG_NET_TCP_CHECKSUM) &&
			   proto == IPPROTO_TCP) {
			u16_t chksum_calc;

			net_tcp_set_chksum(pkt, pkt->frags);
			chksum_calc = net_tcp_get_chksum(pkt, pkt->frags);

			if (chksum != chksum_calc) {
				net_stats_update_tcp_seg_chkerr();
				NET_DBG("TCP checksum mismatch "
					"expected 0x%04x got 0x%04x, dropping packet.",
					ntohs(chksum_calc), ntohs(chksum));
				goto drop;
			}
		}

#if defined(CONFIG_NET_CONN_CACHE)
		NET_DBG("[%d] match found cb %p ud %p rank 0x%02x cache 0x%x",
			best_match,
			conns[best_match].cb,
			conns[best_match].user_data,
			conns[best_match].rank,
			pos < 0 ? 0 : conn_cache[pos].value);

		if (pos >= 0) {
			conn_cache[pos].idx = best_match;
		}
#else
		NET_DBG("[%d] match found cb %p ud %p rank 0x%02x",
			best_match,
			conns[best_match].cb,
			conns[best_match].user_data,
			conns[best_match].rank);
#endif /* CONFIG_NET_CONN_CACHE */

		if (conns[best_match].cb(&conns[best_match], pkt,
			     conns[best_match].user_data) == NET_DROP) {
			goto drop;
		}

		net_stats_update_per_proto_recv(proto);

		return NET_OK;
	}

	NET_DBG("No match found.");

	cache_add_neg(cache_value);

#if defined(CONFIG_NET_IPV6)
	/* If the destination address is multicast address,
	 * we do not send ICMP error as that makes no sense.
	 */
	if (net_pkt_family(pkt) == AF_INET6 &&
	    net_is_ipv6_addr_mcast(&NET_IPV6_HDR(pkt)->dst)) {
		;
	} else
#endif
#if defined(CONFIG_NET_IPV4)
	if (net_pkt_family(pkt) == AF_INET &&
	    net_is_ipv4_addr_mcast(&NET_IPV4_HDR(pkt)->dst)) {
		;
	} else
#endif
	{
		send_icmp_error(pkt);

		if (IS_ENABLED(CONFIG_NET_TCP) && proto == IPPROTO_TCP) {
			net_stats_update_tcp_seg_connrst();
		}
	}

drop:
	net_stats_update_per_proto_drop(proto);

	return NET_DROP;
}

void net_conn_foreach(net_conn_foreach_cb_t cb, void *user_data)
{
	int i;

	for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
		if (!(conns[i].flags & NET_CONN_IN_USE)) {
			continue;
		}

		cb(&conns[i], user_data);
	}
}

void net_conn_init(void)
{
#if defined(CONFIG_NET_CONN_CACHE)
	do {
		int i;

		for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
			conn_cache[i].idx = -1;
		}
	} while (0);
#endif /* CONFIG_NET_CONN_CACHE */
}
