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

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

/* TODO: Make core part of networking subsystem less dependent on
 * UDP, TCP, IPv4 or IPv6. So that we can add new features with
 * less cross-module changes.
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_conn, CONFIG_NET_CONN_LOG_LEVEL);

#include <errno.h>
#include <zephyr/sys/util.h>

#include <zephyr/net/net_core.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/net/udp.h>
#include <zephyr/net/ethernet.h>
#include <zephyr/net/socketcan.h>

#include "net_private.h"
#include "icmpv6.h"
#include "icmpv4.h"
#include "udp_internal.h"
#include "tcp_internal.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)

/** Local port set */
#define NET_CONN_REMOTE_PORT_SPEC	BIT(3)

/** Remote port set */
#define NET_CONN_LOCAL_PORT_SPEC	BIT(4)

/** Local address specified */
#define NET_CONN_REMOTE_ADDR_SPEC	BIT(5)

/** Remote address specified */
#define NET_CONN_LOCAL_ADDR_SPEC	BIT(6)

#define NET_CONN_RANK(_flags)		(_flags & 0x78)

static struct net_conn conns[CONFIG_NET_MAX_CONN];

static sys_slist_t conn_unused;
static sys_slist_t conn_used;

#if (CONFIG_NET_CONN_LOG_LEVEL >= LOG_LEVEL_DBG)
static inline
void conn_register_debug(struct net_conn *conn,
			 uint16_t remote_port, uint16_t local_port)
{
	char dst[NET_IPV6_ADDR_LEN];
	char src[NET_IPV6_ADDR_LEN];

	if (conn->flags & NET_CONN_REMOTE_ADDR_SET) {
		if (IS_ENABLED(CONFIG_NET_IPV6) &&
		    conn->family == AF_INET6) {
			snprintk(dst, sizeof(dst), "%s",
				 net_sprint_ipv6_addr(&net_sin6(&conn->remote_addr)->sin6_addr));
		} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
			   conn->family == AF_INET) {
			snprintk(dst, sizeof(dst), "%s",
				 net_sprint_ipv4_addr(&net_sin(&conn->remote_addr)->sin_addr));
		} else {
			snprintk(dst, sizeof(dst), "%s", "?");
		}
	} else {
		snprintk(dst, sizeof(dst), "%s", "-");
	}

	if (conn->flags & NET_CONN_LOCAL_ADDR_SET) {
		if (IS_ENABLED(CONFIG_NET_IPV6) &&
		    conn->family == AF_INET6) {
			snprintk(src, sizeof(src), "%s",
				 net_sprint_ipv6_addr(&net_sin6(&conn->local_addr)->sin6_addr));
		} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
			   conn->family == AF_INET) {
			snprintk(src, sizeof(src), "%s",
				 net_sprint_ipv4_addr(&net_sin(&conn->local_addr)->sin_addr));
		} else {
			snprintk(src, sizeof(src), "%s", "?");
		}
	} else {
		snprintk(src, sizeof(src), "%s", "-");
	}

	NET_DBG("[%p/%d/%u/0x%02x] remote %s/%u ",
		conn, conn->proto, conn->family, conn->flags,
		dst, remote_port);
	NET_DBG("  local %s/%u cb %p ud %p",
		src, local_port, conn->cb, conn->user_data);
}
#else
#define conn_register_debug(...)
#endif /* (CONFIG_NET_CONN_LOG_LEVEL >= LOG_LEVEL_DBG) */

static K_MUTEX_DEFINE(conn_lock);

static struct net_conn *conn_get_unused(void)
{
	sys_snode_t *node;

	k_mutex_lock(&conn_lock, K_FOREVER);

	node = sys_slist_peek_head(&conn_unused);
	if (!node) {
		k_mutex_unlock(&conn_lock);
		return NULL;
	}

	sys_slist_remove(&conn_unused, NULL, node);

	k_mutex_unlock(&conn_lock);

	return CONTAINER_OF(node, struct net_conn, node);
}

static void conn_set_used(struct net_conn *conn)
{
	conn->flags |= NET_CONN_IN_USE;

	k_mutex_lock(&conn_lock, K_FOREVER);
	sys_slist_prepend(&conn_used, &conn->node);
	k_mutex_unlock(&conn_lock);
}

static void conn_set_unused(struct net_conn *conn)
{
	(void)memset(conn, 0, sizeof(*conn));

	k_mutex_lock(&conn_lock, K_FOREVER);
	sys_slist_prepend(&conn_unused, &conn->node);
	k_mutex_unlock(&conn_lock);
}

