if (!b)
{
warn_elem(e, "requires unavailable target extension %s, disabling", target);
+ *available = false;
}
- *available = b;
}
static void
struct uci_element *e;
struct fw3_defaults *defs = &state->defaults;
- bool flow_offload_avaliable = false;
bool seen = false;
defs->tcp_reject_code = FW3_REJECT_CODE_TCP_RESET;
continue;
}
+ seen = true;
+
if(!fw3_parse_options(&state->defaults, fw3_flag_opts, s))
warn_elem(e, "has invalid options");
check_any_reject_code(e, &defs->any_reject_code);
/* exists in both ipv4 and ipv6, if at all, so only check ipv4 */
- check_target(e, &flow_offload_avaliable, "FLOWOFFLOAD", false);
-
- if (!flow_offload_avaliable)
- defs->flow_offloading = false;
+ check_target(e, &defs->flow_offloading, "FLOWOFFLOAD", false);
}
}
if (defs->syn_flood)
{
- r = fw3_ipt_rule_create(handle, &tcp, NULL, NULL, NULL, NULL);
- fw3_ipt_rule_extra(r, "--syn");
+ r = fw3_ipt_rule_create(handle, NULL, NULL, NULL, NULL, NULL);
fw3_ipt_rule_limit(r, &defs->syn_flood_rate);
fw3_ipt_rule_target(r, "RETURN");
fw3_ipt_rule_append(r, "syn_flood");
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <ctype.h>
+
#include "ipsets.h"
ipset->enabled = true;
ipset->family = FW3_FAMILY_V4;
ipset->reload_set = false;
+ ipset->timeout = -1; /* no timeout by default */
list_add_tail(&ipset->list, &state->ipsets);
{
FILE *f;
char line[128];
+ char *p;
if (!ipset->loadfile)
return;
return;
}
- while (fgets(line, sizeof(line), f))
- fw3_pr("add %s %s", ipset->name, line);
+ while (fgets(line, sizeof(line), f)) {
+ p = line;
+ while (isspace(*p))
+ p++;
+ if (*p && *p != '#')
+ fw3_pr("add %s %s", ipset->name, line);
+ }
fclose(f);
}
ipset->portrange.port_min, ipset->portrange.port_max);
}
- if (ipset->timeout > 0)
+ if (ipset->timeout >= 0)
fw3_pr(" timeout %u", ipset->timeout);
if (ipset->maxelem > 0)
static bool
need_protomatch(struct fw3_ipt_rule *r, const char *pname)
{
+ struct xtables_match *match;
+
if (!pname)
return false;
- if (!xtables_find_match(pname, XTF_DONT_LOAD, NULL))
+ match = xtables_find_match(pname, XTF_DONT_LOAD, NULL);
+ if (!match)
return true;
+ /* Free any kind of clone from xtables_find_match */
+ if (match == match->next)
+ free(match);
return !r->protocol_loaded;
}
#endif
{
if (icmp->code_min == 0 && icmp->code_max == 0xFF)
- sprintf(buf, "%u", icmp->type);
+ snprintf(buf, sizeof(buf), "%u", icmp->type);
else
snprintf(buf, sizeof(buf), "%u/%u", icmp->type, icmp->code_min);
rem--;
}
- p += snprintf(p, rem, "%u", i);
+ len = snprintf(p, rem, "%u", i);
if (len < 0 || len >= rem)
break;
for (table = FW3_TABLE_FILTER; table <= FW3_TABLE_RAW; table++)
{
- if (!fw3_has_table(family == FW3_FAMILY_V6, fw3_flag_names[table]))
- continue;
-
if (!(handle = fw3_ipt_open(family, table)))
continue;
for (table = FW3_TABLE_FILTER; table <= FW3_TABLE_RAW; table++)
{
- if (!fw3_has_table(family == FW3_FAMILY_V6, fw3_flag_names[table]))
- continue;
-
if (!(handle = fw3_ipt_open(family, table)))
continue;
for (table = FW3_TABLE_FILTER; table <= FW3_TABLE_RAW; table++)
{
- if (!fw3_has_table(family == FW3_FAMILY_V6, fw3_flag_names[table]))
- continue;
-
if (!(handle = fw3_ipt_open(family, table)))
continue;
for (table = FW3_TABLE_FILTER; table <= FW3_TABLE_RAW; table++)
{
- if (!fw3_has_table(family == FW3_FAMILY_V6, fw3_flag_names[table]))
- continue;
-
if (!(handle = fw3_ipt_open(family, table)))
continue;
for (table = FW3_TABLE_FILTER; table <= FW3_TABLE_RAW; table++)
{
- if (!fw3_has_table(family == FW3_FAMILY_V6, fw3_flag_names[table]))
- continue;
-
if (!(handle = fw3_ipt_open(family, table)))
continue;
{ "CS6", 0x30 },
{ "CS7", 0x38 },
{ "BE", 0x00 },
+ { "LE", 0x01 },
{ "AF11", 0x0a },
{ "AF12", 0x0c },
{ "AF13", 0x0e },
return false;
}
- if (r->_dest && (r->target == FW3_FLAG_MARK || r->target == FW3_FLAG_DSCP))
- {
- warn_section("rule", r, e, "must not specify 'dest' for %s target",
- fw3_flag_names[r->target]);
- return false;
- }
-
if (r->set_mark.invert || r->set_xmark.invert || r->set_dscp.invert)
{
warn_section("rule", r, e, "must not have inverted 'set_mark', "
{
snprintf(chain, sizeof(chain), "zone_%s_helper", rule->src.name);
}
- else if ((rule->target == FW3_FLAG_MARK || rule->target == FW3_FLAG_DSCP) &&
- (rule->_src || rule->src.any))
+ else if (rule->target == FW3_FLAG_MARK || rule->target == FW3_FLAG_DSCP)
{
- snprintf(chain, sizeof(chain), "PREROUTING");
+ if ((rule->_dest && rule->_src) ||
+ (rule->dest.any && rule->src.any))
+ snprintf(chain, sizeof(chain), "FORWARD");
+ else if (rule->src.any && rule->_dest)
+ snprintf(chain, sizeof(chain), "POSTROUTING");
+ else if (rule->dest.any && rule->_src)
+ snprintf(chain, sizeof(chain), "PREROUTING");
+ else if (!rule->dest.set && rule->src.set)
+ snprintf(chain, sizeof(chain), "INPUT");
+ else /* if (!rule->src.set) */
+ snprintf(chain, sizeof(chain), "OUTPUT");
}
else
{
struct fw3_mac *mac, struct fw3_icmptype *icmptype)
{
struct fw3_ipt_rule *r;
+ struct fw3_device *idev, *odev;
+ struct list_head empty, *idevices, *odevices;
+ INIT_LIST_HEAD(&empty);
+ idevices = odevices = ∅
if (!fw3_is_family(sip, handle->family) ||
!fw3_is_family(dip, handle->family))
return;
}
- r = fw3_ipt_rule_create(handle, proto, NULL, NULL, sip, dip);
- fw3_ipt_rule_sport_dport(r, sport, dport);
- fw3_ipt_rule_device(r, rule->device, rule->direction_out);
- fw3_ipt_rule_icmptype(r, icmptype);
- fw3_ipt_rule_mac(r, mac);
- fw3_ipt_rule_ipset(r, &rule->ipset);
- fw3_ipt_rule_helper(r, &rule->helper);
- fw3_ipt_rule_limit(r, &rule->limit);
- fw3_ipt_rule_time(r, &rule->time);
- fw3_ipt_rule_mark(r, &rule->mark);
- fw3_ipt_rule_dscp(r, &rule->dscp);
- set_target(r, rule);
- fw3_ipt_rule_extra(r, rule->extra);
- set_comment(r, rule->name, num);
- append_chain(r, rule);
+ if (rule->target == FW3_FLAG_DSCP || rule->target == FW3_FLAG_MARK)
+ {
+ if (rule->_src)
+ idevices = &rule->_src->devices;
+ if (rule->_dest)
+ odevices = &rule->_dest->devices;
+ }
+
+ fw3_foreach(idev, idevices)
+ fw3_foreach(odev, odevices)
+ {
+ r = fw3_ipt_rule_create(handle, proto, idev, odev, sip, dip);
+ fw3_ipt_rule_sport_dport(r, sport, dport);
+ fw3_ipt_rule_device(r, rule->device, rule->direction_out);
+ fw3_ipt_rule_icmptype(r, icmptype);
+ fw3_ipt_rule_mac(r, mac);
+ fw3_ipt_rule_ipset(r, &rule->ipset);
+ fw3_ipt_rule_helper(r, &rule->helper);
+ fw3_ipt_rule_limit(r, &rule->limit);
+ fw3_ipt_rule_time(r, &rule->time);
+ fw3_ipt_rule_mark(r, &rule->mark);
+ fw3_ipt_rule_dscp(r, &rule->dscp);
+ set_target(r, rule);
+ fw3_ipt_rule_extra(r, rule->extra);
+ set_comment(r, rule->name, num);
+ append_chain(r, rule);
+ }
}
static void
pipe_pid = -1;
}
-bool
-fw3_has_table(bool ipv6, const char *table)
+static bool
+file_contains(const char *path, const char *str)
{
FILE *f;
-
char line[12];
bool seen = false;
- const char *path = ipv6
- ? "/proc/net/ip6_tables_names" : "/proc/net/ip_tables_names";
-
if (!(f = fopen(path, "r")))
return false;
while (fgets(line, sizeof(line), f))
{
- if (!strncmp(line, table, strlen(table)))
+ if (!strncmp(line, str, strlen(str)))
{
seen = true;
break;
bool
fw3_has_target(const bool ipv6, const char *target)
{
- FILE *f;
-
- char line[12];
- bool seen = false;
-
const char *path = ipv6
? "/proc/net/ip6_tables_targets" : "/proc/net/ip_tables_targets";
- if (!(f = fopen(path, "r")))
- return false;
-
- while (fgets(line, sizeof(line), f))
- {
- if (!strcmp(line, target))
- {
- seen = true;
- break;
- }
- }
-
- fclose(f);
-
- return seen;
+ return file_contains(path, target);
}
bool
warn("Cannot release exclusive lock: %s", strerror(errno));
close(*fd);
- unlink(FW3_LOCKFILE);
*fd = -1;
}
void info(const char *format, ...)
__attribute__ ((format (printf, 1, 2)));
-
#define warn_section(t, r, e, fmt, ...) \
do { \
if (e) \
void fw3_pr(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
-bool fw3_has_table(bool ipv6, const char *table);
-
bool fw3_has_target(const bool ipv6, const char *target);
bool fw3_lock(void);
static void
resolve_networks(struct uci_element *e, struct fw3_zone *zone)
{
- struct fw3_device *net, *tmp;
+ struct fw3_device *net, *dev, *tmp;
list_for_each_entry(net, &zone->networks, list)
{
continue;
}
+ list_for_each_entry(dev, &zone->devices, list)
+ if (!strcmp(dev->name, tmp->name))
+ goto alias;
+
snprintf(tmp->network, sizeof(tmp->network), "%s", net->name);
list_add_tail(&tmp->list, &zone->devices);
+ continue;
+alias:
+ free(tmp);
}
}
#include "options.h"
#include "iptables.h"
-/* 32 - sizeof("postrouting_") - sizeof("_rule") - sizeof("\0") */
-#define FW3_ZONE_MAXNAMELEN 14
+/* XT_EXTENSION_MAXNAMELEN (29)
+ * - sizeof("postrouting_")
+ * - sizeof("_rule")
+ * - sizeof("\0")
+ */
+#define FW3_ZONE_MAXNAMELEN 11
extern const struct fw3_option fw3_zone_opts[];