/** @file
 * @brief DHCPv4 client related functions
 */

/*
 * Copyright (c) 2017 ARM Ltd.
 * Copyright (c) 2016 Intel Corporation
 * Copyright (c) 2018 Vincent van der Locht
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_dhcpv4, CONFIG_NET_DHCPV4_LOG_LEVEL);

#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <zephyr/random/rand32.h>
#include <zephyr/net/net_core.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_mgmt.h>
#include "net_private.h"

#include <zephyr/net/udp.h>
#include "udp_internal.h"
#include <zephyr/net/dhcpv4.h>
#include <zephyr/net/dns_resolve.h>

#include "dhcpv4.h"
#include "ipv4.h"
#include "net_stats.h"

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

#define PKT_WAIT_TIME K_SECONDS(1)

static K_MUTEX_DEFINE(lock);

static sys_slist_t dhcpv4_ifaces;
static struct k_work_delayable timeout_work;

static struct net_mgmt_event_callback mgmt4_cb;

#if defined(CONFIG_NET_DHCPV4_OPTION_CALLBACKS)
static sys_slist_t option_callbacks;
#endif

/* RFC 1497 [17] */
static const uint8_t magic_cookie[4] = { 0x63, 0x82, 0x53, 0x63 };

/* Add magic cookie to DCHPv4 messages */
static inline bool dhcpv4_add_cookie(struct net_pkt *pkt)
{
	if (net_pkt_write(pkt, (void *)magic_cookie,
			  ARRAY_SIZE(magic_cookie))) {
		return false;
	}

	return true;
}

/* Add a an option with the form OPTION LENGTH VALUE.  */
static bool dhcpv4_add_option_length_value(struct net_pkt *pkt, uint8_t option,
					   uint8_t size, const void *value)
{
	if (net_pkt_write_u8(pkt, option) ||
	    net_pkt_write_u8(pkt, size) ||
	    net_pkt_write(pkt, value, size)) {
		return false;
	}

	return true;
}

/* Add DHCPv4 message type */
static bool dhcpv4_add_msg_type(struct net_pkt *pkt, uint8_t type)
{
	return dhcpv4_add_option_length_value(pkt, DHCPV4_OPTIONS_MSG_TYPE,
					      1, &type);
}

/* Add DHCPv4 minimum required options for server to reply.
 * Can be added more if needed.
 */
static bool dhcpv4_add_req_options(struct net_pkt *pkt)
{
	static uint8_t data[3] = { DHCPV4_OPTIONS_SUBNET_MASK,
				DHCPV4_OPTIONS_ROUTER,
				DHCPV4_OPTIONS_DNS_SERVER };

	return dhcpv4_add_option_length_value(pkt, DHCPV4_OPTIONS_REQ_LIST,
					      ARRAY_SIZE(data), data);
}

static bool dhcpv4_add_server_id(struct net_pkt *pkt,
				 const struct in_addr *addr)
{
	return dhcpv4_add_option_length_value(pkt, DHCPV4_OPTIONS_SERVER_ID,
					      4, addr->s4_addr);
}

static bool dhcpv4_add_req_ipaddr(struct net_pkt *pkt,
				  const struct in_addr *addr)
{
	return dhcpv4_add_option_length_value(pkt, DHCPV4_OPTIONS_REQ_IPADDR,
					      4, addr->s4_addr);
}

#if defined(CONFIG_NET_HOSTNAME_ENABLE)
static bool dhcpv4_add_hostname(struct net_pkt *pkt,
				 const char *hostname, const size_t size)
{
	return dhcpv4_add_option_length_value(pkt, DHCPV4_OPTIONS_HOST_NAME,
					      size, hostname);
}
#endif

/* Add DHCPv4 Options end, rest of the message can be padded wit zeros */
static inline bool dhcpv4_add_end(struct net_pkt *pkt)
{
	if (net_pkt_write_u8(pkt, DHCPV4_OPTIONS_END)) {
		return false;
	}

	return true;
}

/* File is empty ATM */
static inline bool dhcpv4_add_file(struct net_pkt *pkt)
{
	if (net_pkt_memset(pkt, 0, SIZE_OF_FILE)) {
		return false;
	}

	return true;
}

/* SNAME is empty ATM */
static inline bool dhcpv4_add_sname(struct net_pkt *pkt)
{
	if (net_pkt_memset(pkt, 0, SIZE_OF_SNAME)) {
		return false;
	}

	return true;
}