/* Check if we already have identical connection handler installed. */
static struct net_conn *conn_find_handler(struct net_if *iface,
					  uint16_t proto, uint8_t family,
					  const struct sockaddr *remote_addr,
					  const struct sockaddr *local_addr,
					  uint16_t remote_port,
					  uint16_t local_port,
					  bool reuseport_set)
{
	struct net_conn *conn;
	struct net_conn *tmp;

	k_mutex_lock(&conn_lock, K_FOREVER);

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&conn_used, conn, tmp, node) {
		if (conn->proto != proto) {
			continue;
		}

		if (conn->family != family) {
			continue;
		}

		if (local_addr) {
			if (!(conn->flags & NET_CONN_LOCAL_ADDR_SET)) {
				continue;
			}

			if (IS_ENABLED(CONFIG_NET_IPV6) &&
			    local_addr->sa_family == AF_INET6 &&
			    local_addr->sa_family ==
			    conn->local_addr.sa_family) {
				if (!net_ipv6_addr_cmp(
					    &net_sin6(local_addr)->sin6_addr,
					    &net_sin6(&conn->local_addr)->
								sin6_addr)) {
					continue;
				}
			} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
				   local_addr->sa_family == AF_INET &&
				   local_addr->sa_family ==
				   conn->local_addr.sa_family) {
				if (!net_ipv4_addr_cmp(
					    &net_sin(local_addr)->sin_addr,
					    &net_sin(&conn->local_addr)->
								sin_addr)) {
					continue;
				}
			} else {
				continue;
			}
		} else if (conn->flags & NET_CONN_LOCAL_ADDR_SET) {
			continue;
		}

		if (net_sin(&conn->local_addr)->sin_port !=
		    htons(local_port)) {
			continue;
		}

		if (remote_addr) {
			if (!(conn->flags & NET_CONN_REMOTE_ADDR_SET)) {
				continue;
			}

			if (IS_ENABLED(CONFIG_NET_IPV6) &&
			    remote_addr->sa_family == AF_INET6 &&
			    remote_addr->sa_family ==
			    conn->remote_addr.sa_family) {
				if (!net_ipv6_addr_cmp(
					    &net_sin6(remote_addr)->sin6_addr,
					    &net_sin6(&conn->remote_addr)->
								sin6_addr)) {
					continue;
				}
			} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
				   remote_addr->sa_family == AF_INET &&
				   remote_addr->sa_family ==
				   conn->remote_addr.sa_family) {
				if (!net_ipv4_addr_cmp(
					    &net_sin(remote_addr)->sin_addr,
					    &net_sin(&conn->remote_addr)->
								sin_addr)) {
					continue;
				}
			} else {
				continue;
			}
		} else if (conn->flags & NET_CONN_REMOTE_ADDR_SET) {
			continue;
		} else if (reuseport_set && conn->context != NULL &&
			   net_context_is_reuseport_set(conn->context)) {
			continue;
		}

		if (net_sin(&conn->remote_addr)->sin_port !=
		    htons(remote_port)) {
			continue;
		}

		if (conn->context != NULL && iface != NULL &&
		    net_context_is_bound_to_iface(conn->context)) {
			if (iface != net_context_get_iface(conn->context)) {
				continue;
			}
		}

		k_mutex_unlock(&conn_lock);
		return conn;
	}

	k_mutex_unlock(&conn_lock);
	return NULL;
}

static void net_conn_change_callback(struct net_conn *conn,
				     net_conn_cb_t cb, void *user_data)
{
	NET_DBG("[%zu] connection handler %p changed callback",
		conn - conns, conn);

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

static int net_conn_change_remote(struct net_conn *conn,
				  const struct sockaddr *remote_addr,
				  uint16_t remote_port)
{
	NET_DBG("[%zu] connection handler %p changed remote",
		conn - conns, conn);

	if (remote_addr) {
		if (IS_ENABLED(CONFIG_NET_IPV6) &&
		    remote_addr->sa_family == AF_INET6) {
			memcpy(&conn->remote_addr, remote_addr,
			       sizeof(struct sockaddr_in6));

			if (!net_ipv6_is_addr_unspecified(
				    &net_sin6(remote_addr)->
				    sin6_addr)) {
				conn->flags |= NET_CONN_REMOTE_ADDR_SPEC;
			}
		} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
			   remote_addr->sa_family == AF_INET) {
			memcpy(&conn->remote_addr, remote_addr,
			       sizeof(struct sockaddr_in));

			if (net_sin(remote_addr)->sin_addr.s_addr) {
				conn->flags |= NET_CONN_REMOTE_ADDR_SPEC;
			}
		} else {
			NET_ERR("Remote address family not set");
			return -EINVAL;
		}

		conn->flags |= NET_CONN_REMOTE_ADDR_SET;
	} else {
		conn->flags &= ~NET_CONN_REMOTE_ADDR_SPEC;
		conn->flags &= ~NET_CONN_REMOTE_ADDR_SET;
	}

	if (remote_port) {
		conn->flags |= NET_CONN_REMOTE_PORT_SPEC;
		net_sin(&conn->remote_addr)->sin_port = htons(remote_port);
	} else {
		conn->flags &= ~NET_CONN_REMOTE_PORT_SPEC;
	}

	return 0;
}

