/*
 * Copyright (c) 2024 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/ztest.h>
#include <zephyr/net/dummy.h>
#include <zephyr/net/ethernet.h>
#include <zephyr/net/icmp.h>
#include <zephyr/net/net_ip.h>
#include <zephyr/net/dhcpv4.h>
#include <zephyr/net/dhcpv4_server.h>

#include "dhcpv4/dhcpv4_internal.h"
#include "icmpv4.h"
#include "ipv4.h"
#include "udp_internal.h"

/* 00-00-5E-00-53-xx Documentation RFC 7042 */
static uint8_t server_mac_addr[] = { 0x00, 0x00, 0x5E, 0x00, 0x53, 0x01 };
static uint8_t client_mac_addr[] = { 0x00, 0x00, 0x5E, 0x00, 0x53, 0x02 };

static struct in_addr server_addr = { { { 192, 0, 2, 1 } } };
static struct in_addr netmask = { { { 255, 255, 255, 0 } } };
static struct in_addr test_base_addr = { { { 192, 0, 2, 10 } } };

/* Only to test Inform. */
static struct in_addr client_addr_static = { { { 192, 0, 2, 2 } } };

typedef void (*test_dhcpv4_server_fn_t)(struct net_if *iface,
					struct net_pkt *pkt);


static struct test_dhcpv4_server_ctx {
	struct net_if *iface;
	struct k_sem test_proceed;
	struct net_pkt *pkt;
	struct in_addr assigned_ip;
	struct in_addr declined_ip;

	/* Request params */
	const char *client_id;
	int lease_time;
	bool broadcast;
	bool send_echo_reply;
} test_ctx;

struct test_lease_count {
	int reserved;
	int allocated;
	int declined;
};

#define CLIENT_ID_1 "client1"
#define CLIENT_ID_2 "client2"
#define NO_LEASE_TIME -1
#define TEST_XID 0x12345678

#define TEST_TIMEOUT K_MSEC(100)

static void server_iface_init(struct net_if *iface)
{
	net_if_set_link_addr(iface, server_mac_addr, sizeof(server_mac_addr),
			     NET_LINK_ETHERNET);

	test_ctx.iface = iface;

	(void)net_if_ipv4_addr_add(iface, &server_addr, NET_ADDR_MANUAL, 0);
	(void)net_if_ipv4_set_netmask_by_addr(iface, &server_addr, &netmask);
}

static void send_icmp_echo_reply(struct net_pkt *pkt,
				 struct net_ipv4_hdr *ipv4_hdr)
{
	struct net_pkt *reply;
	size_t payload_len = net_pkt_get_len(pkt) - net_pkt_ip_hdr_len(pkt) -
			     NET_ICMPH_LEN;

	reply = net_pkt_alloc_with_buffer(net_pkt_iface(pkt), payload_len,
					  AF_INET, IPPROTO_ICMP, K_FOREVER);
	zassert_not_null(reply, "Failed to allocate echo reply");

	zassert_ok(net_ipv4_create(reply, (struct in_addr *)ipv4_hdr->dst,
				   (struct in_addr *)ipv4_hdr->src),
		   "Failed to create IPv4 header");

	zassert_ok(net_icmpv4_create(reply, NET_ICMPV4_ECHO_REPLY, 0),
		   "Failed to create ICMP header");
	zassert_ok(net_pkt_copy(reply, pkt, payload_len),
		   "Failed to copy payload");

	net_pkt_cursor_init(reply);
	net_ipv4_finalize(reply, IPPROTO_ICMP);

	zassert_ok(net_recv_data(test_ctx.iface, reply), "Failed to receive data");
}

static int server_send(const struct device *dev, struct net_pkt *pkt)
{
	NET_PKT_DATA_ACCESS_DEFINE(ipv4_access, struct net_ipv4_hdr);
	struct net_ipv4_hdr *ipv4_hdr;

	ipv4_hdr = (struct net_ipv4_hdr *)net_pkt_get_data(pkt, &ipv4_access);
	zassert_not_null(ipv4_hdr, "Failed to access IPv4 header.");

	if (ipv4_hdr->proto == IPPROTO_ICMP) {
		if (test_ctx.send_echo_reply) {
			test_ctx.send_echo_reply = false;
			memcpy(&test_ctx.declined_ip, ipv4_hdr->dst,
			       sizeof(struct in_addr));
			send_icmp_echo_reply(pkt, ipv4_hdr);
		}

		return 0;
	}

	test_ctx.pkt = pkt;
	net_pkt_ref(pkt);

	k_sem_give(&test_ctx.test_proceed);

	return 0;
}

static struct dummy_api server_if_api = {
	.iface_api.init = server_iface_init,
	.send = server_send,
};

NET_DEVICE_INIT(server_iface, "server_iface", NULL, NULL, NULL, NULL,
		CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &server_if_api,
		DUMMY_L2, NET_L2_GET_CTX_TYPE(DUMMY_L2), NET_IPV4_MTU);

