Blame iptables/xtables-eb-translate.c

Packit 7b22a4
#include <ctype.h>
Packit 7b22a4
#include <errno.h>
Packit 7b22a4
#include <stdio.h>
Packit 7b22a4
#include <stdlib.h>
Packit 7b22a4
#include <stdbool.h>
Packit 7b22a4
#include <stdarg.h>
Packit 7b22a4
#include <string.h>
Packit 7b22a4
#include <fcntl.h>
Packit 7b22a4
#include <getopt.h>
Packit 7b22a4
#include <iptables.h>
Packit 7b22a4
#include <xtables.h>
Packit 7b22a4
Packit 7b22a4
#include <netinet/ether.h>
Packit 7b22a4
Packit 7b22a4
#include <linux/netfilter_bridge.h>
Packit 7b22a4
#include <linux/netfilter/nf_tables.h>
Packit 7b22a4
#include <libiptc/libxtc.h>
Packit 7b22a4
Packit 7b22a4
#include "xshared.h"
Packit 7b22a4
#include "xtables-multi.h"
Packit 7b22a4
#include "nft-bridge.h"
Packit 7b22a4
#include "nft.h"
Packit 7b22a4
#include "nft-shared.h"
Packit 7b22a4
/*
Packit 7b22a4
 * From include/ebtables_u.h
Packit 7b22a4
 */
Packit 7b22a4
#define EXEC_STYLE_PRG    0
Packit 7b22a4
#define EXEC_STYLE_DAEMON 1
Packit 7b22a4
Packit 7b22a4
#define ebt_check_option2(flags, mask) EBT_CHECK_OPTION(flags, mask)
Packit 7b22a4
Packit 7b22a4
extern int ebt_invert;
Packit 7b22a4
Packit 7b22a4
static int ebt_check_inverse2(const char option[], int argc, char **argv)
Packit 7b22a4
{
Packit 7b22a4
	if (!option)
Packit 7b22a4
		return ebt_invert;
Packit 7b22a4
	if (strcmp(option, "!") == 0) {
Packit 7b22a4
		if (ebt_invert == 1)
Packit 7b22a4
			xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
				      "Double use of '!' not allowed");
Packit 7b22a4
		if (optind >= argc)
Packit 7b22a4
			optarg = NULL;
Packit 7b22a4
		else
Packit 7b22a4
			optarg = argv[optind];
Packit 7b22a4
		optind++;
Packit 7b22a4
		ebt_invert = 1;
Packit 7b22a4
		return 1;
Packit 7b22a4
	}
Packit 7b22a4
	return ebt_invert;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
/*
Packit 7b22a4
 * Glue code to use libxtables
Packit 7b22a4
 */
Packit 7b22a4
static int parse_rule_number(const char *rule)
Packit 7b22a4
{
Packit 7b22a4
	unsigned int rule_nr;
Packit 7b22a4
Packit 7b22a4
	if (!xtables_strtoui(rule, NULL, &rule_nr, 1, INT_MAX))
Packit 7b22a4
		xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
			      "Invalid rule number `%s'", rule);
Packit 7b22a4
Packit 7b22a4
	return rule_nr;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static int get_current_chain(const char *chain)