static int net_conn_change_local(struct net_conn *conn,
				 const struct sockaddr *local_addr,
				 uint16_t local_port)
{
	NET_DBG("[%zu] connection handler %p changed local",
		conn - conns, conn);

	if (local_addr != NULL) {
		if (IS_ENABLED(CONFIG_NET_IPV6) &&
		    local_addr->sa_family == AF_INET6) {
			memcpy(&conn->local_addr, local_addr,
			       sizeof(struct sockaddr_in6));

			if (!net_ipv6_is_addr_unspecified(
					&net_sin6(local_addr)->sin6_addr)) {
				conn->flags |= NET_CONN_LOCAL_ADDR_SPEC;
			}
		} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
			   local_addr->sa_family == AF_INET) {
			memcpy(&conn->local_addr, local_addr,
			       sizeof(struct sockaddr_in));

			if (net_sin(local_addr)->sin_addr.s_addr) {
				conn->flags |= NET_CONN_LOCAL_ADDR_SPEC;
			}
		} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) &&
			   local_addr->sa_family == AF_CAN) {
			memcpy(&conn->local_addr, local_addr,
			       sizeof(struct sockaddr_can));
		} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
			   local_addr->sa_family == AF_PACKET) {
			memcpy(&conn->local_addr, local_addr,
			       sizeof(struct sockaddr_ll));
		} else {
			NET_ERR("Local address family not set");
			return -EINVAL;
		}

		conn->flags |= NET_CONN_LOCAL_ADDR_SET;
	} else {
		conn->flags &= ~NET_CONN_LOCAL_ADDR_SPEC;
		conn->flags &= ~NET_CONN_LOCAL_ADDR_SET;
	}

	if (local_port > 0U) {
		conn->flags |= NET_CONN_LOCAL_PORT_SPEC;
		net_sin(&conn->local_addr)->sin_port = htons(local_port);
	} else {
		conn->flags &= ~NET_CONN_LOCAL_PORT_SPEC;
	}

	return 0;
}

int net_conn_register(uint16_t proto, enum net_sock_type type, uint8_t family,
		      const struct sockaddr *remote_addr,
		      const struct sockaddr *local_addr,
		      uint16_t remote_port,
		      uint16_t local_port,
		      struct net_context *context,
		      net_conn_cb_t cb,
		      void *user_data,
		      struct net_conn_handle **handle)
{
	struct net_conn *conn;
	int ret;

	conn = conn_find_handler(context != NULL ? net_context_get_iface(context) : NULL,
				 proto, family, remote_addr, local_addr,
				 remote_port, local_port,
				 context != NULL ?
					net_context_is_reuseport_set(context) :
					false);
	if (conn != NULL) {
		NET_ERR("Identical connection handler %p already found.", conn);
		return -EADDRINUSE;
	}

	conn = conn_get_unused();
	if (conn == NULL) {
		NET_ERR("Not enough connection contexts. "
			"Consider increasing CONFIG_NET_MAX_CONN.");
		return -ENOENT;
	}

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

	net_conn_change_callback(conn, cb, user_data);

	conn->proto = proto;
	conn->type = type;
	conn->family = family;
	conn->context = context;

	ret = net_conn_change_local(conn, local_addr, local_port);
	if (ret < 0) {
		goto error;
	}

	ret = net_conn_change_remote(conn, remote_addr, remote_port);
	if (ret < 0) {
		goto error;
	}

	if (handle) {
		*handle = (struct net_conn_handle *)conn;
	}

	conn_set_used(conn);

	conn->v6only = net_context_is_v6only_set(context);

	conn_register_debug(conn, remote_port, local_port);