static const uint8_t cookie[4] = { 0x63, 0x82, 0x53, 0x63 };

static void test_pkt_free(void)
{
	if (test_ctx.pkt != NULL) {
		net_pkt_unref(test_ctx.pkt);
		test_ctx.pkt = NULL;
	}
}

static void client_prepare_test_msg(
	const struct in_addr *src_addr, const struct in_addr *dst_addr,
	enum net_dhcpv4_msg_type type, const struct in_addr *server_id,
	const struct in_addr *requested_ip, const struct in_addr *ciaddr)
{
	struct dhcp_msg msg = { 0 };
	uint8_t empty_buf[SIZE_OF_FILE] = { 0 };
	struct net_pkt *pkt;

	pkt = net_pkt_alloc_with_buffer(test_ctx.iface, NET_IPV4_MTU, AF_INET,
					IPPROTO_UDP, K_FOREVER);
	zassert_not_null(pkt, "Failed to allocate packet");

	net_pkt_set_ipv4_ttl(pkt, 1);

	zassert_ok(net_ipv4_create(pkt, src_addr, dst_addr),
		   "Failed to create IPv4 header");
	zassert_ok(net_udp_create(pkt, htons(DHCPV4_CLIENT_PORT),
				  htons(DHCPV4_SERVER_PORT)),
		   "Failed to create UDP header");

	msg.op = DHCPV4_MSG_BOOT_REQUEST;
	msg.htype = HARDWARE_ETHERNET_TYPE;
	msg.hlen = sizeof(client_mac_addr);
	msg.xid = htonl(TEST_XID);
	if (test_ctx.broadcast) {
		msg.flags = htons(DHCPV4_MSG_BROADCAST);
	}

	if (ciaddr) {
		memcpy(msg.ciaddr, ciaddr, sizeof(*ciaddr));
	} else {
		memset(msg.ciaddr, 0, sizeof(msg.ciaddr));

	}
	memset(msg.yiaddr, 0, sizeof(msg.ciaddr));
	memset(msg.siaddr, 0, sizeof(msg.siaddr));
	memset(msg.giaddr, 0, sizeof(msg.giaddr));
	memcpy(msg.chaddr, client_mac_addr, sizeof(client_mac_addr));

	net_pkt_write(pkt, &msg, sizeof(msg));
	net_pkt_write(pkt, empty_buf, SIZE_OF_SNAME);
	net_pkt_write(pkt, empty_buf, SIZE_OF_FILE);
	net_pkt_write(pkt, cookie, SIZE_OF_MAGIC_COOKIE);

	/* Options */
	net_pkt_write_u8(pkt, DHCPV4_OPTIONS_MSG_TYPE);
	net_pkt_write_u8(pkt, 1);
	net_pkt_write_u8(pkt, type);

	if (requested_ip) {
		net_pkt_write_u8(pkt, DHCPV4_OPTIONS_REQ_IPADDR);
		net_pkt_write_u8(pkt, sizeof(*requested_ip));
		net_pkt_write(pkt, requested_ip, sizeof(*requested_ip));
	}

	if (server_id) {
		net_pkt_write_u8(pkt, DHCPV4_OPTIONS_SERVER_ID);
		net_pkt_write_u8(pkt, sizeof(*server_id));
		net_pkt_write(pkt, server_id, sizeof(*server_id));
	}

	net_pkt_write_u8(pkt, DHCPV4_OPTIONS_REQ_LIST);
	net_pkt_write_u8(pkt, 1);
	net_pkt_write_u8(pkt, DHCPV4_OPTIONS_SUBNET_MASK);

	if (test_ctx.client_id) {
		net_pkt_write_u8(pkt, DHCPV4_OPTIONS_CLIENT_ID);
		net_pkt_write_u8(pkt, strlen(test_ctx.client_id));
		net_pkt_write(pkt, test_ctx.client_id, strlen(test_ctx.client_id));
	}

	if (test_ctx.lease_time != NO_LEASE_TIME) {
		net_pkt_write_u8(pkt, DHCPV4_OPTIONS_LEASE_TIME);
		net_pkt_write_u8(pkt, 4);
		net_pkt_write_be32(pkt, test_ctx.lease_time);
	}

	net_pkt_write_u8(pkt, DHCPV4_OPTIONS_END);

	net_pkt_cursor_init(pkt);
	net_ipv4_finalize(pkt, IPPROTO_UDP);

	zassert_ok(net_recv_data(test_ctx.iface, pkt), "Failed to receive data");
}

static void client_send_discover(void)
{
	int ret;

	client_prepare_test_msg(
		net_ipv4_unspecified_address(), net_ipv4_broadcast_address(),
		NET_DHCPV4_MSG_TYPE_DISCOVER, NULL, NULL, NULL);

	/* Wait for reply */
	ret = k_sem_take(&test_ctx.test_proceed, TEST_TIMEOUT);
	zassert_ok(ret, "Exchange not completed in required time");
}