Packit 7b22a4
{
Packit 7b22a4
	if (strcmp(chain, "PREROUTING") == 0)
Packit 7b22a4
		return NF_BR_PRE_ROUTING;
Packit 7b22a4
	else if (strcmp(chain, "INPUT") == 0)
Packit 7b22a4
		return NF_BR_LOCAL_IN;
Packit 7b22a4
	else if (strcmp(chain, "FORWARD") == 0)
Packit 7b22a4
		return NF_BR_FORWARD;
Packit 7b22a4
	else if (strcmp(chain, "OUTPUT") == 0)
Packit 7b22a4
		return NF_BR_LOCAL_OUT;
Packit 7b22a4
	else if (strcmp(chain, "POSTROUTING") == 0)
Packit 7b22a4
		return NF_BR_POST_ROUTING;
Packit 7b22a4
Packit 7b22a4
	return -1;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
/*
Packit 7b22a4
 * The original ebtables parser
Packit 7b22a4
 */
Packit 7b22a4
Packit 7b22a4
/* Checks whether a command has already been specified */
Packit 7b22a4
#define OPT_COMMANDS (flags & OPT_COMMAND || flags & OPT_ZERO)
Packit 7b22a4
Packit 7b22a4
#define OPT_COMMAND	0x01
Packit 7b22a4
#define OPT_TABLE	0x02
Packit 7b22a4
#define OPT_IN		0x04
Packit 7b22a4
#define OPT_OUT		0x08
Packit 7b22a4
#define OPT_JUMP	0x10
Packit 7b22a4
#define OPT_PROTOCOL	0x20
Packit 7b22a4
#define OPT_SOURCE	0x40
Packit 7b22a4
#define OPT_DEST	0x80
Packit 7b22a4
#define OPT_ZERO	0x100
Packit 7b22a4
#define OPT_LOGICALIN	0x200
Packit 7b22a4
#define OPT_LOGICALOUT	0x400
Packit 7b22a4
#define OPT_COUNT	0x1000 /* This value is also defined in libebtc.c */
Packit 7b22a4
Packit 7b22a4
/* Default command line options. Do not mess around with the already
Packit 7b22a4
 * assigned numbers unless you know what you are doing */
Packit 7b22a4
extern struct option ebt_original_options[];
Packit 7b22a4
extern struct xtables_globals ebtables_globals;
Packit 7b22a4
#define opts ebtables_globals.opts
Packit 7b22a4
#define prog_name ebtables_globals.program_name
Packit 7b22a4
#define prog_vers ebtables_globals.program_version
Packit 7b22a4
Packit 7b22a4
static void print_help(void)
Packit 7b22a4
{
Packit 7b22a4
	fprintf(stderr, "%s: Translate ebtables command to nft syntax\n"
Packit 7b22a4
			"no side effects occur, the translated command is written "
Packit 7b22a4
			"to standard output.\n"
Packit 7b22a4
			"A '#' followed by input means no translation "
Packit 7b22a4
			"is available.\n", prog_name);
Packit 7b22a4
	exit(0);
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static int parse_rule_range(const char *argv, int *rule_nr, int *rule_nr_end)
Packit 7b22a4
{
Packit 7b22a4
	char *colon = strchr(argv, ':'), *buffer;
Packit 7b22a4
Packit 7b22a4
	if (colon) {
Packit 7b22a4
		*colon = '\0';
Packit 7b22a4
		if (*(colon + 1) == '\0')
Packit 7b22a4
			*rule_nr_end = -1; /* Until the last rule */
Packit 7b22a4
		else {
Packit 7b22a4
			*rule_nr_end = strtol(colon + 1, &buffer, 10);
Packit 7b22a4
			if (*buffer != '\0' || *rule_nr_end == 0)
Packit 7b22a4
				return -1;
Packit 7b22a4
		}
Packit 7b22a4
	}
Packit 7b22a4
	if (colon == argv)
Packit 7b22a4
		*rule_nr = 1; /* Beginning with the first rule */
Packit 7b22a4
	else {
Packit 7b22a4
		*rule_nr = strtol(argv, &buffer, 10);
Packit 7b22a4
		if (*buffer != '\0' || *rule_nr == 0)
Packit 7b22a4
			return -1;
Packit 7b22a4
	}
Packit 7b22a4
	if (!colon)
Packit 7b22a4
		*rule_nr_end = *rule_nr;
Packit 7b22a4
	return 0;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void ebtables_parse_interface(const char *arg, char *vianame)
Packit 7b22a4
{
Packit 7b22a4
	unsigned char mask[IFNAMSIZ];
Packit 7b22a4
	char *c;
Packit 7b22a4
Packit 7b22a4
	xtables_parse_interface(arg, vianame, mask);
Packit 7b22a4
Packit 7b22a4
	if ((c = strchr(vianame, '+'))) {
Packit 7b22a4
		if (*(c + 1) != '\0')
Packit 7b22a4
			xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
				      "Spurious characters after '+' wildcard");
Packit 7b22a4
	}
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void print_ebt_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 nft_rule_eb_xlate_add(struct nft_handle *h, const struct nft_xt_cmd_parse *p,
Packit 7b22a4
				 const struct iptables_command_state *cs, 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 bridge %s %s ", p->table, p->chain);
Packit 7b22a4
	} else {
Packit 7b22a4
		xt_xlate_add(xl, "insert rule bridge %s %s ", 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
/* We use exec_style instead of #ifdef's because ebtables.so is a shared object. */
Packit 7b22a4
static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char **table)
Packit 7b22a4
{
Packit 7b22a4
	char *buffer;
Packit 7b22a4
	int c, i;
Packit 7b22a4
	int rule_nr = 0;
Packit 7b22a4
	int rule_nr_end = 0;
Packit 7b22a4
	int ret = 0;
Packit 7b22a4
	unsigned int flags = 0;
Packit 7b22a4
	struct iptables_command_state cs = {
Packit 7b22a4
		.argv		= argv,
Packit 7b22a4
		.eb.bitmask	= EBT_NOPROTO,
Packit 7b22a4
	};
Packit 7b22a4
	char command = 'h';
Packit 7b22a4
	const char *chain = NULL;
Packit 7b22a4
	int exec_style = EXEC_STYLE_PRG;
Packit 7b22a4
	int selected_chain = -1;
Packit 7b22a4
	struct xtables_rule_match *xtrm_i;
Packit 7b22a4
	struct ebt_match *match;
Packit 7b22a4
	struct nft_xt_cmd_parse p = {
Packit 7b22a4
		.table          = *table,
Packit 7b22a4
        };
Packit 7b22a4
Packit 7b22a4
	/* prevent getopt to spoil our error reporting */
Packit 7b22a4
	opterr = false;
Packit 7b22a4
Packit 7b22a4
	printf("nft ");
Packit 7b22a4
	/* Getopt saves the day */
Packit 7b22a4
	while ((c = getopt_long(argc, argv,
Packit 7b22a4
	   "-A:D:I:N:E:X::L::Z::F::P:Vhi:o:j:c:p:s:d:t:M:", opts, NULL)) != -1) {
Packit 7b22a4
		cs.c = c;
Packit 7b22a4
		cs.invert = ebt_invert;
Packit 7b22a4
		switch (c) {
Packit 7b22a4
		case 'A': /* Add a rule */
Packit 7b22a4
		case 'D': /* Delete a rule */
Packit 7b22a4
		case 'P': /* Define policy */
Packit 7b22a4
		case 'I': /* Insert a rule */
Packit 7b22a4
		case 'N': /* Make a user defined chain */
Packit 7b22a4
		case 'E': /* Rename chain */
Packit 7b22a4
		case 'X': /* Delete chain */
Packit 7b22a4
			/* We allow -N chainname -P policy */
Packit 7b22a4
			/* XXX: Not in ebtables-compat */
Packit 7b22a4
			if (command == 'N' && c == 'P') {
Packit 7b22a4
				command = c;
Packit 7b22a4
				optind--; /* No table specified */
Packit 7b22a4
				break;
Packit 7b22a4
			}
Packit 7b22a4
			if (OPT_COMMANDS)
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "Multiple commands are not allowed");
Packit 7b22a4
			command = c;
Packit 7b22a4
			chain = optarg;
Packit 7b22a4
			selected_chain = get_current_chain(chain);
Packit 7b22a4
			p.chain = chain;
Packit 7b22a4
			flags |= OPT_COMMAND;
Packit 7b22a4
Packit 7b22a4
			if (c == 'N') {
Packit 7b22a4
				printf("add chain bridge %s %s\n", p.table, p.chain);
Packit 7b22a4
				ret = 1;
Packit 7b22a4
				break;
Packit 7b22a4
			} else if (c == 'X') {
Packit 7b22a4
				printf("delete chain bridge %s %s\n", p.table, p.chain);
Packit 7b22a4
				ret = 1;
Packit 7b22a4
				break;
Packit 7b22a4
			}
Packit 7b22a4
Packit 7b22a4
			if (c == 'E') {
Packit 7b22a4
				break;
Packit 7b22a4
			} else if (c == 'D' && optind < argc && (argv[optind][0] != '-' || (argv[optind][1] >= '0' && argv[optind][1] <= '9'))) {
Packit 7b22a4
				if (optind != argc - 1)
Packit 7b22a4
					xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
							 "No extra options allowed with -D start_nr[:end_nr]");
Packit 7b22a4
				if (parse_rule_range(argv[optind], &rule_nr, &rule_nr_end))
Packit 7b22a4
					xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
							 "Problem with the specified rule number(s) '%s'", argv[optind]);
Packit 7b22a4
				optind++;
Packit 7b22a4
			} else if (c == 'I') {
Packit 7b22a4
				if (optind >= argc || (argv[optind][0] == '-' && (argv[optind][1] < '0' || argv[optind][1] > '9')))
Packit 7b22a4
					rule_nr = 1;
Packit 7b22a4
				else {
Packit 7b22a4
					rule_nr = parse_rule_number(argv[optind]);
Packit 7b22a4
					optind++;
Packit 7b22a4
				}
Packit 7b22a4
				p.rulenum = rule_nr;
Packit 7b22a4
			} else if (c == 'P') {
Packit 7b22a4
				break;
Packit 7b22a4
			}
Packit 7b22a4
			break;
Packit 7b22a4
		case 'L': /* List */
Packit 7b22a4
			printf("list table bridge %s\n", p.table);
Packit 7b22a4
			ret = 1;
Packit 7b22a4
			break;
Packit 7b22a4
		case 'F': /* Flush */
Packit 7b22a4
			if (p.chain) {
Packit 7b22a4
				printf("flush chain bridge %s %s\n", p.table, p.chain);
Packit 7b22a4
			} else {
Packit 7b22a4
				printf("flush table bridge %s\n", p.table);
Packit 7b22a4
			}
Packit 7b22a4
			ret = 1;
Packit 7b22a4
			break;
Packit 7b22a4
		case 'Z': /* Zero counters */
Packit 7b22a4
			if (c == 'Z') {
Packit 7b22a4
				if ((flags & OPT_ZERO) || (flags & OPT_COMMAND && command != 'L'))
Packit 7b22a4
print_zero:
Packit 7b22a4
					xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
						      "Command -Z only allowed together with command -L");
Packit 7b22a4
				flags |= OPT_ZERO;
Packit 7b22a4
			} else {
Packit 7b22a4
				if (flags & OPT_COMMAND)
Packit 7b22a4
					xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
						      "Multiple commands are not allowed");
Packit 7b22a4
				command = c;
Packit 7b22a4
				flags |= OPT_COMMAND;
Packit 7b22a4
				if (flags & OPT_ZERO && c != 'L')
Packit 7b22a4
					goto print_zero;
Packit 7b22a4
			}
Packit 7b22a4
			break;
Packit 7b22a4
		case 'V': /* Version */
Packit 7b22a4
			if (OPT_COMMANDS)
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "Multiple commands are not allowed");
Packit 7b22a4
			if (exec_style == EXEC_STYLE_DAEMON)
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "%s %s\n", prog_name, prog_vers);
Packit 7b22a4
			printf("%s %s\n", prog_name, prog_vers);