	return 0;
error:
	conn_set_unused(conn);
	return -EINVAL;
}

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;
	}

	NET_DBG("Connection handler %p removed", conn);

	k_mutex_lock(&conn_lock, K_FOREVER);
	sys_slist_find_and_remove(&conn_used, &conn->node);
	k_mutex_unlock(&conn_lock);

	conn_set_unused(conn);

	return 0;
}

int net_conn_update(struct net_conn_handle *handle,
		    net_conn_cb_t cb,
		    void *user_data,
		    const struct sockaddr *remote_addr,
		    uint16_t remote_port,
		    const struct sockaddr *local_addr,
		    uint16_t local_port)
{
	struct net_conn *conn = (struct net_conn *)handle;
	int ret;

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

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

	net_conn_change_callback(conn, cb, user_data);

	ret = net_conn_change_local(conn, local_addr, local_port);
	if (ret < 0) {
		return ret;
	}

	ret = net_conn_change_remote(conn, remote_addr, remote_port);

	return ret;
}

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

	if (IS_ENABLED(CONFIG_NET_IPV6) &&
	    net_pkt_family(pkt) == AF_INET6 &&
	    addr->sa_family == AF_INET6) {
		uint8_t *addr6;

		if (is_remote) {
			addr6 = ip_hdr->ipv6->src;
		} else {
			addr6 = ip_hdr->ipv6->dst;
		}

		if (!net_ipv6_is_addr_unspecified(
			    &net_sin6(addr)->sin6_addr)) {
			if (!net_ipv6_addr_cmp_raw((uint8_t *)&net_sin6(addr)->sin6_addr,
						   addr6)) {
				return false;
			}
		}

		return true;
	} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
		   net_pkt_family(pkt) == AF_INET &&
		   addr->sa_family == AF_INET) {
		uint8_t *addr4;

		if (is_remote) {
			addr4 = ip_hdr->ipv4->src;
		} else {
			addr4 = ip_hdr->ipv4->dst;
		}

		if (net_sin(addr)->sin_addr.s_addr) {
			if (!net_ipv4_addr_cmp_raw((uint8_t *)&net_sin(addr)->sin_addr,
						   addr4)) {
				return false;
			}
		}
	}

	return true;
}

static inline void conn_send_icmp_error(struct net_pkt *pkt)
{
	if (IS_ENABLED(CONFIG_NET_DISABLE_ICMP_DESTINATION_UNREACHABLE)) {
		return;
	}

	if (IS_ENABLED(CONFIG_NET_IPV6) && net_pkt_family(pkt) == AF_INET6) {
		net_icmpv6_send_error(pkt, NET_ICMPV6_DST_UNREACH,
				      NET_ICMPV6_DST_UNREACH_NO_PORT, 0);

	} else if (IS_ENABLED(CONFIG_NET_IPV4)) {
		net_icmpv4_send_error(pkt, NET_ICMPV4_DST_UNREACH,
				      NET_ICMPV4_DST_UNREACH_NO_PORT);
	}
}

static bool conn_are_endpoints_valid(struct net_pkt *pkt, uint8_t family,
				     union net_ip_header *ip_hdr,
				     uint16_t src_port, uint16_t dst_port)
{
	bool is_my_src_addr;
	bool is_same_src_and_dst_addr;

	if (IS_ENABLED(CONFIG_NET_IPV4) && family == AF_INET) {
		is_my_src_addr = net_ipv4_is_my_addr(
			(struct in_addr *)ip_hdr->ipv4->src);
		is_same_src_and_dst_addr = net_ipv4_addr_cmp_raw(
			ip_hdr->ipv4->src, ip_hdr->ipv4->dst);
	} else if (IS_ENABLED(CONFIG_NET_IPV6) && family == AF_INET6) {
		is_my_src_addr = net_ipv6_is_my_addr(
			(struct in6_addr *)ip_hdr->ipv6->src);
		is_same_src_and_dst_addr = net_ipv6_addr_cmp_raw(
			ip_hdr->ipv6->src, ip_hdr->ipv6->dst);
	} else {
		return true;
	}

	bool is_same_src_and_dst_port = src_port == dst_port;
	bool are_invalid_endpoints =
		(is_same_src_and_dst_addr || is_my_src_addr) && is_same_src_and_dst_port;

	return !are_invalid_endpoints;
}

/* Is the candidate connection matching the packet's interface? */
static bool is_iface_matching(struct net_conn *conn, struct net_pkt *pkt)
{
	if (conn->context == NULL) {
		return true;
	}

	if (!net_context_is_bound_to_iface(conn->context)) {
		return true;
	}

	return (net_pkt_iface(pkt) == net_context_get_iface(conn->context));
}

