ipsec_types: Add utility function to parse mark_t from strings
authorTobias Brunner <tobias@strongswan.org>
Tue, 13 Aug 2013 13:15:45 +0000 (15:15 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 11 Oct 2013 13:32:44 +0000 (15:32 +0200)
src/libstrongswan/ipsec/ipsec_types.c
src/libstrongswan/ipsec/ipsec_types.h
src/libstrongswan/tests/test_utils.c
src/starter/confread.c

index e4e9273..4bbd918 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012-2013 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -36,3 +36,38 @@ ENUM(ipcomp_transform_names, IPCOMP_NONE, IPCOMP_LZJH,
        "IPCOMP_LZS",
        "IPCOMP_LZJH"
 );
+
+/*
+ * See header
+ */
+bool mark_from_string(const char *value, mark_t *mark)
+{
+       char *endptr;
+
+       if (!value)
+       {
+               return FALSE;
+       }
+       mark->value = strtoul(value, &endptr, 0);
+       if (*endptr)
+       {
+               if (*endptr != '/')
+               {
+                       DBG1(DBG_APP, "invalid mark value: %s", value);
+                       return FALSE;
+               }
+               mark->mask = strtoul(endptr+1, &endptr, 0);
+               if (*endptr)
+               {
+                       DBG1(DBG_LIB, "invalid mark mask: %s", endptr);
+                       return FALSE;
+               }
+       }
+       else
+       {
+               mark->mask = 0xffffffff;
+       }
+       /* apply the mask to ensure the value is in range */
+       mark->value &= mark->mask;
+       return TRUE;
+}
index 32e55bc..43f72cc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012-2013 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -169,4 +169,13 @@ struct mark_t {
  */
 #define MARK_REQID (0xFFFFFFFF)
 
+/**
+ * Try to parse a mark_t from the given string of the form <mark>[/<mask>].
+ *
+ * @param value                string to parse
+ * @param mark         mark to fill
+ * @return                     TRUE if parsing was successful
+ */
+bool mark_from_string(const char *value, mark_t *mark);
+
 #endif /** IPSEC_TYPES_H_ @}*/
index 6ab60a6..506b3a1 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <library.h>
 #include <utils/utils.h>
+#include <ipsec/ipsec_types.h>
 
 #include <time.h>
 
@@ -442,6 +443,50 @@ START_TEST(test_time_delta_printf_hook)
 }
 END_TEST
 
+/*******************************************************************************
+ * mark_from_string
+ */
+
+static struct {
+       char *s;
+       bool ok;
+       mark_t m;
+} mark_data[] = {
+       {NULL,                  FALSE, { 0 }},
+       {"",                    TRUE,  { 0, 0xffffffff }},
+       {"/",                   TRUE,  { 0, 0 }},
+       {"42",                  TRUE,  { 42, 0xffffffff }},
+       {"0x42",                TRUE,  { 0x42, 0xffffffff }},
+       {"x",                   FALSE, { 0 }},
+       {"42/",                 TRUE,  { 0, 0 }},
+       {"42/0",                TRUE,  { 0, 0 }},
+       {"42/x",                FALSE, { 0 }},
+       {"42/42",               TRUE,  { 42, 42 }},
+       {"42/0xff",             TRUE,  { 42, 0xff }},
+       {"0x42/0xff",   TRUE,  { 0x42, 0xff }},
+       {"/0xff",               TRUE,  { 0, 0xff }},
+       {"/x",                  FALSE, { 0 }},
+       {"x/x",                 FALSE, { 0 }},
+       {"0xffffffff/0x0000ffff",       TRUE, { 0x0000ffff, 0x0000ffff }},
+       {"0xffffffff/0xffffffff",       TRUE, { 0xffffffff, 0xffffffff }},
+};
+
+START_TEST(test_mark_from_string)
+{
+       mark_t mark;
+
+       if (mark_from_string(mark_data[_i].s, &mark))
+       {
+               ck_assert_int_eq(mark.value, mark_data[_i].m.value);
+               ck_assert_int_eq(mark.mask, mark_data[_i].m.mask);
+       }
+       else
+       {
+               ck_assert(!mark_data[_i].ok);
+       }
+}
+END_TEST
+
 Suite *utils_suite_create()
 {
        Suite *s;
@@ -496,5 +541,9 @@ Suite *utils_suite_create()
        tcase_add_loop_test(tc, test_time_delta_printf_hook, 0, countof(time_delta_data));
        suite_add_tcase(s, tc);
 
+       tc = tcase_create("mark_from_string");
+       tcase_add_loop_test(tc, test_mark_from_string, 0, countof(mark_data));
+       suite_add_tcase(s, tc);
+
        return s;
 }
index cec9399..19178a2 100644 (file)
@@ -375,47 +375,6 @@ static void handle_firewall(const char *label, starter_end_t *end,
        }
 }
 
-static bool handle_mark(char *value, mark_t *mark)
-{
-       char *sep, *endptr;
-
-       sep = strchr(value, '/');
-       if (sep)
-       {
-               *sep = '\0';
-               mark->mask = strtoul(sep+1, &endptr, 0);
-               if (*endptr != '\0')
-               {
-                       DBG1(DBG_APP, "# invalid mark mask: %s", sep+1);
-                       return FALSE;
-               }
-       }
-       else
-       {
-               mark->mask = 0xffffffff;
-       }
-       if (value == '\0')
-       {
-               mark->value = 0;
-       }
-       else
-       {
-               mark->value = strtoul(value, &endptr, 0);
-               if (*endptr != '\0')
-               {
-                       DBG1(DBG_APP, "# invalid mark value: %s", value);
-                       return FALSE;
-               }
-       }
-       if (sep)
-       {       /* restore the original text in case also= is used */
-               *sep = '/';
-       }
-       /* apply the mask to ensure the value is in range */
-       mark->value &= mark->mask;
-       return TRUE;
-}
-
 /*
  * parse a conn section
  */
@@ -522,7 +481,7 @@ static void load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg
                        KW_SA_OPTION_FLAG("yes", "no", SA_OPTION_COMPRESS)
                        break;
                case KW_MARK:
-                       if (!handle_mark(kw->value, &conn->mark_in))
+                       if (!mark_from_string(kw->value, &conn->mark_in))
                        {
                                cfg->err++;
                                break;
@@ -530,13 +489,13 @@ static void load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg
                        conn->mark_out = conn->mark_in;
                        break;
                case KW_MARK_IN:
-                       if (!handle_mark(kw->value, &conn->mark_in))
+                       if (!mark_from_string(kw->value, &conn->mark_in))
                        {
                                cfg->err++;
                        }
                        break;
                case KW_MARK_OUT:
-                       if (!handle_mark(kw->value, &conn->mark_out))
+                       if (!mark_from_string(kw->value, &conn->mark_out))
                        {
                                cfg->err++;
                        }