mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-21 03:54:59 +02:00
Compare commits
247 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
bc5a7d8e3a | ||
![]() |
0628857068 | ||
![]() |
de4f6e8994 | ||
![]() |
439dd913f1 | ||
![]() |
9568747d94 | ||
![]() |
20365cf762 | ||
![]() |
fa601c0fa7 | ||
![]() |
00573d0172 | ||
![]() |
c7036a88f1 | ||
![]() |
af21c1d369 | ||
![]() |
b132101b63 | ||
![]() |
71beab548d | ||
![]() |
6de54e5fcd | ||
![]() |
a921427746 | ||
![]() |
2b2b6246f0 | ||
![]() |
98e5dfd6ef | ||
![]() |
9e5c2e7ee9 | ||
![]() |
284c0e9493 | ||
![]() |
5284b5db92 | ||
![]() |
36035d52d3 | ||
![]() |
4d94687c15 | ||
![]() |
7070678ab4 | ||
![]() |
f6281d498c | ||
![]() |
2cab32596a | ||
![]() |
08f6a82bdc | ||
![]() |
82a8524f1a | ||
![]() |
6bb354d3f0 | ||
![]() |
5184176c3b | ||
![]() |
430723ece1 | ||
![]() |
f1dc7f960c | ||
![]() |
370f47b000 | ||
![]() |
8e812620f0 | ||
![]() |
204b612e23 | ||
![]() |
c2c86f4b3d | ||
![]() |
379e685b0f | ||
![]() |
69dd0686e2 | ||
![]() |
48325a209e | ||
![]() |
96f501ab89 | ||
![]() |
3c1bf73e8e | ||
![]() |
e0276b4875 | ||
![]() |
1bc7f1be67 | ||
![]() |
3c3adcbd07 | ||
![]() |
da6a9b932c | ||
![]() |
5f290cd4a0 | ||
![]() |
181a9cab43 | ||
![]() |
a819458cba | ||
![]() |
654862af21 | ||
![]() |
0d8ae29a60 | ||
![]() |
e05a4d9586 | ||
![]() |
0541154a5e | ||
![]() |
00199427ac | ||
![]() |
35b00f8c3f | ||
![]() |
1f3150bdf9 | ||
![]() |
13c73af796 | ||
![]() |
ba9a3efec1 | ||
![]() |
f474c7d4d4 | ||
![]() |
4a350ddd03 | ||
![]() |
628d137f12 | ||
![]() |
28ecf45548 | ||
![]() |
58839b9b86 | ||
![]() |
e436948ebd | ||
![]() |
79d54ebd7c | ||
![]() |
0b64b27172 | ||
![]() |
d116000784 | ||
![]() |
4b5f0b12d9 | ||
![]() |
c8dde526f2 | ||
![]() |
3058e42a21 | ||
![]() |
40b30f7f27 | ||
![]() |
aaad5f53ac | ||
![]() |
db1057158f | ||
![]() |
713c31e8f7 | ||
![]() |
e5ffb39750 | ||
![]() |
19067393b6 | ||
![]() |
1de82a88a1 | ||
![]() |
9928c864ab | ||
![]() |
45515a0afd | ||
![]() |
75f80fa8f8 | ||
![]() |
d8dc72d151 | ||
![]() |
cee3d25d49 | ||
![]() |
afbeb2fb47 | ||
![]() |
c0dc0858de | ||
![]() |
b04317576b | ||
![]() |
af2bbf0352 | ||
![]() |
db9bb2778d | ||
![]() |
674560d2d9 | ||
![]() |
7ab033e64c | ||
![]() |
3131448443 | ||
![]() |
71322e614c | ||
![]() |
d3fdfe08dd | ||
![]() |
46f9ddbf59 | ||
![]() |
e37985b527 | ||
![]() |
0ccd55abd9 | ||
![]() |
60123a8c07 | ||
![]() |
504f1089fb | ||
![]() |
e119350000 | ||
![]() |
a260e3349f | ||
![]() |
5cb36ed213 | ||
![]() |
1a5b9f0e02 | ||
![]() |
2c53605084 | ||
![]() |
537f25dbad | ||
![]() |
63a1e5329f | ||
![]() |
b0a6111054 | ||
![]() |
b07434386b | ||
![]() |
0c963dee06 | ||
![]() |
09bfb8496e | ||
![]() |
9d1afc4268 | ||
![]() |
342ccf62b2 | ||
![]() |
adabd647b1 | ||
![]() |
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 | ||
![]() |
7dd96ec357 | ||
![]() |
ba6aa51f91 | ||
![]() |
beb7546e20 | ||
![]() |
67579079e0 | ||
![]() |
3a632a9bc5 | ||
![]() |
45b2e64d82 | ||
![]() |
538d74b5d8 | ||
![]() |
e3988b50b5 | ||
![]() |
f4b8440fba | ||
![]() |
d3ee3a0c3c | ||
![]() |
f96bc08f35 | ||
![]() |
a0c791dc88 | ||
![]() |
f717a91bc5 | ||
![]() |
8bd5fc14ba | ||
![]() |
a51b16097b | ||
![]() |
0bb538ba69 | ||
![]() |
e11a07b230 | ||
![]() |
d263cfbd50 | ||
![]() |
36f80be2f7 | ||
![]() |
7b9ca945d4 | ||
![]() |
ffeb1da7d7 | ||
![]() |
d2d8712980 | ||
![]() |
621cef39f5 | ||
![]() |
08e6f23655 | ||
![]() |
4a25321191 | ||
![]() |
8c322a0119 | ||
![]() |
bd39e4671e | ||
![]() |
3d6bb5f86f | ||
![]() |
ce03d0ee8e | ||
![]() |
bca90ca2a7 | ||
![]() |
08cb9e5584 | ||
![]() |
1a8cc305af | ||
![]() |
47a34e0ccf | ||
![]() |
36dab67658 | ||
![]() |
7bb2957e47 | ||
![]() |
c168a2f142 | ||
![]() |
68af6989b1 | ||
![]() |
446c67018a | ||
![]() |
0fe8e180c4 | ||
![]() |
7cdfc0ac3d |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -6,10 +6,15 @@
|
|||||||
.libs
|
.libs
|
||||||
Makefile
|
Makefile
|
||||||
Makefile.in
|
Makefile.in
|
||||||
GNUmakefile
|
|
||||||
|
|
||||||
/downloads
|
/downloads
|
||||||
|
|
||||||
|
/Makefile.iptrules
|
||||||
|
/Makefile.mans
|
||||||
|
/.*.lst
|
||||||
|
/matches.man
|
||||||
|
/targets.man
|
||||||
|
|
||||||
/aclocal.m4
|
/aclocal.m4
|
||||||
/autom4te*.cache
|
/autom4te*.cache
|
||||||
/compile
|
/compile
|
||||||
|
38
INSTALL
38
INSTALL
@@ -9,15 +9,24 @@ in combination with the kernel's Kbuild system.
|
|||||||
# make install
|
# make install
|
||||||
|
|
||||||
|
|
||||||
Prerequirements
|
Supported configurations for this release
|
||||||
===============
|
=========================================
|
||||||
|
|
||||||
* iptables 1.4.1
|
* iptables >= 1.4.3
|
||||||
|
|
||||||
* kernel-source >= 2.6.17 with prepared build/output directory
|
* kernel-source >= 2.6.17, no upper bound known
|
||||||
|
with prepared build/output directory
|
||||||
- CONFIG_NF_CONNTRACK or CONFIG_IP_NF_CONNTRACK
|
- CONFIG_NF_CONNTRACK or CONFIG_IP_NF_CONNTRACK
|
||||||
- CONFIG_NF_CONNTRACK_MARK or CONFIG_IP_NF_CONNTRACK_MARK
|
- CONFIG_NF_CONNTRACK_MARK or CONFIG_IP_NF_CONNTRACK_MARK
|
||||||
enabled =y or as module (=m)
|
enabled =y or as module (=m)
|
||||||
|
- CONFIG_CONNECTOR y/m if you wish to receive userspace
|
||||||
|
notifications from pknock through netlink/connector
|
||||||
|
|
||||||
|
Extra notes:
|
||||||
|
|
||||||
|
* in the kernel 2.6.18.x series, >= 2.6.18.5 is required
|
||||||
|
|
||||||
|
* requires that no vendor backports interfere
|
||||||
|
|
||||||
|
|
||||||
Selecting extensions
|
Selecting extensions
|
||||||
@@ -39,23 +48,23 @@ Configuring and compiling
|
|||||||
/lib/modules/$(running version)/build, which usually points to
|
/lib/modules/$(running version)/build, which usually points to
|
||||||
the right directory. (If not, you need to install something.)
|
the right directory. (If not, you need to install something.)
|
||||||
|
|
||||||
|
For RPM building, it should be /usr/src/linux-obj/...
|
||||||
|
or whatever location the distro makes use of.
|
||||||
|
|
||||||
--with-xtables=
|
--with-xtables=
|
||||||
|
|
||||||
Specifies the path to the directory where we may find
|
Specifies the path to the directory where we may find
|
||||||
xtables.h, should it not be within the standard C compiler
|
xtables.h, should it not be within the standard C compiler
|
||||||
include path (/usr/include), or if you want to override it.
|
include path (/usr/include), or if you want to override it.
|
||||||
The directory will be checked for xtables.h and
|
The directory will be checked for xtables.h and
|
||||||
include/xtables.h. (This is to support the following specs:)
|
include/xtables.h. (The latter to support both standard
|
||||||
|
/usr/include and the iptables source root.)
|
||||||
|
|
||||||
--with-xtables=/usr/src/xtables
|
--with-xtlibdir=
|
||||||
--with-xtables=/usr/src/xtables/include
|
|
||||||
--with-xtables=/opt/xtables/include
|
|
||||||
|
|
||||||
--with-libxtdir=
|
|
||||||
|
|
||||||
Specifies the path to where the newly built extensions should
|
Specifies the path to where the newly built extensions should
|
||||||
be installed when `make install` is run. It uses the same
|
be installed when `make install` is run. It uses the same
|
||||||
default as the Xtables package, ${libexecdir}/xtables.
|
default as the Xtables/iptables package, ${libexecdir}/xtables.
|
||||||
|
|
||||||
If you want to enable debugging, use
|
If you want to enable debugging, use
|
||||||
|
|
||||||
@@ -68,15 +77,10 @@ much easier.)
|
|||||||
Build-time options
|
Build-time options
|
||||||
==================
|
==================
|
||||||
|
|
||||||
V= controls the kernel's make verbosity.
|
V= controls the verbosity of make commands.
|
||||||
V=0 "silent" (output filename)
|
V=0 "silent" (output filename)
|
||||||
V=1 "verbose" (entire gcc command line)
|
V=1 "verbose" (entire gcc command line)
|
||||||
|
|
||||||
VU= controls the Xt-a make verbosity.
|
|
||||||
VU=0 output filename
|
|
||||||
VU=1 output filename and source file
|
|
||||||
VU=2 entire gcc command line
|
|
||||||
|
|
||||||
|
|
||||||
Note to distribution packagers
|
Note to distribution packagers
|
||||||
==============================
|
==============================
|
||||||
|
13
Makefile.am
13
Makefile.am
@@ -1,20 +1,21 @@
|
|||||||
# -*- Makefile -*-
|
# -*- Makefile -*-
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
AUTOMAKE_OPTIONS = foreign subdir-objects
|
|
||||||
SUBDIRS = extensions
|
SUBDIRS = extensions
|
||||||
|
|
||||||
man_MANS := xtables-addons.8
|
man_MANS := xtables-addons.8
|
||||||
|
|
||||||
xtables-addons.8: ${srcdir}/xtables-addons.8.in extensions/matches.man extensions/targets.man
|
.PHONY: FORCE
|
||||||
${am__verbose_GEN}sed -e '/@MATCHES@/ r extensions/matches.man' -e '/@TARGET@/ r extensions/targets.man' $< >$@;
|
FORCE:
|
||||||
|
|
||||||
extensions/%:
|
xtables-addons.8: FORCE
|
||||||
${MAKE} ${AM_MAKEFLAGS} -C $(@D) $(@F)
|
${MAKE} -f Makefile.mans all;
|
||||||
|
|
||||||
install-exec-local:
|
install-exec-hook:
|
||||||
depmod -a || :;
|
depmod -a || :;
|
||||||
|
|
||||||
|
config.status: Makefile.iptrules.in
|
||||||
|
|
||||||
.PHONY: tarball
|
.PHONY: tarball
|
||||||
tarball:
|
tarball:
|
||||||
rm -Rf /tmp/xtables-addons-${PACKAGE_VERSION};
|
rm -Rf /tmp/xtables-addons-${PACKAGE_VERSION};
|
||||||
|
29
Makefile.extra
Normal file
29
Makefile.extra
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
# AUTOMAKE
|
||||||
|
|
||||||
|
XA_SRCDIR = ${srcdir}
|
||||||
|
XA_TOPSRCDIR = ${top_srcdir}
|
||||||
|
XA_ABSTOPSRCDIR = ${abs_top_srcdir}
|
||||||
|
export XA_SRCDIR
|
||||||
|
export XA_TOPSRCDIR
|
||||||
|
export XA_ABSTOPSRCDIR
|
||||||
|
|
||||||
|
_mcall = -f ${top_builddir}/Makefile.iptrules
|
||||||
|
|
||||||
|
all-local: user-all-local
|
||||||
|
|
||||||
|
install-exec-local: user-install-local
|
||||||
|
|
||||||
|
clean-local: user-clean-local
|
||||||
|
|
||||||
|
user-all-local:
|
||||||
|
${MAKE} ${_mcall} all;
|
||||||
|
|
||||||
|
# Have no user-install-data-local ATM
|
||||||
|
user-install-local: user-install-exec-local
|
||||||
|
|
||||||
|
user-install-exec-local:
|
||||||
|
${MAKE} ${_mcall} install;
|
||||||
|
|
||||||
|
user-clean-local:
|
||||||
|
${MAKE} ${_mcall} clean;
|
59
Makefile.iptrules.in
Normal file
59
Makefile.iptrules.in
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
# MANUAL
|
||||||
|
|
||||||
|
prefix = @prefix@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
libexecdir = @libexecdir@
|
||||||
|
xtlibdir = @xtlibdir@
|
||||||
|
|
||||||
|
CC = @CC@
|
||||||
|
CCLD = ${CC}
|
||||||
|
|
||||||
|
regular_CFLAGS = @regular_CFLAGS@
|
||||||
|
xtables_CFLAGS = @xtables_CFLAGS@
|
||||||
|
AM_CFLAGS = ${regular_CFLAGS} ${xtables_CFLAGS}
|
||||||
|
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
|
||||||
|
|
||||||
|
AM_DEFAULT_VERBOSITY = 0
|
||||||
|
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_${AM_DEFAULT_VERBOSITY}}
|
||||||
|
am__v_CCLD_ = ${am__v_CCLD_${AM_DEFAULT_VERBOSITY}}
|
||||||
|
am__v_GEN_ = ${am__v_GEN_${AM_DEFAULT_VERBOSITY}}
|
||||||
|
am__v_SILENT_ = ${am__v_SILENT_${AM_DEFAULT_VERBOSITY}}
|
||||||
|
AM_V_CC = ${am__v_CC_${V}}
|
||||||
|
AM_V_CCLD = ${am__v_CCLD_${V}}
|
||||||
|
AM_V_GEN = ${am__v_GEN_${V}}
|
||||||
|
AM_V_silent = ${am__v_GEN_${V}}
|
||||||
|
|
||||||
|
include ${XA_TOPSRCDIR}/mconfig
|
||||||
|
-include ${XA_TOPSRCDIR}/mconfig.*
|
||||||
|
include ${XA_SRCDIR}/Mbuild
|
||||||
|
-include ${XA_SRCDIR}/Mbuild.*
|
||||||
|
|
||||||
|
targets := $(filter-out %/,${obj-m})
|
||||||
|
subdirs_list := $(filter %/,${obj-m})
|
||||||
|
|
||||||
|
.SECONDARY:
|
||||||
|
|
||||||
|
.PHONY: all install clean
|
||||||
|
|
||||||
|
all: ${targets}
|
||||||
|
@for i in ${subdirs_list}; do ${MAKE} -C $$i; done;
|
||||||
|
|
||||||
|
install: ${targets}
|
||||||
|
@for i in ${subdirs_list}; do ${MAKE} -C $$i $@; done;
|
||||||
|
install -dm0755 "${DESTDIR}/${xtlibdir}";
|
||||||
|
install -pm0755 $^ "${DESTDIR}/${xtlibdir}";
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@for i in ${subdirs_list}; do ${MAKE} -C $$i $@; done;
|
||||||
|
rm -f *.oo *.so;
|
||||||
|
|
||||||
|
lib%.so: lib%.oo
|
||||||
|
${AM_V_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
|
||||||
|
|
||||||
|
%.oo: ${XA_SRCDIR}/%.c
|
||||||
|
${AM_V_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
|
40
Makefile.mans.in
Normal file
40
Makefile.mans.in
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
# MANUAL
|
||||||
|
|
||||||
|
srcdir := @srcdir@
|
||||||
|
|
||||||
|
wcman_matches := $(shell find "${srcdir}" -name 'libxt_[a-z]*.man')
|
||||||
|
wcman_targets := $(shell find "${srcdir}" -name 'libxt_[A-Z]*.man')
|
||||||
|
wlist_matches := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_matches})
|
||||||
|
wlist_targets := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_targets})
|
||||||
|
|
||||||
|
.PHONY: FORCE
|
||||||
|
|
||||||
|
FORCE:
|
||||||
|
|
||||||
|
.manpages.lst: FORCE
|
||||||
|
@echo "${wlist_targets} ${wlist_matches}" >$@.tmp; \
|
||||||
|
cmp -s $@ $@.tmp || mv $@.tmp $@; \
|
||||||
|
rm -f $@.tmp;
|
||||||
|
|
||||||
|
man_run = \
|
||||||
|
${AM_V_GEN}for ext in $(1); do \
|
||||||
|
name="$${ext%.man}"; \
|
||||||
|
name="$${name\#\#*/libxt_}"; \
|
||||||
|
if [ -f "$$ext" ]; then \
|
||||||
|
echo ".SS $$name"; \
|
||||||
|
cat "$$ext"; \
|
||||||
|
continue; \
|
||||||
|
fi; \
|
||||||
|
done >$@;
|
||||||
|
|
||||||
|
all: xtables-addons.8
|
||||||
|
|
||||||
|
xtables-addons.8: ${srcdir}/xtables-addons.8.in matches.man targets.man
|
||||||
|
${AM_V_GEN}sed -e '/@MATCHES@/ r matches.man' -e '/@TARGET@/ r targets.man' $< >$@;
|
||||||
|
|
||||||
|
matches.man: .manpages.lst ${wcman_matches}
|
||||||
|
$(call man_run,${wlist_matches})
|
||||||
|
|
||||||
|
targets.man: .manpages.lst ${wcman_targets}
|
||||||
|
$(call man_run,${wlist_targets})
|
56
configure.ac
56
configure.ac
@@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
AC_INIT([xtables-addons], [1.8])
|
AC_INIT([xtables-addons], [1.19])
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
AM_INIT_AUTOMAKE([-Wall])
|
AM_INIT_AUTOMAKE([1.10 -Wall foreign subdir-objects])
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
AM_PROG_CC_C_O
|
AM_PROG_CC_C_O
|
||||||
AC_DISABLE_STATIC
|
AC_DISABLE_STATIC
|
||||||
@@ -14,10 +14,7 @@ AC_ARG_WITH([kbuild],
|
|||||||
AS_HELP_STRING([--with-kbuild=PATH],
|
AS_HELP_STRING([--with-kbuild=PATH],
|
||||||
[Path to kernel build directory [[/lib/modules/CURRENT/build]]]),
|
[Path to kernel build directory [[/lib/modules/CURRENT/build]]]),
|
||||||
[kbuilddir="$withval"])
|
[kbuilddir="$withval"])
|
||||||
AC_ARG_WITH([ksource],
|
AC_ARG_WITH([ksource],,[ksourcedir="$withval"])
|
||||||
AS_HELP_STRING([--with-ksource=PATH],
|
|
||||||
[Path to kernel source directory [[/lib/modules/CURRENT/source]]]),
|
|
||||||
[ksourcedir="$withval"])
|
|
||||||
AC_ARG_WITH([xtables],
|
AC_ARG_WITH([xtables],
|
||||||
AS_HELP_STRING([--with-xtables=PATH],
|
AS_HELP_STRING([--with-xtables=PATH],
|
||||||
[Path to the Xtables includes [[none]]]),
|
[Path to the Xtables includes [[none]]]),
|
||||||
@@ -28,8 +25,11 @@ AC_ARG_WITH([xtlibdir],
|
|||||||
[xtlibdir="$withval"],
|
[xtlibdir="$withval"],
|
||||||
[xtlibdir='${libexecdir}/xtables'])
|
[xtlibdir='${libexecdir}/xtables'])
|
||||||
|
|
||||||
AC_MSG_CHECKING([xtables.h presence])
|
#
|
||||||
|
# --with-xtables= overrides a possibly installed pkgconfig file.
|
||||||
|
#
|
||||||
if [[ -n "$xtables_location" ]]; then
|
if [[ -n "$xtables_location" ]]; then
|
||||||
|
AC_MSG_CHECKING([xtables.h presence])
|
||||||
if [[ -f "$xtables_location/xtables.h" ]]; then
|
if [[ -f "$xtables_location/xtables.h" ]]; then
|
||||||
AC_MSG_RESULT([$xtables_location/xtables.h])
|
AC_MSG_RESULT([$xtables_location/xtables.h])
|
||||||
xtables_CFLAGS="-I $xtables_location";
|
xtables_CFLAGS="-I $xtables_location";
|
||||||
@@ -37,7 +37,6 @@ if [[ -n "$xtables_location" ]]; then
|
|||||||
AC_MSG_RESULT([$xtables_location/include/xtables.h])
|
AC_MSG_RESULT([$xtables_location/include/xtables.h])
|
||||||
xtables_CFLAGS="-I $xtables_location/include";
|
xtables_CFLAGS="-I $xtables_location/include";
|
||||||
fi;
|
fi;
|
||||||
fi;
|
|
||||||
if [[ -z "$xtables_CFLAGS" ]]; then
|
if [[ -z "$xtables_CFLAGS" ]]; then
|
||||||
if [[ -f "$includedir/xtables.h" ]]; then
|
if [[ -f "$includedir/xtables.h" ]]; then
|
||||||
AC_MSG_RESULT([$includedir/xtables.h])
|
AC_MSG_RESULT([$includedir/xtables.h])
|
||||||
@@ -45,6 +44,9 @@ if [[ -z "$xtables_CFLAGS" ]]; then
|
|||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
fi;
|
fi;
|
||||||
fi;
|
fi;
|
||||||
|
else
|
||||||
|
PKG_CHECK_MODULES([libxtables], [xtables >= 1.4.3])
|
||||||
|
fi;
|
||||||
|
|
||||||
regular_CFLAGS="-D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 \
|
regular_CFLAGS="-D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 \
|
||||||
-D_REENTRANT -Wall -Waggregate-return -Wmissing-declarations \
|
-D_REENTRANT -Wall -Waggregate-return -Wmissing-declarations \
|
||||||
@@ -58,11 +60,47 @@ if [[ -n "$ksourcedir" ]]; then
|
|||||||
kinclude_CFLAGS="$kinclude_CFLAGS -I $ksourcedir/include";
|
kinclude_CFLAGS="$kinclude_CFLAGS -I $ksourcedir/include";
|
||||||
fi;
|
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%%.*}";
|
||||||
|
if test "$kmicro" = "$krel"; 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 32; 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([regular_CFLAGS])
|
||||||
AC_SUBST([xtables_CFLAGS])
|
AC_SUBST([xtables_CFLAGS])
|
||||||
AC_SUBST([kinclude_CFLAGS])
|
AC_SUBST([kinclude_CFLAGS])
|
||||||
AC_SUBST([kbuilddir])
|
AC_SUBST([kbuilddir])
|
||||||
AC_SUBST([ksourcedir])
|
AC_SUBST([ksourcedir])
|
||||||
AC_SUBST([xtlibdir])
|
AC_SUBST([xtlibdir])
|
||||||
AC_CONFIG_FILES([Makefile extensions/GNUmakefile extensions/ipset/GNUmakefile])
|
AC_CONFIG_FILES([Makefile Makefile.iptrules Makefile.mans
|
||||||
|
extensions/Makefile extensions/ACCOUNT/Makefile
|
||||||
|
extensions/ipset/Makefile extensions/pknock/Makefile])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
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: "
|
206
doc/changelog.txt
Normal file
206
doc/changelog.txt
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
|
||||||
|
HEAD
|
||||||
|
====
|
||||||
|
|
||||||
|
|
||||||
|
Xtables-addons 1.19 (October 12 2009)
|
||||||
|
=====================================
|
||||||
|
- build: compile fixes for 2.6.31-rt
|
||||||
|
- build: support for Linux 2.6.32
|
||||||
|
- ipp2p: try to address underflows
|
||||||
|
- psd: avoid potential crash when dealing with non-linear skbs
|
||||||
|
- merge xt_ACCOUNT userspace utilities
|
||||||
|
- added reworked xt_pknock module
|
||||||
|
Changes from pknock v0.5:
|
||||||
|
- pknock: "strict" and "checkip" flags were not displayed in `iptables -L`
|
||||||
|
- pknock: the GC expire time's lower bound is now the default gc time
|
||||||
|
(65000 msec) to avoid rendering anti-spoof protection in SPA mode useless
|
||||||
|
- pknock: avoid crash on memory allocation failure and fix memleak
|
||||||
|
- pknock: avoid fillup of peer table during DDoS
|
||||||
|
- pknock: automatic closing of ports
|
||||||
|
- pknock: make non-zero time mandatory for TCP mode
|
||||||
|
- pknock: display only pknock mode and state relevant information in procfs
|
||||||
|
- pknock: check interknock time only for !ST_ALLOWED peers
|
||||||
|
- pknock: preserve time/autoclose values for rules added in
|
||||||
|
reverse/arbitrary order
|
||||||
|
- pknock: add a manpage
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
- geoip: remove XT_ALIGN from .userspacesize when used with offsetof
|
||||||
|
- SYSRQ: ignore non-UDP packets
|
||||||
|
- SYSRQ: do proper L4 header access in IPv6 code
|
||||||
|
(must not use tcp/udp_hdr in input path)
|
||||||
|
- add "STEAL" target
|
||||||
|
- dhcpmac: rename from dhcpaddr
|
||||||
|
|
||||||
|
|
||||||
|
Xtables-addons 1.13 (March 23 2009)
|
||||||
|
===================================
|
||||||
|
- added a reworked ipv4options match
|
||||||
|
- upgrade to iptables 1.4.3 API
|
||||||
|
|
||||||
|
|
||||||
|
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 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
|
||||||
|
- xt_TEE: enable routing by iif, nfmark and flowlabel
|
||||||
|
|
||||||
|
|
||||||
|
Xtables-addons 1.10 (February 18 2009)
|
||||||
|
======================================
|
||||||
|
- compat: compile fixes for 2.6.29
|
||||||
|
- ipset: upgrade to ipset 2.4.9
|
||||||
|
|
||||||
|
|
||||||
|
Xtables-addons 1.9 (January 30 2009)
|
||||||
|
====================================
|
||||||
|
- add the xt_length2 extension
|
||||||
|
- xt_TEE: remove intrapositional '!' support
|
||||||
|
- ipset: upgrade to ipset 2.4.7
|
||||||
|
|
||||||
|
|
||||||
|
Xtables-addons 1.8 (January 10 2009)
|
||||||
|
====================================
|
||||||
|
- xt_TEE: IPv6 support
|
||||||
|
- xt_TEE: do not include TOS value in routing decision
|
||||||
|
- xt_TEE: fix switch-case inversion for name/IP display
|
||||||
|
- xt_ipp2p: update manpages and help text
|
||||||
|
- xt_ipp2p: remove log flooding
|
||||||
|
- xt_portscan: update manpage about --grscan option caveats
|
||||||
|
|
||||||
|
|
||||||
|
Xtables-addons 1.7 (December 25 2008)
|
||||||
|
=====================================
|
||||||
|
- xt_ECHO: compile fix
|
||||||
|
- avoid the use of "_init" which led to compile errors on some installations
|
||||||
|
- build: do not unconditionally install ipset
|
||||||
|
- doc: add manpages for xt_ECHO and xt_TEE
|
||||||
|
- xt_ipp2p: kazaa detection code cleanup
|
||||||
|
- xt_ipp2p: fix newline inspection in kazaa detection
|
||||||
|
- xt_ipp2p: ensure better array bounds checking
|
||||||
|
- xt_SYSRQ: improve security by hashing password
|
||||||
|
|
||||||
|
|
||||||
|
Xtables-addons 1.6 (November 18 2008)
|
||||||
|
=====================================
|
||||||
|
- build: support for Linux 2.6.17
|
||||||
|
- build: compile fixes for 2.6.18 and 2.6.19
|
||||||
|
- xt_ECHO: resolve compile errors in xt_ECHO
|
||||||
|
- xt_ipp2p: parenthesize unaligned-access macros
|
||||||
|
|
||||||
|
|
||||||
|
Xtables-addons 1.5.7 (September 01 2008)
|
||||||
|
========================================
|
||||||
|
- API layer: fix use of uninitialized 'hotdrop' variable
|
||||||
|
- API layer: move to pskb-based signatures
|
||||||
|
- xt_SYSRQ: compile fixes for Linux <= 2.6.19
|
||||||
|
- ipset: adjust semaphore.h include for Linux >= 2.6.27
|
||||||
|
- build: automatically run `depmod -a` on installation
|
||||||
|
- add reworked xt_fuzzy module
|
||||||
|
- add DHCP address match and mangle module
|
||||||
|
- xt_portscan: IPv6 support
|
||||||
|
- xt_SYSRQ: add missing module aliases
|
||||||
|
|
||||||
|
|
||||||
|
Xtables-addons 1.5.5 (August 03 2008)
|
||||||
|
=====================================
|
||||||
|
- manpage updates for xt_CHAOS, xt_IPMARK; README updates
|
||||||
|
- build: properly recognize external Kbuild/Mbuild files
|
||||||
|
- build: remove dependency on CONFIG_NETWORK_SECMARK
|
||||||
|
- add the xt_SYSRQ target
|
||||||
|
- add the xt_quota2 extension
|
||||||
|
- import ipset extension group
|
||||||
|
|
||||||
|
|
||||||
|
Xtables-addons 1.5.4.1 (April 26 2008)
|
||||||
|
======================================
|
||||||
|
- build: fix compile error for 2.6.18-stable
|
||||||
|
|
||||||
|
|
||||||
|
Xtables-addons 1.5.4 (April 09 2008)
|
||||||
|
====================================
|
||||||
|
- build: support building multiple files with one config option
|
||||||
|
- API layer: add check for pskb relocation
|
||||||
|
- doc: generate manpages
|
||||||
|
- xt_ECHO: catch skb_linearize out-of-memory condition
|
||||||
|
- xt_LOGMARK: add hook= and ctdir= fields in dump
|
||||||
|
- xt_LOGMARK: fix comma output in ctstatus= list
|
||||||
|
- xt_TEE: fix address copying bug
|
||||||
|
- xt_TEE: make skb writable before attempting checksum update
|
||||||
|
- add reworked xt_condition match
|
||||||
|
- add reworked xt_ipp2p match
|
||||||
|
- add reworked xt_IPMARK target
|
||||||
|
|
||||||
|
|
||||||
|
Xtables-addons 1.5.3 (March 22 2008)
|
||||||
|
====================================
|
||||||
|
- support for Linux 2.6.18
|
||||||
|
- add xt_ECHO sample target
|
||||||
|
- add reworked xt_geoip match
|
||||||
|
|
||||||
|
|
||||||
|
Xtables-addons 1.5.2 (March 04 2008)
|
||||||
|
====================================
|
||||||
|
- build: support for GNU make < 3.81 which does not have $(realpath)
|
||||||
|
|
||||||
|
|
||||||
|
Xtables-addons 1.5.1 (February 21 2008)
|
||||||
|
=======================================
|
||||||
|
- build: allow user to select what extensions to compile and install
|
||||||
|
- build: allow external proejcts to be downloaded into the tree
|
||||||
|
- xt_LOGMARK: dump classify mark, ctstate and ctstatus
|
||||||
|
- add xt_CHAOS, xt_DELUDE and xt_portscan from Chaostables
|
||||||
|
|
||||||
|
|
||||||
|
Xtables-addons 1.5.0 (February 11 2008)
|
||||||
|
=======================================
|
||||||
|
Initial release with:
|
||||||
|
- extensions: xt_LOGMARK, xt_TARPIT, xt_TEE
|
||||||
|
- support for Linux >= 2.6.19
|
8
extensions/.gitignore
vendored
8
extensions/.gitignore
vendored
@@ -3,12 +3,10 @@
|
|||||||
.tmp_versions
|
.tmp_versions
|
||||||
*.ko
|
*.ko
|
||||||
*.mod.c
|
*.mod.c
|
||||||
|
Module.markers
|
||||||
Module.symvers
|
Module.symvers
|
||||||
Modules.symvers
|
Modules.symvers
|
||||||
modules.order
|
modules.order
|
||||||
|
|
||||||
/*.so
|
*.so
|
||||||
/*.oo
|
*.oo
|
||||||
/matches.man
|
|
||||||
/targets.man
|
|
||||||
/.manpages.lst
|
|
||||||
|
1
extensions/ACCOUNT/.gitignore
vendored
Normal file
1
extensions/ACCOUNT/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/iptaccount
|
5
extensions/ACCOUNT/Kbuild
Normal file
5
extensions/ACCOUNT/Kbuild
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
|
||||||
|
EXTRA_CFLAGS = -I${src}/..
|
||||||
|
|
||||||
|
obj-m += xt_ACCOUNT.o
|
8
extensions/ACCOUNT/Makefile.am
Normal file
8
extensions/ACCOUNT/Makefile.am
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
|
||||||
|
include ../../Makefile.extra
|
||||||
|
|
||||||
|
sbin_PROGRAMS = iptaccount
|
||||||
|
iptaccount_LDADD = libxt_ACCOUNT_cl.la
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libxt_ACCOUNT_cl.la
|
3
extensions/ACCOUNT/Mbuild
Normal file
3
extensions/ACCOUNT/Mbuild
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
|
||||||
|
obj-${build_ACCOUNT} += libxt_ACCOUNT.so
|
223
extensions/ACCOUNT/iptaccount.c
Normal file
223
extensions/ACCOUNT/iptaccount.c
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* 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 Lesser General Public License *
|
||||||
|
* version 2.1 as published by the Free Software Foundation; *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <libxt_ACCOUNT_cl.h>
|
||||||
|
|
||||||
|
bool exit_now;
|
||||||
|
static void sig_term(int signr)
|
||||||
|
{
|
||||||
|
signal(SIGINT, SIG_IGN);
|
||||||
|
signal(SIGQUIT, SIG_IGN);
|
||||||
|
signal(SIGTERM, SIG_IGN);
|
||||||
|
|
||||||
|
exit_now = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *addr_to_dotted(unsigned int);
|
||||||
|
char *addr_to_dotted(unsigned int addr)
|
||||||
|
{
|
||||||
|
static char buf[17];
|
||||||
|
const unsigned char *bytep;
|
||||||
|
|
||||||
|
bytep = (const unsigned char *)&addr;
|
||||||
|
snprintf(buf, 16, "%u.%u.%u.%u", bytep[0], bytep[1], bytep[2], bytep[3]);
|
||||||
|
buf[16] = 0;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void show_usage(void)
|
||||||
|
{
|
||||||
|
printf("Unknown command line option. Try: [-u] [-h] [-a] [-f] [-c] [-s] [-l name]\n");
|
||||||
|
printf("[-u] show kernel handle usage\n");
|
||||||
|
printf("[-h] free all kernel handles (experts only!)\n\n");
|
||||||
|
printf("[-a] list all table names\n");
|
||||||
|
printf("[-l name] show data in table <name>\n");
|
||||||
|
printf("[-f] flush data after showing\n");
|
||||||
|
printf("[-c] loop every second (abort with CTRL+C)\n");
|
||||||
|
printf("[-s] CSV output (for spreadsheet import)\n");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct ipt_ACCOUNT_context ctx;
|
||||||
|
struct ipt_acc_handle_ip *entry;
|
||||||
|
int i;
|
||||||
|
char optchar;
|
||||||
|
bool doHandleUsage = false, doHandleFree = false, doTableNames = false;
|
||||||
|
bool doFlush = false, doContinue = false, doCSV = false;
|
||||||
|
|
||||||
|
char *table_name = NULL;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
printf("\nlibxt_ACCOUNT_cl userspace accounting tool v%s\n\n",
|
||||||
|
LIBXT_ACCOUNT_VERSION);
|
||||||
|
|
||||||
|
if (argc == 1)
|
||||||
|
{
|
||||||
|
show_usage();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((optchar = getopt(argc, argv, "uhacfsl:")) != -1)
|
||||||
|
{
|
||||||
|
switch (optchar)
|
||||||
|
{
|
||||||
|
case 'u':
|
||||||
|
doHandleUsage = true;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
doHandleFree = true;
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
doTableNames = true;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
doFlush = true;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
doContinue = true;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
doCSV = true;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
table_name = strdup(optarg);
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
default:
|
||||||
|
show_usage();
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// install exit handler
|
||||||
|
if (signal(SIGTERM, sig_term) == SIG_ERR)
|
||||||
|
{
|
||||||
|
printf("can't install signal handler for SIGTERM\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
if (signal(SIGINT, sig_term) == SIG_ERR)
|
||||||
|
{
|
||||||
|
printf("can't install signal handler for SIGINT\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
if (signal(SIGQUIT, sig_term) == SIG_ERR)
|
||||||
|
{
|
||||||
|
printf("can't install signal handler for SIGQUIT\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipt_ACCOUNT_init(&ctx))
|
||||||
|
{
|
||||||
|
printf("Init failed: %s\n", ctx.error_str);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get handle usage?
|
||||||
|
if (doHandleUsage)
|
||||||
|
{
|
||||||
|
int rtn = ipt_ACCOUNT_get_handle_usage(&ctx);
|
||||||
|
if (rtn < 0)
|
||||||
|
{
|
||||||
|
printf("get_handle_usage failed: %s\n", ctx.error_str);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Current kernel handle usage: %d\n", ctx.handle.itemcount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doHandleFree)
|
||||||
|
{
|
||||||
|
int rtn = ipt_ACCOUNT_free_all_handles(&ctx);
|
||||||
|
if (rtn < 0)
|
||||||
|
{
|
||||||
|
printf("handle_free_all failed: %s\n", ctx.error_str);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Freed all handles in kernel space\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doTableNames)
|
||||||
|
{
|
||||||
|
int rtn = ipt_ACCOUNT_get_table_names(&ctx);
|
||||||
|
if (rtn < 0)
|
||||||
|
{
|
||||||
|
printf("get_table_names failed: %s\n", ctx.error_str);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
while ((name = ipt_ACCOUNT_get_next_name(&ctx)) != 0)
|
||||||
|
printf("Found table: %s\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (table_name)
|
||||||
|
{
|
||||||
|
// Read out data
|
||||||
|
if (doCSV)
|
||||||
|
printf("IP;SRC packets;SRC bytes;DST packets;DST bytes\n");
|
||||||
|
else
|
||||||
|
printf("Showing table: %s\n", table_name);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (!exit_now)
|
||||||
|
{
|
||||||
|
// Get entries from table test
|
||||||
|
if (ipt_ACCOUNT_read_entries(&ctx, table_name, !doFlush))
|
||||||
|
{
|
||||||
|
printf("Read failed: %s\n", ctx.error_str);
|
||||||
|
ipt_ACCOUNT_deinit(&ctx);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!doCSV)
|
||||||
|
printf("Run #%d - %u %s found\n", i, ctx.handle.itemcount,
|
||||||
|
ctx.handle.itemcount == 1 ? "item" : "items");
|
||||||
|
|
||||||
|
// Output and free entries
|
||||||
|
while ((entry = ipt_ACCOUNT_get_next_entry(&ctx)) != NULL)
|
||||||
|
{
|
||||||
|
if (doCSV)
|
||||||
|
printf("%s;%u;%u;%u;%u\n",
|
||||||
|
addr_to_dotted(entry->ip), entry->src_packets, entry->src_bytes,
|
||||||
|
entry->dst_packets, entry->dst_bytes);
|
||||||
|
else
|
||||||
|
printf("IP: %s SRC packets: %u bytes: %u DST packets: %u bytes: %u\n",
|
||||||
|
addr_to_dotted(entry->ip), entry->src_packets, entry->src_bytes,
|
||||||
|
entry->dst_packets, entry->dst_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doContinue)
|
||||||
|
{
|
||||||
|
sleep(1);
|
||||||
|
i++;
|
||||||
|
} else
|
||||||
|
exit_now = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Finished.\n");
|
||||||
|
ipt_ACCOUNT_deinit(&ctx);
|
||||||
|
exit(0);
|
||||||
|
}
|
168
extensions/ACCOUNT/libxt_ACCOUNT.c
Normal file
168
extensions/ACCOUNT/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/ACCOUNT/libxt_ACCOUNT.man
Normal file
72
extensions/ACCOUNT/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/
|
199
extensions/ACCOUNT/libxt_ACCOUNT_cl.c
Normal file
199
extensions/ACCOUNT/libxt_ACCOUNT_cl.c
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2004 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 Lesser General Public License *
|
||||||
|
* version 2.1 as published by the Free Software Foundation; *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <linux/if.h>
|
||||||
|
|
||||||
|
#include <libxt_ACCOUNT_cl.h>
|
||||||
|
|
||||||
|
int ipt_ACCOUNT_init(struct ipt_ACCOUNT_context *ctx)
|
||||||
|
{
|
||||||
|
memset(ctx, 0, sizeof(struct ipt_ACCOUNT_context));
|
||||||
|
ctx->handle.handle_nr = -1;
|
||||||
|
|
||||||
|
ctx->sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
|
||||||
|
if (ctx->sockfd < 0) {
|
||||||
|
ctx->sockfd = -1;
|
||||||
|
ctx->error_str = "Can't open socket to kernel. "
|
||||||
|
"Permission denied or ipt_ACCOUNT module not loaded";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4096 bytes default buffer should save us from reallocations
|
||||||
|
// as it fits 200 concurrent active clients
|
||||||
|
if ((ctx->data = malloc(IPT_ACCOUNT_MIN_BUFSIZE)) == NULL) {
|
||||||
|
close(ctx->sockfd);
|
||||||
|
ctx->sockfd = -1;
|
||||||
|
ctx->error_str = "Out of memory for data buffer";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ctx->data_size = IPT_ACCOUNT_MIN_BUFSIZE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipt_ACCOUNT_free_entries(struct ipt_ACCOUNT_context *ctx)
|
||||||
|
{
|
||||||
|
if (ctx->handle.handle_nr != -1) {
|
||||||
|
setsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_SET_ACCOUNT_HANDLE_FREE,
|
||||||
|
&ctx->handle, sizeof(struct ipt_acc_handle_sockopt));
|
||||||
|
ctx->handle.handle_nr = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->handle.itemcount = 0;
|
||||||
|
ctx->pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipt_ACCOUNT_deinit(struct ipt_ACCOUNT_context *ctx)
|
||||||
|
{
|
||||||
|
free(ctx->data);
|
||||||
|
ctx->data = NULL;
|
||||||
|
|
||||||
|
ipt_ACCOUNT_free_entries(ctx);
|
||||||
|
|
||||||
|
close(ctx->sockfd);
|
||||||
|
ctx->sockfd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipt_ACCOUNT_read_entries(struct ipt_ACCOUNT_context *ctx,
|
||||||
|
const char *table, char dont_flush)
|
||||||
|
{
|
||||||
|
unsigned int s = sizeof(struct ipt_acc_handle_sockopt);
|
||||||
|
unsigned int new_size;
|
||||||
|
int rtn;
|
||||||
|
|
||||||
|
strncpy(ctx->handle.name, table, ACCOUNT_TABLE_NAME_LEN-1);
|
||||||
|
|
||||||
|
// Get table information
|
||||||
|
if (!dont_flush)
|
||||||
|
rtn = getsockopt(ctx->sockfd, IPPROTO_IP,
|
||||||
|
IPT_SO_GET_ACCOUNT_PREPARE_READ_FLUSH, &ctx->handle, &s);
|
||||||
|
else
|
||||||
|
rtn = getsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_GET_ACCOUNT_PREPARE_READ,
|
||||||
|
&ctx->handle, &s);
|
||||||
|
|
||||||
|
if (rtn < 0) {
|
||||||
|
ctx->error_str = "Can't get table information from kernel. "
|
||||||
|
"Does it exist?";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check data buffer size
|
||||||
|
ctx->pos = 0;
|
||||||
|
new_size = ctx->handle.itemcount * sizeof(struct ipt_acc_handle_ip);
|
||||||
|
// We want to prevent reallocations all the time
|
||||||
|
if (new_size < IPT_ACCOUNT_MIN_BUFSIZE)
|
||||||
|
new_size = IPT_ACCOUNT_MIN_BUFSIZE;
|
||||||
|
|
||||||
|
// Reallocate if it's too small or twice as big
|
||||||
|
if (ctx->data_size < new_size || ctx->data_size > new_size * 2) {
|
||||||
|
// Free old buffer
|
||||||
|
free(ctx->data);
|
||||||
|
ctx->data_size = 0;
|
||||||
|
|
||||||
|
if ((ctx->data = malloc(new_size)) == NULL) {
|
||||||
|
ctx->error_str = "Out of memory for data buffer";
|
||||||
|
ipt_ACCOUNT_free_entries(ctx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->data_size = new_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy data from kernel
|
||||||
|
memcpy(ctx->data, &ctx->handle, sizeof(struct ipt_acc_handle_sockopt));
|
||||||
|
rtn = getsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_GET_ACCOUNT_GET_DATA,
|
||||||
|
ctx->data, &ctx->data_size);
|
||||||
|
if (rtn < 0) {
|
||||||
|
ctx->error_str = "Can't get data from kernel. "
|
||||||
|
"Check /var/log/messages for details.";
|
||||||
|
ipt_ACCOUNT_free_entries(ctx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free kernel handle but don't reset pos/itemcount
|
||||||
|
setsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_SET_ACCOUNT_HANDLE_FREE,
|
||||||
|
&ctx->handle, sizeof(struct ipt_acc_handle_sockopt));
|
||||||
|
ctx->handle.handle_nr = -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ipt_acc_handle_ip *ipt_ACCOUNT_get_next_entry(struct ipt_ACCOUNT_context *ctx)
|
||||||
|
{
|
||||||
|
struct ipt_acc_handle_ip *rtn;
|
||||||
|
|
||||||
|
// Empty or no more items left to return?
|
||||||
|
if (!ctx->handle.itemcount || ctx->pos >= ctx->handle.itemcount)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Get next entry
|
||||||
|
rtn = (struct ipt_acc_handle_ip *)(ctx->data + ctx->pos
|
||||||
|
* sizeof(struct ipt_acc_handle_ip));
|
||||||
|
ctx->pos++;
|
||||||
|
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipt_ACCOUNT_get_handle_usage(struct ipt_ACCOUNT_context *ctx)
|
||||||
|
{
|
||||||
|
unsigned int s = sizeof(struct ipt_acc_handle_sockopt);
|
||||||
|
if (getsockopt(ctx->sockfd, IPPROTO_IP,
|
||||||
|
IPT_SO_GET_ACCOUNT_GET_HANDLE_USAGE, &ctx->handle, &s) < 0) {
|
||||||
|
ctx->error_str = "Can't get handle usage information from kernel";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ctx->handle.handle_nr = -1;
|
||||||
|
|
||||||
|
return ctx->handle.itemcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipt_ACCOUNT_free_all_handles(struct ipt_ACCOUNT_context *ctx)
|
||||||
|
{
|
||||||
|
if (setsockopt(ctx->sockfd, IPPROTO_IP,
|
||||||
|
IPT_SO_SET_ACCOUNT_HANDLE_FREE_ALL, NULL, 0) < 0) {
|
||||||
|
ctx->error_str = "Can't free all kernel handles";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipt_ACCOUNT_get_table_names(struct ipt_ACCOUNT_context *ctx)
|
||||||
|
{
|
||||||
|
int rtn = getsockopt(ctx->sockfd, IPPROTO_IP,
|
||||||
|
IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES,
|
||||||
|
ctx->data, &ctx->data_size);
|
||||||
|
if (rtn < 0) {
|
||||||
|
ctx->error_str = "Can't get table names from kernel. Out of memory, "
|
||||||
|
"MINBUFISZE too small?";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ctx->pos = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *ipt_ACCOUNT_get_next_name(struct ipt_ACCOUNT_context *ctx)
|
||||||
|
{
|
||||||
|
const char *rtn;
|
||||||
|
if (((char *)ctx->data)[ctx->pos] == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rtn = ctx->data + ctx->pos;
|
||||||
|
ctx->pos += strlen(ctx->data + ctx->pos) + 1;
|
||||||
|
|
||||||
|
return rtn;
|
||||||
|
}
|
60
extensions/ACCOUNT/libxt_ACCOUNT_cl.h
Normal file
60
extensions/ACCOUNT/libxt_ACCOUNT_cl.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2004 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 Lesser General Public License *
|
||||||
|
* version 2.1 as published by the Free Software Foundation; *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _xt_ACCOUNT_cl_H
|
||||||
|
#define _xt_ACCOUNT_cl_H
|
||||||
|
|
||||||
|
#include <xt_ACCOUNT.h>
|
||||||
|
|
||||||
|
#define LIBXT_ACCOUNT_VERSION "1.3"
|
||||||
|
|
||||||
|
/* Don't set this below the size of struct ipt_account_handle_sockopt */
|
||||||
|
#define IPT_ACCOUNT_MIN_BUFSIZE 4096
|
||||||
|
|
||||||
|
struct ipt_ACCOUNT_context
|
||||||
|
{
|
||||||
|
int sockfd;
|
||||||
|
struct ipt_acc_handle_sockopt handle;
|
||||||
|
|
||||||
|
unsigned int data_size;
|
||||||
|
void *data;
|
||||||
|
unsigned int pos;
|
||||||
|
|
||||||
|
char *error_str;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int ipt_ACCOUNT_init(struct ipt_ACCOUNT_context *ctx);
|
||||||
|
void ipt_ACCOUNT_deinit(struct ipt_ACCOUNT_context *ctx);
|
||||||
|
|
||||||
|
void ipt_ACCOUNT_free_entries(struct ipt_ACCOUNT_context *ctx);
|
||||||
|
int ipt_ACCOUNT_read_entries(struct ipt_ACCOUNT_context *ctx,
|
||||||
|
const char *table, char dont_flush);
|
||||||
|
struct ipt_acc_handle_ip *ipt_ACCOUNT_get_next_entry(
|
||||||
|
struct ipt_ACCOUNT_context *ctx);
|
||||||
|
|
||||||
|
/* ipt_ACCOUNT_free_entries is for internal use only function as this library
|
||||||
|
is constructed to be used in a loop -> Don't allocate memory all the time.
|
||||||
|
The data buffer is freed on deinit() */
|
||||||
|
|
||||||
|
int ipt_ACCOUNT_get_handle_usage(struct ipt_ACCOUNT_context *ctx);
|
||||||
|
int ipt_ACCOUNT_free_all_handles(struct ipt_ACCOUNT_context *ctx);
|
||||||
|
int ipt_ACCOUNT_get_table_names(struct ipt_ACCOUNT_context *ctx);
|
||||||
|
const char *ipt_ACCOUNT_get_next_name(struct ipt_ACCOUNT_context *ctx);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
13
extensions/ACCOUNT/xt_ACCOUNT.Kconfig
Normal file
13
extensions/ACCOUNT/xt_ACCOUNT.Kconfig
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
config NETFILTER_XT_TARGET_ACCOUNT
|
||||||
|
tristate "ACCOUNT target support"
|
||||||
|
depends on NETFILTER_XTABLES
|
||||||
|
---help---
|
||||||
|
This module implements an ACCOUNT target
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
For more information go to:
|
||||||
|
http://www.intra2net.com/de/produkte/opensource/ipt_account/
|
1104
extensions/ACCOUNT/xt_ACCOUNT.c
Normal file
1104
extensions/ACCOUNT/xt_ACCOUNT.c
Normal file
File diff suppressed because it is too large
Load Diff
118
extensions/ACCOUNT/xt_ACCOUNT.h
Normal file
118
extensions/ACCOUNT/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 */
|
@@ -1,142 +0,0 @@
|
|||||||
# -*- Makefile -*-
|
|
||||||
|
|
||||||
top_srcdir := @top_srcdir@
|
|
||||||
srcdir := @srcdir@
|
|
||||||
abstop_srcdir := $(shell readlink -f ${top_srcdir})
|
|
||||||
abssrcdir := $(shell readlink -f ${srcdir})
|
|
||||||
|
|
||||||
ifeq (${abstop_srcdir},)
|
|
||||||
$(error Path resolution of ${top_srcdir} failed)
|
|
||||||
endif
|
|
||||||
ifeq (${abssrcdir},)
|
|
||||||
$(error Path resolution of ${srcdir} failed)
|
|
||||||
endif
|
|
||||||
|
|
||||||
prefix := @prefix@
|
|
||||||
exec_prefix := @exec_prefix@
|
|
||||||
libdir := @libdir@
|
|
||||||
libexecdir := @libexecdir@
|
|
||||||
xtlibdir := @xtlibdir@
|
|
||||||
kbuilddir := @kbuilddir@
|
|
||||||
|
|
||||||
CC := @CC@
|
|
||||||
CCLD := ${CC}
|
|
||||||
CFLAGS := @CFLAGS@
|
|
||||||
LDFLAGS := @LDFLAGS@
|
|
||||||
regular_CFLAGS := @regular_CFLAGS@
|
|
||||||
kinclude_CFLAGS := @kinclude_CFLAGS@
|
|
||||||
xtables_CFLAGS := @xtables_CFLAGS@
|
|
||||||
|
|
||||||
AM_CFLAGS := ${regular_CFLAGS} -I${top_srcdir}/include ${xtables_CFLAGS} ${kinclude_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_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}}
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Wildcard module list
|
|
||||||
#
|
|
||||||
include ${top_srcdir}/mconfig
|
|
||||||
-include ${top_srcdir}/mconfig.*
|
|
||||||
include ${srcdir}/Mbuild
|
|
||||||
-include ${srcdir}/Mbuild.*
|
|
||||||
-include ${srcdir}/*.Mbuild
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Building blocks
|
|
||||||
#
|
|
||||||
targets := $(filter-out %/,${obj-m})
|
|
||||||
targets_install := ${targets}
|
|
||||||
subdirs_list := $(filter %/,${obj-m})
|
|
||||||
|
|
||||||
.SECONDARY:
|
|
||||||
|
|
||||||
.PHONY: all install clean distclean FORCE
|
|
||||||
|
|
||||||
all: subdirs modules user matches.man targets.man
|
|
||||||
|
|
||||||
subdirs:
|
|
||||||
@for i in ${subdirs_list}; do ${MAKE} -C $$i; done;
|
|
||||||
|
|
||||||
subdirs-install:
|
|
||||||
@for i in ${subdirs_list}; do ${MAKE} -C $$i install; done;
|
|
||||||
|
|
||||||
user: ${targets}
|
|
||||||
|
|
||||||
install: modules_install subdirs-install ${targets_install}
|
|
||||||
@mkdir -p "${DESTDIR}${xtlibdir}";
|
|
||||||
install -pm0755 ${targets_install} "${DESTDIR}${xtlibdir}/";
|
|
||||||
|
|
||||||
clean: clean_modules
|
|
||||||
@for i in ${subdirs_list}; do make -C $$i clean; done;
|
|
||||||
rm -f *.oo *.so;
|
|
||||||
|
|
||||||
distclean: clean
|
|
||||||
rm -f .*.d .manpages.lst;
|
|
||||||
|
|
||||||
-include .*.d
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Call out to kbuild
|
|
||||||
#
|
|
||||||
.PHONY: modules modules_install clean_modules
|
|
||||||
|
|
||||||
modules:
|
|
||||||
make -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} modules;
|
|
||||||
|
|
||||||
modules_install:
|
|
||||||
make -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} INSTALL_MOD_PATH=${DESTDIR} modules_install;
|
|
||||||
|
|
||||||
clean_modules:
|
|
||||||
make -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} clean;
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Shared libraries
|
|
||||||
#
|
|
||||||
lib%.so: lib%.oo
|
|
||||||
${am__verbose_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 $<;
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Manpages
|
|
||||||
#
|
|
||||||
wcman_matches := $(wildcard ${srcdir}/libxt_[a-z]*.man)
|
|
||||||
wcman_targets := $(wildcard ${srcdir}/libxt_[A-Z]*.man)
|
|
||||||
wlist_matches := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_matches})
|
|
||||||
wlist_targets := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_targets})
|
|
||||||
|
|
||||||
.manpages.lst: FORCE
|
|
||||||
@echo "${wlist_targets} ${wlist_matches}" >$@.tmp; \
|
|
||||||
cmp -s $@ $@.tmp || mv $@.tmp $@; \
|
|
||||||
rm -f $@.tmp;
|
|
||||||
|
|
||||||
man_run = \
|
|
||||||
${am__verbose_GEN}for ext in $(1); do \
|
|
||||||
f="${srcdir}/libxt_$$ext.man"; \
|
|
||||||
if [ -f "$$f" ]; then \
|
|
||||||
echo ".SS $$ext"; \
|
|
||||||
cat "$$f"; \
|
|
||||||
continue; \
|
|
||||||
fi; \
|
|
||||||
done >$@;
|
|
||||||
|
|
||||||
matches.man: .manpages.lst ${wcman_matches}
|
|
||||||
$(call man_run,${wlist_matches})
|
|
||||||
|
|
||||||
targets.man: .manpages.lst ${wcman_targets}
|
|
||||||
$(call man_run,${wlist_targets})
|
|
@@ -1,25 +1,33 @@
|
|||||||
# -*- Makefile -*-
|
# -*- Makefile -*-
|
||||||
|
|
||||||
include ${XA_TOPSRCDIR}/mconfig
|
include ${XA_ABSTOPSRCDIR}/mconfig
|
||||||
-include ${XA_TOPSRCDIR}/mconfig.*
|
-include ${XA_ABSTOPSRCDIR}/mconfig.*
|
||||||
|
|
||||||
obj-m += compat_xtables.o
|
obj-m += compat_xtables.o
|
||||||
|
|
||||||
|
obj-${build_ACCOUNT} += ACCOUNT/
|
||||||
obj-${build_CHAOS} += xt_CHAOS.o
|
obj-${build_CHAOS} += xt_CHAOS.o
|
||||||
obj-${build_DELUDE} += xt_DELUDE.o
|
obj-${build_DELUDE} += xt_DELUDE.o
|
||||||
obj-${build_DHCPADDR} += xt_DHCPADDR.o
|
obj-${build_DHCPMAC} += xt_DHCPMAC.o
|
||||||
obj-${build_ECHO} += xt_ECHO.o
|
obj-${build_ECHO} += xt_ECHO.o
|
||||||
obj-${build_IPMARK} += xt_IPMARK.o
|
obj-${build_IPMARK} += xt_IPMARK.o
|
||||||
obj-${build_LOGMARK} += xt_LOGMARK.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_SYSRQ} += xt_SYSRQ.o
|
||||||
|
obj-${build_STEAL} += xt_STEAL.o
|
||||||
obj-${build_TARPIT} += xt_TARPIT.o
|
obj-${build_TARPIT} += xt_TARPIT.o
|
||||||
obj-${build_TEE} += xt_TEE.o
|
obj-${build_TEE} += xt_TEE.o
|
||||||
obj-${build_condition} += xt_condition.o
|
obj-${build_condition} += xt_condition.o
|
||||||
obj-${build_fuzzy} += xt_fuzzy.o
|
obj-${build_fuzzy} += xt_fuzzy.o
|
||||||
obj-${build_geoip} += xt_geoip.o
|
obj-${build_geoip} += xt_geoip.o
|
||||||
|
obj-${build_iface} += xt_iface.o
|
||||||
obj-${build_ipp2p} += xt_ipp2p.o
|
obj-${build_ipp2p} += xt_ipp2p.o
|
||||||
obj-${build_ipset} += ipset/
|
obj-${build_ipset} += ipset/
|
||||||
obj-${build_portscan} += xt_portscan.o
|
obj-${build_ipv4options} += xt_ipv4options.o
|
||||||
|
obj-${build_length2} += xt_length2.o
|
||||||
|
obj-${build_lscan} += xt_lscan.o
|
||||||
|
obj-${build_pknock} += pknock/
|
||||||
|
obj-${build_psd} += xt_psd.o
|
||||||
obj-${build_quota2} += xt_quota2.o
|
obj-${build_quota2} += xt_quota2.o
|
||||||
|
|
||||||
-include ${M}/*.Kbuild
|
-include ${M}/*.Kbuild
|
||||||
|
24
extensions/Makefile.am
Normal file
24
extensions/Makefile.am
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
# AUTOMAKE
|
||||||
|
|
||||||
|
# Not having Kbuild in Makefile.extra because it will already recurse
|
||||||
|
.PHONY: modules modules_install clean_modules
|
||||||
|
|
||||||
|
_kcall = -C ${kbuilddir} M=${abs_srcdir}
|
||||||
|
|
||||||
|
modules:
|
||||||
|
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} modules; fi;
|
||||||
|
|
||||||
|
modules_install:
|
||||||
|
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} INSTALL_MOD_PATH=${DESTDIR} ext-mod-dir='$${INSTALL_MOD_DIR}' modules_install; fi;
|
||||||
|
|
||||||
|
clean_modules:
|
||||||
|
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} clean; fi;
|
||||||
|
|
||||||
|
all-local: modules
|
||||||
|
|
||||||
|
install-exec-local: modules_install
|
||||||
|
|
||||||
|
clean-local: clean_modules
|
||||||
|
|
||||||
|
include ../Makefile.extra
|
@@ -1,16 +1,26 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
|
||||||
|
obj-${build_ACCOUNT} += ACCOUNT/
|
||||||
obj-${build_CHAOS} += libxt_CHAOS.so
|
obj-${build_CHAOS} += libxt_CHAOS.so
|
||||||
obj-${build_DELUDE} += libxt_DELUDE.so
|
obj-${build_DELUDE} += libxt_DELUDE.so
|
||||||
obj-${build_DHCPADDR} += libxt_DHCPADDR.so libxt_dhcpaddr.so
|
obj-${build_DHCPMAC} += libxt_DHCPMAC.so libxt_dhcpmac.so
|
||||||
obj-${build_ECHO} += libxt_ECHO.so
|
obj-${build_ECHO} += libxt_ECHO.so
|
||||||
obj-${build_IPMARK} += libxt_IPMARK.so
|
obj-${build_IPMARK} += libxt_IPMARK.so
|
||||||
obj-${build_LOGMARK} += libxt_LOGMARK.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_SYSRQ} += libxt_SYSRQ.so
|
||||||
obj-${build_TARPIT} += libxt_TARPIT.so
|
obj-${build_TARPIT} += libxt_TARPIT.so
|
||||||
obj-${build_TEE} += libxt_TEE.so
|
obj-${build_TEE} += libxt_TEE.so
|
||||||
obj-${build_condition} += libxt_condition.so
|
obj-${build_condition} += libxt_condition.so
|
||||||
obj-${build_fuzzy} += libxt_fuzzy.so
|
obj-${build_fuzzy} += libxt_fuzzy.so
|
||||||
obj-${build_geoip} += libxt_geoip.so
|
obj-${build_geoip} += libxt_geoip.so
|
||||||
|
obj-${build_iface} += libxt_iface.so
|
||||||
obj-${build_ipp2p} += libxt_ipp2p.so
|
obj-${build_ipp2p} += libxt_ipp2p.so
|
||||||
obj-${build_ipset} += ipset/
|
obj-${build_ipset} += ipset/
|
||||||
obj-${build_portscan} += libxt_portscan.so
|
obj-${build_ipv4options} += libxt_ipv4options.so
|
||||||
|
obj-${build_length2} += libxt_length2.so
|
||||||
|
obj-${build_lscan} += libxt_lscan.so
|
||||||
|
obj-${build_pknock} += pknock/
|
||||||
|
obj-${build_psd} += libxt_psd.so
|
||||||
obj-${build_quota2} += libxt_quota2.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,9 +4,29 @@
|
|||||||
struct tcphdr;
|
struct tcphdr;
|
||||||
struct udphdr;
|
struct udphdr;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 30)
|
||||||
|
static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst)
|
||||||
|
{
|
||||||
|
skb->dst = dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct dst_entry *skb_dst(const struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return skb->dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct rtable *skb_rtable(const struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return (void *)skb->dst;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
||||||
|
# define skb_ifindex(skb) \
|
||||||
|
(((skb)->input_dev != NULL) ? (skb)->input_dev->ifindex : 0)
|
||||||
# define skb_nfmark(skb) (((struct sk_buff *)(skb))->nfmark)
|
# define skb_nfmark(skb) (((struct sk_buff *)(skb))->nfmark)
|
||||||
#else
|
#else
|
||||||
|
# define skb_ifindex(skb) (skb)->iif
|
||||||
# define skb_nfmark(skb) (((struct sk_buff *)(skb))->mark)
|
# define skb_nfmark(skb) (((struct sk_buff *)(skb))->mark)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -20,11 +20,6 @@
|
|||||||
#include "compat_skbuff.h"
|
#include "compat_skbuff.h"
|
||||||
#include "compat_xtnu.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)
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
||||||
static int xtnu_match_run(const struct sk_buff *skb,
|
static int xtnu_match_run(const struct sk_buff *skb,
|
||||||
const struct net_device *in, const struct net_device *out,
|
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);
|
return ip_route_output_flow(rp, flp, NULL, 0);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xtnu_ip_route_output_key);
|
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
|
#endif
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
#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;
|
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};
|
__be32 diff[] = {~from, to};
|
||||||
*sum = csum_fold(csum_partial((char *)diff, sizeof(diff),
|
*sum = csum_fold(csum_partial((char *)diff, sizeof(diff),
|
||||||
|
@@ -1,10 +1,13 @@
|
|||||||
#ifndef _XTABLES_COMPAT_H
|
#ifndef _XTABLES_COMPAT_H
|
||||||
#define _XTABLES_COMPAT_H 1
|
#define _XTABLES_COMPAT_H 1
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
#include "compat_skbuff.h"
|
#include "compat_skbuff.h"
|
||||||
#include "compat_xtnu.h"
|
#include "compat_xtnu.h"
|
||||||
|
|
||||||
|
#define DEBUGP Use__pr_debug__instead
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17)
|
||||||
# warning Kernels below 2.6.17 not supported.
|
# warning Kernels below 2.6.17 not supported.
|
||||||
#endif
|
#endif
|
||||||
@@ -34,6 +37,7 @@
|
|||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
||||||
# define neigh_hh_output xtnu_neigh_hh_output
|
# define neigh_hh_output xtnu_neigh_hh_output
|
||||||
# define IPPROTO_UDPLITE 136
|
# define IPPROTO_UDPLITE 136
|
||||||
|
# define CSUM_MANGLED_0 ((__force __sum16)0xffff)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
|
||||||
@@ -66,8 +70,33 @@
|
|||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
||||||
# define csum_replace2 xtnu_csum_replace2
|
# 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)
|
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
|
||||||
# define csum_replace2 nf_csum_replace2
|
# 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)
|
||||||
|
# define NIP6(addr) \
|
||||||
|
ntohs((addr).s6_addr16[0]), \
|
||||||
|
ntohs((addr).s6_addr16[1]), \
|
||||||
|
ntohs((addr).s6_addr16[2]), \
|
||||||
|
ntohs((addr).s6_addr16[3]), \
|
||||||
|
ntohs((addr).s6_addr16[4]), \
|
||||||
|
ntohs((addr).s6_addr16[5]), \
|
||||||
|
ntohs((addr).s6_addr16[6]), \
|
||||||
|
ntohs((addr).s6_addr16[7])
|
||||||
|
# define NIP6_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
|
||||||
|
#endif
|
||||||
|
#if !defined(NIPQUAD) && !defined(NIPQUAD_FMT)
|
||||||
|
# define NIPQUAD(addr) \
|
||||||
|
((const unsigned char *)&addr)[0], \
|
||||||
|
((const unsigned char *)&addr)[1], \
|
||||||
|
((const unsigned char *)&addr)[2], \
|
||||||
|
((const unsigned char *)&addr)[3]
|
||||||
|
# define NIPQUAD_FMT "%u.%u.%u.%u"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ip_route_me_harder xtnu_ip_route_me_harder
|
#define ip_route_me_harder xtnu_ip_route_me_harder
|
||||||
|
@@ -9,6 +9,10 @@
|
|||||||
typedef _Bool bool;
|
typedef _Bool bool;
|
||||||
enum { false = 0, true = 1, };
|
enum { false = 0, true = 1, };
|
||||||
#endif
|
#endif
|
||||||
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
||||||
|
typedef __u16 __bitwise __sum16;
|
||||||
|
typedef __u32 __bitwise __wsum;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct flowi;
|
struct flowi;
|
||||||
struct hh_cache;
|
struct hh_cache;
|
||||||
@@ -122,6 +126,13 @@ static inline struct xtnu_target *xtcompat_nutarget(const struct xt_target *t)
|
|||||||
return q;
|
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_local_out(struct sk_buff *);
|
||||||
extern int xtnu_ip_route_me_harder(struct sk_buff **, unsigned int);
|
extern int xtnu_ip_route_me_harder(struct sk_buff **, unsigned int);
|
||||||
extern int xtnu_skb_make_writable(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);
|
const char *, uint8_t);
|
||||||
extern int xtnu_neigh_hh_output(struct hh_cache *, struct sk_buff *);
|
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_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 *);
|
extern int xtnu_skb_linearize(struct sk_buff *);
|
||||||
|
|
||||||
#endif /* _COMPAT_XTNU_H */
|
#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");
|
2
extensions/ipset/.gitignore
vendored
2
extensions/ipset/.gitignore
vendored
@@ -1,3 +1 @@
|
|||||||
*.oo
|
|
||||||
*.so
|
|
||||||
/ipset
|
/ipset
|
||||||
|
@@ -1,84 +0,0 @@
|
|||||||
# -*- Makefile -*-
|
|
||||||
|
|
||||||
top_srcdir := @top_srcdir@
|
|
||||||
srcdir := @srcdir@
|
|
||||||
abstop_srcdir := $(shell readlink -e ${top_srcdir})
|
|
||||||
abssrcdir := $(shell readlink -e ${srcdir})
|
|
||||||
|
|
||||||
ifeq (${abstop_srcdir},)
|
|
||||||
$(error Path resolution of ${top_srcdir} failed)
|
|
||||||
endif
|
|
||||||
ifeq (${abssrcdir},)
|
|
||||||
$(error Path resolution of ${srcdir} failed)
|
|
||||||
endif
|
|
||||||
|
|
||||||
prefix := @prefix@
|
|
||||||
exec_prefix := @exec_prefix@
|
|
||||||
sbindir := @sbindir@
|
|
||||||
libdir := @libdir@
|
|
||||||
libexecdir := @libexecdir@
|
|
||||||
xtlibdir := @xtlibdir@
|
|
||||||
kbuilddir := @kbuilddir@
|
|
||||||
man8dir := @mandir@/man8
|
|
||||||
|
|
||||||
CC := @CC@
|
|
||||||
CCLD := ${CC}
|
|
||||||
CFLAGS := @CFLAGS@
|
|
||||||
LDFLAGS := @LDFLAGS@
|
|
||||||
regular_CFLAGS := @regular_CFLAGS@
|
|
||||||
kinclude_CFLAGS := @kinclude_CFLAGS@
|
|
||||||
xtables_CFLAGS := @xtables_CFLAGS@
|
|
||||||
|
|
||||||
AM_CFLAGS := ${regular_CFLAGS} -I${top_srcdir}/include ${xtables_CFLAGS} ${kinclude_CFLAGS} -DIPSET_LIB_DIR=\"${xtlibdir}\"
|
|
||||||
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
|
|
||||||
|
|
||||||
VU := 0
|
|
||||||
am__1verbose_CC_0 = @echo " CC " $@;
|
|
||||||
am__1verbose_CCLD_0 = @echo " CCLD " $@;
|
|
||||||
am__1verbose_CC_1 = @echo " CC " $@ "<-" $<;
|
|
||||||
am__1verbose_CCLD_1 = @echo " CCLD " $@ "<-" $^;
|
|
||||||
am__verbose_CC = ${am__1verbose_CC_${VU}}
|
|
||||||
am__verbose_CCLD = ${am__1verbose_CCLD_${VU}}
|
|
||||||
|
|
||||||
#
|
|
||||||
# Building blocks
|
|
||||||
#
|
|
||||||
targets := $(addsuffix .so,$(addprefix libipset_, \
|
|
||||||
iphash ipmap ipporthash ipportiphash ipportnethash iptree \
|
|
||||||
iptreemap macipmap nethash portmap setlist))
|
|
||||||
|
|
||||||
.SECONDARY:
|
|
||||||
|
|
||||||
.PHONY: all install clean distclean FORCE
|
|
||||||
|
|
||||||
all: ipset ${targets}
|
|
||||||
|
|
||||||
install: all
|
|
||||||
@mkdir -p "${DESTDIR}${sbindir}" "${DESTDIR}${xtlibdir}" "${DESTDIR}${man8dir}";
|
|
||||||
install -pm0755 ipset "${DESTDIR}${sbindir}/";
|
|
||||||
install -pm0755 ${targets} "${DESTDIR}${xtlibdir}/";
|
|
||||||
install -pm0644 ipset.8 "${DESTDIR}${man8dir}/";
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f *.oo *.so *.o ipset;
|
|
||||||
|
|
||||||
distclean: clean
|
|
||||||
rm -f .*.d;
|
|
||||||
|
|
||||||
-include .*.d
|
|
||||||
|
|
||||||
|
|
||||||
ipset: ipset.o
|
|
||||||
${am__verbose_CCLD}${CCLD} ${AM_LDFLAGS} ${LDFLAGS} -o $@ $< -ldl -rdynamic;
|
|
||||||
|
|
||||||
#
|
|
||||||
# Shared libraries
|
|
||||||
#
|
|
||||||
lib%.so: lib%.oo
|
|
||||||
${am__verbose_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
|
|
||||||
|
|
||||||
libipset_%.oo: ${srcdir}/ipset_%.c
|
|
||||||
${am__verbose_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
|
|
||||||
|
|
||||||
%.o: %.c
|
|
||||||
${am__verbose_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} ${CFLAGS} -o $@ -c $<;
|
|
9
extensions/ipset/Makefile.am
Normal file
9
extensions/ipset/Makefile.am
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
|
||||||
|
AM_CFLAGS = ${regular_CFLAGS} -DIPSET_LIB_DIR=\"${xtlibdir}\"
|
||||||
|
|
||||||
|
include ../../Makefile.extra
|
||||||
|
|
||||||
|
sbin_PROGRAMS = ipset
|
||||||
|
ipset_LDADD = -ldl
|
||||||
|
ipset_LDFLAGS = -rdynamic
|
7
extensions/ipset/Mbuild
Normal file
7
extensions/ipset/Mbuild
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
|
||||||
|
obj-m += $(addprefix lib,$(patsubst %.c,%.so,$(notdir \
|
||||||
|
$(wildcard ${XA_SRCDIR}/ipset_*.c))))
|
||||||
|
|
||||||
|
libipset_%.oo: ${XA_SRCDIR}/ipset_%.c
|
||||||
|
${AM_V_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
|
@@ -19,7 +19,7 @@
|
|||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/random.h>
|
#include <linux/random.h>
|
||||||
#include <linux/jhash.h>
|
#include "ip_set_jhash.h"
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/capability.h>
|
#include <linux/capability.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
static struct list_head set_type_list; /* all registered sets */
|
static struct list_head set_type_list; /* all registered sets */
|
||||||
static struct ip_set **ip_set_list; /* all individual sets */
|
static struct ip_set **ip_set_list; /* all individual sets */
|
||||||
static DEFINE_RWLOCK(ip_set_lock); /* protects the lists and the hash */
|
static DEFINE_RWLOCK(ip_set_lock); /* protects the lists and the hash */
|
||||||
static DECLARE_MUTEX(ip_set_app_mutex); /* serializes user access */
|
static struct semaphore ip_set_app_mutex; /* serializes user access */
|
||||||
static ip_set_id_t ip_set_max = CONFIG_IP_NF_SET_MAX;
|
static ip_set_id_t ip_set_max = CONFIG_IP_NF_SET_MAX;
|
||||||
static ip_set_id_t ip_set_bindings_hash_size = CONFIG_IP_NF_SET_HASHSIZE;
|
static ip_set_id_t ip_set_bindings_hash_size = CONFIG_IP_NF_SET_HASHSIZE;
|
||||||
static struct list_head *ip_set_hash; /* hash of bindings */
|
static struct list_head *ip_set_hash; /* hash of bindings */
|
||||||
@@ -493,7 +493,7 @@ ip_set_find_byindex(ip_set_id_t index)
|
|||||||
static inline int
|
static inline int
|
||||||
__ip_set_testip(struct ip_set *set,
|
__ip_set_testip(struct ip_set *set,
|
||||||
const void *data,
|
const void *data,
|
||||||
size_t size,
|
u_int32_t size,
|
||||||
ip_set_ip_t *ip)
|
ip_set_ip_t *ip)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
@@ -508,7 +508,7 @@ __ip_set_testip(struct ip_set *set,
|
|||||||
static int
|
static int
|
||||||
__ip_set_addip(ip_set_id_t index,
|
__ip_set_addip(ip_set_id_t index,
|
||||||
const void *data,
|
const void *data,
|
||||||
size_t size)
|
u_int32_t size)
|
||||||
{
|
{
|
||||||
struct ip_set *set = ip_set_list[index];
|
struct ip_set *set = ip_set_list[index];
|
||||||
ip_set_ip_t ip;
|
ip_set_ip_t ip;
|
||||||
@@ -529,15 +529,15 @@ __ip_set_addip(ip_set_id_t index,
|
|||||||
static int
|
static int
|
||||||
ip_set_addip(ip_set_id_t index,
|
ip_set_addip(ip_set_id_t index,
|
||||||
const void *data,
|
const void *data,
|
||||||
size_t size)
|
u_int32_t size)
|
||||||
{
|
{
|
||||||
struct ip_set *set = ip_set_list[index];
|
struct ip_set *set = ip_set_list[index];
|
||||||
|
|
||||||
IP_SET_ASSERT(set);
|
IP_SET_ASSERT(set);
|
||||||
|
|
||||||
if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) {
|
if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %lu, have %zu)",
|
||||||
set->type->reqsize,
|
(long unsigned)set->type->reqsize,
|
||||||
size - sizeof(struct ip_set_req_adt));
|
size - sizeof(struct ip_set_req_adt));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -549,7 +549,7 @@ ip_set_addip(ip_set_id_t index,
|
|||||||
static int
|
static int
|
||||||
ip_set_delip(ip_set_id_t index,
|
ip_set_delip(ip_set_id_t index,
|
||||||
const void *data,
|
const void *data,
|
||||||
size_t size)
|
u_int32_t size)
|
||||||
{
|
{
|
||||||
struct ip_set *set = ip_set_list[index];
|
struct ip_set *set = ip_set_list[index];
|
||||||
ip_set_ip_t ip;
|
ip_set_ip_t ip;
|
||||||
@@ -558,8 +558,8 @@ ip_set_delip(ip_set_id_t index,
|
|||||||
IP_SET_ASSERT(set);
|
IP_SET_ASSERT(set);
|
||||||
|
|
||||||
if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) {
|
if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %lu, have %zu)",
|
||||||
set->type->reqsize,
|
(long unsigned)set->type->reqsize,
|
||||||
size - sizeof(struct ip_set_req_adt));
|
size - sizeof(struct ip_set_req_adt));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -576,7 +576,7 @@ ip_set_delip(ip_set_id_t index,
|
|||||||
static int
|
static int
|
||||||
ip_set_testip(ip_set_id_t index,
|
ip_set_testip(ip_set_id_t index,
|
||||||
const void *data,
|
const void *data,
|
||||||
size_t size)
|
u_int32_t size)
|
||||||
{
|
{
|
||||||
struct ip_set *set = ip_set_list[index];
|
struct ip_set *set = ip_set_list[index];
|
||||||
ip_set_ip_t ip;
|
ip_set_ip_t ip;
|
||||||
@@ -585,8 +585,8 @@ ip_set_testip(ip_set_id_t index,
|
|||||||
IP_SET_ASSERT(set);
|
IP_SET_ASSERT(set);
|
||||||
|
|
||||||
if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) {
|
if (size - sizeof(struct ip_set_req_adt) != set->type->reqsize) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %lu, have %zu)",
|
||||||
set->type->reqsize,
|
(long unsigned)set->type->reqsize,
|
||||||
size - sizeof(struct ip_set_req_adt));
|
size - sizeof(struct ip_set_req_adt));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -601,7 +601,7 @@ ip_set_testip(ip_set_id_t index,
|
|||||||
static int
|
static int
|
||||||
ip_set_bindip(ip_set_id_t index,
|
ip_set_bindip(ip_set_id_t index,
|
||||||
const void *data,
|
const void *data,
|
||||||
size_t size)
|
u_int32_t size)
|
||||||
{
|
{
|
||||||
struct ip_set *set = ip_set_list[index];
|
struct ip_set *set = ip_set_list[index];
|
||||||
const struct ip_set_req_bind *req_bind;
|
const struct ip_set_req_bind *req_bind;
|
||||||
@@ -687,7 +687,7 @@ __unbind_default(struct ip_set *set)
|
|||||||
static int
|
static int
|
||||||
ip_set_unbindip(ip_set_id_t index,
|
ip_set_unbindip(ip_set_id_t index,
|
||||||
const void *data,
|
const void *data,
|
||||||
size_t size)
|
u_int32_t size)
|
||||||
{
|
{
|
||||||
struct ip_set *set;
|
struct ip_set *set;
|
||||||
const struct ip_set_req_bind *req_bind;
|
const struct ip_set_req_bind *req_bind;
|
||||||
@@ -760,7 +760,7 @@ ip_set_unbindip(ip_set_id_t index,
|
|||||||
static int
|
static int
|
||||||
ip_set_testbind(ip_set_id_t index,
|
ip_set_testbind(ip_set_id_t index,
|
||||||
const void *data,
|
const void *data,
|
||||||
size_t size)
|
u_int32_t size)
|
||||||
{
|
{
|
||||||
struct ip_set *set = ip_set_list[index];
|
struct ip_set *set = ip_set_list[index];
|
||||||
const struct ip_set_req_bind *req_bind;
|
const struct ip_set_req_bind *req_bind;
|
||||||
@@ -862,7 +862,7 @@ ip_set_create(const char *name,
|
|||||||
const char *typename,
|
const char *typename,
|
||||||
ip_set_id_t restore,
|
ip_set_id_t restore,
|
||||||
const void *data,
|
const void *data,
|
||||||
size_t size)
|
u_int32_t size)
|
||||||
{
|
{
|
||||||
struct ip_set *set;
|
struct ip_set *set;
|
||||||
ip_set_id_t index = 0, id;
|
ip_set_id_t index = 0, id;
|
||||||
@@ -877,7 +877,7 @@ ip_set_create(const char *name,
|
|||||||
set = kmalloc(sizeof(struct ip_set), GFP_KERNEL);
|
set = kmalloc(sizeof(struct ip_set), GFP_KERNEL);
|
||||||
if (!set)
|
if (!set)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
set->lock = RW_LOCK_UNLOCKED;
|
rwlock_init(&set->lock);
|
||||||
strncpy(set->name, name, IP_SET_MAXNAMELEN);
|
strncpy(set->name, name, IP_SET_MAXNAMELEN);
|
||||||
set->binding = IP_SET_INVALID_ID;
|
set->binding = IP_SET_INVALID_ID;
|
||||||
atomic_set(&set->ref, 0);
|
atomic_set(&set->ref, 0);
|
||||||
@@ -915,9 +915,9 @@ ip_set_create(const char *name,
|
|||||||
|
|
||||||
/* Check request size */
|
/* Check request size */
|
||||||
if (size != set->type->header_size) {
|
if (size != set->type->header_size) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %lu, have %lu)",
|
||||||
set->type->header_size,
|
(long unsigned)set->type->header_size,
|
||||||
size);
|
(long unsigned)size);
|
||||||
goto put_out;
|
goto put_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1109,7 +1109,7 @@ ip_set_swap(ip_set_id_t from_index, ip_set_id_t to_index)
|
|||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
__set_hash_bindings_size_list(struct ip_set_hash *set_hash,
|
__set_hash_bindings_size_list(struct ip_set_hash *set_hash,
|
||||||
ip_set_id_t id, size_t *size)
|
ip_set_id_t id, u_int32_t *size)
|
||||||
{
|
{
|
||||||
if (set_hash->id == id)
|
if (set_hash->id == id)
|
||||||
*size += sizeof(struct ip_set_hash_list);
|
*size += sizeof(struct ip_set_hash_list);
|
||||||
@@ -1117,7 +1117,7 @@ __set_hash_bindings_size_list(struct ip_set_hash *set_hash,
|
|||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
__set_hash_bindings_size_save(struct ip_set_hash *set_hash,
|
__set_hash_bindings_size_save(struct ip_set_hash *set_hash,
|
||||||
ip_set_id_t id, size_t *size)
|
ip_set_id_t id, u_int32_t *size)
|
||||||
{
|
{
|
||||||
if (set_hash->id == id)
|
if (set_hash->id == id)
|
||||||
*size += sizeof(struct ip_set_hash_save);
|
*size += sizeof(struct ip_set_hash_save);
|
||||||
@@ -1220,7 +1220,7 @@ static int ip_set_save_set(ip_set_id_t index,
|
|||||||
*used += sizeof(struct ip_set_save);
|
*used += sizeof(struct ip_set_save);
|
||||||
|
|
||||||
set = ip_set_list[index];
|
set = ip_set_list[index];
|
||||||
DP("set: %s, used: %u(%u) %p %p", set->name, *used, len,
|
DP("set: %s, used: %d(%d) %p %p", set->name, *used, len,
|
||||||
data, data + *used);
|
data, data + *used);
|
||||||
|
|
||||||
read_lock_bh(&set->lock);
|
read_lock_bh(&set->lock);
|
||||||
@@ -1237,8 +1237,8 @@ static int ip_set_save_set(ip_set_id_t index,
|
|||||||
set->type->list_header(set, data + *used);
|
set->type->list_header(set, data + *used);
|
||||||
*used += set_save->header_size;
|
*used += set_save->header_size;
|
||||||
|
|
||||||
DP("set header filled: %s, used: %u(%u) %p %p", set->name, *used,
|
DP("set header filled: %s, used: %d(%lu) %p %p", set->name, *used,
|
||||||
set_save->header_size, data, data + *used);
|
(unsigned long)set_save->header_size, data, data + *used);
|
||||||
/* Get and ensure set specific members size */
|
/* Get and ensure set specific members size */
|
||||||
set_save->members_size = set->type->list_members_size(set);
|
set_save->members_size = set->type->list_members_size(set);
|
||||||
if (*used + set_save->members_size > len)
|
if (*used + set_save->members_size > len)
|
||||||
@@ -1248,8 +1248,8 @@ static int ip_set_save_set(ip_set_id_t index,
|
|||||||
set->type->list_members(set, data + *used);
|
set->type->list_members(set, data + *used);
|
||||||
*used += set_save->members_size;
|
*used += set_save->members_size;
|
||||||
read_unlock_bh(&set->lock);
|
read_unlock_bh(&set->lock);
|
||||||
DP("set members filled: %s, used: %u(%u) %p %p", set->name, *used,
|
DP("set members filled: %s, used: %d(%lu) %p %p", set->name, *used,
|
||||||
set_save->members_size, data, data + *used);
|
(unsigned long)set_save->members_size, data, data + *used);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unlock_set:
|
unlock_set:
|
||||||
@@ -1329,7 +1329,7 @@ static int ip_set_restore(void *data,
|
|||||||
while (1) {
|
while (1) {
|
||||||
line++;
|
line++;
|
||||||
|
|
||||||
DP("%u %u %u", used, sizeof(struct ip_set_restore), len);
|
DP("%d %zu %d", used, sizeof(struct ip_set_restore), len);
|
||||||
/* Get and ensure header size */
|
/* Get and ensure header size */
|
||||||
if (used + sizeof(struct ip_set_restore) > len)
|
if (used + sizeof(struct ip_set_restore) > len)
|
||||||
return line;
|
return line;
|
||||||
@@ -1367,12 +1367,13 @@ static int ip_set_restore(void *data,
|
|||||||
/* Try to restore members data */
|
/* Try to restore members data */
|
||||||
set = ip_set_list[index];
|
set = ip_set_list[index];
|
||||||
members_size = 0;
|
members_size = 0;
|
||||||
DP("members_size %u reqsize %u",
|
DP("members_size %lu reqsize %lu",
|
||||||
set_restore->members_size, set->type->reqsize);
|
(unsigned long)set_restore->members_size,
|
||||||
|
(unsigned long)set->type->reqsize);
|
||||||
while (members_size + set->type->reqsize <=
|
while (members_size + set->type->reqsize <=
|
||||||
set_restore->members_size) {
|
set_restore->members_size) {
|
||||||
line++;
|
line++;
|
||||||
DP("members: %u, line %u", members_size, line);
|
DP("members: %d, line %d", members_size, line);
|
||||||
res = __ip_set_addip(index,
|
res = __ip_set_addip(index,
|
||||||
data + used + members_size,
|
data + used + members_size,
|
||||||
set->type->reqsize);
|
set->type->reqsize);
|
||||||
@@ -1381,8 +1382,8 @@ static int ip_set_restore(void *data,
|
|||||||
members_size += set->type->reqsize;
|
members_size += set->type->reqsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
DP("members_size %u %u",
|
DP("members_size %lu %d",
|
||||||
set_restore->members_size, members_size);
|
(unsigned long)set_restore->members_size, members_size);
|
||||||
if (members_size != set_restore->members_size)
|
if (members_size != set_restore->members_size)
|
||||||
return line++;
|
return line++;
|
||||||
used += set_restore->members_size;
|
used += set_restore->members_size;
|
||||||
@@ -1442,10 +1443,10 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
|
|||||||
struct ip_set_req_adt *req_adt;
|
struct ip_set_req_adt *req_adt;
|
||||||
ip_set_id_t index = IP_SET_INVALID_ID;
|
ip_set_id_t index = IP_SET_INVALID_ID;
|
||||||
int (*adtfn)(ip_set_id_t index,
|
int (*adtfn)(ip_set_id_t index,
|
||||||
const void *data, size_t size);
|
const void *data, u_int32_t size);
|
||||||
struct fn_table {
|
struct fn_table {
|
||||||
int (*fn)(ip_set_id_t index,
|
int (*fn)(ip_set_id_t index,
|
||||||
const void *data, size_t size);
|
const void *data, u_int32_t size);
|
||||||
} adtfn_table[] =
|
} adtfn_table[] =
|
||||||
{ { ip_set_addip }, { ip_set_delip }, { ip_set_testip},
|
{ { ip_set_addip }, { ip_set_delip }, { ip_set_testip},
|
||||||
{ ip_set_bindip}, { ip_set_unbindip }, { ip_set_testbind },
|
{ ip_set_bindip}, { ip_set_unbindip }, { ip_set_testbind },
|
||||||
@@ -1910,13 +1911,23 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
|||||||
res = -ENOENT;
|
res = -ENOENT;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SETLIST(set) (strcmp(set->type->typename, "setlist") == 0)
|
||||||
|
|
||||||
used = 0;
|
used = 0;
|
||||||
if (index == IP_SET_INVALID_ID) {
|
if (index == IP_SET_INVALID_ID) {
|
||||||
/* Save all sets */
|
/* Save all sets: ugly setlist type dependency */
|
||||||
|
int setlist = 0;
|
||||||
|
setlists:
|
||||||
for (i = 0; i < ip_set_max && res == 0; i++) {
|
for (i = 0; i < ip_set_max && res == 0; i++) {
|
||||||
if (ip_set_list[i] != NULL)
|
if (ip_set_list[i] != NULL
|
||||||
|
&& !(setlist ^ SETLIST(ip_set_list[i])))
|
||||||
res = ip_set_save_set(i, data, &used, *len);
|
res = ip_set_save_set(i, data, &used, *len);
|
||||||
}
|
}
|
||||||
|
if (!setlist) {
|
||||||
|
setlist = 1;
|
||||||
|
goto setlists;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Save an individual set */
|
/* Save an individual set */
|
||||||
res = ip_set_save_set(index, data, &used, *len);
|
res = ip_set_save_set(index, data, &used, *len);
|
||||||
@@ -1938,14 +1949,14 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
|||||||
|
|
||||||
if (*len < sizeof(struct ip_set_req_setnames)
|
if (*len < sizeof(struct ip_set_req_setnames)
|
||||||
|| *len != req_restore->size) {
|
|| *len != req_restore->size) {
|
||||||
ip_set_printk("invalid RESTORE (want =%zu, got %d)",
|
ip_set_printk("invalid RESTORE (want =%lu, got %d)",
|
||||||
req_restore->size, *len);
|
(long unsigned)req_restore->size, *len);
|
||||||
res = -EINVAL;
|
res = -EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
line = ip_set_restore(data + sizeof(struct ip_set_req_setnames),
|
line = ip_set_restore(data + sizeof(struct ip_set_req_setnames),
|
||||||
req_restore->size - sizeof(struct ip_set_req_setnames));
|
req_restore->size - sizeof(struct ip_set_req_setnames));
|
||||||
DP("ip_set_restore: %u", line);
|
DP("ip_set_restore: %d", line);
|
||||||
if (line != 0) {
|
if (line != 0) {
|
||||||
res = -EAGAIN;
|
res = -EAGAIN;
|
||||||
req_restore->size = line;
|
req_restore->size = line;
|
||||||
@@ -1960,7 +1971,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
|||||||
} /* end of switch(op) */
|
} /* end of switch(op) */
|
||||||
|
|
||||||
copy:
|
copy:
|
||||||
DP("set %s, copylen %u", index != IP_SET_INVALID_ID
|
DP("set %s, copylen %d", index != IP_SET_INVALID_ID
|
||||||
&& ip_set_list[index]
|
&& ip_set_list[index]
|
||||||
? ip_set_list[index]->name
|
? ip_set_list[index]->name
|
||||||
: ":all:", copylen);
|
: ":all:", copylen);
|
||||||
@@ -2005,6 +2016,7 @@ static int __init ip_set_init(void)
|
|||||||
int res;
|
int res;
|
||||||
ip_set_id_t i;
|
ip_set_id_t i;
|
||||||
|
|
||||||
|
sema_init(&ip_set_app_mutex, 1);
|
||||||
get_random_bytes(&ip_set_hash_random, 4);
|
get_random_bytes(&ip_set_hash_random, 4);
|
||||||
if (max_sets)
|
if (max_sets)
|
||||||
ip_set_max = max_sets;
|
ip_set_max = max_sets;
|
||||||
|
@@ -48,7 +48,7 @@
|
|||||||
/*
|
/*
|
||||||
* Used so that the kernel module and ipset-binary can match their versions
|
* Used so that the kernel module and ipset-binary can match their versions
|
||||||
*/
|
*/
|
||||||
#define IP_SET_PROTOCOL_VERSION 2
|
#define IP_SET_PROTOCOL_VERSION 3
|
||||||
|
|
||||||
#define IP_SET_MAXNAMELEN 32 /* set names and set typenames */
|
#define IP_SET_MAXNAMELEN 32 /* set names and set typenames */
|
||||||
|
|
||||||
@@ -236,7 +236,7 @@ struct ip_set_req_max_sets {
|
|||||||
struct ip_set_req_setnames {
|
struct ip_set_req_setnames {
|
||||||
unsigned op;
|
unsigned op;
|
||||||
ip_set_id_t index; /* set to list/save */
|
ip_set_id_t index; /* set to list/save */
|
||||||
size_t size; /* size to get setdata/bindings */
|
u_int32_t size; /* size to get setdata/bindings */
|
||||||
/* followed by sets number of struct ip_set_name_list */
|
/* followed by sets number of struct ip_set_name_list */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -258,9 +258,9 @@ struct ip_set_list {
|
|||||||
ip_set_id_t index;
|
ip_set_id_t index;
|
||||||
ip_set_id_t binding;
|
ip_set_id_t binding;
|
||||||
u_int32_t ref;
|
u_int32_t ref;
|
||||||
size_t header_size; /* Set header data of header_size */
|
u_int32_t header_size; /* Set header data of header_size */
|
||||||
size_t members_size; /* Set members data of members_size */
|
u_int32_t members_size; /* Set members data of members_size */
|
||||||
size_t bindings_size; /* Set bindings data of bindings_size */
|
u_int32_t bindings_size;/* Set bindings data of bindings_size */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ip_set_hash_list {
|
struct ip_set_hash_list {
|
||||||
@@ -277,8 +277,8 @@ struct ip_set_hash_list {
|
|||||||
struct ip_set_save {
|
struct ip_set_save {
|
||||||
ip_set_id_t index;
|
ip_set_id_t index;
|
||||||
ip_set_id_t binding;
|
ip_set_id_t binding;
|
||||||
size_t header_size; /* Set header data of header_size */
|
u_int32_t header_size; /* Set header data of header_size */
|
||||||
size_t members_size; /* Set members data of members_size */
|
u_int32_t members_size; /* Set members data of members_size */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* At restoring, ip == 0 means default binding for the given set: */
|
/* At restoring, ip == 0 means default binding for the given set: */
|
||||||
@@ -298,8 +298,8 @@ struct ip_set_restore {
|
|||||||
char name[IP_SET_MAXNAMELEN];
|
char name[IP_SET_MAXNAMELEN];
|
||||||
char typename[IP_SET_MAXNAMELEN];
|
char typename[IP_SET_MAXNAMELEN];
|
||||||
ip_set_id_t index;
|
ip_set_id_t index;
|
||||||
size_t header_size; /* Create data of header_size */
|
u_int32_t header_size; /* Create data of header_size */
|
||||||
size_t members_size; /* Set members data of members_size */
|
u_int32_t members_size; /* Set members data of members_size */
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline int bitmap_bytes(ip_set_ip_t a, ip_set_ip_t b)
|
static inline int bitmap_bytes(ip_set_ip_t a, ip_set_ip_t b)
|
||||||
@@ -366,14 +366,14 @@ struct ip_set_type {
|
|||||||
* return 0 if not in set, 1 if in set.
|
* return 0 if not in set, 1 if in set.
|
||||||
*/
|
*/
|
||||||
int (*testip) (struct ip_set *set,
|
int (*testip) (struct ip_set *set,
|
||||||
const void *data, size_t size,
|
const void *data, u_int32_t size,
|
||||||
ip_set_ip_t *ip);
|
ip_set_ip_t *ip);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Size of the data structure passed by when
|
* Size of the data structure passed by when
|
||||||
* adding/deletin/testing an entry.
|
* adding/deletin/testing an entry.
|
||||||
*/
|
*/
|
||||||
size_t reqsize;
|
u_int32_t reqsize;
|
||||||
|
|
||||||
/* Add IP into set (userspace: ipset -A set IP)
|
/* Add IP into set (userspace: ipset -A set IP)
|
||||||
* Return -EEXIST if the address is already in the set,
|
* Return -EEXIST if the address is already in the set,
|
||||||
@@ -381,7 +381,7 @@ struct ip_set_type {
|
|||||||
* If the address was not already in the set, 0 is returned.
|
* If the address was not already in the set, 0 is returned.
|
||||||
*/
|
*/
|
||||||
int (*addip) (struct ip_set *set,
|
int (*addip) (struct ip_set *set,
|
||||||
const void *data, size_t size,
|
const void *data, u_int32_t size,
|
||||||
ip_set_ip_t *ip);
|
ip_set_ip_t *ip);
|
||||||
|
|
||||||
/* Add IP into set (kernel: iptables ... -j SET set src|dst)
|
/* Add IP into set (kernel: iptables ... -j SET set src|dst)
|
||||||
@@ -401,7 +401,7 @@ struct ip_set_type {
|
|||||||
* If the address really was in the set, 0 is returned.
|
* If the address really was in the set, 0 is returned.
|
||||||
*/
|
*/
|
||||||
int (*delip) (struct ip_set *set,
|
int (*delip) (struct ip_set *set,
|
||||||
const void *data, size_t size,
|
const void *data, u_int32_t size,
|
||||||
ip_set_ip_t *ip);
|
ip_set_ip_t *ip);
|
||||||
|
|
||||||
/* remove IP from set (kernel: iptables ... -j SET --entry x)
|
/* remove IP from set (kernel: iptables ... -j SET --entry x)
|
||||||
@@ -418,7 +418,7 @@ struct ip_set_type {
|
|||||||
/* new set creation - allocated type specific items
|
/* new set creation - allocated type specific items
|
||||||
*/
|
*/
|
||||||
int (*create) (struct ip_set *set,
|
int (*create) (struct ip_set *set,
|
||||||
const void *data, size_t size);
|
const void *data, u_int32_t size);
|
||||||
|
|
||||||
/* retry the operation after successfully tweaking the set
|
/* retry the operation after successfully tweaking the set
|
||||||
*/
|
*/
|
||||||
@@ -437,7 +437,7 @@ struct ip_set_type {
|
|||||||
|
|
||||||
/* Listing: size needed for header
|
/* Listing: size needed for header
|
||||||
*/
|
*/
|
||||||
size_t header_size;
|
u_int32_t header_size;
|
||||||
|
|
||||||
/* Listing: Get the header
|
/* Listing: Get the header
|
||||||
*
|
*
|
||||||
@@ -523,7 +523,7 @@ extern int ip_set_testip_kernel(ip_set_id_t id,
|
|||||||
|
|
||||||
#define UADT0(type, adt, args...) \
|
#define UADT0(type, adt, args...) \
|
||||||
static int \
|
static int \
|
||||||
FNAME(type,_u,adt)(struct ip_set *set, const void *data, size_t size, \
|
FNAME(type,_u,adt)(struct ip_set *set, const void *data, u_int32_t size,\
|
||||||
ip_set_ip_t *hash_ip) \
|
ip_set_ip_t *hash_ip) \
|
||||||
{ \
|
{ \
|
||||||
const STRUCT(ip_set_req_,type) *req = data; \
|
const STRUCT(ip_set_req_,type) *req = data; \
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
#define BITMAP_CREATE(type) \
|
#define BITMAP_CREATE(type) \
|
||||||
static int \
|
static int \
|
||||||
type##_create(struct ip_set *set, const void *data, size_t size) \
|
type##_create(struct ip_set *set, const void *data, u_int32_t size) \
|
||||||
{ \
|
{ \
|
||||||
int newbytes; \
|
int newbytes; \
|
||||||
const struct ip_set_req_##type##_create *req = data; \
|
const struct ip_set_req_##type##_create *req = data; \
|
||||||
@@ -19,8 +19,8 @@ type##_create(struct ip_set *set, const void *data, size_t size) \
|
|||||||
\
|
\
|
||||||
map = kmalloc(sizeof(struct ip_set_##type), GFP_KERNEL); \
|
map = kmalloc(sizeof(struct ip_set_##type), GFP_KERNEL); \
|
||||||
if (!map) { \
|
if (!map) { \
|
||||||
DP("out of memory for %d bytes", \
|
DP("out of memory for %zu bytes", \
|
||||||
sizeof(struct ip_set_#type)); \
|
sizeof(struct ip_set_##type)); \
|
||||||
return -ENOMEM; \
|
return -ENOMEM; \
|
||||||
} \
|
} \
|
||||||
map->first_ip = req->from; \
|
map->first_ip = req->from; \
|
||||||
@@ -35,7 +35,7 @@ type##_create(struct ip_set *set, const void *data, size_t size) \
|
|||||||
map->size = newbytes; \
|
map->size = newbytes; \
|
||||||
map->members = ip_set_malloc(newbytes); \
|
map->members = ip_set_malloc(newbytes); \
|
||||||
if (!map->members) { \
|
if (!map->members) { \
|
||||||
DP("out of memory for %d bytes", newbytes); \
|
DP("out of memory for %i bytes", newbytes); \
|
||||||
kfree(map); \
|
kfree(map); \
|
||||||
return -ENOMEM; \
|
return -ENOMEM; \
|
||||||
} \
|
} \
|
||||||
|
@@ -58,6 +58,7 @@ static inline void *kzalloc(size_t size, gfp_t flags)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
|
||||||
|
#include <linux/netfilter.h>
|
||||||
#define KMEM_CACHE_CREATE(name, size) \
|
#define KMEM_CACHE_CREATE(name, size) \
|
||||||
kmem_cache_create(name, size, 0, 0, NULL, NULL)
|
kmem_cache_create(name, size, 0, 0, NULL, NULL)
|
||||||
#else
|
#else
|
||||||
|
@@ -28,20 +28,22 @@ type##_retry(struct ip_set *set) \
|
|||||||
hashsize++; \
|
hashsize++; \
|
||||||
\
|
\
|
||||||
ip_set_printk("rehashing of set %s triggered: " \
|
ip_set_printk("rehashing of set %s triggered: " \
|
||||||
"hashsize grows from %u to %u", \
|
"hashsize grows from %lu to %lu", \
|
||||||
set->name, map->hashsize, hashsize); \
|
set->name, \
|
||||||
|
(long unsigned)map->hashsize, \
|
||||||
|
(long unsigned)hashsize); \
|
||||||
\
|
\
|
||||||
tmp = kmalloc(sizeof(struct ip_set_##type) \
|
tmp = kmalloc(sizeof(struct ip_set_##type) \
|
||||||
+ map->probes * sizeof(initval_t), GFP_ATOMIC); \
|
+ map->probes * sizeof(initval_t), GFP_ATOMIC); \
|
||||||
if (!tmp) { \
|
if (!tmp) { \
|
||||||
DP("out of memory for %d bytes", \
|
DP("out of memory for %zu bytes", \
|
||||||
sizeof(struct ip_set_##type) \
|
sizeof(struct ip_set_##type) \
|
||||||
+ map->probes * sizeof(initval_t)); \
|
+ map->probes * sizeof(initval_t)); \
|
||||||
return -ENOMEM; \
|
return -ENOMEM; \
|
||||||
} \
|
} \
|
||||||
tmp->members = harray_malloc(hashsize, sizeof(dtype), GFP_ATOMIC);\
|
tmp->members = harray_malloc(hashsize, sizeof(dtype), GFP_ATOMIC);\
|
||||||
if (!tmp->members) { \
|
if (!tmp->members) { \
|
||||||
DP("out of memory for %d bytes", hashsize * sizeof(dtype));\
|
DP("out of memory for %zu bytes", hashsize * sizeof(dtype));\
|
||||||
kfree(tmp); \
|
kfree(tmp); \
|
||||||
return -ENOMEM; \
|
return -ENOMEM; \
|
||||||
} \
|
} \
|
||||||
@@ -88,7 +90,7 @@ type##_retry(struct ip_set *set) \
|
|||||||
|
|
||||||
#define HASH_CREATE(type, dtype) \
|
#define HASH_CREATE(type, dtype) \
|
||||||
static int \
|
static int \
|
||||||
type##_create(struct ip_set *set, const void *data, size_t size) \
|
type##_create(struct ip_set *set, const void *data, u_int32_t size) \
|
||||||
{ \
|
{ \
|
||||||
const struct ip_set_req_##type##_create *req = data; \
|
const struct ip_set_req_##type##_create *req = data; \
|
||||||
struct ip_set_##type *map; \
|
struct ip_set_##type *map; \
|
||||||
@@ -107,7 +109,7 @@ type##_create(struct ip_set *set, const void *data, size_t size) \
|
|||||||
map = kmalloc(sizeof(struct ip_set_##type) \
|
map = kmalloc(sizeof(struct ip_set_##type) \
|
||||||
+ req->probes * sizeof(initval_t), GFP_KERNEL); \
|
+ req->probes * sizeof(initval_t), GFP_KERNEL); \
|
||||||
if (!map) { \
|
if (!map) { \
|
||||||
DP("out of memory for %d bytes", \
|
DP("out of memory for %zu bytes", \
|
||||||
sizeof(struct ip_set_##type) \
|
sizeof(struct ip_set_##type) \
|
||||||
+ req->probes * sizeof(initval_t)); \
|
+ req->probes * sizeof(initval_t)); \
|
||||||
return -ENOMEM; \
|
return -ENOMEM; \
|
||||||
@@ -124,7 +126,7 @@ type##_create(struct ip_set *set, const void *data, size_t size) \
|
|||||||
} \
|
} \
|
||||||
map->members = harray_malloc(map->hashsize, sizeof(dtype), GFP_KERNEL);\
|
map->members = harray_malloc(map->hashsize, sizeof(dtype), GFP_KERNEL);\
|
||||||
if (!map->members) { \
|
if (!map->members) { \
|
||||||
DP("out of memory for %d bytes", map->hashsize * sizeof(dtype));\
|
DP("out of memory for %zu bytes", map->hashsize * sizeof(dtype));\
|
||||||
kfree(map); \
|
kfree(map); \
|
||||||
return -ENOMEM; \
|
return -ENOMEM; \
|
||||||
} \
|
} \
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/jhash.h>
|
#include "ip_set_jhash.h"
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/bitops.h>
|
#include <asm/bitops.h>
|
||||||
@@ -42,8 +42,7 @@ iphash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
|||||||
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
|
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
|
||||||
if (*elem == *hash_ip)
|
if (*elem == *hash_ip)
|
||||||
return id;
|
return id;
|
||||||
/* No shortcut at testing - there can be deleted
|
/* No shortcut - there can be deleted entries. */
|
||||||
* entries. */
|
|
||||||
}
|
}
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
@@ -64,19 +63,22 @@ __iphash_add(struct ip_set_iphash *map, ip_set_ip_t *ip)
|
|||||||
{
|
{
|
||||||
__u32 probe;
|
__u32 probe;
|
||||||
u_int16_t i;
|
u_int16_t i;
|
||||||
ip_set_ip_t *elem;
|
ip_set_ip_t *elem, *slot = NULL;
|
||||||
|
|
||||||
for (i = 0; i < map->probes; i++) {
|
for (i = 0; i < map->probes; i++) {
|
||||||
probe = jhash_ip(map, i, *ip) % map->hashsize;
|
probe = jhash_ip(map, i, *ip) % map->hashsize;
|
||||||
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, probe);
|
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, probe);
|
||||||
if (*elem == *ip)
|
if (*elem == *ip)
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
if (!*elem) {
|
if (!(slot || *elem))
|
||||||
*elem = *ip;
|
slot = elem;
|
||||||
|
/* There can be deleted entries, must check all slots */
|
||||||
|
}
|
||||||
|
if (slot) {
|
||||||
|
*slot = *ip;
|
||||||
map->elements++;
|
map->elements++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/* Trigger rehashing */
|
/* Trigger rehashing */
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
@@ -13,7 +13,7 @@ struct ip_set_ipmap {
|
|||||||
ip_set_ip_t netmask; /* subnet netmask */
|
ip_set_ip_t netmask; /* subnet netmask */
|
||||||
ip_set_ip_t sizeid; /* size of set in IPs */
|
ip_set_ip_t sizeid; /* size of set in IPs */
|
||||||
ip_set_ip_t hosts; /* number of hosts in a subnet */
|
ip_set_ip_t hosts; /* number of hosts in a subnet */
|
||||||
size_t size; /* size of the ipmap proper */
|
u_int32_t size; /* size of the ipmap proper */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ip_set_req_ipmap_create {
|
struct ip_set_req_ipmap_create {
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
#include <linux/tcp.h>
|
#include <linux/tcp.h>
|
||||||
#include <linux/udp.h>
|
#include <linux/udp.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/jhash.h>
|
#include "ip_set_jhash.h"
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/bitops.h>
|
#include <asm/bitops.h>
|
||||||
@@ -49,8 +49,7 @@ ipporthash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
|
|||||||
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
|
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
|
||||||
if (*elem == *hash_ip)
|
if (*elem == *hash_ip)
|
||||||
return id;
|
return id;
|
||||||
/* No shortcut at testing - there can be deleted
|
/* No shortcut - there can be deleted entries. */
|
||||||
* entries. */
|
|
||||||
}
|
}
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
@@ -86,19 +85,22 @@ __ipporthash_add(struct ip_set_ipporthash *map, ip_set_ip_t *ip)
|
|||||||
{
|
{
|
||||||
__u32 probe;
|
__u32 probe;
|
||||||
u_int16_t i;
|
u_int16_t i;
|
||||||
ip_set_ip_t *elem;
|
ip_set_ip_t *elem, *slot = NULL;
|
||||||
|
|
||||||
for (i = 0; i < map->probes; i++) {
|
for (i = 0; i < map->probes; i++) {
|
||||||
probe = jhash_ip(map, i, *ip) % map->hashsize;
|
probe = jhash_ip(map, i, *ip) % map->hashsize;
|
||||||
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, probe);
|
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, probe);
|
||||||
if (*elem == *ip)
|
if (*elem == *ip)
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
if (!*elem) {
|
if (!(slot || *elem))
|
||||||
*elem = *ip;
|
slot = elem;
|
||||||
|
/* There can be deleted entries, must check all slots */
|
||||||
|
}
|
||||||
|
if (slot) {
|
||||||
|
*slot = *ip;
|
||||||
map->elements++;
|
map->elements++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/* Trigger rehashing */
|
/* Trigger rehashing */
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
#include <linux/tcp.h>
|
#include <linux/tcp.h>
|
||||||
#include <linux/udp.h>
|
#include <linux/udp.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/jhash.h>
|
#include "ip_set_jhash.h"
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/bitops.h>
|
#include <asm/bitops.h>
|
||||||
@@ -51,8 +51,7 @@ ipportiphash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
|
|||||||
elem = HARRAY_ELEM(map->members, struct ipportip *, id);
|
elem = HARRAY_ELEM(map->members, struct ipportip *, id);
|
||||||
if (elem->ip == *hash_ip && elem->ip1 == ip1)
|
if (elem->ip == *hash_ip && elem->ip1 == ip1)
|
||||||
return id;
|
return id;
|
||||||
/* No shortcut at testing - there can be deleted
|
/* No shortcut - there can be deleted entries. */
|
||||||
* entries. */
|
|
||||||
}
|
}
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
@@ -90,20 +89,23 @@ __ipportip_add(struct ip_set_ipportiphash *map,
|
|||||||
{
|
{
|
||||||
__u32 probe;
|
__u32 probe;
|
||||||
u_int16_t i;
|
u_int16_t i;
|
||||||
struct ipportip *elem;
|
struct ipportip *elem, *slot = NULL;
|
||||||
|
|
||||||
for (i = 0; i < map->probes; i++) {
|
for (i = 0; i < map->probes; i++) {
|
||||||
probe = jhash_ip2(map, i, hash_ip, ip1) % map->hashsize;
|
probe = jhash_ip2(map, i, hash_ip, ip1) % map->hashsize;
|
||||||
elem = HARRAY_ELEM(map->members, struct ipportip *, probe);
|
elem = HARRAY_ELEM(map->members, struct ipportip *, probe);
|
||||||
if (elem->ip == hash_ip && elem->ip1 == ip1)
|
if (elem->ip == hash_ip && elem->ip1 == ip1)
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
if (!(elem->ip || elem->ip1)) {
|
if (!(slot || elem->ip || elem->ip1))
|
||||||
elem->ip = hash_ip;
|
slot = elem;
|
||||||
elem->ip1 = ip1;
|
/* There can be deleted entries, must check all slots */
|
||||||
|
}
|
||||||
|
if (slot) {
|
||||||
|
slot->ip = hash_ip;
|
||||||
|
slot->ip1 = ip1;
|
||||||
map->elements++;
|
map->elements++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/* Trigger rehashing */
|
/* Trigger rehashing */
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
#include <linux/tcp.h>
|
#include <linux/tcp.h>
|
||||||
#include <linux/udp.h>
|
#include <linux/udp.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/jhash.h>
|
#include "ip_set_jhash.h"
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/bitops.h>
|
#include <asm/bitops.h>
|
||||||
@@ -53,8 +53,7 @@ ipportnethash_id_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
|
|||||||
elem = HARRAY_ELEM(map->members, struct ipportip *, id);
|
elem = HARRAY_ELEM(map->members, struct ipportip *, id);
|
||||||
if (elem->ip == *hash_ip && elem->ip1 == ip1)
|
if (elem->ip == *hash_ip && elem->ip1 == ip1)
|
||||||
return id;
|
return id;
|
||||||
/* No shortcut at testing - there can be deleted
|
/* No shortcut - there can be deleted entries. */
|
||||||
* entries. */
|
|
||||||
}
|
}
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
@@ -103,7 +102,7 @@ ipportnethash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ipportnethash_utest(struct ip_set *set, const void *data, size_t size,
|
ipportnethash_utest(struct ip_set *set, const void *data, u_int32_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
const struct ip_set_req_ipportnethash *req = data;
|
const struct ip_set_req_ipportnethash *req = data;
|
||||||
@@ -137,20 +136,23 @@ __ipportnet_add(struct ip_set_ipportnethash *map,
|
|||||||
{
|
{
|
||||||
__u32 probe;
|
__u32 probe;
|
||||||
u_int16_t i;
|
u_int16_t i;
|
||||||
struct ipportip *elem;
|
struct ipportip *elem, *slot = NULL;
|
||||||
|
|
||||||
for (i = 0; i < map->probes; i++) {
|
for (i = 0; i < map->probes; i++) {
|
||||||
probe = jhash_ip2(map, i, hash_ip, ip1) % map->hashsize;
|
probe = jhash_ip2(map, i, hash_ip, ip1) % map->hashsize;
|
||||||
elem = HARRAY_ELEM(map->members, struct ipportip *, probe);
|
elem = HARRAY_ELEM(map->members, struct ipportip *, probe);
|
||||||
if (elem->ip == hash_ip && elem->ip1 == ip1)
|
if (elem->ip == hash_ip && elem->ip1 == ip1)
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
if (!(elem->ip || elem->ip1)) {
|
if (!(slot || elem->ip || elem->ip1))
|
||||||
elem->ip = hash_ip;
|
slot = elem;
|
||||||
elem->ip1 = ip1;
|
/* There can be deleted entries, must check all slots */
|
||||||
|
}
|
||||||
|
if (slot) {
|
||||||
|
slot->ip = hash_ip;
|
||||||
|
slot->ip1 = ip1;
|
||||||
map->elements++;
|
map->elements++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/* Trigger rehashing */
|
/* Trigger rehashing */
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
|
#include <linux/jiffies.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
@@ -276,21 +277,21 @@ init_gc_timer(struct ip_set *set)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
iptree_create(struct ip_set *set, const void *data, size_t size)
|
iptree_create(struct ip_set *set, const void *data, u_int32_t size)
|
||||||
{
|
{
|
||||||
const struct ip_set_req_iptree_create *req = data;
|
const struct ip_set_req_iptree_create *req = data;
|
||||||
struct ip_set_iptree *map;
|
struct ip_set_iptree *map;
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_iptree_create)) {
|
if (size != sizeof(struct ip_set_req_iptree_create)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %lu)",
|
||||||
sizeof(struct ip_set_req_iptree_create),
|
sizeof(struct ip_set_req_iptree_create),
|
||||||
size);
|
(unsigned long)size);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
map = kmalloc(sizeof(struct ip_set_iptree), GFP_KERNEL);
|
map = kmalloc(sizeof(struct ip_set_iptree), GFP_KERNEL);
|
||||||
if (!map) {
|
if (!map) {
|
||||||
DP("out of memory for %d bytes",
|
DP("out of memory for %zu bytes",
|
||||||
sizeof(struct ip_set_iptree));
|
sizeof(struct ip_set_iptree));
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
|
#include <linux/jiffies.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
@@ -338,7 +339,7 @@ KADT(iptreemap, add, ipaddr, ip)
|
|||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
__delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
|
__delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||||
ip_set_ip_t ip, unsigned int __nocast flags)
|
ip_set_ip_t ip, gfp_t flags)
|
||||||
{
|
{
|
||||||
struct ip_set_iptreemap *map = set->data;
|
struct ip_set_iptreemap *map = set->data;
|
||||||
struct ip_set_iptreemap_b *btree;
|
struct ip_set_iptreemap_b *btree;
|
||||||
@@ -364,7 +365,7 @@ __delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
|
|||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
iptreemap_del(struct ip_set *set, ip_set_ip_t *hash_ip,
|
iptreemap_del(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||||
ip_set_ip_t start, ip_set_ip_t end, unsigned int __nocast flags)
|
ip_set_ip_t start, ip_set_ip_t end, gfp_t flags)
|
||||||
{
|
{
|
||||||
struct ip_set_iptreemap *map = set->data;
|
struct ip_set_iptreemap *map = set->data;
|
||||||
struct ip_set_iptreemap_b *btree;
|
struct ip_set_iptreemap_b *btree;
|
||||||
@@ -470,7 +471,7 @@ init_gc_timer(struct ip_set *set)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
iptreemap_create(struct ip_set *set, const void *data, size_t size)
|
iptreemap_create(struct ip_set *set, const void *data, u_int32_t size)
|
||||||
{
|
{
|
||||||
const struct ip_set_req_iptreemap_create *req = data;
|
const struct ip_set_req_iptreemap_create *req = data;
|
||||||
struct ip_set_iptreemap *map;
|
struct ip_set_iptreemap *map;
|
||||||
@@ -567,7 +568,7 @@ iptreemap_list_members_size(const struct ip_set *set)
|
|||||||
return (count * sizeof(struct ip_set_req_iptreemap));
|
return (count * sizeof(struct ip_set_req_iptreemap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t
|
static inline u_int32_t
|
||||||
add_member(void *data, size_t offset, ip_set_ip_t start, ip_set_ip_t end)
|
add_member(void *data, size_t offset, ip_set_ip_t start, ip_set_ip_t end)
|
||||||
{
|
{
|
||||||
struct ip_set_req_iptreemap *entry = data + offset;
|
struct ip_set_req_iptreemap *entry = data + offset;
|
||||||
|
@@ -1,148 +1,157 @@
|
|||||||
#ifndef _LINUX_IPSET_JHASH_H
|
#ifndef _LINUX_JHASH_H
|
||||||
#define _LINUX_IPSET_JHASH_H
|
#define _LINUX_JHASH_H
|
||||||
|
|
||||||
/* This is a copy of linux/jhash.h but the types u32/u8 are changed
|
|
||||||
* to __u32/__u8 so that the header file can be included into
|
|
||||||
* userspace code as well. Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* jhash.h: Jenkins hash support.
|
/* jhash.h: Jenkins hash support.
|
||||||
*
|
*
|
||||||
* Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net)
|
* Copyright (C) 2006. Bob Jenkins (bob_jenkins@burtleburtle.net)
|
||||||
*
|
*
|
||||||
* http://burtleburtle.net/bob/hash/
|
* http://burtleburtle.net/bob/hash/
|
||||||
*
|
*
|
||||||
* These are the credits from Bob's sources:
|
* These are the credits from Bob's sources:
|
||||||
*
|
*
|
||||||
* lookup2.c, by Bob Jenkins, December 1996, Public Domain.
|
* lookup3.c, by Bob Jenkins, May 2006, Public Domain.
|
||||||
* hash(), hash2(), hash3, and mix() are externally useful functions.
|
|
||||||
* Routines to test the hash are included if SELF_TEST is defined.
|
|
||||||
* You can use this free for any purpose. It has no warranty.
|
|
||||||
*
|
*
|
||||||
* Copyright (C) 2003 David S. Miller (davem@redhat.com)
|
* These are functions for producing 32-bit hashes for hash table lookup.
|
||||||
|
* hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
|
||||||
|
* are externally useful functions. Routines to test the hash are included
|
||||||
|
* if SELF_TEST is defined. You can use this free for any purpose. It's in
|
||||||
|
* the public domain. It has no warranty.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
|
||||||
*
|
*
|
||||||
* I've modified Bob's hash to be useful in the Linux kernel, and
|
* I've modified Bob's hash to be useful in the Linux kernel, and
|
||||||
* any bugs present are surely my fault. -DaveM
|
* any bugs present are my fault. Jozsef
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* NOTE: Arguments are modified. */
|
#define __rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
|
||||||
|
|
||||||
|
/* __jhash_mix - mix 3 32-bit values reversibly. */
|
||||||
#define __jhash_mix(a,b,c) \
|
#define __jhash_mix(a,b,c) \
|
||||||
{ \
|
{ \
|
||||||
a -= b; a -= c; a ^= (c>>13); \
|
a -= c; a ^= __rot(c, 4); c += b; \
|
||||||
b -= c; b -= a; b ^= (a<<8); \
|
b -= a; b ^= __rot(a, 6); a += c; \
|
||||||
c -= a; c -= b; c ^= (b>>13); \
|
c -= b; c ^= __rot(b, 8); b += a; \
|
||||||
a -= b; a -= c; a ^= (c>>12); \
|
a -= c; a ^= __rot(c,16); c += b; \
|
||||||
b -= c; b -= a; b ^= (a<<16); \
|
b -= a; b ^= __rot(a,19); a += c; \
|
||||||
c -= a; c -= b; c ^= (b>>5); \
|
c -= b; c ^= __rot(b, 4); b += a; \
|
||||||
a -= b; a -= c; a ^= (c>>3); \
|
}
|
||||||
b -= c; b -= a; b ^= (a<<10); \
|
|
||||||
c -= a; c -= b; c ^= (b>>15); \
|
/* __jhash_final - final mixing of 3 32-bit values (a,b,c) into c */
|
||||||
|
#define __jhash_final(a,b,c) \
|
||||||
|
{ \
|
||||||
|
c ^= b; c -= __rot(b,14); \
|
||||||
|
a ^= c; a -= __rot(c,11); \
|
||||||
|
b ^= a; b -= __rot(a,25); \
|
||||||
|
c ^= b; c -= __rot(b,16); \
|
||||||
|
a ^= c; a -= __rot(c,4); \
|
||||||
|
b ^= a; b -= __rot(a,14); \
|
||||||
|
c ^= b; c -= __rot(b,24); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The golden ration: an arbitrary value */
|
/* The golden ration: an arbitrary value */
|
||||||
#define JHASH_GOLDEN_RATIO 0x9e3779b9
|
#define JHASH_GOLDEN_RATIO 0xdeadbeef
|
||||||
|
|
||||||
/* The most generic version, hashes an arbitrary sequence
|
/* The most generic version, hashes an arbitrary sequence
|
||||||
* of bytes. No alignment or length assumptions are made about
|
* of bytes. No alignment or length assumptions are made about
|
||||||
* the input key.
|
* the input key. The result depends on endianness.
|
||||||
*/
|
*/
|
||||||
static inline __u32 jhash(void *key, __u32 length, __u32 initval)
|
static inline u32 jhash(const void *key, u32 length, u32 initval)
|
||||||
{
|
{
|
||||||
__u32 a, b, c, len;
|
u32 a,b,c;
|
||||||
__u8 *k = key;
|
const u8 *k = key;
|
||||||
|
|
||||||
len = length;
|
/* Set up the internal state */
|
||||||
a = b = JHASH_GOLDEN_RATIO;
|
a = b = c = JHASH_GOLDEN_RATIO + length + initval;
|
||||||
c = initval;
|
|
||||||
|
|
||||||
while (len >= 12) {
|
|
||||||
a += (k[0] +((__u32)k[1]<<8) +((__u32)k[2]<<16) +((__u32)k[3]<<24));
|
|
||||||
b += (k[4] +((__u32)k[5]<<8) +((__u32)k[6]<<16) +((__u32)k[7]<<24));
|
|
||||||
c += (k[8] +((__u32)k[9]<<8) +((__u32)k[10]<<16)+((__u32)k[11]<<24));
|
|
||||||
|
|
||||||
|
/* all but the last block: affect some 32 bits of (a,b,c) */
|
||||||
|
while (length > 12) {
|
||||||
|
a += (k[0] + ((u32)k[1]<<8) + ((u32)k[2]<<16) + ((u32)k[3]<<24));
|
||||||
|
b += (k[4] + ((u32)k[5]<<8) + ((u32)k[6]<<16) + ((u32)k[7]<<24));
|
||||||
|
c += (k[8] + ((u32)k[9]<<8) + ((u32)k[10]<<16) + ((u32)k[11]<<24));
|
||||||
__jhash_mix(a, b, c);
|
__jhash_mix(a, b, c);
|
||||||
|
length -= 12;
|
||||||
k += 12;
|
k += 12;
|
||||||
len -= 12;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c += length;
|
/* last block: affect all 32 bits of (c) */
|
||||||
switch (len) {
|
/* all the case statements fall through */
|
||||||
case 11: c += ((__u32)k[10]<<24);
|
switch (length) {
|
||||||
case 10: c += ((__u32)k[9]<<16);
|
case 12: c += (u32)k[11]<<24;
|
||||||
case 9 : c += ((__u32)k[8]<<8);
|
case 11: c += (u32)k[10]<<16;
|
||||||
case 8 : b += ((__u32)k[7]<<24);
|
case 10: c += (u32)k[9]<<8;
|
||||||
case 7 : b += ((__u32)k[6]<<16);
|
case 9 : c += k[8];
|
||||||
case 6 : b += ((__u32)k[5]<<8);
|
case 8 : b += (u32)k[7]<<24;
|
||||||
|
case 7 : b += (u32)k[6]<<16;
|
||||||
|
case 6 : b += (u32)k[5]<<8;
|
||||||
case 5 : b += k[4];
|
case 5 : b += k[4];
|
||||||
case 4 : a += ((__u32)k[3]<<24);
|
case 4 : a += (u32)k[3]<<24;
|
||||||
case 3 : a += ((__u32)k[2]<<16);
|
case 3 : a += (u32)k[2]<<16;
|
||||||
case 2 : a += ((__u32)k[1]<<8);
|
case 2 : a += (u32)k[1]<<8;
|
||||||
case 1 : a += k[0];
|
case 1 : a += k[0];
|
||||||
};
|
__jhash_final(a, b, c);
|
||||||
|
case 0 :
|
||||||
__jhash_mix(a,b,c);
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A special optimized version that handles 1 or more of __u32s.
|
/* A special optimized version that handles 1 or more of u32s.
|
||||||
* The length parameter here is the number of __u32s in the key.
|
* The length parameter here is the number of u32s in the key.
|
||||||
*/
|
*/
|
||||||
static inline __u32 jhash2(__u32 *k, __u32 length, __u32 initval)
|
static inline u32 jhash2(const u32 *k, u32 length, u32 initval)
|
||||||
{
|
{
|
||||||
__u32 a, b, c, len;
|
u32 a, b, c;
|
||||||
|
|
||||||
a = b = JHASH_GOLDEN_RATIO;
|
/* Set up the internal state */
|
||||||
c = initval;
|
a = b = c = JHASH_GOLDEN_RATIO + (length<<2) + initval;
|
||||||
len = length;
|
|
||||||
|
|
||||||
while (len >= 3) {
|
/* handle most of the key */
|
||||||
|
while (length > 3) {
|
||||||
a += k[0];
|
a += k[0];
|
||||||
b += k[1];
|
b += k[1];
|
||||||
c += k[2];
|
c += k[2];
|
||||||
__jhash_mix(a, b, c);
|
__jhash_mix(a, b, c);
|
||||||
k += 3; len -= 3;
|
length -= 3;
|
||||||
|
k += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
c += length * 4;
|
/* handle the last 3 u32's */
|
||||||
|
/* all the case statements fall through */
|
||||||
switch (len) {
|
switch (length) {
|
||||||
|
case 3: c += k[2];
|
||||||
case 2: b += k[1];
|
case 2: b += k[1];
|
||||||
case 1: a += k[0];
|
case 1: a += k[0];
|
||||||
};
|
__jhash_final(a, b, c);
|
||||||
|
case 0: /* case 0: nothing left to add */
|
||||||
__jhash_mix(a,b,c);
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* A special ultra-optimized versions that knows they are hashing exactly
|
/* A special ultra-optimized versions that knows they are hashing exactly
|
||||||
* 3, 2 or 1 word(s).
|
* 3, 2 or 1 word(s).
|
||||||
*
|
|
||||||
* NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally
|
|
||||||
* done at the end is not done here.
|
|
||||||
*/
|
*/
|
||||||
static inline __u32 jhash_3words(__u32 a, __u32 b, __u32 c, __u32 initval)
|
static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval)
|
||||||
{
|
{
|
||||||
a += JHASH_GOLDEN_RATIO;
|
a += JHASH_GOLDEN_RATIO + initval;
|
||||||
b += JHASH_GOLDEN_RATIO;
|
b += JHASH_GOLDEN_RATIO + initval;
|
||||||
c += initval;
|
c += JHASH_GOLDEN_RATIO + initval;
|
||||||
|
|
||||||
__jhash_mix(a, b, c);
|
__jhash_final(a, b, c);
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline __u32 jhash_2words(__u32 a, __u32 b, __u32 initval)
|
static inline u32 jhash_2words(u32 a, u32 b, u32 initval)
|
||||||
{
|
{
|
||||||
return jhash_3words(a, b, 0, initval);
|
return jhash_3words(0, a, b, initval);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline __u32 jhash_1word(__u32 a, __u32 initval)
|
static inline u32 jhash_1word(u32 a, u32 initval)
|
||||||
{
|
{
|
||||||
return jhash_3words(a, 0, 0, initval);
|
return jhash_3words(0, 0, a, initval);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _LINUX_IPSET_JHASH_H */
|
#endif /* _LINUX_JHASH_H */
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
#include "ip_set_macipmap.h"
|
#include "ip_set_macipmap.h"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
macipmap_utest(struct ip_set *set, const void *data, size_t size,
|
macipmap_utest(struct ip_set *set, const void *data, u_int32_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
const struct ip_set_macipmap *map = set->data;
|
const struct ip_set_macipmap *map = set->data;
|
||||||
@@ -35,8 +35,7 @@ macipmap_utest(struct ip_set *set, const void *data, size_t size,
|
|||||||
*hash_ip = req->ip;
|
*hash_ip = req->ip;
|
||||||
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
|
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
|
||||||
set->name, HIPQUAD(req->ip), HIPQUAD(*hash_ip));
|
set->name, HIPQUAD(req->ip), HIPQUAD(*hash_ip));
|
||||||
if (test_bit(IPSET_MACIP_ISSET,
|
if (table[req->ip - map->first_ip].match) {
|
||||||
(void *) &table[req->ip - map->first_ip].flags)) {
|
|
||||||
return (memcmp(req->ethernet,
|
return (memcmp(req->ethernet,
|
||||||
&table[req->ip - map->first_ip].ethernet,
|
&table[req->ip - map->first_ip].ethernet,
|
||||||
ETH_ALEN) == 0);
|
ETH_ALEN) == 0);
|
||||||
@@ -64,8 +63,7 @@ macipmap_ktest(struct ip_set *set,
|
|||||||
*hash_ip = ip;
|
*hash_ip = ip;
|
||||||
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
|
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
|
||||||
set->name, HIPQUAD(ip), HIPQUAD(*hash_ip));
|
set->name, HIPQUAD(ip), HIPQUAD(*hash_ip));
|
||||||
if (test_bit(IPSET_MACIP_ISSET,
|
if (table[ip - map->first_ip].match) {
|
||||||
(void *) &table[ip - map->first_ip].flags)) {
|
|
||||||
/* Is mac pointer valid?
|
/* Is mac pointer valid?
|
||||||
* If so, compare... */
|
* If so, compare... */
|
||||||
return (skb_mac_header(skb) >= skb->head
|
return (skb_mac_header(skb) >= skb->head
|
||||||
@@ -88,13 +86,13 @@ macipmap_add(struct ip_set *set, ip_set_ip_t *hash_ip,
|
|||||||
|
|
||||||
if (ip < map->first_ip || ip > map->last_ip)
|
if (ip < map->first_ip || ip > map->last_ip)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
if (test_and_set_bit(IPSET_MACIP_ISSET,
|
if (table[ip - map->first_ip].match)
|
||||||
(void *) &table[ip - map->first_ip].flags))
|
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
*hash_ip = ip;
|
*hash_ip = ip;
|
||||||
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
|
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
|
||||||
memcpy(&table[ip - map->first_ip].ethernet, ethernet, ETH_ALEN);
|
memcpy(&table[ip - map->first_ip].ethernet, ethernet, ETH_ALEN);
|
||||||
|
table[ip - map->first_ip].match = IPSET_MACIP_ISSET;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,11 +112,11 @@ macipmap_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
|||||||
|
|
||||||
if (ip < map->first_ip || ip > map->last_ip)
|
if (ip < map->first_ip || ip > map->last_ip)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
if (!test_and_clear_bit(IPSET_MACIP_ISSET,
|
if (!table[ip - map->first_ip].match)
|
||||||
(void *)&table[ip - map->first_ip].flags))
|
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
*hash_ip = ip;
|
*hash_ip = ip;
|
||||||
|
table[ip - map->first_ip].match = 0;
|
||||||
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
|
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,7 @@ struct ip_set_macipmap {
|
|||||||
ip_set_ip_t first_ip; /* host byte order, included in range */
|
ip_set_ip_t first_ip; /* host byte order, included in range */
|
||||||
ip_set_ip_t last_ip; /* host byte order, included in range */
|
ip_set_ip_t last_ip; /* host byte order, included in range */
|
||||||
u_int32_t flags;
|
u_int32_t flags;
|
||||||
size_t size; /* size of the ipmap proper */
|
u_int32_t size; /* size of the ipmap proper */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ip_set_req_macipmap_create {
|
struct ip_set_req_macipmap_create {
|
||||||
@@ -32,7 +32,7 @@ struct ip_set_req_macipmap {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ip_set_macip {
|
struct ip_set_macip {
|
||||||
unsigned short flags;
|
unsigned short match;
|
||||||
unsigned char ethernet[ETH_ALEN];
|
unsigned char ethernet[ETH_ALEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -40,7 +40,7 @@ struct harray {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static inline void *
|
static inline void *
|
||||||
__harray_malloc(size_t hashsize, size_t typesize, int flags)
|
__harray_malloc(size_t hashsize, size_t typesize, gfp_t flags)
|
||||||
{
|
{
|
||||||
struct harray *harray;
|
struct harray *harray;
|
||||||
size_t max_elements, size, i, j;
|
size_t max_elements, size, i, j;
|
||||||
@@ -88,7 +88,7 @@ __harray_malloc(size_t hashsize, size_t typesize, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void *
|
static inline void *
|
||||||
harray_malloc(size_t hashsize, size_t typesize, int flags)
|
harray_malloc(size_t hashsize, size_t typesize, gfp_t flags)
|
||||||
{
|
{
|
||||||
void *harray;
|
void *harray;
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/jhash.h>
|
#include "ip_set_jhash.h"
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/bitops.h>
|
#include <asm/bitops.h>
|
||||||
@@ -44,6 +44,7 @@ nethash_id_cidr(const struct ip_set_nethash *map,
|
|||||||
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
|
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
|
||||||
if (*elem == *hash_ip)
|
if (*elem == *hash_ip)
|
||||||
return id;
|
return id;
|
||||||
|
/* No shortcut - there can be deleted entries. */
|
||||||
}
|
}
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
@@ -79,7 +80,7 @@ nethash_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nethash_utest(struct ip_set *set, const void *data, size_t size,
|
nethash_utest(struct ip_set *set, const void *data, u_int32_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
const struct ip_set_req_nethash *req = data;
|
const struct ip_set_req_nethash *req = data;
|
||||||
@@ -99,17 +100,21 @@ __nethash_add(struct ip_set_nethash *map, ip_set_ip_t *ip)
|
|||||||
{
|
{
|
||||||
__u32 probe;
|
__u32 probe;
|
||||||
u_int16_t i;
|
u_int16_t i;
|
||||||
ip_set_ip_t *elem;
|
ip_set_ip_t *elem, *slot = NULL;
|
||||||
|
|
||||||
for (i = 0; i < map->probes; i++) {
|
for (i = 0; i < map->probes; i++) {
|
||||||
probe = jhash_ip(map, i, *ip) % map->hashsize;
|
probe = jhash_ip(map, i, *ip) % map->hashsize;
|
||||||
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, probe);
|
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, probe);
|
||||||
if (*elem == *ip)
|
if (*elem == *ip)
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
if (!*elem) {
|
if (!(slot || *elem))
|
||||||
*elem = *ip;
|
slot = elem;
|
||||||
return 0;
|
/* There can be deleted entries, must check all slots */
|
||||||
}
|
}
|
||||||
|
if (slot) {
|
||||||
|
*slot = *ip;
|
||||||
|
map->elements++;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
/* Trigger rehashing */
|
/* Trigger rehashing */
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
@@ -10,7 +10,7 @@ struct ip_set_portmap {
|
|||||||
void *members; /* the portmap proper */
|
void *members; /* the portmap proper */
|
||||||
ip_set_ip_t first_ip; /* host byte order, included in range */
|
ip_set_ip_t first_ip; /* host byte order, included in range */
|
||||||
ip_set_ip_t last_ip; /* host byte order, included in range */
|
ip_set_ip_t last_ip; /* host byte order, included in range */
|
||||||
size_t size; /* size of the ipmap proper */
|
u_int32_t size; /* size of the ipmap proper */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ip_set_req_portmap_create {
|
struct ip_set_req_portmap_create {
|
||||||
|
@@ -21,14 +21,14 @@
|
|||||||
* after ==> ref, index
|
* after ==> ref, index
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline bool
|
static inline int
|
||||||
next_index_eq(const struct ip_set_setlist *map, int i, ip_set_id_t index)
|
next_index_eq(const struct ip_set_setlist *map, int i, ip_set_id_t index)
|
||||||
{
|
{
|
||||||
return i < map->size && map->index[i] == index;
|
return i < map->size && map->index[i] == index;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
setlist_utest(struct ip_set *set, const void *data, size_t size,
|
setlist_utest(struct ip_set *set, const void *data, u_int32_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
const struct ip_set_setlist *map = set->data;
|
const struct ip_set_setlist *map = set->data;
|
||||||
@@ -38,18 +38,16 @@ setlist_utest(struct ip_set *set, const void *data, size_t size,
|
|||||||
struct ip_set *s;
|
struct ip_set *s;
|
||||||
|
|
||||||
if (req->before && req->ref[0] == '\0')
|
if (req->before && req->ref[0] == '\0')
|
||||||
return -EINVAL;
|
return 0;
|
||||||
|
|
||||||
index = __ip_set_get_byname(req->name, &s);
|
index = __ip_set_get_byname(req->name, &s);
|
||||||
if (index == IP_SET_INVALID_ID)
|
if (index == IP_SET_INVALID_ID)
|
||||||
return -EEXIST;
|
return 0;
|
||||||
if (req->ref[0] != '\0') {
|
if (req->ref[0] != '\0') {
|
||||||
ref = __ip_set_get_byname(req->ref, &s);
|
ref = __ip_set_get_byname(req->ref, &s);
|
||||||
if (ref == IP_SET_INVALID_ID) {
|
if (ref == IP_SET_INVALID_ID)
|
||||||
res = -EEXIST;
|
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for (i = 0; i < map->size
|
for (i = 0; i < map->size
|
||||||
&& map->index[i] != IP_SET_INVALID_ID; i++) {
|
&& map->index[i] != IP_SET_INVALID_ID; i++) {
|
||||||
if (req->before && map->index[i] == index) {
|
if (req->before && map->index[i] == index) {
|
||||||
@@ -109,7 +107,7 @@ insert_setlist(struct ip_set_setlist *map, int i, ip_set_id_t index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
setlist_uadd(struct ip_set *set, const void *data, size_t size,
|
setlist_uadd(struct ip_set *set, const void *data, u_int32_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_setlist *map = set->data;
|
struct ip_set_setlist *map = set->data;
|
||||||
@@ -172,7 +170,7 @@ setlist_kadd(struct ip_set *set,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline int
|
||||||
unshift_setlist(struct ip_set_setlist *map, int i)
|
unshift_setlist(struct ip_set_setlist *map, int i)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
@@ -184,7 +182,7 @@ unshift_setlist(struct ip_set_setlist *map, int i)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
setlist_udel(struct ip_set *set, const void *data, size_t size,
|
setlist_udel(struct ip_set *set, const void *data, u_int32_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_setlist *map = set->data;
|
struct ip_set_setlist *map = set->data;
|
||||||
@@ -251,7 +249,7 @@ setlist_kdel(struct ip_set *set,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
setlist_create(struct ip_set *set, const void *data, size_t size)
|
setlist_create(struct ip_set *set, const void *data, u_int32_t size)
|
||||||
{
|
{
|
||||||
struct ip_set_setlist *map;
|
struct ip_set_setlist *map;
|
||||||
const struct ip_set_req_setlist_create *req = data;
|
const struct ip_set_req_setlist_create *req = data;
|
||||||
|
@@ -50,6 +50,9 @@ IP set bindings pointing to sets and iptables matches and targets
|
|||||||
referring to sets creates references, which protects the given sets in
|
referring to sets creates references, which protects the given sets in
|
||||||
the kernel. A set cannot be removed (destroyed) while there is a single
|
the kernel. A set cannot be removed (destroyed) while there is a single
|
||||||
reference pointing to it.
|
reference pointing to it.
|
||||||
|
.P
|
||||||
|
.B
|
||||||
|
Please note, binding sets is a deprecated feature and will be removed in a later release. Switch to the multidata type of sets from using bindings.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
The options that are recognized by
|
The options that are recognized by
|
||||||
.B ipset
|
.B ipset
|
||||||
@@ -602,8 +605,4 @@ Joakim Axelsson, Patrick Schaaf and Martin Josefsson.
|
|||||||
.P
|
.P
|
||||||
Sven Wegener wrote the iptreemap type.
|
Sven Wegener wrote the iptreemap type.
|
||||||
.SH LAST REMARK
|
.SH LAST REMARK
|
||||||
.BR "I stand on the shoulder of giants."
|
.BR "I stand on the shoulders of giants."
|
||||||
.\" .. and did I mention that we are incredibly cool people?
|
|
||||||
.\" .. sexy, too ..
|
|
||||||
.\" .. witty, charming, powerful ..
|
|
||||||
.\" .. and most of all, modest ..
|
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe"
|
#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define IPSET_VERSION "2.4.5"
|
#define IPSET_VERSION "3.2"
|
||||||
|
|
||||||
char program_name[] = "ipset";
|
char program_name[] = "ipset";
|
||||||
char program_version[] = IPSET_VERSION;
|
char program_version[] = IPSET_VERSION;
|
||||||
@@ -629,7 +629,8 @@ void parse_ip(const char *str, ip_set_ip_t * ip)
|
|||||||
"host/network `%s' resolves to serveral ip-addresses. "
|
"host/network `%s' resolves to serveral ip-addresses. "
|
||||||
"Please specify one.", str);
|
"Please specify one.", str);
|
||||||
|
|
||||||
*ip = ntohl(((struct in_addr *) host->h_addr_list[0])->s_addr);
|
memcpy(&addr, host->h_addr_list[0], sizeof(struct in_addr));
|
||||||
|
*ip = ntohl(addr.s_addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1579,7 +1580,7 @@ static int set_adtip(struct set *set, const char *adt,
|
|||||||
|
|
||||||
/* Alloc memory for the data to send */
|
/* Alloc memory for the data to send */
|
||||||
size = sizeof(struct ip_set_req_adt) + set->settype->adt_size ;
|
size = sizeof(struct ip_set_req_adt) + set->settype->adt_size ;
|
||||||
DP("alloc size %i", size);
|
DP("alloc size %d", size);
|
||||||
data = ipset_malloc(size);
|
data = ipset_malloc(size);
|
||||||
|
|
||||||
/* Fill out the request */
|
/* Fill out the request */
|
||||||
@@ -1665,7 +1666,7 @@ static int set_bind(struct set *set, const char *adt,
|
|||||||
size += IP_SET_MAXNAMELEN;
|
size += IP_SET_MAXNAMELEN;
|
||||||
else if (!(op == IP_SET_OP_UNBIND_SET && set == NULL))
|
else if (!(op == IP_SET_OP_UNBIND_SET && set == NULL))
|
||||||
size += set->settype->adt_size;
|
size += set->settype->adt_size;
|
||||||
DP("alloc size %i", size);
|
DP("alloc size %d", size);
|
||||||
data = ipset_malloc(size);
|
data = ipset_malloc(size);
|
||||||
|
|
||||||
/* Fill out the request */
|
/* Fill out the request */
|
||||||
|
@@ -95,7 +95,7 @@ struct settype {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Size of create data. Will be sent to kernel */
|
/* Size of create data. Will be sent to kernel */
|
||||||
size_t create_size;
|
u_int32_t create_size;
|
||||||
|
|
||||||
/* Initialize the create. */
|
/* Initialize the create. */
|
||||||
void (*create_init) (void *data);
|
void (*create_init) (void *data);
|
||||||
@@ -115,7 +115,7 @@ struct settype {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Size of data. Will be sent to kernel */
|
/* Size of data. Will be sent to kernel */
|
||||||
size_t adt_size;
|
u_int32_t adt_size;
|
||||||
|
|
||||||
/* Function which parses command options */
|
/* Function which parses command options */
|
||||||
ip_set_ip_t (*adt_parser) (int cmd, const char *optarg, void *data);
|
ip_set_ip_t (*adt_parser) (int cmd, const char *optarg, void *data);
|
||||||
@@ -125,7 +125,7 @@ struct settype {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Size of header. */
|
/* Size of header. */
|
||||||
size_t header_size;
|
u_int32_t header_size;
|
||||||
|
|
||||||
/* Initialize the type-header */
|
/* Initialize the type-header */
|
||||||
void (*initheader) (struct set *set, const void *data);
|
void (*initheader) (struct set *set, const void *data);
|
||||||
@@ -134,16 +134,16 @@ struct settype {
|
|||||||
void (*printheader) (struct set *set, unsigned options);
|
void (*printheader) (struct set *set, unsigned options);
|
||||||
|
|
||||||
/* Pretty print all IPs */
|
/* Pretty print all IPs */
|
||||||
void (*printips) (struct set *set, void *data, size_t len, unsigned options);
|
void (*printips) (struct set *set, void *data, u_int32_t len, unsigned options);
|
||||||
|
|
||||||
/* Pretty print all IPs sorted */
|
/* Pretty print all IPs sorted */
|
||||||
void (*printips_sorted) (struct set *set, void *data, size_t len, unsigned options);
|
void (*printips_sorted) (struct set *set, void *data, u_int32_t len, unsigned options);
|
||||||
|
|
||||||
/* Print save arguments for creating the set */
|
/* Print save arguments for creating the set */
|
||||||
void (*saveheader) (struct set *set, unsigned options);
|
void (*saveheader) (struct set *set, unsigned options);
|
||||||
|
|
||||||
/* Print save for all IPs */
|
/* Print save for all IPs */
|
||||||
void (*saveips) (struct set *set, void *data, size_t len, unsigned options);
|
void (*saveips) (struct set *set, void *data, u_int32_t len, unsigned options);
|
||||||
|
|
||||||
/* Conver a single IP (binding) to string */
|
/* Conver a single IP (binding) to string */
|
||||||
char * (*bindip_tostring)(struct set *set, ip_set_ip_t ip, unsigned options);
|
char * (*bindip_tostring)(struct set *set, ip_set_ip_t ip, unsigned options);
|
||||||
@@ -189,10 +189,13 @@ extern struct set *set_find_byid(ip_set_id_t id);
|
|||||||
|
|
||||||
extern unsigned warn_once;
|
extern unsigned warn_once;
|
||||||
|
|
||||||
#define BITSPERBYTE (8*sizeof(char))
|
#define BITS_PER_LONG (8*sizeof(unsigned long))
|
||||||
#define ID2BYTE(id) ((id)/BITSPERBYTE)
|
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
|
||||||
#define ID2MASK(id) (1 << ((id)%BITSPERBYTE))
|
|
||||||
#define test_bit(id, heap) ((((char *)(heap))[ID2BYTE(id)] & ID2MASK(id)) != 0)
|
static inline int test_bit(int nr, const unsigned long *addr)
|
||||||
|
{
|
||||||
|
return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
|
||||||
|
}
|
||||||
|
|
||||||
#define UNUSED __attribute__ ((unused))
|
#define UNUSED __attribute__ ((unused))
|
||||||
#define CONSTRUCTOR(module) \
|
#define CONSTRUCTOR(module) \
|
||||||
|
@@ -192,7 +192,7 @@ printheader(struct set *set, unsigned options UNUSED)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
printips(struct set *set UNUSED, void *data, size_t len, unsigned options)
|
printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
|
||||||
{
|
{
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
ip_set_ip_t *ip;
|
ip_set_ip_t *ip;
|
||||||
@@ -221,7 +221,7 @@ saveheader(struct set *set, unsigned options UNUSED)
|
|||||||
|
|
||||||
/* Print save for an IP */
|
/* Print save for an IP */
|
||||||
static void
|
static void
|
||||||
saveips(struct set *set UNUSED, void *data, size_t len, unsigned options)
|
saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
|
||||||
{
|
{
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
ip_set_ip_t *ip;
|
ip_set_ip_t *ip;
|
||||||
|
@@ -225,12 +225,12 @@ initheader(struct set *set, const void *data)
|
|||||||
mask = range_to_mask(header->from, header->to, &mask_bits);
|
mask = range_to_mask(header->from, header->to, &mask_bits);
|
||||||
netmask_bits = mask_to_bits(header->netmask);
|
netmask_bits = mask_to_bits(header->netmask);
|
||||||
|
|
||||||
DP("bits: %i %i", mask_bits, netmask_bits);
|
DP("bits: %d %d", mask_bits, netmask_bits);
|
||||||
map->hosts = 2 << (32 - netmask_bits - 1);
|
map->hosts = 2 << (32 - netmask_bits - 1);
|
||||||
map->sizeid = 2 << (netmask_bits - mask_bits - 1);
|
map->sizeid = 2 << (netmask_bits - mask_bits - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
DP("%i %i", map->hosts, map->sizeid );
|
DP("%d %d", map->hosts, map->sizeid );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -248,7 +248,7 @@ printheader(struct set *set, unsigned options)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
printips_sorted(struct set *set, void *data,
|
printips_sorted(struct set *set, void *data,
|
||||||
size_t len UNUSED, unsigned options)
|
u_int32_t len UNUSED, unsigned options)
|
||||||
{
|
{
|
||||||
struct ip_set_ipmap *mysetdata = set->settype->header;
|
struct ip_set_ipmap *mysetdata = set->settype->header;
|
||||||
ip_set_ip_t id;
|
ip_set_ip_t id;
|
||||||
@@ -279,7 +279,7 @@ saveheader(struct set *set, unsigned options)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
saveips(struct set *set, void *data, size_t len UNUSED, unsigned options)
|
saveips(struct set *set, void *data, u_int32_t len UNUSED, unsigned options)
|
||||||
{
|
{
|
||||||
struct ip_set_ipmap *mysetdata = set->settype->header;
|
struct ip_set_ipmap *mysetdata = set->settype->header;
|
||||||
ip_set_ip_t id;
|
ip_set_ip_t id;
|
||||||
|
@@ -248,7 +248,7 @@ printheader(struct set *set, unsigned options)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
printips(struct set *set, void *data, size_t len, unsigned options)
|
printips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||||
{
|
{
|
||||||
struct ip_set_ipporthash *mysetdata = set->settype->header;
|
struct ip_set_ipporthash *mysetdata = set->settype->header;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
@@ -284,7 +284,7 @@ saveheader(struct set *set, unsigned options)
|
|||||||
|
|
||||||
/* Print save for an IP */
|
/* Print save for an IP */
|
||||||
static void
|
static void
|
||||||
saveips(struct set *set, void *data, size_t len, unsigned options)
|
saveips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||||
{
|
{
|
||||||
struct ip_set_ipporthash *mysetdata = set->settype->header;
|
struct ip_set_ipporthash *mysetdata = set->settype->header;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
@@ -253,7 +253,7 @@ printheader(struct set *set, unsigned options)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
printips(struct set *set, void *data, size_t len, unsigned options)
|
printips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||||
{
|
{
|
||||||
struct ip_set_ipportiphash *mysetdata = set->settype->header;
|
struct ip_set_ipportiphash *mysetdata = set->settype->header;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
@@ -292,7 +292,7 @@ saveheader(struct set *set, unsigned options)
|
|||||||
|
|
||||||
/* Print save for an IP */
|
/* Print save for an IP */
|
||||||
static void
|
static void
|
||||||
saveips(struct set *set, void *data, size_t len, unsigned options)
|
saveips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||||
{
|
{
|
||||||
struct ip_set_ipportiphash *mysetdata = set->settype->header;
|
struct ip_set_ipportiphash *mysetdata = set->settype->header;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
@@ -318,7 +318,7 @@ unpack_ip_tostring(ip_set_ip_t ip, unsigned options UNUSED)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
printips(struct set *set, void *data, size_t len, unsigned options)
|
printips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||||
{
|
{
|
||||||
struct ip_set_ipportnethash *mysetdata = set->settype->header;
|
struct ip_set_ipportnethash *mysetdata = set->settype->header;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
@@ -357,7 +357,7 @@ saveheader(struct set *set, unsigned options)
|
|||||||
|
|
||||||
/* Print save for an IP */
|
/* Print save for an IP */
|
||||||
static void
|
static void
|
||||||
saveips(struct set *set, void *data, size_t len, unsigned options)
|
saveips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||||
{
|
{
|
||||||
struct ip_set_ipportnethash *mysetdata = set->settype->header;
|
struct ip_set_ipportnethash *mysetdata = set->settype->header;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
@@ -123,7 +123,7 @@ printheader(struct set *set, unsigned options UNUSED)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
printips_sorted(struct set *set, void *data, size_t len, unsigned options)
|
printips_sorted(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||||
{
|
{
|
||||||
struct ip_set_iptree *mysetdata = set->settype->header;
|
struct ip_set_iptree *mysetdata = set->settype->header;
|
||||||
struct ip_set_req_iptree *req;
|
struct ip_set_req_iptree *req;
|
||||||
@@ -155,7 +155,7 @@ saveheader(struct set *set, unsigned options UNUSED)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
saveips(struct set *set, void *data, size_t len, unsigned options)
|
saveips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||||
{
|
{
|
||||||
struct ip_set_iptree *mysetdata = set->settype->header;
|
struct ip_set_iptree *mysetdata = set->settype->header;
|
||||||
struct ip_set_req_iptree *req;
|
struct ip_set_req_iptree *req;
|
||||||
|
@@ -115,7 +115,7 @@ printheader(struct set *set, unsigned int options UNUSED)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
printips_sorted(struct set *set UNUSED, void *data,
|
printips_sorted(struct set *set UNUSED, void *data,
|
||||||
size_t len, unsigned int options)
|
u_int32_t len, unsigned int options)
|
||||||
{
|
{
|
||||||
struct ip_set_req_iptreemap *req;
|
struct ip_set_req_iptreemap *req;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
@@ -147,7 +147,7 @@ saveheader(struct set *set, unsigned int options UNUSED)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
saveips(struct set *set UNUSED, void *data,
|
saveips(struct set *set UNUSED, void *data,
|
||||||
size_t len, unsigned int options)
|
u_int32_t len, unsigned int options)
|
||||||
{
|
{
|
||||||
struct ip_set_req_iptreemap *req;
|
struct ip_set_req_iptreemap *req;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
@@ -245,15 +245,14 @@ print_mac(unsigned char macaddress[ETH_ALEN])
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
printips_sorted(struct set *set, void *data,
|
printips_sorted(struct set *set, void *data,
|
||||||
size_t len UNUSED, unsigned options)
|
u_int32_t len UNUSED, unsigned options)
|
||||||
{
|
{
|
||||||
struct ip_set_macipmap *mysetdata = set->settype->header;
|
struct ip_set_macipmap *mysetdata = set->settype->header;
|
||||||
struct ip_set_macip *table = data;
|
struct ip_set_macip *table = data;
|
||||||
u_int32_t addr = mysetdata->first_ip;
|
u_int32_t addr = mysetdata->first_ip;
|
||||||
|
|
||||||
while (addr <= mysetdata->last_ip) {
|
while (addr <= mysetdata->last_ip) {
|
||||||
if (test_bit(IPSET_MACIP_ISSET,
|
if (table[addr - mysetdata->first_ip].match) {
|
||||||
(void *)&table[addr - mysetdata->first_ip].flags)) {
|
|
||||||
printf("%s,", ip_tostring(addr, options));
|
printf("%s,", ip_tostring(addr, options));
|
||||||
print_mac(table[addr - mysetdata->first_ip].
|
print_mac(table[addr - mysetdata->first_ip].
|
||||||
ethernet);
|
ethernet);
|
||||||
@@ -280,15 +279,14 @@ saveheader(struct set *set, unsigned options)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
saveips(struct set *set, void *data,
|
saveips(struct set *set, void *data,
|
||||||
size_t len UNUSED, unsigned options)
|
u_int32_t len UNUSED, unsigned options)
|
||||||
{
|
{
|
||||||
struct ip_set_macipmap *mysetdata = set->settype->header;
|
struct ip_set_macipmap *mysetdata = set->settype->header;
|
||||||
struct ip_set_macip *table = data;
|
struct ip_set_macip *table = data;
|
||||||
u_int32_t addr = mysetdata->first_ip;
|
u_int32_t addr = mysetdata->first_ip;
|
||||||
|
|
||||||
while (addr <= mysetdata->last_ip) {
|
while (addr <= mysetdata->last_ip) {
|
||||||
if (test_bit(IPSET_MACIP_ISSET,
|
if (table[addr - mysetdata->first_ip].match) {
|
||||||
(void *)&table[addr - mysetdata->first_ip].flags)) {
|
|
||||||
printf("-A %s %s,",
|
printf("-A %s %s,",
|
||||||
set->name, ip_tostring(addr, options));
|
set->name, ip_tostring(addr, options));
|
||||||
print_mac(table[addr - mysetdata->first_ip].
|
print_mac(table[addr - mysetdata->first_ip].
|
||||||
|
@@ -224,7 +224,7 @@ unpack_ip_tostring(ip_set_ip_t ip, unsigned options UNUSED)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
printips(struct set *set UNUSED, void *data, size_t len, unsigned options)
|
printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
|
||||||
{
|
{
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
ip_set_ip_t *ip;
|
ip_set_ip_t *ip;
|
||||||
@@ -249,7 +249,7 @@ saveheader(struct set *set, unsigned options UNUSED)
|
|||||||
|
|
||||||
/* Print save for an IP */
|
/* Print save for an IP */
|
||||||
static void
|
static void
|
||||||
saveips(struct set *set UNUSED, void *data, size_t len, unsigned options)
|
saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
|
||||||
{
|
{
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
ip_set_ip_t *ip;
|
ip_set_ip_t *ip;
|
||||||
|
@@ -149,7 +149,7 @@ printheader(struct set *set, unsigned options)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
printports_sorted(struct set *set, void *data,
|
printports_sorted(struct set *set, void *data,
|
||||||
size_t len UNUSED, unsigned options)
|
u_int32_t len UNUSED, unsigned options)
|
||||||
{
|
{
|
||||||
struct ip_set_portmap *mysetdata = set->settype->header;
|
struct ip_set_portmap *mysetdata = set->settype->header;
|
||||||
u_int32_t addr = mysetdata->first_ip;
|
u_int32_t addr = mysetdata->first_ip;
|
||||||
@@ -184,7 +184,7 @@ saveheader(struct set *set, unsigned options)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
saveports(struct set *set, void *data,
|
saveports(struct set *set, void *data,
|
||||||
size_t len UNUSED, unsigned options)
|
u_int32_t len UNUSED, unsigned options)
|
||||||
{
|
{
|
||||||
struct ip_set_portmap *mysetdata = set->settype->header;
|
struct ip_set_portmap *mysetdata = set->settype->header;
|
||||||
u_int32_t addr = mysetdata->first_ip;
|
u_int32_t addr = mysetdata->first_ip;
|
||||||
|
@@ -134,7 +134,7 @@ printheader(struct set *set, unsigned options UNUSED)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
printips_sorted(struct set *set, void *data,
|
printips_sorted(struct set *set, void *data,
|
||||||
size_t len UNUSED, unsigned options UNUSED)
|
u_int32_t len UNUSED, unsigned options UNUSED)
|
||||||
{
|
{
|
||||||
struct ip_set_setlist *mysetdata = set->settype->header;
|
struct ip_set_setlist *mysetdata = set->settype->header;
|
||||||
int i;
|
int i;
|
||||||
@@ -162,7 +162,7 @@ saveheader(struct set *set, unsigned options UNUSED)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
saveips(struct set *set, void *data,
|
saveips(struct set *set, void *data,
|
||||||
size_t len UNUSED, unsigned options UNUSED)
|
u_int32_t len UNUSED, unsigned options UNUSED)
|
||||||
{
|
{
|
||||||
struct ip_set_setlist *mysetdata = set->settype->header;
|
struct ip_set_setlist *mysetdata = set->settype->header;
|
||||||
int i;
|
int i;
|
||||||
|
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");
|
@@ -58,7 +58,7 @@ static void chaos_tg_check(unsigned int flags)
|
|||||||
{
|
{
|
||||||
if (flags == (F_DELUDE | F_TARPIT))
|
if (flags == (F_DELUDE | F_TARPIT))
|
||||||
/* If flags == 0x03, both were specified, which should not be. */
|
/* If flags == 0x03, both were specified, which should not be. */
|
||||||
exit_error(PARAMETER_PROBLEM,
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
"CHAOS: only one of --tarpit or --delude "
|
"CHAOS: only one of --tarpit or --delude "
|
||||||
"may be specified");
|
"may be specified");
|
||||||
}
|
}
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
Causes confusion on the other end by doing odd things with incoming packets.
|
Causes confusion on the other end by doing odd things with incoming packets.
|
||||||
CHAOS will randomly reply (or not) with one of its configurable subtargets:
|
CHAOS will randomly reply (or not) with one of its configurable subtargets:
|
||||||
.TP
|
.TP
|
||||||
\fB--delude\fP
|
\fB\-\-delude\fP
|
||||||
Use the REJECT and DELUDE targets as a base to do a sudden or deferred
|
Use the REJECT and DELUDE targets as a base to do a sudden or deferred
|
||||||
connection reset, fooling some network scanners to return non-deterministic
|
connection reset, fooling some network scanners to return non-deterministic
|
||||||
(randomly open/closed) results, and in case it is deemed open, it is actually
|
(randomly open/closed) results, and in case it is deemed open, it is actually
|
||||||
closed/filtered.
|
closed/filtered.
|
||||||
.TP
|
.TP
|
||||||
\fB--tarpit\fP
|
\fB\-\-tarpit\fP
|
||||||
Use the REJECT and TARPIT target as a base to hold the connection until it
|
Use the REJECT and TARPIT target as a base to hold the connection until it
|
||||||
times out. This consumes conntrack entries when connection tracking is loaded
|
times out. This consumes conntrack entries when connection tracking is loaded
|
||||||
(which usually is on most machines), and routers inbetween you and the Internet
|
(which usually is on most machines), and routers inbetween you and the Internet
|
||||||
@@ -18,4 +18,4 @@ The randomness factor of not replying vs. replying can be set during load-time
|
|||||||
of the xt_CHAOS module or during runtime in /sys/modules/xt_CHAOS/parameters.
|
of the xt_CHAOS module or during runtime in /sys/modules/xt_CHAOS/parameters.
|
||||||
.PP
|
.PP
|
||||||
See http://jengelh.medozas.de/projects/chaostables/ for more information
|
See http://jengelh.medozas.de/projects/chaostables/ for more information
|
||||||
about CHAOS, DELUDE and portscan.
|
about CHAOS, DELUDE and lscan.
|
||||||
|
@@ -1,101 +0,0 @@
|
|||||||
/*
|
|
||||||
* "DHCPADDR" target extension for iptables
|
|
||||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
|
||||||
*
|
|
||||||
* 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 <getopt.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <netinet/ether.h>
|
|
||||||
#include <xtables.h>
|
|
||||||
#include "xt_DHCPADDR.h"
|
|
||||||
#include "mac.c"
|
|
||||||
|
|
||||||
enum {
|
|
||||||
F_MAC = 1 << 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct option dhcpaddr_tg_opts[] = {
|
|
||||||
{.name = "set-mac", .has_arg = true, .val = 'M'},
|
|
||||||
{NULL},
|
|
||||||
};
|
|
||||||
|
|
||||||
static void dhcpaddr_tg_help(void)
|
|
||||||
{
|
|
||||||
printf(
|
|
||||||
"DHCPADDDR target options:\n"
|
|
||||||
" --set-mac lladdr[/mask] Set MAC address in DHCP Client Host field\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dhcpaddr_tg_parse(int c, char **argv, int invert,
|
|
||||||
unsigned int *flags, const void *entry, struct xt_entry_target **target)
|
|
||||||
{
|
|
||||||
struct dhcpaddr_info *info = (void *)(*target)->data;
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case 'M':
|
|
||||||
param_act(P_ONLY_ONCE, "DHCPADDR", "--set-mac", *flags & F_MAC);
|
|
||||||
param_act(P_NO_INVERT, "DHCPADDR", "--set-mac", invert);
|
|
||||||
if (!mac_parse(optarg, info->addr, &info->mask))
|
|
||||||
param_act(P_BAD_VALUE, "DHCPADDR", "--set-mac", optarg);
|
|
||||||
*flags |= F_MAC;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dhcpaddr_tg_check(unsigned int flags)
|
|
||||||
{
|
|
||||||
if (flags == 0)
|
|
||||||
exit_error(PARAMETER_PROBLEM, "DHCPADDR target: "
|
|
||||||
"--set-mac parameter required");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dhcpaddr_tg_print(const void *ip,
|
|
||||||
const struct xt_entry_target *target, int numeric)
|
|
||||||
{
|
|
||||||
const struct dhcpaddr_info *info = (void *)target->data;
|
|
||||||
|
|
||||||
printf("DHCPADDR %s" DH_MAC_FMT "/%u ",
|
|
||||||
info->invert ? "!" : "", DH_MAC_HEX(info->addr), info->mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dhcpaddr_tg_save(const void *ip,
|
|
||||||
const struct xt_entry_target *target)
|
|
||||||
{
|
|
||||||
const struct dhcpaddr_info *info = (const void *)target->data;
|
|
||||||
|
|
||||||
if (info->invert)
|
|
||||||
printf("! ");
|
|
||||||
printf("--set-mac " DH_MAC_FMT "/%u ",
|
|
||||||
DH_MAC_HEX(info->addr), info->mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct xtables_target dhcpaddr_tg_reg = {
|
|
||||||
.version = XTABLES_VERSION,
|
|
||||||
.name = "DHCPADDR",
|
|
||||||
.revision = 0,
|
|
||||||
.family = PF_INET,
|
|
||||||
.size = XT_ALIGN(sizeof(struct dhcpaddr_info)),
|
|
||||||
.userspacesize = XT_ALIGN(sizeof(struct dhcpaddr_info)),
|
|
||||||
.help = dhcpaddr_tg_help,
|
|
||||||
.parse = dhcpaddr_tg_parse,
|
|
||||||
.final_check = dhcpaddr_tg_check,
|
|
||||||
.print = dhcpaddr_tg_print,
|
|
||||||
.save = dhcpaddr_tg_save,
|
|
||||||
.extra_opts = dhcpaddr_tg_opts,
|
|
||||||
};
|
|
||||||
|
|
||||||
static __attribute__((constructor)) void dhcpaddr_tg_ldr(void)
|
|
||||||
{
|
|
||||||
xtables_register_target(&dhcpaddr_tg_reg);
|
|
||||||
}
|
|
101
extensions/libxt_DHCPMAC.c
Normal file
101
extensions/libxt_DHCPMAC.c
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* "DHCPMAC" target extension for iptables
|
||||||
|
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
||||||
|
*
|
||||||
|
* 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 <getopt.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <netinet/ether.h>
|
||||||
|
#include <xtables.h>
|
||||||
|
#include "xt_DHCPMAC.h"
|
||||||
|
#include "mac.c"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
F_MAC = 1 << 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct option dhcpmac_tg_opts[] = {
|
||||||
|
{.name = "set-mac", .has_arg = true, .val = 'M'},
|
||||||
|
{NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void dhcpmac_tg_help(void)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"DHCPMAC target options:\n"
|
||||||
|
" --set-mac lladdr[/mask] Set MAC address in DHCP Client Host field\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dhcpmac_tg_parse(int c, char **argv, int invert,
|
||||||
|
unsigned int *flags, const void *entry, struct xt_entry_target **target)
|
||||||
|
{
|
||||||
|
struct dhcpmac_info *info = (void *)(*target)->data;
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case 'M':
|
||||||
|
xtables_param_act(XTF_ONLY_ONCE, "DHCPMAC", "--set-mac", *flags & F_MAC);
|
||||||
|
xtables_param_act(XTF_NO_INVERT, "DHCPMAC", "--set-mac", invert);
|
||||||
|
if (!mac_parse(optarg, info->addr, &info->mask))
|
||||||
|
xtables_param_act(XTF_BAD_VALUE, "DHCPMAC", "--set-mac", optarg);
|
||||||
|
*flags |= F_MAC;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dhcpmac_tg_check(unsigned int flags)
|
||||||
|
{
|
||||||
|
if (flags == 0)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, "DHCPMAC target: "
|
||||||
|
"--set-mac parameter required");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dhcpmac_tg_print(const void *ip,
|
||||||
|
const struct xt_entry_target *target, int numeric)
|
||||||
|
{
|
||||||
|
const struct dhcpmac_info *info = (void *)target->data;
|
||||||
|
|
||||||
|
printf("DHCPMAC %s" DH_MAC_FMT "/%u ",
|
||||||
|
info->invert ? "!" : "", DH_MAC_HEX(info->addr), info->mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dhcpmac_tg_save(const void *ip,
|
||||||
|
const struct xt_entry_target *target)
|
||||||
|
{
|
||||||
|
const struct dhcpmac_info *info = (const void *)target->data;
|
||||||
|
|
||||||
|
if (info->invert)
|
||||||
|
printf("! ");
|
||||||
|
printf("--set-mac " DH_MAC_FMT "/%u ",
|
||||||
|
DH_MAC_HEX(info->addr), info->mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct xtables_target dhcpmac_tg_reg = {
|
||||||
|
.version = XTABLES_VERSION,
|
||||||
|
.name = "DHCPMAC",
|
||||||
|
.revision = 0,
|
||||||
|
.family = PF_INET,
|
||||||
|
.size = XT_ALIGN(sizeof(struct dhcpmac_info)),
|
||||||
|
.userspacesize = XT_ALIGN(sizeof(struct dhcpmac_info)),
|
||||||
|
.help = dhcpmac_tg_help,
|
||||||
|
.parse = dhcpmac_tg_parse,
|
||||||
|
.final_check = dhcpmac_tg_check,
|
||||||
|
.print = dhcpmac_tg_print,
|
||||||
|
.save = dhcpmac_tg_save,
|
||||||
|
.extra_opts = dhcpmac_tg_opts,
|
||||||
|
};
|
||||||
|
|
||||||
|
static __attribute__((constructor)) void dhcpmac_tg_ldr(void)
|
||||||
|
{
|
||||||
|
xtables_register_target(&dhcpmac_tg_reg);
|
||||||
|
}
|
@@ -1,10 +1,10 @@
|
|||||||
In conjunction with ebtables, DHCPADDR can be used to completely change all MAC
|
In conjunction with ebtables, DHCPMAC can be used to completely change all MAC
|
||||||
addresses from and to a VMware-based virtual machine. This is needed because
|
addresses from and to a VMware-based virtual machine. This is needed because
|
||||||
VMware does not allow to set a non-VMware MAC address before an operating
|
VMware does not allow to set a non-VMware MAC address before an operating
|
||||||
system is booted (and the MAC be changed with `ip link set eth0 address
|
system is booted (and the MAC be changed with `ip link set eth0 address
|
||||||
aa:bb..`).
|
aa:bb..`).
|
||||||
.TP
|
.TP
|
||||||
\fB--set-mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
|
\fB\-\-set\-mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
|
||||||
Replace the client host MAC address field in the DHCP message with the given
|
Replace the client host MAC address field in the DHCP message with the given
|
||||||
MAC address. This option is mandatory. The \fImask\fP parameter specifies the
|
MAC address. This option is mandatory. The \fImask\fP parameter specifies the
|
||||||
prefix length of bits to change.
|
prefix length of bits to change.
|
||||||
@@ -12,13 +12,13 @@ prefix length of bits to change.
|
|||||||
EXAMPLE, replacing all addresses from one of VMware's assigned vendor IDs
|
EXAMPLE, replacing all addresses from one of VMware's assigned vendor IDs
|
||||||
(00:50:56) addresses with something else:
|
(00:50:56) addresses with something else:
|
||||||
.PP
|
.PP
|
||||||
iptables -t mangle -A FORWARD -p udp --dport 67 -m physdev --physdev-in vmnet1
|
iptables \-t mangle \-A FORWARD \-p udp \-\-dport 67 \-m physdev
|
||||||
-m dhcpaddr --mac 00:50:56:00:00:00/24 -j DHCPADDR --set-mac
|
\-\-physdev\-in vmnet1 \-m dhcpmac \-\-mac 00:50:56:00:00:00/24 \-j DHCPMAC
|
||||||
ab:cd:ef:00:00:00/24
|
\-\-set\-mac ab:cd:ef:00:00:00/24
|
||||||
.PP
|
.PP
|
||||||
iptables -t mangle -A FORWARD -p udp --dport 68 -m physdev --physdev-out vmnet1
|
iptables \-t mangle \-A FORWARD \-p udp \-\-dport 68 \-m physdev
|
||||||
-m dhcpaddr --mac ab:cd:ef:00:00:00/24 -j DHCPADDR --set-mac
|
\-\-physdev\-out vmnet1 \-m dhcpmac \-\-mac ab:cd:ef:00:00:00/24 \-j DHCPMAC
|
||||||
00:50:56:00:00:00/24
|
\-\-set\-mac 00:50:56:00:00:00/24
|
||||||
.PP
|
.PP
|
||||||
(This assumes there is a bridge interface that has vmnet1 as a port. You will
|
(This assumes there is a bridge interface that has vmnet1 as a port. You will
|
||||||
also need to add appropriate ebtables rules to change the MAC address of the
|
also need to add appropriate ebtables rules to change the MAC address of the
|
@@ -58,45 +58,46 @@ static int ipmark_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '1':
|
case '1':
|
||||||
param_act(P_ONLY_ONCE, "IPMARK", "addr", *flags & FL_ADDR_USED);
|
xtables_param_act(XTF_ONLY_ONCE, "IPMARK", "addr", *flags & FL_ADDR_USED);
|
||||||
param_act(P_NO_INVERT, "IPMARK", "addr", invert);
|
xtables_param_act(XTF_NO_INVERT, "IPMARK", "addr", invert);
|
||||||
if (strcmp(optarg, "src") == 0)
|
if (strcmp(optarg, "src") == 0)
|
||||||
info->selector = XT_IPMARK_SRC;
|
info->selector = XT_IPMARK_SRC;
|
||||||
else if (strcmp(optarg, "dst") == 0)
|
else if (strcmp(optarg, "dst") == 0)
|
||||||
info->selector = XT_IPMARK_DST;
|
info->selector = XT_IPMARK_DST;
|
||||||
else
|
else
|
||||||
exit_error(PARAMETER_PROBLEM, "Bad addr value `%s' - should be `src' or `dst'", optarg);
|
xtables_error(PARAMETER_PROBLEM, "Bad addr value `%s' - should be `src' or `dst'", optarg);
|
||||||
*flags |= FL_ADDR_USED;
|
*flags |= FL_ADDR_USED;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case '2':
|
case '2':
|
||||||
param_act(P_ONLY_ONCE, "IPMARK", "and-mask", *flags & FL_AND_MASK_USED);
|
xtables_param_act(XTF_ONLY_ONCE, "IPMARK", "and-mask", *flags & FL_AND_MASK_USED);
|
||||||
param_act(P_NO_INVERT, "IPMARK", "and-mask", invert);
|
xtables_param_act(XTF_NO_INVERT, "IPMARK", "and-mask", invert);
|
||||||
if (!strtonum(optarg, NULL, &n, 0, ~0U))
|
if (!xtables_strtoui(optarg, NULL, &n, 0, ~0U))
|
||||||
param_act(P_BAD_VALUE, "IPMARK", "and-mask", optarg);
|
xtables_param_act(XTF_BAD_VALUE, "IPMARK", "and-mask", optarg);
|
||||||
info->andmask = n;
|
info->andmask = n;
|
||||||
*flags |= FL_AND_MASK_USED;
|
*flags |= FL_AND_MASK_USED;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case '3':
|
case '3':
|
||||||
param_act(P_ONLY_ONCE, "IPMARK", "or-mask", *flags & FL_OR_MASK_USED);
|
xtables_param_act(XTF_ONLY_ONCE, "IPMARK", "or-mask", *flags & FL_OR_MASK_USED);
|
||||||
param_act(P_NO_INVERT, "IPMARK", "or-mask", invert);
|
xtables_param_act(XTF_NO_INVERT, "IPMARK", "or-mask", invert);
|
||||||
if (!strtonum(optarg, NULL, &n, 0, ~0U))
|
if (!xtables_strtoui(optarg, NULL, &n, 0, ~0U))
|
||||||
param_act(P_BAD_VALUE, "IPMARK", "or-mask", optarg);
|
xtables_param_act(XTF_BAD_VALUE, "IPMARK", "or-mask", optarg);
|
||||||
info->ormask = n;
|
info->ormask = n;
|
||||||
*flags |= FL_OR_MASK_USED;
|
*flags |= FL_OR_MASK_USED;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case '4':
|
case '4':
|
||||||
param_act(P_ONLY_ONCE, "IPMARK", "--shift", *flags & FL_SHIFT);
|
xtables_param_act(XTF_ONLY_ONCE, "IPMARK", "--shift", *flags & FL_SHIFT);
|
||||||
param_act(P_NO_INVERT, "IPMARK", "--shift", invert);
|
xtables_param_act(XTF_NO_INVERT, "IPMARK", "--shift", invert);
|
||||||
/*
|
/*
|
||||||
* Anything >31 does not make sense for IPv4, but it still
|
* Anything >31 does not make sense for IPv4, but it still
|
||||||
* does the right thing.
|
* does the right thing.
|
||||||
*/
|
*/
|
||||||
if (!strtonum(optarg, NULL, &n, 0, 128))
|
if (!xtables_strtoui(optarg, NULL, &n, 0, 128))
|
||||||
param_act(P_BAD_VALUE, "IPMARK", "--shift", optarg);
|
xtables_param_act(XTF_BAD_VALUE, "IPMARK", "--shift", optarg);
|
||||||
info->shift = n;
|
info->shift = n;
|
||||||
|
*flags |= FL_SHIFT;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +107,7 @@ static int ipmark_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
static void ipmark_tg_check(unsigned int flags)
|
static void ipmark_tg_check(unsigned int flags)
|
||||||
{
|
{
|
||||||
if (!(flags & FL_ADDR_USED))
|
if (!(flags & FL_ADDR_USED))
|
||||||
exit_error(PARAMETER_PROBLEM,
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
"IPMARK target: Parameter --addr is required");
|
"IPMARK target: Parameter --addr is required");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,6 +122,8 @@ ipmark_tg_print(const void *entry, const struct xt_entry_target *target,
|
|||||||
else
|
else
|
||||||
printf("IPMARK dst ip ");
|
printf("IPMARK dst ip ");
|
||||||
|
|
||||||
|
if (info->shift != 0)
|
||||||
|
printf("shift %u ", (unsigned int)info->shift);
|
||||||
if (info->andmask != ~0U)
|
if (info->andmask != ~0U)
|
||||||
printf("and 0x%x ", (unsigned int)info->andmask);
|
printf("and 0x%x ", (unsigned int)info->andmask);
|
||||||
if (info->ormask != 0)
|
if (info->ormask != 0)
|
||||||
@@ -137,33 +140,19 @@ ipmark_tg_save(const void *entry, const struct xt_entry_target *target)
|
|||||||
else
|
else
|
||||||
printf("--addr dst ");
|
printf("--addr dst ");
|
||||||
|
|
||||||
|
if (info->shift != 0)
|
||||||
|
printf("--shift %u ", (unsigned int)info->shift);
|
||||||
if (info->andmask != ~0U)
|
if (info->andmask != ~0U)
|
||||||
printf("--and-mask 0x%x ", (unsigned int)info->andmask);
|
printf("--and-mask 0x%x ", (unsigned int)info->andmask);
|
||||||
if (info->ormask != 0)
|
if (info->ormask != 0)
|
||||||
printf("--or-mask 0x%x ", (unsigned int)info->ormask);
|
printf("--or-mask 0x%x ", (unsigned int)info->ormask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct xtables_target ipmark_tg4_reg = {
|
static struct xtables_target ipmark_tg_reg = {
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.name = "IPMARK",
|
.name = "IPMARK",
|
||||||
.family = PF_INET,
|
.family = PF_UNSPEC,
|
||||||
.revision = 0,
|
.revision = 1,
|
||||||
.size = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
|
|
||||||
.userspacesize = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
|
|
||||||
.help = ipmark_tg_help,
|
|
||||||
.init = ipmark_tg_init,
|
|
||||||
.parse = ipmark_tg_parse,
|
|
||||||
.final_check = ipmark_tg_check,
|
|
||||||
.print = ipmark_tg_print,
|
|
||||||
.save = ipmark_tg_save,
|
|
||||||
.extra_opts = ipmark_tg_opts,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct xtables_target ipmark_tg6_reg = {
|
|
||||||
.version = XTABLES_VERSION,
|
|
||||||
.name = "IPMARK",
|
|
||||||
.family = PF_INET6,
|
|
||||||
.revision = 0,
|
|
||||||
.size = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
|
.size = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
|
||||||
.userspacesize = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
|
.userspacesize = XT_ALIGN(sizeof(struct xt_ipmark_tginfo)),
|
||||||
.help = ipmark_tg_help,
|
.help = ipmark_tg_help,
|
||||||
@@ -177,6 +166,5 @@ static struct xtables_target ipmark_tg6_reg = {
|
|||||||
|
|
||||||
static __attribute__((constructor)) void ipmark_tg_ldr(void)
|
static __attribute__((constructor)) void ipmark_tg_ldr(void)
|
||||||
{
|
{
|
||||||
xtables_register_target(&ipmark_tg4_reg);
|
xtables_register_target(&ipmark_tg_reg);
|
||||||
xtables_register_target(&ipmark_tg6_reg);
|
|
||||||
}
|
}
|
||||||
|
@@ -4,16 +4,16 @@ firewall based classifier.
|
|||||||
|
|
||||||
This target is to be used inside the \fBmangle\fP table.
|
This target is to be used inside the \fBmangle\fP table.
|
||||||
.TP
|
.TP
|
||||||
\fB--addr\fP {\fBsrc\fP|\fBdst\fP}
|
\fB\-\-addr\fP {\fBsrc\fP|\fBdst\fP}
|
||||||
Select source or destination IP address as a basis for the mark.
|
Select source or destination IP address as a basis for the mark.
|
||||||
.TP
|
.TP
|
||||||
\fB--and-mask\fP \fImask\fP
|
\fB\-\-and\-mask\fP \fImask\fP
|
||||||
Perform bitwise AND on the IP address and this bitmask.
|
Perform bitwise AND on the IP address and this bitmask.
|
||||||
.TP
|
.TP
|
||||||
\fB--or-mask\fP \fImask\fP
|
\fB\-\-or\-mask\fP \fImask\fP
|
||||||
Perform bitwise OR on the IP address and this bitmask.
|
Perform bitwise OR on the IP address and this bitmask.
|
||||||
.TP
|
.TP
|
||||||
\fB--shift\fP \fIvalue\fP
|
\fB\-\-shift\fP \fIvalue\fP
|
||||||
Shift addresses to the right by the given number of bits before taking it
|
Shift addresses to the right by the given number of bits before taking it
|
||||||
as a mark. (This is done before ANDing or ORing it.) This option is needed
|
as a mark. (This is done before ANDing or ORing it.) This option is needed
|
||||||
to select part of an IPv6 address, because marks are only 32 bits in size.
|
to select part of an IPv6 address, because marks are only 32 bits in size.
|
||||||
@@ -34,16 +34,16 @@ tc filter add dev eth3 parent 1:0 protocol ip fw
|
|||||||
.PP
|
.PP
|
||||||
Earlier we had many rules just like below:
|
Earlier we had many rules just like below:
|
||||||
.IP
|
.IP
|
||||||
iptables -t mangle -A POSTROUTING -o eth3 -d 192.168.5.2 -j MARK
|
iptables \-t mangle \-A POSTROUTING \-o eth3 \-d 192.168.5.2 \-j MARK
|
||||||
--set-mark 0x10502
|
\-\-set\-mark 0x10502
|
||||||
.IP
|
.IP
|
||||||
iptables -t mangle -A POSTROUTING -o eth3 -d 192.168.5.3 -j MARK
|
iptables \-t mangle \-A POSTROUTING \-o eth3 \-d 192.168.5.3 \-j MARK
|
||||||
--set-mark 0x10503
|
\-\-set\-mark 0x10503
|
||||||
.PP
|
.PP
|
||||||
Using IPMARK target we can replace all the mangle/mark rules with only one:
|
Using IPMARK target we can replace all the mangle/mark rules with only one:
|
||||||
.IP
|
.IP
|
||||||
iptables -t mangle -A POSTROUTING -o eth3 -j IPMARK --addr dst
|
iptables \-t mangle \-A POSTROUTING \-o eth3 \-j IPMARK \-\-addr dst
|
||||||
--and-mask 0xffff --or-mask 0x10000
|
\-\-and\-mask 0xffff \-\-or\-mask 0x10000
|
||||||
.PP
|
.PP
|
||||||
On the routers with hundreds of users there should be significant load
|
On the routers with hundreds of users there should be significant load
|
||||||
decrease (e.g. twice).
|
decrease (e.g. twice).
|
||||||
@@ -52,5 +52,5 @@ decrease (e.g. twice).
|
|||||||
2001:db8:45:1d:20d:93ff:fe9b:e443 and the resulting mark should be 0x93ff,
|
2001:db8:45:1d:20d:93ff:fe9b:e443 and the resulting mark should be 0x93ff,
|
||||||
then a right-shift of 16 is needed first:
|
then a right-shift of 16 is needed first:
|
||||||
.IP
|
.IP
|
||||||
-t mangle -A PREROUTING -s 2001:db8::/32 -j IPMARK --addr src --shift 16
|
\-t mangle \-A PREROUTING \-s 2001:db8::/32 \-j IPMARK \-\-addr src \-\-shift
|
||||||
--and-mask 0xFFFF
|
16 \-\-and\-mask 0xFFFF
|
||||||
|
@@ -51,23 +51,23 @@ logmark_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'l': /* --log-level */
|
case 'l': /* --log-level */
|
||||||
param_act(P_ONLY_ONCE, "LOGMARK", "--log-level", *flags & F_LEVEL);
|
xtables_param_act(XTF_ONLY_ONCE, "LOGMARK", "--log-level", *flags & F_LEVEL);
|
||||||
param_act(P_NO_INVERT, "LOGMARK", "--log-level", invert);
|
xtables_param_act(XTF_NO_INVERT, "LOGMARK", "--log-level", invert);
|
||||||
if (!strtonum(optarg, NULL, &x, 0, 8))
|
if (!xtables_strtoui(optarg, NULL, &x, 0, 8))
|
||||||
param_act(P_BAD_VALUE, "LOGMARK", "--log-level", optarg);
|
xtables_param_act(XTF_BAD_VALUE, "LOGMARK", "--log-level", optarg);
|
||||||
info->level = x;
|
info->level = x;
|
||||||
*flags |= F_LEVEL;
|
*flags |= F_LEVEL;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case 'p': /* --log-prefix */
|
case 'p': /* --log-prefix */
|
||||||
param_act(P_ONLY_ONCE, "LOGMARK", "--log-prefix", *flags & F_PREFIX);
|
xtables_param_act(XTF_ONLY_ONCE, "LOGMARK", "--log-prefix", *flags & F_PREFIX);
|
||||||
param_act(P_NO_INVERT, "LOGMARK", "--log-prefix", invert);
|
xtables_param_act(XTF_NO_INVERT, "LOGMARK", "--log-prefix", invert);
|
||||||
if (strlen(optarg) > sizeof(info->prefix))
|
if (strlen(optarg) > sizeof(info->prefix))
|
||||||
exit_error(PARAMETER_PROBLEM, "LOGMARK: Maximum "
|
xtables_error(PARAMETER_PROBLEM, "LOGMARK: Maximum "
|
||||||
"prefix length is %zu",
|
"prefix length is %zu",
|
||||||
sizeof(info->prefix));
|
sizeof(info->prefix));
|
||||||
if (strchr(optarg, '\n'))
|
if (strchr(optarg, '\n'))
|
||||||
exit_error(PARAMETER_PROBLEM, "LOGMARK: Newlines not "
|
xtables_error(PARAMETER_PROBLEM, "LOGMARK: Newlines not "
|
||||||
"allowed in log prefix");
|
"allowed in log prefix");
|
||||||
strncpy(info->prefix, optarg, sizeof(info->prefix));
|
strncpy(info->prefix, optarg, sizeof(info->prefix));
|
||||||
*flags |= F_PREFIX;
|
*flags |= F_PREFIX;
|
||||||
|
@@ -1,17 +1,17 @@
|
|||||||
The LOGMARK target will log packet and connection marks to syslog.
|
The LOGMARK target will log packet and connection marks to syslog.
|
||||||
.TP
|
.TP
|
||||||
\fB--log-level\fR \fIlevel\fR
|
\fB\-\-log\-level\fR \fIlevel\fR
|
||||||
A logging level between 0 and 8 (inclusive).
|
A logging level between 0 and 8 (inclusive).
|
||||||
.TP
|
.TP
|
||||||
\fB--log-prefix\fR \fIstring\fR
|
\fB\-\-log\-prefix\fR \fIstring\fR
|
||||||
Prefix log messages with the specified prefix; up to 29 bytes long, and useful
|
Prefix log messages with the specified prefix; up to 29 bytes long, and useful
|
||||||
for distinguishing messages in the logs.
|
for distinguishing messages in the logs.
|
||||||
.TP
|
.TP
|
||||||
\fB--log-nfmark\fR
|
\fB\-\-log\-nfmark\fR
|
||||||
Include the packet mark in the log.
|
Include the packet mark in the log.
|
||||||
.TP
|
.TP
|
||||||
\fB--log-ctmark\fR
|
\fB\-\-log\-ctmark\fR
|
||||||
Include the connection mark in the log.
|
Include the connection mark in the log.
|
||||||
.TP
|
.TP
|
||||||
\fB--log-secmark\fR
|
\fB\-\-log\-secmark\fR
|
||||||
Include the packet secmark in the log.
|
Include the packet secmark in the log.
|
||||||
|
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 \(em 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.
|
33
extensions/libxt_STEAL.c
Normal file
33
extensions/libxt_STEAL.c
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <xtables.h>
|
||||||
|
|
||||||
|
static void steal_tg_help(void)
|
||||||
|
{
|
||||||
|
printf("STEAL takes no options\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int steal_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||||
|
const void *entry, struct xt_entry_target **target)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void steal_tg_check(unsigned int flags)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct xtables_target steal_tg_reg = {
|
||||||
|
.version = XTABLES_VERSION,
|
||||||
|
.name = "STEAL",
|
||||||
|
.family = AF_UNSPEC,
|
||||||
|
.size = XT_ALIGN(0),
|
||||||
|
.userspacesize = XT_ALIGN(0),
|
||||||
|
.help = steal_tg_help,
|
||||||
|
.parse = steal_tg_parse,
|
||||||
|
.final_check = steal_tg_check,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void _init(void)
|
||||||
|
{
|
||||||
|
xtables_register_target(&steal_tg_reg);
|
||||||
|
}
|
2
extensions/libxt_STEAL.man
Normal file
2
extensions/libxt_STEAL.man
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
Like the DROP target, but does not throw an error like DROP when used in the
|
||||||
|
\fBOUTPUT\fP chain.
|
@@ -21,21 +21,11 @@ static void sysrq_tg_check(unsigned int flags)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct xtables_target sysrq_tg4_reg = {
|
static struct xtables_target sysrq_tg_reg = {
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.name = "SYSRQ",
|
.name = "SYSRQ",
|
||||||
.family = PF_INET,
|
.revision = 1,
|
||||||
.size = XT_ALIGN(0),
|
.family = PF_UNSPEC,
|
||||||
.userspacesize = XT_ALIGN(0),
|
|
||||||
.help = sysrq_tg_help,
|
|
||||||
.parse = sysrq_tg_parse,
|
|
||||||
.final_check = sysrq_tg_check,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct xtables_target sysrq_tg6_reg = {
|
|
||||||
.version = XTABLES_VERSION,
|
|
||||||
.name = "SYSRQ",
|
|
||||||
.family = PF_INET6,
|
|
||||||
.size = XT_ALIGN(0),
|
.size = XT_ALIGN(0),
|
||||||
.userspacesize = XT_ALIGN(0),
|
.userspacesize = XT_ALIGN(0),
|
||||||
.help = sysrq_tg_help,
|
.help = sysrq_tg_help,
|
||||||
@@ -45,6 +35,5 @@ static struct xtables_target sysrq_tg6_reg = {
|
|||||||
|
|
||||||
static __attribute__((constructor)) void sysrq_tg_ldr(void)
|
static __attribute__((constructor)) void sysrq_tg_ldr(void)
|
||||||
{
|
{
|
||||||
xtables_register_target(&sysrq_tg4_reg);
|
xtables_register_target(&sysrq_tg_reg);
|
||||||
xtables_register_target(&sysrq_tg6_reg);
|
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
The SYSRQ target allows to remotely trigger sysrq on the local machine over the
|
The SYSRQ target allows to remotely trigger sysrq on the local machine over the
|
||||||
network. This can be useful when vital parts of the machine hang, for example
|
network. This can be useful when vital parts of the machine hang, for example
|
||||||
an oops in a filesystem causing locks to be not released and processes to get
|
an oops in a filesystem causing locks to be not released and processes to get
|
||||||
stuck as a result - if still possible, use /proc/sysrq-trigger. Even when
|
stuck as a result \(em if still possible, use /proc/sysrq-trigger. Even when
|
||||||
processes are stuck, interrupts are likely to be still processed, and as such,
|
processes are stuck, interrupts are likely to be still processed, and as such,
|
||||||
sysrq can be triggered through incoming network packets.
|
sysrq can be triggered through incoming network packets.
|
||||||
.PP
|
.PP
|
||||||
@@ -11,30 +11,30 @@ requests. The initial sequence number comes from the time of day so you will
|
|||||||
have a small window of vulnerability should time go backwards at a reboot.
|
have a small window of vulnerability should time go backwards at a reboot.
|
||||||
However, the file /sys/module/xt_SYSREQ/seqno can be used to both query and
|
However, the file /sys/module/xt_SYSREQ/seqno can be used to both query and
|
||||||
update the current sequence number. Also, you should limit as to who can issue
|
update the current sequence number. Also, you should limit as to who can issue
|
||||||
commands using \fB-s\fP and/or \fB-m mac\fP, and also that the destination is
|
commands using \fB\-s\fP and/or \fB\-m mac\fP, and also that the destination is
|
||||||
correct using \fB-d\fP (to protect against potential broadcast packets), noting
|
correct using \fB\-d\fP (to protect against potential broadcast packets),
|
||||||
that it is still short of MAC/IP spoofing:
|
noting that it is still short of MAC/IP spoofing:
|
||||||
.IP
|
.IP
|
||||||
-A INPUT -s 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
|
||||||
-p udp --dport 9 -j SYSRQ
|
10.10.25.7 \-p udp \-\-dport 9 \-j SYSRQ
|
||||||
.IP
|
.IP
|
||||||
(with IPsec) -A INPUT -s 10.10.25.1 -d 10.10.25.7 -m policy --dir in --pol
|
(with IPsec) \-A INPUT \-s 10.10.25.1 \-d 10.10.25.7 \-m policy \-\-dir in
|
||||||
ipsec --proto esp --tunnel-src 10.10.25.1 --tunnel-dst 10.10.25.7
|
\-\-pol ipsec \-\-proto esp \-\-tunnel\-src 10.10.25.1 \-\-tunnel\-dst
|
||||||
-p udp --dport 9 -j SYSRQ
|
10.10.25.7 \-p udp \-\-dport 9 \-j SYSRQ
|
||||||
.PP
|
.PP
|
||||||
You should also limit the rate at which connections can be received to limit
|
You should also limit the rate at which connections can be received to limit
|
||||||
the CPU time taken by illegal requests, for example:
|
the CPU time taken by illegal requests, for example:
|
||||||
.IP
|
.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
|
||||||
-p udp --dport 9 -m limit --limit 5/minute -j SYSRQ
|
10.10.25.7 \-p udp \-\-dport 9 \-m limit \-\-limit 5/minute \-j SYSRQ
|
||||||
.PP
|
.PP
|
||||||
This extension does not take any options. The \fB-p udp\fP options are
|
This extension does not take any options. The \fB\-p udp\fP options are
|
||||||
required.
|
required.
|
||||||
.PP
|
.PP
|
||||||
The SYSRQ password can be changed through
|
The SYSRQ password can be changed through
|
||||||
/sys/module/xt_SYSRQ/parameters/password, for example:
|
/sys/module/xt_SYSRQ/parameters/password, for example:
|
||||||
.IP
|
.IP
|
||||||
echo -n "password" >/sys/module/xt_SYSRQ/parameters/password
|
echo \-n "password" >/sys/module/xt_SYSRQ/parameters/password
|
||||||
.PP
|
.PP
|
||||||
Alternatively, the password may be specified at modprobe time, but this is
|
Alternatively, the password may be specified at modprobe time, but this is
|
||||||
insecure as people can possible see it through ps(1). You can use an option
|
insecure as people can possible see it through ps(1). You can use an option
|
||||||
@@ -59,13 +59,13 @@ sysrq_key="s" # the SysRq key(s)
|
|||||||
password="password"
|
password="password"
|
||||||
seqno="$(date +%s)"
|
seqno="$(date +%s)"
|
||||||
salt="$(dd bs=12 count=1 if=/dev/urandom 2>/dev/null |
|
salt="$(dd bs=12 count=1 if=/dev/urandom 2>/dev/null |
|
||||||
openssl enc -base64)"
|
openssl enc \-base64)"
|
||||||
req="$sysrq_key,$seqno,$salt"
|
req="$sysrq_key,$seqno,$salt"
|
||||||
req="$req,$(echo -n "$req,$password" | sha1sum | cut -c1-40)"
|
req="$req,$(echo \-n "$req,$password" | sha1sum | cut \-c1\-40)"
|
||||||
|
|
||||||
echo "$req" | socat stdin udp-sendto:10.10.25.7:9
|
echo "$req" | socat stdin udp\-sendto:10.10.25.7:9
|
||||||
# or
|
# or
|
||||||
echo "$req" | netcat -uw1 10.10.25.7 9
|
echo "$req" | netcat \-uw1 10.10.25.7 9
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
See the Linux docs for possible sysrq keys. Important ones are: re(b)oot,
|
See the Linux docs for possible sysrq keys. Important ones are: re(b)oot,
|
||||||
|
@@ -11,16 +11,16 @@ tarpit.
|
|||||||
|
|
||||||
To tarpit connections to TCP port 80 destined for the current machine:
|
To tarpit connections to TCP port 80 destined for the current machine:
|
||||||
.IP
|
.IP
|
||||||
-A INPUT -p tcp -m tcp --dport 80 -j TARPIT
|
\-A INPUT \-p tcp \-m tcp \-\-dport 80 \-j TARPIT
|
||||||
.P
|
.PP
|
||||||
To significantly slow down Code Red/Nimda-style scans of unused address space,
|
To significantly slow down Code Red/Nimda-style scans of unused address space,
|
||||||
forward unused ip addresses to a Linux box not acting as a router (e.g. "ip
|
forward unused ip addresses to a Linux box not acting as a router (e.g. "ip
|
||||||
route 10.0.0.0 255.0.0.0 ip.of.linux.box" on a Cisco), enable IP forwarding on
|
route 10.0.0.0 255.0.0.0 ip.of.linux.box" on a Cisco), enable IP forwarding on
|
||||||
the Linux box, and add:
|
the Linux box, and add:
|
||||||
.IP
|
.IP
|
||||||
-A FORWARD -p tcp -j TARPIT
|
\-A FORWARD \-p tcp \-j TARPIT
|
||||||
.IP
|
.IP
|
||||||
-A FORWARD -j DROP
|
\-A FORWARD \-j DROP
|
||||||
.PP
|
.PP
|
||||||
NOTE:
|
NOTE:
|
||||||
If you use the conntrack module while you are using TARPIT, you should also use
|
If you use the conntrack module while you are using TARPIT, you should also use
|
||||||
@@ -28,6 +28,6 @@ the NOTRACK target, or the kernel will unnecessarily allocate resources for
|
|||||||
each TARPITted connection. To TARPIT incoming connections to the standard IRC
|
each TARPITted connection. To TARPIT incoming connections to the standard IRC
|
||||||
port while using conntrack, you could:
|
port while using conntrack, you could:
|
||||||
.IP
|
.IP
|
||||||
-t raw -A PREROUTING -p tcp --dport 6667 -j NOTRACK
|
\-t raw \-A PREROUTING \-p tcp \-\-dport 6667 \-j NOTRACK
|
||||||
.IP
|
.IP
|
||||||
-A INPUT -p tcp --dport 6667 -j TARPIT
|
\-A INPUT \-p tcp \-\-dport 6667 \-j TARPIT
|
||||||
|
@@ -50,16 +50,12 @@ static int tee_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
switch (c) {
|
switch (c) {
|
||||||
case 'g':
|
case 'g':
|
||||||
if (*flags & FLAG_GATEWAY)
|
if (*flags & FLAG_GATEWAY)
|
||||||
exit_error(PARAMETER_PROBLEM,
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
"Cannot specify --gw more than once");
|
"Cannot specify --gw more than once");
|
||||||
|
|
||||||
if (check_inverse(optarg, &invert, NULL, 0))
|
ia = xtables_numeric_to_ipaddr(optarg);
|
||||||
exit_error(PARAMETER_PROBLEM,
|
|
||||||
"Unexpected \"!\" after --gateway");
|
|
||||||
|
|
||||||
ia = numeric_to_ipaddr(optarg);
|
|
||||||
if (ia == NULL)
|
if (ia == NULL)
|
||||||
exit_error(PARAMETER_PROBLEM,
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
"Invalid IP address %s", optarg);
|
"Invalid IP address %s", optarg);
|
||||||
|
|
||||||
memcpy(&info->gw, ia, sizeof(*ia));
|
memcpy(&info->gw, ia, sizeof(*ia));
|
||||||
@@ -79,16 +75,12 @@ static int tee_tg6_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
switch (c) {
|
switch (c) {
|
||||||
case 'g':
|
case 'g':
|
||||||
if (*flags & FLAG_GATEWAY)
|
if (*flags & FLAG_GATEWAY)
|
||||||
exit_error(PARAMETER_PROBLEM,
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
"Cannot specify --gw more than once");
|
"Cannot specify --gw more than once");
|
||||||
|
|
||||||
if (check_inverse(optarg, &invert, NULL, 0))
|
ia = xtables_numeric_to_ip6addr(optarg);
|
||||||
exit_error(PARAMETER_PROBLEM,
|
|
||||||
"Unexpected \"!\" after --gateway");
|
|
||||||
|
|
||||||
ia = numeric_to_ip6addr(optarg);
|
|
||||||
if (ia == NULL)
|
if (ia == NULL)
|
||||||
exit_error(PARAMETER_PROBLEM,
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
"Invalid IP address %s", optarg);
|
"Invalid IP address %s", optarg);
|
||||||
|
|
||||||
memcpy(&info->gw, ia, sizeof(*ia));
|
memcpy(&info->gw, ia, sizeof(*ia));
|
||||||
@@ -102,7 +94,7 @@ static int tee_tg6_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
static void tee_tg_check(unsigned int flags)
|
static void tee_tg_check(unsigned int flags)
|
||||||
{
|
{
|
||||||
if (flags == 0)
|
if (flags == 0)
|
||||||
exit_error(PARAMETER_PROBLEM, "TEE target: "
|
xtables_error(PARAMETER_PROBLEM, "TEE target: "
|
||||||
"--gateway parameter required");
|
"--gateway parameter required");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,9 +104,9 @@ static void tee_tg_print(const void *ip, const struct xt_entry_target *target,
|
|||||||
const struct xt_tee_tginfo *info = (const void *)target->data;
|
const struct xt_tee_tginfo *info = (const void *)target->data;
|
||||||
|
|
||||||
if (numeric)
|
if (numeric)
|
||||||
printf("TEE gw:%s ", ipaddr_to_numeric(&info->gw.in));
|
printf("TEE gw:%s ", xtables_ipaddr_to_numeric(&info->gw.in));
|
||||||
else
|
else
|
||||||
printf("TEE gw:%s ", ipaddr_to_anyname(&info->gw.in));
|
printf("TEE gw:%s ", xtables_ipaddr_to_anyname(&info->gw.in));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tee_tg6_print(const void *ip, const struct xt_entry_target *target,
|
static void tee_tg6_print(const void *ip, const struct xt_entry_target *target,
|
||||||
@@ -123,23 +115,23 @@ static void tee_tg6_print(const void *ip, const struct xt_entry_target *target,
|
|||||||
const struct xt_tee_tginfo *info = (const void *)target->data;
|
const struct xt_tee_tginfo *info = (const void *)target->data;
|
||||||
|
|
||||||
if (numeric)
|
if (numeric)
|
||||||
printf("TEE gw:%s ", ip6addr_to_numeric(&info->gw.in6));
|
printf("TEE gw:%s ", xtables_ip6addr_to_numeric(&info->gw.in6));
|
||||||
else
|
else
|
||||||
printf("TEE gw:%s ", ip6addr_to_anyname(&info->gw.in6));
|
printf("TEE gw:%s ", xtables_ip6addr_to_anyname(&info->gw.in6));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tee_tg_save(const void *ip, const struct xt_entry_target *target)
|
static void tee_tg_save(const void *ip, const struct xt_entry_target *target)
|
||||||
{
|
{
|
||||||
const struct xt_tee_tginfo *info = (const void *)target->data;
|
const struct xt_tee_tginfo *info = (const void *)target->data;
|
||||||
|
|
||||||
printf("--gateway %s ", ipaddr_to_numeric(&info->gw.in));
|
printf("--gateway %s ", xtables_ipaddr_to_numeric(&info->gw.in));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tee_tg6_save(const void *ip, const struct xt_entry_target *target)
|
static void tee_tg6_save(const void *ip, const struct xt_entry_target *target)
|
||||||
{
|
{
|
||||||
const struct xt_tee_tginfo *info = (const void *)target->data;
|
const struct xt_tee_tginfo *info = (const void *)target->data;
|
||||||
|
|
||||||
printf("--gateway %s ", ip6addr_to_numeric(&info->gw.in6));
|
printf("--gateway %s ", xtables_ip6addr_to_numeric(&info->gw.in6));
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct xtables_target tee_tg_reg = {
|
static struct xtables_target tee_tg_reg = {
|
||||||
|
@@ -3,6 +3,6 @@ machine on the \fBlocal\fP network segment. In other words, the nexthop
|
|||||||
must be the target, or you will have to configure the nexthop to forward it
|
must be the target, or you will have to configure the nexthop to forward it
|
||||||
further if so desired.
|
further if so desired.
|
||||||
.TP
|
.TP
|
||||||
\fB--gw\fP \fIipaddr\fP
|
\fB\-\-gw\fP \fIipaddr\fP
|
||||||
Send the cloned packet to the host reachable at the given IP address.
|
Send the cloned packet to the host reachable at the given IP address.
|
||||||
Use of 0.0.0.0 (for IPv4 packets) or :: (IPv6) is invalid.
|
Use of 0.0.0.0 (for IPv4 packets) or :: (IPv6) is invalid.
|
||||||
|
@@ -37,13 +37,13 @@ static int condition_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
|
|
||||||
if (c == 'X') {
|
if (c == 'X') {
|
||||||
if (*flags)
|
if (*flags)
|
||||||
exit_error(PARAMETER_PROBLEM,
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
"Can't specify multiple conditions");
|
"Can't specify multiple conditions");
|
||||||
|
|
||||||
if (strlen(optarg) < sizeof(info->name))
|
if (strlen(optarg) < sizeof(info->name))
|
||||||
strcpy(info->name, optarg);
|
strcpy(info->name, optarg);
|
||||||
else
|
else
|
||||||
exit_error(PARAMETER_PROBLEM,
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
"File name too long");
|
"File name too long");
|
||||||
|
|
||||||
info->invert = invert;
|
info->invert = invert;
|
||||||
@@ -57,7 +57,7 @@ static int condition_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
static void condition_check(unsigned int flags)
|
static void condition_check(unsigned int flags)
|
||||||
{
|
{
|
||||||
if (flags == 0)
|
if (flags == 0)
|
||||||
exit_error(PARAMETER_PROBLEM,
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
"Condition match: must specify --condition");
|
"Condition match: must specify --condition");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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;
|
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 = {
|
static struct xtables_match condition_mt_reg = {
|
||||||
.name = "condition",
|
.name = "condition",
|
||||||
.revision = 0,
|
.revision = 1,
|
||||||
.family = PF_UNSPEC,
|
.family = PF_UNSPEC,
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.size = XT_ALIGN(sizeof(struct xt_condition_mtinfo)),
|
.size = XT_ALIGN(sizeof(struct xt_condition_mtinfo)),
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
This matches if a specific condition variable is (un)set.
|
This matches if a specific condition variable is (un)set.
|
||||||
.TP
|
.TP
|
||||||
[\fB!\fP] \fB--condition\fP \fIname\fP
|
[\fB!\fP] \fB\-\-condition\fP \fIname\fP
|
||||||
Match on boolean value stored in /proc/net/nf_condition/\fIname\fP.
|
Match on boolean value stored in /proc/net/nf_condition/\fIname\fP.
|
||||||
|
@@ -1,4 +0,0 @@
|
|||||||
.TP
|
|
||||||
\fB--mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
|
|
||||||
Matches the DHCP Client Host address in a DHCP message. \fImask\fP specifies
|
|
||||||
the prefix length of the initial portion to match.
|
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* "dhcpaddr" match extension for iptables
|
* "dhcpmac" match extension for iptables
|
||||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
@@ -14,37 +14,37 @@
|
|||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
#include <xtables.h>
|
#include <xtables.h>
|
||||||
#include "xt_DHCPADDR.h"
|
#include "xt_DHCPMAC.h"
|
||||||
#include "mac.c"
|
#include "mac.c"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
F_MAC = 1 << 0,
|
F_MAC = 1 << 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct option dhcpaddr_mt_opts[] = {
|
static const struct option dhcpmac_mt_opts[] = {
|
||||||
{.name = "mac", .has_arg = true, .val = 'M'},
|
{.name = "mac", .has_arg = true, .val = 'M'},
|
||||||
{NULL},
|
{NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void dhcpaddr_mt_help(void)
|
static void dhcpmac_mt_help(void)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
"dhcpaddr match options:\n"
|
"dhcpmac match options:\n"
|
||||||
"[!] --mac lladdr[/mask] Match on MAC address in DHCP Client Host field\n"
|
"[!] --mac lladdr[/mask] Match on MAC address in DHCP Client Host field\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dhcpaddr_mt_parse(int c, char **argv, int invert,
|
static int dhcpmac_mt_parse(int c, char **argv, int invert,
|
||||||
unsigned int *flags, const void *entry, struct xt_entry_match **match)
|
unsigned int *flags, const void *entry, struct xt_entry_match **match)
|
||||||
{
|
{
|
||||||
struct dhcpaddr_info *info = (void *)(*match)->data;
|
struct dhcpmac_info *info = (void *)(*match)->data;
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'M':
|
case 'M':
|
||||||
param_act(P_ONLY_ONCE, "dhcpaddr", "--mac", *flags & F_MAC);
|
xtables_param_act(XTF_ONLY_ONCE, "dhcpmac", "--mac", *flags & F_MAC);
|
||||||
param_act(P_NO_INVERT, "dhcpaddr", "--mac", invert);
|
xtables_param_act(XTF_NO_INVERT, "dhcpmac", "--mac", invert);
|
||||||
if (!mac_parse(optarg, info->addr, &info->mask))
|
if (!mac_parse(optarg, info->addr, &info->mask))
|
||||||
param_act(P_BAD_VALUE, "dhcpaddr", "--mac", optarg);
|
xtables_param_act(XTF_BAD_VALUE, "dhcpmac", "--mac", optarg);
|
||||||
if (invert)
|
if (invert)
|
||||||
info->invert = true;
|
info->invert = true;
|
||||||
*flags |= F_MAC;
|
*flags |= F_MAC;
|
||||||
@@ -54,26 +54,26 @@ static int dhcpaddr_mt_parse(int c, char **argv, int invert,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dhcpaddr_mt_check(unsigned int flags)
|
static void dhcpmac_mt_check(unsigned int flags)
|
||||||
{
|
{
|
||||||
if (flags == 0)
|
if (flags == 0)
|
||||||
exit_error(PARAMETER_PROBLEM, "dhcpaddr match: "
|
xtables_error(PARAMETER_PROBLEM, "dhcpmac match: "
|
||||||
"--mac parameter required");
|
"--mac parameter required");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dhcpaddr_mt_print(const void *ip,
|
static void dhcpmac_mt_print(const void *ip,
|
||||||
const struct xt_entry_match *match, int numeric)
|
const struct xt_entry_match *match, int numeric)
|
||||||
{
|
{
|
||||||
const struct dhcpaddr_info *info = (void *)match->data;
|
const struct dhcpmac_info *info = (void *)match->data;
|
||||||
|
|
||||||
printf("dhcpaddr %s" DH_MAC_FMT "/%u ",
|
printf("dhcpmac %s" DH_MAC_FMT "/%u ",
|
||||||
info->invert ? "!" : "", DH_MAC_HEX(info->addr), info->mask);
|
info->invert ? "!" : "", DH_MAC_HEX(info->addr), info->mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dhcpaddr_mt_save(const void *ip,
|
static void dhcpmac_mt_save(const void *ip,
|
||||||
const struct xt_entry_match *match)
|
const struct xt_entry_match *match)
|
||||||
{
|
{
|
||||||
const struct dhcpaddr_info *info = (void *)match->data;
|
const struct dhcpmac_info *info = (void *)match->data;
|
||||||
|
|
||||||
if (info->invert)
|
if (info->invert)
|
||||||
printf("! ");
|
printf("! ");
|
||||||
@@ -81,22 +81,22 @@ static void dhcpaddr_mt_save(const void *ip,
|
|||||||
DH_MAC_HEX(info->addr), info->mask);
|
DH_MAC_HEX(info->addr), info->mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct xtables_match dhcpaddr_mt_reg = {
|
static struct xtables_match dhcpmac_mt_reg = {
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.name = "dhcpaddr",
|
.name = "dhcpmac",
|
||||||
.revision = 0,
|
.revision = 0,
|
||||||
.family = PF_INET,
|
.family = PF_INET,
|
||||||
.size = XT_ALIGN(sizeof(struct dhcpaddr_info)),
|
.size = XT_ALIGN(sizeof(struct dhcpmac_info)),
|
||||||
.userspacesize = XT_ALIGN(sizeof(struct dhcpaddr_info)),
|
.userspacesize = XT_ALIGN(sizeof(struct dhcpmac_info)),
|
||||||
.help = dhcpaddr_mt_help,
|
.help = dhcpmac_mt_help,
|
||||||
.parse = dhcpaddr_mt_parse,
|
.parse = dhcpmac_mt_parse,
|
||||||
.final_check = dhcpaddr_mt_check,
|
.final_check = dhcpmac_mt_check,
|
||||||
.print = dhcpaddr_mt_print,
|
.print = dhcpmac_mt_print,
|
||||||
.save = dhcpaddr_mt_save,
|
.save = dhcpmac_mt_save,
|
||||||
.extra_opts = dhcpaddr_mt_opts,
|
.extra_opts = dhcpmac_mt_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
static __attribute__((constructor)) void dhcpaddr_mt_ldr(void)
|
static __attribute__((constructor)) void dhcpmac_mt_ldr(void)
|
||||||
{
|
{
|
||||||
xtables_register_match(&dhcpaddr_mt_reg);
|
xtables_register_match(&dhcpmac_mt_reg);
|
||||||
}
|
}
|
4
extensions/libxt_dhcpmac.man
Normal file
4
extensions/libxt_dhcpmac.man
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
.TP
|
||||||
|
\fB\-\-mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
|
||||||
|
Matches the DHCP "Client Host" address (a MAC address) in a DHCP message.
|
||||||
|
\fImask\fP specifies the prefix length of the initial portion to match.
|
@@ -9,6 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -54,22 +55,22 @@ static int fuzzy_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
switch (c) {
|
switch (c) {
|
||||||
case '1':
|
case '1':
|
||||||
if (invert)
|
if (invert)
|
||||||
exit_error(PARAMETER_PROBLEM,"Can't specify ! --lower-limit");
|
xtables_error(PARAMETER_PROBLEM,"Can't specify ! --lower-limit");
|
||||||
if (*flags & IPT_FUZZY_OPT_MINIMUM)
|
if (*flags & IPT_FUZZY_OPT_MINIMUM)
|
||||||
exit_error(PARAMETER_PROBLEM,"Can't specify --lower-limit twice");
|
xtables_error(PARAMETER_PROBLEM,"Can't specify --lower-limit twice");
|
||||||
if (string_to_number(optarg,1,FUZZY_MAX_RATE,&num) == -1 || num < 1)
|
if (!xtables_strtoui(optarg, NULL, &num, 1, FUZZY_MAX_RATE) || num < 1)
|
||||||
exit_error(PARAMETER_PROBLEM,"BAD --lower-limit");
|
xtables_error(PARAMETER_PROBLEM,"BAD --lower-limit");
|
||||||
info->minimum_rate = num;
|
info->minimum_rate = num;
|
||||||
*flags |= IPT_FUZZY_OPT_MINIMUM;
|
*flags |= IPT_FUZZY_OPT_MINIMUM;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case '2':
|
case '2':
|
||||||
if (invert)
|
if (invert)
|
||||||
exit_error(PARAMETER_PROBLEM,"Can't specify ! --upper-limit");
|
xtables_error(PARAMETER_PROBLEM,"Can't specify ! --upper-limit");
|
||||||
if (*flags & IPT_FUZZY_OPT_MAXIMUM)
|
if (*flags & IPT_FUZZY_OPT_MAXIMUM)
|
||||||
exit_error(PARAMETER_PROBLEM,"Can't specify --upper-limit twice");
|
xtables_error(PARAMETER_PROBLEM,"Can't specify --upper-limit twice");
|
||||||
if (string_to_number(optarg,1,FUZZY_MAX_RATE,&num) == -1 || num < 1)
|
if (!xtables_strtoui(optarg, NULL, &num, 1, FUZZY_MAX_RATE) || num < 1)
|
||||||
exit_error(PARAMETER_PROBLEM,"BAD --upper-limit");
|
xtables_error(PARAMETER_PROBLEM,"BAD --upper-limit");
|
||||||
info->maximum_rate = num;
|
info->maximum_rate = num;
|
||||||
*flags |= IPT_FUZZY_OPT_MAXIMUM;
|
*flags |= IPT_FUZZY_OPT_MAXIMUM;
|
||||||
return true;
|
return true;
|
||||||
@@ -100,9 +101,10 @@ static void fuzzy_mt_save(const void *ip, const struct xt_entry_match *match)
|
|||||||
|
|
||||||
static struct xtables_match fuzzy_mt_reg = {
|
static struct xtables_match fuzzy_mt_reg = {
|
||||||
.name = "fuzzy",
|
.name = "fuzzy",
|
||||||
|
.revision = 1,
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.size = XT_ALIGN(sizeof(struct xt_fuzzy_mtinfo)),
|
.size = XT_ALIGN(sizeof(struct xt_fuzzy_mtinfo)),
|
||||||
.userspacesize = XT_ALIGN(sizeof(struct xt_fuzzy_mtinfo)),
|
.userspacesize = offsetof(struct xt_fuzzy_mtinfo, packets_total),
|
||||||
.help = fuzzy_mt_help,
|
.help = fuzzy_mt_help,
|
||||||
.init = fuzzy_mt_init,
|
.init = fuzzy_mt_init,
|
||||||
.parse = fuzzy_mt_parse,
|
.parse = fuzzy_mt_parse,
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
This module matches a rate limit based on a fuzzy logic controller (FLC).
|
This module matches a rate limit based on a fuzzy logic controller (FLC).
|
||||||
.TP
|
.TP
|
||||||
\fB--lower-limit\fP \fInumber\fP
|
\fB\-\-lower\-limit\fP \fInumber\fP
|
||||||
Specifies the lower limit, in packets per second.
|
Specifies the lower limit, in packets per second.
|
||||||
.TP
|
.TP
|
||||||
\fB--upper-limit\fP \fInumber\fP
|
\fB\-\-upper\-limit\fP \fInumber\fP
|
||||||
Specifies the upper limit, also in packets per second.
|
Specifies the upper limit, also in packets per second.
|
||||||
|
@@ -64,16 +64,16 @@ static struct geoip_subnet *geoip_get_subnets(const char *code, uint32_t *count)
|
|||||||
|
|
||||||
if ((fd = open(buf, O_RDONLY)) < 0) {
|
if ((fd = open(buf, O_RDONLY)) < 0) {
|
||||||
fprintf(stderr, "Could not open %s: %s\n", buf, strerror(errno));
|
fprintf(stderr, "Could not open %s: %s\n", buf, strerror(errno));
|
||||||
exit_error(OTHER_PROBLEM, "Could not read geoip database");
|
xtables_error(OTHER_PROBLEM, "Could not read geoip database");
|
||||||
}
|
}
|
||||||
|
|
||||||
fstat(fd, &sb);
|
fstat(fd, &sb);
|
||||||
if (sb.st_size % sizeof(struct geoip_subnet) != 0)
|
if (sb.st_size % sizeof(struct geoip_subnet) != 0)
|
||||||
exit_error(OTHER_PROBLEM, "Database file %s seems to be "
|
xtables_error(OTHER_PROBLEM, "Database file %s seems to be "
|
||||||
"corrupted", buf);
|
"corrupted", buf);
|
||||||
subnets = malloc(sb.st_size);
|
subnets = malloc(sb.st_size);
|
||||||
if (subnets == NULL)
|
if (subnets == NULL)
|
||||||
exit_error(OTHER_PROBLEM, "geoip: insufficient memory");
|
xtables_error(OTHER_PROBLEM, "geoip: insufficient memory");
|
||||||
read(fd, subnets, sb.st_size);
|
read(fd, subnets, sb.st_size);
|
||||||
close(fd);
|
close(fd);
|
||||||
*count = sb.st_size / sizeof(struct geoip_subnet);
|
*count = sb.st_size / sizeof(struct geoip_subnet);
|
||||||
@@ -103,7 +103,7 @@ check_geoip_cc(char *cc, u_int16_t cc_used[], u_int8_t count)
|
|||||||
|
|
||||||
if (strlen(cc) != 2) /* Country must be 2 chars long according
|
if (strlen(cc) != 2) /* Country must be 2 chars long according
|
||||||
to the ISO3166 standard */
|
to the ISO3166 standard */
|
||||||
exit_error(PARAMETER_PROBLEM,
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
"geoip: invalid country code '%s'", cc);
|
"geoip: invalid country code '%s'", cc);
|
||||||
|
|
||||||
// Verification will fail if chars aren't uppercased.
|
// Verification will fail if chars aren't uppercased.
|
||||||
@@ -112,7 +112,7 @@ check_geoip_cc(char *cc, u_int16_t cc_used[], u_int8_t count)
|
|||||||
if (isalnum(cc[i]) != 0)
|
if (isalnum(cc[i]) != 0)
|
||||||
cc[i] = toupper(cc[i]);
|
cc[i] = toupper(cc[i]);
|
||||||
else
|
else
|
||||||
exit_error(PARAMETER_PROBLEM,
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
"geoip: invalid country code '%s'", cc);
|
"geoip: invalid country code '%s'", cc);
|
||||||
|
|
||||||
/* Convert chars into a single 16 bit integer.
|
/* Convert chars into a single 16 bit integer.
|
||||||
@@ -140,7 +140,7 @@ static unsigned int parse_geoip_cc(const char *ccstr, uint16_t *cc,
|
|||||||
|
|
||||||
buffer = strdup(ccstr);
|
buffer = strdup(ccstr);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
exit_error(OTHER_PROBLEM,
|
xtables_error(OTHER_PROBLEM,
|
||||||
"geoip: insufficient memory available");
|
"geoip: insufficient memory available");
|
||||||
|
|
||||||
for (cp = buffer, i = 0; cp && i < XT_GEOIP_MAX; cp = next, i++)
|
for (cp = buffer, i = 0; cp && i < XT_GEOIP_MAX; cp = next, i++)
|
||||||
@@ -150,19 +150,19 @@ static unsigned int parse_geoip_cc(const char *ccstr, uint16_t *cc,
|
|||||||
|
|
||||||
if ((cctmp = check_geoip_cc(cp, cc, count)) != 0) {
|
if ((cctmp = check_geoip_cc(cp, cc, count)) != 0) {
|
||||||
if ((mem[count++].user = (unsigned long)geoip_load_cc(cp, cctmp)) == 0)
|
if ((mem[count++].user = (unsigned long)geoip_load_cc(cp, cctmp)) == 0)
|
||||||
exit_error(OTHER_PROBLEM,
|
xtables_error(OTHER_PROBLEM,
|
||||||
"geoip: insufficient memory available");
|
"geoip: insufficient memory available");
|
||||||
cc[count-1] = cctmp;
|
cc[count-1] = cctmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cp)
|
if (cp)
|
||||||
exit_error(PARAMETER_PROBLEM,
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
"geoip: too many countries specified");
|
"geoip: too many countries specified");
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
exit_error(PARAMETER_PROBLEM,
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
"geoip: don't know what happened");
|
"geoip: don't know what happened");
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
@@ -176,7 +176,7 @@ static int geoip_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
switch (c) {
|
switch (c) {
|
||||||
case '1':
|
case '1':
|
||||||
if (*flags & (XT_GEOIP_SRC | XT_GEOIP_DST))
|
if (*flags & (XT_GEOIP_SRC | XT_GEOIP_DST))
|
||||||
exit_error(PARAMETER_PROBLEM,
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
"geoip: Only exactly one of --source-country "
|
"geoip: Only exactly one of --source-country "
|
||||||
"or --destination-country must be specified!");
|
"or --destination-country must be specified!");
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ static int geoip_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
|
|
||||||
case '2':
|
case '2':
|
||||||
if (*flags & (XT_GEOIP_SRC | XT_GEOIP_DST))
|
if (*flags & (XT_GEOIP_SRC | XT_GEOIP_DST))
|
||||||
exit_error(PARAMETER_PROBLEM,
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
"geoip: Only exactly one of --source-country "
|
"geoip: Only exactly one of --source-country "
|
||||||
"or --destination-country must be specified!");
|
"or --destination-country must be specified!");
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@ static void
|
|||||||
geoip_final_check(unsigned int flags)
|
geoip_final_check(unsigned int flags)
|
||||||
{
|
{
|
||||||
if (!flags)
|
if (!flags)
|
||||||
exit_error(PARAMETER_PROBLEM,
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
"geoip: missing arguments");
|
"geoip: missing arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,9 +261,10 @@ geoip_save(const void *ip, const struct xt_entry_match *match)
|
|||||||
static struct xtables_match geoip_match = {
|
static struct xtables_match geoip_match = {
|
||||||
.family = AF_INET,
|
.family = AF_INET,
|
||||||
.name = "geoip",
|
.name = "geoip",
|
||||||
|
.revision = 1,
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.size = XT_ALIGN(sizeof(struct xt_geoip_match_info)),
|
.size = XT_ALIGN(sizeof(struct xt_geoip_match_info)),
|
||||||
.userspacesize = XT_ALIGN(offsetof(struct xt_geoip_match_info, mem)),
|
.userspacesize = offsetof(struct xt_geoip_match_info, mem),
|
||||||
.help = geoip_help,
|
.help = geoip_help,
|
||||||
.parse = geoip_parse,
|
.parse = geoip_parse,
|
||||||
.final_check = geoip_final_check,
|
.final_check = geoip_final_check,
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
Match a packet by its source or destination country.
|
Match a packet by its source or destination country.
|
||||||
.TP
|
.TP
|
||||||
[\fB!\fP] \fB--src-cc\fP, \fB--source-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
|
[\fB!\fP] \fB\-\-src\-cc\fP, \fB\-\-source\-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
|
||||||
Match packet coming from (one of) the specified country(ies)
|
Match packet coming from (one of) the specified country(ies)
|
||||||
.TP
|
.TP
|
||||||
[\fB!\fP] \fB--dst-cc\fP, \fB--destination-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
|
[\fB!\fP] \fB\-\-dst\-cc\fP, \fB\-\-destination\-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
|
||||||
Match packet going to (one of) the specified country(ies)
|
Match packet going to (one of) the specified country(ies)
|
||||||
.TP
|
.TP
|
||||||
NOTE:
|
NOTE:
|
||||||
|
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);
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user