static void client_send_request_solicit(void)
{
	int ret;

	client_prepare_test_msg(
		net_ipv4_unspecified_address(), net_ipv4_broadcast_address(),
		NET_DHCPV4_MSG_TYPE_REQUEST, &server_addr, &test_ctx.assigned_ip,
		NULL);

	/* Wait for reply */
	ret = k_sem_take(&test_ctx.test_proceed, TEST_TIMEOUT);
	zassert_ok(ret, "Exchange not completed in required time");
}

static void client_send_request_renew(void)
{
	int ret;

	client_prepare_test_msg(
		&test_ctx.assigned_ip, &server_addr,
		NET_DHCPV4_MSG_TYPE_REQUEST, NULL, NULL,
		&test_ctx.assigned_ip);

	/* Wait for reply */
	ret = k_sem_take(&test_ctx.test_proceed, TEST_TIMEOUT);
	zassert_ok(ret, "Exchange not completed in required time");
}

static void client_send_request_rebind(void)
{
	int ret;

	client_prepare_test_msg(
		&test_ctx.assigned_ip, net_ipv4_broadcast_address(),
		NET_DHCPV4_MSG_TYPE_REQUEST, NULL, NULL,
		&test_ctx.assigned_ip);

	/* Wait for reply */
	ret = k_sem_take(&test_ctx.test_proceed, TEST_TIMEOUT);
	zassert_ok(ret, "Exchange not completed in required time");
}

static void client_send_release(void)
{
	client_prepare_test_msg(
		&test_ctx.assigned_ip, &server_addr,
		NET_DHCPV4_MSG_TYPE_RELEASE, &server_addr, NULL,
		&test_ctx.assigned_ip);

	/* Small delay to let the DHCP server process the packet */
	k_msleep(10);
}

static void client_send_decline(void)
{
	client_prepare_test_msg(
		net_ipv4_unspecified_address(), net_ipv4_broadcast_address(),
		NET_DHCPV4_MSG_TYPE_DECLINE, &server_addr,
		&test_ctx.assigned_ip, NULL);

	/* Small delay to let the DHCP server process the packet */
	k_msleep(10);
}

static void client_send_inform(void)
{
	int ret;

	client_prepare_test_msg(
		&client_addr_static, net_ipv4_broadcast_address(),
		NET_DHCPV4_MSG_TYPE_INFORM, NULL, NULL, &client_addr_static);

	/* Wait for reply */
	ret = k_sem_take(&test_ctx.test_proceed, TEST_TIMEOUT);
	zassert_ok(ret, "Exchange not completed in required time");
}

static void lease_count_cb(struct net_if *iface, struct dhcpv4_addr_slot *lease,
			   void *user_data)
{
	struct test_lease_count *count = user_data;

	switch (lease->state) {
	case DHCPV4_SERVER_ADDR_RESERVED:
		count->reserved++;
		break;

	case DHCPV4_SERVER_ADDR_ALLOCATED:
		count->allocated++;
		break;

	case DHCPV4_SERVER_ADDR_DECLINED:
		count->declined++;
		break;

	default:
		break;
	}
}

static void test_get_lease_count(struct test_lease_count *count)
{
	int ret;

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

	ret = net_dhcpv4_server_foreach_lease(test_ctx.iface, lease_count_cb,
					      count);
	zassert_ok(ret, "Failed to obtain lease count");
}

static void verify_lease_count(int reserved, int allocated, int declined)
{
	struct test_lease_count count;

	test_get_lease_count(&count);
	zassert_equal(count.reserved, reserved,
		      "Incorrect %s count, expected %d got %d", "reserved",
		      reserved, count.reserved);
	zassert_equal(count.allocated, allocated,
		      "Incorrect %s count, expected %d got %d", "allocated",
		      allocated, count.allocated);
	zassert_equal(count.declined, declined,
		      "Incorrect %s count, expected %d got %d", "declined",
		      declined, count.declined);
}

static void get_reserved_cb(struct net_if *iface,
			    struct dhcpv4_addr_slot *lease,
			    void *user_data)
{
	struct in_addr *reserved = user_data;

	if (lease->state == DHCPV4_SERVER_ADDR_RESERVED) {
		reserved->s_addr = lease->addr.s_addr;
	}
}

static void get_reserved_address(struct in_addr *reserved)
{
	int ret;

	ret = net_dhcpv4_server_foreach_lease(test_ctx.iface,
					      get_reserved_cb,
					      reserved);
	zassert_ok(ret, "Failed to obtain reserved address");
}

static void client_get_lease(bool verify)
{
	client_send_discover();
	if (verify) {
		verify_lease_count(1, 0, 0);
	}
	get_reserved_address(&test_ctx.assigned_ip);
	test_pkt_free();

	client_send_request_solicit();
	if (verify) {
		verify_lease_count(0, 1, 0);
	}
	test_pkt_free();
}

