]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
xtables: Introduce and use common function to parse val[/mask] arguments
authorSerhey Popovych <serhe.popovych@gmail.com>
Thu, 1 Mar 2018 11:03:11 +0000 (13:03 +0200)
committerFlorian Westphal <fw@strlen.de>
Fri, 27 Apr 2018 16:56:20 +0000 (18:56 +0200)
There are a couple of places in both core and extensions where arguments
in the form of val[/mask] is parsed (see XTTYPE_MARKMASK32).

In some cases symbolic name might be used which is mapped in code to
numeric value.

Introduce common function to handle both cases where value given is
either val[/mask] or symbolic name.

Signed-off-by: Serhey Popovych <serhe.popovych@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
extensions/libipt_realm.c
extensions/libxt_devgroup.c
include/xtables.h
libxtables/xtables.c
libxtables/xtoptions.c

index 750091053a03c8b9a6ab9491edd11e309b697025..545b2580ac1b0218a04607f7da627c6d48be5c2b 100644 (file)
@@ -34,30 +34,17 @@ static struct xtables_lmap *realms;
 
 static void realm_parse(struct xt_option_call *cb)
 {
-       struct xt_realm_info *realminfo = cb->data;
-       int id;
-       char *end;
+       struct xt_realm_info *ri = cb->data;
+       unsigned int id, mask;
 
        xtables_option_parse(cb);
-       realminfo->id = strtoul(cb->arg, &end, 0);
-       if (end != cb->arg && (*end == '/' || *end == '\0')) {
-               if (*end == '/')
-                       realminfo->mask = strtoul(end+1, &end, 0);
-               else
-                       realminfo->mask = 0xffffffff;
-               if (*end != '\0' || end == cb->arg)
-                       xtables_error(PARAMETER_PROBLEM,
-                                  "Bad realm value \"%s\"", cb->arg);
-       } else {
-               id = xtables_lmap_name2id(realms, cb->arg);
-               if (id == -1)
-                       xtables_error(PARAMETER_PROBLEM,
-                                  "Realm \"%s\" not found", cb->arg);
-               realminfo->id = id;
-               realminfo->mask = 0xffffffff;
-       }
+       xtables_parse_val_mask(cb, &id, &mask, realms);
+
+       ri->id = id;
+       ri->mask = mask;
+
        if (cb->invert)
-               realminfo->invert = 1;
+               ri->invert = 1;
 }
 
 static void
index f1352c47ecc174ed44384c95b6973987dd5f5b57..99a4d50227012220456967b653f6e351484d860e 100644 (file)
@@ -35,49 +35,24 @@ static const char f_devgroups[] = "/etc/iproute2/group";
 /* array of devgroups from f_devgroups[] */
 static struct xtables_lmap *devgroups;
 
