Use libiptc to clear current ruleset
[project/firewall3.git] / options.c
index 1f561d3..3d30c57 100644 (file)
--- a/options.c
+++ b/options.c
@@ -91,13 +91,15 @@ static const char *limit_units[] = {
        "day",
 };
 
-static const char *ipset_methods[] = {
+const char *fw3_ipset_method_names[__FW3_IPSET_METHOD_MAX] = {
+       "(bug)",
        "bitmap",
        "hash",
        "list",
 };
 
-static const char *ipset_types[] = {
+const char *fw3_ipset_type_names[__FW3_IPSET_TYPE_MAX] = {
+       "(bug)",
        "ip",
        "port",
        "mac",
@@ -140,7 +142,7 @@ fw3_parse_bool(void *ptr, const char *val, bool is_list)
 bool
 fw3_parse_int(void *ptr, const char *val, bool is_list)
 {
-       int n = strtol(val, NULL, 10);
+       int n = strtol(val, NULL, 0);
 
        if (errno == ERANGE || errno == EINVAL)
                return false;
@@ -201,6 +203,7 @@ fw3_parse_limit(void *ptr, const char *val, bool is_list)
 bool
 fw3_parse_device(void *ptr, const char *val, bool is_list)
 {
+       char *p;
        struct fw3_device dev = { };
 
        if (*val == '*')
@@ -217,6 +220,12 @@ fw3_parse_device(void *ptr, const char *val, bool is_list)
                while (isspace(*++val));
        }
 
+       if ((p = strchr(val, '@')) != NULL)
+       {
+               *p++ = 0;
+               snprintf(dev.network, sizeof(dev.network), "%s", p);
+       }
+
        if (*val)
                snprintf(dev.name, sizeof(dev.name), "%s", val);
        else
@@ -558,33 +567,39 @@ fw3_parse_protocol(void *ptr, const char *val, bool is_list)
 bool
 fw3_parse_ipset_method(void *ptr, const char *val, bool is_list)
 {
-       return parse_enum(ptr, val, ipset_methods,
+       return parse_enum(ptr, val, &fw3_ipset_method_names[FW3_IPSET_METHOD_BITMAP],
                          FW3_IPSET_METHOD_BITMAP, FW3_IPSET_METHOD_LIST);
 }
 
 bool
 fw3_parse_ipset_datatype(void *ptr, const char *val, bool is_list)
 {
-       struct fw3_ipset_datatype *type = ptr;
+       struct fw3_ipset_datatype type = { };
 
        if (!strncmp(val, "dest_", 5))
        {
                val += 5;
-               type->dest = true;
+               type.dest = true;
        }
        else if (!strncmp(val, "dst_", 4))
        {
                val += 4;
-               type->dest = true;
+               type.dest = true;
        }
        else if (!strncmp(val, "src_", 4))
        {
                val += 4;
-               type->dest = false;
+               type.dest = false;
        }
 
-       return parse_enum(&type->type, val, ipset_types,
-                         FW3_IPSET_TYPE_IP, FW3_IPSET_TYPE_SET);
+       if (parse_enum(&type.type, val, &fw3_ipset_type_names[FW3_IPSET_TYPE_IP],
+                      FW3_IPSET_TYPE_IP, FW3_IPSET_TYPE_SET))
+       {
+               put_value(ptr, &type, sizeof(type), is_list);
+               return true;
+       }
+
+       return false;
 }
 
 bool
@@ -888,58 +903,55 @@ fw3_format_in_out(struct fw3_device *in, struct fw3_device *out)
                fw3_pr(" %s-o %s", out->invert ? "! " : "", out->name);
 }
 
-void
-fw3_format_src_dest(struct fw3_address *src, struct fw3_address *dest)
+const char *
+fw3_address_to_string(struct fw3_address *address, bool allow_invert)
 {
-       char s[INET6_ADDRSTRLEN];
+       char *p, ip[INET6_ADDRSTRLEN];
+       static char buf[INET6_ADDRSTRLEN * 2 + 2];
 
-       if ((src && src->range) || (dest && dest->range))
-               fw3_pr(" -m iprange");
+       p = buf;
 
-       if (src && src->set)
-       {
-               if (src->range)
-               {
-                       inet_ntop(src->family == FW3_FAMILY_V4 ? AF_INET : AF_INET6,
-                                         &src->address.v4, s, sizeof(s));
+       if (address->invert && allow_invert)
+               p += sprintf(p, "!");
 
-                       fw3_pr(" %s--src-range %s", src->invert ? "! " : "", s);
+       inet_ntop(address->family == FW3_FAMILY_V4 ? AF_INET : AF_INET6,
+                 &address->address.v4, ip, sizeof(ip));
 
-                       inet_ntop(src->family == FW3_FAMILY_V4 ? AF_INET : AF_INET6,
-                                         &src->address2.v4, s, sizeof(s));
+       p += sprintf(p, "%s", ip);
 
-                       fw3_pr("-%s", s);
-               }
-               else
-               {
-                       inet_ntop(src->family == FW3_FAMILY_V4 ? AF_INET : AF_INET6,
-                                         &src->address.v4, s, sizeof(s));
+       if (address->range)
+       {
+               inet_ntop(address->family == FW3_FAMILY_V4 ? AF_INET : AF_INET6,
+                         &address->address2.v4, ip, sizeof(ip));
 
-                       fw3_pr(" %s-s %s/%u", src->invert ? "! " : "", s, src->mask);
-               }
+               p += sprintf(p, "-%s", ip);
        }
-
-       if (dest && dest->set)
+       else
        {
-               if (dest->range)
-               {
-                       inet_ntop(dest->family == FW3_FAMILY_V4 ? AF_INET : AF_INET6,
-                                         &dest->address.v4, s, sizeof(s));
+               p += sprintf(p, "/%u", address->mask);
+       }
 
-                       fw3_pr(" %s--dst-range %s", dest->invert ? "! " : "", s);
+       return buf;
+}
 
-                       inet_ntop(dest->family == FW3_FAMILY_V4 ? AF_INET : AF_INET6,
-                                         &dest->address2.v4, s, sizeof(s));
+void
+fw3_format_src_dest(struct fw3_address *src, struct fw3_address *dest)
+{
+       if ((src && src->range) || (dest && dest->range))
+               fw3_pr(" -m iprange");
 
-                       fw3_pr("-%s", s);
-               }
-               else
-               {
-                       inet_ntop(dest->family == FW3_FAMILY_V4 ? AF_INET : AF_INET6,
-                                         &dest->address.v4, s, sizeof(s));
+       if (src && src->set)
+       {
+               fw3_pr(" %s%s %s", src->invert ? "! " : "",
+                                  src->range ? "--src-range" : "-s",
+                                  fw3_address_to_string(src, false));
+       }
 
-                       fw3_pr(" %s-d %s/%u", dest->invert ? "! " : "", s, dest->mask);
-               }
+       if (dest && dest->set)
+       {
+               fw3_pr(" %s%s %s", dest->invert ? "! " : "",
+                                  dest->range ? "--dst-range" : "-d",
+                                  fw3_address_to_string(dest, false));
        }
 }
 
@@ -1045,10 +1057,7 @@ fw3_format_ipset(struct fw3_ipset *ipset, bool invert)
        if (!ipset)
                return;
 
-       if (ipset->external && *ipset->external)
-               name = ipset->external;
-       else
-               name = ipset->name;
+       name = ipset->external ? ipset->external : ipset->name;
 
        fw3_pr(" -m set %s--match-set %s", invert ? "! " : "", name);