/* main.c - Application main entry point */

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

#include <logging/log.h>
LOG_MODULE_REGISTER(net_test, CONFIG_NET_ICMPV4_LOG_LEVEL);

#include <errno.h>
#include <zephyr/types.h>
#include <stddef.h>
#include <string.h>
#include <sys/printk.h>
#include <linker/sections.h>

#include <tc_util.h>

#include <net/buf.h>

#include "net_private.h"
#include "icmpv4.h"

#include <ztest.h>

static int handler_called;
static int handler_status;

static const unsigned char icmpv4_echo_req[] = {
	/* IPv4 Header */
	0x45, 0x00, 0x00, 0x54, 0xea, 0x8c, 0x40, 0x00,
	0x40, 0x01, 0xcc, 0x18, 0xc0, 0x00, 0x02, 0x02,
	0xc0, 0x00, 0x02, 0x01,
	/* ICMP Header (Echo Request) */
	0x08, 0x00, 0xe3, 0x7c,
	0x10, 0x63, 0x00, 0x01,
	/* Payload */
	0xb8, 0xa4, 0x8c, 0x5d, 0x00, 0x00, 0x00, 0x00,
	0xfc, 0x49, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 };

static const unsigned char icmpv4_echo_rep[] = {
	/* IPv4 Header */
	0x45, 0x00, 0x00, 0x20, 0x75, 0xac, 0x00, 0x00,
	0x40, 0x01, 0x81, 0x2d, 0xc0, 0x00, 0x02, 0x02,
	0xc0, 0x00, 0x02, 0x01,
	/* ICMP Header (Echo Reply)*/
	0x00, 0x00, 0x91, 0x12,
	0x16, 0x50, 0x00, 0x00, 0x01, 0xfd, 0x56, 0xa0 };

static const unsigned char icmpv4_echo_req_opt[] = {

	/* IPv4 Header */
	0x4e, 0x00, 0x00, 0x78, 0xe1, 0x4b, 0x40, 0x00,
	0x40, 0x01, 0x9a, 0x83, 0xc0, 0x00, 0x02, 0x02,
	0xc0, 0x00, 0x02, 0x01,
	/* IPv4 Header Options (Timestamp) */
	0x44, 0x24, 0x0d, 0x01, 0xc0, 0x00, 0x02, 0x02,
	0x02, 0x4d, 0x1c, 0x3d, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	/* ICMP Header (Echo Request) */
	0x08, 0x00, 0x35, 0xbf,
	0x5d, 0xe7, 0x00, 0x01,
	0xcf, 0xe7, 0x8d, 0x5d, 0x00, 0x00, 0x00, 0x00,
	/* Payload */
	0x3a, 0x40, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 };

static enum net_verdict handle_reply_msg(struct net_pkt *pkt,
					 struct net_ipv4_hdr *ip_hdr,
					 struct net_icmp_hdr *icmp_hdr)
{
	enum net_verdict ret;

	handler_called++;

	if (net_pkt_get_len(pkt) != sizeof(icmpv4_echo_rep)) {
		goto fail;
	}

	handler_status = 0;
	ret = NET_OK;

	return ret;

fail:
	handler_status = -EINVAL;
	ret = NET_DROP;

	return ret;
}

static enum net_verdict handle_request_msg(struct net_pkt *pkt,
					   struct net_ipv4_hdr *ip_hdr,
					   struct net_icmp_hdr *icmp_hdr)
{
	enum net_verdict ret;

	handler_called++;

	if (net_pkt_get_len(pkt) != sizeof(icmpv4_echo_req)) {
		goto fail;
	}

	handler_status = 0;
	ret = NET_OK;

	return ret;

fail:
	handler_status = -EINVAL;
	ret = NET_DROP;

	return ret;
}

static enum net_verdict handle_request_opt_msg(struct net_pkt *pkt,
					       struct net_ipv4_hdr *ip_hdr,
					       struct net_icmp_hdr *icmp_hdr)
{
	enum net_verdict ret;

	handler_called++;

	if (net_pkt_get_len(pkt) != sizeof(icmpv4_echo_req_opt)) {
		goto fail;
	}

	handler_status = 0;
	ret = NET_OK;

	return ret;

fail:
	handler_status = -EINVAL;
	ret = NET_DROP;

	return ret;
}

static struct net_icmpv4_handler echo_rep_handler = {
	.type = NET_ICMPV4_ECHO_REPLY,
	.code = 0,
	.handler = handle_reply_msg,
};

