aboutsummaryrefslogtreecommitdiff
path: root/iptables/ip6tables.c
diff options
context:
space:
mode:
Diffstat (limited to 'iptables/ip6tables.c')
-rw-r--r--iptables/ip6tables.c269
1 files changed, 119 insertions, 150 deletions
diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
index 4037acfb..1fb33f6d 100644
--- a/iptables/ip6tables.c
+++ b/iptables/ip6tables.c
@@ -52,21 +52,6 @@
#define FALSE 0
#endif
-#define FMT_NUMERIC 0x0001
-#define FMT_NOCOUNTS 0x0002
-#define FMT_KILOMEGAGIGA 0x0004
-#define FMT_OPTIONS 0x0008
-#define FMT_NOTABLE 0x0010
-#define FMT_NOTARGET 0x0020
-#define FMT_VIA 0x0040
-#define FMT_NONEWLINE 0x0080
-#define FMT_LINENUMBERS 0x0100
-
-#define FMT_PRINT_RULE (FMT_NOCOUNTS | FMT_OPTIONS | FMT_VIA \
- | FMT_NUMERIC | FMT_NOTABLE)
-#define FMT(tab,notab) ((format) & FMT_NOTABLE ? (notab) : (tab))
-
-
#define CMD_NONE 0x0000U
#define CMD_INSERT 0x0001U
#define CMD_DELETE 0x0002U
@@ -85,7 +70,7 @@
#define CMD_CHECK 0x4000U
#define NUMBER_OF_CMD 16
static const char cmdflags[] = { 'I', 'D', 'D', 'R', 'A', 'L', 'F', 'Z',
- 'Z', 'N', 'X', 'P', 'E', 'S', 'C' };
+ 'N', 'X', 'P', 'E', 'S', 'Z', 'C' };
#define NUMBER_OF_OPT ARRAY_SIZE(optflags)
static const char optflags[]
@@ -117,6 +102,7 @@ static struct option original_opts[] = {
{.name = "numeric", .has_arg = 0, .val = 'n'},
{.name = "out-interface", .has_arg = 1, .val = 'o'},
{.name = "verbose", .has_arg = 0, .val = 'v'},
+ {.name = "wait", .has_arg = 0, .val = 'w'},
{.name = "exact", .has_arg = 0, .val = 'x'},
{.name = "version", .has_arg = 0, .val = 'V'},
{.name = "help", .has_arg = 2, .val = 'h'},
@@ -172,7 +158,7 @@ static const unsigned int inverse_for_options[NUMBER_OF_OPT] =
/* -n */ 0,
/* -s */ IP6T_INV_SRCIP,
/* -d */ IP6T_INV_DSTIP,
-/* -p */ IP6T_INV_PROTO,
+/* -p */ XT_INV_PROTO,
/* -j */ 0,
/* -v */ 0,
/* -x */ 0,
@@ -252,7 +238,7 @@ exit_printhelp(const struct xtables_rule_match *matches)
"Options:\n"
" --ipv4 -4 Error (line is ignored by ip6tables-restore)\n"
" --ipv6 -6 Nothing (line is ignored by iptables-restore)\n"
-"[!] --proto -p proto protocol: by number or name, eg. `tcp'\n"
+"[!] --protocol -p proto protocol: by number or name, eg. `tcp'\n"
"[!] --source -s address[/mask][,...]\n"
" source specification\n"
"[!] --destination -d address[/mask][,...]\n"
@@ -272,6 +258,7 @@ exit_printhelp(const struct xtables_rule_match *matches)
" network interface name ([+] for wildcard)\n"
" --table -t table table to manipulate (default: `filter')\n"
" --verbose -v verbose mode\n"
+" --wait -w wait for the xtables lock\n"
" --line-numbers print line numbers when listing\n"
" --exact -x expand numbers (display exact values)\n"
/*"[!] --fragment -f match second or further fragments only\n"*/
@@ -442,45 +429,20 @@ set_option(unsigned int *options, unsigned int option, uint8_t *invflg,
}
}
-static void
-print_num(uint64_t number, unsigned int format)
-{
- if (format & FMT_KILOMEGAGIGA) {
- if (number > 99999) {
- number = (number + 500) / 1000;
- if (number > 9999) {
- number = (number + 500) / 1000;
- if (number > 9999) {
- number = (number + 500) / 1000;
- if (number > 9999) {
- number = (number + 500) / 1000;
- printf(FMT("%4lluT ","%lluT "), (unsigned long long)number);
- }
- else printf(FMT("%4lluG ","%lluG "), (unsigned long long)number);
- }
- else printf(FMT("%4lluM ","%lluM "), (unsigned long long)number);
- } else
- printf(FMT("%4lluK ","%lluK "), (unsigned long long)number);
- } else
- printf(FMT("%5llu ","%llu "), (unsigned long long)number);
- } else
- printf(FMT("%8llu ","%llu "), (unsigned long long)number);
-}
-
static void
-print_header(unsigned int format, const char *chain, struct ip6tc_handle *handle)
+print_header(unsigned int format, const char *chain, struct xtc_handle *handle)
{
- struct ip6t_counters counters;
+ struct xt_counters counters;
const char *pol = ip6tc_get_policy(chain, &counters, handle);
printf("Chain %s", chain);
if (pol) {
printf(" (policy %s", pol);
if (!(format & FMT_NOCOUNTS)) {
fputc(' ', stdout);
- print_num(counters.pcnt, (format|FMT_NOTABLE));
+ xtables_print_num(counters.pcnt, (format|FMT_NOTABLE));
fputs("packets, ", stdout);
- print_num(counters.bcnt, (format|FMT_NOTABLE));
+ xtables_print_num(counters.bcnt, (format|FMT_NOTABLE));
fputs("bytes", stdout);
}
printf(")\n");
@@ -519,7 +481,7 @@ print_header(unsigned int format, const char *chain, struct ip6tc_handle *handle
static int
-print_match(const struct ip6t_entry_match *m,
+print_match(const struct xt_entry_match *m,
const struct ip6t_ip6 *ip,
int numeric)
{
@@ -545,16 +507,16 @@ print_firewall(const struct ip6t_entry *fw,
const char *targname,
unsigned int num,
unsigned int format,
- struct ip6tc_handle *const handle)
+ struct xtc_handle *const handle)
{
const struct xtables_target *target = NULL;
- const struct ip6t_entry_target *t;
+ const struct xt_entry_target *t;
char buf[BUFSIZ];
if (!ip6tc_is_chain(targname, handle))
target = xtables_find_target(targname, XTF_TRY_LOAD);
else
- target = xtables_find_target(IP6T_STANDARD_TARGET,
+ target = xtables_find_target(XT_STANDARD_TARGET,
XTF_LOAD_MUST_SUCCEED);
t = ip6t_get_target((struct ip6t_entry *)fw);
@@ -563,14 +525,14 @@ print_firewall(const struct ip6t_entry *fw,
printf(FMT("%-4u ", "%u "), num);
if (!(format & FMT_NOCOUNTS)) {
- print_num(fw->counters.pcnt, format);
- print_num(fw->counters.bcnt, format);
+ xtables_print_num(fw->counters.pcnt, format);
+ xtables_print_num(fw->counters.bcnt, format);
}
if (!(format & FMT_NOTARGET))
printf(FMT("%-9s ", "%s "), targname);
- fputc(fw->ipv6.invflags & IP6T_INV_PROTO ? '!' : ' ', stdout);
+ fputc(fw->ipv6.invflags & XT_INV_PROTO ? '!' : ' ', stdout);
{
const char *pname = proto_to_name(fw->ipv6.proto, format&FMT_NUMERIC);
if (pname)
@@ -667,16 +629,16 @@ print_firewall(const struct ip6t_entry *fw,
static void
print_firewall_line(const struct ip6t_entry *fw,
- struct ip6tc_handle *const h)
+ struct xtc_handle *const h)
{
- struct ip6t_entry_target *t;
+ struct xt_entry_target *t;
t = ip6t_get_target((struct ip6t_entry *)fw);
print_firewall(fw, t->u.user.name, 0, FMT_PRINT_RULE, h);
}
static int
-append_entry(const ip6t_chainlabel chain,
+append_entry(const xt_chainlabel chain,
struct ip6t_entry *fw,
unsigned int nsaddrs,
const struct in6_addr saddrs[],
@@ -685,7 +647,7 @@ append_entry(const ip6t_chainlabel chain,
const struct in6_addr daddrs[],
const struct in6_addr dmasks[],
int verbose,
- struct ip6tc_handle *handle)
+ struct xtc_handle *handle)
{
unsigned int i, j;
int ret = 1;
@@ -706,13 +668,13 @@ append_entry(const ip6t_chainlabel chain,
}
static int
-replace_entry(const ip6t_chainlabel chain,
+replace_entry(const xt_chainlabel chain,
struct ip6t_entry *fw,
unsigned int rulenum,
const struct in6_addr *saddr, const struct in6_addr *smask,
const struct in6_addr *daddr, const struct in6_addr *dmask,
int verbose,
- struct ip6tc_handle *handle)
+ struct xtc_handle *handle)
{
fw->ipv6.src = *saddr;
fw->ipv6.dst = *daddr;
@@ -725,7 +687,7 @@ replace_entry(const ip6t_chainlabel chain,
}
static int
-insert_entry(const ip6t_chainlabel chain,
+insert_entry(const xt_chainlabel chain,
struct ip6t_entry *fw,
unsigned int rulenum,
unsigned int nsaddrs,
@@ -735,7 +697,7 @@ insert_entry(const ip6t_chainlabel chain,
const struct in6_addr daddrs[],
const struct in6_addr dmasks[],
int verbose,
- struct ip6tc_handle *handle)
+ struct xtc_handle *handle)
{
unsigned int i, j;
int ret = 1;
@@ -766,10 +728,10 @@ make_delete_mask(const struct xtables_rule_match *matches,
size = sizeof(struct ip6t_entry);
for (matchp = matches; matchp; matchp = matchp->next)
- size += XT_ALIGN(sizeof(struct ip6t_entry_match)) + matchp->match->size;
+ size += XT_ALIGN(sizeof(struct xt_entry_match)) + matchp->match->size;
mask = xtables_calloc(1, size
- + XT_ALIGN(sizeof(struct ip6t_entry_target))
+ + XT_ALIGN(sizeof(struct xt_entry_target))
+ target->size);
memset(mask, 0xFF, sizeof(struct ip6t_entry));
@@ -777,20 +739,20 @@ make_delete_mask(const struct xtables_rule_match *matches,
for (matchp = matches; matchp; matchp = matchp->next) {
memset(mptr, 0xFF,
- XT_ALIGN(sizeof(struct ip6t_entry_match))
+ XT_ALIGN(sizeof(struct xt_entry_match))
+ matchp->match->userspacesize);
- mptr += XT_ALIGN(sizeof(struct ip6t_entry_match)) + matchp->match->size;
+ mptr += XT_ALIGN(sizeof(struct xt_entry_match)) + matchp->match->size;
}
memset(mptr, 0xFF,
- XT_ALIGN(sizeof(struct ip6t_entry_target))
+ XT_ALIGN(sizeof(struct xt_entry_target))
+ target->userspacesize);
return mask;
}
static int
-delete_entry(const ip6t_chainlabel chain,
+delete_entry(const xt_chainlabel chain,
struct ip6t_entry *fw,
unsigned int nsaddrs,
const struct in6_addr saddrs[],
@@ -799,7 +761,7 @@ delete_entry(const ip6t_chainlabel chain,
const struct in6_addr daddrs[],
const struct in6_addr dmasks[],
int verbose,
- struct ip6tc_handle *handle,
+ struct xtc_handle *handle,
struct xtables_rule_match *matches,
const struct xtables_target *target)
{
@@ -825,11 +787,11 @@ delete_entry(const ip6t_chainlabel chain,
}
static int
-check_entry(const ip6t_chainlabel chain, struct ip6t_entry *fw,
+check_entry(const xt_chainlabel chain, struct ip6t_entry *fw,
unsigned int nsaddrs, const struct in6_addr *saddrs,
const struct in6_addr *smasks, unsigned int ndaddrs,
const struct in6_addr *daddrs, const struct in6_addr *dmasks,
- bool verbose, struct ip6tc_handle *handle,
+ bool verbose, struct xtc_handle *handle,
struct xtables_rule_match *matches,
const struct xtables_target *target)
{
@@ -855,8 +817,8 @@ check_entry(const ip6t_chainlabel chain, struct ip6t_entry *fw,
}
int
-for_each_chain6(int (*fn)(const ip6t_chainlabel, int, struct ip6tc_handle *),
- int verbose, int builtinstoo, struct ip6tc_handle *handle)
+for_each_chain6(int (*fn)(const xt_chainlabel, int, struct xtc_handle *),
+ int verbose, int builtinstoo, struct xtc_handle *handle)
{
int ret = 1;
const char *chain;
@@ -869,21 +831,21 @@ for_each_chain6(int (*fn)(const ip6t_chainlabel, int, struct ip6tc_handle *),
chain = ip6tc_next_chain(handle);
}
- chains = xtables_malloc(sizeof(ip6t_chainlabel) * chaincount);
+ chains = xtables_malloc(sizeof(xt_chainlabel) * chaincount);
i = 0;
chain = ip6tc_first_chain(handle);
while (chain) {
- strcpy(chains + i*sizeof(ip6t_chainlabel), chain);
+ strcpy(chains + i*sizeof(xt_chainlabel), chain);
i++;
chain = ip6tc_next_chain(handle);
}
for (i = 0; i < chaincount; i++) {
if (!builtinstoo
- && ip6tc_builtin(chains + i*sizeof(ip6t_chainlabel),
+ && ip6tc_builtin(chains + i*sizeof(xt_chainlabel),
handle) == 1)
continue;
- ret &= fn(chains + i*sizeof(ip6t_chainlabel), verbose, handle);
+ ret &= fn(chains + i*sizeof(xt_chainlabel), verbose, handle);
}
free(chains);
@@ -891,8 +853,8 @@ for_each_chain6(int (*fn)(const ip6t_chainlabel, int, struct ip6tc_handle *),
}
int
-flush_entries6(const ip6t_chainlabel chain, int verbose,
- struct ip6tc_handle *handle)
+flush_entries6(const xt_chainlabel chain, int verbose,
+ struct xtc_handle *handle)
{
if (!chain)
return for_each_chain6(flush_entries6, verbose, 1, handle);
@@ -903,8 +865,8 @@ flush_entries6(const ip6t_chainlabel chain, int verbose,
}
static int
-zero_entries(const ip6t_chainlabel chain, int verbose,
- struct ip6tc_handle *handle)
+zero_entries(const xt_chainlabel chain, int verbose,
+ struct xtc_handle *handle)
{
if (!chain)
return for_each_chain6(zero_entries, verbose, 1, handle);
@@ -915,8 +877,8 @@ zero_entries(const ip6t_chainlabel chain, int verbose,
}
int
-delete_chain6(const ip6t_chainlabel chain, int verbose,
- struct ip6tc_handle *handle)
+delete_chain6(const xt_chainlabel chain, int verbose,
+ struct xtc_handle *handle)
{
if (!chain)
return for_each_chain6(delete_chain6, verbose, 0, handle);
@@ -927,8 +889,8 @@ delete_chain6(const ip6t_chainlabel chain, int verbose,
}
static int
-list_entries(const ip6t_chainlabel chain, int rulenum, int verbose, int numeric,
- int expanded, int linenumbers, struct ip6tc_handle *handle)
+list_entries(const xt_chainlabel chain, int rulenum, int verbose, int numeric,
+ int expanded, int linenumbers, struct xtc_handle *handle)
{
int found = 0;
unsigned int format;
@@ -1033,14 +995,15 @@ static void print_proto(uint16_t proto, int invert)
}
}
-static int print_match_save(const struct ip6t_entry_match *e,
+static int print_match_save(const struct xt_entry_match *e,
const struct ip6t_ip6 *ip)
{
const struct xtables_match *match =
xtables_find_match(e->u.user.name, XTF_TRY_LOAD, NULL);
if (match) {
- printf(" -m %s", e->u.user.name);
+ printf(" -m %s",
+ match->alias ? match->alias(e) : e->u.user.name);
/* some matches don't provide a save function */
if (match->save)
@@ -1061,7 +1024,7 @@ static void print_ip(const char *prefix, const struct in6_addr *ip,
const struct in6_addr *mask, int invert)
{
char buf[51];
- int l = ipv6_prefix_length(mask);
+ int l = xtables_ip6mask_to_cidr(mask);
if (l == 0 && !invert)
return;
@@ -1080,9 +1043,9 @@ static void print_ip(const char *prefix, const struct in6_addr *ip,
/* We want this to be readable, so only print out neccessary fields.
* Because that's the kind of world I want to live in. */
void print_rule6(const struct ip6t_entry *e,
- struct ip6tc_handle *h, const char *chain, int counters)
+ struct xtc_handle *h, const char *chain, int counters)
{
- const struct ip6t_entry_target *t;
+ const struct xt_entry_target *t;
const char *target_name;
/* print counters for iptables-save */
@@ -1105,7 +1068,7 @@ void print_rule6(const struct ip6t_entry *e,
print_iface('o', e->ipv6.outiface, e->ipv6.outiface_mask,
e->ipv6.invflags & IP6T_INV_VIA_OUT);
- print_proto(e->ipv6.proto, e->ipv6.invflags & IP6T_INV_PROTO);
+ print_proto(e->ipv6.proto, e->ipv6.invflags & XT_INV_PROTO);
#if 0
/* not definied in ipv6
@@ -1129,16 +1092,8 @@ void print_rule6(const struct ip6t_entry *e,
if (counters < 0)
printf(" -c %llu %llu", (unsigned long long)e->counters.pcnt, (unsigned long long)e->counters.bcnt);
- /* Print target name */
+ /* Print target name and targinfo part */
target_name = ip6tc_get_target(e, h);
- if (target_name && (*target_name != '\0'))
-#ifdef IP6T_F_GOTO
- printf(" -%c %s", e->ipv6.flags & IP6T_F_GOTO ? 'g' : 'j', target_name);
-#else
- printf(" -j %s", target_name);
-#endif
-
- /* Print targinfo part */
t = ip6t_get_target((struct ip6t_entry *)e);
if (t->u.user.name[0]) {
struct xtables_target *target =
@@ -1150,27 +1105,34 @@ void print_rule6(const struct ip6t_entry *e,
exit(1);
}
+ printf(" -j %s", target->alias ? target->alias(t) : target_name);
if (target->save)
target->save(&e->ipv6, t);
else {
- /* If the target size is greater than ip6t_entry_target
+ /* If the target size is greater than xt_entry_target
* there is something to be saved, we just don't know
* how to print it */
if (t->u.target_size !=
- sizeof(struct ip6t_entry_target)) {
+ sizeof(struct xt_entry_target)) {
fprintf(stderr, "Target `%s' is missing "
"save function\n",
t->u.user.name);
exit(1);
}
}
- }
+ } else if (target_name && (*target_name != '\0'))
+#ifdef IP6T_F_GOTO
+ printf(" -%c %s", e->ipv6.flags & IP6T_F_GOTO ? 'g' : 'j', target_name);
+#else
+ printf(" -j %s", target_name);
+#endif
+
printf("\n");
}
static int
-list_rules(const ip6t_chainlabel chain, int rulenum, int counters,
- struct ip6tc_handle *handle)
+list_rules(const xt_chainlabel chain, int rulenum, int counters,
+ struct xtc_handle *handle)
{
const char *this = NULL;
int found = 0;
@@ -1187,7 +1149,7 @@ list_rules(const ip6t_chainlabel chain, int rulenum, int counters,
continue;
if (ip6tc_builtin(this, handle)) {
- struct ip6t_counters count;
+ struct xt_counters count;
printf("-P %s %s", this, ip6tc_get_policy(this, &count, handle));
if (counters)
printf(" -c %llu %llu", (unsigned long long)count.pcnt, (unsigned long long)count.bcnt);
@@ -1224,7 +1186,7 @@ list_rules(const ip6t_chainlabel chain, int rulenum, int counters,
static struct ip6t_entry *
generate_entry(const struct ip6t_entry *fw,
struct xtables_rule_match *matches,
- struct ip6t_entry_target *target)
+ struct xt_entry_target *target)
{
unsigned int size;
struct xtables_rule_match *matchp;
@@ -1249,27 +1211,6 @@ generate_entry(const struct ip6t_entry *fw,
return e;
}
-static void clear_rule_matches(struct xtables_rule_match **matches)
-{
- struct xtables_rule_match *matchp, *tmp;
-
- for (matchp = *matches; matchp;) {
- tmp = matchp->next;
- if (matchp->match->m) {
- free(matchp->match->m);
- matchp->match->m = NULL;
- }
- if (matchp->match == matchp->match->next) {
- free(matchp->match);
- matchp->match = NULL;
- }
- free(matchp);
- matchp = tmp;
- }
-
- *matches = NULL;
-}
-
static void command_jump(struct iptables_command_state *cs)
{
size_t size;
@@ -1282,14 +1223,22 @@ static void command_jump(struct iptables_command_state *cs)
if (cs->target == NULL)
return;
- size = XT_ALIGN(sizeof(struct ip6t_entry_target)) + cs->target->size;
+ 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;
- strcpy(cs->target->t->u.user.name, cs->jumpto);
+ if (cs->target->real_name == NULL) {
+ strcpy(cs->target->t->u.user.name, cs->jumpto);
+ } else {
+ 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;
- if (cs->target->init != NULL)
- cs->target->init(cs->target->t);
+
+ xs_init_target(cs->target);
if (cs->target->x6_options != NULL)
opts = xtables_options_xfrm(ip6tables_globals.orig_opts, opts,
cs->target->x6_options,
@@ -1312,13 +1261,20 @@ static void command_match(struct iptables_command_state *cs)
"unexpected ! flag before --match");
m = xtables_find_match(optarg, XTF_LOAD_MUST_SUCCEED, &cs->matches);
- size = XT_ALIGN(sizeof(struct ip6t_entry_match)) + m->size;
+ size = XT_ALIGN(sizeof(struct xt_entry_match)) + m->size;
m->m = xtables_calloc(1, size);
m->m->u.match_size = size;
- strcpy(m->m->u.user.name, m->name);
+ 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;
- if (m->init != NULL)
- m->init(m->m);
+
+ xs_init_match(m);
if (m == m->next)
return;
/* Merge options for non-cloned matches */
@@ -1330,7 +1286,8 @@ static void command_match(struct iptables_command_state *cs)
m->extra_opts, &m->option_offset);
}
-int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **handle)
+int do_command6(int argc, char *argv[], char **table,
+ struct xtc_handle **handle, bool restore)
{
struct iptables_command_state cs;
struct ip6t_entry *e = NULL;
@@ -1339,6 +1296,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
struct in6_addr *smasks = NULL, *dmasks = NULL;
int verbose = 0;
+ bool wait = false;
const char *chain = NULL;
const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL;
const char *policy = NULL, *newname = NULL;
@@ -1374,7 +1332,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
opts = xt_params->orig_opts;
while ((cs.c = getopt_long(argc, argv,
- "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:bvnt:m:xc:g:46",
+ "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:bvwnt:m:xc:g:46",
opts, NULL)) != -1) {
switch (cs.c) {
/*
@@ -1538,7 +1496,6 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
* Option selection
*/
case 'p':
- xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
set_option(&cs.options, OPT_PROTOCOL, &cs.fw6.ipv6.invflags,
cs.invert);
@@ -1551,12 +1508,12 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
cs.fw6.ipv6.flags |= IP6T_F_PROTO;
if (cs.fw6.ipv6.proto == 0
- && (cs.fw6.ipv6.invflags & IP6T_INV_PROTO))
+ && (cs.fw6.ipv6.invflags & XT_INV_PROTO))
xtables_error(PARAMETER_PROBLEM,
"rule would never match protocol");
if (is_exthdr(cs.fw6.ipv6.proto)
- && (cs.fw6.ipv6.invflags & IP6T_INV_PROTO) == 0)
+ && (cs.fw6.ipv6.invflags & XT_INV_PROTO) == 0)
fprintf(stderr,
"Warning: never matched protocol: %s. "
"use extension match instead.\n",
@@ -1564,14 +1521,12 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
break;
case 's':
- xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
set_option(&cs.options, OPT_SOURCE, &cs.fw6.ipv6.invflags,
cs.invert);
shostnetworkmask = optarg;
break;
case 'd':
- xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
set_option(&cs.options, OPT_DESTINATION, &cs.fw6.ipv6.invflags,
cs.invert);
dhostnetworkmask = optarg;
@@ -1596,7 +1551,6 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
xtables_error(PARAMETER_PROBLEM,
"Empty interface is likely to be "
"undesired");
- xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
set_option(&cs.options, OPT_VIANAMEIN, &cs.fw6.ipv6.invflags,
cs.invert);
xtables_parse_interface(optarg,
@@ -1609,7 +1563,6 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
xtables_error(PARAMETER_PROBLEM,
"Empty interface is likely to be "
"undesired");
- xtables_check_inverse(optarg, &cs.invert, &optind, argc, argv);
set_option(&cs.options, OPT_VIANAMEOUT, &cs.fw6.ipv6.invflags,
cs.invert);
xtables_parse_interface(optarg,
@@ -1624,6 +1577,15 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
verbose++;
break;
+ case 'w':
+ if (restore) {
+ xtables_error(PARAMETER_PROBLEM,
+ "You cannot use `-w' from "
+ "ip6tables-restore");
+ }
+ wait = true;
+ break;
+
case 'm':
command_match(&cs);
break;
@@ -1775,6 +1737,14 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
"chain name `%s' too long (must be under %u chars)",
chain, XT_EXTENSION_MAXNAMELEN);
+ /* Attempt to acquire the xtables lock */
+ if (!restore && !xtables_lock(wait)) {
+ fprintf(stderr, "Another app is currently holding the xtables lock. "
+ "Perhaps you want to use the -w option?\n");
+ xtables_free_opts(1);
+ exit(RESOURCE_PROBLEM);
+ }
+
/* only allocate handle if we weren't called with a handle */
if (!*handle)
*handle = ip6tc_init(*table);
@@ -1831,16 +1801,15 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
|| ip6tc_is_chain(cs.jumpto, *handle))) {
size_t size;
- cs.target = xtables_find_target(IP6T_STANDARD_TARGET,
+ cs.target = xtables_find_target(XT_STANDARD_TARGET,
XTF_LOAD_MUST_SUCCEED);
- size = sizeof(struct ip6t_entry_target)
+ size = sizeof(struct xt_entry_target)
+ cs.target->size;
cs.target->t = xtables_calloc(1, size);
cs.target->t->u.target_size = size;
strcpy(cs.target->t->u.user.name, cs.jumpto);
- if (cs.target->init != NULL)
- cs.target->init(cs.target->t);
+ xs_init_target(cs.target);
}
if (!cs.target) {
@@ -1956,7 +1925,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand
if (verbose > 1)
dump_entries6(*handle);
- clear_rule_matches(&cs.matches);
+ xtables_rule_matches_free(&cs.matches);
if (e != NULL) {
free(e);