static void verify_no_option(struct net_pkt *pkt, uint8_t opt_type)
{
	struct net_pkt_cursor cursor;

	net_pkt_cursor_backup(pkt, &cursor);

	while (true) {
		uint8_t type;
		uint8_t len;

		if (net_pkt_read_u8(pkt, &type) < 0) {
			break;
		}

		if (net_pkt_read_u8(pkt, &len) < 0) {
			break;
		}

		zassert_not_equal(type, opt_type,
				 "Option %d should not be present", opt_type);

		(void)net_pkt_skip(pkt, len);
	}

	net_pkt_cursor_restore(pkt, &cursor);
}

static void verify_option(struct net_pkt *pkt, uint8_t opt_type,
			  const void *optval, uint8_t optlen)
{
	struct net_pkt_cursor cursor;

	net_pkt_cursor_backup(pkt, &cursor);

	while (true) {
		static uint8_t buf[255];
		uint8_t type;
		uint8_t len;

		if (net_pkt_read_u8(pkt, &type) < 0) {
			break;
		}

		if (net_pkt_read_u8(pkt, &len) < 0) {
			break;
		}

		if (net_pkt_read(pkt, buf, len)) {
			break;
		}

		if (type == opt_type) {
			zassert_equal(len, optlen, "Invalid option length");
			zassert_mem_equal(buf, optval, optlen, "Invalid option value");

			net_pkt_cursor_restore(pkt, &cursor);
			return;
		}
	}

	zassert_true(false, "Option %d not found", opt_type);
}

static void verify_option_uint32(struct net_pkt *pkt, uint8_t opt_type,
				 uint32_t optval)
{
	optval = htonl(optval);

	verify_option(pkt, opt_type, &optval, sizeof(optval));
}

static void verify_option_uint8(struct net_pkt *pkt, uint8_t opt_type,
				uint8_t optval)
{
	verify_option(pkt, opt_type, &optval, sizeof(optval));
}

static void verify_offer(bool broadcast)
{
	NET_PKT_DATA_ACCESS_DEFINE(ipv4_access, struct net_ipv4_hdr);
	NET_PKT_DATA_ACCESS_DEFINE(udp_access, struct net_udp_hdr);
	NET_PKT_DATA_ACCESS_DEFINE(dhcp_access, struct dhcp_msg);
	uint8_t cookie_buf[SIZE_OF_MAGIC_COOKIE];
	struct net_pkt *pkt = test_ctx.pkt;
	struct net_ipv4_hdr *ipv4_hdr;
	struct net_udp_hdr *udp_hdr;
	struct dhcp_msg *msg;
	int ret;

	ipv4_hdr = (struct net_ipv4_hdr *)net_pkt_get_data(pkt, &ipv4_access);
	zassert_not_null(ipv4_hdr, "Failed to access IPv4 header.");
	net_pkt_acknowledge_data(pkt, &ipv4_access);

	udp_hdr = (struct net_udp_hdr *)net_pkt_get_data(pkt, &udp_access);
	zassert_not_null(udp_hdr, "Failed to access UDP header.");
	net_pkt_acknowledge_data(pkt, &udp_access);

	msg = (struct dhcp_msg *)net_pkt_get_data(pkt, &dhcp_access);
	zassert_not_null(msg, "Failed to access DHCP data.");
	net_pkt_acknowledge_data(pkt, &dhcp_access);

	/* IPv4 */
	zassert_mem_equal(ipv4_hdr->src, server_addr.s4_addr,
			  sizeof(struct in_addr), "Incorrect source address");
	if (broadcast) {
		zassert_mem_equal(ipv4_hdr->dst, net_ipv4_broadcast_address(),
				  sizeof(struct in_addr),
				  "Destination should be broadcast");
	} else {
		zassert_mem_equal(ipv4_hdr->dst, msg->yiaddr,
				  sizeof(struct in_addr),
				  "Destination should match address lease");
	}
	zassert_equal(ipv4_hdr->proto, IPPROTO_UDP, "Wrong protocol");

	/* UDP */
	zassert_equal(udp_hdr->src_port, htons(DHCPV4_SERVER_PORT),
		      "Wrong source port");
	zassert_equal(udp_hdr->dst_port, htons(DHCPV4_CLIENT_PORT),
		      "Wrong client port");

	/* DHCPv4 */
	zassert_equal(msg->op, DHCPV4_MSG_BOOT_REPLY, "Incorrect %s value", "op");
	zassert_equal(msg->htype, HARDWARE_ETHERNET_TYPE, "Incorrect %s value", "htype");
	zassert_equal(msg->hlen, sizeof(client_mac_addr), "Incorrect %s value", "hlen");
	zassert_equal(msg->hops, 0, "Incorrect %s value", "hops");
	zassert_equal(msg->xid, htonl(TEST_XID), "Incorrect %s value", "xid");
	zassert_equal(msg->secs, 0, "Incorrect %s value", "secs");
	zassert_equal(sys_get_be32(msg->ciaddr), 0, "Incorrect %s value", "ciaddr");
	zassert_true((sys_get_be32(msg->yiaddr) >=
			sys_get_be32(test_base_addr.s4_addr)) &&
		     (sys_get_be32(msg->yiaddr) <
			sys_get_be32(test_base_addr.s4_addr) +
				CONFIG_NET_DHCPV4_SERVER_ADDR_COUNT),
		     "Assigned DHCP address outside of address pool");
	zassert_equal(sys_get_be32(msg->siaddr), 0, "Incorrect %s value", "siaddr");
	if (broadcast) {
		zassert_equal(msg->flags, htons(DHCPV4_MSG_BROADCAST),
			      "Incorrect %s value", "flags");
	} else {
		zassert_equal(msg->flags, 0, "Incorrect %s value", "flags");
	}
	zassert_equal(sys_get_be32(msg->giaddr), 0, "Incorrect %s value", "giaddr");
	zassert_mem_equal(msg->chaddr, client_mac_addr, sizeof(client_mac_addr),
			  "Incorrect %s value", "chaddr");

	memcpy(&test_ctx.assigned_ip, msg->yiaddr, sizeof(struct in_addr));

	ret = net_pkt_skip(pkt, SIZE_OF_SNAME + SIZE_OF_FILE);
	zassert_ok(ret, "DHCP Offer too short");

	ret = net_pkt_read(pkt, cookie_buf, SIZE_OF_MAGIC_COOKIE);
	zassert_ok(ret, "DHCP Offer too short");
	zassert_mem_equal(cookie_buf, cookie, SIZE_OF_MAGIC_COOKIE,
			 "Incorrect cookie value");

	verify_option_uint32(pkt, DHCPV4_OPTIONS_LEASE_TIME,
			     CONFIG_NET_DHCPV4_SERVER_ADDR_LEASE_TIME);
	verify_option_uint8(pkt, DHCPV4_OPTIONS_MSG_TYPE,
			    NET_DHCPV4_MSG_TYPE_OFFER);
	verify_option(pkt, DHCPV4_OPTIONS_SERVER_ID, server_addr.s4_addr,
		      sizeof(struct in_addr));
	verify_option(pkt, DHCPV4_OPTIONS_CLIENT_ID, test_ctx.client_id,
		      strlen(test_ctx.client_id));
	verify_option(pkt, DHCPV4_OPTIONS_SUBNET_MASK, netmask.s4_addr,
		      sizeof(struct in_addr));
	verify_no_option(pkt, DHCPV4_OPTIONS_REQ_IPADDR);
	verify_no_option(pkt, DHCPV4_OPTIONS_REQ_LIST);
}