Packit 7b22a4
			exit(0);
Packit 7b22a4
		case 'h':
Packit 7b22a4
			if (OPT_COMMANDS)
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "Multiple commands are not allowed");
Packit 7b22a4
			print_help();
Packit 7b22a4
			break;
Packit 7b22a4
		case 't': /* Table */
Packit 7b22a4
			if (OPT_COMMANDS)
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "Please put the -t option first");
Packit 7b22a4
			ebt_check_option2(&flags, OPT_TABLE);
Packit 7b22a4
			if (strlen(optarg) > EBT_TABLE_MAXNAMELEN - 1)
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "Table name length cannot exceed %d characters",
Packit 7b22a4
					      EBT_TABLE_MAXNAMELEN - 1);
Packit 7b22a4
			*table = optarg;
Packit 7b22a4
			p.table = optarg;
Packit 7b22a4
			break;
Packit 7b22a4
		case 'i': /* Input interface */
Packit 7b22a4
		case 2  : /* Logical input interface */
Packit 7b22a4
		case 'o': /* Output interface */
Packit 7b22a4
		case 3  : /* Logical output interface */
Packit 7b22a4
		case 'j': /* Target */
Packit 7b22a4
		case 'p': /* Net family protocol */
Packit 7b22a4
		case 's': /* Source mac */
