// SPDX-License-Identifier: GPL-2.0

/*
 * Verify that consecutive sends over packet tx_ring are mirrored
 * with their original content intact.
 */

#define _GNU_SOURCE

#include <arpa/inet.h>
#include <assert.h>
#include <error.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/filter.h>
#include <linux/if_packet.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <poll.h>
#include <pthread.h>
#include <sched.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

const int eth_off = TPACKET_HDRLEN - sizeof(struct sockaddr_ll);
const int cfg_frame_size = 1000;

static void build_packet(void *buffer, size_t blen, char payload_char)
{
	struct udphdr *udph;
	struct ethhdr *eth;
	struct iphdr *iph;
	size_t off = 0;

	memset(buffer, 0, blen);

	eth = buffer;
	eth->h_proto = htons(ETH_P_IP);

	off += sizeof(*eth);
	iph = buffer + off;
	iph->ttl	= 8;
	iph->ihl	= 5;
	iph->version	= 4;
	iph->saddr	= htonl(INADDR_LOOPBACK);
	iph->daddr	= htonl(INADDR_LOOPBACK + 1);
	iph->protocol	= IPPROTO_UDP;
	iph->tot_len	= htons(blen - off);
	iph->check	= 0;

	off += sizeof(*iph);
	udph = buffer + off;
	udph->dest	= htons(8000);
	udph->source	= htons(8001);
	udph->len	= htons(blen - off);
	udph->check	= 0;

	off += sizeof(*udph);
	memset(buffer + off, payload_char, blen - off);
}

static int setup_rx(void)
{
	int fdr;

	fdr = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
	if (fdr == -1)
		error(1, errno, "socket r");

	return fdr;
}

static int setup_tx(char **ring)
{
	struct sockaddr_ll laddr = {};
	struct tpacket_req req = {};
	int fdt;

	fdt = socket(PF_PACKET, SOCK_RAW, 0);
	if (fdt == -1)
		error(1, errno, "socket t");

	laddr.sll_family = AF_PACKET;
	laddr.sll_protocol = htons(0);
	laddr.sll_ifindex = if_nametoindex("lo");
	if (!laddr.sll_ifindex)
		error(1, errno, "if_nametoindex");

	if (bind(fdt, (void *)&laddr, sizeof(laddr)))
		error(1, errno, "bind fdt");

	req.tp_block_size = getpagesize();
	req.tp_block_nr   = 1;
	req.tp_frame_size = getpagesize();
	req.tp_frame_nr   = 1;

	if (setsockopt(fdt, SOL_PACKET, PACKET_TX_RING,
		       (void *)&req, sizeof(req)))
		error(1, errno, "setsockopt ring");

	*ring = mmap(0, req.tp_block_size * req.tp_block_nr,
		     PROT_READ | PROT_WRITE, MAP_SHARED, fdt, 0);
	if (!*ring)
		error(1, errno, "mmap");

	return fdt;
}

static void send_pkt(int fdt, void *slot, char payload_char)
{
	struct tpacket_hdr *header = slot;
	int ret;

	while (header->tp_status != TP_STATUS_AVAILABLE)
		usleep(1000);

	build_packet(slot + eth_off, cfg_frame_size, payload_char);

	header->tp_len = cfg_frame_size;
	header->tp_status = TP_STATUS_SEND_REQUEST;

	ret = sendto(fdt, NULL, 0, 0, NULL, 0);
	if (ret == -1)
		error(1, errno, "kick tx");
}

static int read_verify_pkt(int fdr, char payload_char)
{
	char buf[100];
	int ret;

	ret = read(fdr, buf, sizeof(buf));
	if (ret != sizeof(buf))
		error(1, errno, "read");

	if (buf[60] != payload_char) {
		printf("wrong pattern: 0x%x != 0x%x\n", buf[60], payload_char);
		return 1;
	}

	printf("read: %c (0x%x)\n", buf[60], buf[60]);
	return 0;
}

int main(int argc, char **argv)
{
	const char payload_patterns[] = "ab";
	char *ring;
	int fdr, fdt, ret = 0;

	fdr = setup_rx();
	fdt = setup_tx(&ring);

	send_pkt(fdt, ring, payload_patterns[0]);
	send_pkt(fdt, ring, payload_patterns[1]);

	ret |= read_verify_pkt(fdr, payload_patterns[0]);
	ret |= read_verify_pkt(fdr, payload_patterns[1]);

	if (close(fdt))
		error(1, errno, "close t");
	if (close(fdr))
		error(1, errno, "close r");

	return ret;
}
