/*
* firewall3 - 3rd OpenWrt UCI firewall implementation
*
- * Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
+ * Copyright (C) 2013-2014 Jo-Philipp Wich <jow@openwrt.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
"MARK",
"DNAT",
"SNAT",
+ "MASQUERADE",
"ACCEPT",
"REJECT",
bool
fw3_parse_int(void *ptr, const char *val, bool is_list)
{
- int n = strtol(val, NULL, 0);
+ char *e;
+ int n = strtol(val, &e, 0);
- if (errno == ERANGE || errno == EINVAL)
+ if (e == val || *e)
return false;
*((int *)ptr) = n;
fw3_parse_target(void *ptr, const char *val, bool is_list)
{
return parse_enum(ptr, val, &fw3_flag_names[FW3_FLAG_ACCEPT],
- FW3_FLAG_ACCEPT, FW3_FLAG_SNAT);
+ FW3_FLAG_ACCEPT, FW3_FLAG_MASQUERADE);
}
bool
list_for_each_entry(addr, addr_list, list)
{
addr->invert = dev.invert;
+ addr->resolved = true;
if (!put_value(ptr, addr, sizeof(*addr), is_list))
break;
}
- fw3_ubus_address_free(addr_list);
+ fw3_free_list(addr_list);
}
}
{
struct fw3_protocol proto = { };
struct protoent *ent;
+ char *e;
if (*val == '!')
{
return true;
}
- proto.protocol = strtoul(val, NULL, 10);
+ proto.protocol = strtoul(val, &e, 10);
- if (errno == ERANGE || errno == EINVAL)
+ if ((e == val) || (*e != 0))
return false;
put_value(ptr, &proto, sizeof(proto), is_list);
{
struct fw3_ipset_datatype type = { };
+ type.dir = "src";
+
if (!strncmp(val, "dest_", 5))
{
val += 5;
- type.dest = true;
+ type.dir = "dst";
}
else if (!strncmp(val, "dst_", 4))
{
val += 4;
- type.dest = true;
+ type.dir = "dst";
}
else if (!strncmp(val, "src_", 4))
{
val += 4;
- type.dest = false;
+ type.dir = "src";
}
if (parse_enum(&type.type, val, &fw3_ipset_type_names[FW3_IPSET_TYPE_IP],
return true;
}
+bool
+fw3_parse_setmatch(void *ptr, const char *val, bool is_list)
+{
+ struct fw3_setmatch *m = ptr;
+ char *p, *s;
+ int i;
+
+ if (*val == '!')
+ {
+ m->invert = true;
+ while (isspace(*++val));
+ }
+
+ if (!(s = strdup(val)))
+ return false;
-void
+ if (!(p = strtok(s, " \t")))
+ {
+ free(s);
+ return false;
+ }
+
+ strncpy(m->name, p, sizeof(m->name));
+
+ for (i = 0, p = strtok(NULL, " \t,");
+ i < 3 && p != NULL;
+ i++, p = strtok(NULL, " \t,"))
+ {
+ if (!strncmp(p, "dest", 4) || !strncmp(p, "dst", 3))
+ m->dir[i] = "dst";
+ else if (!strncmp(p, "src", 3))
+ m->dir[i] = "src";
+ }
+
+ free(s);
+
+ m->set = true;
+ return true;
+}
+
+
+bool
fw3_parse_options(void *s, const struct fw3_option *opts,
struct uci_section *section)
{
struct uci_option *o;
const struct fw3_option *opt;
struct list_head *dest;
+ bool valid = true;
uci_foreach_element(§ion->options, e)
{
if (!opt->elem_size)
{
warn_elem(e, "must not be a list");
+ valid = false;
}
else
{
if (!opt->parse(dest, l->name, true))
{
warn_elem(e, "has invalid value '%s'", l->name);
+ valid = false;
continue;
}
}
if (!opt->elem_size)
{
if (!opt->parse((char *)s + opt->offset, o->v.string, false))
+ {
warn_elem(e, "has invalid value '%s'", o->v.string);
+ valid = false;
+ }
}
else
{
if (!opt->parse(dest, p, true))
{
warn_elem(e, "has invalid value '%s'", p);
+ valid = false;
continue;
}
}
if (!known)
warn_elem(e, "is unknown");
}
+
+ return valid;
}