/*
 * iptunnel.c	       "ip tuntap"
 *
 *		This program is free software; you can redistribute it and/or
 *		modify it under the terms of the GNU General Public License
 *		as published by the Free Software Foundation; either version
 *		2 of the License, or (at your option) any later version.
 *
 * Authors:	David Woodhouse <David.Woodhouse@intel.com>
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <pwd.h>
#include <grp.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>

#include "rt_names.h"
#include "utils.h"
#include "ip_common.h"

#define TUNDEV "/dev/net/tun"

static void usage(void) __attribute__((noreturn));

static void usage(void)
{
	fprintf(stderr, "Usage: ip tuntap { add | del | show | list | lst | help } [ dev PHYS_DEV ] \n");
	fprintf(stderr, "          [ mode { tun | tap } ] [ user USER ] [ group GROUP ]\n");
	fprintf(stderr, "          [ one_queue ] [ pi ] [ vnet_hdr ] [ multi_queue ]\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "Where: USER  := { STRING | NUMBER }\n");
	fprintf(stderr, "       GROUP := { STRING | NUMBER }\n");
	exit(-1);
}

static int tap_add_ioctl(struct ifreq *ifr, uid_t uid, gid_t gid)
{
	int fd;
	int ret = -1;

#ifdef IFF_TUN_EXCL
	ifr->ifr_flags |= IFF_TUN_EXCL;
#endif

	fd = open(TUNDEV, O_RDWR);
	if (fd < 0) {
		perror("open");
		return -1;
	}
	if (ioctl(fd, TUNSETIFF, ifr)) {
		perror("ioctl(TUNSETIFF)");
		goto out;
	}
	if (uid != -1 && ioctl(fd, TUNSETOWNER, uid)) {
		perror("ioctl(TUNSETOWNER)");
		goto out;
	}
	if (gid != -1 && ioctl(fd, TUNSETGROUP, gid)) {
		perror("ioctl(TUNSETGROUP)");
		goto out;
	}
	if (ioctl(fd, TUNSETPERSIST, 1)) {
		perror("ioctl(TUNSETPERSIST)");
		goto out;
	}
	ret = 0;
 out:
	close(fd);
	return ret;
}

static int tap_del_ioctl(struct ifreq *ifr)
{
	int fd = open(TUNDEV, O_RDWR);
	int ret = -1;

	if (fd < 0) {
		perror("open");
		return -1;
	}
	if (ioctl(fd, TUNSETIFF, ifr)) {
		perror("ioctl(TUNSETIFF)");
		goto out;
	}
	if (ioctl(fd, TUNSETPERSIST, 0)) {
		perror("ioctl(TUNSETPERSIST)");
		goto out;
	}
	ret = 0;
 out:
	close(fd);
	return ret;

}
static int parse_args(int argc, char **argv, struct ifreq *ifr, uid_t *uid, gid_t *gid)
{
	int count = 0;

	memset(ifr, 0, sizeof(*ifr));

	ifr->ifr_flags |= IFF_NO_PI;

	while (argc > 0) {
		if (matches(*argv, "mode") == 0) {
			NEXT_ARG();
			if (matches(*argv, "tun") == 0) {
				if (ifr->ifr_flags & IFF_TAP) {
					fprintf(stderr,"You managed to ask for more than one tunnel mode.\n");
					exit(-1);
				}
				ifr->ifr_flags |= IFF_TUN;
			} else if (matches(*argv, "tap") == 0) {
				if (ifr->ifr_flags & IFF_TUN) {
					fprintf(stderr,"You managed to ask for more than one tunnel mode.\n");
					exit(-1);
				}
				ifr->ifr_flags |= IFF_TAP;
			} else {
				fprintf(stderr,"Unknown tunnel mode \"%s\"\n", *argv);
				exit(-1);
			}
		} else if (uid && matches(*argv, "user") == 0) {
			char *end;
			unsigned long user;

			NEXT_ARG();
			if (**argv && ((user = strtol(*argv, &end, 10)), !*end))
				*uid = user;
			else {
				struct passwd *pw = getpwnam(*argv);
				if (!pw) {
					fprintf(stderr, "invalid user \"%s\"\n", *argv);
					exit(-1);
				}
				*uid = pw->pw_uid;
			}
		} else if (gid && matches(*argv, "group") == 0) {
			char *end;
			unsigned long group;

			NEXT_ARG();

			if (**argv && ((group = strtol(*argv, &end, 10)), !*end))
				*gid = group;
			else {
				struct group *gr = getgrnam(*argv);
				if (!gr) {
					fprintf(stderr, "invalid group \"%s\"\n", *argv);
					exit(-1);
				}
				*gid = gr->gr_gid;
			}
		} else if (matches(*argv, "pi") == 0) {
			ifr->ifr_flags &= ~IFF_NO_PI;
		} else if (matches(*argv, "one_queue") == 0) {
			ifr->ifr_flags |= IFF_ONE_QUEUE;
		} else if (matches(*argv, "vnet_hdr") == 0) {
			ifr->ifr_flags |= IFF_VNET_HDR;
		} else if (matches(*argv, "multi_queue") == 0) {
			ifr->ifr_flags |= IFF_MULTI_QUEUE;
		} else if (matches(*argv, "dev") == 0) {
			NEXT_ARG();
			strncpy(ifr->ifr_name, *argv, IFNAMSIZ-1);
		} else {
			if (matches(*argv, "name") == 0) {
				NEXT_ARG();
			} else if (matches(*argv, "help") == 0)
				usage();
			if (ifr->ifr_name[0])
				duparg2("name", *argv);
			strncpy(ifr->ifr_name, *argv, IFNAMSIZ);
		}
		count++;
		argc--; argv++;
	}

	if (!(ifr->ifr_flags & TUN_TYPE_MASK)) {
		fprintf(stderr, "You failed to specify a tunnel mode\n");
		return -1;
	}

	return 0;
}


static int do_add(int argc, char **argv)
{
	struct ifreq ifr;
	uid_t uid = -1;
	gid_t gid = -1;

	if (parse_args(argc, argv, &ifr, &uid, &gid) < 0)
		return -1;

	return tap_add_ioctl(&ifr, uid, gid);
}

static int do_del(int argc, char **argv)
{
	struct ifreq ifr;

	if (parse_args(argc, argv, &ifr, NULL, NULL) < 0)
		return -1;

	return tap_del_ioctl(&ifr);
}

static int read_prop(char *dev, char *prop, long *value)
{
	char fname[IFNAMSIZ+25], buf[80], *endp;
	ssize_t len;
	int fd;
	long result;

	sprintf(fname, "/sys/class/net/%s/%s", dev, prop);
	fd = open(fname, O_RDONLY);
	if (fd < 0) {
		if (strcmp(prop, "tun_flags"))
			fprintf(stderr, "open %s: %s\n", fname,
				strerror(errno));
		return -1;
	}
	len = read(fd, buf, sizeof(buf)-1);
	close(fd);
	if (len < 0) {
		fprintf(stderr, "read %s: %s", fname, strerror(errno));
		return -1;
	}

	buf[len] = 0;
	result = strtol(buf, &endp, 0);
	if (*endp != '\n') {
		fprintf(stderr, "Failed to parse %s\n", fname);
		return -1;
	}
	*value = result;
	return 0;
}

static void print_flags(long flags)
{
	if (flags & IFF_TUN)
		printf(" tun");

	if (flags & IFF_TAP)
		printf(" tap");

	if (!(flags & IFF_NO_PI))
		printf(" pi");

	if (flags & IFF_ONE_QUEUE)
		printf(" one_queue");

	if (flags & IFF_VNET_HDR)
		printf(" vnet_hdr");

	flags &= ~(IFF_TUN|IFF_TAP|IFF_NO_PI|IFF_ONE_QUEUE|IFF_VNET_HDR);
	if (flags)
		printf(" UNKNOWN_FLAGS:%lx", flags);
}

static int do_show(int argc, char **argv)
{
	DIR *dir;
	struct dirent *d;
	long flags, owner = -1, group = -1;

	dir = opendir("/sys/class/net");
	if (!dir) {
		perror("opendir");
		return -1;
	}
	while ((d = readdir(dir))) {
		if (d->d_name[0] == '.' &&
		    (d->d_name[1] == 0 || d->d_name[1] == '.'))
			continue;

		if (read_prop(d->d_name, "tun_flags", &flags))
			continue;

		read_prop(d->d_name, "owner", &owner);
		read_prop(d->d_name, "group", &group);

		printf("%s:", d->d_name);
		print_flags(flags);
		if (owner != -1)
			printf(" user %ld", owner);
		if (group != -1)
			printf(" group %ld", group);
		printf("\n");
	}
	closedir(dir);
	return 0;
}

int do_iptuntap(int argc, char **argv)
{
	if (argc > 0) {
		if (matches(*argv, "add") == 0)
			return do_add(argc-1, argv+1);
		if (matches(*argv, "delete") == 0)
			return do_del(argc-1, argv+1);
		if (matches(*argv, "show") == 0 ||
                    matches(*argv, "lst") == 0 ||
                    matches(*argv, "list") == 0)
                        return do_show(argc-1, argv+1);
		if (matches(*argv, "help") == 0)
			usage();
	} else
		return do_show(0, NULL);

	fprintf(stderr, "Command \"%s\" is unknown, try \"ip tuntap help\".\n",
		*argv);
	exit(-1);
}