Packit 7b22a4
		case 'd': /* Destination mac */
Packit 7b22a4
		case 'c': /* Set counters */
Packit 7b22a4
			if (!OPT_COMMANDS)
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "No command specified");
Packit 7b22a4
			if (command != 'A' && command != 'D' && command != 'I')
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "Command and option do not match");
Packit 7b22a4
			if (c == 'i') {
Packit 7b22a4
				ebt_check_option2(&flags, OPT_IN);
Packit 7b22a4
				if (selected_chain > 2 && selected_chain < NF_BR_BROUTING)
Packit 7b22a4
					xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
						      "Use -i only in INPUT, FORWARD, PREROUTING and BROUTING chains");
Packit 7b22a4
				if (ebt_check_inverse2(optarg, argc, argv))
Packit 7b22a4
					cs.eb.invflags |= EBT_IIN;
Packit 7b22a4
Packit 7b22a4
				ebtables_parse_interface(optarg, cs.eb.in);
Packit 7b22a4
				break;
Packit 7b22a4
			} else if (c == 2) {
Packit 7b22a4
				ebt_check_option2(&flags, OPT_LOGICALIN);
Packit 7b22a4
				if (selected_chain > 2 && selected_chain < NF_BR_BROUTING)
Packit 7b22a4
					xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
						      "Use --logical-in only in INPUT, FORWARD, PREROUTING and BROUTING chains");
