/*
 * (C) 2014 by Pablo Neira Ayuso <pablo@netfilter.org>
 *
 * 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.
 */
#include "config.h"
#include <time.h>
#include "xtables-multi.h"
#include "nft.h"

#include <string.h>
#include <netdb.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <limits.h>
#include <unistd.h>
#include <iptables.h>
#include <xtables.h>
#include <libiptc/libxtc.h>
#include <fcntl.h>
#include <getopt.h>
#include "xshared.h"
#include "nft-shared.h"

void xlate_ifname(struct xt_xlate *xl, const char *nftmeta, const char *ifname,
		  bool invert)
{
	int ifaclen = strlen(ifname), i, j;
	char iface[IFNAMSIZ * 2];

	if (ifaclen < 1 || ifaclen >= IFNAMSIZ)
		return;

	for (i = 0, j = 0; i < ifaclen + 1; i++, j++) {
		switch (ifname[i]) {
		case '*':
			iface[j++] = '\\';
			/* fall through */
		default:
			iface[j] = ifname[i];
			break;
		}
	}

	if (ifaclen == 1 && ifname[0] == '+') {
		/* Nftables does not support wildcard only string. Workaround
		 * is easy, given that this will match always or never
		 * depending on 'invert' value. To match always, simply don't
		 * generate an expression. To match never, use an invalid
		 * interface name (kernel doesn't accept '/' in names) to match
		 * against. */
		if (!invert)
			return;
		strcpy(iface, "INVAL/D");
		invert = false;
	}

	if (iface[j - 2] == '+')
		iface[j - 2] = '*';

	xt_xlate_add(xl, "%s %s\"%s\" ", nftmeta, invert ? "!= " : "", iface);
}

int xlate_action(const struct iptables_command_state *cs, bool goto_set,
		 struct xt_xlate *xl)
{
	int ret = 1, numeric = cs->options & OPT_NUMERIC;

	/* If no target at all, add nothing (default to continue) */
	if (cs->target != NULL) {
		/* Standard target? */
		if (strcmp(cs->jumpto, XTC_LABEL_ACCEPT) == 0)
			xt_xlate_add(xl, " accept");
		else if (strcmp(cs->jumpto, XTC_LABEL_DROP) == 0)
			xt_xlate_add(xl, " drop");
		else if (strcmp(cs->jumpto, XTC_LABEL_RETURN) == 0)
			xt_xlate_add(xl, " return");
		else if (cs->target->xlate) {
			xt_xlate_add(xl, " ");
			struct xt_xlate_tg_params params = {
				.ip		= (const void *)&cs->fw,
				.target		= cs->target->t,
				.numeric	= numeric,
				.escape_quotes	= !cs->restore,
			};
			ret = cs->target->xlate(xl, &params);
		}
		else
			return 0;
	} else if (strlen(cs->jumpto) > 0) {
		/* Not standard, then it's a go / jump to chain */
		if (goto_set)
			xt_xlate_add(xl, " goto %s", cs->jumpto);
		else
			xt_xlate_add(xl, " jump %s", cs->jumpto);
	}

	return ret;
}

int xlate_matches(const struct iptables_command_state *cs, struct xt_xlate *xl)
{
	struct xtables_rule_match *matchp;
	int ret = 1, numeric = cs->options & OPT_NUMERIC;

	for (matchp = cs->matches; matchp; matchp = matchp->next) {
		struct xt_xlate_mt_params params = {
			.ip		= (const void *)&cs->fw,
			.match		= matchp->match->m,
			.numeric	= numeric,
			.escape_quotes	= !cs->restore,
		};

		if (!matchp->match->xlate)
			return 0;

		ret = matchp->match->xlate(xl, &params);

		if (strcmp(matchp->match->name, "comment") != 0)
			xt_xlate_add(xl, " ");

		if (!ret)
			break;
	}
	return ret;
}

bool xlate_find_match(const struct iptables_command_state *cs, const char *p_name)
{
	struct xtables_rule_match *matchp;

	/* Skip redundant protocol, eg. ip protocol tcp tcp dport */
	for (matchp = cs->matches; matchp; matchp = matchp->next) {
		if (strcmp(matchp->match->name, p_name) == 0)
			return true;
	}
	return false;
}

const char *family2str[] = {
	[NFPROTO_IPV4]	= "ip",
	[NFPROTO_IPV6]	= "ip6",
};

