Blame iptables/xtables-translate.c

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