X-Git-Url: http://git.archive.openwrt.org/?p=project%2Ffirewall3.git;a=blobdiff_plain;f=iptables.c;h=e1ad2d40e7b641bb2ae11614f0a614b819783a6b;hp=21c96b4cb6792eae31a3b31af762194254df041b;hb=aeba5741d7ed3b53fb4f1bb3679feb0fa526f4c6;hpb=73805dcc03e242fe5e25c9764ed33456acebdb95 diff --git a/iptables.c b/iptables.c index 21c96b4..e1ad2d4 100644 --- a/iptables.c +++ b/iptables.c @@ -311,6 +311,21 @@ fw3_ipt_commit(struct fw3_ipt_handle *h) if (!rv) fprintf(stderr, "iptc_commit(): %s\n", iptc_strerror(errno)); } +} + +void +fw3_ipt_close(struct fw3_ipt_handle *h) +{ + if (h->libv) + { + while (h->libc > 0) + { + h->libc--; + dlclose(h->libv[h->libc]); + } + + free(h->libv); + } free(h); } @@ -354,10 +369,45 @@ get_protoname(struct fw3_ipt_rule *r) return NULL; } +static bool +load_extension(struct fw3_ipt_handle *h, const char *name) +{ + char path[256]; + void *lib, **tmp; + const char *pfx = (h->family == FW3_FAMILY_V6) ? "libip6t" : "libipt"; + + snprintf(path, sizeof(path), "/usr/lib/iptables/libxt_%s.so", name); + if (!(lib = dlopen(path, RTLD_NOW))) + { + snprintf(path, sizeof(path), "/usr/lib/iptables/%s_%s.so", pfx, name); + lib = dlopen(path, RTLD_NOW); + } + + if (!lib) + return false; + + tmp = realloc(h->libv, sizeof(lib) * (h->libc + 1)); + + if (!tmp) + return false; + + h->libv = tmp; + h->libv[h->libc++] = lib; + + return true; +} + static struct xtables_match * find_match(struct fw3_ipt_rule *r, const char *name) { - return xtables_find_match(name, XTF_TRY_LOAD, &r->matches); + struct xtables_match *m; + + m = xtables_find_match(name, XTF_DONT_LOAD, &r->matches); + + if (!m && load_extension(r->h, name)) + m = xtables_find_match(name, XTF_DONT_LOAD, &r->matches); + + return m; } static void @@ -417,18 +467,29 @@ load_protomatch(struct fw3_ipt_rule *r) } static struct xtables_target * +find_target(struct fw3_ipt_rule *r, const char *name) +{ + struct xtables_target *t; + + if (is_chain(r->h, name)) + return xtables_find_target(XT_STANDARD_TARGET, XTF_LOAD_MUST_SUCCEED); + + t = xtables_find_target(name, XTF_DONT_LOAD); + + if (!t && load_extension(r->h, name)) + t = xtables_find_target(name, XTF_DONT_LOAD); + + return t; +} + +static struct xtables_target * get_target(struct fw3_ipt_rule *r, const char *name) { size_t s; struct xtables_target *t; struct xtables_globals *g; - bool chain = is_chain(r->h, name); - - if (chain) - t = xtables_find_target(XT_STANDARD_TARGET, XTF_LOAD_MUST_SUCCEED); - else - t = xtables_find_target(name, XTF_TRY_LOAD); + t = find_target(r, name); if (!t) return NULL; @@ -734,29 +795,35 @@ fw3_ipt_rule_limit(struct fw3_ipt_rule *r, struct fw3_limit *limit) } void -fw3_ipt_rule_ipset(struct fw3_ipt_rule *r, struct fw3_ipset *ipset, - bool invert) +fw3_ipt_rule_ipset(struct fw3_ipt_rule *r, struct fw3_setmatch *match) { char buf[sizeof("dst,dst,dst\0")]; char *p = buf; + int i = 0; + struct fw3_ipset *set; struct fw3_ipset_datatype *type; - if (!ipset) + if (!match || !match->set || !match->ptr) return; - list_for_each_entry(type, &ipset->datatypes, list) + set = match->ptr; + list_for_each_entry(type, &set->datatypes, list) { + if (i >= 3) + break; + if (p > buf) *p++ = ','; - p += sprintf(p, "%s", type->dest ? "dst" : "src"); + p += sprintf(p, "%s", match->dir[i] ? match->dir[i] : type->dir); + i++; } fw3_ipt_rule_addarg(r, false, "-m", "set"); - fw3_ipt_rule_addarg(r, invert, "--match-set", - ipset->external ? ipset->external : ipset->name); + fw3_ipt_rule_addarg(r, match->invert, "--match-set", + set->external ? set->external : set->name); fw3_ipt_rule_addarg(r, false, buf, NULL); } @@ -1021,10 +1088,6 @@ rule_print4(struct ipt_entry *e) static void rule_print(struct fw3_ipt_rule *r, const char *chain) { - struct xtables_rule_match *rm; - struct xtables_match *m; - struct xtables_target *t; - debug(r->h, "-A %s", chain); #ifndef DISABLE_IPV6 @@ -1034,23 +1097,8 @@ rule_print(struct fw3_ipt_rule *r, const char *chain) #endif rule_print4(&r->e); - for (rm = r->matches; rm; rm = rm->next) - { - m = rm->match; - printf(" -m %s", fw3_xt_get_match_name(m)); - - if (m->save) - m->save(&r->e.ip, m->m); - } - - if (r->target) - { - t = r->target; - printf(" -j %s", fw3_xt_get_target_name(t)); - - if (t->save) - t->save(&r->e.ip, t->t); - } + fw3_xt_print_matches(&r->e.ip, r->matches); + fw3_xt_print_target(&r->e.ip, r->target); printf("\n"); }