-static void devgroup_parse_groupspec(const char *arg, unsigned int *group,
-                                    unsigned int *mask)
-{
-       char *end;
-       bool ok;
-
-       ok = xtables_strtoui(arg, &end, group, 0, UINT32_MAX);
-       if (ok && (*end == '/' || *end == '\0')) {
-               if (*end == '/')
-                       ok = xtables_strtoui(end + 1, NULL, mask,
-                                            0, UINT32_MAX);
-               else
-                       *mask = ~0U;
-               if (!ok)
-                       xtables_error(PARAMETER_PROBLEM,
-                                     "Bad group value \"%s\"", arg);
-       } else {
-               *group = xtables_lmap_name2id(devgroups, arg);
-               if (*group == -1)
-                       xtables_error(PARAMETER_PROBLEM,
-                                     "Device group \"%s\" not found", arg);
-               *mask = ~0U;
-       }
-}
-
 static void devgroup_parse(struct xt_option_call *cb)
 {
        struct xt_devgroup_info *info = cb->data;
-       unsigned int id, mask;
+       unsigned int group, mask;
 
        xtables_option_parse(cb);
+       xtables_parse_val_mask(cb, &group, &mask, devgroups);
+
        switch (cb->entry->id) {
        case O_SRC_GROUP:
-               devgroup_parse_groupspec(cb->arg, &id, &mask);
-               info->src_group = id;
+               info->src_group = group;
                info->src_mask  = mask;
                info->flags |= XT_DEVGROUP_MATCH_SRC;
                if (cb->invert)
                        info->flags |= XT_DEVGROUP_INVERT_SRC;
                break;
        case O_DST_GROUP:
-               devgroup_parse_groupspec(cb->arg, &id, &mask);
-               info->dst_group = id;
+               info->dst_group = group;
                info->dst_mask  = mask;
                info->flags |= XT_DEVGROUP_MATCH_DST;
                if (cb->invert)
index e9bc3b7d44a6801ec728f41cbc526dc926c97c60..471294838128afadb0e47e7fef44458e5170def5 100644 (file)
@@ -537,6 +537,17 @@ extern void xtables_save_string(const char *value);
 
 extern void xtables_print_num(uint64_t number, unsigned int format);
 
+extern void xtables_parse_val_mask(struct xt_option_call *cb,
+                                  unsigned int *val, unsigned int *mask,
+                                  const struct xtables_lmap *lmap);
+
+static inline void xtables_parse_mark_mask(struct xt_option_call *cb,
+                                          unsigned int *mark,
+                                          unsigned int *mask)
+{
+       xtables_parse_val_mask(cb, mark, mask, NULL);
+}
+
 #if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
 #      ifdef _INIT
 #              undef _init
index 57a11022ab6c8c70a01791da39f6b54d27aa76d4..f93e88ddbf77f22f9788b14f8620a24f617e5f22 100644 (file)
@@ -1960,6 +1960,58 @@ void xtables_print_num(uint64_t number, unsigned int format)
        printf(FMT("%4lluT ","%lluT "), (unsigned long long)number);
 }
 
+void xtables_parse_val_mask(struct xt_option_call *cb,
+                           unsigned int *val, unsigned int *mask,
+                           const struct xtables_lmap *lmap)
+{
+       char *end;
+
+       *mask = ~0U;
+
+       if (!xtables_strtoui(cb->arg, &end, val, 0, UINT32_MAX)) {
+               if (lmap)
+                       goto name2val;
+               else
+                       goto bad_val;
+       }
+
+       if (*end == '\0')
+               return;
+
+       if (*end != '/') {
+               if (lmap)
+                       goto name2val;
+               else
+                       goto garbage;
+       }
+
+       if (!xtables_strtoui(end + 1, &end, mask, 0, UINT32_MAX))
+               goto bad_val;
+
+       if (*end == '\0')
+               return;
+
+garbage:
+       xt_params->exit_err(PARAMETER_PROBLEM,
+                       "%s: trailing garbage after value "
+                       "for option \"--%s\".\n",
+                       cb->ext_name, cb->entry->name);
+
+bad_val:
+       xt_params->exit_err(PARAMETER_PROBLEM,
+                       "%s: bad integer value for option \"--%s\", "
+                       "or out of range.\n",
+                       cb->ext_name, cb->entry->name);
+
+name2val:
+       *val = xtables_lmap_name2id(lmap, cb->arg);
+       if ((int)*val == -1)
+               xt_params->exit_err(PARAMETER_PROBLEM,
+                       "%s: could not map name %s to an integer value "
+                       "for option \"--%s\".\n",
+                       cb->ext_name, cb->arg, cb->entry->name);
+}
+
 int kernel_version;
 
 void get_kernel_version(void)
index d26d2f8b3d65d5d1aab0473d53850c75f27235fc..ba3128bdbeb6b48cff284a06f01a5833423c2a84 100644 (file)
@@ -428,27 +428,7 @@ static void xtopt_parse_tosmask(struct xt_option_call *cb)
  */
 static void xtopt_parse_markmask(struct xt_option_call *cb)
 {
-       unsigned int mark = 0, mask = ~0U;
-       char *end;
-
-       if (!xtables_strtoui(cb->arg, &end, &mark, 0, UINT32_MAX))
-               xt_params->exit_err(PARAMETER_PROBLEM,
-                       "%s: bad mark value for option \"--%s\", "
-                       "or out of range.\n",
-                       cb->ext_name, cb->entry->name);
-       if (*end == '/' &&
-           !xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
-               xt_params->exit_err(PARAMETER_PROBLEM,
-                       "%s: bad mask value for option \"--%s\", "
-                       "or out of range.\n",
-                       cb->ext_name, cb->entry->name);
-       if (*end != '\0')
-               xt_params->exit_err(PARAMETER_PROBLEM,
-                       "%s: trailing garbage after value "
-                       "for option \"--%s\".\n",
-                       cb->ext_name, cb->entry->name);
-       cb->val.mark = mark;
-       cb->val.mask = mask;
+       xtables_parse_mark_mask(cb, &cb->val.mark, &cb->val.mask);
 }
 
 static int xtopt_sysloglvl_compare(const void *a, const void *b)