Add common fw3_address_to_string() helper function
[project/firewall3.git] / options.c
index 031de83..f261e70 100644 (file)
--- a/options.c
+++ b/options.c
@@ -75,6 +75,7 @@ const char *fw3_flag_names[__FW3_FLAG_MAX] = {
        "REJECT",
        "DROP",
        "NOTRACK",
+       "MARK",
        "DNAT",
        "SNAT",
 
@@ -754,6 +755,44 @@ fw3_parse_reflection_source(void *ptr, const char *val, bool is_list)
                          FW3_REFLECTION_INTERNAL, FW3_REFLECTION_EXTERNAL);
 }
 
+bool
+fw3_parse_mark(void *ptr, const char *val, bool is_list)
+{
+       uint32_t n;
+       char *s, *e;
+       struct fw3_mark *m = ptr;
+
+       if (*val == '!')
+       {
+               m->invert = true;
+               while (isspace(*++val));
+       }
+
+       if ((s = strchr(val, '/')) != NULL)
+               *s++ = 0;
+
+       n = strtoul(val, &e, 0);
+
+       if (e == val || *e)
+               return false;
+
+       m->mark = n;
+       m->mask = 0xFFFFFFFF;
+
+       if (s)
+       {
+               n = strtoul(s, &e, 0);
+
+               if (e == s || *e)
+                       return false;
+
+               m->mask = n;
+       }
+
+       m->set = true;
+       return true;
+}
+
 
 void
 fw3_parse_options(void *s, const struct fw3_option *opts,
@@ -849,58 +888,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));
        }
 }
 
@@ -1099,6 +1135,18 @@ fw3_format_time(struct fw3_time *time)
 }
 
 void
+fw3_format_mark(struct fw3_mark *mark)
+{
+       if (!mark->set)
+               return;
+
+       fw3_pr(" -m mark %s--mark 0x%x", mark->invert ? "! " : "", mark->mark);
+
+       if (mark->mask < 0xFFFFFFFF)
+               fw3_pr("/0x%x", mark->mask);
+}
+
+void
 __fw3_format_comment(const char *comment, ...)
 {
        va_list ap;