]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
Combine parse_target() and command_jump() implementations
authorPhil Sutter <phil@nwl.cc>
Mon, 24 Sep 2018 17:25:24 +0000 (19:25 +0200)
committerFlorian Westphal <fw@strlen.de>
Tue, 25 Sep 2018 14:26:28 +0000 (16:26 +0200)
Merge these two functions from xtables, iptables, ip6tables and
arptables. Both functions were basically identical in the first three,
only the last one required a bit more attention.

To eliminate access to 'invflags' in variant-specific location, move the
call to set_option() into callers. This is actually consistent with
parsing of other options in them.

As with command_match(), use xt_params instead of the different
*_globals objects to refer to 'opts' and 'orig_opts'.

It was necessary to rename parse_target() as it otherwise clashes with a
static function of same name in libxt_SET.

In arptables, the maximum allowed target name is a bit larger, so
introduce xtables_globals.target_maxnamelen defining the value. It is
used in the shared xt_parse_target() implementation.

Implementation of command_jump() in arptables diverted from the others
for no obvious reason. The call to parse_target() was done outside of it
and a pointer to cs->arp was passed but not used inside.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Florian Westphal <fw@strlen.de>
include/xtables.h
iptables/ip6tables.c
iptables/iptables.c
iptables/xshared.c
iptables/xshared.h
iptables/xtables-arp.c
iptables/xtables.c

index bf169b08186f5eaacfc9d71d62315a355a7e95a4..fd9e6c33516bc10c9fa30cdf0d330896a675cdac 100644 (file)
@@ -424,6 +424,7 @@ struct xtables_globals
        struct option *opts;
        void (*exit_err)(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3)));
        int (*compat_rev)(const char *name, uint8_t rev, int opt);
+       size_t target_maxnamelen;
 };
 
 #define XT_GETOPT_TABLEEND {.name = NULL, .has_arg = false}