static void reserved_address_cb(struct net_if *iface,
				struct dhcpv4_addr_slot *lease,
				void *user_data)
{
	struct in_addr *reserved = user_data;

	zassert_equal(lease->state, DHCPV4_SERVER_ADDR_RESERVED,
		      "Wrong lease state");
	zassert_equal(reserved->s_addr, lease->addr.s_addr,
		      "Reserved wrong address");
}

static void verify_reserved_address(struct in_addr *reserved)
{
	int ret;

	ret = net_dhcpv4_server_foreach_lease(test_ctx.iface,
					      reserved_address_cb,
					      reserved);
	zassert_ok(ret, "Failed to verify reserved address");
}

/* Verify that the DHCP server replies with Offer for a Discover message. */
ZTEST(dhcpv4_server_tests, test_discover)
{
	client_send_discover();
	verify_offer(false);
	test_pkt_free();

	verify_lease_count(1, 0, 0);
	verify_reserved_address(&test_ctx.assigned_ip);
}

/* Verify that the DHCP server offers the same IP address for repeated Discover
 * message.
 */
ZTEST(dhcpv4_server_tests, test_discover_repeat)
{
	struct in_addr first_addr;

	client_send_discover();
	verify_offer(false);
	test_pkt_free();

	first_addr = test_ctx.assigned_ip;
	verify_lease_count(1, 0, 0);

	/* Repeat Discover with the same client ID */
	client_send_discover();
	verify_offer(false);
	test_pkt_free();

	verify_lease_count(1, 0, 0);
	zassert_equal(first_addr.s_addr, test_ctx.assigned_ip.s_addr,
		      "Received different address for the same client ID");

	/* Send Discover with a different client ID */
	test_ctx.client_id = CLIENT_ID_2;

	client_send_discover();
	verify_offer(false);
	test_pkt_free();

	verify_lease_count(2, 0, 0);
	zassert_not_equal(first_addr.s_addr, test_ctx.assigned_ip.s_addr,
			  "Received same address for the different client ID");
}

/* Verify that the DHCP server replies to broadcast address if broadcast flag
 * is set.
 */