#if defined(CONFIG_NET_SOCKETS_PACKET) || defined(CONFIG_NET_SOCKETS_INET_RAW)
static void conn_raw_socket_deliver(struct net_pkt *pkt, struct net_conn *conn,
				    bool is_ip)
{
	struct net_pkt *raw_pkt;
	struct net_pkt_cursor cur;

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

	NET_DBG("[%p] raw%s match found cb %p ud %p", conn, is_ip ? " IP" : "",
		conn->cb, conn->user_data);

	raw_pkt = net_pkt_clone(pkt, K_MSEC(CONFIG_NET_CONN_PACKET_CLONE_TIMEOUT));
	if (raw_pkt == NULL) {
		NET_WARN("pkt cloning failed, pkt %p not delivered", pkt);
		goto out;
	}

	if (conn->cb(conn, raw_pkt, NULL, NULL, conn->user_data) == NET_DROP) {
		net_pkt_unref(raw_pkt);
	}

out:
	net_pkt_cursor_restore(pkt, &cur);
}
#endif /* defined(CONFIG_NET_SOCKETS_PACKET) || defined(CONFIG_NET_SOCKETS_INET_RAW) */

#if defined(CONFIG_NET_SOCKETS_PACKET)
enum net_verdict net_conn_packet_input(struct net_pkt *pkt, uint16_t proto)
{
	bool raw_sock_found = false;
	bool raw_pkt_continue = false;
	struct sockaddr_ll *local;
	struct net_conn *conn;

	/* Only accept input with AF_PACKET family. */
	if (net_pkt_family(pkt) != AF_PACKET) {
		return NET_CONTINUE;
	}

	NET_DBG("Check proto 0x%04x listener for pkt %p family %d",
		proto, pkt, net_pkt_family(pkt));

	k_mutex_lock(&conn_lock, K_FOREVER);

	SYS_SLIST_FOR_EACH_CONTAINER(&conn_used, conn, node) {
		if (!is_iface_matching(conn, pkt)) {
			continue; /* wrong interface */
		}

		/* If there are other listening connections than
		 * AF_PACKET, the packet shall be also passed back to
		 * net_conn_input() in upper layer processing in order to
		 * re-check if there is any listening socket interested
		 * in this packet.
		 */
		if (conn->family != AF_PACKET) {
			raw_pkt_continue = true;
			continue; /* wrong family */
		}

		if (conn->type == SOCK_DGRAM && !net_pkt_is_l2_processed(pkt)) {
			/* If DGRAM packet sockets are present, we shall continue
			 * with this packet regardless the result.
			 */
			raw_pkt_continue = true;
			continue; /* L2 not processed yet */
		}

		if (conn->type == SOCK_RAW && net_pkt_is_l2_processed(pkt)) {
			continue; /* L2 already processed */
		}

		if (conn->proto == 0) {
			continue; /* Local proto 0 doesn't forward any packets */
		}

		if (conn->proto != proto) {
			/* Allow proto mismatch if socket was created with ETH_P_ALL, or it's raw
			 * packet socket input (proto ETH_P_ALL).
			 */
			if (conn->proto != ETH_P_ALL && proto != ETH_P_ALL) {
				continue; /* wrong protocol */
			}
		}

		/* Apply protocol-specific matching criteria... */

		/* Unbound sockets should collect packets from all interfaces. */
		if ((conn->flags & NET_CONN_LOCAL_ADDR_SET) != 0U) {
			local = (struct sockaddr_ll *)&conn->local_addr;
			if (local->sll_ifindex != 0 &&
			    local->sll_ifindex != net_if_get_by_iface(net_pkt_iface(pkt))) {
				continue;
			}
		}

		conn_raw_socket_deliver(pkt, conn, false);

		raw_sock_found = true;
	}

	k_mutex_unlock(&conn_lock);

	if (!raw_pkt_continue && raw_sock_found) {
		/* As one or more raw socket packets have already been delivered
		 * in the loop above, report NET_OK.
		 */
		net_pkt_unref(pkt);
		return NET_OK;
	}

	/* When there is open connection different than AF_PACKET this
	 * packet shall be also handled in the upper net stack layers.
	 */
	return NET_CONTINUE;
}
#else
enum net_verdict net_conn_packet_input(struct net_pkt *pkt, uint16_t proto)
{
	ARG_UNUSED(pkt);
	ARG_UNUSED(proto);