/* Create DHCPv4 message and add options as per message type */
static struct net_pkt *dhcpv4_create_message(struct net_if *iface, uint8_t type,
					     const struct in_addr *ciaddr,
					     const struct in_addr *src_addr,
					     const struct in_addr *server_addr,
					     bool server_id, bool requested_ip)
{
	NET_PKT_DATA_ACCESS_DEFINE(dhcp_access, struct dhcp_msg);
	const struct in_addr *addr;
	size_t size = DHCPV4_MESSAGE_SIZE;
	struct net_pkt *pkt;
	struct dhcp_msg *msg;
#if defined(CONFIG_NET_HOSTNAME_ENABLE)
	const char *hostname = net_hostname_get();
	const size_t hostname_size = strlen(hostname);
#endif

	if (src_addr == NULL) {
		addr = net_ipv4_unspecified_address();
	} else {
		addr = src_addr;
	}

	if (server_id) {
		size += DHCPV4_OLV_MSG_SERVER_ID;
	}

	if (requested_ip) {
		size +=  DHCPV4_OLV_MSG_REQ_IPADDR;
	}

	if (type == NET_DHCPV4_MSG_TYPE_DISCOVER) {
		size +=  DHCPV4_OLV_MSG_REQ_LIST;
	}

#if defined(CONFIG_NET_HOSTNAME_ENABLE)
	if (hostname_size > 0) {
		size += DHCPV4_OLV_MSG_HOST_NAME + hostname_size;
	}
#endif

	pkt = net_pkt_alloc_with_buffer(iface, size, AF_INET,
					IPPROTO_UDP, K_FOREVER);
	if (!pkt) {
		return NULL;
	}

	net_pkt_set_ipv4_ttl(pkt, 0xFF);

	if (net_ipv4_create(pkt, addr, server_addr) ||
	    net_udp_create(pkt, htons(DHCPV4_CLIENT_PORT),
			   htons(DHCPV4_SERVER_PORT))) {
		goto fail;
	}

	msg = (struct dhcp_msg *)net_pkt_get_data(pkt, &dhcp_access);

	(void)memset(msg, 0, sizeof(struct dhcp_msg));

	msg->op    = DHCPV4_MSG_BOOT_REQUEST;
	msg->htype = HARDWARE_ETHERNET_TYPE;
	msg->hlen  = net_if_get_link_addr(iface)->len;
	msg->xid   = htonl(iface->config.dhcpv4.xid);
	msg->flags = htons(DHCPV4_MSG_BROADCAST);

	if (ciaddr) {
		/* The ciaddr field was zero'd out above, if we are
		 * asked to send a ciaddr then fill it in now
		 * otherwise leave it as all zeros.
		 */
		memcpy(msg->ciaddr, ciaddr, 4);
	}

	memcpy(msg->chaddr, net_if_get_link_addr(iface)->addr,
	       net_if_get_link_addr(iface)->len);

	if (net_pkt_set_data(pkt, &dhcp_access)) {
		goto fail;
	}

	if (!dhcpv4_add_sname(pkt) ||
	    !dhcpv4_add_file(pkt) ||
	    !dhcpv4_add_cookie(pkt) ||
	    !dhcpv4_add_msg_type(pkt, type)) {
		goto fail;
	}

	if ((server_id &&
	     !dhcpv4_add_server_id(pkt, &iface->config.dhcpv4.server_id)) ||
	    (requested_ip &&
	     !dhcpv4_add_req_ipaddr(pkt, &iface->config.dhcpv4.requested_ip))) {
		goto fail;
	}

	if (type == NET_DHCPV4_MSG_TYPE_DISCOVER && !dhcpv4_add_req_options(pkt)) {
		goto fail;
	}

#if defined(CONFIG_NET_HOSTNAME_ENABLE)
	if (hostname_size > 0 &&
	     !dhcpv4_add_hostname(pkt, hostname, hostname_size)) {
		goto fail;
	}
#endif

	if (!dhcpv4_add_end(pkt)) {
		goto fail;
	}

	net_pkt_cursor_init(pkt);

	net_ipv4_finalize(pkt, IPPROTO_UDP);

	return pkt;

fail:
	NET_DBG("Message creation failed");
	net_pkt_unref(pkt);

	return NULL;
}

/* Must be invoked with lock held. */
static void dhcpv4_immediate_timeout(struct net_if_dhcpv4 *dhcpv4)
{
	NET_DBG("force timeout dhcpv4=%p", dhcpv4);
	dhcpv4->timer_start = k_uptime_get() - 1;
	dhcpv4->request_time = 0U;
	k_work_reschedule(&timeout_work, K_NO_WAIT);
}

/* Must be invoked with lock held. */
static void dhcpv4_set_timeout(struct net_if_dhcpv4 *dhcpv4,
			       uint32_t timeout)
{
	NET_DBG("sched timeout dhcvp4=%p timeout=%us", dhcpv4, timeout);
	dhcpv4->timer_start = k_uptime_get();
	dhcpv4->request_time = timeout;

	/* NB: This interface may not be providing the next timeout
	 * event; also this timeout may replace the current timeout
	 * event.  Delegate scheduling to the timeout manager.
	 */
	k_work_reschedule(&timeout_work, K_NO_WAIT);
}

/* Must be invoked with lock held */
static uint32_t dhcpv4_update_message_timeout(struct net_if_dhcpv4 *dhcpv4)
{
	uint32_t timeout;

	timeout = DHCPV4_INITIAL_RETRY_TIMEOUT << dhcpv4->attempts;

	/* Max 64 seconds, see RFC 2131 chapter 4.1 */
	if (timeout < DHCPV4_INITIAL_RETRY_TIMEOUT || timeout > 64) {
		timeout = 64;
	}

	/* +1/-1 second randomization */
	timeout += (sys_rand32_get() % 3U) - 1;

	dhcpv4->attempts++;
	dhcpv4_set_timeout(dhcpv4, timeout);

	return timeout;
}

/* Prepare DHCPv4 Message request and send it to peer.
 *
 * Returns the number of seconds until the next time-triggered event,
 * or UINT32_MAX if the client is in an invalid state.
 */
