summaryrefslogtreecommitdiffstats
path: root/iptables/xtables.c
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2021-12-23 19:03:37 +0100
committerPhil Sutter <phil@nwl.cc>2022-01-12 14:08:54 +0100
commit62c3c93d4b0f5f6b9bb6c6829d507b57b976a644 (patch)
treebf02227c4b05acfcbe49695633d87fb319f72628 /iptables/xtables.c
parent3039a52c3ecf96df4e3b815d242f788c189093e1 (diff)
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 <phil@nwl.cc>
Diffstat (limited to 'iptables/xtables.c')
-rw-r--r--iptables/xtables.c556
1 files changed, 1 insertions, 555 deletions
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 = {