index 1137256a259ca3318a03738061402bb150bde069..7a9cd643f8e764985ab737c1e1fb26891e5b84be 100644 (file)
@@ -125,6 +125,7 @@ struct xtables_globals ip6tables_globals = {
        .orig_opts = original_opts,
        .exit_err = ip6tables_exit_error,
        .compat_rev = xtables_compatible_revision,
+       .target_maxnamelen = XT_EXTENSION_MAXNAMELEN,
 };
 
 /* Table of legal combinations of commands and options.  If any of the
@@ -420,27 +421,6 @@ parse_chain(const char *chainname)
                                   "Invalid chain name `%s'", chainname);
 }
 
-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
 set_option(unsigned int *options, unsigned int option, uint8_t *invflg,
           int invert)
@@ -1221,46 +1201,6 @@ generate_entry(const struct ip6t_entry *fw,
        return e;
 }
 
-static void command_jump(struct iptables_command_state *cs)
-{
-       size_t size;
-
-       set_option(&cs->options, OPT_JUMP, &cs->fw6.ipv6.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 {
-               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(ip6tables_globals.orig_opts, opts,
-                                           cs->target->x6_options,
-                                           &cs->target->option_offset);
-       else
-               opts = xtables_merge_options(ip6tables_globals.orig_opts, opts,
-                                            cs->target->extra_opts,
-                                            &cs->target->option_offset);
-       if (opts == NULL)
-               xtables_error(OTHER_PROBLEM, "can't alloc memory!");
-}
-
 int do_command6(int argc, char *argv[], char **table,
                struct xtc_handle **handle, bool restore)
 {
@@ -1495,11 +1435,13 @@ int do_command6(int argc, char *argv[], char **table,
                        set_option(&cs.options, OPT_JUMP, &cs.fw6.ipv6.invflags,
                                        cs.invert);
                        cs.fw6.ipv6.flags |= IP6T_F_GOTO;
-                       cs.jumpto = parse_target(optarg);
+                       cs.jumpto = xt_parse_target(optarg);
                        break;
 #endif
 
                case 'j':
+                       set_option(&cs.options, OPT_JUMP, &cs.fw6.ipv6.invflags,
+                                       cs.invert);
                        command_jump(&cs);
                        break;
 
index 70ba67c9a9701f9d6a97261f37982753bb25b512..b9ce64e6b32a65837cf84ce53cc8b430ea4fc0e2 100644 (file)
@@ -124,6 +124,7 @@ struct xtables_globals iptables_globals = {
        .orig_opts = original_opts,
        .exit_err = iptables_exit_error,
        .compat_rev = xtables_compatible_revision,
+       .target_maxnamelen = XT_EXTENSION_MAXNAMELEN,
 };
 
 /* Table of legal combinations of commands and options.  If any of the
@@ -405,27 +406,6 @@ parse_chain(const char *chainname)
                                   "Invalid chain name `%s'", chainname);
 }
 
-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
 set_option(unsigned int *options, unsigned int option, uint8_t *invflg,
           int invert)
@@ -1211,49 +1191,6 @@ generate_entry(const struct ipt_entry *fw,
        return e;
 }
 
-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(iptables_globals.orig_opts, opts,
-                                           cs->target->x6_options,
-                                           &cs->target->option_offset);
-       else
-               opts = xtables_merge_options(iptables_globals.orig_opts, opts,
-                                            cs->target->extra_opts,
-                                            &cs->target->option_offset);
-       if (opts == NULL)
-               xtables_error(OTHER_PROBLEM, "can't alloc memory!");
-}
-
 int do_command4(int argc, char *argv[], char **table,
                struct xtc_handle **handle, bool restore)
 {
@@ -1478,11 +1415,13 @@ int do_command4(int argc, char *argv[], char **table,
                        set_option(&cs.options, OPT_JUMP, &cs.fw.ip.invflags,
                                   cs.invert);
                        cs.fw.ip.flags |= IPT_F_GOTO;
-                       cs.jumpto = parse_target(optarg);
+                       cs.jumpto = xt_parse_target(optarg);
                        break;
 #endif
 
                case 'j':
+                       set_option(&cs.options, OPT_JUMP, &cs.fw.ip.invflags,
+                                  cs.invert);
                        command_jump(&cs);
                        break;
 
index 860373cb2db84eaa8dc5db6dee6ca3445e8d17d9..d5365d9398e902738fe8820ead32875f93769d22 100644 (file)
@@ -1,4 +1,5 @@
 #include <config.h>
+#include <ctype.h>
 #include <getopt.h>
 #include <errno.h>
 #include <libgen.h>
@@ -631,3 +632,65 @@ void command_match(struct iptables_command_state *cs)
                xtables_error(OTHER_PROBLEM, "can't alloc memory!");
        xt_params->opts = opts;
 }
+
+const char *xt_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_params->target_maxnamelen)
+               xtables_error(PARAMETER_PROBLEM,
+                          "Invalid target name `%s' (%zu chars max)",
+                          targetname, xt_params->target_maxnamelen - 1);
+
+       for (ptr = targetname; *ptr; ptr++)
+               if (isspace(*ptr))
+                       xtables_error(PARAMETER_PROBLEM,
+                                  "Invalid target name `%s'", targetname);
+       return targetname;
+}
+
+void command_jump(struct iptables_command_state *cs)
+{
+       struct option *opts = xt_params->opts;
+       size_t size;
+
+       cs->jumpto = xt_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(xt_params->orig_opts, opts,
+                                           cs->target->x6_options,
+                                           &cs->target->option_offset);
+       else
+               opts = xtables_merge_options(xt_params->orig_opts, opts,
+                                            cs->target->extra_opts,
+                                            &cs->target->option_offset);
+       if (opts == NULL)
+               xtables_error(OTHER_PROBLEM, "can't alloc memory!");
+       xt_params->opts = opts;
+}
index 9039a24ba75e60e7817ff836c8fe1ff7adeccd0e..db499f29236ed475a552a2871a1656e4846fb894 100644 (file)
@@ -175,5 +175,7 @@ void print_ifaces(const char *iniface, const char *outiface, uint8_t invflags,
                  unsigned int format);
 
 void command_match(struct iptables_command_state *cs);
+const char *xt_parse_target(const char *targetname);
+void command_jump(struct iptables_command_state *cs);
 
 #endif /* IPTABLES_XSHARED_H */