static uint32_t dhcpv4_send_request(struct net_if *iface)
{
	const struct in_addr *server_addr = net_ipv4_broadcast_address();
	const struct in_addr *ciaddr = NULL;
	const struct in_addr *src_addr = NULL;
	bool with_server_id = false;
	bool with_requested_ip = false;
	struct net_pkt *pkt = NULL;
	uint32_t timeout = UINT32_MAX;

	iface->config.dhcpv4.xid++;

	switch (iface->config.dhcpv4.state) {
	case NET_DHCPV4_DISABLED:
	case NET_DHCPV4_INIT:
	case NET_DHCPV4_SELECTING:
	case NET_DHCPV4_BOUND:
		/* Not possible */
		NET_ASSERT(0, "Invalid state %s",
			   net_dhcpv4_state_name(iface->config.dhcpv4.state));
		goto fail;
		break;
	case NET_DHCPV4_REQUESTING:
		with_server_id = true;
		with_requested_ip = true;
		memcpy(&iface->config.dhcpv4.request_server_addr, &iface->config.dhcpv4.server_id,
		       sizeof(struct in_addr));
		break;
	case NET_DHCPV4_RENEWING:
		/* Since we have an address populate the ciaddr field.
		 */
		ciaddr = &iface->config.dhcpv4.requested_ip;

		/* UNICAST the DHCPREQUEST */
		src_addr = ciaddr;
		server_addr = &iface->config.dhcpv4.server_id;

		/* RFC2131 4.4.5 Client MUST NOT include server
		 * identifier in the DHCPREQUEST.
		 */
		break;
	case NET_DHCPV4_REBINDING:
		/* Since we have an address populate the ciaddr field.
		 */
		ciaddr = &iface->config.dhcpv4.requested_ip;
		src_addr = ciaddr;

		break;
	}

	timeout = dhcpv4_update_message_timeout(&iface->config.dhcpv4);

	pkt = dhcpv4_create_message(iface, NET_DHCPV4_MSG_TYPE_REQUEST,
				    ciaddr, src_addr, server_addr,
				    with_server_id, with_requested_ip);
	if (!pkt) {
		goto fail;
	}

	if (net_send_data(pkt) < 0) {
		goto fail;
	}

	net_stats_update_udp_sent(iface);

	NET_DBG("send request dst=%s xid=0x%x ciaddr=%s%s%s timeout=%us",
		net_sprint_ipv4_addr(server_addr),
		iface->config.dhcpv4.xid,
		ciaddr ?
		net_sprint_ipv4_addr(ciaddr) : "<unknown>",
		with_server_id ? " +server-id" : "",
		with_requested_ip ? " +requested-ip" : "",
		timeout);

	return timeout;

fail:
	if (pkt) {
		net_pkt_unref(pkt);
	}

	return timeout;
}

/* Prepare DHCPv4 Discover message and broadcast it */
static uint32_t dhcpv4_send_discover(struct net_if *iface)
{
	struct net_pkt *pkt;
	uint32_t timeout;

	iface->config.dhcpv4.xid++;

	pkt = dhcpv4_create_message(iface, NET_DHCPV4_MSG_TYPE_DISCOVER,
				    NULL, NULL, net_ipv4_broadcast_address(),
				    false, false);
	if (!pkt) {
		goto fail;
	}

	if (net_send_data(pkt) < 0) {
		goto fail;
	}

	net_stats_update_udp_sent(iface);

	timeout = dhcpv4_update_message_timeout(&iface->config.dhcpv4);

	NET_DBG("send discover xid=0x%x timeout=%us",
		iface->config.dhcpv4.xid, timeout);

	return timeout;

fail:
	if (pkt) {
		net_pkt_unref(pkt);
	}

	return iface->config.dhcpv4.xid %
			(CONFIG_NET_DHCPV4_INITIAL_DELAY_MAX -
			 DHCPV4_INITIAL_DELAY_MIN) +
			DHCPV4_INITIAL_DELAY_MIN;
}

static void dhcpv4_enter_selecting(struct net_if *iface)
{
	iface->config.dhcpv4.attempts = 0U;

	iface->config.dhcpv4.lease_time = 0U;
	iface->config.dhcpv4.renewal_time = 0U;
	iface->config.dhcpv4.rebinding_time = 0U;

	iface->config.dhcpv4.server_id.s_addr = INADDR_ANY;
	iface->config.dhcpv4.requested_ip.s_addr = INADDR_ANY;

	iface->config.dhcpv4.state = NET_DHCPV4_SELECTING;
	NET_DBG("enter state=%s",
		net_dhcpv4_state_name(iface->config.dhcpv4.state));
}

static uint32_t dhcpv4_get_timeleft(int64_t start, uint32_t time, int64_t now)
{
	int64_t deadline = start + MSEC_PER_SEC * time;
	uint32_t ret = 0U;

	/* If we haven't reached the deadline, calculate the
	 * rounded-up whole seconds until the deadline.
	 */
	if (deadline > now) {
		ret = (uint32_t)DIV_ROUND_UP(deadline - now, MSEC_PER_SEC);
	}

	return ret;
}

static uint32_t dhcpv4_request_timeleft(struct net_if *iface, int64_t now)
{
	uint32_t request_time = iface->config.dhcpv4.request_time;

	return dhcpv4_get_timeleft(iface->config.dhcpv4.timer_start,
				   request_time, now);
}

static uint32_t dhcpv4_renewal_timeleft(struct net_if *iface, int64_t now)
{
	uint32_t rem = dhcpv4_get_timeleft(iface->config.dhcpv4.timer_start,
					   iface->config.dhcpv4.renewal_time,
					   now);

	if (rem == 0U) {
		iface->config.dhcpv4.state = NET_DHCPV4_RENEWING;
		NET_DBG("enter state=%s",
			net_dhcpv4_state_name(iface->config.dhcpv4.state));
		iface->config.dhcpv4.attempts = 0U;
	}

	return rem;
}

static uint32_t dhcpv4_rebinding_timeleft(struct net_if *iface, int64_t now)
{
	uint32_t rem = dhcpv4_get_timeleft(iface->config.dhcpv4.timer_start,
					   iface->config.dhcpv4.rebinding_time,
					   now);
	if (rem == 0U) {
		iface->config.dhcpv4.state = NET_DHCPV4_REBINDING;
		NET_DBG("enter state=%s",
			net_dhcpv4_state_name(iface->config.dhcpv4.state));
		iface->config.dhcpv4.attempts = 0U;
	}

	return rem;
}

static void dhcpv4_enter_requesting(struct net_if *iface, struct dhcp_msg *msg)
{
	iface->config.dhcpv4.attempts = 0U;
	iface->config.dhcpv4.state = NET_DHCPV4_REQUESTING;
	NET_DBG("enter state=%s",
		net_dhcpv4_state_name(iface->config.dhcpv4.state));

	memcpy(iface->config.dhcpv4.requested_ip.s4_addr,
	       msg->yiaddr, sizeof(msg->yiaddr));

	dhcpv4_send_request(iface);
}

