/configure
/libtool
/stamp-h1
+
+/libltdl/
AC_CONFIG_HEADER([config.h])
AM_INIT_AUTOMAKE([foreign subdir-objects tar-pax])
+AC_ENABLE_STATIC
+LT_INIT([dlopen])
+LT_CONFIG_LTDL_DIR([libltdl])
+LTDL_INIT([nonrecursive])
+
dnl Shortcut: Linux supported alone
case "$host" in
*-*-linux*) ;;
AM_CONDITIONAL([ENABLE_DEBUG], [test "x$enable_debug" = xyes])
+dnl Enable type modules
+AC_ARG_ENABLE([settype_modules],
+ AS_HELP_STRING([--enable-settype-modules],
+ [Enable set type modules support]),
+ [enable_settype_modules="$enableval"],
+ [enable_settype_modules="no"])
+
+AC_ARG_WITH([settype_modules_list],
+ AS_HELP_STRING([--with-settype-modules-list="mod1 mod2 ..."],
+ [List of dynamic loading modules, ignored if settype-modules is disabled. It could be "all" to build all available settypes as modules]),
+ [SETTYPE_MODLIST_RAW="$withval";])
+
+SETTYPE_MODLIST=
+if test "x$enable_settype_modules" = "xyes"; then
+ for mod in $SETTYPE_MODLIST_RAW; do
+ if echo $mod | grep "all"; then
+ m="${mod}"
+ else
+ if echo $mod | grep "ipset_"; then
+ m="${mod}.c"
+ else
+ m="ipset_${mod}.c"
+ fi
+ fi
+
+ SETTYPE_MODLIST="${SETTYPE_MODLIST} $m"
+ done
+
+ AC_MSG_RESULT([checking for configuration with dynamic loading modules... $SETTYPE_MODLIST_RAW])
+fi
+AC_SUBST(SETTYPE_MODLIST)
+
+AM_CONDITIONAL([ENABLE_SETTYPE_MODULES], [test "x$enable_settype_modules" = xyes])
+
+AM_CONDITIONAL([ENABLE_STATIC], [test "x$enable_static" = xyes])
+AM_CONDITIONAL([ENABLE_SHARED], [test "x$enable_shared" = xyes])
+
dnl Checks for programs
: ${CFLAGS=""}
const struct ipset_type *t);
extern void ipset_load_types(void);
+extern void ipset_types_init(void);
+
+#ifdef TYPE_INCLUSIVE
+# ifdef _INIT
+# undef _init
+# define _init _INIT
+# endif
+#else
+# undef _init
+# define _init __attribute__((constructor)) _INIT
+#endif
+
#endif /* LIBIPSET_TYPES_H */
--- /dev/null
+IPSET_MODSDIR=${libdir}/ipset
+
+if ENABLE_SETTYPE_MODULES
+AM_CFLAGS += -DENABLE_SETTYPE_MODULES \
+ -DIPSET_MODSDIR="\"$(IPSET_MODSDIR)\""
+IPSET_SETTYPE_MODULES = yes
+IPSET_SETTYPE_DYNAMIC = $(if $(findstring all,$(SETTYPE_MODLIST)), \
+ $(IPSET_SETTYPE_LIST), $(SETTYPE_MODLIST))
+else
+IPSET_SETTYPE_DYNAMIC =
+endif
+
+IPSET_SETTYPE_STATIC = $(filter-out $(IPSET_SETTYPE_DYNAMIC), \
+ $(IPSET_SETTYPE_LIST))
+IPSET_SETTYPE_STATIC_OBJECTS = $(patsubst %.c, %.lo, $(IPSET_SETTYPE_STATIC))
+
+IPSET_SETTYPE_DYNAMIC_OBJECTS = $(patsubst %.c, %.lo, $(IPSET_SETTYPE_DYNAMIC))
+IPSET_SETTYPE_DYNAMIC_MODULES = $(patsubst %.c, %.la, $(IPSET_SETTYPE_DYNAMIC))
+IPSET_SETTYPE_DYNAMIC_LTFLAGS = -shared -module -avoid-version
+IPSET_SETTYPE_ALL_MODULES = $(patsubst %.c, %.la, $(IPSET_SETTYPE_STATIC)) \
+ $(IPSET_SETTYPE_DYNAMIC_MODULES)
+
+BUILT_SOURCES = ipset_settype_check types_init.c ipset_settype_modules
+CLEANFILES = ipset_settype_check types_init.c $(IPSET_SETTYPE_ALL_MODULES)
+
+ipset_%.lo: ipset_%.c
+ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`; \
+ $(LTCOMPILE) -D_INIT=ipset_$*_init \
+ $(if $(findstring ipset_$*.c,$(IPSET_SETTYPE_STATIC)), -DTYPE_INCLUSIVE,)\
+ -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< && \
+ $(am__mv) $$depbase.Tpo $$depbase.Plo
+
+ipset_%.la: $(lib_LTLIBRARIES) ipset_%.lo
+ lobj="$(patsubst %.la, %.lo, $@)"; \
+ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(CFLAGS) $(IPSET_SETTYPE_DYNAMIC_LTFLAGS) $(LDFLAGS) -o $@ \
+ -rpath $(IPSET_MODSDIR) $$lobj $(LIBS) $(top_builddir)/lib/libipset.la
+
+types_init.c: $(IPSET_SETTYPE_STATIC_OBJECTS)
+ @( \
+ static_list=`echo $(patsubst %.c,%,$(IPSET_SETTYPE_STATIC))`; \
+ echo -n "" > $@; \
+ for i in $$static_list; do \
+ echo "extern void $${i}_init(void);" >> $@; \
+ done; \
+ echo "void ipset_types_init(void);" >> $@; \
+ echo "void ipset_types_init(void)" >> $@; \
+ echo "{" >> $@; \
+ for i in $$static_list; do \
+ echo " ""$${i}_init();" >> $@; \
+ done; \
+ echo "}" >> $@; \
+ );
+
+ipset_settype_check:
+ @list="$(IPSET_SETTYPE_MODULES) $(IPSET_SETTYPE_STATIC_OBJECTS)"; \
+ test -f $@ || echo "$$list" > $@; \
+ if test "$$list" != "`cat $@`"; then \
+ $(MAKE) clean; \
+ echo "$$list" > $@; \
+ fi
+
+ipset_settype_modules: $(lib_LTLIBRARIES) $(IPSET_SETTYPE_DYNAMIC_OBJECTS) \
+ $(IPSET_SETTYPE_DYNAMIC_MODULES)
+
+install-data-local: install-settype-modules
+uninstall-local: uninstall-settype-modules
+
+install-settype-modules: ipset_settype_modules
+ @$(NORMAL_INSTALL)
+ @list='$(IPSET_SETTYPE_DYNAMIC_MODULES)'; \
+ test -n "$(IPSET_MODSDIR)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(IPSET_MODSDIR)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(IPSET_MODSDIR)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(IPSET_MODSDIR)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(IPSET_MODSDIR)"; \
+ }
+
+uninstall-settype-modules:
+ @$(NORMAL_UNINSTALL)
+ @list='$(IPSET_SETTYPE_DYNAMIC_MODULES)'; \
+ test -n "$(IPSET_MODSDIR)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(IPSET_MODSDIR)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(IPSET_MODSDIR)/$$f"; \
+ done
+
+.PHONY: ipset_settype_check ipset_settype_modules ipset_settype_modules-stamp \
+ install-settype-modules uninstall-settype-modules
include $(top_srcdir)/Make_global.am
+IPSET_SETTYPE_LIST = \
+ ipset_bitmap_ip.c \
+ ipset_bitmap_ipmac.c \
+ ipset_bitmap_port.c \
+ ipset_hash_ip.c \
+ ipset_hash_ipport.c \
+ ipset_hash_ipportip.c \
+ ipset_hash_ipportnet.c \
+ ipset_hash_net.c \
+ ipset_hash_netport.c \
+ ipset_hash_netiface.c \
+ ipset_list_set.c
+
AM_CFLAGS += ${libmnl_CFLAGS}
lib_LTLIBRARIES = libipset.la
+include $(top_srcdir)/lib/Make_extra.am
+
libipset_la_LDFLAGS = -Wl,--version-script=$(top_srcdir)/lib/libipset.map -version-info $(LIBVERSION)
-libipset_la_LIBADD = ${libmnl_LIBS}
+libipset_la_LIBADD = ${libmnl_LIBS} $(IPSET_SETTYPE_STATIC_OBJECTS)
libipset_la_SOURCES = \
data.c \
errcode.c \
session.c \
types.c \
ui.c \
- ipset_bitmap_ip.c \
- ipset_bitmap_ipmac.c \
- ipset_bitmap_port.c \
- ipset_hash_ip.c \
- ipset_hash_ipport.c \
- ipset_hash_ipportip.c \
- ipset_hash_ipportnet.c \
- ipset_hash_net.c \
- ipset_hash_netport.c \
- ipset_hash_netiface.c \
- ipset_list_set.c
+ types_init.c
+
+EXTRA_DIST = $(IPSET_SETTYPE_LIST) libipset.map
#%.o: %.c
# ${AM_VERBOSE_CC} ${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} ${CFLAGS} -o $@ -c $<
"where IP, FROM and TO are IPv4 addresses (or hostnames),\n"
" CIDR is a valid IPv4 CIDR prefix.\n";
-struct ipset_type ipset_bitmap_ip0 = {
+static struct ipset_type ipset_bitmap_ip0 = {
.name = "bitmap:ip",
.alias = { "ipmap", NULL },
.revision = 0,
.usage = bitmap_ip_usage,
};
+
+void _init(void)
+{
+ ipset_type_add(&ipset_bitmap_ip0);
+}
" CIDR is a valid IPv4 CIDR prefix,\n"
" MAC is a valid MAC address.\n";
-struct ipset_type ipset_bitmap_ipmac0 = {
+static struct ipset_type ipset_bitmap_ipmac0 = {
.name = "bitmap:ip,mac",
.alias = { "macipmap", NULL },
.revision = 0,
.usage = bitmap_ipmac_usage,
};
+
+void _init(void)
+{
+ ipset_type_add(&ipset_bitmap_ipmac0);
+}
"test SETNAME PORT\n\n"
"where PORT, FROM and TO are port numbers or port names from /etc/services.\n";
-struct ipset_type ipset_bitmap_port0 = {
+static struct ipset_type ipset_bitmap_port0 = {
.name = "bitmap:port",
.alias = { "portmap", NULL },
.revision = 0,
.usage = bitmap_port_usage,
};
+
+void _init(void)
+{
+ ipset_type_add(&ipset_bitmap_port0);
+}
" Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
" is supported for IPv4.\n";
-struct ipset_type ipset_hash_ip0 = {
+static struct ipset_type ipset_hash_ip0 = {
.name = "hash:ip",
.alias = { "iphash", NULL },
.revision = 0,
.usage = hash_ip_usage,
};
+
+void _init(void)
+{
+ ipset_type_add(&ipset_hash_ip0);
+}
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_ipport1 = {
+static struct ipset_type ipset_hash_ipport1 = {
.name = "hash:ip,port",
.alias = { "ipporthash", NULL },
.revision = 1,
.usage = hash_ipport1_usage,
.usagefn = ipset_port_usage,
};
+
+void _init(void)
+{
+ ipset_type_add(&ipset_hash_ipport1);
+}
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_ipportip1 = {
+static struct ipset_type ipset_hash_ipportip1 = {
.name = "hash:ip,port,ip",
.alias = { "ipportiphash", NULL },
.revision = 1,
.usage = hash_ipportip1_usage,
.usagefn = ipset_port_usage,
};
+
+void _init(void)
+{
+ ipset_type_add(&ipset_hash_ipportip1);
+}
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_ipportnet1 = {
+static struct ipset_type ipset_hash_ipportnet1 = {
.name = "hash:ip,port,net",
.alias = { "ipportnethash", NULL },
.revision = 1,
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_ipportnet2 = {
+static struct ipset_type ipset_hash_ipportnet2 = {
.name = "hash:ip,port,net",
.alias = { "ipportnethash", NULL },
.revision = 2,
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_ipportnet3 = {
+static struct ipset_type ipset_hash_ipportnet3 = {
.name = "hash:ip,port,net",
.alias = { "ipportnethash", NULL },
.revision = 3,
.usagefn = ipset_port_usage,
};
+void _init(void)
+{
+ ipset_type_add(&ipset_hash_ipportnet1);
+ ipset_type_add(&ipset_hash_ipportnet2);
+ ipset_type_add(&ipset_hash_ipportnet3);
+}
" IP is an IPv4 or IPv6 address (or hostname),\n"
" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n";
-struct ipset_type ipset_hash_net0 = {
+static struct ipset_type ipset_hash_net0 = {
.name = "hash:net",
.alias = { "nethash", NULL },
.revision = 0,
" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n"
" IP range is not supported with IPv6.\n";
-struct ipset_type ipset_hash_net1 = {
+static struct ipset_type ipset_hash_net1 = {
.name = "hash:net",
.alias = { "nethash", NULL },
.revision = 1,
" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n"
" IP range is not supported with IPv6.\n";
-struct ipset_type ipset_hash_net2 = {
+static struct ipset_type ipset_hash_net2 = {
.name = "hash:net",
.alias = { "nethash", NULL },
.revision = 2,
.usage = hash_net2_usage,
};
+void _init(void)
+{
+ ipset_type_add(&ipset_hash_net0);
+ ipset_type_add(&ipset_hash_net1);
+ ipset_type_add(&ipset_hash_net2);
+}
" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n"
" Adding/deleting multiple elements with IPv4 is supported.\n";
-struct ipset_type ipset_hash_netiface0 = {
+static struct ipset_type ipset_hash_netiface0 = {
.name = "hash:net,iface",
.alias = { "netifacehash", NULL },
.revision = 0,
" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n"
" Adding/deleting multiple elements with IPv4 is supported.\n";
-struct ipset_type ipset_hash_netiface1 = {
+static struct ipset_type ipset_hash_netiface1 = {
.name = "hash:net,iface",
.alias = { "netifacehash", NULL },
.revision = 1,
.usage = hash_netiface1_usage,
};
+void _init(void)
+{
+ ipset_type_add(&ipset_hash_netiface0);
+ ipset_type_add(&ipset_hash_netiface1);
+}
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_netport1 = {
+static struct ipset_type ipset_hash_netport1 = {
.name = "hash:net,port",
.alias = { "netporthash", NULL },
.revision = 1,
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_netport2 = {
+static struct ipset_type ipset_hash_netport2 = {
.name = "hash:net,port",
.alias = { "netporthash", NULL },
.revision = 2,
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_netport3 = {
+static struct ipset_type ipset_hash_netport3 = {
.name = "hash:net,port",
.alias = { "netporthash", NULL },
.revision = 3,
.usage = hash_netport3_usage,
.usagefn = ipset_port_usage,
};
+
+void _init(void)
+{
+ ipset_type_add(&ipset_hash_netport1);
+ ipset_type_add(&ipset_hash_netport2);
+ ipset_type_add(&ipset_hash_netport3);
+}
"test SETNAME NAME [before|after NAME]\n\n"
"where NAME are existing set names.\n";
-struct ipset_type ipset_list_set0 = {
+static struct ipset_type ipset_list_set0 = {
.name = "list:set",
.alias = { "setlist", NULL },
.revision = 0,
.usage = list_set_usage,
};
+
+void _init(void)
+{
+ ipset_type_add(&ipset_list_set0);
+}
global:
ipset_load_types;
ipset_port_usage;
+ ipset_parse_timeout;
} LIBIPSET_1.0;
#include <libipset/utils.h> /* STREQ */
#include <libipset/types.h> /* prototypes */
-/* The known set types: (typename, revision, family) is unique */
-extern struct ipset_type ipset_bitmap_ip0;
-extern struct ipset_type ipset_bitmap_ipmac0;
-extern struct ipset_type ipset_bitmap_port0;
-extern struct ipset_type ipset_hash_ip0;
-extern struct ipset_type ipset_hash_net0;
-extern struct ipset_type ipset_hash_net1;
-extern struct ipset_type ipset_hash_net2;
-extern struct ipset_type ipset_hash_netport1;
-extern struct ipset_type ipset_hash_netport2;
-extern struct ipset_type ipset_hash_netport3;
-extern struct ipset_type ipset_hash_netiface0;
-extern struct ipset_type ipset_hash_netiface1;
-extern struct ipset_type ipset_hash_ipport1;
-extern struct ipset_type ipset_hash_ipportip1;
-extern struct ipset_type ipset_hash_ipportnet1;
-extern struct ipset_type ipset_hash_ipportnet2;
-extern struct ipset_type ipset_hash_ipportnet3;
-extern struct ipset_type ipset_list_set0;
+#ifdef ENABLE_SETTYPE_MODULES
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <dirent.h>
+#endif
/* Userspace cache of sets which exists in the kernel */
void
ipset_load_types(void)
{
+#ifdef ENABLE_SETTYPE_MODULES
+ const char *dir = IPSET_MODSDIR;
+ const char *next = NULL;
+ char path[256];
+ char file[256];
+ struct dirent **list = NULL;
+ int n;
+ int len;
+#endif
+
if (typelist != NULL)
return;
- ipset_type_add(&ipset_bitmap_ip0);
- ipset_type_add(&ipset_bitmap_ipmac0);
- ipset_type_add(&ipset_bitmap_port0);
- ipset_type_add(&ipset_hash_ip0);
- ipset_type_add(&ipset_hash_net0);
- ipset_type_add(&ipset_hash_net1);
- ipset_type_add(&ipset_hash_net2);
- ipset_type_add(&ipset_hash_netport1);
- ipset_type_add(&ipset_hash_netport2);
- ipset_type_add(&ipset_hash_netport3);
- ipset_type_add(&ipset_hash_netiface0);
- ipset_type_add(&ipset_hash_netiface1);
- ipset_type_add(&ipset_hash_ipport1);
- ipset_type_add(&ipset_hash_ipportip1);
- ipset_type_add(&ipset_hash_ipportnet1);
- ipset_type_add(&ipset_hash_ipportnet2);
- ipset_type_add(&ipset_hash_ipportnet3);
- ipset_type_add(&ipset_list_set0);
+ /* Initialize static types */
+ ipset_types_init();
+
+#ifdef ENABLE_SETTYPE_MODULES
+ /* Initialize dynamic types */
+ do {
+ next = strchr(dir, ':');
+ if (next == NULL)
+ next = dir + strlen(dir);
+
+ len = snprintf(path, sizeof(path), "%.*s",
+ (unsigned int)(next - dir), dir);
+
+ if (len >= sizeof(path) || len < 0)
+ continue;
+
+ n = scandir(path, &list, NULL, alphasort);
+ if (n < 0)
+ continue;
+
+ while (n--) {
+ if (strstr(list[n]->d_name, ".so") == NULL)
+ goto nextf;
+
+ len = snprintf(file, sizeof(file), "%s/%s", path, list[n]->d_name);
+ if (len >= sizeof(file) || len < 0)
+ goto nextf;
+
+ if (dlopen(file, RTLD_NOW) == NULL) {
+ fprintf(stderr, "%s: %s\n", file, dlerror());
+ }
+
+nextf:
+ free(list[n]);
+ }
+
+ free(list);
+
+ dir = next + 1;
+ } while (*next != '\0');
+#endif // ENABLE_SETTYPE_MODULES
}
/libtool.m4
/lt*.m4
+/argz.m4
sbin_PROGRAMS = ipset
ipset_SOURCES = ipset.c ui.c
ipset_LDADD = ../lib/libipset.la
+
+if ENABLE_SETTYPE_MODULES
+AM_LDFLAGS = -shared
+else
+if ENABLE_STATIC
AM_LDFLAGS = -static
+endif
+endif
dist_man_MANS = ipset.8