================================================================
FEELING BRAVE?
-1) If you want to try some extensions, you can do the following:
+1) The netfilter core team is maintaining a set of extensions / new
+ features which are not yet committed to the mainstream kernel tree.
+
+If you want to try some extensions, you can do the following:
% make patch-o-matic KERNEL_DIR=<<where-your-kernel-is>>
-This offers you a collection of maybe-broken maybe-cool third-part
+This offers you a collection of maybe-broken maybe-cool third-party
extensions. It will modify you kernel source (so back it up first!).
-
-2) If you want to test out `iptables-save' and `iptables-restore', you
-can use
- % make experimental
- % make install-experimental
+Most of them will require you to recompile / rebuild your kernel and
+modules.
================================================================
PROBLEMS YOU MAY ENCOUNTER:
% make BINDIR=/usr/bin LIBDIR=/usr/lib MANDIR=/usr/man
# make BINDIR=/usr/bin LIBDIR=/usr/lib MANDIR=/usr/man install
+4) If you want to build a statically linked version of the iptables binary,
+ without the need for loading the plugins at runtime (e.g. for an embedded
+ device or router-on-a-disk), please use
+
+ % make NO_SHARED_LIBS=1
+
NOTE: make sure you build with at least the correct LIBDIR=
specification, otherwise iptables(8) won't know where to find the
dynamic objects.
# Standard part of Makefile for topdir.
TOPLEVEL_INCLUDED=YES
+# uncomment this to get a fully statically linked version
+# NO_SHARED_LIBS = 1
+
ifndef KERNEL_DIR
KERNEL_DIR=/usr/src/linux
endif
COPT_FLAGS:=-O2 -DNDEBUG
CFLAGS:=$(COPT_FLAGS) -Wall -Wunused -I$(KERNEL_DIR)/include -Iinclude/ -DNETFILTER_VERSION=\"$(NETFILTER_VERSION)\" #-g #-pg
+ifdef NO_SHARED_LIBS
+CFLAGS += -DNO_SHARED_LIBS=1
+endif
+
+ifndef NO_SHARED_LIBS
DEPFILES = $(SHARED_LIBS:%.so=%.d)
SH_CFLAGS:=$(CFLAGS) -fPIC
+STATIC_LIBS =
+STATIC6_LIBS =
+LDFLAGS = -rdynamic
+LDLIBS = -ldl
+else
+DEPFILES = $(EXT_OBJS:%.o=%.d)
+STATIC_LIBS = extensions/libext.a
+STATIC6_LIBS = extensions/libext6.a
+LDFLAGS =
+LDLIBS =
+endif
EXTRAS+=iptables iptables.o
EXTRA_INSTALLS+=$(DESTDIR)$(BINDIR)/iptables $(DESTDIR)$(MANDIR)/man8/iptables.8
iptables.o: iptables.c
$(CC) $(CFLAGS) -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\" -c -o $@ $<
-iptables: iptables-standalone.c iptables.o libiptc/libiptc.a
- $(CC) $(CFLAGS) -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\" -rdynamic -o $@ $^ -ldl
+iptables: iptables-standalone.c iptables.o $(STATIC_LIBS) libiptc/libiptc.a
+ $(CC) $(CFLAGS) -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\" $(LDFLAGS) -o $@ $^ $(LDLIBS)
$(DESTDIR)$(BINDIR)/iptables: iptables
@[ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR)
cp $< $@
-iptables-save: iptables-save.c iptables.o libiptc/libiptc.a
- $(CC) $(CFLAGS) -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\" -rdynamic -o $@ $^ -ldl
+iptables-save: iptables-save.c iptables.o $(STATIC_LIBS) libiptc/libiptc.a
+ $(CC) $(CFLAGS) -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\" $(LDFLAGS) -o $@ $^ $(LDLIBS)
$(DESTDIR)$(BINDIR)/iptables-save: iptables-save
@[ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR)
cp $< $@
-iptables-restore: iptables-restore.c iptables.o libiptc/libiptc.a
- $(CC) $(CFLAGS) -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\" -rdynamic -o $@ $^ -ldl
+iptables-restore: iptables-restore.c iptables.o $(STATIC_LIBS) libiptc/libiptc.a
+ $(CC) $(CFLAGS) -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\" $(LDFLAGS) -o $@ $^ $(LDLIBS)
$(DESTDIR)$(BINDIR)/iptables-restore: iptables-restore
@[ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR)
ip6tables.o: ip6tables.c
$(CC) $(CFLAGS) -DIP6T_LIB_DIR=\"$(IPT_LIBDIR)\" -c -o $@ $<
-ip6tables: ip6tables-standalone.c ip6tables.o libiptc/libiptc.a
- $(CC) $(CFLAGS) -DIP6T_LIB_DIR=\"$(IPT_LIBDIR)\" -rdynamic -o $@ $^ -ldl
+ip6tables: ip6tables-standalone.c ip6tables.o $(STATIC6_LIBS) libiptc/libiptc.a
+ $(CC) $(CFLAGS) -DIP6T_LIB_DIR=\"$(IPT_LIBDIR)\" -rdynamic -o $@ $^ $(LD_LIBS)
$(DESTDIR)$(BINDIR)/ip6tables: ip6tables
@[ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR)
cp $< $@
-ip6tables-save: ip6tables-save.c ip6tables.o libiptc/libiptc.a
- $(CC) $(CFLAGS) -DIP6T_LIB_DIR=\"$(IPT_LIBDIR)\" -rdynamic -o $@ $^ -ldl
+ip6tables-save: ip6tables-save.c ip6tables.o $(STATIC6_LIBS) libiptc/libiptc.a
+ $(CC) $(CFLAGS) -DIP6T_LIB_DIR=\"$(IPT_LIBDIR)\" -rdynamic -o $@ $^ $(LD_LIBS)
$(DESTDIR)$(BINDIR)/ip6tables-save: ip6tables-save
@[ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR)
cp $< $@
-ip6tables-restore: ip6tables-restore.c ip6tables.o libiptc/libiptc.a
- $(CC) $(CFLAGS) -DIP6T_LIB_DIR=\"$(IPT_LIBDIR)\" -rdynamic -o $@ $^ -ldl
+ip6tables-restore: ip6tables-restore.c ip6tables.o $(STATIC6_LIBS) libiptc/libiptc.a
+ $(CC) $(CFLAGS) -DIP6T_LIB_DIR=\"$(IPT_LIBDIR)\" -rdynamic -o $@ $^ $(LD_LIBS)
$(DESTDIR)$(BINDIR)/ip6tables-restore: ip6tables-restore
@[ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR)
# Have to handle extensions which no longer exist.
clean: $(EXTRA_CLEANS)
rm -f $(SHARED_LIBS) $(EXTRAS) $(EXTRAS_EXP) $(SHARED_LIBS:%.so=%_sh.o)
+ rm -f extensions/initext.c extensions/initext6.c
@find . -name '*.[ao]' -o -name '*.so' | xargs rm -f
install: all $(EXTRA_INSTALLS)
OPTIONALS+=$(patsubst %,IPv4:%,$(PF_EXT_SLIB_OPTS))
OPTIONALS+=$(patsubst %,IPv6:%,$(PF6_EXT_SLIB_OPTS))
+ifndef NO_SHARED_LIBS
SHARED_LIBS+=$(foreach T,$(PF_EXT_SLIB),extensions/libipt_$(T).so)
EXTRA_INSTALLS+=$(foreach T, $(PF_EXT_SLIB), $(DESTDIR)$(LIBDIR)/iptables/libipt_$(T).so)
SHARED_LIBS+=$(foreach T,$(PF6_EXT_SLIB),extensions/libip6t_$(T).so)
EXTRA_INSTALLS+=$(foreach T, $(PF6_EXT_SLIB), $(DESTDIR)$(LIBDIR)/iptables/libip6t_$(T).so)
endif
+else # NO_SHARED_LIBS
+EXT_OBJS+=$(foreach T,$(PF_EXT_SLIB),extensions/libipt_$(T).o)
+EXT_FUNC+=$(foreach T,$(PF_EXT_SLIB),ipt_$(T))
+EXT_OBJS+= extensions/initext.o
+EXT6_OBJS+=$(foreach T,$(PF6_EXT_SLIB),extensions/libip6t_$(T).o)
+EXT6_FUNC+=$(foreach T,$(PF6_EXT_SLIB),ip6t_$(T))
+EXT6_OBJS+= extensions/initext6.o
+endif
ifndef TOPLEVEL_INCLUDED
local:
cd .. && $(MAKE) $(SHARED_LIBS)
endif
+ifdef NO_SHARED_LIBS
+extensions/libext.a: $(EXT_OBJS)
+ rm -f $@; ar crv $@ $(EXT_OBJS)
+
+extensions/libext6.a: $(EXT6_OBJS)
+ rm -f $@; ar crv $@ $(EXT6_OBJS)
+
+extensions/initext.o: extensions/initext.c
+extensions/initext6.o: extensions/initext6.c
+
+extensions/initext.c: extensions/Makefile
+ echo "" > $@
+ for i in $(EXT_FUNC); do \
+ echo "extern void $${i}_init(void);" >> $@; \
+ done
+ echo "void init_extensions(void) {" >> $@
+ for i in $(EXT_FUNC); do \
+ echo " $${i}_init();" >> $@; \
+ done
+ echo "}" >> $@
+
+extensions/initext6.c: extensions/Makefile
+ echo "" > $@
+ for i in $(EXT6_FUNC); do \
+ echo "extern void $${i}_init(void);" >> $@; \
+ done
+ echo "void init_extensions(void) {" >> $@
+ for i in $(EXT6_FUNC); do \
+ echo " $${i}_init();" >> $@; \
+ done
+ echo "}" >> $@
+
+extensions/lib%.o: extensions/lib%.c
+ $(CC) $(CFLAGS) -D_INIT=$*_init -c -o $@ $<
+
+endif
+
$(DESTDIR)$(LIBDIR)/iptables/libipt_%.so: extensions/libipt_%.so
@[ -d $(DESTDIR)$(LIBDIR)/iptables ] || mkdir -p $(DESTDIR)$(LIBDIR)/iptables
cp $< $@
printf("--log-ip-options ");
}
+static
struct ip6tables_target log
= { NULL,
"LOG",
printf("--set-mark 0x%lx ", markinfo->mark);
}
+static
struct ip6tables_target mark
= { NULL,
"MARK",
/* printf("--agr "); */
}
+static
struct ip6tables_match agr
= { NULL,
"agr",
{
}
-struct ip6tables_match icmpv6
+static struct ip6tables_match icmpv6
= { NULL,
"icmpv6",
NETFILTER_VERSION,
printf("--limit-burst %u ", r->burst);
}
+static
struct ip6tables_match limit
= { NULL,
"limit",
((struct ip6t_mac_info *)match->data)->invert);
}
+static
struct ip6tables_match mac
= { NULL,
"mac",
((struct ip6t_mark_info *)match->data)->invert, 0);
}
+static
struct ip6tables_match mark
= { NULL,
"mark",
printf(" ");
}
+static
struct ip6tables_match multiport
= { NULL,
"multiport",
print_item(info, IP6T_OWNER_SID, 0, "--sid-owner ");
}
+static
struct ip6tables_match owner
= { NULL,
"owner",
{
}
+static
struct ip6tables_target standard
= { NULL,
"standard",
}
}
+static
struct ip6tables_match tcp
= { NULL,
"tcp",
}
}
+static
struct ip6tables_match udp
= { NULL,
"udp",
printf("-%s ", addr_to_dotted(&a));
}
+static
struct iptables_target balance
= { NULL,
"BALANCE",
}
}
+static
struct iptables_target dnat
= { NULL,
"DNAT",
printf("--set-ftos 0x%02x ", finfo->ftos);
}
+static
struct iptables_target ftos
= { NULL,
"FTOS",
printf("--log-ip-options ");
}
+static
struct iptables_target log
= { NULL,
"LOG",
printf("--set-mark 0x%lx ", markinfo->mark);
}
+static
struct iptables_target mark
= { NULL,
"MARK",
}
}
+static
struct iptables_target masq
= { NULL,
"MASQUERADE",
{
}
+static
struct iptables_target mirror
= { NULL,
"MIRROR",
printf("nlsize %i ", nld->size);
}
+static
struct iptables_target netlink = { NULL,
"NETLINK",
NETFILTER_VERSION,
print(ip, target, 0);
}
+static
struct iptables_target target_module
= { NULL,
MODULENAME,
}
}
+static
struct iptables_target ipt_pool_target
= { NULL,
"POOL",
}
}
+static
struct iptables_target redir
= { NULL,
"REDIRECT",
printf("--reject-with %s ", reject_table[i].name);
}
+static
struct iptables_target reject
= { NULL,
"REJECT",
printf("--nodst ");
}
+static
struct iptables_target same
= { NULL,
"SAME",
}
}
+static
struct iptables_target snat
= { NULL,
"SNAT",
printf("--set-mss %u ", mssinfo->mss);
}
+static
struct iptables_target mss
= { NULL,
"TCPMSS",
};
/* TOS names and values. */
+static
struct TOS_value
{
unsigned char TOS;
printf("--set-tos 0x%02x ", tosinfo->tos);
}
+static
struct iptables_target tos
= { NULL,
"TOS",
{ 0 }
};
+static
struct iptables_target TTL = { NULL,
"TTL",
NETFILTER_VERSION,
printf("queue_threshold %d ", loginfo->qthreshold);
}
+static
struct iptables_target ulog = { NULL,
"ULOG",
NETFILTER_VERSION,
}
+static
struct iptables_match ah
= { NULL,
"ah",
printf("--iplimit-mask %d ",count_bits(info->mask));
}
+static
static struct iptables_match iplimit = {
name: "iplimit",
version: NETFILTER_VERSION,
}
+static
struct iptables_match esp
= { NULL,
"esp",
{
}
+static
struct iptables_match icmp
= { NULL,
"icmp",
printf(" ");
}
+static
struct iptables_match ipv4options_struct
= { NULL,
"ipv4options",
print_length((struct ipt_length_info *)match->data);
}
+static
struct iptables_match length
= { NULL,
"length",
printf("--limit-burst %u ", r->burst);
}
+static
struct iptables_match limit
= { NULL,
"limit",
((struct ipt_mac_info *)match->data)->invert);
}
+static
struct iptables_match mac
= { NULL,
"mac",
((struct ipt_mark_info *)match->data)->invert, 0);
}
+static
struct iptables_match mark
= { NULL,
"mark",
printf(" ");
}
+static
struct iptables_match multiport
= { NULL,
"multiport",
print_item(info, IPT_OWNER_SID, 0, "--sid-owner ");
}
+static
struct iptables_match owner
= { NULL,
"owner",
print_pkttype(info);
}
+static
struct iptables_match pkttype = {
NULL,
"pkttype",
ip_pool_get_name(buf, sizeof(buf), info->dst, 0));
}
+static
struct iptables_match pool
= { NULL,
"pool",
printf("--psd-hi-ports-weight %u ",psdinfo->hi_ports_weight);
}
+static
struct iptables_match psd
= { NULL,
"psd",
{
}
+static
struct iptables_match record_rpc
= { NULL,
"record_rpc",
{
}
+static
struct iptables_target standard
= { NULL,
"standard",
print_state(sinfo->statemask);
}
+static
struct iptables_match state
= { NULL,
"state",
((struct ipt_string_info *)match->data)->invert, 0);
}
+static
struct iptables_match string
= { NULL,
"string",
}
}
+static
struct iptables_match tcp
= { NULL,
"tcp",
mssinfo->invert, 0);
}
+static
struct iptables_match tcpmss
= { NULL,
"tcpmss",
printf(" ");
}
+static
struct iptables_match timestruct
= { NULL,
"time",
#include <linux/netfilter_ipv4/ipt_tos.h>
/* TOS names and values. */
+static
struct TOS_value
{
unsigned char TOS;
((struct ipt_tos_info *)match->data)->invert, 0);
}
+static
struct iptables_match tos
= { NULL,
"tos",
{ 0 }
};
+static
struct iptables_match ttl = {
NULL,
"ttl",
}
}
+static
struct iptables_match udp
= { NULL,
"udp",
{
}
+static
struct iptables_match unclean
= { NULL,
"unclean",
struct ip6t_entry_match *m;
unsigned int mflags;
unsigned int used;
+#ifdef NO_SHARED_LIBS
+ unsigned int loaded; /* simulate loading so options are merged properly */
+#endif
};
struct ip6tables_target
struct ip6t_entry_target *t;
unsigned int tflags;
unsigned int used;
+#ifdef NO_SHARED_LIBS
+ unsigned int loaded; /* simulate loading so options are merged properly */
+#endif
};
/* Your shared library should call one of these. */
struct ipt_entry_match *m;
unsigned int mflags;
unsigned int used;
+#ifdef NO_SHARED_LIBS
+ unsigned int loaded; /* simulate loading so options are merged properly */
+#endif
};
struct iptables_target
struct ipt_entry_target *t;
unsigned int tflags;
unsigned int used;
+#ifdef NO_SHARED_LIBS
+ unsigned int loaded; /* simulate loading so options are merged properly */
+#endif
};
/* Your shared library should call one of these. */
format(printf,2,3)));
extern const char *program_name, *program_version;
+#ifdef NO_SHARED_LIBS
+# ifdef _INIT
+# define _init _INIT
+# endif
+ extern void init_extensions(void);
+#endif
+
#endif /*_IPTABLES_COMMON_H*/
program_name = "ip6tables-restore";
program_version = NETFILTER_VERSION;
+#ifdef NO_SHARED_LIBS
+ init_extensions();
+#endif
+
while ((c = getopt_long(argc, argv, "bcvhnM:", options, NULL)) != -1) {
switch (c) {
case 'b':
program_name = "ip6tables-save";
program_version = NETFILTER_VERSION;
+#ifdef NO_SHARED_LIBS
+ init_extensions();
+#endif
+
while ((c = getopt_long(argc, argv, "bc", options, NULL)) != -1) {
switch (c) {
case 'b':
program_name = "ip6tables";
program_version = NETFILTER_VERSION;
+#ifdef NO_SHARED_LIBS
+ init_extensions();
+#endif
+
ret = do_command6(argc, argv, &table, &handle);
if (ret)
ret = ip6tc_commit(&handle);
break;
}
+#ifndef NO_SHARED_LIBS
if (!ptr && tryload != DONT_LOAD) {
char path[sizeof(IP6T_LIB_DIR) + sizeof("/libip6t_.so")
+ strlen(name)];
exit_error(PARAMETER_PROBLEM,
"Couldn't load match `%s'\n", name);
}
+#else
+ if (ptr && !ptr->loaded) {
+ if (tryload != DONT_LOAD)
+ ptr->loaded = 1;
+ else
+ ptr = NULL;
+ }
+#endif
if (ptr)
ptr->used = 1;
break;
}
+#ifndef NO_SHARED_LIBS
if (!ptr && tryload != DONT_LOAD) {
char path[sizeof(IP6T_LIB_DIR) + sizeof("/libip6t_.so")
+ strlen(name)];
"Couldn't load target `%s'%s\n",
name, dlerror());
}
+#else
+ if (ptr && !ptr->loaded) {
+ if (tryload != DONT_LOAD)
+ ptr->loaded = 1;
+ else
+ ptr = NULL;
+ }
+#endif
if (ptr)
ptr->used = 1;
*
* This coude is distributed under the terms of GNU GPL
*
- * $Id: iptables-restore.c,v 1.12 2001/05/26 04:41:56 laforge Exp $
+ * $Id: iptables-restore.c,v 1.13 2001/06/16 18:25:25 laforge Exp $
*/
#include <getopt.h>
program_name = "iptables-restore";
program_version = NETFILTER_VERSION;
+#ifdef NO_SHARED_LIBS
+ init_extensions();
+#endif
+
while ((c = getopt_long(argc, argv, "bcvhnM:", options, NULL)) != -1) {
switch (c) {
case 'b':
program_name = "iptables-save";
program_version = NETFILTER_VERSION;
+#ifdef NO_SHARED_LIBS
+ init_extensions();
+#endif
+
while ((c = getopt_long(argc, argv, "bc", options, NULL)) != -1) {
switch (c) {
case 'b':
program_name = "iptables";
program_version = NETFILTER_VERSION;
+#ifdef NO_SHARED_LIBS
+ init_extensions();
+#endif
+
ret = do_command(argc, argv, &table, &handle);
if (ret)
ret = iptc_commit(&handle);
break;
}
+#ifndef NO_SHARED_LIBS
if (!ptr && tryload != DONT_LOAD) {
char path[sizeof(IPT_LIB_DIR) + sizeof("/libipt_.so")
+ strlen(name)];
"Couldn't load match `%s':%s\n",
name, dlerror());
}
+#else
+ if (ptr && !ptr->loaded) {
+ if (tryload != DONT_LOAD)
+ ptr->loaded = 1;
+ else
+ ptr = NULL;
+ }
+#endif
if (ptr)
ptr->used = 1;
break;
}
+#ifndef NO_SHARED_LIBS
if (!ptr && tryload != DONT_LOAD) {
char path[sizeof(IPT_LIB_DIR) + sizeof("/libipt_.so")
+ strlen(name)];
"Couldn't load target `%s':%s\n",
name, dlerror());
}
+#else
+ if (ptr && !ptr->loaded) {
+ if (tryload != DONT_LOAD)
+ ptr->loaded = 1;
+ else
+ ptr = NULL;
+ }
+#endif
if (ptr)
ptr->used = 1;