/* Must be invoked with lock held */
static void dhcpv4_enter_bound(struct net_if *iface)
{
	uint32_t renewal_time;
	uint32_t rebinding_time;

	renewal_time = iface->config.dhcpv4.renewal_time;
	if (!renewal_time) {
		/* The default renewal time rfc2131 4.4.5 */
		renewal_time = iface->config.dhcpv4.lease_time / 2U;
		iface->config.dhcpv4.renewal_time = renewal_time;
	}

	rebinding_time = iface->config.dhcpv4.rebinding_time;
	if (!rebinding_time) {
		/* The default rebinding time rfc2131 4.4.5 */
		rebinding_time = iface->config.dhcpv4.lease_time * 875U / 1000;
		iface->config.dhcpv4.rebinding_time = rebinding_time;
	}

	iface->config.dhcpv4.state = NET_DHCPV4_BOUND;
	NET_DBG("enter state=%s renewal=%us rebinding=%us",
		net_dhcpv4_state_name(iface->config.dhcpv4.state),
		renewal_time, rebinding_time);

	dhcpv4_set_timeout(&iface->config.dhcpv4,
			   MIN(renewal_time, rebinding_time));

	net_mgmt_event_notify_with_info(NET_EVENT_IPV4_DHCP_BOUND, iface,
					&iface->config.dhcpv4,
					sizeof(iface->config.dhcpv4));
}

static uint32_t dhcpv4_manage_timers(struct net_if *iface, int64_t now)
{
	uint32_t timeleft = dhcpv4_request_timeleft(iface, now);

	NET_DBG("iface %p dhcpv4=%p state=%s timeleft=%u", iface,
		&iface->config.dhcpv4,
		net_dhcpv4_state_name(iface->config.dhcpv4.state), timeleft);

	if (timeleft != 0U) {
		return timeleft;
	}

	if (!net_if_is_up(iface)) {
		/* An interface is down, the registered event handler will
		 * restart DHCP procedure when the interface is back up.
		 */
		return UINT32_MAX;
	}

	switch (iface->config.dhcpv4.state) {
	case NET_DHCPV4_DISABLED:
		break;
	case NET_DHCPV4_INIT:
		dhcpv4_enter_selecting(iface);
		__fallthrough;
	case NET_DHCPV4_SELECTING:
		/* Failed to get OFFER message, send DISCOVER again */
		return dhcpv4_send_discover(iface);
	case NET_DHCPV4_REQUESTING:
		/* Maximum number of renewal attempts failed, so start
		 * from the beginning.
		 */
		if (iface->config.dhcpv4.attempts >=
					DHCPV4_MAX_NUMBER_OF_ATTEMPTS) {
			NET_DBG("too many attempts, restart");
			dhcpv4_enter_selecting(iface);
			return dhcpv4_send_discover(iface);
		}

		return dhcpv4_send_request(iface);
	case NET_DHCPV4_BOUND:
		timeleft = dhcpv4_renewal_timeleft(iface, now);
		if (timeleft != 0U) {
			timeleft = MIN(timeleft,
				       dhcpv4_rebinding_timeleft(iface, now));
		}
		if (timeleft == 0U) {
			return dhcpv4_send_request(iface);
		}

		return timeleft;
	case NET_DHCPV4_RENEWING:
	case NET_DHCPV4_REBINDING:
		if (iface->config.dhcpv4.attempts >=
					DHCPV4_MAX_NUMBER_OF_ATTEMPTS) {
			NET_DBG("too many attempts, restart");

			if (!net_if_ipv4_addr_rm(iface,
					 &iface->config.dhcpv4.requested_ip)) {
				NET_DBG("Failed to remove addr from iface");
			}

			/* Maximum number of renewal attempts failed, so start
			 * from the beginning.
			 */
			dhcpv4_enter_selecting(iface);
			return dhcpv4_send_discover(iface);
		} else {
			return dhcpv4_send_request(iface);
		}
	}

	return UINT32_MAX;
}

static void dhcpv4_timeout(struct k_work *work)
{
	uint32_t timeout_update = UINT32_MAX;
	int64_t now = k_uptime_get();
	struct net_if_dhcpv4 *current, *next;

	ARG_UNUSED(work);

	k_mutex_lock(&lock, K_FOREVER);

	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&dhcpv4_ifaces, current, next, node) {
		struct net_if *iface = CONTAINER_OF(
			CONTAINER_OF(current, struct net_if_config, dhcpv4),
			struct net_if, config);
		uint32_t next_timeout;

		next_timeout = dhcpv4_manage_timers(iface, now);
		if (next_timeout < timeout_update) {
			timeout_update = next_timeout;
		}
	}

	k_mutex_unlock(&lock);

	if (timeout_update != UINT32_MAX) {
		NET_DBG("Waiting for %us", timeout_update);

		k_work_reschedule(&timeout_work,
				  K_SECONDS(timeout_update));
	}
}

/* Parse DHCPv4 options and retrieve relevant information
 * as per RFC 2132.
 */
static bool dhcpv4_parse_options(struct net_pkt *pkt,
				 struct net_if *iface,
				 enum net_dhcpv4_msg_type *msg_type)
{
#if defined(CONFIG_NET_DHCPV4_OPTION_CALLBACKS)
	struct net_dhcpv4_option_callback *cb, *tmp;
	struct net_pkt_cursor backup;
#endif
	uint8_t cookie[4];
	uint8_t length;
	uint8_t type;
	bool router_present = false;
	bool unhandled = true;