	return NET_CONTINUE;
}
#endif /* defined(CONFIG_NET_SOCKETS_PACKET) */

#if defined(CONFIG_NET_SOCKETS_INET_RAW)
enum net_verdict net_conn_raw_ip_input(struct net_pkt *pkt,
				       union net_ip_header *ip_hdr,
				       uint8_t proto)
{
	uint8_t pkt_family = net_pkt_family(pkt);
	struct net_conn *conn;

	if (pkt_family != AF_INET && pkt_family != AF_INET6) {
		return NET_CONTINUE;
	}

	NET_DBG("Check %s listener for pkt %p family %d",
		net_proto2str(net_pkt_family(pkt), proto), pkt,
		net_pkt_family(pkt));

	k_mutex_lock(&conn_lock, K_FOREVER);

	SYS_SLIST_FOR_EACH_CONTAINER(&conn_used, conn, node) {
		if (!is_iface_matching(conn, pkt)) {
			continue; /* wrong interface */
		}

		if (conn->family != pkt_family) {
			continue; /* wrong family */
		}

		if (conn->type != SOCK_RAW) {
			continue; /* wrong type */
		}

		if (conn->proto != proto && conn->proto != IPPROTO_IP) {
			continue; /* wrong protocol */
		}

		/* Apply protocol-specific matching criteria... */

		if (((conn->flags & NET_CONN_LOCAL_ADDR_SET) != 0U) &&
		    !conn_addr_cmp(pkt, ip_hdr, &conn->local_addr, false)) {
			continue; /* wrong local address */
		}

		conn_raw_socket_deliver(pkt, conn, true);
	}

	k_mutex_unlock(&conn_lock);

	/* Raw IP packets are passed further in the stack regardless. */
	return NET_CONTINUE;
}
#else
enum net_verdict net_conn_raw_ip_input(struct net_pkt *pkt,
				       union net_ip_header *ip_hdr,
				       uint8_t proto)
{
	ARG_UNUSED(pkt);
	ARG_UNUSED(ip_hdr);
	ARG_UNUSED(proto);

	return NET_CONTINUE;
}
#endif /* defined(CONFIG_NET_SOCKETS_INET_RAW) */

#if defined(CONFIG_NET_SOCKETS_CAN)
enum net_verdict net_conn_can_input(struct net_pkt *pkt, uint8_t proto)
{
	struct net_conn *best_match = NULL;
	struct net_conn *conn;
	net_conn_cb_t cb = NULL;
	void *user_data = NULL;

	/* Only accept input with AF_CAN family and CAN_RAW protocol. */
	if (net_pkt_family(pkt) != AF_CAN || proto != CAN_RAW) {
		return NET_DROP;
	}

	NET_DBG("Check %s listener for pkt %p family %d",
		net_proto2str(net_pkt_family(pkt), proto), pkt,
		net_pkt_family(pkt));

	k_mutex_lock(&conn_lock, K_FOREVER);

	SYS_SLIST_FOR_EACH_CONTAINER(&conn_used, conn, node) {
		if (!is_iface_matching(conn, pkt)) {
			continue; /* wrong interface */
		}

		if (conn->family != AF_CAN) {
			continue; /* wrong family */
		}

		if (conn->proto != CAN_RAW) {
			continue; /* wrong protocol */
		}

		best_match = conn;
	}

	if (best_match != NULL) {
		cb = best_match->cb;
		user_data = best_match->user_data;
	}

	k_mutex_unlock(&conn_lock);

	if (cb != NULL) {
		NET_DBG("[%p] match found cb %p ud %p rank 0x%02x", best_match, cb,
			user_data, NET_CONN_RANK(best_match->flags));

		if (cb(best_match, pkt, NULL, NULL, user_data) == NET_DROP) {
			goto drop;
		}

		net_stats_update_per_proto_recv(net_pkt_iface(pkt), proto);

		return NET_OK;
	}

	NET_DBG("No match found.");

drop:
	net_stats_update_per_proto_drop(net_pkt_iface(pkt), proto);

	return NET_DROP;
}
#else
enum net_verdict net_conn_can_input(struct net_pkt *pkt, uint8_t proto)
{
	ARG_UNUSED(pkt);
	ARG_UNUSED(proto);

	return NET_DROP;
}
#endif /* defined(CONFIG_NET_SOCKETS_CAN) */

enum net_verdict net_conn_input(struct net_pkt *pkt,
				union net_ip_header *ip_hdr,
				uint8_t proto,
				union net_proto_header *proto_hdr)
{
	struct net_if *pkt_iface = net_pkt_iface(pkt);
	uint8_t pkt_family = net_pkt_family(pkt);
	uint16_t src_port = 0U, dst_port = 0U;

