// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2023 Sean Anderson <seanga2@gmail.com>
 */

#include <common.h>
#include <dm.h>
#include <spl.h>
#include <test/spl.h>
#include <asm/eth.h>
#include <test/ut.h>
#include "../../net/bootp.h"

/*
 * sandbox_eth_bootp_req_to_reply()
 *
 * Check if a BOOTP request was sent. If so, inject a reply
 *
 * returns 0 if injected, -EAGAIN if not
 */
static int sandbox_eth_bootp_req_to_reply(struct udevice *dev, void *packet,
					  unsigned int len)
{
	struct eth_sandbox_priv *priv = dev_get_priv(dev);
	struct ethernet_hdr *eth = packet;
	struct ip_udp_hdr *ip;
	struct bootp_hdr *bp;
	struct ethernet_hdr *eth_recv;
	struct ip_udp_hdr *ipr;
	struct bootp_hdr *bpr;

	if (ntohs(eth->et_protlen) != PROT_IP)
		return -EAGAIN;

	ip = packet + ETHER_HDR_SIZE;
	if (ip->ip_p != IPPROTO_UDP)
		return -EAGAIN;

	if (ntohs(ip->udp_dst) != PORT_BOOTPS)
		return -EAGAIN;

	bp = (void *)ip + IP_UDP_HDR_SIZE;
	if (bp->bp_op != OP_BOOTREQUEST)
		return -EAGAIN;

	/* Don't allow the buffer to overrun */
	if (priv->recv_packets >= PKTBUFSRX)
		return 0;

	/* reply to the request */
	eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
	memcpy(eth_recv, packet, len);
	ipr = (void *)eth_recv + ETHER_HDR_SIZE;
	bpr = (void *)ipr + IP_UDP_HDR_SIZE;
	memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN);
	memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN);
	ipr->ip_sum = 0;
	ipr->ip_off = 0;
	net_write_ip(&ipr->ip_dst, net_ip);
	net_write_ip(&ipr->ip_src, priv->fake_host_ipaddr);
	ipr->ip_sum = compute_ip_checksum(ipr, IP_HDR_SIZE);
	ipr->udp_src = ip->udp_dst;
	ipr->udp_dst = ip->udp_src;

	bpr->bp_op = OP_BOOTREPLY;
	net_write_ip(&bpr->bp_yiaddr, net_ip);
	net_write_ip(&bpr->bp_siaddr, priv->fake_host_ipaddr);
	copy_filename(bpr->bp_file, CONFIG_BOOTFILE, sizeof(CONFIG_BOOTFILE));
	memset(&bpr->bp_vend, 0, sizeof(bpr->bp_vend));

	priv->recv_packet_length[priv->recv_packets] = len;
	++priv->recv_packets;

	return 0;
}

struct spl_test_net_priv {
	struct unit_test_state *uts;
	void *img;
	size_t img_size;
	u16 port;
};

/* Well known TFTP port # */
#define TFTP_PORT	69
/* Transaction ID, chosen at random */
#define	TFTP_TID	21313

/*
 *	TFTP operations.
 */
#define TFTP_RRQ	1
#define TFTP_DATA	3
#define TFTP_ACK	4

/* default TFTP block size */
#define TFTP_BLOCK_SIZE		512

struct tftp_hdr {
	u16 opcode;
	u16 block;
};

#define TFTP_HDR_SIZE sizeof(struct tftp_hdr)

/*
 * sandbox_eth_tftp_req_to_reply()
 *
 * Check if a TFTP request was sent. If so, inject a reply. We don't support
 * options, and we don't check for rollover, so we are limited files of less
 * than 32M.
 *
 * returns 0 if injected, -EAGAIN if not
 */
