// SPDX-License-Identifier: GPL-2.0
/* 
 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 */

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <linux/if_tun.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/uio.h>
#include <kern_util.h>
#include <os.h>
#include "tuntap.h"

static int tuntap_user_init(void *data, void *dev)
{
	struct tuntap_data *pri = data;

	pri->dev = dev;
	return 0;
}

static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
			    void *data)
{
	struct tuntap_data *pri = data;

	tap_check_ips(pri->gate_addr, addr);
	if ((pri->fd == -1) || pri->fixed_config)
		return;
	open_addr(addr, netmask, pri->dev_name);
}

static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
			    void *data)
{
	struct tuntap_data *pri = data;

	if ((pri->fd == -1) || pri->fixed_config)
		return;
	close_addr(addr, netmask, pri->dev_name);
}

struct tuntap_pre_exec_data {
	int stdout_fd;
	int close_me;
};

static void tuntap_pre_exec(void *arg)
{
	struct tuntap_pre_exec_data *data = arg;

	dup2(data->stdout_fd, 1);
	close(data->close_me);
}

static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
			     char *buffer, int buffer_len, int *used_out)
{
	struct tuntap_pre_exec_data data;
	char version_buf[sizeof("nnnnn\0")];
	char *argv[] = { "uml_net", version_buf, "tuntap", "up", gate,
			 NULL };
	char buf[CMSG_SPACE(sizeof(*fd_out))];
	struct msghdr msg;
	struct cmsghdr *cmsg;
	struct iovec iov;
	int pid, n, err;

	sprintf(version_buf, "%d", UML_NET_VERSION);

	data.stdout_fd = remote;
	data.close_me = me;

	pid = run_helper(tuntap_pre_exec, &data, argv);

	if (pid < 0)
		return pid;

	close(remote);

	msg.msg_name = NULL;
	msg.msg_namelen = 0;
	if (buffer != NULL) {
		iov = ((struct iovec) { buffer, buffer_len });
		msg.msg_iov = &iov;
		msg.msg_iovlen = 1;
	}
	else {
		msg.msg_iov = NULL;
		msg.msg_iovlen = 0;
	}
	msg.msg_control = buf;
	msg.msg_controllen = sizeof(buf);
	msg.msg_flags = 0;
	n = recvmsg(me, &msg, 0);
	*used_out = n;
	if (n < 0) {
		err = -errno;
		printk(UM_KERN_ERR "tuntap_open_tramp : recvmsg failed - "
		       "errno = %d\n", errno);
		return err;
	}
	helper_wait(pid);

	cmsg = CMSG_FIRSTHDR(&msg);
	if (cmsg == NULL) {
		printk(UM_KERN_ERR "tuntap_open_tramp : didn't receive a "
		       "message\n");
		return -EINVAL;
	}
	if ((cmsg->cmsg_level != SOL_SOCKET) ||
	   (cmsg->cmsg_type != SCM_RIGHTS)) {
		printk(UM_KERN_ERR "tuntap_open_tramp : didn't receive a "
		       "descriptor\n");
		return -EINVAL;
	}
	*fd_out = ((int *) CMSG_DATA(cmsg))[0];
	os_set_exec_close(*fd_out);
	return 0;
}

static int tuntap_open(void *data)
{
	struct ifreq ifr;
	struct tuntap_data *pri = data;
	char *output, *buffer;
	int err, fds[2], len, used;

	err = tap_open_common(pri->dev, pri->gate_addr);
	if (err < 0)
		return err;

	if (pri->fixed_config) {
		pri->fd = os_open_file("/dev/net/tun",
				       of_cloexec(of_rdwr(OPENFLAGS())), 0);
		if (pri->fd < 0) {
			printk(UM_KERN_ERR "Failed to open /dev/net/tun, "
			       "err = %d\n", -pri->fd);
			return pri->fd;
		}
		memset(&ifr, 0, sizeof(ifr));
		ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
		strscpy(ifr.ifr_name, pri->dev_name);
		if (ioctl(pri->fd, TUNSETIFF, &ifr) < 0) {
			err = -errno;
			printk(UM_KERN_ERR "TUNSETIFF failed, errno = %d\n",
			       errno);
			close(pri->fd);
			return err;
		}
	}
	else {
		err = socketpair(AF_UNIX, SOCK_DGRAM, 0, fds);
		if (err) {
			err = -errno;
			printk(UM_KERN_ERR "tuntap_open : socketpair failed - "
			       "errno = %d\n", errno);
			return err;
		}

		buffer = get_output_buffer(&len);
		if (buffer != NULL)
			len--;
		used = 0;

		err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0],
					fds[1], buffer, len, &used);

		output = buffer;
		if (err < 0) {
			printk("%s", output);
			free_output_buffer(buffer);
			printk(UM_KERN_ERR "tuntap_open_tramp failed - "
			       "err = %d\n", -err);
			return err;
		}

		pri->dev_name = uml_strdup(buffer);
		output += IFNAMSIZ;
		printk("%s", output);
		free_output_buffer(buffer);

		close(fds[0]);
		iter_addresses(pri->dev, open_addr, pri->dev_name);
	}

	return pri->fd;
}

static void tuntap_close(int fd, void *data)
{
	struct tuntap_data *pri = data;

	if (!pri->fixed_config)
		iter_addresses(pri->dev, close_addr, pri->dev_name);
	close(fd);
	pri->fd = -1;
}

const struct net_user_info tuntap_user_info = {
	.init		= tuntap_user_init,
	.open		= tuntap_open,
	.close	 	= tuntap_close,
	.remove	 	= NULL,
	.add_address	= tuntap_add_addr,
	.delete_address = tuntap_del_addr,
	.mtu		= ETH_MAX_PACKET,
	.max_packet	= ETH_MAX_PACKET + ETH_HEADER_OTHER,
};