ZTEST(dhcpv4_server_tests, test_discover_with_broadcast)
{
	test_ctx.broadcast = true;

	client_send_discover();
	verify_offer(true);
	verify_lease_count(1, 0, 0);
	test_pkt_free();
}

static void verify_ack(bool inform, bool renew)
{
	NET_PKT_DATA_ACCESS_DEFINE(ipv4_access, struct net_ipv4_hdr);
	NET_PKT_DATA_ACCESS_DEFINE(udp_access, struct net_udp_hdr);
	NET_PKT_DATA_ACCESS_DEFINE(dhcp_access, struct dhcp_msg);
	uint8_t cookie_buf[SIZE_OF_MAGIC_COOKIE];
	struct net_pkt *pkt = test_ctx.pkt;
	struct net_ipv4_hdr *ipv4_hdr;
	struct net_udp_hdr *udp_hdr;
	struct dhcp_msg *msg;
	int ret;

	ipv4_hdr = (struct net_ipv4_hdr *)net_pkt_get_data(pkt, &ipv4_access);
	zassert_not_null(ipv4_hdr, "Failed to access IPv4 header.");
	net_pkt_acknowledge_data(pkt, &ipv4_access);

	udp_hdr = (struct net_udp_hdr *)net_pkt_get_data(pkt, &udp_access);
	zassert_not_null(udp_hdr, "Failed to access UDP header.");
	net_pkt_acknowledge_data(pkt, &udp_access);

	msg = (struct dhcp_msg *)net_pkt_get_data(pkt, &dhcp_access);
	zassert_not_null(msg, "Failed to access DHCP data.");
	net_pkt_acknowledge_data(pkt, &dhcp_access);

	/* IPv4 */
	zassert_mem_equal(ipv4_hdr->src, server_addr.s4_addr,
			  sizeof(struct in_addr), "Incorrect source address");
	if (inform || renew) {
		zassert_mem_equal(ipv4_hdr->dst, msg->ciaddr, sizeof(struct in_addr),
				  "Destination should match client address");
	} else {
		zassert_mem_equal(ipv4_hdr->dst, msg->yiaddr, sizeof(struct in_addr),
				  "Destination should match client address");
	}

	zassert_equal(ipv4_hdr->proto, IPPROTO_UDP, "Wrong protocol");

	/* UDP */
	zassert_equal(udp_hdr->src_port, htons(DHCPV4_SERVER_PORT),
		      "Wrong source port");
	zassert_equal(udp_hdr->dst_port, htons(DHCPV4_CLIENT_PORT),
		      "Wrong client port");

	/* DHCPv4 */
	zassert_equal(msg->op, DHCPV4_MSG_BOOT_REPLY, "Incorrect %s value", "op");
	zassert_equal(msg->htype, HARDWARE_ETHERNET_TYPE, "Incorrect %s value", "htype");
	zassert_equal(msg->hlen, sizeof(client_mac_addr), "Incorrect %s value", "hlen");
	zassert_equal(msg->hops, 0, "Incorrect %s value", "hops");
	zassert_equal(msg->xid, htonl(TEST_XID), "Incorrect %s value", "xid");
	zassert_equal(msg->secs, 0, "Incorrect %s value", "secs");

	if (inform) {
		zassert_mem_equal(msg->ciaddr, client_addr_static.s4_addr,
				  sizeof(struct in_addr),
				  "Incorrect %s value", "ciaddr");
	} else if (renew) {
		zassert_mem_equal(msg->ciaddr, test_ctx.assigned_ip.s4_addr,
				  sizeof(struct in_addr),
				  "Incorrect %s value", "ciaddr");
	} else {
		zassert_equal(sys_get_be32(msg->ciaddr), 0, "Incorrect %s value", "ciaddr");
	}

	if (inform) {
		zassert_equal(sys_get_be32(msg->yiaddr), 0, "Incorrect %s value", "yiaddr");
	} else {
		zassert_mem_equal(msg->yiaddr, test_ctx.assigned_ip.s4_addr,
				  sizeof(struct in_addr), "Incorrect %s value", "yiaddr");
	}

	zassert_equal(sys_get_be32(msg->siaddr), 0, "Incorrect %s value", "siaddr");
	zassert_equal(msg->flags, 0, "Incorrect %s value", "flags");
	zassert_equal(sys_get_be32(msg->giaddr), 0, "Incorrect %s value", "giaddr");
	zassert_mem_equal(msg->chaddr, client_mac_addr, sizeof(client_mac_addr),
			  "Incorrect %s value", "chaddr");

	if (!inform) {
		memcpy(&test_ctx.assigned_ip, msg->yiaddr, sizeof(struct in_addr));
	}

	ret = net_pkt_skip(pkt, SIZE_OF_SNAME + SIZE_OF_FILE);
	zassert_ok(ret, "DHCP Offer too short");

	ret = net_pkt_read(pkt, cookie_buf, SIZE_OF_MAGIC_COOKIE);
	zassert_ok(ret, "DHCP Offer too short");
	zassert_mem_equal(cookie_buf, cookie, SIZE_OF_MAGIC_COOKIE,
			 "Incorrect cookie value");

	if (inform) {
		verify_no_option(pkt, DHCPV4_OPTIONS_LEASE_TIME);
	} else {
		verify_option_uint32(pkt, DHCPV4_OPTIONS_LEASE_TIME,
				     CONFIG_NET_DHCPV4_SERVER_ADDR_LEASE_TIME);
	}

	verify_option_uint8(pkt, DHCPV4_OPTIONS_MSG_TYPE,
			    NET_DHCPV4_MSG_TYPE_ACK);
	verify_option(pkt, DHCPV4_OPTIONS_SERVER_ID, server_addr.s4_addr,
		      sizeof(struct in_addr));
	if (inform) {
		verify_no_option(pkt, DHCPV4_OPTIONS_CLIENT_ID);
	} else {
		verify_option(pkt, DHCPV4_OPTIONS_CLIENT_ID, test_ctx.client_id,
			      strlen(test_ctx.client_id));
	}
	verify_option(pkt, DHCPV4_OPTIONS_SUBNET_MASK, netmask.s4_addr,
		      sizeof(struct in_addr));
	verify_no_option(pkt, DHCPV4_OPTIONS_REQ_IPADDR);
	verify_no_option(pkt, DHCPV4_OPTIONS_REQ_LIST);
}

