Blame iptables/xtables-translate.c

Packit 7b22a4
/*
Packit 7b22a4
 * (C) 2014 by Pablo Neira Ayuso <pablo@netfilter.org>
Packit 7b22a4
 *
Packit 7b22a4
 * This program is free software; you can redistribute it and/or modify
Packit 7b22a4
 * it under the terms of the GNU General Public License as published
Packit 7b22a4
 * by the Free Software Foundation; either version 2 of the License, or
Packit 7b22a4
 * (at your option) any later version.
Packit 7b22a4
 */
Packit 7b22a4
#include "config.h"
Packit 7b22a4
#include <time.h>
Packit 7b22a4
#include "xtables-multi.h"
Packit 7b22a4
#include "nft.h"
Packit 7b22a4
Packit 7b22a4
#include <string.h>
Packit 7b22a4
#include <netdb.h>
Packit 7b22a4
#include <errno.h>
Packit 7b22a4
#include <stdbool.h>
Packit 7b22a4
#include <stdio.h>
Packit 7b22a4
#include <stdlib.h>
Packit 7b22a4
#include <ctype.h>
Packit 7b22a4
#include <stdarg.h>
Packit 7b22a4
#include <limits.h>
Packit 7b22a4
#include <unistd.h>
Packit 7b22a4
#include <iptables.h>
Packit 7b22a4
#include <xtables.h>
Packit 7b22a4
#include <libiptc/libxtc.h>
Packit 7b22a4
#include <fcntl.h>
Packit 7b22a4
#include <getopt.h>
Packit 7b22a4
#include "xshared.h"
Packit 7b22a4
#include "nft-shared.h"
Packit 7b22a4
Packit 7b22a4
void xlate_ifname(struct xt_xlate *xl, const char *nftmeta, const char *ifname,
Packit 7b22a4
		  bool invert)
