X-Git-Url: http://git.archive.openwrt.org/?p=project%2Ffirewall3.git;a=blobdiff_plain;f=iptables.c;h=b574f8dc747307b1375bb745ec2c18c928e036e0;hp=e54ea53f2c39d48cf5e0ab3234e5c36e5d2cfbe8;hb=c520966c2a92a14c931f411d502ed1a8dedf604d;hpb=18f4c6fda6afb912f53ded3112b1f270ddf5ff6c diff --git a/iptables.c b/iptables.c index e54ea53..b574f8d 100644 --- a/iptables.c +++ b/iptables.c @@ -29,14 +29,30 @@ static struct xtables_globals xtg = { .option_offset = 0, .program_version = "4", .orig_opts = base_opts, +#if XTABLES_VERSION_CODE > 10 + .compat_rev = xtables_compatible_revision, +#endif }; static struct xtables_globals xtg6 = { .option_offset = 0, .program_version = "6", .orig_opts = base_opts, +#if XTABLES_VERSION_CODE > 10 + .compat_rev = xtables_compatible_revision, +#endif }; +static struct { + bool retain; + int mcount, tcount; + struct xtables_match **matches; + struct xtables_target **targets; + void (*register_match)(struct xtables_match *); + void (*register_target)(struct xtables_target *); +} xext; + + /* Required by certain extensions like SNAT and DNAT */ int kernel_version = 0; @@ -66,6 +82,7 @@ static void fw3_init_extensions(void) struct fw3_ipt_handle * fw3_ipt_open(enum fw3_family family, enum fw3_table table) { + int i; struct fw3_ipt_handle *h; h = fw3_alloc(sizeof(*h)); @@ -102,6 +119,14 @@ fw3_ipt_open(enum fw3_family family, enum fw3_table table) fw3_xt_reset(); fw3_init_extensions(); + if (xext.register_match) + for (i = 0; i < xext.mcount; i++) + xext.register_match(xext.matches[i]); + + if (xext.register_target) + for (i = 0; i < xext.tcount; i++) + xext.register_target(xext.targets[i]); + return h; } @@ -467,17 +492,6 @@ fw3_ipt_commit(struct fw3_ipt_handle *h) 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); } @@ -521,43 +535,14 @@ 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) { 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); + xext.retain = true; + m = xtables_find_match(name, XTF_TRY_LOAD, &r->matches); + xext.retain = false; return m; } @@ -623,13 +608,14 @@ 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); + xext.retain = true; - t = xtables_find_target(name, XTF_DONT_LOAD); + if (is_chain(r->h, name)) + t = xtables_find_target(XT_STANDARD_TARGET, XTF_TRY_LOAD); + else + t = xtables_find_target(name, XTF_TRY_LOAD); - if (!t && load_extension(r->h, name)) - t = xtables_find_target(name, XTF_DONT_LOAD); + xext.retain = false; return t; } @@ -1642,3 +1628,63 @@ fw3_ipt_rule_create(struct fw3_ipt_handle *handle, struct fw3_protocol *proto, return r; } + +void +xtables_register_match(struct xtables_match *me) +{ + int i; + static struct xtables_match **tmp; + + if (!xext.register_match) + xext.register_match = dlsym(RTLD_NEXT, "xtables_register_match"); + + if (!xext.register_match) + return; + + xext.register_match(me); + + if (xext.retain) + { + for (i = 0; i < xext.mcount; i++) + if (xext.matches[i] == me) + return; + + tmp = realloc(xext.matches, sizeof(me) * (xext.mcount + 1)); + + if (!tmp) + return; + + xext.matches = tmp; + xext.matches[xext.mcount++] = me; + } +} + +void +xtables_register_target(struct xtables_target *me) +{ + int i; + static struct xtables_target **tmp; + + if (!xext.register_target) + xext.register_target = dlsym(RTLD_NEXT, "xtables_register_target"); + + if (!xext.register_target) + return; + + xext.register_target(me); + + if (xext.retain) + { + for (i = 0; i < xext.tcount; i++) + if (xext.targets[i] == me) + return; + + tmp = realloc(xext.targets, sizeof(me) * (xext.tcount + 1)); + + if (!tmp) + return; + + xext.targets = tmp; + xext.targets[xext.tcount++] = me; + } +}