index a457ea30ad68535c3fd12c6dd3281b7f5e438baf..4a782148d0f6a29707126b0d1b9e2f8999eec776 100644 (file)
@@ -158,6 +158,7 @@ struct xtables_globals arptables_globals = {
        .orig_opts              = original_opts,
        .exit_err               = xtables_exit_error,
        .compat_rev             = nft_compatible_revision,
+       .target_maxnamelen      = sizeof(arpt_chainlabel),
 };
 
 /* Table of legal combinations of commands and options.  If any of the
@@ -755,27 +756,6 @@ parse_rulenumber(const char *rule)
        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)+1 > sizeof(arpt_chainlabel))
-               xtables_error(PARAMETER_PROBLEM,
-                             "Invalid target name `%s' (%zu chars max)",
-                             targetname, sizeof(arpt_chainlabel)-1);
-
-       for (ptr = targetname; *ptr; ptr++)
-               if (isspace(*ptr))
-                       xtables_error(PARAMETER_PROBLEM,
-                                     "Invalid target name `%s'", targetname);
-       return targetname;
-}
-
 static void
 set_option(unsigned int *options, unsigned int option, u_int16_t *invflg,
           int invert)
@@ -822,41 +802,6 @@ list_entries(struct nft_handle *h, const char *chain, const char *table,
        return nft_rule_list(h, chain, table, rulenum, format);
 }
 
-static struct xtables_target *command_jump(struct arpt_entry *fw,
-                                          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;
-       strncpy(target->t->u.user.name, jumpto, sizeof(target->t->u.user.name) - 1);
-       target->t->u.user.name[sizeof(target->t->u.user.name)-1] = '\0';
-       target->t->u.user.revision = target->revision;
-
-       xs_init_target(target);
-
-       if (target->x6_options != NULL)
-               opts = xtables_options_xfrm(arptables_globals.orig_opts,
-                                           opts, target->x6_options,
-                                           &target->option_offset);
-       else
-               opts = xtables_merge_options(arptables_globals.orig_opts,
-                                            opts, target->extra_opts,
-                                            &target->option_offset);
-
-       return target;
-}
-
 static int
 append_entry(struct nft_handle *h,
             const char *chain,
@@ -1216,8 +1161,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
                case 'j':
                        set_option(&options, OPT_JUMP, &cs.arp.arp.invflags,
                                   invert);
-                       cs.jumpto = parse_target(optarg);
-                       cs.target = command_jump(&cs.arp, cs.jumpto);
+                       command_jump(&cs);
                        break;
 
                case 'i':
index 423be37f51fbc1422bb24ac74fac8570c48e0a66..c17e66f1a805f18e9f2c91034f62e81671a36aad 100644 (file)
@@ -108,6 +108,7 @@ struct xtables_globals xtables_globals = {
        .orig_opts = original_opts,
        .exit_err = xtables_exit_error,
        .compat_rev = nft_compatible_revision,
+       .target_maxnamelen = XT_EXTENSION_MAXNAMELEN,
 };
 
 /* Table of legal combinations of commands and options.  If any of the
@@ -363,27 +364,6 @@ parse_rulenumber(const char *rule)
        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
 set_option(unsigned int *options, unsigned int option, uint8_t *invflg,
           int invert)
@@ -602,48 +582,6 @@ list_rules(struct nft_handle *h, const char *chain, const char *table,
        return nft_rule_list_save(h, chain, table, rulenum, counters);
 }
 
-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!");
-}
-
 void do_parse(struct nft_handle *h, int argc, char *argv[],
              struct nft_xt_cmd_parse *p, struct iptables_command_state *cs,
              struct xtables_args *args)
@@ -876,11 +814,13 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
                        set_option(&cs->options, OPT_JUMP, &args->invflags,
                                   cs->invert);
                        args->goto_set = true;
-                       cs->jumpto = parse_target(optarg);
+                       cs->jumpto = xt_parse_target(optarg);
                        break;
 #endif
 
                case 'j':
+                       set_option(&cs->options, OPT_JUMP, &cs->fw.ip.invflags,
+                                  cs->invert);
                        command_jump(cs);
                        break;