	if (!net_pkt_filter_local_in_recv_ok(pkt)) {
		/* drop the packet */
		net_stats_update_filter_rx_local_drop(net_pkt_iface(pkt));
		return NET_DROP;
	}

	if (pkt_family == AF_INET || pkt_family == AF_INET6) {
		if (IS_ENABLED(CONFIG_NET_UDP) && proto == IPPROTO_UDP) {
			src_port = proto_hdr->udp->src_port;
			dst_port = proto_hdr->udp->dst_port;
		} else if (IS_ENABLED(CONFIG_NET_TCP) && proto == IPPROTO_TCP) {
			if (proto_hdr->tcp == NULL) {
				return NET_DROP;
			}
			src_port = proto_hdr->tcp->src_port;
			dst_port = proto_hdr->tcp->dst_port;
		}
		if (!conn_are_endpoints_valid(pkt, pkt_family, ip_hdr,
					      src_port, dst_port)) {
			NET_DBG("Dropping invalid src/dst end-points packet");
			return NET_DROP;
		}
	} else {
		NET_DBG("No suitable protocol handler configured");
		return NET_DROP;
	}

	NET_DBG("Check %s listener for pkt %p src port %u dst port %u"
		" family %d", net_proto2str(net_pkt_family(pkt), proto), pkt,
		ntohs(src_port), ntohs(dst_port), net_pkt_family(pkt));

	struct net_conn *best_match = NULL;
	int16_t best_rank = -1;
	bool is_mcast_pkt = false;
	bool mcast_pkt_delivered = false;
	bool is_bcast_pkt = false;
	struct net_conn *conn;
	net_conn_cb_t cb = NULL;
	void *user_data = NULL;

	/* If we receive a packet with multicast destination address, we might
	 * need to deliver the packet to multiple recipients.
	 */
	if (IS_ENABLED(CONFIG_NET_IPV4) && pkt_family == AF_INET) {
		if (net_ipv4_is_addr_mcast((struct in_addr *)ip_hdr->ipv4->dst)) {
			is_mcast_pkt = true;
		} else if (net_if_ipv4_is_addr_bcast(pkt_iface,
						     (struct in_addr *)ip_hdr->ipv4->dst)) {
			is_bcast_pkt = true;
		}
	} else if (IS_ENABLED(CONFIG_NET_IPV6) && pkt_family == AF_INET6) {
		is_mcast_pkt = net_ipv6_is_addr_mcast((struct in6_addr *)ip_hdr->ipv6->dst);
	}

	k_mutex_lock(&conn_lock, K_FOREVER);

	SYS_SLIST_FOR_EACH_CONTAINER(&conn_used, conn, node) {
		/* Is the candidate connection matching the packet's interface? */
		if (!is_iface_matching(conn, pkt)) {
			continue; /* wrong interface */
		}

		/* Is the candidate connection matching the packet's protocol family? */
		if (conn->family != AF_UNSPEC && conn->family != pkt_family) {
			if (IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6)) {
				if (!(conn->family == AF_INET6 && pkt_family == AF_INET &&
				      !conn->v6only && conn->type != SOCK_RAW)) {
					continue;
				}
			} else {
				continue; /* wrong protocol family */
			}

			/* We might have a match for v4-to-v6 mapping, check more */
		}

		/* Is the candidate connection matching the packet's protocol within the family? */
		if (conn->proto != proto) {
			continue; /* wrong protocol */
		}

		/* Apply protocol-specific matching criteria... */
		uint8_t conn_family = conn->family;

