X-Git-Url: http://git.archive.openwrt.org/?p=project%2Ffirewall3.git;a=blobdiff_plain;f=redirects.c;h=627438b3232b553088966a74fa6e9199645a6784;hp=f8eaed3f6e8c02fb63623c740f94e969932342d2;hb=275a37dbf280bd471ebb2c673267c49a81071bbb;hpb=5b051a66fad3c208380d69b4b13d09929fcfe101 diff --git a/redirects.c b/redirects.c index f8eaed3..627438b 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) { @@ -87,14 +132,14 @@ fw3_load_redirects(struct fw3_state *state, struct uci_package *p) continue; } else if (redir->src.set && !redir->src.any && - !(redir->_src = fw3_lookup_zone(state, redir->src.name))) + !(redir->_src = fw3_lookup_zone(state, redir->src.name, false))) { warn_elem(e, "refers to not existing zone '%s'", redir->src.name); fw3_free_redirect(redir); continue; } else if (redir->dest.set && !redir->dest.any && - !(redir->_dest = fw3_lookup_zone(state, redir->dest.name))) + !(redir->_dest = fw3_lookup_zone(state, redir->dest.name, false))) { warn_elem(e, "refers to not existing zone '%s'", redir->dest.name); fw3_free_redirect(redir); @@ -107,9 +152,15 @@ fw3_load_redirects(struct fw3_state *state, struct uci_package *p) continue; } else if (redir->ipset.set && !redir->ipset.any && - !(redir->_ipset = fw3_lookup_ipset(state, redir->ipset.name))) + !(redir->_ipset = fw3_lookup_ipset(state, redir->ipset.name, false))) + { + warn_elem(e, "refers to unknown ipset '%s'", redir->ipset.name); + fw3_free_redirect(redir); + continue; + } + + if (!check_families(e, redir)) { - warn_elem(e, "refers to not declared ipset '%s'", redir->ipset.name); fw3_free_redirect(redir); continue; } @@ -133,16 +184,16 @@ fw3_load_redirects(struct fw3_state *state, struct uci_package *p) warn_elem(e, "has no source specified"); else { - setbit(redir->_src->has_dest_target, redir->target); + setbit(redir->_src->dst_flags, redir->target); redir->_src->conntrack = true; valid = true; } if (redir->reflection && redir->_dest && redir->_src->masq) { - setbit(redir->_dest->has_dest_target, FW3_TARGET_ACCEPT); - setbit(redir->_dest->has_dest_target, FW3_TARGET_DNAT); - setbit(redir->_dest->has_dest_target, FW3_TARGET_SNAT); + setbit(redir->_dest->dst_flags, FW3_TARGET_ACCEPT); + setbit(redir->_dest->dst_flags, FW3_TARGET_DNAT); + setbit(redir->_dest->dst_flags, FW3_TARGET_SNAT); } } else @@ -155,7 +206,7 @@ fw3_load_redirects(struct fw3_state *state, struct uci_package *p) warn_elem(e, "has no src_dip option specified"); else { - setbit(redir->_dest->has_dest_target, redir->target); + setbit(redir->_dest->dst_flags, redir->target); redir->_dest->conntrack = true; valid = true; } @@ -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++); }