/*
 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 * Licensed under the GPL
 */

#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include <errno.h>
#include <stddef.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include "net_user.h"
#include "kern_constants.h"
#include "os.h"
#include "um_malloc.h"
#include "user.h"

int tap_open_common(void *dev, char *gate_addr)
{
	int tap_addr[4];

	if (gate_addr == NULL)
		return 0;
	if (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
		  &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4) {
		printk(UM_KERN_ERR "Invalid tap IP address - '%s'\n",
		       gate_addr);
		return -EINVAL;
	}
	return 0;
}

void tap_check_ips(char *gate_addr, unsigned char *eth_addr)
{
	int tap_addr[4];

	if ((gate_addr != NULL) &&
	    (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
		    &tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) &&
	    (eth_addr[0] == tap_addr[0]) &&
	    (eth_addr[1] == tap_addr[1]) &&
	    (eth_addr[2] == tap_addr[2]) &&
	    (eth_addr[3] == tap_addr[3])) {
		printk(UM_KERN_ERR "The tap IP address and the UML eth IP "
		       "address must be different\n");
	}
}

/* Do reliable error handling as this fails frequently enough. */
void read_output(int fd, char *output, int len)
{
	int remain, ret, expected;
	char c;
	char *str;

	if (output == NULL) {
		output = &c;
		len = sizeof(c);
	}

	*output = '\0';
	ret = read(fd, &remain, sizeof(remain));

	if (ret != sizeof(remain)) {
		if (ret < 0)
			ret = -errno;
		expected = sizeof(remain);
		str = "length";
		goto err;
	}

	while (remain != 0) {
		expected = (remain < len) ? remain : len;
		ret = read(fd, output, expected);
		if (ret != expected) {
			if (ret < 0)
				ret = -errno;
			str = "data";
			goto err;
		}
		remain -= ret;
	}

	return;

err:
	if (ret < 0)
		printk(UM_KERN_ERR "read_output - read of %s failed, "
		       "errno = %d\n", str, -ret);
	else
		printk(UM_KERN_ERR "read_output - read of %s failed, read only "
		       "%d of %d bytes\n", str, ret, expected);
}

int net_read(int fd, void *buf, int len)
{
	int n;

	n = read(fd,  buf,  len);

	if ((n < 0) && (errno == EAGAIN))
		return 0;
	else if (n == 0)
		return -ENOTCONN;
	return n;
}

int net_recvfrom(int fd, void *buf, int len)
{
	int n;

	CATCH_EINTR(n = recvfrom(fd,  buf,  len, 0, NULL, NULL));
	if (n < 0) {
		if (errno == EAGAIN)
			return 0;
		return -errno;
	}
	else if (n == 0)
		return -ENOTCONN;
	return n;
}

int net_write(int fd, void *buf, int len)
{
	int n;

	n = write(fd, buf, len);

	if ((n < 0) && (errno == EAGAIN))
		return 0;
	else if (n == 0)
		return -ENOTCONN;
	return n;
}

int net_send(int fd, void *buf, int len)
{
	int n;

	CATCH_EINTR(n = send(fd, buf, len, 0));
	if (n < 0) {
		if (errno == EAGAIN)
			return 0;
		return -errno;
	}
	else if (n == 0)
		return -ENOTCONN;
	return n;
}

int net_sendto(int fd, void *buf, int len, void *to, int sock_len)
{
	int n;

	CATCH_EINTR(n = sendto(fd, buf, len, 0, (struct sockaddr *) to,
			       sock_len));
	if (n < 0) {
		if (errno == EAGAIN)
			return 0;
		return -errno;
	}
	else if (n == 0)
		return -ENOTCONN;
	return n;
}

struct change_pre_exec_data {
	int close_me;
	int stdout;
};

static void change_pre_exec(void *arg)
{
	struct change_pre_exec_data *data = arg;

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

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

	err = os_pipe(fds, 1, 0);
	if (err < 0) {
		printk(UM_KERN_ERR "change_tramp - pipe failed, err = %d\n",
		       -err);
		return err;
	}
	pe_data.close_me = fds[0];
	pe_data.stdout = fds[1];
	pid = run_helper(change_pre_exec, &pe_data, argv);

	if (pid > 0)	/* Avoid hang as we won't get data in failure case. */
		read_output(fds[0], output, output_len);

	close(fds[0]);
	close(fds[1]);

	if (pid > 0)
		CATCH_EINTR(err = waitpid(pid, NULL, 0));
	return pid;
}

static void change(char *dev, char *what, unsigned char *addr,
		   unsigned char *netmask)
{
	char addr_buf[sizeof("255.255.255.255\0")];
	char netmask_buf[sizeof("255.255.255.255\0")];
	char version[sizeof("nnnnn\0")];
	char *argv[] = { "uml_net", version, what, dev, addr_buf,
			 netmask_buf, NULL };
	char *output;
	int output_len, pid;

	sprintf(version, "%d", UML_NET_VERSION);
	sprintf(addr_buf, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
	sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1],
		netmask[2], netmask[3]);

	output_len = UM_KERN_PAGE_SIZE;
	output = kmalloc(output_len, UM_GFP_KERNEL);
	if (output == NULL)
		printk(UM_KERN_ERR "change : failed to allocate output "
		       "buffer\n");

	pid = change_tramp(argv, output, output_len);
	if (pid < 0) return;

	if (output != NULL) {
		printk("%s", output);
		kfree(output);
	}
}

void open_addr(unsigned char *addr, unsigned char *netmask, void *arg)
{
	change(arg, "add", addr, netmask);
}

void close_addr(unsigned char *addr, unsigned char *netmask, void *arg)
{
	change(arg, "del", addr, netmask);
}

char *split_if_spec(char *str, ...)
{
	char **arg, *end;
	va_list ap;

	va_start(ap, str);
	while ((arg = va_arg(ap, char **)) != NULL) {
		if (*str == '\0')
			return NULL;
		end = strchr(str, ',');
		if (end != str)
			*arg = str;
		if (end == NULL)
			return NULL;
		*end++ = '\0';
		str = end;
	}
	va_end(ap);
	return str;
}