Packit 7b22a4
				if (ebt_check_inverse2(optarg, argc, argv))
Packit 7b22a4
					cs.eb.invflags |= EBT_ILOGICALIN;
Packit 7b22a4
Packit 7b22a4
				ebtables_parse_interface(optarg, cs.eb.logical_in);
Packit 7b22a4
				break;
Packit 7b22a4
			} else if (c == 'o') {
Packit 7b22a4
				ebt_check_option2(&flags, OPT_OUT);
Packit 7b22a4
				if (selected_chain < 2 || selected_chain == NF_BR_BROUTING)
Packit 7b22a4
					xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
						      "Use -o only in OUTPUT, FORWARD and POSTROUTING chains");
Packit 7b22a4
				if (ebt_check_inverse2(optarg, argc, argv))
Packit 7b22a4
					cs.eb.invflags |= EBT_IOUT;
Packit 7b22a4
Packit 7b22a4
				ebtables_parse_interface(optarg, cs.eb.out);
Packit 7b22a4
				break;
Packit 7b22a4
			} else if (c == 3) {
Packit 7b22a4
				ebt_check_option2(&flags, OPT_LOGICALOUT);
Packit 7b22a4
				if (selected_chain < 2 || selected_chain == NF_BR_BROUTING)
Packit 7b22a4
					xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
						      "Use --logical-out only in OUTPUT, FORWARD and POSTROUTING chains");
Packit 7b22a4
				if (ebt_check_inverse2(optarg, argc, argv))
Packit 7b22a4
					cs.eb.invflags |= EBT_ILOGICALOUT;
Packit 7b22a4
Packit 7b22a4
				ebtables_parse_interface(optarg, cs.eb.logical_out);
Packit 7b22a4
				break;
Packit 7b22a4
			} else if (c == 'j') {
Packit 7b22a4
				ebt_check_option2(&flags, OPT_JUMP);
Packit 7b22a4
				command_jump(&cs, optarg);
Packit 7b22a4
				break;
Packit 7b22a4
			} else if (c == 's') {
Packit 7b22a4
				ebt_check_option2(&flags, OPT_SOURCE);
Packit 7b22a4
				if (ebt_check_inverse2(optarg, argc, argv))
Packit 7b22a4
					cs.eb.invflags |= EBT_ISOURCE;
Packit 7b22a4
Packit 7b22a4
				if (ebt_get_mac_and_mask(optarg, cs.eb.sourcemac, cs.eb.sourcemsk))
Packit 7b22a4
					xtables_error(PARAMETER_PROBLEM, "Problem with specified source mac '%s'", optarg);
Packit 7b22a4
				cs.eb.bitmask |= EBT_SOURCEMAC;
Packit 7b22a4
				break;
Packit 7b22a4
			} else if (c == 'd') {
Packit 7b22a4
				ebt_check_option2(&flags, OPT_DEST);
Packit 7b22a4
				if (ebt_check_inverse2(optarg, argc, argv))
Packit 7b22a4
					cs.eb.invflags |= EBT_IDEST;
Packit 7b22a4
Packit 7b22a4
				if (ebt_get_mac_and_mask(optarg, cs.eb.destmac, cs.eb.destmsk))
Packit 7b22a4
					xtables_error(PARAMETER_PROBLEM, "Problem with specified destination mac '%s'", optarg);
Packit 7b22a4
				cs.eb.bitmask |= EBT_DESTMAC;
Packit 7b22a4
				break;
Packit 7b22a4
			} else if (c == 'c') {
Packit 7b22a4
				ebt_check_option2(&flags, OPT_COUNT);
Packit 7b22a4
				if (ebt_check_inverse2(optarg, argc, argv))
Packit 7b22a4
					xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
						      "Unexpected '!' after -c");