static int nft_rule_xlate_add(struct nft_handle *h,
			      const struct nft_xt_cmd_parse *p,
			      const struct iptables_command_state *cs,
			      bool append)
{
	struct xt_xlate *xl = xt_xlate_alloc(10240);
	int ret;

	if (append) {
		xt_xlate_add(xl, "add rule %s %s %s ",
			   family2str[h->family], p->table, p->chain);
	} else {
		xt_xlate_add(xl, "insert rule %s %s %s ",
			   family2str[h->family], p->table, p->chain);
	}

	ret = h->ops->xlate(cs, xl);
	if (ret)
		printf("%s\n", xt_xlate_get(xl));

	xt_xlate_free(xl);
	return ret;
}

static int xlate(struct nft_handle *h, struct nft_xt_cmd_parse *p,
		 struct iptables_command_state *cs,
		 struct xtables_args *args, bool append,
		 int (*cb)(struct nft_handle *h,
			   const struct nft_xt_cmd_parse *p,
			   const struct iptables_command_state *cs,
			   bool append))
{
	unsigned int i, j;
	int ret = 1;

	for (i = 0; i < args->s.naddrs; i++) {
		switch (h->family) {
		case AF_INET:
			cs->fw.ip.src.s_addr = args->s.addr.v4[i].s_addr;
			cs->fw.ip.smsk.s_addr = args->s.mask.v4[i].s_addr;
			for (j = 0; j < args->d.naddrs; j++) {
				cs->fw.ip.dst.s_addr =
					args->d.addr.v4[j].s_addr;
				cs->fw.ip.dmsk.s_addr =
					args->d.mask.v4[j].s_addr;
				ret = cb(h, p, cs, append);
			}
			break;
		case AF_INET6:
			memcpy(&cs->fw6.ipv6.src,
			       &args->s.addr.v6[i], sizeof(struct in6_addr));
			memcpy(&cs->fw6.ipv6.smsk,
			       &args->s.mask.v6[i], sizeof(struct in6_addr));
			for (j = 0; j < args->d.naddrs; j++) {
				memcpy(&cs->fw6.ipv6.dst,
				       &args->d.addr.v6[j],
				       sizeof(struct in6_addr));
				memcpy(&cs->fw6.ipv6.dmsk,
				       &args->d.mask.v6[j],
				       sizeof(struct in6_addr));
				ret = cb(h, p, cs, append);
			}
			break;
		}
		if (!cs->restore && i < args->s.naddrs - 1)
			printf("nft ");
	}

	return ret;
}

static void print_ipt_cmd(int argc, char *argv[])
{
	int i;

	printf("# ");
	for (i = 1; i < argc; i++)
		printf("%s ", argv[i]);

	printf("\n");
}

static int do_command_xlate(struct nft_handle *h, int argc, char *argv[],
			    char **table, bool restore)
{
	int ret = 0;
	struct nft_xt_cmd_parse p = {
		.table		= *table,
		.restore	= restore,
		.xlate		= true,
	};
	struct iptables_command_state cs;
	struct xtables_args args = {
		.family = h->family,
	};

	do_parse(h, argc, argv, &p, &cs, &args);

	cs.restore = restore;

	if (!restore && p.command != CMD_NONE)
		printf("nft ");

	switch (p.command) {
	case CMD_APPEND:
		ret = 1;
		if (!xlate(h, &p, &cs, &args, true, nft_rule_xlate_add))
			print_ipt_cmd(argc, argv);
		break;
	case CMD_DELETE:
		break;
	case CMD_DELETE_NUM:
		break;
	case CMD_CHECK:
		break;
	case CMD_REPLACE:
		break;
	case CMD_INSERT:
		ret = 1;
		if (!xlate(h, &p, &cs, &args, false, nft_rule_xlate_add))
			print_ipt_cmd(argc, argv);
		break;
	case CMD_FLUSH:
		if (p.chain) {
			printf("flush chain %s %s %s\n",
				family2str[h->family], p.table, p.chain);
		} else {
			printf("flush table %s %s\n",
				family2str[h->family], p.table);
		}
		ret = 1;
		break;
	case CMD_ZERO:
		break;
	case CMD_ZERO_NUM:
		break;
	case CMD_LIST:
	case CMD_LIST|CMD_ZERO:
	case CMD_LIST|CMD_ZERO_NUM:
		printf("list table %s %s\n",
		       family2str[h->family], p.table);
		ret = 1;
		break;
	case CMD_LIST_RULES:
	case CMD_LIST_RULES|CMD_ZERO:
	case CMD_LIST_RULES|CMD_ZERO_NUM:
		break;
	case CMD_NEW_CHAIN:
		printf("add chain %s %s %s\n",
		       family2str[h->family], p.table, p.chain);
		ret = 1;
		break;
	case CMD_DELETE_CHAIN:
		printf("delete chain %s %s %s\n",
		       family2str[h->family], p.table, p.chain);
		ret = 1;
		break;
	case CMD_RENAME_CHAIN:
		break;
	case CMD_SET_POLICY:
		break;
	case CMD_NONE:
		ret = 1;
		break;
	default:
		/* We should never reach this... */
		printf("Unsupported command?\n");
		exit(1);
	}

	nft_clear_iptables_command_state(&cs);

	if (h->family == AF_INET) {
		free(args.s.addr.v4);
		free(args.s.mask.v4);
		free(args.d.addr.v4);
		free(args.d.mask.v4);
	} else if (h->family == AF_INET6) {
		free(args.s.addr.v6);
		free(args.s.mask.v6);
		free(args.d.addr.v6);
		free(args.d.mask.v6);
	}
	xtables_free_opts(1);

	return ret;
}