Packit 7b22a4
{
Packit Service aab5b7
	int ifaclen = strlen(ifname), i, j;
Packit Service aab5b7
	char iface[IFNAMSIZ * 2];
Packit 7b22a4
Packit Service 6a5833
	if (ifaclen < 1 || ifaclen >= IFNAMSIZ)
Packit 7b22a4
		return;
Packit 7b22a4
Packit Service aab5b7
	for (i = 0, j = 0; i < ifaclen + 1; i++, j++) {
Packit Service aab5b7
		switch (ifname[i]) {
Packit Service aab5b7
		case '*':
Packit Service aab5b7
			iface[j++] = '\\';
Packit Service aab5b7
			/* fall through */
Packit Service aab5b7
		default:
Packit Service aab5b7
			iface[j] = ifname[i];
Packit Service aab5b7
			break;
Packit Service aab5b7
		}
Packit Service aab5b7
	}
Packit Service aab5b7
Packit Service aab5b7
	if (ifaclen == 1 && ifname[0] == '+') {
Packit Service aab5b7
		/* Nftables does not support wildcard only string. Workaround
Packit Service aab5b7
		 * is easy, given that this will match always or never
Packit Service aab5b7
		 * depending on 'invert' value. To match always, simply don't
Packit Service aab5b7
		 * generate an expression. To match never, use an invalid
Packit Service aab5b7
		 * interface name (kernel doesn't accept '/' in names) to match
Packit Service aab5b7
		 * against. */
Packit Service aab5b7
		if (!invert)
Packit Service aab5b7
			return;
Packit Service aab5b7
		strcpy(iface, "INVAL/D");
Packit Service aab5b7
		invert = false;
Packit Service aab5b7
	}
Packit Service c907bb
Packit Service ecc75c
	if (iface[j - 2] == '+')
Packit Service ecc75c
		iface[j - 2] = '*';
Packit Service ecc75c
Packit 7b22a4
	xt_xlate_add(xl, "%s %s\"%s\" ", nftmeta, invert ? "!= " : "", iface);
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
int xlate_action(const struct iptables_command_state *cs, bool goto_set,
Packit 7b22a4
		 struct xt_xlate *xl)
Packit 7b22a4
{
Packit 7b22a4
	int ret = 1, numeric = cs->options & OPT_NUMERIC;
Packit 7b22a4
Packit 7b22a4
	/* If no target at all, add nothing (default to continue) */
Packit 7b22a4
	if (cs->target != NULL) {
Packit 7b22a4
		/* Standard target? */
Packit 7b22a4
		if (strcmp(cs->jumpto, XTC_LABEL_ACCEPT) == 0)
Packit 7b22a4
			xt_xlate_add(xl, " accept");
Packit 7b22a4
		else if (strcmp(cs->jumpto, XTC_LABEL_DROP) == 0)
Packit 7b22a4
			xt_xlate_add(xl, " drop");
Packit 7b22a4
		else if (strcmp(cs->jumpto, XTC_LABEL_RETURN) == 0)
Packit 7b22a4
			xt_xlate_add(xl, " return");
Packit 7b22a4
		else if (cs->target->xlate) {
Packit 7b22a4
			xt_xlate_add(xl, " ");
Packit 7b22a4
			struct xt_xlate_tg_params params = {
Packit 7b22a4
				.ip		= (const void *)&cs->fw,
Packit 7b22a4
				.target		= cs->target->t,
Packit 7b22a4
				.numeric	= numeric,
Packit 7b22a4
				.escape_quotes	= !cs->restore,
Packit 7b22a4
			};
Packit 7b22a4
			ret = cs->target->xlate(xl, &params);
Packit 7b22a4
		}
Packit 7b22a4
		else
Packit 7b22a4
			return 0;
Packit 7b22a4
	} else if (strlen(cs->jumpto) > 0) {
Packit 7b22a4
		/* Not standard, then it's a go / jump to chain */
Packit 7b22a4
		if (goto_set)
Packit 7b22a4
			xt_xlate_add(xl, " goto %s", cs->jumpto);
Packit 7b22a4
		else
Packit 7b22a4
			xt_xlate_add(xl, " jump %s", cs->jumpto);
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	return ret;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
int xlate_matches(const struct iptables_command_state *cs, struct xt_xlate *xl)
Packit 7b22a4
{
Packit 7b22a4
	struct xtables_rule_match *matchp;
Packit 7b22a4
	int ret = 1, numeric = cs->options & OPT_NUMERIC;
Packit 7b22a4
Packit 7b22a4
	for (matchp = cs->matches; matchp; matchp = matchp->next) {
Packit 7b22a4
		struct xt_xlate_mt_params params = {
Packit 7b22a4
			.ip		= (const void *)&cs->fw,
Packit 7b22a4
			.match		= matchp->match->m,
Packit 7b22a4
			.numeric	= numeric,
Packit 7b22a4
			.escape_quotes	= !cs->restore,
Packit 7b22a4
		};
Packit 7b22a4
Packit 7b22a4
		if (!matchp->match->xlate)
Packit 7b22a4
			return 0;
Packit 7b22a4
Packit 7b22a4
		ret = matchp->match->xlate(xl, &params);
Packit 7b22a4
Packit 7b22a4
		if (strcmp(matchp->match->name, "comment") != 0)
Packit 7b22a4
			xt_xlate_add(xl, " ");
Packit 7b22a4
Packit 7b22a4
		if (!ret)
Packit 7b22a4
			break;
Packit 7b22a4
	}
Packit 7b22a4
	return ret;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
bool xlate_find_match(const struct iptables_command_state *cs, const char *p_name)
Packit 7b22a4
{
Packit 7b22a4
	struct xtables_rule_match *matchp;
Packit 7b22a4
Packit 7b22a4
	/* Skip redundant protocol, eg. ip protocol tcp tcp dport */
Packit 7b22a4
	for (matchp = cs->matches; matchp; matchp = matchp->next) {
Packit 7b22a4
		if (strcmp(matchp->match->name, p_name) == 0)
Packit 7b22a4
			return true;
Packit 7b22a4
	}
Packit 7b22a4
	return false;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
const char *family2str[] = {
Packit 7b22a4
	[NFPROTO_IPV4]	= "ip",
Packit 7b22a4
	[NFPROTO_IPV6]	= "ip6",
Packit 7b22a4
};
Packit 7b22a4
Packit 7b22a4
static int nft_rule_xlate_add(struct nft_handle *h,
Packit 7b22a4
			      const struct nft_xt_cmd_parse *p,
Packit 7b22a4
			      const struct iptables_command_state *cs,
Packit 7b22a4
			      bool append)
Packit 7b22a4
{
Packit 7b22a4
	struct xt_xlate *xl = xt_xlate_alloc(10240);
Packit 7b22a4
	int ret;
Packit 7b22a4
Packit 7b22a4
	if (append) {
Packit 7b22a4
		xt_xlate_add(xl, "add rule %s %s %s ",
Packit 7b22a4
			   family2str[h->family], p->table, p->chain);
Packit 7b22a4
	} else {
Packit 7b22a4
		xt_xlate_add(xl, "insert rule %s %s %s ",
Packit 7b22a4
			   family2str[h->family], p->table, p->chain);
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	ret = h->ops->xlate(cs, xl);
Packit 7b22a4
	if (ret)
Packit 7b22a4
		printf("%s\n", xt_xlate_get(xl));
Packit 7b22a4
Packit 7b22a4
	xt_xlate_free(xl);
Packit 7b22a4
	return ret;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static int xlate(struct nft_handle *h, struct nft_xt_cmd_parse *p,
Packit 7b22a4
		 struct iptables_command_state *cs,
Packit 7b22a4
		 struct xtables_args *args, bool append,
Packit 7b22a4
		 int (*cb)(struct nft_handle *h,
Packit 7b22a4
			   const struct nft_xt_cmd_parse *p,
Packit 7b22a4
			   const struct iptables_command_state *cs,
Packit 7b22a4
			   bool append))
Packit 7b22a4
{
Packit 7b22a4
	unsigned int i, j;
Packit 7b22a4
	int ret = 1;
Packit 7b22a4
Packit 7b22a4
	for (i = 0; i < args->s.naddrs; i++) {
Packit 7b22a4
		switch (h->family) {
Packit 7b22a4
		case AF_INET:
Packit 7b22a4
			cs->fw.ip.src.s_addr = args->s.addr.v4[i].s_addr;
Packit 7b22a4
			cs->fw.ip.smsk.s_addr = args->s.mask.v4[i].s_addr;
Packit 7b22a4
			for (j = 0; j < args->d.naddrs; j++) {
Packit 7b22a4
				cs->fw.ip.dst.s_addr =
Packit 7b22a4
					args->d.addr.v4[j].s_addr;
Packit 7b22a4
				cs->fw.ip.dmsk.s_addr =
Packit 7b22a4
					args->d.mask.v4[j].s_addr;
Packit 7b22a4
				ret = cb(h, p, cs, append);
Packit 7b22a4
			}
Packit 7b22a4
			break;
Packit 7b22a4
		case AF_INET6:
Packit 7b22a4
			memcpy(&cs->fw6.ipv6.src,
Packit 7b22a4
			       &args->s.addr.v6[i], sizeof(struct in6_addr));
Packit 7b22a4
			memcpy(&cs->fw6.ipv6.smsk,
Packit 7b22a4
			       &args->s.mask.v6[i], sizeof(struct in6_addr));
Packit 7b22a4
			for (j = 0; j < args->d.naddrs; j++) {
Packit 7b22a4
				memcpy(&cs->fw6.ipv6.dst,
Packit 7b22a4
				       &args->d.addr.v6[j],
Packit 7b22a4
				       sizeof(struct in6_addr));
Packit 7b22a4
				memcpy(&cs->fw6.ipv6.dmsk,
Packit 7b22a4
				       &args->d.mask.v6[j],
Packit 7b22a4
				       sizeof(struct in6_addr));
Packit 7b22a4
				ret = cb(h, p, cs, append);
Packit 7b22a4
			}
Packit 7b22a4
			break;
Packit 7b22a4
		}
Packit 7b22a4
		if (!cs->restore && i < args->s.naddrs - 1)
Packit 7b22a4
			printf("nft ");
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	return ret;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void print_ipt_cmd(int argc, char *argv[])
Packit 7b22a4
{
Packit 7b22a4
	int i;
Packit 7b22a4
Packit 7b22a4
	printf("# ");
Packit 7b22a4
	for (i = 1; i < argc; i++)
Packit 7b22a4
		printf("%s ", argv[i]);
Packit 7b22a4
Packit 7b22a4
	printf("\n");
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static int do_command_xlate(struct nft_handle *h, int argc, char *argv[],
Packit 7b22a4
			    char **table, bool restore)
Packit 7b22a4
{
Packit 7b22a4
	int ret = 0;
Packit 7b22a4
	struct nft_xt_cmd_parse p = {
Packit 7b22a4
		.table		= *table,
Packit 7b22a4
		.restore	= restore,
Packit 7b22a4
		.xlate		= true,
Packit 7b22a4
	};
Packit 7b22a4
	struct iptables_command_state cs;
Packit 7b22a4
	struct xtables_args args = {
Packit 7b22a4
		.family = h->family,
Packit 7b22a4
	};
Packit 7b22a4
Packit 7b22a4
	do_parse(h, argc, argv, &p, &cs, &args);
Packit 7b22a4
Packit 7b22a4
	cs.restore = restore;
Packit 7b22a4
Packit 7b22a4
	if (!restore)
Packit 7b22a4
		printf("nft ");
Packit 7b22a4
Packit 7b22a4
	switch (p.command) {
Packit 7b22a4
	case CMD_APPEND:
Packit 7b22a4
		ret = 1;
Packit 7b22a4
		if (!xlate(h, &p, &cs, &args, true, nft_rule_xlate_add))
Packit 7b22a4
			print_ipt_cmd(argc, argv);
Packit 7b22a4
		break;
Packit 7b22a4
	case CMD_DELETE:
Packit 7b22a4
		break;
Packit 7b22a4
	case CMD_DELETE_NUM:
Packit 7b22a4
		break;
Packit 7b22a4
	case CMD_CHECK:
Packit 7b22a4
		break;
Packit 7b22a4
	case CMD_REPLACE:
Packit 7b22a4
		break;
Packit 7b22a4
	case CMD_INSERT:
Packit 7b22a4
		ret = 1;
Packit 7b22a4
		if (!xlate(h, &p, &cs, &args, false, nft_rule_xlate_add))
Packit 7b22a4
			print_ipt_cmd(argc, argv);
Packit 7b22a4
		break;
Packit 7b22a4
	case CMD_FLUSH:
Packit 7b22a4
		if (p.chain) {
Packit 7b22a4
			printf("flush chain %s %s %s\n",
Packit 7b22a4
				family2str[h->family], p.table, p.chain);
Packit 7b22a4
		} else {
Packit 7b22a4
			printf("flush table %s %s\n",
Packit 7b22a4
				family2str[h->family], p.table);
Packit 7b22a4
		}
Packit 7b22a4
		ret = 1;
Packit 7b22a4
		break;
Packit 7b22a4
	case CMD_ZERO:
Packit 7b22a4
		break;
Packit 7b22a4
	case CMD_ZERO_NUM:
Packit 7b22a4
		break;
Packit 7b22a4
	case CMD_LIST:
Packit 7b22a4
	case CMD_LIST|CMD_ZERO:
Packit 7b22a4
	case CMD_LIST|CMD_ZERO_NUM:
Packit 7b22a4
		printf("list table %s %s\n",
Packit 7b22a4
		       family2str[h->family], p.table);
Packit 7b22a4
		ret = 1;
Packit 7b22a4
		break;
Packit 7b22a4
	case CMD_LIST_RULES:
Packit 7b22a4
	case CMD_LIST_RULES|CMD_ZERO:
Packit 7b22a4
	case CMD_LIST_RULES|CMD_ZERO_NUM:
Packit 7b22a4
		break;
Packit 7b22a4
	case CMD_NEW_CHAIN:
Packit 7b22a4
		printf("add chain %s %s %s\n",
Packit 7b22a4
		       family2str[h->family], p.table, p.chain);
Packit 7b22a4
		ret = 1;
Packit 7b22a4
		break;
Packit 7b22a4
	case CMD_DELETE_CHAIN:
Packit 7b22a4
		printf("delete chain %s %s %s\n",
Packit 7b22a4
		       family2str[h->family], p.table, p.chain);
Packit 7b22a4
		ret = 1;
Packit 7b22a4
		break;
Packit 7b22a4
	case CMD_RENAME_CHAIN:
Packit 7b22a4
		break;
Packit 7b22a4
	case CMD_SET_POLICY:
Packit 7b22a4
		break;
Packit 7b22a4
	default:
Packit 7b22a4
		/* We should never reach this... */
Packit 7b22a4
		printf("Unsupported command?\n");
Packit 7b22a4
		exit(1);
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	xtables_rule_matches_free(&cs.matches);
Packit 7b22a4
Packit 7b22a4
	if (h->family == AF_INET) {
Packit 7b22a4
		free(args.s.addr.v4);
Packit 7b22a4
		free(args.s.mask.v4);
Packit 7b22a4
		free(args.d.addr.v4);
Packit 7b22a4
		free(args.d.mask.v4);
Packit 7b22a4
	} else if (h->family == AF_INET6) {
Packit 7b22a4
		free(args.s.addr.v6);
Packit 7b22a4
		free(args.s.mask.v6);
Packit 7b22a4
		free(args.d.addr.v6);
Packit 7b22a4
		free(args.d.mask.v6);
Packit 7b22a4
	}
Packit 7b22a4
	xtables_free_opts(1);
Packit 7b22a4
Packit 7b22a4
	return ret;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void print_usage(const char *name, const char *version)
Packit 7b22a4
{
Packit 7b22a4
	fprintf(stderr, "%s %s "
Packit 7b22a4
			"(c) 2014 by Pablo Neira Ayuso <pablo@netfilter.org>\n"
Packit 7b22a4
			"Usage: %s [-h] [-f]\n"
Packit 7b22a4
                        "	[ --help ]\n"
Packit 7b22a4
                        "	[ --file=<FILE> ]\n", name, version, name);
Packit 7b22a4
        exit(1);
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static const struct option options[] = {
Packit 7b22a4
	{ .name = "help",	.has_arg = false,	.val = 'h' },
Packit 7b22a4
	{ .name = "file",	.has_arg = true,	.val = 'f' },
Packit 7b22a4
	{ .name = "version",	.has_arg = false,	.val = 'V' },
Packit 7b22a4
	{ NULL },
Packit 7b22a4
};
Packit 7b22a4
Packit 7b22a4
static int xlate_chain_user_restore(struct nft_handle *h, const char *chain,
Packit 7b22a4
				    const char *table)
Packit 7b22a4
{
Packit 7b22a4
	printf("add chain %s %s %s\n", family2str[h->family], table, chain);
Packit 7b22a4
	return 0;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static int commit(struct nft_handle *h)
Packit 7b22a4
{
Packit 7b22a4
	return 1;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void xlate_table_new(struct nft_handle *h, const char *table)
Packit 7b22a4
{
Packit 7b22a4
	printf("add table %s %s\n", family2str[h->family], table);
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static int get_hook_prio(const char *table, const char *chain)
Packit 7b22a4
{
Packit 7b22a4
	int prio = 0;
Packit 7b22a4
Packit 7b22a4
	if (strcmp("nat", table) == 0) {
Packit 7b22a4
		if (strcmp(chain, "PREROUTING") == 0)
Packit 7b22a4
			prio = NF_IP_PRI_NAT_DST;
Packit 7b22a4
		if (strcmp(chain, "INPUT") == 0)
Packit 7b22a4
			prio = NF_IP_PRI_NAT_SRC;
Packit 7b22a4
		if (strcmp(chain, "OUTPUT") == 0)
Packit 7b22a4
			prio = NF_IP_PRI_NAT_DST;
Packit 7b22a4
		if (strcmp(chain, "POSTROUTING") == 0)
Packit 7b22a4
			prio = NF_IP_PRI_NAT_SRC;
Packit 7b22a4
	} else if (strcmp("mangle", table) == 0) {
Packit 7b22a4
		prio = NF_IP_PRI_MANGLE;
Packit 7b22a4
	} else if (strcmp("raw", table) == 0) {
Packit 7b22a4
		prio = NF_IP_PRI_RAW;
Packit 7b22a4
	} else if (strcmp(chain, "security") == 0) {
Packit 7b22a4
		prio = NF_IP_PRI_SECURITY;
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	return prio;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static int xlate_chain_set(struct nft_handle *h, const char *table,
Packit 7b22a4
			   const char *chain, const char *policy,
Packit 7b22a4
			   const struct xt_counters *counters)
Packit 7b22a4
{
Packit 7b22a4
	const char *type = "filter";
Packit 7b22a4
	int prio;
Packit 7b22a4
Packit 7b22a4
	if (strcmp(table, "nat") == 0)
Packit 7b22a4
		type = "nat";
Packit 7b22a4
	else if (strcmp(table, "mangle") == 0 && strcmp(chain, "OUTPUT") == 0)
Packit 7b22a4
		type = "route";
Packit 7b22a4
Packit 7b22a4
	printf("add chain %s %s %s { type %s ",
Packit 7b22a4
	       family2str[h->family], table, chain, type);
Packit 7b22a4
	prio = get_hook_prio(table, chain);
Packit 7b22a4
	if (strcmp(chain, "PREROUTING") == 0)
Packit 7b22a4
		printf("hook prerouting priority %d; ", prio);
Packit 7b22a4
	else if (strcmp(chain, "INPUT") == 0)
Packit 7b22a4
		printf("hook input priority %d; ", prio);
Packit 7b22a4
	else if (strcmp(chain, "FORWARD") == 0)
Packit 7b22a4
		printf("hook forward priority %d; ", prio);
Packit 7b22a4
	else if (strcmp(chain, "OUTPUT") == 0)
Packit 7b22a4
		printf("hook output priority %d; ", prio);
Packit 7b22a4
	else if (strcmp(chain, "POSTROUTING") == 0)
Packit 7b22a4
		printf("hook postrouting priority %d; ", prio);
Packit 7b22a4
Packit 7b22a4
	if (strcmp(policy, "ACCEPT") == 0)
Packit 7b22a4
		printf("policy accept; ");
Packit 7b22a4
	else if (strcmp(policy, "DROP") == 0)
Packit 7b22a4
		printf("policy drop; ");
Packit 7b22a4
Packit 7b22a4
	printf("}\n");
Packit 7b22a4
	return 1;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static int dummy_compat_rev(const char *name, uint8_t rev, int opt)
Packit 7b22a4
{
Packit 7b22a4
	/* Avoid querying the kernel - it's not needed when just translating
Packit 7b22a4
	 * rules and not even possible when running as unprivileged user.
Packit 7b22a4
	 */
Packit 7b22a4
	return 1;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static const struct nft_xt_restore_cb cb_xlate = {
Packit 7b22a4
	.table_new	= xlate_table_new,
Packit 7b22a4
	.chain_set	= xlate_chain_set,
Packit 7b22a4
	.chain_restore	= xlate_chain_user_restore,
Packit 7b22a4
	.do_command	= do_command_xlate,
Packit 7b22a4
	.commit		= commit,
Packit 7b22a4
	.abort		= commit,
Packit 7b22a4
};
Packit 7b22a4
Packit 7b22a4
static int xtables_xlate_main_common(struct nft_handle *h,
Packit 7b22a4
				     int family,
Packit 7b22a4
				     const char *progname)
Packit 7b22a4
{
Packit 7b22a4
	const struct builtin_table *tables;
Packit 7b22a4
	int ret;
Packit 7b22a4
Packit 7b22a4
	xtables_globals.program_name = progname;
Packit 7b22a4
	xtables_globals.compat_rev = dummy_compat_rev;
Packit 7b22a4
	ret = xtables_init_all(&xtables_globals, family);
Packit 7b22a4
	if (ret < 0) {
Packit 7b22a4
		fprintf(stderr, "%s/%s Failed to initialize xtables\n",
Packit 7b22a4
			xtables_globals.program_name,
Packit 7b22a4
			xtables_globals.program_version);
Packit 7b22a4
		return 1;
Packit 7b22a4
	}
Packit 7b22a4
	switch (family) {
Packit 7b22a4
	case NFPROTO_IPV4:
Packit 7b22a4
	case NFPROTO_IPV6: /* fallthrough: same table */
Packit 7b22a4
#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
Packit 7b22a4
	init_extensions();
Packit 7b22a4
	init_extensions4();
Packit 7b22a4
#endif
Packit 7b22a4
		tables = xtables_ipv4;
Packit 7b22a4
		break;
Packit 7b22a4
	case NFPROTO_ARP:
Packit 7b22a4
		tables = xtables_arp;
Packit 7b22a4
		break;
Packit 7b22a4
	case NFPROTO_BRIDGE:
Packit 7b22a4
		tables = xtables_bridge;
Packit 7b22a4
		break;
Packit 7b22a4
	default:
Packit 7b22a4
		fprintf(stderr, "Unknown family %d\n", family);
Packit 7b22a4
		return 1;
Packit 7b22a4
	}
Packit 7b22a4
Packit Service 635b90
	if (nft_init(h, tables) < 0) {
Packit 7b22a4
		fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
Packit 7b22a4
				xtables_globals.program_name,
Packit 7b22a4
				xtables_globals.program_version,
Packit 7b22a4
				strerror(errno));
Packit 7b22a4
		return 1;
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	return 0;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static int xtables_xlate_main(int family, const char *progname, int argc,
Packit 7b22a4
			      char *argv[])
Packit 7b22a4
{
Packit 7b22a4
	int ret;
Packit 7b22a4
	char *table = "filter";
Packit 7b22a4
	struct nft_handle h = {
Packit 7b22a4
		.family = family,
Packit 7b22a4
	};
Packit 7b22a4
Packit 7b22a4
	ret = xtables_xlate_main_common(&h, family, progname);
Packit 7b22a4
	if (ret < 0)
Packit 7b22a4
		exit(EXIT_FAILURE);
Packit 7b22a4
Packit 7b22a4
	ret = do_command_xlate(&h, argc, argv, &table, false);
Packit 7b22a4
	if (!ret)
Packit 7b22a4
		fprintf(stderr, "Translation not implemented\n");
Packit 7b22a4
Packit 7b22a4
	nft_fini(&h);
Packit 7b22a4
	exit(!ret);
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static int xtables_restore_xlate_main(int family, const char *progname,
Packit 7b22a4
				      int argc, char *argv[])
Packit 7b22a4
{
Packit 7b22a4
	int ret;
Packit 7b22a4
	struct nft_handle h = {
Packit 7b22a4
		.family = family,
Packit 7b22a4
	};
Packit 7b22a4
	const char *file = NULL;
Packit 7b22a4
	struct nft_xt_restore_parse p = {
Packit 7b22a4
		.cb = &cb_xlate,
Packit 7b22a4
	};
Packit 7b22a4
	time_t now = time(NULL);
Packit 7b22a4
	int c;
Packit 7b22a4
Packit 7b22a4
	ret = xtables_xlate_main_common(&h, family, progname);
Packit 7b22a4
	if (ret < 0)
Packit 7b22a4
		exit(EXIT_FAILURE);
Packit 7b22a4
Packit 7b22a4
	opterr = 0;
Packit 7b22a4
	while ((c = getopt_long(argc, argv, "hf:V", options, NULL)) != -1) {
Packit 7b22a4
		switch (c) {
Packit 7b22a4
		case 'h':
Packit 7b22a4
			print_usage(argv[0], PACKAGE_VERSION);
Packit 7b22a4
			exit(0);
Packit 7b22a4
		case 'f':
Packit 7b22a4
			file = optarg;
Packit 7b22a4
			break;
Packit 7b22a4
		case 'V':
Packit 7b22a4
			printf("%s v%s\n", argv[0], PACKAGE_VERSION);
Packit 7b22a4
			exit(0);
Packit 7b22a4
		}
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	if (file == NULL) {
Packit 7b22a4
		fprintf(stderr, "ERROR: missing file name\n");
Packit 7b22a4
		print_usage(argv[0], PACKAGE_VERSION);
Packit 7b22a4
		exit(0);
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	p.in = fopen(file, "r");
Packit 7b22a4
	if (p.in == NULL) {
Packit 7b22a4
		fprintf(stderr, "Cannot open file %s\n", file);
Packit 7b22a4
		exit(1);
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	printf("# Translated by %s v%s on %s",
Packit 7b22a4
	       argv[0], PACKAGE_VERSION, ctime(&now));
Packit 7b22a4
	xtables_restore_parse(&h, &p);
Packit 7b22a4
	printf("# Completed on %s", ctime(&now));
Packit 7b22a4
Packit 7b22a4
	nft_fini(&h);
Packit 7b22a4
	fclose(p.in);
Packit 7b22a4
	exit(0);
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
int xtables_ip4_xlate_main(int argc, char *argv[])
Packit 7b22a4
{
Packit 7b22a4
	return xtables_xlate_main(NFPROTO_IPV4, "iptables-translate",
Packit 7b22a4
				  argc, argv);
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
int xtables_ip6_xlate_main(int argc, char *argv[])
Packit 7b22a4
{
Packit 7b22a4
	return xtables_xlate_main(NFPROTO_IPV6, "ip6tables-translate",
Packit 7b22a4
				  argc, argv);
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
int xtables_ip4_xlate_restore_main(int argc, char *argv[])
Packit 7b22a4
{
Packit 7b22a4
	return xtables_restore_xlate_main(NFPROTO_IPV4,
Packit 7b22a4
					  "iptables-translate-restore",
Packit 7b22a4
					  argc, argv);
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
int xtables_ip6_xlate_restore_main(int argc, char *argv[])
Packit 7b22a4
{
Packit 7b22a4
	return xtables_restore_xlate_main(NFPROTO_IPV6,
Packit 7b22a4
					  "ip6tables-translate-restore",
Packit 7b22a4
					  argc, argv);
Packit 7b22a4
}