|
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 |
|