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

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

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

#include <zephyr/zephyr.h>
#include <zephyr/linker/sections.h>

#include <tc_util.h>

#include <zephyr/types.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <zephyr/device.h>
#include <zephyr/init.h>
#include <zephyr/net/net_core.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/net/net_ip.h>
#include <zephyr/net/dummy.h>
#include <ztest.h>
#include <zephyr/random/rand32.h>

#include "arp.h"

#define NET_LOG_ENABLED 1
#include "net_private.h"

static bool req_test;

static char *app_data = "0123456789";

static bool entry_found;
static struct net_eth_addr *expected_hwaddr;

static struct net_pkt *pending_pkt;

static struct net_eth_addr hwaddr = { { 0x42, 0x11, 0x69, 0xde, 0xfa, 0xec } };

static int send_status = -EINVAL;

struct net_arp_context {
	uint8_t mac_addr[sizeof(struct net_eth_addr)];
	struct net_linkaddr ll_addr;
};

int net_arp_dev_init(const struct device *dev)
{
	struct net_arp_context *net_arp_context = dev->data;

	net_arp_context = net_arp_context;

	return 0;
}

static uint8_t *net_arp_get_mac(const struct device *dev)
{
	struct net_arp_context *context = dev->data;

	if (context->mac_addr[2] == 0x00) {
		/* 00-00-5E-00-53-xx Documentation RFC 7042 */
		context->mac_addr[0] = 0x00;
		context->mac_addr[1] = 0x00;
		context->mac_addr[2] = 0x5E;
		context->mac_addr[3] = 0x00;
		context->mac_addr[4] = 0x53;
		context->mac_addr[5] = sys_rand32_get();
	}

	return context->mac_addr;
}

static void net_arp_iface_init(struct net_if *iface)
{
	uint8_t *mac = net_arp_get_mac(net_if_get_device(iface));

	net_if_set_link_addr(iface, mac, 6, NET_LINK_ETHERNET);
}

static int tester_send(const struct device *dev, struct net_pkt *pkt)
{
	struct net_eth_hdr *hdr;

	if (!pkt->buffer) {
		printk("No data to send!\n");
		return -ENODATA;
	}

	hdr = (struct net_eth_hdr *)net_pkt_data(pkt);

	if (ntohs(hdr->type) == NET_ETH_PTYPE_ARP) {
		/* First frag has eth hdr */
		struct net_arp_hdr *arp_hdr =
			(struct net_arp_hdr *)pkt->frags->frags;

		if (ntohs(arp_hdr->opcode) == NET_ARP_REPLY) {
			if (!req_test && pkt != pending_pkt) {
				printk("Pending data but to be sent is wrong, "
				       "expecting %p but got %p\n",
				       pending_pkt, pkt);
				return -EINVAL;
			}

			if (!req_test && memcmp(&hdr->dst, &hwaddr,
						sizeof(struct net_eth_addr))) {
				char out[sizeof("xx:xx:xx:xx:xx:xx")];

				snprintk(out, sizeof(out), "%s",
					 net_sprint_ll_addr(
						 (uint8_t *)&hdr->dst,
						 sizeof(struct net_eth_addr)));
				printk("Invalid dst hwaddr %s, should be %s\n",
				       out,
				       net_sprint_ll_addr(
					       (uint8_t *)&hwaddr,
					       sizeof(struct net_eth_addr)));
				send_status = -EINVAL;
				return send_status;
			}

		} else if (ntohs(arp_hdr->opcode) == NET_ARP_REQUEST) {
			if (memcmp(&hdr->src, &hwaddr,
				   sizeof(struct net_eth_addr))) {
				char out[sizeof("xx:xx:xx:xx:xx:xx")];

				snprintk(out, sizeof(out), "%s",
					 net_sprint_ll_addr(
						 (uint8_t *)&hdr->src,
						 sizeof(struct net_eth_addr)));
				printk("Invalid src hwaddr %s, should be %s\n",
				       out,
				       net_sprint_ll_addr(
					       (uint8_t *)&hwaddr,
					       sizeof(struct net_eth_addr)));
				send_status = -EINVAL;
				return send_status;
			}
		}
	}

	send_status = 0;

	return 0;
}

