X-Git-Url: http://git.archive.openwrt.org/?a=blobdiff_plain;f=iptables.c;h=95fc0d45835d565217d8caad63dc4486a92c426b;hb=dd013720b42d6df91176dc9e87f815dcd5d69519;hp=e54ea53f2c39d48cf5e0ab3234e5c36e5d2cfbe8;hpb=18f4c6fda6afb912f53ded3112b1f270ddf5ff6c;p=project%2Ffirewall3.git diff --git a/iptables.c b/iptables.c index e54ea53..95fc0d4 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); } @@ -525,9 +539,11 @@ static bool load_extension(struct fw3_ipt_handle *h, const char *name) { char path[256]; - void *lib, **tmp; + void *lib; const char *pfx = (h->family == FW3_FAMILY_V6) ? "libip6t" : "libipt"; + xext.retain = true; + snprintf(path, sizeof(path), "/usr/lib/iptables/libxt_%s.so", name); if (!(lib = dlopen(path, RTLD_NOW))) { @@ -535,18 +551,9 @@ load_extension(struct fw3_ipt_handle *h, const char *name) lib = dlopen(path, RTLD_NOW); } - if (!lib) - return false; - - tmp = realloc(h->libv, sizeof(lib) * (h->libc + 1)); + xext.retain = false; - if (!tmp) - return false; - - h->libv = tmp; - h->libv[h->libc++] = lib; - - return true; + return !!lib; } static struct xtables_match * @@ -1642,3 +1649,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; + } +}