	if (net_pkt_read(pkt, cookie, sizeof(cookie)) ||
	    memcmp(magic_cookie, cookie, sizeof(magic_cookie))) {
		NET_DBG("Incorrect magic cookie");
		return false;
	}

	while (!net_pkt_read_u8(pkt, &type)) {
		if (type == DHCPV4_OPTIONS_END) {
			NET_DBG("options_end");
			goto end;
		}

		if (net_pkt_read_u8(pkt, &length)) {
			NET_ERR("option parsing, bad length");
			return false;
		}


#if defined(CONFIG_NET_DHCPV4_OPTION_CALLBACKS)
		net_pkt_cursor_backup(pkt, &backup);
		unhandled = true;

		SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&option_callbacks,
						  cb, tmp, node) {
			if (cb->option == type) {
				NET_ASSERT(cb->handler, "No callback handler!");

				if (net_pkt_read(pkt, cb->data,
						 MIN(cb->max_length, length))) {
					NET_DBG("option callback, read err");
					return false;
				}

				cb->handler(cb, length, *msg_type, iface);
				unhandled = false;
			}
			net_pkt_cursor_restore(pkt, &backup);
		}
#endif /* CONFIG_NET_DHCPV4_OPTION_CALLBACKS */

		switch (type) {
		case DHCPV4_OPTIONS_SUBNET_MASK: {
			struct in_addr netmask;

			if (length != 4U) {
				NET_ERR("options_subnet_mask, bad length");
				return false;
			}

			if (net_pkt_read(pkt, netmask.s4_addr, length)) {
				NET_ERR("options_subnet_mask, short packet");
				return false;
			}

			net_if_ipv4_set_netmask(iface, &netmask);
			NET_DBG("options_subnet_mask %s",
				net_sprint_ipv4_addr(&netmask));
			break;
		}
		case DHCPV4_OPTIONS_ROUTER: {
			struct in_addr router;

			/* Router option may present 1 or more
			 * addresses for routers on the clients
			 * subnet.  Routers should be listed in order
			 * of preference.  Hence we choose the first
			 * and skip the rest.
			 */
			if (length % 4 != 0U || length < 4) {
				NET_ERR("options_router, bad length");
				return false;
			}

			if (net_pkt_read(pkt, router.s4_addr, 4) ||
			    net_pkt_skip(pkt, length - 4U)) {
				NET_ERR("options_router, short packet");
				return false;
			}

			NET_DBG("options_router: %s",
				net_sprint_ipv4_addr(&router));
			net_if_ipv4_set_gw(iface, &router);
			router_present = true;

			break;
		}
#if defined(CONFIG_DNS_RESOLVER)
		case DHCPV4_OPTIONS_DNS_SERVER: {
			struct dns_resolve_context *ctx;
			struct sockaddr_in dns;
			const struct sockaddr *dns_servers[] = {
				(struct sockaddr *)&dns, NULL
			};
			int status;

			/* DNS server option may present 1 or more
			 * addresses. Each 4 bytes in length. DNS
			 * servers should be listed in order
			 * of preference.  Hence we choose the first
			 * and skip the rest.
			 */
			if (length % 4 != 0U) {
				NET_ERR("options_dns, bad length");
				return false;
			}

			(void)memset(&dns, 0, sizeof(dns));

			if (net_pkt_read(pkt, dns.sin_addr.s4_addr, 4) ||
			    net_pkt_skip(pkt, length - 4U)) {
				NET_ERR("options_dns, short packet");
				return false;
			}

			ctx = dns_resolve_get_default();
			dns.sin_family = AF_INET;
			status = dns_resolve_reconfigure(ctx, NULL, dns_servers);
			if (status < 0) {
				NET_DBG("options_dns, failed to set "
					"resolve address: %d", status);
				return false;
			}

			break;
		}
#endif
		case DHCPV4_OPTIONS_LEASE_TIME:
			if (length != 4U) {
				NET_ERR("options_lease_time, bad length");
				return false;
			}

			if (net_pkt_read_be32(
				    pkt, &iface->config.dhcpv4.lease_time) ||
			    !iface->config.dhcpv4.lease_time) {
				NET_ERR("options_lease_time, wrong value");
				return false;
			}

			NET_DBG("options_lease_time: %u",
				iface->config.dhcpv4.lease_time);

			break;
		case DHCPV4_OPTIONS_RENEWAL:
			if (length != 4U) {
				NET_DBG("options_renewal, bad length");
				return false;
			}

			if (net_pkt_read_be32(
				    pkt, &iface->config.dhcpv4.renewal_time) ||
			    !iface->config.dhcpv4.renewal_time) {
				NET_DBG("options_renewal, wrong value");
				return false;
			}

			NET_DBG("options_renewal: %u",
				iface->config.dhcpv4.renewal_time);

			break;
		case DHCPV4_OPTIONS_REBINDING:
			if (length != 4U) {
				NET_DBG("options_rebinding, bad length");
				return false;
			}

			if (net_pkt_read_be32(
				    pkt,
				    &iface->config.dhcpv4.rebinding_time) ||
			    !iface->config.dhcpv4.rebinding_time) {
				NET_DBG("options_rebinding, wrong value");
				return false;
			}

			NET_DBG("options_rebinding: %u",
				iface->config.dhcpv4.rebinding_time);

			break;
		case DHCPV4_OPTIONS_SERVER_ID:
			if (length != 4U) {
				NET_DBG("options_server_id, bad length");
				return false;
			}

			if (net_pkt_read(
				    pkt,
				    iface->config.dhcpv4.server_id.s4_addr,
				    length)) {
				NET_DBG("options_server_id, read err");
				return false;
			}

			NET_DBG("options_server_id: %s",
				net_sprint_ipv4_addr(&iface->config.dhcpv4.server_id));
			break;
		case DHCPV4_OPTIONS_MSG_TYPE: {
			if (length != 1U) {
				NET_DBG("options_msg_type, bad length");
				return false;
			}

			{
				uint8_t val = 0U;

				if (net_pkt_read_u8(pkt, &val)) {
					NET_DBG("options_msg_type, read err");
					return false;
				}
				*msg_type = val;
			}

			break;
		}
		default:
			if (unhandled) {
				NET_DBG("option unknown: %d", type);
			} else {
				NET_DBG("option unknown, handled by callback: %d", type);
			}

			if (net_pkt_skip(pkt, length)) {
				NET_DBG("option unknown, skip err");
				return false;
			}
			break;
		}
	}

	/* Invalid case: Options without DHCPV4_OPTIONS_END. */
	return false;