Packit 7b22a4
				if (optind >= argc || optarg[0] == '-' || argv[optind][0] == '-')
Packit 7b22a4
					xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
						      "Option -c needs 2 arguments");
Packit 7b22a4
Packit 7b22a4
				cs.counters.pcnt = strtoull(optarg, &buffer, 10);
Packit 7b22a4
				if (*buffer != '\0')
Packit 7b22a4
					xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
						      "Packet counter '%s' invalid",
Packit 7b22a4
						      optarg);
Packit 7b22a4
				cs.counters.bcnt = strtoull(argv[optind], &buffer, 10);
Packit 7b22a4
				if (*buffer != '\0')
Packit 7b22a4
					xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
						      "Packet counter '%s' invalid",
Packit 7b22a4
						      argv[optind]);
Packit 7b22a4
				optind++;
Packit 7b22a4
				break;
Packit 7b22a4
			}
Packit 7b22a4
			ebt_check_option2(&flags, OPT_PROTOCOL);
Packit 7b22a4
			if (ebt_check_inverse2(optarg, argc, argv))
Packit 7b22a4
				cs.eb.invflags |= EBT_IPROTO;
Packit 7b22a4
Packit 7b22a4
			cs.eb.bitmask &= ~((unsigned int)EBT_NOPROTO);
Packit 7b22a4
			i = strtol(optarg, &buffer, 16);
Packit 7b22a4
			if (*buffer == '\0' && (i < 0 || i > 0xFFFF))
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "Problem with the specified protocol");
Packit 7b22a4
			if (*buffer != '\0') {
Packit 7b22a4
				struct xt_ethertypeent *ent;
Packit 7b22a4
Packit 7b22a4
				if (!strcasecmp(optarg, "LENGTH")) {
Packit 7b22a4
					cs.eb.bitmask |= EBT_802_3;
Packit 7b22a4
					break;
Packit 7b22a4
				}
Packit 7b22a4
				ent = xtables_getethertypebyname(optarg);
Packit 7b22a4
				if (!ent)
Packit 7b22a4
					xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
						      "Problem with the specified Ethernet protocol '%s', perhaps "XT_PATH_ETHERTYPES " is missing", optarg);
Packit 7b22a4
				cs.eb.ethproto = ent->e_ethertype;
Packit 7b22a4
			} else
Packit 7b22a4
				cs.eb.ethproto = i;
Packit 7b22a4
Packit 7b22a4
			if (cs.eb.ethproto < 0x0600)
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "Sorry, protocols have values above or equal to 0x0600");
Packit 7b22a4
			break;
Packit 7b22a4
		case 4  : /* Lc */
Packit 7b22a4
			ebt_check_option2(&flags, LIST_C);
Packit 7b22a4
			if (command != 'L')
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "Use --Lc with -L");
Packit 7b22a4
			flags |= LIST_C;
Packit 7b22a4
			break;
Packit 7b22a4
		case 5  : /* Ln */
Packit 7b22a4
			ebt_check_option2(&flags, LIST_N);
Packit 7b22a4
			if (command != 'L')
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "Use --Ln with -L");
Packit 7b22a4
			if (flags & LIST_X)
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "--Lx is not compatible with --Ln");
Packit 7b22a4
			flags |= LIST_N;
Packit 7b22a4
			break;
Packit 7b22a4
		case 6  : /* Lx */
Packit 7b22a4
			ebt_check_option2(&flags, LIST_X);