static inline struct in_addr *if_get_addr(struct net_if *iface)
{
	int i;

	for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) {
		if (iface->config.ip.ipv4->unicast[i].is_used &&
		    iface->config.ip.ipv4->unicast[i].address.family ==
								AF_INET &&
		    iface->config.ip.ipv4->unicast[i].addr_state ==
							NET_ADDR_PREFERRED) {
			return
			    &iface->config.ip.ipv4->unicast[i].address.in_addr;
		}
	}

	return NULL;
}

static inline struct net_pkt *prepare_arp_reply(struct net_if *iface,
						struct net_pkt *req,
						struct net_eth_addr *addr,
						struct net_eth_hdr **eth_rep)
{
	struct net_pkt *pkt;
	struct net_arp_hdr *hdr;
	struct net_eth_hdr *eth;

	pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_eth_hdr) +
					sizeof(struct net_eth_hdr) +
					sizeof(struct net_arp_hdr),
					AF_UNSPEC, 0, K_SECONDS(1));
	zassert_not_null(pkt, "out of mem reply");

	eth = NET_ETH_HDR(pkt);

	net_buf_add(pkt->buffer, sizeof(struct net_eth_hdr));
	net_buf_pull(pkt->buffer, sizeof(struct net_eth_hdr));

	(void)memset(&eth->dst.addr, 0xff, sizeof(struct net_eth_addr));
	memcpy(&eth->src.addr, net_if_get_link_addr(iface)->addr,
	       sizeof(struct net_eth_addr));
	eth->type = htons(NET_ETH_PTYPE_ARP);

	*eth_rep = eth;

	net_buf_add(pkt->buffer, sizeof(struct net_eth_hdr));
	net_buf_pull(pkt->buffer, sizeof(struct net_eth_hdr));

	hdr = NET_ARP_HDR(pkt);

	hdr->hwtype = htons(NET_ARP_HTYPE_ETH);
	hdr->protocol = htons(NET_ETH_PTYPE_IP);
	hdr->hwlen = sizeof(struct net_eth_addr);
	hdr->protolen = sizeof(struct in_addr);
	hdr->opcode = htons(NET_ARP_REPLY);

	memcpy(&hdr->dst_hwaddr.addr, &eth->src.addr,
	       sizeof(struct net_eth_addr));
	memcpy(&hdr->src_hwaddr.addr, addr,
	       sizeof(struct net_eth_addr));

	net_ipv4_addr_copy_raw(hdr->dst_ipaddr, NET_ARP_HDR(req)->src_ipaddr);
	net_ipv4_addr_copy_raw(hdr->src_ipaddr, NET_ARP_HDR(req)->dst_ipaddr);

	net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));

	return pkt;
}

static inline struct net_pkt *prepare_arp_request(struct net_if *iface,
						  struct net_pkt *req,
						  struct net_eth_addr *addr,
						  struct net_eth_hdr **eth_hdr)
{
	struct net_pkt *pkt;
	struct net_arp_hdr *hdr, *req_hdr;
	struct net_eth_hdr *eth, *eth_req;

	pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_eth_hdr) +
					sizeof(struct net_arp_hdr),
					AF_UNSPEC, 0, K_SECONDS(1));
	zassert_not_null(pkt, "out of mem request");

	eth_req = NET_ETH_HDR(req);
	eth = NET_ETH_HDR(pkt);

	net_buf_add(req->buffer, sizeof(struct net_eth_hdr));
	net_buf_pull(req->buffer, sizeof(struct net_eth_hdr));

	req_hdr = NET_ARP_HDR(req);

	(void)memset(&eth->dst.addr, 0xff, sizeof(struct net_eth_addr));
	memcpy(&eth->src.addr, addr, sizeof(struct net_eth_addr));

	eth->type = htons(NET_ETH_PTYPE_ARP);
	*eth_hdr = eth;

	net_buf_add(pkt->buffer, sizeof(struct net_eth_hdr));
	net_buf_pull(pkt->buffer, sizeof(struct net_eth_hdr));

	hdr = NET_ARP_HDR(pkt);

	hdr->hwtype = htons(NET_ARP_HTYPE_ETH);
	hdr->protocol = htons(NET_ETH_PTYPE_IP);
	hdr->hwlen = sizeof(struct net_eth_addr);
	hdr->protolen = sizeof(struct in_addr);
	hdr->opcode = htons(NET_ARP_REQUEST);

	(void)memset(&hdr->dst_hwaddr.addr, 0x00, sizeof(struct net_eth_addr));
	memcpy(&hdr->src_hwaddr.addr, addr, sizeof(struct net_eth_addr));

	net_ipv4_addr_copy_raw(hdr->src_ipaddr, req_hdr->src_ipaddr);
	net_ipv4_addr_copy_raw(hdr->dst_ipaddr, req_hdr->dst_ipaddr);

	net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));

	return pkt;
}

static void setup_eth_header(struct net_if *iface, struct net_pkt *pkt,
			     const struct net_eth_addr *hwaddr, uint16_t type)
{
	struct net_eth_hdr *hdr = (struct net_eth_hdr *)net_pkt_data(pkt);

	memcpy(&hdr->dst.addr, hwaddr, sizeof(struct net_eth_addr));
	memcpy(&hdr->src.addr, net_if_get_link_addr(iface)->addr,
	       sizeof(struct net_eth_addr));

	hdr->type = htons(type);
}

struct net_arp_context net_arp_context_data;

#if defined(CONFIG_NET_ARP) && defined(CONFIG_NET_L2_ETHERNET)
static const struct ethernet_api net_arp_if_api = {
	.iface_api.init = net_arp_iface_init,
	.send = tester_send,
};

#define _ETH_L2_LAYER ETHERNET_L2
#define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(ETHERNET_L2)
#else
static const struct dummy_api net_arp_if_api = {
	.iface_api.init = net_arp_iface_init,
	.send = tester_send,
};

#define _ETH_L2_LAYER DUMMY_L2
#define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)
#endif

NET_DEVICE_INIT(net_arp_test, "net_arp_test",
		net_arp_dev_init, NULL,
		&net_arp_context_data, NULL,
		CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
		&net_arp_if_api, _ETH_L2_LAYER, _ETH_L2_CTX_TYPE, 127);

static void arp_cb(struct arp_entry *entry, void *user_data)
{
	struct in_addr *addr = user_data;

	if (memcmp(&entry->ip, addr, sizeof(struct in_addr)) == 0 &&
	    memcmp(&entry->eth, expected_hwaddr,
		   sizeof(struct net_eth_addr)) == 0) {
		entry_found = true;
	}
}

