mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-20 19:44:56 +02:00
Compare commits
311 Commits
v1.44
...
e3ae438e2e
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e3ae438e2e | ||
![]() |
c90ecf4320 | ||
![]() |
1abcd731c0 | ||
![]() |
af10045c75 | ||
![]() |
6d74a85f70 | ||
![]() |
b9893b9505 | ||
![]() |
714998176a | ||
![]() |
81ab0b9586 | ||
![]() |
1f308c7262 | ||
![]() |
87189b0051 | ||
![]() |
d3fb275c03 | ||
![]() |
9faa3085bb | ||
![]() |
947a677ddb | ||
![]() |
42a9b5c6c3 | ||
![]() |
3233a0ed2c | ||
![]() |
97808473f9 | ||
![]() |
3aa4ca3eaf | ||
![]() |
5104269605 | ||
![]() |
4ee209416f | ||
![]() |
43df040e05 | ||
![]() |
f59a4eb9d9 | ||
![]() |
a238253509 | ||
![]() |
4547e4c5cc | ||
![]() |
5d94a36d22 | ||
![]() |
9d5b2e2e0e | ||
![]() |
f973577ec0 | ||
![]() |
a35feefa0f | ||
![]() |
a1b3d81ccb | ||
![]() |
6504f251c6 | ||
![]() |
1c67775d10 | ||
![]() |
7327cd725b | ||
![]() |
5c8aecdd56 | ||
![]() |
5ad9de75d4 | ||
![]() |
9e84e8f13d | ||
![]() |
50153ffdb9 | ||
![]() |
9c4aeea422 | ||
![]() |
c09d0704af | ||
![]() |
0021003dc7 | ||
![]() |
0ab3247900 | ||
![]() |
d3f7dc1f55 | ||
![]() |
87d3aab175 | ||
![]() |
bfb0516c79 | ||
![]() |
939d3ee0d3 | ||
![]() |
5df71f8741 | ||
![]() |
82379e8ec1 | ||
![]() |
b3a3f2e91b | ||
![]() |
63fb5d3490 | ||
![]() |
05cacbe84c | ||
![]() |
3c120ef5f1 | ||
![]() |
b0a1aacd4b | ||
![]() |
c3bd1c61d1 | ||
![]() |
9cd0b44c81 | ||
![]() |
b4faa4de65 | ||
![]() |
b05ea5644c | ||
![]() |
b052ec0f7d | ||
![]() |
249df831b0 | ||
![]() |
86112194da | ||
![]() |
20e1b669fc | ||
![]() |
e4784832ed | ||
![]() |
48e30a0990 | ||
![]() |
ea588d0b9c | ||
![]() |
96460646e9 | ||
![]() |
2cb4b2bec6 | ||
![]() |
37f19c6b96 | ||
![]() |
73b96e25e4 | ||
![]() |
ca84ee8e15 | ||
![]() |
c9ba3507fc | ||
![]() |
b87366bb83 | ||
![]() |
8bbb0cb3eb | ||
![]() |
b4629f46c6 | ||
![]() |
f7f18f0c4f | ||
![]() |
9193adc835 | ||
![]() |
74fcd4a2ae | ||
![]() |
4b43df69f5 | ||
![]() |
4c68c774c8 | ||
![]() |
0888357642 | ||
![]() |
d31067b32e | ||
![]() |
fc44fcb94f | ||
![]() |
26f5bcbdbb | ||
![]() |
061fc794b5 | ||
![]() |
bf1ca298ae | ||
![]() |
6e5edc8372 | ||
![]() |
7ad14b7150 | ||
![]() |
0cc51e6b35 | ||
![]() |
fa7bcbfb9b | ||
![]() |
d86101e470 | ||
![]() |
00114dea3d | ||
![]() |
d4c2aac5f8 | ||
![]() |
5622c5f024 | ||
![]() |
358991306c | ||
![]() |
2bbdcb1d58 | ||
![]() |
b14728691d | ||
![]() |
708f883635 | ||
![]() |
f822b8bc1b | ||
![]() |
4205900d9b | ||
![]() |
266638e41e | ||
![]() |
ebcd176822 | ||
![]() |
6b47d09a36 | ||
![]() |
1849c47ae8 | ||
![]() |
68d895f75c | ||
![]() |
53b6b862cc | ||
![]() |
ed10cb9c17 | ||
![]() |
5903f4bcfc | ||
![]() |
5e19871613 | ||
![]() |
30fb410003 | ||
![]() |
3ea761a1ed | ||
![]() |
4603d3e0f4 | ||
![]() |
b0b2b5a74c | ||
![]() |
082d42fb21 | ||
![]() |
b1f0e118a0 | ||
![]() |
56fba3ecff | ||
![]() |
9057fb48f3 | ||
![]() |
e19f91ddb4 | ||
![]() |
256ac1a4f6 | ||
![]() |
b91dbd03c7 | ||
![]() |
254c6926d3 | ||
![]() |
2e78cf03a4 | ||
![]() |
bf63a25a64 | ||
![]() |
94656621ed | ||
![]() |
95d4f9e113 | ||
![]() |
123e1a14e9 | ||
![]() |
f4f3f98609 | ||
![]() |
9b1c7c1c04 | ||
![]() |
ed8e496750 | ||
![]() |
5339fcc65b | ||
![]() |
2265c1b854 | ||
![]() |
2c574f992d | ||
![]() |
3a24468a68 | ||
![]() |
7682cc8c34 | ||
![]() |
215b3c5b12 | ||
![]() |
4dbb36b723 | ||
![]() |
10f951e61d | ||
![]() |
a4c50ae405 | ||
![]() |
38d89983ca | ||
![]() |
25985650a9 | ||
![]() |
4de9ff1505 | ||
![]() |
46b7cf206b | ||
![]() |
29d10e11fa | ||
![]() |
60a26f1dea | ||
![]() |
cdf90737be | ||
![]() |
5713415014 | ||
![]() |
230bc1f327 | ||
![]() |
d360f5578c | ||
![]() |
dd32060f6a | ||
![]() |
d5eb4e586c | ||
![]() |
1b4b4347c5 | ||
![]() |
2f37af43c5 | ||
![]() |
56e5970c64 | ||
![]() |
2b76b68c65 | ||
![]() |
d2eeac4c32 | ||
![]() |
0e9037b000 | ||
![]() |
0a6091b64a | ||
![]() |
b565a85fb6 | ||
![]() |
425a035959 | ||
![]() |
89c80f5981 | ||
![]() |
8579fd2b3b | ||
![]() |
0a836e9677 | ||
![]() |
90b0f3a51f | ||
![]() |
89d1b808b9 | ||
![]() |
c839e87bbb | ||
![]() |
a587f9526d | ||
![]() |
1874fcd519 | ||
![]() |
21ea7b76ec | ||
![]() |
ee8da2b1ac | ||
![]() |
19a4359368 | ||
![]() |
1b379667d3 | ||
![]() |
cd410aefe7 | ||
![]() |
e4b5cef8f0 | ||
![]() |
a8af97b8fa | ||
![]() |
db234c30cd | ||
![]() |
2e6fb73e85 | ||
![]() |
6024758b28 | ||
![]() |
69f3f21a32 | ||
![]() |
7af1b9737c | ||
![]() |
f5e95f35a7 | ||
![]() |
80bed0655f | ||
![]() |
bc6aaf74d8 | ||
![]() |
192243483a | ||
![]() |
e3114d60d5 | ||
![]() |
e6f20befad | ||
![]() |
5038e160f8 | ||
![]() |
a6289ec3ff | ||
![]() |
01e7128a80 | ||
![]() |
1dc2a1c2de | ||
![]() |
60b6b1dbef | ||
![]() |
fcb19403bc | ||
![]() |
f89f10bbe9 | ||
![]() |
a9358542fe | ||
![]() |
237fe7c660 | ||
![]() |
939fc901c1 | ||
![]() |
a4a077ff86 | ||
![]() |
bccf64d820 | ||
![]() |
7e3e156d92 | ||
![]() |
8f70b9a99d | ||
![]() |
e277360bcd | ||
![]() |
672f12b2a6 | ||
![]() |
8788b6c096 | ||
![]() |
96ce5ec488 | ||
![]() |
5e22c9c592 | ||
![]() |
01f97bfdd1 | ||
![]() |
1324442bce | ||
![]() |
a576f4d43e | ||
![]() |
cc17e1d0fe | ||
![]() |
c08835d65c | ||
![]() |
4c21811919 | ||
![]() |
431062c6ec | ||
![]() |
87adf3461f | ||
![]() |
f2e21e67a5 | ||
![]() |
ae307c0bf3 | ||
![]() |
ec8c6b8732 | ||
![]() |
7916b74a42 | ||
![]() |
7fbbd0401e | ||
![]() |
991c0cf4cf | ||
![]() |
b58e78968e | ||
![]() |
02eb0e5df9 | ||
![]() |
98ea6c538b | ||
![]() |
7cf7250e07 | ||
![]() |
f9b0ee7533 | ||
![]() |
a82d0ba517 | ||
![]() |
bc2bcc383c | ||
![]() |
c6c70ab30b | ||
![]() |
a0a8fbc091 | ||
![]() |
9414a5df34 | ||
![]() |
f28cfff138 | ||
![]() |
a8d7ec5ad6 | ||
![]() |
29f293743a | ||
![]() |
3bf7ebc48c | ||
![]() |
172bc7e306 | ||
![]() |
db45bbcb9e | ||
![]() |
b2cd0ab65b | ||
![]() |
b5a2f9aa14 | ||
![]() |
6fbb35d686 | ||
![]() |
e1d9825475 | ||
![]() |
efa8b9670a | ||
![]() |
2b38d081a5 | ||
![]() |
fda591dba4 | ||
![]() |
9de3027c02 | ||
![]() |
2dc8f21476 | ||
![]() |
e027089782 | ||
![]() |
fe7a30c746 | ||
![]() |
d582cc04df | ||
![]() |
13db8d78c9 | ||
![]() |
6a60b5ab75 | ||
![]() |
d48a5fe0f4 | ||
![]() |
b70905e7cb | ||
![]() |
3f04148501 | ||
![]() |
d96fff8893 | ||
![]() |
aceca54912 | ||
![]() |
cb1cdb190f | ||
![]() |
48ebf55444 | ||
![]() |
57c3cc1722 | ||
![]() |
29141b6e95 | ||
![]() |
cdac8506c3 | ||
![]() |
5494bc40f4 | ||
![]() |
bcdb7ed4e9 | ||
![]() |
1ed86c6bbd | ||
![]() |
2a5f1099c8 | ||
![]() |
c243c78af4 | ||
![]() |
91da2a0dbd | ||
![]() |
a160a2aa36 | ||
![]() |
b25e96fd49 | ||
![]() |
6d74f76a29 | ||
![]() |
78e47758c6 | ||
![]() |
bcdd42f556 | ||
![]() |
acf92ff914 | ||
![]() |
0e845bf23f | ||
![]() |
158e6a26eb | ||
![]() |
693c32f414 | ||
![]() |
3e337562d7 | ||
![]() |
bb25bc08c4 | ||
![]() |
ea3e4b2ed5 | ||
![]() |
557af2177f | ||
![]() |
60f5239630 | ||
![]() |
3ba7d8c3a9 | ||
![]() |
28d12faba8 | ||
![]() |
cf7a3d4342 | ||
![]() |
fabad77f8f | ||
![]() |
5e020d380c | ||
![]() |
a7fbf4f4de | ||
![]() |
4137f6c111 | ||
![]() |
04d8ebe31c | ||
![]() |
6ab4c02a54 | ||
![]() |
a66e4510b8 | ||
![]() |
31aebc134e | ||
![]() |
e640a15ec9 | ||
![]() |
66f213e324 | ||
![]() |
0dcc56bc62 | ||
![]() |
8db01220fd | ||
![]() |
95ff9a2de3 | ||
![]() |
2f1e094125 | ||
![]() |
37b000182f | ||
![]() |
255a310536 | ||
![]() |
3a6e73e986 | ||
![]() |
0a97126f5b | ||
![]() |
2ba833fe47 | ||
![]() |
77240e0918 | ||
![]() |
651e60f8d7 | ||
![]() |
54ac2a899a | ||
![]() |
61d2be172d | ||
![]() |
093f3b0a97 | ||
![]() |
57d25f22f1 | ||
![]() |
2f18ab31ec | ||
![]() |
12d0a8702c | ||
![]() |
35ce1adf5e | ||
![]() |
e5fe0b9c14 | ||
![]() |
cd7fc84b29 | ||
![]() |
4ff5a8fbf6 | ||
![]() |
37e3a543a9 | ||
![]() |
5f6cbbc663 | ||
![]() |
a2676585da | ||
![]() |
4a8aab6aed |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,7 +1,10 @@
|
|||||||
|
*.gcno
|
||||||
*.la
|
*.la
|
||||||
*.lo
|
*.lo
|
||||||
*.loT
|
*.loT
|
||||||
|
*.mod
|
||||||
*.o
|
*.o
|
||||||
|
.cache.mk
|
||||||
.deps/
|
.deps/
|
||||||
.dirstamp
|
.dirstamp
|
||||||
.libs/
|
.libs/
|
||||||
|
15
INSTALL
15
INSTALL
@@ -12,16 +12,21 @@ in combination with the kernel's Kbuild system.
|
|||||||
Supported configurations for this release
|
Supported configurations for this release
|
||||||
=========================================
|
=========================================
|
||||||
|
|
||||||
* iptables >= 1.4.5
|
* iptables >= 1.6.0
|
||||||
|
|
||||||
* kernel-devel >= 2.6.32
|
* kernel-devel >= 4.15
|
||||||
with prepared build/output directory
|
with prepared build/output directory
|
||||||
- CONFIG_NF_CONNTRACK or CONFIG_IP_NF_CONNTRACK
|
- CONFIG_NF_CONNTRACK
|
||||||
- CONFIG_NF_CONNTRACK_MARK or CONFIG_IP_NF_CONNTRACK_MARK
|
- CONFIG_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
|
- CONFIG_CONNECTOR y/m if you wish to receive userspace
|
||||||
notifications from pknock through netlink/connector
|
notifications from pknock through netlink/connector
|
||||||
|
|
||||||
|
(Use xtables-addons-1.x if you need support for Linux < 3.7.
|
||||||
|
Use xtables-addons-2.x if you need support for Linux < 4.15.)
|
||||||
|
Note: xtables-addons regularly fails to build with patched-to-death
|
||||||
|
kernels like on RHEL or SLES because the API does not match
|
||||||
|
LINUX_KERNEL_VERSION anymore.
|
||||||
|
|
||||||
|
|
||||||
Selecting extensions
|
Selecting extensions
|
||||||
====================
|
====================
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
# -*- Makefile -*-
|
# -*- Makefile -*-
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
SUBDIRS = extensions geoip
|
SUBDIRS = extensions extensions/ACCOUNT extensions/pknock geoip
|
||||||
|
|
||||||
man_MANS := xtables-addons.8
|
man_MANS := xtables-addons.8
|
||||||
|
|
||||||
@@ -11,8 +11,10 @@ FORCE:
|
|||||||
xtables-addons.8: FORCE
|
xtables-addons.8: FORCE
|
||||||
${MAKE} -f Makefile.mans all;
|
${MAKE} -f Makefile.mans all;
|
||||||
|
|
||||||
install-exec-hook:
|
clean-local-mans:
|
||||||
depmod -a || :;
|
${MAKE} -f Makefile.mans clean;
|
||||||
|
|
||||||
|
clean-local: clean-local-mans
|
||||||
|
|
||||||
config.status: Makefile.iptrules.in
|
config.status: Makefile.iptrules.in
|
||||||
|
|
||||||
|
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
srcdir := @srcdir@
|
srcdir := @srcdir@
|
||||||
|
|
||||||
wcman_matches := $(shell find "${srcdir}" -name 'libxt_[a-z]*.man' | sort)
|
wcman_matches := $(shell find "${srcdir}/extensions" -name 'libxt_[a-z]*.man' -print | sort)
|
||||||
wcman_targets := $(shell find "${srcdir}" -name 'libxt_[A-Z]*.man' | sort)
|
wcman_targets := $(shell find "${srcdir}/extensions" -name 'libxt_[A-Z]*.man' -print | sort)
|
||||||
wlist_matches := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_matches})
|
wlist_matches := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_matches})
|
||||||
wlist_targets := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_targets})
|
wlist_targets := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_targets})
|
||||||
|
|
||||||
@@ -38,3 +38,6 @@ matches.man: .manpages.lst ${wcman_matches}
|
|||||||
|
|
||||||
targets.man: .manpages.lst ${wcman_targets}
|
targets.man: .manpages.lst ${wcman_targets}
|
||||||
$(call man_run,${wlist_targets})
|
$(call man_run,${wlist_targets})
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f xtables-addons.8 matches.man targets.man .manpages.lst
|
||||||
|
54
README
54
README
@@ -1,57 +1,15 @@
|
|||||||
Xtables-addons
|
Xtables-addons
|
||||||
==============
|
==============
|
||||||
|
|
||||||
Xtables-addons is the proclaimed successor to patch-o-matic(-ng). It
|
Xtables-addons is a set of extensions that were not accepted in the
|
||||||
contains extensions that were not accepted in the main Xtables
|
Linux kernel and/or main Xtables/iptables package.
|
||||||
package.
|
|
||||||
|
|
||||||
Xtables-addons is different from patch-o-matic in that you do not
|
It superseded the earlier patch-o-matic(-ng) package in that no
|
||||||
have to patch or recompile either kernel or Xtables(iptables). But
|
patching and/or recompilation of either the kernel or
|
||||||
please see the INSTALL file for the minimum requirements of this
|
Xtables/iptables is required. However, do see the INSTALL file for
|
||||||
package.
|
the minimum requirements of Xtables-addons.
|
||||||
|
|
||||||
All code imported from patch-o-matic has been reviewed and all
|
|
||||||
apparent bugs like binary stability across multiarches, missing
|
|
||||||
sanity checks and incorrect endianess handling have been fixed,
|
|
||||||
simplified, and sped up.
|
|
||||||
|
|
||||||
|
|
||||||
Included in this package
|
Included in this package
|
||||||
========================
|
========================
|
||||||
- xt_ACCOUNT 1.16, libxt_ACCOUNT 1.3
|
- xt_ACCOUNT 1.16, libxt_ACCOUNT 1.3
|
||||||
|
|
||||||
|
|
||||||
Inclusion into a kernel tree
|
|
||||||
============================
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
External extensions
|
|
||||||
===================
|
|
||||||
|
|
||||||
The program "xa-download-more" can be used to download more
|
|
||||||
extensions from 3rd parties into the source tree. The URLs are listed
|
|
||||||
in the "sources" file. If the "sources" file contains an entry like
|
|
||||||
|
|
||||||
http://foobar.org/xa/
|
|
||||||
|
|
||||||
xa-download-more will inspect http://foobar.org/xa/xa-index.txt for
|
|
||||||
files to download. That file may contain
|
|
||||||
|
|
||||||
foobar.tar.bz2
|
|
||||||
|
|
||||||
and xa-download-more will then retrieve and unpack
|
|
||||||
http://foobar.org/xa/foobar.tar.bz2.
|
|
||||||
|
|
||||||
Files that should be contained in the tarball are an mconfig and
|
|
||||||
Kbuild files to control building the extension, libxt_foobar.c for
|
|
||||||
the userspace extension and xt_foobar.c for the kernel extension.
|
|
||||||
|
|
||||||
mconfig.foobar
|
|
||||||
extensions/Kbuild.foobar
|
|
||||||
extensions/Mbuild.foobar
|
|
||||||
extensions/libxt_foobar.c
|
|
||||||
extensions/libxt_foobar.man
|
|
||||||
extensions/xt_foobar.c
|
|
||||||
extensions/xt_foobar.h
|
|
||||||
|
44
configure.ac
44
configure.ac
@@ -1,4 +1,4 @@
|
|||||||
AC_INIT([xtables-addons], [1.44])
|
AC_INIT([xtables-addons], [3.18])
|
||||||
AC_CONFIG_AUX_DIR([build-aux])
|
AC_CONFIG_AUX_DIR([build-aux])
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
@@ -26,12 +26,12 @@ fi
|
|||||||
|
|
||||||
AC_CHECK_HEADERS([linux/netfilter/x_tables.h], [],
|
AC_CHECK_HEADERS([linux/netfilter/x_tables.h], [],
|
||||||
[AC_MSG_ERROR([You need to have linux/netfilter/x_tables.h, see INSTALL file for details])])
|
[AC_MSG_ERROR([You need to have linux/netfilter/x_tables.h, see INSTALL file for details])])
|
||||||
PKG_CHECK_MODULES([libxtables], [xtables >= 1.4.5])
|
PKG_CHECK_MODULES([libxtables], [xtables >= 1.6.0])
|
||||||
xtlibdir="$(pkg-config --variable=xtlibdir xtables)"
|
xtlibdir="$($PKG_CONFIG --variable=xtlibdir xtables)"
|
||||||
|
|
||||||
AC_ARG_WITH([xtlibdir],
|
AC_ARG_WITH([xtlibdir],
|
||||||
AS_HELP_STRING([--with-xtlibdir=PATH],
|
AS_HELP_STRING([--with-xtlibdir=PATH],
|
||||||
[Path where to install Xtables extensions [[autodetect]]]]),
|
[Path where to install Xtables extensions [[autodetect]]]),
|
||||||
[xtlibdir="$withval"])
|
[xtlibdir="$withval"])
|
||||||
AC_MSG_CHECKING([Xtables module directory])
|
AC_MSG_CHECKING([Xtables module directory])
|
||||||
AC_MSG_RESULT([$xtlibdir])
|
AC_MSG_RESULT([$xtlibdir])
|
||||||
@@ -44,31 +44,25 @@ regular_CFLAGS="-Wall -Waggregate-return -Wmissing-declarations \
|
|||||||
|
|
||||||
if test -n "$kbuilddir"; then
|
if test -n "$kbuilddir"; then
|
||||||
AC_MSG_CHECKING([kernel version that we will build against])
|
AC_MSG_CHECKING([kernel version that we will build against])
|
||||||
krel="$(make -sC "$kbuilddir" M=$PWD kernelrelease)";
|
krel="$(make -sC "$kbuilddir" M=$PWD kernelrelease | $AWK -v 'FS=[[^0-9.]]' '{print $1; exit}')"
|
||||||
kmajor="${krel%%[[^0-9]]*}";
|
save_IFS="$IFS"
|
||||||
kmajor="$(($kmajor+0))";
|
IFS='.'
|
||||||
krel="${krel:${#kmajor}}";
|
set x $krel
|
||||||
krel="${krel#.}";
|
IFS="$save_IFS"
|
||||||
kminor="${krel%%[[^0-9]]*}";
|
kmajor="$(($2+0))"
|
||||||
kminor="$(($kminor+0))";
|
kminor="$(($3+0))"
|
||||||
krel="${krel:${#kminor}}";
|
kmicro="$(($4+0))"
|
||||||
krel="${krel#.}";
|
kstable="$(($5+0))"
|
||||||
kmicro="${krel%%[[^0-9]]*}";
|
|
||||||
kmicro="$(($kmicro+0))";
|
|
||||||
krel="${krel:${#kmicro}}";
|
|
||||||
krel="${krel#.}";
|
|
||||||
kstable="${krel%%[[^0-9]]*}";
|
|
||||||
kstable="$(($kstable+0))";
|
|
||||||
if test -z "$kmajor" -o -z "$kminor" -o -z "$kmicro"; then
|
if test -z "$kmajor" -o -z "$kminor" -o -z "$kmicro"; then
|
||||||
echo "WARNING: Version detection did not succeed. Continue at own luck.";
|
echo "WARNING: Version detection did not succeed. Continue at own luck.";
|
||||||
else
|
else
|
||||||
echo "$kmajor.$kminor.$kmicro.$kstable in $kbuilddir";
|
echo "$kmajor.$kminor.$kmicro.$kstable in $kbuilddir";
|
||||||
if test "$kmajor" -gt 3 -o "$kmajor" -eq 3 -a "$kminor" -gt 4; then
|
if test "$kmajor" -gt 5 -o "$kmajor" -eq 5 -a "$kminor" -gt 11; then
|
||||||
echo "WARNING: You are trying a newer kernel. Results may vary. :-)";
|
echo "WARNING: That kernel version is not officially supported yet. Continue at own luck.";
|
||||||
elif test "$kmajor" -eq 3; then
|
elif test "$kmajor" -eq 5 -a "$kminor" -ge 0; then
|
||||||
:;
|
:
|
||||||
elif test "$kmajor" -eq 2 -a "$kminor" -eq 6 -a "$kmicro" -ge 32; then
|
elif test "$kmajor" -eq 4 -a "$kminor" -ge 15; then
|
||||||
:;
|
:
|
||||||
else
|
else
|
||||||
echo "WARNING: That kernel version is not officially supported.";
|
echo "WARNING: That kernel version is not officially supported.";
|
||||||
fi;
|
fi;
|
||||||
|
@@ -1,64 +0,0 @@
|
|||||||
match:
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
int
|
|
||||||
(*match)(
|
|
||||||
const struct sk_buff *skb,
|
|
||||||
const struct net_device *in,
|
|
||||||
const struct net_device *out,
|
|
||||||
const struct xt_match *match,
|
|
||||||
const void *matchinfo,
|
|
||||||
int offset,
|
|
||||||
unsigned int protoff,
|
|
||||||
int *hotdrop,
|
|
||||||
);
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
int
|
|
||||||
(*checkentry)(
|
|
||||||
const char *tablename,
|
|
||||||
const void *ip,
|
|
||||||
const struct xt_match *match,
|
|
||||||
void *matchinfo,
|
|
||||||
unsigned int matchinfosize,
|
|
||||||
unsigned int hook_mask,
|
|
||||||
);
|
|
||||||
|
|
||||||
void
|
|
||||||
(*destroy)(
|
|
||||||
const struct xt_match *match,
|
|
||||||
void *matchinfo,
|
|
||||||
unsigned int matchinfosize,
|
|
||||||
);
|
|
||||||
|
|
||||||
target:
|
|
||||||
|
|
||||||
/* verdict */
|
|
||||||
unsigned int
|
|
||||||
(*target)(
|
|
||||||
struct sk_buff **pskb,
|
|
||||||
const struct net_device *in,
|
|
||||||
const struct net_device *out,
|
|
||||||
unsigned int hooknum,
|
|
||||||
const struct xt_target *target,
|
|
||||||
const void *targinfo,
|
|
||||||
void *userdata,
|
|
||||||
);
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
int
|
|
||||||
(*checkentry)(
|
|
||||||
const char *tablename,
|
|
||||||
const void *entry,
|
|
||||||
const struct xt_target *target,
|
|
||||||
void *targinfo,
|
|
||||||
unsigned int targinfosize,
|
|
||||||
unsigned int hook_mask,
|
|
||||||
);
|
|
||||||
|
|
||||||
void
|
|
||||||
(*destroy)(
|
|
||||||
const struct xt_target *target,
|
|
||||||
void *targinfo,
|
|
||||||
unsigned int targinfosize,
|
|
||||||
);
|
|
@@ -1,59 +0,0 @@
|
|||||||
match:
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
int
|
|
||||||
(*match)(
|
|
||||||
const struct sk_buff *skb,
|
|
||||||
const struct net_device *in,
|
|
||||||
const struct net_device *out,
|
|
||||||
const struct xt_match *match,
|
|
||||||
const void *matchinfo,
|
|
||||||
int offset,
|
|
||||||
unsigned int protoff,
|
|
||||||
int *hotdrop,
|
|
||||||
);
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
int
|
|
||||||
(*checkentry)(
|
|
||||||
const char *tablename,
|
|
||||||
const void *ip,
|
|
||||||
const struct xt_match *match,
|
|
||||||
void *matchinfo,
|
|
||||||
unsigned int hook_mask,
|
|
||||||
);
|
|
||||||
|
|
||||||
void
|
|
||||||
(*destroy)(
|
|
||||||
const struct xt_match *match,
|
|
||||||
void *matchinfo,
|
|
||||||
);
|
|
||||||
|
|
||||||
target:
|
|
||||||
|
|
||||||
/* verdict */
|
|
||||||
unsigned int
|
|
||||||
(*target)(
|
|
||||||
struct sk_buff **pskb,
|
|
||||||
const struct net_device *in,
|
|
||||||
const struct net_device *out,
|
|
||||||
unsigned int hooknum,
|
|
||||||
const struct xt_target *target,
|
|
||||||
const void *targinfo,
|
|
||||||
);
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
int
|
|
||||||
(*checkentry)(
|
|
||||||
const char *tablename,
|
|
||||||
const void *entry,
|
|
||||||
const struct xt_target *target,
|
|
||||||
void *targinfo,
|
|
||||||
unsigned int hook_mask,
|
|
||||||
);
|
|
||||||
|
|
||||||
void
|
|
||||||
(*destroy)(
|
|
||||||
const struct xt_target *target,
|
|
||||||
void *targinfo,
|
|
||||||
);
|
|
@@ -1,59 +0,0 @@
|
|||||||
match:
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
bool
|
|
||||||
(*match)(
|
|
||||||
const struct sk_buff *skb,
|
|
||||||
const struct net_device *in,
|
|
||||||
const struct net_device *out,
|
|
||||||
const struct xt_match *match,
|
|
||||||
const void *matchinfo,
|
|
||||||
int offset,
|
|
||||||
unsigned int protoff,
|
|
||||||
bool *hotdrop,
|
|
||||||
);
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
bool
|
|
||||||
(*checkentry)(
|
|
||||||
const char *tablename,
|
|
||||||
const void *ip,
|
|
||||||
const struct xt_match *match,
|
|
||||||
void *matchinfo,
|
|
||||||
unsigned int hook_mask,
|
|
||||||
);
|
|
||||||
|
|
||||||
void
|
|
||||||
(*destroy)(
|
|
||||||
const struct xt_match *match,
|
|
||||||
void *matchinfo,
|
|
||||||
);
|
|
||||||
|
|
||||||
target:
|
|
||||||
|
|
||||||
/* verdict */
|
|
||||||
unsigned int
|
|
||||||
(*target)(
|
|
||||||
struct sk_buff **pskb,
|
|
||||||
const struct net_device *in,
|
|
||||||
const struct net_device *out,
|
|
||||||
unsigned int hooknum,
|
|
||||||
const struct xt_target *target,
|
|
||||||
const void *targinfo,
|
|
||||||
);
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
bool
|
|
||||||
(*checkentry)(
|
|
||||||
const char *tablename,
|
|
||||||
const void *entry,
|
|
||||||
const struct xt_target *target,
|
|
||||||
void *targinfo,
|
|
||||||
unsigned int hook_mask,
|
|
||||||
);
|
|
||||||
|
|
||||||
void
|
|
||||||
(*destroy)(
|
|
||||||
const struct xt_target *target,
|
|
||||||
void *targinfo,
|
|
||||||
);
|
|
@@ -1,59 +0,0 @@
|
|||||||
match:
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
bool
|
|
||||||
(*match)(
|
|
||||||
const struct sk_buff *skb,
|
|
||||||
const struct net_device *in,
|
|
||||||
const struct net_device *out,
|
|
||||||
const struct xt_match *match,
|
|
||||||
const void *matchinfo,
|
|
||||||
int offset,
|
|
||||||
unsigned int protoff,
|
|
||||||
bool *hotdrop,
|
|
||||||
);
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
bool
|
|
||||||
(*checkentry)(
|
|
||||||
const char *tablename,
|
|
||||||
const void *ip,
|
|
||||||
const struct xt_match *match,
|
|
||||||
void *matchinfo,
|
|
||||||
unsigned int hook_mask,
|
|
||||||
);
|
|
||||||
|
|
||||||
void
|
|
||||||
(*destroy)(
|
|
||||||
const struct xt_match *match,
|
|
||||||
void *matchinfo,
|
|
||||||
);
|
|
||||||
|
|
||||||
target:
|
|
||||||
|
|
||||||
/* verdict */
|
|
||||||
unsigned int
|
|
||||||
(*target)(
|
|
||||||
struct sk_buff *skb,
|
|
||||||
const struct net_device *in,
|
|
||||||
const struct net_device *out,
|
|
||||||
unsigned int hooknum,
|
|
||||||
const struct xt_target *target,
|
|
||||||
const void *targinfo,
|
|
||||||
);
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
bool
|
|
||||||
(*checkentry)(
|
|
||||||
const char *tablename,
|
|
||||||
const void *entry,
|
|
||||||
const struct xt_target *target,
|
|
||||||
void *targinfo,
|
|
||||||
unsigned int hook_mask,
|
|
||||||
);
|
|
||||||
|
|
||||||
void
|
|
||||||
(*destroy)(
|
|
||||||
const struct xt_target *target,
|
|
||||||
void *targinfo,
|
|
||||||
);
|
|
@@ -1,39 +0,0 @@
|
|||||||
match:
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
bool
|
|
||||||
(*match)(
|
|
||||||
const struct sk_buff *skb,
|
|
||||||
const struct xt_match_param *,
|
|
||||||
);
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
bool
|
|
||||||
(*checkentry)(
|
|
||||||
const struct xt_mtchk_param *,
|
|
||||||
);
|
|
||||||
|
|
||||||
void
|
|
||||||
(*destroy)(
|
|
||||||
const struct xt_mtdtor_param *,
|
|
||||||
);
|
|
||||||
|
|
||||||
target:
|
|
||||||
|
|
||||||
/* verdict */
|
|
||||||
unsigned int
|
|
||||||
(*target)(
|
|
||||||
struct sk_buff *skb,
|
|
||||||
const struct xt_target_param *,
|
|
||||||
);
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
bool
|
|
||||||
(*checkentry)(
|
|
||||||
const struct xt_tgchk_param *,
|
|
||||||
);
|
|
||||||
|
|
||||||
void
|
|
||||||
(*destroy)(
|
|
||||||
const struct xt_tgdtor_param *,
|
|
||||||
);
|
|
@@ -1,38 +0,0 @@
|
|||||||
match:
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
bool
|
|
||||||
(*match)(
|
|
||||||
const struct sk_buff *skb,
|
|
||||||
const struct xt_match_param *,
|
|
||||||
);
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
bool
|
|
||||||
(*checkentry)(
|
|
||||||
const struct xt_mtchk_param *,
|
|
||||||
);
|
|
||||||
|
|
||||||
void
|
|
||||||
(*destroy)(
|
|
||||||
const struct xt_mtdtor_param *,
|
|
||||||
);
|
|
||||||
|
|
||||||
target:
|
|
||||||
|
|
||||||
unsigned int
|
|
||||||
(*target)(
|
|
||||||
struct sk_buff *skb,
|
|
||||||
const struct xt_target_param *,
|
|
||||||
);
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
bool
|
|
||||||
(*checkentry)(
|
|
||||||
const struct xt_tgchk_param *,
|
|
||||||
);
|
|
||||||
|
|
||||||
void
|
|
||||||
(*destroy)(
|
|
||||||
const struct xt_tgdtor_param *,
|
|
||||||
);
|
|
@@ -1,39 +0,0 @@
|
|||||||
match:
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
bool
|
|
||||||
(*match)(
|
|
||||||
const struct sk_buff *skb,
|
|
||||||
const struct xt_match_param *,
|
|
||||||
);
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
bool
|
|
||||||
(*checkentry)(
|
|
||||||
const struct xt_mtchk_param *,
|
|
||||||
);
|
|
||||||
|
|
||||||
void
|
|
||||||
(*destroy)(
|
|
||||||
const struct xt_mtdtor_param *,
|
|
||||||
);
|
|
||||||
|
|
||||||
target:
|
|
||||||
|
|
||||||
/* verdict */
|
|
||||||
unsigned int
|
|
||||||
(*target)(
|
|
||||||
struct sk_buff *skb,
|
|
||||||
const struct xt_target_param *,
|
|
||||||
);
|
|
||||||
|
|
||||||
/* true/false */
|
|
||||||
bool
|
|
||||||
(*checkentry)(
|
|
||||||
const struct xt_tgchk_param *,
|
|
||||||
);
|
|
||||||
|
|
||||||
void
|
|
||||||
(*destroy)(
|
|
||||||
const struct xt_tgdtor_param *,
|
|
||||||
);
|
|
@@ -1,482 +1,242 @@
|
|||||||
|
v3.18 (2021-03-11)
|
||||||
HEAD
|
|
||||||
====
|
|
||||||
|
|
||||||
|
|
||||||
v1.44 (2012-07-15)
|
|
||||||
==================
|
==================
|
||||||
Fixes:
|
- xt_pknock: fix a build failure on ARM 32-bit
|
||||||
- SYSRQ: fix double target initialization at module load
|
|
||||||
- build: do not attempt to build IPv6 parts if CONFIG_IP6_NF_IPTABLES=n
|
|
||||||
Enhancements:
|
|
||||||
- TARPIT gained IPv6 support
|
|
||||||
|
|
||||||
|
|
||||||
v1.43 (2012-06-30)
|
v3.17 (2021-02-28)
|
||||||
==================
|
==================
|
||||||
Fixes:
|
- xt_pknock: cure a NULL deref
|
||||||
- xt_psd: avoid crash due to curr->next corruption
|
|
||||||
Changes:
|
|
||||||
- xt_psd: reject invalid match options
|
|
||||||
Enhancements:
|
|
||||||
- Support for Linux 3.5
|
|
||||||
- DNETMAP: new type: static binding
|
|
||||||
- DNETMAP: new persistent flag option for prefix
|
|
||||||
- DNETMAP: add write support to procfs interface
|
|
||||||
|
|
||||||
|
|
||||||
v1.42 (2012-04-05)
|
v3.16 (2021-02-24)
|
||||||
==================
|
==================
|
||||||
Fixes:
|
- xt_pknock: build fix for ILP32 targets
|
||||||
- compat_xtables: fixed mistranslation of checkentry return values
|
|
||||||
(affected kernels < 2.6.23)
|
|
||||||
- xt_SYSRQ: fix compile error when crypto is turned off
|
|
||||||
Changes:
|
|
||||||
- ipset6-genl has been dropped from the tree;
|
|
||||||
the libmnl build-time dependency is thus no longer needed
|
|
||||||
Enhancements:
|
|
||||||
- Support for Linux 3.3, 3.4
|
|
||||||
|
|
||||||
|
|
||||||
v1.41 (2012-01-04)
|
v3.15 (2021-02-05)
|
||||||
==================
|
==================
|
||||||
Changes:
|
- xt_ECHO: support new function signature of security_skb_classify_flow
|
||||||
- Deactivate build of ipset-genl by default.
|
- xt_lscan: add --mirai option
|
||||||
I think the original ipset package can now take over, given there are
|
- Support for Linux 5.11
|
||||||
a handful of kernels (2.6.39 onwards) that do not need patching.
|
|
||||||
Enhancements:
|
|
||||||
- Support for Linux 3.2
|
|
||||||
|
|
||||||
|
|
||||||
v1.40 (2011-11-30)
|
v3.14 (2020-11-24)
|
||||||
==================
|
==================
|
||||||
Fixes:
|
- DELUDE, ECHO, TARPIT: use actual tunnel socket (ip_route_me_harder).
|
||||||
- build: the code actually requires at least iptables 1.4.5 (would yield a
|
- geoip: scripts for use with MaxMind DB have been brought back,
|
||||||
compile error otherwise), make sure configure checks for it; update INSTALL
|
partly under new names.
|
||||||
- xt_ECHO: fix kernel warning about RTAX_HOPLIMIT being used
|
- Gave xt_geoip_fetch a more fitting name, xt_geoip_query.
|
||||||
- xt_ipv4options: fix an infinite loop
|
|
||||||
Changes:
|
|
||||||
- xt_ECHO: now calculates UDP checksum
|
|
||||||
- Linux kernel versions below 2.6.32 are no longer officially
|
|
||||||
supported, and will not be part of compilation testing.
|
|
||||||
- update to ipset 6.10
|
|
||||||
Enhancements:
|
|
||||||
- xt_ECHO: IPv6 support
|
|
||||||
|
|
||||||
|
|
||||||
v1.39 (2011-09-21)
|
v3.13 (2020-11-20)
|
||||||
==================
|
==================
|
||||||
Fixes:
|
- Support for Linux 4.19.158 and 5.4.78 (ip_route_me_harder)
|
||||||
- libxt_ACCOUNT: fix compilation after missing libxtables_CFLAGS
|
|
||||||
- build: fix compilation after missing libxtables_CFLAGS in submodules
|
|
||||||
- build: add missing linux/version.h includes where needed
|
|
||||||
Changes:
|
|
||||||
- Remove unsupported ipset 4.x from the Xtables-addons distribution
|
|
||||||
- ipset: move ipset_errcode from src to library to avoid undefined reference
|
|
||||||
- update to ipset 6.9.1
|
|
||||||
|
|
||||||
|
|
||||||
v1.38 (2011-08-20)
|
v3.12 (2020-11-19)
|
||||||
==================
|
==================
|
||||||
- xt_CHECKSUM: abort build when the feature is already provided by mainline
|
- Support for Linux 5.10 and 5.9.9 API
|
||||||
- xt_SYSRQ: fix UDPLITE header lookup in IPv6
|
(changes to ip_route_me_harder there)
|
||||||
- xt_TARPIT: fix kernel warning about RTAX_HOPLIMIT being used
|
|
||||||
- xt_TEE: abort build when the feature is already provided by mainline
|
|
||||||
- xt_ipp2p: support UDPLITE
|
|
||||||
- xt_pknock: support UDPLITE
|
|
||||||
- xt_psd: restore functionality with UDP
|
|
||||||
- xt_psd: support UDPLITE
|
|
||||||
- update to ipset 6.8
|
|
||||||
- support for Linux 3.1
|
|
||||||
|
|
||||||
|
|
||||||
v1.37 (2011-06-25)
|
v3.11 (2020-09-06)
|
||||||
==================
|
==================
|
||||||
Fixes:
|
- Support for up to Linux 5.9
|
||||||
- xt_SYSRQ: make IPv6 trigger work again
|
|
||||||
- xt_SYSRQ: improve security: include host address in digest
|
|
||||||
- xt_TARPIT: fix a kernel oops in --reset mode
|
|
||||||
|
|
||||||
|
|
||||||
v1.36 (2011-06-03)
|
v3.10 (2020-07-28)
|
||||||
==================
|
==================
|
||||||
Changes:
|
- Support for up to Linux 5.8
|
||||||
- xt_geoip: avoid recursive function calls
|
|
||||||
- xt_TARPIT: unlock for use in all tables
|
|
||||||
- xt_TARPIT: honeypot and reset modes
|
|
||||||
- update to ipset 6.7
|
|
||||||
- support for Linux 3.0
|
|
||||||
|
|
||||||
|
|
||||||
v1.35 (2011-04-11)
|
v3.9 (2020-02-25)
|
||||||
==================
|
|
||||||
Enhancements:
|
|
||||||
- update to ipset 6.3
|
|
||||||
* allow "new" as a commad alias to "create"
|
|
||||||
* resolving IP addresses did not work at listing/saving sets, fixed
|
|
||||||
* check ICMP and ICMPv6 with the set match and target in the testsuite
|
|
||||||
* avoid possible syntax clashing at saving hostnames
|
|
||||||
* fix linking with CONFIG_IPV6=n
|
|
||||||
* sctp, udplite support for the hash:*port* types
|
|
||||||
- ipset-genl: handle EAGAIN return value emitted from autoloader
|
|
||||||
- ipset-genl: resolve nfgenmsg remains and fix spurious protocol abort
|
|
||||||
|
|
||||||
|
|
||||||
v1.34 (2011-04-07)
|
|
||||||
==================
|
|
||||||
Fixes:
|
|
||||||
- xt_pknock: avoid crash when hash TFM could not be allocated
|
|
||||||
- xt_pknock: avoid inversion of rule lookup that led to warnings
|
|
||||||
- xt_DNETMAP: add missing module alias
|
|
||||||
- xt_DNETMAP: support for kernels below 2.6.34
|
|
||||||
Changes:
|
|
||||||
- Linux kernel versions below 2.6.29 are no longer officially
|
|
||||||
supported, and will not be part of compilation testing.
|
|
||||||
|
|
||||||
|
|
||||||
v1.33 (2011-02-02)
|
|
||||||
==================
|
|
||||||
Fixes:
|
|
||||||
- build: restore functionality of `configure --without-kbuild`
|
|
||||||
- build: fix objdir builds for ipset-5 (xt-a specific)
|
|
||||||
- build: fix missing inclusion of dependency rules
|
|
||||||
- xt_LOGMARK: fix detection of untracked connection for Linux >= 2.6.36
|
|
||||||
Enhancements:
|
|
||||||
- IPv6 support for xt_geoip
|
|
||||||
- Update to ipset 5.3
|
|
||||||
* make IPv4 and IPv6 address handling similar
|
|
||||||
* show correct line numbers in restore output for parser errors
|
|
||||||
- Update to ipset 5.4
|
|
||||||
* fixed ICMP and ICMPv6 handling
|
|
||||||
* fixed trailing whitespaces and pr_* messages
|
|
||||||
* fixed module loading at create/header commands
|
|
||||||
- build: support for Linux up to 2.6.38
|
|
||||||
- build: preliminary support for iptables 1.4.11
|
|
||||||
|
|
||||||
|
|
||||||
v1.32 (2011-01-04)
|
|
||||||
==================
|
|
||||||
Fixes:
|
|
||||||
- Update to ipset 4.5
|
|
||||||
* the iptreemap type used wrong gfp flags when deleting entries
|
|
||||||
- Include ipset 5.2 with genetlink patch (beta)
|
|
||||||
* no kernel patch needed, but requires Linux >= 2.6.35
|
|
||||||
and thus needs to be manually enabled in mconfig
|
|
||||||
|
|
||||||
|
|
||||||
v1.31 (2010-11-05)
|
|
||||||
==================
|
|
||||||
Fixes:
|
|
||||||
- build: improve detection of kernel version and error handling
|
|
||||||
Changes:
|
|
||||||
- build: automatically derive Xtables module directory, thus
|
|
||||||
--with-xtlibdir is no longer needed for ./configure in most cases
|
|
||||||
(If I still see a distro using it, I will scold you for not
|
|
||||||
reading this changelog.)
|
|
||||||
Enhancements:
|
|
||||||
- LOGMARK: print remaining lifetime of cts
|
|
||||||
- xt_iface: allow matching against incoming/outgoing interface
|
|
||||||
- libxt_gradm: match packets based on status of grsecurity RBAC
|
|
||||||
(userspace part only - xt_gradm is in the grsec patch)
|
|
||||||
|
|
||||||
|
|
||||||
v1.30 (2010-010-02)
|
|
||||||
===================
|
|
||||||
Fixes:
|
|
||||||
- update to ipset 4.4
|
|
||||||
* ipport{,ip,net}hash did not work with mixed "src" and "dst"
|
|
||||||
destination parameters
|
|
||||||
Changes:
|
|
||||||
- deactivate building xt_TEE and xt_CHECKSUM by default, as these have been
|
|
||||||
merged upstream in Linux 2.6.35 and 2.6.36, respectively.
|
|
||||||
Distros still wishing to build this need to enable it in their build
|
|
||||||
script, e.g. perl -i -pe 's{^build_TEE=.*}{build_TEE=m}' mconfig;
|
|
||||||
|
|
||||||
|
|
||||||
v1.29 (2010-09-29)
|
|
||||||
==================
|
|
||||||
- compat_xtables: return bool for match_check and target_check in 2.6.23..34
|
|
||||||
- ipset: enable building of ip_set_ipport{ip,net}hash.ko
|
|
||||||
- support for Linux 2.6.36
|
|
||||||
- SYSRQ: resolve compile error with Linux 2.6.36
|
|
||||||
- TEE: resolve compile error with Linux 2.6.36
|
|
||||||
- add workaround for broken linux-glibc-devel 2.6.34 userspace headers
|
|
||||||
("implicit declaration of function 'ALIGN'")
|
|
||||||
|
|
||||||
|
|
||||||
v1.28 (2010-07-24)
|
|
||||||
==================
|
|
||||||
- RAWNAT: IPv6 variants erroneously rejected masks /33-/128
|
|
||||||
- new target xt_CHECKSUM
|
|
||||||
- xt_length2: add support for IPv6 jumbograms
|
|
||||||
- xt_geoip: fix possible out-of-bounds access
|
|
||||||
- import xt_geoip database scripts
|
|
||||||
|
|
||||||
|
|
||||||
v1.27 (2010-05-16)
|
|
||||||
==================
|
|
||||||
- further updates for the upcoming 2.6.35 changes
|
|
||||||
|
|
||||||
|
|
||||||
v1.26 (2010-04-30)
|
|
||||||
==================
|
|
||||||
- compat_xtables: fix 2.6.34 compile error due to a typo
|
|
||||||
|
|
||||||
|
|
||||||
v1.25 (2010-04-26)
|
|
||||||
==================
|
|
||||||
- TEE: do rechecksumming in PREROUTING too
|
|
||||||
- TEE: decrease TTL on cloned packet
|
|
||||||
- TEE: set dont-fragment on cloned packets
|
|
||||||
- TEE: free skb when route lookup failed
|
|
||||||
- TEE: do not limit use to mangle table
|
|
||||||
- TEE: do not retain iif and mark on cloned packet
|
|
||||||
- TEE: new loop detection logic
|
|
||||||
- TEE: use less expensive pskb_copy
|
|
||||||
- condition: remove unnecessary RCU protection
|
|
||||||
|
|
||||||
|
|
||||||
v1.24 (2010-03-17)
|
|
||||||
==================
|
|
||||||
- build: fix build of userspace modules against old (pre-2.6.25)
|
|
||||||
headers from linux-glibc-devel (/usr/include/linux)
|
|
||||||
- ipp2p: updated bittorent command recognition
|
|
||||||
- SYSRQ: let module load when crypto is unavailable
|
|
||||||
- SYSRQ: allow processing of UDP-Lite
|
|
||||||
|
|
||||||
|
|
||||||
v1.23 (2010-02-24)
|
|
||||||
==================
|
|
||||||
- build: support for Linux 2.6.34
|
|
||||||
- build: remove unused --with-ksource option
|
|
||||||
- build: remove unneeded --with-xtables option
|
|
||||||
- build: fix compilations in RAWNAT, SYSRQ and length2 when CONFIG_IPV6=n
|
|
||||||
- ipset: update to 4.2
|
|
||||||
- ECHO: fix compilation w.r.t. skb_dst
|
|
||||||
|
|
||||||
|
|
||||||
v1.22 (2010-01-22)
|
|
||||||
==================
|
|
||||||
- compat_xtables: support for 2.6.33 skb_iif changes
|
|
||||||
- geoip: for FHS compliance use /usr/share/xt_geoip instead of /var/geoip
|
|
||||||
- ipset: enable build of ip_set_setlist.ko
|
|
||||||
- quota2: add the --no-change mode
|
|
||||||
|
|
||||||
|
|
||||||
v1.21 (2009-12-09)
|
|
||||||
==================
|
|
||||||
- ACCOUNT: avoid collision with arp_tables setsockopt numbers
|
|
||||||
- doc: fix option mismatch --gw/--gateway in libxt_TEE.man
|
|
||||||
|
|
||||||
|
|
||||||
v1.20 (2009-11-19)
|
|
||||||
==================
|
|
||||||
- ipp2p: add more boundary checks
|
|
||||||
- ipp2p: fix Gnutelle line ending detection
|
|
||||||
- LOGMARK: remove unknown options from manpage
|
|
||||||
- ACCOUNT: endianess-correctness
|
|
||||||
- ipset: install manpage
|
|
||||||
- ipset: fast forward to v4.1
|
|
||||||
|
|
||||||
|
|
||||||
v1.19 (2009-10-12)
|
|
||||||
==================
|
|
||||||
- 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
|
|
||||||
|
|
||||||
|
|
||||||
v1.18 (2009-09-09)
|
|
||||||
==================
|
|
||||||
- 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
|
|
||||||
|
|
||||||
|
|
||||||
v1.17 (2009-06-16)
|
|
||||||
==================
|
|
||||||
- IPMARK: print missing --shift parameter
|
|
||||||
- build: use readlink -f in extensions/ipset/
|
|
||||||
- build: support for Linux 2.6.30
|
|
||||||
|
|
||||||
|
|
||||||
v1.16 (2009-05-27)
|
|
||||||
==================
|
|
||||||
- RAWNAT: make iptable_rawpost compile with 2.6.30-rc5
|
|
||||||
- ipset: fast forward to 3.0
|
|
||||||
|
|
||||||
|
|
||||||
v1.15 (2009-04-30)
|
|
||||||
==================
|
|
||||||
- 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
|
|
||||||
|
|
||||||
|
|
||||||
v1.14 (2009-03-31)
|
|
||||||
==================
|
|
||||||
- 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
|
|
||||||
|
|
||||||
|
|
||||||
v1.13 (2009-03-23)
|
|
||||||
==================
|
|
||||||
- added a reworked ipv4options match
|
|
||||||
- upgrade to iptables 1.4.3 API
|
|
||||||
|
|
||||||
|
|
||||||
v1.12 (2009-03-07)
|
|
||||||
==================
|
|
||||||
- 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
|
|
||||||
|
|
||||||
|
|
||||||
v1.10 (2009-02-18)
|
|
||||||
==================
|
|
||||||
- compat: compile fixes for 2.6.29
|
|
||||||
- ipset: upgrade to ipset 2.4.9
|
|
||||||
|
|
||||||
|
|
||||||
v1.9 (2009-01-30)
|
|
||||||
=================
|
=================
|
||||||
- add the xt_length2 extension
|
- Support for Linux 5.6 procfs changes
|
||||||
- xt_TEE: remove intrapositional '!' support
|
|
||||||
- ipset: upgrade to ipset 2.4.7
|
|
||||||
|
|
||||||
|
|
||||||
v1.8 (2009-01-10)
|
v3.8 (2020-02-03)
|
||||||
=================
|
=================
|
||||||
- xt_TEE: IPv6 support
|
- Support for Linux 5.5
|
||||||
- xt_TEE: do not include TOS value in routing decision
|
- xt_geoip_build now expects the DBIP format as input,
|
||||||
- xt_TEE: fix switch-case inversion for name/IP display
|
Maxmind is thrown out.
|
||||||
- xt_ipp2p: update manpages and help text
|
|
||||||
- xt_ipp2p: remove log flooding
|
|
||||||
- xt_portscan: update manpage about --grscan option caveats
|
|
||||||
|
|
||||||
|
|
||||||
v1.7 (2008-12-25)
|
v3.7 (2019-12-01)
|
||||||
=================
|
=================
|
||||||
- xt_ECHO: compile fix
|
Fixes:
|
||||||
- avoid the use of "_init" which led to compile errors on some installations
|
- xt_geoip: fix in6_addr little-endian byte swapping
|
||||||
- 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
|
|
||||||
|
|
||||||
|
|
||||||
v1.6 (2008-11-18)
|
v3.6 (2019-11-20)
|
||||||
=================
|
=================
|
||||||
- build: support for Linux 2.6.17
|
Enhancements:
|
||||||
- build: compile fixes for 2.6.18 and 2.6.19
|
- support for up to Linux 5.4
|
||||||
- xt_ECHO: resolve compile errors in xt_ECHO
|
|
||||||
- xt_ipp2p: parenthesize unaligned-access macros
|
|
||||||
|
|
||||||
|
|
||||||
v1.5.7 (2008-09-01)
|
v3.5 (2019-09-10)
|
||||||
===================
|
=================
|
||||||
- API layer: fix use of uninitialized 'hotdrop' variable
|
Enhancements:
|
||||||
- API layer: move to pskb-based signatures
|
- xt_DELUDE, xt_TARPIT: added additional code needed to work with
|
||||||
- xt_SYSRQ: compile fixes for Linux <= 2.6.19
|
bridges from Linux 5.0 onwards.
|
||||||
- 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
|
|
||||||
|
|
||||||
|
|
||||||
v1.5.5 (2008-08-03)
|
v3.4 (2019-09-06)
|
||||||
===================
|
=================
|
||||||
- manpage updates for xt_CHAOS, xt_IPMARK; README updates
|
Enhancements:
|
||||||
- build: properly recognize external Kbuild/Mbuild files
|
- support for up to Linux 5.3
|
||||||
- build: remove dependency on CONFIG_NETWORK_SECMARK
|
- xt_PROTO module
|
||||||
- add the xt_SYSRQ target
|
|
||||||
- add the xt_quota2 extension
|
|
||||||
- import ipset extension group
|
|
||||||
|
|
||||||
|
|
||||||
v1.5.4.1 (2008-04-26)
|
v3.3 (2019-03-07)
|
||||||
=====================
|
=================
|
||||||
- build: fix compile error for 2.6.18-stable
|
Enhancements:
|
||||||
|
- support for Linux 5.0
|
||||||
|
|
||||||
|
|
||||||
v1.5.4 (2008-04-09)
|
v3.2 (2018-09-07)
|
||||||
===================
|
=================
|
||||||
- build: support building multiple files with one config option
|
Changes:
|
||||||
- API layer: add check for pskb relocation
|
- rework xt_geoip_build to scan the immediate directory for .csv,
|
||||||
- doc: generate manpages
|
not to scan for GeoLite2-Country-CSV_\d+.
|
||||||
- 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
|
|
||||||
|
|
||||||
|
|
||||||
v1.5.3 (2008-03-22)
|
v3.1 (2018-08-14)
|
||||||
===================
|
=================
|
||||||
- support for Linux 2.6.18
|
Enhancements:
|
||||||
- add xt_ECHO sample target
|
- support for Linux 4.17, 4.18
|
||||||
- add reworked xt_geoip match
|
|
||||||
|
|
||||||
|
|
||||||
v1.5.2 (2008-03-04)
|
v3.0 (2018-02-12)
|
||||||
===================
|
=================
|
||||||
- build: support for GNU make < 3.81 which does not have $(realpath)
|
Enhancements:
|
||||||
|
- support for Linux 4.15, 4.16
|
||||||
|
Changes:
|
||||||
|
- remove support for Linux 3.7--4.14
|
||||||
|
|
||||||
|
|
||||||
v1.5.1 (2008-02-21)
|
v2.14 (2017-11-22)
|
||||||
===================
|
==================
|
||||||
- build: allow user to select what extensions to compile and install
|
Enhancements:
|
||||||
- build: allow external proejcts to be downloaded into the tree
|
- support for Linux up to 4.14
|
||||||
- xt_LOGMARK: dump classify mark, ctstate and ctstatus
|
Fixes:
|
||||||
- add xt_CHAOS, xt_DELUDE and xt_portscan from Chaostables
|
- xt_DNETMAP: fix some reports from PVSStudio (a static checker)
|
||||||
|
|
||||||
|
|
||||||
v1.5.0 (2008-02-11)
|
v2.13 (2017-06-29)
|
||||||
===================
|
==================
|
||||||
Initial release with:
|
Enhancements:
|
||||||
- extensions: xt_LOGMARK, xt_TARPIT, xt_TEE
|
- support for Linux up to 4.12
|
||||||
- support for Linux >= 2.6.19
|
- xt_condition: namespace support
|
||||||
|
Fixes:
|
||||||
|
- xt_geoip: check for allocation overflow
|
||||||
|
- xt_DNETMAP: fix a buffer overflow
|
||||||
|
|
||||||
|
|
||||||
|
v2.12 (2017-01-11)
|
||||||
|
==================
|
||||||
|
Enhancements:
|
||||||
|
- support for Linux up to 4.10
|
||||||
|
|
||||||
|
|
||||||
|
v2.11 (2016-05-20)
|
||||||
|
==================
|
||||||
|
Enhancements:
|
||||||
|
- support for Linux 4.5, 4.6
|
||||||
|
- xt_ECHO: tentatively support responding to fragments
|
||||||
|
|
||||||
|
|
||||||
|
v2.10 (2015-11-20)
|
||||||
|
==================
|
||||||
|
Enhancements:
|
||||||
|
- Support for Linux 4.4
|
||||||
|
Fixes:
|
||||||
|
- xt_ACCOUNT: call free_page with the right amount of pages
|
||||||
|
|
||||||
|
|
||||||
|
v2.9 (2015-10-12)
|
||||||
|
=================
|
||||||
|
Enhancements:
|
||||||
|
- Support for Linux 4.3
|
||||||
|
|
||||||
|
|
||||||
|
v2.8 (2015-08-19)
|
||||||
|
=================
|
||||||
|
Enhancements:
|
||||||
|
- Support for Linux 4.2
|
||||||
|
- Enable xt_ECHO for Linux 4.0+
|
||||||
|
|
||||||
|
|
||||||
|
v2.7 (2015-07-06)
|
||||||
|
=================
|
||||||
|
Enhancements:
|
||||||
|
- Support for Linux up to 4.1
|
||||||
|
|
||||||
|
|
||||||
|
v2.6 (2014-09-29)
|
||||||
|
=================
|
||||||
|
Enhancements:
|
||||||
|
- Support for Linux up to 3.17
|
||||||
|
Fixes:
|
||||||
|
- xt_pknock: UDP SPA mode erroneously returned an error saying
|
||||||
|
crypto was unavailable
|
||||||
|
|
||||||
|
|
||||||
|
v2.5 (2014-04-18)
|
||||||
|
=================
|
||||||
|
Enhancements:
|
||||||
|
- Support for Linux up to 3.15
|
||||||
|
- xt_quota2: introduce support for network namespaces
|
||||||
|
|
||||||
|
|
||||||
|
v2.4 (2014-01-09)
|
||||||
|
=================
|
||||||
|
Enhancements:
|
||||||
|
- Support for Linux up to 3.13
|
||||||
|
Changes:
|
||||||
|
- remove unmaintained RAWSNAT/RAWDNAT code
|
||||||
|
- remove unused parts of compat_xtables that served Linux <3.7
|
||||||
|
Fixes:
|
||||||
|
- xt_quota2: --no-change should not alter quota to zero ever
|
||||||
|
- xt_quota2: --packet should not be set to zero based on skb->len
|
||||||
|
|
||||||
|
|
||||||
|
v2.3 (2013-06-18)
|
||||||
|
=================
|
||||||
|
Enhancements:
|
||||||
|
- Support for Linux 3.10
|
||||||
|
Fixes:
|
||||||
|
- xt_DNETMAP, xt_condition, xt_quota2: resolve compile error when
|
||||||
|
CONFIG_UIDGID_STRICT_TYPE_CHECKS=y
|
||||||
|
- xt_RAWNAT: ensure correct operation in the presence of IPv4 options
|
||||||
|
- xt_geoip: do not throw a warnings when country database is size 0
|
||||||
|
- xt_quota2: print "!" at the correct position during iptables-save
|
||||||
|
Changes:
|
||||||
|
- Make print (iptables -L) output the same as save (-S)
|
||||||
|
|
||||||
|
|
||||||
|
v2.2 (2013-03-31)
|
||||||
|
=================
|
||||||
|
Enhancements:
|
||||||
|
- Support for Linux 3.9
|
||||||
|
- iptaccount: fix entire program being erroneously optimized away on PPC
|
||||||
|
|
||||||
|
|
||||||
|
v2.1 (2012-11-27)
|
||||||
|
=================
|
||||||
|
Fixes:
|
||||||
|
- DNETMAP: fix compile error with Linux 3.7
|
||||||
|
Enhancements:
|
||||||
|
- Support for Linux 3.8
|
||||||
|
|
||||||
|
|
||||||
|
v2.0 (2012-11-12)
|
||||||
|
=================
|
||||||
|
Changes:
|
||||||
|
- remove support for Linux 2.6.17–3.6
|
||||||
|
- remove xt_TEE (this is available upstream since 2.6.35)
|
||||||
|
- remove xt_CHECKSUM (this is available upstream since 2.6.36)
|
||||||
|
Enhancements:
|
||||||
|
- Support for Linux 3.7
|
||||||
|
|
||||||
|
If you want to use Xtables-addons with kernels older than 4.15,
|
||||||
|
use the addons 2.x series.
|
||||||
|
@@ -9,5 +9,6 @@ sbin_PROGRAMS = iptaccount
|
|||||||
iptaccount_LDADD = libxt_ACCOUNT_cl.la
|
iptaccount_LDADD = libxt_ACCOUNT_cl.la
|
||||||
|
|
||||||
lib_LTLIBRARIES = libxt_ACCOUNT_cl.la
|
lib_LTLIBRARIES = libxt_ACCOUNT_cl.la
|
||||||
|
libxt_ACCOUNT_cl_la_LDFLAGS = -version-info 1:0:0
|
||||||
|
|
||||||
man_MANS = iptaccount.8
|
man_MANS = iptaccount.8
|
||||||
|
@@ -64,7 +64,7 @@ int main(int argc, char *argv[])
|
|||||||
struct ipt_ACCOUNT_context ctx;
|
struct ipt_ACCOUNT_context ctx;
|
||||||
struct ipt_acc_handle_ip *entry;
|
struct ipt_acc_handle_ip *entry;
|
||||||
int i;
|
int i;
|
||||||
char optchar;
|
int optchar;
|
||||||
bool doHandleUsage = false, doHandleFree = false, doTableNames = false;
|
bool doHandleUsage = false, doHandleFree = false, doTableNames = false;
|
||||||
bool doFlush = false, doContinue = false, doCSV = false;
|
bool doFlush = false, doContinue = false, doCSV = false;
|
||||||
|
|
||||||
@@ -200,13 +200,19 @@ int main(int argc, char *argv[])
|
|||||||
while ((entry = ipt_ACCOUNT_get_next_entry(&ctx)) != NULL)
|
while ((entry = ipt_ACCOUNT_get_next_entry(&ctx)) != NULL)
|
||||||
{
|
{
|
||||||
if (doCSV)
|
if (doCSV)
|
||||||
printf("%s;%u;%u;%u;%u\n",
|
printf("%s;%llu;%llu;%llu;%llu\n",
|
||||||
addr_to_dotted(entry->ip), entry->src_packets, entry->src_bytes,
|
addr_to_dotted(entry->ip),
|
||||||
entry->dst_packets, entry->dst_bytes);
|
(unsigned long long)entry->src_packets,
|
||||||
|
(unsigned long long)entry->src_bytes,
|
||||||
|
(unsigned long long)entry->dst_packets,
|
||||||
|
(unsigned long long)entry->dst_bytes);
|
||||||
else
|
else
|
||||||
printf("IP: %s SRC packets: %u bytes: %u DST packets: %u bytes: %u\n",
|
printf("IP: %s SRC packets: %llu bytes: %llu DST packets: %llu bytes: %llu\n",
|
||||||
addr_to_dotted(entry->ip), entry->src_packets, entry->src_bytes,
|
addr_to_dotted(entry->ip),
|
||||||
entry->dst_packets, entry->dst_bytes);
|
(unsigned long long)entry->src_packets,
|
||||||
|
(unsigned long long)entry->src_bytes,
|
||||||
|
(unsigned long long)entry->dst_packets,
|
||||||
|
(unsigned long long)entry->dst_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doContinue)
|
if (doContinue)
|
||||||
|
@@ -34,7 +34,8 @@ int ipt_ACCOUNT_init(struct ipt_ACCOUNT_context *ctx)
|
|||||||
|
|
||||||
// 4096 bytes default buffer should save us from reallocations
|
// 4096 bytes default buffer should save us from reallocations
|
||||||
// as it fits 200 concurrent active clients
|
// as it fits 200 concurrent active clients
|
||||||
if ((ctx->data = malloc(IPT_ACCOUNT_MIN_BUFSIZE)) == NULL) {
|
ctx->data = malloc(IPT_ACCOUNT_MIN_BUFSIZE);
|
||||||
|
if (ctx->data == NULL) {
|
||||||
close(ctx->sockfd);
|
close(ctx->sockfd);
|
||||||
ctx->sockfd = -1;
|
ctx->sockfd = -1;
|
||||||
ctx->error_str = "Out of memory for data buffer";
|
ctx->error_str = "Out of memory for data buffer";
|
||||||
|
@@ -7,10 +7,7 @@
|
|||||||
* version 2.1 as published by the Free Software Foundation; *
|
* version 2.1 as published by the Free Software Foundation; *
|
||||||
* *
|
* *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
#pragma once
|
||||||
#ifndef _xt_ACCOUNT_cl_H
|
|
||||||
#define _xt_ACCOUNT_cl_H
|
|
||||||
|
|
||||||
#include <xt_ACCOUNT.h>
|
#include <xt_ACCOUNT.h>
|
||||||
|
|
||||||
#define LIBXT_ACCOUNT_VERSION "1.3"
|
#define LIBXT_ACCOUNT_VERSION "1.3"
|
||||||
@@ -23,9 +20,8 @@ struct ipt_ACCOUNT_context
|
|||||||
int sockfd;
|
int sockfd;
|
||||||
struct ipt_acc_handle_sockopt handle;
|
struct ipt_acc_handle_sockopt handle;
|
||||||
|
|
||||||
unsigned int data_size;
|
unsigned int data_size, pos;
|
||||||
void *data;
|
void *data;
|
||||||
unsigned int pos;
|
|
||||||
|
|
||||||
char *error_str;
|
char *error_str;
|
||||||
};
|
};
|
||||||
@@ -55,6 +51,3 @@ const char *ipt_ACCOUNT_get_next_name(struct ipt_ACCOUNT_context *ctx);
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -7,9 +7,7 @@
|
|||||||
* version 2 as published by the Free Software Foundation; *
|
* version 2 as published by the Free Software Foundation; *
|
||||||
* *
|
* *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
#pragma once
|
||||||
#ifndef _IPT_ACCOUNT_H
|
|
||||||
#define _IPT_ACCOUNT_H
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Socket option interface shared between kernel (xt_ACCOUNT) and userspace
|
* Socket option interface shared between kernel (xt_ACCOUNT) and userspace
|
||||||
@@ -34,14 +32,12 @@
|
|||||||
#define IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES (SO_ACCOUNT_BASE_CTL + 8)
|
#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 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_TABLE_NAME_LEN 32
|
||||||
#define ACCOUNT_MAX_HANDLES 10
|
#define ACCOUNT_MAX_HANDLES 10
|
||||||
|
|
||||||
/* Structure for the userspace part of ipt_ACCOUNT */
|
/* Structure for the userspace part of ipt_ACCOUNT */
|
||||||
struct ipt_acc_info {
|
struct ipt_acc_info {
|
||||||
__be32 net_ip;
|
__be32 net_ip, net_mask;
|
||||||
__be32 net_mask;
|
|
||||||
char table_name[ACCOUNT_TABLE_NAME_LEN];
|
char table_name[ACCOUNT_TABLE_NAME_LEN];
|
||||||
int32_t table_nr;
|
int32_t table_nr;
|
||||||
};
|
};
|
||||||
@@ -59,11 +55,6 @@ struct ipt_acc_handle_sockopt {
|
|||||||
Used for every IP when returning data
|
Used for every IP when returning data
|
||||||
*/
|
*/
|
||||||
struct ipt_acc_handle_ip {
|
struct ipt_acc_handle_ip {
|
||||||
__be32 ip;
|
__be32 ip, __dummy;
|
||||||
uint32_t src_packets;
|
uint64_t src_packets, src_bytes, dst_packets, dst_bytes;
|
||||||
uint32_t src_bytes;
|
|
||||||
uint32_t dst_packets;
|
|
||||||
uint32_t dst_bytes;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _IPT_ACCOUNT_H */
|
|
||||||
|
@@ -7,23 +7,15 @@ obj-m += compat_xtables.o
|
|||||||
|
|
||||||
obj-${build_ACCOUNT} += ACCOUNT/
|
obj-${build_ACCOUNT} += ACCOUNT/
|
||||||
obj-${build_CHAOS} += xt_CHAOS.o
|
obj-${build_CHAOS} += xt_CHAOS.o
|
||||||
obj-${build_CHECKSUM} += xt_CHECKSUM.o
|
|
||||||
obj-${build_DELUDE} += xt_DELUDE.o
|
obj-${build_DELUDE} += xt_DELUDE.o
|
||||||
obj-${build_DHCPMAC} += xt_DHCPMAC.o
|
obj-${build_DHCPMAC} += xt_DHCPMAC.o
|
||||||
obj-${build_DNETMAP} += xt_DNETMAP.o
|
obj-${build_DNETMAP} += xt_DNETMAP.o
|
||||||
ifeq (${VERSION},3)
|
|
||||||
obj-${build_ECHO} += xt_ECHO.o
|
obj-${build_ECHO} += xt_ECHO.o
|
||||||
endif
|
|
||||||
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
|
obj-${build_PROTO} += xt_PROTO.o
|
||||||
ifneq (${CONFIG_IP6_NF_IPTABLES},)
|
|
||||||
obj-${build_RAWNAT} += ip6table_rawpost.o
|
|
||||||
endif
|
|
||||||
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_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
|
||||||
|
@@ -2,18 +2,15 @@
|
|||||||
|
|
||||||
obj-${build_ACCOUNT} += ACCOUNT/
|
obj-${build_ACCOUNT} += ACCOUNT/
|
||||||
obj-${build_CHAOS} += libxt_CHAOS.so
|
obj-${build_CHAOS} += libxt_CHAOS.so
|
||||||
obj-${build_CHECKSUM} += libxt_CHECKSUM.so
|
|
||||||
obj-${build_DELUDE} += libxt_DELUDE.so
|
obj-${build_DELUDE} += libxt_DELUDE.so
|
||||||
obj-${build_DHCPMAC} += libxt_DHCPMAC.so libxt_dhcpmac.so
|
obj-${build_DHCPMAC} += libxt_DHCPMAC.so libxt_dhcpmac.so
|
||||||
obj-${build_DNETMAP} += libxt_DNETMAP.so
|
obj-${build_DNETMAP} += libxt_DNETMAP.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_PROTO} += libxt_PROTO.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_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
|
||||||
|
@@ -1,14 +0,0 @@
|
|||||||
#ifndef _COMPAT_NFINETADDR_H
|
|
||||||
#define _COMPAT_NFINETADDR_H 1
|
|
||||||
|
|
||||||
#include <linux/in.h>
|
|
||||||
#include <linux/in6.h>
|
|
||||||
|
|
||||||
union nf_inet_addr {
|
|
||||||
__be32 ip;
|
|
||||||
__be32 ip6[4];
|
|
||||||
struct in_addr in;
|
|
||||||
struct in6_addr in6;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _COMPAT_NFINETADDR_H */
|
|
@@ -1,87 +0,0 @@
|
|||||||
#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 */
|
|
@@ -1,62 +1,12 @@
|
|||||||
#ifndef COMPAT_SKBUFF_H
|
#pragma once
|
||||||
#define COMPAT_SKBUFF_H 1
|
|
||||||
|
|
||||||
struct tcphdr;
|
struct tcphdr;
|
||||||
struct udphdr;
|
struct udphdr;
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 30)
|
#define skb_ifindex(skb) (skb)->skb_iif
|
||||||
static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst)
|
#define skb_nfmark(skb) (((struct sk_buff *)(skb))->mark)
|
||||||
{
|
|
||||||
skb->dst = dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct dst_entry *skb_dst(const struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
return skb->dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct rtable *skb_rtable(const struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
return (void *)skb->dst;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
|
||||||
# define skb_ifindex(skb) \
|
|
||||||
(((skb)->input_dev != NULL) ? (skb)->input_dev->ifindex : 0)
|
|
||||||
# define skb_nfmark(skb) (((struct sk_buff *)(skb))->nfmark)
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
|
|
||||||
# define skb_ifindex(skb) (skb)->iif
|
|
||||||
# define skb_nfmark(skb) (((struct sk_buff *)(skb))->mark)
|
|
||||||
#else
|
|
||||||
# define skb_ifindex(skb) (skb)->skb_iif
|
|
||||||
# define skb_nfmark(skb) (((struct sk_buff *)(skb))->mark)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_NETWORK_SECMARK
|
#ifdef CONFIG_NETWORK_SECMARK
|
||||||
# define skb_secmark(skb) ((skb)->secmark)
|
# define skb_secmark(skb) ((skb)->secmark)
|
||||||
#else
|
#else
|
||||||
# define skb_secmark(skb) 0
|
# define skb_secmark(skb) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 21)
|
|
||||||
# define ip_hdr(skb) ((skb)->nh.iph)
|
|
||||||
# define ip_hdrlen(skb) (ip_hdr(skb)->ihl * 4)
|
|
||||||
# define ipv6_hdr(skb) ((skb)->nh.ipv6h)
|
|
||||||
# define skb_network_header(skb) ((skb)->nh.raw)
|
|
||||||
# define skb_transport_header(skb) ((skb)->h.raw)
|
|
||||||
static inline void skb_reset_network_header(struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
skb->nh.raw = skb->data;
|
|
||||||
}
|
|
||||||
static inline struct tcphdr *tcp_hdr(const struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
return (void *)skb_transport_header(skb);
|
|
||||||
}
|
|
||||||
static inline struct udphdr *udp_hdr(const struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
return (void *)skb_transport_header(skb);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* COMPAT_SKBUFF_H */
|
|
||||||
|
@@ -1,12 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Userspace-level compat hacks
|
* Userspace-level compat hacks
|
||||||
*/
|
*/
|
||||||
#ifndef _XTABLES_COMPAT_USER_H
|
#pragma once
|
||||||
#define _XTABLES_COMPAT_USER_H 1
|
|
||||||
|
|
||||||
/* linux-glibc-devel 2.6.34 header screwup */
|
/* linux-glibc-devel 2.6.34 header screwup */
|
||||||
#ifndef ALIGN
|
#ifndef ALIGN
|
||||||
# define ALIGN(s, n) (((s) + ((n) - 1)) & ~((n) - 1))
|
# define ALIGN(s, n) (((s) + ((n) - 1)) & ~((n) - 1))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _XTABLES_COMPAT_USER_H */
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* API compat layer
|
* API compat layer
|
||||||
* written by Jan Engelhardt <jengelh [at] medozas de>, 2008 - 2010
|
* written by Jan Engelhardt, 2008 - 2010
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License, either
|
* modify it under the terms of the GNU General Public License, either
|
||||||
@@ -21,588 +21,12 @@
|
|||||||
#include <net/ip.h>
|
#include <net/ip.h>
|
||||||
#include <net/ipv6.h>
|
#include <net/ipv6.h>
|
||||||
#include <net/route.h>
|
#include <net/route.h>
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
|
#include <linux/export.h>
|
||||||
# include <linux/export.h>
|
|
||||||
#endif
|
|
||||||
#include "compat_skbuff.h"
|
#include "compat_skbuff.h"
|
||||||
#include "compat_xtnu.h"
|
|
||||||
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
|
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
|
||||||
# define WITH_IPV6 1
|
# define WITH_IPV6 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
|
||||||
static int xtnu_match_run(const struct sk_buff *skb,
|
|
||||||
const struct net_device *in, const struct net_device *out,
|
|
||||||
const struct xt_match *cm, const void *matchinfo, int offset,
|
|
||||||
unsigned int protoff, int *hotdrop)
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
static bool xtnu_match_run(const struct sk_buff *skb,
|
|
||||||
const struct net_device *in, const struct net_device *out,
|
|
||||||
const struct xt_match *cm, const void *matchinfo, int offset,
|
|
||||||
unsigned int protoff, bool *hotdrop)
|
|
||||||
#endif
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
{
|
|
||||||
struct xtnu_match *nm = xtcompat_numatch(cm);
|
|
||||||
bool lo_ret;
|
|
||||||
struct xt_action_param local_par;
|
|
||||||
local_par.in = in;
|
|
||||||
local_par.out = out;
|
|
||||||
local_par.match = cm;
|
|
||||||
local_par.matchinfo = matchinfo;
|
|
||||||
local_par.fragoff = offset;
|
|
||||||
local_par.thoff = protoff;
|
|
||||||
local_par.hotdrop = false;
|
|
||||||
local_par.family = NFPROTO_UNSPEC; /* don't have that info */
|
|
||||||
|
|
||||||
if (nm == NULL || nm->match == NULL)
|
|
||||||
return false;
|
|
||||||
lo_ret = nm->match(skb, &local_par);
|
|
||||||
*hotdrop = local_par.hotdrop;
|
|
||||||
return lo_ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) && \
|
|
||||||
LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
|
|
||||||
static bool xtnu_match_run(const struct sk_buff *skb,
|
|
||||||
const struct xt_match_param *par)
|
|
||||||
{
|
|
||||||
struct xtnu_match *nm = xtcompat_numatch(par->match);
|
|
||||||
struct xt_action_param local_par;
|
|
||||||
bool ret;
|
|
||||||
|
|
||||||
local_par.in = par->in;
|
|
||||||
local_par.out = par->out;
|
|
||||||
local_par.match = par->match;
|
|
||||||
local_par.matchinfo = par->matchinfo;
|
|
||||||
local_par.fragoff = par->fragoff;
|
|
||||||
local_par.thoff = par->thoff;
|
|
||||||
local_par.hotdrop = false;
|
|
||||||
local_par.family = par->family;
|
|
||||||
|
|
||||||
if (nm == NULL || nm->match == NULL)
|
|
||||||
return false;
|
|
||||||
ret = nm->match(skb, &local_par);
|
|
||||||
*par->hotdrop = local_par.hotdrop;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
|
||||||
static int xtnu_match_check(const char *table, const void *entry,
|
|
||||||
const struct xt_match *cm, void *matchinfo, unsigned int matchinfosize,
|
|
||||||
unsigned int hook_mask)
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
|
||||||
static int xtnu_match_check(const char *table, const void *entry,
|
|
||||||
const struct xt_match *cm, void *matchinfo, unsigned int hook_mask)
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
static bool xtnu_match_check(const char *table, const void *entry,
|
|
||||||
const struct xt_match *cm, void *matchinfo, unsigned int hook_mask)
|
|
||||||
#endif
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
{
|
|
||||||
struct xtnu_match *nm = xtcompat_numatch(cm);
|
|
||||||
struct xt_mtchk_param local_par = {
|
|
||||||
.table = table,
|
|
||||||
.entryinfo = entry,
|
|
||||||
.match = cm,
|
|
||||||
.matchinfo = matchinfo,
|
|
||||||
.hook_mask = hook_mask,
|
|
||||||
.family = NFPROTO_UNSPEC,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (nm == NULL)
|
|
||||||
return false;
|
|
||||||
if (nm->checkentry == NULL)
|
|
||||||
return true;
|
|
||||||
return nm->checkentry(&local_par) == 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) && \
|
|
||||||
LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
|
|
||||||
static bool xtnu_match_check(const struct xt_mtchk_param *par)
|
|
||||||
{
|
|
||||||
struct xtnu_match *nm = xtcompat_numatch(par->match);
|
|
||||||
|
|
||||||
if (nm == NULL)
|
|
||||||
return false;
|
|
||||||
if (nm->checkentry == NULL)
|
|
||||||
return true;
|
|
||||||
return nm->checkentry(par) == 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
|
||||||
static void xtnu_match_destroy(const struct xt_match *cm, void *matchinfo,
|
|
||||||
unsigned int matchinfosize)
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
static void xtnu_match_destroy(const struct xt_match *cm, void *matchinfo)
|
|
||||||
#endif
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
{
|
|
||||||
struct xtnu_match *nm = xtcompat_numatch(cm);
|
|
||||||
struct xt_mtdtor_param local_par = {
|
|
||||||
.match = cm,
|
|
||||||
.matchinfo = matchinfo,
|
|
||||||
.family = NFPROTO_UNSPEC,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (nm != NULL && nm->destroy != NULL)
|
|
||||||
nm->destroy(&local_par);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
|
|
||||||
int xtnu_register_match(struct xtnu_match *nt)
|
|
||||||
{
|
|
||||||
struct xt_match *ct;
|
|
||||||
char *tmp;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ct = kzalloc(sizeof(struct xt_match), GFP_KERNEL);
|
|
||||||
if (ct == NULL)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
tmp = (char *)ct->name;
|
|
||||||
memcpy(tmp, nt->name, sizeof(nt->name));
|
|
||||||
tmp = (char *)(ct->name + sizeof(ct->name) - sizeof(void *));
|
|
||||||
*(tmp-1) = '\0';
|
|
||||||
memcpy(tmp, &nt, sizeof(void *));
|
|
||||||
|
|
||||||
ct->revision = nt->revision;
|
|
||||||
ct->family = nt->family;
|
|
||||||
ct->table = (char *)nt->table;
|
|
||||||
ct->hooks = nt->hooks;
|
|
||||||
ct->proto = nt->proto;
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
ct->match = xtnu_match_run;
|
|
||||||
ct->checkentry = xtnu_match_check;
|
|
||||||
ct->destroy = xtnu_match_destroy;
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
|
|
||||||
ct->match = xtnu_match_run;
|
|
||||||
ct->checkentry = xtnu_match_check;
|
|
||||||
ct->destroy = nt->destroy;
|
|
||||||
#else
|
|
||||||
ct->match = nt->match;
|
|
||||||
ct->checkentry = xtnu_match_check;
|
|
||||||
ct->destroy = nt->destroy;
|
|
||||||
#endif
|
|
||||||
ct->matchsize = nt->matchsize;
|
|
||||||
ct->me = nt->me;
|
|
||||||
|
|
||||||
nt->__compat_match = ct;
|
|
||||||
ret = xt_register_match(ct);
|
|
||||||
if (ret != 0)
|
|
||||||
kfree(ct);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_register_match);
|
|
||||||
|
|
||||||
int xtnu_register_matches(struct xtnu_match *nt, unsigned int num)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
for (i = 0; i < num; ++i) {
|
|
||||||
ret = xtnu_register_match(&nt[i]);
|
|
||||||
if (ret < 0) {
|
|
||||||
if (i > 0)
|
|
||||||
xtnu_unregister_matches(nt, i);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_register_matches);
|
|
||||||
|
|
||||||
void xtnu_unregister_match(struct xtnu_match *nt)
|
|
||||||
{
|
|
||||||
xt_unregister_match(nt->__compat_match);
|
|
||||||
kfree(nt->__compat_match);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_unregister_match);
|
|
||||||
|
|
||||||
void xtnu_unregister_matches(struct xtnu_match *nt, unsigned int num)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < num; ++i)
|
|
||||||
xtnu_unregister_match(&nt[i]);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_unregister_matches);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
|
||||||
static unsigned int xtnu_target_run(struct sk_buff **pskb,
|
|
||||||
const struct net_device *in, const struct net_device *out,
|
|
||||||
unsigned int hooknum, const struct xt_target *ct, const void *targinfo,
|
|
||||||
void *userdata)
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
|
||||||
static unsigned int xtnu_target_run(struct sk_buff **pskb,
|
|
||||||
const struct net_device *in, const struct net_device *out,
|
|
||||||
unsigned int hooknum, const struct xt_target *ct, const void *targinfo)
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
static unsigned int xtnu_target_run(struct sk_buff *skb,
|
|
||||||
const struct net_device *in, const struct net_device *out,
|
|
||||||
unsigned int hooknum, const struct xt_target *ct, const void *targinfo)
|
|
||||||
#endif
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
{
|
|
||||||
struct xtnu_target *nt = xtcompat_nutarget(ct);
|
|
||||||
struct xt_action_param local_par;
|
|
||||||
|
|
||||||
local_par.in = in;
|
|
||||||
local_par.out = out;
|
|
||||||
local_par.hooknum = hooknum;
|
|
||||||
local_par.target = ct;
|
|
||||||
local_par.targinfo = targinfo;
|
|
||||||
local_par.family = NFPROTO_UNSPEC;
|
|
||||||
|
|
||||||
if (nt != NULL && nt->target != NULL)
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
|
||||||
return nt->target(pskb, &local_par);
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
return nt->target(&skb, &local_par);
|
|
||||||
#endif
|
|
||||||
return XT_CONTINUE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) && \
|
|
||||||
LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
|
|
||||||
static unsigned int
|
|
||||||
xtnu_target_run(struct sk_buff *skb, const struct xt_target_param *par)
|
|
||||||
{
|
|
||||||
struct xtnu_target *nt = xtcompat_nutarget(par->target);
|
|
||||||
struct xt_action_param local_par;
|
|
||||||
|
|
||||||
local_par.in = par->in;
|
|
||||||
local_par.out = par->out;
|
|
||||||
local_par.hooknum = par->hooknum;
|
|
||||||
local_par.target = par->target;
|
|
||||||
local_par.targinfo = par->targinfo;
|
|
||||||
local_par.family = par->family;
|
|
||||||
|
|
||||||
return nt->target(&skb, &local_par);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
|
|
||||||
static unsigned int
|
|
||||||
xtnu_target_run(struct sk_buff *skb, const struct xt_action_param *par)
|
|
||||||
{
|
|
||||||
struct xtnu_target *nt = xtcompat_nutarget(par->target);
|
|
||||||
|
|
||||||
return nt->target(&skb, par);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
|
||||||
static int xtnu_target_check(const char *table, const void *entry,
|
|
||||||
const struct xt_target *ct, void *targinfo,
|
|
||||||
unsigned int targinfosize, unsigned int hook_mask)
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
|
||||||
static int xtnu_target_check(const char *table, const void *entry,
|
|
||||||
const struct xt_target *ct, void *targinfo, unsigned int hook_mask)
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
static bool xtnu_target_check(const char *table, const void *entry,
|
|
||||||
const struct xt_target *ct, void *targinfo, unsigned int hook_mask)
|
|
||||||
#endif
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
{
|
|
||||||
struct xtnu_target *nt = xtcompat_nutarget(ct);
|
|
||||||
struct xt_tgchk_param local_par = {
|
|
||||||
.table = table,
|
|
||||||
.entryinfo = entry,
|
|
||||||
.target = ct,
|
|
||||||
.targinfo = targinfo,
|
|
||||||
.hook_mask = hook_mask,
|
|
||||||
.family = NFPROTO_UNSPEC,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (nt == NULL)
|
|
||||||
return false;
|
|
||||||
if (nt->checkentry == NULL)
|
|
||||||
/* this is valid, just like if there was no function */
|
|
||||||
return true;
|
|
||||||
return nt->checkentry(&local_par) == 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) && \
|
|
||||||
LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
|
|
||||||
static bool xtnu_target_check(const struct xt_tgchk_param *par)
|
|
||||||
{
|
|
||||||
struct xtnu_target *nt = xtcompat_nutarget(par->target);
|
|
||||||
|
|
||||||
if (nt == NULL)
|
|
||||||
return false;
|
|
||||||
if (nt->checkentry == NULL)
|
|
||||||
return true;
|
|
||||||
return nt->checkentry(par) == 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
|
||||||
static void xtnu_target_destroy(const struct xt_target *ct, void *targinfo,
|
|
||||||
unsigned int targinfosize)
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
static void xtnu_target_destroy(const struct xt_target *ct, void *targinfo)
|
|
||||||
#endif
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
{
|
|
||||||
struct xtnu_target *nt = xtcompat_nutarget(ct);
|
|
||||||
struct xt_tgdtor_param local_par = {
|
|
||||||
.target = ct,
|
|
||||||
.targinfo = targinfo,
|
|
||||||
.family = NFPROTO_UNSPEC,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (nt != NULL && nt->destroy != NULL)
|
|
||||||
nt->destroy(&local_par);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int xtnu_register_target(struct xtnu_target *nt)
|
|
||||||
{
|
|
||||||
struct xt_target *ct;
|
|
||||||
char *tmp;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ct = kzalloc(sizeof(struct xt_target), GFP_KERNEL);
|
|
||||||
if (ct == NULL)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
tmp = (char *)ct->name;
|
|
||||||
memcpy(tmp, nt->name, sizeof(nt->name));
|
|
||||||
tmp = (char *)(ct->name + sizeof(ct->name) - sizeof(void *));
|
|
||||||
*(tmp-1) = '\0';
|
|
||||||
memcpy(tmp, &nt, sizeof(void *));
|
|
||||||
|
|
||||||
ct->revision = nt->revision;
|
|
||||||
ct->family = nt->family;
|
|
||||||
ct->table = (char *)nt->table;
|
|
||||||
ct->hooks = nt->hooks;
|
|
||||||
ct->proto = nt->proto;
|
|
||||||
ct->target = xtnu_target_run;
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
ct->checkentry = xtnu_target_check;
|
|
||||||
ct->destroy = xtnu_target_destroy;
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
|
|
||||||
ct->checkentry = xtnu_target_check;
|
|
||||||
ct->destroy = nt->destroy;
|
|
||||||
#else
|
|
||||||
ct->checkentry = nt->checkentry;
|
|
||||||
ct->destroy = nt->destroy;
|
|
||||||
#endif
|
|
||||||
ct->targetsize = nt->targetsize;
|
|
||||||
ct->me = nt->me;
|
|
||||||
|
|
||||||
nt->__compat_target = ct;
|
|
||||||
ret = xt_register_target(ct);
|
|
||||||
if (ret != 0)
|
|
||||||
kfree(ct);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_register_target);
|
|
||||||
|
|
||||||
int xtnu_register_targets(struct xtnu_target *nt, unsigned int num)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
for (i = 0; i < num; ++i) {
|
|
||||||
ret = xtnu_register_target(&nt[i]);
|
|
||||||
if (ret < 0) {
|
|
||||||
if (i > 0)
|
|
||||||
xtnu_unregister_targets(nt, i);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_register_targets);
|
|
||||||
|
|
||||||
void xtnu_unregister_target(struct xtnu_target *nt)
|
|
||||||
{
|
|
||||||
xt_unregister_target(nt->__compat_target);
|
|
||||||
kfree(nt->__compat_target);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_unregister_target);
|
|
||||||
|
|
||||||
void xtnu_unregister_targets(struct xtnu_target *nt, unsigned int num)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < num; ++i)
|
|
||||||
xtnu_unregister_target(&nt[i]);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_unregister_targets);
|
|
||||||
|
|
||||||
struct xt_match *xtnu_request_find_match(unsigned int af, const char *name,
|
|
||||||
uint8_t revision)
|
|
||||||
{
|
|
||||||
static const char *const xt_prefix[] = {
|
|
||||||
[AF_UNSPEC] = "x",
|
|
||||||
[AF_INET] = "ip",
|
|
||||||
[AF_INET6] = "ip6",
|
|
||||||
#ifdef AF_ARP
|
|
||||||
[AF_ARP] = "arp",
|
|
||||||
#elif defined(NF_ARP) && NF_ARP != AF_UNSPEC
|
|
||||||
[NF_ARP] = "arp",
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
struct xt_match *match;
|
|
||||||
|
|
||||||
match = try_then_request_module(xt_find_match(af, name, revision),
|
|
||||||
"%st_%s", xt_prefix[af], name);
|
|
||||||
if (IS_ERR(match) || match == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_request_find_match);
|
|
||||||
|
|
||||||
int xtnu_ip_route_me_harder(struct sk_buff **pskb, unsigned int addr_type)
|
|
||||||
{
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 17)
|
|
||||||
/* Actually this one is valid up to 2.6.18.4, but changed in 2.6.18.5 */
|
|
||||||
return ip_route_me_harder(pskb);
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
|
||||||
return ip_route_me_harder(pskb, addr_type);
|
|
||||||
#else
|
|
||||||
return ip_route_me_harder(*pskb, addr_type);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_ip_route_me_harder);
|
|
||||||
|
|
||||||
int xtnu_skb_make_writable(struct sk_buff **pskb, unsigned int len)
|
|
||||||
{
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
|
||||||
return skb_make_writable(pskb, len);
|
|
||||||
#else
|
|
||||||
return skb_make_writable(*pskb, len);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_skb_make_writable);
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 24)
|
|
||||||
static int __xtnu_ip_local_out(struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
struct iphdr *iph = ip_hdr(skb);
|
|
||||||
|
|
||||||
iph->tot_len = htons(skb->len);
|
|
||||||
ip_send_check(iph);
|
|
||||||
return nf_hook(PF_INET, NF_IP_LOCAL_OUT, skb, NULL,
|
|
||||||
skb->dst->dev, dst_output);
|
|
||||||
}
|
|
||||||
|
|
||||||
int xtnu_ip_local_out(struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = __xtnu_ip_local_out(skb);
|
|
||||||
if (likely(err == 1))
|
|
||||||
err = dst_output(skb);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_ip_local_out);
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
|
||||||
static int __xtnu_ip_local_out(struct sk_buff **pskb)
|
|
||||||
{
|
|
||||||
struct iphdr *iph = ip_hdr(*pskb);
|
|
||||||
|
|
||||||
iph->tot_len = htons((*pskb)->len);
|
|
||||||
ip_send_check(iph);
|
|
||||||
return nf_hook(PF_INET, NF_IP_LOCAL_OUT, pskb, NULL,
|
|
||||||
(*pskb)->dst->dev, dst_output);
|
|
||||||
}
|
|
||||||
|
|
||||||
int xtnu_ip_local_out(struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = __xtnu_ip_local_out(&skb);
|
|
||||||
if (likely(err == 1))
|
|
||||||
err = dst_output(skb);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_ip_local_out);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
|
|
||||||
int xtnu_ip_route_output_key(void *net, struct rtable **rp, struct flowi *flp)
|
|
||||||
{
|
|
||||||
return ip_route_output_flow(rp, flp, NULL, 0);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_ip_route_output_key);
|
|
||||||
|
|
||||||
void xtnu_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
|
|
||||||
__be32 from, __be32 to, bool pseudohdr)
|
|
||||||
{
|
|
||||||
__be32 diff[] = {~from, to};
|
|
||||||
const void *dv = diff; /* kludge for < v2.6.19-555-g72685fc */
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
|
|
||||||
if (skb->ip_summed != CHECKSUM_PARTIAL) {
|
|
||||||
*sum = csum_fold(csum_partial(dv, sizeof(diff),
|
|
||||||
~csum_unfold(*sum)));
|
|
||||||
if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
|
|
||||||
skb->csum = ~csum_partial(dv, sizeof(diff),
|
|
||||||
~skb->csum);
|
|
||||||
} else if (pseudohdr) {
|
|
||||||
*sum = ~csum_fold(csum_partial(dv, sizeof(diff),
|
|
||||||
csum_unfold(*sum)));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
*sum = csum_fold(csum_partial(dv, sizeof(diff),
|
|
||||||
~csum_unfold(*sum)));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_proto_csum_replace4);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
|
||||||
int xtnu_neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
unsigned int hh_alen;
|
|
||||||
|
|
||||||
read_lock_bh(&hh->hh_lock);
|
|
||||||
hh_alen = HH_DATA_ALIGN(hh->hh_len);
|
|
||||||
memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
|
|
||||||
read_unlock_bh(&hh->hh_lock);
|
|
||||||
skb_push(skb, hh->hh_len);
|
|
||||||
return hh->hh_output(skb);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_neigh_hh_output);
|
|
||||||
|
|
||||||
static inline __wsum xtnu_csum_unfold(__sum16 n)
|
|
||||||
{
|
|
||||||
return (__force __wsum)n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void xtnu_csum_replace4(__sum16 *sum, __be32 from, __be32 to)
|
|
||||||
{
|
|
||||||
__be32 diff[] = {~from, to};
|
|
||||||
*sum = csum_fold(csum_partial((char *)diff, sizeof(diff),
|
|
||||||
~xtnu_csum_unfold(*sum)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void xtnu_csum_replace2(__sum16 *sum, __be16 from, __be16 to)
|
|
||||||
{
|
|
||||||
xtnu_csum_replace4(sum, (__force __be32)from, (__force __be32)to);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_csum_replace2);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 17)
|
|
||||||
int xtnu_skb_linearize(struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
return skb_linearize(skb, GFP_ATOMIC);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xtnu_skb_linearize);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *HX_memmem(const void *space, size_t spacesize,
|
void *HX_memmem(const void *space, size_t spacesize,
|
||||||
const void *point, size_t pointsize)
|
const void *point, size_t pointsize)
|
||||||
{
|
{
|
||||||
@@ -617,20 +41,4 @@ void *HX_memmem(const void *space, size_t spacesize,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(HX_memmem);
|
EXPORT_SYMBOL_GPL(HX_memmem);
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0) && defined(WITH_IPV6)
|
|
||||||
int xtnu_ipv6_skip_exthdr(const struct sk_buff *skb, int start,
|
|
||||||
uint8_t *nexthdrp, __be16 *fragoffp)
|
|
||||||
{
|
|
||||||
return ipv6_skip_exthdr(skb, start, nexthdrp);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) && defined(WITH_IPV6)
|
|
||||||
int xtnu_ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
|
|
||||||
int target, unsigned short *fragoff, int *fragflg)
|
|
||||||
{
|
|
||||||
return ipv6_find_hdr(skb, offset, target, fragoff);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
@@ -1,15 +1,12 @@
|
|||||||
#ifndef _XTABLES_COMPAT_H
|
#pragma once
|
||||||
#define _XTABLES_COMPAT_H 1
|
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
#include "compat_skbuff.h"
|
#include "compat_skbuff.h"
|
||||||
#include "compat_xtnu.h"
|
|
||||||
|
|
||||||
#define DEBUGP Use__pr_debug__instead
|
#define DEBUGP Use__pr_debug__instead
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||||
# warning Kernels below 2.6.17 not supported.
|
# warning Kernels below 4.15 not supported.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
||||||
@@ -17,121 +14,35 @@
|
|||||||
# warning You have CONFIG_NF_CONNTRACK enabled, but CONFIG_NF_CONNTRACK_MARK is not (please enable).
|
# warning You have CONFIG_NF_CONNTRACK enabled, but CONFIG_NF_CONNTRACK_MARK is not (please enable).
|
||||||
# endif
|
# endif
|
||||||
# include <net/netfilter/nf_conntrack.h>
|
# include <net/netfilter/nf_conntrack.h>
|
||||||
#elif defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
|
|
||||||
# if !defined(CONFIG_IP_NF_CONNTRACK_MARK)
|
|
||||||
# warning You have CONFIG_IP_NF_CONNTRACK enabled, but CONFIG_IP_NF_CONNTRACK_MARK is not (please enable).
|
|
||||||
# endif
|
|
||||||
# include <linux/netfilter_ipv4/ip_conntrack.h>
|
|
||||||
# define nf_conn ip_conntrack
|
|
||||||
# define nf_ct_get ip_conntrack_get
|
|
||||||
# define nf_conntrack_untracked ip_conntrack_untracked
|
|
||||||
#else
|
#else
|
||||||
# warning You need either CONFIG_NF_CONNTRACK or CONFIG_IP_NF_CONNTRACK.
|
# warning You need CONFIG_NF_CONNTRACK.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 17)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) || \
|
||||||
# define skb_init_secmark(skb)
|
LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 9) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) || \
|
||||||
# define skb_linearize xtnu_skb_linearize
|
LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 78) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0) || \
|
||||||
#endif
|
LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 158) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
|
||||||
# define neigh_hh_output xtnu_neigh_hh_output
|
|
||||||
# define IPPROTO_UDPLITE 136
|
|
||||||
# define CSUM_MANGLED_0 ((__force __sum16)0xffff)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
|
|
||||||
# define NF_INET_PRE_ROUTING NF_IP_PRE_ROUTING
|
|
||||||
# define NF_INET_LOCAL_IN NF_IP_LOCAL_IN
|
|
||||||
# define NF_INET_FORWARD NF_IP_FORWARD
|
|
||||||
# define NF_INET_LOCAL_OUT NF_IP_LOCAL_OUT
|
|
||||||
# define NF_INET_POST_ROUTING NF_IP_POST_ROUTING
|
|
||||||
# define ip_local_out xtnu_ip_local_out
|
|
||||||
# define ip_route_output_key xtnu_ip_route_output_key
|
|
||||||
# include "compat_nfinetaddr.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
|
||||||
# define init_net xtnu_ip_route_output_key /* yes */
|
|
||||||
# define init_net__loopback_dev (&loopback_dev)
|
|
||||||
# define init_net__proc_net proc_net
|
|
||||||
#else
|
#else
|
||||||
# define init_net__loopback_dev init_net.loopback_dev
|
# define ip_route_me_harder(xnet, xsk, xskb, xaddrtype) ip_route_me_harder((xnet), (xskb), (xaddrtype))
|
||||||
# define init_net__proc_net init_net.proc_net
|
# define ip6_route_me_harder(xnet, xsk, xskb) ip6_route_me_harder((xnet), (xskb))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
|
static inline struct net *par_net(const struct xt_action_param *par)
|
||||||
# define xt_match xtnu_match
|
{
|
||||||
# define xt_register_match xtnu_register_match
|
return par->state->net;
|
||||||
# define xt_unregister_match xtnu_unregister_match
|
}
|
||||||
# define xt_register_matches xtnu_register_matches
|
|
||||||
# define xt_unregister_matches xtnu_unregister_matches
|
#ifndef NF_CT_ASSERT
|
||||||
|
# define NF_CT_ASSERT(x) WARN_ON(!(x))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
|
||||||
# define csum_replace2 xtnu_csum_replace2
|
# define proc_ops file_operations
|
||||||
# define csum_replace4 xtnu_csum_replace4
|
# define proc_open open
|
||||||
# define inet_proto_csum_replace4 xtnu_proto_csum_replace4
|
# define proc_read read
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
|
# define proc_write write
|
||||||
# define csum_replace2 nf_csum_replace2
|
# define proc_lseek llseek
|
||||||
# define csum_replace4 nf_csum_replace4
|
# define proc_release release
|
||||||
# define inet_proto_csum_replace4 xtnu_proto_csum_replace4
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
|
extern void *HX_memmem(const void *, size_t, const void *, size_t);
|
||||||
# define ipt_unregister_table(tbl) ipt_unregister_table(&init_net, (tbl))
|
|
||||||
# define ip6t_unregister_table(tbl) ip6t_unregister_table(&init_net, (tbl))
|
|
||||||
#else
|
|
||||||
# define ipt_unregister_table(tbl) ipt_unregister_table(tbl)
|
|
||||||
# define ip6t_unregister_table(tbl) ip6t_unregister_table(tbl)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
|
|
||||||
# define rt_dst(rt) (&(rt)->dst)
|
|
||||||
#else
|
|
||||||
# define rt_dst(rt) (&(rt)->u.dst)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
|
|
||||||
# define nf_nat_ipv4_multi_range_compat nf_nat_multi_range_compat
|
|
||||||
# define nf_nat_ipv4_range nf_nat_range
|
|
||||||
# define NF_NAT_RANGE_MAP_IPS IP_NAT_RANGE_MAP_IPS
|
|
||||||
# define ipv6_skip_exthdr xtnu_ipv6_skip_exthdr
|
|
||||||
#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
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
|
|
||||||
# define ipv6_find_hdr xtnu_ipv6_find_hdr
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ip_route_me_harder xtnu_ip_route_me_harder
|
|
||||||
#define skb_make_writable xtnu_skb_make_writable
|
|
||||||
#define xt_target xtnu_target
|
|
||||||
#define xt_register_target xtnu_register_target
|
|
||||||
#define xt_unregister_target xtnu_unregister_target
|
|
||||||
#define xt_register_targets xtnu_register_targets
|
|
||||||
#define xt_unregister_targets xtnu_unregister_targets
|
|
||||||
|
|
||||||
#define xt_request_find_match xtnu_request_find_match
|
|
||||||
|
|
||||||
#endif /* _XTABLES_COMPAT_H */
|
|
||||||
|
@@ -1,172 +0,0 @@
|
|||||||
#ifndef _COMPAT_XTNU_H
|
|
||||||
#define _COMPAT_XTNU_H 1
|
|
||||||
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/netfilter/x_tables.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
|
||||||
typedef _Bool bool;
|
|
||||||
enum { false = 0, true = 1, };
|
|
||||||
#endif
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
|
||||||
typedef __u16 __bitwise __sum16;
|
|
||||||
typedef __u32 __bitwise __wsum;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct flowi;
|
|
||||||
struct hh_cache;
|
|
||||||
struct module;
|
|
||||||
struct net_device;
|
|
||||||
struct rtable;
|
|
||||||
struct sk_buff;
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
enum {
|
|
||||||
NFPROTO_UNSPEC = 0,
|
|
||||||
NFPROTO_IPV4 = 2,
|
|
||||||
NFPROTO_ARP = 3,
|
|
||||||
NFPROTO_BRIDGE = 7,
|
|
||||||
NFPROTO_IPV6 = 10,
|
|
||||||
NFPROTO_DECNET = 12,
|
|
||||||
NFPROTO_NUMPROTO,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct xt_mtchk_param {
|
|
||||||
const char *table;
|
|
||||||
const void *entryinfo;
|
|
||||||
const struct xt_match *match;
|
|
||||||
void *matchinfo;
|
|
||||||
unsigned int hook_mask;
|
|
||||||
u_int8_t family;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct xt_mtdtor_param {
|
|
||||||
const struct xt_match *match;
|
|
||||||
void *matchinfo;
|
|
||||||
u_int8_t family;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct xt_target_param {
|
|
||||||
const struct net_device *in, *out;
|
|
||||||
unsigned int hooknum;
|
|
||||||
const struct xt_target *target;
|
|
||||||
const void *targinfo;
|
|
||||||
u_int8_t family;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct xt_tgchk_param {
|
|
||||||
const char *table;
|
|
||||||
const void *entryinfo;
|
|
||||||
const struct xt_target *target;
|
|
||||||
void *targinfo;
|
|
||||||
unsigned int hook_mask;
|
|
||||||
u_int8_t family;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct xt_tgdtor_param {
|
|
||||||
const struct xt_target *target;
|
|
||||||
void *targinfo;
|
|
||||||
u_int8_t family;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
|
|
||||||
struct xt_action_param {
|
|
||||||
union {
|
|
||||||
const struct xt_match *match;
|
|
||||||
const struct xt_target *target;
|
|
||||||
};
|
|
||||||
union {
|
|
||||||
const void *matchinfo, *targinfo;
|
|
||||||
};
|
|
||||||
const struct net_device *in, *out;
|
|
||||||
int fragoff;
|
|
||||||
unsigned int thoff, hooknum;
|
|
||||||
u_int8_t family;
|
|
||||||
bool hotdrop;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct xtnu_match {
|
|
||||||
/*
|
|
||||||
* Making it smaller by sizeof(void *) on purpose to catch
|
|
||||||
* lossy translation, if any.
|
|
||||||
*/
|
|
||||||
char name[sizeof(((struct xt_match *)NULL)->name) - 1 - sizeof(void *)];
|
|
||||||
uint8_t revision;
|
|
||||||
bool (*match)(const struct sk_buff *, struct xt_action_param *);
|
|
||||||
int (*checkentry)(const struct xt_mtchk_param *);
|
|
||||||
void (*destroy)(const struct xt_mtdtor_param *);
|
|
||||||
struct module *me;
|
|
||||||
const char *table;
|
|
||||||
unsigned int matchsize, hooks;
|
|
||||||
unsigned short proto, family;
|
|
||||||
|
|
||||||
void *__compat_match;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct xtnu_target {
|
|
||||||
char name[sizeof(((struct xt_target *)NULL)->name) - 1 - sizeof(void *)];
|
|
||||||
uint8_t revision;
|
|
||||||
unsigned int (*target)(struct sk_buff **,
|
|
||||||
const struct xt_action_param *);
|
|
||||||
int (*checkentry)(const struct xt_tgchk_param *);
|
|
||||||
void (*destroy)(const struct xt_tgdtor_param *);
|
|
||||||
struct module *me;
|
|
||||||
const char *table;
|
|
||||||
unsigned int targetsize, hooks;
|
|
||||||
unsigned short proto, family;
|
|
||||||
|
|
||||||
void *__compat_target;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline struct xtnu_match *xtcompat_numatch(const struct xt_match *m)
|
|
||||||
{
|
|
||||||
void *q;
|
|
||||||
memcpy(&q, m->name + sizeof(m->name) - sizeof(void *), sizeof(void *));
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct xtnu_target *xtcompat_nutarget(const struct xt_target *t)
|
|
||||||
{
|
|
||||||
void *q;
|
|
||||||
memcpy(&q, t->name + sizeof(t->name) - sizeof(void *), sizeof(void *));
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
|
||||||
static inline __wsum csum_unfold(__sum16 n)
|
|
||||||
{
|
|
||||||
return (__force __wsum)n;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern int xtnu_ip_local_out(struct sk_buff *);
|
|
||||||
extern int xtnu_ip_route_me_harder(struct sk_buff **, unsigned int);
|
|
||||||
extern int xtnu_skb_make_writable(struct sk_buff **, unsigned int);
|
|
||||||
extern int xtnu_register_match(struct xtnu_match *);
|
|
||||||
extern int xtnu_ip_route_output_key(void *, struct rtable **, struct flowi *);
|
|
||||||
extern void xtnu_unregister_match(struct xtnu_match *);
|
|
||||||
extern int xtnu_register_matches(struct xtnu_match *, unsigned int);
|
|
||||||
extern void xtnu_unregister_matches(struct xtnu_match *, unsigned int);
|
|
||||||
extern int xtnu_register_target(struct xtnu_target *);
|
|
||||||
extern void xtnu_unregister_target(struct xtnu_target *);
|
|
||||||
extern int xtnu_register_targets(struct xtnu_target *, unsigned int);
|
|
||||||
extern void xtnu_unregister_targets(struct xtnu_target *, unsigned int);
|
|
||||||
extern struct xt_match *xtnu_request_find_match(unsigned int,
|
|
||||||
const char *, uint8_t);
|
|
||||||
extern int xtnu_neigh_hh_output(struct hh_cache *, struct sk_buff *);
|
|
||||||
extern void xtnu_csum_replace2(__u16 __bitwise *, __be16, __be16);
|
|
||||||
extern void xtnu_csum_replace4(__u16 __bitwise *, __be32, __be32);
|
|
||||||
extern void xtnu_proto_csum_replace4(__u16 __bitwise *, struct sk_buff *,
|
|
||||||
__be32, __be32, bool);
|
|
||||||
extern int xtnu_skb_linearize(struct sk_buff *);
|
|
||||||
extern int xtnu_ipv6_skip_exthdr(const struct sk_buff *, int,
|
|
||||||
uint8_t *, __be16 *);
|
|
||||||
extern int xtnu_ipv6_find_hdr(const struct sk_buff *, unsigned int *,
|
|
||||||
int, unsigned short *, int *);
|
|
||||||
|
|
||||||
extern void *HX_memmem(const void *, size_t, const void *, size_t);
|
|
||||||
|
|
||||||
#endif /* _COMPAT_XTNU_H */
|
|
@@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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");
|
|
@@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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");
|
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* "CHAOS" target extension for iptables
|
* "CHAOS" target extension for iptables
|
||||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2006 - 2008
|
* Copyright © Jan Engelhardt, 2006 - 2008
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License; either
|
* modify it under the terms of the GNU General Public License; either
|
||||||
@@ -64,21 +64,6 @@ static void chaos_tg_check(unsigned int flags)
|
|||||||
"may be specified");
|
"may be specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void chaos_tg_print(const void *ip,
|
|
||||||
const struct xt_entry_target *target, int numeric)
|
|
||||||
{
|
|
||||||
const struct xt_chaos_tginfo *info = (const void *)target->data;
|
|
||||||
|
|
||||||
switch (info->variant) {
|
|
||||||
case XTCHAOS_DELUDE:
|
|
||||||
printf(" DELUDE ");
|
|
||||||
break;
|
|
||||||
case XTCHAOS_TARPIT:
|
|
||||||
printf(" TARPIT ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void chaos_tg_save(const void *ip, const struct xt_entry_target *target)
|
static void chaos_tg_save(const void *ip, const struct xt_entry_target *target)
|
||||||
{
|
{
|
||||||
const struct xt_chaos_tginfo *info = (const void *)target->data;
|
const struct xt_chaos_tginfo *info = (const void *)target->data;
|
||||||
@@ -93,6 +78,13 @@ static void chaos_tg_save(const void *ip, const struct xt_entry_target *target)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void chaos_tg_print(const void *ip,
|
||||||
|
const struct xt_entry_target *target, int numeric)
|
||||||
|
{
|
||||||
|
printf(" -j CHAOS");
|
||||||
|
chaos_tg_save(ip, target);
|
||||||
|
}
|
||||||
|
|
||||||
static struct xtables_target chaos_tg_reg = {
|
static struct xtables_target chaos_tg_reg = {
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.name = "CHAOS",
|
.name = "CHAOS",
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
.PP
|
||||||
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
|
||||||
@@ -17,5 +18,5 @@ connections than they can.
|
|||||||
The randomness factor of not replying vs. replying can be set during load-time
|
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://inai.de/projects/chaostables/ for more information
|
||||||
about CHAOS, DELUDE and lscan.
|
about CHAOS, DELUDE and lscan.
|
||||||
|
@@ -1,94 +0,0 @@
|
|||||||
/*
|
|
||||||
* (C) 2002 by Harald Welte <laforge@gnumonks.org>
|
|
||||||
* (C) 2010 by Red Hat, Inc
|
|
||||||
* Author: Michael S. Tsirkin <mst@redhat.com>
|
|
||||||
*
|
|
||||||
* This program is distributed under the terms of GNU GPL v2, 1991
|
|
||||||
*/
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
|
|
||||||
#include <xtables.h>
|
|
||||||
#include "xt_CHECKSUM.h"
|
|
||||||
#include "compat_user.h"
|
|
||||||
|
|
||||||
static void CHECKSUM_help(void)
|
|
||||||
{
|
|
||||||
printf(
|
|
||||||
"CHECKSUM target options\n"
|
|
||||||
" --checksum-fill Fill in packet checksum.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct option CHECKSUM_opts[] = {
|
|
||||||
{ "checksum-fill", 0, NULL, 'F' },
|
|
||||||
{ .name = NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static int CHECKSUM_parse(int c, char **argv, int invert, unsigned int *flags,
|
|
||||||
const void *entry, struct xt_entry_target **target)
|
|
||||||
{
|
|
||||||
struct xt_CHECKSUM_info *einfo
|
|
||||||
= (struct xt_CHECKSUM_info *)(*target)->data;
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case 'F':
|
|
||||||
xtables_param_act(XTF_ONLY_ONCE, "CHECKSUM", "--checksum-fill",
|
|
||||||
*flags & XT_CHECKSUM_OP_FILL);
|
|
||||||
einfo->operation = XT_CHECKSUM_OP_FILL;
|
|
||||||
*flags |= XT_CHECKSUM_OP_FILL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void CHECKSUM_check(unsigned int flags)
|
|
||||||
{
|
|
||||||
if (!flags)
|
|
||||||
xtables_error(PARAMETER_PROBLEM,
|
|
||||||
"CHECKSUM target: Parameter --checksum-fill is required");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void CHECKSUM_print(const void *ip, const struct xt_entry_target *target,
|
|
||||||
int numeric)
|
|
||||||
{
|
|
||||||
const struct xt_CHECKSUM_info *einfo =
|
|
||||||
(const struct xt_CHECKSUM_info *)target->data;
|
|
||||||
|
|
||||||
printf("CHECKSUM ");
|
|
||||||
|
|
||||||
if (einfo->operation & XT_CHECKSUM_OP_FILL)
|
|
||||||
printf(" fill ");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void CHECKSUM_save(const void *ip, const struct xt_entry_target *target)
|
|
||||||
{
|
|
||||||
const struct xt_CHECKSUM_info *einfo =
|
|
||||||
(const struct xt_CHECKSUM_info *)target->data;
|
|
||||||
|
|
||||||
if (einfo->operation & XT_CHECKSUM_OP_FILL)
|
|
||||||
printf(" --checksum-fill ");
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct xtables_target checksum_tg_reg = {
|
|
||||||
.name = "CHECKSUM",
|
|
||||||
.version = XTABLES_VERSION,
|
|
||||||
.family = NFPROTO_UNSPEC,
|
|
||||||
.size = XT_ALIGN(sizeof(struct xt_CHECKSUM_info)),
|
|
||||||
.userspacesize = XT_ALIGN(sizeof(struct xt_CHECKSUM_info)),
|
|
||||||
.help = CHECKSUM_help,
|
|
||||||
.parse = CHECKSUM_parse,
|
|
||||||
.final_check = CHECKSUM_check,
|
|
||||||
.print = CHECKSUM_print,
|
|
||||||
.save = CHECKSUM_save,
|
|
||||||
.extra_opts = CHECKSUM_opts,
|
|
||||||
};
|
|
||||||
|
|
||||||
static __attribute__((constructor)) void _init(void)
|
|
||||||
{
|
|
||||||
xtables_register_target(&checksum_tg_reg);
|
|
||||||
}
|
|
@@ -1,8 +0,0 @@
|
|||||||
This target allows to selectively work around broken/old applications.
|
|
||||||
It can only be used in the mangle table.
|
|
||||||
.TP
|
|
||||||
\fB\-\-checksum\-fill\fP
|
|
||||||
Compute and fill in the checksum in a packet that lacks a checksum.
|
|
||||||
This is particularly useful, if you need to work around old applications
|
|
||||||
such as dhcp clients, that do not work well with checksum offloads,
|
|
||||||
but don't want to disable checksum offload in your device.
|
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* "DELUDE" target extension for iptables
|
* "DELUDE" target extension for iptables
|
||||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2006 - 2008
|
* Copyright © Jan Engelhardt, 2006 - 2008
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License; either
|
* modify it under the terms of the GNU General Public License; either
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
.PP
|
||||||
The DELUDE target will reply to a SYN packet with SYN-ACK, and to all other
|
The DELUDE target will reply to a SYN packet with SYN-ACK, and to all other
|
||||||
packets with an RST. This will terminate the connection much like REJECT, but
|
packets with an RST. This will terminate the connection much like REJECT, but
|
||||||
network scanners doing TCP half-open discovery can be spoofed to make them
|
network scanners doing TCP half-open discovery can be spoofed to make them
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* "DHCPMAC" target extension for iptables
|
* "DHCPMAC" target extension for iptables
|
||||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
* Copyright © Jan Engelhardt, 2008
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License; either
|
* modify it under the terms of the GNU General Public License; either
|
||||||
@@ -61,15 +61,6 @@ static void dhcpmac_tg_check(unsigned int flags)
|
|||||||
"--set-mac parameter required");
|
"--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,
|
static void dhcpmac_tg_save(const void *ip,
|
||||||
const struct xt_entry_target *target)
|
const struct xt_entry_target *target)
|
||||||
{
|
{
|
||||||
@@ -81,6 +72,13 @@ static void dhcpmac_tg_save(const void *ip,
|
|||||||
DH_MAC_HEX(info->addr), info->mask);
|
DH_MAC_HEX(info->addr), info->mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dhcpmac_tg_print(const void *ip,
|
||||||
|
const struct xt_entry_target *target, int numeric)
|
||||||
|
{
|
||||||
|
printf(" -j DHCPMAC");
|
||||||
|
dhcpmac_tg_save(ip, target);
|
||||||
|
}
|
||||||
|
|
||||||
static struct xtables_target dhcpmac_tg_reg = {
|
static struct xtables_target dhcpmac_tg_reg = {
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.name = "DHCPMAC",
|
.name = "DHCPMAC",
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
.PP
|
||||||
In conjunction with ebtables, DHCPMAC 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
|
||||||
|
@@ -69,19 +69,8 @@ static int netmask2bits(u_int32_t netmask)
|
|||||||
return bits;
|
return bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DNETMAP_init(struct xt_entry_target *t)
|
|
||||||
{
|
|
||||||
struct xt_DNETMAP_tginfo *tginfo = (void *)&t->data;
|
|
||||||
struct nf_nat_ipv4_multi_range_compat *mr = &tginfo->prefix;
|
|
||||||
|
|
||||||
/* Actually, it's 0, but it's ignored at the moment. */
|
|
||||||
mr->rangesize = 1;
|
|
||||||
tginfo->ttl = 0;
|
|
||||||
tginfo->flags = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parses network address */
|
/* Parses network address */
|
||||||
static void parse_prefix(char *arg, struct nf_nat_ipv4_range *range)
|
static void parse_prefix(char *arg, struct nf_nat_range *range)
|
||||||
{
|
{
|
||||||
char *slash;
|
char *slash;
|
||||||
const struct in_addr *ip;
|
const struct in_addr *ip;
|
||||||
@@ -97,7 +86,7 @@ static void parse_prefix(char *arg, struct nf_nat_ipv4_range *range)
|
|||||||
if (ip == NULL)
|
if (ip == NULL)
|
||||||
xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
|
xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
|
||||||
arg);
|
arg);
|
||||||
range->min_ip = ip->s_addr;
|
range->min_addr.in = *ip;
|
||||||
if (slash) {
|
if (slash) {
|
||||||
if (strchr(slash + 1, '.')) {
|
if (strchr(slash + 1, '.')) {
|
||||||
ip = xtables_numeric_to_ipmask(slash + 1);
|
ip = xtables_numeric_to_ipmask(slash + 1);
|
||||||
@@ -123,20 +112,20 @@ static void parse_prefix(char *arg, struct nf_nat_ipv4_range *range)
|
|||||||
} else
|
} else
|
||||||
netmask = ~0;
|
netmask = ~0;
|
||||||
|
|
||||||
if (range->min_ip & ~netmask) {
|
if (range->min_addr.ip & ~netmask) {
|
||||||
if (slash)
|
if (slash)
|
||||||
*slash = '/';
|
*slash = '/';
|
||||||
xtables_error(PARAMETER_PROBLEM, "Bad network address \"%s\"\n",
|
xtables_error(PARAMETER_PROBLEM, "Bad network address \"%s\"\n",
|
||||||
arg);
|
arg);
|
||||||
}
|
}
|
||||||
range->max_ip = range->min_ip | ~netmask;
|
range->max_addr.ip = range->min_addr.ip | ~netmask;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DNETMAP_parse(int c, char **argv, int invert, unsigned int *flags,
|
static int DNETMAP_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||||
const void *entry, struct xt_entry_target **target)
|
const void *entry, struct xt_entry_target **target)
|
||||||
{
|
{
|
||||||
struct xt_DNETMAP_tginfo *tginfo = (void *)(*target)->data;
|
struct xt_DNETMAP_tginfo *tginfo = (void *)(*target)->data;
|
||||||
struct nf_nat_ipv4_multi_range_compat *mr = &tginfo->prefix;
|
struct nf_nat_range *mr = &tginfo->prefix;
|
||||||
char *end;
|
char *end;
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
@@ -147,7 +136,7 @@ static int DNETMAP_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
invert);
|
invert);
|
||||||
|
|
||||||
/* TO-DO use xtables_ipparse_any instead? */
|
/* TO-DO use xtables_ipparse_any instead? */
|
||||||
parse_prefix(optarg, &mr->range[0]);
|
parse_prefix(optarg, mr);
|
||||||
*flags |= XT_DNETMAP_PREFIX;
|
*flags |= XT_DNETMAP_PREFIX;
|
||||||
tginfo->flags |= XT_DNETMAP_PREFIX;
|
tginfo->flags |= XT_DNETMAP_PREFIX;
|
||||||
return 1;
|
return 1;
|
||||||
@@ -192,14 +181,13 @@ static void DNETMAP_print_addr(const void *ip,
|
|||||||
int numeric)
|
int numeric)
|
||||||
{
|
{
|
||||||
struct xt_DNETMAP_tginfo *tginfo = (void *)&target->data;
|
struct xt_DNETMAP_tginfo *tginfo = (void *)&target->data;
|
||||||
const struct nf_nat_ipv4_multi_range_compat *mr = &tginfo->prefix;
|
const struct nf_nat_range *r = &tginfo->prefix;
|
||||||
const struct nf_nat_ipv4_range *r = &mr->range[0];
|
|
||||||
struct in_addr a;
|
struct in_addr a;
|
||||||
int bits;
|
int bits;
|
||||||
|
|
||||||
a.s_addr = r->min_ip;
|
a = r->min_addr.in;
|
||||||
printf("%s", xtables_ipaddr_to_numeric(&a));
|
printf("%s", xtables_ipaddr_to_numeric(&a));
|
||||||
a.s_addr = ~(r->min_ip ^ r->max_ip);
|
a.s_addr = ~(r->min_addr.ip ^ r->max_addr.ip);
|
||||||
bits = netmask2bits(a.s_addr);
|
bits = netmask2bits(a.s_addr);
|
||||||
if (bits < 0)
|
if (bits < 0)
|
||||||
printf("/%s", xtables_ipaddr_to_numeric(&a));
|
printf("/%s", xtables_ipaddr_to_numeric(&a));
|
||||||
@@ -207,33 +195,6 @@ static void DNETMAP_print_addr(const void *ip,
|
|||||||
printf("/%d", bits);
|
printf("/%d", bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DNETMAP_print(const void *ip, const struct xt_entry_target *target,
|
|
||||||
int numeric)
|
|
||||||
{
|
|
||||||
struct xt_DNETMAP_tginfo *tginfo = (void *)&target->data;
|
|
||||||
const __u8 *flags = &tginfo->flags;
|
|
||||||
|
|
||||||
printf(" prefix ");
|
|
||||||
if (*flags & XT_DNETMAP_PREFIX)
|
|
||||||
DNETMAP_print_addr(ip, target, numeric);
|
|
||||||
else
|
|
||||||
printf("any");
|
|
||||||
|
|
||||||
if (*flags & XT_DNETMAP_REUSE)
|
|
||||||
printf(" reuse");
|
|
||||||
|
|
||||||
if (*flags & XT_DNETMAP_STATIC)
|
|
||||||
printf(" static");
|
|
||||||
|
|
||||||
if (*flags & XT_DNETMAP_PERSISTENT)
|
|
||||||
printf(" persistent");
|
|
||||||
|
|
||||||
if (*flags & XT_DNETMAP_TTL)
|
|
||||||
printf(" ttl %i", tginfo->ttl);
|
|
||||||
else
|
|
||||||
printf(" ttl default");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DNETMAP_save(const void *ip, const struct xt_entry_target *target)
|
static void DNETMAP_save(const void *ip, const struct xt_entry_target *target)
|
||||||
{
|
{
|
||||||
struct xt_DNETMAP_tginfo *tginfo = (void *)&target->data;
|
struct xt_DNETMAP_tginfo *tginfo = (void *)&target->data;
|
||||||
@@ -258,6 +219,13 @@ static void DNETMAP_save(const void *ip, const struct xt_entry_target *target)
|
|||||||
printf(" --ttl %i ", tginfo->ttl);
|
printf(" --ttl %i ", tginfo->ttl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void DNETMAP_print(const void *ip, const struct xt_entry_target *target,
|
||||||
|
int numeric)
|
||||||
|
{
|
||||||
|
printf(" -j DNETMAP");
|
||||||
|
DNETMAP_save(ip, target);
|
||||||
|
}
|
||||||
|
|
||||||
static struct xtables_target dnetmap_tg_reg = {
|
static struct xtables_target dnetmap_tg_reg = {
|
||||||
.name = MODULENAME,
|
.name = MODULENAME,
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
@@ -265,7 +233,6 @@ static struct xtables_target dnetmap_tg_reg = {
|
|||||||
.size = XT_ALIGN(sizeof(struct xt_DNETMAP_tginfo)),
|
.size = XT_ALIGN(sizeof(struct xt_DNETMAP_tginfo)),
|
||||||
.userspacesize = XT_ALIGN(sizeof(struct xt_DNETMAP_tginfo)),
|
.userspacesize = XT_ALIGN(sizeof(struct xt_DNETMAP_tginfo)),
|
||||||
.help = DNETMAP_help,
|
.help = DNETMAP_help,
|
||||||
.init = DNETMAP_init,
|
|
||||||
.parse = DNETMAP_parse,
|
.parse = DNETMAP_parse,
|
||||||
.print = DNETMAP_print,
|
.print = DNETMAP_print,
|
||||||
.save = DNETMAP_save,
|
.save = DNETMAP_save,
|
||||||
|
@@ -1,172 +1,179 @@
|
|||||||
The \fBDNETMAP\fR target allows dynamic two-way 1:1 mapping of IPv4 subnets.
|
.PP
|
||||||
Single rule can map private subnet to shorter public subnet creating and
|
The \fBDNETMAP\fR target allows dynamic two-way 1:1 mapping of IPv4 subnets. A
|
||||||
maintaining unambigeous private-public ip bindings. Second rule can be used to
|
single rule can map a private subnet to a shorter public subnet, creating and
|
||||||
map new flows to private subnet according to maintained bindings. Target allows
|
maintaining unambiguous private-public IP address bindings. The second rule can
|
||||||
efficient public IPv4 space usage and unambigeous NAT at the same time.
|
be used to map new flows to a private subnet according to maintained bindings.
|
||||||
|
The target allows efficient public IPv4 space usage and unambiguous NAT at the
|
||||||
Target can be used only in \fBnat\fR table in \fBPOSTROUTING\fR or \fBOUTPUT\fR
|
same time.
|
||||||
chains for SNAT and in \fBPREROUTING\fR for DNAT. Only flows directed to bound
|
.PP
|
||||||
IPs will be DNATed. Packet continues chain traversal if there is no free
|
The target can be used only in the \fBnat\fR table in \fBPOSTROUTING\fR or
|
||||||
postnat-ip to be assigned to prenat-ip. Default binding \fBttl\fR is \fI10
|
\fBOUTPUT\fR chains for SNAT, and in \fBPREROUTING\fR for DNAT. Only flows
|
||||||
minutes\fR and can be changed using \fBdefault_ttl\fR module option. Default ip
|
directed to bound addresses will be DNATed. The packet continues chain
|
||||||
hash size is 256 and can be changed using \fBhash_size\fR module option.
|
traversal if there is no free postnat address to be assigned to the prenat
|
||||||
|
address. The default binding \fBTTL\fR is \fI10 minutes\fR and can be changed
|
||||||
|
using the \fBdefault_ttl\fR module option. The default address hash size is 256
|
||||||
|
and can be changed using the \fBhash_size\fR module option.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-prefix\fR \fIaddr\fR\fB/\fR\fImask\fR
|
\fB\-\-prefix\fR \fIaddr\fR\fB/\fR\fImask\fR
|
||||||
Network subnet to map to. If not specified, all existing prefixes are used.
|
The network subnet to map to. If not specified, all existing prefixes are used.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-reuse\fR
|
\fB\-\-reuse\fR
|
||||||
Reuse entry for given prenat-ip from any prefix despite bindings ttl < 0.
|
Reuse the entry for a given prenat address from any prefix even if the
|
||||||
|
binding's TTL is < 0.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-persistent\fR
|
\fB\-\-persistent\fR
|
||||||
Set prefix persistent. It won't be removed after deleting last iptables rule.
|
Set the prefix to be persistent. It will not be removed after deleting the last
|
||||||
Option is effective only in the first rule for a given prefix. If you
|
iptables rule. The option is effective only in the first rule for a given
|
||||||
need to change persistency for existing prefix, please use proc interface
|
prefix. If you need to change persistency for an existing prefix, please use
|
||||||
described below.
|
the procfs interface described below.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-static\fR
|
\fB\-\-static\fR
|
||||||
Don't create dynamic mappings using this rule. Use static mappings only. Note
|
Do not create dynamic mappings using this rule. Use static mappings only. Note
|
||||||
that you need to create static mappings via proc interface for this rule with
|
that you need to create static mappings via the procfs interface for this rule
|
||||||
this option to have any effect.
|
for this option to have any effect.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-ttl\fR \fIseconds\fR
|
\fB\-\-ttl\fR \fIseconds\fR
|
||||||
Regenerate bindings ttl value to \fIseconds\fR. If negative value is specified,
|
Reset the binding's TTL value to \fIseconds\fR. If a negative value is
|
||||||
bindings ttl is kept unchanged. If not specified then default ttl value (600s)
|
specified, the binding's TTL is kept unchanged. If this option is not
|
||||||
is used.
|
specified, then the default TTL value (600s) is used.
|
||||||
.PP
|
.PP
|
||||||
\fB* /proc interface\fR
|
\fB* /proc interface\fR
|
||||||
|
.PP
|
||||||
Module creates following entries for each new specified subnet:
|
The module creates the following entries for each new specified subnet:
|
||||||
.TP
|
.TP
|
||||||
\fB/proc/net/xt_DNETMAP/\fR\fIsubnet\fR\fB_\fR\fImask\fR
|
\fB/proc/net/xt_DNETMAP/\fR\fIsubnet\fR\fB_\fR\fImask\fR
|
||||||
Contains binding table for subnet/mask. Each line contains \fBprenat-ip\fR,
|
Contains the binding table for the given \fIsubnet/mask\fP. Each line contains
|
||||||
\fBpostnat-ip\fR,\fBttl\fR (seconds till entry times out), \fBlasthit\fR (last
|
\fBprenat address\fR, \fBpostnat address\fR, \fBttl\fR (seconds until the entry
|
||||||
entry hit in seconds relative to system boot time). Please note that \fBttl\fR
|
times out), \fBlasthit\fR (last hit to the entry in seconds relative to system
|
||||||
and \fBlasthit\fR entries contain \fBS\fR in case of static binding.
|
boot time). Please note that the \fBttl\fR and \fBlasthit\fR entries contain an
|
||||||
|
\(oq\fBS\fR\(cq in case of a static binding.
|
||||||
.TP
|
.TP
|
||||||
\fB/proc/net/xt_DNETMAP/\fR\fIsubnet\fR\fB_\fR\fImask\fR\fB_stat\fR
|
\fB/proc/net/xt_DNETMAP/\fR\fIsubnet\fR\fB_\fR\fImask\fR\fB_stat\fR
|
||||||
Contains statistics for given subnet/mask. Line contains contains four
|
Contains statistics for a given \fIsubnet/mask\fP. The line contains four
|
||||||
numerical values separated by spaces. First one is number of currently used
|
numerical values separated by spaces. The first one is the number of currently
|
||||||
dynamic addresses (bindings with negative ttl excluded), second one is number
|
used dynamic addresses (bindings with negative TTL excluded), the second one is
|
||||||
static assignments, third one is number of all usable addresses in subnet and
|
the number of static assignments, the third one is the number of all usable
|
||||||
the fourth one is mean \fBttl\fR value for all active entries. If prefix has
|
addresses in the subnet, and the fourth one is the mean \fBTTL\fR value for all
|
||||||
persistent flag set it'll be noted as fifth entry.
|
active entries. If the prefix has the persistent flag set, it will be noted as
|
||||||
|
fifth entry.
|
||||||
.PP
|
.PP
|
||||||
Following write operations are supported via proc interface:
|
The following write operations are supported via the procfs interface:
|
||||||
.TP
|
.TP
|
||||||
echo "+\fIprenatIP\fR:\fIpostnatIP\fR" > \fB/proc/net/xt_DNETMAP/subnet_mask\fR
|
echo "+\fIprenat-address\fR:\fIpostnat-address\fR" >\fB/proc/net/xt_DNETMAP/subnet_mask\fR
|
||||||
Adds static binding between prenatIP nad postnatIP. If postnatIP is already
|
Adds a static binding between the prenat and postnap address. If
|
||||||
bound, previous binding will be timedout immediatelly. Static binding is never
|
postnat_address is already bound, any previous binding will be timed out
|
||||||
timedout.
|
immediately. A static binding is never timed out.
|
||||||
.TP
|
.TP
|
||||||
echo "-\fIIP\fR" > \fB/proc/net/xt_DNETMAP/subnet_mask\fR
|
echo "\-\fIaddress\fR" >\fB/proc/net/xt_DNETMAP/subnet_mask\fR
|
||||||
Removes binding with \fIIP\fR as prenat or postnat address. If removed binding
|
Removes the binding with \fIaddress\fR as prenat or postnat address. If the
|
||||||
is currently static, it'll make entry available for dynamic allocation.
|
removed binding is currently static, it will make the entry available for
|
||||||
|
dynamic allocation.
|
||||||
.TP
|
.TP
|
||||||
echo "+persistent" > \fB/proc/net/xt_DNETMAP/subnet_mask\fR
|
echo "+persistent" >\fB/proc/net/xt_DNETMAP/subnet_mask\fR
|
||||||
Sets persistent flag for prefix. It's usefull if you don't want bindings to get
|
Sets the persistent flag for the prefix. It is useful if you do not want
|
||||||
flushed when firewall is restarted. You can check if prefix is persistent by
|
bindings to get flushed when the firewall is restarted. You can check if the
|
||||||
printing \fB/proc/net/xt_DNETMAP/\fR\fIsubnet\fR\fB_\fR\fImask\fR\fB_stat\fR
|
prefix is persistent by printing the contents of
|
||||||
contents.
|
\fB/proc/net/xt_DNETMAP/\fR\fIsubnet\fR\fB_\fR\fImask\fR\fB_stat\fR.
|
||||||
.TP
|
.TP
|
||||||
echo "-persistent" > \fB/proc/net/xt_DNETMAP/subnet_mask\fR
|
echo "\-persistent" >\fB/proc/net/xt_DNETMAP/subnet_mask\fR
|
||||||
Unsets persistent flag for prefix. In this mode prefix will be deleted if the
|
Unsets the persistent flag for the prefix. In this mode, the prefix will be
|
||||||
last iptables rule for that prefix is removed.
|
deleted if the last iptables rule for that prefix is removed.
|
||||||
.TP
|
.TP
|
||||||
echo "flush" > \fB/proc/net/xt_DNETMAP/subnet_mask\fR
|
echo "flush" >\fB/proc/net/xt_DNETMAP/subnet_mask\fR
|
||||||
Flushes all bindings for specific prefix. All static entries are also flushed
|
Flushes all bindings for the specific prefix. All static entries are also
|
||||||
and are available for dynamic bindings.
|
flushed and become available for dynamic bindings.
|
||||||
.PP
|
.PP
|
||||||
Note! Entries are removed if the last iptables rule for a specific prefix is
|
Note! Entries are removed if the last iptables rule for a specific prefix is
|
||||||
deleted unless there's persistent flag set.
|
deleted unless the persistent flag is set.
|
||||||
.PP
|
.PP
|
||||||
|
|
||||||
\fB* Logging\fR
|
\fB* Logging\fR
|
||||||
|
.PP
|
||||||
Module logs binding add/timeout events to klog. This behaviour can be disabled
|
The module logs binding add/timeout events to klog. This behaviour can be
|
||||||
using \fBdisable_log\fR module parameter.
|
disabled using the \fBdisable_log\fR module parameter.
|
||||||
|
.PP
|
||||||
\fB* Examples\fR
|
\fB* Examples\fR
|
||||||
|
.PP
|
||||||
\fB1.\fR Map subnet 192.168.0.0/24 to subnets 20.0.0.0/26. SNAT only:
|
\fB1.\fR Map subnet 192.168.0.0/24 to subnets 20.0.0.0/26. SNAT only:
|
||||||
|
.PP
|
||||||
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j DNETMAP --prefix 20.0.0.0/26
|
iptables \-t nat \-A POSTROUTING \-s 192.168.0.0/24 \-j DNETMAP \-\-prefix 20.0.0.0/26
|
||||||
|
.PP
|
||||||
Active hosts from 192.168.0.0/24 subnet are mapped to 20.0.0.0/26. If packet
|
Active hosts from the 192.168.0.0/24 subnet are mapped to 20.0.0.0/26. If the
|
||||||
from not yet bound prenat-ip hits the rule and there are no free or timed-out
|
packet from a not yet bound prenat address hits the rule and there are no free
|
||||||
(ttl<0) entries in prefix 20.0.0.0/28, then notice is logged to klog and chain
|
or timed-out (TTL<0) entries in prefix 20.0.0.0/28, then a notice is logged to
|
||||||
traversal continues. If packet from already bound prenat-ip hits the rule,
|
klog and chain traversal continues. If packet from an already-bound prenat
|
||||||
bindings ttl value is regenerated to default_ttl and SNAT is performed.
|
address hits the rule, the binding's TTL value is reset to default_ttl and SNAT
|
||||||
|
is performed.
|
||||||
|
.PP
|
||||||
\fB2.\fR Use of \fB\-\-reuse\fR and \fB\-\-ttl\fR switches, multiple rule
|
\fB2.\fR Use of \fB\-\-reuse\fR and \fB\-\-ttl\fR switches, multiple rule
|
||||||
interaction:
|
interaction:
|
||||||
|
.PP
|
||||||
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j DNETMAP --prefix
|
iptables \-t nat \-A POSTROUTING \-s 192.168.0.0/24 \-j DNETMAP \-\-prefix
|
||||||
20.0.0.0/26 --reuse --ttl 200
|
20.0.0.0/26 \-\-reuse \-\-ttl 200
|
||||||
|
.PP
|
||||||
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j DNETMAP --prefix 30.0.0.0/26
|
iptables \-t nat \-A POSTROUTING \-s 192.168.0.0/24 \-j DNETMAP \-\-prefix 30.0.0.0/26
|
||||||
|
.PP
|
||||||
Active hosts from 192.168.0.0/24 subnet are mapped to 20.0.0.0/26 with ttl =
|
Active hosts from 192.168.0.0/24 subnet are mapped to 20.0.0.0/26 with TTL =
|
||||||
200 seconds. If there are no free addresses in first prefix the next one
|
200 seconds. If there are no free addresses in first prefix, the next one
|
||||||
(30.0.0.0/26) is used with default ttl. It's important to note that the first
|
(30.0.0.0/26) is used with the default TTL. It is important to note that the
|
||||||
rule SNATs all flows whose source IP is already actively (ttl>0) bound to ANY
|
first rule SNATs all flows whose source address is already actively bound
|
||||||
prefix. Parameter \fB\-\-reuse\fR makes this functionality work even for
|
(TTL>0) to ANY prefix. The \fB\-\-reuse\fR parameter makes this functionality
|
||||||
inactive (ttl<0) entries.
|
work even for inactive (TTL<0) entries.
|
||||||
|
.PP
|
||||||
If both subnets are exhaused, then chain traversal continues.
|
If both subnets are exhausted, then chain traversal continues.
|
||||||
|
.PP
|
||||||
\fB3.\fR Map 192.168.0.0/24 to subnets 20.0.0.0/26 bidirectional way:
|
\fB3.\fR Map 192.168.0.0/24 to subnets 20.0.0.0/26 in a bidirectional way:
|
||||||
|
.PP
|
||||||
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j DNETMAP --prefix 20.0.0.0/26
|
iptables \-t nat \-A POSTROUTING \-s 192.168.0.0/24 \-j DNETMAP \-\-prefix 20.0.0.0/26
|
||||||
|
.PP
|
||||||
iptables -t nat -A PREROUTING -j DNETMAP
|
iptables \-t nat \-A PREROUTING \-j DNETMAP
|
||||||
|
.PP
|
||||||
If host 192.168.0.10 generates some traffic, it gets bound to first free IP in
|
If the host 192.168.0.10 generates some traffic, it gets bound to first free
|
||||||
subnet - 20.0.0.0. Now any traffic directed to 20.0.0.0 gets DNATed to
|
address in the subnet \(em 20.0.0.0. Now, any traffic directed to 20.0.0.0 gets
|
||||||
192.168.0.10 as long as there's an active (ttl>0) binding. There's no need to
|
DNATed to 192.168.0.10 as long as there is an active (TTL>0) binding. There is
|
||||||
specify \fB\-\-prefix\fR parameter in PREROUTING rule, because this way it DNATs
|
no need to specify \fB\-\-prefix\fR parameter in a PREROUTING rule, because
|
||||||
traffic to all active prefixes. You could specify prefix it you'd like to make
|
this way, it DNATs traffic to all active prefixes. You could specify the prefix
|
||||||
DNAT work for specific prefix only.
|
you would like to make DNAT work for a specific prefix only.
|
||||||
|
.PP
|
||||||
\fB4.\fR Map 192.168.0.0/24 to subnets 20.0.0.0/26 with static assignments only:
|
\fB4.\fR Map 192.168.0.0/24 to subnets 20.0.0.0/26 with static assignments
|
||||||
|
only:
|
||||||
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j DNETMAP --prefix 20.0.0.0/26
|
.PP
|
||||||
--static
|
iptables \-t nat \-A POSTROUTING \-s 192.168.0.0/24 \-j DNETMAP \-\-prefix 20.0.0.0/26
|
||||||
|
\-\-static
|
||||||
echo "+192.168.0.10:20.0.0.1" > /proc/net/xt_DNETMAP/20.0.0.0_26
|
.PP
|
||||||
|
echo "+192.168.0.10:20.0.0.1" >/proc/net/xt_DNETMAP/20.0.0.0_26
|
||||||
.br
|
.br
|
||||||
echo "+192.168.0.11:20.0.0.2" > /proc/net/xt_DNETMAP/20.0.0.0_26
|
echo "+192.168.0.11:20.0.0.2" >/proc/net/xt_DNETMAP/20.0.0.0_26
|
||||||
.br
|
.br
|
||||||
echo "+192.168.0.51:20.0.0.3" > /proc/net/xt_DNETMAP/20.0.0.0_26
|
echo "+192.168.0.51:20.0.0.3" >/proc/net/xt_DNETMAP/20.0.0.0_26
|
||||||
|
.PP
|
||||||
This configuration will allow only preconfigured static bindings to work due to
|
This configuration will allow only preconfigured static bindings to work due to
|
||||||
\fBstatic\fR rule option. Without this flag dynamic bindings would be created
|
the \fBstatic\fR rule option. Without this flag, dynamic bindings would be
|
||||||
using non-static entries.
|
created using non-static entries.
|
||||||
|
.PP
|
||||||
\fB5.\fR Persistent prefix:
|
\fB5.\fR Persistent prefix:
|
||||||
|
.PP
|
||||||
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j DNETMAP --prefix 20.0.0.0/26
|
iptables \-t nat \-A POSTROUTING \-s 192.168.0.0/24 \-j DNETMAP \-\-prefix 20.0.0.0/26
|
||||||
--persistent
|
\-\-persistent
|
||||||
.br
|
.br
|
||||||
\fBor\fR
|
\fBor\fR
|
||||||
.br
|
.br
|
||||||
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j DNETMAP --prefix 20.0.0.0/26
|
iptables \-t nat \-A POSTROUTING \-s 192.168.0.0/24 \-j DNETMAP \-\-prefix 20.0.0.0/26
|
||||||
.br
|
.br
|
||||||
echo "+persistent" > /proc/net/xt_DNETMAP/20.0.0.0_26
|
echo "+persistent" >/proc/net/xt_DNETMAP/20.0.0.0_26
|
||||||
|
.PP
|
||||||
Now we can check persistent flag of the prefix:
|
Now, we can check the persistent flag of the prefix:
|
||||||
.br
|
.br
|
||||||
cat /proc/net/xt_DNETMAP/20.0.0.0_26
|
cat /proc/net/xt_DNETMAP/20.0.0.0_26
|
||||||
.br
|
.br
|
||||||
0 0 64 0 \fBpersistent\fR
|
0 0 64 0 \fBpersistent\fR
|
||||||
|
.PP
|
||||||
Flush iptables nat table and see that prefix is still in existence:
|
Flush the iptables nat table and see that prefix is still in existence:
|
||||||
.br
|
.br
|
||||||
iptables -F -t nat
|
iptables \-F \-t nat
|
||||||
.br
|
.br
|
||||||
ls -l /proc/net/xt_DNETMAP
|
ls \-l /proc/net/xt_DNETMAP
|
||||||
.br
|
.br
|
||||||
-rw-r--r-- 1 root root 0 06-10 09:01 20.0.0.0_26
|
\-rw\-r\-\-r\-\- 1 root root 0 06\-10 09:01 20.0.0.0_26
|
||||||
.br
|
.br
|
||||||
-rw-r--r-- 1 root root 0 06-10 09:01 20.0.0.0_26_stat
|
\-rw\-r\-\-r\-\- 1 root root 0 06\-10 09:01 20.0.0.0_26_stat
|
||||||
.
|
.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* "ECHO" target extension for iptables
|
* "ECHO" target extension for iptables
|
||||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
* Copyright © Jan Engelhardt, 2008
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License; either
|
* modify it under the terms of the GNU General Public License; either
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
.PP
|
||||||
The \fBECHO\fP target will send back all packets it received. It serves as an
|
The \fBECHO\fP target will send back all packets it received. It serves as an
|
||||||
examples for an Xtables target.
|
examples for an Xtables target.
|
||||||
.PP
|
.PP
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* "IPMARK" target extension for iptables
|
* "IPMARK" target extension for iptables
|
||||||
* Copyright © Grzegorz Janoszka <Grzegorz.Janoszka@pro.onet.pl>, 2003
|
* Copyright © Grzegorz Janoszka <Grzegorz.Janoszka@pro.onet.pl>, 2003
|
||||||
* Jan Engelhardt <jengelh [at] medozas de>, 2008
|
* Jan Engelhardt, 2008
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License; either
|
* modify it under the terms of the GNU General Public License; either
|
||||||
@@ -112,25 +112,6 @@ static void ipmark_tg_check(unsigned int flags)
|
|||||||
"IPMARK target: Parameter --addr is required");
|
"IPMARK target: Parameter --addr is required");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
ipmark_tg_print(const void *entry, const struct xt_entry_target *target,
|
|
||||||
int numeric)
|
|
||||||
{
|
|
||||||
const struct xt_ipmark_tginfo *info = (const void *)target->data;
|
|
||||||
|
|
||||||
if (info->selector == XT_IPMARK_SRC)
|
|
||||||
printf(" IPMARK src ip ");
|
|
||||||
else
|
|
||||||
printf(" IPMARK dst ip ");
|
|
||||||
|
|
||||||
if (info->shift != 0)
|
|
||||||
printf(" shift %u ", (unsigned int)info->shift);
|
|
||||||
if (info->andmask != ~0U)
|
|
||||||
printf(" and 0x%x ", (unsigned int)info->andmask);
|
|
||||||
if (info->ormask != 0)
|
|
||||||
printf(" or 0x%x ", (unsigned int)info->ormask);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ipmark_tg_save(const void *entry, const struct xt_entry_target *target)
|
ipmark_tg_save(const void *entry, const struct xt_entry_target *target)
|
||||||
{
|
{
|
||||||
@@ -149,6 +130,14 @@ ipmark_tg_save(const void *entry, const struct xt_entry_target *target)
|
|||||||
printf(" --or-mask 0x%x ", (unsigned int)info->ormask);
|
printf(" --or-mask 0x%x ", (unsigned int)info->ormask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ipmark_tg_print(const void *entry, const struct xt_entry_target *target,
|
||||||
|
int numeric)
|
||||||
|
{
|
||||||
|
printf(" -j IPMARK");
|
||||||
|
ipmark_tg_save(entry, target);
|
||||||
|
}
|
||||||
|
|
||||||
static struct xtables_target ipmark_tg_reg = {
|
static struct xtables_target ipmark_tg_reg = {
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.name = "IPMARK",
|
.name = "IPMARK",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
|
.PP
|
||||||
Allows you to mark a received packet basing on its IP address. This
|
Allows you to mark a received packet basing on its IP address. This
|
||||||
can replace many mangle/mark entries with only one, if you use
|
can replace many mangle/mark entries with only one, if you use
|
||||||
firewall based classifier.
|
firewall based classifier.
|
||||||
|
.PP
|
||||||
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}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* "LOGMARK" target extension for iptables
|
* "LOGMARK" target extension for iptables
|
||||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
* Copyright © Jan Engelhardt, 2008
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License; either
|
* modify it under the terms of the GNU General Public License; either
|
||||||
@@ -77,15 +77,6 @@ logmark_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
logmark_tg_print(const void *ip, const struct xt_entry_target *target,
|
|
||||||
int numeric)
|
|
||||||
{
|
|
||||||
const struct xt_logmark_tginfo *info = (void *)target->data;
|
|
||||||
|
|
||||||
printf(" LOGMARK level %u prefix \"%s\" ", info->level, info->prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
logmark_tg_save(const void *ip, const struct xt_entry_target *target)
|
logmark_tg_save(const void *ip, const struct xt_entry_target *target)
|
||||||
{
|
{
|
||||||
@@ -97,6 +88,14 @@ logmark_tg_save(const void *ip, const struct xt_entry_target *target)
|
|||||||
printf(" --log-prefix \"%s\" ", info->prefix);
|
printf(" --log-prefix \"%s\" ", info->prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
logmark_tg_print(const void *ip, const struct xt_entry_target *target,
|
||||||
|
int numeric)
|
||||||
|
{
|
||||||
|
printf(" -j LOGMARK");
|
||||||
|
logmark_tg_save(ip, target);
|
||||||
|
}
|
||||||
|
|
||||||
static struct xtables_target logmark_tg_reg = {
|
static struct xtables_target logmark_tg_reg = {
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.name = "LOGMARK",
|
.name = "LOGMARK",
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
.PP
|
||||||
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
|
||||||
|
105
extensions/libxt_PROTO.c
Normal file
105
extensions/libxt_PROTO.c
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* PROTO Target module
|
||||||
|
* This program is distributed under the terms of GNU GPL
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <xtables.h>
|
||||||
|
#include "xt_PROTO.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
O_PROTO_SET = 0,
|
||||||
|
O_PROTO_STOP_AT_FRAG = 1,
|
||||||
|
O_PROTO_STOP_AT_AUTH = 2,
|
||||||
|
F_PROTO_SET = 1 << O_PROTO_SET,
|
||||||
|
F_PROTO_STOP_AT_FRAG = 1 << O_PROTO_STOP_AT_FRAG,
|
||||||
|
F_PROTO_STOP_AT_AUTH = 1 << O_PROTO_STOP_AT_AUTH,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define s struct xt_PROTO_info
|
||||||
|
static const struct xt_option_entry PROTO_opts[] = {
|
||||||
|
{.name = "proto-set", .type = XTTYPE_UINT8, .id = O_PROTO_SET,
|
||||||
|
.flags = XTOPT_PUT | XTOPT_MAND, XTOPT_POINTER(s, proto)},
|
||||||
|
{.name = "stop-at-frag", .type = XTTYPE_NONE, .id = O_PROTO_STOP_AT_FRAG},
|
||||||
|
{.name = "stop-at-auth", .type = XTTYPE_NONE, .id = O_PROTO_STOP_AT_AUTH},
|
||||||
|
XTOPT_TABLEEND,
|
||||||
|
};
|
||||||
|
#undef s
|
||||||
|
|
||||||
|
static void PROTO_help(void)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"PROTO target options\n"
|
||||||
|
" --proto-set value Set protocol to <value 0-255>\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PROTO_parse(struct xt_option_call *cb)
|
||||||
|
{
|
||||||
|
struct xt_PROTO_info *info = cb->data;
|
||||||
|
|
||||||
|
xtables_option_parse(cb);
|
||||||
|
switch (cb->entry->id) {
|
||||||
|
case O_PROTO_SET:
|
||||||
|
info->mode |= 1 << XT_PROTO_SET;
|
||||||
|
break;
|
||||||
|
case O_PROTO_STOP_AT_FRAG:
|
||||||
|
info->mode |= 1 << XT_PROTO_STOP_AT_FRAG;
|
||||||
|
break;
|
||||||
|
case O_PROTO_STOP_AT_AUTH:
|
||||||
|
info->mode |= 1 << XT_PROTO_STOP_AT_AUTH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PROTO_check(struct xt_fcheck_call *cb)
|
||||||
|
{
|
||||||
|
if (!(cb->xflags & F_PROTO_SET))
|
||||||
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
|
"PROTO: You must specify the proto to be set");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PROTO_save(const void *ip, const struct xt_entry_target *target)
|
||||||
|
{
|
||||||
|
const struct xt_PROTO_info *info = (void *)target->data;
|
||||||
|
|
||||||
|
if (info->mode & (1 << XT_PROTO_SET))
|
||||||
|
printf(" --proto-set %u", info->proto);
|
||||||
|
if (info->mode & (1 << XT_PROTO_STOP_AT_FRAG))
|
||||||
|
printf(" --stop-at-frag");
|
||||||
|
if (info->mode & (1 << XT_PROTO_STOP_AT_AUTH))
|
||||||
|
printf(" --stop-at-auth");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PROTO_print(const void *ip, const struct xt_entry_target *target,
|
||||||
|
int numeric)
|
||||||
|
{
|
||||||
|
const struct xt_PROTO_info *info = (void *)target->data;
|
||||||
|
|
||||||
|
printf(" PROTO ");
|
||||||
|
if (info->mode & (1 << XT_PROTO_SET))
|
||||||
|
printf("set to %u", info->proto);
|
||||||
|
if (info->mode & (1 << XT_PROTO_STOP_AT_FRAG))
|
||||||
|
printf(" stop-at-frag");
|
||||||
|
if (info->mode & (1 << XT_PROTO_STOP_AT_AUTH))
|
||||||
|
printf(" stop-at-auth");
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct xtables_target proto_tg_reg = {
|
||||||
|
.name = "PROTO",
|
||||||
|
.version = XTABLES_VERSION,
|
||||||
|
.family = NFPROTO_UNSPEC,
|
||||||
|
.size = XT_ALIGN(sizeof(struct xt_PROTO_info)),
|
||||||
|
.userspacesize = XT_ALIGN(sizeof(struct xt_PROTO_info)),
|
||||||
|
.help = PROTO_help,
|
||||||
|
.print = PROTO_print,
|
||||||
|
.save = PROTO_save,
|
||||||
|
.x6_parse = PROTO_parse,
|
||||||
|
.x6_fcheck = PROTO_check,
|
||||||
|
.x6_options = PROTO_opts,
|
||||||
|
};
|
||||||
|
|
||||||
|
static __attribute__((constructor)) void _init(void)
|
||||||
|
{
|
||||||
|
xtables_register_target(&proto_tg_reg);
|
||||||
|
|
||||||
|
}
|
30
extensions/libxt_PROTO.man
Normal file
30
extensions/libxt_PROTO.man
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
.PP
|
||||||
|
The PROTO target modifies the protocol number in IP packet header.
|
||||||
|
.TP
|
||||||
|
\fB\-\-proto-set\fP \fIproto_num\fP
|
||||||
|
This option is mandatory. \fIproto_num\fP is the protocol number to which you want to
|
||||||
|
modify the packets.
|
||||||
|
.TP
|
||||||
|
\fB\-\-stop-at-frag\fP
|
||||||
|
This option is only valid for IPv6 rules. When specifying this option, the
|
||||||
|
fragment extension header will be seen as a non-extension header.
|
||||||
|
.TP
|
||||||
|
\fB\-\-stop-at-auth\fP
|
||||||
|
This option is only valid for IPv6 rules. When specifying this option, the
|
||||||
|
authentication extension header will be seen as a non-extension header.
|
||||||
|
.PP
|
||||||
|
For IPv4 packets, the \fBProtocol\fP field is modified and the checksum is
|
||||||
|
re-calculated.
|
||||||
|
.PP
|
||||||
|
For IPv6 packets, the scenario can be more complex due to the introduction of
|
||||||
|
the extension headers mechanism. By default, the PROTO target will scan the IPv6
|
||||||
|
packet, finding the last extension header and modify its \fBNext-header\fP field.
|
||||||
|
Normally, the following headers will be seen as an extension header:
|
||||||
|
\fINEXTHDR_HOP\fP,
|
||||||
|
\fINEXTHDR_ROUTING\fP,
|
||||||
|
\fINEXTHDR_FRAGMENT\fP,
|
||||||
|
\fINEXTHDR_AUTH\fP,
|
||||||
|
\fINEXTHDR_DEST\fP.
|
||||||
|
.PP
|
||||||
|
For fragmented packets, only the first fragment is processed and other fragments
|
||||||
|
are not touched.
|
@@ -1,189 +0,0 @@
|
|||||||
/*
|
|
||||||
* "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"
|
|
||||||
#include "compat_user.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, 128))
|
|
||||||
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_tg_reg[] = {
|
|
||||||
{
|
|
||||||
.version = XTABLES_VERSION,
|
|
||||||
.name = "RAWDNAT",
|
|
||||||
.revision = 0,
|
|
||||||
.family = NFPROTO_IPV4,
|
|
||||||
.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,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.version = XTABLES_VERSION,
|
|
||||||
.name = "RAWDNAT",
|
|
||||||
.revision = 0,
|
|
||||||
.family = NFPROTO_IPV6,
|
|
||||||
.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_targets(rawdnat_tg_reg,
|
|
||||||
sizeof(rawdnat_tg_reg) / sizeof(*rawdnat_tg_reg));
|
|
||||||
}
|
|
@@ -1,10 +0,0 @@
|
|||||||
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.
|
|
@@ -1,189 +0,0 @@
|
|||||||
/*
|
|
||||||
* "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"
|
|
||||||
#include "compat_user.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, 128))
|
|
||||||
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_tg_reg[] = {
|
|
||||||
{
|
|
||||||
.version = XTABLES_VERSION,
|
|
||||||
.name = "RAWSNAT",
|
|
||||||
.revision = 0,
|
|
||||||
.family = NFPROTO_IPV4,
|
|
||||||
.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,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.version = XTABLES_VERSION,
|
|
||||||
.name = "RAWSNAT",
|
|
||||||
.revision = 0,
|
|
||||||
.family = NFPROTO_IPV6,
|
|
||||||
.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_targets(rawsnat_tg_reg,
|
|
||||||
sizeof(rawsnat_tg_reg) / sizeof(*rawsnat_tg_reg));
|
|
||||||
}
|
|
@@ -1,38 +0,0 @@
|
|||||||
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.
|
|
@@ -1,32 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <xtables.h>
|
|
||||||
#include "compat_user.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 = NFPROTO_UNSPEC,
|
|
||||||
.help = steal_tg_help,
|
|
||||||
.parse = steal_tg_parse,
|
|
||||||
.final_check = steal_tg_check,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void _init(void)
|
|
||||||
{
|
|
||||||
xtables_register_target(&steal_tg_reg);
|
|
||||||
}
|
|
@@ -1,2 +0,0 @@
|
|||||||
Like the DROP target, but does not throw an error like DROP when used in the
|
|
||||||
\fBOUTPUT\fP chain.
|
|
@@ -1,3 +1,4 @@
|
|||||||
|
.PP
|
||||||
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
|
||||||
@@ -62,7 +63,7 @@ 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)"
|
||||||
ipaddr=10.10.25.7
|
ipaddr="2001:0db8:0000:0000:0000:ff00:0042:8329"
|
||||||
req="$sysrq_key,$seqno,$salt"
|
req="$sysrq_key,$seqno,$salt"
|
||||||
req="$req,$(echo \-n "$req,$ipaddr,$password" | sha1sum | cut \-c1\-40)"
|
req="$req,$(echo \-n "$req,$ipaddr,$password" | sha1sum | cut \-c1\-40)"
|
||||||
|
|
||||||
@@ -75,8 +76,8 @@ sysrq key can be used at once, but bear in mind that, for example, a sync may
|
|||||||
not complete before a subsequent reboot or poweroff.
|
not complete before a subsequent reboot or poweroff.
|
||||||
.PP
|
.PP
|
||||||
An IPv4 address should have no leading zeros, an IPv6 address should
|
An IPv4 address should have no leading zeros, an IPv6 address should
|
||||||
be in the form recommended by RFC 5952. The debug option will log the
|
be in the full expanded form (as shown above). The debug option will cause
|
||||||
correct form of the address.
|
output to be emitted in the same form.
|
||||||
.PP
|
.PP
|
||||||
The hashing scheme should be enough to prevent mis-use of SYSRQ in many
|
The hashing scheme should be enough to prevent mis-use of SYSRQ in many
|
||||||
environments, but it is not perfect: take reasonable precautions to
|
environments, but it is not perfect: take reasonable precautions to
|
||||||
|
@@ -67,24 +67,6 @@ static void tarpit_tg_check(unsigned int flags)
|
|||||||
"TARPIT: only one action can be used at a time");
|
"TARPIT: only one action can be used at a time");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tarpit_tg_print(const void *ip,
|
|
||||||
const struct xt_entry_target *target, int numeric)
|
|
||||||
{
|
|
||||||
const struct xt_tarpit_tginfo *info = (void *)target->data;
|
|
||||||
|
|
||||||
switch (info->variant) {
|
|
||||||
case XTTARPIT_HONEYPOT:
|
|
||||||
printf(" honeypot mode ");
|
|
||||||
break;
|
|
||||||
case XTTARPIT_RESET:
|
|
||||||
printf(" reset mode ");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf(" tarpit mode ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tarpit_tg_save(const void *ip,
|
static void tarpit_tg_save(const void *ip,
|
||||||
const struct xt_entry_target *target)
|
const struct xt_entry_target *target)
|
||||||
{
|
{
|
||||||
@@ -103,6 +85,13 @@ static void tarpit_tg_save(const void *ip,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tarpit_tg_print(const void *ip,
|
||||||
|
const struct xt_entry_target *target, int numeric)
|
||||||
|
{
|
||||||
|
printf(" -j TARPIT");
|
||||||
|
tarpit_tg_save(ip, target);
|
||||||
|
}
|
||||||
|
|
||||||
static struct xtables_target tarpit_tg_reg = {
|
static struct xtables_target tarpit_tg_reg = {
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.name = "TARPIT",
|
.name = "TARPIT",
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
.PP
|
||||||
Captures and holds incoming TCP connections using no local per-connection
|
Captures and holds incoming TCP connections using no local per-connection
|
||||||
resources.
|
resources.
|
||||||
.PP
|
.PP
|
||||||
|
@@ -1,173 +0,0 @@
|
|||||||
/*
|
|
||||||
* "TEE" target extension for iptables
|
|
||||||
* Copyright © Sebastian Claßen <sebastian.classen [at] freenet.ag>, 2007
|
|
||||||
* Jan Engelhardt <jengelh [at] medozas de>, 2007 - 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 <sys/socket.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
|
|
||||||
#include <xtables.h>
|
|
||||||
#include <linux/netfilter.h>
|
|
||||||
#include <linux/netfilter/x_tables.h>
|
|
||||||
#include "xt_TEE.h"
|
|
||||||
#include "compat_user.h"
|
|
||||||
|
|
||||||
enum {
|
|
||||||
FLAG_GATEWAY = 1 << 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct option tee_tg_opts[] = {
|
|
||||||
{.name = "gateway", .has_arg = true, .val = 'g'},
|
|
||||||
{NULL},
|
|
||||||
};
|
|
||||||
|
|
||||||
static void tee_tg_help(void)
|
|
||||||
{
|
|
||||||
printf(
|
|
||||||
"TEE target options:\n"
|
|
||||||
" --gateway IPADDR Route packet via the gateway given by address\n"
|
|
||||||
"\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tee_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
|
||||||
const void *entry, struct xt_entry_target **target)
|
|
||||||
{
|
|
||||||
struct xt_tee_tginfo *info = (void *)(*target)->data;
|
|
||||||
const struct in_addr *ia;
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case 'g':
|
|
||||||
if (*flags & FLAG_GATEWAY)
|
|
||||||
xtables_error(PARAMETER_PROBLEM,
|
|
||||||
"Cannot specify --gateway more than once");
|
|
||||||
|
|
||||||
ia = xtables_numeric_to_ipaddr(optarg);
|
|
||||||
if (ia == NULL)
|
|
||||||
xtables_error(PARAMETER_PROBLEM,
|
|
||||||
"Invalid IP address %s", optarg);
|
|
||||||
|
|
||||||
memcpy(&info->gw, ia, sizeof(*ia));
|
|
||||||
*flags |= FLAG_GATEWAY;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tee_tg6_parse(int c, char **argv, int invert, unsigned int *flags,
|
|
||||||
const void *entry, struct xt_entry_target **target)
|
|
||||||
{
|
|
||||||
struct xt_tee_tginfo *info = (void *)(*target)->data;
|
|
||||||
const struct in6_addr *ia;
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case 'g':
|
|
||||||
if (*flags & FLAG_GATEWAY)
|
|
||||||
xtables_error(PARAMETER_PROBLEM,
|
|
||||||
"Cannot specify --gateway more than once");
|
|
||||||
|
|
||||||
ia = xtables_numeric_to_ip6addr(optarg);
|
|
||||||
if (ia == NULL)
|
|
||||||
xtables_error(PARAMETER_PROBLEM,
|
|
||||||
"Invalid IP address %s", optarg);
|
|
||||||
|
|
||||||
memcpy(&info->gw, ia, sizeof(*ia));
|
|
||||||
*flags |= FLAG_GATEWAY;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tee_tg_check(unsigned int flags)
|
|
||||||
{
|
|
||||||
if (flags == 0)
|
|
||||||
xtables_error(PARAMETER_PROBLEM, "TEE target: "
|
|
||||||
"--gateway parameter required");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tee_tg_print(const void *ip, const struct xt_entry_target *target,
|
|
||||||
int numeric)
|
|
||||||
{
|
|
||||||
const struct xt_tee_tginfo *info = (const void *)target->data;
|
|
||||||
|
|
||||||
if (numeric)
|
|
||||||
printf(" TEE gw:%s ", xtables_ipaddr_to_numeric(&info->gw.in));
|
|
||||||
else
|
|
||||||
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,
|
|
||||||
int numeric)
|
|
||||||
{
|
|
||||||
const struct xt_tee_tginfo *info = (const void *)target->data;
|
|
||||||
|
|
||||||
if (numeric)
|
|
||||||
printf(" TEE gw:%s ", xtables_ip6addr_to_numeric(&info->gw.in6));
|
|
||||||
else
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
const struct xt_tee_tginfo *info = (const void *)target->data;
|
|
||||||
|
|
||||||
printf(" --gateway %s ", xtables_ipaddr_to_numeric(&info->gw.in));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tee_tg6_save(const void *ip, const struct xt_entry_target *target)
|
|
||||||
{
|
|
||||||
const struct xt_tee_tginfo *info = (const void *)target->data;
|
|
||||||
|
|
||||||
printf(" --gateway %s ", xtables_ip6addr_to_numeric(&info->gw.in6));
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct xtables_target tee_tg_reg[] = {
|
|
||||||
{
|
|
||||||
.name = "TEE",
|
|
||||||
.version = XTABLES_VERSION,
|
|
||||||
.revision = 0,
|
|
||||||
.family = NFPROTO_IPV4,
|
|
||||||
.size = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
|
|
||||||
.userspacesize = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
|
|
||||||
.help = tee_tg_help,
|
|
||||||
.parse = tee_tg_parse,
|
|
||||||
.final_check = tee_tg_check,
|
|
||||||
.print = tee_tg_print,
|
|
||||||
.save = tee_tg_save,
|
|
||||||
.extra_opts = tee_tg_opts,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "TEE",
|
|
||||||
.version = XTABLES_VERSION,
|
|
||||||
.revision = 0,
|
|
||||||
.family = NFPROTO_IPV6,
|
|
||||||
.size = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
|
|
||||||
.userspacesize = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
|
|
||||||
.help = tee_tg_help,
|
|
||||||
.parse = tee_tg6_parse,
|
|
||||||
.final_check = tee_tg_check,
|
|
||||||
.print = tee_tg6_print,
|
|
||||||
.save = tee_tg6_save,
|
|
||||||
.extra_opts = tee_tg_opts,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static __attribute__((constructor)) void tee_tg_ldr(void)
|
|
||||||
{
|
|
||||||
xtables_register_targets(tee_tg_reg,
|
|
||||||
sizeof(tee_tg_reg) / sizeof(*tee_tg_reg));
|
|
||||||
}
|
|
@@ -1,12 +0,0 @@
|
|||||||
The \fBTEE\fP target will clone a packet and redirect this clone to another
|
|
||||||
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
|
|
||||||
further if so desired.
|
|
||||||
.TP
|
|
||||||
\fB\-\-gateway\fP \fIipaddr\fP
|
|
||||||
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.
|
|
||||||
.PP
|
|
||||||
To forward all incoming traffic on eth0 to an Network Layer logging box:
|
|
||||||
.PP
|
|
||||||
\-t mangle \-A PREROUTING \-i eth0 \-j TEE \-\-gateway 2001:db8::1
|
|
@@ -2,7 +2,7 @@
|
|||||||
* "condition" match extension for iptables
|
* "condition" match extension for iptables
|
||||||
* Stephane Ouellette <ouellettes [at] videotron ca>, 2002-10-22
|
* Stephane Ouellette <ouellettes [at] videotron ca>, 2002-10-22
|
||||||
* Massimiliano Hofer <max [at] nucleus it>, 2006-05-15
|
* Massimiliano Hofer <max [at] nucleus it>, 2006-05-15
|
||||||
* Jan Engelhardt <jengelh [at] medozas de>, 2008
|
* Jan Engelhardt, 2008
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* 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
|
* under the terms of the GNU General Public License; either version 2
|
||||||
@@ -62,15 +62,6 @@ static void condition_check(unsigned int flags)
|
|||||||
"Condition match: must specify --condition");
|
"Condition match: must specify --condition");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void condition_print(const void *ip, const struct xt_entry_match *match,
|
|
||||||
int numeric)
|
|
||||||
{
|
|
||||||
const struct xt_condition_mtinfo *info = (const void *)match->data;
|
|
||||||
|
|
||||||
printf(" condition %s%s ", (info->invert) ? "!" : "", info->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void condition_save(const void *ip, const struct xt_entry_match *match)
|
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;
|
||||||
@@ -78,6 +69,13 @@ static void condition_save(const void *ip, const struct xt_entry_match *match)
|
|||||||
printf("%s --condition \"%s\" ", info->invert ? " !" : "", info->name);
|
printf("%s --condition \"%s\" ", info->invert ? " !" : "", info->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void condition_print(const void *ip, const struct xt_entry_match *match,
|
||||||
|
int numeric)
|
||||||
|
{
|
||||||
|
printf(" -m condition");
|
||||||
|
condition_save(ip, match);
|
||||||
|
}
|
||||||
|
|
||||||
static struct xtables_match condition_mt_reg = {
|
static struct xtables_match condition_mt_reg = {
|
||||||
.name = "condition",
|
.name = "condition",
|
||||||
.revision = 1,
|
.revision = 1,
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
.PP
|
||||||
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
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* "dhcpmac" match extension for iptables
|
* "dhcpmac" match extension for iptables
|
||||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
* Copyright © Jan Engelhardt, 2008
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License; either
|
* modify it under the terms of the GNU General Public License; either
|
||||||
@@ -62,15 +62,6 @@ static void dhcpmac_mt_check(unsigned int flags)
|
|||||||
"--mac parameter required");
|
"--mac parameter required");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dhcpmac_mt_print(const void *ip,
|
|
||||||
const struct xt_entry_match *match, int numeric)
|
|
||||||
{
|
|
||||||
const struct dhcpmac_info *info = (void *)match->data;
|
|
||||||
|
|
||||||
printf(" dhcpmac %s" DH_MAC_FMT "/%u ",
|
|
||||||
info->invert ? "!" : "", DH_MAC_HEX(info->addr), info->mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dhcpmac_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)
|
||||||
{
|
{
|
||||||
@@ -82,6 +73,13 @@ static void dhcpmac_mt_save(const void *ip,
|
|||||||
DH_MAC_HEX(info->addr), info->mask);
|
DH_MAC_HEX(info->addr), info->mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dhcpmac_mt_print(const void *ip,
|
||||||
|
const struct xt_entry_match *match, int numeric)
|
||||||
|
{
|
||||||
|
printf(" -m dhcpmac");
|
||||||
|
dhcpmac_mt_save(ip, match);
|
||||||
|
}
|
||||||
|
|
||||||
static struct xtables_match dhcpmac_mt_reg = {
|
static struct xtables_match dhcpmac_mt_reg = {
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.name = "dhcpmac",
|
.name = "dhcpmac",
|
||||||
|
@@ -83,15 +83,6 @@ static void fuzzy_mt_check(unsigned int flags)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fuzzy_mt_print(const void *ip, const struct xt_entry_match *match,
|
|
||||||
int numeric)
|
|
||||||
{
|
|
||||||
const struct xt_fuzzy_mtinfo *info = (const void *)match->data;
|
|
||||||
|
|
||||||
printf(" fuzzy: lower limit = %u pps - upper limit = %u pps ",
|
|
||||||
info->minimum_rate, info->maximum_rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fuzzy_mt_save(const void *ip, const struct xt_entry_match *match)
|
static void fuzzy_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||||
{
|
{
|
||||||
const struct xt_fuzzy_mtinfo *info = (const void *)match->data;
|
const struct xt_fuzzy_mtinfo *info = (const void *)match->data;
|
||||||
@@ -100,6 +91,13 @@ static void fuzzy_mt_save(const void *ip, const struct xt_entry_match *match)
|
|||||||
printf(" --upper-limit %u ", info->maximum_rate);
|
printf(" --upper-limit %u ", info->maximum_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fuzzy_mt_print(const void *ip, const struct xt_entry_match *match,
|
||||||
|
int numeric)
|
||||||
|
{
|
||||||
|
printf(" -m fuzzy");
|
||||||
|
fuzzy_mt_save(ip, match);
|
||||||
|
}
|
||||||
|
|
||||||
static struct xtables_match fuzzy_mt_reg = {
|
static struct xtables_match fuzzy_mt_reg = {
|
||||||
.name = "fuzzy",
|
.name = "fuzzy",
|
||||||
.revision = 1,
|
.revision = 1,
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
.PP
|
||||||
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
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* "geoip" match extension for iptables
|
* "geoip" match extension for iptables
|
||||||
* Copyright © Samuel Jean <peejix [at] people netfilter org>, 2004 - 2008
|
* Copyright © Samuel Jean <peejix [at] people netfilter org>, 2004 - 2008
|
||||||
* Copyright © Nicolas Bouliane <acidfu [at] people netfilter org>, 2004 - 2008
|
* Copyright © Nicolas Bouliane <acidfu [at] people netfilter org>, 2004 - 2008
|
||||||
* Jan Engelhardt <jengelh [at] medozas de>, 2008-2011
|
* Jan Engelhardt, 2008-2011
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License; either
|
* modify it under the terms of the GNU General Public License; either
|
||||||
@@ -49,30 +49,44 @@ static struct option geoip_opts[] = {
|
|||||||
{NULL},
|
{NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
|
static void geoip_swap_le32(uint32_t *buf)
|
||||||
|
{
|
||||||
|
unsigned char *p = (void *)buf;
|
||||||
|
uint32_t n = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
|
||||||
|
p[0] = (n >> 24) & 0xff;
|
||||||
|
p[1] = (n >> 16) & 0xff;
|
||||||
|
p[2] = (n >> 8) & 0xff;
|
||||||
|
p[3] = n & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void geoip_swap_in6(struct in6_addr *in6)
|
||||||
|
{
|
||||||
|
geoip_swap_le32(&in6->s6_addr32[0]);
|
||||||
|
geoip_swap_le32(&in6->s6_addr32[1]);
|
||||||
|
geoip_swap_le32(&in6->s6_addr32[2]);
|
||||||
|
geoip_swap_le32(&in6->s6_addr32[3]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
geoip_get_subnets(const char *code, uint32_t *count, uint8_t nfproto)
|
geoip_get_subnets(const char *code, uint32_t *count, uint8_t nfproto)
|
||||||
{
|
{
|
||||||
void *subnets;
|
void *subnets;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
int fd;
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
|
unsigned int n;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Use simple integer vector files */
|
/* Use simple integer vector files */
|
||||||
if (nfproto == NFPROTO_IPV6) {
|
if (nfproto == NFPROTO_IPV6)
|
||||||
#if __BYTE_ORDER == _BIG_ENDIAN
|
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/%s.iv6", code);
|
||||||
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/BE/%s.iv6", code);
|
else
|
||||||
#else
|
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/%s.iv4", code);
|
||||||
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/LE/%s.iv6", code);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
#if __BYTE_ORDER == _BIG_ENDIAN
|
|
||||||
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/BE/%s.iv4", code);
|
|
||||||
#else
|
|
||||||
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/LE/%s.iv4", code);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((fd = open(buf, O_RDONLY)) < 0) {
|
int fd = open(buf, O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
fprintf(stderr, "Could not open %s: %s\n", buf, strerror(errno));
|
fprintf(stderr, "Could not open %s: %s\n", buf, strerror(errno));
|
||||||
xtables_error(OTHER_PROBLEM, "Could not read geoip database");
|
xtables_error(OTHER_PROBLEM, "Could not read geoip database");
|
||||||
}
|
}
|
||||||
@@ -98,6 +112,25 @@ geoip_get_subnets(const char *code, uint32_t *count, uint8_t nfproto)
|
|||||||
xtables_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);
|
||||||
|
|
||||||
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
|
for (n = 0; n < *count; ++n) {
|
||||||
|
switch (nfproto) {
|
||||||
|
case NFPROTO_IPV6: {
|
||||||
|
struct geoip_subnet6 *gs6 = &(((struct geoip_subnet6 *)subnets)[n]);
|
||||||
|
geoip_swap_in6(&gs6->begin);
|
||||||
|
geoip_swap_in6(&gs6->end);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NFPROTO_IPV4: {
|
||||||
|
struct geoip_subnet4 *gs4 = &(((struct geoip_subnet4 *)subnets)[n]);
|
||||||
|
geoip_swap_le32(&gs4->begin);
|
||||||
|
geoip_swap_le32(&gs4->end);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return subnets;
|
return subnets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +168,7 @@ check_geoip_cc(char *cc, u_int16_t cc_used[], u_int8_t count)
|
|||||||
cc[i] = toupper(cc[i]);
|
cc[i] = toupper(cc[i]);
|
||||||
else
|
else
|
||||||
xtables_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.
|
||||||
* FIXME: This assumes that a country code is
|
* FIXME: This assumes that a country code is
|
||||||
@@ -170,7 +203,8 @@ static unsigned int parse_geoip_cc(const char *ccstr, uint16_t *cc,
|
|||||||
next = strchr(cp, ',');
|
next = strchr(cp, ',');
|
||||||
if (next) *next++ = '\0';
|
if (next) *next++ = '\0';
|
||||||
|
|
||||||
if ((cctmp = check_geoip_cc(cp, cc, count)) != 0) {
|
cctmp = check_geoip_cc(cp, cc, count);
|
||||||
|
if (cctmp != 0) {
|
||||||
if ((mem[count++].user =
|
if ((mem[count++].user =
|
||||||
(unsigned long)geoip_load_cc(cp, cctmp, nfproto)) == 0)
|
(unsigned long)geoip_load_cc(cp, cctmp, nfproto)) == 0)
|
||||||
xtables_error(OTHER_PROBLEM,
|
xtables_error(OTHER_PROBLEM,
|
||||||
@@ -251,31 +285,6 @@ geoip_final_check(unsigned int flags)
|
|||||||
"geoip: missing arguments");
|
"geoip: missing arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
geoip_print(const void *ip, const struct xt_entry_match *match, int numeric)
|
|
||||||
{
|
|
||||||
const struct xt_geoip_match_info *info = (void*)match->data;
|
|
||||||
|
|
||||||
u_int8_t i;
|
|
||||||
|
|
||||||
if (info->flags & XT_GEOIP_SRC)
|
|
||||||
printf(" Source ");
|
|
||||||
else
|
|
||||||
printf(" Destination ");
|
|
||||||
|
|
||||||
if (info->count > 1)
|
|
||||||
printf("countries: ");
|
|
||||||
else
|
|
||||||
printf("country: ");
|
|
||||||
|
|
||||||
if (info->flags & XT_GEOIP_INV)
|
|
||||||
printf("! ");
|
|
||||||
|
|
||||||
for (i = 0; i < info->count; i++)
|
|
||||||
printf("%s%c%c", i ? "," : "", COUNTRY(info->cc[i]));
|
|
||||||
printf(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
geoip_save(const void *ip, const struct xt_entry_match *match)
|
geoip_save(const void *ip, const struct xt_entry_match *match)
|
||||||
{
|
{
|
||||||
@@ -295,6 +304,13 @@ geoip_save(const void *ip, const struct xt_entry_match *match)
|
|||||||
printf(" ");
|
printf(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
geoip_print(const void *ip, const struct xt_entry_match *match, int numeric)
|
||||||
|
{
|
||||||
|
printf(" -m geoip");
|
||||||
|
geoip_save(ip, match);
|
||||||
|
}
|
||||||
|
|
||||||
static struct xtables_match geoip_match[] = {
|
static struct xtables_match geoip_match[] = {
|
||||||
{
|
{
|
||||||
.family = NFPROTO_IPV6,
|
.family = NFPROTO_IPV6,
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
.PP
|
||||||
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]
|
||||||
@@ -15,8 +16,8 @@ with the source package, and which should be available in compiled packages in
|
|||||||
/usr/lib(exec)/xtables-addons/. The first command retrieves CSV files from
|
/usr/lib(exec)/xtables-addons/. The first command retrieves CSV files from
|
||||||
MaxMind, while the other two build packed bisectable range files:
|
MaxMind, while the other two build packed bisectable range files:
|
||||||
.PP
|
.PP
|
||||||
mkdir -p /usr/share/xt_geoip; cd /tmp; $path/to/xt_geoip_dl;
|
mkdir \-p /usr/share/xt_geoip; cd /tmp; $path/to/xt_geoip_dl;
|
||||||
.PP
|
.PP
|
||||||
$path/to/xt_geoip_build -D /usr/share/xt_geoip GeoIP*.csv;
|
$path/to/xt_geoip_build \-D /usr/share/xt_geoip GeoIP*.csv;
|
||||||
.PP
|
.PP
|
||||||
The shared library is hardcoded to look in these paths, so use them.
|
The shared library is hardcoded to look in these paths, so use them.
|
||||||
|
@@ -57,17 +57,6 @@ static void gradm_mt_check(unsigned int flags)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gradm_mt_print(const void *ip, const struct xt_entry_match *match,
|
|
||||||
int numeric)
|
|
||||||
{
|
|
||||||
const struct xt_gradm_mtinfo *info = (const void *)match->data;
|
|
||||||
|
|
||||||
if (info->invflags)
|
|
||||||
printf("gradm: disabled");
|
|
||||||
else
|
|
||||||
printf("gradm: enabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gradm_mt_save(const void *ip, const struct xt_entry_match *match)
|
static void gradm_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||||
{
|
{
|
||||||
const struct xt_gradm_mtinfo *info = (const void *)match->data;
|
const struct xt_gradm_mtinfo *info = (const void *)match->data;
|
||||||
@@ -78,6 +67,13 @@ static void gradm_mt_save(const void *ip, const struct xt_entry_match *match)
|
|||||||
printf(" --enabled ");
|
printf(" --enabled ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gradm_mt_print(const void *ip, const struct xt_entry_match *match,
|
||||||
|
int numeric)
|
||||||
|
{
|
||||||
|
printf(" -m gradm");
|
||||||
|
gradm_mt_save(ip, match);
|
||||||
|
}
|
||||||
|
|
||||||
static struct xtables_match gradm_mt_reg = {
|
static struct xtables_match gradm_mt_reg = {
|
||||||
.family = NFPROTO_UNSPEC,
|
.family = NFPROTO_UNSPEC,
|
||||||
.name = "gradm",
|
.name = "gradm",
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
.PP
|
||||||
This module matches packets based on grsecurity RBAC status.
|
This module matches packets based on grsecurity RBAC status.
|
||||||
.TP
|
.TP
|
||||||
[\fB!\fP] \fB\-\-enabled\fP
|
[\fB!\fP] \fB\-\-enabled\fP
|
||||||
|
@@ -175,33 +175,6 @@ static void iface_mt_check(unsigned int flags)
|
|||||||
"iface: You must specify at least one option");
|
"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: ");
|
|
||||||
if (info->flags & XT_IFACE_DEV_IN)
|
|
||||||
printf("(in)");
|
|
||||||
else if (info->flags & XT_IFACE_DEV_OUT)
|
|
||||||
printf("(out)");
|
|
||||||
else
|
|
||||||
printf("%s", info->ifname);
|
|
||||||
printf(" [state:");
|
|
||||||
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)
|
static void iface_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||||
{
|
{
|
||||||
const struct xt_iface_mtinfo *info = (const void *)match->data;
|
const struct xt_iface_mtinfo *info = (const void *)match->data;
|
||||||
@@ -226,6 +199,13 @@ static void iface_mt_save(const void *ip, const struct xt_entry_match *match)
|
|||||||
printf(" ");
|
printf(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void iface_mt_print(const void *ip, const struct xt_entry_match *match,
|
||||||
|
int numeric)
|
||||||
|
{
|
||||||
|
printf(" -m iface");
|
||||||
|
iface_mt_save(ip, match);
|
||||||
|
}
|
||||||
|
|
||||||
static struct xtables_match iface_mt_reg = {
|
static struct xtables_match iface_mt_reg = {
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.name = "iface",
|
.name = "iface",
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
.PP
|
||||||
Allows you to check interface states. First, an interface needs to be selected
|
Allows you to check interface states. First, an interface needs to be selected
|
||||||
for comparison. Exactly one option of the following three must be specified:
|
for comparison. Exactly one option of the following three must be specified:
|
||||||
.TP
|
.TP
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* "ipp2p" match extension for iptables
|
* "ipp2p" match extension for iptables
|
||||||
* Eicke Friedrich/Klaus Degner <ipp2p@ipp2p.org>, 2005 - 2006
|
* Eicke Friedrich/Klaus Degner <ipp2p@ipp2p.org>, 2005 - 2006
|
||||||
* Jan Engelhardt <jengelh [at] medozas de>, 2008 - 2009
|
* Jan Engelhardt, 2008 - 2009
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License; either
|
* modify it under the terms of the GNU General Public License; either
|
||||||
@@ -217,7 +217,7 @@ ipp2p_mt_print1(const void *entry, const struct xt_entry_match *match,
|
|||||||
static void ipp2p_mt_print(const void *entry,
|
static void ipp2p_mt_print(const void *entry,
|
||||||
const struct xt_entry_match *match, int numeric)
|
const struct xt_entry_match *match, int numeric)
|
||||||
{
|
{
|
||||||
printf(" ipp2p ");
|
printf(" -m ipp2p ");
|
||||||
ipp2p_mt_print1(entry, match, true);
|
ipp2p_mt_print1(entry, match, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
.PP
|
||||||
This module matches certain packets in P2P flows. It is not
|
This module matches certain packets in P2P flows. It is not
|
||||||
designed to match all packets belonging to a P2P connection \(em
|
designed to match all packets belonging to a P2P connection \(em
|
||||||
use IPP2P together with CONNMARK for this purpose.
|
use IPP2P together with CONNMARK for this purpose.
|
||||||
|
@@ -133,17 +133,6 @@ static void ipv4options_print_flags(const struct xt_ipv4options_mtinfo1 *info,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ipv4options_mt_print(const void *ip,
|
|
||||||
const struct xt_entry_match *match, int numeric)
|
|
||||||
{
|
|
||||||
const struct xt_ipv4options_mtinfo1 *info = (void *)match->data;
|
|
||||||
|
|
||||||
printf(" ipv4options %s ",
|
|
||||||
(info->flags & XT_V4OPTS_ANY) ? "any-of" : "all-of");
|
|
||||||
ipv4options_print_flags(info, numeric);
|
|
||||||
printf(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ipv4options_mt_save(const void *ip,
|
static void ipv4options_mt_save(const void *ip,
|
||||||
const struct xt_entry_match *match)
|
const struct xt_entry_match *match)
|
||||||
{
|
{
|
||||||
@@ -158,6 +147,13 @@ static void ipv4options_mt_save(const void *ip,
|
|||||||
printf(" ");
|
printf(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ipv4options_mt_print(const void *ip,
|
||||||
|
const struct xt_entry_match *match, int numeric)
|
||||||
|
{
|
||||||
|
printf(" -m ipv4options");
|
||||||
|
ipv4options_mt_save(ip, match);
|
||||||
|
}
|
||||||
|
|
||||||
static struct xtables_match ipv4options_mt_reg = {
|
static struct xtables_match ipv4options_mt_reg = {
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.name = "ipv4options",
|
.name = "ipv4options",
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
.PP
|
||||||
The "ipv4options" module allows to match against a set of IPv4 header options.
|
The "ipv4options" module allows to match against a set of IPv4 header options.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-flags\fP [\fB!\fP]\fIsymbol\fP[\fB,\fP[\fB!\fP]\fIsymbol...\fP]
|
\fB\-\-flags\fP [\fB!\fP]\fIsymbol\fP[\fB,\fP[\fB!\fP]\fIsymbol...\fP]
|
||||||
|
@@ -107,29 +107,6 @@ static void length_mt_check(unsigned int flags)
|
|||||||
"--layer3. Consider specifying it explicitly.\n");
|
"--layer3. Consider specifying it explicitly.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void length_mt_print(const void *ip, const struct xt_entry_match *match,
|
|
||||||
int numeric)
|
|
||||||
{
|
|
||||||
const struct xt_length_mtinfo2 *info = (const void *)match->data;
|
|
||||||
|
|
||||||
if (info->flags & XT_LENGTH_LAYER3)
|
|
||||||
printf(" layer3 ");
|
|
||||||
else if (info->flags & XT_LENGTH_LAYER4)
|
|
||||||
printf(" layer4 ");
|
|
||||||
else if (info->flags & XT_LENGTH_LAYER5)
|
|
||||||
printf(" layer5 ");
|
|
||||||
else if (info->flags & XT_LENGTH_LAYER7)
|
|
||||||
printf(" layer7 ");
|
|
||||||
printf(" length ");
|
|
||||||
if (info->flags & XT_LENGTH_INVERT)
|
|
||||||
printf("! ");
|
|
||||||
if (info->min == info->max)
|
|
||||||
printf("%u ", (unsigned int)info->min);
|
|
||||||
else
|
|
||||||
printf("%u-%u ", (unsigned int)info->min,
|
|
||||||
(unsigned int)info->max);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void length_mt_save(const void *ip, const struct xt_entry_match *match)
|
static void length_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||||
{
|
{
|
||||||
const struct xt_length_mtinfo2 *info = (const void *)match->data;
|
const struct xt_length_mtinfo2 *info = (const void *)match->data;
|
||||||
@@ -152,6 +129,13 @@ static void length_mt_save(const void *ip, const struct xt_entry_match *match)
|
|||||||
(unsigned int)info->max);
|
(unsigned int)info->max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void length_mt_print(const void *ip, const struct xt_entry_match *match,
|
||||||
|
int numeric)
|
||||||
|
{
|
||||||
|
printf(" -m length2");
|
||||||
|
length_mt_save(ip, match);
|
||||||
|
}
|
||||||
|
|
||||||
static struct xtables_match length2_mt_reg = {
|
static struct xtables_match length2_mt_reg = {
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.name = "length2",
|
.name = "length2",
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
.PP
|
||||||
This module matches the length of a packet against a specific value or range of
|
This module matches the length of a packet against a specific value or range of
|
||||||
values.
|
values.
|
||||||
.TP
|
.TP
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* LSCAN match extension for iptables
|
* LSCAN match extension for iptables
|
||||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2006 - 2009
|
* Copyright © Jan Engelhardt, 2006 - 2009
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License; either
|
* modify it under the terms of the GNU General Public License; either
|
||||||
@@ -24,6 +24,7 @@ static const struct option lscan_mt_opts[] = {
|
|||||||
{.name = "synscan", .has_arg = false, .val = 's'},
|
{.name = "synscan", .has_arg = false, .val = 's'},
|
||||||
{.name = "cnscan", .has_arg = false, .val = 'c'},
|
{.name = "cnscan", .has_arg = false, .val = 'c'},
|
||||||
{.name = "grscan", .has_arg = false, .val = 'g'},
|
{.name = "grscan", .has_arg = false, .val = 'g'},
|
||||||
|
{.name = "mirai", .has_arg = false, .val = 'm'},
|
||||||
{NULL},
|
{NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -35,7 +36,8 @@ static void lscan_mt_help(void)
|
|||||||
" --stealth Match TCP Stealth packets\n"
|
" --stealth Match TCP Stealth packets\n"
|
||||||
" --synscan Match TCP SYN scans\n"
|
" --synscan Match TCP SYN scans\n"
|
||||||
" --cnscan Match TCP Connect scans\n"
|
" --cnscan Match TCP Connect scans\n"
|
||||||
" --grscan Match Banner Grabbing scans\n");
|
" --grscan Match Banner Grabbing scans\n"
|
||||||
|
" --mirai Match TCP scan with ISN = dest. IP\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lscan_mt_parse(int c, char **argv, int invert,
|
static int lscan_mt_parse(int c, char **argv, int invert,
|
||||||
@@ -45,16 +47,19 @@ static int lscan_mt_parse(int c, char **argv, int invert,
|
|||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'c':
|
case 'c':
|
||||||
info->match_cn = true;
|
info->match_fl3 |= LSCAN_FL3_CN;
|
||||||
return true;
|
return true;
|
||||||
case 'g':
|
case 'g':
|
||||||
info->match_gr = true;
|
info->match_fl4 |= LSCAN_FL4_GR;
|
||||||
|
return true;
|
||||||
|
case 'm':
|
||||||
|
info->match_fl1 |= LSCAN_FL1_MIRAI;
|
||||||
return true;
|
return true;
|
||||||
case 's':
|
case 's':
|
||||||
info->match_syn = true;
|
info->match_fl2 |= LSCAN_FL2_SYN;
|
||||||
return true;
|
return true;
|
||||||
case 'x':
|
case 'x':
|
||||||
info->match_stealth = true;
|
info->match_fl1 |= LSCAN_FL1_STEALTH;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -64,42 +69,27 @@ static void lscan_mt_check(unsigned int flags)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lscan_mt_print(const void *ip,
|
|
||||||
const struct xt_entry_match *match, int numeric)
|
|
||||||
{
|
|
||||||
const struct xt_lscan_mtinfo *info = (const void *)(match->data);
|
|
||||||
const char *s = "";
|
|
||||||
|
|
||||||
printf(" lscan ");
|
|
||||||
if (info->match_stealth) {
|
|
||||||
printf("STEALTH");
|
|
||||||
s = ",";
|
|
||||||
}
|
|
||||||
if (info->match_syn) {
|
|
||||||
printf("%sSYNSCAN", s);
|
|
||||||
s = ",";
|
|
||||||
}
|
|
||||||
if (info->match_cn) {
|
|
||||||
printf("%sCNSCAN", s);
|
|
||||||
s = ",";
|
|
||||||
}
|
|
||||||
if (info->match_gr)
|
|
||||||
printf("%sGRSCAN", s);
|
|
||||||
printf(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void lscan_mt_save(const void *ip, const struct xt_entry_match *match)
|
static void lscan_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||||
{
|
{
|
||||||
const struct xt_lscan_mtinfo *info = (const void *)(match->data);
|
const struct xt_lscan_mtinfo *info = (const void *)(match->data);
|
||||||
|
|
||||||
if (info->match_stealth)
|
if (info->match_fl1 & LSCAN_FL1_STEALTH)
|
||||||
printf(" --stealth ");
|
printf(" --stealth ");
|
||||||
if (info->match_syn)
|
if (info->match_fl2 & LSCAN_FL2_SYN)
|
||||||
printf(" --synscan ");
|
printf(" --synscan ");
|
||||||
if (info->match_cn)
|
if (info->match_fl3 & LSCAN_FL3_CN)
|
||||||
printf(" --cnscan ");
|
printf(" --cnscan ");
|
||||||
if (info->match_gr)
|
if (info->match_fl4 & LSCAN_FL4_GR)
|
||||||
printf(" --grscan ");
|
printf(" --grscan ");
|
||||||
|
if (info->match_fl1 & LSCAN_FL1_MIRAI)
|
||||||
|
printf(" --mirai ");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lscan_mt_print(const void *ip,
|
||||||
|
const struct xt_entry_match *match, int numeric)
|
||||||
|
{
|
||||||
|
printf(" -m lscan");
|
||||||
|
lscan_mt_save(ip, match);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct xtables_match lscan_mt_reg = {
|
static struct xtables_match lscan_mt_reg = {
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
Detects simple low-level scan attemps based upon the packet's contents.
|
.PP
|
||||||
|
Detects simple low-level scan attempts based upon the packet's contents.
|
||||||
(This is
|
(This is
|
||||||
different from other implementations, which also try to match the rate of new
|
different from other implementations, which also try to match the rate of new
|
||||||
connections.) Note that an attempt is only discovered after it has been carried
|
connections.) Note that an attempt is only discovered after it has been carried
|
||||||
@@ -26,6 +27,11 @@ warranted single-direction data flows, usually bulk data transfers such as
|
|||||||
FTP DATA connections or IRC DCC. Grab Scan Detection should only be used on
|
FTP DATA connections or IRC DCC. Grab Scan Detection should only be used on
|
||||||
ports where a protocol runs that is guaranteed to do a bidirectional exchange
|
ports where a protocol runs that is guaranteed to do a bidirectional exchange
|
||||||
of bytes.
|
of bytes.
|
||||||
|
.TP
|
||||||
|
\fB\-\-mirai\fP
|
||||||
|
Match if the TCP ISN is equal to the IPv4 destination address; this is used
|
||||||
|
by the devices in the Mirai botnet as a form of TCP SYN scan, so you will
|
||||||
|
have to explicitly specify --syn for the rule.
|
||||||
.PP
|
.PP
|
||||||
NOTE: Some clients (Windows XP for example) may do what looks like a SYN scan,
|
NOTE: Some clients (Windows XP for example) may do what looks like a SYN scan,
|
||||||
so be advised to carefully use xt_lscan in conjunction with blocking rules,
|
so be advised to carefully use xt_lscan in conjunction with blocking rules,
|
||||||
|
@@ -117,18 +117,6 @@ static int psd_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
/* Final check; nothing. */
|
/* Final check; nothing. */
|
||||||
static void psd_mt_final_check(unsigned int flags) {}
|
static void psd_mt_final_check(unsigned int flags) {}
|
||||||
|
|
||||||
/* Prints out the targinfo. */
|
|
||||||
static void psd_mt_print(const void *ip, const struct xt_entry_match *match, int numeric)
|
|
||||||
{
|
|
||||||
const struct xt_psd_info *psdinfo = (const struct xt_psd_info *)match->data;
|
|
||||||
printf(" psd ");
|
|
||||||
printf("weight-threshold: %u ", psdinfo->weight_threshold);
|
|
||||||
printf("delay-threshold: %u ", psdinfo->delay_threshold);
|
|
||||||
printf("lo-ports-weight: %u ", psdinfo->lo_ports_weight);
|
|
||||||
printf("hi-ports-weight: %u ", psdinfo->hi_ports_weight);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Saves the union ipt_targinfo in parsable form to stdout. */
|
|
||||||
static void psd_mt_save(const void *ip, const struct xt_entry_match *match)
|
static void psd_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||||
{
|
{
|
||||||
const struct xt_psd_info *psdinfo = (const struct xt_psd_info *)match->data;
|
const struct xt_psd_info *psdinfo = (const struct xt_psd_info *)match->data;
|
||||||
@@ -138,11 +126,17 @@ static void psd_mt_save(const void *ip, const struct xt_entry_match *match)
|
|||||||
printf("--psd-hi-ports-weight %u ", psdinfo->hi_ports_weight);
|
printf("--psd-hi-ports-weight %u ", psdinfo->hi_ports_weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void psd_mt_print(const void *ip, const struct xt_entry_match *match, int numeric)
|
||||||
|
{
|
||||||
|
printf(" -m psd");
|
||||||
|
psd_mt_save(ip, match);
|
||||||
|
}
|
||||||
|
|
||||||
static struct xtables_match psd_mt_reg = {
|
static struct xtables_match psd_mt_reg = {
|
||||||
.name = "psd",
|
.name = "psd",
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.revision = 1,
|
.revision = 1,
|
||||||
.family = NFPROTO_IPV4,
|
.family = NFPROTO_UNSPEC,
|
||||||
.size = XT_ALIGN(sizeof(struct xt_psd_info)),
|
.size = XT_ALIGN(sizeof(struct xt_psd_info)),
|
||||||
.userspacesize = XT_ALIGN(sizeof(struct xt_psd_info)),
|
.userspacesize = XT_ALIGN(sizeof(struct xt_psd_info)),
|
||||||
.help = psd_mt_help,
|
.help = psd_mt_help,
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
.PP
|
||||||
Attempt to detect TCP and UDP port scans. This match was derived from
|
Attempt to detect TCP and UDP port scans. This match was derived from
|
||||||
Solar Designer's scanlogd.
|
Solar Designer's scanlogd.
|
||||||
.TP
|
.TP
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* "quota2" match extension for iptables
|
* "quota2" match extension for iptables
|
||||||
* Sam Johnston <samj [at] samj net>
|
* Sam Johnston <samj [at] samj net>
|
||||||
* Jan Engelhardt <jengelh [at] medozas de>, 2008
|
* Jan Engelhardt, 2008
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License; either
|
* modify it under the terms of the GNU General Public License; either
|
||||||
@@ -70,7 +70,7 @@ quota_mt2_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
/* zero termination done on behalf of the kernel module */
|
/* zero termination done on behalf of the kernel module */
|
||||||
xtables_param_act(XTF_ONLY_ONCE, "quota", "--name", *flags & FL_NAME);
|
xtables_param_act(XTF_ONLY_ONCE, "quota", "--name", *flags & FL_NAME);
|
||||||
xtables_param_act(XTF_NO_INVERT, "quota", "--name", invert);
|
xtables_param_act(XTF_NO_INVERT, "quota", "--name", invert);
|
||||||
strncpy(info->name, optarg, sizeof(info->name));
|
snprintf(info->name, sizeof(info->name), "%s", optarg);
|
||||||
*flags |= FL_NAME;
|
*flags |= FL_NAME;
|
||||||
return true;
|
return true;
|
||||||
case 'p':
|
case 'p':
|
||||||
@@ -98,8 +98,6 @@ quota_mt2_save(const void *ip, const struct xt_entry_match *match)
|
|||||||
{
|
{
|
||||||
const struct xt_quota_mtinfo2 *q = (void *)match->data;
|
const struct xt_quota_mtinfo2 *q = (void *)match->data;
|
||||||
|
|
||||||
if (q->flags & XT_QUOTA_INVERT)
|
|
||||||
printf(" !");
|
|
||||||
if (q->flags & XT_QUOTA_GROW)
|
if (q->flags & XT_QUOTA_GROW)
|
||||||
printf(" --grow ");
|
printf(" --grow ");
|
||||||
if (q->flags & XT_QUOTA_NO_CHANGE)
|
if (q->flags & XT_QUOTA_NO_CHANGE)
|
||||||
@@ -108,29 +106,16 @@ quota_mt2_save(const void *ip, const struct xt_entry_match *match)
|
|||||||
printf(" --packets ");
|
printf(" --packets ");
|
||||||
if (*q->name != '\0')
|
if (*q->name != '\0')
|
||||||
printf(" --name %s ", q->name);
|
printf(" --name %s ", q->name);
|
||||||
|
if (q->flags & XT_QUOTA_INVERT)
|
||||||
|
printf(" !");
|
||||||
printf(" --quota %llu ", (unsigned long long)q->quota);
|
printf(" --quota %llu ", (unsigned long long)q->quota);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void quota_mt2_print(const void *ip, const struct xt_entry_match *match,
|
static void quota_mt2_print(const void *ip, const struct xt_entry_match *match,
|
||||||
int numeric)
|
int numeric)
|
||||||
{
|
{
|
||||||
const struct xt_quota_mtinfo2 *q = (const void *)match->data;
|
printf(" -m quota");
|
||||||
|
quota_mt2_save(ip, match);
|
||||||
if (q->flags & XT_QUOTA_INVERT)
|
|
||||||
printf(" !");
|
|
||||||
if (q->flags & XT_QUOTA_GROW)
|
|
||||||
printf(" counter");
|
|
||||||
else
|
|
||||||
printf(" quota");
|
|
||||||
if (*q->name != '\0')
|
|
||||||
printf(" %s:", q->name);
|
|
||||||
printf(" %llu ", (unsigned long long)q->quota);
|
|
||||||
if (q->flags & XT_QUOTA_PACKET)
|
|
||||||
printf("packets ");
|
|
||||||
else
|
|
||||||
printf("bytes ");
|
|
||||||
if (q->flags & XT_QUOTA_NO_CHANGE)
|
|
||||||
printf("(no-change mode) ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct xtables_match quota_mt2_reg = {
|
static struct xtables_match quota_mt2_reg = {
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
.PP
|
||||||
The "quota2" implements a named counter which can be increased or decreased
|
The "quota2" implements a named counter which can be increased or decreased
|
||||||
on a per-match basis. Available modes are packet counting or byte counting.
|
on a per-match basis. Available modes are packet counting or byte counting.
|
||||||
The value of the counter can be read and reset through procfs, thereby making
|
The value of the counter can be read and reset through procfs, thereby making
|
||||||
|
@@ -5,4 +5,5 @@ AM_CFLAGS = ${regular_CFLAGS} ${libxtables_CFLAGS}
|
|||||||
|
|
||||||
include ../../Makefile.extra
|
include ../../Makefile.extra
|
||||||
|
|
||||||
noinst_PROGRAMS = pknlusr
|
sbin_PROGRAMS = pknlusr
|
||||||
|
dist_man_MANS = pknlusr.8
|
||||||
|
17
extensions/pknock/gen_hmac.py
Normal file
17
extensions/pknock/gen_hmac.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
from Crypto.Hash import SHA256
|
||||||
|
from Crypto.Hash import MD5
|
||||||
|
import sys
|
||||||
|
import hmac
|
||||||
|
import struct
|
||||||
|
import socket
|
||||||
|
from time import time
|
||||||
|
|
||||||
|
def gen_hmac(secret, ip):
|
||||||
|
epoch_mins = (long)(time()/60)
|
||||||
|
s = hmac.HMAC(secret, digestmod = SHA256)
|
||||||
|
s.update(socket.inet_aton(socket.gethostbyname(ip)))
|
||||||
|
s.update(struct.pack("i", epoch_mins)) # "i" is for integer
|
||||||
|
print s.hexdigest()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
gen_hmac(sys.argv[1], sys.argv[2])
|
6
extensions/pknock/knock.sh
Executable file
6
extensions/pknock/knock.sh
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
if [ "$#" -ne 4 ]; then
|
||||||
|
echo "usage: $0 <IP src> <IP dst> <PORT dst> <secret>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
python gen_hmac.py "$4" "$1" | socat - "udp-sendto:$2:$3,bind=$1"
|
@@ -11,7 +11,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <xtables.h>
|
#include <xtables.h>
|
||||||
#include <linux/netfilter.h>
|
#include <linux/netfilter.h>
|
||||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||||
@@ -34,18 +33,23 @@ static const struct option pknock_mt_opts[] = {
|
|||||||
static void pknock_mt_help(void)
|
static void pknock_mt_help(void)
|
||||||
{
|
{
|
||||||
printf("pknock match options:\n"
|
printf("pknock match options:\n"
|
||||||
" --knockports port[,port,port,...] "
|
" --knockports port[,port[,port[,...]]]\n"
|
||||||
"Matches destination port(s).\n"
|
"\t\t\t\tMatches destination port(s).\n"
|
||||||
" --time seconds\n"
|
" --time seconds "
|
||||||
"Max allowed time between knocks.\n"
|
"Max allowed time between knocks.\n"
|
||||||
" --autoclose minutes\n"
|
" --autoclose minutes "
|
||||||
"Time after which to automatically close opened\n"
|
"Time after which to automatically close opened\n"
|
||||||
"\t\t\t\t\tport(s).\n"
|
"\t\t\t\tport(s).\n"
|
||||||
" --strict "
|
" --name rule_name "
|
||||||
"Knocks sequence must be exact.\n"
|
|
||||||
" --name rule_name "
|
|
||||||
"Rule name.\n"
|
"Rule name.\n"
|
||||||
" --checkip "
|
" --opensecret secret "
|
||||||
|
"(UDP only) Secret to activate the rule.\n"
|
||||||
|
" --closesecret secret "
|
||||||
|
"(UDP only) Secret to deactivate the\n"
|
||||||
|
"\t\t\t\trule.\n"
|
||||||
|
" --strict "
|
||||||
|
"Knocks sequence must be exact.\n"
|
||||||
|
" --checkip "
|
||||||
"Matches if the source ip is in the list.\n"
|
"Matches if the source ip is in the list.\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -70,7 +74,6 @@ parse_ports(const char *portstring, uint16_t *ports, const char *proto)
|
|||||||
|
|
||||||
if (cp != NULL)
|
if (cp != NULL)
|
||||||
xtables_error(PARAMETER_PROBLEM, "too many ports specified");
|
xtables_error(PARAMETER_PROBLEM, "too many ports specified");
|
||||||
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@@ -91,12 +94,11 @@ proto_to_name(uint8_t proto)
|
|||||||
static const char *
|
static const char *
|
||||||
check_proto(uint16_t pnum, uint8_t invflags)
|
check_proto(uint16_t pnum, uint8_t invflags)
|
||||||
{
|
{
|
||||||
char *proto;
|
|
||||||
|
|
||||||
if (invflags & XT_INV_PROTO)
|
if (invflags & XT_INV_PROTO)
|
||||||
xtables_error(PARAMETER_PROBLEM, PKNOCK "only works with TCP and UDP.");
|
xtables_error(PARAMETER_PROBLEM, PKNOCK "only works with TCP and UDP.");
|
||||||
|
|
||||||
if ((proto = proto_to_name(pnum)) != NULL)
|
const char *proto = proto_to_name(pnum);
|
||||||
|
if (proto != NULL)
|
||||||
return proto;
|
return proto;
|
||||||
else if (pnum == 0)
|
else if (pnum == 0)
|
||||||
xtables_error(PARAMETER_PROBLEM, PKNOCK "needs `-p tcp' or `-p udp'");
|
xtables_error(PARAMETER_PROBLEM, PKNOCK "needs `-p tcp' or `-p udp'");
|
||||||
@@ -123,7 +125,7 @@ __pknock_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
info->ports_count = parse_ports(optarg, info->port, proto);
|
info->ports_count = parse_ports(optarg, info->port, proto);
|
||||||
info->option |= XT_PKNOCK_KNOCKPORT;
|
info->option |= XT_PKNOCK_KNOCKPORT;
|
||||||
*flags |= XT_PKNOCK_KNOCKPORT;
|
*flags |= XT_PKNOCK_KNOCKPORT;
|
||||||
#if DEBUG
|
#ifdef DEBUG
|
||||||
printf("ports_count: %d\n", info->ports_count);
|
printf("ports_count: %d\n", info->ports_count);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
@@ -162,7 +164,7 @@ __pknock_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
info->rule_name_len = strlen(info->rule_name);
|
info->rule_name_len = strlen(info->rule_name);
|
||||||
info->option |= XT_PKNOCK_NAME;
|
info->option |= XT_PKNOCK_NAME;
|
||||||
*flags |= XT_PKNOCK_NAME;
|
*flags |= XT_PKNOCK_NAME;
|
||||||
#if DEBUG
|
#ifdef DEBUG
|
||||||
printf("info->rule_name: %s\n", info->rule_name);
|
printf("info->rule_name: %s\n", info->rule_name);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
@@ -213,7 +215,6 @@ __pknock_parse(int c, char **argv, int invert, unsigned int *flags,
|
|||||||
|
|
||||||
if (invert)
|
if (invert)
|
||||||
xtables_error(PARAMETER_PROBLEM, PKNOCK "does not support invert.");
|
xtables_error(PARAMETER_PROBLEM, PKNOCK "does not support invert.");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,7 +268,7 @@ static void pknock_mt_check(unsigned int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void pknock_mt_print(const void *ip,
|
static void pknock_mt_print(const void *ip,
|
||||||
const struct xt_entry_match *match, int numeric)
|
const struct xt_entry_match *match, int numeric)
|
||||||
{
|
{
|
||||||
const struct xt_pknock_mtinfo *info = (void *)match->data;
|
const struct xt_pknock_mtinfo *info = (void *)match->data;
|
||||||
int i;
|
int i;
|
||||||
|
@@ -15,10 +15,10 @@ modprobe xt_pknock
|
|||||||
.PP
|
.PP
|
||||||
Example 1 (TCP mode, manual closing of opened port not possible):
|
Example 1 (TCP mode, manual closing of opened port not possible):
|
||||||
.IP
|
.IP
|
||||||
iptables -P INPUT DROP
|
iptables \-P INPUT DROP
|
||||||
.IP
|
.IP
|
||||||
iptables -A INPUT -p tcp -m pknock --knockports 4002,4001,4004 --strict
|
iptables \-A INPUT \-p tcp \-m pknock \-\-knockports 4002,4001,4004 \-\-strict
|
||||||
--name SSH --time 10 --autoclose 60 --dport 22 -j ACCEPT
|
\-\-name SSH \-\-time 10 \-\-autoclose 60 \-\-dport 22 \-j ACCEPT
|
||||||
.PP
|
.PP
|
||||||
The rule will allow tcp port 22 for the attempting IP address after the successful reception of TCP SYN packets
|
The rule will allow tcp port 22 for the attempting IP address after the successful reception of TCP SYN packets
|
||||||
to ports 4002, 4001 and 4004, in this order (a.k.a. port-knocking).
|
to ports 4002, 4001 and 4004, in this order (a.k.a. port-knocking).
|
||||||
@@ -33,10 +33,10 @@ Example 2 (UDP mode \(em non-replayable and non-spoofable, manual closing
|
|||||||
of opened port possible, secure, also called "SPA" = Secure Port
|
of opened port possible, secure, also called "SPA" = Secure Port
|
||||||
Authorization):
|
Authorization):
|
||||||
.IP
|
.IP
|
||||||
iptables -A INPUT -p udp -m pknock --knockports 4000 --name FTP
|
iptables \-A INPUT \-p udp \-m pknock \-\-knockports 4000 \-\-name FTP
|
||||||
--opensecret foo --closesecret bar --autoclose 240 -j DROP
|
\-\-opensecret foo \-\-closesecret bar \-\-autoclose 240 \-j DROP
|
||||||
.IP
|
.IP
|
||||||
iptables -A INPUT -p tcp -m pknock --checkip --name FTP --dport 21 -j ACCEPT
|
iptables \-A INPUT \-p tcp \-m pknock \-\-checkip \-\-name FTP \-\-dport 21 \-j ACCEPT
|
||||||
.PP
|
.PP
|
||||||
The first rule will create an "ALLOWED" record in /proc/net/xt_pknock/FTP after
|
The first rule will create an "ALLOWED" record in /proc/net/xt_pknock/FTP after
|
||||||
the successful reception of an UDP packet to port 4000. The packet payload must be
|
the successful reception of an UDP packet to port 4000. The packet payload must be
|
||||||
@@ -62,8 +62,6 @@ Specifying \fB--autoclose 0\fP means that no automatic close will be performed a
|
|||||||
xt_pknock is capable of sending information about successful matches
|
xt_pknock is capable of sending information about successful matches
|
||||||
via a netlink socket to userspace, should you need to implement your own
|
via a netlink socket to userspace, should you need to implement your own
|
||||||
way of receiving and handling portknock notifications.
|
way of receiving and handling portknock notifications.
|
||||||
Be sure to read the documentation in the doc/pknock/ directory,
|
|
||||||
or visit the original site \(em http://portknocko.berlios.de/ .
|
|
||||||
.PP
|
.PP
|
||||||
\fBTCP mode\fP:
|
\fBTCP mode\fP:
|
||||||
.PP
|
.PP
|
||||||
|
18
extensions/pknock/pknlusr.8
Normal file
18
extensions/pknock/pknlusr.8
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
.TH pknlusr 8 "2020-10-22" "xtables-addons" "xtables-addons"
|
||||||
|
.SH NAME
|
||||||
|
.PP
|
||||||
|
pknlusr \(em userspace monitor for successful xt_pknock matches
|
||||||
|
.SH Synopsis
|
||||||
|
.PP
|
||||||
|
\fBpknlusr\fP [\fIgroup-id\fP]
|
||||||
|
.SH Description
|
||||||
|
\fIxt_pknock\fP is an xtables match extension that implements so-called \fIport
|
||||||
|
knocking\fP. It can be configured to send information about each successful
|
||||||
|
match via a netlink socket to userspace. \fBpknluser\fP listens for these
|
||||||
|
notifications.
|
||||||
|
.PP
|
||||||
|
By default, \fBpknlusr\fP listens for messages sent to netlink multicast group
|
||||||
|
1. Another group ID may be passed as a command-line argument.
|
||||||
|
.SH See also
|
||||||
|
.PP
|
||||||
|
xtables-addons(8)
|
@@ -7,85 +7,94 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
#include <linux/connector.h>
|
#include <linux/connector.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "xt_pknock.h"
|
#include "xt_pknock.h"
|
||||||
|
|
||||||
#define GROUP 1
|
#define DEFAULT_GROUP_ID 1
|
||||||
|
#define MIN_GROUP_ID DEFAULT_GROUP_ID
|
||||||
|
#define MAX_GROUP_ID \
|
||||||
|
(sizeof((struct sockaddr_nl){0}.nl_groups) * CHAR_BIT)
|
||||||
|
|
||||||
static struct sockaddr_nl src_addr, dest_addr;
|
int main(int argc, char **argv)
|
||||||
static int sock_fd;
|
|
||||||
|
|
||||||
static unsigned char *buf;
|
|
||||||
|
|
||||||
static struct xt_pknock_nl_msg *nlmsg;
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
{
|
||||||
socklen_t addrlen;
|
|
||||||
int status;
|
int status;
|
||||||
int group = GROUP;
|
unsigned int group_id = DEFAULT_GROUP_ID;
|
||||||
|
struct sockaddr_nl local_addr = {.nl_family = AF_NETLINK};
|
||||||
|
int sock_fd;
|
||||||
|
size_t nlmsg_size;
|
||||||
|
struct nlmgrhdr *nlmsg;
|
||||||
|
struct cn_msg *cn_msg;
|
||||||
|
struct xt_pknock_nl_msg *pknock_msg;
|
||||||
|
|
||||||
int buf_size;
|
if (argc > 2) {
|
||||||
|
char *prog = strdup(argv[0]);
|
||||||
|
if (prog == NULL) {
|
||||||
|
perror("strdup()");
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "%s [ group-id ]\n", basename(prog));
|
||||||
|
free(prog);
|
||||||
|
}
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
const char *ip;
|
if (argc == 2) {
|
||||||
char ipbuf[48];
|
long n;
|
||||||
|
char *end;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
n = strtol(argv[1], &end, 10);
|
||||||
|
if (*end || (errno && (n == LONG_MIN || n == LONG_MAX)) ||
|
||||||
|
n < MIN_GROUP_ID || n > MAX_GROUP_ID) {
|
||||||
|
fputs("Group ID invalid.\n", stderr);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
group_id = n;
|
||||||
|
}
|
||||||
|
|
||||||
sock_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
|
sock_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
|
||||||
|
|
||||||
if (sock_fd == -1) {
|
if (sock_fd == -1) {
|
||||||
perror("socket()");
|
perror("socket()");
|
||||||
return 1;
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&src_addr, 0, sizeof(src_addr));
|
local_addr.nl_groups = 1U << (group_id - 1);
|
||||||
src_addr.nl_family = AF_NETLINK;
|
status = bind(sock_fd, (struct sockaddr *)&local_addr, sizeof(local_addr));
|
||||||
src_addr.nl_pid = getpid();
|
|
||||||
src_addr.nl_groups = group;
|
|
||||||
|
|
||||||
status = bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr));
|
|
||||||
|
|
||||||
if (status == -1) {
|
if (status == -1) {
|
||||||
close(sock_fd);
|
|
||||||
perror("bind()");
|
perror("bind()");
|
||||||
return 1;
|
goto err_close_sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&dest_addr, 0, sizeof(dest_addr));
|
nlmsg_size = NLMSG_SPACE(sizeof(*cn_msg) + sizeof(*pknock_msg));
|
||||||
dest_addr.nl_family = AF_NETLINK;
|
nlmsg = malloc(nlmsg_size);
|
||||||
dest_addr.nl_pid = 0;
|
if (!nlmsg) {
|
||||||
dest_addr.nl_groups = group;
|
|
||||||
|
|
||||||
buf_size = sizeof(struct xt_pknock_nl_msg) + sizeof(struct cn_msg) + sizeof(struct nlmsghdr);
|
|
||||||
buf = malloc(buf_size);
|
|
||||||
|
|
||||||
if (!buf) {
|
|
||||||
perror("malloc()");
|
perror("malloc()");
|
||||||
return 1;
|
goto err_close_sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
addrlen = sizeof(dest_addr);
|
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
|
const char *ip;
|
||||||
|
char ipbuf[INET_ADDRSTRLEN];
|
||||||
|
|
||||||
memset(buf, 0, buf_size);
|
memset(nlmsg, 0, nlmsg_size);
|
||||||
|
status = recv(sock_fd, nlmsg, nlmsg_size, 0);
|
||||||
status = recvfrom(sock_fd, buf, buf_size, 0, (struct sockaddr *)&dest_addr, &addrlen);
|
if (status < 0) {
|
||||||
|
perror("recv()");
|
||||||
if (status <= 0) {
|
goto err_free_msg;
|
||||||
perror("recvfrom()");
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
if (status == 0)
|
||||||
nlmsg = (struct xt_pknock_nl_msg *) (buf + sizeof(struct cn_msg) + sizeof(struct nlmsghdr));
|
break;
|
||||||
|
cn_msg = NLMSG_DATA(nlmsg);
|
||||||
ip = inet_ntop(AF_INET, &nlmsg->peer_ip, ipbuf, sizeof(ipbuf));
|
pknock_msg = (struct xt_pknock_nl_msg *)(cn_msg->data);
|
||||||
printf("rule_name: %s - ip %s\n", nlmsg->rule_name, ip);
|
ip = inet_ntop(AF_INET, &pknock_msg->peer_ip, ipbuf, sizeof(ipbuf));
|
||||||
|
printf("rule_name: %s - ip %s\n", pknock_msg->rule_name, ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err_free_msg:
|
||||||
|
free(nlmsg);
|
||||||
|
err_close_sock:
|
||||||
close(sock_fd);
|
close(sock_fd);
|
||||||
|
exit(status == -1 ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||||
free(buf);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
@@ -19,23 +19,17 @@
|
|||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/jhash.h>
|
#include <linux/jhash.h>
|
||||||
#include <linux/random.h>
|
#include <linux/random.h>
|
||||||
#include <linux/crypto.h>
|
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include <linux/scatterlist.h>
|
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/jiffies.h>
|
#include <linux/jiffies.h>
|
||||||
#include <linux/timer.h>
|
#include <linux/timer.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/connector.h>
|
#include <linux/connector.h>
|
||||||
|
|
||||||
#include <linux/netfilter/x_tables.h>
|
#include <linux/netfilter/x_tables.h>
|
||||||
|
#include <crypto/hash.h>
|
||||||
#include "xt_pknock.h"
|
#include "xt_pknock.h"
|
||||||
#include "compat_xtables.h"
|
#include "compat_xtables.h"
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
|
|
||||||
# define PK_CRYPTO 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum status {
|
enum status {
|
||||||
ST_INIT = 1,
|
ST_INIT = 1,
|
||||||
ST_MATCHING,
|
ST_MATCHING,
|
||||||
@@ -96,35 +90,27 @@ enum {
|
|||||||
#define hashtable_for_each_safe(pos, n, head, size, i) \
|
#define hashtable_for_each_safe(pos, n, head, size, i) \
|
||||||
for ((i) = 0; (i) < (size); ++(i)) \
|
for ((i) = 0; (i) < (size); ++(i)) \
|
||||||
list_for_each_safe((pos), (n), (&head[(i)]))
|
list_for_each_safe((pos), (n), (&head[(i)]))
|
||||||
|
#define pk_debug(msg, peer) pr_debug("(S) peer: %pI4 - %s.\n", &((peer)->ip), msg)
|
||||||
#define pk_debug(msg, peer) pr_debug( \
|
|
||||||
"(S) peer: " NIPQUAD_FMT " - %s.\n", \
|
|
||||||
NIPQUAD((peer)->ip), msg)
|
|
||||||
|
|
||||||
static uint32_t ipt_pknock_hash_rnd;
|
static uint32_t ipt_pknock_hash_rnd;
|
||||||
|
|
||||||
static unsigned int rule_hashsize = DEFAULT_RULE_HASH_SIZE;
|
static unsigned int rule_hashsize = DEFAULT_RULE_HASH_SIZE;
|
||||||
static unsigned int peer_hashsize = DEFAULT_PEER_HASH_SIZE;
|
static unsigned int peer_hashsize = DEFAULT_PEER_HASH_SIZE;
|
||||||
static unsigned int gc_expir_time = DEFAULT_GC_EXPIRATION_TIME;
|
static unsigned int gc_expir_time = DEFAULT_GC_EXPIRATION_TIME;
|
||||||
static int nl_multicast_group = -1;
|
static int nl_multicast_group = -1;
|
||||||
|
|
||||||
static struct list_head *rule_hashtable;
|
static struct list_head *rule_hashtable;
|
||||||
static struct proc_dir_entry *pde;
|
static struct proc_dir_entry *pde;
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(list_lock);
|
static DEFINE_SPINLOCK(list_lock);
|
||||||
|
|
||||||
#ifdef PK_CRYPTO
|
|
||||||
static struct {
|
static struct {
|
||||||
const char *algo;
|
const char *algo;
|
||||||
struct crypto_hash *tfm;
|
struct crypto_shash *tfm;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
struct hash_desc desc;
|
struct shash_desc desc;
|
||||||
} crypto = {
|
} crypto = {
|
||||||
.algo = "hmac(sha256)",
|
.algo = "hmac(sha256)",
|
||||||
.tfm = NULL,
|
.tfm = NULL,
|
||||||
.size = 0
|
.size = 0
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
module_param(rule_hashsize, int, S_IRUGO);
|
module_param(rule_hashsize, int, S_IRUGO);
|
||||||
MODULE_PARM_DESC(rule_hashsize, "Buckets in rule hash table (default: 8)");
|
MODULE_PARM_DESC(rule_hashsize, "Buckets in rule hash table (default: 8)");
|
||||||
@@ -167,7 +153,6 @@ alloc_hashtable(unsigned int size)
|
|||||||
return NULL;
|
return NULL;
|
||||||
for (i = 0; i < size; ++i)
|
for (i = 0; i < size; ++i)
|
||||||
INIT_LIST_HEAD(&hash[i]);
|
INIT_LIST_HEAD(&hash[i]);
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,14 +181,11 @@ status_itoa(enum status status)
|
|||||||
static void *
|
static void *
|
||||||
pknock_seq_start(struct seq_file *s, loff_t *pos)
|
pknock_seq_start(struct seq_file *s, loff_t *pos)
|
||||||
{
|
{
|
||||||
const struct proc_dir_entry *pde = s->private;
|
const struct xt_pknock_rule *rule = s->private;
|
||||||
const struct xt_pknock_rule *rule = pde->data;
|
|
||||||
|
|
||||||
spin_lock_bh(&list_lock);
|
spin_lock_bh(&list_lock);
|
||||||
|
|
||||||
if (*pos >= peer_hashsize)
|
if (*pos >= peer_hashsize)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return rule->peer_head + *pos;
|
return rule->peer_head + *pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,13 +198,11 @@ pknock_seq_start(struct seq_file *s, loff_t *pos)
|
|||||||
static void *
|
static void *
|
||||||
pknock_seq_next(struct seq_file *s, void *v, loff_t *pos)
|
pknock_seq_next(struct seq_file *s, void *v, loff_t *pos)
|
||||||
{
|
{
|
||||||
const struct proc_dir_entry *pde = s->private;
|
const struct xt_pknock_rule *rule = s->private;
|
||||||
const struct xt_pknock_rule *rule = pde->data;
|
|
||||||
|
|
||||||
++*pos;
|
++*pos;
|
||||||
if (*pos >= peer_hashsize)
|
if (*pos >= peer_hashsize)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return rule->peer_head + *pos;
|
return rule->peer_head + *pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,14 +228,11 @@ pknock_seq_show(struct seq_file *s, void *v)
|
|||||||
const struct peer *peer;
|
const struct peer *peer;
|
||||||
unsigned long time;
|
unsigned long time;
|
||||||
const struct list_head *peer_head = v;
|
const struct list_head *peer_head = v;
|
||||||
|
const struct xt_pknock_rule *rule = s->private;
|
||||||
const struct proc_dir_entry *pde = s->private;
|
|
||||||
const struct xt_pknock_rule *rule = pde->data;
|
|
||||||
|
|
||||||
list_for_each_safe(pos, n, peer_head) {
|
list_for_each_safe(pos, n, peer_head) {
|
||||||
peer = list_entry(pos, struct peer, head);
|
peer = list_entry(pos, struct peer, head);
|
||||||
|
seq_printf(s, "src=%pI4 ", &peer->ip);
|
||||||
seq_printf(s, "src=" NIPQUAD_FMT " ", NIPQUAD(peer->ip));
|
|
||||||
seq_printf(s, "proto=%s ", (peer->proto == IPPROTO_TCP) ?
|
seq_printf(s, "proto=%s ", (peer->proto == IPPROTO_TCP) ?
|
||||||
"TCP" : "UDP");
|
"TCP" : "UDP");
|
||||||
seq_printf(s, "status=%s ", status_itoa(peer->status));
|
seq_printf(s, "status=%s ", status_itoa(peer->status));
|
||||||
@@ -270,12 +247,11 @@ pknock_seq_show(struct seq_file *s, void *v)
|
|||||||
seq_printf(s, "expir_time=%lu [secs] ", time);
|
seq_printf(s, "expir_time=%lu [secs] ", time);
|
||||||
}
|
}
|
||||||
if (peer->status == ST_ALLOWED && rule->autoclose_time != 0) {
|
if (peer->status == ST_ALLOWED && rule->autoclose_time != 0) {
|
||||||
|
unsigned long x = ktime_get_seconds();
|
||||||
|
unsigned long y = peer->login_sec + rule->autoclose_time * 60;
|
||||||
time = 0;
|
time = 0;
|
||||||
if (time_before(get_seconds(), peer->login_sec +
|
if (time_before(x, y))
|
||||||
rule->autoclose_time * 60))
|
time = y - x;
|
||||||
time = peer->login_sec +
|
|
||||||
rule->autoclose_time * 60 -
|
|
||||||
get_seconds();
|
|
||||||
seq_printf(s, "autoclose_time=%lu [secs] ", time);
|
seq_printf(s, "autoclose_time=%lu [secs] ", time);
|
||||||
}
|
}
|
||||||
seq_printf(s, "\n");
|
seq_printf(s, "\n");
|
||||||
@@ -301,17 +277,16 @@ pknock_proc_open(struct inode *inode, struct file *file)
|
|||||||
int ret = seq_open(file, &pknock_seq_ops);
|
int ret = seq_open(file, &pknock_seq_ops);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
struct seq_file *sf = file->private_data;
|
struct seq_file *sf = file->private_data;
|
||||||
sf->private = PDE(inode);
|
sf->private = PDE_DATA(inode);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations pknock_proc_ops = {
|
static const struct proc_ops pknock_proc_ops = {
|
||||||
.owner = THIS_MODULE,
|
.proc_open = pknock_proc_open,
|
||||||
.open = pknock_proc_open,
|
.proc_read = seq_read,
|
||||||
.read = seq_read,
|
.proc_lseek = seq_lseek,
|
||||||
.llseek = seq_lseek,
|
.proc_release = seq_release,
|
||||||
.release = seq_release
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -323,7 +298,6 @@ static void update_rule_gc_timer(struct xt_pknock_rule *rule)
|
|||||||
{
|
{
|
||||||
if (timer_pending(&rule->timer))
|
if (timer_pending(&rule->timer))
|
||||||
del_timer(&rule->timer);
|
del_timer(&rule->timer);
|
||||||
|
|
||||||
rule->timer.expires = jiffies + msecs_to_jiffies(gc_expir_time);
|
rule->timer.expires = jiffies + msecs_to_jiffies(gc_expir_time);
|
||||||
add_timer(&rule->timer);
|
add_timer(&rule->timer);
|
||||||
}
|
}
|
||||||
@@ -337,8 +311,12 @@ static void update_rule_gc_timer(struct xt_pknock_rule *rule)
|
|||||||
static inline bool
|
static inline bool
|
||||||
autoclose_time_passed(const struct peer *peer, unsigned int autoclose_time)
|
autoclose_time_passed(const struct peer *peer, unsigned int autoclose_time)
|
||||||
{
|
{
|
||||||
return peer != NULL && autoclose_time != 0 && time_after(get_seconds(),
|
unsigned long x, y;
|
||||||
peer->login_sec + autoclose_time * 60);
|
if (peer == NULL || autoclose_time == 0)
|
||||||
|
return false;
|
||||||
|
x = ktime_get_seconds();
|
||||||
|
y = peer->login_sec + autoclose_time * 60;
|
||||||
|
return time_after(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -360,7 +338,12 @@ is_interknock_time_exceeded(const struct peer *peer, unsigned int max_time)
|
|||||||
static inline bool
|
static inline bool
|
||||||
has_logged_during_this_minute(const struct peer *peer)
|
has_logged_during_this_minute(const struct peer *peer)
|
||||||
{
|
{
|
||||||
return peer != NULL && peer->login_sec / 60 == get_seconds() / 60;
|
uint64_t x, y;
|
||||||
|
if (peer == NULL)
|
||||||
|
return 0;
|
||||||
|
x = ktime_get_seconds();
|
||||||
|
y = peer->login_sec;
|
||||||
|
return do_div(y, 60) == do_div(x, 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -368,11 +351,10 @@ has_logged_during_this_minute(const struct peer *peer)
|
|||||||
*
|
*
|
||||||
* @r: rule
|
* @r: rule
|
||||||
*/
|
*/
|
||||||
static void
|
static void peer_gc(struct timer_list *tl)
|
||||||
peer_gc(unsigned long r)
|
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
struct xt_pknock_rule *rule = (struct xt_pknock_rule *)r;
|
struct xt_pknock_rule *rule = from_timer(rule, tl, timer);
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
struct list_head *pos, *n;
|
struct list_head *pos, *n;
|
||||||
|
|
||||||
@@ -446,7 +428,6 @@ add_rule(struct xt_pknock_mtinfo *info)
|
|||||||
|
|
||||||
list_for_each_safe(pos, n, &rule_hashtable[hash]) {
|
list_for_each_safe(pos, n, &rule_hashtable[hash]) {
|
||||||
rule = list_entry(pos, struct xt_pknock_rule, head);
|
rule = list_entry(pos, struct xt_pknock_rule, head);
|
||||||
|
|
||||||
if (!rulecmp(info, rule))
|
if (!rulecmp(info, rule))
|
||||||
continue;
|
continue;
|
||||||
++rule->ref_count;
|
++rule->ref_count;
|
||||||
@@ -455,7 +436,6 @@ add_rule(struct xt_pknock_mtinfo *info)
|
|||||||
rule->max_time = info->max_time;
|
rule->max_time = info->max_time;
|
||||||
rule->autoclose_time = info->autoclose_time;
|
rule->autoclose_time = info->autoclose_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->option & XT_PKNOCK_CHECKIP)
|
if (info->option & XT_PKNOCK_CHECKIP)
|
||||||
pr_debug("add_rule() (AC) rule found: %s - "
|
pr_debug("add_rule() (AC) rule found: %s - "
|
||||||
"ref_count: %d\n",
|
"ref_count: %d\n",
|
||||||
@@ -463,34 +443,25 @@ add_rule(struct xt_pknock_mtinfo *info)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
rule = kmalloc(sizeof(*rule), GFP_KERNEL);
|
rule = kzalloc(sizeof(*rule), GFP_KERNEL);
|
||||||
if (rule == NULL)
|
if (rule == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&rule->head);
|
INIT_LIST_HEAD(&rule->head);
|
||||||
|
|
||||||
memset(rule->rule_name, 0, sizeof(rule->rule_name));
|
|
||||||
strncpy(rule->rule_name, info->rule_name, info->rule_name_len);
|
strncpy(rule->rule_name, info->rule_name, info->rule_name_len);
|
||||||
rule->rule_name_len = info->rule_name_len;
|
rule->rule_name_len = info->rule_name_len;
|
||||||
|
|
||||||
rule->ref_count = 1;
|
rule->ref_count = 1;
|
||||||
rule->max_time = info->max_time;
|
rule->max_time = info->max_time;
|
||||||
rule->autoclose_time = info->autoclose_time;
|
rule->autoclose_time = info->autoclose_time;
|
||||||
rule->peer_head = alloc_hashtable(peer_hashsize);
|
rule->peer_head = alloc_hashtable(peer_hashsize);
|
||||||
if (rule->peer_head == NULL)
|
if (rule->peer_head == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
timer_setup(&rule->timer, peer_gc, 0);
|
||||||
init_timer(&rule->timer);
|
rule->status_proc = proc_create_data(info->rule_name, 0, pde,
|
||||||
rule->timer.function = peer_gc;
|
&pknock_proc_ops, rule);
|
||||||
rule->timer.data = (unsigned long)rule;
|
|
||||||
|
|
||||||
rule->status_proc = create_proc_entry(info->rule_name, 0, pde);
|
|
||||||
if (rule->status_proc == NULL)
|
if (rule->status_proc == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rule->status_proc->proc_fops = &pknock_proc_ops;
|
|
||||||
rule->status_proc->data = rule;
|
|
||||||
|
|
||||||
list_add(&rule->head, &rule_hashtable[hash]);
|
list_add(&rule->head, &rule_hashtable[hash]);
|
||||||
pr_debug("(A) rule_name: %s - created.\n", rule->rule_name);
|
pr_debug("(A) rule_name: %s - created.\n", rule->rule_name);
|
||||||
return true;
|
return true;
|
||||||
@@ -521,7 +492,6 @@ remove_rule(struct xt_pknock_mtinfo *info)
|
|||||||
|
|
||||||
list_for_each_safe(pos, n, &rule_hashtable[hash]) {
|
list_for_each_safe(pos, n, &rule_hashtable[hash]) {
|
||||||
rule = list_entry(pos, struct xt_pknock_rule, head);
|
rule = list_entry(pos, struct xt_pknock_rule, head);
|
||||||
|
|
||||||
if (rulecmp(info, rule)) {
|
if (rulecmp(info, rule)) {
|
||||||
found = 1;
|
found = 1;
|
||||||
rule->ref_count--;
|
rule->ref_count--;
|
||||||
@@ -547,7 +517,6 @@ remove_rule(struct xt_pknock_mtinfo *info)
|
|||||||
pr_debug("(D) rule deleted: %s.\n", rule->rule_name);
|
pr_debug("(D) rule deleted: %s.\n", rule->rule_name);
|
||||||
if (timer_pending(&rule->timer))
|
if (timer_pending(&rule->timer))
|
||||||
del_timer(&rule->timer);
|
del_timer(&rule->timer);
|
||||||
|
|
||||||
list_del(&rule->head);
|
list_del(&rule->head);
|
||||||
kfree(rule->peer_head);
|
kfree(rule->peer_head);
|
||||||
kfree(rule);
|
kfree(rule);
|
||||||
@@ -567,7 +536,6 @@ static struct peer *get_peer(struct xt_pknock_rule *rule, __be32 ip)
|
|||||||
unsigned int hash;
|
unsigned int hash;
|
||||||
|
|
||||||
hash = pknock_hash(&ip, sizeof(ip), ipt_pknock_hash_rnd, peer_hashsize);
|
hash = pknock_hash(&ip, sizeof(ip), ipt_pknock_hash_rnd, peer_hashsize);
|
||||||
|
|
||||||
list_for_each_safe(pos, n, &rule->peer_head[hash]) {
|
list_for_each_safe(pos, n, &rule->peer_head[hash]) {
|
||||||
peer = list_entry(pos, struct peer, head);
|
peer = list_entry(pos, struct peer, head);
|
||||||
if (peer->ip == ip)
|
if (peer->ip == ip)
|
||||||
@@ -601,14 +569,12 @@ static struct peer *new_peer(__be32 ip, uint8_t proto)
|
|||||||
|
|
||||||
if (peer == NULL)
|
if (peer == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&peer->head);
|
INIT_LIST_HEAD(&peer->head);
|
||||||
peer->ip = ip;
|
peer->ip = ip;
|
||||||
peer->proto = proto;
|
peer->proto = proto;
|
||||||
peer->timestamp = jiffies/HZ;
|
peer->timestamp = jiffies/HZ;
|
||||||
peer->login_sec = 0;
|
peer->login_sec = 0;
|
||||||
reset_knock_status(peer);
|
reset_knock_status(peer);
|
||||||
|
|
||||||
return peer;
|
return peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -632,9 +598,10 @@ static void add_peer(struct peer *peer, struct xt_pknock_rule *rule)
|
|||||||
*/
|
*/
|
||||||
static void remove_peer(struct peer *peer)
|
static void remove_peer(struct peer *peer)
|
||||||
{
|
{
|
||||||
|
if (peer == NULL)
|
||||||
|
return;
|
||||||
list_del(&peer->head);
|
list_del(&peer->head);
|
||||||
if (peer != NULL)
|
kfree(peer);
|
||||||
kfree(peer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -695,31 +662,24 @@ static bool
|
|||||||
msg_to_userspace_nl(const struct xt_pknock_mtinfo *info,
|
msg_to_userspace_nl(const struct xt_pknock_mtinfo *info,
|
||||||
const struct peer *peer, int multicast_group)
|
const struct peer *peer, int multicast_group)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_CONNECTOR) || defined(CONFIG_CONNECTOR_MODULE)
|
#if IS_ENABLED(CONFIG_CONNECTOR)
|
||||||
struct cn_msg *m;
|
struct cn_msg *m;
|
||||||
struct xt_pknock_nl_msg msg;
|
struct xt_pknock_nl_msg msg;
|
||||||
|
|
||||||
m = kmalloc(sizeof(*m) + sizeof(msg), GFP_ATOMIC);
|
m = kzalloc(sizeof(*m) + sizeof(msg), GFP_ATOMIC);
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
memset(m, 0, sizeof(*m) + sizeof(msg));
|
|
||||||
m->seq = 0;
|
|
||||||
m->len = sizeof(msg);
|
m->len = sizeof(msg);
|
||||||
|
|
||||||
msg.peer_ip = peer->ip;
|
msg.peer_ip = peer->ip;
|
||||||
scnprintf(msg.rule_name, info->rule_name_len + 1, info->rule_name);
|
scnprintf(msg.rule_name, info->rule_name_len + 1, info->rule_name);
|
||||||
|
|
||||||
memcpy(m + 1, &msg, m->len);
|
memcpy(m + 1, &msg, m->len);
|
||||||
|
cn_netlink_send(m, 0, multicast_group, GFP_ATOMIC);
|
||||||
cn_netlink_send(m, multicast_group, GFP_ATOMIC);
|
|
||||||
|
|
||||||
kfree(m);
|
kfree(m);
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PK_CRYPTO
|
|
||||||
/**
|
/**
|
||||||
* Transforms a sequence of characters to hexadecimal.
|
* Transforms a sequence of characters to hexadecimal.
|
||||||
*
|
*
|
||||||
@@ -752,12 +712,12 @@ static bool
|
|||||||
has_secret(const unsigned char *secret, unsigned int secret_len, uint32_t ipsrc,
|
has_secret(const unsigned char *secret, unsigned int secret_len, uint32_t ipsrc,
|
||||||
const unsigned char *payload, unsigned int payload_len)
|
const unsigned char *payload, unsigned int payload_len)
|
||||||
{
|
{
|
||||||
struct scatterlist sg[2];
|
char result[64] = ""; // 64 bytes * 8 = 512 bits
|
||||||
char result[64]; // 64 bytes * 8 = 512 bits
|
|
||||||
char *hexresult;
|
char *hexresult;
|
||||||
unsigned int hexa_size;
|
unsigned int hexa_size;
|
||||||
int ret;
|
int ret;
|
||||||
bool fret = false;
|
bool fret = false;
|
||||||
|
uint64_t x;
|
||||||
unsigned int epoch_min;
|
unsigned int epoch_min;
|
||||||
|
|
||||||
if (payload_len == 0)
|
if (payload_len == 0)
|
||||||
@@ -773,23 +733,13 @@ has_secret(const unsigned char *secret, unsigned int secret_len, uint32_t ipsrc,
|
|||||||
/* + 1 cause we MUST add NULL in the payload */
|
/* + 1 cause we MUST add NULL in the payload */
|
||||||
if (payload_len != hexa_size + 1)
|
if (payload_len != hexa_size + 1)
|
||||||
return false;
|
return false;
|
||||||
|
hexresult = kzalloc(hexa_size, GFP_ATOMIC);
|
||||||
hexresult = kmalloc(hexa_size, GFP_ATOMIC);
|
|
||||||
if (hexresult == NULL)
|
if (hexresult == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
x = ktime_get_seconds();
|
||||||
|
epoch_min = do_div(x, 60);
|
||||||
|
|
||||||
memset(result, 0, sizeof(result));
|
ret = crypto_shash_setkey(crypto.tfm, secret, secret_len);
|
||||||
memset(hexresult, 0, hexa_size);
|
|
||||||
|
|
||||||
epoch_min = get_seconds() / 60;
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
|
|
||||||
sg_init_table(sg, ARRAY_SIZE(sg));
|
|
||||||
#endif
|
|
||||||
sg_set_buf(&sg[0], &ipsrc, sizeof(ipsrc));
|
|
||||||
sg_set_buf(&sg[1], &epoch_min, sizeof(epoch_min));
|
|
||||||
|
|
||||||
ret = crypto_hash_setkey(crypto.tfm, secret, secret_len);
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
printk("crypto_hash_setkey() failed ret=%d\n", ret);
|
printk("crypto_hash_setkey() failed ret=%d\n", ret);
|
||||||
goto out;
|
goto out;
|
||||||
@@ -800,25 +750,21 @@ has_secret(const unsigned char *secret, unsigned int secret_len, uint32_t ipsrc,
|
|||||||
* 4 bytes IP (32 bits) +
|
* 4 bytes IP (32 bits) +
|
||||||
* 4 bytes int epoch_min (32 bits)
|
* 4 bytes int epoch_min (32 bits)
|
||||||
*/
|
*/
|
||||||
ret = crypto_hash_digest(&crypto.desc, sg,
|
if ((ret = crypto_shash_update(&crypto.desc, (const void *)&ipsrc, sizeof(ipsrc))) != 0 ||
|
||||||
sizeof(ipsrc) + sizeof(epoch_min), result);
|
(ret = crypto_shash_update(&crypto.desc, (const void *)&epoch_min, sizeof(epoch_min))) != 0 ||
|
||||||
if (ret != 0) {
|
(ret = crypto_shash_final(&crypto.desc, result)) != 0) {
|
||||||
printk("crypto_hash_digest() failed ret=%d\n", ret);
|
printk("crypto_shash_update/final() failed ret=%d\n", ret);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
crypt_to_hex(hexresult, result, crypto.size);
|
crypt_to_hex(hexresult, result, crypto.size);
|
||||||
|
|
||||||
if (memcmp(hexresult, payload, hexa_size) != 0)
|
if (memcmp(hexresult, payload, hexa_size) != 0)
|
||||||
pr_debug("secret match failed\n");
|
pr_debug("secret match failed\n");
|
||||||
else
|
else
|
||||||
fret = true;
|
fret = true;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
kfree(hexresult);
|
kfree(hexresult);
|
||||||
return fret;
|
return fret;
|
||||||
}
|
}
|
||||||
#endif /* PK_CRYPTO */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the peer pass the security policy.
|
* If the peer pass the security policy.
|
||||||
@@ -841,14 +787,11 @@ pass_security(struct peer *peer, const struct xt_pknock_mtinfo *info,
|
|||||||
pk_debug("DENIED (anti-spoof protection)", peer);
|
pk_debug("DENIED (anti-spoof protection)", peer);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#ifdef PK_CRYPTO
|
|
||||||
/* Check for OPEN secret */
|
/* Check for OPEN secret */
|
||||||
if (has_secret(info->open_secret,
|
if (has_secret(info->open_secret,
|
||||||
info->open_secret_len, peer->ip,
|
info->open_secret_len, peer->ip,
|
||||||
payload, payload_len))
|
payload, payload_len))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -875,7 +818,6 @@ update_peer(struct peer *peer, const struct xt_pknock_mtinfo *info,
|
|||||||
/* Peer must start the sequence from scratch. */
|
/* Peer must start the sequence from scratch. */
|
||||||
if (info->option & XT_PKNOCK_STRICT)
|
if (info->option & XT_PKNOCK_STRICT)
|
||||||
remove_peer(peer);
|
remove_peer(peer);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -883,25 +825,20 @@ update_peer(struct peer *peer, const struct xt_pknock_mtinfo *info,
|
|||||||
if (info->option & XT_PKNOCK_OPENSECRET ) {
|
if (info->option & XT_PKNOCK_OPENSECRET ) {
|
||||||
if (hdr->proto != IPPROTO_UDP && hdr->proto != IPPROTO_UDPLITE)
|
if (hdr->proto != IPPROTO_UDP && hdr->proto != IPPROTO_UDPLITE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!pass_security(peer, info, hdr->payload, hdr->payload_len))
|
if (!pass_security(peer, info, hdr->payload, hdr->payload_len))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the gc timer when there is a state change. */
|
/* Update the gc timer when there is a state change. */
|
||||||
update_rule_gc_timer(rule);
|
update_rule_gc_timer(rule);
|
||||||
|
|
||||||
++peer->accepted_knock_count;
|
++peer->accepted_knock_count;
|
||||||
|
|
||||||
if (is_last_knock(peer, info)) {
|
if (is_last_knock(peer, info)) {
|
||||||
peer->status = ST_ALLOWED;
|
peer->status = ST_ALLOWED;
|
||||||
|
|
||||||
pk_debug("ALLOWED", peer);
|
pk_debug("ALLOWED", peer);
|
||||||
peer->login_sec = get_seconds();
|
peer->login_sec = ktime_get_seconds();
|
||||||
|
|
||||||
if (nl_multicast_group > 0)
|
if (nl_multicast_group > 0)
|
||||||
msg_to_userspace_nl(info, peer, nl_multicast_group);
|
msg_to_userspace_nl(info, peer, nl_multicast_group);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -939,7 +876,6 @@ static bool
|
|||||||
is_close_knock(const struct peer *peer, const struct xt_pknock_mtinfo *info,
|
is_close_knock(const struct peer *peer, const struct xt_pknock_mtinfo *info,
|
||||||
const unsigned char *payload, unsigned int payload_len)
|
const unsigned char *payload, unsigned int payload_len)
|
||||||
{
|
{
|
||||||
#ifdef PK_CRYPTO
|
|
||||||
/* Check for CLOSE secret. */
|
/* Check for CLOSE secret. */
|
||||||
if (has_secret(info->close_secret,
|
if (has_secret(info->close_secret,
|
||||||
info->close_secret_len, peer->ip,
|
info->close_secret_len, peer->ip,
|
||||||
@@ -948,7 +884,6 @@ is_close_knock(const struct peer *peer, const struct xt_pknock_mtinfo *info,
|
|||||||
pk_debug("BLOCKED", peer);
|
pk_debug("BLOCKED", peer);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -980,17 +915,10 @@ static bool pknock_mt(const struct sk_buff *skb,
|
|||||||
switch (hdr.proto) {
|
switch (hdr.proto) {
|
||||||
case IPPROTO_TCP:
|
case IPPROTO_TCP:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IPPROTO_UDP:
|
case IPPROTO_UDP:
|
||||||
case IPPROTO_UDPLITE:
|
case IPPROTO_UDPLITE:
|
||||||
#ifdef PK_CRYPTO
|
|
||||||
hdr_len = (iph->ihl * 4) + sizeof(struct udphdr);
|
hdr_len = (iph->ihl * 4) + sizeof(struct udphdr);
|
||||||
break;
|
break;
|
||||||
#else
|
|
||||||
pr_debug("UDP protocol not supported\n");
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
pr_debug("IP payload protocol is neither tcp nor udp.\n");
|
pr_debug("IP payload protocol is neither tcp nor udp.\n");
|
||||||
return false;
|
return false;
|
||||||
@@ -1008,12 +936,10 @@ static bool pknock_mt(const struct sk_buff *skb,
|
|||||||
|
|
||||||
/* Gives the peer matching status added to rule depending on ip src. */
|
/* Gives the peer matching status added to rule depending on ip src. */
|
||||||
peer = get_peer(rule, iph->saddr);
|
peer = get_peer(rule, iph->saddr);
|
||||||
|
|
||||||
if (info->option & XT_PKNOCK_CHECKIP) {
|
if (info->option & XT_PKNOCK_CHECKIP) {
|
||||||
ret = is_allowed(peer);
|
ret = is_allowed(peer);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iph->protocol == IPPROTO_UDP || iph->protocol == IPPROTO_UDPLITE) {
|
if (iph->protocol == IPPROTO_UDP || iph->protocol == IPPROTO_UDPLITE) {
|
||||||
hdr.payload = (void *)iph + hdr_len;
|
hdr.payload = (void *)iph + hdr_len;
|
||||||
hdr.payload_len = skb->len - hdr_len;
|
hdr.payload_len = skb->len - hdr_len;
|
||||||
@@ -1021,7 +947,8 @@ static bool pknock_mt(const struct sk_buff *skb,
|
|||||||
|
|
||||||
/* Sets, updates, removes or checks the peer matching status. */
|
/* Sets, updates, removes or checks the peer matching status. */
|
||||||
if (info->option & XT_PKNOCK_KNOCKPORT) {
|
if (info->option & XT_PKNOCK_KNOCKPORT) {
|
||||||
if ((ret = is_allowed(peer))) {
|
ret = is_allowed(peer);
|
||||||
|
if (ret != 0) {
|
||||||
if (info->option & XT_PKNOCK_CLOSESECRET &&
|
if (info->option & XT_PKNOCK_CLOSESECRET &&
|
||||||
(iph->protocol == IPPROTO_UDP ||
|
(iph->protocol == IPPROTO_UDP ||
|
||||||
iph->protocol == IPPROTO_UDPLITE))
|
iph->protocol == IPPROTO_UDPLITE))
|
||||||
@@ -1039,10 +966,8 @@ static bool pknock_mt(const struct sk_buff *skb,
|
|||||||
peer = new_peer(iph->saddr, iph->protocol);
|
peer = new_peer(iph->saddr, iph->protocol);
|
||||||
add_peer(peer, rule);
|
add_peer(peer, rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peer == NULL)
|
if (peer == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
update_peer(peer, info, rule, &hdr);
|
update_peer(peer, info, rule, &hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1062,7 +987,7 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RETURN_ERR(err) do { printk(KERN_ERR PKNOCK err); return -EINVAL; } while (false)
|
#define RETURN_ERR(err) do { pr_err(err); return -EINVAL; } while (false)
|
||||||
|
|
||||||
static int pknock_mt_check(const struct xt_mtchk_param *par)
|
static int pknock_mt_check(const struct xt_mtchk_param *par)
|
||||||
{
|
{
|
||||||
@@ -1079,12 +1004,6 @@ static int pknock_mt_check(const struct xt_mtchk_param *par)
|
|||||||
|
|
||||||
if (!(info->option & XT_PKNOCK_NAME))
|
if (!(info->option & XT_PKNOCK_NAME))
|
||||||
RETURN_ERR("You must specify --name option.\n");
|
RETURN_ERR("You must specify --name option.\n");
|
||||||
|
|
||||||
#ifndef PK_CRYPTO
|
|
||||||
if (info->option & (XT_PKNOCK_OPENSECRET | XT_PKNOCK_CLOSESECRET))
|
|
||||||
RETURN_ERR("No crypto support available; "
|
|
||||||
"cannot use opensecret/closescret\n");
|
|
||||||
#endif
|
|
||||||
if (info->option & XT_PKNOCK_OPENSECRET && info->ports_count != 1)
|
if (info->option & XT_PKNOCK_OPENSECRET && info->ports_count != 1)
|
||||||
RETURN_ERR("--opensecret must have just one knock port\n");
|
RETURN_ERR("--opensecret must have just one knock port\n");
|
||||||
if (info->option & XT_PKNOCK_KNOCKPORT) {
|
if (info->option & XT_PKNOCK_KNOCKPORT) {
|
||||||
@@ -1118,11 +1037,9 @@ static int pknock_mt_check(const struct xt_mtchk_param *par)
|
|||||||
memcmp(info->open_secret, info->close_secret,
|
memcmp(info->open_secret, info->close_secret,
|
||||||
info->open_secret_len) == 0)
|
info->open_secret_len) == 0)
|
||||||
RETURN_ERR("opensecret & closesecret cannot be equal.\n");
|
RETURN_ERR("opensecret & closesecret cannot be equal.\n");
|
||||||
|
|
||||||
if (!add_rule(info))
|
if (!add_rule(info))
|
||||||
/* should ENOMEM here */
|
/* should ENOMEM here */
|
||||||
RETURN_ERR("add_rule() error in checkentry() function.\n");
|
RETURN_ERR("add_rule() error in checkentry() function.\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1146,7 +1063,7 @@ static struct xt_match xt_pknock_mt_reg __read_mostly = {
|
|||||||
|
|
||||||
static int __init xt_pknock_mt_init(void)
|
static int __init xt_pknock_mt_init(void)
|
||||||
{
|
{
|
||||||
#if !defined(CONFIG_CONNECTOR) && !defined(CONFIG_CONNECTOR_MODULE)
|
#if !IS_ENABLED(CONFIG_CONNECTOR)
|
||||||
if (nl_multicast_group != -1)
|
if (nl_multicast_group != -1)
|
||||||
pr_info("CONFIG_CONNECTOR not present; "
|
pr_info("CONFIG_CONNECTOR not present; "
|
||||||
"netlink messages disabled\n");
|
"netlink messages disabled\n");
|
||||||
@@ -1154,30 +1071,25 @@ static int __init xt_pknock_mt_init(void)
|
|||||||
|
|
||||||
if (gc_expir_time < DEFAULT_GC_EXPIRATION_TIME)
|
if (gc_expir_time < DEFAULT_GC_EXPIRATION_TIME)
|
||||||
gc_expir_time = DEFAULT_GC_EXPIRATION_TIME;
|
gc_expir_time = DEFAULT_GC_EXPIRATION_TIME;
|
||||||
#ifdef PK_CRYPTO
|
|
||||||
if (request_module(crypto.algo) < 0) {
|
if (request_module(crypto.algo) < 0) {
|
||||||
printk(KERN_ERR PKNOCK "request_module('%s') error.\n",
|
pr_err("request_module('%s') error.\n",
|
||||||
crypto.algo);
|
crypto.algo);
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
crypto.tfm = crypto_alloc_hash(crypto.algo, 0, CRYPTO_ALG_ASYNC);
|
crypto.tfm = crypto_alloc_shash(crypto.algo, 0, 0);
|
||||||
if (IS_ERR(crypto.tfm)) {
|
if (IS_ERR(crypto.tfm)) {
|
||||||
printk(KERN_ERR PKNOCK "failed to load transform for %s\n",
|
pr_err("failed to load transform for %s\n",
|
||||||
crypto.algo);
|
crypto.algo);
|
||||||
return PTR_ERR(crypto.tfm);
|
return PTR_ERR(crypto.tfm);
|
||||||
}
|
}
|
||||||
|
|
||||||
crypto.size = crypto_hash_digestsize(crypto.tfm);
|
crypto.size = crypto_shash_digestsize(crypto.tfm);
|
||||||
crypto.desc.tfm = crypto.tfm;
|
crypto.desc.tfm = crypto.tfm;
|
||||||
crypto.desc.flags = 0;
|
|
||||||
#else
|
|
||||||
pr_info("No crypto support for < 2.6.19\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pde = proc_mkdir("xt_pknock", init_net__proc_net);
|
pde = proc_mkdir("xt_pknock", init_net.proc_net);
|
||||||
if (pde == NULL) {
|
if (pde == NULL) {
|
||||||
printk(KERN_ERR PKNOCK "proc_mkdir() error in _init().\n");
|
pr_err("proc_mkdir() error in _init().\n");
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
return xt_register_match(&xt_pknock_mt_reg);
|
return xt_register_match(&xt_pknock_mt_reg);
|
||||||
@@ -1185,14 +1097,11 @@ static int __init xt_pknock_mt_init(void)
|
|||||||
|
|
||||||
static void __exit xt_pknock_mt_exit(void)
|
static void __exit xt_pknock_mt_exit(void)
|
||||||
{
|
{
|
||||||
remove_proc_entry("xt_pknock", init_net__proc_net);
|
remove_proc_entry("xt_pknock", init_net.proc_net);
|
||||||
xt_unregister_match(&xt_pknock_mt_reg);
|
xt_unregister_match(&xt_pknock_mt_reg);
|
||||||
kfree(rule_hashtable);
|
kfree(rule_hashtable);
|
||||||
|
|
||||||
#ifdef PK_CRYPTO
|
|
||||||
if (crypto.tfm != NULL)
|
if (crypto.tfm != NULL)
|
||||||
crypto_free_hash(crypto.tfm);
|
crypto_free_shash(crypto.tfm);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(xt_pknock_mt_init);
|
module_init(xt_pknock_mt_init);
|
||||||
|
@@ -8,9 +8,7 @@
|
|||||||
*
|
*
|
||||||
* This program is released under the terms of GNU GPL version 2.
|
* This program is released under the terms of GNU GPL version 2.
|
||||||
*/
|
*/
|
||||||
#ifndef _XT_PKNOCK_H
|
#pragma once
|
||||||
#define _XT_PKNOCK_H
|
|
||||||
|
|
||||||
#define PKNOCK "xt_pknock: "
|
#define PKNOCK "xt_pknock: "
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -29,8 +27,6 @@ enum {
|
|||||||
XT_PKNOCK_MAX_PASSWD_LEN = 31,
|
XT_PKNOCK_MAX_PASSWD_LEN = 31,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEBUG 1
|
|
||||||
|
|
||||||
struct xt_pknock_mtinfo {
|
struct xt_pknock_mtinfo {
|
||||||
char rule_name[XT_PKNOCK_MAX_BUF_LEN+1];
|
char rule_name[XT_PKNOCK_MAX_BUF_LEN+1];
|
||||||
uint32_t rule_name_len;
|
uint32_t rule_name_len;
|
||||||
@@ -49,5 +45,3 @@ struct xt_pknock_nl_msg {
|
|||||||
char rule_name[XT_PKNOCK_MAX_BUF_LEN+1];
|
char rule_name[XT_PKNOCK_MAX_BUF_LEN+1];
|
||||||
__be32 peer_ip;
|
__be32 peer_ip;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _XT_PKNOCK_H */
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* "CHAOS" target extension for Xtables
|
* "CHAOS" target extension for Xtables
|
||||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2006 - 2008
|
* Copyright © Jan Engelhardt, 2006 - 2008
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License; either
|
* modify it under the terms of the GNU General Public License; either
|
||||||
@@ -54,33 +54,11 @@ xt_chaos_total(struct sk_buff *skb, const struct xt_action_param *par)
|
|||||||
const int fragoff = ntohs(iph->frag_off) & IP_OFFSET;
|
const int fragoff = ntohs(iph->frag_off) & IP_OFFSET;
|
||||||
typeof(xt_tarpit) destiny;
|
typeof(xt_tarpit) destiny;
|
||||||
bool ret;
|
bool ret;
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
|
||||||
int hotdrop = false;
|
|
||||||
#else
|
|
||||||
bool hotdrop = false;
|
bool hotdrop = false;
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
ret = xm_tcp->match(skb, par->in, par->out, xm_tcp, &tcp_params,
|
|
||||||
fragoff, thoff, &hotdrop);
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
|
|
||||||
{
|
|
||||||
struct xt_match_param local_par = {
|
|
||||||
.in = par->in,
|
|
||||||
.out = par->out,
|
|
||||||
.match = xm_tcp,
|
|
||||||
.matchinfo = &tcp_params,
|
|
||||||
.fragoff = fragoff,
|
|
||||||
.thoff = thoff,
|
|
||||||
.hotdrop = &hotdrop,
|
|
||||||
};
|
|
||||||
ret = xm_tcp->match(skb, &local_par);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
{
|
||||||
struct xt_action_param local_par;
|
struct xt_action_param local_par;
|
||||||
local_par.in = par->in,
|
local_par.state = par->state;
|
||||||
local_par.out = par->out,
|
|
||||||
local_par.match = xm_tcp;
|
local_par.match = xm_tcp;
|
||||||
local_par.matchinfo = &tcp_params;
|
local_par.matchinfo = &tcp_params;
|
||||||
local_par.fragoff = fragoff;
|
local_par.fragoff = fragoff;
|
||||||
@@ -89,45 +67,21 @@ xt_chaos_total(struct sk_buff *skb, const struct xt_action_param *par)
|
|||||||
ret = xm_tcp->match(skb, &local_par);
|
ret = xm_tcp->match(skb, &local_par);
|
||||||
hotdrop = local_par.hotdrop;
|
hotdrop = local_par.hotdrop;
|
||||||
}
|
}
|
||||||
#endif
|
if (!ret || hotdrop || (unsigned int)prandom_u32() > delude_percentage)
|
||||||
if (!ret || hotdrop || (unsigned int)net_random() > delude_percentage)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
destiny = (info->variant == XTCHAOS_TARPIT) ? xt_tarpit : xt_delude;
|
destiny = (info->variant == XTCHAOS_TARPIT) ? xt_tarpit : xt_delude;
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
|
||||||
destiny->target(&skb, par->in, par->out, par->hooknum, destiny, NULL, NULL);
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
|
||||||
destiny->target(&skb, par->in, par->out, par->hooknum, destiny, NULL);
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
destiny->target(skb, par->in, par->out, par->hooknum, destiny, NULL);
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
|
|
||||||
{
|
|
||||||
struct xt_target_param local_par = {
|
|
||||||
.in = par->in,
|
|
||||||
.out = par->out,
|
|
||||||
.hooknum = par->hooknum,
|
|
||||||
.target = destiny,
|
|
||||||
.targinfo = par->targinfo,
|
|
||||||
.family = par->family,
|
|
||||||
};
|
|
||||||
destiny->target(skb, &local_par);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
{
|
||||||
struct xt_action_param local_par;
|
struct xt_action_param local_par;
|
||||||
local_par.in = par->in;
|
local_par.state = par->state;
|
||||||
local_par.out = par->out;
|
|
||||||
local_par.hooknum = par->hooknum;
|
|
||||||
local_par.target = destiny;
|
local_par.target = destiny;
|
||||||
local_par.targinfo = par->targinfo;
|
local_par.targinfo = par->targinfo;
|
||||||
local_par.family = par->family;
|
|
||||||
destiny->target(skb, &local_par);
|
destiny->target(skb, &local_par);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
chaos_tg(struct sk_buff **pskb, const struct xt_action_param *par)
|
chaos_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Equivalent to:
|
* Equivalent to:
|
||||||
@@ -138,43 +92,19 @@ chaos_tg(struct sk_buff **pskb, const struct xt_action_param *par)
|
|||||||
* -A chaos -j DROP;
|
* -A chaos -j DROP;
|
||||||
*/
|
*/
|
||||||
const struct xt_chaos_tginfo *info = par->targinfo;
|
const struct xt_chaos_tginfo *info = par->targinfo;
|
||||||
struct sk_buff *skb = *pskb;
|
|
||||||
const struct iphdr *iph = ip_hdr(skb);
|
const struct iphdr *iph = ip_hdr(skb);
|
||||||
|
|
||||||
if ((unsigned int)net_random() <= reject_percentage) {
|
if ((unsigned int)prandom_u32() <= reject_percentage) {
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
|
||||||
return xt_reject->target(pskb, par->in, par->out, par->hooknum,
|
|
||||||
xt_reject, &reject_params, NULL);
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
|
||||||
return xt_reject->target(pskb, par->in, par->out, par->hooknum,
|
|
||||||
xt_reject, &reject_params);
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 27)
|
|
||||||
return xt_reject->target(skb, par->in, par->out, par->hooknum,
|
|
||||||
xt_reject, &reject_params);
|
|
||||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 34)
|
|
||||||
struct xt_target_param local_par = {
|
|
||||||
.in = par->in,
|
|
||||||
.out = par->out,
|
|
||||||
.hooknum = par->hooknum,
|
|
||||||
.target = xt_reject,
|
|
||||||
.targinfo = &reject_params,
|
|
||||||
};
|
|
||||||
return xt_reject->target(skb, &local_par);
|
|
||||||
#else
|
|
||||||
struct xt_action_param local_par;
|
struct xt_action_param local_par;
|
||||||
local_par.in = par->in;
|
local_par.state = par->state;
|
||||||
local_par.out = par->out;
|
|
||||||
local_par.hooknum = par->hooknum;
|
|
||||||
local_par.target = xt_reject;
|
local_par.target = xt_reject;
|
||||||
local_par.targinfo = &reject_params;
|
local_par.targinfo = &reject_params;
|
||||||
return xt_reject->target(skb, &local_par);
|
return xt_reject->target(skb, &local_par);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TARPIT/DELUDE may not be called from the OUTPUT chain */
|
/* TARPIT/DELUDE may not be called from the OUTPUT chain */
|
||||||
if (iph->protocol == IPPROTO_TCP &&
|
if (iph->protocol == IPPROTO_TCP && info->variant != XTCHAOS_NORMAL &&
|
||||||
info->variant != XTCHAOS_NORMAL &&
|
par->state->hook != NF_INET_LOCAL_OUT)
|
||||||
par->hooknum != NF_INET_LOCAL_OUT)
|
|
||||||
xt_chaos_total(skb, par);
|
xt_chaos_total(skb, par);
|
||||||
|
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
@@ -241,7 +171,8 @@ static int __init chaos_tg_init(void)
|
|||||||
printk(KERN_WARNING PFX "Warning: Could not find or load "
|
printk(KERN_WARNING PFX "Warning: Could not find or load "
|
||||||
"\"DELUDE\" target\n");
|
"\"DELUDE\" target\n");
|
||||||
|
|
||||||
if ((ret = xt_register_target(&chaos_tg_reg)) != 0) {
|
ret = xt_register_target(&chaos_tg_reg);
|
||||||
|
if (ret != 0) {
|
||||||
printk(KERN_WARNING PFX "xt_register_target returned "
|
printk(KERN_WARNING PFX "xt_register_target returned "
|
||||||
"error %d\n", ret);
|
"error %d\n", ret);
|
||||||
goto out3;
|
goto out3;
|
||||||
@@ -274,6 +205,6 @@ static void __exit chaos_tg_exit(void)
|
|||||||
module_init(chaos_tg_init);
|
module_init(chaos_tg_init);
|
||||||
module_exit(chaos_tg_exit);
|
module_exit(chaos_tg_exit);
|
||||||
MODULE_DESCRIPTION("Xtables: Network scan slowdown with non-deterministic results");
|
MODULE_DESCRIPTION("Xtables: Network scan slowdown with non-deterministic results");
|
||||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
MODULE_AUTHOR("Jan Engelhardt ");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_ALIAS("ipt_CHAOS");
|
MODULE_ALIAS("ipt_CHAOS");
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
#ifndef _LINUX_NETFILTER_XT_CHAOS_H
|
#pragma once
|
||||||
#define _LINUX_NETFILTER_XT_CHAOS_H 1
|
|
||||||
|
|
||||||
enum xt_chaos_target_variant {
|
enum xt_chaos_target_variant {
|
||||||
XTCHAOS_NORMAL,
|
XTCHAOS_NORMAL,
|
||||||
XTCHAOS_TARPIT,
|
XTCHAOS_TARPIT,
|
||||||
@@ -10,5 +8,3 @@ enum xt_chaos_target_variant {
|
|||||||
struct xt_chaos_tginfo {
|
struct xt_chaos_tginfo {
|
||||||
uint8_t variant;
|
uint8_t variant;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _LINUX_NETFILTER_XT_CHAOS_H */
|
|
||||||
|
@@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* (C) 2002 by Harald Welte <laforge@netfilter.org>
|
|
||||||
* (C) 2010 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* Author: Michael S. Tsirkin <mst@redhat.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.
|
|
||||||
*/
|
|
||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/skbuff.h>
|
|
||||||
#include <linux/version.h>
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
|
|
||||||
# error ----------------------------------------------------------
|
|
||||||
# error This module has been merged into, and is available in the
|
|
||||||
# error mainline since Linux kernel v2.6.36. Please use that.
|
|
||||||
# error ----------------------------------------------------------
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <linux/netfilter/x_tables.h>
|
|
||||||
#include "xt_CHECKSUM.h"
|
|
||||||
#include "compat_xtables.h"
|
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
MODULE_AUTHOR("Michael S. Tsirkin <mst@redhat.com>");
|
|
||||||
MODULE_DESCRIPTION("Xtables: checksum modification");
|
|
||||||
MODULE_ALIAS("ipt_CHECKSUM");
|
|
||||||
MODULE_ALIAS("ip6t_CHECKSUM");
|
|
||||||
|
|
||||||
static unsigned int
|
|
||||||
checksum_tg(struct sk_buff **pskb, const struct xt_action_param *par)
|
|
||||||
{
|
|
||||||
struct sk_buff *skb = *pskb;
|
|
||||||
|
|
||||||
if (skb->ip_summed == CHECKSUM_PARTIAL)
|
|
||||||
skb_checksum_help(skb);
|
|
||||||
|
|
||||||
return XT_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int checksum_tg_check(const struct xt_tgchk_param *par)
|
|
||||||
{
|
|
||||||
const struct xt_CHECKSUM_info *einfo = par->targinfo;
|
|
||||||
|
|
||||||
if (einfo->operation & ~XT_CHECKSUM_OP_FILL) {
|
|
||||||
pr_info("unsupported CHECKSUM operation %x\n", einfo->operation);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (!einfo->operation) {
|
|
||||||
pr_info("no CHECKSUM operation enabled\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct xt_target checksum_tg_reg __read_mostly = {
|
|
||||||
.name = "CHECKSUM",
|
|
||||||
.family = NFPROTO_UNSPEC,
|
|
||||||
.target = checksum_tg,
|
|
||||||
.targetsize = sizeof(struct xt_CHECKSUM_info),
|
|
||||||
.table = "mangle",
|
|
||||||
.checkentry = checksum_tg_check,
|
|
||||||
.me = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init checksum_tg_init(void)
|
|
||||||
{
|
|
||||||
return xt_register_target(&checksum_tg_reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit checksum_tg_exit(void)
|
|
||||||
{
|
|
||||||
xt_unregister_target(&checksum_tg_reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(checksum_tg_init);
|
|
||||||
module_exit(checksum_tg_exit);
|
|
@@ -1,18 +0,0 @@
|
|||||||
/* Header file for iptables ipt_CHECKSUM target
|
|
||||||
*
|
|
||||||
* (C) 2002 by Harald Welte <laforge@gnumonks.org>
|
|
||||||
* (C) 2010 Red Hat Inc
|
|
||||||
* Author: Michael S. Tsirkin <mst@redhat.com>
|
|
||||||
*
|
|
||||||
* This software is distributed under GNU GPL v2, 1991
|
|
||||||
*/
|
|
||||||
#ifndef _IPT_CHECKSUM_TARGET_H
|
|
||||||
#define _IPT_CHECKSUM_TARGET_H
|
|
||||||
|
|
||||||
#define XT_CHECKSUM_OP_FILL 0x01 /* fill in checksum in IP header */
|
|
||||||
|
|
||||||
struct xt_CHECKSUM_info {
|
|
||||||
__u8 operation; /* bitset of operations */
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _IPT_CHECKSUM_TARGET_H */
|
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* "DELUDE" target extension for Xtables
|
* "DELUDE" target extension for Xtables
|
||||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2007 - 2008
|
* Copyright © Jan Engelhardt, 2007 - 2008
|
||||||
*
|
*
|
||||||
* Based upon linux-2.6.18.5/net/ipv4/netfilter/ipt_REJECT.c:
|
* Based upon linux-2.6.18.5/net/ipv4/netfilter/ipt_REJECT.c:
|
||||||
* (C) 1999-2001 Paul `Rusty' Russell
|
* (C) 1999-2001 Paul `Rusty' Russell
|
||||||
@@ -25,7 +25,8 @@
|
|||||||
#include "compat_xtables.h"
|
#include "compat_xtables.h"
|
||||||
#define PFX KBUILD_MODNAME ": "
|
#define PFX KBUILD_MODNAME ": "
|
||||||
|
|
||||||
static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
|
static void delude_send_reset(struct sk_buff *oldskb,
|
||||||
|
const struct xt_action_param *par)
|
||||||
{
|
{
|
||||||
struct tcphdr _otcph, *tcph;
|
struct tcphdr _otcph, *tcph;
|
||||||
const struct tcphdr *oth;
|
const struct tcphdr *oth;
|
||||||
@@ -50,7 +51,8 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Check checksum */
|
/* Check checksum */
|
||||||
if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP))
|
if (nf_ip_checksum(oldskb, par->state->hook, ip_hdrlen(oldskb),
|
||||||
|
IPPROTO_TCP))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nskb = alloc_skb(sizeof(struct iphdr) + sizeof(struct tcphdr) +
|
nskb = alloc_skb(sizeof(struct iphdr) + sizeof(struct tcphdr) +
|
||||||
@@ -78,7 +80,7 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
|
|||||||
tcph->doff = sizeof(struct tcphdr) / 4;
|
tcph->doff = sizeof(struct tcphdr) / 4;
|
||||||
|
|
||||||
/* DELUDE essential part */
|
/* DELUDE essential part */
|
||||||
if (oth->syn && !oth->ack && !oth->rst && !oth->fin) {
|
if (oth->syn && !oth->ack && !oth->fin) {
|
||||||
tcph->syn = true;
|
tcph->syn = true;
|
||||||
tcph->seq = 0;
|
tcph->seq = 0;
|
||||||
tcph->ack = true;
|
tcph->ack = true;
|
||||||
@@ -100,29 +102,28 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 20)
|
|
||||||
tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr), niph->saddr,
|
|
||||||
niph->daddr, csum_partial((char *)tcph,
|
|
||||||
sizeof(struct tcphdr), 0));
|
|
||||||
#else
|
|
||||||
tcph->check = tcp_v4_check(sizeof(struct tcphdr), niph->saddr,
|
tcph->check = tcp_v4_check(sizeof(struct tcphdr), niph->saddr,
|
||||||
niph->daddr, csum_partial((char *)tcph,
|
niph->daddr, csum_partial((char *)tcph,
|
||||||
sizeof(struct tcphdr), 0));
|
sizeof(struct tcphdr), 0));
|
||||||
#endif
|
|
||||||
|
|
||||||
addr_type = RTN_UNSPEC;
|
addr_type = RTN_UNSPEC;
|
||||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||||
if (hook != NF_INET_FORWARD || (nskb->nf_bridge != NULL &&
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
nskb->nf_bridge->mask & BRNF_BRIDGED))
|
if (par->state->hook != NF_INET_FORWARD ||
|
||||||
|
((struct nf_bridge_info *)skb_ext_find(nskb, SKB_EXT_BRIDGE_NF) != NULL &&
|
||||||
|
((struct nf_bridge_info *)skb_ext_find(nskb, SKB_EXT_BRIDGE_NF))->physoutdev))
|
||||||
#else
|
#else
|
||||||
if (hook != NF_INET_FORWARD)
|
if (par->state->hook != NF_INET_FORWARD || (nskb->nf_bridge != NULL &&
|
||||||
|
nskb->nf_bridge->physoutdev))
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
if (par->state->hook != NF_INET_FORWARD)
|
||||||
#endif
|
#endif
|
||||||
addr_type = RTN_LOCAL;
|
addr_type = RTN_LOCAL;
|
||||||
|
|
||||||
/* ip_route_me_harder expects skb->dst to be set */
|
/* ip_route_me_harder expects skb->dst to be set */
|
||||||
skb_dst_set(nskb, dst_clone(skb_dst(oldskb)));
|
skb_dst_set(nskb, dst_clone(skb_dst(oldskb)));
|
||||||
|
if (ip_route_me_harder(par_net(par), par->state->sk, nskb, addr_type))
|
||||||
if (ip_route_me_harder(&nskb, addr_type))
|
|
||||||
goto free_nskb;
|
goto free_nskb;
|
||||||
else
|
else
|
||||||
niph = ip_hdr(nskb);
|
niph = ip_hdr(nskb);
|
||||||
@@ -135,8 +136,7 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
|
|||||||
goto free_nskb;
|
goto free_nskb;
|
||||||
|
|
||||||
nf_ct_attach(nskb, oldskb);
|
nf_ct_attach(nskb, oldskb);
|
||||||
|
ip_local_out(par_net(par), nskb->sk, nskb);
|
||||||
ip_local_out(nskb);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
free_nskb:
|
free_nskb:
|
||||||
@@ -144,12 +144,14 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
delude_tg(struct sk_buff **pskb, const struct xt_action_param *par)
|
delude_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
||||||
{
|
{
|
||||||
/* WARNING: This code causes reentry within iptables.
|
/*
|
||||||
This means that the iptables jump stack is now crap. We
|
* Sending the reset causes reentrancy within iptables - and should not pose
|
||||||
must return an absolute verdict. --RR */
|
* a problem, as that is supported since Linux 2.6.35. But since we do not
|
||||||
delude_send_reset(*pskb, par->hooknum);
|
* actually want to have a connection open, we are still going to drop it.
|
||||||
|
*/
|
||||||
|
delude_send_reset(skb, par);
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,6 +179,6 @@ static void __exit delude_tg_exit(void)
|
|||||||
module_init(delude_tg_init);
|
module_init(delude_tg_init);
|
||||||
module_exit(delude_tg_exit);
|
module_exit(delude_tg_exit);
|
||||||
MODULE_DESCRIPTION("Xtables: Close TCP connections after handshake");
|
MODULE_DESCRIPTION("Xtables: Close TCP connections after handshake");
|
||||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
MODULE_AUTHOR("Jan Engelhardt ");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_ALIAS("ipt_DELUDE");
|
MODULE_ALIAS("ipt_DELUDE");
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* "DHCPMAC" extensions for Xtables
|
* "DHCPMAC" extensions for Xtables
|
||||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
* Copyright © Jan Engelhardt, 2008
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License; either
|
* modify it under the terms of the GNU General Public License; either
|
||||||
@@ -34,9 +34,9 @@ static void ether_set(unsigned char *addr, const unsigned char *op,
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < ETH_ALEN && mask > 0; ++i) {
|
for (i = 0; i < ETH_ALEN && mask > 0; ++i) {
|
||||||
lo_mask = mask % 8;
|
lo_mask = (mask >= 8) ? 8 : mask;
|
||||||
/* FF << 4 >> 4 = 0F */
|
/* FF << 4 >> 4 = 0F */
|
||||||
lo_mask = ~(uint8_t)0U << lo_mask >> lo_mask;
|
lo_mask = (uint8_t)(~0U << lo_mask) >> lo_mask;
|
||||||
addr[i] &= lo_mask;
|
addr[i] &= lo_mask;
|
||||||
addr[i] |= op[i] & ~lo_mask;
|
addr[i] |= op[i] & ~lo_mask;
|
||||||
if (mask >= 8)
|
if (mask >= 8)
|
||||||
@@ -55,9 +55,9 @@ static bool ether_cmp(const unsigned char *lh, const unsigned char *rh,
|
|||||||
#define ZMACHEX(s) s[0], s[1], s[2], s[3], s[4], s[5]
|
#define ZMACHEX(s) s[0], s[1], s[2], s[3], s[4], s[5]
|
||||||
|
|
||||||
for (i = 0; i < ETH_ALEN && mask > 0; ++i) {
|
for (i = 0; i < ETH_ALEN && mask > 0; ++i) {
|
||||||
lo_mask = mask % 8;
|
lo_mask = (mask >= 8) ? 8 : mask;
|
||||||
/* ~(0xFF << 4 >> 4) = ~0x0F = 0xF0 */
|
/* ~(0xFF << 4 >> 4) = ~0x0F = 0xF0 */
|
||||||
lo_mask = ~(~(uint8_t)0U << lo_mask >> lo_mask);
|
lo_mask = ~((uint8_t)(~0U << lo_mask) >> lo_mask);
|
||||||
if ((lh[i] ^ rh[i]) & lo_mask)
|
if ((lh[i] ^ rh[i]) & lo_mask)
|
||||||
return false;
|
return false;
|
||||||
if (mask >= 8)
|
if (mask >= 8)
|
||||||
@@ -89,15 +89,15 @@ dhcpmac_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
dhcpmac_tg(struct sk_buff **pskb, const struct xt_action_param *par)
|
dhcpmac_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
||||||
{
|
{
|
||||||
const struct dhcpmac_info *info = par->targinfo;
|
const struct dhcpmac_info *info = par->targinfo;
|
||||||
struct dhcp_message dhcpbuf, *dh;
|
struct dhcp_message dhcpbuf, *dh;
|
||||||
struct udphdr udpbuf, *udph;
|
struct udphdr udpbuf, *udph;
|
||||||
struct sk_buff *skb = *pskb;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (!skb_make_writable(pskb, 0))
|
if (skb_ensure_writable(skb, ip_hdrlen(skb) + sizeof(udpbuf) +
|
||||||
|
sizeof(dhcpbuf)))
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
|
|
||||||
udph = skb_header_pointer(skb, ip_hdrlen(skb),
|
udph = skb_header_pointer(skb, ip_hdrlen(skb),
|
||||||
@@ -111,13 +111,12 @@ dhcpmac_tg(struct sk_buff **pskb, const struct xt_action_param *par)
|
|||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
|
|
||||||
for (i = 0; i < sizeof(dh->chaddr); i += 2)
|
for (i = 0; i < sizeof(dh->chaddr); i += 2)
|
||||||
csum_replace2(&udph->check, *(const __be16 *)dh->chaddr, 0);
|
csum_replace2(&udph->check, *(const __be16 *)(dh->chaddr + i), 0);
|
||||||
|
|
||||||
memset(dh->chaddr, 0, sizeof(dh->chaddr));
|
|
||||||
ether_set(dh->chaddr, info->addr, info->mask);
|
ether_set(dh->chaddr, info->addr, info->mask);
|
||||||
|
|
||||||
for (i = 0; i < sizeof(dh->chaddr); i += 2)
|
for (i = 0; i < sizeof(dh->chaddr); i += 2)
|
||||||
csum_replace2(&udph->check, 0, *(const __be16 *)dh->chaddr);
|
csum_replace2(&udph->check, 0, *(const __be16 *)(dh->chaddr + i));
|
||||||
|
|
||||||
return XT_CONTINUE;
|
return XT_CONTINUE;
|
||||||
}
|
}
|
||||||
@@ -167,7 +166,7 @@ static void __exit dhcpmac_exit(void)
|
|||||||
module_init(dhcpmac_init);
|
module_init(dhcpmac_init);
|
||||||
module_exit(dhcpmac_exit);
|
module_exit(dhcpmac_exit);
|
||||||
MODULE_DESCRIPTION("Xtables: Clamp DHCP MAC to packet MAC addresses");
|
MODULE_DESCRIPTION("Xtables: Clamp DHCP MAC to packet MAC addresses");
|
||||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
MODULE_AUTHOR("Jan Engelhardt ");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_ALIAS("ipt_DHCPMAC");
|
MODULE_ALIAS("ipt_DHCPMAC");
|
||||||
MODULE_ALIAS("ipt_dhcpmac");
|
MODULE_ALIAS("ipt_dhcpmac");
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
#ifndef _LINUX_NETFILTER_XT_DHCPMAC_H
|
#pragma once
|
||||||
#define _LINUX_NETFILTER_XT_DHCPMAC_H 1
|
|
||||||
|
|
||||||
#define DH_MAC_FMT "%02X:%02X:%02X:%02X:%02X:%02X"
|
#define DH_MAC_FMT "%02X:%02X:%02X:%02X:%02X:%02X"
|
||||||
#define DH_MAC_HEX(z) z[0], z[1], z[2], z[3], z[4], z[5]
|
#define DH_MAC_HEX(z) z[0], z[1], z[2], z[3], z[4], z[5]
|
||||||
|
|
||||||
@@ -8,5 +6,3 @@ struct dhcpmac_info {
|
|||||||
unsigned char addr[ETH_ALEN];
|
unsigned char addr[ETH_ALEN];
|
||||||
uint8_t mask, invert;
|
uint8_t mask, invert;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _LINUX_NETFILTER_XT_DHCPMAC_H */
|
|
||||||
|
@@ -19,33 +19,24 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
#include <linux/module.h>
|
||||||
|
#ifdef CONFIG_NF_NAT
|
||||||
#include <linux/inet.h>
|
#include <linux/inet.h>
|
||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <linux/netfilter.h>
|
#include <linux/netfilter.h>
|
||||||
#include <linux/netfilter_ipv4.h>
|
#include <linux/netfilter_ipv4.h>
|
||||||
#include <linux/netfilter/x_tables.h>
|
#include <linux/netfilter/x_tables.h>
|
||||||
|
#include <linux/proc_fs.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
|
#include <linux/uidgid.h>
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
#include <net/netfilter/nf_nat_rule.h>
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
|
|
||||||
#include <net/net_namespace.h>
|
#include <net/net_namespace.h>
|
||||||
#include <net/netns/generic.h>
|
#include <net/netns/generic.h>
|
||||||
#endif
|
#include <net/netfilter/nf_nat.h>
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
|
|
||||||
# include <net/netfilter/nf_nat.h>
|
|
||||||
#else
|
|
||||||
# include <linux/netfilter/nf_nat.h>
|
|
||||||
#endif
|
|
||||||
#include "compat_xtables.h"
|
#include "compat_xtables.h"
|
||||||
#include "xt_DNETMAP.h"
|
#include "xt_DNETMAP.h"
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
MODULE_AUTHOR("Marek Kierdelewicz <marek@piasta.pl>");
|
|
||||||
MODULE_DESCRIPTION(
|
|
||||||
"Xtables: dynamic two-way 1:1 NAT mapping of IPv4 addresses");
|
|
||||||
MODULE_ALIAS("ipt_DNETMAP");
|
|
||||||
|
|
||||||
static unsigned int default_ttl = 600;
|
static unsigned int default_ttl = 600;
|
||||||
static unsigned int proc_perms = S_IRUGO | S_IWUSR;
|
static unsigned int proc_perms = S_IRUGO | S_IWUSR;
|
||||||
static unsigned int proc_uid;
|
static unsigned int proc_uid;
|
||||||
@@ -70,25 +61,18 @@ MODULE_PARM_DESC(whole_prefix,
|
|||||||
static unsigned int jtimeout;
|
static unsigned int jtimeout;
|
||||||
|
|
||||||
struct dnetmap_entry {
|
struct dnetmap_entry {
|
||||||
struct list_head list;
|
struct list_head list, glist, grlist, lru_list;
|
||||||
/* priv2entry */
|
__be32 prenat_addr, postnat_addr;
|
||||||
struct list_head glist;
|
|
||||||
/* pub2entry */
|
|
||||||
struct list_head grlist;
|
|
||||||
struct list_head lru_list;
|
|
||||||
__be32 prenat_addr;
|
|
||||||
__be32 postnat_addr;
|
|
||||||
__u8 flags;
|
__u8 flags;
|
||||||
unsigned long stamp;
|
unsigned long stamp;
|
||||||
struct dnetmap_prefix *prefix;
|
struct dnetmap_prefix *prefix;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dnetmap_prefix {
|
struct dnetmap_prefix {
|
||||||
struct nf_nat_ipv4_multi_range_compat prefix;
|
struct nf_nat_range prefix;
|
||||||
char prefix_str[16];
|
char prefix_str[20];
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
char proc_str_data[20];
|
char proc_str_data[20], proc_str_stat[25];
|
||||||
char proc_str_stat[25];
|
|
||||||
#endif
|
#endif
|
||||||
struct list_head elist; // element list head
|
struct list_head elist; // element list head
|
||||||
struct list_head list; // prefix list
|
struct list_head list; // prefix list
|
||||||
@@ -109,28 +93,19 @@ struct dnetmap_net {
|
|||||||
struct list_head *dnetmap_iphash;
|
struct list_head *dnetmap_iphash;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
|
|
||||||
static int dnetmap_net_id;
|
static int dnetmap_net_id;
|
||||||
static inline struct dnetmap_net *dnetmap_pernet(struct net *net)
|
static inline struct dnetmap_net *dnetmap_pernet(struct net *net)
|
||||||
{
|
{
|
||||||
return net_generic(net, dnetmap_net_id);
|
return net_generic(net, dnetmap_net_id);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
struct dnetmap_net *dnetmap;
|
|
||||||
#define dnetmap_pernet(x) dnetmap
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(dnetmap_lock);
|
static DEFINE_SPINLOCK(dnetmap_lock);
|
||||||
static DEFINE_MUTEX(dnetmap_mutex);
|
static DEFINE_MUTEX(dnetmap_mutex);
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
static const struct file_operations dnetmap_tg_fops;
|
static const struct proc_ops dnetmap_tg_fops, dnetmap_stat_proc_fops;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int dnetmap_stat_proc_read(char __user *buffer, char **start,
|
|
||||||
off_t offset, int length, int *eof,
|
|
||||||
void *data);
|
|
||||||
|
|
||||||
static inline unsigned int dnetmap_entry_hash(const __be32 addr)
|
static inline unsigned int dnetmap_entry_hash(const __be32 addr)
|
||||||
{
|
{
|
||||||
return ntohl(addr) & (hash_size - 1);
|
return ntohl(addr) & (hash_size - 1);
|
||||||
@@ -140,9 +115,7 @@ static struct dnetmap_entry *
|
|||||||
dnetmap_entry_lookup(struct dnetmap_net *dnetmap_net, const __be32 addr)
|
dnetmap_entry_lookup(struct dnetmap_net *dnetmap_net, const __be32 addr)
|
||||||
{
|
{
|
||||||
struct dnetmap_entry *e;
|
struct dnetmap_entry *e;
|
||||||
unsigned int h;
|
unsigned int h = dnetmap_entry_hash(addr);
|
||||||
|
|
||||||
h = dnetmap_entry_hash(addr);
|
|
||||||
|
|
||||||
list_for_each_entry(e, &dnetmap_net->dnetmap_iphash[h], glist)
|
list_for_each_entry(e, &dnetmap_net->dnetmap_iphash[h], glist)
|
||||||
if (memcmp(&e->prenat_addr, &addr, sizeof(addr)) == 0)
|
if (memcmp(&e->prenat_addr, &addr, sizeof(addr)) == 0)
|
||||||
@@ -154,9 +127,7 @@ static struct dnetmap_entry *
|
|||||||
dnetmap_entry_rlookup(struct dnetmap_net *dnetmap_net, const __be32 addr)
|
dnetmap_entry_rlookup(struct dnetmap_net *dnetmap_net, const __be32 addr)
|
||||||
{
|
{
|
||||||
struct dnetmap_entry *e;
|
struct dnetmap_entry *e;
|
||||||
unsigned int h;
|
unsigned int h = dnetmap_entry_hash(addr);
|
||||||
|
|
||||||
h = dnetmap_entry_hash(addr);
|
|
||||||
|
|
||||||
list_for_each_entry(e, &dnetmap_net->dnetmap_iphash[hash_size + h],
|
list_for_each_entry(e, &dnetmap_net->dnetmap_iphash[hash_size + h],
|
||||||
grlist)
|
grlist)
|
||||||
@@ -179,7 +150,7 @@ dnetmap_addr_in_prefix(struct dnetmap_net *dnetmap_net, const __be32 addr,
|
|||||||
|
|
||||||
static struct dnetmap_prefix *
|
static struct dnetmap_prefix *
|
||||||
dnetmap_prefix_lookup(struct dnetmap_net *dnetmap_net,
|
dnetmap_prefix_lookup(struct dnetmap_net *dnetmap_net,
|
||||||
const struct nf_nat_ipv4_multi_range_compat *mr)
|
const struct nf_nat_range *mr)
|
||||||
{
|
{
|
||||||
struct dnetmap_prefix *p;
|
struct dnetmap_prefix *p;
|
||||||
|
|
||||||
@@ -258,7 +229,7 @@ static int dnetmap_tg_check(const struct xt_tgchk_param *par)
|
|||||||
{
|
{
|
||||||
struct dnetmap_net *dnetmap_net = dnetmap_pernet(par->net);
|
struct dnetmap_net *dnetmap_net = dnetmap_pernet(par->net);
|
||||||
const struct xt_DNETMAP_tginfo *tginfo = par->targinfo;
|
const struct xt_DNETMAP_tginfo *tginfo = par->targinfo;
|
||||||
const struct nf_nat_ipv4_multi_range_compat *mr = &tginfo->prefix;
|
const struct nf_nat_range *mr = &tginfo->prefix;
|
||||||
struct dnetmap_prefix *p;
|
struct dnetmap_prefix *p;
|
||||||
struct dnetmap_entry *e;
|
struct dnetmap_entry *e;
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
@@ -274,14 +245,10 @@ static int dnetmap_tg_check(const struct xt_tgchk_param *par)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(mr->range[0].flags & NF_NAT_RANGE_MAP_IPS)) {
|
if (!(mr->flags & NF_NAT_RANGE_MAP_IPS)) {
|
||||||
pr_debug("DNETMAP:check: bad MAP_IPS.\n");
|
pr_debug("DNETMAP:check: bad MAP_IPS.\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (mr->rangesize != 1) {
|
|
||||||
pr_debug("DNETMAP:check: bad rangesize %u.\n", mr->rangesize);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_lock(&dnetmap_mutex);
|
mutex_lock(&dnetmap_mutex);
|
||||||
p = dnetmap_prefix_lookup(dnetmap_net, mr);
|
p = dnetmap_prefix_lookup(dnetmap_net, mr);
|
||||||
@@ -307,15 +274,15 @@ static int dnetmap_tg_check(const struct xt_tgchk_param *par)
|
|||||||
INIT_LIST_HEAD(&p->lru_list);
|
INIT_LIST_HEAD(&p->lru_list);
|
||||||
INIT_LIST_HEAD(&p->elist);
|
INIT_LIST_HEAD(&p->elist);
|
||||||
|
|
||||||
ip_min = ntohl(mr->range[0].min_ip) + (whole_prefix == 0);
|
ip_min = ntohl(mr->min_addr.ip) + (whole_prefix == 0);
|
||||||
ip_max = ntohl(mr->range[0].max_ip) - (whole_prefix == 0);
|
ip_max = ntohl(mr->max_addr.ip) - (whole_prefix == 0);
|
||||||
|
|
||||||
sprintf(p->prefix_str, NIPQUAD_FMT "/%u", NIPQUAD(mr->range[0].min_ip),
|
sprintf(p->prefix_str, "%pI4/%u", &mr->min_addr.ip,
|
||||||
33 - ffs(~(ip_min ^ ip_max)));
|
33 - ffs(~(ip_min ^ ip_max)));
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
sprintf(p->proc_str_data, NIPQUAD_FMT "_%u", NIPQUAD(mr->range[0].min_ip),
|
sprintf(p->proc_str_data, "%pI4_%u", &mr->min_addr.ip,
|
||||||
33 - ffs(~(ip_min ^ ip_max)));
|
33 - ffs(~(ip_min ^ ip_max)));
|
||||||
sprintf(p->proc_str_stat, NIPQUAD_FMT "_%u_stat", NIPQUAD(mr->range[0].min_ip),
|
sprintf(p->proc_str_stat, "%pI4_%u_stat", &mr->min_addr.ip,
|
||||||
33 - ffs(~(ip_min ^ ip_max)));
|
33 - ffs(~(ip_min ^ ip_max)));
|
||||||
#endif
|
#endif
|
||||||
printk(KERN_INFO KBUILD_MODNAME ": new prefix %s\n", p->prefix_str);
|
printk(KERN_INFO KBUILD_MODNAME ": new prefix %s\n", p->prefix_str);
|
||||||
@@ -344,21 +311,20 @@ static int dnetmap_tg_check(const struct xt_tgchk_param *par)
|
|||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
pde_data->uid = proc_uid;
|
proc_set_user(pde_data, make_kuid(&init_user_ns, proc_uid),
|
||||||
pde_data->gid = proc_gid;
|
make_kgid(&init_user_ns, proc_gid));
|
||||||
|
|
||||||
/* statistics */
|
/* statistics */
|
||||||
pde_stat = create_proc_entry(p->proc_str_stat, proc_perms,
|
pde_stat = proc_create_data(p->proc_str_stat, proc_perms,
|
||||||
dnetmap_net->xt_dnetmap);
|
dnetmap_net->xt_dnetmap,
|
||||||
|
&dnetmap_stat_proc_fops, p);
|
||||||
if (pde_stat == NULL) {
|
if (pde_stat == NULL) {
|
||||||
kfree(p);
|
kfree(p);
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
pde_stat->data = p;
|
proc_set_user(pde_stat, make_kuid(&init_user_ns, proc_uid),
|
||||||
pde_stat->read_proc = dnetmap_stat_proc_read;
|
make_kgid(&init_user_ns, proc_gid));
|
||||||
pde_stat->uid = proc_uid;
|
|
||||||
pde_stat->gid = proc_gid;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
spin_lock_bh(&dnetmap_lock);
|
spin_lock_bh(&dnetmap_lock);
|
||||||
@@ -372,30 +338,27 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
dnetmap_tg(struct sk_buff **pskb, const struct xt_action_param *par)
|
dnetmap_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb = *pskb;
|
struct net *net = dev_net(par->state->in ? par->state->in : par->state->out);
|
||||||
struct net *net = dev_net(par->in ? par->in : par->out);
|
|
||||||
struct dnetmap_net *dnetmap_net = dnetmap_pernet(net);
|
struct dnetmap_net *dnetmap_net = dnetmap_pernet(net);
|
||||||
struct nf_conn *ct;
|
|
||||||
enum ip_conntrack_info ctinfo;
|
enum ip_conntrack_info ctinfo;
|
||||||
__be32 prenat_ip, postnat_ip, prenat_ip_prev;
|
__be32 prenat_ip, postnat_ip, prenat_ip_prev;
|
||||||
const struct xt_DNETMAP_tginfo *tginfo = par->targinfo;
|
const struct xt_DNETMAP_tginfo *tginfo = par->targinfo;
|
||||||
const struct nf_nat_ipv4_multi_range_compat *mr = &tginfo->prefix;
|
const struct nf_nat_range *mr = &tginfo->prefix;
|
||||||
struct nf_nat_ipv4_range newrange;
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)
|
||||||
|
struct nf_nat_range2 newrange;
|
||||||
|
#else
|
||||||
|
struct nf_nat_range newrange;
|
||||||
|
#endif
|
||||||
struct dnetmap_entry *e;
|
struct dnetmap_entry *e;
|
||||||
struct dnetmap_prefix *p;
|
struct dnetmap_prefix *p;
|
||||||
__s32 jttl;
|
unsigned int hooknum = par->state->hook;
|
||||||
|
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
|
||||||
NF_CT_ASSERT(par->hooknum == NF_INET_POST_ROUTING ||
|
__s32 jttl = tginfo->flags & XT_DNETMAP_TTL ? tginfo->ttl * HZ : jtimeout;
|
||||||
par->hooknum == NF_INET_LOCAL_OUT ||
|
|
||||||
par->hooknum == NF_INET_PRE_ROUTING);
|
|
||||||
ct = nf_ct_get(skb, &ctinfo);
|
|
||||||
|
|
||||||
jttl = tginfo->flags & XT_DNETMAP_TTL ? tginfo->ttl * HZ : jtimeout;
|
|
||||||
|
|
||||||
/* in prerouting we try to map postnat-ip to prenat-ip */
|
/* in prerouting we try to map postnat-ip to prenat-ip */
|
||||||
if (par->hooknum == NF_INET_PRE_ROUTING) {
|
if (hooknum == NF_INET_PRE_ROUTING) {
|
||||||
postnat_ip = ip_hdr(skb)->daddr;
|
postnat_ip = ip_hdr(skb)->daddr;
|
||||||
|
|
||||||
spin_lock_bh(&dnetmap_lock);
|
spin_lock_bh(&dnetmap_lock);
|
||||||
@@ -408,7 +371,7 @@ dnetmap_tg(struct sk_buff **pskb, const struct xt_action_param *par)
|
|||||||
/* if prefix is specified, we check if
|
/* if prefix is specified, we check if
|
||||||
it matches lookedup entry */
|
it matches lookedup entry */
|
||||||
if (tginfo->flags & XT_DNETMAP_PREFIX)
|
if (tginfo->flags & XT_DNETMAP_PREFIX)
|
||||||
if (memcmp(mr, &e->prefix, sizeof(*mr)))
|
if (memcmp(mr, &e->prefix->prefix, sizeof(*mr)))
|
||||||
goto no_rev_map;
|
goto no_rev_map;
|
||||||
/* don't reset ttl if flag is set */
|
/* don't reset ttl if flag is set */
|
||||||
if (jttl >= 0 && (! (e->flags & XT_DNETMAP_STATIC) ) ) {
|
if (jttl >= 0 && (! (e->flags & XT_DNETMAP_STATIC) ) ) {
|
||||||
@@ -419,15 +382,14 @@ dnetmap_tg(struct sk_buff **pskb, const struct xt_action_param *par)
|
|||||||
|
|
||||||
spin_unlock_bh(&dnetmap_lock);
|
spin_unlock_bh(&dnetmap_lock);
|
||||||
|
|
||||||
newrange = ((struct nf_nat_ipv4_range) {
|
memset(&newrange, 0, sizeof(newrange));
|
||||||
mr->range[0].flags | NF_NAT_RANGE_MAP_IPS,
|
newrange.flags = mr->flags | NF_NAT_RANGE_MAP_IPS;
|
||||||
e->prenat_addr, e->prenat_addr,
|
newrange.min_addr.ip = e->prenat_addr;
|
||||||
mr->range[0].min, mr->range[0].max});
|
newrange.max_addr.ip = e->prenat_addr;
|
||||||
|
newrange.min_proto = mr->min_proto;
|
||||||
/* Hand modified range to generic setup. */
|
newrange.max_proto = mr->max_proto;
|
||||||
return nf_nat_setup_info(ct, &newrange,
|
return nf_nat_setup_info(ct, &newrange,
|
||||||
HOOK2MANIP(par->hooknum));
|
HOOK2MANIP(hooknum));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prenat_ip = ip_hdr(skb)->saddr;
|
prenat_ip = ip_hdr(skb)->saddr;
|
||||||
@@ -448,8 +410,8 @@ bind_new_prefix:
|
|||||||
if (e->prenat_addr != 0 && time_before(jiffies, e->stamp)) {
|
if (e->prenat_addr != 0 && time_before(jiffies, e->stamp)) {
|
||||||
if (!disable_log && ! (p->flags & XT_DNETMAP_FULL) ){
|
if (!disable_log && ! (p->flags & XT_DNETMAP_FULL) ){
|
||||||
printk(KERN_INFO KBUILD_MODNAME
|
printk(KERN_INFO KBUILD_MODNAME
|
||||||
": ip " NIPQUAD_FMT " - no free adresses in prefix %s\n",
|
": ip %pI4 - no free adresses in prefix %s\n",
|
||||||
NIPQUAD(prenat_ip), p->prefix_str);
|
&prenat_ip, p->prefix_str);
|
||||||
p->flags |= XT_DNETMAP_FULL;
|
p->flags |= XT_DNETMAP_FULL;
|
||||||
}
|
}
|
||||||
goto no_free_ip;
|
goto no_free_ip;
|
||||||
@@ -462,8 +424,8 @@ bind_new_prefix:
|
|||||||
prenat_ip_prev = e->prenat_addr;
|
prenat_ip_prev = e->prenat_addr;
|
||||||
if (!disable_log)
|
if (!disable_log)
|
||||||
printk(KERN_INFO KBUILD_MODNAME
|
printk(KERN_INFO KBUILD_MODNAME
|
||||||
": timeout binding " NIPQUAD_FMT " -> " NIPQUAD_FMT "\n",
|
": timeout binding %pI4 -> %pI4\n",
|
||||||
NIPQUAD(prenat_ip_prev), NIPQUAD(postnat_ip) );
|
&prenat_ip_prev, &postnat_ip);
|
||||||
list_del(&e->glist);
|
list_del(&e->glist);
|
||||||
list_del(&e->grlist);
|
list_del(&e->grlist);
|
||||||
}
|
}
|
||||||
@@ -480,18 +442,16 @@ bind_new_prefix:
|
|||||||
(postnat_ip)]);
|
(postnat_ip)]);
|
||||||
if (!disable_log)
|
if (!disable_log)
|
||||||
printk(KERN_INFO KBUILD_MODNAME
|
printk(KERN_INFO KBUILD_MODNAME
|
||||||
": add binding " NIPQUAD_FMT " -> " NIPQUAD_FMT "\n",
|
": add binding %pI4 -> %pI4\n",
|
||||||
NIPQUAD(prenat_ip),NIPQUAD(postnat_ip));
|
&prenat_ip, &postnat_ip);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (!(tginfo->flags & XT_DNETMAP_REUSE) && !(e->flags & XT_DNETMAP_STATIC))
|
if (!(tginfo->flags & XT_DNETMAP_REUSE) && !(e->flags & XT_DNETMAP_STATIC))
|
||||||
if (time_before(e->stamp, jiffies) && p != e->prefix) {
|
if (time_before(e->stamp, jiffies) && p != e->prefix) {
|
||||||
if (!disable_log)
|
if (!disable_log)
|
||||||
printk(KERN_INFO KBUILD_MODNAME
|
printk(KERN_INFO KBUILD_MODNAME
|
||||||
": timeout binding " NIPQUAD_FMT " -> " NIPQUAD_FMT "\n",
|
": timeout binding %pI4 -> %pI4\n",
|
||||||
NIPQUAD(e->prenat_addr),
|
&e->prenat_addr, &e->postnat_addr);
|
||||||
NIPQUAD(e->postnat_addr));
|
|
||||||
list_del(&e->glist);
|
list_del(&e->glist);
|
||||||
list_del(&e->grlist);
|
list_del(&e->grlist);
|
||||||
e->prenat_addr = 0;
|
e->prenat_addr = 0;
|
||||||
@@ -509,14 +469,13 @@ bind_new_prefix:
|
|||||||
|
|
||||||
spin_unlock_bh(&dnetmap_lock);
|
spin_unlock_bh(&dnetmap_lock);
|
||||||
|
|
||||||
newrange = ((struct nf_nat_ipv4_range) {
|
memset(&newrange, 0, sizeof(newrange));
|
||||||
mr->range[0].flags | NF_NAT_RANGE_MAP_IPS,
|
newrange.flags = mr->flags | NF_NAT_RANGE_MAP_IPS;
|
||||||
postnat_ip, postnat_ip,
|
newrange.min_addr.ip = postnat_ip;
|
||||||
mr->range[0].min, mr->range[0].max});
|
newrange.max_addr.ip = postnat_ip;
|
||||||
|
newrange.min_proto = mr->min_proto;
|
||||||
/* Hand modified range to generic setup. */
|
newrange.max_proto = mr->max_proto;
|
||||||
return nf_nat_setup_info(ct, &newrange, HOOK2MANIP(par->hooknum));
|
return nf_nat_setup_info(ct, &newrange, HOOK2MANIP(par->state->hook));
|
||||||
|
|
||||||
no_rev_map:
|
no_rev_map:
|
||||||
no_free_ip:
|
no_free_ip:
|
||||||
spin_unlock_bh(&dnetmap_lock);
|
spin_unlock_bh(&dnetmap_lock);
|
||||||
@@ -528,7 +487,7 @@ static void dnetmap_tg_destroy(const struct xt_tgdtor_param *par)
|
|||||||
{
|
{
|
||||||
struct dnetmap_net *dnetmap_net = dnetmap_pernet(par->net);
|
struct dnetmap_net *dnetmap_net = dnetmap_pernet(par->net);
|
||||||
const struct xt_DNETMAP_tginfo *tginfo = par->targinfo;
|
const struct xt_DNETMAP_tginfo *tginfo = par->targinfo;
|
||||||
const struct nf_nat_ipv4_multi_range_compat *mr = &tginfo->prefix;
|
const struct nf_nat_range *mr = &tginfo->prefix;
|
||||||
struct dnetmap_prefix *p;
|
struct dnetmap_prefix *p;
|
||||||
|
|
||||||
if (!(tginfo->flags & XT_DNETMAP_PREFIX))
|
if (!(tginfo->flags & XT_DNETMAP_PREFIX))
|
||||||
@@ -591,12 +550,13 @@ static int dnetmap_seq_show(struct seq_file *seq, void *v)
|
|||||||
const struct dnetmap_entry *e = v;
|
const struct dnetmap_entry *e = v;
|
||||||
|
|
||||||
if((e->flags & XT_DNETMAP_STATIC) == 0){
|
if((e->flags & XT_DNETMAP_STATIC) == 0){
|
||||||
seq_printf(seq, NIPQUAD_FMT " -> " NIPQUAD_FMT " --- ttl: %d lasthit: %lu\n",
|
seq_printf(seq, "%pI4 -> %pI4 --- ttl: %d lasthit: %lu\n",
|
||||||
NIPQUAD(e->prenat_addr), NIPQUAD(e->postnat_addr),
|
&e->prenat_addr, &e->postnat_addr,
|
||||||
(int)(e->stamp - jiffies) / HZ, (e->stamp - jtimeout) / HZ);
|
(int)(e->stamp - jiffies) / HZ,
|
||||||
|
(e->stamp - jtimeout) / HZ);
|
||||||
}else{
|
}else{
|
||||||
seq_printf(seq, NIPQUAD_FMT " -> " NIPQUAD_FMT " --- ttl: S lasthit: S\n",
|
seq_printf(seq, "%pI4 -> %pI4 --- ttl: S lasthit: S\n",
|
||||||
NIPQUAD(e->prenat_addr), NIPQUAD(e->postnat_addr));
|
&e->prenat_addr, &e->postnat_addr);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -610,27 +570,24 @@ static const struct seq_operations dnetmap_seq_ops = {
|
|||||||
|
|
||||||
static int dnetmap_seq_open(struct inode *inode, struct file *file)
|
static int dnetmap_seq_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
struct proc_dir_entry *pde = PDE(inode);
|
|
||||||
struct dnetmap_iter_state *st;
|
struct dnetmap_iter_state *st;
|
||||||
|
|
||||||
st = __seq_open_private(file, &dnetmap_seq_ops, sizeof(*st));
|
st = __seq_open_private(file, &dnetmap_seq_ops, sizeof(*st));
|
||||||
if (st == NULL)
|
if (st == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
st->p = pde->data;
|
st->p = PDE_DATA(inode);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
dnetmap_tg_proc_write(struct file *file, const char __user *input,size_t size, loff_t *loff)
|
dnetmap_tg_proc_write(struct file *file, const char __user *input,size_t size, loff_t *loff)
|
||||||
{
|
{
|
||||||
const struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
|
struct dnetmap_prefix *p = PDE_DATA(file_inode(file));
|
||||||
struct dnetmap_prefix *p = pde->data;
|
|
||||||
struct dnetmap_entry *e;
|
struct dnetmap_entry *e;
|
||||||
char buf[sizeof("+192.168.100.100:200.200.200.200")];
|
char buf[sizeof("+192.168.100.100:200.200.200.200")];
|
||||||
const char *c = buf;
|
const char *c = buf;
|
||||||
const char *c2;
|
const char *c2;
|
||||||
//union nf_inet_addr addr = {};
|
|
||||||
__be32 addr1,addr2;
|
__be32 addr1,addr2;
|
||||||
bool add;
|
bool add;
|
||||||
char str[25];
|
char str[25];
|
||||||
@@ -721,8 +678,8 @@ dnetmap_tg_proc_write(struct file *file, const char __user *input,size_t size, l
|
|||||||
if(e != NULL){
|
if(e != NULL){
|
||||||
if (!disable_log)
|
if (!disable_log)
|
||||||
printk(KERN_INFO KBUILD_MODNAME
|
printk(KERN_INFO KBUILD_MODNAME
|
||||||
": timeout binding " NIPQUAD_FMT " -> " NIPQUAD_FMT "\n",
|
": timeout binding %pI4 -> %pI4\n",
|
||||||
NIPQUAD(e->prenat_addr), NIPQUAD(e->postnat_addr) );
|
&e->prenat_addr, &e->postnat_addr);
|
||||||
list_del(&e->glist);
|
list_del(&e->glist);
|
||||||
list_del(&e->grlist);
|
list_del(&e->grlist);
|
||||||
}else{
|
}else{
|
||||||
@@ -744,7 +701,7 @@ dnetmap_tg_proc_write(struct file *file, const char __user *input,size_t size, l
|
|||||||
(e->postnat_addr)]);
|
(e->postnat_addr)]);
|
||||||
list_del(&e->lru_list);
|
list_del(&e->lru_list);
|
||||||
|
|
||||||
sprintf(str, NIPQUAD_FMT ":" NIPQUAD_FMT, NIPQUAD(addr1),NIPQUAD(addr2));
|
sprintf(str, "%pI4:%pI4", &addr1, &addr2);
|
||||||
printk(KERN_INFO KBUILD_MODNAME ": adding static binding %s\n", str);
|
printk(KERN_INFO KBUILD_MODNAME ": adding static binding %s\n", str);
|
||||||
|
|
||||||
// case of removing binding
|
// case of removing binding
|
||||||
@@ -760,8 +717,8 @@ dnetmap_tg_proc_write(struct file *file, const char __user *input,size_t size, l
|
|||||||
if(e != NULL){
|
if(e != NULL){
|
||||||
if (!disable_log)
|
if (!disable_log)
|
||||||
printk(KERN_INFO KBUILD_MODNAME
|
printk(KERN_INFO KBUILD_MODNAME
|
||||||
": remove binding " NIPQUAD_FMT " -> " NIPQUAD_FMT "\n",
|
": remove binding %pI4 -> %pI4\n",
|
||||||
NIPQUAD(e->prenat_addr), NIPQUAD(e->postnat_addr) );
|
&e->prenat_addr, &e->postnat_addr);
|
||||||
list_del(&e->glist);
|
list_del(&e->glist);
|
||||||
list_del(&e->grlist);
|
list_del(&e->grlist);
|
||||||
if(e->flags & XT_DNETMAP_STATIC){
|
if(e->flags & XT_DNETMAP_STATIC){
|
||||||
@@ -791,20 +748,17 @@ dnetmap_tg_proc_write(struct file *file, const char __user *input,size_t size, l
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const struct file_operations dnetmap_tg_fops = {
|
static const struct proc_ops dnetmap_tg_fops = {
|
||||||
.open = dnetmap_seq_open,
|
.proc_open = dnetmap_seq_open,
|
||||||
.read = seq_read,
|
.proc_read = seq_read,
|
||||||
.write = dnetmap_tg_proc_write,
|
.proc_write = dnetmap_tg_proc_write,
|
||||||
.release = seq_release_private,
|
.proc_release = seq_release_private,
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* for statistics */
|
/* for statistics */
|
||||||
static int dnetmap_stat_proc_read(char __user *buffer, char **start,
|
static int dnetmap_stat_proc_show(struct seq_file *m, void *data)
|
||||||
off_t offset, int length, int *eof,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
const struct dnetmap_prefix *p = data;
|
const struct dnetmap_prefix *p = m->private;
|
||||||
struct dnetmap_entry *e;
|
struct dnetmap_entry *e;
|
||||||
unsigned int used, used_static, all;
|
unsigned int used, used_static, all;
|
||||||
long int ttl, sum_ttl;
|
long int ttl, sum_ttl;
|
||||||
@@ -830,16 +784,25 @@ static int dnetmap_stat_proc_read(char __user *buffer, char **start,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sum_ttl = used > 0 ? sum_ttl / (used * HZ) : 0;
|
sum_ttl = used > 0 ? sum_ttl / (used * HZ) : 0;
|
||||||
sprintf(buffer, "%u %u %u %ld %s\n", used, used_static, all, sum_ttl,(p->flags & XT_DNETMAP_PERSISTENT ? "persistent" : ""));
|
seq_printf(m, "%u %u %u %ld %s\n", used, used_static, all, sum_ttl,(p->flags & XT_DNETMAP_PERSISTENT ? "persistent" : ""));
|
||||||
|
|
||||||
if (length >= strlen(buffer))
|
|
||||||
*eof = true;
|
|
||||||
|
|
||||||
spin_unlock_bh(&dnetmap_lock);
|
spin_unlock_bh(&dnetmap_lock);
|
||||||
|
|
||||||
return strlen(buffer);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dnetmap_stat_proc_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, dnetmap_stat_proc_show, PDE_DATA(inode));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct proc_ops dnetmap_stat_proc_fops = {
|
||||||
|
.proc_open = dnetmap_stat_proc_open,
|
||||||
|
.proc_read = seq_read,
|
||||||
|
.proc_lseek = seq_lseek,
|
||||||
|
.proc_release = single_release,
|
||||||
|
};
|
||||||
|
|
||||||
static int __net_init dnetmap_proc_net_init(struct net *net)
|
static int __net_init dnetmap_proc_net_init(struct net *net)
|
||||||
{
|
{
|
||||||
struct dnetmap_net *dnetmap_net = dnetmap_pernet(net);
|
struct dnetmap_net *dnetmap_net = dnetmap_pernet(net);
|
||||||
@@ -852,7 +815,7 @@ static int __net_init dnetmap_proc_net_init(struct net *net)
|
|||||||
|
|
||||||
static void __net_exit dnetmap_proc_net_exit(struct net *net)
|
static void __net_exit dnetmap_proc_net_exit(struct net *net)
|
||||||
{
|
{
|
||||||
proc_net_remove(net, "xt_DNETMAP");
|
remove_proc_entry("xt_DNETMAP", net->proc_net);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@@ -871,13 +834,6 @@ static int __net_init dnetmap_net_init(struct net *net)
|
|||||||
struct dnetmap_net *dnetmap_net = dnetmap_pernet(net);
|
struct dnetmap_net *dnetmap_net = dnetmap_pernet(net);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)
|
|
||||||
dnetmap = kmalloc(sizeof(struct dnetmap_net),GFP_ATOMIC);
|
|
||||||
if (dnetmap == NULL)
|
|
||||||
return -ENOMEM;
|
|
||||||
dnetmap_net = dnetmap;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dnetmap_net->dnetmap_iphash = kmalloc(sizeof(struct list_head) *
|
dnetmap_net->dnetmap_iphash = kmalloc(sizeof(struct list_head) *
|
||||||
hash_size * 2, GFP_ATOMIC);
|
hash_size * 2, GFP_ATOMIC);
|
||||||
if (dnetmap_net->dnetmap_iphash == NULL)
|
if (dnetmap_net->dnetmap_iphash == NULL)
|
||||||
@@ -906,20 +862,15 @@ static void __net_exit dnetmap_net_exit(struct net *net)
|
|||||||
mutex_unlock(&dnetmap_mutex);
|
mutex_unlock(&dnetmap_mutex);
|
||||||
|
|
||||||
kfree(dnetmap_net->dnetmap_iphash);
|
kfree(dnetmap_net->dnetmap_iphash);
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)
|
|
||||||
kfree(dnetmap_net);
|
kfree(dnetmap_net);
|
||||||
#endif
|
|
||||||
|
|
||||||
dnetmap_proc_net_exit(net);
|
dnetmap_proc_net_exit(net);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pernet_operations dnetmap_net_ops = {
|
static struct pernet_operations dnetmap_net_ops = {
|
||||||
.init = dnetmap_net_init,
|
.init = dnetmap_net_init,
|
||||||
.exit = dnetmap_net_exit,
|
.exit = dnetmap_net_exit,
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
|
|
||||||
.id = &dnetmap_net_id,
|
.id = &dnetmap_net_id,
|
||||||
.size = sizeof(struct dnetmap_net),
|
.size = sizeof(struct dnetmap_net),
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct xt_target dnetmap_tg_reg __read_mostly = {
|
static struct xt_target dnetmap_tg_reg __read_mostly = {
|
||||||
@@ -965,6 +916,18 @@ static void __exit dnetmap_tg_exit(void)
|
|||||||
xt_unregister_target(&dnetmap_tg_reg);
|
xt_unregister_target(&dnetmap_tg_reg);
|
||||||
unregister_pernet_subsys(&dnetmap_net_ops);
|
unregister_pernet_subsys(&dnetmap_net_ops);
|
||||||
}
|
}
|
||||||
|
#else /* CONFIG_NF_NAT */
|
||||||
|
static int __init dnetmap_tg_init(void)
|
||||||
|
{
|
||||||
|
pr_err("CONFIG_NF_NAT is not available in your kernel, hence this module cannot function.");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
static void __exit dnetmap_tg_exit(void) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
module_init(dnetmap_tg_init);
|
module_init(dnetmap_tg_init);
|
||||||
module_exit(dnetmap_tg_exit);
|
module_exit(dnetmap_tg_exit);
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_AUTHOR("Marek Kierdelewicz <marek@piasta.pl>");
|
||||||
|
MODULE_DESCRIPTION("Xtables: dynamic two-way 1:1 NAT mapping of IPv4 addresses");
|
||||||
|
MODULE_ALIAS("ipt_DNETMAP");
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user