From 77f48c2f1ef21fa43aa68c25a1457db319ca2526 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sat, 7 Feb 2009 19:59:53 +0100 Subject: libxtables: move afinfo around libxtables should not rely on the program executable providing the magic constants for using [gs]etsockopt. Signed-off-by: Jan Engelhardt --- include/xtables.h.in | 1 + include/xtables/internal.h.in | 24 -------------- ip6tables-restore.c | 1 + ip6tables-save.c | 1 + ip6tables-standalone.c | 1 + ip6tables.c | 9 ------ iptables-restore.c | 1 + iptables-save.c | 1 + iptables-standalone.c | 1 + iptables.c | 9 ------ xtables.c | 74 +++++++++++++++++++++++++++++++++++++------ 11 files changed, 71 insertions(+), 52 deletions(-) diff --git a/include/xtables.h.in b/include/xtables.h.in index 07217d6a..02750fb9 100644 --- a/include/xtables.h.in +++ b/include/xtables.h.in @@ -189,6 +189,7 @@ extern struct xtables_match *xtables_matches; extern struct xtables_target *xtables_targets; extern void xtables_init(void); +extern void xtables_set_nfproto(uint8_t); extern void *xtables_calloc(size_t, size_t); extern void *xtables_malloc(size_t); diff --git a/include/xtables/internal.h.in b/include/xtables/internal.h.in index 21438290..81ddb48a 100644 --- a/include/xtables/internal.h.in +++ b/include/xtables/internal.h.in @@ -7,30 +7,6 @@ # define XT_LIB_DIR "/usr/local/lib/iptables" #endif -/* protocol family dependent informations */ -struct afinfo { - /* protocol family */ - int family; - - /* prefix of library name (ex "libipt_" */ - char *libprefix; - - /* used by setsockopt (ex IPPROTO_IP */ - int ipproto; - - /* kernel module (ex "ip_tables" */ - char *kmod; - - /* optname to check revision support of match */ - int so_rev_match; - - /* optname to check revision support of match */ - int so_rev_target; -}; - -/* This is decleared in ip[6]tables.c */ -extern struct afinfo afinfo; - /** * Program's own name and version. */ diff --git a/ip6tables-restore.c b/ip6tables-restore.c index beb640b2..acaf97b4 100644 --- a/ip6tables-restore.c +++ b/ip6tables-restore.c @@ -132,6 +132,7 @@ int main(int argc, char *argv[]) xtables_program_name = program_name; xtables_init(); + xtables_set_nfproto(NFPROTO_IPV6); #ifdef NO_SHARED_LIBS init_extensions(); #endif diff --git a/ip6tables-save.c b/ip6tables-save.c index 86ec6b26..32b59926 100644 --- a/ip6tables-save.c +++ b/ip6tables-save.c @@ -141,6 +141,7 @@ int main(int argc, char *argv[]) xtables_program_name = program_name; xtables_init(); + xtables_set_nfproto(NFPROTO_IPV6); #ifdef NO_SHARED_LIBS init_extensions(); #endif diff --git a/ip6tables-standalone.c b/ip6tables-standalone.c index 3ab114ea..cea48186 100644 --- a/ip6tables-standalone.c +++ b/ip6tables-standalone.c @@ -54,6 +54,7 @@ main(int argc, char *argv[]) xtables_program_name = program_name; xtables_init(); + xtables_set_nfproto(NFPROTO_IPV6); #ifdef NO_SHARED_LIBS init_extensions(); #endif diff --git a/ip6tables.c b/ip6tables.c index 53163b7b..233974f2 100644 --- a/ip6tables.c +++ b/ip6tables.c @@ -199,15 +199,6 @@ struct pprot { u_int8_t num; }; -struct afinfo afinfo = { - .family = NFPROTO_IPV6, - .libprefix = "libip6t_", - .ipproto = IPPROTO_IPV6, - .kmod = "ip6_tables", - .so_rev_match = IP6T_SO_GET_REVISION_MATCH, - .so_rev_target = IP6T_SO_GET_REVISION_TARGET, -}; - static const char * proto_to_name(u_int8_t proto, int nolookup) { diff --git a/iptables-restore.c b/iptables-restore.c index 56812ee9..810806f0 100644 --- a/iptables-restore.c +++ b/iptables-restore.c @@ -134,6 +134,7 @@ main(int argc, char *argv[]) xtables_program_name = program_name; xtables_init(); + xtables_set_nfproto(NFPROTO_IPV4); #ifdef NO_SHARED_LIBS init_extensions(); #endif diff --git a/iptables-save.c b/iptables-save.c index d08ec4b2..c4306fd1 100644 --- a/iptables-save.c +++ b/iptables-save.c @@ -141,6 +141,7 @@ main(int argc, char *argv[]) xtables_program_name = program_name; xtables_init(); + xtables_set_nfproto(NFPROTO_IPV4); #ifdef NO_SHARED_LIBS init_extensions(); #endif diff --git a/iptables-standalone.c b/iptables-standalone.c index 91908732..ece7cf42 100644 --- a/iptables-standalone.c +++ b/iptables-standalone.c @@ -55,6 +55,7 @@ main(int argc, char *argv[]) xtables_program_name = program_name; xtables_init(); + xtables_set_nfproto(NFPROTO_IPV4); #ifdef NO_SHARED_LIBS init_extensions(); #endif diff --git a/iptables.c b/iptables.c index b43aadfd..f1a5d33e 100644 --- a/iptables.c +++ b/iptables.c @@ -194,15 +194,6 @@ const char *program_name; int kernel_version; -struct afinfo afinfo = { - .family = NFPROTO_IPV4, - .libprefix = "libipt_", - .ipproto = IPPROTO_IP, - .kmod = "ip_tables", - .so_rev_match = IPT_SO_GET_REVISION_MATCH, - .so_rev_target = IPT_SO_GET_REVISION_TARGET, -}; - /* Primitive headers... */ /* defined in netinet/in.h */ #if 0 diff --git a/xtables.c b/xtables.c index cf643521..6c954754 100644 --- a/xtables.c +++ b/xtables.c @@ -32,7 +32,8 @@ #include #include -#include +#include +#include #include #ifndef NO_SHARED_LIBS @@ -45,6 +46,44 @@ #define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe" #endif +/** + * xtables_afinfo - protocol family dependent information + * @kmod: kernel module basename (e.g. "ip_tables") + * @libprefix: prefix of .so library name (e.g. "libipt_") + * @family: nfproto family + * @ipproto: used by setsockopt (e.g. IPPROTO_IP) + * @so_rev_match: optname to check revision support of match + * @so_rev_target: optname to check revision support of target + */ +struct xtables_afinfo { + const char *kmod; + const char *libprefix; + uint8_t family; + uint8_t ipproto; + int so_rev_match; + int so_rev_target; +}; + +static const struct xtables_afinfo afinfo_ipv4 = { + .kmod = "ip_tables", + .libprefix = "libipt_", + .family = NFPROTO_IPV4, + .ipproto = IPPROTO_IP, + .so_rev_match = IPT_SO_GET_REVISION_MATCH, + .so_rev_target = IPT_SO_GET_REVISION_TARGET, +}; + +static const struct xtables_afinfo afinfo_ipv6 = { + .kmod = "ip6_tables", + .libprefix = "libip6t_", + .family = NFPROTO_IPV6, + .ipproto = IPPROTO_IPV6, + .so_rev_match = IP6T_SO_GET_REVISION_MATCH, + .so_rev_target = IP6T_SO_GET_REVISION_TARGET, +}; + +static const struct xtables_afinfo *afinfo; + /** * Program will set this to its own name. */ @@ -74,6 +113,21 @@ void xtables_init(void) xtables_libdir = XTABLES_LIBDIR; } +void xtables_set_nfproto(uint8_t nfproto) +{ + switch (nfproto) { + case NFPROTO_IPV4: + afinfo = &afinfo_ipv4; + break; + case NFPROTO_IPV6: + afinfo = &afinfo_ipv6; + break; + default: + fprintf(stderr, "libxtables: unhandled NFPROTO in %s\n", + __func__); + } +} + /** * xtables_*alloc - wrappers that exit on failure */ @@ -177,7 +231,7 @@ int xtables_load_ko(const char *modprobe, bool quiet) static int ret = -1; if (!loaded) { - ret = xtables_insmod(afinfo.kmod, modprobe, quiet); + ret = xtables_insmod(afinfo->kmod, modprobe, quiet); loaded = (ret == 0); } @@ -387,7 +441,7 @@ xtables_find_match(const char *name, enum xtables_tryload tryload, #ifndef NO_SHARED_LIBS if (!ptr && tryload != XTF_DONT_LOAD && tryload != XTF_DURING_LOAD) { - ptr = load_extension(xtables_libdir, afinfo.libprefix, + ptr = load_extension(xtables_libdir, afinfo->libprefix, name, false); if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED) @@ -447,7 +501,7 @@ xtables_find_target(const char *name, enum xtables_tryload tryload) #ifndef NO_SHARED_LIBS if (!ptr && tryload != XTF_DONT_LOAD && tryload != XTF_DURING_LOAD) { - ptr = load_extension(xtables_libdir, afinfo.libprefix, + ptr = load_extension(xtables_libdir, afinfo->libprefix, name, true); if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED) @@ -480,7 +534,7 @@ static int compatible_revision(const char *name, u_int8_t revision, int opt) socklen_t s = sizeof(rev); int max_rev, sockfd; - sockfd = socket(afinfo.family, SOCK_RAW, IPPROTO_RAW); + sockfd = socket(afinfo->family, SOCK_RAW, IPPROTO_RAW); if (sockfd < 0) { if (errno == EPERM) { /* revision 0 is always supported. */ @@ -501,7 +555,7 @@ static int compatible_revision(const char *name, u_int8_t revision, int opt) strcpy(rev.name, name); rev.revision = revision; - max_rev = getsockopt(sockfd, afinfo.ipproto, opt, &rev, &s); + max_rev = getsockopt(sockfd, afinfo->ipproto, opt, &rev, &s); if (max_rev < 0) { /* Definitely don't support this? */ if (errno == ENOENT || errno == EPROTONOSUPPORT) { @@ -524,12 +578,12 @@ static int compatible_revision(const char *name, u_int8_t revision, int opt) static int compatible_match_revision(const char *name, u_int8_t revision) { - return compatible_revision(name, revision, afinfo.so_rev_match); + return compatible_revision(name, revision, afinfo->so_rev_match); } static int compatible_target_revision(const char *name, u_int8_t revision) { - return compatible_revision(name, revision, afinfo.so_rev_target); + return compatible_revision(name, revision, afinfo->so_rev_target); } void xtables_register_match(struct xtables_match *me) @@ -559,7 +613,7 @@ void xtables_register_match(struct xtables_match *me) } /* ignore not interested match */ - if (me->family != afinfo.family && me->family != AF_UNSPEC) + if (me->family != afinfo->family && me->family != AF_UNSPEC) return; old = xtables_find_match(me->name, XTF_DURING_LOAD, NULL); @@ -632,7 +686,7 @@ void xtables_register_target(struct xtables_target *me) } /* ignore not interested target */ - if (me->family != afinfo.family && me->family != AF_UNSPEC) + if (me->family != afinfo->family && me->family != AF_UNSPEC) return; old = xtables_find_target(me->name, XTF_DURING_LOAD); -- cgit v1.2.3