		if ((IS_ENABLED(CONFIG_NET_UDP) || IS_ENABLED(CONFIG_NET_TCP)) &&
		    (conn_family == AF_INET || conn_family == AF_INET6 ||
		     conn_family == AF_UNSPEC)) {
			/* Is the candidate connection matching the packet's TCP/UDP
			 * address and port?
			 */
			if (net_sin(&conn->remote_addr)->sin_port &&
			    net_sin(&conn->remote_addr)->sin_port != src_port) {
				continue; /* wrong remote port */
			}

			if (net_sin(&conn->local_addr)->sin_port &&
			    net_sin(&conn->local_addr)->sin_port != dst_port) {
				continue; /* wrong local port */
			}

			if ((conn->flags & NET_CONN_REMOTE_ADDR_SET) &&
			    !conn_addr_cmp(pkt, ip_hdr, &conn->remote_addr, true)) {
				continue; /* wrong remote address */
			}

			if ((conn->flags & NET_CONN_LOCAL_ADDR_SET) &&
			    !conn_addr_cmp(pkt, ip_hdr, &conn->local_addr, false)) {

				/* Check if we could do a v4-mapping-to-v6 and the IPv6 socket
				 * has no IPV6_V6ONLY option set and if the local IPV6 address
				 * is unspecified, then we could accept a connection from IPv4
				 * address by mapping it to IPv6 address.
				 */
				if (IS_ENABLED(CONFIG_NET_IPV4_MAPPING_TO_IPV6)) {
					if (!(conn->family == AF_INET6 && pkt_family == AF_INET &&
					      !conn->v6only &&
					      net_ipv6_is_addr_unspecified(
						      &net_sin6(&conn->local_addr)->sin6_addr))) {
						continue; /* wrong local address */
					}
				} else {
					continue; /* wrong local address */
				}

				/* We might have a match for v4-to-v6 mapping,
				 * continue with rank checking.
				 */
			}

			if (best_rank < NET_CONN_RANK(conn->flags)) {
				struct net_pkt *mcast_pkt;

				if (!is_mcast_pkt) {
					best_rank = NET_CONN_RANK(conn->flags);
					best_match = conn;

					continue; /* found a match - but maybe not yet the best */
				}

				/* If we have a multicast packet, and we found
				 * a match, then deliver the packet immediately
				 * to the handler. As there might be several
				 * sockets interested about these, we need to
				 * clone the received pkt.
				 */

				NET_DBG("[%p] mcast match found cb %p ud %p", conn, conn->cb,
					conn->user_data);

				mcast_pkt = net_pkt_clone(
					pkt, K_MSEC(CONFIG_NET_CONN_PACKET_CLONE_TIMEOUT));
				if (!mcast_pkt) {
					k_mutex_unlock(&conn_lock);
					goto drop;
				}

				if (conn->cb(conn, mcast_pkt, ip_hdr, proto_hdr, conn->user_data) ==
				    NET_DROP) {
					net_stats_update_per_proto_drop(pkt_iface, proto);
					net_pkt_unref(mcast_pkt);
				} else {
					net_stats_update_per_proto_recv(pkt_iface, proto);
				}

				mcast_pkt_delivered = true;
			}
		}
	} /* loop end */

	if (best_match != NULL) {
		cb = best_match->cb;
		user_data = best_match->user_data;
	}

	k_mutex_unlock(&conn_lock);

	if (is_mcast_pkt && mcast_pkt_delivered) {
		/* As one or more multicast packets
		 * have already been delivered in the loop above,
		 * we shall not call the callback again here.
		 */
		net_pkt_unref(pkt);
		return NET_OK;
	}

	if (cb != NULL) {
		NET_DBG("[%p] match found cb %p ud %p rank 0x%02x", best_match, cb,
			user_data, NET_CONN_RANK(best_match->flags));

		if (cb(best_match, pkt, ip_hdr, proto_hdr, user_data)
				== NET_DROP) {
			goto drop;
		}

		net_stats_update_per_proto_recv(pkt_iface, proto);

		return NET_OK;
	}

	NET_DBG("No match found.");

	if ((pkt_family == AF_INET || pkt_family == AF_INET6) &&
	    !(is_mcast_pkt || is_bcast_pkt)) {
		if (IS_ENABLED(CONFIG_NET_TCP) && proto == IPPROTO_TCP &&
		    IS_ENABLED(CONFIG_NET_TCP_REJECT_CONN_WITH_RST)) {
			net_tcp_reply_rst(pkt);
			net_stats_update_tcp_seg_connrst(pkt_iface);
		} else {
			conn_send_icmp_error(pkt);
		}
	}

drop:
	net_stats_update_per_proto_drop(pkt_iface, proto);

	return NET_DROP;
}

void net_conn_foreach(net_conn_foreach_cb_t cb, void *user_data)
{
	struct net_conn *conn;

	k_mutex_lock(&conn_lock, K_FOREVER);

	SYS_SLIST_FOR_EACH_CONTAINER(&conn_used, conn, node) {
		cb(conn, user_data);
	}

	k_mutex_unlock(&conn_lock);
}

void net_conn_init(void)
{
	int i;

	sys_slist_init(&conn_unused);
	sys_slist_init(&conn_used);

	for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
		sys_slist_prepend(&conn_unused, &conns[i].node);
	}
}