static void allocated_address_cb(struct net_if *iface,
				 struct dhcpv4_addr_slot *lease,
				 void *user_data)
{
	struct in_addr *allocated = user_data;

	zassert_equal(lease->state, DHCPV4_SERVER_ADDR_ALLOCATED,
		      "Wrong lease state");
	zassert_equal(allocated->s_addr, lease->addr.s_addr,
		      "Reserved wrong address");
}

static void verify_allocated_address(struct in_addr *allocated)
{
	int ret;

	ret = net_dhcpv4_server_foreach_lease(test_ctx.iface,
					      allocated_address_cb,
					      allocated);
	zassert_ok(ret, "Failed to verify allocated address");
}

/* Verify that the DHCP server replies with ACK for a Request message. */
ZTEST(dhcpv4_server_tests, test_request)
{
	client_send_discover();
	verify_offer(false);
	verify_lease_count(1, 0, 0);
	test_pkt_free();

	client_send_request_solicit();
	verify_ack(false, false);
	verify_lease_count(0, 1, 0);
	verify_allocated_address(&test_ctx.assigned_ip);
	test_pkt_free();
}

/* Verify that the DHCP server replies with ACK for a Request message
 * (renewing).
 */
ZTEST(dhcpv4_server_tests, test_renew)
{
	client_get_lease(true);

	client_send_request_renew();
	verify_ack(false, true);
	verify_lease_count(0, 1, 0);
	test_pkt_free();
}

/* Verify that the DHCP server replies with ACK for a Request message
 * (rebinding).
 */
ZTEST(dhcpv4_server_tests, test_rebind)
{
	client_get_lease(true);

	client_send_request_rebind();
	verify_ack(false, true);
	verify_lease_count(0, 1, 0);
	test_pkt_free();
}

/* Verify that the DHCP server lease expires after the lease timeout. */
ZTEST(dhcpv4_server_tests, test_expiry)
{
	test_ctx.lease_time = 1;
	client_get_lease(true);

	/* Add extra 10ms to avoid race. */
	k_msleep(1000 + 10);
	verify_lease_count(0, 0, 0);
}

/* Verify that the DHCP server releases the lease after receiving Release
 * message.
 */
ZTEST(dhcpv4_server_tests, test_release)
{
	client_get_lease(true);

	client_send_release();
	verify_lease_count(0, 0, 0);
}

static void declined_address_cb(struct net_if *iface,
				struct dhcpv4_addr_slot *lease,
				void *user_data)
{
	struct in_addr *declined = user_data;

	zassert_equal(lease->state, DHCPV4_SERVER_ADDR_DECLINED,
		      "Wrong lease state");
	zassert_equal(declined->s_addr, lease->addr.s_addr,
		      "Declined wrong address");
}

static void verify_declined_address(struct in_addr *declined)
{
	int ret;

	ret = net_dhcpv4_server_foreach_lease(test_ctx.iface,
					      declined_address_cb,
					      declined);
	zassert_ok(ret, "Failed to verify declined address");
}

/* Verify that the DHCP server blocks the address after receiving Decline
 * message, and gets released after configured time.
 */
ZTEST(dhcpv4_server_tests, test_decline)
{
	client_get_lease(true);
	verify_lease_count(0, 1, 0);

	client_send_decline();
	verify_lease_count(0, 0, 1);
	verify_declined_address(&test_ctx.assigned_ip);

	/* Add extra 10ms to avoid race. */
	k_msleep(1000 + 10);
	verify_lease_count(0, 0, 0);
}

