diff options
Diffstat (limited to 'iptables/ip6tables.c')
-rw-r--r-- | iptables/ip6tables.c | 269 |
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); |