static struct net_icmpv4_handler echo_req_handler = {
	.type = NET_ICMPV4_ECHO_REQUEST,
	.code = 0,
	.handler = handle_request_msg,
};

static struct net_icmpv4_handler echo_req_opt_handler = {
	.type = NET_ICMPV4_ECHO_REQUEST,
	.code = 0,
	.handler = handle_request_opt_msg,
};

void test_icmpv4(void)
{
	k_thread_priority_set(k_current_get(), K_PRIO_COOP(7));

	struct net_ipv4_hdr *hdr;
	struct net_pkt *pkt;
	int ret;

	/* ================ Echo Request ================= */
	net_icmpv4_register_handler(&echo_req_handler);

	pkt = net_pkt_alloc_with_buffer(NULL, sizeof(icmpv4_echo_req),
					AF_UNSPEC, 0, K_SECONDS(1));
	net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv4_hdr));

	zassert_not_null(pkt, "Allocation failed");

	net_pkt_write(pkt, icmpv4_echo_req, sizeof(icmpv4_echo_req));

	net_pkt_cursor_init(pkt);

	net_pkt_set_ipv4_opts_len(pkt, 0);
	net_pkt_set_overwrite(pkt, true);

	net_pkt_skip(pkt, sizeof(struct net_ipv4_hdr));

	hdr = (struct net_ipv4_hdr *)pkt->buffer->data;

	ret = net_icmpv4_input(pkt, hdr);

	/** TESTPOINT: Check input */
	zassert_true(!(ret == NET_DROP || handler_status != 0),
			"Callback not called properly");

	/** TESTPOINT: Check input */
	zassert_true(!(handler_called != 1), "Callbacks not called properly");

	net_icmpv4_unregister_handler(&echo_req_handler);

	net_pkt_unref(pkt);

	/* ================ Echo Reply ================= */
	net_icmpv4_register_handler(&echo_rep_handler);

	pkt = net_pkt_alloc_with_buffer(NULL, sizeof(icmpv4_echo_rep),
					AF_UNSPEC, 0, K_SECONDS(1));
	net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv4_hdr));

	zassert_not_null(pkt, "Allocation failed");

	net_pkt_write(pkt, icmpv4_echo_rep, sizeof(icmpv4_echo_rep));

	net_pkt_cursor_init(pkt);

	net_pkt_set_ipv4_opts_len(pkt, 0);
	net_pkt_set_overwrite(pkt, true);

	net_pkt_skip(pkt, sizeof(struct net_ipv4_hdr));

	hdr = (struct net_ipv4_hdr *)pkt->buffer->data;

	ret = net_icmpv4_input(pkt, hdr);

	/** TESTPOINT: Check input */
	zassert_true(!(ret == NET_DROP || handler_status != 0),
			"Callback not called properly");

	/** TESTPOINT: Check input */
	zassert_true(!(handler_called != 2), "Callbacks not called properly");

	net_icmpv4_unregister_handler(&echo_rep_handler);

	net_pkt_unref(pkt);

	/* ================ Echo Request with Options  ================= */
	net_icmpv4_register_handler(&echo_req_opt_handler);

	pkt = net_pkt_alloc_with_buffer(NULL, sizeof(icmpv4_echo_req_opt),
					AF_UNSPEC, 0, K_SECONDS(1));
	net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv4_hdr));

	zassert_not_null(pkt, "Allocation failed");

	net_pkt_write(pkt, icmpv4_echo_req_opt, sizeof(icmpv4_echo_req_opt));

	net_pkt_cursor_init(pkt);

	net_pkt_set_ipv4_opts_len(pkt, 36);
	net_pkt_set_overwrite(pkt, true);

	net_pkt_skip(pkt, sizeof(struct net_ipv4_hdr)); /* Header*/
	net_pkt_skip(pkt, 36); /* Options length */

	hdr = (struct net_ipv4_hdr *)pkt->buffer->data;

	ret = net_icmpv4_input(pkt, hdr);

	/** TESTPOINT: Check input */
	zassert_true(!(ret == NET_DROP || handler_status != 0),
			"Callback not called properly");

	/** TESTPOINT: Check input */
	zassert_true(!(handler_called != 3), "Callbacks not called properly");

	net_icmpv4_unregister_handler(&echo_req_opt_handler);

	net_pkt_unref(pkt);
}

/**test case main entry*/
void test_main(void)
{
	ztest_test_suite(test_icmpv4_fn,
		ztest_unit_test(test_icmpv4));
	ztest_run_test_suite(test_icmpv4_fn);
}