/* Verify that if all of the address leases get blocked (due to conflict), the
 * server will try to reuse the oldest blocked entry on Discovery.
 */
ZTEST(dhcpv4_server_tests, test_declined_reuse)
{
	struct in_addr oldest_addr;

	for (int i = 0; i < CONFIG_NET_DHCPV4_SERVER_ADDR_COUNT; i++) {
		client_get_lease(false);
		if (i == 0) {
			oldest_addr = test_ctx.assigned_ip;
		}
		client_send_decline();
		k_msleep(10);
	}

	verify_lease_count(0, 0, 4);

	client_send_discover();
	verify_offer(false);
	verify_lease_count(1, 0, 3);
	test_pkt_free();

	client_send_request_solicit();
	verify_ack(false, false);
	verify_lease_count(0, 1, 3);
	test_pkt_free();

	zassert_equal(oldest_addr.s_addr, test_ctx.assigned_ip.s_addr,
		      "Should've reassing oldest declined address");
}

/* Verify that the DHCP server replies with ACK for a Inform message, w/o
 * address assignment.
 */
ZTEST(dhcpv4_server_tests, test_inform)
{
	client_send_inform();
	verify_ack(true, false);
	verify_lease_count(0, 0, 0);
}

static void after_probe_address_cb(struct net_if *iface,
				struct dhcpv4_addr_slot *lease,
				void *user_data)
{
	if (lease->state == DHCPV4_SERVER_ADDR_DECLINED) {
		zassert_equal(test_ctx.declined_ip.s_addr, lease->addr.s_addr,
			      "Declined wrong address");
	}

	if (lease->state == DHCPV4_SERVER_ADDR_RESERVED) {
		zassert_equal(test_ctx.assigned_ip.s_addr, lease->addr.s_addr,
			      "Reserved wrong address");
	}
}

static void verify_address_after_probe(void)
{
	int ret;

	ret = net_dhcpv4_server_foreach_lease(test_ctx.iface,
					      after_probe_address_cb,
					      NULL);
	zassert_ok(ret, "Failed to verify address after probe");
}

/* Verify that if the server detects conflict with ICMP probe, it assigns
 * different address.
 */
ZTEST(dhcpv4_server_tests, test_icmp_probe)
{
	if (CONFIG_NET_DHCPV4_SERVER_ICMP_PROBE_TIMEOUT == 0) {
		ztest_test_skip();
	}

	test_ctx.send_echo_reply = true;

	client_send_discover();
	verify_offer(false);
	test_pkt_free();

	verify_lease_count(1, 0, 1);
	zassert_not_equal(test_ctx.assigned_ip.s_addr,
			  test_ctx.declined_ip.s_addr,
			  "DHCPv4 srever offered conflicted address");
	verify_address_after_probe();
}

/* Verify that the DHCP server can start and validate input properly. */
ZTEST(dhcpv4_server_tests_no_init, test_initialization)
{
	struct in_addr base_addr_wrong_subnet = { { { 192, 0, 3, 10 } } };
	struct in_addr base_addr_overlap = { { { 192, 0, 2, 1 } } };
	int ret;

	ret = net_dhcpv4_server_start(test_ctx.iface, &base_addr_wrong_subnet);
	zassert_equal(ret, -EINVAL, "Started server for wrong subnet");

	ret = net_dhcpv4_server_start(test_ctx.iface, &base_addr_overlap);
	zassert_equal(ret, -EINVAL, "Started server for overlapping address");

	ret = net_dhcpv4_server_start(test_ctx.iface, &test_base_addr);
	zassert_ok(ret, "Failed to start server for valid address range");

	net_dhcpv4_server_stop(test_ctx.iface);
}

static void dhcpv4_server_tests_before(void *fixture)
{
	ARG_UNUSED(fixture);

	k_sem_init(&test_ctx.test_proceed, 0, 1);
	test_ctx.client_id = CLIENT_ID_1;
	test_ctx.broadcast = false;
	test_ctx.pkt = NULL;
	test_ctx.lease_time = NO_LEASE_TIME;
	test_ctx.send_echo_reply = false;
	memset(&test_ctx.assigned_ip, 0, sizeof(test_ctx.assigned_ip));

	net_dhcpv4_server_start(test_ctx.iface, &test_base_addr);
}

static void dhcpv4_server_tests_after(void *fixture)
{
	ARG_UNUSED(fixture);

	test_pkt_free();

	net_dhcpv4_server_stop(test_ctx.iface);
}

ZTEST_SUITE(dhcpv4_server_tests, NULL, NULL, dhcpv4_server_tests_before,
	    dhcpv4_server_tests_after, NULL);

ZTEST_SUITE(dhcpv4_server_tests_no_init, NULL, NULL, NULL, NULL, NULL);
