From df1bb55631c967aa0e4ee49cd29cf463fb86c85b Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Tue, 19 Feb 2013 19:32:39 +0100 Subject: [PATCH] track used family for ipsets --- redirects.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++------ rules.c | 40 ++++++++++++++++------ utils.h | 2 +- 3 files changed, 116 insertions(+), 23 deletions(-) diff --git a/redirects.c b/redirects.c index da14971..fc6b6b6 100644 --- a/redirects.c +++ b/redirects.c @@ -48,6 +48,51 @@ static struct fw3_option redirect_opts[] = { }; +static bool +check_families(struct uci_element *e, struct fw3_redirect *r) +{ + if (r->family == FW3_FAMILY_ANY) + return true; + + if (r->_src && r->_src->family && r->_src->family != r->family) + { + warn_elem(e, "refers to source zone with different family"); + return false; + } + + if (r->_dest && r->_dest->family && r->_dest->family != r->family) + { + warn_elem(e, "refers to destination zone with different family"); + return false; + } + + if (r->_ipset && r->_ipset->family && r->_ipset->family != r->family) + { + warn_elem(e, "refers to ipset with different family"); + return false; + } + + if (r->ip_src.family && r->ip_src.family != r->family) + { + warn_elem(e, "uses source ip with different family"); + return false; + } + + if (r->ip_dest.family && r->ip_dest.family != r->family) + { + warn_elem(e, "uses destination ip with different family"); + return false; + } + + if (r->ip_redir.family && r->ip_redir.family != r->family) + { + warn_elem(e, "uses redirect ip with different family"); + return false; + } + + return true; +} + void fw3_load_redirects(struct fw3_state *state, struct uci_package *p) { @@ -109,7 +154,13 @@ fw3_load_redirects(struct fw3_state *state, struct uci_package *p) else if (redir->ipset.set && !redir->ipset.any && !(redir->_ipset = fw3_lookup_ipset(state, redir->ipset.name))) { - warn_elem(e, "refers to not declared ipset '%s'", redir->ipset.name); + warn_elem(e, "refers to unknown ipset '%s'", redir->ipset.name); + fw3_free_redirect(redir); + continue; + } + + if (!check_families(e, redir)) + { fw3_free_redirect(redir); continue; } @@ -259,16 +310,42 @@ print_redirect(enum fw3_table table, enum fw3_family family, struct fw3_protocol *proto; struct fw3_mac *mac; + if (redir->name) + info(" * Redirect '%s'", redir->name); + else + info(" * Redirect #%u", num); + + if (!fw3_is_family(redir->_src, family) || + !fw3_is_family(redir->_dest, family)) + { + info(" ! Skipping due to different family of zone"); + return; + } + + if (!fw3_is_family(&redir->ip_src, family) || + !fw3_is_family(&redir->ip_dest, family) || + !fw3_is_family(&redir->ip_redir, family)) + { + info(" ! Skipping due to different family of ip address"); + return; + } + + if (redir->_ipset) + { + if (!fw3_is_family(redir->_ipset, family)) + { + info(" ! Skipping due to different family in ipset"); + return; + } + + setbit(redir->_ipset->flags, family); + } + fw3_foreach(proto, &redir->proto) fw3_foreach(mac, &redir->mac_src) { if (table == FW3_TABLE_NAT) { - if (redir->name) - info(" * Redirect '%s'", redir->name); - else - info(" * Redirect #%u", num); - print_chain_nat(redir); fw3_format_ipset(redir->_ipset, redir->ipset.invert); fw3_format_protocol(proto, family); @@ -291,11 +368,6 @@ print_redirect(enum fw3_table table, enum fw3_family family, } else if (table == FW3_TABLE_FILTER) { - if (redir->name) - info(" * Redirect '%s'", redir->name); - else - info(" * Redirect #%u", num); - print_chain_filter(redir); fw3_format_ipset(redir->_ipset, redir->ipset.invert); fw3_format_protocol(proto, family); @@ -387,6 +459,9 @@ fw3_print_redirects(enum fw3_table table, enum fw3_family family, if (family == FW3_FAMILY_V6) return; + if (table != FW3_TABLE_FILTER && table != FW3_TABLE_NAT) + return; + list_for_each_entry(redir, &state->redirects, list) print_redirect(table, family, redir, num++); } diff --git a/rules.c b/rules.c index f998628..bc983a6 100644 --- a/rules.c +++ b/rules.c @@ -112,7 +112,7 @@ fw3_load_rules(struct fw3_state *state, struct uci_package *p) else if (rule->ipset.set && !rule->ipset.any && !(rule->_ipset = fw3_lookup_ipset(state, rule->ipset.name))) { - warn_elem(e, "refers to not declared ipset '%s'", rule->ipset.name); + warn_elem(e, "refers to unknown ipset '%s'", rule->ipset.name); fw3_free_rule(rule); continue; } @@ -190,30 +190,24 @@ print_chain(struct fw3_rule *rule) static void print_target(struct fw3_rule *rule) { - char target[256]; + const char *target; switch(rule->target) { case FW3_TARGET_ACCEPT: - sprintf(target, "ACCEPT"); - break; - case FW3_TARGET_DROP: - sprintf(target, "DROP"); - break; - case FW3_TARGET_NOTRACK: - sprintf(target, "NOTRACK"); + target = fw3_flag_names[rule->target]; break; default: - sprintf(target, "REJECT"); + target = fw3_flag_names[FW3_TARGET_REJECT]; break; } if (rule->dest.set && !rule->dest.any) fw3_pr(" -j zone_%s_dest_%s\n", rule->dest.name, target); - else if (!strcmp(target, "REJECT")) + else if (rule->target == FW3_TARGET_REJECT) fw3_pr(" -j reject\n"); else fw3_pr(" -j %s\n", target); @@ -227,10 +221,16 @@ print_rule(enum fw3_table table, enum fw3_family family, struct fw3_mac *mac, struct fw3_icmptype *icmptype) { if (!fw3_is_family(sip, family) || !fw3_is_family(dip, family)) + { + info(" ! Skipping due to different family of ip address"); return; + } if (proto->protocol == 58 && family == FW3_FAMILY_V4) + { + info(" ! Skipping due to different family of protocol"); return; + } print_chain(rule); fw3_format_ipset(rule->_ipset, rule->ipset.invert); @@ -276,6 +276,24 @@ expand_rule(enum fw3_table table, enum fw3_family family, else info(" * Rule #%u", num); + if (!fw3_is_family(rule->_src, family) || + !fw3_is_family(rule->_dest, family)) + { + info(" ! Skipping due to different family of zone"); + return; + } + + if (rule->_ipset) + { + if (!fw3_is_family(rule->_ipset, family)) + { + info(" ! Skipping due to different family in ipset"); + return; + } + + setbit(rule->_ipset->flags, family); + } + list_for_each_entry(proto, &rule->proto, list) { /* icmp / ipv6-icmp */ diff --git a/utils.h b/utils.h index 590895a..5cadd58 100644 --- a/utils.h +++ b/utils.h @@ -63,7 +63,7 @@ fw3_free_list(struct list_head *list) } #define fw3_is_family(p, f) \ - (!p || p->family == FW3_FAMILY_ANY || p->family == f) + (!p || (p)->family == FW3_FAMILY_ANY || (p)->family == f) const char * fw3_find_command(const char *cmd); -- 2.25.1