static void print_usage(const char *name, const char *version)
{
	fprintf(stderr, "%s %s "
			"(c) 2014 by Pablo Neira Ayuso <pablo@netfilter.org>\n"
			"Usage: %s [-h] [-f]\n"
                        "	[ --help ]\n"
                        "	[ --file=<FILE> ]\n", name, version, name);
        exit(1);
}

static const struct option options[] = {
	{ .name = "help",	.has_arg = false,	.val = 'h' },
	{ .name = "file",	.has_arg = true,	.val = 'f' },
	{ .name = "version",	.has_arg = false,	.val = 'V' },
	{ NULL },
};

static int xlate_chain_user_restore(struct nft_handle *h, const char *chain,
				    const char *table)
{
	printf("add chain %s %s %s\n", family2str[h->family], table, chain);
	return 0;
}

static int commit(struct nft_handle *h)
{
	return 1;
}

static void xlate_table_new(struct nft_handle *h, const char *table)
{
	printf("add table %s %s\n", family2str[h->family], table);
}

static int get_hook_prio(const char *table, const char *chain)
{
	int prio = 0;

	if (strcmp("nat", table) == 0) {
		if (strcmp(chain, "PREROUTING") == 0)
			prio = NF_IP_PRI_NAT_DST;
		if (strcmp(chain, "INPUT") == 0)
			prio = NF_IP_PRI_NAT_SRC;
		if (strcmp(chain, "OUTPUT") == 0)
			prio = NF_IP_PRI_NAT_DST;
		if (strcmp(chain, "POSTROUTING") == 0)
			prio = NF_IP_PRI_NAT_SRC;
	} else if (strcmp("mangle", table) == 0) {
		prio = NF_IP_PRI_MANGLE;
	} else if (strcmp("raw", table) == 0) {
		prio = NF_IP_PRI_RAW;
	} else if (strcmp(chain, "security") == 0) {
		prio = NF_IP_PRI_SECURITY;
	}

	return prio;
}

static int xlate_chain_set(struct nft_handle *h, const char *table,
			   const char *chain, const char *policy,
			   const struct xt_counters *counters)
{
	const char *type = "filter";
	int prio;

	if (strcmp(table, "nat") == 0)
		type = "nat";
	else if (strcmp(table, "mangle") == 0 && strcmp(chain, "OUTPUT") == 0)
		type = "route";

	printf("add chain %s %s %s { type %s ",
	       family2str[h->family], table, chain, type);
	prio = get_hook_prio(table, chain);
	if (strcmp(chain, "PREROUTING") == 0)
		printf("hook prerouting priority %d; ", prio);
	else if (strcmp(chain, "INPUT") == 0)
		printf("hook input priority %d; ", prio);
	else if (strcmp(chain, "FORWARD") == 0)
		printf("hook forward priority %d; ", prio);
	else if (strcmp(chain, "OUTPUT") == 0)
		printf("hook output priority %d; ", prio);
	else if (strcmp(chain, "POSTROUTING") == 0)
		printf("hook postrouting priority %d; ", prio);

	if (strcmp(policy, "ACCEPT") == 0)
		printf("policy accept; ");
	else if (strcmp(policy, "DROP") == 0)
		printf("policy drop; ");

	printf("}\n");
	return 1;
}

