Compare commits

..

61 Commits
v1.15 ... v1.18

Author SHA1 Message Date
Jan Engelhardt
26f25a43a9 Xtables-addons 1.18 2009-09-09 17:37:07 +02:00
Jan Engelhardt
bcda21a2b0 Merge branch 'psd' 2009-09-09 17:27:28 +02:00
Jan Engelhardt
4e6bc8af95 Merge branch 'ACCOUNT' 2009-09-09 17:26:00 +02:00
Jan Engelhardt
bd4be0d991 ACCOUNT: remove pointless casts 2009-09-05 04:39:00 +02:00
Jan Engelhardt
1f736c8203 ACCOUNT: remove static initializers to zero
These are not needed, .bss is zeroed.
2009-09-05 04:39:00 +02:00
Jan Rafaj
90fa3ab9e2 ACCOUNT: tweak base ctl number for setsockopts
IPT_BASE_CTL+3 is already used IPT_SO_GET_REVISION_TARGET and
therefore must not be used by extensions.
2009-09-05 04:38:57 +02:00
Jan Engelhardt
fd82a312d6 Merge branch 'ipset' 2009-09-05 03:49:47 +02:00
Jan Engelhardt
27c1676821 ipset: fix compile error with 2.6.20
$e/ipset/ip_set_iptree.c: In function "iptree_test":
$e/ipset/ip_set_iptree.c:84:6: warning: implicit declaration of
function "time_after"
$e/ipset/ip_set_iptree.c:84:39: error: "jiffies" undeclared (first
use in this function)
$e/ipset/ip_set_iptree.c:84:39: error: (Each undeclared identifier is
reported only once
$e/ipset/ip_set_iptree.c:84:39: error: for each function it appears
in.)
$e/ipset/ip_set_iptree.c: In function "iptree_add":
$e/ipset/ip_set_iptree.c:130:57: error: "jiffies" undeclared (first
use in this function)
$e/ipset/ip_set_iptree.c:134:48: error: "HZ" undeclared (first use in
this function)
$e/ipset/ip_set_iptree.c: In function "ip_tree_gc":
$e/ipset/ip_set_iptree.c:214:8: warning: implicit declaration of
function "time_before"
$e/ipset/ip_set_iptree.c:214:42: error: "jiffies" undeclared (first
use in this function)
$e/ipset/ip_set_iptree.c:258:49: error: "HZ" undeclared (first use in
this function)
$e/ipset/ip_set_iptree.c: In function "init_gc_timer":
$e/ipset/ip_set_iptree.c:274:20: error: "jiffies" undeclared (first
use in this function)
$e/ipset/ip_set_iptree.c:274:49: error: "HZ" undeclared (first use in
this function)
$e/ipset/ip_set_iptree.c: In function "iptree_list_members_size":
$e/ipset/ip_set_iptree.c:380:58: error: "jiffies" undeclared (first
use in this function)
$e/ipset/ip_set_iptree.c: In function "iptree_list_members":
$e/ipset/ip_set_iptree.c:407:58: error: "jiffies" undeclared (first
use in this function)
$e/ipset/ip_set_iptree.c:411:37: error: "HZ" undeclared (first use in
this function)

$e/ipset/ip_set_iptreemap.c: In function "gc":
$e/ipset/ip_set_iptreemap.c:456:20: error: "jiffies" undeclared
(first use in this function)
$e/ipset/ip_set_iptreemap.c:456:20: error: (Each undeclared
identifier is reported only once
$e/ipset/ip_set_iptreemap.c:456:20: error: for each function it
appears in.)
$e/ipset/ip_set_iptreemap.c:456:49: error: "HZ" undeclared (first use
in this function)
$e/ipset/ip_set_iptreemap.c: In function "init_gc_timer":
$e/ipset/ip_set_iptreemap.c:468:20: error: "jiffies" undeclared
(first use in this function)
$e/ipset/ip_set_iptreemap.c:468:49: error: "HZ" undeclared (first use
in this function)
2009-09-05 03:49:37 +02:00
Jan Engelhardt
3e26335cbd ipset: fast forward to v3.2 2009-09-05 03:49:37 +02:00
Jan Rafaj
f4b96672ef ACCOUNT: add kernel module metadata and alias 2009-09-05 03:40:47 +02:00
Jan Engelhardt
c3d080f21a ACCOUNT: manpage updates
- expand "f.e."
- escape dashes where appropriate
- fB/fI formatting
2009-09-05 03:40:47 +02:00
Jan Rafaj
cb268031b7 ACCOUNT: supply manpage 2009-09-05 03:40:47 +02:00
Jan Engelhardt
ac44a5a1fe ACCOUNT: direct-inline two short functions 2009-09-05 03:40:47 +02:00
Jan Rafaj
a3baa78ae2 ACCOUNT: remove compat glue from libxt_ACCOUNT 2009-09-05 03:40:47 +02:00
Jan Rafaj
47e002127c ACCOUNT: use non-clashing function names
[jengelh: It is just impossible to set a breakpoint right on functions
if all modules call or/use the same symbol name.]
2009-09-05 03:40:47 +02:00
Jan Rafaj
03363a528a ACCOUNT: utilize compat_xtables.h for backwards compatibility 2009-09-05 03:40:47 +02:00
Jan Rafaj
58b016f0af ACCOUNT: replace own DEBUGP by kernel's pr_debug 2009-09-05 03:40:47 +02:00
Jan Rafaj
8d64e7bd50 ACCOUNT: remove manual compat support 2009-09-05 03:40:47 +02:00
Jan Engelhardt
dd6cb27da4 ACCOUNT: simple reformat, use tabs instead of spaces
The result is not perfect, but at more manageable.
2009-09-05 03:40:46 +02:00
Jan Engelhardt
06c01131e8 ACCOUNT: remove trailing whitespace 2009-09-05 03:38:58 +02:00
Jan Engelhardt
a44c4e4b1d Import ACCOUNT kernel and iptables modules
Reference: git://developer.intra2net.com/ipt_ACCOUNT # v1.15-1-gfb4dd1a
2009-09-05 03:38:31 +02:00
Jan Engelhardt
1fb6f187d3 build: enable fully parallel builds
Make make happy by using ${MAKE} instead of make.
2009-08-28 12:32:52 +02:00
Jan Engelhardt
83e474f9ab psd: move pr_ prefix into pr_fmt 2009-08-28 12:32:23 +02:00
Jan Engelhardt
efd4c91557 psd: style: remove braces for single statements in ifs 2009-08-16 12:40:44 +02:00
Jan Engelhardt
65a257a67d psd: style: add explicit comparisons where not used in bool context 2009-08-14 20:26:37 +02:00
Jan Engelhardt
5b07e04600 psd: style: break double statements 2009-08-14 20:24:36 +02:00
Jan Engelhardt
6b175b40cb psd: jiffies is an unsigned long, fix compiler warning
"jiffies" has always been unsigned long, not clock_t.

xt_psd.c:176:7: warning: comparison of distinct pointer types lacks a cast
2009-08-14 20:19:13 +02:00
Jan Engelhardt
0887365f8b psd: remove whitespace at EOL 2009-08-14 20:15:00 +02:00
Jan Engelhardt
cebadbfcd7 psd: merge into main configuration files
When psd is included in the main tree, it can use the main
configuration files.
2009-08-14 20:12:43 +02:00
Mohd Nawawi Mohamad Jamili
380b1b6997 psd: fix revision mismatch 2009-08-13 13:11:18 +02:00
Jan Engelhardt
8e5219636a psd: tag match reg struct as __read_mostly 2009-08-13 01:04:26 +02:00
Jan Engelhardt
760edd3db6 psd: use fixated types in info struct 2009-08-13 00:52:46 +02:00
Jan Engelhardt
502c1c05aa psd: return correct status from init 2009-08-13 00:46:33 +02:00
Jan Engelhardt
a7ceccc0f4 psd: bss is always zero-initialized 2009-08-13 00:45:52 +02:00
Jan Engelhardt
10bd08d0f3 psd: remove empty checkentry function 2009-08-13 00:44:39 +02:00
Jan Engelhardt
1e5315d338 psd: replace open-coded access by skb handling functions
pskb->network_header would not even compile under older kernels.

This also fixes the compile warning:
xt_psd.c:116:18: warning: cast to pointer from integer of different size
2009-08-13 00:42:01 +02:00
Jan Engelhardt
579484ed70 psd: avoid shadowing of function
ip_hdr and tcp_hdr are actually functions. Because we need them means
they must not be shadowed by variables.
2009-08-13 00:38:39 +02:00
Mohd Nawawi Mohamad Jamili
2aa32d4bce psd: import 20090807 code base 2009-08-12 21:59:33 +02:00
Jan Engelhardt
5aee8738ed quota2: fix invalid page access in cleanup function 2009-08-07 10:35:52 +02:00
Jan Engelhardt
1111edfd85 quota2: change max name length from 31 to 15 2009-07-10 17:21:27 +02:00
Jan Engelhardt
0d47cb8b37 quota2: direct-code XT_QUOTA_COUNTER_NAME_LENGTH 2009-07-10 17:21:12 +02:00
Jan Engelhardt
1c55aec64a quota2: use strtoull instead of strtoul 2009-07-10 17:18:48 +02:00
Jan Engelhardt
dd26ab476c quota2: extend locked period during cleanup 2009-07-04 02:11:25 +02:00
Jan Engelhardt
4bf667d8eb quota2: reduce memory footprint for anonymous counters
48/64 bytes (32/64-bit arch, resp.) per counter.
2009-07-04 01:53:35 +02:00
Jan Engelhardt
0a88bd3435 quota2: consolidate spinlocking calls 2009-07-04 01:31:13 +02:00
Jan Engelhardt
62fb261265 quota2: prefix internal struct name with xt_ 2009-07-04 01:29:32 +02:00
Jan Engelhardt
d97f77a8f5 TEE: spello fix 2009-07-02 04:16:14 +02:00
Jan Engelhardt
822c6bebe2 quota2: support nameless counters 2009-07-02 02:21:11 +02:00
Jan Engelhardt
fdf42a3a50 build: support for Linux 2.6.31-rc1 2009-07-02 01:51:40 +02:00
Jan Engelhardt
6b2ca78af7 build: fix kernel version info 2009-07-02 01:04:48 +02:00
Jan Engelhardt
ee24cd1ac1 Xtables-addons 1.17 2009-06-16 16:25:53 +02:00
kd6lvw
71812a2053 build: support for Linux 2.6.30
Fix a compile error with xt_quota2. Linux kernel commit
v2.6.29-7544-g3ba113d removed the "owner" member.
2009-06-12 03:41:00 +02:00
kd6lvw
31e4e18998 build: use readlink -f in extensions/ipset/
Supplement to v1.5.7-5-gf373750.
2009-06-12 03:37:18 +02:00
Marek Michalkiewicz
9fb2ffe1d3 IPMARK: print missing --shift parameter 2009-06-12 03:33:54 +02:00
Jan Engelhardt
23e83aa04c Xtables-addons 1.16 2009-05-27 14:55:51 +02:00
Jan Engelhardt
77ee63ba8b ipset: fast forward to 3.0 2009-05-27 14:51:15 +02:00
Jan Engelhardt
49e59a6dce RAWNAT: make iptable_rawpost compile with 2.6.30-rc5 2009-05-15 18:35:53 +02:00
Jan Engelhardt
137ecb9814 extensions: bump revision number to avoid possible POM clash
Users still using a kernel with POM modules may have problems due to
differing binary structures. Bump the revision numbers of the
Xtables-addons modules, to make them distinct from POM.
2009-05-14 21:42:05 +02:00
Jan Engelhardt
7e25254e93 SYSRQ: enable userspace module for multiprotocol 2009-05-14 21:39:48 +02:00
Jan Engelhardt
0c9ae3cb1b iface: enable for multiprotocol 2009-05-14 21:38:09 +02:00
Jan Engelhardt
471e747fc0 STEAL: enable for multiprotocol 2009-05-14 21:38:08 +02:00
70 changed files with 2370 additions and 293 deletions

View File

