"REJECT",
"DROP",
"NOTRACK",
+ "MARK",
"DNAT",
"SNAT",
"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",
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;
bool
fw3_parse_device(void *ptr, const char *val, bool is_list)
{
+ char *p;
struct fw3_device dev = { };
if (*val == '*')
{
dev.set = true;
dev.any = true;
+ put_value(ptr, &dev, sizeof(dev), is_list);
return true;
}
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
if (!strcmp(val, "all"))
{
proto.any = true;
+ put_value(ptr, &proto, sizeof(proto), is_list);
return true;
}
else if (!strcmp(val, "icmpv6"))
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;
+ }
+
+ 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 parse_enum(&type->type, val, ipset_types,
- FW3_IPSET_TYPE_IP, FW3_IPSET_TYPE_SET);
+ return false;
}
bool
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,
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));
}
}
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);
}
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;