static int dummy_compat_rev(const char *name, uint8_t rev, int opt)
{
	/* Avoid querying the kernel - it's not needed when just translating
	 * rules and not even possible when running as unprivileged user.
	 */
	return 1;
}

static const struct nft_xt_restore_cb cb_xlate = {
	.table_new	= xlate_table_new,
	.chain_set	= xlate_chain_set,
	.chain_restore	= xlate_chain_user_restore,
	.do_command	= do_command_xlate,
	.commit		= commit,
	.abort		= commit,
};

static int xtables_xlate_main_common(struct nft_handle *h,
				     int family,
				     const char *progname)
{
	const struct builtin_table *tables;
	int ret;

	xtables_globals.program_name = progname;
	xtables_globals.compat_rev = dummy_compat_rev;
	ret = xtables_init_all(&xtables_globals, family);
	if (ret < 0) {
		fprintf(stderr, "%s/%s Failed to initialize xtables\n",
			xtables_globals.program_name,
			xtables_globals.program_version);
		return 1;
	}
	switch (family) {
	case NFPROTO_IPV4:
	case NFPROTO_IPV6: /* fallthrough: same table */
#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
	init_extensions();
	init_extensions4();
#endif
		tables = xtables_ipv4;
		break;
	case NFPROTO_ARP:
		tables = xtables_arp;
		break;
	case NFPROTO_BRIDGE:
		tables = xtables_bridge;
		break;
	default:
		fprintf(stderr, "Unknown family %d\n", family);
		return 1;
	}

	if (nft_init(h, family, tables) < 0) {
		fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
				xtables_globals.program_name,
				xtables_globals.program_version,
				strerror(errno));
		return 1;
	}

	return 0;
}

static int xtables_xlate_main(int family, const char *progname, int argc,
			      char *argv[])
{
	int ret;
	char *table = "filter";
	struct nft_handle h = {
		.family = family,
	};

	ret = xtables_xlate_main_common(&h, family, progname);
	if (ret < 0)
		exit(EXIT_FAILURE);

	ret = do_command_xlate(&h, argc, argv, &table, false);
	if (!ret)
		fprintf(stderr, "Translation not implemented\n");

	nft_fini(&h);
	xtables_fini();
	exit(!ret);
}

static int xtables_restore_xlate_main(int family, const char *progname,
				      int argc, char *argv[])
{
	int ret;
	struct nft_handle h = {
		.family = family,
	};
	const char *file = NULL;
	struct nft_xt_restore_parse p = {
		.cb = &cb_xlate,
	};
	time_t now = time(NULL);
	int c;

	ret = xtables_xlate_main_common(&h, family, progname);
	if (ret < 0)
		exit(EXIT_FAILURE);

	opterr = 0;
	while ((c = getopt_long(argc, argv, "hf:V", options, NULL)) != -1) {
		switch (c) {
		case 'h':
			print_usage(argv[0], PACKAGE_VERSION);
			exit(0);
		case 'f':
			file = optarg;
			break;
		case 'V':
			printf("%s v%s\n", argv[0], PACKAGE_VERSION);
			exit(0);
		}
	}

	if (file == NULL) {
		fprintf(stderr, "ERROR: missing file name\n");
		print_usage(argv[0], PACKAGE_VERSION);
		exit(0);
	}

	p.in = fopen(file, "r");
	if (p.in == NULL) {
		fprintf(stderr, "Cannot open file %s\n", file);
		exit(1);
	}

	printf("# Translated by %s v%s on %s",
	       argv[0], PACKAGE_VERSION, ctime(&now));
	xtables_restore_parse(&h, &p);
	printf("# Completed on %s", ctime(&now));

	nft_fini(&h);
	xtables_fini();
	fclose(p.in);
	exit(0);
}

int xtables_ip4_xlate_main(int argc, char *argv[])
{
	return xtables_xlate_main(NFPROTO_IPV4, "iptables-translate",
				  argc, argv);
}

int xtables_ip6_xlate_main(int argc, char *argv[])
{
	return xtables_xlate_main(NFPROTO_IPV6, "ip6tables-translate",
				  argc, argv);
}

int xtables_ip4_xlate_restore_main(int argc, char *argv[])
{
	return xtables_restore_xlate_main(NFPROTO_IPV4,
					  "iptables-translate-restore",
					  argc, argv);
}

int xtables_ip6_xlate_restore_main(int argc, char *argv[])
{
	return xtables_restore_xlate_main(NFPROTO_IPV6,
					  "ip6tables-translate-restore",
					  argc, argv);
}
