From 62c3c93d4b0f5f6b9bb6c6829d507b57b976a644 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Thu, 23 Dec 2021 19:03:37 +0100 Subject: xshared: Move do_parse to shared space Small adjustments were needed: - Pass line variable via xt_cmd_parse, xshared.c does not have it in namespace. - Replace opts, prog_name and prog_vers defines by the respective xt_params field reference. Signed-off-by: Phil Sutter --- iptables/xtables.c | 556 +---------------------------------------------------- 1 file changed, 1 insertion(+), 555 deletions(-) (limited to 'iptables/xtables.c') diff --git a/iptables/xtables.c b/iptables/xtables.c index 59fc63d0..051d5c7b 100644 --- a/iptables/xtables.c +++ b/iptables/xtables.c @@ -95,10 +95,6 @@ struct xtables_globals xtables_globals = { .print_help = xtables_printhelp, }; -#define opts xt_params->opts -#define prog_name xt_params->program_name -#define prog_vers xt_params->program_version - /* * All functions starting with "parse" should succeed, otherwise * the program fails. @@ -145,557 +141,6 @@ list_rules(struct nft_handle *h, const char *chain, const char *table, return nft_cmd_rule_list_save(h, chain, table, rulenum, counters); } -static void check_empty_interface(struct xtables_args *args, const char *arg) -{ - const char *msg = "Empty interface is likely to be undesired"; - - if (*arg != '\0') - return; - - if (args->family != NFPROTO_ARP) - xtables_error(PARAMETER_PROBLEM, msg); - - fprintf(stderr, "%s", msg); -} - -static void check_inverse(struct xtables_args *args, const char option[], - bool *invert, int *optidx, int argc) -{ - switch (args->family) { - case NFPROTO_ARP: - break; - default: - return; - } - - if (!option || strcmp(option, "!")) - return; - - fprintf(stderr, "Using intrapositioned negation (`--option ! this`) " - "is deprecated in favor of extrapositioned (`! --option this`).\n"); - - if (*invert) - xtables_error(PARAMETER_PROBLEM, - "Multiple `!' flags not allowed"); - *invert = true; - if (optidx) { - *optidx = *optidx + 1; - if (argc && *optidx > argc) - xtables_error(PARAMETER_PROBLEM, - "no argument following `!'"); - } -} - -void do_parse(int argc, char *argv[], - struct xt_cmd_parse *p, struct iptables_command_state *cs, - struct xtables_args *args) -{ - struct xtables_match *m; - struct xtables_rule_match *matchp; - bool wait_interval_set = false; - struct timeval wait_interval; - struct xtables_target *t; - bool table_set = false; - bool invert = false; - int wait = 0; - - /* re-set optind to 0 in case do_command4 gets called - * a second time */ - optind = 0; - - /* clear mflags in case do_command4 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; - } - - /* Suppress error messages: we may add new options if we - demand-load a protocol. */ - opterr = 0; - - opts = xt_params->orig_opts; - while ((cs->c = getopt_long(argc, argv, xt_params->optstring, - opts, NULL)) != -1) { - switch (cs->c) { - /* - * Command selection - */ - case 'A': - add_command(&p->command, CMD_APPEND, CMD_NONE, invert); - p->chain = optarg; - break; - - case 'C': - add_command(&p->command, CMD_CHECK, CMD_NONE, invert); - p->chain = optarg; - break; - - case 'D': - add_command(&p->command, CMD_DELETE, CMD_NONE, invert); - p->chain = optarg; - if (xs_has_arg(argc, argv)) { - p->rulenum = parse_rulenumber(argv[optind++]); - p->command = CMD_DELETE_NUM; - } - break; - - case 'R': - add_command(&p->command, CMD_REPLACE, CMD_NONE, invert); - p->chain = optarg; - if (xs_has_arg(argc, argv)) - p->rulenum = parse_rulenumber(argv[optind++]); - else - xtables_error(PARAMETER_PROBLEM, - "-%c requires a rule number", - cmd2char(CMD_REPLACE)); - break; - - case 'I': - add_command(&p->command, CMD_INSERT, CMD_NONE, invert); - p->chain = optarg; - if (xs_has_arg(argc, argv)) - p->rulenum = parse_rulenumber(argv[optind++]); - else - p->rulenum = 1; - break; - - case 'L': - add_command(&p->command, CMD_LIST, - CMD_ZERO | CMD_ZERO_NUM, invert); - if (optarg) - p->chain = optarg; - else if (xs_has_arg(argc, argv)) - p->chain = argv[optind++]; - if (xs_has_arg(argc, argv)) - p->rulenum = parse_rulenumber(argv[optind++]); - break; - - case 'S': - add_command(&p->command, CMD_LIST_RULES, - CMD_ZERO|CMD_ZERO_NUM, invert); - if (optarg) - p->chain = optarg; - else if (xs_has_arg(argc, argv)) - p->chain = argv[optind++]; - if (xs_has_arg(argc, argv)) - p->rulenum = parse_rulenumber(argv[optind++]); - break; - - case 'F': - add_command(&p->command, CMD_FLUSH, CMD_NONE, invert); - if (optarg) - p->chain = optarg; - else if (xs_has_arg(argc, argv)) - p->chain = argv[optind++]; - break; - - case 'Z': - add_command(&p->command, CMD_ZERO, - CMD_LIST|CMD_LIST_RULES, invert); - if (optarg) - p->chain = optarg; - else if (xs_has_arg(argc, argv)) - p->chain = argv[optind++]; - if (xs_has_arg(argc, argv)) { - p->rulenum = parse_rulenumber(argv[optind++]); - p->command = CMD_ZERO_NUM; - } - break; - - case 'N': - parse_chain(optarg); - add_command(&p->command, CMD_NEW_CHAIN, CMD_NONE, - invert); - p->chain = optarg; - break; - - case 'X': - add_command(&p->command, CMD_DELETE_CHAIN, CMD_NONE, - invert); - if (optarg) - p->chain = optarg; - else if (xs_has_arg(argc, argv)) - p->chain = argv[optind++]; - break; - - case 'E': - add_command(&p->command, CMD_RENAME_CHAIN, CMD_NONE, - invert); - p->chain = optarg; - if (xs_has_arg(argc, argv)) - p->newname = argv[optind++]; - else - xtables_error(PARAMETER_PROBLEM, - "-%c requires old-chain-name and " - "new-chain-name", - cmd2char(CMD_RENAME_CHAIN)); - break; - - case 'P': - add_command(&p->command, CMD_SET_POLICY, CMD_NONE, - invert); - p->chain = optarg; - if (xs_has_arg(argc, argv)) - p->policy = argv[optind++]; - else - xtables_error(PARAMETER_PROBLEM, - "-%c requires a chain and a policy", - cmd2char(CMD_SET_POLICY)); - break; - - case 'h': - if (!optarg) - optarg = argv[optind]; - - /* iptables -p icmp -h */ - if (!cs->matches && cs->protocol) - xtables_find_match(cs->protocol, - XTF_TRY_LOAD, &cs->matches); - - xt_params->print_help(cs->matches); - p->command = CMD_NONE; - return; - - /* - * Option selection - */ - case 'p': - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_PROTOCOL, - &args->invflags, invert); - - /* Canonicalize into lower case */ - for (cs->protocol = argv[optind - 1]; - *cs->protocol; cs->protocol++) - *cs->protocol = tolower(*cs->protocol); - - cs->protocol = argv[optind - 1]; - args->proto = xtables_parse_protocol(cs->protocol); - - if (args->proto == 0 && - (args->invflags & XT_INV_PROTO)) - xtables_error(PARAMETER_PROBLEM, - "rule would never match protocol"); - - /* This needs to happen here to parse extensions */ - if (p->ops->proto_parse) - p->ops->proto_parse(cs, args); - break; - - case 's': - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_SOURCE, - &args->invflags, invert); - args->shostnetworkmask = argv[optind - 1]; - break; - - case 'd': - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_DESTINATION, - &args->invflags, invert); - args->dhostnetworkmask = argv[optind - 1]; - break; - -#ifdef IPT_F_GOTO - case 'g': - set_option(&cs->options, OPT_JUMP, &args->invflags, - invert); - args->goto_set = true; - cs->jumpto = xt_parse_target(optarg); - break; -#endif - - case 2:/* src-mac */ - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_S_MAC, &args->invflags, - invert); - args->src_mac = argv[optind - 1]; - break; - - case 3:/* dst-mac */ - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_D_MAC, &args->invflags, - invert); - args->dst_mac = argv[optind - 1]; - break; - - case 'l':/* hardware length */ - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_H_LENGTH, &args->invflags, - invert); - args->arp_hlen = argv[optind - 1]; - break; - - case 8: /* was never supported, not even in arptables-legacy */ - xtables_error(PARAMETER_PROBLEM, "not supported"); - case 4:/* opcode */ - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_OPCODE, &args->invflags, - invert); - args->arp_opcode = argv[optind - 1]; - break; - - case 5:/* h-type */ - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_H_TYPE, &args->invflags, - invert); - args->arp_htype = argv[optind - 1]; - break; - - case 6:/* proto-type */ - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_P_TYPE, &args->invflags, - invert); - args->arp_ptype = argv[optind - 1]; - break; - - case 'j': - set_option(&cs->options, OPT_JUMP, &args->invflags, - invert); - command_jump(cs, argv[optind - 1]); - break; - - case 'i': - check_empty_interface(args, optarg); - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_VIANAMEIN, - &args->invflags, invert); - xtables_parse_interface(argv[optind - 1], - args->iniface, - args->iniface_mask); - break; - - case 'o': - check_empty_interface(args, optarg); - check_inverse(args, optarg, &invert, &optind, argc); - set_option(&cs->options, OPT_VIANAMEOUT, - &args->invflags, invert); - xtables_parse_interface(argv[optind - 1], - args->outiface, - args->outiface_mask); - break; - - case 'f': - if (args->family == AF_INET6) { - xtables_error(PARAMETER_PROBLEM, - "`-f' is not supported in IPv6, " - "use -m frag instead"); - } - set_option(&cs->options, OPT_FRAGMENT, &args->invflags, - invert); - args->flags |= IPT_F_FRAG; - break; - - case 'v': - if (!p->verbose) - set_option(&cs->options, OPT_VERBOSE, - &args->invflags, invert); - p->verbose++; - break; - - case 'm': - command_match(cs, invert); - break; - - case 'n': - set_option(&cs->options, OPT_NUMERIC, &args->invflags, - invert); - break; - - case 't': - if (invert) - xtables_error(PARAMETER_PROBLEM, - "unexpected ! flag before --table"); - if (p->restore && table_set) - xtables_error(PARAMETER_PROBLEM, - "The -t option cannot be used in %s.\n", - xt_params->program_name); - p->table = optarg; - table_set = true; - break; - - case 'x': - set_option(&cs->options, OPT_EXPANDED, &args->invflags, - invert); - break; - - case 'V': - if (invert) - printf("Not %s ;-)\n", prog_vers); - else - printf("%s v%s\n", - prog_name, prog_vers); - exit(0); - - case 'w': - if (p->restore) { - xtables_error(PARAMETER_PROBLEM, - "You cannot use `-w' from " - "iptables-restore"); - } - - wait = parse_wait_time(argc, argv); - break; - - case 'W': - if (p->restore) { - xtables_error(PARAMETER_PROBLEM, - "You cannot use `-W' from " - "iptables-restore"); - } - - parse_wait_interval(argc, argv, &wait_interval); - wait_interval_set = true; - break; - - case '0': - set_option(&cs->options, OPT_LINENUMBERS, - &args->invflags, invert); - break; - - case 'M': - xtables_modprobe_program = optarg; - break; - - case 'c': - set_option(&cs->options, OPT_COUNTERS, &args->invflags, - invert); - args->pcnt = optarg; - args->bcnt = strchr(args->pcnt + 1, ','); - if (args->bcnt) - args->bcnt++; - if (!args->bcnt && xs_has_arg(argc, argv)) - args->bcnt = argv[optind++]; - if (!args->bcnt) - xtables_error(PARAMETER_PROBLEM, - "-%c requires packet and byte counter", - opt2char(OPT_COUNTERS)); - - if (sscanf(args->pcnt, "%llu", &args->pcnt_cnt) != 1) - xtables_error(PARAMETER_PROBLEM, - "-%c packet counter not numeric", - opt2char(OPT_COUNTERS)); - - if (sscanf(args->bcnt, "%llu", &args->bcnt_cnt) != 1) - xtables_error(PARAMETER_PROBLEM, - "-%c byte counter not numeric", - opt2char(OPT_COUNTERS)); - break; - - case '4': - if (args->family == AF_INET) - break; - - if (p->restore && args->family == AF_INET6) - return; - - exit_tryhelp(2, line); - - case '6': - if (args->family == AF_INET6) - break; - - if (p->restore && args->family == AF_INET) - return; - - exit_tryhelp(2, line); - - case 1: /* non option */ - if (optarg[0] == '!' && optarg[1] == '\0') { - if (invert) - xtables_error(PARAMETER_PROBLEM, - "multiple consecutive ! not" - " allowed"); - invert = true; - optarg[0] = '\0'; - continue; - } - fprintf(stderr, "Bad argument `%s'\n", optarg); - exit_tryhelp(2, line); - - default: - if (command_default(cs, xt_params, invert)) - /* cf. ip6tables.c */ - continue; - break; - } - invert = false; - } - - if (strcmp(p->table, "nat") == 0 && - ((p->policy != NULL && strcmp(p->policy, "DROP") == 0) || - (cs->jumpto != NULL && strcmp(cs->jumpto, "DROP") == 0))) - xtables_error(PARAMETER_PROBLEM, - "\nThe \"nat\" table is not intended for filtering, " - "the use of DROP is therefore inhibited.\n\n"); - - if (!wait && wait_interval_set) - xtables_error(PARAMETER_PROBLEM, - "--wait-interval only makes sense with --wait\n"); - - for (matchp = cs->matches; matchp; matchp = matchp->next) - xtables_option_mfcall(matchp->match); - if (cs->target != NULL) - xtables_option_tfcall(cs->target); - - /* Fix me: must put inverse options checking here --MN */ - - if (optind < argc) - xtables_error(PARAMETER_PROBLEM, - "unknown arguments found on commandline"); - if (!p->command) - xtables_error(PARAMETER_PROBLEM, "no command specified"); - if (invert) - xtables_error(PARAMETER_PROBLEM, - "nothing appropriate following !"); - - if (p->ops->post_parse) - p->ops->post_parse(p->command, cs, args); - - if (p->command == CMD_REPLACE && - (args->s.naddrs != 1 || args->d.naddrs != 1)) - xtables_error(PARAMETER_PROBLEM, "Replacement rule does not " - "specify a unique address"); - - generic_opt_check(p->command, cs->options); - - if (p->chain != NULL && strlen(p->chain) >= XT_EXTENSION_MAXNAMELEN) - xtables_error(PARAMETER_PROBLEM, - "chain name `%s' too long (must be under %u chars)", - p->chain, XT_EXTENSION_MAXNAMELEN); - - if (p->command == CMD_APPEND || - p->command == CMD_DELETE || - p->command == CMD_DELETE_NUM || - p->command == CMD_CHECK || - p->command == CMD_INSERT || - p->command == CMD_REPLACE) { - if (strcmp(p->chain, "PREROUTING") == 0 - || strcmp(p->chain, "INPUT") == 0) { - /* -o not valid with incoming packets. */ - if (cs->options & OPT_VIANAMEOUT) - xtables_error(PARAMETER_PROBLEM, - "Can't use -%c with %s\n", - opt2char(OPT_VIANAMEOUT), - p->chain); - } - - if (strcmp(p->chain, "POSTROUTING") == 0 - || strcmp(p->chain, "OUTPUT") == 0) { - /* -i not valid with outgoing packets */ - if (cs->options & OPT_VIANAMEIN) - xtables_error(PARAMETER_PROBLEM, - "Can't use -%c with %s\n", - opt2char(OPT_VIANAMEIN), - p->chain); - } - } -} - int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, bool restore) { @@ -703,6 +148,7 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, struct xt_cmd_parse p = { .table = *table, .restore = restore, + .line = line, .ops = &h->ops->cmd_parse, }; struct iptables_command_state cs = { -- cgit v1.2.3