end:
	if (*msg_type == NET_DHCPV4_MSG_TYPE_OFFER && !router_present) {
		struct in_addr any = INADDR_ANY_INIT;

		net_if_ipv4_set_gw(iface, &any);
	}

	return true;
}

static inline void dhcpv4_handle_msg_offer(struct net_if *iface,
					   struct dhcp_msg *msg)
{
	switch (iface->config.dhcpv4.state) {
	case NET_DHCPV4_DISABLED:
	case NET_DHCPV4_INIT:
	case NET_DHCPV4_REQUESTING:
	case NET_DHCPV4_RENEWING:
	case NET_DHCPV4_REBINDING:
	case NET_DHCPV4_BOUND:
		break;
	case NET_DHCPV4_SELECTING:
		dhcpv4_enter_requesting(iface, msg);
		break;
	}
}

/* Must be invoked with lock held */
static void dhcpv4_handle_msg_ack(struct net_if *iface)
{
	switch (iface->config.dhcpv4.state) {
	case NET_DHCPV4_DISABLED:
	case NET_DHCPV4_INIT:
	case NET_DHCPV4_SELECTING:
	case NET_DHCPV4_BOUND:
		break;
	case NET_DHCPV4_REQUESTING:
		NET_INFO("Received: %s",
			 net_sprint_ipv4_addr(&iface->config.dhcpv4.requested_ip));

		if (!net_if_ipv4_addr_add(iface,
					  &iface->config.dhcpv4.requested_ip,
					  NET_ADDR_DHCP,
					  iface->config.dhcpv4.lease_time)) {
			NET_DBG("Failed to add IPv4 addr to iface %p", iface);
			return;
		}

		dhcpv4_enter_bound(iface);
		break;

	case NET_DHCPV4_RENEWING:
	case NET_DHCPV4_REBINDING:
		/* TODO: If the renewal is success, update only
		 * vlifetime on iface.
		 */
		dhcpv4_enter_bound(iface);
		break;
	}
}

static void dhcpv4_handle_msg_nak(struct net_if *iface)
{
	switch (iface->config.dhcpv4.state) {
	case NET_DHCPV4_DISABLED:
	case NET_DHCPV4_INIT:
	case NET_DHCPV4_SELECTING:
	case NET_DHCPV4_REQUESTING:
		if (memcmp(&iface->config.dhcpv4.request_server_addr,
			   &iface->config.dhcpv4.response_src_addr,
			   sizeof(iface->config.dhcpv4.request_server_addr)) == 0) {
			LOG_DBG("NAK from requesting server %s, restart config",
				net_sprint_ipv4_addr(&iface->config.dhcpv4.request_server_addr));
			dhcpv4_enter_selecting(iface);
		} else {
			LOG_DBG("NAK from non-requesting server %s, ignore it",
				net_sprint_ipv4_addr(&iface->config.dhcpv4.response_src_addr));
		}
		break;
	case NET_DHCPV4_BOUND:
		break;
	case NET_DHCPV4_RENEWING:
	case NET_DHCPV4_REBINDING:
		if (!net_if_ipv4_addr_rm(iface,
					 &iface->config.dhcpv4.requested_ip)) {
			NET_DBG("Failed to remove addr from iface");
		}

		/* Restart the configuration process. */
		dhcpv4_enter_selecting(iface);
		break;
	}
}

/* Takes and releases lock */
static void dhcpv4_handle_reply(struct net_if *iface,
				enum net_dhcpv4_msg_type msg_type,
				struct dhcp_msg *msg)
{
	NET_DBG("state=%s msg=%s",
		net_dhcpv4_state_name(iface->config.dhcpv4.state),
		net_dhcpv4_msg_type_name(msg_type));

	switch (msg_type) {
	case NET_DHCPV4_MSG_TYPE_OFFER:
		dhcpv4_handle_msg_offer(iface, msg);
		break;
	case NET_DHCPV4_MSG_TYPE_ACK:
		dhcpv4_handle_msg_ack(iface);
		break;
	case NET_DHCPV4_MSG_TYPE_NAK:
		dhcpv4_handle_msg_nak(iface);
		break;
	default:
		NET_DBG("ignore message");
		break;
	}
}