static int sandbox_eth_tftp_req_to_reply(struct udevice *dev, void *packet,
					 unsigned int len)
{
	struct eth_sandbox_priv *priv = dev_get_priv(dev);
	struct spl_test_net_priv *test_priv = priv->priv;
	struct ethernet_hdr *eth = packet;
	struct ip_udp_hdr *ip;
	struct tftp_hdr *tftp;
	struct ethernet_hdr *eth_recv;
	struct ip_udp_hdr *ipr;
	struct tftp_hdr *tftpr;
	size_t size;
	u16 block;

	if (ntohs(eth->et_protlen) != PROT_IP)
		return -EAGAIN;

	ip = packet + ETHER_HDR_SIZE;
	if (ip->ip_p != IPPROTO_UDP)
		return -EAGAIN;

	if (ntohs(ip->udp_dst) == TFTP_PORT) {
		tftp = (void *)ip + IP_UDP_HDR_SIZE;
		if (htons(tftp->opcode) != TFTP_RRQ)
			return -EAGAIN;

		block = 0;
	} else if (ntohs(ip->udp_dst) == TFTP_TID) {
		tftp = (void *)ip + IP_UDP_HDR_SIZE;
		if (htons(tftp->opcode) != TFTP_ACK)
			return -EAGAIN;

		block = htons(tftp->block);
	} else {
		return -EAGAIN;
	}

	if (block * TFTP_BLOCK_SIZE > test_priv->img_size)
		return 0;

	size = min(test_priv->img_size - block * TFTP_BLOCK_SIZE,
		   (size_t)TFTP_BLOCK_SIZE);

	/* Don't allow the buffer to overrun */
	if (priv->recv_packets >= PKTBUFSRX)
		return 0;

	/* reply to the request */
	eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets];
	memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN);
	memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN);
	eth_recv->et_protlen = htons(PROT_IP);

	ipr = (void *)eth_recv + ETHER_HDR_SIZE;
	ipr->ip_hl_v = 0x45;
	ipr->ip_len = htons(IP_UDP_HDR_SIZE + TFTP_HDR_SIZE + size);
	ipr->ip_off = htons(IP_FLAGS_DFRAG);
	ipr->ip_ttl = 255;
	ipr->ip_p = IPPROTO_UDP;
	ipr->ip_sum = 0;
	net_copy_ip(&ipr->ip_dst, &ip->ip_src);
	net_copy_ip(&ipr->ip_src, &ip->ip_dst);
	ipr->ip_sum = compute_ip_checksum(ipr, IP_HDR_SIZE);

	ipr->udp_src = htons(TFTP_TID);
	ipr->udp_dst = ip->udp_src;
	ipr->udp_len = htons(UDP_HDR_SIZE + TFTP_HDR_SIZE + size);
	ipr->udp_xsum = 0;

	tftpr = (void *)ipr + IP_UDP_HDR_SIZE;
	tftpr->opcode = htons(TFTP_DATA);
	tftpr->block = htons(block + 1);
	memcpy((void *)tftpr + TFTP_HDR_SIZE,
	       test_priv->img + block * TFTP_BLOCK_SIZE, size);

	priv->recv_packet_length[priv->recv_packets] =
		ETHER_HDR_SIZE + IP_UDP_HDR_SIZE + TFTP_HDR_SIZE + size;
	++priv->recv_packets;

	return 0;
}

static int spl_net_handler(struct udevice *dev, void *packet,
			   unsigned int len)
{
	struct eth_sandbox_priv *priv = dev_get_priv(dev);
	int old_packets = priv->recv_packets;

	priv->fake_host_ipaddr = string_to_ip("1.1.2.4");
	net_ip = string_to_ip("1.1.2.2");

	sandbox_eth_arp_req_to_reply(dev, packet, len);
	sandbox_eth_bootp_req_to_reply(dev, packet, len);
	sandbox_eth_tftp_req_to_reply(dev, packet, len);

	if (old_packets == priv->recv_packets)
		return 0;

	return 0;
}

static int spl_test_net_write_image(struct unit_test_state *uts, void *img,
				    size_t img_size)
{
	struct spl_test_net_priv *test_priv = malloc(sizeof(*test_priv));

	ut_assertnonnull(test_priv);
	test_priv->uts = uts;
	test_priv->img = img;
	test_priv->img_size = img_size;

	sandbox_eth_set_tx_handler(0, spl_net_handler);
	sandbox_eth_set_priv(0, test_priv);
	return 0;
}

static int spl_test_net(struct unit_test_state *uts, const char *test_name,
			enum spl_test_image type)
{
	struct eth_sandbox_priv *priv;
	struct udevice *dev;
	int ret;

	net_server_ip = string_to_ip("1.1.2.4");
	ret = do_spl_test_load(uts, test_name, type,
			       SPL_LOAD_IMAGE_GET(0, BOOT_DEVICE_CPGMAC,
						  spl_net_load_image_cpgmac),
			       spl_test_net_write_image);

	sandbox_eth_set_tx_handler(0, NULL);
	ut_assertok(uclass_get_device(UCLASS_ETH, 0, &dev));
	priv = dev_get_priv(dev);
	free(priv->priv);
	return ret;
}
SPL_IMG_TEST(spl_test_net, LEGACY, DM_FLAGS);
SPL_IMG_TEST(spl_test_net, FIT_INTERNAL, DM_FLAGS);
SPL_IMG_TEST(spl_test_net, FIT_EXTERNAL, DM_FLAGS);