@@ -1,5 +1,5 @@
AC_INIT([xtables-addons], [1.15]) AC_INIT([xtables-addons], [1.18])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
AC_PROG_INSTALL AC_PROG_INSTALL
@@ -79,13 +79,17 @@ krel="${krel#*.}";
kminor="${krel%%.*}"; kminor="${krel%%.*}";
krel="${krel#*.}"; krel="${krel#*.}";
kmicro="${krel%%.*}"; kmicro="${krel%%.*}";
krel="${krel#*.}"; krel2="${krel#*.}";
if test "$krel" = "$krel2"; then
kstable=0;
else
kstable="${krel%%.*}"; kstable="${krel%%.*}";
if test -z "$kstable"; then if test -z "$kstable"; then
kstable=0; kstable=0;
fi; fi;
fi;
echo "Found kernel version $kmajor.$kminor.$kmicro.$kstable in $kbuilddir"; echo "Found kernel version $kmajor.$kminor.$kmicro.$kstable in $kbuilddir";
if test "$kmajor" -gt 2 -o "$kminor" -gt 6 -o "$kmicro" -gt 30; then if test "$kmajor" -gt 2 -o "$kminor" -gt 6 -o "$kmicro" -gt 31; then
echo "WARNING: You are trying a newer kernel. Results may vary. :-)"; echo "WARNING: You are trying a newer kernel. Results may vary. :-)";
elif test \( "$kmajor" -lt 2 -o "$kminor" -lt 6 -o "$kmicro" -lt 17 \) -o \ elif test \( "$kmajor" -lt 2 -o "$kminor" -lt 6 -o "$kmicro" -lt 17 \) -o \
\( "$kmajor" -eq 2 -a "$kminor" -eq 6 -a "$kmicro" -eq 18 -a \ \( "$kmajor" -eq 2 -a "$kminor" -eq 6 -a "$kmicro" -eq 18 -a \

4
doc/README.psd Normal file
View File

@@ -0,0 +1,4 @@
PSD (Portscan Detection) External extensions for Xtables-addons
Example:
iptables -A INPUT -m psd --psd-weight-threshold 21 --psd-delay-threshold 300 --psd-lo-ports-weight 1 --psd-hi-ports-weight 10 -j LOG --log-prefix "PSD: "

View File

@@ -1,5 +1,30 @@
Xtables-addons 1.18 (September 09 2009)
=======================================
- build: support for Linux 2.6.31
- ipset: fast forward to v3.2
- quota2: support anonymous counters
- quota2: reduce memory footprint for anonymous counters
- quota2: extend locked period during cleanup (locking bugfix)
- quota2: use strtoull instead of strtoul
- merged xt_ACCOUNT module
- merged xt_psd module
Xtables-addons 1.17 (June 16 2009)
==================================
- IPMARK: print missing --shift parameter
- build: use readlink -f in extensions/ipset/
- build: support for Linux 2.6.30
Xtables-addons 1.16 (May 27 2009)
=================================
- RAWNAT: make iptable_rawpost compile with 2.6.30-rc5
- ipset: fast forward to 3.0
Xtables-addons 1.15 (April 30 2009) Xtables-addons 1.15 (April 30 2009)
=================================== ===================================
- build: add kernel version check to configure - build: add kernel version check to configure

View File

@@ -31,17 +31,14 @@ AM_CFLAGS := ${regular_CFLAGS} -I${top_srcdir}/include ${xtables_CFLAGS} ${
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@ AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
VU := 0 VU := 0
am__1verbose_CC_0 = @echo " CC " $@; am__v_CC_0 = @echo " CC " $@;
am__1verbose_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_0 = @echo " CCLD " $@;
am__1verbose_GEN_0 = @echo " GEN " $@; am__v_GEN_0 = @echo " GEN " $@;
am__1verbose_SILENT_0 = @ am__v_SILENT_0 = @
am__1verbose_CC_1 = @echo " CC " $@ "<-" $<; AM_V_CC = ${am__v_CC_${VU}}
am__1verbose_CCLD_1 = @echo " CCLD " $@ "<-" $^; AM_V_CCLD = ${am__v_CCLD_${VU}}
am__1verbose_GEN_1 = @echo " GEN " $@ "<-" $<; AM_V_GEN = ${am__v_GEN_${VU}}
am__verbose_CC = ${am__1verbose_CC_${VU}} AM_V_silent = ${am__v_GEN_${VU}}
am__verbose_CCLD = ${am__1verbose_CCLD_${VU}}
am__verbose_GEN = ${am__1verbose_GEN_${VU}}
am__verbose_SILENT = ${am__1verbose_GEN_${VU}}
# #
@@ -80,7 +77,7 @@ install: modules_install subdirs-install ${targets_install}
install -pm0755 ${targets_install} "${DESTDIR}${xtlibdir}/"; install -pm0755 ${targets_install} "${DESTDIR}${xtlibdir}/";
clean: clean_modules clean: clean_modules
@for i in ${subdirs_list}; do make -C $$i clean; done; @for i in ${subdirs_list}; do ${MAKE} -C $$i clean; done;
rm -f *.oo *.so; rm -f *.oo *.so;
distclean: clean distclean: clean
@@ -95,23 +92,23 @@ distclean: clean
.PHONY: modules modules_install clean_modules .PHONY: modules modules_install clean_modules
modules: modules:
${am__verbose_SILENT}if [ -n "${kbuilddir}" ]; then make -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} modules; fi; ${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} modules; fi;
modules_install: modules_install:
${am__verbose_SILENT}if [ -n "${kbuilddir}" ]; then make -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} INSTALL_MOD_PATH=${DESTDIR} modules_install; fi; ${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} INSTALL_MOD_PATH=${DESTDIR} modules_install; fi;
clean_modules: clean_modules:
${am__verbose_SILENT}if [ -n "${kbuilddir}" ]; then make -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} clean; fi; ${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} clean; fi;
# #
# Shared libraries # Shared libraries
# #
lib%.so: lib%.oo lib%.so: lib%.oo
${am__verbose_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<; ${AM_V_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
lib%.oo: ${srcdir}/lib%.c lib%.oo: ${srcdir}/lib%.c
${am__verbose_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=lib$*_init -DPIC -fPIC ${CFLAGS} -o $@ -c $<; ${AM_V_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=lib$*_init -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
# #
@@ -128,7 +125,7 @@ wlist_targets := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_targets})
rm -f $@.tmp; rm -f $@.tmp;
man_run = \ man_run = \
${am__verbose_GEN}for ext in $(1); do \ ${AM_V_GEN}for ext in $(1); do \
f="${srcdir}/libxt_$$ext.man"; \ f="${srcdir}/libxt_$$ext.man"; \
if [ -f "$$f" ]; then \ if [ -f "$$f" ]; then \
echo ".SS $$ext"; \ echo ".SS $$ext"; \

View File

@@ -5,6 +5,7 @@ include ${XA_TOPSRCDIR}/mconfig
obj-m += compat_xtables.o obj-m += compat_xtables.o
obj-${build_ACCOUNT} += xt_ACCOUNT.o
obj-${build_CHAOS} += xt_CHAOS.o obj-${build_CHAOS} += xt_CHAOS.o
obj-${build_DELUDE} += xt_DELUDE.o obj-${build_DELUDE} += xt_DELUDE.o
obj-${build_DHCPMAC} += xt_DHCPMAC.o obj-${build_DHCPMAC} += xt_DHCPMAC.o
@@ -25,6 +26,7 @@ obj-${build_ipset} += ipset/
obj-${build_ipv4options} += xt_ipv4options.o obj-${build_ipv4options} += xt_ipv4options.o
obj-${build_length2} += xt_length2.o obj-${build_length2} += xt_length2.o
obj-${build_lscan} += xt_lscan.o obj-${build_lscan} += xt_lscan.o
obj-${build_psd} += xt_psd.o
obj-${build_quota2} += xt_quota2.o obj-${build_quota2} += xt_quota2.o
-include ${M}/*.Kbuild -include ${M}/*.Kbuild

View File

@@ -1,3 +1,4 @@
obj-${build_ACCOUNT} += libxt_ACCOUNT.so
obj-${build_CHAOS} += libxt_CHAOS.so obj-${build_CHAOS} += libxt_CHAOS.so
obj-${build_DELUDE} += libxt_DELUDE.so obj-${build_DELUDE} += libxt_DELUDE.so
obj-${build_DHCPMAC} += libxt_DHCPMAC.so libxt_dhcpmac.so obj-${build_DHCPMAC} += libxt_DHCPMAC.so libxt_dhcpmac.so
@@ -18,4 +19,5 @@ obj-${build_ipset} += ipset/
obj-${build_ipv4options} += libxt_ipv4options.so obj-${build_ipv4options} += libxt_ipv4options.so
obj-${build_length2} += libxt_length2.so obj-${build_length2} += libxt_length2.so
obj-${build_lscan} += libxt_lscan.so obj-${build_lscan} += libxt_lscan.so
obj-${build_psd} += libxt_psd.so
obj-${build_quota2} += libxt_quota2.so obj-${build_quota2} += libxt_quota2.so

View File

@@ -4,6 +4,23 @@
struct tcphdr; struct tcphdr;
struct udphdr; struct udphdr;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 30)
static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst)
{
skb->dst = dst;
}
static inline struct dst_entry *skb_dst(const struct sk_buff *skb)
{
return skb->dst;
}
static inline struct rtable *skb_rtable(const struct sk_buff *skb)
{
return (void *)skb->dst;
}
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19) #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
# define skb_ifindex(skb) \ # define skb_ifindex(skb) \
(((skb)->input_dev != NULL) ? (skb)->input_dev->ifindex : 0) (((skb)->input_dev != NULL) ? (skb)->input_dev->ifindex : 0)

View File

@@ -69,7 +69,9 @@ static int __init rawpost6_table_init(void)
{ {
int ret; int ret;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 29)
rwlock_init(&rawpost6_itable.lock); rwlock_init(&rawpost6_itable.lock);
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
rawpost6_ptable = ip6t_register_table(&init_net, &rawpost6_itable, rawpost6_ptable = ip6t_register_table(&init_net, &rawpost6_itable,
&rawpost6_initial.repl); &rawpost6_initial.repl);

View File

@@ -3,8 +3,8 @@
top_srcdir := @top_srcdir@ top_srcdir := @top_srcdir@
srcdir := @srcdir@ srcdir := @srcdir@
datarootdir := @datarootdir@ datarootdir := @datarootdir@
abstop_srcdir := $(shell readlink -e ${top_srcdir}) abstop_srcdir := $(shell readlink -f ${top_srcdir})
abssrcdir := $(shell readlink -e ${srcdir}) abssrcdir := $(shell readlink -f ${srcdir})
ifeq (${abstop_srcdir},) ifeq (${abstop_srcdir},)
$(error Path resolution of ${top_srcdir} failed) $(error Path resolution of ${top_srcdir} failed)

View File

@@ -493,7 +493,7 @@ ip_set_find_byindex(ip_set_id_t index)
static inline int static inline int
__ip_set_testip(struct ip_set *set, __ip_set_testip(struct ip_set *set,
const void *data, const void *data,
size_t size, u_int32_t size,
ip_set_ip_t *ip) ip_set_ip_t *ip)
{ {
int res; int res;
@@ -508,7 +508,7 @@ __ip_set_testip(struct ip_set *set,
static int static int
__ip_set_addip(ip_set_id_t index, __ip_set_addip(ip_set_id_t index,
const void *data, const void *data,
size_t size) u_int32_t size)
{ {
struct ip_set *set = ip_set_list[index]; struct ip_set *set = ip_set_list[index];
ip_set_ip_t ip; ip_set_ip_t ip;
@@ -529,15 +529,15 @@ __ip_set_addip(ip_set_id_t index,
static int static int
ip_set_addip(ip_set_id_t index, ip_set_addip(ip_set_id_t index,
const void *data, const void *data,
size_t size) u_int32_t size)
{ {
struct ip_set *set = ip_set_list[index]; struct ip_set *set = ip_set_list[index];
IP_SET_ASSERT(set); IP_SET_ASSERT(set);
if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) { if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) {
ip_set_printk("data length wrong (want %zu, have %zu)", ip_set_printk("data length wrong (want %lu, have %zu)",
set->type->reqsize, (long unsigned)set->type->reqsize,
size - sizeof(struct ip_set_req_adt)); size - sizeof(struct ip_set_req_adt));
return -EINVAL; return -EINVAL;
} }
@@ -549,7 +549,7 @@ ip_set_addip(ip_set_id_t index,
static int static int
ip_set_delip(ip_set_id_t index, ip_set_delip(ip_set_id_t index,
const void *data, const void *data,
size_t size) u_int32_t size)
{ {
struct ip_set *set = ip_set_list[index]; struct ip_set *set = ip_set_list[index];
ip_set_ip_t ip; ip_set_ip_t ip;
@@ -558,8 +558,8 @@ ip_set_delip(ip_set_id_t index,
IP_SET_ASSERT(set); IP_SET_ASSERT(set);
if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) { if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) {
ip_set_printk("data length wrong (want %zu, have %zu)", ip_set_printk("data length wrong (want %lu, have %zu)",
set->type->reqsize, (long unsigned)set->type->reqsize,
size - sizeof(struct ip_set_req_adt)); size - sizeof(struct ip_set_req_adt));
return -EINVAL; return -EINVAL;
} }
@@ -576,7 +576,7 @@ ip_set_delip(ip_set_id_t index,
static int static int
ip_set_testip(ip_set_id_t index, ip_set_testip(ip_set_id_t index,
const void *data, const void *data,
size_t size) u_int32_t size)
{ {
struct ip_set *set = ip_set_list[index]; struct ip_set *set = ip_set_list[index];
ip_set_ip_t ip; ip_set_ip_t ip;
@@ -585,8 +585,8 @@ ip_set_testip(ip_set_id_t index,
IP_SET_ASSERT(set); IP_SET_ASSERT(set);
if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) { if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) {
ip_set_printk("data length wrong (want %zu, have %zu)", ip_set_printk("data length wrong (want %lu, have %zu)",
set->type->reqsize, (long unsigned)set->type->reqsize,
size - sizeof(struct ip_set_req_adt)); size - sizeof(struct ip_set_req_adt));
return -EINVAL; return -EINVAL;
} }
@@ -601,7 +601,7 @@ ip_set_testip(ip_set_id_t index,
static int static int
ip_set_bindip(ip_set_id_t index, ip_set_bindip(ip_set_id_t index,
const void *data, const void *data,
size_t size) u_int32_t size)
{ {
struct ip_set *set = ip_set_list[index]; struct ip_set *set = ip_set_list[index];
const struct ip_set_req_bind *req_bind; const struct ip_set_req_bind *req_bind;
@@ -687,7 +687,7 @@ __unbind_default(struct ip_set *set)
static int static int
ip_set_unbindip(ip_set_id_t index, ip_set_unbindip(ip_set_id_t index,
const void *data, const void *data,
size_t size) u_int32_t size)
{ {
struct ip_set *set; struct ip_set *set;
const struct ip_set_req_bind *req_bind; const struct ip_set_req_bind *req_bind;
@@ -760,7 +760,7 @@ ip_set_unbindip(ip_set_id_t index,
static int static int
ip_set_testbind(ip_set_id_t index, ip_set_testbind(ip_set_id_t index,
const void *data, const void *data,
size_t size) u_int32_t size)
{ {
struct ip_set *set = ip_set_list[index]; struct ip_set *set = ip_set_list[index];
const struct ip_set_req_bind *req_bind; const struct ip_set_req_bind *req_bind;
@@ -862,7 +862,7 @@ ip_set_create(const char *name,
const char *typename, const char *typename,
ip_set_id_t restore, ip_set_id_t restore,
const void *data, const void *data,
size_t size) u_int32_t size)
{ {
struct ip_set *set; struct ip_set *set;
ip_set_id_t index = 0, id; ip_set_id_t index = 0, id;
@@ -915,9 +915,9 @@ ip_set_create(const char *name,
/* Check request size */ /* Check request size */
if (size != set->type->header_size) { if (size != set->type->header_size) {
ip_set_printk("data length wrong (want %zu, have %zu)", ip_set_printk("data length wrong (want %lu, have %lu)",
set->type->header_size, (long unsigned)set->type->header_size,
size); (long unsigned)size);
goto put_out; goto put_out;
} }
@@ -1109,7 +1109,7 @@ ip_set_swap(ip_set_id_t from_index, ip_set_id_t to_index)
static inline void static inline void
__set_hash_bindings_size_list(struct ip_set_hash *set_hash, __set_hash_bindings_size_list(struct ip_set_hash *set_hash,
ip_set_id_t id, size_t *size) ip_set_id_t id, u_int32_t *size)
{ {
if (set_hash->id == id) if (set_hash->id == id)
*size += sizeof(struct ip_set_hash_list); *size += sizeof(struct ip_set_hash_list);
@@ -1117,7 +1117,7 @@ __set_hash_bindings_size_list(struct ip_set_hash *set_hash,
static inline void static inline void
__set_hash_bindings_size_save(struct ip_set_hash *set_hash, __set_hash_bindings_size_save(struct ip_set_hash *set_hash,
ip_set_id_t id, size_t *size) ip_set_id_t id, u_int32_t *size)
{ {
if (set_hash->id == id) if (set_hash->id == id)
*size += sizeof(struct ip_set_hash_save); *size += sizeof(struct ip_set_hash_save);
@@ -1220,7 +1220,7 @@ static int ip_set_save_set(ip_set_id_t index,
*used += sizeof(struct ip_set_save); *used += sizeof(struct ip_set_save);
set = ip_set_list[index]; set = ip_set_list[index];
DP("set: %s, used: %u(%u) %p %p", set->name, *used, len, DP("set: %s, used: %d(%d) %p %p", set->name, *used, len,
data, data + *used); data, data + *used);
read_lock_bh(&set->lock); read_lock_bh(&set->lock);
@@ -1237,8 +1237,8 @@ static int ip_set_save_set(ip_set_id_t index,
set->type->list_header(set, data + *used); set->type->list_header(set, data + *used);
*used += set_save->header_size; *used += set_save->header_size;
DP("set header filled: %s, used: %u(%u) %p %p", set->name, *used, DP("set header filled: %s, used: %d(%lu) %p %p", set->name, *used,
set_save->header_size, data, data + *used); (unsigned long)set_save->header_size, data, data + *used);
/* Get and ensure set specific members size */ /* Get and ensure set specific members size */
set_save->members_size = set->type->list_members_size(set); set_save->members_size = set->type->list_members_size(set);
if (*used + set_save->members_size > len) if (*used + set_save->members_size > len)
@@ -1248,8 +1248,8 @@ static int ip_set_save_set(ip_set_id_t index,
set->type->list_members(set, data + *used); set->type->list_members(set, data + *used);
*used += set_save->members_size; *used += set_save->members_size;
read_unlock_bh(&set->lock); read_unlock_bh(&set->lock);
DP("set members filled: %s, used: %u(%u) %p %p", set->name, *used, DP("set members filled: %s, used: %d(%lu) %p %p", set->name, *used,
set_save->members_size, data, data + *used); (unsigned long)set_save->members_size, data, data + *used);
return 0; return 0;
unlock_set: unlock_set:
@@ -1329,7 +1329,7 @@ static int ip_set_restore(void *data,
while (1) { while (1) {
line++; line++;
DP("%u %u %u", used, sizeof(struct ip_set_restore), len); DP("%d %zu %d", used, sizeof(struct ip_set_restore), len);
/* Get and ensure header size */ /* Get and ensure header size */
if (used + sizeof(struct ip_set_restore) > len) if (used + sizeof(struct ip_set_restore) > len)
return line; return line;
@@ -1367,12 +1367,13 @@ static int ip_set_restore(void *data,
/* Try to restore members data */ /* Try to restore members data */
set = ip_set_list[index]; set = ip_set_list[index];
members_size = 0; members_size = 0;
DP("members_size %u reqsize %u", DP("members_size %lu reqsize %lu",
set_restore->members_size, set->type->reqsize); (unsigned long)set_restore->members_size,
(unsigned long)set->type->reqsize);
while (members_size + set->type->reqsize <= while (members_size + set->type->reqsize <=
set_restore->members_size) { set_restore->members_size) {
line++; line++;
DP("members: %u, line %u", members_size, line); DP("members: %d, line %d", members_size, line);
res = __ip_set_addip(index, res = __ip_set_addip(index,
data + used + members_size, data + used + members_size,
set->type->reqsize); set->type->reqsize);
@@ -1381,8 +1382,8 @@ static int ip_set_restore(void *data,
members_size += set->type->reqsize; members_size += set->type->reqsize;
} }
DP("members_size %u %u", DP("members_size %lu %d",
set_restore->members_size, members_size); (unsigned long)set_restore->members_size, members_size);
if (members_size != set_restore->members_size) if (members_size != set_restore->members_size)
return line++; return line++;
used += set_restore->members_size; used += set_restore->members_size;
@@ -1442,10 +1443,10 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
struct ip_set_req_adt *req_adt; struct ip_set_req_adt *req_adt;
ip_set_id_t index = IP_SET_INVALID_ID; ip_set_id_t index = IP_SET_INVALID_ID;
int (*adtfn)(ip_set_id_t index, int (*adtfn)(ip_set_id_t index,
const void *data, size_t size); const void *data, u_int32_t size);
struct fn_table { struct fn_table {
int (*fn)(ip_set_id_t index, int (*fn)(ip_set_id_t index,
const void *data, size_t size); const void *data, u_int32_t size);
} adtfn_table[] = } adtfn_table[] =
{ { ip_set_addip }, { ip_set_delip }, { ip_set_testip}, { { ip_set_addip }, { ip_set_delip }, { ip_set_testip},
{ ip_set_bindip}, { ip_set_unbindip }, { ip_set_testbind }, { ip_set_bindip}, { ip_set_unbindip }, { ip_set_testbind },
@@ -1910,13 +1911,23 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
res = -ENOENT; res = -ENOENT;
goto done; goto done;
} }
#define SETLIST(set) (strcmp(set->type->typename, "setlist") == 0)
used = 0; used = 0;
if (index == IP_SET_INVALID_ID) { if (index == IP_SET_INVALID_ID) {
/* Save all sets */ /* Save all sets: ugly setlist type dependency */
int setlist = 0;
setlists:
for (i = 0; i < ip_set_max && res == 0; i++) { for (i = 0; i < ip_set_max && res == 0; i++) {
if (ip_set_list[i] != NULL) if (ip_set_list[i] != NULL
&& !(setlist ^ SETLIST(ip_set_list[i])))
res = ip_set_save_set(i, data, &used, *len); res = ip_set_save_set(i, data, &used, *len);
} }
if (!setlist) {
setlist = 1;
goto setlists;
}
} else { } else {
/* Save an individual set */ /* Save an individual set */
res = ip_set_save_set(index, data, &used, *len); res = ip_set_save_set(index, data, &used, *len);
@@ -1938,14 +1949,14 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
if (*len < sizeof(struct ip_set_req_setnames) if (*len < sizeof(struct ip_set_req_setnames)
|| *len != req_restore->size) { || *len != req_restore->size) {
ip_set_printk("invalid RESTORE (want =%zu, got %d)", ip_set_printk("invalid RESTORE (want =%lu, got %d)",
req_restore->size, *len); (long unsigned)req_restore->size, *len);
res = -EINVAL; res = -EINVAL;
goto done; goto done;
} }
line = ip_set_restore(data + sizeof(struct ip_set_req_setnames), line = ip_set_restore(data + sizeof(struct ip_set_req_setnames),
req_restore->size - sizeof(struct ip_set_req_setnames)); req_restore->size - sizeof(struct ip_set_req_setnames));
DP("ip_set_restore: %u", line); DP("ip_set_restore: %d", line);
if (line != 0) { if (line != 0) {
res = -EAGAIN; res = -EAGAIN;
req_restore->size = line; req_restore->size = line;
@@ -1960,7 +1971,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
} /* end of switch(op) */ } /* end of switch(op) */
copy: copy:
DP("set %s, copylen %u", index != IP_SET_INVALID_ID DP("set %s, copylen %d", index != IP_SET_INVALID_ID
&& ip_set_list[index] && ip_set_list[index]
? ip_set_list[index]->name ? ip_set_list[index]->name
: ":all:", copylen); : ":all:", copylen);

View File

@@ -48,7 +48,7 @@
/* /*
* Used so that the kernel module and ipset-binary can match their versions * Used so that the kernel module and ipset-binary can match their versions
*/ */
#define IP_SET_PROTOCOL_VERSION 2 #define IP_SET_PROTOCOL_VERSION 3
#define IP_SET_MAXNAMELEN 32 /* set names and set typenames */ #define IP_SET_MAXNAMELEN 32 /* set names and set typenames */
@@ -236,7 +236,7 @@ struct ip_set_req_max_sets {
struct ip_set_req_setnames { struct ip_set_req_setnames {
unsigned op; unsigned op;
ip_set_id_t index; /* set to list/save */ ip_set_id_t index; /* set to list/save */
size_t size; /* size to get setdata/bindings */ u_int32_t size; /* size to get setdata/bindings */
/* followed by sets number of struct ip_set_name_list */ /* followed by sets number of struct ip_set_name_list */
}; };
@@ -258,9 +258,9 @@ struct ip_set_list {
ip_set_id_t index; ip_set_id_t index;
ip_set_id_t binding; ip_set_id_t binding;
u_int32_t ref; u_int32_t ref;
size_t header_size; /* Set header data of header_size */ u_int32_t header_size; /* Set header data of header_size */
size_t members_size; /* Set members data of members_size */ u_int32_t members_size; /* Set members data of members_size */
size_t bindings_size; /* Set bindings data of bindings_size */ u_int32_t bindings_size;/* Set bindings data of bindings_size */
}; };
struct ip_set_hash_list { struct ip_set_hash_list {
@@ -277,8 +277,8 @@ struct ip_set_hash_list {
struct ip_set_save { struct ip_set_save {
ip_set_id_t index; ip_set_id_t index;
ip_set_id_t binding; ip_set_id_t binding;
size_t header_size; /* Set header data of header_size */ u_int32_t header_size; /* Set header data of header_size */
size_t members_size; /* Set members data of members_size */ u_int32_t members_size; /* Set members data of members_size */
}; };
/* At restoring, ip == 0 means default binding for the given set: */ /* At restoring, ip == 0 means default binding for the given set: */
@@ -298,8 +298,8 @@ struct ip_set_restore {
char name[IP_SET_MAXNAMELEN]; char name[IP_SET_MAXNAMELEN];
char typename[IP_SET_MAXNAMELEN]; char typename[IP_SET_MAXNAMELEN];
ip_set_id_t index; ip_set_id_t index;
size_t header_size; /* Create data of header_size */ u_int32_t header_size; /* Create data of header_size */
size_t members_size; /* Set members data of members_size */ u_int32_t members_size; /* Set members data of members_size */
}; };
static inline int bitmap_bytes(ip_set_ip_t a, ip_set_ip_t b) static inline int bitmap_bytes(ip_set_ip_t a, ip_set_ip_t b)
@@ -366,14 +366,14 @@ struct ip_set_type {
* return 0 if not in set, 1 if in set. * return 0 if not in set, 1 if in set.
*/ */
int (*testip) (struct ip_set *set, int (*testip) (struct ip_set *set,
const void *data, size_t size, const void *data, u_int32_t size,
ip_set_ip_t *ip); ip_set_ip_t *ip);
/* /*
* Size of the data structure passed by when * Size of the data structure passed by when
* adding/deletin/testing an entry. * adding/deletin/testing an entry.
*/ */
size_t reqsize; u_int32_t reqsize;
/* Add IP into set (userspace: ipset -A set IP) /* Add IP into set (userspace: ipset -A set IP)
* Return -EEXIST if the address is already in the set, * Return -EEXIST if the address is already in the set,
@@ -381,7 +381,7 @@ struct ip_set_type {
* If the address was not already in the set, 0 is returned. * If the address was not already in the set, 0 is returned.
*/ */
int (*addip) (struct ip_set *set, int (*addip) (struct ip_set *set,
const void *data, size_t size, const void *data, u_int32_t size,
ip_set_ip_t *ip); ip_set_ip_t *ip);
/* Add IP into set (kernel: iptables ... -j SET set src|dst) /* Add IP into set (kernel: iptables ... -j SET set src|dst)
@@ -401,7 +401,7 @@ struct ip_set_type {
* If the address really was in the set, 0 is returned. * If the address really was in the set, 0 is returned.
*/ */
int (*delip) (struct ip_set *set, int (*delip) (struct ip_set *set,
const void *data, size_t size, const void *data, u_int32_t size,
ip_set_ip_t *ip); ip_set_ip_t *ip);
/* remove IP from set (kernel: iptables ... -j SET --entry x) /* remove IP from set (kernel: iptables ... -j SET --entry x)
@@ -418,7 +418,7 @@ struct ip_set_type {
/* new set creation - allocated type specific items /* new set creation - allocated type specific items
*/ */
int (*create) (struct ip_set *set, int (*create) (struct ip_set *set,
const void *data, size_t size); const void *data, u_int32_t size);
/* retry the operation after successfully tweaking the set /* retry the operation after successfully tweaking the set
*/ */
@@ -437,7 +437,7 @@ struct ip_set_type {
/* Listing: size needed for header /* Listing: size needed for header
*/ */
size_t header_size; u_int32_t header_size;
/* Listing: Get the header /* Listing: Get the header
* *
@@ -523,7 +523,7 @@ extern int ip_set_testip_kernel(ip_set_id_t id,
#define UADT0(type, adt, args...) \ #define UADT0(type, adt, args...) \
static int \ static int \
FNAME(type,_u,adt)(struct ip_set *set, const void *data, size_t size, \ FNAME(type,_u,adt)(struct ip_set *set, const void *data, u_int32_t size,\
ip_set_ip_t *hash_ip) \ ip_set_ip_t *hash_ip) \
{ \ { \
const STRUCT(ip_set_req_,type) *req = data; \ const STRUCT(ip_set_req_,type) *req = data; \

View File

@@ -6,7 +6,7 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#define BITMAP_CREATE(type) \ #define BITMAP_CREATE(type) \
static int \ static int \
type##_create(struct ip_set *set, const void *data, size_t size) \ type##_create(struct ip_set *set, const void *data, u_int32_t size) \
{ \ { \
int newbytes; \ int newbytes; \
const struct ip_set_req_##type##_create *req = data; \ const struct ip_set_req_##type##_create *req = data; \
@@ -19,8 +19,8 @@ type##_create(struct ip_set *set, const void *data, size_t size) \
\ \
map = kmalloc(sizeof(struct ip_set_##type), GFP_KERNEL); \ map = kmalloc(sizeof(struct ip_set_##type), GFP_KERNEL); \
if (!map) { \ if (!map) { \
DP("out of memory for %d bytes", \ DP("out of memory for %zu bytes", \
sizeof(struct ip_set_#type)); \ sizeof(struct ip_set_##type)); \
return -ENOMEM; \ return -ENOMEM; \
} \ } \
map->first_ip = req->from; \ map->first_ip = req->from; \
@@ -35,7 +35,7 @@ type##_create(struct ip_set *set, const void *data, size_t size) \
map->size = newbytes; \ map->size = newbytes; \
map->members = ip_set_malloc(newbytes); \ map->members = ip_set_malloc(newbytes); \
if (!map->members) { \ if (!map->members) { \
DP("out of memory for %d bytes", newbytes); \ DP("out of memory for %i bytes", newbytes); \
kfree(map); \ kfree(map); \
return -ENOMEM; \ return -ENOMEM; \
} \ } \

View File

@@ -58,6 +58,7 @@ static inline void *kzalloc(size_t size, gfp_t flags)
#endif #endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
#include <linux/netfilter.h>
#define KMEM_CACHE_CREATE(name, size) \ #define KMEM_CACHE_CREATE(name, size) \
kmem_cache_create(name, size, 0, 0, NULL, NULL) kmem_cache_create(name, size, 0, 0, NULL, NULL)
#else #else

View File

@@ -28,20 +28,22 @@ type##_retry(struct ip_set *set) \
hashsize++; \ hashsize++; \
\ \
ip_set_printk("rehashing of set %s triggered: " \ ip_set_printk("rehashing of set %s triggered: " \
"hashsize grows from %u to %u", \ "hashsize grows from %lu to %lu", \
set->name, map->hashsize, hashsize); \ set->name, \
(long unsigned)map->hashsize, \
(long unsigned)hashsize); \
\ \
tmp = kmalloc(sizeof(struct ip_set_##type) \ tmp = kmalloc(sizeof(struct ip_set_##type) \
+ map->probes * sizeof(initval_t), GFP_ATOMIC); \ + map->probes * sizeof(initval_t), GFP_ATOMIC); \
if (!tmp) { \ if (!tmp) { \
DP("out of memory for %d bytes", \ DP("out of memory for %zu bytes", \
sizeof(struct ip_set_##type) \ sizeof(struct ip_set_##type) \
+ map->probes * sizeof(initval_t)); \ + map->probes * sizeof(initval_t)); \
return -ENOMEM; \ return -ENOMEM; \
} \ } \
tmp->members = harray_malloc(hashsize, sizeof(dtype), GFP_ATOMIC);\ tmp->members = harray_malloc(hashsize, sizeof(dtype), GFP_ATOMIC);\
if (!tmp->members) { \ if (!tmp->members) { \
DP("out of memory for %d bytes", hashsize * sizeof(dtype));\ DP("out of memory for %zu bytes", hashsize * sizeof(dtype));\
kfree(tmp); \ kfree(tmp); \
return -ENOMEM; \ return -ENOMEM; \
} \ } \
@@ -88,7 +90,7 @@ type##_retry(struct ip_set *set) \
#define HASH_CREATE(type, dtype) \ #define HASH_CREATE(type, dtype) \
static int \ static int \
type##_create(struct ip_set *set, const void *data, size_t size) \ type##_create(struct ip_set *set, const void *data, u_int32_t size) \
{ \ { \
const struct ip_set_req_##type##_create *req = data; \ const struct ip_set_req_##type##_create *req = data; \
struct ip_set_##type *map; \ struct ip_set_##type *map; \
@@ -107,7 +109,7 @@ type##_create(struct ip_set *set, const void *data, size_t size) \
map = kmalloc(sizeof(struct ip_set_##type) \ map = kmalloc(sizeof(struct ip_set_##type) \
+ req->probes * sizeof(initval_t), GFP_KERNEL); \ + req->probes * sizeof(initval_t), GFP_KERNEL); \
if (!map) { \ if (!map) { \
DP("out of memory for %d bytes", \ DP("out of memory for %zu bytes", \
sizeof(struct ip_set_##type) \ sizeof(struct ip_set_##type) \
+ req->probes * sizeof(initval_t)); \ + req->probes * sizeof(initval_t)); \
return -ENOMEM; \ return -ENOMEM; \
@@ -124,7 +126,7 @@ type##_create(struct ip_set *set, const void *data, size_t size) \
} \ } \
map->members = harray_malloc(map->hashsize, sizeof(dtype), GFP_KERNEL);\ map->members = harray_malloc(map->hashsize, sizeof(dtype), GFP_KERNEL);\
if (!map->members) { \ if (!map->members) { \
DP("out of memory for %d bytes", map->hashsize * sizeof(dtype));\ DP("out of memory for %zu bytes", map->hashsize * sizeof(dtype));\
kfree(map); \ kfree(map); \
return -ENOMEM; \ return -ENOMEM; \
} \ } \

View File

@@ -13,7 +13,7 @@ struct ip_set_ipmap {
ip_set_ip_t netmask; /* subnet netmask */ ip_set_ip_t netmask; /* subnet netmask */
ip_set_ip_t sizeid; /* size of set in IPs */ ip_set_ip_t sizeid; /* size of set in IPs */
ip_set_ip_t hosts; /* number of hosts in a subnet */ ip_set_ip_t hosts; /* number of hosts in a subnet */
size_t size; /* size of the ipmap proper */ u_int32_t size; /* size of the ipmap proper */
}; };
struct ip_set_req_ipmap_create { struct ip_set_req_ipmap_create {

View File

@@ -102,7 +102,7 @@ ipportnethash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
} }
static int static int
ipportnethash_utest(struct ip_set *set, const void *data, size_t size, ipportnethash_utest(struct ip_set *set, const void *data, u_int32_t size,
ip_set_ip_t *hash_ip) ip_set_ip_t *hash_ip)
{ {
const struct ip_set_req_ipportnethash *req = data; const struct ip_set_req_ipportnethash *req = data;

View File

@@ -10,6 +10,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/jiffies.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h> #include <linux/delay.h>
@@ -276,21 +277,21 @@ init_gc_timer(struct ip_set *set)
} }
static int static int
iptree_create(struct ip_set *set, const void *data, size_t size) iptree_create(struct ip_set *set, const void *data, u_int32_t size)
{ {
const struct ip_set_req_iptree_create *req = data; const struct ip_set_req_iptree_create *req = data;
struct ip_set_iptree *map; struct ip_set_iptree *map;
if (size != sizeof(struct ip_set_req_iptree_create)) { if (size != sizeof(struct ip_set_req_iptree_create)) {
ip_set_printk("data length wrong (want %zu, have %zu)", ip_set_printk("data length wrong (want %zu, have %lu)",
sizeof(struct ip_set_req_iptree_create), sizeof(struct ip_set_req_iptree_create),
size); (unsigned long)size);
return -EINVAL; return -EINVAL;
} }
map = kmalloc(sizeof(struct ip_set_iptree), GFP_KERNEL); map = kmalloc(sizeof(struct ip_set_iptree), GFP_KERNEL);
if (!map) { if (!map) {
DP("out of memory for %d bytes", DP("out of memory for %zu bytes",
sizeof(struct ip_set_iptree)); sizeof(struct ip_set_iptree));
return -ENOMEM; return -ENOMEM;
} }

View File

@@ -14,6 +14,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/jiffies.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h> #include <linux/delay.h>
@@ -338,7 +339,7 @@ KADT(iptreemap, add, ipaddr, ip)
static inline int static inline int
__delip_single(struct ip_set *set, ip_set_ip_t *hash_ip, __delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
ip_set_ip_t ip, unsigned int __nocast flags) ip_set_ip_t ip, gfp_t flags)
{ {
struct ip_set_iptreemap *map = set->data; struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree; struct ip_set_iptreemap_b *btree;
@@ -364,7 +365,7 @@ __delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
static inline int static inline int
iptreemap_del(struct ip_set *set, ip_set_ip_t *hash_ip, iptreemap_del(struct ip_set *set, ip_set_ip_t *hash_ip,
ip_set_ip_t start, ip_set_ip_t end, unsigned int __nocast flags) ip_set_ip_t start, ip_set_ip_t end, gfp_t flags)
{ {
struct ip_set_iptreemap *map = set->data; struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree; struct ip_set_iptreemap_b *btree;
@@ -470,7 +471,7 @@ init_gc_timer(struct ip_set *set)
} }
static int static int
iptreemap_create(struct ip_set *set, const void *data, size_t size) iptreemap_create(struct ip_set *set, const void *data, u_int32_t size)
{ {
const struct ip_set_req_iptreemap_create *req = data; const struct ip_set_req_iptreemap_create *req = data;
struct ip_set_iptreemap *map; struct ip_set_iptreemap *map;
@@ -567,7 +568,7 @@ iptreemap_list_members_size(const struct ip_set *set)
return (count * sizeof(struct ip_set_req_iptreemap)); return (count * sizeof(struct ip_set_req_iptreemap));
} }
static inline size_t static inline u_int32_t
add_member(void *data, size_t offset, ip_set_ip_t start, ip_set_ip_t end) add_member(void *data, size_t offset, ip_set_ip_t start, ip_set_ip_t end)
{ {
struct ip_set_req_iptreemap *entry = data + offset; struct ip_set_req_iptreemap *entry = data + offset;

View File

@@ -22,7 +22,7 @@
#include "ip_set_macipmap.h" #include "ip_set_macipmap.h"
static int static int
macipmap_utest(struct ip_set *set, const void *data, size_t size, macipmap_utest(struct ip_set *set, const void *data, u_int32_t size,
ip_set_ip_t *hash_ip) ip_set_ip_t *hash_ip)
{ {
const struct ip_set_macipmap *map = set->data; const struct ip_set_macipmap *map = set->data;
@@ -35,8 +35,7 @@ macipmap_utest(struct ip_set *set, const void *data, size_t size,
*hash_ip = req->ip; *hash_ip = req->ip;
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u", DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
set->name, HIPQUAD(req->ip), HIPQUAD(*hash_ip)); set->name, HIPQUAD(req->ip), HIPQUAD(*hash_ip));
if (test_bit(IPSET_MACIP_ISSET, if (table[req->ip - map->first_ip].match) {
(void *) &table[req->ip - map->first_ip].flags)) {
return (memcmp(req->ethernet, return (memcmp(req->ethernet,
&table[req->ip - map->first_ip].ethernet, &table[req->ip - map->first_ip].ethernet,
ETH_ALEN) == 0); ETH_ALEN) == 0);
@@ -64,8 +63,7 @@ macipmap_ktest(struct ip_set *set,
*hash_ip = ip; *hash_ip = ip;
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u", DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
set->name, HIPQUAD(ip), HIPQUAD(*hash_ip)); set->name, HIPQUAD(ip), HIPQUAD(*hash_ip));
if (test_bit(IPSET_MACIP_ISSET, if (table[ip - map->first_ip].match) {
(void *) &table[ip - map->first_ip].flags)) {
/* Is mac pointer valid? /* Is mac pointer valid?
* If so, compare... */ * If so, compare... */
return (skb_mac_header(skb) >= skb->head return (skb_mac_header(skb) >= skb->head
@@ -88,13 +86,13 @@ macipmap_add(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip) if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE; return -ERANGE;
if (test_and_set_bit(IPSET_MACIP_ISSET, if (table[ip - map->first_ip].match)
(void *) &table[ip - map->first_ip].flags))
return -EEXIST; return -EEXIST;
*hash_ip = ip; *hash_ip = ip;
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip)); DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
memcpy(&table[ip - map->first_ip].ethernet, ethernet, ETH_ALEN); memcpy(&table[ip - map->first_ip].ethernet, ethernet, ETH_ALEN);
table[ip - map->first_ip].match = IPSET_MACIP_ISSET;
return 0; return 0;
} }
@@ -114,11 +112,11 @@ macipmap_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
if (ip < map->first_ip || ip > map->last_ip) if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE; return -ERANGE;
if (!test_and_clear_bit(IPSET_MACIP_ISSET, if (!table[ip - map->first_ip].match)
(void *)&table[ip - map->first_ip].flags))
return -EEXIST; return -EEXIST;
*hash_ip = ip; *hash_ip = ip;
table[ip - map->first_ip].match = 0;
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip)); DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
return 0; return 0;
} }

View File

@@ -17,7 +17,7 @@ struct ip_set_macipmap {
ip_set_ip_t first_ip; /* host byte order, included in range */ ip_set_ip_t first_ip; /* host byte order, included in range */
ip_set_ip_t last_ip; /* host byte order, included in range */ ip_set_ip_t last_ip; /* host byte order, included in range */
u_int32_t flags; u_int32_t flags;
size_t size; /* size of the ipmap proper */ u_int32_t size; /* size of the ipmap proper */
}; };
struct ip_set_req_macipmap_create { struct ip_set_req_macipmap_create {
@@ -32,7 +32,7 @@ struct ip_set_req_macipmap {
}; };
struct ip_set_macip { struct ip_set_macip {
unsigned short flags; unsigned short match;
unsigned char ethernet[ETH_ALEN]; unsigned char ethernet[ETH_ALEN];
}; };

View File

@@ -40,7 +40,7 @@ struct harray {
}; };
static inline void * static inline void *
__harray_malloc(size_t hashsize, size_t typesize, int flags) __harray_malloc(size_t hashsize, size_t typesize, gfp_t flags)
{ {
struct harray *harray; struct harray *harray;
size_t max_elements, size, i, j; size_t max_elements, size, i, j;
@@ -88,7 +88,7 @@ __harray_malloc(size_t hashsize, size_t typesize, int flags)
} }
static inline void * static inline void *
harray_malloc(size_t hashsize, size_t typesize, int flags) harray_malloc(size_t hashsize, size_t typesize, gfp_t flags)
{ {
void *harray; void *harray;

View File

@@ -80,7 +80,7 @@ nethash_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
} }
static int static int
nethash_utest(struct ip_set *set, const void *data, size_t size, nethash_utest(struct ip_set *set, const void *data, u_int32_t size,
ip_set_ip_t *hash_ip) ip_set_ip_t *hash_ip)
{ {
const struct ip_set_req_nethash *req = data; const struct ip_set_req_nethash *req = data;

View File

@@ -10,7 +10,7 @@ struct ip_set_portmap {
void *members; /* the portmap proper */ void *members; /* the portmap proper */
ip_set_ip_t first_ip; /* host byte order, included in range */ ip_set_ip_t first_ip; /* host byte order, included in range */
ip_set_ip_t last_ip; /* host byte order, included in range */ ip_set_ip_t last_ip; /* host byte order, included in range */
size_t size; /* size of the ipmap proper */ u_int32_t size; /* size of the ipmap proper */
}; };
struct ip_set_req_portmap_create { struct ip_set_req_portmap_create {

View File

@@ -21,14 +21,14 @@
* after ==> ref, index * after ==> ref, index
*/ */
static inline bool static inline int
next_index_eq(const struct ip_set_setlist *map, int i, ip_set_id_t index) next_index_eq(const struct ip_set_setlist *map, int i, ip_set_id_t index)
{ {
return i < map->size && map->index[i] == index; return i < map->size && map->index[i] == index;
} }
static int static int
setlist_utest(struct ip_set *set, const void *data, size_t size, setlist_utest(struct ip_set *set, const void *data, u_int32_t size,
ip_set_ip_t *hash_ip) ip_set_ip_t *hash_ip)
{ {
const struct ip_set_setlist *map = set->data; const struct ip_set_setlist *map = set->data;
@@ -38,18 +38,16 @@ setlist_utest(struct ip_set *set, const void *data, size_t size,
struct ip_set *s; struct ip_set *s;
if (req->before && req->ref[0] == '\0') if (req->before && req->ref[0] == '\0')
return -EINVAL; return 0;
index = __ip_set_get_byname(req->name, &s); index = __ip_set_get_byname(req->name, &s);
if (index == IP_SET_INVALID_ID) if (index == IP_SET_INVALID_ID)
return -EEXIST; return 0;
if (req->ref[0] != '\0') { if (req->ref[0] != '\0') {
ref = __ip_set_get_byname(req->ref, &s); ref = __ip_set_get_byname(req->ref, &s);
if (ref == IP_SET_INVALID_ID) { if (ref == IP_SET_INVALID_ID)
res = -EEXIST;
goto finish; goto finish;
} }
}
for (i = 0; i < map->size for (i = 0; i < map->size
&& map->index[i] != IP_SET_INVALID_ID; i++) { && map->index[i] != IP_SET_INVALID_ID; i++) {
if (req->before && map->index[i] == index) { if (req->before && map->index[i] == index) {
@@ -109,7 +107,7 @@ insert_setlist(struct ip_set_setlist *map, int i, ip_set_id_t index)
} }
static int static int
setlist_uadd(struct ip_set *set, const void *data, size_t size, setlist_uadd(struct ip_set *set, const void *data, u_int32_t size,
ip_set_ip_t *hash_ip) ip_set_ip_t *hash_ip)
{ {
struct ip_set_setlist *map = set->data; struct ip_set_setlist *map = set->data;
@@ -172,7 +170,7 @@ setlist_kadd(struct ip_set *set,
return res; return res;
} }
static inline bool static inline int
unshift_setlist(struct ip_set_setlist *map, int i) unshift_setlist(struct ip_set_setlist *map, int i)
{ {
int j; int j;
@@ -184,7 +182,7 @@ unshift_setlist(struct ip_set_setlist *map, int i)
} }
static int static int
setlist_udel(struct ip_set *set, const void *data, size_t size, setlist_udel(struct ip_set *set, const void *data, u_int32_t size,
ip_set_ip_t *hash_ip) ip_set_ip_t *hash_ip)
{ {
struct ip_set_setlist *map = set->data; struct ip_set_setlist *map = set->data;
@@ -251,7 +249,7 @@ setlist_kdel(struct ip_set *set,
} }
static int static int
setlist_create(struct ip_set *set, const void *data, size_t size) setlist_create(struct ip_set *set, const void *data, u_int32_t size)
{ {
struct ip_set_setlist *map; struct ip_set_setlist *map;
const struct ip_set_req_setlist_create *req = data; const struct ip_set_req_setlist_create *req = data;

View File

@@ -50,6 +50,9 @@ IP set bindings pointing to sets and iptables matches and targets
referring to sets creates references, which protects the given sets in referring to sets creates references, which protects the given sets in
the kernel. A set cannot be removed (destroyed) while there is a single the kernel. A set cannot be removed (destroyed) while there is a single
reference pointing to it. reference pointing to it.
.P
.B
Please note, binding sets is a deprecated feature and will be removed in a later release. Switch to the multidata type of sets from using bindings.
.SH OPTIONS .SH OPTIONS
The options that are recognized by The options that are recognized by
.B ipset .B ipset

View File

@@ -30,7 +30,7 @@
#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe" #define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe"
#endif #endif
#define IPSET_VERSION "2.5.0" #define IPSET_VERSION "3.2"
char program_name[] = "ipset"; char program_name[] = "ipset";
char program_version[] = IPSET_VERSION; char program_version[] = IPSET_VERSION;
@@ -1580,7 +1580,7 @@ static int set_adtip(struct set *set, const char *adt,
/* Alloc memory for the data to send */ /* Alloc memory for the data to send */
size = sizeof(struct ip_set_req_adt) + set->settype->adt_size ; size = sizeof(struct ip_set_req_adt) + set->settype->adt_size ;
DP("alloc size %i", size); DP("alloc size %d", size);
data = ipset_malloc(size); data = ipset_malloc(size);
/* Fill out the request */ /* Fill out the request */
@@ -1666,7 +1666,7 @@ static int set_bind(struct set *set, const char *adt,
size += IP_SET_MAXNAMELEN; size += IP_SET_MAXNAMELEN;
else if (!(op == IP_SET_OP_UNBIND_SET && set == NULL)) else if (!(op == IP_SET_OP_UNBIND_SET && set == NULL))
size += set->settype->adt_size; size += set->settype->adt_size;
DP("alloc size %i", size); DP("alloc size %d", size);
data = ipset_malloc(size); data = ipset_malloc(size);
/* Fill out the request */ /* Fill out the request */

View File

@@ -95,7 +95,7 @@ struct settype {
*/ */
/* Size of create data. Will be sent to kernel */ /* Size of create data. Will be sent to kernel */
size_t create_size; u_int32_t create_size;
/* Initialize the create. */ /* Initialize the create. */
void (*create_init) (void *data); void (*create_init) (void *data);
@@ -115,7 +115,7 @@ struct settype {
*/ */
/* Size of data. Will be sent to kernel */ /* Size of data. Will be sent to kernel */
size_t adt_size; u_int32_t adt_size;
/* Function which parses command options */ /* Function which parses command options */
ip_set_ip_t (*adt_parser) (int cmd, const char *optarg, void *data); ip_set_ip_t (*adt_parser) (int cmd, const char *optarg, void *data);
@@ -125,7 +125,7 @@ struct settype {
*/ */
/* Size of header. */ /* Size of header. */
size_t header_size; u_int32_t header_size;
/* Initialize the type-header */ /* Initialize the type-header */
void (*initheader) (struct set *set, const void *data); void (*initheader) (struct set *set, const void *data);
@@ -134,16 +134,16 @@ struct settype {
void (*printheader) (struct set *set, unsigned options); void (*printheader) (struct set *set, unsigned options);
/* Pretty print all IPs */ /* Pretty print all IPs */
void (*printips) (struct set *set, void *data, size_t len, unsigned options); void (*printips) (struct set *set, void *data, u_int32_t len, unsigned options);
/* Pretty print all IPs sorted */ /* Pretty print all IPs sorted */
void (*printips_sorted) (struct set *set, void *data, size_t len, unsigned options); void (*printips_sorted) (struct set *set, void *data, u_int32_t len, unsigned options);
/* Print save arguments for creating the set */ /* Print save arguments for creating the set */
void (*saveheader) (struct set *set, unsigned options); void (*saveheader) (struct set *set, unsigned options);
/* Print save for all IPs */ /* Print save for all IPs */
void (*saveips) (struct set *set, void *data, size_t len, unsigned options); void (*saveips) (struct set *set, void *data, u_int32_t len, unsigned options);
/* Conver a single IP (binding) to string */ /* Conver a single IP (binding) to string */
char * (*bindip_tostring)(struct set *set, ip_set_ip_t ip, unsigned options); char * (*bindip_tostring)(struct set *set, ip_set_ip_t ip, unsigned options);
@@ -189,10 +189,13 @@ extern struct set *set_find_byid(ip_set_id_t id);
extern unsigned warn_once; extern unsigned warn_once;
#define BITSPERBYTE (8*sizeof(char)) #define BITS_PER_LONG (8*sizeof(unsigned long))
#define ID2BYTE(id) ((id)/BITSPERBYTE) #define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
#define ID2MASK(id) (1 << ((id)%BITSPERBYTE))
#define test_bit(id, heap) ((((char *)(heap))[ID2BYTE(id)] & ID2MASK(id)) != 0) static inline int test_bit(int nr, const unsigned long *addr)
{
return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
}
#define UNUSED __attribute__ ((unused)) #define UNUSED __attribute__ ((unused))
#define CONSTRUCTOR(module) \ #define CONSTRUCTOR(module) \

View File

@@ -192,7 +192,7 @@ printheader(struct set *set, unsigned options UNUSED)
} }
static void static void
printips(struct set *set UNUSED, void *data, size_t len, unsigned options) printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
{ {
size_t offset = 0; size_t offset = 0;
ip_set_ip_t *ip; ip_set_ip_t *ip;
@@ -221,7 +221,7 @@ saveheader(struct set *set, unsigned options UNUSED)
/* Print save for an IP */ /* Print save for an IP */
static void static void
saveips(struct set *set UNUSED, void *data, size_t len, unsigned options) saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
{ {
size_t offset = 0; size_t offset = 0;
ip_set_ip_t *ip; ip_set_ip_t *ip;

View File

@@ -225,12 +225,12 @@ initheader(struct set *set, const void *data)
mask = range_to_mask(header->from, header->to, &mask_bits); mask = range_to_mask(header->from, header->to, &mask_bits);
netmask_bits = mask_to_bits(header->netmask); netmask_bits = mask_to_bits(header->netmask);
DP("bits: %i %i", mask_bits, netmask_bits); DP("bits: %d %d", mask_bits, netmask_bits);
map->hosts = 2 << (32 - netmask_bits - 1); map->hosts = 2 << (32 - netmask_bits - 1);
map->sizeid = 2 << (netmask_bits - mask_bits - 1); map->sizeid = 2 << (netmask_bits - mask_bits - 1);
} }
DP("%i %i", map->hosts, map->sizeid ); DP("%d %d", map->hosts, map->sizeid );
} }
static void static void
@@ -248,7 +248,7 @@ printheader(struct set *set, unsigned options)
static void static void
printips_sorted(struct set *set, void *data, printips_sorted(struct set *set, void *data,
size_t len UNUSED, unsigned options) u_int32_t len UNUSED, unsigned options)
{ {
struct ip_set_ipmap *mysetdata = set->settype->header; struct ip_set_ipmap *mysetdata = set->settype->header;
ip_set_ip_t id; ip_set_ip_t id;
@@ -279,7 +279,7 @@ saveheader(struct set *set, unsigned options)
} }
static void static void
saveips(struct set *set, void *data, size_t len UNUSED, unsigned options) saveips(struct set *set, void *data, u_int32_t len UNUSED, unsigned options)
{ {
struct ip_set_ipmap *mysetdata = set->settype->header; struct ip_set_ipmap *mysetdata = set->settype->header;
ip_set_ip_t id; ip_set_ip_t id;

View File

@@ -248,7 +248,7 @@ printheader(struct set *set, unsigned options)
} }
static void static void
printips(struct set *set, void *data, size_t len, unsigned options) printips(struct set *set, void *data, u_int32_t len, unsigned options)
{ {
struct ip_set_ipporthash *mysetdata = set->settype->header; struct ip_set_ipporthash *mysetdata = set->settype->header;
size_t offset = 0; size_t offset = 0;
@@ -284,7 +284,7 @@ saveheader(struct set *set, unsigned options)
/* Print save for an IP */ /* Print save for an IP */
static void static void
saveips(struct set *set, void *data, size_t len, unsigned options) saveips(struct set *set, void *data, u_int32_t len, unsigned options)
{ {
struct ip_set_ipporthash *mysetdata = set->settype->header; struct ip_set_ipporthash *mysetdata = set->settype->header;
size_t offset = 0; size_t offset = 0;

View File

@@ -253,7 +253,7 @@ printheader(struct set *set, unsigned options)
} }
static void static void
printips(struct set *set, void *data, size_t len, unsigned options) printips(struct set *set, void *data, u_int32_t len, unsigned options)
{ {
struct ip_set_ipportiphash *mysetdata = set->settype->header; struct ip_set_ipportiphash *mysetdata = set->settype->header;
size_t offset = 0; size_t offset = 0;
@@ -292,7 +292,7 @@ saveheader(struct set *set, unsigned options)
/* Print save for an IP */ /* Print save for an IP */
static void static void
saveips(struct set *set, void *data, size_t len, unsigned options) saveips(struct set *set, void *data, u_int32_t len, unsigned options)
{ {
struct ip_set_ipportiphash *mysetdata = set->settype->header; struct ip_set_ipportiphash *mysetdata = set->settype->header;
size_t offset = 0; size_t offset = 0;

View File

@@ -318,7 +318,7 @@ unpack_ip_tostring(ip_set_ip_t ip, unsigned options UNUSED)
} }
static void static void
printips(struct set *set, void *data, size_t len, unsigned options) printips(struct set *set, void *data, u_int32_t len, unsigned options)
{ {
struct ip_set_ipportnethash *mysetdata = set->settype->header; struct ip_set_ipportnethash *mysetdata = set->settype->header;
size_t offset = 0; size_t offset = 0;
@@ -357,7 +357,7 @@ saveheader(struct set *set, unsigned options)
/* Print save for an IP */ /* Print save for an IP */
static void static void
saveips(struct set *set, void *data, size_t len, unsigned options) saveips(struct set *set, void *data, u_int32_t len, unsigned options)
{ {
struct ip_set_ipportnethash *mysetdata = set->settype->header; struct ip_set_ipportnethash *mysetdata = set->settype->header;
size_t offset = 0; size_t offset = 0;

View File

@@ -123,7 +123,7 @@ printheader(struct set *set, unsigned options UNUSED)
} }
static void static void
printips_sorted(struct set *set, void *data, size_t len, unsigned options) printips_sorted(struct set *set, void *data, u_int32_t len, unsigned options)
{ {
struct ip_set_iptree *mysetdata = set->settype->header; struct ip_set_iptree *mysetdata = set->settype->header;
struct ip_set_req_iptree *req; struct ip_set_req_iptree *req;
@@ -155,7 +155,7 @@ saveheader(struct set *set, unsigned options UNUSED)
} }
static void static void
saveips(struct set *set, void *data, size_t len, unsigned options) saveips(struct set *set, void *data, u_int32_t len, unsigned options)
{ {
struct ip_set_iptree *mysetdata = set->settype->header; struct ip_set_iptree *mysetdata = set->settype->header;
struct ip_set_req_iptree *req; struct ip_set_req_iptree *req;

View File

@@ -115,7 +115,7 @@ printheader(struct set *set, unsigned int options UNUSED)
static void static void
printips_sorted(struct set *set UNUSED, void *data, printips_sorted(struct set *set UNUSED, void *data,
size_t len, unsigned int options) u_int32_t len, unsigned int options)
{ {
struct ip_set_req_iptreemap *req; struct ip_set_req_iptreemap *req;
size_t offset = 0; size_t offset = 0;
@@ -147,7 +147,7 @@ saveheader(struct set *set, unsigned int options UNUSED)
static void static void
saveips(struct set *set UNUSED, void *data, saveips(struct set *set UNUSED, void *data,
size_t len, unsigned int options) u_int32_t len, unsigned int options)
{ {
struct ip_set_req_iptreemap *req; struct ip_set_req_iptreemap *req;
size_t offset = 0; size_t offset = 0;

View File

@@ -245,15 +245,14 @@ print_mac(unsigned char macaddress[ETH_ALEN])
static void static void
printips_sorted(struct set *set, void *data, printips_sorted(struct set *set, void *data,
size_t len UNUSED, unsigned options) u_int32_t len UNUSED, unsigned options)
{ {
struct ip_set_macipmap *mysetdata = set->settype->header; struct ip_set_macipmap *mysetdata = set->settype->header;
struct ip_set_macip *table = data; struct ip_set_macip *table = data;
u_int32_t addr = mysetdata->first_ip; u_int32_t addr = mysetdata->first_ip;
while (addr <= mysetdata->last_ip) { while (addr <= mysetdata->last_ip) {
if (test_bit(IPSET_MACIP_ISSET, if (table[addr - mysetdata->first_ip].match) {
(void *)&table[addr - mysetdata->first_ip].flags)) {
printf("%s,", ip_tostring(addr, options)); printf("%s,", ip_tostring(addr, options));
print_mac(table[addr - mysetdata->first_ip]. print_mac(table[addr - mysetdata->first_ip].
ethernet); ethernet);
@@ -280,15 +279,14 @@ saveheader(struct set *set, unsigned options)
static void static void
saveips(struct set *set, void *data, saveips(struct set *set, void *data,
size_t len UNUSED, unsigned options) u_int32_t len UNUSED, unsigned options)
{ {
struct ip_set_macipmap *mysetdata = set->settype->header; struct ip_set_macipmap *mysetdata = set->settype->header;
struct ip_set_macip *table = data; struct ip_set_macip *table = data;
u_int32_t addr = mysetdata->first_ip; u_int32_t addr = mysetdata->first_ip;
while (addr <= mysetdata->last_ip) { while (addr <= mysetdata->last_ip) {
if (test_bit(IPSET_MACIP_ISSET, if (table[addr - mysetdata->first_ip].match) {
(void *)&table[addr - mysetdata->first_ip].flags)) {
printf("-A %s %s,", printf("-A %s %s,",
set->name, ip_tostring(addr, options)); set->name, ip_tostring(addr, options));
print_mac(table[addr - mysetdata->first_ip]. print_mac(table[addr - mysetdata->first_ip].

View File

@@ -224,7 +224,7 @@ unpack_ip_tostring(ip_set_ip_t ip, unsigned options UNUSED)
} }
static void static void
printips(struct set *set UNUSED, void *data, size_t len, unsigned options) printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
{ {
size_t offset = 0; size_t offset = 0;
ip_set_ip_t *ip; ip_set_ip_t *ip;
@@ -249,7 +249,7 @@ saveheader(struct set *set, unsigned options UNUSED)
/* Print save for an IP */ /* Print save for an IP */
static void static void
saveips(struct set *set UNUSED, void *data, size_t len, unsigned options) saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
{ {
size_t offset = 0; size_t offset = 0;
ip_set_ip_t *ip; ip_set_ip_t *ip;

View File

@@ -149,7 +149,7 @@ printheader(struct set *set, unsigned options)
static void static void
printports_sorted(struct set *set, void *data, printports_sorted(struct set *set, void *data,
size_t len UNUSED, unsigned options) u_int32_t len UNUSED, unsigned options)
{ {
struct ip_set_portmap *mysetdata = set->settype->header; struct ip_set_portmap *mysetdata = set->settype->header;
u_int32_t addr = mysetdata->first_ip; u_int32_t addr = mysetdata->first_ip;
@@ -184,7 +184,7 @@ saveheader(struct set *set, unsigned options)
static void static void
saveports(struct set *set, void *data, saveports(struct set *set, void *data,
size_t len UNUSED, unsigned options) u_int32_t len UNUSED, unsigned options)
{ {
struct ip_set_portmap *mysetdata = set->settype->header; struct ip_set_portmap *mysetdata = set->settype->header;
u_int32_t addr = mysetdata->first_ip; u_int32_t addr = mysetdata->first_ip;

View File

@@ -134,7 +134,7 @@ printheader(struct set *set, unsigned options UNUSED)
static void static void
printips_sorted(struct set *set, void *data, printips_sorted(struct set *set, void *data,
size_t len UNUSED, unsigned options UNUSED) u_int32_t len UNUSED, unsigned options UNUSED)
{ {
struct ip_set_setlist *mysetdata = set->settype->header; struct ip_set_setlist *mysetdata = set->settype->header;
int i; int i;
@@ -162,7 +162,7 @@ saveheader(struct set *set, unsigned options UNUSED)
static void static void
saveips(struct set *set, void *data, saveips(struct set *set, void *data,
size_t len UNUSED, unsigned options UNUSED) u_int32_t len UNUSED, unsigned options UNUSED)
{ {
struct ip_set_setlist *mysetdata = set->settype->header; struct ip_set_setlist *mysetdata = set->settype->header;
int i; int i;

View File

@@ -70,7 +70,9 @@ static int __init rawpost4_table_init(void)
{ {
int ret; int ret;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 29)
rwlock_init(&rawpost4_itable.lock); rwlock_init(&rawpost4_itable.lock);
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
rawpost4_ptable = ipt_register_table(&init_net, &rawpost4_itable, rawpost4_ptable = ipt_register_table(&init_net, &rawpost4_itable,
&rawpost4_initial.repl); &rawpost4_initial.repl);

168
extensions/libxt_ACCOUNT.c Normal file
View File

@@ -0,0 +1,168 @@
/* Shared library add-on to iptables to add ACCOUNT(ing) support.
Author: Intra2net AG <opensource@intra2net.com>
*/
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <syslog.h>
#include <getopt.h>
#include <stddef.h>
#include <xtables.h>
#include "xt_ACCOUNT.h"
static struct option account_tg_opts[] = {
{ .name = "addr", .has_arg = 1, .flag = 0, .val = 'a' },
{ .name = "tname", .has_arg = 1, .flag = 0, .val = 't' },
{ .name = 0 }
};
/* Function which prints out usage message. */
static void account_tg_help(void)
{
printf(
"ACCOUNT target options:\n"
" --%s ip/netmask\t\tBase network IP and netmask used for this table\n"
" --%s name\t\t\tTable name for the userspace library\n",
account_tg_opts[0].name, account_tg_opts[1].name);
}
/* Initialize the target. */
static void
account_tg_init(struct xt_entry_target *t)
{
struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)t->data;
accountinfo->table_nr = -1;
}
#define IPT_ACCOUNT_OPT_ADDR 0x01
#define IPT_ACCOUNT_OPT_TABLE 0x02
/* Function which parses command options; returns true if it
ate an option */
static int account_tg_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_target **target)
{
struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)(*target)->data;
struct in_addr *addrs = NULL, mask;
unsigned int naddrs = 0;
switch (c) {
case 'a':
if (*flags & IPT_ACCOUNT_OPT_ADDR)
xtables_error(PARAMETER_PROBLEM, "Can't specify --%s twice",
account_tg_opts[0].name);
if (xtables_check_inverse(optarg, &invert, NULL, 0))
xtables_error(PARAMETER_PROBLEM, "Unexpected `!' after --%s",
account_tg_opts[0].name);
xtables_ipparse_any(optarg, &addrs, &mask, &naddrs);
if (naddrs > 1)
xtables_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed");
accountinfo->net_ip = addrs[0].s_addr;
accountinfo->net_mask = mask.s_addr;
*flags |= IPT_ACCOUNT_OPT_ADDR;
break;
case 't':
if (*flags & IPT_ACCOUNT_OPT_TABLE)
xtables_error(PARAMETER_PROBLEM,
"Can't specify --%s twice",
account_tg_opts[1].name);
if (xtables_check_inverse(optarg, &invert, NULL, 0))
xtables_error(PARAMETER_PROBLEM,
"Unexpected `!' after --%s",
account_tg_opts[1].name);
if (strlen(optarg) > ACCOUNT_TABLE_NAME_LEN - 1)
xtables_error(PARAMETER_PROBLEM,
"Maximum table name length %u for --%s",
ACCOUNT_TABLE_NAME_LEN - 1,
account_tg_opts[1].name);
strcpy(accountinfo->table_name, optarg);
*flags |= IPT_ACCOUNT_OPT_TABLE;
break;
default:
return 0;
}
return 1;
}
static void account_tg_check(unsigned int flags)
{
if (!(flags & IPT_ACCOUNT_OPT_ADDR) || !(flags & IPT_ACCOUNT_OPT_TABLE))
xtables_error(PARAMETER_PROBLEM, "ACCOUNT: needs --%s and --%s",
account_tg_opts[0].name, account_tg_opts[1].name);
}
static void account_tg_print_it(const void *ip,
const struct xt_entry_target *target, char do_prefix)
{
const struct ipt_acc_info *accountinfo
= (const struct ipt_acc_info *)target->data;
struct in_addr a;
if (!do_prefix)
printf("ACCOUNT ");
// Network information
if (do_prefix)
printf("--");
printf("%s ", account_tg_opts[0].name);
a.s_addr = accountinfo->net_ip;
printf("%s", xtables_ipaddr_to_numeric(&a));
a.s_addr = accountinfo->net_mask;
printf("%s", xtables_ipmask_to_numeric(&a));
printf(" ");
if (do_prefix)
printf("--");
printf("%s %s", account_tg_opts[1].name, accountinfo->table_name);
}
static void
account_tg_print(const void *ip,
const struct xt_entry_target *target,
int numeric)
{
account_tg_print_it(ip, target, 0);
}
/* Saves the union ipt_targinfo in parsable form to stdout. */
static void
account_tg_save(const void *ip, const struct xt_entry_target *target)
{
account_tg_print_it(ip, target, 1);
}
static struct xtables_target account_tg_reg = {
.name = "ACCOUNT",
.family = AF_INET,
.version = XTABLES_VERSION,
.size = XT_ALIGN(sizeof(struct ipt_acc_info)),
.userspacesize = offsetof(struct ipt_acc_info, table_nr),
.help = account_tg_help,
.init = account_tg_init,
.parse = account_tg_parse,
.final_check = account_tg_check,
.print = account_tg_print,
.save = account_tg_save,
.extra_opts = account_tg_opts,
};
static __attribute__((constructor)) void account_tg_ldr(void)
{
xtables_register_target(&account_tg_reg);
}

View File

@@ -0,0 +1,72 @@
The ACCOUNT target is a high performance accounting system for large
local networks. It allows per-IP accounting in whole prefixes of IPv4
addresses with size of up to /8 without the need to add individual
accouting rule for each IP address.
.PP
The ACCOUNT is designed to be queried for data every second or at
least every ten seconds. It is written as kernel module to handle high
bandwidths without packet loss.
.PP
The largest possible subnet size is 24 bit, meaning for example 10.0.0.0/8
network. ACCOUNT uses fixed internal data structures
which speeds up the processing of each packet. Furthermore,
accounting data for one complete 192.168.1.X/24 network takes 4 KB of
memory. Memory for 16 or 24 bit networks is only allocated when
needed.
.PP
To optimize the kernel<->userspace data transfer a bit more, the
kernel module only transfers information about IPs, where the src/dst
packet counter is not 0. This saves precious kernel time.
.PP
There is no /proc interface as it would be too slow for continuous access.
The read-and-flush query operation is the fastest, as no internal data
snapshot needs to be created&copied for all data. Use the "read"
operation without flush only for debugging purposes!
.PP
Usage:
.PP
ACCOUNT takes two mandatory parameters:
.TP
\fB\-\-addr\fR \fInetwork\fP\fB/\fP\fInetmask\fR
where \fInetwork\fP\fB/\fP\fInetmask\fP is the subnet to account for, in CIDR syntax
.TP
\fB\-\-tname\fP \fINAME\fP
where \fINAME\fP is the name of the table where the accounting information
should be stored
.PP
The subnet 0.0.0.0/0 is a special case: all data are then stored in the src_bytes
and src_packets structure of slot "0". This is useful if you want
to account the overall traffic to/from your internet provider.
.PP
The data can be queried using the userspace libxt_ACCOUNT_cl library,
and by the reference implementation to show usage of this library,
the \fBiptaccount\fP(8) tool, which features following options:
.PP
[\fB\-u\fP] show kernel handle usage
.PP
[\fB\-h\fP] free all kernel handles (experts only!)
.PP
[\fB\-a\fP] list all table names
.PP
[\fB\-l\fP \fIname\fP] show data in table \fIname\fP
.PP
[\fB\-f\fP] flush data after showing
.PP
[\fB\-c\fP] loop every second (abort with CTRL+C)
.PP
Here is an example of use:
.PP
iptables \-A FORWARD \-j ACCOUNT \-\-addr 0.0.0.0/0 \-\-tname all_outgoing
iptables \-A FORWARD \-j ACCOUNT \-\-addr 192.168.1.0/24 \-\-tname sales
.PP
This creates two tables called "all_outgoing" and "sales" which can be
queried using the userspace library/iptaccount tool.
.PP
Note that this target is non-terminating \(em the packet destined to it
will continue traversing the chain in which it has been used.
.PP
Also note that once a table has been defined for specific CIDR address/netmask
block, it can be referenced multiple times using \-j ACCOUNT, provided
that both the original table name and address/netmask block are specified.
.PP
For more information go to http://www.intra2net.com/en/developer/ipt_ACCOUNT/

View File

@@ -97,6 +97,7 @@ static int ipmark_tg_parse(int c, char **argv, int invert, unsigned int *flags,
if (!xtables_strtoui(optarg, NULL, &n, 0, 128)) if (!xtables_strtoui(optarg, NULL, &n, 0, 128))
xtables_param_act(XTF_BAD_VALUE, "IPMARK", "--shift", optarg); xtables_param_act(XTF_BAD_VALUE, "IPMARK", "--shift", optarg);
info->shift = n; info->shift = n;
*flags |= FL_SHIFT;
return true; return true;
} }
@@ -121,6 +122,8 @@ ipmark_tg_print(const void *entry, const struct xt_entry_target *target,
else else
printf("IPMARK dst ip "); printf("IPMARK dst ip ");
if (info->shift != 0)
printf("shift %u ", (unsigned int)info->shift);
if (info->andmask != ~0U) if (info->andmask != ~0U)
printf("and 0x%x ", (unsigned int)info->andmask); printf("and 0x%x ", (unsigned int)info->andmask);
if (info->ormask != 0) if (info->ormask != 0)
@@ -137,33 +140,19 @@ ipmark_tg_save(const void *entry, const struct xt_entry_target *target)
else else
printf("--addr dst "); printf("--addr dst ");
if (info->shift != 0)
printf("--shift %u ", (unsigned int)info->shift);
if (info->andmask != ~0U) if (info->andmask != ~0U)
printf("--and-mask 0x%x ", (unsigned int)info->andmask); printf("--and-mask 0x%x ", (unsigned int)info->andmask);
if (info->ormask != 0) if (info->ormask != 0)
printf("--or-mask 0x%x ", (unsigned int)info->ormask); printf("--or-mask 0x%x ", (unsigned int)info->ormask);
} }
static struct xtables_target ipmark_tg4_reg = { static struct xtables_target ipmark_tg_reg = {
.version = XTABLES_VERSION, .version = XTABLES_VERSION,
.name = "IPMARK", .name = "IPMARK",
.family = PF_INET, .family = PF_UNSPEC,
.revision = 0, .revision = 1,
.size = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
.userspacesize = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
.help = ipmark_tg_help,
.init = ipmark_tg_init,
.parse = ipmark_tg_parse,
.final_check = ipmark_tg_check,
.print = ipmark_tg_print,
.save = ipmark_tg_save,
.extra_opts = ipmark_tg_opts,
};
static struct xtables_target ipmark_tg6_reg = {
.version = XTABLES_VERSION,
.name = "IPMARK",
.family = PF_INET6,
.revision = 0,
.size = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)), .size = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
.userspacesize = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)), .userspacesize = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
.help = ipmark_tg_help, .help = ipmark_tg_help,
@@ -177,6 +166,5 @@ static struct xtables_target ipmark_tg6_reg = {
static __attribute__((constructor)) void ipmark_tg_ldr(void) static __attribute__((constructor)) void ipmark_tg_ldr(void)
{ {
xtables_register_target(&ipmark_tg4_reg); xtables_register_target(&ipmark_tg_reg);
xtables_register_target(&ipmark_tg6_reg);
} }

View File

@@ -19,7 +19,7 @@ static void steal_tg_check(unsigned int flags)
static struct xtables_target steal_tg_reg = { static struct xtables_target steal_tg_reg = {
.version = XTABLES_VERSION, .version = XTABLES_VERSION,
.name = "STEAL", .name = "STEAL",
.family = AF_INET, .family = AF_UNSPEC,
.size = XT_ALIGN(0), .size = XT_ALIGN(0),
.userspacesize = XT_ALIGN(0), .userspacesize = XT_ALIGN(0),
.help = steal_tg_help, .help = steal_tg_help,

View File

@@ -21,21 +21,11 @@ static void sysrq_tg_check(unsigned int flags)
{ {
} }
static struct xtables_target sysrq_tg4_reg = { static struct xtables_target sysrq_tg_reg = {
.version = XTABLES_VERSION, .version = XTABLES_VERSION,
.name = "SYSRQ", .name = "SYSRQ",
.family = PF_INET, .revision = 1,
.size = XT_ALIGN(0), .family = PF_UNSPEC,
.userspacesize = XT_ALIGN(0),
.help = sysrq_tg_help,
.parse = sysrq_tg_parse,
.final_check = sysrq_tg_check,
};
static struct xtables_target sysrq_tg6_reg = {
.version = XTABLES_VERSION,
.name = "SYSRQ",
.family = PF_INET6,
.size = XT_ALIGN(0), .size = XT_ALIGN(0),
.userspacesize = XT_ALIGN(0), .userspacesize = XT_ALIGN(0),
.help = sysrq_tg_help, .help = sysrq_tg_help,
@@ -45,6 +35,5 @@ static struct xtables_target sysrq_tg6_reg = {
static __attribute__((constructor)) void sysrq_tg_ldr(void) static __attribute__((constructor)) void sysrq_tg_ldr(void)
{ {
xtables_register_target(&sysrq_tg4_reg); xtables_register_target(&sysrq_tg_reg);
xtables_register_target(&sysrq_tg6_reg);
} }

View File

@@ -79,7 +79,7 @@ static void condition_save(const void *ip, const struct xt_entry_match *match)
static struct xtables_match condition_mt_reg = { static struct xtables_match condition_mt_reg = {
.name = "condition", .name = "condition",
.revision = 0, .revision = 1,
.family = PF_UNSPEC, .family = PF_UNSPEC,
.version = XTABLES_VERSION, .version = XTABLES_VERSION,
.size = XT_ALIGN(sizeof(struct xt_condition_mtinfo)), .size = XT_ALIGN(sizeof(struct xt_condition_mtinfo)),

View File

@@ -101,6 +101,7 @@ static void fuzzy_mt_save(const void *ip, const struct xt_entry_match *match)
static struct xtables_match fuzzy_mt_reg = { static struct xtables_match fuzzy_mt_reg = {
.name = "fuzzy", .name = "fuzzy",
.revision = 1,
.version = XTABLES_VERSION, .version = XTABLES_VERSION,
.size = XT_ALIGN(sizeof(struct xt_fuzzy_mtinfo)), .size = XT_ALIGN(sizeof(struct xt_fuzzy_mtinfo)),
.userspacesize = offsetof(struct xt_fuzzy_mtinfo, packets_total), .userspacesize = offsetof(struct xt_fuzzy_mtinfo, packets_total),

View File

@@ -261,6 +261,7 @@ geoip_save(const void *ip, const struct xt_entry_match *match)
static struct xtables_match geoip_match = { static struct xtables_match geoip_match = {
.family = AF_INET, .family = AF_INET,
.name = "geoip", .name = "geoip",
.revision = 1,
.version = XTABLES_VERSION, .version = XTABLES_VERSION,
.size = XT_ALIGN(sizeof(struct xt_geoip_match_info)), .size = XT_ALIGN(sizeof(struct xt_geoip_match_info)),
.userspacesize = offsetof(struct xt_geoip_match_info, mem), .userspacesize = offsetof(struct xt_geoip_match_info, mem),

View File

@@ -200,22 +200,7 @@ static struct xtables_match iface_mt_reg = {
.version = XTABLES_VERSION, .version = XTABLES_VERSION,
.name = "iface", .name = "iface",
.revision = 0, .revision = 0,
.family = AF_INET, .family = AF_UNSPEC,
.size = XT_ALIGN(sizeof(struct xt_iface_mtinfo)),
.userspacesize = XT_ALIGN(sizeof(struct xt_iface_mtinfo)),
.help = iface_mt_help,
.parse = iface_mt_parse,
.final_check = iface_mt_check,
.print = iface_mt_print,
.save = iface_mt_save,
.extra_opts = iface_mt_opts,
};
static struct xtables_match iface_mt6_reg = {
.version = XTABLES_VERSION,
.name = "iface",
.revision = 0,
.family = AF_INET6,
.size = XT_ALIGN(sizeof(struct xt_iface_mtinfo)), .size = XT_ALIGN(sizeof(struct xt_iface_mtinfo)),
.userspacesize = XT_ALIGN(sizeof(struct xt_iface_mtinfo)), .userspacesize = XT_ALIGN(sizeof(struct xt_iface_mtinfo)),
.help = iface_mt_help, .help = iface_mt_help,
@@ -229,5 +214,4 @@ static struct xtables_match iface_mt6_reg = {
static void _init(void) static void _init(void)
{ {
xtables_register_match(&iface_mt_reg); xtables_register_match(&iface_mt_reg);
xtables_register_match(&iface_mt6_reg);
} }

View File

@@ -228,7 +228,7 @@ static void ipp2p_mt_save(const void *entry, const struct xt_entry_match *match)
static struct xtables_match ipp2p_mt_reg = { static struct xtables_match ipp2p_mt_reg = {
.version = XTABLES_VERSION, .version = XTABLES_VERSION,
.name = "ipp2p", .name = "ipp2p",
.revision = 0, .revision = 1,
.family = AF_INET, .family = AF_INET,
.size = XT_ALIGN(sizeof(struct ipt_p2p_info)), .size = XT_ALIGN(sizeof(struct ipt_p2p_info)),
.userspacesize = XT_ALIGN(sizeof(struct ipt_p2p_info)), .userspacesize = XT_ALIGN(sizeof(struct ipt_p2p_info)),

158
extensions/libxt_psd.c Normal file
View File

@@ -0,0 +1,158 @@
/*
Shared library add-on to iptables to add PSD support
Copyright (C) 2000,2001 astaro AG
This file is distributed under the terms of the GNU General Public
License (GPL). Copies of the GPL can be obtained from:
ftp://prep.ai.mit.edu/pub/gnu/GPL
2000-05-04 Markus Hennig <hennig@astaro.de> : initial
2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
2003-03-02 Harald Welte <laforge@netfilter.org>: fix 'storage' bug
2008-04-03 Mohd Nawawi <nawawi@tracenetworkcorporation.com>: update to 2.6.24 / 1.4 code
2008-06-24 Mohd Nawawi <nawawi@tracenetworkcorporation.com>: update to 2.6.24 / 1.4.1 code
2009-08-07 Mohd Nawawi Mohamad Jamili <nawawi@tracenetworkcorporation.com> : ported to xtables-addons
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <syslog.h>
#include <getopt.h>
#include <xtables.h>
#include <linux/netfilter/x_tables.h>
#include "xt_psd.h"
/* Function which prints out usage message. */
static void psd_mt_help(void) {
printf(
"psd match options:\n"
" --psd-weight-threshold threshhold Portscan detection weight threshold\n"
" --psd-delay-threshold delay Portscan detection delay threshold\n"
" --psd-lo-ports-weight lo Privileged ports weight\n"
" --psd-hi-ports-weight hi High ports weight\n\n");
}
static const struct option psd_mt_opts[] = {
{.name = "psd-weight-threshold", .has_arg = true, .val = '1'},
{.name = "psd-delay-threshold", .has_arg = true, .val = '2'},
{.name = "psd-lo-ports-weight", .has_arg = true, .val = '3'},
{.name = "psd-hi-ports-weight", .has_arg = true, .val = '4'},
{NULL}
};
/* Initialize the target. */
static void psd_mt_init(struct xt_entry_match *match) {
struct xt_psd_info *psdinfo = (struct xt_psd_info *)match->data;
psdinfo->weight_threshold = SCAN_WEIGHT_THRESHOLD;
psdinfo->delay_threshold = SCAN_DELAY_THRESHOLD;
psdinfo->lo_ports_weight = PORT_WEIGHT_PRIV;
psdinfo->hi_ports_weight = PORT_WEIGHT_HIGH;
}
#define XT_PSD_OPT_CTRESH 0x01
#define XT_PSD_OPT_DTRESH 0x02
#define XT_PSD_OPT_LPWEIGHT 0x04
#define XT_PSD_OPT_HPWEIGHT 0x08
static int psd_mt_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_match **match)
{
struct xt_psd_info *psdinfo = (struct xt_psd_info *)(*match)->data;
unsigned int num;
switch (c) {
/* PSD-weight-threshold */
case '1':
if (*flags & XT_PSD_OPT_CTRESH)
xtables_error(PARAMETER_PROBLEM,"Can't specify --psd-weight-threshold twice");
if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
xtables_error(PARAMETER_PROBLEM, "bad --psd-weight-threshold '%s'", optarg);
psdinfo->weight_threshold = num;
*flags |= XT_PSD_OPT_CTRESH;
return true;
/* PSD-delay-threshold */
case '2':
if (*flags & XT_PSD_OPT_DTRESH)
xtables_error(PARAMETER_PROBLEM, "Can't specify --psd-delay-threshold twice");
if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
xtables_error(PARAMETER_PROBLEM, "bad --psd-delay-threshold '%s'", optarg);
psdinfo->delay_threshold = num;
*flags |= XT_PSD_OPT_DTRESH;
return true;
/* PSD-lo-ports-weight */
case '3':
if (*flags & XT_PSD_OPT_LPWEIGHT)
xtables_error(PARAMETER_PROBLEM, "Can't specify --psd-lo-ports-weight twice");
if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
xtables_error(PARAMETER_PROBLEM, "bad --psd-lo-ports-weight '%s'", optarg);
psdinfo->lo_ports_weight = num;
*flags |= XT_PSD_OPT_LPWEIGHT;
return true;
/* PSD-hi-ports-weight */
case '4':
if (*flags & XT_PSD_OPT_HPWEIGHT)
xtables_error(PARAMETER_PROBLEM, "Can't specify --psd-hi-ports-weight twice");
if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
xtables_error(PARAMETER_PROBLEM, "bad --psd-hi-ports-weight '%s'", optarg);
psdinfo->hi_ports_weight = num;
*flags |= XT_PSD_OPT_HPWEIGHT;
return true;
}
return false;
}
/* Final check; nothing. */
static void psd_mt_final_check(unsigned int flags) {}
/* Prints out the targinfo. */
static void psd_mt_print(const void *ip, const struct xt_entry_match *match, int numeric)
{
const struct xt_psd_info *psdinfo = (const struct xt_psd_info *)match->data;
printf("psd ");
printf("weight-threshold: %u ", psdinfo->weight_threshold);
printf("delay-threshold: %u ", psdinfo->delay_threshold);
printf("lo-ports-weight: %u ", psdinfo->lo_ports_weight);
printf("hi-ports-weight: %u ", psdinfo->hi_ports_weight);
}
/* Saves the union ipt_targinfo in parsable form to stdout. */
static void psd_mt_save(const void *ip, const struct xt_entry_match *match)
{
const struct xt_psd_info *psdinfo = (const struct xt_psd_info *)match->data;
printf("--psd-weight-threshold %u ", psdinfo->weight_threshold);
printf("--psd-delay-threshold %u ", psdinfo->delay_threshold);
printf("--psd-lo-ports-weight %u ", psdinfo->lo_ports_weight);
printf("--psd-hi-ports-weight %u ", psdinfo->hi_ports_weight);
}
static struct xtables_match psd_mt_reg = {
.name = "psd",
.version = XTABLES_VERSION,
.revision = 1,
.family = PF_INET,
.size = XT_ALIGN(sizeof(struct xt_psd_info)),
.userspacesize = XT_ALIGN(sizeof(struct xt_psd_info)),
.help = psd_mt_help,
.init = psd_mt_init,
.parse = psd_mt_parse,
.final_check = psd_mt_final_check,
.print = psd_mt_print,
.save = psd_mt_save,
.extra_opts = psd_mt_opts,
};
static __attribute__((constructor)) void psd_mt_ldr(void)
{
xtables_register_match(&psd_mt_reg);
}

18
extensions/libxt_psd.man Normal file
View File

@@ -0,0 +1,18 @@
Attempt to detect TCP and UDP port scans. This match was derived from
Solar Designer's scanlogd.
.TP
.BI "--psd-weight-threshold " "threshold"
Total weight of the latest TCP/UDP packets with different
destination ports coming from the same host to be treated as port
scan sequence.
.TP
.BI "--psd-delay-threshold " "delay"
Delay (in hundredths of second) for the packets with different
destination ports coming from the same host to be treated as
possible port scan subsequence.
.TP
.BI "--psd-lo-ports-weight " "weight"
Weight of the packet with privileged (<=1024) destination port.
.TP
.BI "--psd-hi-ports-weight " "weight"
Weight of the packet with non-priviliged destination port.

View File

@@ -121,7 +121,7 @@ static void quota_mt2_print(const void *ip, const struct xt_entry_match *match,
static struct xtables_match quota_mt2_reg = { static struct xtables_match quota_mt2_reg = {
.family = AF_UNSPEC, .family = AF_UNSPEC,
.revision = 2, .revision = 3,
.name = "quota2", .name = "quota2",
.version = XTABLES_VERSION, .version = XTABLES_VERSION,
.size = XT_ALIGN(sizeof (struct xt_quota_mtinfo2)), .size = XT_ALIGN(sizeof (struct xt_quota_mtinfo2)),

1104
extensions/xt_ACCOUNT.c Normal file

File diff suppressed because it is too large Load Diff

118
extensions/xt_ACCOUNT.h Normal file
View File

@@ -0,0 +1,118 @@
/***************************************************************************
* Copyright (C) 2004-2006 by Intra2net AG *
* opensource@intra2net.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License *
* version 2 as published by the Free Software Foundation; *
* *
***************************************************************************/
#ifndef _IPT_ACCOUNT_H
#define _IPT_ACCOUNT_H
/*
* Socket option interface shared between kernel (xt_ACCOUNT) and userspace
* library (libxt_ACCOUNT_cl). Hopefully we are unique at least within our
* kernel & xtables-addons space.
*/
#define SO_ACCOUNT_BASE_CTL 90
#define IPT_SO_SET_ACCOUNT_HANDLE_FREE (SO_ACCOUNT_BASE_CTL + 1)
#define IPT_SO_SET_ACCOUNT_HANDLE_FREE_ALL (SO_ACCOUNT_BASE_CTL + 2)
#define IPT_SO_SET_ACCOUNT_MAX IPT_SO_SET_ACCOUNT_HANDLE_FREE_ALL
#define IPT_SO_GET_ACCOUNT_PREPARE_READ (SO_ACCOUNT_BASE_CTL + 4)
#define IPT_SO_GET_ACCOUNT_PREPARE_READ_FLUSH (SO_ACCOUNT_BASE_CTL + 5)
#define IPT_SO_GET_ACCOUNT_GET_DATA (SO_ACCOUNT_BASE_CTL + 6)
#define IPT_SO_GET_ACCOUNT_GET_HANDLE_USAGE (SO_ACCOUNT_BASE_CTL + 7)
#define IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES (SO_ACCOUNT_BASE_CTL + 8)
#define IPT_SO_GET_ACCOUNT_MAX IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES
#define ACCOUNT_MAX_TABLES 128
#define ACCOUNT_TABLE_NAME_LEN 32
#define ACCOUNT_MAX_HANDLES 10
/* Structure for the userspace part of ipt_ACCOUNT */
struct ipt_acc_info {
uint32_t net_ip;
uint32_t net_mask;
char table_name[ACCOUNT_TABLE_NAME_LEN];
int32_t table_nr;
};
/* Internal table structure, generated by check_entry() */
struct ipt_acc_table {
char name[ACCOUNT_TABLE_NAME_LEN]; /* name of the table */
uint32_t ip; /* base IP of network */
uint32_t netmask; /* netmask of the network */
unsigned char depth; /* size of network:
0: 8 bit, 1: 16bit, 2: 24 bit */
uint32_t refcount; /* refcount of this table.
if zero, destroy it */
uint32_t itemcount; /* number of IPs in this table */
void *data; /* pointer to the actual data,
depending on netmask */
};
/* Internal handle structure */
struct ipt_acc_handle {
uint32_t ip; /* base IP of network. Used for
caculating the final IP during
get_data() */
unsigned char depth; /* size of network. See above for
details */
uint32_t itemcount; /* number of IPs in this table */
void *data; /* pointer to the actual data,
depending on size */
};
/* Handle structure for communication with the userspace library */
struct ipt_acc_handle_sockopt {
uint32_t handle_nr; /* Used for HANDLE_FREE */
char name[ACCOUNT_TABLE_NAME_LEN]; /* Used for HANDLE_PREPARE_READ/
HANDLE_READ_FLUSH */
uint32_t itemcount; /* Used for HANDLE_PREPARE_READ/
HANDLE_READ_FLUSH */
};
/* Used for every IP entry
Size is 16 bytes so that 256 (class C network) * 16
fits in one kernel (zero) page */
struct ipt_acc_ip {
uint32_t src_packets;
uint32_t src_bytes;
uint32_t dst_packets;
uint32_t dst_bytes;
};
/*
Used for every IP when returning data
*/
struct ipt_acc_handle_ip {
uint32_t ip;
uint32_t src_packets;
uint32_t src_bytes;
uint32_t dst_packets;
uint32_t dst_bytes;
};
/*
The IPs are organized as an array so that direct slot
calculations are possible.
Only 8 bit networks are preallocated, 16/24 bit networks
allocate their slots when needed -> very efficent.
*/
struct ipt_acc_mask_24 {
struct ipt_acc_ip ip[256];
};
struct ipt_acc_mask_16 {
struct ipt_acc_mask_24 *mask_24[256];
};
struct ipt_acc_mask_8 {
struct ipt_acc_mask_16 *mask_16[256];
};
#endif /* _IPT_ACCOUNT_H */

View File

@@ -119,19 +119,18 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
addr_type = RTN_LOCAL; addr_type = RTN_LOCAL;
/* ip_route_me_harder expects skb->dst to be set */ /* ip_route_me_harder expects skb->dst to be set */
dst_hold(oldskb->dst); skb_dst_set(nskb, dst_clone(skb_dst(oldskb)));
nskb->dst = oldskb->dst;
if (ip_route_me_harder(&nskb, addr_type)) if (ip_route_me_harder(&nskb, addr_type))
goto free_nskb; goto free_nskb;
else else
niph = ip_hdr(nskb); niph = ip_hdr(nskb);
niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); niph->ttl = dst_metric(skb_dst(nskb), RTAX_HOPLIMIT);
nskb->ip_summed = CHECKSUM_NONE; nskb->ip_summed = CHECKSUM_NONE;
/* "Never happens" */ /* "Never happens" */
if (nskb->len > dst_mtu(nskb->dst)) if (nskb->len > dst_mtu(skb_dst(nskb)))
goto free_nskb; goto free_nskb;
nf_ct_attach(nskb, oldskb); nf_ct_attach(nskb, oldskb);

View File

@@ -82,7 +82,7 @@ ipmark_tg6(struct sk_buff **pskb, const struct xt_target_param *par)
static struct xt_target ipmark_tg_reg[] __read_mostly = { static struct xt_target ipmark_tg_reg[] __read_mostly = {
{ {
.name = "IPMARK", .name = "IPMARK",
.revision = 0, .revision = 1,
.family = NFPROTO_IPV4, .family = NFPROTO_IPV4,
.table = "mangle", .table = "mangle",
.target = ipmark_tg4, .target = ipmark_tg4,
@@ -91,7 +91,7 @@ static struct xt_target ipmark_tg_reg[] __read_mostly = {
}, },
{ {
.name = "IPMARK", .name = "IPMARK",
.revision = 0, .revision = 1,
.family = NFPROTO_IPV6, .family = NFPROTO_IPV6,
.table = "mangle", .table = "mangle",
.target = ipmark_tg6, .target = ipmark_tg6,

View File

@@ -272,7 +272,7 @@ static bool sysrq_tg_check(const struct xt_tgchk_param *par)
static struct xt_target sysrq_tg_reg[] __read_mostly = { static struct xt_target sysrq_tg_reg[] __read_mostly = {
{ {
.name = "SYSRQ", .name = "SYSRQ",
.revision = 0, .revision = 1,
.family = NFPROTO_IPV4, .family = NFPROTO_IPV4,
.target = sysrq_tg4, .target = sysrq_tg4,
.checkentry = sysrq_tg_check, .checkentry = sysrq_tg_check,
@@ -280,7 +280,7 @@ static struct xt_target sysrq_tg_reg[] __read_mostly = {
}, },
{ {
.name = "SYSRQ", .name = "SYSRQ",
.revision = 0, .revision = 1,
.family = NFPROTO_IPV6, .family = NFPROTO_IPV6,
.target = sysrq_tg6, .target = sysrq_tg6,
.checkentry = sysrq_tg_check, .checkentry = sysrq_tg_check,

View File

@@ -167,20 +167,20 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
nskb->ip_summed = CHECKSUM_NONE; nskb->ip_summed = CHECKSUM_NONE;
/* Adjust IP TTL */ /* Adjust IP TTL */
niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); niph->ttl = dst_metric(skb_dst(nskb), RTAX_HOPLIMIT);
/* Adjust IP checksum */ /* Adjust IP checksum */
niph->check = 0; niph->check = 0;
niph->check = ip_fast_csum(skb_network_header(nskb), niph->ihl); niph->check = ip_fast_csum(skb_network_header(nskb), niph->ihl);
/* "Never happens" */ /* "Never happens" */
if (nskb->len > dst_mtu(nskb->dst)) if (nskb->len > dst_mtu(skb_dst(nskb)))
goto free_nskb; goto free_nskb;
nf_ct_attach(nskb, oldskb); nf_ct_attach(nskb, oldskb);
NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, nskb, NULL, nskb->dst->dev, NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, nskb, NULL,
dst_output); skb_dst(nskb)->dev, dst_output);
return; return;
free_nskb: free_nskb:
@@ -192,7 +192,7 @@ tarpit_tg(struct sk_buff **pskb, const struct xt_target_param *par)
{ {
const struct sk_buff *skb = *pskb; const struct sk_buff *skb = *pskb;
const struct iphdr *iph = ip_hdr(skb); const struct iphdr *iph = ip_hdr(skb);
const struct rtable *rt = (const void *)skb->dst; const struct rtable *rt = skb_rtable(skb);
/* Do we have an input route cache entry? (Not in PREROUTING.) */ /* Do we have an input route cache entry? (Not in PREROUTING.) */
if (rt == NULL) if (rt == NULL)

View File

@@ -79,9 +79,9 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info)
return false; return false;
} }
dst_release(skb->dst); dst_release(skb_dst(skb));
skb->dst = &rt->u.dst; skb_dst_set(skb, &rt->u.dst);
skb->dev = skb->dst->dev; skb->dev = rt->u.dst.dev;
skb->protocol = htons(ETH_P_IP); skb->protocol = htons(ETH_P_IP);
return true; return true;
} }
@@ -104,7 +104,7 @@ static inline bool dev_hh_avail(const struct net_device *dev)
*/ */
static void tee_tg_send(struct sk_buff *skb) static void tee_tg_send(struct sk_buff *skb)
{ {
const struct dst_entry *dst = skb->dst; const struct dst_entry *dst = skb_dst(skb);
const struct net_device *dev = dst->dev; const struct net_device *dev = dst->dev;
unsigned int hh_len = LL_RESERVED_SPACE(dev); unsigned int hh_len = LL_RESERVED_SPACE(dev);
@@ -175,7 +175,7 @@ tee_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
/* /*
* Copy the skb, and route the copy. Will later return %XT_CONTINUE for * Copy the skb, and route the copy. Will later return %XT_CONTINUE for
* the original skb, which should continue on its way as if nothing has * the original skb, which should continue on its way as if nothing has
* happened. The copy should be independantly delivered to the TEE --gw. * happened. The copy should be independently delivered to the TEE --gw.
*/ */
skb = skb_copy(skb, GFP_ATOMIC); skb = skb_copy(skb, GFP_ATOMIC);
if (skb == NULL) { if (skb == NULL) {
@@ -251,9 +251,9 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info)
return false; return false;
} }
dst_release(skb->dst); dst_release(skb_dst(skb));
skb->dst = dst; skb_dst_set(skb, dst);
skb->dev = skb->dst->dev; skb->dev = dst->dev;
skb->protocol = htons(ETH_P_IPV6); skb->protocol = htons(ETH_P_IPV6);
return true; return true;
} }

View File

@@ -206,7 +206,7 @@ static void condition_mt_destroy(const struct xt_mtdtor_param *par)
static struct xt_match condition_mt_reg[] __read_mostly = { static struct xt_match condition_mt_reg[] __read_mostly = {
{ {
.name = "condition", .name = "condition",
.revision = 0, .revision = 1,
.family = NFPROTO_IPV4, .family = NFPROTO_IPV4,
.matchsize = XT_ALIGN(sizeof(struct xt_condition_mtinfo)), .matchsize = XT_ALIGN(sizeof(struct xt_condition_mtinfo)),
.match = condition_mt, .match = condition_mt,
@@ -216,7 +216,7 @@ static struct xt_match condition_mt_reg[] __read_mostly = {
}, },
{ {
.name = "condition", .name = "condition",
.revision = 0, .revision = 1,
.family = NFPROTO_IPV6, .family = NFPROTO_IPV6,
.matchsize = XT_ALIGN(sizeof(struct xt_condition_mtinfo)), .matchsize = XT_ALIGN(sizeof(struct xt_condition_mtinfo)),
.match = condition_mt, .match = condition_mt,

View File

@@ -142,7 +142,7 @@ static bool fuzzy_mt_check(const struct xt_mtchk_param *par)
static struct xt_match fuzzy_mt_reg[] __read_mostly = { static struct xt_match fuzzy_mt_reg[] __read_mostly = {
{ {
.name = "fuzzy", .name = "fuzzy",
.revision = 0, .revision = 1,
.family = NFPROTO_IPV4, .family = NFPROTO_IPV4,
.match = fuzzy_mt, .match = fuzzy_mt,
.checkentry = fuzzy_mt_check, .checkentry = fuzzy_mt_check,
@@ -151,7 +151,7 @@ static struct xt_match fuzzy_mt_reg[] __read_mostly = {
}, },
{ {
.name = "fuzzy", .name = "fuzzy",
.revision = 0, .revision = 1,
.family = NFPROTO_IPV6, .family = NFPROTO_IPV6,
.match = fuzzy_mt, .match = fuzzy_mt,
.checkentry = fuzzy_mt_check, .checkentry = fuzzy_mt_check,

View File

@@ -222,7 +222,7 @@ static void xt_geoip_mt_destroy(const struct xt_mtdtor_param *par)
static struct xt_match xt_geoip_match __read_mostly = { static struct xt_match xt_geoip_match __read_mostly = {
.name = "geoip", .name = "geoip",
.revision = 0, .revision = 1,
.family = NFPROTO_IPV4, .family = NFPROTO_IPV4,
.match = xt_geoip_mt, .match = xt_geoip_mt,
.checkentry = xt_geoip_mt_checkentry, .checkentry = xt_geoip_mt_checkentry,

View File

@@ -890,7 +890,7 @@ ipp2p_mt(const struct sk_buff *skb, const struct xt_match_param *par)
static struct xt_match ipp2p_mt_reg __read_mostly = { static struct xt_match ipp2p_mt_reg __read_mostly = {
.name = "ipp2p", .name = "ipp2p",
.revision = 0, .revision = 1,
.family = NFPROTO_IPV4, .family = NFPROTO_IPV4,
.match = ipp2p_mt, .match = ipp2p_mt,
.matchsize = sizeof(struct ipt_p2p_info), .matchsize = sizeof(struct ipt_p2p_info),

View File

@@ -0,0 +1,6 @@
config NETFILTER_XT_MATCH_PSD
tristate 'psd match support'
depends on NETFILTER_XTABLES && NETFILTER_ADVANCED
---help---
This option adds a `psd' match, which allows you to create rules in
any iptables table wich will detect TCP and UDP port scans.

332
extensions/xt_psd.c Normal file
View File

@@ -0,0 +1,332 @@
/*
This is a module which is used for PSD (portscan detection)
Derived from scanlogd v2.1 written by Solar Designer <solar@false.com>
and LOG target module.
Copyright (C) 2000,2001 astaro AG
This file is distributed under the terms of the GNU General Public
License (GPL). Copies of the GPL can be obtained from:
ftp://prep.ai.mit.edu/pub/gnu/GPL
2000-05-04 Markus Hennig <hennig@astaro.de> : initial
2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified
2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
2004-05-05 Martijn Lievaart <m@rtij.nl> : ported to 2.6
2007-04-05 Mohd Nawawi Mohamad Jamili <nawawi@tracenetworkcorporation.com> : ported to 2.6.18
2008-03-21 Mohd Nawawi Mohamad Jamili <nawawi@tracenetworkcorporation.com> : ported to 2.6.24
2009-08-07 Mohd Nawawi Mohamad Jamili <nawawi@tracenetworkcorporation.com> : ported to xtables-addons
*/
#define pr_fmt(x) KBUILD_MODNAME ": " x
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <net/tcp.h>
#include <linux/spinlock.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter/x_tables.h>
#include "xt_psd.h"
#include "compat_xtables.h"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Dennis Koslowski <koslowski@astaro.com>");
MODULE_AUTHOR("Martijn Lievaart <m@rtij.nl>");
MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
MODULE_AUTHOR(" Mohd Nawawi Mohamad Jamili <nawawi@tracenetworkcorporation.com>");
MODULE_DESCRIPTION("Xtables: PSD - portscan detection");
MODULE_ALIAS("ipt_psd");
#define HF_DADDR_CHANGING 0x01
#define HF_SPORT_CHANGING 0x02
#define HF_TOS_CHANGING 0x04
#define HF_TTL_CHANGING 0x08
/*
* Information we keep per each target port
*/
struct port {
u_int16_t number; /* port number */
u_int8_t proto; /* protocol number */
u_int8_t and_flags; /* tcp ANDed flags */
u_int8_t or_flags; /* tcp ORed flags */
};
/*
* Information we keep per each source address.
*/
struct host {
struct host *next; /* Next entry with the same hash */
unsigned long timestamp; /* Last update time */
struct in_addr src_addr; /* Source address */
struct in_addr dest_addr; /* Destination address */
unsigned short src_port; /* Source port */
int count; /* Number of ports in the list */
int weight; /* Total weight of ports in the list */
struct port ports[SCAN_MAX_COUNT - 1]; /* List of ports */
unsigned char tos; /* TOS */
unsigned char ttl; /* TTL */
unsigned char flags; /* HF_ flags bitmask */
};
/*
* State information.
*/
static struct {
spinlock_t lock;
struct host list[LIST_SIZE]; /* List of source addresses */
struct host *hash[HASH_SIZE]; /* Hash: pointers into the list */
int index; /* Oldest entry to be replaced */
} state;
/*
* Convert an IP address into a hash table index.
*/
static inline int hashfunc(struct in_addr addr)
{
unsigned int value;
int hash;
value = addr.s_addr;
hash = 0;
do {
hash ^= value;
} while ((value >>= HASH_LOG) != 0);
return hash & (HASH_SIZE - 1);
}
static bool
xt_psd_match(const struct sk_buff *pskb, const struct xt_match_param *match)
{
struct iphdr *iph;
struct tcphdr *tcph;
struct in_addr addr;
u_int16_t src_port,dest_port;
u_int8_t tcp_flags, proto;
unsigned long now;
struct host *curr, *last, **head;
int hash, index, count;
/* Parameters from userspace */
const struct xt_psd_info *psdinfo = match->matchinfo;
/* IP header */
iph = ip_hdr(pskb);
/* Sanity check */
if (ntohs(iph->frag_off) & IP_OFFSET) {
pr_debug("sanity check failed\n");
return false;
}
/* TCP or UDP ? */
proto = iph->protocol;
if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
pr_debug("protocol not supported\n");
return false;
}
/* Get the source address, source & destination ports, and TCP flags */
addr.s_addr = iph->saddr;
tcph = (void *)iph + ip_hdrlen(pskb);
/* Yep, it's dirty */
src_port = tcph->source;
dest_port = tcph->dest;
if (proto == IPPROTO_TCP)
tcp_flags = *((u_int8_t*)tcph + 13);
else
tcp_flags = 0x00;
/* We're using IP address 0.0.0.0 for a special purpose here, so don't let
* them spoof us. [DHCP needs this feature - HW] */
if (addr.s_addr == 0) {
pr_debug("spoofed source address (0.0.0.0)\n");
return false;
}
/* Use jiffies here not to depend on someone setting the time while we're
* running; we need to be careful with possible return value overflows. */
now = jiffies;
spin_lock(&state.lock);
/* Do we know this source address already? */
count = 0;
last = NULL;
if ((curr = *(head = &state.hash[hash = hashfunc(addr)])) != NULL)
do {
if (curr->src_addr.s_addr == addr.s_addr)
break;
count++;
if (curr->next != NULL)
last = curr;
} while ((curr = curr->next) != NULL);
if (curr != NULL) {
/* We know this address, and the entry isn't too old. Update it. */
if (now - curr->timestamp <= (psdinfo->delay_threshold*HZ)/100 &&
time_after_eq(now, curr->timestamp)) {
/* Just update the appropriate list entry if we've seen this port already */
for (index = 0; index < curr->count; index++) {
if (curr->ports[index].number == dest_port) {
curr->ports[index].proto = proto;
curr->ports[index].and_flags &= tcp_flags;
curr->ports[index].or_flags |= tcp_flags;
goto out_no_match;
}
}
/* TCP/ACK and/or TCP/RST to a new port? This could be an outgoing connection. */
if (proto == IPPROTO_TCP && (tcph->ack || tcph->rst))
goto out_no_match;
/* Packet to a new port, and not TCP/ACK: update the timestamp */
curr->timestamp = now;
/* Logged this scan already? Then drop the packet. */
if (curr->weight >= psdinfo->weight_threshold)
goto out_match;
/* Specify if destination address, source port, TOS or TTL are not fixed */
if (curr->dest_addr.s_addr != iph->daddr)
curr->flags |= HF_DADDR_CHANGING;
if (curr->src_port != src_port)
curr->flags |= HF_SPORT_CHANGING;
if (curr->tos != iph->tos)
curr->flags |= HF_TOS_CHANGING;
if (curr->ttl != iph->ttl)
curr->flags |= HF_TTL_CHANGING;
/* Update the total weight */
curr->weight += (ntohs(dest_port) < 1024) ?
psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
/* Got enough destination ports to decide that this is a scan? */
/* Then log it and drop the packet. */
if (curr->weight >= psdinfo->weight_threshold)
goto out_match;
/* Remember the new port */
if (curr->count < SCAN_MAX_COUNT) {
curr->ports[curr->count].number = dest_port;
curr->ports[curr->count].proto = proto;
curr->ports[curr->count].and_flags = tcp_flags;
curr->ports[curr->count].or_flags = tcp_flags;
curr->count++;
}
goto out_no_match;
}
/* We know this address, but the entry is outdated. Mark it unused, and
* remove from the hash table. We'll allocate a new entry instead since
* this one might get re-used too soon. */
curr->src_addr.s_addr = 0;
if (last != NULL)
last->next = last->next->next;
else if (*head != NULL)
*head = (*head)->next;
last = NULL;
}
/* We don't need an ACK from a new source address */
if (proto == IPPROTO_TCP && tcph->ack)
goto out_no_match;
/* Got too many source addresses with the same hash value? Then remove the
* oldest one from the hash table, so that they can't take too much of our
* CPU time even with carefully chosen spoofed IP addresses. */
if (count >= HASH_MAX && last != NULL)
last->next = NULL;
/* We're going to re-use the oldest list entry, so remove it from the hash
* table first (if it is really already in use, and isn't removed from the
* hash table already because of the HASH_MAX check above). */
/* First, find it */
if (state.list[state.index].src_addr.s_addr != 0)
head = &state.hash[hashfunc(state.list[state.index].src_addr)];
else
head = &last;
last = NULL;
if ((curr = *head) != NULL)
do {
if (curr == &state.list[state.index])
break;
last = curr;
} while ((curr = curr->next) != NULL);
/* Then, remove it */
if (curr != NULL) {
if (last != NULL)
last->next = last->next->next;
else if (*head != NULL)
*head = (*head)->next;
}
/* Get our list entry */
curr = &state.list[state.index++];
if (state.index >= LIST_SIZE)
state.index = 0;
/* Link it into the hash table */
head = &state.hash[hash];
curr->next = *head;
*head = curr;
/* And fill in the fields */
curr->timestamp = now;
curr->src_addr = addr;
curr->dest_addr.s_addr = iph->daddr;
curr->src_port = src_port;
curr->count = 1;
curr->weight = (ntohs(dest_port) < 1024) ? psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
curr->ports[0].number = dest_port;
curr->ports[0].proto = proto;
curr->ports[0].and_flags = tcp_flags;
curr->ports[0].or_flags = tcp_flags;
curr->tos = iph->tos;
curr->ttl = iph->ttl;
out_no_match:
spin_unlock(&state.lock);
return false;
out_match:
spin_unlock(&state.lock);
return true;
}
static struct xt_match xt_psd_reg __read_mostly = {
.name = "psd",
.family = AF_INET,
.revision = 1,
.match = xt_psd_match,
.matchsize = sizeof(struct xt_psd_info),
.me = THIS_MODULE,
};
static int __init xt_psd_init(void)
{
spin_lock_init(&(state.lock));
return xt_register_match(&xt_psd_reg);
}
static void __exit xt_psd_exit(void)
{
xt_unregister_match(&xt_psd_reg);
}
module_init(xt_psd_init);
module_exit(xt_psd_exit);

41
extensions/xt_psd.h Normal file
View File

@@ -0,0 +1,41 @@
#ifndef _LINUX_NETFILTER_XT_PSD_H
#define _LINUX_NETFILTER_XT_PSD_H 1
#include <linux/param.h>
#include <linux/types.h>
/*
* High port numbers have a lower weight to reduce the frequency of false
* positives, such as from passive mode FTP transfers.
*/
#define PORT_WEIGHT_PRIV 3
#define PORT_WEIGHT_HIGH 1
#define PSD_MAX_RATE 10000
/*
* Port scan detection thresholds: at least COUNT ports need to be scanned
* from the same source, with no longer than DELAY ticks between ports.
*/
#define SCAN_MIN_COUNT 7
#define SCAN_MAX_COUNT (SCAN_MIN_COUNT * PORT_WEIGHT_PRIV)
#define SCAN_WEIGHT_THRESHOLD SCAN_MAX_COUNT
#define SCAN_DELAY_THRESHOLD (300) /* old usage of HZ here was erroneously and broke under uml */
/*
* Keep track of up to LIST_SIZE source addresses, using a hash table of
* HASH_SIZE entries for faster lookups, but limiting hash collisions to
* HASH_MAX source addresses per the same hash value.
*/
#define LIST_SIZE 0x100
#define HASH_LOG 9
#define HASH_SIZE (1 << HASH_LOG)
#define HASH_MAX 0x10
struct xt_psd_info {
__u32 weight_threshold;
__u32 delay_threshold;
__u16 lo_ports_weight;
__u16 hi_ports_weight;
};
#endif /*_LINUX_NETFILTER_XT_PSD_H*/

View File

@@ -21,12 +21,15 @@
#include "xt_quota2.h" #include "xt_quota2.h"
#include "compat_xtables.h" #include "compat_xtables.h"
struct quota_counter { /**
* @lock: lock to protect quota writers from each other
*/
struct xt_quota_counter {
u_int64_t quota; u_int64_t quota;
spinlock_t lock; spinlock_t lock;
struct list_head list; struct list_head list;
atomic_t ref; atomic_t ref;
char name[XT_QUOTA_COUNTER_NAME_LENGTH]; char name[sizeof(((struct xt_quota_mtinfo2 *)NULL)->name)];
struct proc_dir_entry *procfs_entry; struct proc_dir_entry *procfs_entry;
}; };
@@ -44,7 +47,7 @@ module_param_named(gid, quota_list_gid, uint, S_IRUGO | S_IWUSR);
static int quota_proc_read(char *page, char **start, off_t offset, static int quota_proc_read(char *page, char **start, off_t offset,
int count, int *eof, void *data) int count, int *eof, void *data)
{ {
struct quota_counter *e = data; struct xt_quota_counter *e = data;
int ret; int ret;
spin_lock_bh(&e->lock); spin_lock_bh(&e->lock);
@@ -56,7 +59,7 @@ static int quota_proc_read(char *page, char **start, off_t offset,
static int quota_proc_write(struct file *file, const char __user *input, static int quota_proc_write(struct file *file, const char __user *input,
unsigned long size, void *data) unsigned long size, void *data)
{ {
struct quota_counter *e = data; struct xt_quota_counter *e = data;
char buf[sizeof("18446744073709551616")]; char buf[sizeof("18446744073709551616")];
if (size > sizeof(buf)) if (size > sizeof(buf))
@@ -66,45 +69,66 @@ static int quota_proc_write(struct file *file, const char __user *input,
buf[sizeof(buf)-1] = '\0'; buf[sizeof(buf)-1] = '\0';
spin_lock_bh(&e->lock); spin_lock_bh(&e->lock);
e->quota = simple_strtoul(buf, NULL, 0); e->quota = simple_strtoull(buf, NULL, 0);
spin_unlock_bh(&e->lock); spin_unlock_bh(&e->lock);
return size; return size;
} }
static struct xt_quota_counter *
q2_new_counter(const struct xt_quota_mtinfo2 *q, bool anon)
{
struct xt_quota_counter *e;
unsigned int size;
/* Do not need all the procfs things for anonymous counters. */
size = anon ? offsetof(typeof(*e), list) : sizeof(*e);
e = kmalloc(size, GFP_KERNEL);
if (e == NULL)
return NULL;
e->quota = q->quota;
spin_lock_init(&e->lock);
if (!anon) {
INIT_LIST_HEAD(&e->list);
atomic_set(&e->ref, 1);
strncpy(e->name, q->name, sizeof(e->name));
}
return e;
}
/** /**
* q2_get_counter - get ref to counter or create new * q2_get_counter - get ref to counter or create new
* @name: name of counter * @name: name of counter
*/ */
static struct quota_counter *q2_get_counter(const struct xt_quota_mtinfo2 *q) static struct xt_quota_counter *
q2_get_counter(const struct xt_quota_mtinfo2 *q)
{ {
struct proc_dir_entry *p; struct proc_dir_entry *p;
struct quota_counter *e; struct xt_quota_counter *e;
if (*q->name == '\0')
return q2_new_counter(q, true);
spin_lock_bh(&counter_list_lock); spin_lock_bh(&counter_list_lock);
list_for_each_entry(e, &counter_list, list) { list_for_each_entry(e, &counter_list, list)
if (strcmp(e->name, q->name) == 0) { if (strcmp(e->name, q->name) == 0) {
atomic_inc(&e->ref); atomic_inc(&e->ref);
spin_unlock_bh(&counter_list_lock); spin_unlock_bh(&counter_list_lock);
return e; return e;
} }
}
e = kmalloc(sizeof(struct quota_counter), GFP_KERNEL); e = q2_new_counter(q, false);
if (e == NULL) if (e == NULL)
goto out; goto out;
e->quota = q->quota;
spin_lock_init(&e->lock);
INIT_LIST_HEAD(&e->list);
atomic_set(&e->ref, 1);
strncpy(e->name, q->name, sizeof(e->name));
p = e->procfs_entry = create_proc_entry(e->name, quota_list_perms, p = e->procfs_entry = create_proc_entry(e->name, quota_list_perms,
proc_xt_quota); proc_xt_quota);
if (p == NULL || IS_ERR(p)) if (p == NULL || IS_ERR(p))
goto out; goto out;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 29)
p->owner = THIS_MODULE; p->owner = THIS_MODULE;
#endif
p->data = e; p->data = e;
p->read_proc = quota_proc_read; p->read_proc = quota_proc_read;
p->write_proc = quota_proc_write; p->write_proc = quota_proc_write;
@@ -128,15 +152,16 @@ static bool quota_mt2_check(const struct xt_mtchk_param *par)
return false; return false;
q->name[sizeof(q->name)-1] = '\0'; q->name[sizeof(q->name)-1] = '\0';
if (*q->name == '\0' || *q->name == '.' || if (*q->name == '.' || strchr(q->name, '/') != NULL) {
strchr(q->name, '/') != NULL) { printk(KERN_ERR "xt_quota<%u>: illegal name\n",
printk(KERN_ERR "xt_quota.2: illegal name\n"); par->match->revision);
return false; return false;
} }
q->master = q2_get_counter(q); q->master = q2_get_counter(q);
if (q->master == NULL) { if (q->master == NULL) {
printk(KERN_ERR "xt_quota.2: memory alloc failure\n"); printk(KERN_ERR "xt_quota<%u>: memory alloc failure\n",
par->match->revision);
return false; return false;
} }
@@ -146,7 +171,12 @@ static bool quota_mt2_check(const struct xt_mtchk_param *par)
static void quota_mt2_destroy(const struct xt_mtdtor_param *par) static void quota_mt2_destroy(const struct xt_mtdtor_param *par)
{ {
struct xt_quota_mtinfo2 *q = par->matchinfo; struct xt_quota_mtinfo2 *q = par->matchinfo;
struct quota_counter *e = q->master; struct xt_quota_counter *e = q->master;
if (*q->name == '\0') {
kfree(e);
return;
}
spin_lock_bh(&counter_list_lock); spin_lock_bh(&counter_list_lock);
if (!atomic_dec_and_test(&e->ref)) { if (!atomic_dec_and_test(&e->ref)) {
@@ -155,8 +185,8 @@ static void quota_mt2_destroy(const struct xt_mtdtor_param *par)
} }
list_del(&e->list); list_del(&e->list);
spin_unlock_bh(&counter_list_lock);
remove_proc_entry(e->name, proc_xt_quota); remove_proc_entry(e->name, proc_xt_quota);
spin_unlock_bh(&counter_list_lock);
kfree(e); kfree(e);
} }
@@ -164,17 +194,15 @@ static bool
quota_mt2(const struct sk_buff *skb, const struct xt_match_param *par) quota_mt2(const struct sk_buff *skb, const struct xt_match_param *par)
{ {
struct xt_quota_mtinfo2 *q = (void *)par->matchinfo; struct xt_quota_mtinfo2 *q = (void *)par->matchinfo;
struct quota_counter *e = q->master; struct xt_quota_counter *e = q->master;
bool ret = q->flags & XT_QUOTA_INVERT; bool ret = q->flags & XT_QUOTA_INVERT;
if (q->flags & XT_QUOTA_GROW) {
spin_lock_bh(&e->lock); spin_lock_bh(&e->lock);
if (q->flags & XT_QUOTA_GROW) {
e->quota += (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len; e->quota += (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;
q->quota = e->quota; q->quota = e->quota;
spin_unlock_bh(&e->lock);
ret = true; ret = true;
} else { } else {
spin_lock_bh(&e->lock);
if (e->quota >= skb->len) { if (e->quota >= skb->len) {
e->quota -= (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len; e->quota -= (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;
ret = !ret; ret = !ret;
@@ -183,16 +211,15 @@ quota_mt2(const struct sk_buff *skb, const struct xt_match_param *par)
e->quota = 0; e->quota = 0;
} }
q->quota = e->quota; q->quota = e->quota;
spin_unlock_bh(&e->lock);
} }
spin_unlock_bh(&e->lock);
return ret; return ret;
} }
static struct xt_match quota_mt2_reg[] __read_mostly = { static struct xt_match quota_mt2_reg[] __read_mostly = {
{ {
.name = "quota2", .name = "quota2",
.revision = 2, .revision = 3,
.family = NFPROTO_IPV4, .family = NFPROTO_IPV4,
.checkentry = quota_mt2_check, .checkentry = quota_mt2_check,
.match = quota_mt2, .match = quota_mt2,
@@ -202,7 +229,7 @@ static struct xt_match quota_mt2_reg[] __read_mostly = {
}, },
{ {
.name = "quota2", .name = "quota2",
.revision = 2, .revision = 3,
.family = NFPROTO_IPV6, .family = NFPROTO_IPV6,
.checkentry = quota_mt2_check, .checkentry = quota_mt2_check,
.match = quota_mt2, .match = quota_mt2,

View File

@@ -6,21 +6,19 @@ enum xt_quota_flags {
XT_QUOTA_GROW = 1 << 1, XT_QUOTA_GROW = 1 << 1,
XT_QUOTA_PACKET = 1 << 2, XT_QUOTA_PACKET = 1 << 2,
XT_QUOTA_MASK = 0x7, XT_QUOTA_MASK = 0x7,
XT_QUOTA_COUNTER_NAME_LENGTH = 31,
}; };
struct quota_counter; struct xt_quota_counter;
struct xt_quota_mtinfo2 { struct xt_quota_mtinfo2 {
char name[XT_QUOTA_COUNTER_NAME_LENGTH]; char name[15];
u_int8_t flags; u_int8_t flags;
/* Comparison-invariant */ /* Comparison-invariant */
aligned_u64 quota; aligned_u64 quota;
/* Used internally by the kernel */ /* Used internally by the kernel */
struct quota_counter *master __attribute__((aligned(8))); struct xt_quota_counter *master __attribute__((aligned(8)));
}; };
#endif /* _XT_QUOTA_H */ #endif /* _XT_QUOTA_H */

View File

@@ -1,5 +1,6 @@
# -*- Makefile -*- # -*- Makefile -*-
# #
build_ACCOUNT=m
build_CHAOS=m build_CHAOS=m
build_DELUDE=m build_DELUDE=m
build_DHCPMAC=m build_DHCPMAC=m
@@ -20,4 +21,5 @@ build_ipset=m
build_ipv4options=m build_ipv4options=m
build_length2=m build_length2=m
build_lscan=m build_lscan=m
build_psd=m
build_quota2=m build_quota2=m

View File

@@ -1,6 +1,6 @@
.TH xtables\-addons 8 "v1.15 (2009\-04\-30)" "" "v1.15 (2009\-04\-30)" .TH xtables-addons 8 "v1.18 (2009-09-09)" "" "v1.18 (2009-09-09)"
.SH Name .SH Name
Xtables\-addons - additional extensions for iptables, ip6tables, etc. Xtables-addons \(em additional extensions for iptables, ip6tables, etc.
.SH Targets .SH Targets
.\" @TARGET@ .\" @TARGET@
.SH Matches .SH Matches