static enum net_verdict net_dhcpv4_input(struct net_conn *conn,
					 struct net_pkt *pkt,
					 union net_ip_header *ip_hdr,
					 union net_proto_header *proto_hdr,
					 void *user_data)
{
	NET_PKT_DATA_ACCESS_DEFINE(dhcp_access, struct dhcp_msg);
	enum net_verdict verdict = NET_DROP;
	enum net_dhcpv4_msg_type msg_type = 0;
	struct dhcp_msg *msg;
	struct net_if *iface;

	if (!conn) {
		NET_DBG("Invalid connection");
		return NET_DROP;
	}

	if (!pkt) {
		NET_DBG("Invalid packet");
		return NET_DROP;
	}

	iface = net_pkt_iface(pkt);
	if (!iface) {
		NET_DBG("no iface");
		return NET_DROP;
	}

	/* If the message is not DHCP then drop the packet. */
	if (net_pkt_get_len(pkt) < NET_IPV4UDPH_LEN + sizeof(struct dhcp_msg)) {
		NET_DBG("Input msg is not related to DHCPv4");
		return NET_DROP;

	}

	net_pkt_cursor_init(pkt);

	if (net_pkt_skip(pkt, NET_IPV4UDPH_LEN)) {
		return NET_DROP;
	}

	msg = (struct dhcp_msg *)net_pkt_get_data(pkt, &dhcp_access);
	if (!msg) {
		return NET_DROP;
	}

	NET_DBG("Received dhcp msg [op=0x%x htype=0x%x hlen=%u xid=0x%x "
		"secs=%u flags=0x%x chaddr=%s",
		msg->op, msg->htype, msg->hlen, ntohl(msg->xid),
		msg->secs, msg->flags,
		net_sprint_ll_addr(msg->chaddr, 6));
	NET_DBG("  ciaddr=%d.%d.%d.%d",
		msg->ciaddr[0], msg->ciaddr[1], msg->ciaddr[2], msg->ciaddr[3]);
	NET_DBG("  yiaddr=%d.%d.%d.%d",
		msg->yiaddr[0], msg->yiaddr[1], msg->yiaddr[2], msg->yiaddr[3]);
	NET_DBG("  siaddr=%d.%d.%d.%d",
		msg->siaddr[0], msg->siaddr[1], msg->siaddr[2], msg->siaddr[3]);
	NET_DBG("  giaddr=%d.%d.%d.%d]",
		msg->giaddr[0], msg->giaddr[1], msg->giaddr[2], msg->giaddr[3]);

	k_mutex_lock(&lock, K_FOREVER);

	if (!(msg->op == DHCPV4_MSG_BOOT_REPLY &&
	      iface->config.dhcpv4.xid == ntohl(msg->xid) &&
	      !memcmp(msg->chaddr, net_if_get_link_addr(iface)->addr,
		      net_if_get_link_addr(iface)->len))) {

		NET_DBG("Unexpected op (%d), xid (%x vs %x) or chaddr",
			msg->op, iface->config.dhcpv4.xid, ntohl(msg->xid));
		goto drop;
	}

	if (msg->hlen != net_if_get_link_addr(iface)->len) {
		NET_DBG("Unexpected hlen (%d)", msg->hlen);
		goto drop;
	}

	net_pkt_acknowledge_data(pkt, &dhcp_access);

	/* SNAME, FILE are not used at the moment, skip it */
	if (net_pkt_skip(pkt, SIZE_OF_SNAME + SIZE_OF_FILE)) {
		NET_DBG("short packet while skipping sname");
		goto drop;
	}

	if (!dhcpv4_parse_options(pkt, iface, &msg_type)) {
		goto drop;
	}

	memcpy(&iface->config.dhcpv4.response_src_addr, ip_hdr->ipv4->src,
		       sizeof(struct in_addr));

	dhcpv4_handle_reply(iface, msg_type, msg);

	net_pkt_unref(pkt);

	verdict = NET_OK;

drop:
	k_mutex_unlock(&lock);

	return verdict;
}

static void dhcpv4_iface_event_handler(struct net_mgmt_event_callback *cb,
				       uint32_t mgmt_event, struct net_if *iface)
{
	sys_snode_t *node = NULL;

	k_mutex_lock(&lock, K_FOREVER);

	SYS_SLIST_FOR_EACH_NODE(&dhcpv4_ifaces, node) {
		if (node == &iface->config.dhcpv4.node) {
			break;
		}
	}

	if (node == NULL) {
		goto out;
	}

	if (mgmt_event == NET_EVENT_IF_DOWN) {
		NET_DBG("Interface %p going down", iface);

		if (iface->config.dhcpv4.state == NET_DHCPV4_BOUND) {
			iface->config.dhcpv4.attempts = 0U;
			iface->config.dhcpv4.state = NET_DHCPV4_RENEWING;
			NET_DBG("enter state=%s", net_dhcpv4_state_name(
					iface->config.dhcpv4.state));
		}
	} else if (mgmt_event == NET_EVENT_IF_UP) {
		NET_DBG("Interface %p coming up", iface);

		/* We should not call dhcpv4_send_request() directly here as
		 * the CONFIG_NET_MGMT_EVENT_STACK_SIZE is not large
		 * enough. Instead we can force a request timeout
		 * which will then call dhcpv4_send_request() automatically.
		 */
		dhcpv4_immediate_timeout(&iface->config.dhcpv4);
	}

out:
	k_mutex_unlock(&lock);
}

const char *net_dhcpv4_state_name(enum net_dhcpv4_state state)
{
	static const char * const name[] = {
		"disabled",
		"init",
		"selecting",
		"requesting",
		"renewing",
		"rebinding",
		"bound",
	};

	__ASSERT_NO_MSG(state >= 0 && state < sizeof(name));
	return name[state];
}

const char *net_dhcpv4_msg_type_name(enum net_dhcpv4_msg_type msg_type)
{
	static const char * const name[] = {
		"discover",
		"offer",
		"request",
		"decline",
		"ack",
		"nak",
		"release",
		"inform"
	};

	__ASSERT_NO_MSG(msg_type >= 1 && msg_type <= sizeof(name));
	return name[msg_type - 1];
}

