mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-20 19:44:56 +02:00
Compare commits
99 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
26f25a43a9 | ||
![]() |
bcda21a2b0 | ||
![]() |
4e6bc8af95 | ||
![]() |
bd4be0d991 | ||
![]() |
1f736c8203 | ||
![]() |
90fa3ab9e2 | ||
![]() |
fd82a312d6 | ||
![]() |
27c1676821 | ||
![]() |
3e26335cbd | ||
![]() |
f4b96672ef | ||
![]() |
c3d080f21a | ||
![]() |
cb268031b7 | ||
![]() |
ac44a5a1fe | ||
![]() |
a3baa78ae2 | ||
![]() |
47e002127c | ||
![]() |
03363a528a | ||
![]() |
58b016f0af | ||
![]() |
8d64e7bd50 | ||
![]() |
dd6cb27da4 | ||
![]() |
06c01131e8 | ||
![]() |
a44c4e4b1d | ||
![]() |
1fb6f187d3 | ||
![]() |
83e474f9ab | ||
![]() |
efd4c91557 | ||
![]() |
65a257a67d | ||
![]() |
5b07e04600 | ||
![]() |
6b175b40cb | ||
![]() |
0887365f8b | ||
![]() |
cebadbfcd7 | ||
![]() |
380b1b6997 | ||
![]() |
8e5219636a | ||
![]() |
760edd3db6 | ||
![]() |
502c1c05aa | ||
![]() |
a7ceccc0f4 | ||
![]() |
10bd08d0f3 | ||
![]() |
1e5315d338 | ||
![]() |
579484ed70 | ||
![]() |
2aa32d4bce | ||
![]() |
5aee8738ed | ||
![]() |
1111edfd85 | ||
![]() |
0d47cb8b37 | ||
![]() |
1c55aec64a | ||
![]() |
dd26ab476c | ||
![]() |
4bf667d8eb | ||
![]() |
0a88bd3435 | ||
![]() |
62fb261265 | ||
![]() |
d97f77a8f5 | ||
![]() |
822c6bebe2 | ||
![]() |
fdf42a3a50 | ||
![]() |
6b2ca78af7 | ||
![]() |
ee24cd1ac1 | ||
![]() |
71812a2053 | ||
![]() |
31e4e18998 | ||
![]() |
9fb2ffe1d3 | ||
![]() |
23e83aa04c | ||
![]() |
77ee63ba8b | ||
![]() |
49e59a6dce | ||
![]() |
137ecb9814 | ||
![]() |
7e25254e93 | ||
![]() |
0c9ae3cb1b | ||
![]() |
471e747fc0 | ||
![]() |
fe7a66f3cb | ||
![]() |
a13650f94d | ||
![]() |
73e7b5ead1 | ||
![]() |
e5920cc577 | ||
![]() |
39655fe83b | ||
![]() |
9df309a14a | ||
![]() |
5e2085a45f | ||
![]() |
4bcb7077c0 | ||
![]() |
000c2d73fd | ||
![]() |
e89c5d976a | ||
![]() |
f5ed98fbf5 | ||
![]() |
60c4162087 | ||
![]() |
074a7d6cb7 | ||
![]() |
a6ba463c43 | ||
![]() |
be2061c520 | ||
![]() |
3f96deb0f0 | ||
![]() |
6d8ce3acae | ||
![]() |
f6c317710f | ||
![]() |
6799806300 | ||
![]() |
0d36136f54 | ||
![]() |
e1fc5f2086 | ||
![]() |
9d5f4bf468 | ||
![]() |
637516f2d4 | ||
![]() |
b427c930f2 | ||
![]() |
34f39756ec | ||
![]() |
e36c7575fc | ||
![]() |
0a23bd2580 | ||
![]() |
03aeed615d | ||
![]() |
49018e2ff7 | ||
![]() |
50d14a33c0 | ||
![]() |
c64a78ffcc | ||
![]() |
1aae519356 | ||
![]() |
af5823b407 | ||
![]() |
9b198fe6e7 | ||
![]() |
4997b326f6 | ||
![]() |
c288ecdb9c | ||
![]() |
f21e372402 | ||
![]() |
927dd88dc4 |
37
configure.ac
37
configure.ac
@@ -1,5 +1,5 @@
|
||||
|
||||
AC_INIT([xtables-addons], [1.14])
|
||||
AC_INIT([xtables-addons], [1.18])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_PROG_INSTALL
|
||||
@@ -63,6 +63,41 @@ if [[ -n "$ksourcedir" ]]; then
|
||||
kinclude_CFLAGS="$kinclude_CFLAGS -I $ksourcedir/include";
|
||||
fi;
|
||||
|
||||
#
|
||||
# check kernel version
|
||||
#
|
||||
if grep -q "CentOS release 5\." /etc/redhat-release 2>/dev/null ||
|
||||
grep -q "Red Hat Enterprise Linux Server release 5" /etc/redhat-release 2>/dev/null; then
|
||||
# しまった!
|
||||
# Well, just a warning. Maybe the admin updated the kernel.
|
||||
echo "WARNING: This distribution's shipped kernel is not supported.";
|
||||
fi;
|
||||
krel="$(make -sC ${kbuilddir} kernelrelease)";
|
||||
krel="${krel%%-*}";
|
||||
kmajor="${krel%%.*}";
|
||||
krel="${krel#*.}";
|
||||
kminor="${krel%%.*}";
|
||||
krel="${krel#*.}";
|
||||
kmicro="${krel%%.*}";
|
||||
krel2="${krel#*.}";
|
||||
if test "$krel" = "$krel2"; then
|
||||
kstable=0;
|
||||
else
|
||||
kstable="${krel%%.*}";
|
||||
if test -z "$kstable"; then
|
||||
kstable=0;
|
||||
fi;
|
||||
fi;
|
||||
echo "Found kernel version $kmajor.$kminor.$kmicro.$kstable in $kbuilddir";
|
||||
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. :-)";
|
||||
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 \
|
||||
"$kstable" -lt 5 \); then
|
||||
echo "ERROR: That kernel version is not supported. Please see INSTALL for minimum configuration.";
|
||||
exit 1;
|
||||
fi;
|
||||
|
||||
AC_SUBST([regular_CFLAGS])
|
||||
AC_SUBST([xtables_CFLAGS])
|
||||
AC_SUBST([kinclude_CFLAGS])
|
||||
|
4
doc/README.psd
Normal file
4
doc/README.psd
Normal 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: "
|
@@ -1,5 +1,43 @@
|
||||
|
||||
|
||||
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)
|
||||
===================================
|
||||
- build: add kernel version check to configure
|
||||
- condition: compile fix for 2.6.30-rc
|
||||
- condition: fix intrapositional negation sign
|
||||
- fuzzy: fix bogus comparison logic leftover from move to new 1.4.3 API
|
||||
- ipp2p: fix bogus varargs call
|
||||
- ipp2p: fix typo in error message
|
||||
- added "iface" match
|
||||
- added rawpost table (for use with RAWNAT)
|
||||
- added RAWSNAT/RAWDNAT targets
|
||||
|
||||
|
||||
Xtables-addons 1.14 (March 31 2009)
|
||||
===================================
|
||||
- fuzzy: need to account for kernel-level modified variables in .userspacesize
|
||||
@@ -22,7 +60,7 @@ Xtables-addons 1.12 (March 07 2009)
|
||||
- ipset: fix for compilation with 2.6.29-rt
|
||||
- ipset: fast forward to 2.5.0
|
||||
- rename xt_portscan to xt_lscan ("low-level scan") because
|
||||
"portscan" as a wor caused confusion
|
||||
"portscan" as a word caused confusion
|
||||
- xt_LOGMARK: print incoming interface index
|
||||
- revert "TEE: do not use TOS for routing"
|
||||
- xt_TEE: resolve unknown symbol error with CONFIG_IPV6=n
|
||||
|
@@ -31,17 +31,14 @@ AM_CFLAGS := ${regular_CFLAGS} -I${top_srcdir}/include ${xtables_CFLAGS} ${
|
||||
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
|
||||
|
||||
VU := 0
|
||||
am__1verbose_CC_0 = @echo " CC " $@;
|
||||
am__1verbose_CCLD_0 = @echo " CCLD " $@;
|
||||
am__1verbose_GEN_0 = @echo " GEN " $@;
|
||||
am__1verbose_SILENT_0 = @
|
||||
am__1verbose_CC_1 = @echo " CC " $@ "<-" $<;
|
||||
am__1verbose_CCLD_1 = @echo " CCLD " $@ "<-" $^;
|
||||
am__1verbose_GEN_1 = @echo " GEN " $@ "<-" $<;
|
||||
am__verbose_CC = ${am__1verbose_CC_${VU}}
|
||||
am__verbose_CCLD = ${am__1verbose_CCLD_${VU}}
|
||||
am__verbose_GEN = ${am__1verbose_GEN_${VU}}
|
||||
am__verbose_SILENT = ${am__1verbose_GEN_${VU}}
|
||||
am__v_CC_0 = @echo " CC " $@;
|
||||
am__v_CCLD_0 = @echo " CCLD " $@;
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_SILENT_0 = @
|
||||
AM_V_CC = ${am__v_CC_${VU}}
|
||||
AM_V_CCLD = ${am__v_CCLD_${VU}}
|
||||
AM_V_GEN = ${am__v_GEN_${VU}}
|
||||
AM_V_silent = ${am__v_GEN_${VU}}
|
||||
|
||||
|
||||
#
|
||||
@@ -80,7 +77,7 @@ install: modules_install subdirs-install ${targets_install}
|
||||
install -pm0755 ${targets_install} "${DESTDIR}${xtlibdir}/";
|
||||
|
||||
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;
|
||||
|
||||
distclean: clean
|
||||
@@ -95,23 +92,23 @@ distclean: clean
|
||||
.PHONY: modules modules_install clean_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:
|
||||
${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:
|
||||
${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
|
||||
#
|
||||
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
|
||||
${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;
|
||||
|
||||
man_run = \
|
||||
${am__verbose_GEN}for ext in $(1); do \
|
||||
${AM_V_GEN}for ext in $(1); do \
|
||||
f="${srcdir}/libxt_$$ext.man"; \
|
||||
if [ -f "$$f" ]; then \
|
||||
echo ".SS $$ext"; \
|
||||
|
@@ -5,12 +5,14 @@ include ${XA_TOPSRCDIR}/mconfig
|
||||
|
||||
obj-m += compat_xtables.o
|
||||
|
||||
obj-${build_ACCOUNT} += xt_ACCOUNT.o
|
||||
obj-${build_CHAOS} += xt_CHAOS.o
|
||||
obj-${build_DELUDE} += xt_DELUDE.o
|
||||
obj-${build_DHCPMAC} += xt_DHCPMAC.o
|
||||
obj-${build_ECHO} += xt_ECHO.o
|
||||
obj-${build_IPMARK} += xt_IPMARK.o
|
||||
obj-${build_LOGMARK} += xt_LOGMARK.o
|
||||
obj-${build_RAWNAT} += xt_RAWNAT.o iptable_rawpost.o ip6table_rawpost.o
|
||||
obj-${build_SYSRQ} += xt_SYSRQ.o
|
||||
obj-${build_STEAL} += xt_STEAL.o
|
||||
obj-${build_TARPIT} += xt_TARPIT.o
|
||||
@@ -18,11 +20,13 @@ obj-${build_TEE} += xt_TEE.o
|
||||
obj-${build_condition} += xt_condition.o
|
||||
obj-${build_fuzzy} += xt_fuzzy.o
|
||||
obj-${build_geoip} += xt_geoip.o
|
||||
obj-${build_iface} += xt_iface.o
|
||||
obj-${build_ipp2p} += xt_ipp2p.o
|
||||
obj-${build_ipset} += ipset/
|
||||
obj-${build_ipv4options} += xt_ipv4options.o
|
||||
obj-${build_length2} += xt_length2.o
|
||||
obj-${build_lscan} += xt_lscan.o
|
||||
obj-${build_psd} += xt_psd.o
|
||||
obj-${build_quota2} += xt_quota2.o
|
||||
|
||||
-include ${M}/*.Kbuild
|
||||
|
@@ -1,9 +1,11 @@
|
||||
obj-${build_ACCOUNT} += libxt_ACCOUNT.so
|
||||
obj-${build_CHAOS} += libxt_CHAOS.so
|
||||
obj-${build_DELUDE} += libxt_DELUDE.so
|
||||
obj-${build_DHCPMAC} += libxt_DHCPMAC.so libxt_dhcpmac.so
|
||||
obj-${build_ECHO} += libxt_ECHO.so
|
||||
obj-${build_IPMARK} += libxt_IPMARK.so
|
||||
obj-${build_LOGMARK} += libxt_LOGMARK.so
|
||||
obj-${build_RAWNAT} += libxt_RAWDNAT.so libxt_RAWSNAT.so
|
||||
obj-${build_STEAL} += libxt_STEAL.so
|
||||
obj-${build_SYSRQ} += libxt_SYSRQ.so
|
||||
obj-${build_TARPIT} += libxt_TARPIT.so
|
||||
@@ -11,9 +13,11 @@ obj-${build_TEE} += libxt_TEE.so
|
||||
obj-${build_condition} += libxt_condition.so
|
||||
obj-${build_fuzzy} += libxt_fuzzy.so
|
||||
obj-${build_geoip} += libxt_geoip.so
|
||||
obj-${build_iface} += libxt_iface.so
|
||||
obj-${build_ipp2p} += libxt_ipp2p.so
|
||||
obj-${build_ipset} += ipset/
|
||||
obj-${build_ipv4options} += libxt_ipv4options.so
|
||||
obj-${build_length2} += libxt_length2.so
|
||||
obj-${build_lscan} += libxt_lscan.so
|
||||
obj-${build_psd} += libxt_psd.so
|
||||
obj-${build_quota2} += libxt_quota2.so
|
||||
|
87
extensions/compat_rawpost.h
Normal file
87
extensions/compat_rawpost.h
Normal file
@@ -0,0 +1,87 @@
|
||||
#ifndef XTA_COMPAT_RAWPOST_H
|
||||
#define XTA_COMPAT_RAWPOST_H 1
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
|
||||
typedef struct sk_buff sk_buff_t;
|
||||
#else
|
||||
typedef struct sk_buff *sk_buff_t;
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 21)
|
||||
#define XT_TARGET_INIT(__name, __size) \
|
||||
{ \
|
||||
.target.u.user = { \
|
||||
.target_size = XT_ALIGN(__size), \
|
||||
.name = __name, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define IPT_ENTRY_INIT(__size) \
|
||||
{ \
|
||||
.target_offset = sizeof(struct ipt_entry), \
|
||||
.next_offset = (__size), \
|
||||
}
|
||||
|
||||
#define IPT_STANDARD_INIT(__verdict) \
|
||||
{ \
|
||||
.entry = IPT_ENTRY_INIT(sizeof(struct ipt_standard)), \
|
||||
.target = XT_TARGET_INIT(IPT_STANDARD_TARGET, \
|
||||
sizeof(struct xt_standard_target)), \
|
||||
.target.verdict = -(__verdict) - 1, \
|
||||
}
|
||||
|
||||
#define IPT_ERROR_INIT \
|
||||
{ \
|
||||
.entry = IPT_ENTRY_INIT(sizeof(struct ipt_error)), \
|
||||
.target = XT_TARGET_INIT(IPT_ERROR_TARGET, \
|
||||
sizeof(struct ipt_error_target)), \
|
||||
.target.errorname = "ERROR", \
|
||||
}
|
||||
|
||||
#define IP6T_ENTRY_INIT(__size) \
|
||||
{ \
|
||||
.target_offset = sizeof(struct ip6t_entry), \
|
||||
.next_offset = (__size), \
|
||||
}
|
||||
|
||||
#define IP6T_STANDARD_INIT(__verdict) \
|
||||
{ \
|
||||
.entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_standard)), \
|
||||
.target = XT_TARGET_INIT(IP6T_STANDARD_TARGET, \
|
||||
sizeof(struct ip6t_standard_target)), \
|
||||
.target.verdict = -(__verdict) - 1, \
|
||||
}
|
||||
|
||||
#define IP6T_ERROR_INIT \
|
||||
{ \
|
||||
.entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_error)), \
|
||||
.target = XT_TARGET_INIT(IP6T_ERROR_TARGET, \
|
||||
sizeof(struct ip6t_error_target)), \
|
||||
.target.errorname = "ERROR", \
|
||||
}
|
||||
|
||||
#endif /* 2.6.21 */
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 20)
|
||||
# include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
/* Standard entry */
|
||||
struct ip6t_standard
|
||||
{
|
||||
struct ip6t_entry entry;
|
||||
struct ip6t_standard_target target;
|
||||
};
|
||||
|
||||
struct ip6t_error_target
|
||||
{
|
||||
struct ip6t_entry_target target;
|
||||
char errorname[IP6T_FUNCTION_MAXNAMELEN];
|
||||
};
|
||||
|
||||
struct ip6t_error
|
||||
{
|
||||
struct ip6t_entry entry;
|
||||
struct ip6t_error_target target;
|
||||
};
|
||||
#endif /* 2.6.20 */
|
||||
|
||||
#endif /* XTA_COMPAT_RAWPOST_H */
|
@@ -4,6 +4,23 @@
|
||||
struct tcphdr;
|
||||
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)
|
||||
# define skb_ifindex(skb) \
|
||||
(((skb)->input_dev != NULL) ? (skb)->input_dev->ifindex : 0)
|
||||
|
@@ -20,11 +20,6 @@
|
||||
#include "compat_skbuff.h"
|
||||
#include "compat_xtnu.h"
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
||||
typedef __u16 __bitwise __sum16;
|
||||
typedef __u32 __bitwise __wsum;
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
||||
static int xtnu_match_run(const struct sk_buff *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
@@ -447,6 +442,30 @@ int xtnu_ip_route_output_key(void *net, struct rtable **rp, struct flowi *flp)
|
||||
return ip_route_output_flow(rp, flp, NULL, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_ip_route_output_key);
|
||||
|
||||
void xtnu_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
|
||||
__be32 from, __be32 to, bool pseudohdr)
|
||||
{
|
||||
__be32 diff[] = {~from, to};
|
||||
const void *dv = diff; /* kludge for < v2.6.19-555-g72685fc */
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
|
||||
if (skb->ip_summed != CHECKSUM_PARTIAL) {
|
||||
*sum = csum_fold(csum_partial(dv, sizeof(diff),
|
||||
~csum_unfold(*sum)));
|
||||
if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
|
||||
skb->csum = ~csum_partial(dv, sizeof(diff),
|
||||
~skb->csum);
|
||||
} else if (pseudohdr) {
|
||||
*sum = ~csum_fold(csum_partial(dv, sizeof(diff),
|
||||
csum_unfold(*sum)));
|
||||
}
|
||||
#else
|
||||
*sum = csum_fold(csum_partial(dv, sizeof(diff),
|
||||
~csum_unfold(*sum)));
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_proto_csum_replace4);
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
||||
@@ -468,7 +487,7 @@ static inline __wsum xtnu_csum_unfold(__sum16 n)
|
||||
return (__force __wsum)n;
|
||||
}
|
||||
|
||||
static inline void xtnu_csum_replace4(__sum16 *sum, __be32 from, __be32 to)
|
||||
void xtnu_csum_replace4(__sum16 *sum, __be32 from, __be32 to)
|
||||
{
|
||||
__be32 diff[] = {~from, to};
|
||||
*sum = csum_fold(csum_partial((char *)diff, sizeof(diff),
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
||||
# define neigh_hh_output xtnu_neigh_hh_output
|
||||
# define IPPROTO_UDPLITE 136
|
||||
# define CSUM_MANGLED_0 ((__force __sum16)0xffff)
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
|
||||
@@ -69,8 +70,12 @@
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
||||
# define csum_replace2 xtnu_csum_replace2
|
||||
# define csum_replace4 xtnu_csum_replace4
|
||||
# define inet_proto_csum_replace4 xtnu_proto_csum_replace4
|
||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
|
||||
# define csum_replace2 nf_csum_replace2
|
||||
# define csum_replace4 nf_csum_replace4
|
||||
# define inet_proto_csum_replace4 xtnu_proto_csum_replace4
|
||||
#endif
|
||||
|
||||
#if !defined(NIP6) && !defined(NIP6_FMT)
|
||||
|
@@ -9,6 +9,10 @@
|
||||
typedef _Bool bool;
|
||||
enum { false = 0, true = 1, };
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
||||
typedef __u16 __bitwise __sum16;
|
||||
typedef __u32 __bitwise __wsum;
|
||||
#endif
|
||||
|
||||
struct flowi;
|
||||
struct hh_cache;
|
||||
@@ -122,6 +126,13 @@ static inline struct xtnu_target *xtcompat_nutarget(const struct xt_target *t)
|
||||
return q;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
||||
static inline __wsum csum_unfold(__sum16 n)
|
||||
{
|
||||
return (__force __wsum)n;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern int xtnu_ip_local_out(struct sk_buff *);
|
||||
extern int xtnu_ip_route_me_harder(struct sk_buff **, unsigned int);
|
||||
extern int xtnu_skb_make_writable(struct sk_buff **, unsigned int);
|
||||
@@ -138,6 +149,9 @@ extern struct xt_match *xtnu_request_find_match(unsigned int,
|
||||
const char *, uint8_t);
|
||||
extern int xtnu_neigh_hh_output(struct hh_cache *, struct sk_buff *);
|
||||
extern void xtnu_csum_replace2(__u16 __bitwise *, __be16, __be16);
|
||||
extern void xtnu_csum_replace4(__u16 __bitwise *, __be32, __be32);
|
||||
extern void xtnu_proto_csum_replace4(__u16 __bitwise *, struct sk_buff *,
|
||||
__be32, __be32, bool);
|
||||
extern int xtnu_skb_linearize(struct sk_buff *);
|
||||
|
||||
#endif /* _COMPAT_XTNU_H */
|
||||
|
107
extensions/ip6table_rawpost.c
Normal file
107
extensions/ip6table_rawpost.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* rawpost table for ip6_tables
|
||||
* written by Jan Engelhardt <jengelh [at] medozas de>, 2008 - 2009
|
||||
* placed in the Public Domain
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
#include <net/ip.h>
|
||||
#include "compat_xtables.h"
|
||||
#include "compat_rawpost.h"
|
||||
|
||||
enum {
|
||||
RAWPOST_VALID_HOOKS = 1 << NF_INET_POST_ROUTING,
|
||||
};
|
||||
|
||||
static struct {
|
||||
struct ip6t_replace repl;
|
||||
struct ip6t_standard entries[1];
|
||||
struct ip6t_error term;
|
||||
} rawpost6_initial __initdata = {
|
||||
.repl = {
|
||||
.name = "rawpost",
|
||||
.valid_hooks = RAWPOST_VALID_HOOKS,
|
||||
.num_entries = 2,
|
||||
.size = sizeof(struct ip6t_standard) +
|
||||
sizeof(struct ip6t_error),
|
||||
.hook_entry = {
|
||||
[NF_INET_POST_ROUTING] = 0,
|
||||
},
|
||||
.underflow = {
|
||||
[NF_INET_POST_ROUTING] = 0,
|
||||
},
|
||||
},
|
||||
.entries = {
|
||||
IP6T_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */
|
||||
},
|
||||
.term = IP6T_ERROR_INIT, /* ERROR */
|
||||
};
|
||||
|
||||
static struct xt_table *rawpost6_ptable;
|
||||
|
||||
static struct xt_table rawpost6_itable = {
|
||||
.name = "rawpost",
|
||||
.af = NFPROTO_IPV6,
|
||||
.valid_hooks = RAWPOST_VALID_HOOKS,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static unsigned int rawpost6_hook_fn(unsigned int hook, sk_buff_t *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
|
||||
return ip6t_do_table(skb, hook, in, out, rawpost6_ptable);
|
||||
#else
|
||||
return ip6t_do_table(skb, hook, in, out, rawpost6_ptable, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct nf_hook_ops rawpost6_hook_ops __read_mostly = {
|
||||
.hook = rawpost6_hook_fn,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP6_PRI_LAST,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init rawpost6_table_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 29)
|
||||
rwlock_init(&rawpost6_itable.lock);
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
|
||||
rawpost6_ptable = ip6t_register_table(&init_net, &rawpost6_itable,
|
||||
&rawpost6_initial.repl);
|
||||
if (IS_ERR(rawpost6_ptable))
|
||||
return PTR_ERR(rawpost6_ptable);
|
||||
#else
|
||||
ret = ip6t_register_table(&rawpost6_itable, &rawpost6_initial.repl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
rawpost6_ptable = &rawpost6_itable;
|
||||
#endif
|
||||
|
||||
ret = nf_register_hook(&rawpost6_hook_ops);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
return ret;
|
||||
|
||||
out:
|
||||
ip6t_unregister_table(rawpost6_ptable);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit rawpost6_table_exit(void)
|
||||
{
|
||||
nf_unregister_hook(&rawpost6_hook_ops);
|
||||
ip6t_unregister_table(rawpost6_ptable);
|
||||
}
|
||||
|
||||
module_init(rawpost6_table_init);
|
||||
module_exit(rawpost6_table_exit);
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_LICENSE("GPL");
|
@@ -3,8 +3,8 @@
|
||||
top_srcdir := @top_srcdir@
|
||||
srcdir := @srcdir@
|
||||
datarootdir := @datarootdir@
|
||||
abstop_srcdir := $(shell readlink -e ${top_srcdir})
|
||||
abssrcdir := $(shell readlink -e ${srcdir})
|
||||
abstop_srcdir := $(shell readlink -f ${top_srcdir})
|
||||
abssrcdir := $(shell readlink -f ${srcdir})
|
||||
|
||||
ifeq (${abstop_srcdir},)
|
||||
$(error Path resolution of ${top_srcdir} failed)
|
||||
|
@@ -493,7 +493,7 @@ ip_set_find_byindex(ip_set_id_t index)
|
||||
static inline int
|
||||
__ip_set_testip(struct ip_set *set,
|
||||
const void *data,
|
||||
size_t size,
|
||||
u_int32_t size,
|
||||
ip_set_ip_t *ip)
|
||||
{
|
||||
int res;
|
||||
@@ -508,7 +508,7 @@ __ip_set_testip(struct ip_set *set,
|
||||
static int
|
||||
__ip_set_addip(ip_set_id_t index,
|
||||
const void *data,
|
||||
size_t size)
|
||||
u_int32_t size)
|
||||
{
|
||||
struct ip_set *set = ip_set_list[index];
|
||||
ip_set_ip_t ip;
|
||||
@@ -529,15 +529,15 @@ __ip_set_addip(ip_set_id_t index,
|
||||
static int
|
||||
ip_set_addip(ip_set_id_t index,
|
||||
const void *data,
|
||||
size_t size)
|
||||
u_int32_t size)
|
||||
{
|
||||
struct ip_set *set = ip_set_list[index];
|
||||
|
||||
IP_SET_ASSERT(set);
|
||||
|
||||
if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) {
|
||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||
set->type->reqsize,
|
||||
ip_set_printk("data length wrong (want %lu, have %zu)",
|
||||
(long unsigned)set->type->reqsize,
|
||||
size - sizeof(struct ip_set_req_adt));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -549,7 +549,7 @@ ip_set_addip(ip_set_id_t index,
|
||||
static int
|
||||
ip_set_delip(ip_set_id_t index,
|
||||
const void *data,
|
||||
size_t size)
|
||||
u_int32_t size)
|
||||
{
|
||||
struct ip_set *set = ip_set_list[index];
|
||||
ip_set_ip_t ip;
|
||||
@@ -558,8 +558,8 @@ ip_set_delip(ip_set_id_t index,
|
||||
IP_SET_ASSERT(set);
|
||||
|
||||
if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) {
|
||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||
set->type->reqsize,
|
||||
ip_set_printk("data length wrong (want %lu, have %zu)",
|
||||
(long unsigned)set->type->reqsize,
|
||||
size - sizeof(struct ip_set_req_adt));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -576,7 +576,7 @@ ip_set_delip(ip_set_id_t index,
|
||||
static int
|
||||
ip_set_testip(ip_set_id_t index,
|
||||
const void *data,
|
||||
size_t size)
|
||||
u_int32_t size)
|
||||
{
|
||||
struct ip_set *set = ip_set_list[index];
|
||||
ip_set_ip_t ip;
|
||||
@@ -585,8 +585,8 @@ ip_set_testip(ip_set_id_t index,
|
||||
IP_SET_ASSERT(set);
|
||||
|
||||
if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) {
|
||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||
set->type->reqsize,
|
||||
ip_set_printk("data length wrong (want %lu, have %zu)",
|
||||
(long unsigned)set->type->reqsize,
|
||||
size - sizeof(struct ip_set_req_adt));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -601,7 +601,7 @@ ip_set_testip(ip_set_id_t index,
|
||||
static int
|
||||
ip_set_bindip(ip_set_id_t index,
|
||||
const void *data,
|
||||
size_t size)
|
||||
u_int32_t size)
|
||||
{
|
||||
struct ip_set *set = ip_set_list[index];
|
||||
const struct ip_set_req_bind *req_bind;
|
||||
@@ -687,7 +687,7 @@ __unbind_default(struct ip_set *set)
|
||||
static int
|
||||
ip_set_unbindip(ip_set_id_t index,
|
||||
const void *data,
|
||||
size_t size)
|
||||
u_int32_t size)
|
||||
{
|
||||
struct ip_set *set;
|
||||
const struct ip_set_req_bind *req_bind;
|
||||
@@ -760,7 +760,7 @@ ip_set_unbindip(ip_set_id_t index,
|
||||
static int
|
||||
ip_set_testbind(ip_set_id_t index,
|
||||
const void *data,
|
||||
size_t size)
|
||||
u_int32_t size)
|
||||
{
|
||||
struct ip_set *set = ip_set_list[index];
|
||||
const struct ip_set_req_bind *req_bind;
|
||||
@@ -862,7 +862,7 @@ ip_set_create(const char *name,
|
||||
const char *typename,
|
||||
ip_set_id_t restore,
|
||||
const void *data,
|
||||
size_t size)
|
||||
u_int32_t size)
|
||||
{
|
||||
struct ip_set *set;
|
||||
ip_set_id_t index = 0, id;
|
||||
@@ -915,9 +915,9 @@ ip_set_create(const char *name,
|
||||
|
||||
/* Check request size */
|
||||
if (size != set->type->header_size) {
|
||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||
set->type->header_size,
|
||||
size);
|
||||
ip_set_printk("data length wrong (want %lu, have %lu)",
|
||||
(long unsigned)set->type->header_size,
|
||||
(long unsigned)size);
|
||||
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
|
||||
__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)
|
||||
*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
|
||||
__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)
|
||||
*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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
*used += set_save->header_size;
|
||||
|
||||
DP("set header filled: %s, used: %u(%u) %p %p", set->name, *used,
|
||||
set_save->header_size, data, data + *used);
|
||||
DP("set header filled: %s, used: %d(%lu) %p %p", set->name, *used,
|
||||
(unsigned long)set_save->header_size, data, data + *used);
|
||||
/* Get and ensure set specific members size */
|
||||
set_save->members_size = set->type->list_members_size(set);
|
||||
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);
|
||||
*used += set_save->members_size;
|
||||
read_unlock_bh(&set->lock);
|
||||
DP("set members filled: %s, used: %u(%u) %p %p", set->name, *used,
|
||||
set_save->members_size, data, data + *used);
|
||||
DP("set members filled: %s, used: %d(%lu) %p %p", set->name, *used,
|
||||
(unsigned long)set_save->members_size, data, data + *used);
|
||||
return 0;
|
||||
|
||||
unlock_set:
|
||||
@@ -1329,7 +1329,7 @@ static int ip_set_restore(void *data,
|
||||
while (1) {
|
||||
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 */
|
||||
if (used + sizeof(struct ip_set_restore) > len)
|
||||
return line;
|
||||
@@ -1367,12 +1367,13 @@ static int ip_set_restore(void *data,
|
||||
/* Try to restore members data */
|
||||
set = ip_set_list[index];
|
||||
members_size = 0;
|
||||
DP("members_size %u reqsize %u",
|
||||
set_restore->members_size, set->type->reqsize);
|
||||
DP("members_size %lu reqsize %lu",
|
||||
(unsigned long)set_restore->members_size,
|
||||
(unsigned long)set->type->reqsize);
|
||||
while (members_size + set->type->reqsize <=
|
||||
set_restore->members_size) {
|
||||
line++;
|
||||
DP("members: %u, line %u", members_size, line);
|
||||
DP("members: %d, line %d", members_size, line);
|
||||
res = __ip_set_addip(index,
|
||||
data + used + members_size,
|
||||
set->type->reqsize);
|
||||
@@ -1381,8 +1382,8 @@ static int ip_set_restore(void *data,
|
||||
members_size += set->type->reqsize;
|
||||
}
|
||||
|
||||
DP("members_size %u %u",
|
||||
set_restore->members_size, members_size);
|
||||
DP("members_size %lu %d",
|
||||
(unsigned long)set_restore->members_size, members_size);
|
||||
if (members_size != set_restore->members_size)
|
||||
return line++;
|
||||
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;
|
||||
ip_set_id_t index = IP_SET_INVALID_ID;
|
||||
int (*adtfn)(ip_set_id_t index,
|
||||
const void *data, size_t size);
|
||||
const void *data, u_int32_t size);
|
||||
struct fn_table {
|
||||
int (*fn)(ip_set_id_t index,
|
||||
const void *data, size_t size);
|
||||
const void *data, u_int32_t size);
|
||||
} adtfn_table[] =
|
||||
{ { ip_set_addip }, { ip_set_delip }, { ip_set_testip},
|
||||
{ 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;
|
||||
goto done;
|
||||
}
|
||||
|
||||
#define SETLIST(set) (strcmp(set->type->typename, "setlist") == 0)
|
||||
|
||||
used = 0;
|
||||
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++) {
|
||||
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);
|
||||
}
|
||||
if (!setlist) {
|
||||
setlist = 1;
|
||||
goto setlists;
|
||||
}
|
||||
} else {
|
||||
/* Save an individual set */
|
||||
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)
|
||||
|| *len != req_restore->size) {
|
||||
ip_set_printk("invalid RESTORE (want =%zu, got %d)",
|
||||
req_restore->size, *len);
|
||||
ip_set_printk("invalid RESTORE (want =%lu, got %d)",
|
||||
(long unsigned)req_restore->size, *len);
|
||||
res = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
line = ip_set_restore(data + 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) {
|
||||
res = -EAGAIN;
|
||||
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) */
|
||||
|
||||
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]->name
|
||||
: ":all:", copylen);
|
||||
|
@@ -48,7 +48,7 @@
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
@@ -236,7 +236,7 @@ struct ip_set_req_max_sets {
|
||||
struct ip_set_req_setnames {
|
||||
unsigned op;
|
||||
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 */
|
||||
};
|
||||
|
||||
@@ -258,9 +258,9 @@ struct ip_set_list {
|
||||
ip_set_id_t index;
|
||||
ip_set_id_t binding;
|
||||
u_int32_t ref;
|
||||
size_t header_size; /* Set header data of header_size */
|
||||
size_t members_size; /* Set members data of members_size */
|
||||
size_t bindings_size; /* Set bindings data of bindings_size */
|
||||
u_int32_t header_size; /* Set header data of header_size */
|
||||
u_int32_t members_size; /* Set members data of members_size */
|
||||
u_int32_t bindings_size;/* Set bindings data of bindings_size */
|
||||
};
|
||||
|
||||
struct ip_set_hash_list {
|
||||
@@ -277,8 +277,8 @@ struct ip_set_hash_list {
|
||||
struct ip_set_save {
|
||||
ip_set_id_t index;
|
||||
ip_set_id_t binding;
|
||||
size_t header_size; /* Set header data of header_size */
|
||||
size_t members_size; /* Set members data of members_size */
|
||||
u_int32_t header_size; /* Set header data of header_size */
|
||||
u_int32_t members_size; /* Set members data of members_size */
|
||||
};
|
||||
|
||||
/* 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 typename[IP_SET_MAXNAMELEN];
|
||||
ip_set_id_t index;
|
||||
size_t header_size; /* Create data of header_size */
|
||||
size_t members_size; /* Set members data of members_size */
|
||||
u_int32_t header_size; /* Create data of header_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)
|
||||
@@ -366,14 +366,14 @@ struct ip_set_type {
|
||||
* return 0 if not in set, 1 if in 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);
|
||||
|
||||
/*
|
||||
* Size of the data structure passed by when
|
||||
* adding/deletin/testing an entry.
|
||||
*/
|
||||
size_t reqsize;
|
||||
u_int32_t reqsize;
|
||||
|
||||
/* Add IP into set (userspace: ipset -A set IP)
|
||||
* 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.
|
||||
*/
|
||||
int (*addip) (struct ip_set *set,
|
||||
const void *data, size_t size,
|
||||
const void *data, u_int32_t size,
|
||||
ip_set_ip_t *ip);
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
int (*delip) (struct ip_set *set,
|
||||
const void *data, size_t size,
|
||||
const void *data, u_int32_t size,
|
||||
ip_set_ip_t *ip);
|
||||
|
||||
/* 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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@@ -437,7 +437,7 @@ struct ip_set_type {
|
||||
|
||||
/* Listing: size needed for header
|
||||
*/
|
||||
size_t header_size;
|
||||
u_int32_t header_size;
|
||||
|
||||
/* Listing: Get the header
|
||||
*
|
||||
@@ -523,7 +523,7 @@ extern int ip_set_testip_kernel(ip_set_id_t id,
|
||||
|
||||
#define UADT0(type, adt, args...) \
|
||||
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) \
|
||||
{ \
|
||||
const STRUCT(ip_set_req_,type) *req = data; \
|
||||
|
@@ -6,7 +6,7 @@
|
||||
#ifdef __KERNEL__
|
||||
#define BITMAP_CREATE(type) \
|
||||
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; \
|
||||
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); \
|
||||
if (!map) { \
|
||||
DP("out of memory for %d bytes", \
|
||||
sizeof(struct ip_set_#type)); \
|
||||
DP("out of memory for %zu bytes", \
|
||||
sizeof(struct ip_set_##type)); \
|
||||
return -ENOMEM; \
|
||||
} \
|
||||
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->members = ip_set_malloc(newbytes); \
|
||||
if (!map->members) { \
|
||||
DP("out of memory for %d bytes", newbytes); \
|
||||
DP("out of memory for %i bytes", newbytes); \
|
||||
kfree(map); \
|
||||
return -ENOMEM; \
|
||||
} \
|
||||
|
@@ -58,6 +58,7 @@ static inline void *kzalloc(size_t size, gfp_t flags)
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
|
||||
#include <linux/netfilter.h>
|
||||
#define KMEM_CACHE_CREATE(name, size) \
|
||||
kmem_cache_create(name, size, 0, 0, NULL, NULL)
|
||||
#else
|
||||
|
@@ -28,20 +28,22 @@ type##_retry(struct ip_set *set) \
|
||||
hashsize++; \
|
||||
\
|
||||
ip_set_printk("rehashing of set %s triggered: " \
|
||||
"hashsize grows from %u to %u", \
|
||||
set->name, map->hashsize, hashsize); \
|
||||
"hashsize grows from %lu to %lu", \
|
||||
set->name, \
|
||||
(long unsigned)map->hashsize, \
|
||||
(long unsigned)hashsize); \
|
||||
\
|
||||
tmp = kmalloc(sizeof(struct ip_set_##type) \
|
||||
+ map->probes * sizeof(initval_t), GFP_ATOMIC); \
|
||||
if (!tmp) { \
|
||||
DP("out of memory for %d bytes", \
|
||||
DP("out of memory for %zu bytes", \
|
||||
sizeof(struct ip_set_##type) \
|
||||
+ map->probes * sizeof(initval_t)); \
|
||||
return -ENOMEM; \
|
||||
} \
|
||||
tmp->members = harray_malloc(hashsize, sizeof(dtype), GFP_ATOMIC);\
|
||||
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); \
|
||||
return -ENOMEM; \
|
||||
} \
|
||||
@@ -88,7 +90,7 @@ type##_retry(struct ip_set *set) \
|
||||
|
||||
#define HASH_CREATE(type, dtype) \
|
||||
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; \
|
||||
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) \
|
||||
+ req->probes * sizeof(initval_t), GFP_KERNEL); \
|
||||
if (!map) { \
|
||||
DP("out of memory for %d bytes", \
|
||||
DP("out of memory for %zu bytes", \
|
||||
sizeof(struct ip_set_##type) \
|
||||
+ req->probes * sizeof(initval_t)); \
|
||||
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);\
|
||||
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); \
|
||||
return -ENOMEM; \
|
||||
} \
|
||||
|
@@ -13,7 +13,7 @@ struct ip_set_ipmap {
|
||||
ip_set_ip_t netmask; /* subnet netmask */
|
||||
ip_set_ip_t sizeid; /* size of set in IPs */
|
||||
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 {
|
||||
|
@@ -102,7 +102,7 @@ ipportnethash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
const struct ip_set_req_ipportnethash *req = data;
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
@@ -276,21 +277,21 @@ init_gc_timer(struct ip_set *set)
|
||||
}
|
||||
|
||||
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;
|
||||
struct ip_set_iptree *map;
|
||||
|
||||
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),
|
||||
size);
|
||||
(unsigned long)size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
map = kmalloc(sizeof(struct ip_set_iptree), GFP_KERNEL);
|
||||
if (!map) {
|
||||
DP("out of memory for %d bytes",
|
||||
DP("out of memory for %zu bytes",
|
||||
sizeof(struct ip_set_iptree));
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
@@ -338,7 +339,7 @@ KADT(iptreemap, add, ipaddr, ip)
|
||||
|
||||
static inline int
|
||||
__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_b *btree;
|
||||
@@ -364,7 +365,7 @@ __delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
|
||||
static inline int
|
||||
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_b *btree;
|
||||
@@ -470,7 +471,7 @@ init_gc_timer(struct ip_set *set)
|
||||
}
|
||||
|
||||
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;
|
||||
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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct ip_set_req_iptreemap *entry = data + offset;
|
||||
|
@@ -22,7 +22,7 @@
|
||||
#include "ip_set_macipmap.h"
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
|
||||
set->name, HIPQUAD(req->ip), HIPQUAD(*hash_ip));
|
||||
if (test_bit(IPSET_MACIP_ISSET,
|
||||
(void *) &table[req->ip - map->first_ip].flags)) {
|
||||
if (table[req->ip - map->first_ip].match) {
|
||||
return (memcmp(req->ethernet,
|
||||
&table[req->ip - map->first_ip].ethernet,
|
||||
ETH_ALEN) == 0);
|
||||
@@ -64,8 +63,7 @@ macipmap_ktest(struct ip_set *set,
|
||||
*hash_ip = ip;
|
||||
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
|
||||
set->name, HIPQUAD(ip), HIPQUAD(*hash_ip));
|
||||
if (test_bit(IPSET_MACIP_ISSET,
|
||||
(void *) &table[ip - map->first_ip].flags)) {
|
||||
if (table[ip - map->first_ip].match) {
|
||||
/* Is mac pointer valid?
|
||||
* If so, compare... */
|
||||
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)
|
||||
return -ERANGE;
|
||||
if (test_and_set_bit(IPSET_MACIP_ISSET,
|
||||
(void *) &table[ip - map->first_ip].flags))
|
||||
if (table[ip - map->first_ip].match)
|
||||
return -EEXIST;
|
||||
|
||||
*hash_ip = 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);
|
||||
table[ip - map->first_ip].match = IPSET_MACIP_ISSET;
|
||||
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)
|
||||
return -ERANGE;
|
||||
if (!test_and_clear_bit(IPSET_MACIP_ISSET,
|
||||
(void *)&table[ip - map->first_ip].flags))
|
||||
if (!table[ip - map->first_ip].match)
|
||||
return -EEXIST;
|
||||
|
||||
*hash_ip = ip;
|
||||
table[ip - map->first_ip].match = 0;
|
||||
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
|
||||
return 0;
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ struct ip_set_macipmap {
|
||||
ip_set_ip_t first_ip; /* host byte order, included in range */
|
||||
ip_set_ip_t last_ip; /* host byte order, included in range */
|
||||
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 {
|
||||
@@ -32,7 +32,7 @@ struct ip_set_req_macipmap {
|
||||
};
|
||||
|
||||
struct ip_set_macip {
|
||||
unsigned short flags;
|
||||
unsigned short match;
|
||||
unsigned char ethernet[ETH_ALEN];
|
||||
};
|
||||
|
||||
|
@@ -40,7 +40,7 @@ struct harray {
|
||||
};
|
||||
|
||||
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;
|
||||
size_t max_elements, size, i, j;
|
||||
@@ -88,7 +88,7 @@ __harray_malloc(size_t hashsize, size_t typesize, int flags)
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@@ -80,7 +80,7 @@ nethash_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
const struct ip_set_req_nethash *req = data;
|
||||
|
@@ -10,7 +10,7 @@ struct ip_set_portmap {
|
||||
void *members; /* the portmap proper */
|
||||
ip_set_ip_t first_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 {
|
||||
|
@@ -21,14 +21,14 @@
|
||||
* 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)
|
||||
{
|
||||
return i < map->size && map->index[i] == index;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
const struct ip_set_setlist *map = set->data;
|
||||
@@ -38,17 +38,15 @@ setlist_utest(struct ip_set *set, const void *data, size_t size,
|
||||
struct ip_set *s;
|
||||
|
||||
if (req->before && req->ref[0] == '\0')
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
|
||||
index = __ip_set_get_byname(req->name, &s);
|
||||
if (index == IP_SET_INVALID_ID)
|
||||
return -EEXIST;
|
||||
return 0;
|
||||
if (req->ref[0] != '\0') {
|
||||
ref = __ip_set_get_byname(req->ref, &s);
|
||||
if (ref == IP_SET_INVALID_ID) {
|
||||
res = -EEXIST;
|
||||
if (ref == IP_SET_INVALID_ID)
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < map->size
|
||||
&& map->index[i] != IP_SET_INVALID_ID; i++) {
|
||||
@@ -109,7 +107,7 @@ insert_setlist(struct ip_set_setlist *map, int i, ip_set_id_t index)
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct ip_set_setlist *map = set->data;
|
||||
@@ -172,7 +170,7 @@ setlist_kadd(struct ip_set *set,
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
static inline int
|
||||
unshift_setlist(struct ip_set_setlist *map, int i)
|
||||
{
|
||||
int j;
|
||||
@@ -184,7 +182,7 @@ unshift_setlist(struct ip_set_setlist *map, int i)
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct ip_set_setlist *map = set->data;
|
||||
@@ -251,7 +249,7 @@ setlist_kdel(struct ip_set *set,
|
||||
}
|
||||
|
||||
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;
|
||||
const struct ip_set_req_setlist_create *req = data;
|
||||
|
@@ -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
|
||||
the kernel. A set cannot be removed (destroyed) while there is a single
|
||||
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
|
||||
The options that are recognized by
|
||||
.B ipset
|
||||
|
@@ -30,7 +30,7 @@
|
||||
#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe"
|
||||
#endif
|
||||
|
||||
#define IPSET_VERSION "2.5.0"
|
||||
#define IPSET_VERSION "3.2"
|
||||
|
||||
char program_name[] = "ipset";
|
||||
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 */
|
||||
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);
|
||||
|
||||
/* Fill out the request */
|
||||
@@ -1666,7 +1666,7 @@ static int set_bind(struct set *set, const char *adt,
|
||||
size += IP_SET_MAXNAMELEN;
|
||||
else if (!(op == IP_SET_OP_UNBIND_SET && set == NULL))
|
||||
size += set->settype->adt_size;
|
||||
DP("alloc size %i", size);
|
||||
DP("alloc size %d", size);
|
||||
data = ipset_malloc(size);
|
||||
|
||||
/* Fill out the request */
|
||||
|
@@ -95,7 +95,7 @@ struct settype {
|
||||
*/
|
||||
|
||||
/* Size of create data. Will be sent to kernel */
|
||||
size_t create_size;
|
||||
u_int32_t create_size;
|
||||
|
||||
/* Initialize the create. */
|
||||
void (*create_init) (void *data);
|
||||
@@ -115,7 +115,7 @@ struct settype {
|
||||
*/
|
||||
|
||||
/* Size of data. Will be sent to kernel */
|
||||
size_t adt_size;
|
||||
u_int32_t adt_size;
|
||||
|
||||
/* Function which parses command options */
|
||||
ip_set_ip_t (*adt_parser) (int cmd, const char *optarg, void *data);
|
||||
@@ -125,7 +125,7 @@ struct settype {
|
||||
*/
|
||||
|
||||
/* Size of header. */
|
||||
size_t header_size;
|
||||
u_int32_t header_size;
|
||||
|
||||
/* Initialize the type-header */
|
||||
void (*initheader) (struct set *set, const void *data);
|
||||
@@ -134,16 +134,16 @@ struct settype {
|
||||
void (*printheader) (struct set *set, unsigned options);
|
||||
|
||||
/* 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 */
|
||||
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 */
|
||||
void (*saveheader) (struct set *set, unsigned options);
|
||||
|
||||
/* 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 */
|
||||
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;
|
||||
|
||||
#define BITSPERBYTE (8*sizeof(char))
|
||||
#define ID2BYTE(id) ((id)/BITSPERBYTE)
|
||||
#define ID2MASK(id) (1 << ((id)%BITSPERBYTE))
|
||||
#define test_bit(id, heap) ((((char *)(heap))[ID2BYTE(id)] & ID2MASK(id)) != 0)
|
||||
#define BITS_PER_LONG (8*sizeof(unsigned long))
|
||||
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
|
||||
|
||||
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 CONSTRUCTOR(module) \
|
||||
|
@@ -192,7 +192,7 @@ printheader(struct set *set, unsigned options UNUSED)
|
||||
}
|
||||
|
||||
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;
|
||||
ip_set_ip_t *ip;
|
||||
@@ -221,7 +221,7 @@ saveheader(struct set *set, unsigned options UNUSED)
|
||||
|
||||
/* Print save for an IP */
|
||||
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;
|
||||
ip_set_ip_t *ip;
|
||||
|
@@ -225,12 +225,12 @@ initheader(struct set *set, const void *data)
|
||||
mask = range_to_mask(header->from, header->to, &mask_bits);
|
||||
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->sizeid = 2 << (netmask_bits - mask_bits - 1);
|
||||
}
|
||||
|
||||
DP("%i %i", map->hosts, map->sizeid );
|
||||
DP("%d %d", map->hosts, map->sizeid );
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -248,7 +248,7 @@ printheader(struct set *set, unsigned options)
|
||||
|
||||
static void
|
||||
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;
|
||||
ip_set_ip_t id;
|
||||
@@ -279,7 +279,7 @@ saveheader(struct set *set, unsigned options)
|
||||
}
|
||||
|
||||
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;
|
||||
ip_set_ip_t id;
|
||||
|
@@ -248,7 +248,7 @@ printheader(struct set *set, unsigned options)
|
||||
}
|
||||
|
||||
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;
|
||||
size_t offset = 0;
|
||||
@@ -284,7 +284,7 @@ saveheader(struct set *set, unsigned options)
|
||||
|
||||
/* Print save for an IP */
|
||||
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;
|
||||
size_t offset = 0;
|
||||
|
@@ -253,7 +253,7 @@ printheader(struct set *set, unsigned options)
|
||||
}
|
||||
|
||||
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;
|
||||
size_t offset = 0;
|
||||
@@ -292,7 +292,7 @@ saveheader(struct set *set, unsigned options)
|
||||
|
||||
/* Print save for an IP */
|
||||
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;
|
||||
size_t offset = 0;
|
||||
|
@@ -318,7 +318,7 @@ unpack_ip_tostring(ip_set_ip_t ip, unsigned options UNUSED)
|
||||
}
|
||||
|
||||
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;
|
||||
size_t offset = 0;
|
||||
@@ -357,7 +357,7 @@ saveheader(struct set *set, unsigned options)
|
||||
|
||||
/* Print save for an IP */
|
||||
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;
|
||||
size_t offset = 0;
|
||||
|
@@ -123,7 +123,7 @@ printheader(struct set *set, unsigned options UNUSED)
|
||||
}
|
||||
|
||||
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_req_iptree *req;
|
||||
@@ -155,7 +155,7 @@ saveheader(struct set *set, unsigned options UNUSED)
|
||||
}
|
||||
|
||||
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_req_iptree *req;
|
||||
|
@@ -115,7 +115,7 @@ printheader(struct set *set, unsigned int options UNUSED)
|
||||
|
||||
static void
|
||||
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;
|
||||
size_t offset = 0;
|
||||
@@ -147,7 +147,7 @@ saveheader(struct set *set, unsigned int options UNUSED)
|
||||
|
||||
static void
|
||||
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;
|
||||
size_t offset = 0;
|
||||
|
@@ -245,15 +245,14 @@ print_mac(unsigned char macaddress[ETH_ALEN])
|
||||
|
||||
static void
|
||||
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_macip *table = data;
|
||||
u_int32_t addr = mysetdata->first_ip;
|
||||
|
||||
while (addr <= mysetdata->last_ip) {
|
||||
if (test_bit(IPSET_MACIP_ISSET,
|
||||
(void *)&table[addr - mysetdata->first_ip].flags)) {
|
||||
if (table[addr - mysetdata->first_ip].match) {
|
||||
printf("%s,", ip_tostring(addr, options));
|
||||
print_mac(table[addr - mysetdata->first_ip].
|
||||
ethernet);
|
||||
@@ -280,15 +279,14 @@ saveheader(struct set *set, unsigned options)
|
||||
|
||||
static void
|
||||
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_macip *table = data;
|
||||
u_int32_t addr = mysetdata->first_ip;
|
||||
|
||||
while (addr <= mysetdata->last_ip) {
|
||||
if (test_bit(IPSET_MACIP_ISSET,
|
||||
(void *)&table[addr - mysetdata->first_ip].flags)) {
|
||||
if (table[addr - mysetdata->first_ip].match) {
|
||||
printf("-A %s %s,",
|
||||
set->name, ip_tostring(addr, options));
|
||||
print_mac(table[addr - mysetdata->first_ip].
|
||||
|
@@ -224,7 +224,7 @@ unpack_ip_tostring(ip_set_ip_t ip, unsigned options UNUSED)
|
||||
}
|
||||
|
||||
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;
|
||||
ip_set_ip_t *ip;
|
||||
@@ -249,7 +249,7 @@ saveheader(struct set *set, unsigned options UNUSED)
|
||||
|
||||
/* Print save for an IP */
|
||||
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;
|
||||
ip_set_ip_t *ip;
|
||||
|
@@ -149,7 +149,7 @@ printheader(struct set *set, unsigned options)
|
||||
|
||||
static void
|
||||
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;
|
||||
u_int32_t addr = mysetdata->first_ip;
|
||||
@@ -184,7 +184,7 @@ saveheader(struct set *set, unsigned options)
|
||||
|
||||
static void
|
||||
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;
|
||||
u_int32_t addr = mysetdata->first_ip;
|
||||
|
@@ -134,7 +134,7 @@ printheader(struct set *set, unsigned options UNUSED)
|
||||
|
||||
static void
|
||||
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;
|
||||
int i;
|
||||
@@ -162,7 +162,7 @@ saveheader(struct set *set, unsigned options UNUSED)
|
||||
|
||||
static void
|
||||
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;
|
||||
int i;
|
||||
|
109
extensions/iptable_rawpost.c
Normal file
109
extensions/iptable_rawpost.c
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* rawpost table for ip_tables
|
||||
* written by Jan Engelhardt <jengelh [at] medozas de>, 2008 - 2009
|
||||
* placed in the Public Domain
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/version.h>
|
||||
#include <net/ip.h>
|
||||
#include "compat_xtables.h"
|
||||
#include "compat_rawpost.h"
|
||||
|
||||
enum {
|
||||
RAWPOST_VALID_HOOKS = 1 << NF_INET_POST_ROUTING,
|
||||
};
|
||||
|
||||
static struct {
|
||||
struct ipt_replace repl;
|
||||
struct ipt_standard entries[1];
|
||||
struct ipt_error term;
|
||||
} rawpost4_initial __initdata = {
|
||||
.repl = {
|
||||
.name = "rawpost",
|
||||
.valid_hooks = RAWPOST_VALID_HOOKS,
|
||||
.num_entries = 2,
|
||||
.size = sizeof(struct ipt_standard) +
|
||||
sizeof(struct ipt_error),
|
||||
.hook_entry = {
|
||||
[NF_INET_POST_ROUTING] = 0,
|
||||
},
|
||||
.underflow = {
|
||||
[NF_INET_POST_ROUTING] = 0,
|
||||
},
|
||||
},
|
||||
.entries = {
|
||||
IPT_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */
|
||||
},
|
||||
.term = IPT_ERROR_INIT, /* ERROR */
|
||||
};
|
||||
|
||||
static struct xt_table *rawpost4_ptable;
|
||||
|
||||
static struct xt_table rawpost4_itable = {
|
||||
.name = "rawpost",
|
||||
.af = NFPROTO_IPV4,
|
||||
.valid_hooks = RAWPOST_VALID_HOOKS,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static unsigned int rawpost4_hook_fn(unsigned int hook, sk_buff_t *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
|
||||
return ipt_do_table(skb, hook, in, out, rawpost4_ptable);
|
||||
#else
|
||||
return ipt_do_table(skb, hook, in, out, rawpost4_ptable, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct nf_hook_ops rawpost4_hook_ops __read_mostly = {
|
||||
.hook = rawpost4_hook_fn,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP_PRI_LAST,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init rawpost4_table_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 29)
|
||||
rwlock_init(&rawpost4_itable.lock);
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
|
||||
rawpost4_ptable = ipt_register_table(&init_net, &rawpost4_itable,
|
||||
&rawpost4_initial.repl);
|
||||
if (IS_ERR(rawpost4_ptable))
|
||||
return PTR_ERR(rawpost4_ptable);
|
||||
#else
|
||||
ret = ipt_register_table(&rawpost4_itable, &rawpost4_initial.repl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
rawpost4_ptable = &rawpost4_itable;
|
||||
#endif
|
||||
|
||||
ret = nf_register_hook(&rawpost4_hook_ops);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
return ret;
|
||||
|
||||
out:
|
||||
ipt_unregister_table(rawpost4_ptable);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit rawpost4_table_exit(void)
|
||||
{
|
||||
nf_unregister_hook(&rawpost4_hook_ops);
|
||||
ipt_unregister_table(rawpost4_ptable);
|
||||
}
|
||||
|
||||
module_init(rawpost4_table_init);
|
||||
module_exit(rawpost4_table_exit);
|
||||
MODULE_DESCRIPTION("Xtables: rawpost table for use with RAWNAT");
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_LICENSE("GPL");
|
168
extensions/libxt_ACCOUNT.c
Normal file
168
extensions/libxt_ACCOUNT.c
Normal 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);
|
||||
}
|
72
extensions/libxt_ACCOUNT.man
Normal file
72
extensions/libxt_ACCOUNT.man
Normal 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/
|
@@ -30,7 +30,7 @@ static const struct option dhcpmac_tg_opts[] = {
|
||||
static void dhcpmac_tg_help(void)
|
||||
{
|
||||
printf(
|
||||
"DHCPADDDR target options:\n"
|
||||
"DHCPMAC target options:\n"
|
||||
" --set-mac lladdr[/mask] Set MAC address in DHCP Client Host field\n"
|
||||
);
|
||||
}
|
||||
|
@@ -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))
|
||||
xtables_param_act(XTF_BAD_VALUE, "IPMARK", "--shift", optarg);
|
||||
info->shift = n;
|
||||
*flags |= FL_SHIFT;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -117,14 +118,16 @@ ipmark_tg_print(const void *entry, const struct xt_entry_target *target,
|
||||
const struct xt_ipmark_tginfo *info = (const void *)target->data;
|
||||
|
||||
if (info->selector == XT_IPMARK_SRC)
|
||||
printf("IPMARK src ip");
|
||||
printf("IPMARK src ip ");
|
||||
else
|
||||
printf("IPMARK dst ip");
|
||||
printf("IPMARK dst ip ");
|
||||
|
||||
if (info->shift != 0)
|
||||
printf("shift %u ", (unsigned int)info->shift);
|
||||
if (info->andmask != ~0U)
|
||||
printf(" and 0x%x ", (unsigned int)info->andmask);
|
||||
printf("and 0x%x ", (unsigned int)info->andmask);
|
||||
if (info->ormask != 0)
|
||||
printf(" or 0x%x ", (unsigned int)info->ormask);
|
||||
printf("or 0x%x ", (unsigned int)info->ormask);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -137,33 +140,19 @@ ipmark_tg_save(const void *entry, const struct xt_entry_target *target)
|
||||
else
|
||||
printf("--addr dst ");
|
||||
|
||||
if (info->shift != 0)
|
||||
printf("--shift %u ", (unsigned int)info->shift);
|
||||
if (info->andmask != ~0U)
|
||||
printf("--and-mask 0x%x ", (unsigned int)info->andmask);
|
||||
if (info->ormask != 0)
|
||||
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,
|
||||
.name = "IPMARK",
|
||||
.family = PF_INET,
|
||||
.revision = 0,
|
||||
.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,
|
||||
.family = PF_UNSPEC,
|
||||
.revision = 1,
|
||||
.size = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
|
||||
.help = ipmark_tg_help,
|
||||
@@ -177,6 +166,5 @@ static struct xtables_target ipmark_tg6_reg = {
|
||||
|
||||
static __attribute__((constructor)) void ipmark_tg_ldr(void)
|
||||
{
|
||||
xtables_register_target(&ipmark_tg4_reg);
|
||||
xtables_register_target(&ipmark_tg6_reg);
|
||||
xtables_register_target(&ipmark_tg_reg);
|
||||
}
|
||||
|
187
extensions/libxt_RAWDNAT.c
Normal file
187
extensions/libxt_RAWDNAT.c
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* "RAWNAT" target extension for iptables
|
||||
* Copyright © Jan Engelhardt, 2008 - 2009
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <netinet/in.h>
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include "xt_RAWNAT.h"
|
||||
|
||||
enum {
|
||||
FLAGS_TO = 1 << 0,
|
||||
};
|
||||
|
||||
static const struct option rawdnat_tg_opts[] = {
|
||||
{.name = "to-destination", .has_arg = true, .val = 't'},
|
||||
{},
|
||||
};
|
||||
|
||||
static void rawdnat_tg_help(void)
|
||||
{
|
||||
printf(
|
||||
"RAWDNAT target options:\n"
|
||||
" --to-destination addr[/mask] Address or network to map to\n"
|
||||
);
|
||||
}
|
||||
|
||||
static int
|
||||
rawdnat_tg4_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_rawnat_tginfo *info = (void *)(*target)->data;
|
||||
struct in_addr *a;
|
||||
unsigned int mask;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case 't':
|
||||
info->mask = 32;
|
||||
end = strchr(optarg, '/');
|
||||
if (end != NULL) {
|
||||
*end++ = '\0';
|
||||
if (!xtables_strtoui(end, NULL, &mask, 0, 32))
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWDNAT",
|
||||
"--to-destination", optarg);
|
||||
info->mask = mask;
|
||||
}
|
||||
a = xtables_numeric_to_ipaddr(optarg);
|
||||
if (a == NULL)
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWDNAT",
|
||||
"--to-destination", optarg);
|
||||
memcpy(&info->addr.in, a, sizeof(*a));
|
||||
*flags |= FLAGS_TO;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
rawdnat_tg6_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_rawnat_tginfo *info = (void *)(*target)->data;
|
||||
struct in6_addr *a;
|
||||
unsigned int mask;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case 't':
|
||||
info->mask = 128;
|
||||
end = strchr(optarg, '/');
|
||||
if (end != NULL) {
|
||||
*end++ = '\0';
|
||||
if (!xtables_strtoui(end, NULL, &mask, 0, 32))
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWDNAT",
|
||||
"--to-destination", optarg);
|
||||
info->mask = mask;
|
||||
}
|
||||
a = xtables_numeric_to_ip6addr(optarg);
|
||||
if (a == NULL)
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWDNAT",
|
||||
"--to-destination", optarg);
|
||||
memcpy(&info->addr.in6, a, sizeof(*a));
|
||||
*flags |= FLAGS_TO;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void rawdnat_tg_check(unsigned int flags)
|
||||
{
|
||||
if (!(flags & FLAGS_TO))
|
||||
xtables_error(PARAMETER_PROBLEM, "RAWDNAT: "
|
||||
"\"--to-destination\" is required.");
|
||||
}
|
||||
|
||||
static void
|
||||
rawdnat_tg4_print(const void *entry, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
if (!numeric && info->mask == 32)
|
||||
printf("to-destination %s ",
|
||||
xtables_ipaddr_to_anyname(&info->addr.in));
|
||||
else
|
||||
printf("to-destination %s/%u ",
|
||||
xtables_ipaddr_to_numeric(&info->addr.in), info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawdnat_tg6_print(const void *entry, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
if (!numeric && info->mask == 128)
|
||||
printf("to-destination %s ",
|
||||
xtables_ip6addr_to_anyname(&info->addr.in6));
|
||||
else
|
||||
printf("to-destination %s/%u ",
|
||||
xtables_ip6addr_to_numeric(&info->addr.in6), info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawdnat_tg4_save(const void *entry, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
printf("--to-destination %s/%u ",
|
||||
xtables_ipaddr_to_numeric(&info->addr.in),
|
||||
info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawdnat_tg6_save(const void *entry, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
printf("--to-destination %s/%u ",
|
||||
xtables_ip6addr_to_numeric(&info->addr.in6),
|
||||
info->mask);
|
||||
}
|
||||
|
||||
static struct xtables_target rawdnat_tg4_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "RAWDNAT",
|
||||
.revision = 0,
|
||||
.family = PF_INET,
|
||||
.size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.help = rawdnat_tg_help,
|
||||
.parse = rawdnat_tg4_parse,
|
||||
.final_check = rawdnat_tg_check,
|
||||
.print = rawdnat_tg4_print,
|
||||
.save = rawdnat_tg4_save,
|
||||
.extra_opts = rawdnat_tg_opts,
|
||||
};
|
||||
|
||||
static struct xtables_target rawdnat_tg6_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "RAWDNAT",
|
||||
.revision = 0,
|
||||
.family = PF_INET6,
|
||||
.size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.help = rawdnat_tg_help,
|
||||
.parse = rawdnat_tg6_parse,
|
||||
.final_check = rawdnat_tg_check,
|
||||
.print = rawdnat_tg6_print,
|
||||
.save = rawdnat_tg6_save,
|
||||
.extra_opts = rawdnat_tg_opts,
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
{
|
||||
xtables_register_target(&rawdnat_tg4_reg);
|
||||
xtables_register_target(&rawdnat_tg6_reg);
|
||||
}
|
10
extensions/libxt_RAWDNAT.man
Normal file
10
extensions/libxt_RAWDNAT.man
Normal file
@@ -0,0 +1,10 @@
|
||||
The \fBRAWDNAT\fR target will rewrite the destination address in the IP header,
|
||||
much like the \fBNETMAP\fR target.
|
||||
.TP
|
||||
\fB--to-destination\fR \fIaddr\fR[\fB/\fR\fImask\fR]
|
||||
Network address to map to. The resulting address will be constructed the
|
||||
following way: All 'one' bits in the \fImask\fR are filled in from the new
|
||||
\fIaddress\fR. All bits that are zero in the mask are filled in from the
|
||||
original address.
|
||||
.PP
|
||||
See the \fBRAWSNAT\fR help entry for examples and constraints.
|
187
extensions/libxt_RAWSNAT.c
Normal file
187
extensions/libxt_RAWSNAT.c
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* "RAWNAT" target extension for iptables
|
||||
* Copyright © Jan Engelhardt, 2008 - 2009
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <netinet/in.h>
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include "xt_RAWNAT.h"
|
||||
|
||||
enum {
|
||||
FLAGS_TO = 1 << 0,
|
||||
};
|
||||
|
||||
static const struct option rawsnat_tg_opts[] = {
|
||||
{.name = "to-source", .has_arg = true, .val = 't'},
|
||||
{},
|
||||
};
|
||||
|
||||
static void rawsnat_tg_help(void)
|
||||
{
|
||||
printf(
|
||||
"RAWSNAT target options:\n"
|
||||
" --to-source addr[/mask] Address or network to map to\n"
|
||||
);
|
||||
}
|
||||
|
||||
static int
|
||||
rawsnat_tg4_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_rawnat_tginfo *info = (void *)(*target)->data;
|
||||
struct in_addr *a;
|
||||
unsigned int mask;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case 't':
|
||||
info->mask = 32;
|
||||
end = strchr(optarg, '/');
|
||||
if (end != NULL) {
|
||||
*end++ = '\0';
|
||||
if (!xtables_strtoui(end, NULL, &mask, 0, 32))
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWSNAT",
|
||||
"--to-source", optarg);
|
||||
info->mask = mask;
|
||||
}
|
||||
a = xtables_numeric_to_ipaddr(optarg);
|
||||
if (a == NULL)
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWSNAT",
|
||||
"--to-source", optarg);
|
||||
memcpy(&info->addr.in, a, sizeof(*a));
|
||||
*flags |= FLAGS_TO;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
rawsnat_tg6_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_rawnat_tginfo *info = (void *)(*target)->data;
|
||||
struct in6_addr *a;
|
||||
unsigned int mask;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case 't':
|
||||
info->mask = 128;
|
||||
end = strchr(optarg, '/');
|
||||
if (end != NULL) {
|
||||
*end++ = '\0';
|
||||
if (!xtables_strtoui(end, NULL, &mask, 0, 32))
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWSNAT",
|
||||
"--to-source", optarg);
|
||||
info->mask = mask;
|
||||
}
|
||||
a = xtables_numeric_to_ip6addr(optarg);
|
||||
if (a == NULL)
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWSNAT",
|
||||
"--to-source", optarg);
|
||||
memcpy(&info->addr.in6, a, sizeof(*a));
|
||||
*flags |= FLAGS_TO;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void rawsnat_tg_check(unsigned int flags)
|
||||
{
|
||||
if (!(flags & FLAGS_TO))
|
||||
xtables_error(PARAMETER_PROBLEM, "RAWSNAT: "
|
||||
"\"--to-source\" is required.");
|
||||
}
|
||||
|
||||
static void
|
||||
rawsnat_tg4_print(const void *entry, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
if (!numeric && info->mask == 32)
|
||||
printf("to-source %s ",
|
||||
xtables_ipaddr_to_anyname(&info->addr.in));
|
||||
else
|
||||
printf("to-source %s/%u ",
|
||||
xtables_ipaddr_to_numeric(&info->addr.in), info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawsnat_tg6_print(const void *entry, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
if (!numeric && info->mask == 128)
|
||||
printf("to-source %s ",
|
||||
xtables_ip6addr_to_anyname(&info->addr.in6));
|
||||
else
|
||||
printf("to-source %s/%u ",
|
||||
xtables_ip6addr_to_numeric(&info->addr.in6), info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawsnat_tg4_save(const void *entry, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
printf("--to-source %s/%u ",
|
||||
xtables_ipaddr_to_numeric(&info->addr.in),
|
||||
info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawsnat_tg6_save(const void *entry, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
printf("--to-source %s/%u ",
|
||||
xtables_ip6addr_to_numeric(&info->addr.in6),
|
||||
info->mask);
|
||||
}
|
||||
|
||||
static struct xtables_target rawsnat_tg4_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "RAWSNAT",
|
||||
.revision = 0,
|
||||
.family = PF_INET,
|
||||
.size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.help = rawsnat_tg_help,
|
||||
.parse = rawsnat_tg4_parse,
|
||||
.final_check = rawsnat_tg_check,
|
||||
.print = rawsnat_tg4_print,
|
||||
.save = rawsnat_tg4_save,
|
||||
.extra_opts = rawsnat_tg_opts,
|
||||
};
|
||||
|
||||
static struct xtables_target rawsnat_tg6_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "RAWSNAT",
|
||||
.revision = 0,
|
||||
.family = PF_INET6,
|
||||
.size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.help = rawsnat_tg_help,
|
||||
.parse = rawsnat_tg6_parse,
|
||||
.final_check = rawsnat_tg_check,
|
||||
.print = rawsnat_tg6_print,
|
||||
.save = rawsnat_tg6_save,
|
||||
.extra_opts = rawsnat_tg_opts,
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
{
|
||||
xtables_register_target(&rawsnat_tg4_reg);
|
||||
xtables_register_target(&rawsnat_tg6_reg);
|
||||
}
|
38
extensions/libxt_RAWSNAT.man
Normal file
38
extensions/libxt_RAWSNAT.man
Normal file
@@ -0,0 +1,38 @@
|
||||
The \fBRAWSNAT\fR and \fBRAWDNAT\fP targets provide stateless network address
|
||||
translation.
|
||||
.PP
|
||||
The \fBRAWSNAT\fR target will rewrite the source address in the IP header, much
|
||||
like the \fBNETMAP\fP target. \fBRAWSNAT\fP (and \fBRAWDNAT\fP) may only be
|
||||
used in the \fBraw\fP or \fBrawpost\fP tables, but can be used in all chains,
|
||||
which makes it possible to change the source address either when the packet
|
||||
enters the machine or when it leaves it. The reason for this table constraint
|
||||
is that RAWNAT must happen outside of connection tracking.
|
||||
.TP
|
||||
\fB--to-source\fR \fIaddr\fR[\fB/\fR\fImask\fR]
|
||||
Network address to map to. The resulting address will be constructed the
|
||||
following way: All 'one' bits in the \fImask\fR are filled in from the new
|
||||
\fIaddress\fR. All bits that are zero in the mask are filled in from the
|
||||
original address.
|
||||
.PP
|
||||
As an example, changing the destination for packets forwarded from an internal
|
||||
LAN to the internet:
|
||||
.IP
|
||||
-t raw -A PREROUTING -i lan0 -d 212.201.100.135 -j RAWDNAT --to-destination 199.181.132.250
|
||||
-t rawpost -A POSTROUTING -o lan0 -s 199.181.132.250 -j RAWSNAT --to-source 212.201.100.135
|
||||
.PP
|
||||
Note that changing addresses may influence the route selection! Specifically,
|
||||
it statically NATs packets, not connections, like the normal DNAT/SNAT targets
|
||||
would do. Also note that it can transform already-NATed connections -- as said,
|
||||
it is completely external to Netfilter's connection tracking/NAT.
|
||||
.PP
|
||||
If the machine itself generates packets that are to be rawnat'ed, you need a
|
||||
rule in the OUTPUT chain instead, just like you would with the stateful NAT
|
||||
targets.
|
||||
.PP
|
||||
It may be necessary that in doing so, you also need an extra RAWSNAT rule, to
|
||||
override the automatic source address selection that the routing code does
|
||||
before passing packets to iptables. If the connecting socket has not been
|
||||
explicitly bound to an address, as is the common mode of operation, the address
|
||||
that will be chosen is the primary address of the device through which the
|
||||
packet would be routed with its initial destination address - the address as
|
||||
seen before any RAWNAT takes place.
|
@@ -19,7 +19,7 @@ static void steal_tg_check(unsigned int flags)
|
||||
static struct xtables_target steal_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "STEAL",
|
||||
.family = AF_INET,
|
||||
.family = AF_UNSPEC,
|
||||
.size = XT_ALIGN(0),
|
||||
.userspacesize = XT_ALIGN(0),
|
||||
.help = steal_tg_help,
|
||||
|
@@ -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,
|
||||
.name = "SYSRQ",
|
||||
.family = PF_INET,
|
||||
.size = XT_ALIGN(0),
|
||||
.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,
|
||||
.revision = 1,
|
||||
.family = PF_UNSPEC,
|
||||
.size = XT_ALIGN(0),
|
||||
.userspacesize = XT_ALIGN(0),
|
||||
.help = sysrq_tg_help,
|
||||
@@ -45,6 +35,5 @@ static struct xtables_target sysrq_tg6_reg = {
|
||||
|
||||
static __attribute__((constructor)) void sysrq_tg_ldr(void)
|
||||
{
|
||||
xtables_register_target(&sysrq_tg4_reg);
|
||||
xtables_register_target(&sysrq_tg6_reg);
|
||||
xtables_register_target(&sysrq_tg_reg);
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ ipsec --proto esp --tunnel-src 10.10.25.1 --tunnel-dst 10.10.25.7
|
||||
You should also limit the rate at which connections can be received to limit
|
||||
the CPU time taken by illegal requests, for example:
|
||||
.IP
|
||||
-A INPUT 0s 10.10.25.1 -m mac --mac-source aa:bb:cc:dd:ee:ff -d 10.10.25.7
|
||||
-A INPUT -s 10.10.25.1 -m mac --mac-source aa:bb:cc:dd:ee:ff -d 10.10.25.7
|
||||
-p udp --dport 9 -m limit --limit 5/minute -j SYSRQ
|
||||
.PP
|
||||
This extension does not take any options. The \fB-p udp\fP options are
|
||||
|
@@ -74,12 +74,12 @@ static void condition_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
const struct xt_condition_mtinfo *info = (const void *)match->data;
|
||||
|
||||
printf("--condition %s\"%s\" ", (info->invert) ? "! " : "", info->name);
|
||||
printf("%s--condition \"%s\" ", info->invert ? "! " : "", info->name);
|
||||
}
|
||||
|
||||
static struct xtables_match condition_mt_reg = {
|
||||
.name = "condition",
|
||||
.revision = 0,
|
||||
.revision = 1,
|
||||
.family = PF_UNSPEC,
|
||||
.version = XTABLES_VERSION,
|
||||
.size = XT_ALIGN(sizeof(struct xt_condition_mtinfo)),
|
||||
|
@@ -58,7 +58,7 @@ static int fuzzy_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
xtables_error(PARAMETER_PROBLEM,"Can't specify ! --lower-limit");
|
||||
if (*flags & IPT_FUZZY_OPT_MINIMUM)
|
||||
xtables_error(PARAMETER_PROBLEM,"Can't specify --lower-limit twice");
|
||||
if (!xtables_strtoui(optarg, NULL, &num, 1, FUZZY_MAX_RATE) == -1 || num < 1)
|
||||
if (!xtables_strtoui(optarg, NULL, &num, 1, FUZZY_MAX_RATE) || num < 1)
|
||||
xtables_error(PARAMETER_PROBLEM,"BAD --lower-limit");
|
||||
info->minimum_rate = num;
|
||||
*flags |= IPT_FUZZY_OPT_MINIMUM;
|
||||
@@ -69,7 +69,7 @@ static int fuzzy_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
xtables_error(PARAMETER_PROBLEM,"Can't specify ! --upper-limit");
|
||||
if (*flags & IPT_FUZZY_OPT_MAXIMUM)
|
||||
xtables_error(PARAMETER_PROBLEM,"Can't specify --upper-limit twice");
|
||||
if (!xtables_strtoui(optarg, NULL, &num, 1, FUZZY_MAX_RATE) == -1 || num < 1)
|
||||
if (!xtables_strtoui(optarg, NULL, &num, 1, FUZZY_MAX_RATE) || num < 1)
|
||||
xtables_error(PARAMETER_PROBLEM,"BAD --upper-limit");
|
||||
info->maximum_rate = num;
|
||||
*flags |= IPT_FUZZY_OPT_MAXIMUM;
|
||||
@@ -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 = {
|
||||
.name = "fuzzy",
|
||||
.revision = 1,
|
||||
.version = XTABLES_VERSION,
|
||||
.size = XT_ALIGN(sizeof(struct xt_fuzzy_mtinfo)),
|
||||
.userspacesize = offsetof(struct xt_fuzzy_mtinfo, packets_total),
|
||||
|
@@ -261,6 +261,7 @@ geoip_save(const void *ip, const struct xt_entry_match *match)
|
||||
static struct xtables_match geoip_match = {
|
||||
.family = AF_INET,
|
||||
.name = "geoip",
|
||||
.revision = 1,
|
||||
.version = XTABLES_VERSION,
|
||||
.size = XT_ALIGN(sizeof(struct xt_geoip_match_info)),
|
||||
.userspacesize = offsetof(struct xt_geoip_match_info, mem),
|
||||
|
217
extensions/libxt_iface.c
Normal file
217
extensions/libxt_iface.c
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Shared library add-on to iptables to add interface state matching
|
||||
* support.
|
||||
*
|
||||
* (C) 2008 Gáspár Lajos <gaspar.lajos@glsys.eu>
|
||||
*
|
||||
* This program is released under the terms of GNU GPL version 2.
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <xtables.h>
|
||||
#include "xt_iface.h"
|
||||
|
||||
static const struct option iface_mt_opts[] = {
|
||||
{.name = "iface", .has_arg = true, .val = 'i'},
|
||||
{.name = "up", .has_arg = false, .val = 'u'},
|
||||
{.name = "down", .has_arg = false, .val = 'U'}, /* not up */
|
||||
{.name = "broadcast", .has_arg = false, .val = 'b'},
|
||||
{.name = "loopback", .has_arg = false, .val = 'l'},
|
||||
{.name = "pointopoint", .has_arg = false, .val = 'p'},
|
||||
{.name = "pointtopoint", .has_arg = false, .val = 'p'}, /* eq pointopoint */
|
||||
{.name = "running", .has_arg = false, .val = 'r'},
|
||||
{.name = "noarp", .has_arg = false, .val = 'n'},
|
||||
{.name = "arp", .has_arg = false, .val = 'N'}, /* not noarp */
|
||||
{.name = "promisc", .has_arg = false, .val = 'o'},
|
||||
{.name = "multicast", .has_arg = false, .val = 'm'},
|
||||
{.name = "dynamic", .has_arg = false, .val = 'd'},
|
||||
{.name = "lower-up", .has_arg = false, .val = 'w'},
|
||||
{.name = "dormant", .has_arg = false, .val = 'a'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void iface_print_opt(const struct xt_iface_mtinfo *info,
|
||||
const unsigned int option, const char *command)
|
||||
{
|
||||
if (info->flags & option)
|
||||
printf(" %s", command);
|
||||
if (info->invflags & option)
|
||||
printf(" ! %s", command);
|
||||
}
|
||||
|
||||
static void iface_setflag(struct xt_iface_mtinfo *info,
|
||||
unsigned int *flags, int invert, u_int16_t flag, const char *command)
|
||||
{
|
||||
if (*flags & flag)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"iface: \"--%s\" flag already specified", command);
|
||||
if (invert)
|
||||
info->invflags |= flag;
|
||||
else
|
||||
info->flags |= flag;
|
||||
*flags |= flag;
|
||||
}
|
||||
|
||||
static bool iface_valid_name(const char *name)
|
||||
{
|
||||
static const char invalid_chars[] = ".+!*";
|
||||
|
||||
return strlen(name) < IFNAMSIZ && strpbrk(name, invalid_chars) == NULL;
|
||||
}
|
||||
|
||||
static void iface_mt_help(void)
|
||||
{
|
||||
printf(
|
||||
"iface match options:\n"
|
||||
" --iface interface Name of interface\n"
|
||||
"[!] --up / --down match if UP flag (not) set\n"
|
||||
"[!] --broadcast match if BROADCAST flag (not) set\n"
|
||||
"[!] --loopback match if LOOPBACK flag (not) set\n"
|
||||
"[!] --pointopoint\n"
|
||||
"[!] --pointtopoint match if POINTOPOINT flag (not) set\n"
|
||||
"[!] --running match if RUNNING flag (not) set\n"
|
||||
"[!] --noarp / --arp match if NOARP flag (not) set\n"
|
||||
"[!] --promisc match if PROMISC flag (not) set\n"
|
||||
"[!] --multicast match if MULTICAST flag (not) set\n"
|
||||
"[!] --dynamic match if DYNAMIC flag (not) set\n"
|
||||
"[!] --lower-up match if LOWER_UP flag (not) set\n"
|
||||
"[!] --dormant match if DORMANT flag (not) set\n");
|
||||
}
|
||||
|
||||
static int iface_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct xt_iface_mtinfo *info = (void *)(*match)->data;
|
||||
|
||||
switch (c) {
|
||||
case 'U':
|
||||
c = 'u';
|
||||
invert = !invert;
|
||||
break;
|
||||
case 'N':
|
||||
c = 'n';
|
||||
invert = !invert;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case 'i': /* interface name */
|
||||
if (*flags & XT_IFACE_IFACE)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"iface: Interface name already specified");
|
||||
if (!iface_valid_name(optarg))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"iface: Invalid interface name!");
|
||||
strcpy(info->ifname, optarg);
|
||||
*flags |= XT_IFACE_IFACE;
|
||||
return true;
|
||||
case 'u': /* UP */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_UP, "up");
|
||||
return true;
|
||||
case 'b': /* BROADCAST */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_BROADCAST, "broadcast");
|
||||
return true;
|
||||
case 'l': /* LOOPBACK */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_LOOPBACK, "loopback");
|
||||
return true;
|
||||
case 'p': /* POINTOPOINT */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_POINTOPOINT, "pointopoint");
|
||||
return true;
|
||||
case 'r': /* RUNNING */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_RUNNING, "running");
|
||||
return true;
|
||||
case 'n': /* NOARP */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_NOARP, "noarp");
|
||||
return true;
|
||||
case 'o': /* PROMISC */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_PROMISC, "promisc");
|
||||
return true;
|
||||
case 'm': /* MULTICAST */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_MULTICAST, "multicast");
|
||||
return true;
|
||||
case 'd': /* DYNAMIC */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_DYNAMIC, "dynamic");
|
||||
return true;
|
||||
case 'w': /* LOWER_UP */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_LOWER_UP, "lower_up");
|
||||
return true;
|
||||
case 'a': /* DORMANT */
|
||||
iface_setflag(info, flags, invert, XT_IFACE_DORMANT, "dormant");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void iface_mt_check(unsigned int flags)
|
||||
{
|
||||
if (!(flags & XT_IFACE_IFACE))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"iface: You must specify an interface");
|
||||
if (flags == 0 || flags == XT_IFACE_IFACE)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"iface: You must specify at least one option");
|
||||
}
|
||||
|
||||
static void iface_mt_print(const void *ip, const struct xt_entry_match *match,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_iface_mtinfo *info = (const void *)match->data;
|
||||
|
||||
printf("iface: \"%s\" [state:", info->ifname);
|
||||
iface_print_opt(info, XT_IFACE_UP, "up");
|
||||
iface_print_opt(info, XT_IFACE_BROADCAST, "broadcast");
|
||||
iface_print_opt(info, XT_IFACE_LOOPBACK, "loopback");
|
||||
iface_print_opt(info, XT_IFACE_POINTOPOINT, "pointopoint");
|
||||
iface_print_opt(info, XT_IFACE_RUNNING, "running");
|
||||
iface_print_opt(info, XT_IFACE_NOARP, "noarp");
|
||||
iface_print_opt(info, XT_IFACE_PROMISC, "promisc");
|
||||
iface_print_opt(info, XT_IFACE_MULTICAST, "multicast");
|
||||
iface_print_opt(info, XT_IFACE_DYNAMIC, "dynamic");
|
||||
iface_print_opt(info, XT_IFACE_LOWER_UP, "lower_up");
|
||||
iface_print_opt(info, XT_IFACE_DORMANT, "dormant");
|
||||
printf("] ");
|
||||
}
|
||||
|
||||
static void iface_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
const struct xt_iface_mtinfo *info = (const void *)match->data;
|
||||
|
||||
printf(" --iface %s", info->ifname);
|
||||
iface_print_opt(info, XT_IFACE_UP, "--up");
|
||||
iface_print_opt(info, XT_IFACE_BROADCAST, "--broadcast");
|
||||
iface_print_opt(info, XT_IFACE_LOOPBACK, "--loopback");
|
||||
iface_print_opt(info, XT_IFACE_POINTOPOINT, "--pointopoint");
|
||||
iface_print_opt(info, XT_IFACE_RUNNING, "--running");
|
||||
iface_print_opt(info, XT_IFACE_NOARP, "--noarp");
|
||||
iface_print_opt(info, XT_IFACE_PROMISC, "--promisc");
|
||||
iface_print_opt(info, XT_IFACE_MULTICAST, "--multicast");
|
||||
iface_print_opt(info, XT_IFACE_DYNAMIC, "--dynamic");
|
||||
iface_print_opt(info, XT_IFACE_LOWER_UP, "--lower_up");
|
||||
iface_print_opt(info, XT_IFACE_DORMANT, "--dormant");
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static struct xtables_match iface_mt_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "iface",
|
||||
.revision = 0,
|
||||
.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 void _init(void)
|
||||
{
|
||||
xtables_register_match(&iface_mt_reg);
|
||||
}
|
37
extensions/libxt_iface.man
Normal file
37
extensions/libxt_iface.man
Normal file
@@ -0,0 +1,37 @@
|
||||
Allows you to check interface states.
|
||||
.TP
|
||||
\fB\-\-iface\fP \fIname\fP
|
||||
Check the states on the given interface. This option is required.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-up\fP, [\fB!\fP] \fB\-\-down\fP
|
||||
Check the UP flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-broadcast\fP
|
||||
Check the BROADCAST flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-loopback\fP
|
||||
Check the LOOPBACK flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-pointtopoint\fP
|
||||
Check the POINTTOPOINT flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-running\fP
|
||||
Check the RUNNING flag. Do NOT rely on it!
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-noarp\fP, [\fB!\fP] \fB\-\-arp\fP
|
||||
Check the NOARP flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-promisc\fP
|
||||
Check the PROMISC flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-multicast\fP
|
||||
Check the MULTICAST flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-dynamic\fP
|
||||
Check the DYNAMIC flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-lower-up\fP
|
||||
Check the LOWER_UP flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-dormant\fP
|
||||
Check the DORMANT flag.
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* "ipp2p" match extension for iptables
|
||||
* Eicke Friedrich/Klaus Degner <ipp2p@ipp2p.org>, 2005 - 2006
|
||||
* Jan Engelhardt <jengelh [at] medozas de>, 2008
|
||||
* Jan Engelhardt <jengelh [at] medozas de>, 2008 - 2009
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <ctype.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_ipp2p.h"
|
||||
#define param_act(t, s, f) param_act((t), "ipp2p", (s), (f))
|
||||
#define param_act(t, s, f) xtables_param_act((t), "ipp2p", (s), (f))
|
||||
|
||||
static void ipp2p_mt_help(void)
|
||||
{
|
||||
@@ -63,8 +63,8 @@ static int ipp2p_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
|
||||
switch (c) {
|
||||
case '2': /*cmd: edk*/
|
||||
xtables_param_act(XTF_ONLY_ONCE, "--edk", *flags & IPP2P_EDK);
|
||||
xtables_param_act(XTF_NO_INVERT, "--edk", invert);
|
||||
param_act(XTF_ONLY_ONCE, "--edk", *flags & IPP2P_EDK);
|
||||
param_act(XTF_NO_INVERT, "--edk", invert);
|
||||
if (*flags & IPP2P_DATA_EDK)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"ipp2p: use `--edk' OR `--edk-data' but not both of them!");
|
||||
@@ -73,8 +73,8 @@ static int ipp2p_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
break;
|
||||
|
||||
case '7': /*cmd: dc*/
|
||||
xtables_param_act(XTF_ONLY_ONCE, "--dc", *flags & IPP2P_DC);
|
||||
xtables_param_act(XTF_NO_INVERT, "--dc", invert);
|
||||
param_act(XTF_ONLY_ONCE, "--dc", *flags & IPP2P_DC);
|
||||
param_act(XTF_NO_INVERT, "--dc", invert);
|
||||
if (*flags & IPP2P_DATA_DC)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"ipp2p: use `--dc' OR `--dc-data' but not both of them!");
|
||||
@@ -83,8 +83,8 @@ static int ipp2p_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
break;
|
||||
|
||||
case '9': /*cmd: gnu*/
|
||||
xtables_param_act(XTF_ONLY_ONCE, "--gnu", *flags & IPP2P_GNU);
|
||||
xtables_param_act(XTF_NO_INVERT, "--gnu", invert);
|
||||
param_act(XTF_ONLY_ONCE, "--gnu", *flags & IPP2P_GNU);
|
||||
param_act(XTF_NO_INVERT, "--gnu", invert);
|
||||
if (*flags & IPP2P_DATA_GNU)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"ipp2p: use `--gnu' OR `--gnu-data' but not both of them!");
|
||||
@@ -93,8 +93,8 @@ static int ipp2p_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
break;
|
||||
|
||||
case 'a': /*cmd: kazaa*/
|
||||
xtables_param_act(XTF_ONLY_ONCE, "--kazaa", *flags & IPP2P_KAZAA);
|
||||
xtables_param_act(XTF_NO_INVERT, "--kazaa", invert);
|
||||
param_act(XTF_ONLY_ONCE, "--kazaa", *flags & IPP2P_KAZAA);
|
||||
param_act(XTF_NO_INVERT, "--kazaa", invert);
|
||||
if (*flags & IPP2P_DATA_KAZAA)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"ipp2p: use `--kazaa' OR `--kazaa-data' but not both of them!");
|
||||
@@ -103,64 +103,64 @@ static int ipp2p_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
break;
|
||||
|
||||
case 'b': /*cmd: bit*/
|
||||
xtables_param_act(XTF_ONLY_ONCE, "--kazaa", *flags & IPP2P_BIT);
|
||||
xtables_param_act(XTF_NO_INVERT, "--kazaa", invert);
|
||||
param_act(XTF_ONLY_ONCE, "--bit", *flags & IPP2P_BIT);
|
||||
param_act(XTF_NO_INVERT, "--bit", invert);
|
||||
*flags |= IPP2P_BIT;
|
||||
info->cmd |= IPP2P_BIT;
|
||||
break;
|
||||
|
||||
case 'c': /*cmd: apple*/
|
||||
xtables_param_act(XTF_ONLY_ONCE, "--apple", *flags & IPP2P_APPLE);
|
||||
xtables_param_act(XTF_NO_INVERT, "--apple", invert);
|
||||
param_act(XTF_ONLY_ONCE, "--apple", *flags & IPP2P_APPLE);
|
||||
param_act(XTF_NO_INVERT, "--apple", invert);
|
||||
*flags |= IPP2P_APPLE;
|
||||
info->cmd |= IPP2P_APPLE;
|
||||
break;
|
||||
|
||||
case 'd': /*cmd: soul*/
|
||||
xtables_param_act(XTF_ONLY_ONCE, "--soul", *flags & IPP2P_SOUL);
|
||||
xtables_param_act(XTF_NO_INVERT, "--soul", invert);
|
||||
param_act(XTF_ONLY_ONCE, "--soul", *flags & IPP2P_SOUL);
|
||||
param_act(XTF_NO_INVERT, "--soul", invert);
|
||||
*flags |= IPP2P_SOUL;
|
||||
info->cmd |= IPP2P_SOUL;
|
||||
break;
|
||||
|
||||
case 'e': /*cmd: winmx*/
|
||||
xtables_param_act(XTF_ONLY_ONCE, "--winmx", *flags & IPP2P_WINMX);
|
||||
xtables_param_act(XTF_NO_INVERT, "--winmx", invert);
|
||||
param_act(XTF_ONLY_ONCE, "--winmx", *flags & IPP2P_WINMX);
|
||||
param_act(XTF_NO_INVERT, "--winmx", invert);
|
||||
*flags |= IPP2P_WINMX;
|
||||
info->cmd |= IPP2P_WINMX;
|
||||
break;
|
||||
|
||||
case 'f': /*cmd: ares*/
|
||||
xtables_param_act(XTF_ONLY_ONCE, "--ares", *flags & IPP2P_ARES);
|
||||
xtables_param_act(XTF_NO_INVERT, "--ares", invert);
|
||||
param_act(XTF_ONLY_ONCE, "--ares", *flags & IPP2P_ARES);
|
||||
param_act(XTF_NO_INVERT, "--ares", invert);
|
||||
*flags |= IPP2P_ARES;
|
||||
info->cmd |= IPP2P_ARES;
|
||||
break;
|
||||
|
||||
case 'g': /*cmd: mute*/
|
||||
xtables_param_act(XTF_ONLY_ONCE, "--mute", *flags & IPP2P_MUTE);
|
||||
xtables_param_act(XTF_NO_INVERT, "--mute", invert);
|
||||
param_act(XTF_ONLY_ONCE, "--mute", *flags & IPP2P_MUTE);
|
||||
param_act(XTF_NO_INVERT, "--mute", invert);
|
||||
*flags |= IPP2P_MUTE;
|
||||
info->cmd |= IPP2P_MUTE;
|
||||
break;
|
||||
|
||||
case 'h': /*cmd: waste*/
|
||||
xtables_param_act(XTF_ONLY_ONCE, "--waste", *flags & IPP2P_WASTE);
|
||||
xtables_param_act(XTF_NO_INVERT, "--waste", invert);
|
||||
param_act(XTF_ONLY_ONCE, "--waste", *flags & IPP2P_WASTE);
|
||||
param_act(XTF_NO_INVERT, "--waste", invert);
|
||||
*flags |= IPP2P_WASTE;
|
||||
info->cmd |= IPP2P_WASTE;
|
||||
break;
|
||||
|
||||
case 'i': /*cmd: xdcc*/
|
||||
xtables_param_act(XTF_ONLY_ONCE, "--xdcc", *flags & IPP2P_XDCC);
|
||||
xtables_param_act(XTF_NO_INVERT, "--xdcc", invert);
|
||||
param_act(XTF_ONLY_ONCE, "--xdcc", *flags & IPP2P_XDCC);
|
||||
param_act(XTF_NO_INVERT, "--xdcc", invert);
|
||||
*flags |= IPP2P_XDCC;
|
||||
info->cmd |= IPP2P_XDCC;
|
||||
break;
|
||||
|
||||
case 'j': /*cmd: debug*/
|
||||
xtables_param_act(XTF_ONLY_ONCE, "--debug", info->debug);
|
||||
xtables_param_act(XTF_NO_INVERT, "--debug", invert);
|
||||
param_act(XTF_ONLY_ONCE, "--debug", info->debug);
|
||||
param_act(XTF_NO_INVERT, "--debug", invert);
|
||||
info->debug = 1;
|
||||
break;
|
||||
|
||||
@@ -199,7 +199,7 @@ static const char *const ipp2p_cmds[] = {
|
||||
};
|
||||
|
||||
static void
|
||||
ipp2p_mt_print(const void *entry, const struct xt_entry_match *match,
|
||||
ipp2p_mt_print1(const void *entry, const struct xt_entry_match *match,
|
||||
int numeric)
|
||||
{
|
||||
const struct ipt_p2p_info *info = (const void *)match->data;
|
||||
@@ -213,15 +213,22 @@ ipp2p_mt_print(const void *entry, const struct xt_entry_match *match,
|
||||
printf("--debug ");
|
||||
}
|
||||
|
||||
static void ipp2p_mt_print(const void *entry,
|
||||
const struct xt_entry_match *match, int numeric)
|
||||
{
|
||||
printf("ipp2p ");
|
||||
ipp2p_mt_print1(entry, match, true);
|
||||
}
|
||||
|
||||
static void ipp2p_mt_save(const void *entry, const struct xt_entry_match *match)
|
||||
{
|
||||
ipp2p_mt_print(entry, match, true);
|
||||
ipp2p_mt_print1(entry, match, true);
|
||||
}
|
||||
|
||||
static struct xtables_match ipp2p_mt_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "ipp2p",
|
||||
.revision = 0,
|
||||
.revision = 1,
|
||||
.family = AF_INET,
|
||||
.size = XT_ALIGN(sizeof(struct ipt_p2p_info)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct ipt_p2p_info)),
|
||||
|
158
extensions/libxt_psd.c
Normal file
158
extensions/libxt_psd.c
Normal 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
18
extensions/libxt_psd.man
Normal 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.
|
@@ -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 = {
|
||||
.family = AF_UNSPEC,
|
||||
.revision = 2,
|
||||
.revision = 3,
|
||||
.name = "quota2",
|
||||
.version = XTABLES_VERSION,
|
||||
.size = XT_ALIGN(sizeof (struct xt_quota_mtinfo2)),
|
||||
|
1104
extensions/xt_ACCOUNT.c
Normal file
1104
extensions/xt_ACCOUNT.c
Normal file
File diff suppressed because it is too large
Load Diff
118
extensions/xt_ACCOUNT.h
Normal file
118
extensions/xt_ACCOUNT.h
Normal 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 */
|
@@ -119,19 +119,18 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
|
||||
addr_type = RTN_LOCAL;
|
||||
|
||||
/* ip_route_me_harder expects skb->dst to be set */
|
||||
dst_hold(oldskb->dst);
|
||||
nskb->dst = oldskb->dst;
|
||||
skb_dst_set(nskb, dst_clone(skb_dst(oldskb)));
|
||||
|
||||
if (ip_route_me_harder(&nskb, addr_type))
|
||||
goto free_nskb;
|
||||
else
|
||||
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;
|
||||
|
||||
/* "Never happens" */
|
||||
if (nskb->len > dst_mtu(nskb->dst))
|
||||
if (nskb->len > dst_mtu(skb_dst(nskb)))
|
||||
goto free_nskb;
|
||||
|
||||
nf_ct_attach(nskb, oldskb);
|
||||
|
@@ -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 = {
|
||||
{
|
||||
.name = "IPMARK",
|
||||
.revision = 0,
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV4,
|
||||
.table = "mangle",
|
||||
.target = ipmark_tg4,
|
||||
@@ -91,7 +91,7 @@ static struct xt_target ipmark_tg_reg[] __read_mostly = {
|
||||
},
|
||||
{
|
||||
.name = "IPMARK",
|
||||
.revision = 0,
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV6,
|
||||
.table = "mangle",
|
||||
.target = ipmark_tg6,
|
||||
|
8
extensions/xt_RAWNAT.Kconfig
Normal file
8
extensions/xt_RAWNAT.Kconfig
Normal file
@@ -0,0 +1,8 @@
|
||||
config NETFILTER_XT_TARGET_RAWNAT
|
||||
tristate '"RAWNAT" raw address translation w/o conntrack'
|
||||
depends on NETFILTER_XTABLES && NETFILTER_ADVANCED
|
||||
depends on IP_NF_RAW || IP_NF6_RAW
|
||||
---help---
|
||||
This option adds the RAWSNAT and RAWDNAT targets which can do Network
|
||||
Address Translation (no port translation) without requiring Netfilter
|
||||
connection tracking.
|
346
extensions/xt_RAWNAT.c
Normal file
346
extensions/xt_RAWNAT.c
Normal file
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* "RAWNAT" target extension for Xtables - untracked NAT
|
||||
* Copyright © Jan Engelhardt, 2008 - 2009
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <linux/ip.h>
|
||||
#include <linux/ipv6.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/udp.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter/nf_conntrack_common.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/ipv6.h>
|
||||
#include "compat_xtables.h"
|
||||
#include "xt_RAWNAT.h"
|
||||
|
||||
static inline __be32
|
||||
remask(__be32 addr, __be32 repl, unsigned int shift)
|
||||
{
|
||||
uint32_t mask = (shift == 32) ? 0 : (~(uint32_t)0 >> shift);
|
||||
return htonl((ntohl(addr) & mask) | (ntohl(repl) & ~mask));
|
||||
}
|
||||
|
||||
static void
|
||||
rawnat_ipv6_mask(__be32 *addr, const __be32 *repl, unsigned int mask)
|
||||
{
|
||||
switch (mask) {
|
||||
case 0:
|
||||
break;
|
||||
case 1 ... 31:
|
||||
addr[0] = remask(addr[0], repl[0], mask);
|
||||
break;
|
||||
case 32:
|
||||
addr[0] = repl[0];
|
||||
break;
|
||||
case 33 ... 63:
|
||||
addr[0] = repl[0];
|
||||
addr[1] = remask(addr[1], repl[1], mask - 64);
|
||||
break;
|
||||
case 64:
|
||||
addr[0] = repl[0];
|
||||
addr[1] = repl[1];
|
||||
break;
|
||||
case 65 ... 95:
|
||||
addr[0] = repl[0];
|
||||
addr[1] = repl[1];
|
||||
addr[2] = remask(addr[2], repl[2], mask - 96);
|
||||
case 96:
|
||||
addr[0] = repl[0];
|
||||
addr[1] = repl[1];
|
||||
addr[2] = repl[2];
|
||||
break;
|
||||
case 97 ... 127:
|
||||
addr[0] = repl[0];
|
||||
addr[1] = repl[1];
|
||||
addr[2] = repl[2];
|
||||
addr[3] = remask(addr[3], repl[3], mask - 128);
|
||||
break;
|
||||
case 128:
|
||||
addr[0] = repl[0];
|
||||
addr[1] = repl[1];
|
||||
addr[2] = repl[2];
|
||||
addr[3] = repl[3];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rawnat4_update_l4(struct sk_buff *skb, __be32 oldip, __be32 newip)
|
||||
{
|
||||
struct iphdr *iph = ip_hdr(skb);
|
||||
void *transport_hdr = (void *)iph + ip_hdrlen(skb);
|
||||
struct tcphdr *tcph;
|
||||
struct udphdr *udph;
|
||||
bool cond;
|
||||
|
||||
switch (iph->protocol) {
|
||||
case IPPROTO_TCP:
|
||||
tcph = transport_hdr;
|
||||
inet_proto_csum_replace4(&tcph->check, skb, oldip, newip, true);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
case IPPROTO_UDPLITE:
|
||||
udph = transport_hdr;
|
||||
cond = udph->check != 0;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
|
||||
cond |= skb->ip_summed == CHECKSUM_PARTIAL;
|
||||
#endif
|
||||
if (cond) {
|
||||
inet_proto_csum_replace4(&udph->check, skb,
|
||||
oldip, newip, true);
|
||||
if (udph->check == 0)
|
||||
udph->check = CSUM_MANGLED_0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int rawnat4_writable_part(const struct iphdr *iph)
|
||||
{
|
||||
unsigned int wlen = sizeof(*iph);
|
||||
|
||||
switch (iph->protocol) {
|
||||
case IPPROTO_TCP:
|
||||
wlen += sizeof(struct tcphdr);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
wlen += sizeof(struct udphdr);
|
||||
break;
|
||||
}
|
||||
return wlen;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
rawsnat_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = par->targinfo;
|
||||
struct iphdr *iph;
|
||||
__be32 new_addr;
|
||||
|
||||
iph = ip_hdr(*pskb);
|
||||
new_addr = remask(iph->saddr, info->addr.ip, info->mask);
|
||||
if (iph->saddr == new_addr)
|
||||
return XT_CONTINUE;
|
||||
|
||||
if (!skb_make_writable(pskb, rawnat4_writable_part(iph)))
|
||||
return NF_DROP;
|
||||
|
||||
iph = ip_hdr(*pskb);
|
||||
csum_replace4(&iph->check, iph->saddr, new_addr);
|
||||
rawnat4_update_l4(*pskb, iph->saddr, new_addr);
|
||||
iph->saddr = new_addr;
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
rawdnat_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = par->targinfo;
|
||||
struct iphdr *iph;
|
||||
__be32 new_addr;
|
||||
|
||||
iph = ip_hdr(*pskb);
|
||||
new_addr = remask(iph->daddr, info->addr.ip, info->mask);
|
||||
if (iph->daddr == new_addr)
|
||||
return XT_CONTINUE;
|
||||
|
||||
if (!skb_make_writable(pskb, rawnat4_writable_part(iph)))
|
||||
return NF_DROP;
|
||||
|
||||
iph = ip_hdr(*pskb);
|
||||
csum_replace4(&iph->check, iph->daddr, new_addr);
|
||||
rawnat4_update_l4(*pskb, iph->daddr, new_addr);
|
||||
iph->daddr = new_addr;
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
static bool rawnat6_prepare_l4(struct sk_buff **pskb, unsigned int *l4offset,
|
||||
unsigned int *l4proto)
|
||||
{
|
||||
static const unsigned int types[] =
|
||||
{IPPROTO_TCP, IPPROTO_UDP, IPPROTO_UDPLITE};
|
||||
unsigned int i;
|
||||
int err;
|
||||
|
||||
*l4proto = NEXTHDR_MAX;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(types); ++i) {
|
||||
err = ipv6_find_hdr(*pskb, l4offset, types[i], NULL);
|
||||
if (err >= 0) {
|
||||
*l4proto = types[i];
|
||||
break;
|
||||
}
|
||||
if (err != -ENOENT)
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (*l4proto) {
|
||||
case IPPROTO_TCP:
|
||||
if (!skb_make_writable(pskb, *l4offset + sizeof(struct tcphdr)))
|
||||
return false;
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
case IPPROTO_UDPLITE:
|
||||
if (!skb_make_writable(pskb, *l4offset + sizeof(struct udphdr)))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void rawnat6_update_l4(struct sk_buff *skb, unsigned int l4proto,
|
||||
unsigned int l4offset, const struct in6_addr *oldip,
|
||||
const struct in6_addr *newip)
|
||||
{
|
||||
const struct ipv6hdr *iph = ipv6_hdr(skb);
|
||||
struct tcphdr *tcph;
|
||||
struct udphdr *udph;
|
||||
unsigned int i;
|
||||
bool cond;
|
||||
|
||||
switch (l4proto) {
|
||||
case IPPROTO_TCP:
|
||||
tcph = (void *)iph + l4offset;
|
||||
for (i = 0; i < 4; ++i)
|
||||
inet_proto_csum_replace4(&tcph->check, skb,
|
||||
oldip->s6_addr32[i], newip->s6_addr32[i], true);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
case IPPROTO_UDPLITE:
|
||||
udph = (void *)iph + l4offset;
|
||||
cond = udph->check;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
|
||||
cond |= skb->ip_summed == CHECKSUM_PARTIAL;
|
||||
#endif
|
||||
if (cond) {
|
||||
for (i = 0; i < 4; ++i)
|
||||
inet_proto_csum_replace4(&udph->check, skb,
|
||||
oldip->s6_addr32[i],
|
||||
newip->s6_addr32[i], true);
|
||||
if (udph->check == 0)
|
||||
udph->check = CSUM_MANGLED_0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
rawsnat_tg6(struct sk_buff **pskb, const struct xt_target_param *par)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = par->targinfo;
|
||||
unsigned int l4offset, l4proto;
|
||||
struct ipv6hdr *iph;
|
||||
struct in6_addr new_addr;
|
||||
|
||||
iph = ipv6_hdr(*pskb);
|
||||
memcpy(&new_addr, &iph->saddr, sizeof(new_addr));
|
||||
rawnat_ipv6_mask(new_addr.s6_addr32, info->addr.ip6, info->mask);
|
||||
if (ipv6_addr_cmp(&iph->saddr, &new_addr) == 0)
|
||||
return XT_CONTINUE;
|
||||
if (!rawnat6_prepare_l4(pskb, &l4offset, &l4proto))
|
||||
return NF_DROP;
|
||||
iph = ipv6_hdr(*pskb);
|
||||
rawnat6_update_l4(*pskb, l4proto, l4offset, &iph->saddr, &new_addr);
|
||||
memcpy(&iph->saddr, &new_addr, sizeof(new_addr));
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
rawdnat_tg6(struct sk_buff **pskb, const struct xt_target_param *par)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = par->targinfo;
|
||||
unsigned int l4offset, l4proto;
|
||||
struct ipv6hdr *iph;
|
||||
struct in6_addr new_addr;
|
||||
|
||||
iph = ipv6_hdr(*pskb);
|
||||
memcpy(&new_addr, &iph->daddr, sizeof(new_addr));
|
||||
rawnat_ipv6_mask(new_addr.s6_addr32, info->addr.ip6, info->mask);
|
||||
if (ipv6_addr_cmp(&iph->daddr, &new_addr) == 0)
|
||||
return XT_CONTINUE;
|
||||
if (!rawnat6_prepare_l4(pskb, &l4offset, &l4proto))
|
||||
return NF_DROP;
|
||||
iph = ipv6_hdr(*pskb);
|
||||
rawnat6_update_l4(*pskb, l4proto, l4offset, &iph->daddr, &new_addr);
|
||||
memcpy(&iph->daddr, &new_addr, sizeof(new_addr));
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
static bool rawnat_tg_check(const struct xt_tgchk_param *par)
|
||||
{
|
||||
if (strcmp(par->table, "raw") == 0 ||
|
||||
strcmp(par->table, "rawpost") == 0)
|
||||
return true;
|
||||
|
||||
printk(KERN_ERR KBUILD_MODNAME " may only be used in the \"raw\" or "
|
||||
"\"rawpost\" table.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct xt_target rawnat_tg_reg[] __read_mostly = {
|
||||
{
|
||||
.name = "RAWSNAT",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV4,
|
||||
.target = rawsnat_tg4,
|
||||
.targetsize = sizeof(struct xt_rawnat_tginfo),
|
||||
.checkentry = rawnat_tg_check,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
{
|
||||
.name = "RAWSNAT",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV6,
|
||||
.target = rawsnat_tg6,
|
||||
.targetsize = sizeof(struct xt_rawnat_tginfo),
|
||||
.checkentry = rawnat_tg_check,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
{
|
||||
.name = "RAWDNAT",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV4,
|
||||
.target = rawdnat_tg4,
|
||||
.targetsize = sizeof(struct xt_rawnat_tginfo),
|
||||
.checkentry = rawnat_tg_check,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
{
|
||||
.name = "RAWDNAT",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV6,
|
||||
.target = rawdnat_tg6,
|
||||
.targetsize = sizeof(struct xt_rawnat_tginfo),
|
||||
.checkentry = rawnat_tg_check,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init rawnat_tg_init(void)
|
||||
{
|
||||
return xt_register_targets(rawnat_tg_reg, ARRAY_SIZE(rawnat_tg_reg));
|
||||
}
|
||||
|
||||
static void __exit rawnat_tg_exit(void)
|
||||
{
|
||||
xt_unregister_targets(rawnat_tg_reg, ARRAY_SIZE(rawnat_tg_reg));
|
||||
}
|
||||
|
||||
module_init(rawnat_tg_init);
|
||||
module_exit(rawnat_tg_exit);
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_DESCRIPTION("Xtables: conntrack-less raw NAT");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_RAWSNAT");
|
||||
MODULE_ALIAS("ipt_RAWDNAT");
|
||||
MODULE_ALIAS("ip6t_RAWSNAT");
|
||||
MODULE_ALIAS("ip6t_RAWDNAT");
|
9
extensions/xt_RAWNAT.h
Normal file
9
extensions/xt_RAWNAT.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef _LINUX_NETFILTER_XT_TARGET_RAWNAT
|
||||
#define _LINUX_NETFILTER_XT_TARGET_RAWNAT 1
|
||||
|
||||
struct xt_rawnat_tginfo {
|
||||
union nf_inet_addr addr;
|
||||
__u8 mask;
|
||||
};
|
||||
|
||||
#endif /* _LINUX_NETFILTER_XT_TARGET_RAWNAT */
|
@@ -272,7 +272,7 @@ static bool sysrq_tg_check(const struct xt_tgchk_param *par)
|
||||
static struct xt_target sysrq_tg_reg[] __read_mostly = {
|
||||
{
|
||||
.name = "SYSRQ",
|
||||
.revision = 0,
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV4,
|
||||
.target = sysrq_tg4,
|
||||
.checkentry = sysrq_tg_check,
|
||||
@@ -280,7 +280,7 @@ static struct xt_target sysrq_tg_reg[] __read_mostly = {
|
||||
},
|
||||
{
|
||||
.name = "SYSRQ",
|
||||
.revision = 0,
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV6,
|
||||
.target = sysrq_tg6,
|
||||
.checkentry = sysrq_tg_check,
|
||||
|
@@ -167,20 +167,20 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
|
||||
nskb->ip_summed = CHECKSUM_NONE;
|
||||
|
||||
/* Adjust IP TTL */
|
||||
niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
|
||||
niph->ttl = dst_metric(skb_dst(nskb), RTAX_HOPLIMIT);
|
||||
|
||||
/* Adjust IP checksum */
|
||||
niph->check = 0;
|
||||
niph->check = ip_fast_csum(skb_network_header(nskb), niph->ihl);
|
||||
|
||||
/* "Never happens" */
|
||||
if (nskb->len > dst_mtu(nskb->dst))
|
||||
if (nskb->len > dst_mtu(skb_dst(nskb)))
|
||||
goto free_nskb;
|
||||
|
||||
nf_ct_attach(nskb, oldskb);
|
||||
|
||||
NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
|
||||
dst_output);
|
||||
NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, nskb, NULL,
|
||||
skb_dst(nskb)->dev, dst_output);
|
||||
return;
|
||||
|
||||
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 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.) */
|
||||
if (rt == NULL)
|
||||
|
@@ -79,9 +79,9 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info)
|
||||
return false;
|
||||
}
|
||||
|
||||
dst_release(skb->dst);
|
||||
skb->dst = &rt->u.dst;
|
||||
skb->dev = skb->dst->dev;
|
||||
dst_release(skb_dst(skb));
|
||||
skb_dst_set(skb, &rt->u.dst);
|
||||
skb->dev = rt->u.dst.dev;
|
||||
skb->protocol = htons(ETH_P_IP);
|
||||
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)
|
||||
{
|
||||
const struct dst_entry *dst = skb->dst;
|
||||
const struct dst_entry *dst = skb_dst(skb);
|
||||
const struct net_device *dev = dst->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
|
||||
* 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);
|
||||
if (skb == NULL) {
|
||||
@@ -251,9 +251,9 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info)
|
||||
return false;
|
||||
}
|
||||
|
||||
dst_release(skb->dst);
|
||||
skb->dst = dst;
|
||||
skb->dev = skb->dst->dev;
|
||||
dst_release(skb_dst(skb));
|
||||
skb_dst_set(skb, dst);
|
||||
skb->dev = dst->dev;
|
||||
skb->protocol = htons(ETH_P_IPV6);
|
||||
return true;
|
||||
}
|
||||
|
@@ -161,7 +161,9 @@ static bool condition_mt_check(const struct xt_mtchk_param *par)
|
||||
|
||||
var->refcount = 1;
|
||||
var->enabled = false;
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 29)
|
||||
var->status_proc->owner = THIS_MODULE;
|
||||
#endif
|
||||
var->status_proc->data = var;
|
||||
wmb();
|
||||
var->status_proc->read_proc = condition_proc_read;
|
||||
@@ -204,7 +206,7 @@ static void condition_mt_destroy(const struct xt_mtdtor_param *par)
|
||||
static struct xt_match condition_mt_reg[] __read_mostly = {
|
||||
{
|
||||
.name = "condition",
|
||||
.revision = 0,
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV4,
|
||||
.matchsize = XT_ALIGN(sizeof(struct xt_condition_mtinfo)),
|
||||
.match = condition_mt,
|
||||
@@ -214,7 +216,7 @@ static struct xt_match condition_mt_reg[] __read_mostly = {
|
||||
},
|
||||
{
|
||||
.name = "condition",
|
||||
.revision = 0,
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV6,
|
||||
.matchsize = XT_ALIGN(sizeof(struct xt_condition_mtinfo)),
|
||||
.match = condition_mt,
|
||||
|
@@ -142,7 +142,7 @@ static bool fuzzy_mt_check(const struct xt_mtchk_param *par)
|
||||
static struct xt_match fuzzy_mt_reg[] __read_mostly = {
|
||||
{
|
||||
.name = "fuzzy",
|
||||
.revision = 0,
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV4,
|
||||
.match = fuzzy_mt,
|
||||
.checkentry = fuzzy_mt_check,
|
||||
@@ -151,7 +151,7 @@ static struct xt_match fuzzy_mt_reg[] __read_mostly = {
|
||||
},
|
||||
{
|
||||
.name = "fuzzy",
|
||||
.revision = 0,
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV6,
|
||||
.match = fuzzy_mt,
|
||||
.checkentry = fuzzy_mt_check,
|
||||
|
@@ -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 = {
|
||||
.name = "geoip",
|
||||
.revision = 0,
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV4,
|
||||
.match = xt_geoip_mt,
|
||||
.checkentry = xt_geoip_mt_checkentry,
|
||||
|
100
extensions/xt_iface.c
Normal file
100
extensions/xt_iface.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* xt_iface - kernel module to match interface state flags
|
||||
*
|
||||
* Original author: Gáspár Lajos <gaspar.lajos@glsys.eu>
|
||||
*/
|
||||
|
||||
#include <linux/if.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include "xt_iface.h"
|
||||
#include "compat_xtables.h"
|
||||
|
||||
struct xt_iface_flag_pairs {
|
||||
uint16_t iface_flag;
|
||||
uint32_t iff_flag;
|
||||
};
|
||||
|
||||
MODULE_AUTHOR("Gáspár Lajos <gaspar.lajos@glsys.eu>");
|
||||
MODULE_DESCRIPTION("Xtables: iface match module");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_iface");
|
||||
MODULE_ALIAS("ip6t_iface");
|
||||
//MODULE_ALIAS("arpt_iface");
|
||||
|
||||
static const struct xt_iface_flag_pairs xt_iface_lookup[] =
|
||||
{
|
||||
{.iface_flag = XT_IFACE_UP, .iff_flag = IFF_UP},
|
||||
{.iface_flag = XT_IFACE_BROADCAST, .iff_flag = IFF_BROADCAST},
|
||||
{.iface_flag = XT_IFACE_LOOPBACK, .iff_flag = IFF_LOOPBACK},
|
||||
{.iface_flag = XT_IFACE_POINTOPOINT, .iff_flag = IFF_POINTOPOINT},
|
||||
{.iface_flag = XT_IFACE_RUNNING, .iff_flag = IFF_RUNNING},
|
||||
{.iface_flag = XT_IFACE_NOARP, .iff_flag = IFF_NOARP},
|
||||
{.iface_flag = XT_IFACE_PROMISC, .iff_flag = IFF_PROMISC},
|
||||
{.iface_flag = XT_IFACE_MULTICAST, .iff_flag = IFF_MULTICAST},
|
||||
{.iface_flag = XT_IFACE_DYNAMIC, .iff_flag = IFF_DYNAMIC},
|
||||
{.iface_flag = XT_IFACE_LOWER_UP, .iff_flag = IFF_LOWER_UP},
|
||||
{.iface_flag = XT_IFACE_DORMANT, .iff_flag = IFF_DORMANT},
|
||||
};
|
||||
|
||||
static bool xt_iface_mt(const struct sk_buff *skb,
|
||||
const struct xt_match_param *par)
|
||||
{
|
||||
const struct xt_iface_mtinfo *info = par->matchinfo;
|
||||
struct net_device *dev;
|
||||
bool retval;
|
||||
int i;
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
|
||||
dev = dev_get_by_name(&init_net, info->ifname);
|
||||
#else
|
||||
dev = dev_get_by_name(info->ifname);
|
||||
#endif
|
||||
retval = dev != NULL;
|
||||
if (retval) {
|
||||
for (i = 0; i < ARRAY_SIZE(xt_iface_lookup) && retval; ++i) {
|
||||
if (info->flags & xt_iface_lookup[i].iface_flag)
|
||||
retval &= dev->flags & xt_iface_lookup[i].iff_flag;
|
||||
if (info->invflags & xt_iface_lookup[i].iface_flag)
|
||||
retval &= !(dev->flags & xt_iface_lookup[i].iff_flag);
|
||||
}
|
||||
dev_put(dev);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static struct xt_match xt_iface_mt_reg[] __read_mostly = {
|
||||
{
|
||||
.name = "iface",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV4,
|
||||
.matchsize = XT_ALIGN(sizeof(struct xt_iface_mtinfo)),
|
||||
.match = xt_iface_mt,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
{
|
||||
.name = "iface",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV6,
|
||||
.matchsize = XT_ALIGN(sizeof(struct xt_iface_mtinfo)),
|
||||
.match = xt_iface_mt,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init xt_iface_match_init(void)
|
||||
{
|
||||
return xt_register_matches(xt_iface_mt_reg,
|
||||
ARRAY_SIZE(xt_iface_mt_reg));
|
||||
}
|
||||
|
||||
static void __exit xt_iface_match_exit(void)
|
||||
{
|
||||
xt_unregister_matches(xt_iface_mt_reg, ARRAY_SIZE(xt_iface_mt_reg));
|
||||
}
|
||||
|
||||
module_init(xt_iface_match_init);
|
||||
module_exit(xt_iface_match_exit);
|
25
extensions/xt_iface.h
Normal file
25
extensions/xt_iface.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef _LINUX_NETFILTER_XT_IFACE_H
|
||||
#define _LINUX_NETFILTER_XT_IFACE_H 1
|
||||
|
||||
enum {
|
||||
XT_IFACE_UP = 1 << 0,
|
||||
XT_IFACE_BROADCAST = 1 << 1,
|
||||
XT_IFACE_LOOPBACK = 1 << 2,
|
||||
XT_IFACE_POINTOPOINT = 1 << 3,
|
||||
XT_IFACE_RUNNING = 1 << 4,
|
||||
XT_IFACE_NOARP = 1 << 5,
|
||||
XT_IFACE_PROMISC = 1 << 6,
|
||||
XT_IFACE_MULTICAST = 1 << 7,
|
||||
XT_IFACE_DYNAMIC = 1 << 8,
|
||||
XT_IFACE_LOWER_UP = 1 << 9,
|
||||
XT_IFACE_DORMANT = 1 << 10,
|
||||
XT_IFACE_IFACE = 1 << 15,
|
||||
};
|
||||
|
||||
struct xt_iface_mtinfo {
|
||||
char ifname[IFNAMSIZ];
|
||||
__u16 flags;
|
||||
__u16 invflags;
|
||||
};
|
||||
|
||||
#endif
|
@@ -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 = {
|
||||
.name = "ipp2p",
|
||||
.revision = 0,
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV4,
|
||||
.match = ipp2p_mt,
|
||||
.matchsize = sizeof(struct ipt_p2p_info),
|
||||
|
6
extensions/xt_psd.Kconfig
Normal file
6
extensions/xt_psd.Kconfig
Normal 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
332
extensions/xt_psd.c
Normal 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
41
extensions/xt_psd.h
Normal 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*/
|
@@ -21,12 +21,15 @@
|
||||
#include "xt_quota2.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;
|
||||
spinlock_t lock;
|
||||
struct list_head list;
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
int count, int *eof, void *data)
|
||||
{
|
||||
struct quota_counter *e = data;
|
||||
struct xt_quota_counter *e = data;
|
||||
int ret;
|
||||
|
||||
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,
|
||||
unsigned long size, void *data)
|
||||
{
|
||||
struct quota_counter *e = data;
|
||||
struct xt_quota_counter *e = data;
|
||||
char buf[sizeof("18446744073709551616")];
|
||||
|
||||
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';
|
||||
|
||||
spin_lock_bh(&e->lock);
|
||||
e->quota = simple_strtoul(buf, NULL, 0);
|
||||
e->quota = simple_strtoull(buf, NULL, 0);
|
||||
spin_unlock_bh(&e->lock);
|
||||
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
|
||||
* @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 quota_counter *e;
|
||||
struct xt_quota_counter *e;
|
||||
|
||||
if (*q->name == '\0')
|
||||
return q2_new_counter(q, true);
|
||||
|
||||
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) {
|
||||
atomic_inc(&e->ref);
|
||||
spin_unlock_bh(&counter_list_lock);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
e = kmalloc(sizeof(struct quota_counter), GFP_KERNEL);
|
||||
e = q2_new_counter(q, false);
|
||||
if (e == NULL)
|
||||
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,
|
||||
proc_xt_quota);
|
||||
if (p == NULL || IS_ERR(p))
|
||||
goto out;
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 29)
|
||||
p->owner = THIS_MODULE;
|
||||
#endif
|
||||
p->data = e;
|
||||
p->read_proc = quota_proc_read;
|
||||
p->write_proc = quota_proc_write;
|
||||
@@ -128,15 +152,16 @@ static bool quota_mt2_check(const struct xt_mtchk_param *par)
|
||||
return false;
|
||||
|
||||
q->name[sizeof(q->name)-1] = '\0';
|
||||
if (*q->name == '\0' || *q->name == '.' ||
|
||||
strchr(q->name, '/') != NULL) {
|
||||
printk(KERN_ERR "xt_quota.2: illegal name\n");
|
||||
if (*q->name == '.' || strchr(q->name, '/') != NULL) {
|
||||
printk(KERN_ERR "xt_quota<%u>: illegal name\n",
|
||||
par->match->revision);
|
||||
return false;
|
||||
}
|
||||
|
||||
q->master = q2_get_counter(q);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
spin_unlock_bh(&counter_list_lock);
|
||||
remove_proc_entry(e->name, proc_xt_quota);
|
||||
spin_unlock_bh(&counter_list_lock);
|
||||
kfree(e);
|
||||
}
|
||||
|
||||
@@ -164,17 +194,15 @@ static bool
|
||||
quota_mt2(const struct sk_buff *skb, const struct xt_match_param *par)
|
||||
{
|
||||
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;
|
||||
|
||||
spin_lock_bh(&e->lock);
|
||||
if (q->flags & XT_QUOTA_GROW) {
|
||||
spin_lock_bh(&e->lock);
|
||||
e->quota += (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;
|
||||
q->quota = e->quota;
|
||||
spin_unlock_bh(&e->lock);
|
||||
ret = true;
|
||||
} else {
|
||||
spin_lock_bh(&e->lock);
|
||||
if (e->quota >= skb->len) {
|
||||
e->quota -= (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;
|
||||
ret = !ret;
|
||||
@@ -183,16 +211,15 @@ quota_mt2(const struct sk_buff *skb, const struct xt_match_param *par)
|
||||
e->quota = 0;
|
||||
}
|
||||
q->quota = e->quota;
|
||||
spin_unlock_bh(&e->lock);
|
||||
}
|
||||
|
||||
spin_unlock_bh(&e->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct xt_match quota_mt2_reg[] __read_mostly = {
|
||||
{
|
||||
.name = "quota2",
|
||||
.revision = 2,
|
||||
.revision = 3,
|
||||
.family = NFPROTO_IPV4,
|
||||
.checkentry = quota_mt2_check,
|
||||
.match = quota_mt2,
|
||||
@@ -202,7 +229,7 @@ static struct xt_match quota_mt2_reg[] __read_mostly = {
|
||||
},
|
||||
{
|
||||
.name = "quota2",
|
||||
.revision = 2,
|
||||
.revision = 3,
|
||||
.family = NFPROTO_IPV6,
|
||||
.checkentry = quota_mt2_check,
|
||||
.match = quota_mt2,
|
||||
|
@@ -6,21 +6,19 @@ enum xt_quota_flags {
|
||||
XT_QUOTA_GROW = 1 << 1,
|
||||
XT_QUOTA_PACKET = 1 << 2,
|
||||
XT_QUOTA_MASK = 0x7,
|
||||
|
||||
XT_QUOTA_COUNTER_NAME_LENGTH = 31,
|
||||
};
|
||||
|
||||
struct quota_counter;
|
||||
struct xt_quota_counter;
|
||||
|
||||
struct xt_quota_mtinfo2 {
|
||||
char name[XT_QUOTA_COUNTER_NAME_LENGTH];
|
||||
char name[15];
|
||||
u_int8_t flags;
|
||||
|
||||
/* Comparison-invariant */
|
||||
aligned_u64 quota;
|
||||
|
||||
/* Used internally by the kernel */
|
||||
struct quota_counter *master __attribute__((aligned(8)));
|
||||
struct xt_quota_counter *master __attribute__((aligned(8)));
|
||||
};
|
||||
|
||||
#endif /* _XT_QUOTA_H */
|
||||
|
4
mconfig
4
mconfig
@@ -1,11 +1,13 @@
|
||||
# -*- Makefile -*-
|
||||
#
|
||||
build_ACCOUNT=m
|
||||
build_CHAOS=m
|
||||
build_DELUDE=m
|
||||
build_DHCPMAC=m
|
||||
build_ECHO=
|
||||
build_IPMARK=m
|
||||
build_LOGMARK=m
|
||||
build_RAWNAT=m
|
||||
build_STEAL=m
|
||||
build_SYSRQ=m
|
||||
build_TARPIT=m
|
||||
@@ -13,9 +15,11 @@ build_TEE=m
|
||||
build_condition=m
|
||||
build_fuzzy=m
|
||||
build_geoip=m
|
||||
build_iface=m
|
||||
build_ipp2p=m
|
||||
build_ipset=m
|
||||
build_ipv4options=m
|
||||
build_length2=m
|
||||
build_lscan=m
|
||||
build_psd=m
|
||||
build_quota2=m
|
||||
|
@@ -1,6 +1,6 @@
|
||||
.TH xtables\-addons 8 "v1.14 (2009\-03\-31)" "" "v1.14 (2009\-03\-31)"
|
||||
.TH xtables-addons 8 "v1.18 (2009-09-09)" "" "v1.18 (2009-09-09)"
|
||||
.SH Name
|
||||
Xtables\-addons - additional extensions for iptables, ip6tables, etc.
|
||||
Xtables-addons \(em additional extensions for iptables, ip6tables, etc.
|
||||
.SH Targets
|
||||
.\" @TARGET@
|
||||
.SH Matches
|
||||
|
Reference in New Issue
Block a user