Implement support for "network" datatype and use it for masq_src / masq_dest
[project/firewall3.git] / options.c
index ff9a964..98ef9de 100644 (file)
--- a/options.c
+++ b/options.c
@@ -17,6 +17,7 @@
  */
 
 #include "options.h"
+#include "ubus.h"
 
 
 static bool
@@ -40,7 +41,7 @@ parse_enum(void *ptr, const char *val, const char **values, int min, int max)
 }
 
 
-const char *fw3_flag_names[FW3_DEFAULT_DROP_INVALID + 1] = {
+const char *fw3_flag_names[__FW3_FLAG_MAX] = {
        "filter",
        "nat",
        "mangle",
@@ -55,6 +56,10 @@ const char *fw3_flag_names[FW3_DEFAULT_DROP_INVALID + 1] = {
        "NOTRACK",
        "DNAT",
        "SNAT",
+
+       "ACCEPT",
+       "REJECT",
+       "DROP",
 };
 
 static const char *limit_units[] = {
@@ -93,6 +98,11 @@ static const char *include_types[] = {
        "restore",
 };
 
+static const char *reflection_sources[] = {
+       "internal",
+       "external",
+};
+
 
 bool
 fw3_parse_bool(void *ptr, const char *val)
@@ -128,8 +138,8 @@ fw3_parse_string(void *ptr, const char *val)
 bool
 fw3_parse_target(void *ptr, const char *val)
 {
-       return parse_enum(ptr, val, &fw3_flag_names[FW3_TARGET_ACCEPT],
-                         FW3_TARGET_ACCEPT, FW3_TARGET_SNAT);
+       return parse_enum(ptr, val, &fw3_flag_names[FW3_FLAG_ACCEPT],
+                         FW3_FLAG_ACCEPT, FW3_FLAG_SNAT);
 }
 
 bool
@@ -280,6 +290,38 @@ fw3_parse_address(void *ptr, const char *val)
 }
 
 bool
+fw3_parse_network(void *ptr, const char *val)
+{
+       struct fw3_device dev;
+       struct fw3_address *tmp, *addr = ptr;
+       struct list_head *list;
+
+       if (!fw3_parse_address(addr, val))
+       {
+               memset(&dev, 0, sizeof(dev));
+
+               if (!fw3_parse_device(&dev, val))
+                       return false;
+
+               list = fw3_ubus_address(dev.name);
+
+               if (list)
+               {
+                       list_for_each_entry(tmp, list, list)
+                       {
+                               *addr = *tmp;
+                               addr->invert = dev.invert;
+                               break;
+                       }
+
+                       fw3_ubus_address_free(list);
+               }
+       }
+
+       return true;
+}
+
+bool
 fw3_parse_mac(void *ptr, const char *val)
 {
        struct fw3_mac *addr = ptr;
@@ -636,7 +678,7 @@ fw3_parse_monthdays(void *ptr, const char *val)
        if (!(s = strdup(val)))
                return false;
 
-       for (p = strtok((char *)val, " \t"); p; p = strtok(NULL, " \t"))
+       for (p = strtok(s, " \t"); p; p = strtok(NULL, " \t"))
        {
                d = strtoul(p, &p, 10);
 
@@ -660,12 +702,19 @@ fw3_parse_include_type(void *ptr, const char *val)
                          FW3_INC_TYPE_SCRIPT, FW3_INC_TYPE_RESTORE);
 }
 
+bool
+fw3_parse_reflection_source(void *ptr, const char *val)
+{
+       return parse_enum(ptr, val, reflection_sources,
+                         FW3_REFLECTION_INTERNAL, FW3_REFLECTION_EXTERNAL);
+}
+
 
 void
 fw3_parse_options(void *s, const struct fw3_option *opts,
                   struct uci_section *section)
 {
-       char *p;
+       char *p, *v;
        bool known;
        struct uci_element *e, *l;
        struct uci_option *o;
@@ -720,9 +769,15 @@ fw3_parse_options(void *s, const struct fw3_option *opts,
                        }
                        else
                        {
-                               if (!o->v.string)
+                               v = o->v.string;
+
+                               if (!v)
                                        continue;
 
+                               /* protocol "tcpudp" compatibility hack */
+                               if (opt->parse == fw3_parse_protocol && !strcmp(v, "tcpudp"))
+                                       v = strdup("tcp udp");
+
                                if (!opt->elem_size)
                                {
                                        if (!opt->parse((char *)s + opt->offset, o->v.string))
@@ -730,9 +785,7 @@ fw3_parse_options(void *s, const struct fw3_option *opts,
                                }
                                else
                                {
-                                       for (p = strtok(o->v.string, " \t");
-                                            p != NULL;
-                                            p = strtok(NULL, " \t"))
+                                       for (p = strtok(v, " \t"); p != NULL; p = strtok(NULL, " \t"))
                                        {
                                                item = malloc(opt->elem_size);
 
@@ -752,6 +805,9 @@ fw3_parse_options(void *s, const struct fw3_option *opts,
                                                list_add_tail(item, dest);
                                        }
                                }
+
+                               if (v != o->v.string)
+                                       free(v);
                        }
 
                        known = true;