Packit 7b22a4
			if (command != 'L')
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "Use --Lx with -L");
Packit 7b22a4
			if (flags & LIST_N)
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "--Lx is not compatible with --Ln");
Packit 7b22a4
			flags |= LIST_X;
Packit 7b22a4
			break;
Packit 7b22a4
		case 12 : /* Lmac2 */
Packit 7b22a4
			ebt_check_option2(&flags, LIST_MAC2);
Packit 7b22a4
			if (command != 'L')
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					       "Use --Lmac2 with -L");
Packit 7b22a4
			flags |= LIST_MAC2;
Packit 7b22a4
			break;
Packit 7b22a4
		case 1 :
Packit 7b22a4
			if (!strcmp(optarg, "!"))
Packit 7b22a4
				ebt_check_inverse2(optarg, argc, argv);
Packit 7b22a4
			else
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "Bad argument : '%s'", optarg);
Packit 7b22a4
			/* ebt_ebt_check_inverse2() did optind++ */
Packit 7b22a4
			optind--;
Packit 7b22a4
			continue;
Packit 7b22a4
		default:
Packit 7b22a4
			ebt_check_inverse2(optarg, argc, argv);
Packit 7b22a4
Packit 7b22a4
			if (ebt_command_default(&cs))
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "Unknown argument: '%s'",
Packit 7b22a4
					      argv[optind - 1]);
Packit 7b22a4
Packit 7b22a4
			if (command != 'A' && command != 'I' &&
Packit 7b22a4
			    command != 'D')
Packit 7b22a4
				xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
					      "Extensions only for -A, -I, -D");
Packit 7b22a4
		}
Packit 7b22a4
		ebt_invert = 0;
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	/* Do the final checks */
Packit 7b22a4
	if (command == 'A' || command == 'I' || command == 'D') {
Packit 7b22a4
		for (xtrm_i = cs.matches; xtrm_i; xtrm_i = xtrm_i->next)
Packit 7b22a4
			xtables_option_mfcall(xtrm_i->match);
Packit 7b22a4
Packit 7b22a4
		for (match = cs.match_list; match; match = match->next) {
Packit 7b22a4
			if (match->ismatch)
Packit 7b22a4
				continue;
Packit 7b22a4
Packit 7b22a4
			xtables_option_tfcall(match->u.watcher);
Packit 7b22a4
		}
Packit 7b22a4
Packit 7b22a4
		if (cs.target != NULL)
Packit 7b22a4
			xtables_option_tfcall(cs.target);
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	cs.eb.ethproto = htons(cs.eb.ethproto);
Packit 7b22a4
Packit 7b22a4
	if (command == 'P') {
Packit 7b22a4
		return 0;
Packit 7b22a4
	} else if (command == 'A') {
Packit 7b22a4
		ret = nft_rule_eb_xlate_add(h, &p, &cs, true);
Packit 7b22a4
		if (!ret)
Packit 7b22a4
			print_ebt_cmd(argc, argv);
Packit 7b22a4
	} else if (command == 'I') {
Packit 7b22a4
		ret = nft_rule_eb_xlate_add(h, &p, &cs, false);
Packit 7b22a4
		if (!ret)
Packit 7b22a4
			print_ebt_cmd(argc, argv);
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	ebt_cs_clean(&cs);
Packit 7b22a4
	return ret;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static int dummy_compat_rev(const char *name, uint8_t rev, int opt)
Packit 7b22a4
{
Packit 7b22a4
	return 1;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
int xtables_eb_xlate_main(int argc, char *argv[])
Packit 7b22a4
{
Packit 7b22a4
	int ret;
Packit 7b22a4
	char *table = "filter";
Packit 7b22a4
	struct nft_handle h;
Packit 7b22a4
Packit 7b22a4
	nft_init_eb(&h, argv[0]);
Packit 7b22a4
	ebtables_globals.compat_rev = dummy_compat_rev;
Packit 7b22a4
Packit 7b22a4
	ret = do_commandeb_xlate(&h, argc, argv, &table);
Packit 7b22a4
	if (!ret)
Packit 7b22a4
		fprintf(stderr, "Translation not implemented\n");
Packit 7b22a4
Packit 7b22a4
	exit(!ret);
Packit 7b22a4
}
Packit 7b22a4