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

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <sys/wait.h>
#include <net_user.h>
#include <os.h>
#include "slip.h"
#include <um_malloc.h>

static int slip_user_init(void *data, void *dev)
{
	struct slip_data *pri = data;

	pri->dev = dev;
	return 0;
}

static int set_up_tty(int fd)
{
	int i;
	struct termios tios;

	if (tcgetattr(fd, &tios) < 0) {
		printk(UM_KERN_ERR "could not get initial terminal "
		       "attributes\n");
		return -1;
	}

	tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
	tios.c_iflag = IGNBRK | IGNPAR;
	tios.c_oflag = 0;
	tios.c_lflag = 0;
	for (i = 0; i < NCCS; i++)
		tios.c_cc[i] = 0;
	tios.c_cc[VMIN] = 1;
	tios.c_cc[VTIME] = 0;

	cfsetospeed(&tios, B38400);
	cfsetispeed(&tios, B38400);

	if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
		printk(UM_KERN_ERR "failed to set terminal attributes\n");
		return -1;
	}
	return 0;
}

struct slip_pre_exec_data {
	int stdin_fd;
	int stdout_fd;
	int close_me;
};

static void slip_pre_exec(void *arg)
{
	struct slip_pre_exec_data *data = arg;

	if (data->stdin_fd >= 0)
		dup2(data->stdin_fd, 0);
	dup2(data->stdout_fd, 1);
	if (data->close_me >= 0)
		close(data->close_me);
}

static int slip_tramp(char **argv, int fd)
{
	struct slip_pre_exec_data pe_data;
	char *output;
	int pid, fds[2], err, output_len;

	err = os_pipe(fds, 1, 0);
	if (err < 0) {
		printk(UM_KERN_ERR "slip_tramp : pipe failed, err = %d\n",
		       -err);
		goto out;
	}

	err = 0;
	pe_data.stdin_fd = fd;
	pe_data.stdout_fd = fds[1];
	pe_data.close_me = fds[0];
	err = run_helper(slip_pre_exec, &pe_data, argv);
	if (err < 0)
		goto out_close;
	pid = err;

	output_len = UM_KERN_PAGE_SIZE;
	output = uml_kmalloc(output_len, UM_GFP_KERNEL);
	if (output == NULL) {
		printk(UM_KERN_ERR "slip_tramp : failed to allocate output "
		       "buffer\n");
		os_kill_process(pid, 1);
		err = -ENOMEM;
		goto out_close;
	}

	close(fds[1]);
	read_output(fds[0], output, output_len);
	printk("%s", output);

	err = helper_wait(pid);
	close(fds[0]);

	kfree(output);
	return err;

out_close:
	close(fds[0]);
	close(fds[1]);
out:
	return err;
}

static int slip_open(void *data)
{
	struct slip_data *pri = data;
	char version_buf[sizeof("nnnnn\0")];
	char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
	char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf,
			 NULL };
	int sfd, mfd, err;

	err = get_pty();
	if (err < 0) {
		printk(UM_KERN_ERR "slip-open : Failed to open pty, err = %d\n",
		       -err);
		goto out;
	}
	mfd = err;

	err = open(ptsname(mfd), O_RDWR, 0);
	if (err < 0) {
		printk(UM_KERN_ERR "Couldn't open tty for slip line, "
		       "err = %d\n", -err);
		goto out_close;
	}
	sfd = err;

	err = set_up_tty(sfd);
	if (err)
		goto out_close2;

	pri->slave = sfd;
	pri->slip.pos = 0;
	pri->slip.esc = 0;
	if (pri->gate_addr != NULL) {
		sprintf(version_buf, "%d", UML_NET_VERSION);
		strcpy(gate_buf, pri->gate_addr);

		err = slip_tramp(argv, sfd);

		if (err < 0) {
			printk(UM_KERN_ERR "slip_tramp failed - err = %d\n",
			       -err);
			goto out_close2;
		}
		err = os_get_ifname(pri->slave, pri->name);
		if (err < 0) {
			printk(UM_KERN_ERR "get_ifname failed, err = %d\n",
			       -err);
			goto out_close2;
		}
		iter_addresses(pri->dev, open_addr, pri->name);
	}
	else {
		err = os_set_slip(sfd);
		if (err < 0) {
			printk(UM_KERN_ERR "Failed to set slip discipline "
			       "encapsulation - err = %d\n", -err);
			goto out_close2;
		}
	}
	return mfd;
out_close2:
	close(sfd);
out_close:
	close(mfd);
out:
	return err;
}

static void slip_close(int fd, void *data)
{
	struct slip_data *pri = data;
	char version_buf[sizeof("nnnnn\0")];
	char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name,
			 NULL };
	int err;

	if (pri->gate_addr != NULL)
		iter_addresses(pri->dev, close_addr, pri->name);

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

	err = slip_tramp(argv, pri->slave);

	if (err != 0)
		printk(UM_KERN_ERR "slip_tramp failed - errno = %d\n", -err);
	close(fd);
	close(pri->slave);
	pri->slave = -1;
}

int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
{
	return slip_proto_read(fd, buf, len, &pri->slip);
}

int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
{
	return slip_proto_write(fd, buf, len, &pri->slip);
}

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

	if (pri->slave < 0)
		return;
	open_addr(addr, netmask, pri->name);
}

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

	if (pri->slave < 0)
		return;
	close_addr(addr, netmask, pri->name);
}

const struct net_user_info slip_user_info = {
	.init		= slip_user_init,
	.open		= slip_open,
	.close	 	= slip_close,
	.remove	 	= NULL,
	.add_address	= slip_add_addr,
	.delete_address = slip_del_addr,
	.mtu		= BUF_SIZE,
	.max_packet	= BUF_SIZE,
};