void test_arp(void)
{
	if (IS_ENABLED(CONFIG_NET_TC_THREAD_COOPERATIVE)) {
		k_thread_priority_set(k_current_get(),
				K_PRIO_COOP(CONFIG_NUM_COOP_PRIORITIES - 1));
	} else {
		k_thread_priority_set(k_current_get(), K_PRIO_PREEMPT(9));
	}

	struct net_eth_hdr *eth_hdr = NULL;
	struct net_pkt *pkt;
	struct net_pkt *pkt2;
	struct net_if *iface;
	struct net_if_addr *ifaddr;
	struct net_arp_hdr *arp_hdr;
	struct net_ipv4_hdr *ipv4;
	int len;

	struct in_addr dst = { { { 192, 168, 0, 2 } } };
	struct in_addr dst_far = { { { 10, 11, 12, 13 } } };
	struct in_addr dst_far2 = { { { 172, 16, 14, 186 } } };
	struct in_addr src = { { { 192, 168, 0, 1 } } };
	struct in_addr netmask = { { { 255, 255, 255, 0 } } };
	struct in_addr gw = { { { 192, 168, 0, 42 } } };

	net_arp_init();

	iface = net_if_lookup_by_dev(DEVICE_GET(net_arp_test));

	net_if_ipv4_set_gw(iface, &gw);
	net_if_ipv4_set_netmask(iface, &netmask);

	/* Unicast test */
	ifaddr = net_if_ipv4_addr_add(iface,
				      &src,
				      NET_ADDR_MANUAL,
				      0);
	zassert_not_null(ifaddr, "Cannot add address");
	ifaddr->addr_state = NET_ADDR_PREFERRED;

	len = strlen(app_data);

	/* Application data for testing */
	pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_ipv4_hdr) +
		len, AF_INET, 0, K_SECONDS(1));
	zassert_not_null(pkt, "out of mem");

	net_pkt_lladdr_src(pkt)->addr = (uint8_t *)net_if_get_link_addr(iface);
	net_pkt_lladdr_src(pkt)->len = sizeof(struct net_eth_addr);

	ipv4 = (struct net_ipv4_hdr *)net_buf_add(pkt->buffer,
						  sizeof(struct net_ipv4_hdr));
	net_ipv4_addr_copy_raw(ipv4->src, (uint8_t *)&src);
	net_ipv4_addr_copy_raw(ipv4->dst, (uint8_t *)&dst);

	memcpy(net_buf_add(pkt->buffer, len), app_data, len);

	pkt2 = net_arp_prepare(pkt, &dst, NULL);

	/* pkt2 is the ARP packet and pkt is the IPv4 packet and it was
	 * stored in ARP table.
	 */

	/**TESTPOINTS: Check packets*/
	zassert_not_equal((void *)(pkt2), (void *)(pkt),
		/* The packets cannot be the same as the ARP cache has
		 * still room for the pkt.
		 */
		"ARP cache should still have free space");

	zassert_not_null(pkt2, "ARP pkt is empty");

	/* The ARP cache should now have a link to pending net_pkt
	 * that is to be sent after we have got an ARP reply.
	 */
	zassert_not_null(pkt->buffer,
		"Pending pkt buffer is NULL");

	pending_pkt = pkt;

	/* pkt2 should contain the arp header, verify it */
	arp_hdr = NET_ARP_HDR(pkt2);

	if (arp_hdr->hwtype != htons(NET_ARP_HTYPE_ETH)) {
		printk("ARP hwtype 0x%x, should be 0x%x\n",
		       arp_hdr->hwtype, htons(NET_ARP_HTYPE_ETH));
		zassert_true(0, "exiting");
	}

	if (arp_hdr->protocol != htons(NET_ETH_PTYPE_IP)) {
		printk("ARP protocol 0x%x, should be 0x%x\n",
		       arp_hdr->protocol, htons(NET_ETH_PTYPE_IP));
		zassert_true(0, "exiting");
	}

	if (arp_hdr->hwlen != sizeof(struct net_eth_addr)) {
		printk("ARP hwlen 0x%x, should be 0x%zx\n",
		       arp_hdr->hwlen, sizeof(struct net_eth_addr));
		zassert_true(0, "exiting");
	}

	if (arp_hdr->protolen != sizeof(struct in_addr)) {
		printk("ARP IP addr len 0x%x, should be 0x%zx\n",
		       arp_hdr->protolen, sizeof(struct in_addr));
		zassert_true(0, "exiting");
	}

	if (arp_hdr->opcode != htons(NET_ARP_REQUEST)) {
		printk("ARP opcode 0x%x, should be 0x%x\n",
		       arp_hdr->opcode, htons(NET_ARP_REQUEST));
		zassert_true(0, "exiting");
	}

	if (!net_ipv4_addr_cmp_raw(arp_hdr->dst_ipaddr,
				   NET_IPV4_HDR(pkt)->dst)) {
		printk("ARP IP dest invalid %s, should be %s",
			net_sprint_ipv4_addr(&arp_hdr->dst_ipaddr),
			net_sprint_ipv4_addr(&NET_IPV4_HDR(pkt)->dst));
		zassert_true(0, "exiting");
	}

	if (!net_ipv4_addr_cmp_raw(arp_hdr->src_ipaddr,
				   NET_IPV4_HDR(pkt)->src)) {
		printk("ARP IP src invalid %s, should be %s",
			net_sprint_ipv4_addr(&arp_hdr->src_ipaddr),
			net_sprint_ipv4_addr(&NET_IPV4_HDR(pkt)->src));
		zassert_true(0, "exiting");
	}

	/* We could have send the new ARP request but for this test we
	 * just free it.
	 */
	net_pkt_unref(pkt2);

	zassert_equal(atomic_get(&pkt->atomic_ref), 2,
		"ARP cache should own the original packet");

	/* Then a case where target is not in the same subnet */
	net_ipv4_addr_copy_raw(ipv4->dst, (uint8_t *)&dst_far);

	pkt2 = net_arp_prepare(pkt, &dst_far, NULL);

	zassert_not_equal((void *)(pkt2), (void *)(pkt),
		"ARP cache should not find anything");

	/**TESTPOINTS: Check if packets not empty*/
	zassert_not_null(pkt2,
		"ARP pkt2 is empty");

	arp_hdr = NET_ARP_HDR(pkt2);

	if (!net_ipv4_addr_cmp_raw(arp_hdr->dst_ipaddr,
				   (uint8_t *)&iface->config.ip.ipv4->gw)) {
		printk("ARP IP dst invalid %s, should be %s\n",
			net_sprint_ipv4_addr(&arp_hdr->dst_ipaddr),
			net_sprint_ipv4_addr(&iface->config.ip.ipv4->gw));
		zassert_true(0, "exiting");
	}

	net_pkt_unref(pkt2);

	/* Try to find the same destination again, this should fail as there
	 * is a pending request in ARP cache.
	 */
	net_ipv4_addr_copy_raw(ipv4->dst, (uint8_t *)&dst_far);

	/* Make sure prepare will not free the pkt because it will be
	 * needed in the later test case.
	 */
	net_pkt_ref(pkt);

	pkt2 = net_arp_prepare(pkt, &dst_far, NULL);

	zassert_not_null(pkt2,
		"ARP cache is not sending the request again");

	net_pkt_unref(pkt2);

	/* Try to find the different destination, this should fail too
	 * as the cache table should be full.
	 */
	net_ipv4_addr_copy_raw(ipv4->dst, (uint8_t *)&dst_far2);

	/* Make sure prepare will not free the pkt because it will be
	 * needed in the next test case.
	 */
	net_pkt_ref(pkt);

	pkt2 = net_arp_prepare(pkt, &dst_far2, NULL);

	zassert_not_null(pkt2,
		"ARP cache did not send a req");

	/* Restore the original address so that following test case can
	 * work properly.
	 */
	net_ipv4_addr_copy_raw(ipv4->dst, (uint8_t *)&dst);

	/* The arp request packet is now verified, create an arp reply.
	 * The previous value of pkt is stored in arp table and is not lost.
	 */
	pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_eth_hdr) +
					sizeof(struct net_arp_hdr),
					AF_UNSPEC, 0, K_SECONDS(1));
	zassert_not_null(pkt, "out of mem reply");

	arp_hdr = NET_ARP_HDR(pkt);
	net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));

	net_ipv4_addr_copy_raw(arp_hdr->dst_ipaddr, (uint8_t *)&dst);
	net_ipv4_addr_copy_raw(arp_hdr->src_ipaddr, (uint8_t *)&src);

	pkt2 = prepare_arp_reply(iface, pkt, &hwaddr, &eth_hdr);

	zassert_not_null(pkt2, "ARP reply generation failed.");

	/* The pending packet should now be sent */
	switch (net_arp_input(pkt2, eth_hdr)) {
	case NET_OK:
	case NET_CONTINUE:
		break;
	case NET_DROP:
		break;
	}

	/* Yielding so that network interface TX thread can proceed. */
	k_yield();

	/**TESTPOINTS: Check ARP reply*/
	zassert_false(send_status < 0, "ARP reply was not sent");

	zassert_equal(atomic_get(&pkt->atomic_ref), 1,
		      "ARP cache should no longer own the original packet");

	net_pkt_unref(pkt);

	/* Then feed in ARP request */
	pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_eth_hdr) +
					sizeof(struct net_arp_hdr),
					AF_UNSPEC, 0, K_SECONDS(1));
	zassert_not_null(pkt, "out of mem reply");

	send_status = -EINVAL;

	setup_eth_header(iface, pkt, &hwaddr, NET_ETH_PTYPE_ARP);

	arp_hdr = (struct net_arp_hdr *)(pkt->buffer->data +
					 (sizeof(struct net_eth_hdr)));
	net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));

	net_ipv4_addr_copy_raw(arp_hdr->dst_ipaddr, (uint8_t *)&src);
	net_ipv4_addr_copy_raw(arp_hdr->src_ipaddr, (uint8_t *)&dst);

	pkt2 = prepare_arp_request(iface, pkt, &hwaddr, &eth_hdr);

	/**TESTPOINT: Check if ARP request generation failed*/
	zassert_not_null(pkt2, "ARP request generation failed.");

	req_test = true;

	switch (net_arp_input(pkt2, eth_hdr)) {
	case NET_OK:
	case NET_CONTINUE:
		break;
	case NET_DROP:
		break;
	}

	/* Yielding so that network interface TX thread can proceed. */
	k_yield();

	/**TESTPOINT: Check if ARP request sent*/
	zassert_false(send_status < 0, "ARP req was not sent");

	net_pkt_unref(pkt);

	/**TESTPOINT: Check gratuitous ARP */
	if (IS_ENABLED(CONFIG_NET_ARP_GRATUITOUS)) {
		struct net_eth_addr new_hwaddr = {
			{ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 }
		};
		enum net_verdict verdict;

		/* First make sure that we have an entry in cache */
		entry_found = false;
		expected_hwaddr = &hwaddr;
		net_arp_foreach(arp_cb, &dst);
		zassert_true(entry_found, "Entry not found");

		pkt = net_pkt_alloc_with_buffer(iface,
						sizeof(struct net_eth_hdr) +
						sizeof(struct net_arp_hdr),
						AF_UNSPEC, 0, K_SECONDS(1));
		zassert_not_null(pkt, "out of mem request");

		setup_eth_header(iface, pkt, net_eth_broadcast_addr(),
				 NET_ETH_PTYPE_ARP);

		eth_hdr = (struct net_eth_hdr *)net_pkt_data(pkt);
		net_buf_add(pkt->buffer, sizeof(struct net_eth_hdr));
		net_buf_pull(pkt->buffer, sizeof(struct net_eth_hdr));
		arp_hdr = NET_ARP_HDR(pkt);

		arp_hdr->hwtype = htons(NET_ARP_HTYPE_ETH);
		arp_hdr->protocol = htons(NET_ETH_PTYPE_IP);
		arp_hdr->hwlen = sizeof(struct net_eth_addr);
		arp_hdr->protolen = sizeof(struct in_addr);
		arp_hdr->opcode = htons(NET_ARP_REQUEST);
		memcpy(&arp_hdr->src_hwaddr, &new_hwaddr, 6);
		memcpy(&arp_hdr->dst_hwaddr, net_eth_broadcast_addr(), 6);
		net_ipv4_addr_copy_raw(arp_hdr->dst_ipaddr, (uint8_t *)&dst);
		net_ipv4_addr_copy_raw(arp_hdr->src_ipaddr, (uint8_t *)&dst);

		net_buf_add(pkt->buffer, sizeof(struct net_arp_hdr));

		verdict = net_arp_input(pkt, eth_hdr);
		zassert_not_equal(verdict, NET_DROP, "Gratuitous ARP failed");

		/* Then check that the HW address is changed for an existing
		 * entry.
		 */
		entry_found = false;
		expected_hwaddr = &new_hwaddr;
		net_arp_foreach(arp_cb, &dst);
		zassert_true(entry_found, "Changed entry not found");

		net_pkt_unref(pkt);
	}
}

void test_main(void)
{
	ztest_test_suite(test_arp_fn,
		ztest_unit_test(test_arp));
	ztest_run_test_suite(test_arp_fn);
}