static void dhcpv4_start_internal(struct net_if *iface, bool first_start)
{
	uint32_t entropy;
	uint32_t timeout = 0;

	net_mgmt_event_notify(NET_EVENT_IPV4_DHCP_START, iface);

	k_mutex_lock(&lock, K_FOREVER);

	switch (iface->config.dhcpv4.state) {
	case NET_DHCPV4_DISABLED:
		iface->config.dhcpv4.state = NET_DHCPV4_INIT;
		NET_DBG("iface %p state=%s", iface,
			net_dhcpv4_state_name(iface->config.dhcpv4.state));

		/* We need entropy for both an XID and a random delay
		 * before sending the initial discover message.
		 */
		entropy = sys_rand32_get();

		/* A DHCP client MUST choose xid's in such a way as to
		 * minimize the change of using and xid identical to
		 * one used by another client.  Choose a random xid st
		 * startup and increment it on each new request.
		 */
		iface->config.dhcpv4.xid = entropy;

		/* Use default */
		if (first_start) {
			/* RFC2131 4.1.1 requires we wait a random period
			 * between 1 and 10 seconds before sending the initial
			 * discover.
			 */
			timeout = entropy % (CONFIG_NET_DHCPV4_INITIAL_DELAY_MAX -
					DHCPV4_INITIAL_DELAY_MIN) + DHCPV4_INITIAL_DELAY_MIN;
		}

		NET_DBG("wait timeout=%us", timeout);

		if (sys_slist_is_empty(&dhcpv4_ifaces)) {
			net_mgmt_add_event_callback(&mgmt4_cb);
		}

		sys_slist_append(&dhcpv4_ifaces,
				 &iface->config.dhcpv4.node);

		dhcpv4_set_timeout(&iface->config.dhcpv4, timeout);

		break;
	case NET_DHCPV4_INIT:
	case NET_DHCPV4_SELECTING:
	case NET_DHCPV4_REQUESTING:
	case NET_DHCPV4_RENEWING:
	case NET_DHCPV4_REBINDING:
	case NET_DHCPV4_BOUND:
		break;
	}

	k_mutex_unlock(&lock);
}

#if defined(CONFIG_NET_DHCPV4_OPTION_CALLBACKS)

int net_dhcpv4_add_option_callback(struct net_dhcpv4_option_callback *cb)
{
	if (!cb || !cb->handler) {
		return -EINVAL;
	}

	k_mutex_lock(&lock, K_FOREVER);
	sys_slist_prepend(&option_callbacks, &cb->node);
	k_mutex_unlock(&lock);
	return 0;
}

int net_dhcpv4_remove_option_callback(struct net_dhcpv4_option_callback *cb)
{
	int ret = 0;

	if (!cb || !cb->handler) {
		return -EINVAL;
	}

	k_mutex_lock(&lock, K_FOREVER);
	if (!sys_slist_find_and_remove(&option_callbacks, &cb->node)) {
		ret = -EINVAL;
	}
	k_mutex_unlock(&lock);
	return ret;
}

#endif /* CONFIG_NET_DHCPV4_OPTION_CALLBACKS */

void net_dhcpv4_start(struct net_if *iface)
{
	return dhcpv4_start_internal(iface, true);
}

void net_dhcpv4_stop(struct net_if *iface)
{
	k_mutex_lock(&lock, K_FOREVER);

	switch (iface->config.dhcpv4.state) {
	case NET_DHCPV4_DISABLED:
		break;

	case NET_DHCPV4_RENEWING:
	case NET_DHCPV4_BOUND:
		if (!net_if_ipv4_addr_rm(iface,
					 &iface->config.dhcpv4.requested_ip)) {
			NET_DBG("Failed to remove addr from iface");
		}

		__fallthrough;
	case NET_DHCPV4_INIT:
	case NET_DHCPV4_SELECTING:
	case NET_DHCPV4_REQUESTING:
	case NET_DHCPV4_REBINDING:
		iface->config.dhcpv4.state = NET_DHCPV4_DISABLED;
		NET_DBG("state=%s",
			net_dhcpv4_state_name(iface->config.dhcpv4.state));

		sys_slist_find_and_remove(&dhcpv4_ifaces,
					  &iface->config.dhcpv4.node);

		if (sys_slist_is_empty(&dhcpv4_ifaces)) {
			/* Best effort cancel.  Handler is safe to invoke if
			 * cancellation is unsuccessful.
			 */
			(void)k_work_cancel_delayable(&timeout_work);
			net_mgmt_del_event_callback(&mgmt4_cb);
		}

		break;
	}

	net_mgmt_event_notify(NET_EVENT_IPV4_DHCP_STOP, iface);

	k_mutex_unlock(&lock);
}

void net_dhcpv4_restart(struct net_if *iface)
{
	net_dhcpv4_stop(iface);
	dhcpv4_start_internal(iface, false);
}

int net_dhcpv4_init(void)
{
	struct sockaddr local_addr;
	int ret;

	NET_DBG("");

	net_ipaddr_copy(&net_sin(&local_addr)->sin_addr,
			net_ipv4_unspecified_address());
	local_addr.sa_family = AF_INET;

	/* Register UDP input callback on
	 * DHCPV4_SERVER_PORT(67) and DHCPV4_CLIENT_PORT(68) for
	 * all dhcpv4 related incoming packets.
	 */
	ret = net_udp_register(AF_INET, NULL, &local_addr,
			       DHCPV4_SERVER_PORT,
			       DHCPV4_CLIENT_PORT,
			       NULL, net_dhcpv4_input, NULL, NULL);
	if (ret < 0) {
		NET_DBG("UDP callback registration failed");
		return ret;
	}

	k_work_init_delayable(&timeout_work, dhcpv4_timeout);

	/* Catch network interface UP or DOWN events and renew the address
	 * if interface is coming back up again.
	 */
	net_mgmt_init_event_callback(&mgmt4_cb, dhcpv4_iface_event_handler,
					 NET_EVENT_IF_DOWN | NET_EVENT_IF_UP);

#if defined(CONFIG_NET_DHCPV4_OPTION_CALLBACKS)
	k_mutex_lock(&lock, K_FOREVER);
	sys_slist_init(&option_callbacks);
	k_mutex_unlock(&lock);
#endif
	return 0;
}
