Commit c2d7e04a authored by Arturo Borrero Gonzalez's avatar Arturo Borrero Gonzalez
Browse files

Update upstream source from tag 'upstream/1.8.1'

Update to upstream version '1.8.1'
with Debian dir f7eefdbc289bc01f3d8a1522cd469a3564de9051
parents 698f2511 dab1e98e
...@@ -41,29 +41,15 @@ ...@@ -41,29 +41,15 @@
#include "xtables-multi.h" #include "xtables-multi.h"
extern struct xtables_globals ebtables_globals;
int xtables_eb_main(int argc, char *argv[]) int xtables_eb_main(int argc, char *argv[])
{ {
int ret; int ret;
char *table = "filter"; char *table = "filter";
struct nft_handle h = { struct nft_handle h;
.family = NFPROTO_BRIDGE,
};
ebtables_globals.program_name = "ebtables"; nft_init_eb(&h, "ebtables");
ret = xtables_init_all(&ebtables_globals, NFPROTO_BRIDGE);
if (ret < 0) {
fprintf(stderr, "%s/%s Failed to initialize ebtables-compat\n",
ebtables_globals.program_name,
ebtables_globals.program_version);
exit(1);
}
#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS) ret = do_commandeb(&h, argc, argv, &table, false);
init_extensionsb();
#endif
ret = do_commandeb(&h, argc, argv, &table);
if (ret) if (ret)
ret = nft_commit(&h); ret = nft_commit(&h);
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <linux/netfilter_bridge.h> #include <linux/netfilter_bridge.h>
#include <linux/netfilter/nf_tables.h> #include <linux/netfilter/nf_tables.h>
#include <ebtables/ethernetdb.h>
#include <libiptc/libxtc.h> #include <libiptc/libxtc.h>
#include "xshared.h" #include "xshared.h"
...@@ -130,72 +129,6 @@ extern struct xtables_globals ebtables_globals; ...@@ -130,72 +129,6 @@ extern struct xtables_globals ebtables_globals;
#define prog_name ebtables_globals.program_name #define prog_name ebtables_globals.program_name
#define prog_vers ebtables_globals.program_version #define prog_vers ebtables_globals.program_version
#define OPTION_OFFSET 256
static struct option *merge_options(struct option *oldopts,
const struct option *newopts,
unsigned int *options_offset)
{
unsigned int num_old, num_new, i;
struct option *merge;
if (!newopts || !oldopts || !options_offset)
return oldopts;
for (num_old = 0; oldopts[num_old].name; num_old++);
for (num_new = 0; newopts[num_new].name; num_new++);
ebtables_globals.option_offset += OPTION_OFFSET;
*options_offset = ebtables_globals.option_offset;
merge = malloc(sizeof(struct option) * (num_new + num_old + 1));
if (!merge)
return NULL;
memcpy(merge, oldopts, num_old * sizeof(struct option));
for (i = 0; i < num_new; i++) {
merge[num_old + i] = newopts[i];
merge[num_old + i].val += *options_offset;
}
memset(merge + num_old + num_new, 0, sizeof(struct option));
/* Only free dynamically allocated stuff */
if (oldopts != ebt_original_options)
free(oldopts);
return merge;
}
/*
* More glue code.
*/
static struct xtables_target *command_jump(struct iptables_command_state *cs,
const char *jumpto)
{
struct xtables_target *target;
size_t size;
/* XTF_TRY_LOAD (may be chain name) */
target = xtables_find_target(jumpto, XTF_TRY_LOAD);
if (!target)
return NULL;
size = XT_ALIGN(sizeof(struct xt_entry_target))
+ target->size;
target->t = xtables_calloc(1, size);
target->t->u.target_size = size;
snprintf(target->t->u.user.name,
sizeof(target->t->u.user.name), "%s", jumpto);
target->t->u.user.name[sizeof(target->t->u.user.name)-1] = '\0';
target->t->u.user.revision = target->revision;
xs_init_target(target);
opts = merge_options(opts, target->extra_opts, &target->option_offset);
if (opts == NULL)
xtables_error(OTHER_PROBLEM, "Can't alloc memory");
return target;
}
static void print_help(void) static void print_help(void)
{ {
fprintf(stderr, "%s: Translate ebtables command to nft syntax\n" fprintf(stderr, "%s: Translate ebtables command to nft syntax\n"
...@@ -286,9 +219,10 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char ...@@ -286,9 +219,10 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char
int rule_nr_end = 0; int rule_nr_end = 0;
int ret = 0; int ret = 0;
unsigned int flags = 0; unsigned int flags = 0;
struct xtables_target *t, *w; struct iptables_command_state cs = {
struct xtables_match *m; .argv = argv,
struct iptables_command_state cs; .eb.bitmask = EBT_NOPROTO,
};
char command = 'h'; char command = 'h';
const char *chain = NULL; const char *chain = NULL;
int exec_style = EXEC_STYLE_PRG; int exec_style = EXEC_STYLE_PRG;
...@@ -299,36 +233,8 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char ...@@ -299,36 +233,8 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char
.table = *table, .table = *table,
}; };
memset(&cs, 0, sizeof(cs));
cs.argv = argv;
if (nft_init(h, xtables_bridge) < 0)
xtables_error(OTHER_PROBLEM,
"Could not initialize nftables layer.");
h->ops = nft_family_ops_lookup(h->family);
if (h->ops == NULL)
xtables_error(PARAMETER_PROBLEM, "Unknown family");
/* manually registering ebt matches, given the original ebtables parser
* don't use '-m matchname' and the match can't loaded dinamically when
* the user calls it.
*/
ebt_load_match_extensions();
/* clear mflags in case do_commandeb gets called a second time
* (we clear the global list of all matches for security)*/
for (m = xtables_matches; m; m = m->next)
m->mflags = 0;
for (t = xtables_targets; t; t = t->next) {
t->tflags = 0;
t->used = 0;
}
/* prevent getopt to spoil our error reporting */ /* prevent getopt to spoil our error reporting */
opterr = false; opterr = false;
cs.eb.bitmask = EBT_NOPROTO;
printf("nft "); printf("nft ");
/* Getopt saves the day */ /* Getopt saves the day */
...@@ -425,7 +331,6 @@ print_zero: ...@@ -425,7 +331,6 @@ print_zero:
if (OPT_COMMANDS) if (OPT_COMMANDS)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"Multiple commands are not allowed"); "Multiple commands are not allowed");
command = 'V';
if (exec_style == EXEC_STYLE_DAEMON) if (exec_style == EXEC_STYLE_DAEMON)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"%s %s\n", prog_name, prog_vers); "%s %s\n", prog_name, prog_vers);
...@@ -507,7 +412,7 @@ print_zero: ...@@ -507,7 +412,7 @@ print_zero:
} else if (c == 'j') { } else if (c == 'j') {
ebt_check_option2(&flags, OPT_JUMP); ebt_check_option2(&flags, OPT_JUMP);
cs.jumpto = parse_target(optarg); cs.jumpto = parse_target(optarg);
cs.target = command_jump(&cs, cs.jumpto); cs.target = ebt_command_jump(cs.jumpto);
break; break;
} else if (c == 's') { } else if (c == 's') {
ebt_check_option2(&flags, OPT_SOURCE); ebt_check_option2(&flags, OPT_SOURCE);
...@@ -559,16 +464,16 @@ print_zero: ...@@ -559,16 +464,16 @@ print_zero:
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"Problem with the specified protocol"); "Problem with the specified protocol");
if (*buffer != '\0') { if (*buffer != '\0') {
struct ethertypeent *ent; struct xt_ethertypeent *ent;
if (!strcasecmp(optarg, "LENGTH")) { if (!strcasecmp(optarg, "LENGTH")) {
cs.eb.bitmask |= EBT_802_3; cs.eb.bitmask |= EBT_802_3;
break; break;
} }
ent = getethertypebyname(optarg); ent = xtables_getethertypebyname(optarg);
if (!ent) if (!ent)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"Problem with the specified Ethernet protocol '%s', perhaps "_PATH_ETHERTYPES " is missing", optarg); "Problem with the specified Ethernet protocol '%s', perhaps "XT_PATH_ETHERTYPES " is missing", optarg);
cs.eb.ethproto = ent->e_ethertype; cs.eb.ethproto = ent->e_ethertype;
} else } else
cs.eb.ethproto = i; cs.eb.ethproto = i;
...@@ -621,34 +526,13 @@ print_zero: ...@@ -621,34 +526,13 @@ print_zero:
optind--; optind--;
continue; continue;
default: default:
/* Is it a target option? */ ebt_check_inverse2(optarg, argc, argv);
if (cs.target != NULL && cs.target->parse != NULL) {
int opt_offset = cs.target->option_offset;
if (cs.target->parse(c - opt_offset,
argv, ebt_invert,
&cs.target->tflags,
NULL, &cs.target->t))
goto check_extension;
}
/* Is it a match_option? */ if (ebt_command_default(&cs))
for (m = xtables_matches; m; m = m->next) { xtables_error(PARAMETER_PROBLEM,
if (m->parse(c - m->option_offset, argv, ebt_check_inverse2(optarg, argc, argv), &m->mflags, NULL, &m->m)) { "Unknown argument: '%s'",
ebt_add_match(m, &cs); argv[optind - 1]);
goto check_extension;
}
}
/* Is it a watcher option? */
for (w = xtables_targets; w; w = w->next) {
if (w->parse(c - w->option_offset, argv,
ebt_invert, &w->tflags,
NULL, &w->t)) {
ebt_add_watcher(w, &cs);
goto check_extension;
}
}
check_extension:
if (command != 'A' && command != 'I' && if (command != 'A' && command != 'I' &&
command != 'D') command != 'D')
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
...@@ -700,20 +584,11 @@ int xtables_eb_xlate_main(int argc, char *argv[]) ...@@ -700,20 +584,11 @@ int xtables_eb_xlate_main(int argc, char *argv[])
{ {
int ret; int ret;
char *table = "filter"; char *table = "filter";
struct nft_handle h = { struct nft_handle h;
.family = NFPROTO_BRIDGE,
};
ebtables_globals.program_name = argv[0];
ret = xtables_init_all(&ebtables_globals, NFPROTO_BRIDGE);
if (ret < 0) {
fprintf(stderr, "%s/%s Failed to initialize xtables\n",
ebtables_globals.program_name,
ebtables_globals.program_version);
exit(EXIT_FAILURE);
}
nft_init_eb(&h, argv[0]);
ebtables_globals.compat_rev = dummy_compat_rev; ebtables_globals.compat_rev = dummy_compat_rev;
ret = do_commandeb_xlate(&h, argc, argv, &table); ret = do_commandeb_xlate(&h, argc, argv, &table);
if (!ret) if (!ret)
fprintf(stderr, "Translation not implemented\n"); fprintf(stderr, "Translation not implemented\n");
......
...@@ -37,7 +37,6 @@ ...@@ -37,7 +37,6 @@
#include <linux/netfilter_bridge.h> #include <linux/netfilter_bridge.h>
#include <linux/netfilter/nf_tables.h> #include <linux/netfilter/nf_tables.h>
#include <ebtables/ethernetdb.h>
#include <libiptc/libxtc.h> #include <libiptc/libxtc.h>
#include "xshared.h" #include "xshared.h"
#include "nft.h" #include "nft.h"
...@@ -203,7 +202,7 @@ delete_entry(struct nft_handle *h, ...@@ -203,7 +202,7 @@ delete_entry(struct nft_handle *h,
return ret; return ret;
} }
static int get_current_chain(const char *chain) int ebt_get_current_chain(const char *chain)
{ {
if (!chain) if (!chain)
return -1; return -1;
...@@ -380,33 +379,22 @@ static struct option *merge_options(struct option *oldopts, ...@@ -380,33 +379,22 @@ static struct option *merge_options(struct option *oldopts,
/* /*
* More glue code. * More glue code.
*/ */
static struct xtables_target *command_jump(struct iptables_command_state *cs, struct xtables_target *ebt_command_jump(const char *jumpto)
const char *jumpto)
{ {
struct xtables_target *target; struct xtables_target *target;
size_t size; unsigned int verdict;
/* XTF_TRY_LOAD (may be chain name) */
target = xtables_find_target(jumpto, XTF_TRY_LOAD);
if (!target)
return NULL;
size = XT_ALIGN(sizeof(struct xt_entry_target))
+ target->size;
target->t = xtables_calloc(1, size);
target->t->u.target_size = size;
snprintf(target->t->u.user.name,
sizeof(target->t->u.user.name), "%s", jumpto);
target->t->u.user.name[sizeof(target->t->u.user.name)-1] = '\0';
target->t->u.user.revision = target->revision;
xs_init_target(target); /* Standard target? */
if (!ebt_fill_target(jumpto, &verdict))
jumpto = "standard";
opts = merge_options(opts, target->extra_opts, &target->option_offset); /* For ebtables, all targets are preloaded. Hence it is either in
if (opts == NULL) * xtables_targets or a custom chain to jump to, in which case
xtables_error(OTHER_PROBLEM, "Can't alloc memory"); * returning NULL is fine. */
for (target = xtables_targets; target; target = target->next) {
if (!strcmp(target->name, jumpto))
break;
}
return target; return target;
} }
...@@ -668,29 +656,30 @@ void ebt_load_match_extensions(void) ...@@ -668,29 +656,30 @@ void ebt_load_match_extensions(void)
ebt_load_target("dnat"); ebt_load_target("dnat");
ebt_load_target("snat"); ebt_load_target("snat");
ebt_load_target("redirect"); ebt_load_target("redirect");
ebt_load_target("standard");
} }
void ebt_add_match(struct xtables_match *m, void ebt_add_match(struct xtables_match *m,
struct iptables_command_state *cs) struct iptables_command_state *cs)
{ {
struct xtables_rule_match *i, **rule_matches = &cs->matches; struct xtables_rule_match **rule_matches = &cs->matches;
struct xtables_match *newm; struct xtables_match *newm;
struct ebt_match *newnode; struct ebt_match *newnode, **matchp;
struct xt_entry_match *m2;
/* match already in rule_matches, skip inclusion */
for (i = *rule_matches; i; i = i->next) {
if (strcmp(m->name, i->match->name) == 0) {
i->match->mflags |= m->mflags;
return;
}
}
newm = xtables_find_match(m->name, XTF_LOAD_MUST_SUCCEED, rule_matches); newm = xtables_find_match(m->name, XTF_LOAD_MUST_SUCCEED, rule_matches);
if (newm == NULL) if (newm == NULL)
xtables_error(OTHER_PROBLEM, xtables_error(OTHER_PROBLEM,
"Unable to add match %s", m->name); "Unable to add match %s", m->name);
m2 = xtables_calloc(1, newm->m->u.match_size);
memcpy(m2, newm->m, newm->m->u.match_size);
memset(newm->m->data, 0, newm->size);
xs_init_match(newm);
newm->m = m2;
newm->mflags = m->mflags; newm->mflags = m->mflags;
m->mflags = 0;
/* glue code for watchers */ /* glue code for watchers */
newnode = calloc(1, sizeof(struct ebt_match)); newnode = calloc(1, sizeof(struct ebt_match));
...@@ -700,88 +689,153 @@ void ebt_add_match(struct xtables_match *m, ...@@ -700,88 +689,153 @@ void ebt_add_match(struct xtables_match *m,
newnode->ismatch = true; newnode->ismatch = true;
newnode->u.match = newm; newnode->u.match = newm;
if (cs->match_list == NULL) for (matchp = &cs->match_list; *matchp; matchp = &(*matchp)->next)
cs->match_list = newnode; ;
else *matchp = newnode;
cs->match_list->next = newnode;
} }
void ebt_add_watcher(struct xtables_target *watcher, void ebt_add_watcher(struct xtables_target *watcher,
struct iptables_command_state *cs) struct iptables_command_state *cs)
{ {
struct ebt_match *i, *newnode; struct ebt_match *newnode, **matchp;
struct xtables_target *clone;
clone = xtables_malloc(sizeof(struct xtables_target));
memcpy(clone, watcher, sizeof(struct xtables_target));
clone->udata = NULL;
clone->tflags = watcher->tflags;
clone->next = clone;
clone->t = xtables_calloc(1, watcher->t->u.target_size);
memcpy(clone->t, watcher->t, watcher->t->u.target_size);
memset(watcher->t->data, 0, watcher->size);
xs_init_target(watcher);
watcher->tflags = 0;
for (i = cs->match_list; i; i = i->next) {
if (i->ismatch)
continue;
if (strcmp(i->u.watcher->name, watcher->name) == 0) {
i->u.watcher->tflags |= watcher->tflags;
return;
}
}
newnode = calloc(1, sizeof(struct ebt_match)); newnode = calloc(1, sizeof(struct ebt_match));
if (newnode == NULL) if (newnode == NULL)
xtables_error(OTHER_PROBLEM, "Unable to alloc memory"); xtables_error(OTHER_PROBLEM, "Unable to alloc memory");
newnode->u.watcher = watcher; newnode->u.watcher = clone;
if (cs->match_list == NULL) for (matchp = &cs->match_list; *matchp; matchp = &(*matchp)->next)
cs->match_list = newnode; ;
else *matchp = newnode;
cs->match_list->next = newnode;
} }
int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table) int ebt_command_default(struct iptables_command_state *cs)
{ {
char *buffer; struct xtables_target *t = cs->target;
int c, i;
int zerochain = -1; /* Needed for the -Z option (we can have -Z <this> -L <that>) */
int chcounter = 0; /* Needed for -C */
int rule_nr = 0;
int rule_nr_end = 0;
int ret = 0;
unsigned int flags = 0;
struct xtables_target *t, *w;
struct xtables_match *m; struct xtables_match *m;
struct iptables_command_state cs; struct ebt_match *matchp;
char command = 'h';
const char *chain = NULL; /* Is it a target option? */
const char *policy = NULL; if (t && t->parse) {
int selected_chain = -1; if (t->parse(cs->c - t->option_offset, cs->argv,
struct xtables_rule_match *xtrm_i; ebt_invert, &t->tflags, NULL, &t->t))
struct ebt_match *match; return 0;
}
memset(&cs, 0, sizeof(cs)); /* check previously added matches/watchers to this rule first */
cs.argv = argv; for (matchp = cs->match_list; matchp; matchp = matchp->next) {
if (matchp->ismatch) {
m = matchp->u.match;
if (m->parse &&
m->parse(cs->c - m->option_offset, cs->argv,
ebt_invert, &m->mflags, NULL, &m->m))
return 0;
} else {
t = matchp->u.watcher;
if (t->parse &&
t->parse(cs->c - t->option_offset, cs->argv,
ebt_invert, &t->tflags, NULL, &t->t))
return 0;
}
}
/* Is it a match_option? */
for (m = xtables_matches; m; m = m->next) {
if (m->parse &&
m->parse(cs->c - m->option_offset, cs->argv,
ebt_invert, &m->mflags, NULL, &m->m)) {
ebt_add_match(m, cs);
return 0;
}
}
/* Is it a watcher option? */
for (t = xtables_targets; t; t = t->next) {
if (t->parse &&
t->parse(cs->c - t->option_offset, cs->argv,
ebt_invert, &t->tflags, NULL, &t->t)) {
ebt_add_watcher(t, cs);
return 0;
}
}
return 1;
}
int nft_init_eb(struct nft_handle *h, const char *pname)
{
ebtables_globals.program_name = pname;
if (xtables_init_all(&ebtables_globals, NFPROTO_BRIDGE) < 0) {
fprintf(stderr, "%s/%s Failed to initialize ebtables-compat\n",
ebtables_globals.program_name,
ebtables_globals.program_version);
exit(1);
}
#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
init_extensionsb();
#endif
memset(h, 0, sizeof(*h));
h->family = NFPROTO_BRIDGE;
if (nft_init(h, xtables_bridge) < 0) if (nft_init(h, xtables_bridge) < 0)
xtables_error(OTHER_PROBLEM, xtables_error(OTHER_PROBLEM,
"Could not initialize nftables layer."); "Could not initialize nftables layer.");
h->ops = nft_family_ops_lookup(h->family); h->ops = nft_family_ops_lookup(h->family);
if (h->ops == NULL) if (!h->ops)
xtables_error(PARAMETER_PROBLEM, "Unknown family"); xtables_error(PARAMETER_PROBLEM, "Unknown family");
/* manually registering ebt matches, given the original ebtables parser /* manually registering ebt matches, given the original ebtables parser
* don't use '-m matchname' and the match can't loaded dinamically when * don't use '-m matchname' and the match can't be loaded dynamically when
* the user calls it. * the user calls it.
*/ */
ebt_load_match_extensions(); ebt_load_match_extensions();
/* clear mflags in case do_commandeb gets called a second time return 0;
* (we clear the global list of all matches for security)*/ }
for (m = xtables_matches; m; m = m->next)
m->mflags = 0;
for (t = xtables_targets; t; t = t->next) { int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
t->tflags = 0; bool restore)
t->used = 0; {
} char *buffer;
int c, i;
int chcounter = 0; /* Needed for -C */
int rule_nr = 0;
int rule_nr_end = 0;
int ret = 0;
unsigned int flags = 0;
struct xtables_target *t;
struct iptables_command_state cs = {
.argv = argv,
.eb.bitmask = EBT_NOPROTO,
};
char command = 'h';
const char *chain = NULL;
const char *policy = NULL;
int selected_chain = -1;
struct xtables_rule_match *xtrm_i;
struct ebt_match *match;
/* prevent getopt to spoil our error reporting */ /* prevent getopt to spoil our error reporting */
optind = 0;
opterr = false; opterr = false;
cs.eb.bitmask = EBT_NOPROTO;
/* Getopt saves the day */ /* Getopt saves the day */
while ((c = getopt_long(argc, argv, while ((c = getopt_long(argc, argv,
...@@ -813,7 +867,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -813,7 +867,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table)
if (optarg && (optarg[0] == '-' || !strcmp(optarg, "!"))) if (optarg && (optarg[0] == '-' || !strcmp(optarg, "!")))
xtables_error(PARAMETER_PROBLEM, "No chain name specified"); xtables_error(PARAMETER_PROBLEM, "No chain name specified");
chain = optarg; chain = optarg;
selected_chain = get_current_chain(chain); selected_chain = ebt_get_current_chain(chain);
flags |= OPT_COMMAND; flags |= OPT_COMMAND;
if (c == 'N') { if (c == 'N') {
...@@ -825,7 +879,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table) ...@@ -825,7 +879,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table)
chain = argv[optind]; chain = argv[optind];
optind++; optind++;
} }
ret = nft_chain_user_del(h, chain, *table); ret = nft_chain_user_del(h, chain, *table, 0);
break; break;
} }
...@@ -912,7 +966,6 @@ print_zero: ...@@ -912,7 +966,6 @@ print_zero:
if (OPT_COMMANDS) if (OPT_COMMANDS)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"Multiple commands are not allowed"); "Multiple commands are not allowed");
command = 'V';
printf("%s %s (nf_tables)\n", prog_name, prog_vers); printf("%s %s (nf_tables)\n", prog_name, prog_vers);
exit(0); exit(0);
case 'h': /* Help */ case 'h': /* Help */
...@@ -1014,7 +1067,7 @@ print_zero: ...@@ -1014,7 +1067,7 @@ print_zero:
} else if (c == 'j') { } else if (c == 'j') {
ebt_check_option2(&flags, OPT_JUMP); ebt_check_option2(&flags, OPT_JUMP);
cs.jumpto = parse_target(optarg); cs.jumpto = parse_target(optarg);
cs.target = command_jump(&cs, cs.jumpto); cs.target = ebt_command_jump(cs.jumpto);
break; break;
} else if (c == 's') { } else if (c == 's') {
ebt_check_option2(&flags, OPT_SOURCE); ebt_check_option2(&flags, OPT_SOURCE);
...@@ -1066,16 +1119,16 @@ print_zero: ...@@ -1066,16 +1119,16 @@ print_zero:
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"Problem with the specified protocol"); "Problem with the specified protocol");
if (*buffer != '\0') { if (*buffer != '\0') {
struct ethertypeent *ent; struct xt_ethertypeent *ent;
if (!strcasecmp(optarg, "LENGTH")) { if (!strcasecmp(optarg, "LENGTH")) {
cs.eb.bitmask |= EBT_802_3; cs.eb.bitmask |= EBT_802_3;
break; break;
} }
ent = getethertypebyname(optarg); ent = xtables_getethertypebyname(optarg);
if (!ent) if (!ent)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"Problem with the specified Ethernet protocol '%s', perhaps "_PATH_ETHERTYPES " is missing", optarg); "Problem with the specified Ethernet protocol '%s', perhaps "XT_PATH_ETHERTYPES " is missing", optarg);
cs.eb.ethproto = ent->e_ethertype; cs.eb.ethproto = ent->e_ethertype;
} else } else
cs.eb.ethproto = i; cs.eb.ethproto = i;
...@@ -1138,7 +1191,9 @@ print_zero: ...@@ -1138,7 +1191,9 @@ print_zero:
break;*/ break;*/
/*case 7 :*/ /* atomic-init */ /*case 7 :*/ /* atomic-init */
/*case 10:*/ /* atomic-save */ /*case 10:*/ /* atomic-save */
/*case 11:*/ /* init-table */ case 11: /* init-table */
nft_table_flush(h, *table);
return 1;
/* /*
replace->command = c; replace->command = c;
if (OPT_COMMANDS) if (OPT_COMMANDS)
...@@ -1176,49 +1231,13 @@ print_zero: ...@@ -1176,49 +1231,13 @@ print_zero:
optind--; optind--;
continue; continue;
default: default:
/* Is it a target option? */ ebt_check_inverse2(optarg, argc, argv);
if (cs.target != NULL && cs.target->parse != NULL) {
int opt_offset = cs.target->option_offset;
if (cs.target->parse(c - opt_offset,
argv, ebt_invert,
&cs.target->tflags,
NULL, &cs.target->t))
goto check_extension;
}
/* Is it a match_option? */ if (ebt_command_default(&cs))
for (m = xtables_matches; m; m = m->next) { xtables_error(PARAMETER_PROBLEM,
if (m->parse(c - m->option_offset, argv, ebt_check_inverse2(optarg, argc, argv), &m->mflags, NULL, &m->m)) { "Unknown argument: '%s'",
ebt_add_match(m, &cs); argv[optind - 1]);
goto check_extension;
}
}
/* Is it a watcher option? */
for (w = xtables_targets; w; w = w->next) {
if (w->parse(c - w->option_offset, argv,
ebt_invert, &w->tflags,
NULL, &w->t)) {
ebt_add_watcher(w, &cs);
goto check_extension;
}
}
/*
if (w == NULL && c == '?')
ebt_print_error2("Unknown argument: '%s'", argv[optind - 1], (char)optopt, (char)c);
else if (w == NULL) {
if (!strcmp(t->name, "standard"))
ebt_print_error2("Unknown argument: don't forget the -t option");
else
ebt_print_error2("Target-specific option does not correspond with specified target");
}
if (ebt_errormsg[0] != '\0')
return -1;
if (w->used == 0) {
ebt_add_watcher(new_entry, w);
w->used = 1;
}*/
check_extension:
if (command != 'A' && command != 'I' && if (command != 'A' && command != 'I' &&
command != 'D' && command != 'C') command != 'D' && command != 'C')
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
...@@ -1274,28 +1293,24 @@ check_extension: ...@@ -1274,28 +1293,24 @@ check_extension:
xtables_error(PARAMETER_PROBLEM, "Wrong policy"); xtables_error(PARAMETER_PROBLEM, "Wrong policy");
} else if (command == 'L') { } else if (command == 'L') {
ret = list_rules(h, chain, *table, rule_nr, ret = list_rules(h, chain, *table, rule_nr,
flags&OPT_VERBOSE, 0,
flags&OPT_NUMERIC, 0,
/*flags&OPT_EXPANDED*/0, /*flags&OPT_EXPANDED*/0,
flags&LIST_N, flags&LIST_N,
flags&LIST_C); flags&LIST_C);
if (!(flags & OPT_ZERO))
exit(0);
} }
if (flags & OPT_ZERO) { if (flags & OPT_ZERO) {
selected_chain = zerochain; ret = nft_chain_zero_counters(h, chain, *table, 0);
ret = nft_chain_zero_counters(h, chain, *table);
} else if (command == 'F') { } else if (command == 'F') {
ret = nft_rule_flush(h, chain, *table); ret = nft_rule_flush(h, chain, *table, 0);
} else if (command == 'A') { } else if (command == 'A') {
ret = append_entry(h, chain, *table, &cs, 0, ret = append_entry(h, chain, *table, &cs, 0, 0, true);
flags&OPT_VERBOSE, true);
} else if (command == 'I') { } else if (command == 'I') {
ret = append_entry(h, chain, *table, &cs, rule_nr - 1, ret = append_entry(h, chain, *table, &cs, rule_nr - 1,
flags&OPT_VERBOSE, false); 0, false);
} else if (command == 'D') { } else if (command == 'D') {
ret = delete_entry(h, chain, *table, &cs, rule_nr - 1, ret = delete_entry(h, chain, *table, &cs, rule_nr - 1,
rule_nr_end, flags&OPT_VERBOSE); rule_nr_end, 0);
} /*else if (replace->command == 'C') { } /*else if (replace->command == 'C') {
ebt_change_counters(replace, new_entry, rule_nr, rule_nr_end, &(new_entry->cnt_surplus), chcounter); ebt_change_counters(replace, new_entry, rule_nr, rule_nr_end, &(new_entry->cnt_surplus), chcounter);
if (ebt_errormsg[0] != '\0') if (ebt_errormsg[0] != '\0')
......
...@@ -25,10 +25,10 @@ Watch for trace events generated by packets that have been tagged ...@@ -25,10 +25,10 @@ Watch for trace events generated by packets that have been tagged
using the TRACE target. using the TRACE target.
.TP .TP
\fB\-4\fP \fB\-4\fP
Restrict output to ipv4. Restrict output to IPv4.
.TP .TP
\fB\-6\fP \fB\-6\fP
Restrict output to ipv6. Restrict output to IPv6.
.SH EXAMPLE OUTPUT .SH EXAMPLE OUTPUT
.TP .TP
.B xtables-monitor \-\-trace .B xtables-monitor \-\-trace
...@@ -55,10 +55,10 @@ PREROUTING chain, and is returning, followed by use the chain policy to make acc ...@@ -55,10 +55,10 @@ PREROUTING chain, and is returning, followed by use the chain policy to make acc
decision (the example shows accept being applied). decision (the example shows accept being applied).
The fifth line shows that the packet leaves the filter INPUT chain, i.e., no rules in the filter tables The fifth line shows that the packet leaves the filter INPUT chain, i.e., no rules in the filter tables
INPUT chain matched the packet. INPUT chain matched the packet.
It then got DROPPED by the policy of the INPUT table, as hown by line six. It then got DROPPED by the policy of the INPUT table, as shown by line six.
The last line shows another packet arriving \-\- the packet id is different. The last line shows another packet arriving \-\- the packet id is different.
When using the TRACE target, it is usally a good idea to only select packets When using the TRACE target, it is usually a good idea to only select packets
that are relevant, for example via that are relevant, for example via
.nf .nf
iptables \-t raw \-A PREROUTING \-p tcp \-\-dport 80 \-\-syn \-m limit \-\-limit 1/s \-j TRACE iptables \-t raw \-A PREROUTING \-p tcp \-\-dport 80 \-\-syn \-m limit \-\-limit 1/s \-j TRACE
......
...@@ -73,12 +73,9 @@ static bool events; ...@@ -73,12 +73,9 @@ static bool events;
static int rule_cb(const struct nlmsghdr *nlh, void *data) static int rule_cb(const struct nlmsghdr *nlh, void *data)
{ {
struct arptables_command_state cs_arp = {};
struct iptables_command_state cs = {};
uint32_t type = nlh->nlmsg_type & 0xFF; uint32_t type = nlh->nlmsg_type & 0xFF;
const struct cb_arg *arg = data; const struct cb_arg *arg = data;
struct nftnl_rule *r; struct nftnl_rule *r;
void *fw = NULL;
uint8_t family; uint8_t family;
r = nftnl_rule_alloc(); r = nftnl_rule_alloc();
...@@ -98,21 +95,16 @@ static int rule_cb(const struct nlmsghdr *nlh, void *data) ...@@ -98,21 +95,16 @@ static int rule_cb(const struct nlmsghdr *nlh, void *data)
case AF_INET: case AF_INET:
case AF_INET6: case AF_INET6:
printf("-%c ", family == AF_INET ? '4' : '6'); printf("-%c ", family == AF_INET ? '4' : '6');
nft_rule_to_iptables_command_state(r, &cs);
fw = &cs;
break; break;
case NFPROTO_ARP: case NFPROTO_ARP:
printf("-0 "); printf("-0 ");
nft_rule_to_arptables_command_state(r, &cs_arp);
fw = &cs_arp;
break; break;
default: default:
goto err_free; goto err_free;
} }
printf("-t %s ", nftnl_rule_get_str(r, NFTNL_RULE_TABLE)); printf("-t %s ", nftnl_rule_get_str(r, NFTNL_RULE_TABLE));
nft_rule_print_save(fw, r, nft_rule_print_save(r, type == NFT_MSG_NEWRULE ? NFT_RULE_APPEND :
type == NFT_MSG_NEWRULE ? NFT_RULE_APPEND :
NFT_RULE_DEL, NFT_RULE_DEL,
counters ? 0 : FMT_NOCOUNTS); counters ? 0 : FMT_NOCOUNTS);
err_free: err_free:
...@@ -576,6 +568,7 @@ static const struct option options[] = { ...@@ -576,6 +568,7 @@ static const struct option options[] = {
{.name = "ipv4", .has_arg = false, .val = '4'}, {.name = "ipv4", .has_arg = false, .val = '4'},
{.name = "ipv6", .has_arg = false, .val = '6'}, {.name = "ipv6", .has_arg = false, .val = '6'},
{.name = "version", .has_arg = false, .val = 'V'}, {.name = "version", .has_arg = false, .val = 'V'},
{.name = "help", .has_arg = false, .val = 'h'},
{NULL}, {NULL},
}; };
...@@ -585,10 +578,10 @@ static void print_usage(void) ...@@ -585,10 +578,10 @@ static void print_usage(void)
xtables_globals.program_version); xtables_globals.program_version);
printf("Usage: %s [ -t | -e ]\n" printf("Usage: %s [ -t | -e ]\n"
" --trace -t trace ruleset traversal of packets tagged via -j TRACE rule\n" " --trace -t trace ruleset traversal of packets tagged via -j TRACE rule\n"
" --event -e show events taht modify the ruleset\n" " --event -e show events that modify the ruleset\n"
"Optional arguments:\n" "Optional arguments:\n"
" --ipv4 -4 only monitor ipv4\n" " --ipv4 -4 only monitor IPv4\n"
" --ipv6 -6 only monitor ipv6\n" " --ipv6 -6 only monitor IPv6\n"
" --counters -c show counters in rules\n" " --counters -c show counters in rules\n"
, xtables_globals.program_name); , xtables_globals.program_name);
...@@ -600,7 +593,7 @@ int xtables_monitor_main(int argc, char *argv[]) ...@@ -600,7 +593,7 @@ int xtables_monitor_main(int argc, char *argv[])
struct mnl_socket *nl; struct mnl_socket *nl;
char buf[MNL_SOCKET_BUFFER_SIZE]; char buf[MNL_SOCKET_BUFFER_SIZE];
uint32_t nfgroup = 0; uint32_t nfgroup = 0;
struct cb_arg cb_arg; struct cb_arg cb_arg = {};
int ret, c; int ret, c;
xtables_globals.program_name = "xtables-monitor"; xtables_globals.program_name = "xtables-monitor";
...@@ -617,7 +610,6 @@ int xtables_monitor_main(int argc, char *argv[]) ...@@ -617,7 +610,6 @@ int xtables_monitor_main(int argc, char *argv[])
init_extensions4(); init_extensions4();
#endif #endif
memset(&cb_arg, 0, sizeof(cb_arg));
opterr = 0; opterr = 0;
while ((c = getopt_long(argc, argv, "ceht46V", options, NULL)) != -1) { while ((c = getopt_long(argc, argv, "ceht46V", options, NULL)) != -1) {
switch (c) { switch (c) {
...@@ -644,7 +636,7 @@ int xtables_monitor_main(int argc, char *argv[]) ...@@ -644,7 +636,7 @@ int xtables_monitor_main(int argc, char *argv[])
exit(0); exit(0);
default: default:
fprintf(stderr, "xtables-monitor %s: Bad argument.\n", IPTABLES_VERSION); fprintf(stderr, "xtables-monitor %s: Bad argument.\n", IPTABLES_VERSION);
fprintf(stderr, "Try `xtables-monitor -h' for more information."); fprintf(stderr, "Try `xtables-monitor -h' for more information.\n");
exit(PARAMETER_PROBLEM); exit(PARAMETER_PROBLEM);
} }
} }
......
...@@ -15,7 +15,11 @@ extern int xtables_eb_xlate_main(int, char **); ...@@ -15,7 +15,11 @@ extern int xtables_eb_xlate_main(int, char **);
extern int xtables_ip4_xlate_restore_main(int, char **); extern int xtables_ip4_xlate_restore_main(int, char **);
extern int xtables_ip6_xlate_restore_main(int, char **); extern int xtables_ip6_xlate_restore_main(int, char **);
extern int xtables_arp_main(int, char **); extern int xtables_arp_main(int, char **);
extern int xtables_arp_restore_main(int, char **);
extern int xtables_arp_save_main(int, char **);
extern int xtables_eb_main(int, char **); extern int xtables_eb_main(int, char **);
extern int xtables_eb_restore_main(int, char **);
extern int xtables_eb_save_main(int, char **);
extern int xtables_config_main(int, char **); extern int xtables_config_main(int, char **);
extern int xtables_monitor_main(int, char **); extern int xtables_monitor_main(int, char **);
#endif #endif
......
...@@ -31,8 +31,18 @@ static const struct subcommand multi_subcommands[] = { ...@@ -31,8 +31,18 @@ static const struct subcommand multi_subcommands[] = {
{"iptables-restore-translate", xtables_ip4_xlate_restore_main}, {"iptables-restore-translate", xtables_ip4_xlate_restore_main},
{"ip6tables-restore-translate", xtables_ip6_xlate_restore_main}, {"ip6tables-restore-translate", xtables_ip6_xlate_restore_main},
{"arptables", xtables_arp_main}, {"arptables", xtables_arp_main},
{"arptables-nft", xtables_arp_main},
{"arptables-restore", xtables_arp_restore_main},
{"arptables-nft-restore", xtables_arp_restore_main},
{"arptables-save", xtables_arp_save_main},
{"arptables-nft-save", xtables_arp_save_main},
{"ebtables-translate", xtables_eb_xlate_main}, {"ebtables-translate", xtables_eb_xlate_main},
{"ebtables", xtables_eb_main}, {"ebtables", xtables_eb_main},
{"ebtables-restore", xtables_eb_restore_main},
{"ebtables-save", xtables_eb_save_main},
{"ebtables-nft", xtables_eb_main},
{"ebtables-nft-restore", xtables_eb_restore_main},
{"ebtables-nft-save", xtables_eb_save_main},
{"xtables-monitor", xtables_monitor_main}, {"xtables-monitor", xtables_monitor_main},
{NULL}, {NULL},
}; };
......
...@@ -16,14 +16,9 @@ ...@@ -16,14 +16,9 @@
#include "libiptc/libiptc.h" #include "libiptc/libiptc.h"
#include "xtables-multi.h" #include "xtables-multi.h"
#include "nft.h" #include "nft.h"
#include "nft-bridge.h"
#include <libnftnl/chain.h> #include <libnftnl/chain.h>
#ifdef DEBUG
#define DEBUGP(x, args...) fprintf(stderr, x, ## args)
#else
#define DEBUGP(x, args...)
#endif
static int counters, verbose, noflush; static int counters, verbose, noflush;
/* Keeping track of external matches and targets. */ /* Keeping track of external matches and targets. */
...@@ -61,110 +56,6 @@ static void print_usage(const char *name, const char *version) ...@@ -61,110 +56,6 @@ static void print_usage(const char *name, const char *version)
" [ --ipv6 ]\n", name); " [ --ipv6 ]\n", name);
} }
static int parse_counters(char *string, struct xt_counters *ctr)
{
unsigned long long pcnt, bcnt;
int ret;
ret = sscanf(string, "[%llu:%llu]", &pcnt, &bcnt);
ctr->pcnt = pcnt;
ctr->bcnt = bcnt;
return ret == 2;
}
/* global new argv and argc */
static char *newargv[255];
static int newargc;
/* function adding one argument to newargv, updating newargc
* returns true if argument added, false otherwise */
static int add_argv(char *what) {
DEBUGP("add_argv: %s\n", what);
if (what && newargc + 1 < ARRAY_SIZE(newargv)) {
newargv[newargc] = strdup(what);
newargv[++newargc] = NULL;
return 1;
} else {
xtables_error(PARAMETER_PROBLEM,
"Parser cannot handle more arguments\n");
return 0;
}
}
static void free_argv(void) {
int i;
for (i = 0; i < newargc; i++)
free(newargv[i]);
}
static void add_param_to_argv(char *parsestart)
{
int quote_open = 0, escaped = 0, param_len = 0;
char param_buffer[1024], *curchar;
/* After fighting with strtok enough, here's now
* a 'real' parser. According to Rusty I'm now no
* longer a real hacker, but I can live with that */
for (curchar = parsestart; *curchar; curchar++) {
if (quote_open) {
if (escaped) {
param_buffer[param_len++] = *curchar;
escaped = 0;
continue;
} else if (*curchar == '\\') {
escaped = 1;
continue;
} else if (*curchar == '"') {
quote_open = 0;
*curchar = ' ';
} else {
param_buffer[param_len++] = *curchar;
continue;
}
} else {
if (*curchar == '"') {
quote_open = 1;
continue;
}
}
if (*curchar == ' '
|| *curchar == '\t'
|| * curchar == '\n') {
if (!param_len) {
/* two spaces? */
continue;
}
param_buffer[param_len] = '\0';
/* check if table name specified */
if ((param_buffer[0] == '-' &&
param_buffer[1] != '-' &&
strchr(param_buffer, 't')) ||
(!strncmp(param_buffer, "--t", 3) &&
!strncmp(param_buffer, "--table", strlen(param_buffer)))) {
xtables_error(PARAMETER_PROBLEM,
"The -t option (seen in line %u) cannot be "
"used in xtables-restore.\n", line);
exit(1);
}
add_argv(param_buffer);
param_len = 0;
} else {
/* regular character, copy to buffer */
param_buffer[param_len++] = *curchar;
if (param_len >= sizeof(param_buffer))
xtables_error(PARAMETER_PROBLEM,
"Parameter too long!");
}
}
}
static struct nftnl_chain_list *get_chain_list(struct nft_handle *h) static struct nftnl_chain_list *get_chain_list(struct nft_handle *h)
{ {
struct nftnl_chain_list *chain_list; struct nftnl_chain_list *chain_list;
...@@ -215,7 +106,7 @@ void xtables_restore_parse(struct nft_handle *h, ...@@ -215,7 +106,7 @@ void xtables_restore_parse(struct nft_handle *h,
{ {
char buffer[10240]; char buffer[10240];
int in_table = 0; int in_table = 0;
char curtable[XT_TABLE_MAXNAMELEN + 1]; struct builtin_table *curtable = NULL;
const struct xtc_ops *ops = &xtc_ops; const struct xtc_ops *ops = &xtc_ops;
struct nftnl_chain_list *chain_list = NULL; struct nftnl_chain_list *chain_list = NULL;
...@@ -253,7 +144,7 @@ void xtables_restore_parse(struct nft_handle *h, ...@@ -253,7 +144,7 @@ void xtables_restore_parse(struct nft_handle *h,
} }
in_table = 0; in_table = 0;
} else if ((buffer[0] == '*') && (!in_table)) { } else if ((buffer[0] == '*') && (!in_table || !p->commit)) {
/* New table */ /* New table */
char *table; char *table;
...@@ -265,8 +156,11 @@ void xtables_restore_parse(struct nft_handle *h, ...@@ -265,8 +156,11 @@ void xtables_restore_parse(struct nft_handle *h,
xt_params->program_name, line); xt_params->program_name, line);
exit(1); exit(1);
} }
strncpy(curtable, table, XT_TABLE_MAXNAMELEN); curtable = nft_table_builtin_find(h, table);
curtable[XT_TABLE_MAXNAMELEN] = '\0'; if (!curtable)
xtables_error(PARAMETER_PROBLEM,
"%s: line %u table name '%s' invalid\n",
xt_params->program_name, line, table);
if (p->tablename && (strcmp(p->tablename, table) != 0)) if (p->tablename && (strcmp(p->tablename, table) != 0))
continue; continue;
...@@ -288,6 +182,7 @@ void xtables_restore_parse(struct nft_handle *h, ...@@ -288,6 +182,7 @@ void xtables_restore_parse(struct nft_handle *h,
/* New chain. */ /* New chain. */
char *policy, *chain = NULL; char *policy, *chain = NULL;
struct xt_counters count = {}; struct xt_counters count = {};
bool chain_exists = false;
chain = strtok(buffer+1, " \t\n"); chain = strtok(buffer+1, " \t\n");
DEBUGP("line %u, chain '%s'\n", line, chain); DEBUGP("line %u, chain '%s'\n", line, chain);
...@@ -300,16 +195,18 @@ void xtables_restore_parse(struct nft_handle *h, ...@@ -300,16 +195,18 @@ void xtables_restore_parse(struct nft_handle *h,
if (noflush == 0) { if (noflush == 0) {
if (cb->chain_del) if (cb->chain_del)
cb->chain_del(chain_list, curtable, cb->chain_del(chain_list, curtable->name,
chain); chain);
} else { } else if (nft_chain_list_find(chain_list,
curtable->name, chain)) {
chain_exists = true;
/* Apparently -n still flushes existing user /* Apparently -n still flushes existing user
* defined chains that are redefined. Otherwise, * defined chains that are redefined. Otherwise,
* leave them as is. * leave them as is.
*/ */
if (cb->chain_user_flush) if (cb->chain_user_flush)
cb->chain_user_flush(h, chain_list, cb->chain_user_flush(h, chain_list,
curtable, chain); curtable->name, chain);
} }
if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN) if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN)
...@@ -327,7 +224,7 @@ void xtables_restore_parse(struct nft_handle *h, ...@@ -327,7 +224,7 @@ void xtables_restore_parse(struct nft_handle *h,
exit(1); exit(1);
} }
if (strcmp(policy, "-") != 0) { if (nft_chain_builtin_find(curtable, chain)) {
if (counters) { if (counters) {
char *ctrs; char *ctrs;
ctrs = strtok(NULL, " \t\n"); ctrs = strtok(NULL, " \t\n");
...@@ -339,7 +236,8 @@ void xtables_restore_parse(struct nft_handle *h, ...@@ -339,7 +236,8 @@ void xtables_restore_parse(struct nft_handle *h,
} }
if (cb->chain_set && if (cb->chain_set &&
cb->chain_set(h, curtable, chain, policy, &count) < 0) { cb->chain_set(h, curtable->name,
chain, policy, &count) < 0) {
xtables_error(OTHER_PROBLEM, xtables_error(OTHER_PROBLEM,
"Can't set policy `%s'" "Can't set policy `%s'"
" on `%s' line %u: %s\n", " on `%s' line %u: %s\n",
...@@ -351,8 +249,10 @@ void xtables_restore_parse(struct nft_handle *h, ...@@ -351,8 +249,10 @@ void xtables_restore_parse(struct nft_handle *h,
ret = 1; ret = 1;
} else { } else {
if (cb->chain_user_add && if (!chain_exists &&
cb->chain_user_add(h, chain, curtable) < 0) { cb->chain_user_add &&
cb->chain_user_add(h, chain,
curtable->name) < 0) {
if (errno == EEXIST) if (errno == EEXIST)
continue; continue;
...@@ -366,7 +266,6 @@ void xtables_restore_parse(struct nft_handle *h, ...@@ -366,7 +266,6 @@ void xtables_restore_parse(struct nft_handle *h,
} else if (in_table) { } else if (in_table) {
int a; int a;
char *ptr = buffer;
char *pcnt = NULL; char *pcnt = NULL;
char *bcnt = NULL; char *bcnt = NULL;
char *parsestart; char *parsestart;
...@@ -376,7 +275,8 @@ void xtables_restore_parse(struct nft_handle *h, ...@@ -376,7 +275,8 @@ void xtables_restore_parse(struct nft_handle *h,
if (buffer[0] == '[') { if (buffer[0] == '[') {
/* we have counters in our input */ /* we have counters in our input */
ptr = strchr(buffer, ']'); char *ptr = strchr(buffer, ']');
if (!ptr) if (!ptr)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"Bad line %u: need ]\n", "Bad line %u: need ]\n",
...@@ -401,20 +301,20 @@ void xtables_restore_parse(struct nft_handle *h, ...@@ -401,20 +301,20 @@ void xtables_restore_parse(struct nft_handle *h,
parsestart = buffer; parsestart = buffer;
} }
add_argv(argv[0]); add_argv(argv[0], 0);
add_argv("-t"); add_argv("-t", 0);
add_argv(curtable); add_argv(curtable->name, 0);
if (counters && pcnt && bcnt) { if (counters && pcnt && bcnt) {
add_argv("--set-counters"); add_argv("--set-counters", 0);
add_argv((char *) pcnt); add_argv((char *) pcnt, 0);
add_argv((char *) bcnt); add_argv((char *) bcnt, 0);
} }
add_param_to_argv(parsestart); add_param_to_argv(parsestart, line);
DEBUGP("calling do_command4(%u, argv, &%s, handle):\n", DEBUGP("calling do_command4(%u, argv, &%s, handle):\n",
newargc, curtable); newargc, curtable->name);
for (a = 0; a < newargc; a++) for (a = 0; a < newargc; a++)
DEBUGP("argv[%u]: %s\n", a, newargv[a]); DEBUGP("argv[%u]: %s\n", a, newargv[a]);
...@@ -437,7 +337,8 @@ void xtables_restore_parse(struct nft_handle *h, ...@@ -437,7 +337,8 @@ void xtables_restore_parse(struct nft_handle *h,
free_argv(); free_argv();
fflush(stdout); fflush(stdout);
} }
if (p->tablename && (strcmp(p->tablename, curtable) != 0)) if (p->tablename && curtable &&
(strcmp(p->tablename, curtable->name) != 0))
continue; continue;
if (!ret) { if (!ret) {
fprintf(stderr, "%s: line %u failed\n", fprintf(stderr, "%s: line %u failed\n",
...@@ -445,10 +346,13 @@ void xtables_restore_parse(struct nft_handle *h, ...@@ -445,10 +346,13 @@ void xtables_restore_parse(struct nft_handle *h,
exit(1); exit(1);
} }
} }
if (in_table) { if (in_table && p->commit) {
fprintf(stderr, "%s: COMMIT expected at line %u\n", fprintf(stderr, "%s: COMMIT expected at line %u\n",
xt_params->program_name, line + 1); xt_params->program_name, line + 1);
exit(1); exit(1);
} else if (in_table && cb->commit && !cb->commit(h)) {
xtables_error(OTHER_PROBLEM, "%s: final implicit COMMIT failed",
xt_params->program_name);
} }
} }
...@@ -461,7 +365,9 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) ...@@ -461,7 +365,9 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[])
.restore = true, .restore = true,
}; };
int c; int c;
struct nft_xt_restore_parse p = {}; struct nft_xt_restore_parse p = {
.commit = true,
};
line = 0; line = 0;
...@@ -513,6 +419,8 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) ...@@ -513,6 +419,8 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[])
break; break;
case 'w': /* fallthrough. Ignored by xt-restore */ case 'w': /* fallthrough. Ignored by xt-restore */
case 'W': case 'W':
if (!optarg && xs_has_arg(argc, argv))
optind++;
break; break;
default: default:
fprintf(stderr, fprintf(stderr,
...@@ -581,3 +489,75 @@ int xtables_ip6_restore_main(int argc, char *argv[]) ...@@ -581,3 +489,75 @@ int xtables_ip6_restore_main(int argc, char *argv[])
return xtables_restore_main(NFPROTO_IPV6, "ip6tables-restore", return xtables_restore_main(NFPROTO_IPV6, "ip6tables-restore",
argc, argv); argc, argv);
} }
struct nft_xt_restore_cb ebt_restore_cb = {
.chain_list = get_chain_list,
.commit = nft_commit,
.table_new = nft_table_new,
.table_flush = nft_table_flush,
.chain_user_flush = nft_chain_user_flush,
.chain_del = chain_delete,
.do_command = do_commandeb,
.chain_set = nft_chain_set,
.chain_user_add = nft_chain_user_add,
};
static const struct option ebt_restore_options[] = {
{.name = "noflush", .has_arg = 0, .val = 'n'},
{ 0 }
};
int xtables_eb_restore_main(int argc, char *argv[])
{
struct nft_xt_restore_parse p = {
.in = stdin,
};
struct nft_handle h;
int c;
while ((c = getopt_long(argc, argv, "n",
ebt_restore_options, NULL)) != -1) {
switch(c) {
case 'n':
noflush = 1;
break;
default:
fprintf(stderr,
"Usage: ebtables-restore [ --noflush ]\n");
exit(1);
break;
}
}
nft_init_eb(&h, "ebtables-restore");
xtables_restore_parse(&h, &p, &ebt_restore_cb, argc, argv);
nft_fini(&h);
return 0;
}
struct nft_xt_restore_cb arp_restore_cb = {
.chain_list = get_chain_list,
.commit = nft_commit,
.table_new = nft_table_new,
.table_flush = nft_table_flush,
.chain_user_flush = nft_chain_user_flush,
.chain_del = chain_delete,
.do_command = do_commandarp,
.chain_set = nft_chain_set,
.chain_user_add = nft_chain_user_add,
};
int xtables_arp_restore_main(int argc, char *argv[])
{
struct nft_xt_restore_parse p = {
.in = stdin,
};
struct nft_handle h;
nft_init_arp(&h, "arptables-restore");
xtables_restore_parse(&h, &p, &arp_restore_cb, argc, argv);
nft_fini(&h);
return 0;
}
...@@ -49,13 +49,10 @@ __do_output(struct nft_handle *h, const char *tablename, bool counters) ...@@ -49,13 +49,10 @@ __do_output(struct nft_handle *h, const char *tablename, bool counters)
struct nftnl_chain_list *chain_list; struct nftnl_chain_list *chain_list;
if (!nft_table_find(h, tablename)) {
printf("Table `%s' does not exist\n", tablename);
return 1;
}
if (!nft_is_table_compatible(h, tablename)) { if (!nft_is_table_compatible(h, tablename)) {
printf("# Table `%s' is incompatible, use 'nft' tool.\n", tablename); if (!nft_table_builtin_find(h, tablename))
printf("# Table `%s' is incompatible, use 'nft' tool.\n",
tablename);
return 0; return 0;
} }
...@@ -70,7 +67,7 @@ __do_output(struct nft_handle *h, const char *tablename, bool counters) ...@@ -70,7 +67,7 @@ __do_output(struct nft_handle *h, const char *tablename, bool counters)
/* Dump out chain names first, /* Dump out chain names first,
* thereby preventing dependency conflicts */ * thereby preventing dependency conflicts */
nft_chain_save(h, chain_list, tablename); nft_chain_save(h, chain_list, tablename);
nft_rule_save(h, tablename, counters); nft_rule_save(h, tablename, counters ? 0 : FMT_NOCOUNTS);
now = time(NULL); now = time(NULL);
printf("COMMIT\n"); printf("COMMIT\n");
...@@ -89,6 +86,11 @@ do_output(struct nft_handle *h, const char *tablename, bool counters) ...@@ -89,6 +86,11 @@ do_output(struct nft_handle *h, const char *tablename, bool counters)
return !!ret; return !!ret;
} }
if (!nft_table_find(h, tablename)) {
printf("Table `%s' does not exist\n", tablename);
return 1;
}
ret = __do_output(h, tablename, counters); ret = __do_output(h, tablename, counters);
nft_check_xt_legacy(h->family, true); nft_check_xt_legacy(h->family, true);
return ret; return ret;
...@@ -203,12 +205,12 @@ xtables_save_main(int family, const char *progname, int argc, char *argv[]) ...@@ -203,12 +205,12 @@ xtables_save_main(int family, const char *progname, int argc, char *argv[])
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (dump) { ret = do_output(&h, tablename, show_counters);
do_output(&h, tablename, show_counters); nft_fini(&h);
if (dump)
exit(0); exit(0);
}
return do_output(&h, tablename, show_counters); return ret;
} }
int xtables_ip4_save_main(int argc, char *argv[]) int xtables_ip4_save_main(int argc, char *argv[])
...@@ -220,3 +222,111 @@ int xtables_ip6_save_main(int argc, char *argv[]) ...@@ -220,3 +222,111 @@ int xtables_ip6_save_main(int argc, char *argv[])
{ {
return xtables_save_main(NFPROTO_IPV6, "ip6tables-save", argc, argv); return xtables_save_main(NFPROTO_IPV6, "ip6tables-save", argc, argv);
} }
static int __ebt_save(struct nft_handle *h, const char *tablename, bool counters)
{
struct nftnl_chain_list *chain_list;
static bool first = true;
time_t now;
if (!nft_table_find(h, tablename)) {
printf("Table `%s' does not exist\n", tablename);
return 1;
}
if (!nft_is_table_compatible(h, tablename)) {
printf("# Table `%s' is incompatible, use 'nft' tool.\n", tablename);
return 0;
}
chain_list = nft_chain_dump(h);
if (first) {
now = time(NULL);
printf("# Generated by ebtables-save v%s on %s",
IPTABLES_VERSION, ctime(&now));
first = false;
}
printf("*%s\n", tablename);
/* Dump out chain names first,
* thereby preventing dependency conflicts */
nft_chain_save(h, chain_list, tablename);
nft_rule_save(h, tablename,
FMT_EBT_SAVE | (counters ? 0 : FMT_NOCOUNTS));
printf("\n");
return 0;
}
int xtables_eb_save_main(int argc_, char *argv_[])
{
const char *ctr = getenv("EBTABLES_SAVE_COUNTER");
struct nft_handle h = {
.family = NFPROTO_BRIDGE,
};
int c;
if (ctr && strcmp(ctr, "yes"))
ctr = NULL;
xtables_globals.program_name = "ebtables-save";
c = xtables_init_all(&xtables_globals, h.family);
if (c < 0) {
fprintf(stderr, "%s/%s Failed to initialize xtables\n",
xtables_globals.program_name,
xtables_globals.program_version);
exit(1);
}
if (nft_init(&h, xtables_bridge) < 0) {
fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
xtables_globals.program_name,
xtables_globals.program_version,
strerror(errno));
exit(EXIT_FAILURE);
}
nft_for_each_table(&h, __ebt_save, !!ctr);
nft_fini(&h);
return 0;
}
int xtables_arp_save_main(int argc, char **argv)
{
struct nft_handle h = {
.family = NFPROTO_ARP,
};
int c;
xtables_globals.program_name = "arptables-save";
c = xtables_init_all(&xtables_globals, h.family);
if (c < 0) {
fprintf(stderr, "%s/%s Failed to initialize xtables\n",
xtables_globals.program_name,
xtables_globals.program_version);
exit(1);
}
if (nft_init(&h, xtables_arp) < 0) {
fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
xtables_globals.program_name,
xtables_globals.program_version,
strerror(errno));
exit(EXIT_FAILURE);
}
if (!nft_table_find(&h, "filter"))
return 0;
if (!nft_is_table_compatible(&h, "filter")) {
printf("# Table `filter' is incompatible, use 'nft' tool.\n");
return 0;
}
printf("*filter\n");
nft_chain_save(&h, nft_chain_dump(&h), "filter");
nft_rule_save(&h, "filter", FMT_NOCOUNTS);
printf("\n");
nft_fini(&h);
return 0;
}
...@@ -156,9 +156,9 @@ static const int inverse_for_options[NUMBER_OF_OPT] = ...@@ -156,9 +156,9 @@ static const int inverse_for_options[NUMBER_OF_OPT] =
/* -f */ IPT_INV_FRAG, /* -f */ IPT_INV_FRAG,
}; };
#define opts xtables_globals.opts #define opts xt_params->opts
#define prog_name xtables_globals.program_name #define prog_name xt_params->program_name
#define prog_vers xtables_globals.program_version #define prog_vers xt_params->program_version
static void __attribute__((noreturn)) static void __attribute__((noreturn))
exit_tryhelp(int status) exit_tryhelp(int status)
...@@ -363,27 +363,6 @@ parse_rulenumber(const char *rule) ...@@ -363,27 +363,6 @@ parse_rulenumber(const char *rule)
return rulenum; return rulenum;
} }
static const char *
parse_target(const char *targetname)
{
const char *ptr;
if (strlen(targetname) < 1)
xtables_error(PARAMETER_PROBLEM,
"Invalid target name (too short)");
if (strlen(targetname) >= XT_EXTENSION_MAXNAMELEN)
xtables_error(PARAMETER_PROBLEM,
"Invalid target name `%s' (%u chars max)",
targetname, XT_EXTENSION_MAXNAMELEN - 1);
for (ptr = targetname; *ptr; ptr++)
if (isspace(*ptr))
xtables_error(PARAMETER_PROBLEM,
"Invalid target name `%s'", targetname);
return targetname;
}
static void static void
set_option(unsigned int *options, unsigned int option, uint8_t *invflg, set_option(unsigned int *options, unsigned int option, uint8_t *invflg,
int invert) int invert)
...@@ -599,88 +578,7 @@ list_rules(struct nft_handle *h, const char *chain, const char *table, ...@@ -599,88 +578,7 @@ list_rules(struct nft_handle *h, const char *chain, const char *table,
if (counters) if (counters)
counters = -1; /* iptables -c format */ counters = -1; /* iptables -c format */
nft_rule_list_save(h, chain, table, rulenum, counters); return nft_rule_list_save(h, chain, table, rulenum, counters);
/* iptables does not return error if rule number not found */
return 1;
}
static void command_jump(struct iptables_command_state *cs)
{
size_t size;
set_option(&cs->options, OPT_JUMP, &cs->fw.ip.invflags, cs->invert);
cs->jumpto = parse_target(optarg);
/* TRY_LOAD (may be chain name) */
cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
if (cs->target == NULL)
return;
size = XT_ALIGN(sizeof(struct xt_entry_target))
+ cs->target->size;
cs->target->t = xtables_calloc(1, size);
cs->target->t->u.target_size = size;
if (cs->target->real_name == NULL) {
strcpy(cs->target->t->u.user.name, cs->jumpto);
} else {
/* Alias support for userspace side */
strcpy(cs->target->t->u.user.name, cs->target->real_name);
if (!(cs->target->ext_flags & XTABLES_EXT_ALIAS))
fprintf(stderr, "Notice: The %s target is converted into %s target "
"in rule listing and saving.\n",
cs->jumpto, cs->target->real_name);
}
cs->target->t->u.user.revision = cs->target->revision;
xs_init_target(cs->target);
if (cs->target->x6_options != NULL)
opts = xtables_options_xfrm(xtables_globals.orig_opts, opts,
cs->target->x6_options,
&cs->target->option_offset);
else
opts = xtables_merge_options(xtables_globals.orig_opts, opts,
cs->target->extra_opts,
&cs->target->option_offset);
if (opts == NULL)
xtables_error(OTHER_PROBLEM, "can't alloc memory!");
}
static void command_match(struct iptables_command_state *cs)
{
struct xtables_match *m;
size_t size;
if (cs->invert)
xtables_error(PARAMETER_PROBLEM,
"unexpected ! flag before --match");
m = xtables_find_match(optarg, XTF_LOAD_MUST_SUCCEED, &cs->matches);
size = XT_ALIGN(sizeof(struct xt_entry_match)) + m->size;
m->m = xtables_calloc(1, size);
m->m->u.match_size = size;
if (m->real_name == NULL) {
strcpy(m->m->u.user.name, m->name);
} else {
strcpy(m->m->u.user.name, m->real_name);
if (!(m->ext_flags & XTABLES_EXT_ALIAS))
fprintf(stderr, "Notice: the %s match is converted into %s match "
"in rule listing and saving.\n", m->name, m->real_name);
}
m->m->u.user.revision = m->revision;
xs_init_match(m);
if (m == m->next)
return;
/* Merge options for non-cloned matches */
if (m->x6_options != NULL)
opts = xtables_options_xfrm(xtables_globals.orig_opts, opts,
m->x6_options, &m->option_offset);
else if (m->extra_opts != NULL)
opts = xtables_merge_options(xtables_globals.orig_opts, opts,
m->extra_opts, &m->option_offset);
if (opts == NULL)
xtables_error(OTHER_PROBLEM, "can't alloc memory!");
} }
void do_parse(struct nft_handle *h, int argc, char *argv[], void do_parse(struct nft_handle *h, int argc, char *argv[],
...@@ -915,11 +813,13 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], ...@@ -915,11 +813,13 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
set_option(&cs->options, OPT_JUMP, &args->invflags, set_option(&cs->options, OPT_JUMP, &args->invflags,
cs->invert); cs->invert);
args->goto_set = true; args->goto_set = true;
cs->jumpto = parse_target(optarg); cs->jumpto = xt_parse_target(optarg);
break; break;
#endif #endif
case 'j': case 'j':
set_option(&cs->options, OPT_JUMP, &cs->fw.ip.invflags,
cs->invert);
command_jump(cs); command_jump(cs);
break; break;
...@@ -979,6 +879,10 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], ...@@ -979,6 +879,10 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
if (cs->invert) if (cs->invert)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"unexpected ! flag before --table"); "unexpected ! flag before --table");
if (!nft_table_builtin_find(h, optarg))
xtables_error(VERSION_PROBLEM,
"table '%s' does not exist",
optarg);
p->table = optarg; p->table = optarg;
break; break;
...@@ -1159,12 +1063,18 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], ...@@ -1159,12 +1063,18 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
p->chain); p->chain);
} }
/* if (!nft_chain_exists(h, p->table, p->chain))
* Contrary to what iptables does, we assume that any jumpto xtables_error(OTHER_PROBLEM,
* is a custom chain jumps (if no target is found). Later on, "Chain '%s' does not exist", cs->jumpto);
* nf_table will spot the error if the chain does not exists.
*/ if (!cs->target && strlen(cs->jumpto) > 0 &&
!nft_chain_exists(h, p->table, cs->jumpto))
xtables_error(PARAMETER_PROBLEM,
"Chain '%s' does not exist", cs->jumpto);
} }
if (p->command == CMD_NEW_CHAIN &&
nft_chain_exists(h, p->table, p->chain))
xtables_error(OTHER_PROBLEM, "Chain already exists");
} }
int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
...@@ -1213,10 +1123,12 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1213,10 +1123,12 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
cs.options&OPT_VERBOSE, h, false); cs.options&OPT_VERBOSE, h, false);
break; break;
case CMD_FLUSH: case CMD_FLUSH:
ret = nft_rule_flush(h, p.chain, p.table); ret = nft_rule_flush(h, p.chain, p.table,
cs.options & OPT_VERBOSE);
break; break;
case CMD_ZERO: case CMD_ZERO:
ret = nft_chain_zero_counters(h, p.chain, p.table); ret = nft_chain_zero_counters(h, p.chain, p.table,
cs.options & OPT_VERBOSE);
break; break;
case CMD_ZERO_NUM: case CMD_ZERO_NUM:
ret = nft_rule_zero_counters(h, p.chain, p.table, ret = nft_rule_zero_counters(h, p.chain, p.table,
...@@ -1231,8 +1143,8 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1231,8 +1143,8 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
cs.options & OPT_EXPANDED, cs.options & OPT_EXPANDED,
cs.options & OPT_LINENUMBERS); cs.options & OPT_LINENUMBERS);
if (ret && (p.command & CMD_ZERO)) { if (ret && (p.command & CMD_ZERO)) {
ret = nft_chain_zero_counters(h, p.chain, ret = nft_chain_zero_counters(h, p.chain, p.table,
p.table); cs.options & OPT_VERBOSE);
} }
if (ret && (p.command & CMD_ZERO_NUM)) { if (ret && (p.command & CMD_ZERO_NUM)) {
ret = nft_rule_zero_counters(h, p.chain, p.table, ret = nft_rule_zero_counters(h, p.chain, p.table,
...@@ -1246,8 +1158,8 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1246,8 +1158,8 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
ret = list_rules(h, p.chain, p.table, p.rulenum, ret = list_rules(h, p.chain, p.table, p.rulenum,
cs.options & OPT_VERBOSE); cs.options & OPT_VERBOSE);
if (ret && (p.command & CMD_ZERO)) { if (ret && (p.command & CMD_ZERO)) {
ret = nft_chain_zero_counters(h, p.chain, ret = nft_chain_zero_counters(h, p.chain, p.table,
p.table); cs.options & OPT_VERBOSE);
} }
if (ret && (p.command & CMD_ZERO_NUM)) { if (ret && (p.command & CMD_ZERO_NUM)) {
ret = nft_rule_zero_counters(h, p.chain, p.table, ret = nft_rule_zero_counters(h, p.chain, p.table,
...@@ -1259,16 +1171,14 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, ...@@ -1259,16 +1171,14 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
ret = nft_chain_user_add(h, p.chain, p.table); ret = nft_chain_user_add(h, p.chain, p.table);
break; break;
case CMD_DELETE_CHAIN: case CMD_DELETE_CHAIN:
ret = nft_chain_user_del(h, p.chain, p.table); ret = nft_chain_user_del(h, p.chain, p.table,
cs.options & OPT_VERBOSE);
break; break;
case CMD_RENAME_CHAIN: case CMD_RENAME_CHAIN:
ret = nft_chain_user_rename(h, p.chain, p.table, p.newname); ret = nft_chain_user_rename(h, p.chain, p.table, p.newname);
break; break;
case CMD_SET_POLICY: case CMD_SET_POLICY:
ret = nft_chain_set(h, p.table, p.chain, p.policy, NULL); ret = nft_chain_set(h, p.table, p.chain, p.policy, NULL);
if (ret < 0)
xtables_error(PARAMETER_PROBLEM, "Wrong policy `%s'\n",
p.policy);
break; break;
default: default:
/* We should never reach this... */ /* We should never reach this... */
......
...@@ -1115,8 +1115,9 @@ static inline int iptcc_compile_rule (struct xtc_handle *h, STRUCT_REPLACE *repl ...@@ -1115,8 +1115,9 @@ static inline int iptcc_compile_rule (struct xtc_handle *h, STRUCT_REPLACE *repl
STRUCT_STANDARD_TARGET *t; STRUCT_STANDARD_TARGET *t;
t = (STRUCT_STANDARD_TARGET *)GET_TARGET(r->entry); t = (STRUCT_STANDARD_TARGET *)GET_TARGET(r->entry);
/* memset for memcmp convenience on delete/replace */ /* memset for memcmp convenience on delete/replace */
memset(t->target.u.user.name, 0, FUNCTION_MAXNAMELEN); memset(t->target.u.user.name, 0, XT_EXTENSION_MAXNAMELEN);
strcpy(t->target.u.user.name, STANDARD_TARGET); strcpy(t->target.u.user.name, STANDARD_TARGET);
t->target.u.user.revision = 0;
/* Jumps can only happen to builtin chains, so we /* Jumps can only happen to builtin chains, so we
* can safely assume that they always have a header */ * can safely assume that they always have a header */
t->verdict = r->jump->head_offset + IPTCB_CHAIN_START_SIZE; t->verdict = r->jump->head_offset + IPTCB_CHAIN_START_SIZE;
...@@ -1149,7 +1150,8 @@ static int iptcc_compile_chain(struct xtc_handle *h, STRUCT_REPLACE *repl, struc ...@@ -1149,7 +1150,8 @@ static int iptcc_compile_chain(struct xtc_handle *h, STRUCT_REPLACE *repl, struc
strcpy(head->name.target.u.user.name, ERROR_TARGET); strcpy(head->name.target.u.user.name, ERROR_TARGET);
head->name.target.u.target_size = head->name.target.u.target_size =
ALIGN(sizeof(struct xt_error_target)); ALIGN(sizeof(struct xt_error_target));
strcpy(head->name.errorname, c->name); strncpy(head->name.errorname, c->name, XT_FUNCTION_MAXNAMELEN);
head->name.errorname[XT_FUNCTION_MAXNAMELEN - 1] = '\0';
} else { } else {
repl->hook_entry[c->hooknum-1] = c->head_offset; repl->hook_entry[c->hooknum-1] = c->head_offset;
repl->underflow[c->hooknum-1] = c->foot_offset; repl->underflow[c->hooknum-1] = c->foot_offset;
...@@ -1269,7 +1271,7 @@ static int iptcc_compile_table(struct xtc_handle *h, STRUCT_REPLACE *repl) ...@@ -1269,7 +1271,7 @@ static int iptcc_compile_table(struct xtc_handle *h, STRUCT_REPLACE *repl)
/* Allocate handle of given size */ /* Allocate handle of given size */
static struct xtc_handle * static struct xtc_handle *
alloc_handle(const char *tablename, unsigned int size, unsigned int num_rules) alloc_handle(STRUCT_GETINFO *infop)
{ {
struct xtc_handle *h; struct xtc_handle *h;
...@@ -1280,14 +1282,14 @@ alloc_handle(const char *tablename, unsigned int size, unsigned int num_rules) ...@@ -1280,14 +1282,14 @@ alloc_handle(const char *tablename, unsigned int size, unsigned int num_rules)
} }
memset(h, 0, sizeof(*h)); memset(h, 0, sizeof(*h));
INIT_LIST_HEAD(&h->chains); INIT_LIST_HEAD(&h->chains);
strcpy(h->info.name, tablename); strcpy(h->info.name, infop->name);
h->entries = malloc(sizeof(STRUCT_GET_ENTRIES) + size); h->entries = malloc(sizeof(STRUCT_GET_ENTRIES) + infop->size);
if (!h->entries) if (!h->entries)
goto out_free_handle; goto out_free_handle;
strcpy(h->entries->name, tablename); strcpy(h->entries->name, infop->name);
h->entries->size = size; h->entries->size = infop->size;
return h; return h;
...@@ -1336,8 +1338,8 @@ retry: ...@@ -1336,8 +1338,8 @@ retry:
DEBUGP("valid_hooks=0x%08x, num_entries=%u, size=%u\n", DEBUGP("valid_hooks=0x%08x, num_entries=%u, size=%u\n",
info.valid_hooks, info.num_entries, info.size); info.valid_hooks, info.num_entries, info.size);
if ((h = alloc_handle(info.name, info.size, info.num_entries)) h = alloc_handle(&info);
== NULL) { if (h == NULL) {
close(sockfd); close(sockfd);
return NULL; return NULL;
} }
...@@ -1675,8 +1677,9 @@ iptcc_standard_map(struct rule_head *r, int verdict) ...@@ -1675,8 +1677,9 @@ iptcc_standard_map(struct rule_head *r, int verdict)
return 0; return 0;
} }
/* memset for memcmp convenience on delete/replace */ /* memset for memcmp convenience on delete/replace */
memset(t->target.u.user.name, 0, FUNCTION_MAXNAMELEN); memset(t->target.u.user.name, 0, XT_EXTENSION_MAXNAMELEN);
strcpy(t->target.u.user.name, STANDARD_TARGET); strcpy(t->target.u.user.name, STANDARD_TARGET);
t->target.u.user.revision = 0;
t->verdict = verdict; t->verdict = verdict;
r->type = IPTCC_R_STANDARD; r->type = IPTCC_R_STANDARD;
......
...@@ -4,7 +4,7 @@ AM_CFLAGS = ${regular_CFLAGS} ...@@ -4,7 +4,7 @@ AM_CFLAGS = ${regular_CFLAGS}
AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_builddir}/include -I${top_srcdir}/include -I${top_srcdir}/iptables ${kinclude_CPPFLAGS} AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_builddir}/include -I${top_srcdir}/include -I${top_srcdir}/iptables ${kinclude_CPPFLAGS}
lib_LTLIBRARIES = libxtables.la lib_LTLIBRARIES = libxtables.la
libxtables_la_SOURCES = xtables.c xtoptions.c libxtables_la_SOURCES = xtables.c xtoptions.c getethertype.c
libxtables_la_LDFLAGS = -version-info ${libxtables_vcurrent}:0:${libxtables_vage} libxtables_la_LDFLAGS = -version-info ${libxtables_vcurrent}:0:${libxtables_vage}
libxtables_la_LIBADD = libxtables_la_LIBADD =
if ENABLE_STATIC if ENABLE_STATIC
......
...@@ -140,7 +140,7 @@ am__DEPENDENCIES_1 = ...@@ -140,7 +140,7 @@ am__DEPENDENCIES_1 =
libxtables_la_DEPENDENCIES = $(am__DEPENDENCIES_2) \ libxtables_la_DEPENDENCIES = $(am__DEPENDENCIES_2) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
am_libxtables_la_OBJECTS = libxtables_la-xtables.lo \ am_libxtables_la_OBJECTS = libxtables_la-xtables.lo \
libxtables_la-xtoptions.lo libxtables_la-xtoptions.lo libxtables_la-getethertype.lo
libxtables_la_OBJECTS = $(am_libxtables_la_OBJECTS) libxtables_la_OBJECTS = $(am_libxtables_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@) AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
...@@ -366,7 +366,7 @@ xtlibdir = @xtlibdir@ ...@@ -366,7 +366,7 @@ xtlibdir = @xtlibdir@
AM_CFLAGS = ${regular_CFLAGS} AM_CFLAGS = ${regular_CFLAGS}
AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_builddir}/include -I${top_srcdir}/include -I${top_srcdir}/iptables ${kinclude_CPPFLAGS} AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_builddir}/include -I${top_srcdir}/include -I${top_srcdir}/iptables ${kinclude_CPPFLAGS}
lib_LTLIBRARIES = libxtables.la lib_LTLIBRARIES = libxtables.la
libxtables_la_SOURCES = xtables.c xtoptions.c libxtables_la_SOURCES = xtables.c xtoptions.c getethertype.c
libxtables_la_LDFLAGS = -version-info ${libxtables_vcurrent}:0:${libxtables_vage} libxtables_la_LDFLAGS = -version-info ${libxtables_vcurrent}:0:${libxtables_vage}
libxtables_la_LIBADD = $(am__append_1) $(am__append_2) libxtables_la_LIBADD = $(am__append_1) $(am__append_2)
@ENABLE_SHARED_FALSE@libxtables_la_CFLAGS = ${AM_CFLAGS} -DNO_SHARED_LIBS=1 @ENABLE_SHARED_FALSE@libxtables_la_CFLAGS = ${AM_CFLAGS} -DNO_SHARED_LIBS=1
...@@ -449,6 +449,7 @@ mostlyclean-compile: ...@@ -449,6 +449,7 @@ mostlyclean-compile:
distclean-compile: distclean-compile:
-rm -f *.tab.c -rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxtables_la-getethertype.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxtables_la-xtables.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxtables_la-xtables.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxtables_la-xtoptions.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxtables_la-xtoptions.Plo@am__quote@
...@@ -487,6 +488,13 @@ libxtables_la-xtoptions.lo: xtoptions.c ...@@ -487,6 +488,13 @@ libxtables_la-xtoptions.lo: xtoptions.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxtables_la_CFLAGS) $(CFLAGS) -c -o libxtables_la-xtoptions.lo `test -f 'xtoptions.c' || echo '$(srcdir)/'`xtoptions.c @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxtables_la_CFLAGS) $(CFLAGS) -c -o libxtables_la-xtoptions.lo `test -f 'xtoptions.c' || echo '$(srcdir)/'`xtoptions.c
libxtables_la-getethertype.lo: getethertype.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxtables_la_CFLAGS) $(CFLAGS) -MT libxtables_la-getethertype.lo -MD -MP -MF $(DEPDIR)/libxtables_la-getethertype.Tpo -c -o libxtables_la-getethertype.lo `test -f 'getethertype.c' || echo '$(srcdir)/'`getethertype.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libxtables_la-getethertype.Tpo $(DEPDIR)/libxtables_la-getethertype.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getethertype.c' object='libxtables_la-getethertype.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libxtables_la_CFLAGS) $(CFLAGS) -c -o libxtables_la-getethertype.lo `test -f 'getethertype.c' || echo '$(srcdir)/'`getethertype.c
mostlyclean-libtool: mostlyclean-libtool:
-rm -f *.lo -rm -f *.lo
......
...@@ -42,27 +42,26 @@ ...@@ -42,27 +42,26 @@
#include <string.h> #include <string.h>
#include <netinet/ether.h> #include <netinet/ether.h>
#include <net/ethernet.h> #include <net/ethernet.h>
#include <xtables.h>
#include <ebtables/ethernetdb.h>
#define MAXALIASES 35 #define MAXALIASES 35
static FILE *etherf = NULL; static FILE *etherf = NULL;
static char line[BUFSIZ + 1]; static char line[BUFSIZ + 1];
static struct ethertypeent et_ent; static struct xt_ethertypeent et_ent;
static char *ethertype_aliases[MAXALIASES]; static char *ethertype_aliases[MAXALIASES];
static int ethertype_stayopen; static int ethertype_stayopen;
void setethertypeent(int f) static void setethertypeent(int f)
{ {
if (etherf == NULL) if (etherf == NULL)
etherf = fopen(_PATH_ETHERTYPES, "r"); etherf = fopen(XT_PATH_ETHERTYPES, "r");
else else
rewind(etherf); rewind(etherf);
ethertype_stayopen |= f; ethertype_stayopen |= f;
} }
void endethertypeent(void) static void endethertypeent(void)
{ {
if (etherf) { if (etherf) {
fclose(etherf); fclose(etherf);
...@@ -71,14 +70,15 @@ void endethertypeent(void) ...@@ -71,14 +70,15 @@ void endethertypeent(void)
ethertype_stayopen = 0; ethertype_stayopen = 0;
} }
struct ethertypeent *getethertypeent(void)
static struct xt_ethertypeent *getethertypeent(void)
{ {
char *e; char *e;
char *endptr; char *endptr;
register char *cp, **q; register char *cp, **q;
if (etherf == NULL if (etherf == NULL
&& (etherf = fopen(_PATH_ETHERTYPES, "r")) == NULL) { && (etherf = fopen(XT_PATH_ETHERTYPES, "r")) == NULL) {
return (NULL); return (NULL);
} }
...@@ -127,10 +127,9 @@ again: ...@@ -127,10 +127,9 @@ again:
return (&et_ent); return (&et_ent);
} }
struct xt_ethertypeent *xtables_getethertypebyname(const char *name)
struct ethertypeent *getethertypebyname(const char *name)
{ {
register struct ethertypeent *e; register struct xt_ethertypeent *e;
register char **cp; register char **cp;
setethertypeent(ethertype_stayopen); setethertypeent(ethertype_stayopen);
...@@ -147,9 +146,9 @@ found: ...@@ -147,9 +146,9 @@ found:
return (e); return (e);
} }
struct ethertypeent *getethertypebynumber(int type) struct xt_ethertypeent *xtables_getethertypebynumber(int type)
{ {
register struct ethertypeent *e; register struct xt_ethertypeent *e;
setethertypeent(ethertype_stayopen); setethertypeent(ethertype_stayopen);
while ((e = getethertypeent()) != NULL) while ((e = getethertypeent()) != NULL)
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <inttypes.h> #include <inttypes.h>
#include <netdb.h> #include <netdb.h>
#include <spawn.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
...@@ -119,8 +120,10 @@ struct option *xtables_merge_options(struct option *orig_opts, ...@@ -119,8 +120,10 @@ struct option *xtables_merge_options(struct option *orig_opts,
* Since @oldopts also has @orig_opts already (and does so at the * Since @oldopts also has @orig_opts already (and does so at the
* start), skip these entries. * start), skip these entries.
*/ */
oldopts += num_oold; if (oldopts != NULL) {
num_old -= num_oold; oldopts += num_oold;
num_old -= num_oold;
}
merge = malloc(sizeof(*mp) * (num_oold + num_old + num_new + 1)); merge = malloc(sizeof(*mp) * (num_oold + num_old + num_new + 1));
if (merge == NULL) if (merge == NULL)
...@@ -139,8 +142,10 @@ struct option *xtables_merge_options(struct option *orig_opts, ...@@ -139,8 +142,10 @@ struct option *xtables_merge_options(struct option *orig_opts,
mp->val += *option_offset; mp->val += *option_offset;
/* Third, the old options */ /* Third, the old options */
memcpy(mp, oldopts, sizeof(*mp) * num_old); if (oldopts != NULL) {
mp += num_old; memcpy(mp, oldopts, sizeof(*mp) * num_old);
mp += num_old;
}
xtables_free_opts(0); xtables_free_opts(0);
/* Clear trailing entry */ /* Clear trailing entry */
...@@ -358,6 +363,7 @@ int xtables_insmod(const char *modname, const char *modprobe, bool quiet) ...@@ -358,6 +363,7 @@ int xtables_insmod(const char *modname, const char *modprobe, bool quiet)
char *buf = NULL; char *buf = NULL;
char *argv[4]; char *argv[4];
int status; int status;
pid_t pid;
/* If they don't explicitly set it, read out of kernel */ /* If they don't explicitly set it, read out of kernel */
if (!modprobe) { if (!modprobe) {
...@@ -378,18 +384,11 @@ int xtables_insmod(const char *modname, const char *modprobe, bool quiet) ...@@ -378,18 +384,11 @@ int xtables_insmod(const char *modname, const char *modprobe, bool quiet)
*/ */
fflush(stdout); fflush(stdout);
switch (vfork()) { if (posix_spawn(&pid, argv[0], NULL, NULL, argv, NULL)) {
case 0:
execv(argv[0], argv);
/* not usually reached */
_exit(1);
case -1:
free(buf); free(buf);
return -1; return -1;
} else {
default: /* parent */ waitpid(pid, &status, 0);
wait(&status);
} }
free(buf); free(buf);
...@@ -488,7 +487,7 @@ bool xtables_strtoui(const char *s, char **end, unsigned int *value, ...@@ -488,7 +487,7 @@ bool xtables_strtoui(const char *s, char **end, unsigned int *value,
bool ret; bool ret;
ret = xtables_strtoul(s, end, &v, min, max); ret = xtables_strtoul(s, end, &v, min, max);
if (value != NULL) if (ret && value != NULL)
*value = v; *value = v;
return ret; return ret;
} }
...@@ -921,6 +920,12 @@ void xtables_register_match(struct xtables_match *me) ...@@ -921,6 +920,12 @@ void xtables_register_match(struct xtables_match *me)
exit(1); exit(1);
} }
if (me->real_name && strlen(me->real_name) >= XT_EXTENSION_MAXNAMELEN) {
fprintf(stderr, "%s: match `%s' has invalid real name\n",
xt_params->program_name, me->real_name);
exit(1);
}
if (me->family >= NPROTO) { if (me->family >= NPROTO) {
fprintf(stderr, fprintf(stderr,
"%s: BUG: match %s has invalid protocol family\n", "%s: BUG: match %s has invalid protocol family\n",
...@@ -1108,6 +1113,12 @@ void xtables_register_target(struct xtables_target *me) ...@@ -1108,6 +1113,12 @@ void xtables_register_target(struct xtables_target *me)
exit(1); exit(1);
} }
if (me->real_name && strlen(me->real_name) >= XT_EXTENSION_MAXNAMELEN) {
fprintf(stderr, "%s: target `%s' has invalid real name\n",
xt_params->program_name, me->real_name);
exit(1);
}
if (me->family >= NPROTO) { if (me->family >= NPROTO) {
fprintf(stderr, fprintf(stderr,
"%s: BUG: target %s has invalid protocol family\n", "%s: BUG: target %s has invalid protocol family\n",
......
...@@ -91,8 +91,10 @@ xtables_options_xfrm(struct option *orig_opts, struct option *oldopts, ...@@ -91,8 +91,10 @@ xtables_options_xfrm(struct option *orig_opts, struct option *oldopts,
* Since @oldopts also has @orig_opts already (and does so at the * Since @oldopts also has @orig_opts already (and does so at the
* start), skip these entries. * start), skip these entries.
*/ */
oldopts += num_orig; if (oldopts != NULL) {
num_old -= num_orig; oldopts += num_orig;
num_old -= num_orig;
}
merge = malloc(sizeof(*mp) * (num_orig + num_old + num_new + 1)); merge = malloc(sizeof(*mp) * (num_orig + num_old + num_new + 1));
if (merge == NULL) if (merge == NULL)
...@@ -114,8 +116,10 @@ xtables_options_xfrm(struct option *orig_opts, struct option *oldopts, ...@@ -114,8 +116,10 @@ xtables_options_xfrm(struct option *orig_opts, struct option *oldopts,
} }
/* Third, the old options */ /* Third, the old options */
memcpy(mp, oldopts, sizeof(*mp) * num_old); if (oldopts != NULL) {
mp += num_old; memcpy(mp, oldopts, sizeof(*mp) * num_old);
mp += num_old;
}
xtables_free_opts(0); xtables_free_opts(0);
/* Clear trailing entry */ /* Clear trailing entry */
...@@ -282,7 +286,7 @@ static void xtopt_mint_value_to_ptr(struct xt_option_call *cb, void **datap, ...@@ -282,7 +286,7 @@ static void xtopt_mint_value_to_ptr(struct xt_option_call *cb, void **datap,
static void xtopt_parse_mint(struct xt_option_call *cb) static void xtopt_parse_mint(struct xt_option_call *cb)
{ {
const struct xt_option_entry *entry = cb->entry; const struct xt_option_entry *entry = cb->entry;
const char *arg = cb->arg; const char *arg;
size_t esize = xtopt_esize_by_type(entry->type); size_t esize = xtopt_esize_by_type(entry->type);
const uintmax_t lmax = xtopt_max_by_type(entry->type); const uintmax_t lmax = xtopt_max_by_type(entry->type);
void *put = XTOPT_MKPTR(cb); void *put = XTOPT_MKPTR(cb);
...@@ -844,7 +848,7 @@ void xtables_option_parse(struct xt_option_call *cb) ...@@ -844,7 +848,7 @@ void xtables_option_parse(struct xt_option_call *cb)
* a *RC option type. * a *RC option type.
*/ */
cb->nvals = 1; cb->nvals = 1;
if (entry->type <= ARRAY_SIZE(xtopt_subparse) && if (entry->type < ARRAY_SIZE(xtopt_subparse) &&
xtopt_subparse[entry->type] != NULL) xtopt_subparse[entry->type] != NULL)
xtopt_subparse[entry->type](cb); xtopt_subparse[entry->type](cb);
/* Exclusion with other flags tested later in finalize. */ /* Exclusion with other flags tested later in finalize. */
......
...@@ -141,7 +141,7 @@ static char *xt_osf_strchr(char *ptr, char c) ...@@ -141,7 +141,7 @@ static char *xt_osf_strchr(char *ptr, char c)
if (tmp) if (tmp)
*tmp = '\0'; *tmp = '\0';
while (tmp && tmp + 1 && isspace(*(tmp + 1))) while (tmp && isspace(*(tmp + 1)))
tmp++; tmp++;
return tmp; return tmp;
...@@ -157,7 +157,6 @@ static void xt_osf_parse_opt(struct xt_osf_opt *opt, __u16 *optnum, char *obuf, ...@@ -157,7 +157,6 @@ static void xt_osf_parse_opt(struct xt_osf_opt *opt, __u16 *optnum, char *obuf,
i = 0; i = 0;
while (ptr != NULL && i < olen && *ptr != 0) { while (ptr != NULL && i < olen && *ptr != 0) {
val = 0; val = 0;
op = 0;
wc = OSF_WSS_PLAIN; wc = OSF_WSS_PLAIN;
switch (obuf[i]) { switch (obuf[i]) {
case 'N': case 'N':
...@@ -344,7 +343,7 @@ static int osf_load_line(char *buffer, int len, int del) ...@@ -344,7 +343,7 @@ static int osf_load_line(char *buffer, int len, int del)
pend = xt_osf_strchr(pbeg, OSFPDEL); pend = xt_osf_strchr(pbeg, OSFPDEL);
if (pend) { if (pend) {
*pend = '\0'; *pend = '\0';
cnt = snprintf(obuf, sizeof(obuf), "%s,", pbeg); snprintf(obuf, sizeof(obuf), "%s,", pbeg);
pbeg = pend + 1; pbeg = pend + 1;
} }
...@@ -352,25 +351,23 @@ static int osf_load_line(char *buffer, int len, int del) ...@@ -352,25 +351,23 @@ static int osf_load_line(char *buffer, int len, int del)
if (pend) { if (pend) {
*pend = '\0'; *pend = '\0';
if (pbeg[0] == '@' || pbeg[0] == '*') if (pbeg[0] == '@' || pbeg[0] == '*')
cnt = snprintf(f.genre, sizeof(f.genre), "%s", pbeg + 1); snprintf(f.genre, sizeof(f.genre), "%s", pbeg + 1);
else else
cnt = snprintf(f.genre, sizeof(f.genre), "%s", pbeg); snprintf(f.genre, sizeof(f.genre), "%s", pbeg);
pbeg = pend + 1; pbeg = pend + 1;
} }
pend = xt_osf_strchr(pbeg, OSFPDEL); pend = xt_osf_strchr(pbeg, OSFPDEL);
if (pend) { if (pend) {
*pend = '\0'; *pend = '\0';
cnt = snprintf(f.version, sizeof(f.version), "%s", pbeg); snprintf(f.version, sizeof(f.version), "%s", pbeg);
pbeg = pend + 1; pbeg = pend + 1;
} }
pend = xt_osf_strchr(pbeg, OSFPDEL); pend = xt_osf_strchr(pbeg, OSFPDEL);
if (pend) { if (pend) {
*pend = '\0'; *pend = '\0';
cnt = snprintf(f.subtype, sizeof(f.subtype), "%s", pbeg);
snprintf(f.subtype, sizeof(f.subtype), "%s", pbeg);
pbeg = pend + 1;
} }
xt_osf_parse_opt(f.opt, &f.opt_num, obuf, sizeof(obuf)); xt_osf_parse_opt(f.opt, &f.opt_num, obuf, sizeof(obuf));
...@@ -384,7 +381,7 @@ static int osf_load_line(char *buffer, int len, int del) ...@@ -384,7 +381,7 @@ static int osf_load_line(char *buffer, int len, int del)
nfnl_addattr_l(nmh, sizeof(buf), OSF_ATTR_FINGER, &f, sizeof(struct xt_osf_user_finger)); nfnl_addattr_l(nmh, sizeof(buf), OSF_ATTR_FINGER, &f, sizeof(struct xt_osf_user_finger));
return nfnl_talk(nfnlh, nmh, 0, 0, NULL, NULL, NULL); return nfnl_query(nfnlh, nmh);
} }
static int osf_load_entries(char *path, int del) static int osf_load_entries(char *path, int del)
......
...@@ -40,7 +40,7 @@ def run_test(name, payload): ...@@ -40,7 +40,7 @@ def run_test(name, payload):
for line in payload: for line in payload:
if line.startswith(keywords): if line.startswith(keywords):
tests += 1 tests += 1
process = Popen([ os.path.abspath(os.path.curdir) + "/iptables/xtables-compat-multi" ] + shlex.split(line), stdout=PIPE, stderr=PIPE) process = Popen([ os.path.abspath(os.path.curdir) + "/iptables/xtables-nft-multi" ] + shlex.split(line), stdout=PIPE, stderr=PIPE)
(output, error) = process.communicate() (output, error) = process.communicate()
if process.returncode == 0: if process.returncode == 0:
translation = output.decode("utf-8").rstrip(" \n") translation = output.decode("utf-8").rstrip(" \n")
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment