mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-21 12:04:56 +02:00
Compare commits
140 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3c0397867b | ||
![]() |
16e4968343 | ||
![]() |
8c910aa82b | ||
![]() |
6340d999d7 | ||
![]() |
11af976e8b | ||
![]() |
a4afc4159e | ||
![]() |
24bb655130 | ||
![]() |
2eaa5c5606 | ||
![]() |
0593b96c2c | ||
![]() |
6f1c1ef0ce | ||
![]() |
d5ff452ea5 | ||
![]() |
c012379e0b | ||
![]() |
15de3beb63 | ||
![]() |
160e04d13e | ||
![]() |
359ecc7a8c | ||
![]() |
6ee71ed485 | ||
![]() |
7bd0157a9a | ||
![]() |
6f8582eb5e | ||
![]() |
df7168bb4d | ||
![]() |
0aa7be2f1d | ||
![]() |
d9cd40e9fa | ||
![]() |
8bd6ef78f9 | ||
![]() |
578af6f726 | ||
![]() |
22edc7a24d | ||
![]() |
304e5e52ca | ||
![]() |
3f7288abfe | ||
![]() |
aad0cafd19 | ||
![]() |
17a0312848 | ||
![]() |
c66d291eb8 | ||
![]() |
cb407ce7c4 | ||
![]() |
3f426f3b43 | ||
![]() |
0b3ae22673 | ||
![]() |
bc5a7d8e3a | ||
![]() |
0628857068 | ||
![]() |
de4f6e8994 | ||
![]() |
439dd913f1 | ||
![]() |
9568747d94 | ||
![]() |
20365cf762 | ||
![]() |
fa601c0fa7 | ||
![]() |
00573d0172 | ||
![]() |
c7036a88f1 | ||
![]() |
af21c1d369 | ||
![]() |
b132101b63 | ||
![]() |
71beab548d | ||
![]() |
6de54e5fcd | ||
![]() |
a921427746 | ||
![]() |
2b2b6246f0 | ||
![]() |
98e5dfd6ef | ||
![]() |
9e5c2e7ee9 | ||
![]() |
284c0e9493 | ||
![]() |
5284b5db92 | ||
![]() |
36035d52d3 | ||
![]() |
4d94687c15 | ||
![]() |
7070678ab4 | ||
![]() |
f6281d498c | ||
![]() |
2cab32596a | ||
![]() |
08f6a82bdc | ||
![]() |
82a8524f1a | ||
![]() |
6bb354d3f0 | ||
![]() |
5184176c3b | ||
![]() |
430723ece1 | ||
![]() |
f1dc7f960c | ||
![]() |
370f47b000 | ||
![]() |
8e812620f0 | ||
![]() |
204b612e23 | ||
![]() |
c2c86f4b3d | ||
![]() |
379e685b0f | ||
![]() |
69dd0686e2 | ||
![]() |
48325a209e | ||
![]() |
96f501ab89 | ||
![]() |
3c1bf73e8e | ||
![]() |
e0276b4875 | ||
![]() |
1bc7f1be67 | ||
![]() |
3c3adcbd07 | ||
![]() |
da6a9b932c | ||
![]() |
5f290cd4a0 | ||
![]() |
181a9cab43 | ||
![]() |
a819458cba | ||
![]() |
654862af21 | ||
![]() |
0d8ae29a60 | ||
![]() |
e05a4d9586 | ||
![]() |
0541154a5e | ||
![]() |
00199427ac | ||
![]() |
35b00f8c3f | ||
![]() |
1f3150bdf9 | ||
![]() |
13c73af796 | ||
![]() |
ba9a3efec1 | ||
![]() |
f474c7d4d4 | ||
![]() |
4a350ddd03 | ||
![]() |
628d137f12 | ||
![]() |
28ecf45548 | ||
![]() |
58839b9b86 | ||
![]() |
e436948ebd | ||
![]() |
79d54ebd7c | ||
![]() |
0b64b27172 | ||
![]() |
d116000784 | ||
![]() |
4b5f0b12d9 | ||
![]() |
c8dde526f2 | ||
![]() |
3058e42a21 | ||
![]() |
40b30f7f27 | ||
![]() |
aaad5f53ac | ||
![]() |
db1057158f | ||
![]() |
713c31e8f7 | ||
![]() |
e5ffb39750 | ||
![]() |
19067393b6 | ||
![]() |
1de82a88a1 | ||
![]() |
9928c864ab | ||
![]() |
45515a0afd | ||
![]() |
75f80fa8f8 | ||
![]() |
d8dc72d151 | ||
![]() |
cee3d25d49 | ||
![]() |
afbeb2fb47 | ||
![]() |
c0dc0858de | ||
![]() |
b04317576b | ||
![]() |
af2bbf0352 | ||
![]() |
db9bb2778d | ||
![]() |
674560d2d9 | ||
![]() |
7ab033e64c | ||
![]() |
3131448443 | ||
![]() |
71322e614c | ||
![]() |
d3fdfe08dd | ||
![]() |
46f9ddbf59 | ||
![]() |
e37985b527 | ||
![]() |
0ccd55abd9 | ||
![]() |
60123a8c07 | ||
![]() |
504f1089fb | ||
![]() |
e119350000 | ||
![]() |
a260e3349f | ||
![]() |
5cb36ed213 | ||
![]() |
1a5b9f0e02 | ||
![]() |
2c53605084 | ||
![]() |
537f25dbad | ||
![]() |
63a1e5329f | ||
![]() |
b0a6111054 | ||
![]() |
b07434386b | ||
![]() |
0c963dee06 | ||
![]() |
09bfb8496e | ||
![]() |
9d1afc4268 | ||
![]() |
342ccf62b2 | ||
![]() |
adabd647b1 |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -6,10 +6,15 @@
|
||||
.libs
|
||||
Makefile
|
||||
Makefile.in
|
||||
GNUmakefile
|
||||
|
||||
/downloads
|
||||
|
||||
/Makefile.iptrules
|
||||
/Makefile.mans
|
||||
/.*.lst
|
||||
/matches.man
|
||||
/targets.man
|
||||
|
||||
/aclocal.m4
|
||||
/autom4te*.cache
|
||||
/compile
|
||||
|
16
INSTALL
16
INSTALL
@@ -19,6 +19,8 @@ Supported configurations for this release
|
||||
- CONFIG_NF_CONNTRACK or CONFIG_IP_NF_CONNTRACK
|
||||
- CONFIG_NF_CONNTRACK_MARK or CONFIG_IP_NF_CONNTRACK_MARK
|
||||
enabled =y or as module (=m)
|
||||
- CONFIG_CONNECTOR y/m if you wish to receive userspace
|
||||
notifications from pknock through netlink/connector
|
||||
|
||||
Extra notes:
|
||||
|
||||
@@ -46,6 +48,9 @@ Configuring and compiling
|
||||
/lib/modules/$(running version)/build, which usually points to
|
||||
the right directory. (If not, you need to install something.)
|
||||
|
||||
For RPM building, it should be /usr/src/linux-obj/...
|
||||
or whatever location the distro makes use of.
|
||||
|
||||
--with-xtables=
|
||||
|
||||
Specifies the path to the directory where we may find
|
||||
@@ -55,11 +60,11 @@ Configuring and compiling
|
||||
include/xtables.h. (The latter to support both standard
|
||||
/usr/include and the iptables source root.)
|
||||
|
||||
--with-libxtdir=
|
||||
--with-xtlibdir=
|
||||
|
||||
Specifies the path to where the newly built extensions should
|
||||
be installed when `make install` is run. It uses the same
|
||||
default as the Xtables package, ${libexecdir}/xtables.
|
||||
default as the Xtables/iptables package, ${libexecdir}/xtables.
|
||||
|
||||
If you want to enable debugging, use
|
||||
|
||||
@@ -72,15 +77,10 @@ much easier.)
|
||||
Build-time options
|
||||
==================
|
||||
|
||||
V= controls the kernel's make verbosity.
|
||||
V= controls the verbosity of make commands.
|
||||
V=0 "silent" (output filename)
|
||||
V=1 "verbose" (entire gcc command line)
|
||||
|
||||
VU= controls the Xt-a make verbosity.
|
||||
VU=0 output filename
|
||||
VU=1 output filename and source file
|
||||
VU=2 entire gcc command line
|
||||
|
||||
|
||||
Note to distribution packagers
|
||||
==============================
|
||||
|
12
Makefile.am
12
Makefile.am
@@ -5,16 +5,16 @@ SUBDIRS = extensions
|
||||
|
||||
man_MANS := xtables-addons.8
|
||||
|
||||
xtables-addons.8: ${srcdir}/xtables-addons.8.in extensions/matches.man extensions/targets.man
|
||||
${am__verbose_GEN}sed -e '/@MATCHES@/ r extensions/matches.man' -e '/@TARGET@/ r extensions/targets.man' $< >$@;
|
||||
.PHONY: FORCE
|
||||
FORCE:
|
||||
|
||||
extensions/%:
|
||||
${MAKE} ${AM_MAKEFLAGS} -C $(@D) $(@F)
|
||||
xtables-addons.8: FORCE
|
||||
${MAKE} -f Makefile.mans all;
|
||||
|
||||
install-exec-local:
|
||||
install-exec-hook:
|
||||
depmod -a || :;
|
||||
|
||||
config.status: extensions/GNUmakefile.in
|
||||
config.status: Makefile.iptrules.in
|
||||
|
||||
.PHONY: tarball
|
||||
tarball:
|
||||
|
29
Makefile.extra
Normal file
29
Makefile.extra
Normal file
@@ -0,0 +1,29 @@
|
||||
# -*- Makefile -*-
|
||||
# AUTOMAKE
|
||||
|
||||
XA_SRCDIR = ${srcdir}
|
||||
XA_TOPSRCDIR = ${top_srcdir}
|
||||
XA_ABSTOPSRCDIR = ${abs_top_srcdir}
|
||||
export XA_SRCDIR
|
||||
export XA_TOPSRCDIR
|
||||
export XA_ABSTOPSRCDIR
|
||||
|
||||
_mcall = -f ${top_builddir}/Makefile.iptrules
|
||||
|
||||
all-local: user-all-local
|
||||
|
||||
install-exec-local: user-install-local
|
||||
|
||||
clean-local: user-clean-local
|
||||
|
||||
user-all-local:
|
||||
${MAKE} ${_mcall} all;
|
||||
|
||||
# Have no user-install-data-local ATM
|
||||
user-install-local: user-install-exec-local
|
||||
|
||||
user-install-exec-local:
|
||||
${MAKE} ${_mcall} install;
|
||||
|
||||
user-clean-local:
|
||||
${MAKE} ${_mcall} clean;
|
60
Makefile.iptrules.in
Normal file
60
Makefile.iptrules.in
Normal file
@@ -0,0 +1,60 @@
|
||||
# -*- Makefile -*-
|
||||
# MANUAL
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
libexecdir = @libexecdir@
|
||||
xtlibdir = @xtlibdir@
|
||||
|
||||
CC = @CC@
|
||||
CCLD = ${CC}
|
||||
|
||||
regular_CFLAGS = @regular_CFLAGS@
|
||||
libxtables_CFLAGS = @libxtables_CFLAGS@
|
||||
libxtables_LIBS = @libxtables_LIBS@
|
||||
AM_CFLAGS = ${regular_CFLAGS} ${libxtables_CFLAGS}
|
||||
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
|
||||
|
||||
AM_DEFAULT_VERBOSITY = 0
|
||||
am__v_CC_0 = @echo " CC " $@;
|
||||
am__v_CCLD_0 = @echo " CCLD " $@;
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_SILENT_0 = @
|
||||
am__v_CC_ = ${am__v_CC_${AM_DEFAULT_VERBOSITY}}
|
||||
am__v_CCLD_ = ${am__v_CCLD_${AM_DEFAULT_VERBOSITY}}
|
||||
am__v_GEN_ = ${am__v_GEN_${AM_DEFAULT_VERBOSITY}}
|
||||
am__v_SILENT_ = ${am__v_SILENT_${AM_DEFAULT_VERBOSITY}}
|
||||
AM_V_CC = ${am__v_CC_${V}}
|
||||
AM_V_CCLD = ${am__v_CCLD_${V}}
|
||||
AM_V_GEN = ${am__v_GEN_${V}}
|
||||
AM_V_silent = ${am__v_GEN_${V}}
|
||||
|
||||
include ${XA_TOPSRCDIR}/mconfig
|
||||
-include ${XA_TOPSRCDIR}/mconfig.*
|
||||
include ${XA_SRCDIR}/Mbuild
|
||||
-include ${XA_SRCDIR}/Mbuild.*
|
||||
|
||||
targets := $(filter-out %/,${obj-m})
|
||||
subdirs_list := $(filter %/,${obj-m})
|
||||
|
||||
.SECONDARY:
|
||||
|
||||
.PHONY: all install clean
|
||||
|
||||
all: ${targets}
|
||||
@for i in ${subdirs_list}; do ${MAKE} -C $$i; done;
|
||||
|
||||
install: ${targets}
|
||||
@for i in ${subdirs_list}; do ${MAKE} -C $$i $@; done;
|
||||
install -dm0755 "${DESTDIR}/${xtlibdir}";
|
||||
install -pm0755 $^ "${DESTDIR}/${xtlibdir}";
|
||||
|
||||
clean:
|
||||
@for i in ${subdirs_list}; do ${MAKE} -C $$i $@; done;
|
||||
rm -f *.oo *.so;
|
||||
|
||||
lib%.so: lib%.oo
|
||||
${AM_V_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $< ${libxtables_LIBS} ${LDLIBS};
|
||||
|
||||
%.oo: ${XA_SRCDIR}/%.c
|
||||
${AM_V_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
|
40
Makefile.mans.in
Normal file
40
Makefile.mans.in
Normal file
@@ -0,0 +1,40 @@
|
||||
# -*- Makefile -*-
|
||||
# MANUAL
|
||||
|
||||
srcdir := @srcdir@
|
||||
|
||||
wcman_matches := $(shell find "${srcdir}" -name 'libxt_[a-z]*.man')
|
||||
wcman_targets := $(shell find "${srcdir}" -name 'libxt_[A-Z]*.man')
|
||||
wlist_matches := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_matches})
|
||||
wlist_targets := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_targets})
|
||||
|
||||
.PHONY: FORCE
|
||||
|
||||
FORCE:
|
||||
|
||||
.manpages.lst: FORCE
|
||||
@echo "${wlist_targets} ${wlist_matches}" >$@.tmp; \
|
||||
cmp -s $@ $@.tmp || mv $@.tmp $@; \
|
||||
rm -f $@.tmp;
|
||||
|
||||
man_run = \
|
||||
${AM_V_GEN}for ext in $(1); do \
|
||||
name="$${ext%.man}"; \
|
||||
name="$${name\#\#*/libxt_}"; \
|
||||
if [ -f "$$ext" ]; then \
|
||||
echo ".SS $$name"; \
|
||||
cat "$$ext"; \
|
||||
continue; \
|
||||
fi; \
|
||||
done >$@;
|
||||
|
||||
all: xtables-addons.8
|
||||
|
||||
xtables-addons.8: ${srcdir}/xtables-addons.8.in matches.man targets.man
|
||||
${AM_V_GEN}sed -e '/@MATCHES@/ r matches.man' -e '/@TARGET@/ r targets.man' $< >$@;
|
||||
|
||||
matches.man: .manpages.lst ${wcman_matches}
|
||||
$(call man_run,${wlist_matches})
|
||||
|
||||
targets.man: .manpages.lst ${wcman_targets}
|
||||
$(call man_run,${wlist_targets})
|
41
configure.ac
41
configure.ac
@@ -1,23 +1,27 @@
|
||||
|
||||
AC_INIT([xtables-addons], [1.18])
|
||||
AC_INIT([xtables-addons], [1.20])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_PROG_INSTALL
|
||||
AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
|
||||
AM_INIT_AUTOMAKE([1.10 -Wall foreign subdir-objects])
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
AC_DISABLE_STATIC
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
kbuilddir="/lib/modules/$(uname -r)/build";
|
||||
AC_ARG_WITH([kbuild],
|
||||
AS_HELP_STRING([--with-kbuild=PATH],
|
||||
[Path to kernel build directory [[/lib/modules/CURRENT/build]]]),
|
||||
[kbuilddir="$withval"])
|
||||
AC_ARG_WITH([ksource],
|
||||
AS_HELP_STRING([--with-ksource=PATH],
|
||||
[Path to kernel source directory [[/lib/modules/CURRENT/source]]]),
|
||||
[ksourcedir="$withval"])
|
||||
[kbuilddir="$withval"],
|
||||
[kbuilddir="/lib/modules/$(uname -r)/build"])
|
||||
#
|
||||
# check for --without-kbuild
|
||||
#
|
||||
if [[ "$kbuilddir" == no ]]; then
|
||||
kbuilddir="";
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([ksource],,[ksourcedir="$withval"])
|
||||
AC_ARG_WITH([xtables],
|
||||
AS_HELP_STRING([--with-xtables=PATH],
|
||||
[Path to the Xtables includes [[none]]]),
|
||||
@@ -35,10 +39,10 @@ if [[ -n "$xtables_location" ]]; then
|
||||
AC_MSG_CHECKING([xtables.h presence])
|
||||
if [[ -f "$xtables_location/xtables.h" ]]; then
|
||||
AC_MSG_RESULT([$xtables_location/xtables.h])
|
||||
xtables_CFLAGS="-I $xtables_location";
|
||||
libxtables_CFLAGS="-I $xtables_location";
|
||||
elif [[ -f "$xtables_location/include/xtables.h" ]]; then
|
||||
AC_MSG_RESULT([$xtables_location/include/xtables.h])
|
||||
xtables_CFLAGS="-I $xtables_location/include";
|
||||
libxtables_CFLAGS="-I $xtables_location/include";
|
||||
fi;
|
||||
if [[ -z "$xtables_CFLAGS" ]]; then
|
||||
if [[ -f "$includedir/xtables.h" ]]; then
|
||||
@@ -47,9 +51,14 @@ if [[ -n "$xtables_location" ]]; then
|
||||
AC_MSG_RESULT([no])
|
||||
fi;
|
||||
fi;
|
||||
libxtables_LIBS="-lxtables";
|
||||
AC_SUBST([libxtables_CFLAGS])
|
||||
AC_SUBST([libxtables_LIBS])
|
||||
else
|
||||
PKG_CHECK_MODULES([libxtables], [xtables >= 1.4.3])
|
||||
fi;
|
||||
AC_CHECK_HEADERS([linux/netfilter/x_tables.h], [],
|
||||
[AC_MSG_ERROR([You need to have linux/netfilter/x_tables.h, either through /usr/include or the iptables directory (--with-xtables=)])])
|
||||
|
||||
regular_CFLAGS="-D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 \
|
||||
-D_REENTRANT -Wall -Waggregate-return -Wmissing-declarations \
|
||||
@@ -79,17 +88,16 @@ krel="${krel#*.}";
|
||||
kminor="${krel%%.*}";
|
||||
krel="${krel#*.}";
|
||||
kmicro="${krel%%.*}";
|
||||
krel2="${krel#*.}";
|
||||
if test "$krel" = "$krel2"; then
|
||||
if test "$kmicro" = "$krel"; then
|
||||
kstable=0;
|
||||
else
|
||||
kstable="${krel%%.*}";
|
||||
kstable="${krel#*.}";
|
||||
if test -z "$kstable"; then
|
||||
kstable=0;
|
||||
fi;
|
||||
fi;
|
||||
echo "Found kernel version $kmajor.$kminor.$kmicro.$kstable in $kbuilddir";
|
||||
if test "$kmajor" -gt 2 -o "$kminor" -gt 6 -o "$kmicro" -gt 31; then
|
||||
if test "$kmajor" -gt 2 -o "$kminor" -gt 6 -o "$kmicro" -gt 32; then
|
||||
echo "WARNING: You are trying a newer kernel. Results may vary. :-)";
|
||||
elif test \( "$kmajor" -lt 2 -o "$kminor" -lt 6 -o "$kmicro" -lt 17 \) -o \
|
||||
\( "$kmajor" -eq 2 -a "$kminor" -eq 6 -a "$kmicro" -eq 18 -a \
|
||||
@@ -99,10 +107,11 @@ elif test \( "$kmajor" -lt 2 -o "$kminor" -lt 6 -o "$kmicro" -lt 17 \) -o \
|
||||
fi;
|
||||
|
||||
AC_SUBST([regular_CFLAGS])
|
||||
AC_SUBST([xtables_CFLAGS])
|
||||
AC_SUBST([kinclude_CFLAGS])
|
||||
AC_SUBST([kbuilddir])
|
||||
AC_SUBST([ksourcedir])
|
||||
AC_SUBST([xtlibdir])
|
||||
AC_CONFIG_FILES([Makefile extensions/GNUmakefile extensions/ipset/GNUmakefile])
|
||||
AC_CONFIG_FILES([Makefile Makefile.iptrules Makefile.mans
|
||||
extensions/Makefile extensions/ACCOUNT/Makefile
|
||||
extensions/ipset/Makefile extensions/pknock/Makefile])
|
||||
AC_OUTPUT
|
||||
|
@@ -1,4 +1,40 @@
|
||||
|
||||
HEAD
|
||||
====
|
||||
|
||||
|
||||
Xtables-addons 1.20 (November 19 2009)
|
||||
======================================
|
||||
- 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
|
||||
|
||||
|
||||
Xtables-addons 1.19 (October 12 2009)
|
||||
=====================================
|
||||
- build: compile fixes for 2.6.31-rt
|
||||
- build: support for Linux 2.6.32
|
||||
- ipp2p: try to address underflows
|
||||
- psd: avoid potential crash when dealing with non-linear skbs
|
||||
- merge xt_ACCOUNT userspace utilities
|
||||
- added reworked xt_pknock module
|
||||
Changes from pknock v0.5:
|
||||
- pknock: "strict" and "checkip" flags were not displayed in `iptables -L`
|
||||
- pknock: the GC expire time's lower bound is now the default gc time
|
||||
(65000 msec) to avoid rendering anti-spoof protection in SPA mode useless
|
||||
- pknock: avoid crash on memory allocation failure and fix memleak
|
||||
- pknock: avoid fillup of peer table during DDoS
|
||||
- pknock: automatic closing of ports
|
||||
- pknock: make non-zero time mandatory for TCP mode
|
||||
- pknock: display only pknock mode and state relevant information in procfs
|
||||
- pknock: check interknock time only for !ST_ALLOWED peers
|
||||
- pknock: preserve time/autoclose values for rules added in
|
||||
reverse/arbitrary order
|
||||
- pknock: add a manpage
|
||||
|
||||
|
||||
Xtables-addons 1.18 (September 09 2009)
|
||||
=======================================
|
||||
|
7
extensions/.gitignore
vendored
7
extensions/.gitignore
vendored
@@ -8,8 +8,5 @@ Module.symvers
|
||||
Modules.symvers
|
||||
modules.order
|
||||
|
||||
/*.so
|
||||
/*.oo
|
||||
/matches.man
|
||||
/targets.man
|
||||
/.manpages.lst
|
||||
*.so
|
||||
*.oo
|
||||
|
1
extensions/ACCOUNT/.gitignore
vendored
Normal file
1
extensions/ACCOUNT/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/iptaccount
|
5
extensions/ACCOUNT/Kbuild
Normal file
5
extensions/ACCOUNT/Kbuild
Normal file
@@ -0,0 +1,5 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
EXTRA_CFLAGS = -I${src}/..
|
||||
|
||||
obj-m += xt_ACCOUNT.o
|
8
extensions/ACCOUNT/Makefile.am
Normal file
8
extensions/ACCOUNT/Makefile.am
Normal file
@@ -0,0 +1,8 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
include ../../Makefile.extra
|
||||
|
||||
sbin_PROGRAMS = iptaccount
|
||||
iptaccount_LDADD = libxt_ACCOUNT_cl.la
|
||||
|
||||
lib_LTLIBRARIES = libxt_ACCOUNT_cl.la
|
3
extensions/ACCOUNT/Mbuild
Normal file
3
extensions/ACCOUNT/Mbuild
Normal file
@@ -0,0 +1,3 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
obj-${build_ACCOUNT} += libxt_ACCOUNT.so
|
224
extensions/ACCOUNT/iptaccount.c
Normal file
224
extensions/ACCOUNT/iptaccount.c
Normal file
@@ -0,0 +1,224 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2004-2006 by Intra2net AG *
|
||||
* opensource@intra2net.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License *
|
||||
* version 2.1 as published by the Free Software Foundation; *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/types.h>
|
||||
#include <libxt_ACCOUNT_cl.h>
|
||||
|
||||
bool exit_now;
|
||||
static void sig_term(int signr)
|
||||
{
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGQUIT, SIG_IGN);
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
|
||||
exit_now = true;
|
||||
}
|
||||
|
||||
static char *addr_to_dotted(unsigned int addr)
|
||||
{
|
||||
static char buf[16];
|
||||
const unsigned char *bytep;
|
||||
|
||||
addr = htonl(addr);
|
||||
bytep = (const unsigned char *)&addr;
|
||||
snprintf(buf, sizeof(buf), "%u.%u.%u.%u", bytep[0], bytep[1], bytep[2], bytep[3]);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void show_usage(void)
|
||||
{
|
||||
printf("Unknown command line option. Try: [-u] [-h] [-a] [-f] [-c] [-s] [-l name]\n");
|
||||
printf("[-u] show kernel handle usage\n");
|
||||
printf("[-h] free all kernel handles (experts only!)\n\n");
|
||||
printf("[-a] list all table names\n");
|
||||
printf("[-l name] show data in table <name>\n");
|
||||
printf("[-f] flush data after showing\n");
|
||||
printf("[-c] loop every second (abort with CTRL+C)\n");
|
||||
printf("[-s] CSV output (for spreadsheet import)\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct ipt_ACCOUNT_context ctx;
|
||||
struct ipt_acc_handle_ip *entry;
|
||||
int i;
|
||||
char optchar;
|
||||
bool doHandleUsage = false, doHandleFree = false, doTableNames = false;
|
||||
bool doFlush = false, doContinue = false, doCSV = false;
|
||||
|
||||
char *table_name = NULL;
|
||||
const char *name;
|
||||
|
||||
printf("\nlibxt_ACCOUNT_cl userspace accounting tool v%s\n\n",
|
||||
LIBXT_ACCOUNT_VERSION);
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
show_usage();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
while ((optchar = getopt(argc, argv, "uhacfsl:")) != -1)
|
||||
{
|
||||
switch (optchar)
|
||||
{
|
||||
case 'u':
|
||||
doHandleUsage = true;
|
||||
break;
|
||||
case 'h':
|
||||
doHandleFree = true;
|
||||
break;
|
||||
case 'a':
|
||||
doTableNames = true;
|
||||
break;
|
||||
case 'f':
|
||||
doFlush = true;
|
||||
break;
|
||||
case 'c':
|
||||
doContinue = true;
|
||||
break;
|
||||
case 's':
|
||||
doCSV = true;
|
||||
break;
|
||||
case 'l':
|
||||
table_name = strdup(optarg);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
show_usage();
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// install exit handler
|
||||
if (signal(SIGTERM, sig_term) == SIG_ERR)
|
||||
{
|
||||
printf("can't install signal handler for SIGTERM\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (signal(SIGINT, sig_term) == SIG_ERR)
|
||||
{
|
||||
printf("can't install signal handler for SIGINT\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (signal(SIGQUIT, sig_term) == SIG_ERR)
|
||||
{
|
||||
printf("can't install signal handler for SIGQUIT\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (ipt_ACCOUNT_init(&ctx))
|
||||
{
|
||||
printf("Init failed: %s\n", ctx.error_str);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Get handle usage?
|
||||
if (doHandleUsage)
|
||||
{
|
||||
int rtn = ipt_ACCOUNT_get_handle_usage(&ctx);
|
||||
if (rtn < 0)
|
||||
{
|
||||
printf("get_handle_usage failed: %s\n", ctx.error_str);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
printf("Current kernel handle usage: %d\n", ctx.handle.itemcount);
|
||||
}
|
||||
|
||||
if (doHandleFree)
|
||||
{
|
||||
int rtn = ipt_ACCOUNT_free_all_handles(&ctx);
|
||||
if (rtn < 0)
|
||||
{
|
||||
printf("handle_free_all failed: %s\n", ctx.error_str);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
printf("Freed all handles in kernel space\n");
|
||||
}
|
||||
|
||||
if (doTableNames)
|
||||
{
|
||||
int rtn = ipt_ACCOUNT_get_table_names(&ctx);
|
||||
if (rtn < 0)
|
||||
{
|
||||
printf("get_table_names failed: %s\n", ctx.error_str);
|
||||
exit(-1);
|
||||
}
|
||||
while ((name = ipt_ACCOUNT_get_next_name(&ctx)) != 0)
|
||||
printf("Found table: %s\n", name);
|
||||
}
|
||||
|
||||
if (table_name)
|
||||
{
|
||||
// Read out data
|
||||
if (doCSV)
|
||||
printf("IP;SRC packets;SRC bytes;DST packets;DST bytes\n");
|
||||
else
|
||||
printf("Showing table: %s\n", table_name);
|
||||
|
||||
i = 0;
|
||||
while (!exit_now)
|
||||
{
|
||||
// Get entries from table test
|
||||
if (ipt_ACCOUNT_read_entries(&ctx, table_name, !doFlush))
|
||||
{
|
||||
printf("Read failed: %s\n", ctx.error_str);
|
||||
ipt_ACCOUNT_deinit(&ctx);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!doCSV)
|
||||
printf("Run #%d - %u %s found\n", i, ctx.handle.itemcount,
|
||||
ctx.handle.itemcount == 1 ? "item" : "items");
|
||||
|
||||
// Output and free entries
|
||||
while ((entry = ipt_ACCOUNT_get_next_entry(&ctx)) != NULL)
|
||||
{
|
||||
if (doCSV)
|
||||
printf("%s;%u;%u;%u;%u\n",
|
||||
addr_to_dotted(entry->ip), entry->src_packets, entry->src_bytes,
|
||||
entry->dst_packets, entry->dst_bytes);
|
||||
else
|
||||
printf("IP: %s SRC packets: %u bytes: %u DST packets: %u bytes: %u\n",
|
||||
addr_to_dotted(entry->ip), entry->src_packets, entry->src_bytes,
|
||||
entry->dst_packets, entry->dst_bytes);
|
||||
}
|
||||
|
||||
if (doContinue)
|
||||
{
|
||||
sleep(1);
|
||||
i++;
|
||||
} else
|
||||
exit_now = true;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Finished.\n");
|
||||
ipt_ACCOUNT_deinit(&ctx);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@@ -2,6 +2,7 @@
|
||||
Author: Intra2net AG <opensource@intra2net.com>
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
@@ -13,9 +14,9 @@
|
||||
#include "xt_ACCOUNT.h"
|
||||
|
||||
static struct option account_tg_opts[] = {
|
||||
{ .name = "addr", .has_arg = 1, .flag = 0, .val = 'a' },
|
||||
{ .name = "tname", .has_arg = 1, .flag = 0, .val = 't' },
|
||||
{ .name = 0 }
|
||||
{.name = "addr", .has_arg = true, .val = 'a'},
|
||||
{.name = "tname", .has_arg = true, .val = 't'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
/* Function which prints out usage message. */
|
||||
@@ -56,10 +57,6 @@ static int account_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
xtables_error(PARAMETER_PROBLEM, "Can't specify --%s twice",
|
||||
account_tg_opts[0].name);
|
||||
|
||||
if (xtables_check_inverse(optarg, &invert, NULL, 0))
|
||||
xtables_error(PARAMETER_PROBLEM, "Unexpected `!' after --%s",
|
||||
account_tg_opts[0].name);
|
||||
|
||||
xtables_ipparse_any(optarg, &addrs, &mask, &naddrs);
|
||||
if (naddrs > 1)
|
||||
xtables_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed");
|
||||
@@ -76,11 +73,6 @@ static int account_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
"Can't specify --%s twice",
|
||||
account_tg_opts[1].name);
|
||||
|
||||
if (xtables_check_inverse(optarg, &invert, NULL, 0))
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Unexpected `!' after --%s",
|
||||
account_tg_opts[1].name);
|
||||
|
||||
if (strlen(optarg) > ACCOUNT_TABLE_NAME_LEN - 1)
|
||||
xtables_error(PARAMETER_PROBLEM,
|
||||
"Maximum table name length %u for --%s",
|
||||
@@ -105,7 +97,7 @@ static void account_tg_check(unsigned int flags)
|
||||
}
|
||||
|
||||
static void account_tg_print_it(const void *ip,
|
||||
const struct xt_entry_target *target, char do_prefix)
|
||||
const struct xt_entry_target *target, bool do_prefix)
|
||||
{
|
||||
const struct ipt_acc_info *accountinfo
|
||||
= (const struct ipt_acc_info *)target->data;
|
||||
@@ -137,18 +129,19 @@ account_tg_print(const void *ip,
|
||||
const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
account_tg_print_it(ip, target, 0);
|
||||
account_tg_print_it(ip, target, false);
|
||||
}
|
||||
|
||||
/* Saves the union ipt_targinfo in parsable form to stdout. */
|
||||
static void
|
||||
account_tg_save(const void *ip, const struct xt_entry_target *target)
|
||||
{
|
||||
account_tg_print_it(ip, target, 1);
|
||||
account_tg_print_it(ip, target, true);
|
||||
}
|
||||
|
||||
static struct xtables_target account_tg_reg = {
|
||||
.name = "ACCOUNT",
|
||||
.revision = 1,
|
||||
.family = AF_INET,
|
||||
.version = XTABLES_VERSION,
|
||||
.size = XT_ALIGN(sizeof(struct ipt_acc_info)),
|
@@ -56,8 +56,8 @@ the \fBiptaccount\fP(8) tool, which features following options:
|
||||
.PP
|
||||
Here is an example of use:
|
||||
.PP
|
||||
iptables \-A FORWARD \-j ACCOUNT \-\-addr 0.0.0.0/0 \-\-tname all_outgoing
|
||||
iptables \-A FORWARD \-j ACCOUNT \-\-addr 192.168.1.0/24 \-\-tname sales
|
||||
iptables \-A FORWARD \-j ACCOUNT \-\-addr 0.0.0.0/0 \-\-tname all_outgoing;
|
||||
iptables \-A FORWARD \-j ACCOUNT \-\-addr 192.168.1.0/24 \-\-tname sales;
|
||||
.PP
|
||||
This creates two tables called "all_outgoing" and "sales" which can be
|
||||
queried using the userspace library/iptaccount tool.
|
199
extensions/ACCOUNT/libxt_ACCOUNT_cl.c
Normal file
199
extensions/ACCOUNT/libxt_ACCOUNT_cl.c
Normal file
@@ -0,0 +1,199 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2004 by Intra2net AG *
|
||||
* opensource@intra2net.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License *
|
||||
* version 2.1 as published by the Free Software Foundation; *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if.h>
|
||||
|
||||
#include <libxt_ACCOUNT_cl.h>
|
||||
|
||||
int ipt_ACCOUNT_init(struct ipt_ACCOUNT_context *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(struct ipt_ACCOUNT_context));
|
||||
ctx->handle.handle_nr = -1;
|
||||
|
||||
ctx->sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
|
||||
if (ctx->sockfd < 0) {
|
||||
ctx->sockfd = -1;
|
||||
ctx->error_str = "Can't open socket to kernel. "
|
||||
"Permission denied or ipt_ACCOUNT module not loaded";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 4096 bytes default buffer should save us from reallocations
|
||||
// as it fits 200 concurrent active clients
|
||||
if ((ctx->data = malloc(IPT_ACCOUNT_MIN_BUFSIZE)) == NULL) {
|
||||
close(ctx->sockfd);
|
||||
ctx->sockfd = -1;
|
||||
ctx->error_str = "Out of memory for data buffer";
|
||||
return -1;
|
||||
}
|
||||
ctx->data_size = IPT_ACCOUNT_MIN_BUFSIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ipt_ACCOUNT_free_entries(struct ipt_ACCOUNT_context *ctx)
|
||||
{
|
||||
if (ctx->handle.handle_nr != -1) {
|
||||
setsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_SET_ACCOUNT_HANDLE_FREE,
|
||||
&ctx->handle, sizeof(struct ipt_acc_handle_sockopt));
|
||||
ctx->handle.handle_nr = -1;
|
||||
}
|
||||
|
||||
ctx->handle.itemcount = 0;
|
||||
ctx->pos = 0;
|
||||
}
|
||||
|
||||
void ipt_ACCOUNT_deinit(struct ipt_ACCOUNT_context *ctx)
|
||||
{
|
||||
free(ctx->data);
|
||||
ctx->data = NULL;
|
||||
|
||||
ipt_ACCOUNT_free_entries(ctx);
|
||||
|
||||
close(ctx->sockfd);
|
||||
ctx->sockfd = -1;
|
||||
}
|
||||
|
||||
int ipt_ACCOUNT_read_entries(struct ipt_ACCOUNT_context *ctx,
|
||||
const char *table, char dont_flush)
|
||||
{
|
||||
unsigned int s = sizeof(struct ipt_acc_handle_sockopt);
|
||||
unsigned int new_size;
|
||||
int rtn;
|
||||
|
||||
strncpy(ctx->handle.name, table, ACCOUNT_TABLE_NAME_LEN-1);
|
||||
|
||||
// Get table information
|
||||
if (!dont_flush)
|
||||
rtn = getsockopt(ctx->sockfd, IPPROTO_IP,
|
||||
IPT_SO_GET_ACCOUNT_PREPARE_READ_FLUSH, &ctx->handle, &s);
|
||||
else
|
||||
rtn = getsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_GET_ACCOUNT_PREPARE_READ,
|
||||
&ctx->handle, &s);
|
||||
|
||||
if (rtn < 0) {
|
||||
ctx->error_str = "Can't get table information from kernel. "
|
||||
"Does it exist?";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check data buffer size
|
||||
ctx->pos = 0;
|
||||
new_size = ctx->handle.itemcount * sizeof(struct ipt_acc_handle_ip);
|
||||
// We want to prevent reallocations all the time
|
||||
if (new_size < IPT_ACCOUNT_MIN_BUFSIZE)
|
||||
new_size = IPT_ACCOUNT_MIN_BUFSIZE;
|
||||
|
||||
// Reallocate if it's too small or twice as big
|
||||
if (ctx->data_size < new_size || ctx->data_size > new_size * 2) {
|
||||
// Free old buffer
|
||||
free(ctx->data);
|
||||
ctx->data_size = 0;
|
||||
|
||||
if ((ctx->data = malloc(new_size)) == NULL) {
|
||||
ctx->error_str = "Out of memory for data buffer";
|
||||
ipt_ACCOUNT_free_entries(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->data_size = new_size;
|
||||
}
|
||||
|
||||
// Copy data from kernel
|
||||
memcpy(ctx->data, &ctx->handle, sizeof(struct ipt_acc_handle_sockopt));
|
||||
rtn = getsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_GET_ACCOUNT_GET_DATA,
|
||||
ctx->data, &ctx->data_size);
|
||||
if (rtn < 0) {
|
||||
ctx->error_str = "Can't get data from kernel. "
|
||||
"Check /var/log/messages for details.";
|
||||
ipt_ACCOUNT_free_entries(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Free kernel handle but don't reset pos/itemcount
|
||||
setsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_SET_ACCOUNT_HANDLE_FREE,
|
||||
&ctx->handle, sizeof(struct ipt_acc_handle_sockopt));
|
||||
ctx->handle.handle_nr = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ipt_acc_handle_ip *ipt_ACCOUNT_get_next_entry(struct ipt_ACCOUNT_context *ctx)
|
||||
{
|
||||
struct ipt_acc_handle_ip *rtn;
|
||||
|
||||
// Empty or no more items left to return?
|
||||
if (!ctx->handle.itemcount || ctx->pos >= ctx->handle.itemcount)
|
||||
return NULL;
|
||||
|
||||
// Get next entry
|
||||
rtn = (struct ipt_acc_handle_ip *)(ctx->data + ctx->pos
|
||||
* sizeof(struct ipt_acc_handle_ip));
|
||||
ctx->pos++;
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
int ipt_ACCOUNT_get_handle_usage(struct ipt_ACCOUNT_context *ctx)
|
||||
{
|
||||
unsigned int s = sizeof(struct ipt_acc_handle_sockopt);
|
||||
if (getsockopt(ctx->sockfd, IPPROTO_IP,
|
||||
IPT_SO_GET_ACCOUNT_GET_HANDLE_USAGE, &ctx->handle, &s) < 0) {
|
||||
ctx->error_str = "Can't get handle usage information from kernel";
|
||||
return -1;
|
||||
}
|
||||
ctx->handle.handle_nr = -1;
|
||||
|
||||
return ctx->handle.itemcount;
|
||||
}
|
||||
|
||||
int ipt_ACCOUNT_free_all_handles(struct ipt_ACCOUNT_context *ctx)
|
||||
{
|
||||
if (setsockopt(ctx->sockfd, IPPROTO_IP,
|
||||
IPT_SO_SET_ACCOUNT_HANDLE_FREE_ALL, NULL, 0) < 0) {
|
||||
ctx->error_str = "Can't free all kernel handles";
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipt_ACCOUNT_get_table_names(struct ipt_ACCOUNT_context *ctx)
|
||||
{
|
||||
int rtn = getsockopt(ctx->sockfd, IPPROTO_IP,
|
||||
IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES,
|
||||
ctx->data, &ctx->data_size);
|
||||
if (rtn < 0) {
|
||||
ctx->error_str = "Can't get table names from kernel. Out of memory, "
|
||||
"MINBUFISZE too small?";
|
||||
return -1;
|
||||
}
|
||||
ctx->pos = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *ipt_ACCOUNT_get_next_name(struct ipt_ACCOUNT_context *ctx)
|
||||
{
|
||||
const char *rtn;
|
||||
if (((char *)ctx->data)[ctx->pos] == 0)
|
||||
return 0;
|
||||
|
||||
rtn = ctx->data + ctx->pos;
|
||||
ctx->pos += strlen(ctx->data + ctx->pos) + 1;
|
||||
|
||||
return rtn;
|
||||
}
|
60
extensions/ACCOUNT/libxt_ACCOUNT_cl.h
Normal file
60
extensions/ACCOUNT/libxt_ACCOUNT_cl.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2004 by Intra2net AG *
|
||||
* opensource@intra2net.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License *
|
||||
* version 2.1 as published by the Free Software Foundation; *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _xt_ACCOUNT_cl_H
|
||||
#define _xt_ACCOUNT_cl_H
|
||||
|
||||
#include <xt_ACCOUNT.h>
|
||||
|
||||
#define LIBXT_ACCOUNT_VERSION "1.3"
|
||||
|
||||
/* Don't set this below the size of struct ipt_account_handle_sockopt */
|
||||
#define IPT_ACCOUNT_MIN_BUFSIZE 4096
|
||||
|
||||
struct ipt_ACCOUNT_context
|
||||
{
|
||||
int sockfd;
|
||||
struct ipt_acc_handle_sockopt handle;
|
||||
|
||||
unsigned int data_size;
|
||||
void *data;
|
||||
unsigned int pos;
|
||||
|
||||
char *error_str;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int ipt_ACCOUNT_init(struct ipt_ACCOUNT_context *ctx);
|
||||
void ipt_ACCOUNT_deinit(struct ipt_ACCOUNT_context *ctx);
|
||||
|
||||
void ipt_ACCOUNT_free_entries(struct ipt_ACCOUNT_context *ctx);
|
||||
int ipt_ACCOUNT_read_entries(struct ipt_ACCOUNT_context *ctx,
|
||||
const char *table, char dont_flush);
|
||||
struct ipt_acc_handle_ip *ipt_ACCOUNT_get_next_entry(
|
||||
struct ipt_ACCOUNT_context *ctx);
|
||||
|
||||
/* ipt_ACCOUNT_free_entries is for internal use only function as this library
|
||||
is constructed to be used in a loop -> Don't allocate memory all the time.
|
||||
The data buffer is freed on deinit() */
|
||||
|
||||
int ipt_ACCOUNT_get_handle_usage(struct ipt_ACCOUNT_context *ctx);
|
||||
int ipt_ACCOUNT_free_all_handles(struct ipt_ACCOUNT_context *ctx);
|
||||
int ipt_ACCOUNT_get_table_names(struct ipt_ACCOUNT_context *ctx);
|
||||
const char *ipt_ACCOUNT_get_next_name(struct ipt_ACCOUNT_context *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
13
extensions/ACCOUNT/xt_ACCOUNT.Kconfig
Normal file
13
extensions/ACCOUNT/xt_ACCOUNT.Kconfig
Normal file
@@ -0,0 +1,13 @@
|
||||
config NETFILTER_XT_TARGET_ACCOUNT
|
||||
tristate "ACCOUNT target support"
|
||||
depends on NETFILTER_XTABLES
|
||||
---help---
|
||||
This module implements an ACCOUNT target
|
||||
|
||||
The ACCOUNT target is a high performance accounting system for large
|
||||
local networks. It allows per-IP accounting in whole prefixes of IPv4
|
||||
addresses with size of up to /8 without the need to add individual
|
||||
accouting rule for each IP address.
|
||||
|
||||
For more information go to:
|
||||
http://www.intra2net.com/de/produkte/opensource/ipt_account/
|
@@ -42,6 +42,68 @@
|
||||
#error "ipt_ACCOUNT needs at least a PAGE_SIZE of 4096"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Internal table structure, generated by check_entry()
|
||||
* @name: name of the table
|
||||
* @ip: base IP address of the network
|
||||
* @mask: netmask of the network
|
||||
* @depth: size of network (0: 8-bit, 1: 16-bit, 2: 24-bit)
|
||||
* @refcount: refcount of the table; if zero, destroy it
|
||||
* @itemcount: number of IP addresses in this table
|
||||
* @data; pointer to the actual data, depending on netmask
|
||||
*/
|
||||
struct ipt_acc_table {
|
||||
char name[ACCOUNT_TABLE_NAME_LEN];
|
||||
__be32 ip;
|
||||
__be32 netmask;
|
||||
uint8_t depth;
|
||||
uint32_t refcount;
|
||||
uint32_t itemcount;
|
||||
void *data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal handle structure
|
||||
* @ip: base IP address of the network. Used for caculating the final
|
||||
* address during get_data().
|
||||
* @depth: size of the network; see above
|
||||
* @itemcount: number of addresses in this table
|
||||
*/
|
||||
struct ipt_acc_handle {
|
||||
uint32_t ip;
|
||||
uint8_t depth;
|
||||
uint32_t itemcount;
|
||||
void *data;
|
||||
};
|
||||
|
||||
/* Used for every IP entry
|
||||
Size is 16 bytes so that 256 (class C network) * 16
|
||||
fits in one kernel (zero) page */
|
||||
struct ipt_acc_ip {
|
||||
uint32_t src_packets;
|
||||
uint32_t src_bytes;
|
||||
uint32_t dst_packets;
|
||||
uint32_t dst_bytes;
|
||||
};
|
||||
|
||||
/*
|
||||
* The IP addresses are organized as an array so that direct slot
|
||||
* calculations are possible.
|
||||
* Only 8-bit networks are preallocated, 16/24-bit networks
|
||||
* allocate their slots when needed -> very efficent.
|
||||
*/
|
||||
struct ipt_acc_mask_24 {
|
||||
struct ipt_acc_ip ip[256];
|
||||
};
|
||||
|
||||
struct ipt_acc_mask_16 {
|
||||
struct ipt_acc_mask_24 *mask_24[256];
|
||||
};
|
||||
|
||||
struct ipt_acc_mask_8 {
|
||||
struct ipt_acc_mask_16 *mask_16[256];
|
||||
};
|
||||
|
||||
static struct ipt_acc_table *ipt_acc_tables;
|
||||
static struct ipt_acc_handle *ipt_acc_handles;
|
||||
static void *ipt_acc_tmpbuf;
|
||||
@@ -65,7 +127,7 @@ static void *ipt_acc_zalloc_page(void)
|
||||
}
|
||||
|
||||
/* Recursive free of all data structures */
|
||||
static void ipt_acc_data_free(void *data, unsigned char depth)
|
||||
static void ipt_acc_data_free(void *data, uint8_t depth)
|
||||
{
|
||||
/* Empty data set */
|
||||
if (!data)
|
||||
@@ -117,7 +179,7 @@ static void ipt_acc_data_free(void *data, unsigned char depth)
|
||||
|
||||
/* Look for existing table / insert new one.
|
||||
Return internal ID or -1 on error */
|
||||
static int ipt_acc_table_insert(char *name, uint32_t ip, uint32_t netmask)
|
||||
static int ipt_acc_table_insert(const char *name, __be32 ip, __be32 netmask)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@@ -265,12 +327,14 @@ static void ipt_acc_destroy(const struct xt_tgdtor_param *par)
|
||||
}
|
||||
|
||||
static void ipt_acc_depth0_insert(struct ipt_acc_mask_24 *mask_24,
|
||||
uint32_t net_ip, uint32_t netmask,
|
||||
uint32_t src_ip, uint32_t dst_ip,
|
||||
__be32 net_ip, __be32 netmask,
|
||||
__be32 src_ip, __be32 dst_ip,
|
||||
uint32_t size, uint32_t *itemcount)
|
||||
{
|
||||
unsigned char is_src = 0, is_dst = 0, src_slot, dst_slot;
|
||||
char is_src_new_ip = 0, is_dst_new_ip = 0; /* Check if this entry is new */
|
||||
uint8_t src_slot, dst_slot;
|
||||
bool is_src = false, is_dst = false;
|
||||
/* Check if this entry is new */
|
||||
bool is_src_new_ip = false, is_dst_new_ip = false;
|
||||
|
||||
pr_debug("ACCOUNT: ipt_acc_depth0_insert: %u.%u.%u.%u/%u.%u.%u.%u "
|
||||
"for net %u.%u.%u.%u/%u.%u.%u.%u, size: %u\n", NIPQUAD(src_ip),
|
||||
@@ -278,12 +342,12 @@ static void ipt_acc_depth0_insert(struct ipt_acc_mask_24 *mask_24,
|
||||
|
||||
/* Check if src/dst is inside our network. */
|
||||
/* Special: net_ip = 0.0.0.0/0 gets stored as src in slot 0 */
|
||||
if (!netmask)
|
||||
if (netmask == 0)
|
||||
src_ip = 0;
|
||||
if ((net_ip & netmask) == (src_ip & netmask))
|
||||
is_src = 1;
|
||||
if ((net_ip & netmask) == (dst_ip & netmask) && netmask)
|
||||
is_dst = 1;
|
||||
is_src = true;
|
||||
if ((net_ip & netmask) == (dst_ip & netmask) && netmask != 0)
|
||||
is_dst = true;
|
||||
|
||||
if (!is_src && !is_dst) {
|
||||
pr_debug("ACCOUNT: Skipping packet %u.%u.%u.%u/%u.%u.%u.%u "
|
||||
@@ -293,8 +357,8 @@ static void ipt_acc_depth0_insert(struct ipt_acc_mask_24 *mask_24,
|
||||
}
|
||||
|
||||
/* Calculate array positions */
|
||||
src_slot = (src_ip & 0xFF000000) >> 24;
|
||||
dst_slot = (dst_ip & 0xFF000000) >> 24;
|
||||
src_slot = ntohl(src_ip) & 0xFF;
|
||||
dst_slot = ntohl(dst_ip) & 0xFF;
|
||||
|
||||
/* Increase size counters */
|
||||
if (is_src) {
|
||||
@@ -302,7 +366,7 @@ static void ipt_acc_depth0_insert(struct ipt_acc_mask_24 *mask_24,
|
||||
pr_debug("ACCOUNT: Calculated SRC 8 bit network slot: %d\n", src_slot);
|
||||
if (!mask_24->ip[src_slot].src_packets
|
||||
&& !mask_24->ip[src_slot].dst_packets)
|
||||
is_src_new_ip = 1;
|
||||
is_src_new_ip = true;
|
||||
|
||||
mask_24->ip[src_slot].src_packets++;
|
||||
mask_24->ip[src_slot].src_bytes += size;
|
||||
@@ -311,7 +375,7 @@ static void ipt_acc_depth0_insert(struct ipt_acc_mask_24 *mask_24,
|
||||
pr_debug("ACCOUNT: Calculated DST 8 bit network slot: %d\n", dst_slot);
|
||||
if (!mask_24->ip[dst_slot].src_packets
|
||||
&& !mask_24->ip[dst_slot].dst_packets)
|
||||
is_dst_new_ip = 1;
|
||||
is_dst_new_ip = true;
|
||||
|
||||
mask_24->ip[dst_slot].dst_packets++;
|
||||
mask_24->ip[dst_slot].dst_bytes += size;
|
||||
@@ -323,29 +387,29 @@ static void ipt_acc_depth0_insert(struct ipt_acc_mask_24 *mask_24,
|
||||
if (is_src_new_ip || is_dst_new_ip) {
|
||||
pr_debug("ACCOUNT: src_slot == dst_slot: %d, %d\n",
|
||||
is_src_new_ip, is_dst_new_ip);
|
||||
(*itemcount)++;
|
||||
++*itemcount;
|
||||
}
|
||||
} else {
|
||||
if (is_src_new_ip) {
|
||||
pr_debug("ACCOUNT: New src_ip: %u.%u.%u.%u\n", NIPQUAD(src_ip));
|
||||
(*itemcount)++;
|
||||
++*itemcount;
|
||||
}
|
||||
if (is_dst_new_ip) {
|
||||
pr_debug("ACCOUNT: New dst_ip: %u.%u.%u.%u\n", NIPQUAD(dst_ip));
|
||||
(*itemcount)++;
|
||||
++*itemcount;
|
||||
}
|
||||
}
|
||||
pr_debug("ACCOUNT: Itemcounter after: %d\n", *itemcount);
|
||||
}
|
||||
|
||||
static void ipt_acc_depth1_insert(struct ipt_acc_mask_16 *mask_16,
|
||||
uint32_t net_ip, uint32_t netmask,
|
||||
uint32_t src_ip, uint32_t dst_ip,
|
||||
__be32 net_ip, __be32 netmask,
|
||||
__be32 src_ip, __be32 dst_ip,
|
||||
uint32_t size, uint32_t *itemcount)
|
||||
{
|
||||
/* Do we need to process src IP? */
|
||||
if ((net_ip & netmask) == (src_ip & netmask)) {
|
||||
unsigned char slot = (src_ip & 0x00FF0000) >> 16;
|
||||
uint8_t slot = (ntohl(src_ip) & 0xFF00) >> 8;
|
||||
pr_debug("ACCOUNT: Calculated SRC 16 bit network slot: %d\n", slot);
|
||||
|
||||
/* Do we need to create a new mask_24 bucket? */
|
||||
@@ -361,7 +425,7 @@ static void ipt_acc_depth1_insert(struct ipt_acc_mask_16 *mask_16,
|
||||
|
||||
/* Do we need to process dst IP? */
|
||||
if ((net_ip & netmask) == (dst_ip & netmask)) {
|
||||
unsigned char slot = (dst_ip & 0x00FF0000) >> 16;
|
||||
uint8_t slot = (ntohl(dst_ip) & 0xFF00) >> 8;
|
||||
pr_debug("ACCOUNT: Calculated DST 16 bit network slot: %d\n", slot);
|
||||
|
||||
/* Do we need to create a new mask_24 bucket? */
|
||||
@@ -377,13 +441,13 @@ static void ipt_acc_depth1_insert(struct ipt_acc_mask_16 *mask_16,
|
||||
}
|
||||
|
||||
static void ipt_acc_depth2_insert(struct ipt_acc_mask_8 *mask_8,
|
||||
uint32_t net_ip, uint32_t netmask,
|
||||
uint32_t src_ip, uint32_t dst_ip,
|
||||
__be32 net_ip, __be32 netmask,
|
||||
__be32 src_ip, __be32 dst_ip,
|
||||
uint32_t size, uint32_t *itemcount)
|
||||
{
|
||||
/* Do we need to process src IP? */
|
||||
if ((net_ip & netmask) == (src_ip & netmask)) {
|
||||
unsigned char slot = (src_ip & 0x0000FF00) >> 8;
|
||||
uint8_t slot = (ntohl(src_ip) & 0xFF0000) >> 16;
|
||||
pr_debug("ACCOUNT: Calculated SRC 24 bit network slot: %d\n", slot);
|
||||
|
||||
/* Do we need to create a new mask_24 bucket? */
|
||||
@@ -399,7 +463,7 @@ static void ipt_acc_depth2_insert(struct ipt_acc_mask_8 *mask_8,
|
||||
|
||||
/* Do we need to process dst IP? */
|
||||
if ((net_ip & netmask) == (dst_ip & netmask)) {
|
||||
unsigned char slot = (dst_ip & 0x0000FF00) >> 8;
|
||||
uint8_t slot = (ntohl(dst_ip) & 0xFF0000) >> 16;
|
||||
pr_debug("ACCOUNT: Calculated DST 24 bit network slot: %d\n", slot);
|
||||
|
||||
/* Do we need to create a new mask_24 bucket? */
|
||||
@@ -419,8 +483,8 @@ static unsigned int ipt_acc_target(struct sk_buff **pskb, const struct xt_target
|
||||
const struct ipt_acc_info *info =
|
||||
par->targinfo;
|
||||
|
||||
uint32_t src_ip = ip_hdr(*pskb)->saddr;
|
||||
uint32_t dst_ip = ip_hdr(*pskb)->daddr;
|
||||
__be32 src_ip = ip_hdr(*pskb)->saddr;
|
||||
__be32 dst_ip = ip_hdr(*pskb)->daddr;
|
||||
uint32_t size = ntohs(ip_hdr(*pskb)->tot_len);
|
||||
|
||||
spin_lock_bh(&ipt_acc_lock);
|
||||
@@ -532,7 +596,7 @@ static int ipt_acc_handle_prepare_read(char *tablename,
|
||||
struct ipt_acc_handle *dest, uint32_t *count)
|
||||
{
|
||||
int table_nr = -1;
|
||||
unsigned char depth;
|
||||
uint8_t depth;
|
||||
|
||||
for (table_nr = 0; table_nr < ACCOUNT_MAX_TABLES; table_nr++)
|
||||
if (strncmp(ipt_acc_tables[table_nr].name, tablename,
|
||||
@@ -682,7 +746,7 @@ static int ipt_acc_handle_copy_data(void *to_user, unsigned long *to_user_pos,
|
||||
|
||||
for (i = 0; i <= 255; i++) {
|
||||
if (data->ip[i].src_packets || data->ip[i].dst_packets) {
|
||||
handle_ip.ip = net_ip | net_OR_mask | (i << 24);
|
||||
handle_ip.ip = net_ip | net_OR_mask | i;
|
||||
|
||||
handle_ip.src_packets = data->ip[i].src_packets;
|
||||
handle_ip.src_bytes = data->ip[i].src_bytes;
|
||||
@@ -713,7 +777,7 @@ static int ipt_acc_handle_get_data(uint32_t handle, void *to_user)
|
||||
{
|
||||
unsigned long to_user_pos = 0, tmpbuf_pos = 0;
|
||||
uint32_t net_ip;
|
||||
unsigned char depth;
|
||||
uint8_t depth;
|
||||
|
||||
if (handle >= ACCOUNT_MAX_HANDLES) {
|
||||
printk("ACCOUNT: invalid handle for ipt_acc_handle_get_data() "
|
||||
@@ -726,7 +790,7 @@ static int ipt_acc_handle_get_data(uint32_t handle, void *to_user)
|
||||
return -1;
|
||||
}
|
||||
|
||||
net_ip = ipt_acc_handles[handle].ip;
|
||||
net_ip = ntohl(ipt_acc_handles[handle].ip);
|
||||
depth = ipt_acc_handles[handle].depth;
|
||||
|
||||
/* 8 bit network */
|
||||
@@ -755,7 +819,7 @@ static int ipt_acc_handle_get_data(uint32_t handle, void *to_user)
|
||||
struct ipt_acc_mask_24 *network =
|
||||
network_16->mask_24[b];
|
||||
if (ipt_acc_handle_copy_data(to_user, &to_user_pos,
|
||||
&tmpbuf_pos, network, net_ip, (b << 16)))
|
||||
&tmpbuf_pos, network, net_ip, (b << 8)))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -783,7 +847,7 @@ static int ipt_acc_handle_get_data(uint32_t handle, void *to_user)
|
||||
network_16->mask_24[b];
|
||||
if (ipt_acc_handle_copy_data(to_user,
|
||||
&to_user_pos, &tmpbuf_pos,
|
||||
network, net_ip, (a << 8) | (b << 16)))
|
||||
network, net_ip, (a << 16) | (b << 8)))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1015,8 +1079,9 @@ static int ipt_acc_get_ctl(struct sock *sk, int cmd, void *user, int *len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct xt_target xt_acc_reg = {
|
||||
static struct xt_target xt_acc_reg __read_mostly = {
|
||||
.name = "ACCOUNT",
|
||||
.revision = 1,
|
||||
.family = AF_INET,
|
||||
.target = ipt_acc_target,
|
||||
.targetsize = sizeof(struct ipt_acc_info),
|
||||
@@ -1037,7 +1102,7 @@ static struct nf_sockopt_ops ipt_acc_sockopts = {
|
||||
|
||||
static int __init account_tg_init(void)
|
||||
{
|
||||
init_MUTEX(&ipt_acc_userspace_mutex);
|
||||
sema_init(&ipt_acc_userspace_mutex, 1);
|
||||
|
||||
if ((ipt_acc_tables =
|
||||
kmalloc(ACCOUNT_MAX_TABLES *
|
@@ -35,38 +35,12 @@
|
||||
|
||||
/* Structure for the userspace part of ipt_ACCOUNT */
|
||||
struct ipt_acc_info {
|
||||
uint32_t net_ip;
|
||||
uint32_t net_mask;
|
||||
__be32 net_ip;
|
||||
__be32 net_mask;
|
||||
char table_name[ACCOUNT_TABLE_NAME_LEN];
|
||||
int32_t table_nr;
|
||||
};
|
||||
|
||||
/* Internal table structure, generated by check_entry() */
|
||||
struct ipt_acc_table {
|
||||
char name[ACCOUNT_TABLE_NAME_LEN]; /* name of the table */
|
||||
uint32_t ip; /* base IP of network */
|
||||
uint32_t netmask; /* netmask of the network */
|
||||
unsigned char depth; /* size of network:
|
||||
0: 8 bit, 1: 16bit, 2: 24 bit */
|
||||
uint32_t refcount; /* refcount of this table.
|
||||
if zero, destroy it */
|
||||
uint32_t itemcount; /* number of IPs in this table */
|
||||
void *data; /* pointer to the actual data,
|
||||
depending on netmask */
|
||||
};
|
||||
|
||||
/* Internal handle structure */
|
||||
struct ipt_acc_handle {
|
||||
uint32_t ip; /* base IP of network. Used for
|
||||
caculating the final IP during
|
||||
get_data() */
|
||||
unsigned char depth; /* size of network. See above for
|
||||
details */
|
||||
uint32_t itemcount; /* number of IPs in this table */
|
||||
void *data; /* pointer to the actual data,
|
||||
depending on size */
|
||||
};
|
||||
|
||||
/* Handle structure for communication with the userspace library */
|
||||
struct ipt_acc_handle_sockopt {
|
||||
uint32_t handle_nr; /* Used for HANDLE_FREE */
|
||||
@@ -76,43 +50,15 @@ struct ipt_acc_handle_sockopt {
|
||||
HANDLE_READ_FLUSH */
|
||||
};
|
||||
|
||||
/* Used for every IP entry
|
||||
Size is 16 bytes so that 256 (class C network) * 16
|
||||
fits in one kernel (zero) page */
|
||||
struct ipt_acc_ip {
|
||||
uint32_t src_packets;
|
||||
uint32_t src_bytes;
|
||||
uint32_t dst_packets;
|
||||
uint32_t dst_bytes;
|
||||
};
|
||||
|
||||
/*
|
||||
Used for every IP when returning data
|
||||
*/
|
||||
struct ipt_acc_handle_ip {
|
||||
uint32_t ip;
|
||||
__be32 ip;
|
||||
uint32_t src_packets;
|
||||
uint32_t src_bytes;
|
||||
uint32_t dst_packets;
|
||||
uint32_t dst_bytes;
|
||||
};
|
||||
|
||||
/*
|
||||
The IPs are organized as an array so that direct slot
|
||||
calculations are possible.
|
||||
Only 8 bit networks are preallocated, 16/24 bit networks
|
||||
allocate their slots when needed -> very efficent.
|
||||
*/
|
||||
struct ipt_acc_mask_24 {
|
||||
struct ipt_acc_ip ip[256];
|
||||
};
|
||||
|
||||
struct ipt_acc_mask_16 {
|
||||
struct ipt_acc_mask_24 *mask_24[256];
|
||||
};
|
||||
|
||||
struct ipt_acc_mask_8 {
|
||||
struct ipt_acc_mask_16 *mask_16[256];
|
||||
};
|
||||
|
||||
#endif /* _IPT_ACCOUNT_H */
|
@@ -1,141 +0,0 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
top_srcdir := @top_srcdir@
|
||||
srcdir := @srcdir@
|
||||
abstop_srcdir := $(shell readlink -f ${top_srcdir})
|
||||
abssrcdir := $(shell readlink -f ${srcdir})
|
||||
|
||||
ifeq (${abstop_srcdir},)
|
||||
$(error Path resolution of ${top_srcdir} failed)
|
||||
endif
|
||||
ifeq (${abssrcdir},)
|
||||
$(error Path resolution of ${srcdir} failed)
|
||||
endif
|
||||
|
||||
prefix := @prefix@
|
||||
exec_prefix := @exec_prefix@
|
||||
libdir := @libdir@
|
||||
libexecdir := @libexecdir@
|
||||
xtlibdir := @xtlibdir@
|
||||
kbuilddir := @kbuilddir@
|
||||
|
||||
CC := @CC@
|
||||
CCLD := ${CC}
|
||||
CFLAGS := @CFLAGS@
|
||||
LDFLAGS := @LDFLAGS@
|
||||
regular_CFLAGS := @regular_CFLAGS@
|
||||
kinclude_CFLAGS := @kinclude_CFLAGS@
|
||||
xtables_CFLAGS := @xtables_CFLAGS@
|
||||
|
||||
AM_CFLAGS := ${regular_CFLAGS} -I${top_srcdir}/include ${xtables_CFLAGS} ${kinclude_CFLAGS}
|
||||
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
|
||||
|
||||
VU := 0
|
||||
am__v_CC_0 = @echo " CC " $@;
|
||||
am__v_CCLD_0 = @echo " CCLD " $@;
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_SILENT_0 = @
|
||||
AM_V_CC = ${am__v_CC_${VU}}
|
||||
AM_V_CCLD = ${am__v_CCLD_${VU}}
|
||||
AM_V_GEN = ${am__v_GEN_${VU}}
|
||||
AM_V_silent = ${am__v_GEN_${VU}}
|
||||
|
||||
|
||||
#
|
||||
# Wildcard module list
|
||||
#
|
||||
include ${top_srcdir}/mconfig
|
||||
-include ${top_srcdir}/mconfig.*
|
||||
include ${srcdir}/Mbuild
|
||||
-include ${srcdir}/Mbuild.*
|
||||
-include ${srcdir}/*.Mbuild
|
||||
|
||||
|
||||
#
|
||||
# Building blocks
|
||||
#
|
||||
targets := $(filter-out %/,${obj-m})
|
||||
targets_install := ${targets}
|
||||
subdirs_list := $(filter %/,${obj-m})
|
||||
|
||||
.SECONDARY:
|
||||
|
||||
.PHONY: all install clean distclean FORCE
|
||||
|
||||
all: subdirs modules user matches.man targets.man
|
||||
|
||||
subdirs:
|
||||
@for i in ${subdirs_list}; do ${MAKE} -C $$i; done;
|
||||
|
||||
subdirs-install:
|
||||
@for i in ${subdirs_list}; do ${MAKE} -C $$i install; done;
|
||||
|
||||
user: ${targets}
|
||||
|
||||
install: modules_install subdirs-install ${targets_install}
|
||||
@mkdir -p "${DESTDIR}${xtlibdir}";
|
||||
install -pm0755 ${targets_install} "${DESTDIR}${xtlibdir}/";
|
||||
|
||||
clean: clean_modules
|
||||
@for i in ${subdirs_list}; do ${MAKE} -C $$i clean; done;
|
||||
rm -f *.oo *.so;
|
||||
|
||||
distclean: clean
|
||||
rm -f .*.d .manpages.lst;
|
||||
|
||||
-include .*.d
|
||||
|
||||
|
||||
#
|
||||
# Call out to kbuild
|
||||
#
|
||||
.PHONY: modules modules_install clean_modules
|
||||
|
||||
modules:
|
||||
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} modules; fi;
|
||||
|
||||
modules_install:
|
||||
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} INSTALL_MOD_PATH=${DESTDIR} modules_install; fi;
|
||||
|
||||
clean_modules:
|
||||
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} clean; fi;
|
||||
|
||||
|
||||
#
|
||||
# Shared libraries
|
||||
#
|
||||
lib%.so: lib%.oo
|
||||
${AM_V_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
|
||||
|
||||
lib%.oo: ${srcdir}/lib%.c
|
||||
${AM_V_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=lib$*_init -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
|
||||
|
||||
|
||||
#
|
||||
# Manpages
|
||||
#
|
||||
wcman_matches := $(wildcard ${srcdir}/libxt_[a-z]*.man)
|
||||
wcman_targets := $(wildcard ${srcdir}/libxt_[A-Z]*.man)
|
||||
wlist_matches := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_matches})
|
||||
wlist_targets := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_targets})
|
||||
|
||||
.manpages.lst: FORCE
|
||||
@echo "${wlist_targets} ${wlist_matches}" >$@.tmp; \
|
||||
cmp -s $@ $@.tmp || mv $@.tmp $@; \
|
||||
rm -f $@.tmp;
|
||||
|
||||
man_run = \
|
||||
${AM_V_GEN}for ext in $(1); do \
|
||||
f="${srcdir}/libxt_$$ext.man"; \
|
||||
if [ -f "$$f" ]; then \
|
||||
echo ".SS $$ext"; \
|
||||
cat "$$f"; \
|
||||
continue; \
|
||||
fi; \
|
||||
done >$@;
|
||||
|
||||
matches.man: .manpages.lst ${wcman_matches}
|
||||
$(call man_run,${wlist_matches})
|
||||
|
||||
targets.man: .manpages.lst ${wcman_targets}
|
||||
$(call man_run,${wlist_targets})
|
@@ -1,11 +1,11 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
include ${XA_TOPSRCDIR}/mconfig
|
||||
-include ${XA_TOPSRCDIR}/mconfig.*
|
||||
include ${XA_ABSTOPSRCDIR}/mconfig
|
||||
-include ${XA_ABSTOPSRCDIR}/mconfig.*
|
||||
|
||||
obj-m += compat_xtables.o
|
||||
|
||||
obj-${build_ACCOUNT} += xt_ACCOUNT.o
|
||||
obj-${build_ACCOUNT} += ACCOUNT/
|
||||
obj-${build_CHAOS} += xt_CHAOS.o
|
||||
obj-${build_DELUDE} += xt_DELUDE.o
|
||||
obj-${build_DHCPMAC} += xt_DHCPMAC.o
|
||||
@@ -26,6 +26,7 @@ obj-${build_ipset} += ipset/
|
||||
obj-${build_ipv4options} += xt_ipv4options.o
|
||||
obj-${build_length2} += xt_length2.o
|
||||
obj-${build_lscan} += xt_lscan.o
|
||||
obj-${build_pknock} += pknock/
|
||||
obj-${build_psd} += xt_psd.o
|
||||
obj-${build_quota2} += xt_quota2.o
|
||||
|
||||
|
24
extensions/Makefile.am
Normal file
24
extensions/Makefile.am
Normal file
@@ -0,0 +1,24 @@
|
||||
# -*- Makefile -*-
|
||||
# AUTOMAKE
|
||||
|
||||
# Not having Kbuild in Makefile.extra because it will already recurse
|
||||
.PHONY: modules modules_install clean_modules
|
||||
|
||||
_kcall = -C ${kbuilddir} M=${abs_srcdir}
|
||||
|
||||
modules:
|
||||
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} modules; fi;
|
||||
|
||||
modules_install:
|
||||
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} INSTALL_MOD_PATH=${DESTDIR} ext-mod-dir='$${INSTALL_MOD_DIR}' modules_install; fi;
|
||||
|
||||
clean_modules:
|
||||
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} clean; fi;
|
||||
|
||||
all-local: modules
|
||||
|
||||
install-exec-local: modules_install
|
||||
|
||||
clean-local: clean_modules
|
||||
|
||||
include ../Makefile.extra
|
@@ -1,4 +1,6 @@
|
||||
obj-${build_ACCOUNT} += libxt_ACCOUNT.so
|
||||
# -*- Makefile -*-
|
||||
|
||||
obj-${build_ACCOUNT} += ACCOUNT/
|
||||
obj-${build_CHAOS} += libxt_CHAOS.so
|
||||
obj-${build_DELUDE} += libxt_DELUDE.so
|
||||
obj-${build_DHCPMAC} += libxt_DHCPMAC.so libxt_dhcpmac.so
|
||||
@@ -19,5 +21,6 @@ obj-${build_ipset} += ipset/
|
||||
obj-${build_ipv4options} += libxt_ipv4options.so
|
||||
obj-${build_length2} += libxt_length2.so
|
||||
obj-${build_lscan} += libxt_lscan.so
|
||||
obj-${build_pknock} += pknock/
|
||||
obj-${build_psd} += libxt_psd.so
|
||||
obj-${build_quota2} += libxt_quota2.so
|
||||
|
2
extensions/ipset/.gitignore
vendored
2
extensions/ipset/.gitignore
vendored
@@ -1,3 +1 @@
|
||||
*.oo
|
||||
*.so
|
||||
/ipset
|
||||
|
@@ -1,85 +0,0 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
top_srcdir := @top_srcdir@
|
||||
srcdir := @srcdir@
|
||||
datarootdir := @datarootdir@
|
||||
abstop_srcdir := $(shell readlink -f ${top_srcdir})
|
||||
abssrcdir := $(shell readlink -f ${srcdir})
|
||||
|
||||
ifeq (${abstop_srcdir},)
|
||||
$(error Path resolution of ${top_srcdir} failed)
|
||||
endif
|
||||
ifeq (${abssrcdir},)
|
||||
$(error Path resolution of ${srcdir} failed)
|
||||
endif
|
||||
|
||||
prefix := @prefix@
|
||||
exec_prefix := @exec_prefix@
|
||||
sbindir := @sbindir@
|
||||
libdir := @libdir@
|
||||
libexecdir := @libexecdir@
|
||||
xtlibdir := @xtlibdir@
|
||||
kbuilddir := @kbuilddir@
|
||||
man8dir := @mandir@/man8
|
||||
|
||||
CC := @CC@
|
||||
CCLD := ${CC}
|
||||
CFLAGS := @CFLAGS@
|
||||
LDFLAGS := @LDFLAGS@
|
||||
regular_CFLAGS := @regular_CFLAGS@
|
||||
kinclude_CFLAGS := @kinclude_CFLAGS@
|
||||
xtables_CFLAGS := @xtables_CFLAGS@
|
||||
|
||||
AM_CFLAGS := ${regular_CFLAGS} -I${top_srcdir}/include ${xtables_CFLAGS} ${kinclude_CFLAGS} -DIPSET_LIB_DIR=\"${xtlibdir}\"
|
||||
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
|
||||
|
||||
VU := 0
|
||||
am__1verbose_CC_0 = @echo " CC " $@;
|
||||
am__1verbose_CCLD_0 = @echo " CCLD " $@;
|
||||
am__1verbose_CC_1 = @echo " CC " $@ "<-" $<;
|
||||
am__1verbose_CCLD_1 = @echo " CCLD " $@ "<-" $^;
|
||||
am__verbose_CC = ${am__1verbose_CC_${VU}}
|
||||
am__verbose_CCLD = ${am__1verbose_CCLD_${VU}}
|
||||
|
||||
#
|
||||
# Building blocks
|
||||
#
|
||||
targets := $(addsuffix .so,$(addprefix libipset_, \
|
||||
iphash ipmap ipporthash ipportiphash ipportnethash iptree \
|
||||
iptreemap macipmap nethash portmap setlist))
|
||||
|
||||
.SECONDARY:
|
||||
|
||||
.PHONY: all install clean distclean FORCE
|
||||
|
||||
all: ipset ${targets}
|
||||
|
||||
install: all
|
||||
@mkdir -p "${DESTDIR}${sbindir}" "${DESTDIR}${xtlibdir}" "${DESTDIR}${man8dir}";
|
||||
install -pm0755 ipset "${DESTDIR}${sbindir}/";
|
||||
install -pm0755 ${targets} "${DESTDIR}${xtlibdir}/";
|
||||
install -pm0644 ipset.8 "${DESTDIR}${man8dir}/";
|
||||
|
||||
clean:
|
||||
rm -f *.oo *.so *.o ipset;
|
||||
|
||||
distclean: clean
|
||||
rm -f .*.d;
|
||||
|
||||
-include .*.d
|
||||
|
||||
|
||||
ipset: ipset.o
|
||||
${am__verbose_CCLD}${CCLD} ${AM_LDFLAGS} ${LDFLAGS} -o $@ $< -ldl -rdynamic;
|
||||
|
||||
#
|
||||
# Shared libraries
|
||||
#
|
||||
lib%.so: lib%.oo
|
||||
${am__verbose_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
|
||||
|
||||
libipset_%.oo: ${srcdir}/ipset_%.c
|
||||
${am__verbose_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
|
||||
|
||||
%.o: %.c
|
||||
${am__verbose_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} ${CFLAGS} -o $@ -c $<;
|
11
extensions/ipset/Makefile.am
Normal file
11
extensions/ipset/Makefile.am
Normal file
@@ -0,0 +1,11 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
AM_CFLAGS = ${regular_CFLAGS} -DIPSET_LIB_DIR=\"${xtlibdir}\"
|
||||
|
||||
include ../../Makefile.extra
|
||||
|
||||
sbin_PROGRAMS = ipset
|
||||
ipset_LDADD = -ldl
|
||||
ipset_LDFLAGS = -rdynamic
|
||||
|
||||
man_MANS = ipset.8
|
7
extensions/ipset/Mbuild
Normal file
7
extensions/ipset/Mbuild
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
obj-m += $(addprefix lib,$(patsubst %.c,%.so,$(notdir \
|
||||
$(wildcard ${XA_SRCDIR}/ipset_*.c))))
|
||||
|
||||
libipset_%.oo: ${XA_SRCDIR}/ipset_%.c
|
||||
${AM_V_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
|
File diff suppressed because it is too large
Load Diff
@@ -48,7 +48,8 @@
|
||||
/*
|
||||
* Used so that the kernel module and ipset-binary can match their versions
|
||||
*/
|
||||
#define IP_SET_PROTOCOL_VERSION 3
|
||||
#define IP_SET_PROTOCOL_UNALIGNED 3
|
||||
#define IP_SET_PROTOCOL_VERSION 4
|
||||
|
||||
#define IP_SET_MAXNAMELEN 32 /* set names and set typenames */
|
||||
|
||||
@@ -236,7 +237,7 @@ struct ip_set_req_max_sets {
|
||||
struct ip_set_req_setnames {
|
||||
unsigned op;
|
||||
ip_set_id_t index; /* set to list/save */
|
||||
u_int32_t size; /* size to get setdata/bindings */
|
||||
u_int32_t size; /* size to get setdata */
|
||||
/* followed by sets number of struct ip_set_name_list */
|
||||
};
|
||||
|
||||
@@ -310,6 +311,11 @@ static inline int bitmap_bytes(ip_set_ip_t a, ip_set_ip_t b)
|
||||
/* General limit for the elements in a set */
|
||||
#define MAX_RANGE 0x0000FFFF
|
||||
|
||||
/* Alignment: 'unsigned long' unsupported */
|
||||
#define IPSET_ALIGNTO 4
|
||||
#define IPSET_ALIGN(len) (((len) + IPSET_ALIGNTO - 1) & ~(IPSET_ALIGNTO - 1))
|
||||
#define IPSET_VALIGN(len, old) ((old) ? (len) : IPSET_ALIGN(len))
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include "ip_set_compat.h"
|
||||
#include "ip_set_malloc.h"
|
||||
@@ -358,16 +364,13 @@ struct ip_set_type {
|
||||
*/
|
||||
int (*testip_kernel) (struct ip_set *set,
|
||||
const struct sk_buff * skb,
|
||||
ip_set_ip_t *ip,
|
||||
const u_int32_t *flags,
|
||||
unsigned char index);
|
||||
const u_int32_t *flags);
|
||||
|
||||
/* test for IP in set (userspace: ipset -T set IP)
|
||||
* return 0 if not in set, 1 if in set.
|
||||
*/
|
||||
int (*testip) (struct ip_set *set,
|
||||
const void *data, u_int32_t size,
|
||||
ip_set_ip_t *ip);
|
||||
const void *data, u_int32_t size);
|
||||
|
||||
/*
|
||||
* Size of the data structure passed by when
|
||||
@@ -381,8 +384,7 @@ struct ip_set_type {
|
||||
* If the address was not already in the set, 0 is returned.
|
||||
*/
|
||||
int (*addip) (struct ip_set *set,
|
||||
const void *data, u_int32_t size,
|
||||
ip_set_ip_t *ip);
|
||||
const void *data, u_int32_t size);
|
||||
|
||||
/* Add IP into set (kernel: iptables ... -j SET set src|dst)
|
||||
* Return -EEXIST if the address is already in the set,
|
||||
@@ -390,10 +392,8 @@ struct ip_set_type {
|
||||
* If the address was not already in the set, 0 is returned.
|
||||
*/
|
||||
int (*addip_kernel) (struct ip_set *set,
|
||||
const struct sk_buff * skb,
|
||||
ip_set_ip_t *ip,
|
||||
const u_int32_t *flags,
|
||||
unsigned char index);
|
||||
const struct sk_buff * skb,
|
||||
const u_int32_t *flags);
|
||||
|
||||
/* remove IP from set (userspace: ipset -D set --entry x)
|
||||
* Return -EEXIST if the address is NOT in the set,
|
||||
@@ -401,8 +401,7 @@ struct ip_set_type {
|
||||
* If the address really was in the set, 0 is returned.
|
||||
*/
|
||||
int (*delip) (struct ip_set *set,
|
||||
const void *data, u_int32_t size,
|
||||
ip_set_ip_t *ip);
|
||||
const void *data, u_int32_t size);
|
||||
|
||||
/* remove IP from set (kernel: iptables ... -j SET --entry x)
|
||||
* Return -EEXIST if the address is NOT in the set,
|
||||
@@ -410,10 +409,8 @@ struct ip_set_type {
|
||||
* If the address really was in the set, 0 is returned.
|
||||
*/
|
||||
int (*delip_kernel) (struct ip_set *set,
|
||||
const struct sk_buff * skb,
|
||||
ip_set_ip_t *ip,
|
||||
const u_int32_t *flags,
|
||||
unsigned char index);
|
||||
const struct sk_buff * skb,
|
||||
const u_int32_t *flags);
|
||||
|
||||
/* new set creation - allocated type specific items
|
||||
*/
|
||||
@@ -451,7 +448,7 @@ struct ip_set_type {
|
||||
|
||||
/* Listing: Get the size for the set members
|
||||
*/
|
||||
int (*list_members_size) (const struct ip_set *set);
|
||||
int (*list_members_size) (const struct ip_set *set, char dont_align);
|
||||
|
||||
/* Listing: Get the set members
|
||||
*
|
||||
@@ -461,7 +458,7 @@ struct ip_set_type {
|
||||
* correct.
|
||||
*/
|
||||
void (*list_members) (const struct ip_set *set,
|
||||
void *data);
|
||||
void *data, char dont_align);
|
||||
|
||||
char typename[IP_SET_MAXNAMELEN];
|
||||
unsigned char features;
|
||||
@@ -479,20 +476,11 @@ struct ip_set {
|
||||
char name[IP_SET_MAXNAMELEN]; /* the name of the set */
|
||||
rwlock_t lock; /* lock for concurrency control */
|
||||
ip_set_id_t id; /* set id for swapping */
|
||||
ip_set_id_t binding; /* default binding for the set */
|
||||
atomic_t ref; /* in kernel and in hash references */
|
||||
struct ip_set_type *type; /* the set types */
|
||||
void *data; /* pooltype specific data */
|
||||
};
|
||||
|
||||
/* Structure to bind set elements to sets */
|
||||
struct ip_set_hash {
|
||||
struct list_head list; /* list of clashing entries in hash */
|
||||
ip_set_ip_t ip; /* ip from set */
|
||||
ip_set_id_t id; /* set id */
|
||||
ip_set_id_t binding; /* set we bind the element to */
|
||||
};
|
||||
|
||||
/* register and unregister set references */
|
||||
extern ip_set_id_t ip_set_get_byname(const char name[IP_SET_MAXNAMELEN]);
|
||||
extern ip_set_id_t ip_set_get_byindex(ip_set_id_t index);
|
||||
@@ -523,12 +511,11 @@ extern int ip_set_testip_kernel(ip_set_id_t id,
|
||||
|
||||
#define UADT0(type, adt, args...) \
|
||||
static int \
|
||||
FNAME(type,_u,adt)(struct ip_set *set, const void *data, u_int32_t size,\
|
||||
ip_set_ip_t *hash_ip) \
|
||||
FNAME(type,_u,adt)(struct ip_set *set, const void *data, u_int32_t size)\
|
||||
{ \
|
||||
const STRUCT(ip_set_req_,type) *req = data; \
|
||||
\
|
||||
return FNAME(type,_,adt)(set, hash_ip , ## args); \
|
||||
return FNAME(type,_,adt)(set , ## args); \
|
||||
}
|
||||
|
||||
#define UADT(type, adt, args...) \
|
||||
@@ -538,14 +525,12 @@ FNAME(type,_u,adt)(struct ip_set *set, const void *data, u_int32_t size,\
|
||||
static int \
|
||||
FNAME(type,_k,adt)(struct ip_set *set, \
|
||||
const struct sk_buff *skb, \
|
||||
ip_set_ip_t *hash_ip, \
|
||||
const u_int32_t *flags, \
|
||||
unsigned char index) \
|
||||
const u_int32_t *flags) \
|
||||
{ \
|
||||
ip_set_ip_t ip = getfn(skb, flags[index]); \
|
||||
ip_set_ip_t ip = getfn(skb, flags); \
|
||||
\
|
||||
KADT_CONDITION \
|
||||
return FNAME(type,_,adt)(set, hash_ip, ip , ##args); \
|
||||
return FNAME(type,_,adt)(set, ip , ##args); \
|
||||
}
|
||||
|
||||
#define REGISTER_MODULE(type) \
|
||||
@@ -567,9 +552,9 @@ module_exit(ip_set_##type##_fini);
|
||||
/* Common functions */
|
||||
|
||||
static inline ip_set_ip_t
|
||||
ipaddr(const struct sk_buff *skb, u_int32_t flag)
|
||||
ipaddr(const struct sk_buff *skb, const u_int32_t *flags)
|
||||
{
|
||||
return ntohl(flag & IPSET_SRC ? ip_hdr(skb)->saddr : ip_hdr(skb)->daddr);
|
||||
return ntohl(flags[0] & IPSET_SRC ? ip_hdr(skb)->saddr : ip_hdr(skb)->daddr);
|
||||
}
|
||||
|
||||
#define jhash_ip(map, i, ip) jhash_1word(ip, *(map->initval + i))
|
||||
@@ -579,4 +564,6 @@ ipaddr(const struct sk_buff *skb, u_int32_t flag)
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#define UNUSED __attribute__ ((unused))
|
||||
|
||||
#endif /*_IP_SET_H*/
|
||||
|
@@ -77,22 +77,21 @@ type##_list_header(const struct ip_set *set, void *data) \
|
||||
__##type##_list_header(map, header); \
|
||||
}
|
||||
|
||||
#define BITMAP_LIST_MEMBERS_SIZE(type) \
|
||||
#define BITMAP_LIST_MEMBERS_SIZE(type, dtype, sizeid, testfn) \
|
||||
static int \
|
||||
type##_list_members_size(const struct ip_set *set) \
|
||||
type##_list_members_size(const struct ip_set *set, char dont_align) \
|
||||
{ \
|
||||
const struct ip_set_##type *map = set->data; \
|
||||
ip_set_ip_t i, elements = 0; \
|
||||
\
|
||||
return map->size; \
|
||||
}
|
||||
|
||||
#define BITMAP_LIST_MEMBERS(type) \
|
||||
static void \
|
||||
type##_list_members(const struct ip_set *set, void *data) \
|
||||
{ \
|
||||
const struct ip_set_##type *map = set->data; \
|
||||
if (dont_align) \
|
||||
return map->size; \
|
||||
\
|
||||
memcpy(data, map->members, map->size); \
|
||||
for (i = 0; i < sizeid; i++) \
|
||||
if (testfn) \
|
||||
elements++; \
|
||||
\
|
||||
return elements * IPSET_ALIGN(sizeof(dtype)); \
|
||||
}
|
||||
|
||||
#define IP_SET_TYPE(type, __features) \
|
||||
|
@@ -65,7 +65,28 @@ static inline void *kzalloc(size_t size, gfp_t flags)
|
||||
#define KMEM_CACHE_CREATE(name, size) \
|
||||
kmem_cache_create(name, size, 0, 0, NULL)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef NIPQUAD
|
||||
#define NIPQUAD(addr) \
|
||||
((unsigned char *)&addr)[0], \
|
||||
((unsigned char *)&addr)[1], \
|
||||
((unsigned char *)&addr)[2], \
|
||||
((unsigned char *)&addr)[3]
|
||||
#endif
|
||||
|
||||
#ifndef HIPQUAD
|
||||
#if defined(__LITTLE_ENDIAN)
|
||||
#define HIPQUAD(addr) \
|
||||
((unsigned char *)&addr)[3], \
|
||||
((unsigned char *)&addr)[2], \
|
||||
((unsigned char *)&addr)[1], \
|
||||
((unsigned char *)&addr)[0]
|
||||
#elif defined(__BIG_ENDIAN)
|
||||
#define HIPQUAD NIPQUAD
|
||||
#else
|
||||
#error "Please fix asm/byteorder.h"
|
||||
#endif /* __LITTLE_ENDIAN */
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _IP_SET_COMPAT_H */
|
||||
|
@@ -7,7 +7,7 @@
|
||||
|
||||
/* We must handle non-linear skbs */
|
||||
static inline ip_set_ip_t
|
||||
get_port(const struct sk_buff *skb, u_int32_t flags)
|
||||
get_port(const struct sk_buff *skb, const u_int32_t *flags)
|
||||
{
|
||||
struct iphdr *iph = ip_hdr(skb);
|
||||
u_int16_t offset = ntohs(iph->frag_off) & IP_OFFSET;
|
||||
@@ -23,7 +23,7 @@ get_port(const struct sk_buff *skb, u_int32_t flags)
|
||||
/* No choice either */
|
||||
return INVALID_PORT;
|
||||
|
||||
return ntohs(flags & IPSET_SRC ?
|
||||
return ntohs(flags[0] & IPSET_SRC ?
|
||||
tcph.source : tcph.dest);
|
||||
}
|
||||
case IPPROTO_UDP: {
|
||||
@@ -36,7 +36,7 @@ get_port(const struct sk_buff *skb, u_int32_t flags)
|
||||
/* No choice either */
|
||||
return INVALID_PORT;
|
||||
|
||||
return ntohs(flags & IPSET_SRC ?
|
||||
return ntohs(flags[0] & IPSET_SRC ?
|
||||
udph.source : udph.dest);
|
||||
}
|
||||
default:
|
||||
|
@@ -182,38 +182,46 @@ type##_list_header(const struct ip_set *set, void *data) \
|
||||
|
||||
#define HASH_LIST_MEMBERS_SIZE(type, dtype) \
|
||||
static int \
|
||||
type##_list_members_size(const struct ip_set *set) \
|
||||
type##_list_members_size(const struct ip_set *set, char dont_align) \
|
||||
{ \
|
||||
const struct ip_set_##type *map = set->data; \
|
||||
\
|
||||
return (map->hashsize * sizeof(dtype)); \
|
||||
return (map->elements * IPSET_VALIGN(sizeof(dtype), dont_align));\
|
||||
}
|
||||
|
||||
#define HASH_LIST_MEMBERS(type, dtype) \
|
||||
static void \
|
||||
type##_list_members(const struct ip_set *set, void *data) \
|
||||
type##_list_members(const struct ip_set *set, void *data, char dont_align)\
|
||||
{ \
|
||||
const struct ip_set_##type *map = set->data; \
|
||||
dtype *elem; \
|
||||
uint32_t i; \
|
||||
dtype *elem, *d; \
|
||||
uint32_t i, n = 0; \
|
||||
\
|
||||
for (i = 0; i < map->hashsize; i++) { \
|
||||
elem = HARRAY_ELEM(map->members, dtype *, i); \
|
||||
((dtype *)data)[i] = *elem; \
|
||||
if (*elem) { \
|
||||
d = data + n * IPSET_VALIGN(sizeof(dtype), dont_align);\
|
||||
*d = *elem; \
|
||||
n++; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define HASH_LIST_MEMBERS_MEMCPY(type, dtype) \
|
||||
#define HASH_LIST_MEMBERS_MEMCPY(type, dtype, nonzero) \
|
||||
static void \
|
||||
type##_list_members(const struct ip_set *set, void *data) \
|
||||
type##_list_members(const struct ip_set *set, void *data, char dont_align)\
|
||||
{ \
|
||||
const struct ip_set_##type *map = set->data; \
|
||||
dtype *elem; \
|
||||
uint32_t i; \
|
||||
uint32_t i, n = 0; \
|
||||
\
|
||||
for (i = 0; i < map->hashsize; i++) { \
|
||||
elem = HARRAY_ELEM(map->members, dtype *, i); \
|
||||
memcpy((((dtype *)data)+i), elem, sizeof(dtype)); \
|
||||
if (nonzero) { \
|
||||
memcpy(data + n * IPSET_VALIGN(sizeof(dtype), dont_align),\
|
||||
elem, sizeof(dtype)); \
|
||||
n++; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@@ -25,22 +25,21 @@
|
||||
static int limit = MAX_RANGE;
|
||||
|
||||
static inline __u32
|
||||
iphash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
iphash_id(struct ip_set *set, ip_set_ip_t ip)
|
||||
{
|
||||
struct ip_set_iphash *map = set->data;
|
||||
__u32 id;
|
||||
u_int16_t i;
|
||||
ip_set_ip_t *elem;
|
||||
|
||||
*hash_ip = ip & map->netmask;
|
||||
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u, %u.%u.%u.%u",
|
||||
set->name, HIPQUAD(ip), HIPQUAD(*hash_ip), HIPQUAD(map->netmask));
|
||||
|
||||
|
||||
ip &= map->netmask;
|
||||
DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
|
||||
for (i = 0; i < map->probes; i++) {
|
||||
id = jhash_ip(map, i, *hash_ip) % map->hashsize;
|
||||
id = jhash_ip(map, i, ip) % map->hashsize;
|
||||
DP("hash key: %u", id);
|
||||
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
|
||||
if (*elem == *hash_ip)
|
||||
if (*elem == ip)
|
||||
return id;
|
||||
/* No shortcut - there can be deleted entries. */
|
||||
}
|
||||
@@ -48,9 +47,9 @@ iphash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
}
|
||||
|
||||
static inline int
|
||||
iphash_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
iphash_test(struct ip_set *set, ip_set_ip_t ip)
|
||||
{
|
||||
return (ip && iphash_id(set, hash_ip, ip) != UINT_MAX);
|
||||
return (ip && iphash_id(set, ip) != UINT_MAX);
|
||||
}
|
||||
|
||||
#define KADT_CONDITION
|
||||
@@ -84,16 +83,15 @@ __iphash_add(struct ip_set_iphash *map, ip_set_ip_t *ip)
|
||||
}
|
||||
|
||||
static inline int
|
||||
iphash_add(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
iphash_add(struct ip_set *set, ip_set_ip_t ip)
|
||||
{
|
||||
struct ip_set_iphash *map = set->data;
|
||||
|
||||
if (!ip || map->elements >= limit)
|
||||
return -ERANGE;
|
||||
|
||||
*hash_ip = ip & map->netmask;
|
||||
|
||||
return __iphash_add(map, hash_ip);
|
||||
ip &= map->netmask;
|
||||
return __iphash_add(map, &ip);
|
||||
}
|
||||
|
||||
UADT(iphash, add)
|
||||
@@ -108,7 +106,7 @@ __iphash_retry(struct ip_set_iphash *tmp, struct ip_set_iphash *map)
|
||||
HASH_RETRY(iphash, ip_set_ip_t)
|
||||
|
||||
static inline int
|
||||
iphash_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
iphash_del(struct ip_set *set, ip_set_ip_t ip)
|
||||
{
|
||||
struct ip_set_iphash *map = set->data;
|
||||
ip_set_ip_t id, *elem;
|
||||
@@ -116,7 +114,7 @@ iphash_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
if (!ip)
|
||||
return -ERANGE;
|
||||
|
||||
id = iphash_id(set, hash_ip, ip);
|
||||
id = iphash_id(set, ip);
|
||||
if (id == UINT_MAX)
|
||||
return -EEXIST;
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
#include "ip_set.h"
|
||||
#include "ip_set_hashes.h"
|
||||
|
||||
#define SETTYPE_NAME "iphash"
|
||||
#define SETTYPE_NAME "iphash"
|
||||
|
||||
struct ip_set_iphash {
|
||||
ip_set_ip_t *members; /* the iphash proper */
|
||||
|
@@ -22,21 +22,19 @@
|
||||
static inline ip_set_ip_t
|
||||
ip_to_id(const struct ip_set_ipmap *map, ip_set_ip_t ip)
|
||||
{
|
||||
return (ip - map->first_ip)/map->hosts;
|
||||
return ((ip & map->netmask) - map->first_ip)/map->hosts;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ipmap_test(const struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
ipmap_test(const struct ip_set *set, ip_set_ip_t ip)
|
||||
{
|
||||
const struct ip_set_ipmap *map = set->data;
|
||||
|
||||
if (ip < map->first_ip || ip > map->last_ip)
|
||||
return -ERANGE;
|
||||
|
||||
*hash_ip = ip & map->netmask;
|
||||
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
|
||||
set->name, HIPQUAD(ip), HIPQUAD(*hash_ip));
|
||||
return !!test_bit(ip_to_id(map, *hash_ip), map->members);
|
||||
DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
|
||||
return !!test_bit(ip_to_id(map, ip), map->members);
|
||||
}
|
||||
|
||||
#define KADT_CONDITION
|
||||
@@ -45,16 +43,15 @@ UADT(ipmap, test)
|
||||
KADT(ipmap, test, ipaddr)
|
||||
|
||||
static inline int
|
||||
ipmap_add(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
ipmap_add(struct ip_set *set, ip_set_ip_t ip)
|
||||
{
|
||||
struct ip_set_ipmap *map = set->data;
|
||||
|
||||
if (ip < map->first_ip || ip > map->last_ip)
|
||||
return -ERANGE;
|
||||
|
||||
*hash_ip = ip & map->netmask;
|
||||
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
|
||||
if (test_and_set_bit(ip_to_id(map, *hash_ip), map->members))
|
||||
DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
|
||||
if (test_and_set_bit(ip_to_id(map, ip), map->members))
|
||||
return -EEXIST;
|
||||
|
||||
return 0;
|
||||
@@ -64,16 +61,15 @@ UADT(ipmap, add)
|
||||
KADT(ipmap, add, ipaddr)
|
||||
|
||||
static inline int
|
||||
ipmap_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
ipmap_del(struct ip_set *set, ip_set_ip_t ip)
|
||||
{
|
||||
struct ip_set_ipmap *map = set->data;
|
||||
|
||||
if (ip < map->first_ip || ip > map->last_ip)
|
||||
return -ERANGE;
|
||||
|
||||
*hash_ip = ip & map->netmask;
|
||||
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
|
||||
if (!test_and_clear_bit(ip_to_id(map, *hash_ip), map->members))
|
||||
DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
|
||||
if (!test_and_clear_bit(ip_to_id(map, ip), map->members))
|
||||
return -EEXIST;
|
||||
|
||||
return 0;
|
||||
@@ -130,8 +126,28 @@ __ipmap_list_header(const struct ip_set_ipmap *map,
|
||||
}
|
||||
|
||||
BITMAP_LIST_HEADER(ipmap)
|
||||
BITMAP_LIST_MEMBERS_SIZE(ipmap)
|
||||
BITMAP_LIST_MEMBERS(ipmap)
|
||||
BITMAP_LIST_MEMBERS_SIZE(ipmap, ip_set_ip_t, map->sizeid,
|
||||
test_bit(i, map->members))
|
||||
|
||||
static void
|
||||
ipmap_list_members(const struct ip_set *set, void *data, char dont_align)
|
||||
{
|
||||
const struct ip_set_ipmap *map = set->data;
|
||||
uint32_t i, n = 0;
|
||||
ip_set_ip_t *d;
|
||||
|
||||
if (dont_align) {
|
||||
memcpy(data, map->members, map->size);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < map->sizeid; i++)
|
||||
if (test_bit(i, map->members)) {
|
||||
d = data + n * IPSET_ALIGN(sizeof(ip_set_ip_t));
|
||||
*d = map->first_ip + i * map->hosts;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
IP_SET_TYPE(ipmap, IPSET_TYPE_IP | IPSET_DATA_SINGLE)
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
#include "ip_set.h"
|
||||
#include "ip_set_bitmaps.h"
|
||||
|
||||
#define SETTYPE_NAME "ipmap"
|
||||
#define SETTYPE_NAME "ipmap"
|
||||
|
||||
struct ip_set_ipmap {
|
||||
void *members; /* the ipmap proper */
|
||||
|
@@ -28,26 +28,23 @@
|
||||
static int limit = MAX_RANGE;
|
||||
|
||||
static inline __u32
|
||||
ipporthash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ip_set_ip_t ip, ip_set_ip_t port)
|
||||
ipporthash_id(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port)
|
||||
{
|
||||
struct ip_set_ipporthash *map = set->data;
|
||||
__u32 id;
|
||||
u_int16_t i;
|
||||
ip_set_ip_t *elem;
|
||||
|
||||
*hash_ip = pack_ip_port(map, ip, port);
|
||||
ip = pack_ip_port(map, ip, port);
|
||||
|
||||
DP("set: %s, ipport:%u.%u.%u.%u:%u, %u.%u.%u.%u",
|
||||
set->name, HIPQUAD(ip), port, HIPQUAD(*hash_ip));
|
||||
if (!*hash_ip)
|
||||
if (!ip)
|
||||
return UINT_MAX;
|
||||
|
||||
for (i = 0; i < map->probes; i++) {
|
||||
id = jhash_ip(map, i, *hash_ip) % map->hashsize;
|
||||
id = jhash_ip(map, i, ip) % map->hashsize;
|
||||
DP("hash key: %u", id);
|
||||
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
|
||||
if (*elem == *hash_ip)
|
||||
if (*elem == ip)
|
||||
return id;
|
||||
/* No shortcut - there can be deleted entries. */
|
||||
}
|
||||
@@ -55,24 +52,23 @@ ipporthash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
}
|
||||
|
||||
static inline int
|
||||
ipporthash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ip_set_ip_t ip, ip_set_ip_t port)
|
||||
ipporthash_test(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port)
|
||||
{
|
||||
struct ip_set_ipporthash *map = set->data;
|
||||
|
||||
if (ip < map->first_ip || ip > map->last_ip)
|
||||
return -ERANGE;
|
||||
|
||||
return (ipporthash_id(set, hash_ip, ip, port) != UINT_MAX);
|
||||
return (ipporthash_id(set, ip, port) != UINT_MAX);
|
||||
}
|
||||
|
||||
#define KADT_CONDITION \
|
||||
ip_set_ip_t port; \
|
||||
\
|
||||
if (flags[index+1] == 0) \
|
||||
if (flags[1] == 0) \
|
||||
return 0; \
|
||||
\
|
||||
port = get_port(skb, flags[index+1]); \
|
||||
port = get_port(skb, flags++); \
|
||||
\
|
||||
if (port == INVALID_PORT) \
|
||||
return 0;
|
||||
@@ -106,8 +102,7 @@ __ipporthash_add(struct ip_set_ipporthash *map, ip_set_ip_t *ip)
|
||||
}
|
||||
|
||||
static inline int
|
||||
ipporthash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ip_set_ip_t ip, ip_set_ip_t port)
|
||||
ipporthash_add(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port)
|
||||
{
|
||||
struct ip_set_ipporthash *map = set->data;
|
||||
if (map->elements > limit)
|
||||
@@ -115,12 +110,12 @@ ipporthash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
if (ip < map->first_ip || ip > map->last_ip)
|
||||
return -ERANGE;
|
||||
|
||||
*hash_ip = pack_ip_port(map, ip, port);
|
||||
ip = pack_ip_port(map, ip, port);
|
||||
|
||||
if (!*hash_ip)
|
||||
if (!ip)
|
||||
return -ERANGE;
|
||||
|
||||
return __ipporthash_add(map, hash_ip);
|
||||
return __ipporthash_add(map, &ip);
|
||||
}
|
||||
|
||||
UADT(ipporthash, add, req->port)
|
||||
@@ -137,8 +132,7 @@ __ipporthash_retry(struct ip_set_ipporthash *tmp,
|
||||
HASH_RETRY(ipporthash, ip_set_ip_t)
|
||||
|
||||
static inline int
|
||||
ipporthash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ip_set_ip_t ip, ip_set_ip_t port)
|
||||
ipporthash_del(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port)
|
||||
{
|
||||
struct ip_set_ipporthash *map = set->data;
|
||||
ip_set_ip_t id;
|
||||
@@ -147,7 +141,7 @@ ipporthash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
if (ip < map->first_ip || ip > map->last_ip)
|
||||
return -ERANGE;
|
||||
|
||||
id = ipporthash_id(set, hash_ip, ip, port);
|
||||
id = ipporthash_id(set, ip, port);
|
||||
|
||||
if (id == UINT_MAX)
|
||||
return -EEXIST;
|
||||
|
@@ -4,7 +4,7 @@
|
||||
#include "ip_set.h"
|
||||
#include "ip_set_hashes.h"
|
||||
|
||||
#define SETTYPE_NAME "ipporthash"
|
||||
#define SETTYPE_NAME "ipporthash"
|
||||
|
||||
struct ip_set_ipporthash {
|
||||
ip_set_ip_t *members; /* the ipporthash proper */
|
||||
|
@@ -31,7 +31,7 @@ static int limit = MAX_RANGE;
|
||||
jhash_2words(ipport, ip1, *(map->initval + i))
|
||||
|
||||
static inline __u32
|
||||
ipportiphash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ipportiphash_id(struct ip_set *set,
|
||||
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
|
||||
{
|
||||
struct ip_set_ipportiphash *map = set->data;
|
||||
@@ -39,17 +39,15 @@ ipportiphash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
u_int16_t i;
|
||||
struct ipportip *elem;
|
||||
|
||||
*hash_ip = pack_ip_port(map, ip, port);
|
||||
DP("set: %s, ipport:%u.%u.%u.%u:%u, %u.%u.%u.%u",
|
||||
set->name, HIPQUAD(ip), port, HIPQUAD(*hash_ip));
|
||||
if (!(*hash_ip || ip1))
|
||||
ip = pack_ip_port(map, ip, port);
|
||||
if (!(ip || ip1))
|
||||
return UINT_MAX;
|
||||
|
||||
for (i = 0; i < map->probes; i++) {
|
||||
id = jhash_ip2(map, i, *hash_ip, ip1) % map->hashsize;
|
||||
id = jhash_ip2(map, i, ip, ip1) % map->hashsize;
|
||||
DP("hash key: %u", id);
|
||||
elem = HARRAY_ELEM(map->members, struct ipportip *, id);
|
||||
if (elem->ip == *hash_ip && elem->ip1 == ip1)
|
||||
if (elem->ip == ip && elem->ip1 == ip1)
|
||||
return id;
|
||||
/* No shortcut - there can be deleted entries. */
|
||||
}
|
||||
@@ -57,7 +55,7 @@ ipportiphash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
}
|
||||
|
||||
static inline int
|
||||
ipportiphash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ipportiphash_test(struct ip_set *set,
|
||||
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
|
||||
{
|
||||
struct ip_set_ipportiphash *map = set->data;
|
||||
@@ -65,17 +63,17 @@ ipportiphash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
if (ip < map->first_ip || ip > map->last_ip)
|
||||
return -ERANGE;
|
||||
|
||||
return (ipportiphash_id(set, hash_ip, ip, port, ip1) != UINT_MAX);
|
||||
return (ipportiphash_id(set, ip, port, ip1) != UINT_MAX);
|
||||
}
|
||||
|
||||
#define KADT_CONDITION \
|
||||
ip_set_ip_t port, ip1; \
|
||||
\
|
||||
if (flags[index+2] == 0) \
|
||||
if (flags[2] == 0) \
|
||||
return 0; \
|
||||
\
|
||||
port = get_port(skb, flags[index+1]); \
|
||||
ip1 = ipaddr(skb, flags[index+2]); \
|
||||
port = get_port(skb, flags++); \
|
||||
ip1 = ipaddr(skb, flags++); \
|
||||
\
|
||||
if (port == INVALID_PORT) \
|
||||
return 0;
|
||||
@@ -85,23 +83,23 @@ KADT(ipportiphash, test, ipaddr, port, ip1)
|
||||
|
||||
static inline int
|
||||
__ipportip_add(struct ip_set_ipportiphash *map,
|
||||
ip_set_ip_t hash_ip, ip_set_ip_t ip1)
|
||||
ip_set_ip_t ip, ip_set_ip_t ip1)
|
||||
{
|
||||
__u32 probe;
|
||||
u_int16_t i;
|
||||
struct ipportip *elem, *slot = NULL;
|
||||
|
||||
for (i = 0; i < map->probes; i++) {
|
||||
probe = jhash_ip2(map, i, hash_ip, ip1) % map->hashsize;
|
||||
probe = jhash_ip2(map, i, ip, ip1) % map->hashsize;
|
||||
elem = HARRAY_ELEM(map->members, struct ipportip *, probe);
|
||||
if (elem->ip == hash_ip && elem->ip1 == ip1)
|
||||
if (elem->ip == ip && elem->ip1 == ip1)
|
||||
return -EEXIST;
|
||||
if (!(slot || elem->ip || elem->ip1))
|
||||
slot = elem;
|
||||
/* There can be deleted entries, must check all slots */
|
||||
}
|
||||
if (slot) {
|
||||
slot->ip = hash_ip;
|
||||
slot->ip = ip;
|
||||
slot->ip1 = ip1;
|
||||
map->elements++;
|
||||
return 0;
|
||||
@@ -118,7 +116,7 @@ __ipportiphash_add(struct ip_set_ipportiphash *map,
|
||||
}
|
||||
|
||||
static inline int
|
||||
ipportiphash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ipportiphash_add(struct ip_set *set,
|
||||
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
|
||||
{
|
||||
struct ip_set_ipportiphash *map = set->data;
|
||||
@@ -128,11 +126,11 @@ ipportiphash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
if (ip < map->first_ip || ip > map->last_ip)
|
||||
return -ERANGE;
|
||||
|
||||
*hash_ip = pack_ip_port(map, ip, port);
|
||||
if (!(*hash_ip || ip1))
|
||||
ip = pack_ip_port(map, ip, port);
|
||||
if (!(ip || ip1))
|
||||
return -ERANGE;
|
||||
|
||||
return __ipportip_add(map, *hash_ip, ip1);
|
||||
return __ipportip_add(map, ip, ip1);
|
||||
}
|
||||
|
||||
UADT(ipportiphash, add, req->port, req->ip1)
|
||||
@@ -149,7 +147,7 @@ __ipportiphash_retry(struct ip_set_ipportiphash *tmp,
|
||||
HASH_RETRY2(ipportiphash, struct ipportip)
|
||||
|
||||
static inline int
|
||||
ipportiphash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ipportiphash_del(struct ip_set *set,
|
||||
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
|
||||
{
|
||||
struct ip_set_ipportiphash *map = set->data;
|
||||
@@ -159,7 +157,7 @@ ipportiphash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
if (ip < map->first_ip || ip > map->last_ip)
|
||||
return -ERANGE;
|
||||
|
||||
id = ipportiphash_id(set, hash_ip, ip, port, ip1);
|
||||
id = ipportiphash_id(set, ip, port, ip1);
|
||||
|
||||
if (id == UINT_MAX)
|
||||
return -EEXIST;
|
||||
@@ -202,7 +200,8 @@ __ipportiphash_list_header(const struct ip_set_ipportiphash *map,
|
||||
|
||||
HASH_LIST_HEADER(ipportiphash)
|
||||
HASH_LIST_MEMBERS_SIZE(ipportiphash, struct ipportip)
|
||||
HASH_LIST_MEMBERS_MEMCPY(ipportiphash, struct ipportip)
|
||||
HASH_LIST_MEMBERS_MEMCPY(ipportiphash, struct ipportip,
|
||||
(elem->ip || elem->ip1))
|
||||
|
||||
IP_SET_RTYPE(ipportiphash, IPSET_TYPE_IP | IPSET_TYPE_PORT
|
||||
| IPSET_TYPE_IP1 | IPSET_DATA_TRIPLE)
|
||||
|
@@ -4,7 +4,7 @@
|
||||
#include "ip_set.h"
|
||||
#include "ip_set_hashes.h"
|
||||
|
||||
#define SETTYPE_NAME "ipportiphash"
|
||||
#define SETTYPE_NAME "ipportiphash"
|
||||
|
||||
struct ipportip {
|
||||
ip_set_ip_t ip;
|
||||
|
@@ -31,7 +31,7 @@ static int limit = MAX_RANGE;
|
||||
jhash_2words(ipport, ip1, *(map->initval + i))
|
||||
|
||||
static inline __u32
|
||||
ipportnethash_id_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ipportnethash_id_cidr(struct ip_set *set,
|
||||
ip_set_ip_t ip, ip_set_ip_t port,
|
||||
ip_set_ip_t ip1, uint8_t cidr)
|
||||
{
|
||||
@@ -40,18 +40,16 @@ ipportnethash_id_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
u_int16_t i;
|
||||
struct ipportip *elem;
|
||||
|
||||
*hash_ip = pack_ip_port(map, ip, port);
|
||||
DP("set: %s, ipport:%u.%u.%u.%u:%u, %u.%u.%u.%u",
|
||||
set->name, HIPQUAD(ip), port, HIPQUAD(*hash_ip));
|
||||
ip = pack_ip_port(map, ip, port);
|
||||
ip1 = pack_ip_cidr(ip1, cidr);
|
||||
if (!(*hash_ip || ip1))
|
||||
if (!(ip || ip1))
|
||||
return UINT_MAX;
|
||||
|
||||
for (i = 0; i < map->probes; i++) {
|
||||
id = jhash_ip2(map, i, *hash_ip, ip1) % map->hashsize;
|
||||
id = jhash_ip2(map, i, ip, ip1) % map->hashsize;
|
||||
DP("hash key: %u", id);
|
||||
elem = HARRAY_ELEM(map->members, struct ipportip *, id);
|
||||
if (elem->ip == *hash_ip && elem->ip1 == ip1)
|
||||
if (elem->ip == ip && elem->ip1 == ip1)
|
||||
return id;
|
||||
/* No shortcut - there can be deleted entries. */
|
||||
}
|
||||
@@ -59,7 +57,7 @@ ipportnethash_id_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
}
|
||||
|
||||
static inline __u32
|
||||
ipportnethash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ipportnethash_id(struct ip_set *set,
|
||||
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
|
||||
{
|
||||
struct ip_set_ipportnethash *map = set->data;
|
||||
@@ -67,8 +65,7 @@ ipportnethash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 30 && map->cidr[i]; i++) {
|
||||
id = ipportnethash_id_cidr(set, hash_ip, ip, port, ip1,
|
||||
map->cidr[i]);
|
||||
id = ipportnethash_id_cidr(set, ip, port, ip1, map->cidr[i]);
|
||||
if (id != UINT_MAX)
|
||||
break;
|
||||
}
|
||||
@@ -76,7 +73,7 @@ ipportnethash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
}
|
||||
|
||||
static inline int
|
||||
ipportnethash_test_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ipportnethash_test_cidr(struct ip_set *set,
|
||||
ip_set_ip_t ip, ip_set_ip_t port,
|
||||
ip_set_ip_t ip1, uint8_t cidr)
|
||||
{
|
||||
@@ -85,12 +82,11 @@ ipportnethash_test_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
if (ip < map->first_ip || ip > map->last_ip)
|
||||
return -ERANGE;
|
||||
|
||||
return (ipportnethash_id_cidr(set, hash_ip, ip, port, ip1,
|
||||
cidr) != UINT_MAX);
|
||||
return (ipportnethash_id_cidr(set, ip, port, ip1, cidr) != UINT_MAX);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ipportnethash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ipportnethash_test(struct ip_set *set,
|
||||
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
|
||||
{
|
||||
struct ip_set_ipportnethash *map = set->data;
|
||||
@@ -98,32 +94,30 @@ ipportnethash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
if (ip < map->first_ip || ip > map->last_ip)
|
||||
return -ERANGE;
|
||||
|
||||
return (ipportnethash_id(set, hash_ip, ip, port, ip1) != UINT_MAX);
|
||||
return (ipportnethash_id(set, ip, port, ip1) != UINT_MAX);
|
||||
}
|
||||
|
||||
static int
|
||||
ipportnethash_utest(struct ip_set *set, const void *data, u_int32_t size,
|
||||
ip_set_ip_t *hash_ip)
|
||||
ipportnethash_utest(struct ip_set *set, const void *data, u_int32_t size)
|
||||
{
|
||||
const struct ip_set_req_ipportnethash *req = data;
|
||||
|
||||
if (req->cidr <= 0 || req->cidr > 32)
|
||||
return -EINVAL;
|
||||
return (req->cidr == 32
|
||||
? ipportnethash_test(set, hash_ip, req->ip, req->port,
|
||||
req->ip1)
|
||||
: ipportnethash_test_cidr(set, hash_ip, req->ip, req->port,
|
||||
? ipportnethash_test(set, req->ip, req->port, req->ip1)
|
||||
: ipportnethash_test_cidr(set, req->ip, req->port,
|
||||
req->ip1, req->cidr));
|
||||
}
|
||||
|
||||
#define KADT_CONDITION \
|
||||
ip_set_ip_t port, ip1; \
|
||||
\
|
||||
if (flags[index+2] == 0) \
|
||||
if (flags[2] == 0) \
|
||||
return 0; \
|
||||
\
|
||||
port = get_port(skb, flags[index+1]); \
|
||||
ip1 = ipaddr(skb, flags[index+2]); \
|
||||
port = get_port(skb, flags++); \
|
||||
ip1 = ipaddr(skb, flags++); \
|
||||
\
|
||||
if (port == INVALID_PORT) \
|
||||
return 0;
|
||||
@@ -132,23 +126,23 @@ KADT(ipportnethash, test, ipaddr, port, ip1)
|
||||
|
||||
static inline int
|
||||
__ipportnet_add(struct ip_set_ipportnethash *map,
|
||||
ip_set_ip_t hash_ip, ip_set_ip_t ip1)
|
||||
ip_set_ip_t ip, ip_set_ip_t ip1)
|
||||
{
|
||||
__u32 probe;
|
||||
u_int16_t i;
|
||||
struct ipportip *elem, *slot = NULL;
|
||||
|
||||
for (i = 0; i < map->probes; i++) {
|
||||
probe = jhash_ip2(map, i, hash_ip, ip1) % map->hashsize;
|
||||
probe = jhash_ip2(map, i, ip, ip1) % map->hashsize;
|
||||
elem = HARRAY_ELEM(map->members, struct ipportip *, probe);
|
||||
if (elem->ip == hash_ip && elem->ip1 == ip1)
|
||||
if (elem->ip == ip && elem->ip1 == ip1)
|
||||
return -EEXIST;
|
||||
if (!(slot || elem->ip || elem->ip1))
|
||||
slot = elem;
|
||||
/* There can be deleted entries, must check all slots */
|
||||
}
|
||||
if (slot) {
|
||||
slot->ip = hash_ip;
|
||||
slot->ip = ip;
|
||||
slot->ip1 = ip1;
|
||||
map->elements++;
|
||||
return 0;
|
||||
@@ -165,7 +159,7 @@ __ipportnethash_add(struct ip_set_ipportnethash *map,
|
||||
}
|
||||
|
||||
static inline int
|
||||
ipportnethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ipportnethash_add(struct ip_set *set,
|
||||
ip_set_ip_t ip, ip_set_ip_t port,
|
||||
ip_set_ip_t ip1, uint8_t cidr)
|
||||
{
|
||||
@@ -182,12 +176,12 @@ ipportnethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
if (map->nets[cidr-1] == UINT16_MAX)
|
||||
return -ERANGE;
|
||||
|
||||
*hash_ip = pack_ip_port(map, ip, port);
|
||||
ip = pack_ip_port(map, ip, port);
|
||||
ip1 = pack_ip_cidr(ip1, cidr);
|
||||
if (!(*hash_ip || ip1))
|
||||
if (!(ip || ip1))
|
||||
return -ERANGE;
|
||||
|
||||
ret =__ipportnet_add(map, *hash_ip, ip1);
|
||||
ret =__ipportnet_add(map, ip, ip1);
|
||||
if (ret == 0) {
|
||||
if (!map->nets[cidr-1]++)
|
||||
add_cidr_size(map->cidr, cidr);
|
||||
@@ -202,11 +196,11 @@ ipportnethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
uint8_t cidr = map->cidr[0] ? map->cidr[0] : 31; \
|
||||
ip_set_ip_t port, ip1; \
|
||||
\
|
||||
if (flags[index+2] == 0) \
|
||||
if (flags[2] == 0) \
|
||||
return 0; \
|
||||
\
|
||||
port = get_port(skb, flags[index+1]); \
|
||||
ip1 = ipaddr(skb, flags[index+2]); \
|
||||
port = get_port(skb, flags++); \
|
||||
ip1 = ipaddr(skb, flags++); \
|
||||
\
|
||||
if (port == INVALID_PORT) \
|
||||
return 0;
|
||||
@@ -227,7 +221,7 @@ __ipportnethash_retry(struct ip_set_ipportnethash *tmp,
|
||||
HASH_RETRY2(ipportnethash, struct ipportip)
|
||||
|
||||
static inline int
|
||||
ipportnethash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ipportnethash_del(struct ip_set *set,
|
||||
ip_set_ip_t ip, ip_set_ip_t port,
|
||||
ip_set_ip_t ip1, uint8_t cidr)
|
||||
{
|
||||
@@ -242,7 +236,7 @@ ipportnethash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
if (cidr <= 0 || cidr >= 32)
|
||||
return -EINVAL;
|
||||
|
||||
id = ipportnethash_id_cidr(set, hash_ip, ip, port, ip1, cidr);
|
||||
id = ipportnethash_id_cidr(set, ip, port, ip1, cidr);
|
||||
|
||||
if (id == UINT_MAX)
|
||||
return -EEXIST;
|
||||
@@ -290,7 +284,8 @@ __ipportnethash_list_header(const struct ip_set_ipportnethash *map,
|
||||
HASH_LIST_HEADER(ipportnethash)
|
||||
|
||||
HASH_LIST_MEMBERS_SIZE(ipportnethash, struct ipportip)
|
||||
HASH_LIST_MEMBERS_MEMCPY(ipportnethash, struct ipportip)
|
||||
HASH_LIST_MEMBERS_MEMCPY(ipportnethash, struct ipportip,
|
||||
(elem->ip || elem->ip1))
|
||||
|
||||
IP_SET_RTYPE(ipportnethash, IPSET_TYPE_IP | IPSET_TYPE_PORT
|
||||
| IPSET_TYPE_IP1 | IPSET_DATA_TRIPLE)
|
||||
|
@@ -4,7 +4,7 @@
|
||||
#include "ip_set.h"
|
||||
#include "ip_set_hashes.h"
|
||||
|
||||
#define SETTYPE_NAME "ipportnethash"
|
||||
#define SETTYPE_NAME "ipportnethash"
|
||||
|
||||
struct ipportip {
|
||||
ip_set_ip_t ip;
|
||||
|
@@ -62,7 +62,7 @@ static __KMEM_CACHE_T__ *leaf_cachep;
|
||||
} while (0)
|
||||
|
||||
static inline int
|
||||
iptree_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
iptree_test(struct ip_set *set, ip_set_ip_t ip)
|
||||
{
|
||||
struct ip_set_iptree *map = set->data;
|
||||
struct ip_set_iptreeb *btree;
|
||||
@@ -73,8 +73,7 @@ iptree_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
if (!ip)
|
||||
return -ERANGE;
|
||||
|
||||
*hash_ip = ip;
|
||||
ABCD(a, b, c, d, hash_ip);
|
||||
ABCD(a, b, c, d, &ip);
|
||||
DP("%u %u %u %u timeout %u", a, b, c, d, map->timeout);
|
||||
TESTIP_WALK(map, a, btree);
|
||||
TESTIP_WALK(btree, b, ctree);
|
||||
@@ -106,8 +105,7 @@ KADT(iptree, test, ipaddr)
|
||||
} while (0)
|
||||
|
||||
static inline int
|
||||
iptree_add(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ip_set_ip_t ip, unsigned int timeout)
|
||||
iptree_add(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout)
|
||||
{
|
||||
struct ip_set_iptree *map = set->data;
|
||||
struct ip_set_iptreeb *btree;
|
||||
@@ -121,8 +119,7 @@ iptree_add(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
* but it's probably overkill */
|
||||
return -ERANGE;
|
||||
|
||||
*hash_ip = ip;
|
||||
ABCD(a, b, c, d, hash_ip);
|
||||
ABCD(a, b, c, d, &ip);
|
||||
DP("%u %u %u %u timeout %u", a, b, c, d, timeout);
|
||||
ADDIP_WALK(map, a, btree, struct ip_set_iptreeb, branch_cachep);
|
||||
ADDIP_WALK(btree, b, ctree, struct ip_set_iptreec, branch_cachep);
|
||||
@@ -153,7 +150,7 @@ KADT(iptree, add, ipaddr, 0)
|
||||
} while (0)
|
||||
|
||||
static inline int
|
||||
iptree_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
iptree_del(struct ip_set *set, ip_set_ip_t ip)
|
||||
{
|
||||
struct ip_set_iptree *map = set->data;
|
||||
struct ip_set_iptreeb *btree;
|
||||
@@ -164,8 +161,7 @@ iptree_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
if (!ip)
|
||||
return -ERANGE;
|
||||
|
||||
*hash_ip = ip;
|
||||
ABCD(a, b, c, d, hash_ip);
|
||||
ABCD(a, b, c, d, &ip);
|
||||
DELIP_WALK(map, a, btree);
|
||||
DELIP_WALK(btree, b, ctree);
|
||||
DELIP_WALK(ctree, c, dtree);
|
||||
@@ -364,7 +360,7 @@ iptree_list_header(const struct ip_set *set, void *data)
|
||||
}
|
||||
|
||||
static int
|
||||
iptree_list_members_size(const struct ip_set *set)
|
||||
iptree_list_members_size(const struct ip_set *set, char dont_align)
|
||||
{
|
||||
const struct ip_set_iptree *map = set->data;
|
||||
struct ip_set_iptreeb *btree;
|
||||
@@ -386,20 +382,21 @@ iptree_list_members_size(const struct ip_set *set)
|
||||
LOOP_WALK_END;
|
||||
|
||||
DP("members %u", count);
|
||||
return (count * sizeof(struct ip_set_req_iptree));
|
||||
return (count * IPSET_VALIGN(sizeof(struct ip_set_req_iptree), dont_align));
|
||||
}
|
||||
|
||||
static void
|
||||
iptree_list_members(const struct ip_set *set, void *data)
|
||||
iptree_list_members(const struct ip_set *set, void *data, char dont_align)
|
||||
{
|
||||
const struct ip_set_iptree *map = set->data;
|
||||
struct ip_set_iptreeb *btree;
|
||||
struct ip_set_iptreec *ctree;
|
||||
struct ip_set_iptreed *dtree;
|
||||
unsigned int a,b,c,d;
|
||||
size_t offset = 0;
|
||||
size_t offset = 0, datasize;
|
||||
struct ip_set_req_iptree *entry;
|
||||
|
||||
datasize = IPSET_VALIGN(sizeof(struct ip_set_req_iptree), dont_align);
|
||||
LOOP_WALK_BEGIN(map, a, btree);
|
||||
LOOP_WALK_BEGIN(btree, b, ctree);
|
||||
LOOP_WALK_BEGIN(ctree, c, dtree);
|
||||
@@ -410,7 +407,7 @@ iptree_list_members(const struct ip_set *set, void *data)
|
||||
entry->ip = ((a << 24) | (b << 16) | (c << 8) | d);
|
||||
entry->timeout = !map->timeout ? 0
|
||||
: (dtree->expires[d] - jiffies)/HZ;
|
||||
offset += sizeof(struct ip_set_req_iptree);
|
||||
offset += datasize;
|
||||
}
|
||||
}
|
||||
LOOP_WALK_END;
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "ip_set.h"
|
||||
|
||||
#define SETTYPE_NAME "iptree"
|
||||
#define SETTYPE_NAME "iptree"
|
||||
|
||||
struct ip_set_iptreed {
|
||||
unsigned long expires[256]; /* x.x.x.ADDR */
|
||||
|
@@ -251,7 +251,7 @@ free_b(struct ip_set_iptreemap_b *map)
|
||||
}
|
||||
|
||||
static inline int
|
||||
iptreemap_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
iptreemap_test(struct ip_set *set, ip_set_ip_t ip)
|
||||
{
|
||||
struct ip_set_iptreemap *map = set->data;
|
||||
struct ip_set_iptreemap_b *btree;
|
||||
@@ -259,9 +259,7 @@ iptreemap_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
struct ip_set_iptreemap_d *dtree;
|
||||
unsigned char a, b, c, d;
|
||||
|
||||
*hash_ip = ip;
|
||||
|
||||
ABCD(a, b, c, d, hash_ip);
|
||||
ABCD(a, b, c, d, &ip);
|
||||
|
||||
TESTIP_WALK(map, a, btree, fullbitmap_b);
|
||||
TESTIP_WALK(btree, b, ctree, fullbitmap_c);
|
||||
@@ -276,7 +274,7 @@ UADT(iptreemap, test)
|
||||
KADT(iptreemap, test, ipaddr)
|
||||
|
||||
static inline int
|
||||
__addip_single(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
__addip_single(struct ip_set *set, ip_set_ip_t ip)
|
||||
{
|
||||
struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data;
|
||||
struct ip_set_iptreemap_b *btree;
|
||||
@@ -284,9 +282,7 @@ __addip_single(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
struct ip_set_iptreemap_d *dtree;
|
||||
unsigned char a, b, c, d;
|
||||
|
||||
*hash_ip = ip;
|
||||
|
||||
ABCD(a, b, c, d, hash_ip);
|
||||
ABCD(a, b, c, d, &ip);
|
||||
|
||||
ADDIP_WALK(map, a, btree, struct ip_set_iptreemap_b, cachep_b, fullbitmap_b);
|
||||
ADDIP_WALK(btree, b, ctree, struct ip_set_iptreemap_c, cachep_c, fullbitmap_c);
|
||||
@@ -301,8 +297,7 @@ __addip_single(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
}
|
||||
|
||||
static inline int
|
||||
iptreemap_add(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ip_set_ip_t start, ip_set_ip_t end)
|
||||
iptreemap_add(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end)
|
||||
{
|
||||
struct ip_set_iptreemap *map = set->data;
|
||||
struct ip_set_iptreemap_b *btree;
|
||||
@@ -313,9 +308,7 @@ iptreemap_add(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
unsigned char a2, b2, c2, d2;
|
||||
|
||||
if (start == end)
|
||||
return __addip_single(set, hash_ip, start);
|
||||
|
||||
*hash_ip = start;
|
||||
return __addip_single(set, start);
|
||||
|
||||
ABCD(a1, b1, c1, d1, &start);
|
||||
ABCD(a2, b2, c2, d2, &end);
|
||||
@@ -338,8 +331,7 @@ UADT0(iptreemap, add, min(req->ip, req->end), max(req->ip, req->end))
|
||||
KADT(iptreemap, add, ipaddr, ip)
|
||||
|
||||
static inline int
|
||||
__delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ip_set_ip_t ip, gfp_t flags)
|
||||
__delip_single(struct ip_set *set, ip_set_ip_t ip, gfp_t flags)
|
||||
{
|
||||
struct ip_set_iptreemap *map = set->data;
|
||||
struct ip_set_iptreemap_b *btree;
|
||||
@@ -347,9 +339,7 @@ __delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
struct ip_set_iptreemap_d *dtree;
|
||||
unsigned char a,b,c,d;
|
||||
|
||||
*hash_ip = ip;
|
||||
|
||||
ABCD(a, b, c, d, hash_ip);
|
||||
ABCD(a, b, c, d, &ip);
|
||||
|
||||
DELIP_WALK(map, a, btree, cachep_b, fullbitmap_b, flags);
|
||||
DELIP_WALK(btree, b, ctree, cachep_c, fullbitmap_c, flags);
|
||||
@@ -364,7 +354,7 @@ __delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
}
|
||||
|
||||
static inline int
|
||||
iptreemap_del(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
iptreemap_del(struct ip_set *set,
|
||||
ip_set_ip_t start, ip_set_ip_t end, gfp_t flags)
|
||||
{
|
||||
struct ip_set_iptreemap *map = set->data;
|
||||
@@ -376,9 +366,7 @@ iptreemap_del(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
unsigned char a2, b2, c2, d2;
|
||||
|
||||
if (start == end)
|
||||
return __delip_single(set, hash_ip, start, flags);
|
||||
|
||||
*hash_ip = start;
|
||||
return __delip_single(set, start, flags);
|
||||
|
||||
ABCD(a1, b1, c1, d1, &start);
|
||||
ABCD(a2, b2, c2, d2, &end);
|
||||
@@ -518,6 +506,7 @@ static void
|
||||
iptreemap_flush(struct ip_set *set)
|
||||
{
|
||||
struct ip_set_iptreemap *map = set->data;
|
||||
unsigned int gc_interval = map->gc_interval;
|
||||
|
||||
while (!del_timer(&map->gc))
|
||||
msleep(IPTREEMAP_DESTROY_SLEEP);
|
||||
@@ -525,6 +514,7 @@ iptreemap_flush(struct ip_set *set)
|
||||
__flush(map);
|
||||
|
||||
memset(map, 0, sizeof(*map));
|
||||
map->gc_interval = gc_interval;
|
||||
|
||||
init_gc_timer(set);
|
||||
}
|
||||
@@ -539,7 +529,7 @@ iptreemap_list_header(const struct ip_set *set, void *data)
|
||||
}
|
||||
|
||||
static int
|
||||
iptreemap_list_members_size(const struct ip_set *set)
|
||||
iptreemap_list_members_size(const struct ip_set *set, char dont_align)
|
||||
{
|
||||
struct ip_set_iptreemap *map = set->data;
|
||||
struct ip_set_iptreemap_b *btree;
|
||||
@@ -565,31 +555,30 @@ iptreemap_list_members_size(const struct ip_set *set)
|
||||
if (inrange)
|
||||
count++;
|
||||
|
||||
return (count * sizeof(struct ip_set_req_iptreemap));
|
||||
return (count * IPSET_VALIGN(sizeof(struct ip_set_req_iptreemap), dont_align));
|
||||
}
|
||||
|
||||
static inline u_int32_t
|
||||
static inline void
|
||||
add_member(void *data, size_t offset, ip_set_ip_t start, ip_set_ip_t end)
|
||||
{
|
||||
struct ip_set_req_iptreemap *entry = data + offset;
|
||||
|
||||
entry->ip = start;
|
||||
entry->end = end;
|
||||
|
||||
return sizeof(*entry);
|
||||
}
|
||||
|
||||
static void
|
||||
iptreemap_list_members(const struct ip_set *set, void *data)
|
||||
iptreemap_list_members(const struct ip_set *set, void *data, char dont_align)
|
||||
{
|
||||
struct ip_set_iptreemap *map = set->data;
|
||||
struct ip_set_iptreemap_b *btree;
|
||||
struct ip_set_iptreemap_c *ctree;
|
||||
struct ip_set_iptreemap_d *dtree;
|
||||
unsigned int a, b, c, d, inrange = 0;
|
||||
size_t offset = 0;
|
||||
size_t offset = 0, datasize;
|
||||
ip_set_ip_t start = 0, end = 0, ip;
|
||||
|
||||
datasize = IPSET_VALIGN(sizeof(struct ip_set_req_iptreemap), dont_align);
|
||||
LOOP_WALK_BEGIN(map, a, btree) {
|
||||
LOOP_WALK_BEGIN(btree, b, ctree) {
|
||||
LOOP_WALK_BEGIN(ctree, c, dtree) {
|
||||
@@ -600,12 +589,14 @@ iptreemap_list_members(const struct ip_set *set, void *data)
|
||||
inrange = 1;
|
||||
start = ip;
|
||||
} else if (end < ip - 1) {
|
||||
offset += add_member(data, offset, start, end);
|
||||
add_member(data, offset, start, end);
|
||||
offset += datasize;
|
||||
start = ip;
|
||||
}
|
||||
end = ip;
|
||||
} else if (inrange) {
|
||||
offset += add_member(data, offset, start, end);
|
||||
add_member(data, offset, start, end);
|
||||
offset += datasize;
|
||||
inrange = 0;
|
||||
}
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "ip_set.h"
|
||||
|
||||
#define SETTYPE_NAME "iptreemap"
|
||||
#define SETTYPE_NAME "iptreemap"
|
||||
|
||||
#ifdef __KERNEL__
|
||||
struct ip_set_iptreemap_d {
|
||||
|
@@ -22,8 +22,7 @@
|
||||
#include "ip_set_macipmap.h"
|
||||
|
||||
static int
|
||||
macipmap_utest(struct ip_set *set, const void *data, u_int32_t size,
|
||||
ip_set_ip_t *hash_ip)
|
||||
macipmap_utest(struct ip_set *set, const void *data, u_int32_t size)
|
||||
{
|
||||
const struct ip_set_macipmap *map = set->data;
|
||||
const struct ip_set_macip *table = map->members;
|
||||
@@ -32,9 +31,7 @@ macipmap_utest(struct ip_set *set, const void *data, u_int32_t size,
|
||||
if (req->ip < map->first_ip || req->ip > map->last_ip)
|
||||
return -ERANGE;
|
||||
|
||||
*hash_ip = req->ip;
|
||||
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
|
||||
set->name, HIPQUAD(req->ip), HIPQUAD(*hash_ip));
|
||||
DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(req->ip));
|
||||
if (table[req->ip - map->first_ip].match) {
|
||||
return (memcmp(req->ethernet,
|
||||
&table[req->ip - map->first_ip].ethernet,
|
||||
@@ -47,22 +44,18 @@ macipmap_utest(struct ip_set *set, const void *data, u_int32_t size,
|
||||
static int
|
||||
macipmap_ktest(struct ip_set *set,
|
||||
const struct sk_buff *skb,
|
||||
ip_set_ip_t *hash_ip,
|
||||
const u_int32_t *flags,
|
||||
unsigned char index)
|
||||
const u_int32_t *flags)
|
||||
{
|
||||
const struct ip_set_macipmap *map = set->data;
|
||||
const struct ip_set_macip *table = map->members;
|
||||
ip_set_ip_t ip;
|
||||
|
||||
ip = ipaddr(skb, flags[index]);
|
||||
ip = ipaddr(skb, flags);
|
||||
|
||||
if (ip < map->first_ip || ip > map->last_ip)
|
||||
return 0;
|
||||
|
||||
*hash_ip = ip;
|
||||
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
|
||||
set->name, HIPQUAD(ip), HIPQUAD(*hash_ip));
|
||||
DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
|
||||
if (table[ip - map->first_ip].match) {
|
||||
/* Is mac pointer valid?
|
||||
* If so, compare... */
|
||||
@@ -78,7 +71,7 @@ macipmap_ktest(struct ip_set *set,
|
||||
|
||||
/* returns 0 on success */
|
||||
static inline int
|
||||
macipmap_add(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
macipmap_add(struct ip_set *set,
|
||||
ip_set_ip_t ip, const unsigned char *ethernet)
|
||||
{
|
||||
struct ip_set_macipmap *map = set->data;
|
||||
@@ -89,8 +82,7 @@ macipmap_add(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
if (table[ip - map->first_ip].match)
|
||||
return -EEXIST;
|
||||
|
||||
*hash_ip = ip;
|
||||
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
|
||||
DP("set: %s, ip: %u.%u.%u.%u", set->name, HIPQUAD(ip));
|
||||
memcpy(&table[ip - map->first_ip].ethernet, ethernet, ETH_ALEN);
|
||||
table[ip - map->first_ip].match = IPSET_MACIP_ISSET;
|
||||
return 0;
|
||||
@@ -105,7 +97,7 @@ UADT(macipmap, add, req->ethernet)
|
||||
KADT(macipmap, add, ipaddr, eth_hdr(skb)->h_source)
|
||||
|
||||
static inline int
|
||||
macipmap_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
macipmap_del(struct ip_set *set, ip_set_ip_t ip)
|
||||
{
|
||||
struct ip_set_macipmap *map = set->data;
|
||||
struct ip_set_macip *table = map->members;
|
||||
@@ -115,9 +107,8 @@ macipmap_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
if (!table[ip - map->first_ip].match)
|
||||
return -EEXIST;
|
||||
|
||||
*hash_ip = ip;
|
||||
table[ip - map->first_ip].match = 0;
|
||||
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
|
||||
DP("set: %s, ip: %u.%u.%u.%u", set->name, HIPQUAD(ip));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -152,8 +143,32 @@ __macipmap_list_header(const struct ip_set_macipmap *map,
|
||||
}
|
||||
|
||||
BITMAP_LIST_HEADER(macipmap)
|
||||
BITMAP_LIST_MEMBERS_SIZE(macipmap)
|
||||
BITMAP_LIST_MEMBERS(macipmap)
|
||||
BITMAP_LIST_MEMBERS_SIZE(macipmap, struct ip_set_req_macipmap,
|
||||
(map->last_ip - map->first_ip + 1),
|
||||
((const struct ip_set_macip *)map->members)[i].match)
|
||||
|
||||
|
||||
static void
|
||||
macipmap_list_members(const struct ip_set *set, void *data, char dont_align)
|
||||
{
|
||||
const struct ip_set_macipmap *map = set->data;
|
||||
const struct ip_set_macip *table = map->members;
|
||||
uint32_t i, n = 0;
|
||||
struct ip_set_req_macipmap *d;
|
||||
|
||||
if (dont_align) {
|
||||
memcpy(data, map->members, map->size);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < map->last_ip - map->first_ip + 1; i++)
|
||||
if (table[i].match) {
|
||||
d = data + n * IPSET_ALIGN(sizeof(struct ip_set_req_macipmap));
|
||||
d->ip = map->first_ip + i;
|
||||
memcpy(d->ethernet, &table[i].ethernet, ETH_ALEN);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
IP_SET_TYPE(macipmap, IPSET_TYPE_IP | IPSET_DATA_SINGLE)
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
#include "ip_set.h"
|
||||
#include "ip_set_bitmaps.h"
|
||||
|
||||
#define SETTYPE_NAME "macipmap"
|
||||
#define SETTYPE_NAME "macipmap"
|
||||
|
||||
/* general flags */
|
||||
#define IPSET_MACIP_MATCHUNSET 1
|
||||
|
@@ -26,7 +26,6 @@ static int limit = MAX_RANGE;
|
||||
|
||||
static inline __u32
|
||||
nethash_id_cidr(const struct ip_set_nethash *map,
|
||||
ip_set_ip_t *hash_ip,
|
||||
ip_set_ip_t ip,
|
||||
uint8_t cidr)
|
||||
{
|
||||
@@ -34,15 +33,15 @@ nethash_id_cidr(const struct ip_set_nethash *map,
|
||||
u_int16_t i;
|
||||
ip_set_ip_t *elem;
|
||||
|
||||
*hash_ip = pack_ip_cidr(ip, cidr);
|
||||
if (!*hash_ip)
|
||||
ip = pack_ip_cidr(ip, cidr);
|
||||
if (!ip)
|
||||
return MAX_RANGE;
|
||||
|
||||
for (i = 0; i < map->probes; i++) {
|
||||
id = jhash_ip(map, i, *hash_ip) % map->hashsize;
|
||||
id = jhash_ip(map, i, ip) % map->hashsize;
|
||||
DP("hash key: %u", id);
|
||||
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
|
||||
if (*elem == *hash_ip)
|
||||
if (*elem == ip)
|
||||
return id;
|
||||
/* No shortcut - there can be deleted entries. */
|
||||
}
|
||||
@@ -50,14 +49,14 @@ nethash_id_cidr(const struct ip_set_nethash *map,
|
||||
}
|
||||
|
||||
static inline __u32
|
||||
nethash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
nethash_id(struct ip_set *set, ip_set_ip_t ip)
|
||||
{
|
||||
const struct ip_set_nethash *map = set->data;
|
||||
__u32 id = UINT_MAX;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 30 && map->cidr[i]; i++) {
|
||||
id = nethash_id_cidr(map, hash_ip, ip, map->cidr[i]);
|
||||
id = nethash_id_cidr(map, ip, map->cidr[i]);
|
||||
if (id != UINT_MAX)
|
||||
break;
|
||||
}
|
||||
@@ -65,30 +64,28 @@ nethash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
}
|
||||
|
||||
static inline int
|
||||
nethash_test_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ip_set_ip_t ip, uint8_t cidr)
|
||||
nethash_test_cidr(struct ip_set *set, ip_set_ip_t ip, uint8_t cidr)
|
||||
{
|
||||
const struct ip_set_nethash *map = set->data;
|
||||
|
||||
return (nethash_id_cidr(map, hash_ip, ip, cidr) != UINT_MAX);
|
||||
return (nethash_id_cidr(map, ip, cidr) != UINT_MAX);
|
||||
}
|
||||
|
||||
static inline int
|
||||
nethash_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
|
||||
nethash_test(struct ip_set *set, ip_set_ip_t ip)
|
||||
{
|
||||
return (nethash_id(set, hash_ip, ip) != UINT_MAX);
|
||||
return (nethash_id(set, ip) != UINT_MAX);
|
||||
}
|
||||
|
||||
static int
|
||||
nethash_utest(struct ip_set *set, const void *data, u_int32_t size,
|
||||
ip_set_ip_t *hash_ip)
|
||||
nethash_utest(struct ip_set *set, const void *data, u_int32_t size)
|
||||
{
|
||||
const struct ip_set_req_nethash *req = data;
|
||||
|
||||
if (req->cidr <= 0 || req->cidr > 32)
|
||||
return -EINVAL;
|
||||
return (req->cidr == 32 ? nethash_test(set, hash_ip, req->ip)
|
||||
: nethash_test_cidr(set, hash_ip, req->ip, req->cidr));
|
||||
return (req->cidr == 32 ? nethash_test(set, req->ip)
|
||||
: nethash_test_cidr(set, req->ip, req->cidr));
|
||||
}
|
||||
|
||||
#define KADT_CONDITION
|
||||
@@ -121,8 +118,7 @@ __nethash_add(struct ip_set_nethash *map, ip_set_ip_t *ip)
|
||||
}
|
||||
|
||||
static inline int
|
||||
nethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ip_set_ip_t ip, uint8_t cidr)
|
||||
nethash_add(struct ip_set *set, ip_set_ip_t ip, uint8_t cidr)
|
||||
{
|
||||
struct ip_set_nethash *map = set->data;
|
||||
int ret;
|
||||
@@ -132,12 +128,11 @@ nethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
if (cidr <= 0 || cidr >= 32)
|
||||
return -EINVAL;
|
||||
|
||||
*hash_ip = pack_ip_cidr(ip, cidr);
|
||||
DP("%u.%u.%u.%u/%u, %u.%u.%u.%u", HIPQUAD(ip), cidr, HIPQUAD(*hash_ip));
|
||||
if (!*hash_ip)
|
||||
ip = pack_ip_cidr(ip, cidr);
|
||||
if (!ip)
|
||||
return -ERANGE;
|
||||
|
||||
ret = __nethash_add(map, hash_ip);
|
||||
ret = __nethash_add(map, &ip);
|
||||
if (ret == 0) {
|
||||
if (!map->nets[cidr-1]++)
|
||||
add_cidr_size(map->cidr, cidr);
|
||||
@@ -165,8 +160,7 @@ __nethash_retry(struct ip_set_nethash *tmp, struct ip_set_nethash *map)
|
||||
HASH_RETRY(nethash, ip_set_ip_t)
|
||||
|
||||
static inline int
|
||||
nethash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
ip_set_ip_t ip, uint8_t cidr)
|
||||
nethash_del(struct ip_set *set, ip_set_ip_t ip, uint8_t cidr)
|
||||
{
|
||||
struct ip_set_nethash *map = set->data;
|
||||
ip_set_ip_t id, *elem;
|
||||
@@ -174,7 +168,7 @@ nethash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||
if (cidr <= 0 || cidr >= 32)
|
||||
return -EINVAL;
|
||||
|
||||
id = nethash_id_cidr(map, hash_ip, ip, cidr);
|
||||
id = nethash_id_cidr(map, ip, cidr);
|
||||
if (id == UINT_MAX)
|
||||
return -EEXIST;
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
#include "ip_set.h"
|
||||
#include "ip_set_hashes.h"
|
||||
|
||||
#define SETTYPE_NAME "nethash"
|
||||
#define SETTYPE_NAME "nethash"
|
||||
|
||||
struct ip_set_nethash {
|
||||
ip_set_ip_t *members; /* the nethash proper */
|
||||
|
@@ -23,16 +23,14 @@
|
||||
#include "ip_set_getport.h"
|
||||
|
||||
static inline int
|
||||
portmap_test(const struct ip_set *set, ip_set_ip_t *hash_port,
|
||||
ip_set_ip_t port)
|
||||
portmap_test(const struct ip_set *set, ip_set_ip_t port)
|
||||
{
|
||||
const struct ip_set_portmap *map = set->data;
|
||||
|
||||
if (port < map->first_ip || port > map->last_ip)
|
||||
return -ERANGE;
|
||||
|
||||
*hash_port = port;
|
||||
DP("set: %s, port:%u, %u", set->name, port, *hash_port);
|
||||
DP("set: %s, port: %u", set->name, port);
|
||||
return !!test_bit(port - map->first_ip, map->members);
|
||||
}
|
||||
|
||||
@@ -44,7 +42,7 @@ UADT(portmap, test)
|
||||
KADT(portmap, test, get_port)
|
||||
|
||||
static inline int
|
||||
portmap_add(struct ip_set *set, ip_set_ip_t *hash_port, ip_set_ip_t port)
|
||||
portmap_add(struct ip_set *set, ip_set_ip_t port)
|
||||
{
|
||||
struct ip_set_portmap *map = set->data;
|
||||
|
||||
@@ -52,9 +50,8 @@ portmap_add(struct ip_set *set, ip_set_ip_t *hash_port, ip_set_ip_t port)
|
||||
return -ERANGE;
|
||||
if (test_and_set_bit(port - map->first_ip, map->members))
|
||||
return -EEXIST;
|
||||
|
||||
*hash_port = port;
|
||||
DP("port %u", port);
|
||||
|
||||
DP("set: %s, port %u", set->name, port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -62,7 +59,7 @@ UADT(portmap, add)
|
||||
KADT(portmap, add, get_port)
|
||||
|
||||
static inline int
|
||||
portmap_del(struct ip_set *set, ip_set_ip_t *hash_port, ip_set_ip_t port)
|
||||
portmap_del(struct ip_set *set, ip_set_ip_t port)
|
||||
{
|
||||
struct ip_set_portmap *map = set->data;
|
||||
|
||||
@@ -70,9 +67,8 @@ portmap_del(struct ip_set *set, ip_set_ip_t *hash_port, ip_set_ip_t port)
|
||||
return -ERANGE;
|
||||
if (!test_and_clear_bit(port - map->first_ip, map->members))
|
||||
return -EEXIST;
|
||||
|
||||
*hash_port = port;
|
||||
DP("port %u", port);
|
||||
|
||||
DP("set: %s, port %u", set->name, port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -102,8 +98,28 @@ __portmap_list_header(const struct ip_set_portmap *map,
|
||||
}
|
||||
|
||||
BITMAP_LIST_HEADER(portmap)
|
||||
BITMAP_LIST_MEMBERS_SIZE(portmap)
|
||||
BITMAP_LIST_MEMBERS(portmap)
|
||||
BITMAP_LIST_MEMBERS_SIZE(portmap, ip_set_ip_t, (map->last_ip - map->first_ip + 1),
|
||||
test_bit(i, map->members))
|
||||
|
||||
static void
|
||||
portmap_list_members(const struct ip_set *set, void *data, char dont_align)
|
||||
{
|
||||
const struct ip_set_portmap *map = set->data;
|
||||
uint32_t i, n = 0;
|
||||
ip_set_ip_t *d;
|
||||
|
||||
if (dont_align) {
|
||||
memcpy(data, map->members, map->size);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < map->last_ip - map->first_ip + 1; i++)
|
||||
if (test_bit(i, map->members)) {
|
||||
d = data + n * IPSET_ALIGN(sizeof(ip_set_ip_t));
|
||||
*d = map->first_ip + i;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
IP_SET_TYPE(portmap, IPSET_TYPE_PORT | IPSET_DATA_SINGLE)
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
#include "ip_set.h"
|
||||
#include "ip_set_bitmaps.h"
|
||||
|
||||
#define SETTYPE_NAME "portmap"
|
||||
#define SETTYPE_NAME "portmap"
|
||||
|
||||
struct ip_set_portmap {
|
||||
void *members; /* the portmap proper */
|
||||
|
@@ -28,8 +28,7 @@ next_index_eq(const struct ip_set_setlist *map, int i, ip_set_id_t index)
|
||||
}
|
||||
|
||||
static int
|
||||
setlist_utest(struct ip_set *set, const void *data, u_int32_t size,
|
||||
ip_set_ip_t *hash_ip)
|
||||
setlist_utest(struct ip_set *set, const void *data, u_int32_t size)
|
||||
{
|
||||
const struct ip_set_setlist *map = set->data;
|
||||
const struct ip_set_req_setlist *req = data;
|
||||
@@ -72,10 +71,8 @@ finish:
|
||||
|
||||
static int
|
||||
setlist_ktest(struct ip_set *set,
|
||||
const struct sk_buff *skb,
|
||||
ip_set_ip_t *hash_ip,
|
||||
const u_int32_t *flags,
|
||||
unsigned char index)
|
||||
const struct sk_buff *skb,
|
||||
const u_int32_t *flags)
|
||||
{
|
||||
struct ip_set_setlist *map = set->data;
|
||||
int i, res = 0;
|
||||
@@ -107,8 +104,7 @@ insert_setlist(struct ip_set_setlist *map, int i, ip_set_id_t index)
|
||||
}
|
||||
|
||||
static int
|
||||
setlist_uadd(struct ip_set *set, const void *data, u_int32_t size,
|
||||
ip_set_ip_t *hash_ip)
|
||||
setlist_uadd(struct ip_set *set, const void *data, u_int32_t size)
|
||||
{
|
||||
struct ip_set_setlist *map = set->data;
|
||||
const struct ip_set_req_setlist *req = data;
|
||||
@@ -156,9 +152,7 @@ finish:
|
||||
static int
|
||||
setlist_kadd(struct ip_set *set,
|
||||
const struct sk_buff *skb,
|
||||
ip_set_ip_t *hash_ip,
|
||||
const u_int32_t *flags,
|
||||
unsigned char index)
|
||||
const u_int32_t *flags)
|
||||
{
|
||||
struct ip_set_setlist *map = set->data;
|
||||
int i, res = -EINVAL;
|
||||
@@ -182,8 +176,7 @@ unshift_setlist(struct ip_set_setlist *map, int i)
|
||||
}
|
||||
|
||||
static int
|
||||
setlist_udel(struct ip_set *set, const void *data, u_int32_t size,
|
||||
ip_set_ip_t *hash_ip)
|
||||
setlist_udel(struct ip_set *set, const void *data, u_int32_t size)
|
||||
{
|
||||
struct ip_set_setlist *map = set->data;
|
||||
const struct ip_set_req_setlist *req = data;
|
||||
@@ -234,9 +227,7 @@ finish:
|
||||
static int
|
||||
setlist_kdel(struct ip_set *set,
|
||||
const struct sk_buff *skb,
|
||||
ip_set_ip_t *hash_ip,
|
||||
const u_int32_t *flags,
|
||||
unsigned char index)
|
||||
const u_int32_t *flags)
|
||||
{
|
||||
struct ip_set_setlist *map = set->data;
|
||||
int i, res = -EINVAL;
|
||||
@@ -304,21 +295,24 @@ setlist_list_header(const struct ip_set *set, void *data)
|
||||
}
|
||||
|
||||
static int
|
||||
setlist_list_members_size(const struct ip_set *set)
|
||||
setlist_list_members_size(const struct ip_set *set, char dont_align)
|
||||
{
|
||||
const struct ip_set_setlist *map = set->data;
|
||||
|
||||
return map->size * sizeof(ip_set_id_t);
|
||||
return map->size * IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
|
||||
}
|
||||
|
||||
static void
|
||||
setlist_list_members(const struct ip_set *set, void *data)
|
||||
setlist_list_members(const struct ip_set *set, void *data, char dont_align)
|
||||
{
|
||||
struct ip_set_setlist *map = set->data;
|
||||
ip_set_id_t *d;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < map->size; i++)
|
||||
*((ip_set_id_t *)data + i) = ip_set_id(map->index[i]);
|
||||
for (i = 0; i < map->size; i++) {
|
||||
d = data + i * IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
|
||||
*d = ip_set_id(map->index[i]);
|
||||
}
|
||||
}
|
||||
|
||||
IP_SET_TYPE(setlist, IPSET_TYPE_SETNAME | IPSET_DATA_SINGLE)
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "ip_set.h"
|
||||
|
||||
#define SETTYPE_NAME "setlist"
|
||||
#define SETTYPE_NAME "setlist"
|
||||
|
||||
#define IP_SET_SETLIST_ADD_AFTER 0
|
||||
#define IP_SET_SETLIST_ADD_BEFORE 1
|
||||
|
@@ -18,21 +18,21 @@
|
||||
.\"
|
||||
.\"
|
||||
.SH NAME
|
||||
ipset \- administration tool for IP sets
|
||||
ipset \(em administration tool for IP sets
|
||||
.SH SYNOPSIS
|
||||
.BR "ipset -N " "set type-specification [options]"
|
||||
.br
|
||||
.BR "ipset -[XFLSHh] " "[set] [options]"
|
||||
.br
|
||||
.BR "ipset -[EW] " "from-set to-set"
|
||||
.br
|
||||
.BR "ipset -[ADU] " "set entry"
|
||||
.br
|
||||
.BR "ipset -B " "set entry -b binding"
|
||||
.br
|
||||
.BR "ipset -T " "set entry [-b binding]"
|
||||
.br
|
||||
.BR "ipset -R "
|
||||
.PP
|
||||
\fBipset \-N\fP \fIset\fP \fItype-specification\fP [\fIoptions\fP...]
|
||||
.PP
|
||||
\fBipset\fP {\fB\-F\fP|\fB\-H\fP|\fB\-L\fP|\fB\-S\fP|\fB\-X\fP} [\fIset\fP]
|
||||
[\fIoptions\fP...]
|
||||
.PP
|
||||
\fBipset\fP {\fB\-E\fP|\fB\-W\fP} \fIfrom-set\fP \fIto-set\fP
|
||||
.PP
|
||||
\fBipset\fP {\fB\-A\fP|\fB\-D\fP|\fB\-T\fP} \fIset\fP \fIentry\fP
|
||||
.PP
|
||||
\fBipset \-R\fP
|
||||
.PP
|
||||
\fBipset\fP {\fB-V\fP|\fB\-v\fP}
|
||||
.SH DESCRIPTION
|
||||
.B ipset
|
||||
is used to set up, maintain and inspect so called IP sets in the Linux
|
||||
@@ -40,19 +40,9 @@ kernel. Depending on the type, an IP set may store IP addresses, (TCP/UDP)
|
||||
port numbers or additional informations besides IP addresses: the word IP
|
||||
means a general term here. See the set type definitions below.
|
||||
.P
|
||||
Any entry in a set can be bound to another set, which forms a relationship
|
||||
between a set element and the set it is bound to. In order to define a
|
||||
binding it is not required that the entry be already added to the set.
|
||||
The sets may have a default binding, which is valid for every set element
|
||||
for which there is no binding defined at all.
|
||||
.P
|
||||
IP set bindings pointing to sets and iptables matches and targets
|
||||
referring to sets creates references, which protects the given sets in
|
||||
the kernel. A set cannot be removed (destroyed) while there is a single
|
||||
reference pointing to it.
|
||||
.P
|
||||
.B
|
||||
Please note, binding sets is a deprecated feature and will be removed in a later release. Switch to the multidata type of sets from using bindings.
|
||||
Iptables matches and targets referring to sets creates references, which
|
||||
protects the given sets in the kernel. A set cannot be removed (destroyed)
|
||||
while there is a single reference pointing to it.
|
||||
.SH OPTIONS
|
||||
The options that are recognized by
|
||||
.B ipset
|
||||
@@ -65,134 +55,87 @@ need to use only enough letters to ensure that
|
||||
.B ipset
|
||||
can differentiate it from all other options.
|
||||
.TP
|
||||
.BI "-N, --create " "\fIsetname\fP type type-specific-options"
|
||||
\fB\-N\fP, \fB\-\-create\fP \fIsetname\fP \fItype\fP \fItype-specific-options\fP
|
||||
Create a set identified with setname and specified type.
|
||||
Type-specific options must be supplied.
|
||||
.TP
|
||||
.BI "-X, --destroy " "[\fIsetname\fP]"
|
||||
Destroy the specified set, or all sets if none or the keyword
|
||||
.B
|
||||
:all:
|
||||
is specified.
|
||||
Before destroying the set, all bindings belonging to the
|
||||
set elements and the default binding of the set are removed.
|
||||
\fB\-X\fP, \fB\-\-destroy\fP [\fIsetname\fP]
|
||||
Destroy the specified set or all the sets if none is given.
|
||||
|
||||
If the set has got references, nothing is done.
|
||||
.TP
|
||||
.BI "-F, --flush " "[\fIsetname\fP]"
|
||||
Delete all entries from the specified set, or flush
|
||||
all sets if none or the keyword
|
||||
.B
|
||||
:all:
|
||||
is given. Bindings are not affected by the flush operation.
|
||||
\fB\-F\fP, \fB\-\-flush\fP [\fIsetname\fP]
|
||||
Delete all entries from the specified set or flush
|
||||
all sets if none is given.
|
||||
.TP
|
||||
.BI "-E, --rename " "\fIfrom-setname\fP \fIto-setname\fP"
|
||||
\fB\-E\fP, \fB\-\-rename\fP \fIfrom-setname\fP \fIto-setname\fP
|
||||
Rename a set. Set identified by to-setname must not exist.
|
||||
.TP
|
||||
.BI "-W, --swap " "\fIfrom-setname\fP \fIto-setname\fP"
|
||||
\fB\-W\fP, \fB\-\-swap\fP \fIfrom-setname\fP \fIto-setname\fP
|
||||
Swap the content of two sets, or in another words,
|
||||
exchange the name of two sets. The referred sets must exist and
|
||||
identical type of sets can be swapped only.
|
||||
.TP
|
||||
.BI "-L, --list " "[\fIsetname\fP]"
|
||||
List the entries and bindings for the specified set, or for
|
||||
all sets if none or the keyword
|
||||
.B
|
||||
:all:
|
||||
is given. The
|
||||
.B "-n, --numeric"
|
||||
option can be used to suppress name lookups and generate numeric
|
||||
output. When the
|
||||
.B "-s, --sorted"
|
||||
\fB\-L\fP, \fB\-\-list\fP [\fIsetname\fP]
|
||||
List the entries for the specified set, or for
|
||||
all sets if none is given. The
|
||||
\fB\-r\fP/\fB\-\-resolve\fP
|
||||
option can be used to force name lookups (which may be slow). When the
|
||||
\fB\-s\fP/\fB\-\-sorted\fP
|
||||
option is given, the entries are listed sorted (if the given set
|
||||
type supports the operation).
|
||||
.TP
|
||||
.BI "-S, --save " "[\fIsetname\fP]"
|
||||
Save the given set, or all sets if none or the keyword
|
||||
.B
|
||||
:all:
|
||||
is specified to stdout in a format that --restore can read.
|
||||
\fB\-S\fP, \fB\-\-save\fP [\fIsetname\fP]
|
||||
Save the given set, or all sets if none is given
|
||||
to stdout in a format that \fB\-\-restore\fP can read.
|
||||
.TP
|
||||
.BI "-R, --restore "
|
||||
Restore a saved session generated by --save. The saved session
|
||||
\fB\-R\fP, \fB\-\-restore\fP
|
||||
Restore a saved session generated by \fB\-\-save\fP. The saved session
|
||||
can be fed from stdin.
|
||||
|
||||
When generating a session file please note that the supported commands
|
||||
(create set, add element, bind) must appear in a strict order: first create
|
||||
(create set and add element) must appear in a strict order: first create
|
||||
the set, then add all elements. Then create the next set, add all its elements
|
||||
and so on. Finally you can list all binding commands. Also, it is a restore
|
||||
operation, so the sets being restored must not exist.
|
||||
and so on. Also, it is a restore operation, so the sets being restored must
|
||||
not exist.
|
||||
.TP
|
||||
.BI "-A, --add " "\fIsetname\fP \fIIP\fP"
|
||||
Add an IP to a set.
|
||||
\fB\-A\fP, \fB\-\-add\fP \fIsetname\fP \fIentry\fP
|
||||
Add an entry to a set.
|
||||
.TP
|
||||
.BI "-D, --del " "\fIsetname\fP \fIIP\fP"
|
||||
Delete an IP from a set.
|
||||
\fB\-D\fP, \fB\-\-del\fP \fIsetname\fP \fIentry\fP
|
||||
Delete an entry from a set.
|
||||
.TP
|
||||
.BI "-T, --test " "\fIsetname\fP \fIIP
|
||||
Test wether an IP is in a set or not. Exit status number is zero
|
||||
if the tested IP is in the set and nonzero if it is missing from
|
||||
\fB-T\fP, \fB\-\-test\fP \fIsetname\fP \fIentry\fP
|
||||
Test wether an entry is in a set or not. Exit status number is zero
|
||||
if the tested entry is in the set and nonzero if it is missing from
|
||||
the set.
|
||||
.TP
|
||||
.BI "-T, --test " "\fIsetname\fP \fIIP\fP \fI--binding\fP \fIto-setname\fP"
|
||||
Test wether the IP belonging to the set points to the specified binding.
|
||||
Exit status number is zero if the binding points to the specified set,
|
||||
otherwise it is nonzero. The keyword
|
||||
.B
|
||||
:default:
|
||||
can be used to test the default binding of the set.
|
||||
.TP
|
||||
.BI "-B, --bind " "\fIsetname\fP \fIIP\fP \fI--binding\fP \fIto-setname\fP"
|
||||
Bind the IP in setname to to-setname.
|
||||
.TP
|
||||
.BI "-U, --unbind " "\fIsetname\fP \fIIP\fP"
|
||||
Delete the binding belonging to IP in set setname.
|
||||
.TP
|
||||
.BI "-H, --help " "[settype]"
|
||||
\fB\-H\fP, \fB\-\-help\fP [\fIsettype\fP]
|
||||
Print help and settype specific help if settype specified.
|
||||
.TP
|
||||
\fB\-V\fP, \fB\-v\fP, \fB\-\-version\fP
|
||||
Print program version and protocol version.
|
||||
.P
|
||||
At the
|
||||
.B
|
||||
-B, -U
|
||||
and
|
||||
.B
|
||||
-T
|
||||
commands you can use the token
|
||||
.B
|
||||
:default:
|
||||
to bind, unbind or test the default binding of a set instead
|
||||
of an IP. At the
|
||||
.B
|
||||
-U
|
||||
command you can use the token
|
||||
.B
|
||||
:all:
|
||||
to destroy the bindings of all elements of a set.
|
||||
.SS "OTHER OPTIONS"
|
||||
The following additional options can be specified:
|
||||
.TP
|
||||
.B "-b, --binding setname"
|
||||
The option specifies the value of the binding for the
|
||||
.B "-B"
|
||||
binding command, for which it is a mandatory option.
|
||||
You can use it in the
|
||||
.B "-T"
|
||||
test command as well to test bindings.
|
||||
.TP
|
||||
.B "-s, --sorted"
|
||||
Sorted output. When listing sets, entries are listed sorted.
|
||||
.TP
|
||||
.B "-n, --numeric"
|
||||
Numeric output. When listing sets, bindings, IP addresses and
|
||||
port numbers will be printed in numeric format. By default the
|
||||
program will try to display them as host names, network names
|
||||
or services (whenever applicable), which can trigger
|
||||
\fB\-r\fP, \fB\-\-resolve\fP
|
||||
When listing sets, enforce name lookup. The
|
||||
program will try to display the IP entries resolved to
|
||||
host names or services (whenever applicable), which can trigger
|
||||
.B
|
||||
slow
|
||||
DNS
|
||||
lookups.
|
||||
.TP
|
||||
.B "-q, --quiet"
|
||||
\fB\-s\fP, \fB\-\-sorted\fP
|
||||
Sorted output. When listing sets, entries are listed sorted.
|
||||
.TP
|
||||
\fB\-n\fP, \fB\-\-numeric\fP
|
||||
Numeric output. When listing sets, IP addresses and
|
||||
port numbers will be printed in numeric format. This is the default.
|
||||
.TP
|
||||
\fB\-q\fP, \fB\-\-quiet\fP
|
||||
Suppress any output to stdout and stderr. ipset will still return
|
||||
possible errors.
|
||||
.SH SET TYPES
|
||||
@@ -202,7 +145,7 @@ The ipmap set type uses a memory range, where each bit represents
|
||||
one IP address. An ipmap set can store up to 65536 (B-class network)
|
||||
IP addresses. The ipmap set type is very fast and memory cheap, great
|
||||
for use when one want to match certain IPs in a range. If the optional
|
||||
.B "--netmask"
|
||||
\fB\-\-netmask\fP
|
||||
parameter is specified with a CIDR netmask value between 1-31 then
|
||||
network addresses are stored in the given set: i.e an
|
||||
IP address will be in the set if the network address, which is resulted
|
||||
@@ -210,52 +153,54 @@ by masking the address with the specified netmask, can be found in the set.
|
||||
.P
|
||||
Options to use when creating an ipmap set:
|
||||
.TP
|
||||
.BR "--from " from-IP
|
||||
\fB\-\-from\fP \fIfrom-addr\fP
|
||||
.TP
|
||||
.BR "--to " to-IP
|
||||
Create an ipmap set from the specified range.
|
||||
\fB\-\-to\fP \fIto-addr\fP
|
||||
Create an ipmap set from the specified address range.
|
||||
.TP
|
||||
.BR "--network " IP/mask
|
||||
\fB\-\-network\fP \fIaddr\fP\fB/\fP\fImask\fP
|
||||
Create an ipmap set from the specified network.
|
||||
.TP
|
||||
.BR "--netmask " CIDR-netmask
|
||||
\fB\-\-netmask\fP \fIprefixlen\fP
|
||||
When the optional
|
||||
.B "--netmask"
|
||||
\fB\-\-netmask\fP
|
||||
parameter specified, network addresses will be
|
||||
stored in the set instead of IP addresses, and the from-IP parameter
|
||||
must be a network address. The CIDR-netmask value must be between 1-31.
|
||||
stored in the set instead of IP addresses, and the \fIfrom-addr\fP parameter
|
||||
must be a network address. The \fIprefixlen\fP value must be between 1-31.
|
||||
.PP
|
||||
Example:
|
||||
.IP
|
||||
ipset \-N test ipmap \-\-network 192.168.0.0/16
|
||||
.SS macipmap
|
||||
The macipmap set type uses a memory range, where each 8 bytes
|
||||
represents one IP and a MAC addresses. A macipmap set type can store
|
||||
up to 65536 (B-class network) IP addresses with MAC.
|
||||
When adding an entry to a macipmap set, you must specify the entry as
|
||||
.I IP,MAC.
|
||||
"\fIaddress\fP\fB,\fP\fImac\fP".
|
||||
When deleting or testing macipmap entries, the
|
||||
.I ,MAC
|
||||
"\fB,\fP\fImac\fP"
|
||||
part is not mandatory.
|
||||
.P
|
||||
Options to use when creating an macipmap set:
|
||||
.TP
|
||||
.BR "--from " from-IP
|
||||
\fB\-\-from\fP \fIfrom-addr\fP
|
||||
.TP
|
||||
.BR "--to " to-IP
|
||||
Create a macipmap set from the specified range.
|
||||
\fB\-\-to\fP \fIto-addr\fP
|
||||
Create a macipmap set from the specified address range.
|
||||
.TP
|
||||
.BR "--network " IP/mask
|
||||
\fB\-\-network\fP \fIaddr\fP\fB/\fP\fImask\fP
|
||||
Create a macipmap set from the specified network.
|
||||
.TP
|
||||
.BR "--matchunset"
|
||||
\fB\-\-matchunset\fP
|
||||
When the optional
|
||||
.B "--matchunset"
|
||||
\fB\-\-matchunset\fP
|
||||
parameter specified, IP addresses which could be stored
|
||||
in the set but not set yet, will always match.
|
||||
.P
|
||||
Please note, the
|
||||
.I
|
||||
set
|
||||
"set"
|
||||
and
|
||||
.I
|
||||
SET
|
||||
"SET"
|
||||
netfilter kernel modules
|
||||
.B
|
||||
always
|
||||
@@ -268,42 +213,41 @@ The portmap set type is very fast and memory cheap.
|
||||
.P
|
||||
Options to use when creating an portmap set:
|
||||
.TP
|
||||
.BR "--from " from-port
|
||||
\fB\-\-from\fP \fIfrom-port\fP
|
||||
.TP
|
||||
.BR "--to " to-port
|
||||
Create a portmap set from the specified range.
|
||||
\fB\-\-to\fP \fIto-port\fP
|
||||
Create a portmap set from the specified port range.
|
||||
.SS iphash
|
||||
The iphash set type uses a hash to store IP addresses.
|
||||
In order to avoid clashes in the hash double-hashing, and as a last
|
||||
resort, dynamic growing of the hash performed. The iphash set type is
|
||||
great to store random addresses. If the optional
|
||||
.B "--netmask"
|
||||
parameter is specified with a CIDR netmask value between 1-31 then
|
||||
\fB\-\-netmask\fP
|
||||
parameter is specified with a CIDR prefix length value between 1-31 then
|
||||
network addresses are stored in the given set: i.e an
|
||||
IP address will be in the set if the network address, which is resulted
|
||||
by masking the address with the specified netmask, can be found in the set.
|
||||
.P
|
||||
Options to use when creating an iphash set:
|
||||
.TP
|
||||
.BR "--hashsize " hashsize
|
||||
\fB\-\-hashsize\fP \fIhashsize\fP
|
||||
The initial hash size (default 1024)
|
||||
.TP
|
||||
.BR "--probes " probes
|
||||
\fB\-\-probes\fP \fIprobes\fP
|
||||
How many times try to resolve clashing at adding an IP to the hash
|
||||
by double-hashing (default 8).
|
||||
.TP
|
||||
.BR "--resize " percent
|
||||
\fB\-\-resize\fP \fIpercent\fP
|
||||
Increase the hash size by this many percent (default 50) when adding
|
||||
an IP to the hash could not be performed after
|
||||
.B
|
||||
probes
|
||||
\fIprobes\fP
|
||||
number of double-hashing.
|
||||
.TP
|
||||
.BR "--netmask " CIDR-netmask
|
||||
\fB\-\-netmask\fP \fIprefixlen\fP
|
||||
When the optional
|
||||
.B "--netmask"
|
||||
\fB\-\-netmask\fP
|
||||
parameter specified, network addresses will be
|
||||
stored in the set instead of IP addresses. The CIDR-netmask value must
|
||||
stored in the set instead of IP addresses. The \fIprefixlen\fP value must
|
||||
be between 1-31.
|
||||
.P
|
||||
The iphash type of sets can store up to 65536 entries. If a set is full,
|
||||
@@ -312,35 +256,36 @@ no new entries can be added to it.
|
||||
Sets created by zero valued resize parameter won't be resized at all.
|
||||
The lookup time in an iphash type of set grows approximately linearly with
|
||||
the value of the
|
||||
.B
|
||||
probes
|
||||
\fIprobes\fP
|
||||
parameter. In general higher
|
||||
.B
|
||||
probe
|
||||
\fIprobes\fP
|
||||
value results better utilized hash while smaller value
|
||||
produces larger, sparser hash.
|
||||
.PP
|
||||
Example:
|
||||
.IP
|
||||
ipset \-N test iphash \-\-probes 2
|
||||
.SS nethash
|
||||
The nethash set type uses a hash to store different size of
|
||||
network addresses. The
|
||||
.I
|
||||
IP
|
||||
"address" used in the ipset commands must be in the form
|
||||
.I
|
||||
IP-address/cidr-size
|
||||
where the CIDR block size must be in the inclusive range of 1-31.
|
||||
entry
|
||||
used in the ipset commands must be in the form
|
||||
"\fIaddress\fP\fB/\fP\fIprefixlen\fP"
|
||||
where prefixlen must be in the inclusive range of 1-31.
|
||||
In order to avoid clashes in the hash
|
||||
double-hashing, and as a last resort, dynamic growing of the hash performed.
|
||||
.P
|
||||
Options to use when creating an nethash set:
|
||||
.TP
|
||||
.BR "--hashsize " hashsize
|
||||
\fB\-\-hashsize\fP \fIhashsize\fP
|
||||
The initial hash size (default 1024)
|
||||
.TP
|
||||
.BR "--probes " probes
|
||||
\fB\-\-probes\fP \fIprobes\fP
|
||||
How many times try to resolve clashing at adding an IP to the hash
|
||||
by double-hashing (default 4).
|
||||
.TP
|
||||
.BR "--resize " percent
|
||||
\fB\-\-resize\fP \fIpercent\fP
|
||||
Increase the hash size by this many percent (default 50) when adding
|
||||
an IP to the hash could not be performed after
|
||||
.P
|
||||
@@ -352,15 +297,13 @@ netblocks added to the set. The matching always start from the smallest
|
||||
size of netblock (most specific netmask) to the largest ones (least
|
||||
specific netmasks). When adding/deleting IP addresses
|
||||
to a nethash set by the
|
||||
.I
|
||||
SET
|
||||
"SET"
|
||||
netfilter kernel module, it will be added/deleted by the smallest
|
||||
netblock size which can be found in the set, or by /31 if the set is empty.
|
||||
.P
|
||||
The lookup time in a nethash type of set grows approximately linearly
|
||||
with the times of the
|
||||
.B
|
||||
probes
|
||||
\fIprobes\fP
|
||||
parameter and the number of different mask parameters in the hash.
|
||||
Otherwise the same speed and memory efficiency comments applies here
|
||||
as at the iphash type.
|
||||
@@ -371,39 +314,35 @@ resort, dynamic growing of the hash performed. An ipporthash set can
|
||||
store up to 65536 (B-class network) IP addresses with all possible port
|
||||
values. When adding, deleting and testing values in an ipporthash type of
|
||||
set, the entries must be specified as
|
||||
.B
|
||||
"IP,port".
|
||||
"\fIaddress\fP\fB,\fP\fIport\fP".
|
||||
.P
|
||||
The ipporthash types of sets evaluates two src/dst parameters of the
|
||||
.I
|
||||
set
|
||||
"set"
|
||||
match and
|
||||
.I
|
||||
SET
|
||||
"SET"
|
||||
target.
|
||||
.P
|
||||
Options to use when creating an ipporthash set:
|
||||
.TP
|
||||
.BR "--from " from-IP
|
||||
\fB\-\-from\fP \fIfrom-addr\fP
|
||||
.TP
|
||||
.BR "--to " to-IP
|
||||
Create an ipporthash set from the specified range.
|
||||
\fB\-\-to\fP \fIto-addr\fP
|
||||
Create an ipporthash set from the specified address range.
|
||||
.TP
|
||||
.BR "--network " IP/mask
|
||||
\fB\-\-network\fP \fIaddr\fP\fB/\fP\fImask\fP
|
||||
Create an ipporthash set from the specified network.
|
||||
.TP
|
||||
.BR "--hashsize " hashsize
|
||||
\fB\-\-hashsize\fP \fIhashsize\fP
|
||||
The initial hash size (default 1024)
|
||||
.TP
|
||||
.BR "--probes " probes
|
||||
\fB\-\-probes\fP \fIprobes\fP
|
||||
How many times try to resolve clashing at adding an IP to the hash
|
||||
by double-hashing (default 8).
|
||||
.TP
|
||||
.BR "--resize " percent
|
||||
\fB\-\-resize\fP \fIpercent\fP
|
||||
Increase the hash size by this many percent (default 50) when adding
|
||||
an IP to the hash could not be performed after
|
||||
.B
|
||||
probes
|
||||
\fIprobes\fP
|
||||
number of double-hashing.
|
||||
.P
|
||||
The same resizing, speed and memory efficiency comments applies here
|
||||
@@ -414,39 +353,35 @@ address triples. The first IP address must come form a maximum /16
|
||||
sized network or range while the port number and the second IP address
|
||||
parameters are arbitrary. When adding, deleting and testing values in an
|
||||
ipportiphash type of set, the entries must be specified as
|
||||
.B
|
||||
"IP,port,IP".
|
||||
"\fIaddress\fP\fB,\fP\fIport\fP\fB,\fP\fIaddress\fP".
|
||||
.P
|
||||
The ipportiphash types of sets evaluates three src/dst parameters of the
|
||||
.I
|
||||
set
|
||||
"set"
|
||||
match and
|
||||
.I
|
||||
SET
|
||||
"SET"
|
||||
target.
|
||||
.P
|
||||
Options to use when creating an ipportiphash set:
|
||||
.TP
|
||||
.BR "--from " from-IP
|
||||
\fB\-\-from\fP \fIfrom-addr\fP
|
||||
.TP
|
||||
.BR "--to " to-IP
|
||||
Create an ipportiphash set from the specified range.
|
||||
\fB\-\-to\fP \fIto-addr\fP
|
||||
Create an ipportiphash set from the specified address range.
|
||||
.TP
|
||||
.BR "--network " IP/mask
|
||||
\fB\-\-network\fP \fIaddr\fP\fB/\fP\fImask\fP
|
||||
Create an ipportiphash set from the specified network.
|
||||
.TP
|
||||
.BR "--hashsize " hashsize
|
||||
\fB\-\-hashsize\fP \fIhashsize\fP
|
||||
The initial hash size (default 1024)
|
||||
.TP
|
||||
.BR "--probes " probes
|
||||
\fB\-\-probes\fP \fIprobes\fP
|
||||
How many times try to resolve clashing at adding an IP to the hash
|
||||
by double-hashing (default 8).
|
||||
.TP
|
||||
.BR "--resize " percent
|
||||
\fB\-\-resize\fP \fIpercent\fP
|
||||
Increase the hash size by this many percent (default 50) when adding
|
||||
an IP to the hash could not be performed after
|
||||
.B
|
||||
probes
|
||||
\fIprobes\fP
|
||||
number of double-hashing.
|
||||
.P
|
||||
The same resizing, speed and memory efficiency comments applies here
|
||||
@@ -459,39 +394,35 @@ parameters are arbitrary, but the size of the network address must be
|
||||
between /1-/31. When adding, deleting
|
||||
and testing values in an ipportnethash type of set, the entries must be
|
||||
specified as
|
||||
.B
|
||||
"IP,port,IP/cidr-size".
|
||||
"\fIaddress\fP\fB,\fP\fIport\fP\fB,\fP\fIaddress\fP\fB/\fP\fIprefixlen\fP".
|
||||
.P
|
||||
The ipportnethash types of sets evaluates three src/dst parameters of the
|
||||
.I
|
||||
set
|
||||
"set"
|
||||
match and
|
||||
.I
|
||||
SET
|
||||
"SET"
|
||||
target.
|
||||
.P
|
||||
Options to use when creating an ipportnethash set:
|
||||
.TP
|
||||
.BR "--from " from-IP
|
||||
\fB\-\-from\fP \fIfrom-address\fP
|
||||
.TP
|
||||
.BR "--to " to-IP
|
||||
\fB\-\-to\fP \fIto-address\fP
|
||||
Create an ipporthash set from the specified range.
|
||||
.TP
|
||||
.BR "--network " IP/mask
|
||||
\fB\-\-network\fP \fIaddress\fP\fB/\fP\fImask\fP
|
||||
Create an ipporthash set from the specified network.
|
||||
.TP
|
||||
.BR "--hashsize " hashsize
|
||||
\fB\-\-hashsize\fP \fIhashsize\fP
|
||||
The initial hash size (default 1024)
|
||||
.TP
|
||||
.BR "--probes " probes
|
||||
\fB\-\-probes\fP \fIprobes\fP
|
||||
How many times try to resolve clashing at adding an IP to the hash
|
||||
by double-hashing (default 8).
|
||||
.TP
|
||||
.BR "--resize " percent
|
||||
\fB\-\-resize\fP \fIpercent\fP
|
||||
Increase the hash size by this many percent (default 50) when adding
|
||||
an IP to the hash could not be performed after
|
||||
.B
|
||||
probes
|
||||
\fIprobes\fP
|
||||
number of double-hashing.
|
||||
.P
|
||||
The same resizing, speed and memory efficiency comments applies here
|
||||
@@ -502,14 +433,14 @@ with timeout values.
|
||||
.P
|
||||
Options to use when creating an iptree set:
|
||||
.TP
|
||||
.BR "--timeout " value
|
||||
\fB\-\-timeout\fP \fIvalue\fP
|
||||
The timeout value for the entries in seconds (default 0)
|
||||
.P
|
||||
If a set was created with a nonzero valued
|
||||
.B "--timeout"
|
||||
\fB\-\-timeout\fP
|
||||
parameter then one may add IP addresses to the set with a specific
|
||||
timeout value using the syntax
|
||||
.I IP,timeout-value.
|
||||
"\fIaddress\fP\fB,\fP\fItimeout-value\fP".
|
||||
Similarly to the hash types, the iptree type of sets can store up to 65536
|
||||
entries.
|
||||
.SS iptreemap
|
||||
@@ -517,37 +448,32 @@ The iptreemap set type uses a tree to store IP addresses or networks,
|
||||
where the last octet of an IP address are stored in a bitmap.
|
||||
As input entry, you can add IP addresses, CIDR blocks or network ranges
|
||||
to the set. Network ranges can be specified in the format
|
||||
.I IP1-IP2
|
||||
"\fIaddress1\fP\fB-\fP\fIaddress2\fP".
|
||||
.P
|
||||
Options to use when creating an iptreemap set:
|
||||
.TP
|
||||
.BR "--gc " value
|
||||
\fB\-\-gc\fP \fIvalue\fP
|
||||
How often the garbage collection should be called, in seconds (default 300)
|
||||
.SS setlist
|
||||
The setlist type uses a simple list in which you can store sets. By the
|
||||
.I
|
||||
ipset
|
||||
command you can add, delete and test sets in a setlist type of set.
|
||||
You can specify the sets as
|
||||
.B
|
||||
"setname[,after|before,setname]".
|
||||
"\fIsetname\fP[\fB,\fP{\fBafter\fP|\fBbefore\fP},\fIsetname\fP]".
|
||||
By default new sets are added after (appended to) the existing
|
||||
elements. Setlist type of sets cannot be added to a setlist type of set.
|
||||
.P
|
||||
Options to use when creating a setlist type of set:
|
||||
.TP
|
||||
.BR "--size " size
|
||||
\fB\-\-size\fP \fIsize\fP
|
||||
Create a setlist type of set with the given size (default 8).
|
||||
.P
|
||||
.PP
|
||||
By the
|
||||
.I
|
||||
set
|
||||
"set"
|
||||
match or
|
||||
.I
|
||||
SET
|
||||
"SET"
|
||||
target of
|
||||
.I
|
||||
iptables
|
||||
\fBiptables\fP(8)
|
||||
you can test, add or delete entries in the sets. The match
|
||||
will try to find a matching IP address/port in the sets and
|
||||
the target will try to add the IP address/port to the first set
|
||||
@@ -562,8 +488,9 @@ and
|
||||
.I
|
||||
b
|
||||
are setlist type of sets then in the command
|
||||
.TP
|
||||
iptables -m set --match-set a src,dst -j SET --add-set b src,dst
|
||||
.IP
|
||||
iptables \-m set \-\-match\-set a src,dst \-j SET \-\-add-set b src,dst
|
||||
.PP
|
||||
the match and target will skip any set in
|
||||
.I a
|
||||
and
|
||||
@@ -574,7 +501,7 @@ data storage in
|
||||
.I a
|
||||
set and add src to the first single or src,dst to the first double
|
||||
data storage set in
|
||||
.I b.
|
||||
\fIb\fP.
|
||||
.P
|
||||
You can imagine a setlist type of set as an ordered union of
|
||||
the set elements.
|
||||
@@ -589,6 +516,8 @@ use the iphash set type. If you have got random size of netblocks,
|
||||
use nethash.
|
||||
.P
|
||||
Old separator tokens (':' and '%") are still accepted.
|
||||
.P
|
||||
Binding support is removed.
|
||||
.SH DIAGNOSTICS
|
||||
Various error messages are printed to standard error. The exit code
|
||||
is 0 for correct functioning. Errors which appear to be caused by
|
||||
|
@@ -30,11 +30,15 @@
|
||||
#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe"
|
||||
#endif
|
||||
|
||||
#define IPSET_VERSION "3.2"
|
||||
#define IPSET_VERSION "4.1"
|
||||
|
||||
char program_name[] = "ipset";
|
||||
char program_version[] = IPSET_VERSION;
|
||||
const char *ipset_libdir = IPSET_LIB_DIR;
|
||||
static int protocol_version = 0;
|
||||
|
||||
#define STREQ(a,b) (strncmp(a,b,IP_SET_MAXNAMELEN) == 0)
|
||||
#define DONT_ALIGN (protocol_version == IP_SET_PROTOCOL_UNALIGNED)
|
||||
#define ALIGNED(len) IPSET_VALIGN(len, DONT_ALIGN)
|
||||
|
||||
/* The list of loaded set types */
|
||||
static struct settype *all_settypes = NULL;
|
||||
@@ -68,7 +72,7 @@ static unsigned int global_option_offset = 0;
|
||||
|
||||
static const char cmdflags[] = { ' ', /* CMD_NONE */
|
||||
'N', 'X', 'F', 'E', 'W', 'L', 'S', 'R',
|
||||
'A', 'D', 'T', 'B', 'U', 'H', 'V',
|
||||
'A', 'D', 'T', 'H', 'V',
|
||||
};
|
||||
|
||||
/* Options */
|
||||
@@ -77,11 +81,10 @@ static const char cmdflags[] = { ' ', /* CMD_NONE */
|
||||
#define OPT_SORTED 0x0002U /* -s */
|
||||
#define OPT_QUIET 0x0004U /* -q */
|
||||
#define OPT_DEBUG 0x0008U /* -z */
|
||||
#define OPT_BINDING 0x0010U /* -b */
|
||||
#define OPT_RESOLVE 0x0020U /* -r */
|
||||
#define NUMBER_OF_OPT 6
|
||||
#define NUMBER_OF_OPT 5
|
||||
static const char optflags[] =
|
||||
{ 'n', 's', 'q', 'z', 'b', 'r' };
|
||||
{ 'n', 's', 'q', 'z', 'r' };
|
||||
|
||||
static struct option opts_long[] = {
|
||||
/* set operations */
|
||||
@@ -100,15 +103,10 @@ static struct option opts_long[] = {
|
||||
{"del", 1, 0, 'D'},
|
||||
{"test", 1, 0, 'T'},
|
||||
|
||||
/* binding operations */
|
||||
{"bind", 1, 0, 'B'},
|
||||
{"unbind", 1, 0, 'U'},
|
||||
|
||||
/* free options */
|
||||
{"numeric", 0, 0, 'n'},
|
||||
{"sorted", 0, 0, 's'},
|
||||
{"quiet", 0, 0, 'q'},
|
||||
{"binding", 1, 0, 'b'},
|
||||
{"resolve", 0, 0, 'r'},
|
||||
|
||||
#ifdef IPSET_DEBUG
|
||||
@@ -125,7 +123,7 @@ static struct option opts_long[] = {
|
||||
};
|
||||
|
||||
static char opts_short[] =
|
||||
"-N:X::F::E:W:L::S::RA:D:T:B:U:nrsqzb:Vh::H::";
|
||||
"-N:X::F::E:W:L::S::RA:D:T:nrsqzvVh::H::";
|
||||
|
||||
/* Table of legal combinations of commands and options. If any of the
|
||||
* given commands make an option legal, that option is legal.
|
||||
@@ -136,22 +134,20 @@ static char opts_short[] =
|
||||
*/
|
||||
|
||||
static char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] = {
|
||||
/* -n -s -q -z -b */
|
||||
/*CREATE*/ {'x', 'x', ' ', ' ', 'x', 'x'},
|
||||
/*DESTROY*/ {'x', 'x', ' ', ' ', 'x', 'x'},
|
||||
/*FLUSH*/ {'x', 'x', ' ', ' ', 'x', 'x'},
|
||||
/*RENAME*/ {'x', 'x', ' ', ' ', 'x', 'x'},
|
||||
/*SWAP*/ {'x', 'x', ' ', ' ', 'x', 'x'},
|
||||
/*LIST*/ {' ', ' ', 'x', ' ', 'x', ' '},
|
||||
/*SAVE*/ {'x', 'x', ' ', ' ', 'x', 'x'},
|
||||
/*RESTORE*/ {'x', 'x', ' ', ' ', 'x', 'x'},
|
||||
/*ADD*/ {'x', 'x', ' ', ' ', 'x', 'x'},
|
||||
/*DEL*/ {'x', 'x', ' ', ' ', 'x', 'x'},
|
||||
/*TEST*/ {'x', 'x', ' ', ' ', ' ', 'x'},
|
||||
/*BIND*/ {'x', 'x', ' ', ' ', '+', 'x'},
|
||||
/*UNBIND*/ {'x', 'x', ' ', ' ', 'x', 'x'},
|
||||
/*HELP*/ {'x', 'x', 'x', ' ', 'x', 'x'},
|
||||
/*VERSION*/ {'x', 'x', 'x', ' ', 'x', 'x'},
|
||||
/* -n -s -q -z -r */
|
||||
/*CREATE*/ {'x', 'x', ' ', ' ', 'x'},
|
||||
/*DESTROY*/ {'x', 'x', ' ', ' ', 'x'},
|
||||
/*FLUSH*/ {'x', 'x', ' ', ' ', 'x'},
|
||||
/*RENAME*/ {'x', 'x', ' ', ' ', 'x'},
|
||||
/*SWAP*/ {'x', 'x', ' ', ' ', 'x'},
|
||||
/*LIST*/ {' ', ' ', 'x', ' ', ' '},
|
||||
/*SAVE*/ {'x', 'x', ' ', ' ', 'x'},
|
||||
/*RESTORE*/ {'x', 'x', ' ', ' ', 'x'},
|
||||
/*ADD*/ {'x', 'x', ' ', ' ', 'x'},
|
||||
/*DEL*/ {'x', 'x', ' ', ' ', 'x'},
|
||||
/*TEST*/ {'x', 'x', ' ', ' ', 'x'},
|
||||
/*HELP*/ {'x', 'x', 'x', ' ', 'x'},
|
||||
/*VERSION*/ {'x', 'x', 'x', ' ', 'x'},
|
||||
};
|
||||
|
||||
/* Main parser function */
|
||||
@@ -454,25 +450,26 @@ static void check_protocolversion(void)
|
||||
{
|
||||
struct ip_set_req_version req_version;
|
||||
socklen_t size = sizeof(struct ip_set_req_version);
|
||||
int sockfd = kernel_getsocket();
|
||||
int res;
|
||||
|
||||
req_version.op = IP_SET_OP_VERSION;
|
||||
res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req_version, &size);
|
||||
|
||||
if (res != 0) {
|
||||
ipset_printf("I'm of protocol version %u.\n"
|
||||
"Kernel module is not loaded in, "
|
||||
"cannot verify kernel version.",
|
||||
IP_SET_PROTOCOL_VERSION);
|
||||
if (protocol_version)
|
||||
return;
|
||||
}
|
||||
if (req_version.version != IP_SET_PROTOCOL_VERSION)
|
||||
|
||||
req_version.op = IP_SET_OP_VERSION;
|
||||
res = wrapped_getsockopt(&req_version, &size);
|
||||
|
||||
if (res != 0)
|
||||
exit_error(OTHER_PROBLEM,
|
||||
"Kernel ipset code is of protocol version %u."
|
||||
"Couldn't verify kernel module version!");
|
||||
|
||||
if (!(req_version.version == IP_SET_PROTOCOL_VERSION
|
||||
|| req_version.version == IP_SET_PROTOCOL_UNALIGNED))
|
||||
exit_error(OTHER_PROBLEM,
|
||||
"Kernel ip_set module is of protocol version %u."
|
||||
"I'm of protocol version %u.\n"
|
||||
"Please upgrade your kernel and/or ipset(8) utillity.",
|
||||
req_version.version, IP_SET_PROTOCOL_VERSION);
|
||||
protocol_version = req_version.version;
|
||||
}
|
||||
|
||||
static void set_command(int *cmd, int newcmd)
|
||||
@@ -594,11 +591,6 @@ char *ip_tostring(ip_set_ip_t ip, unsigned options)
|
||||
return inet_ntoa(addr);
|
||||
}
|
||||
|
||||
char *binding_ip_tostring(struct set *set UNUSED,
|
||||
ip_set_ip_t ip, unsigned options)
|
||||
{
|
||||
return ip_tostring(ip, options);
|
||||
}
|
||||
char *ip_tostring_numeric(ip_set_ip_t ip)
|
||||
{
|
||||
return ip_tostring(ip, OPT_NUMERIC);
|
||||
@@ -763,8 +755,7 @@ static struct settype *settype_find(const char *typename)
|
||||
DP("%s", typename);
|
||||
|
||||
while (runner != NULL) {
|
||||
if (strncmp(runner->typename, typename,
|
||||
IP_SET_MAXNAMELEN) == 0)
|
||||
if (STREQ(runner->typename, typename))
|
||||
return runner;
|
||||
|
||||
runner = runner->next;
|
||||
@@ -886,9 +877,7 @@ struct set *set_find_byname(const char *name)
|
||||
ip_set_id_t i;
|
||||
|
||||
for (i = 0; i < max_sets; i++)
|
||||
if (set_list[i]
|
||||
&& strncmp(set_list[i]->name, name,
|
||||
IP_SET_MAXNAMELEN) == 0) {
|
||||
if (set_list[i] != NULL && STREQ(set_list[i]->name, name)) {
|
||||
set = set_list[i];
|
||||
break;
|
||||
}
|
||||
@@ -906,9 +895,7 @@ static ip_set_id_t set_find_free_index(const char *name)
|
||||
if (idx == IP_SET_INVALID_ID
|
||||
&& set_list[i] == NULL)
|
||||
idx = i;
|
||||
if (set_list[i] != NULL
|
||||
&& strncmp(set_list[i]->name, name,
|
||||
IP_SET_MAXNAMELEN) == 0)
|
||||
if (set_list[i] != NULL && STREQ(set_list[i]->name, name))
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"Set %s is already defined, cannot be restored",
|
||||
name);
|
||||
@@ -935,7 +922,7 @@ static void set_create(const char *name, struct settype *settype)
|
||||
DP("%s %s", name, settype->typename);
|
||||
|
||||
req_create.op = IP_SET_OP_CREATE;
|
||||
req_create.version = IP_SET_PROTOCOL_VERSION;
|
||||
req_create.version = protocol_version;
|
||||
strcpy(req_create.name, name);
|
||||
strcpy(req_create.typename, settype->typename);
|
||||
|
||||
@@ -959,14 +946,14 @@ static void set_restore_create(const char *name, struct settype *settype)
|
||||
{
|
||||
struct set *set;
|
||||
|
||||
DP("%s %s %u %u %u %u", name, settype->typename,
|
||||
DP("%s %s %zu %zu %u %u", name, settype->typename,
|
||||
restore_offset, sizeof(struct ip_set_restore),
|
||||
settype->create_size, restore_size);
|
||||
|
||||
/* Sanity checking */
|
||||
if (restore_offset
|
||||
+ sizeof(struct ip_set_restore)
|
||||
+ settype->create_size > restore_size)
|
||||
+ ALIGNED(sizeof(struct ip_set_restore))
|
||||
+ ALIGNED(settype->create_size) > restore_size)
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"Giving up, restore file is screwed up!");
|
||||
|
||||
@@ -985,11 +972,11 @@ static void set_restore_create(const char *name, struct settype *settype)
|
||||
DP("name %s, restore index %u", restore_set->name, restore_set->index);
|
||||
/* Add settype data */
|
||||
|
||||
memcpy(restore_data + restore_offset + sizeof(struct ip_set_restore),
|
||||
settype->data, settype->create_size);
|
||||
restore_offset += ALIGNED(sizeof(struct ip_set_restore));
|
||||
memcpy(restore_data + restore_offset, settype->data, settype->create_size);
|
||||
|
||||
restore_offset += sizeof(struct ip_set_restore)
|
||||
+ settype->create_size;
|
||||
restore_offset += ALIGNED(settype->create_size);
|
||||
DP("restore_offset: %zu", restore_offset);
|
||||
|
||||
/* Add set to set_list */
|
||||
set = ipset_malloc(sizeof(struct set));
|
||||
@@ -1009,7 +996,7 @@ static void set_destroy(const char *name, unsigned op, unsigned cmd)
|
||||
DP("%s %s", cmd == CMD_DESTROY ? "destroy" : "flush", name);
|
||||
|
||||
req.op = op;
|
||||
req.version = IP_SET_PROTOCOL_VERSION;
|
||||
req.version = protocol_version;
|
||||
strcpy(req.name, name);
|
||||
|
||||
kernel_sendto(cmd, &req, sizeof(struct ip_set_req_std));
|
||||
@@ -1027,7 +1014,7 @@ static void set_rename(const char *name, const char *newname,
|
||||
name, newname);
|
||||
|
||||
req.op = op;
|
||||
req.version = IP_SET_PROTOCOL_VERSION;
|
||||
req.version = protocol_version;
|
||||
strcpy(req.name, name);
|
||||
strcpy(req.typename, newname);
|
||||
|
||||
@@ -1065,7 +1052,7 @@ tryagain:
|
||||
}
|
||||
/* Get max_sets */
|
||||
req_max_sets.op = IP_SET_OP_MAX_SETS;
|
||||
req_max_sets.version = IP_SET_PROTOCOL_VERSION;
|
||||
req_max_sets.version = protocol_version;
|
||||
strcpy(req_max_sets.set.name, name);
|
||||
size = sizeof(req_max_sets);
|
||||
kernel_getfrom(CMD_MAX_SETS, &req_max_sets, &size);
|
||||
@@ -1083,8 +1070,8 @@ tryagain:
|
||||
return 0;
|
||||
|
||||
/* Get setnames */
|
||||
size = req_size = sizeof(struct ip_set_req_setnames)
|
||||
+ req_max_sets.sets * sizeof(struct ip_set_name_list);
|
||||
size = req_size = ALIGNED(sizeof(struct ip_set_req_setnames))
|
||||
+ req_max_sets.sets * ALIGNED(sizeof(struct ip_set_name_list));
|
||||
data = ipset_malloc(size);
|
||||
((struct ip_set_req_setnames *) data)->op = op;
|
||||
((struct ip_set_req_setnames *) data)->index = *idx;
|
||||
@@ -1102,8 +1089,8 @@ tryagain:
|
||||
}
|
||||
|
||||
/* Load in setnames */
|
||||
size = sizeof(struct ip_set_req_setnames);
|
||||
while (size + sizeof(struct ip_set_name_list) <= req_size) {
|
||||
size = ALIGNED(sizeof(struct ip_set_req_setnames));
|
||||
while (size + ALIGNED(sizeof(struct ip_set_name_list)) <= req_size) {
|
||||
name_list = (struct ip_set_name_list *)
|
||||
(data + size);
|
||||
set = ipset_malloc(sizeof(struct set));
|
||||
@@ -1114,9 +1101,9 @@ tryagain:
|
||||
set_list[name_list->index] = set;
|
||||
DP("loaded %s, type %s, index %u",
|
||||
set->name, set->settype->typename, set->index);
|
||||
size += sizeof(struct ip_set_name_list);
|
||||
size += ALIGNED(sizeof(struct ip_set_name_list));
|
||||
}
|
||||
/* Size to get set members, bindings */
|
||||
/* Size to get set members */
|
||||
size = ((struct ip_set_req_setnames *)data)->size;
|
||||
free(data);
|
||||
|
||||
@@ -1126,36 +1113,7 @@ tryagain:
|
||||
/*
|
||||
* Save operation
|
||||
*/
|
||||
static size_t save_bindings(void *data, size_t offset, size_t len)
|
||||
{
|
||||
struct ip_set_hash_save *hash =
|
||||
(struct ip_set_hash_save *) (data + offset);
|
||||
struct set *set;
|
||||
|
||||
DP("offset %u, len %u", offset, len);
|
||||
if (offset + sizeof(struct ip_set_hash_save) > len)
|
||||
exit_error(OTHER_PROBLEM,
|
||||
"Save operation failed, try again later.");
|
||||
|
||||
set = set_find_byid(hash->id);
|
||||
if (!(set && set_list[hash->binding]))
|
||||
exit_error(OTHER_PROBLEM,
|
||||
"Save binding failed, try again later.");
|
||||
if (!set->settype->bindip_tostring)
|
||||
exit_error(OTHER_PROBLEM,
|
||||
"Internal error, binding is not supported with set %s"
|
||||
" of settype %s\n",
|
||||
set->name, set->settype->typename);
|
||||
printf("-B %s %s -b %s\n",
|
||||
set->name,
|
||||
set->settype->bindip_tostring(set, hash->ip, OPT_NUMERIC),
|
||||
set_list[hash->binding]->name);
|
||||
|
||||
return sizeof(struct ip_set_hash_save);
|
||||
}
|
||||
|
||||
static size_t save_set(void *data, int *bindings,
|
||||
size_t offset, size_t len)
|
||||
static size_t save_set(void *data, size_t offset, size_t len)
|
||||
{
|
||||
struct ip_set_save *set_save =
|
||||
(struct ip_set_save *) (data + offset);
|
||||
@@ -1163,12 +1121,12 @@ static size_t save_set(void *data, int *bindings,
|
||||
struct settype *settype;
|
||||
size_t used;
|
||||
|
||||
DP("offset %u (%u/%u/%u), len %u", offset,
|
||||
DP("offset %zu (%zu/%u/%u), len %zu", offset,
|
||||
sizeof(struct ip_set_save),
|
||||
set_save->header_size, set_save->members_size,
|
||||
len);
|
||||
if (offset + sizeof(struct ip_set_save) > len
|
||||
|| offset + sizeof(struct ip_set_save)
|
||||
if (offset + ALIGNED(sizeof(struct ip_set_save)) > len
|
||||
|| offset + ALIGNED(sizeof(struct ip_set_save))
|
||||
+ set_save->header_size + set_save->members_size > len)
|
||||
exit_error(OTHER_PROBLEM,
|
||||
"Save operation failed, try again later.");
|
||||
@@ -1176,8 +1134,7 @@ static size_t save_set(void *data, int *bindings,
|
||||
DP("index: %u", set_save->index);
|
||||
if (set_save->index == IP_SET_INVALID_ID) {
|
||||
/* Marker */
|
||||
*bindings = 1;
|
||||
return sizeof(struct ip_set_save);
|
||||
return ALIGNED(sizeof(struct ip_set_save));
|
||||
}
|
||||
set = set_list[set_save->index];
|
||||
if (!set)
|
||||
@@ -1186,7 +1143,7 @@ static size_t save_set(void *data, int *bindings,
|
||||
settype = set->settype;
|
||||
|
||||
/* Init set header */
|
||||
used = sizeof(struct ip_set_save);
|
||||
used = ALIGNED(sizeof(struct ip_set_save));
|
||||
settype->initheader(set, data + offset + used);
|
||||
|
||||
/* Print create set */
|
||||
@@ -1195,44 +1152,18 @@ static size_t save_set(void *data, int *bindings,
|
||||
/* Print add IPs */
|
||||
used += set_save->header_size;
|
||||
settype->saveips(set, data + offset + used,
|
||||
set_save->members_size, OPT_NUMERIC);
|
||||
set_save->members_size, OPT_NUMERIC,
|
||||
DONT_ALIGN);
|
||||
|
||||
return (used + set_save->members_size);
|
||||
}
|
||||
|
||||
static size_t save_default_bindings(void *data, int *bindings)
|
||||
{
|
||||
struct ip_set_save *set_save = (struct ip_set_save *) data;
|
||||
struct set *set;
|
||||
|
||||
if (set_save->index == IP_SET_INVALID_ID) {
|
||||
/* Marker */
|
||||
*bindings = 1;
|
||||
return sizeof(struct ip_set_save);
|
||||
}
|
||||
|
||||
set = set_list[set_save->index];
|
||||
DP("%s, binding %u", set->name, set_save->binding);
|
||||
if (set_save->binding != IP_SET_INVALID_ID) {
|
||||
if (!set_list[set_save->binding])
|
||||
exit_error(OTHER_PROBLEM,
|
||||
"Save set failed, try again later.");
|
||||
|
||||
printf("-B %s %s -b %s\n",
|
||||
set->name, IPSET_TOKEN_DEFAULT,
|
||||
set_list[set_save->binding]->name);
|
||||
}
|
||||
return (sizeof(struct ip_set_save)
|
||||
+ set_save->header_size
|
||||
+ set_save->members_size);
|
||||
}
|
||||
|
||||
static int try_save_sets(const char name[IP_SET_MAXNAMELEN])
|
||||
{
|
||||
void *data = NULL;
|
||||
socklen_t size, req_size = 0;
|
||||
ip_set_id_t idx;
|
||||
int res = 0, bindings = 0;
|
||||
int res = 0;
|
||||
time_t now = time(NULL);
|
||||
|
||||
/* Load set_list from kernel */
|
||||
@@ -1240,15 +1171,17 @@ static int try_save_sets(const char name[IP_SET_MAXNAMELEN])
|
||||
IP_SET_OP_SAVE_SIZE, CMD_SAVE);
|
||||
|
||||
if (size) {
|
||||
/* Get sets, bindings and print them */
|
||||
/* Get sets and print them */
|
||||
/* Take into account marker */
|
||||
req_size = (size += sizeof(struct ip_set_save));
|
||||
req_size = (size += ALIGNED(sizeof(struct ip_set_save)));
|
||||
data = ipset_malloc(size);
|
||||
((struct ip_set_req_list *) data)->op = IP_SET_OP_SAVE;
|
||||
((struct ip_set_req_list *) data)->index = idx;
|
||||
res = kernel_getfrom_handleerrno(CMD_SAVE, data, &size);
|
||||
|
||||
if (res != 0 || size != req_size) {
|
||||
DP("Try again: res: %i, size %u, req_size: %u",
|
||||
res, size, req_size);
|
||||
free(data);
|
||||
return -EAGAIN;
|
||||
}
|
||||
@@ -1258,17 +1191,8 @@ static int try_save_sets(const char name[IP_SET_MAXNAMELEN])
|
||||
size = 0;
|
||||
while (size < req_size) {
|
||||
DP("size: %u, req_size: %u", size, req_size);
|
||||
if (bindings)
|
||||
size += save_bindings(data, size, req_size);
|
||||
else
|
||||
size += save_set(data, &bindings, size, req_size);
|
||||
size += save_set(data, size, req_size);
|
||||
}
|
||||
/* Re-read data to save default bindings */
|
||||
bindings = 0;
|
||||
size = 0;
|
||||
while (size < req_size && bindings == 0)
|
||||
size += save_default_bindings(data + size, &bindings);
|
||||
|
||||
printf("COMMIT\n");
|
||||
now = time(NULL);
|
||||
printf("# Completed on %s", ctime(&now));
|
||||
@@ -1366,7 +1290,7 @@ static void set_restore(char *argv0)
|
||||
char buffer[1024];
|
||||
char *ptr, *name = NULL;
|
||||
char cmd = ' ';
|
||||
int first_pass, i, bindings = 0;
|
||||
int first_pass, i;
|
||||
struct settype *settype = NULL;
|
||||
struct ip_set_req_setnames *header;
|
||||
ip_set_id_t idx;
|
||||
@@ -1381,8 +1305,7 @@ static void set_restore(char *argv0)
|
||||
IP_SET_OP_LIST_SIZE, CMD_RESTORE);
|
||||
|
||||
restore_line = 0;
|
||||
restore_size = sizeof(struct ip_set_req_setnames)/* header */
|
||||
+ sizeof(struct ip_set_restore); /* marker */
|
||||
restore_size = ALIGNED(sizeof(struct ip_set_req_setnames)); /* header */
|
||||
DP("restore_size: %u", restore_size);
|
||||
/* First pass: calculate required amount of data */
|
||||
while (fgets(buffer, sizeof(buffer), in)) {
|
||||
@@ -1429,13 +1352,9 @@ static void set_restore(char *argv0)
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"Missing settype in line %u\n",
|
||||
restore_line);
|
||||
if (bindings)
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"Invalid line %u: create must precede bindings\n",
|
||||
restore_line);
|
||||
settype = check_set_typename(ptr);
|
||||
restore_size += sizeof(struct ip_set_restore)
|
||||
+ settype->create_size;
|
||||
restore_size += ALIGNED(sizeof(struct ip_set_restore))
|
||||
+ ALIGNED(settype->create_size);
|
||||
DP("restore_size (N): %u", restore_size);
|
||||
break;
|
||||
}
|
||||
@@ -1446,20 +1365,10 @@ static void set_restore(char *argv0)
|
||||
"Add IP to set %s in line %u without "
|
||||
"preceding corresponding create set line\n",
|
||||
ptr, restore_line);
|
||||
if (bindings)
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"Invalid line %u: adding entries must precede bindings\n",
|
||||
restore_line);
|
||||
restore_size += settype->adt_size;
|
||||
restore_size += ALIGNED(settype->adt_size);
|
||||
DP("restore_size (A): %u", restore_size);
|
||||
break;
|
||||
}
|
||||
case 'B': {
|
||||
bindings = 1;
|
||||
restore_size += sizeof(struct ip_set_hash_save);
|
||||
DP("restore_size (B): %u", restore_size);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"Unrecognized restore command in line %u\n",
|
||||
@@ -1471,12 +1380,13 @@ static void set_restore(char *argv0)
|
||||
if (!restore)
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"Missing COMMIT line\n");
|
||||
restore_size += ALIGNED(sizeof(struct ip_set_restore)); /* marker */
|
||||
DP("restore_size: %u", restore_size);
|
||||
restore_data = ipset_malloc(restore_size);
|
||||
header = (struct ip_set_req_setnames *) restore_data;
|
||||
header->op = IP_SET_OP_RESTORE;
|
||||
header->size = restore_size;
|
||||
restore_offset = sizeof(struct ip_set_req_setnames);
|
||||
restore_offset = ALIGNED(sizeof(struct ip_set_req_setnames));
|
||||
|
||||
/* Rewind to scan the file again */
|
||||
fseek(in, 0L, SEEK_SET);
|
||||
@@ -1508,17 +1418,15 @@ static void set_restore(char *argv0)
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"Broken restore file\n");
|
||||
do_restore:
|
||||
if (bindings == 0
|
||||
&& restore_size ==
|
||||
(restore_offset + sizeof(struct ip_set_restore))) {
|
||||
if (restore_size == (restore_offset + ALIGNED(sizeof(struct ip_set_restore)))) {
|
||||
/* No bindings */
|
||||
struct ip_set_restore *marker =
|
||||
(struct ip_set_restore *) (restore_data + restore_offset);
|
||||
|
||||
DP("restore marker");
|
||||
marker->index = IP_SET_INVALID_ID;
|
||||
marker->header_size = marker->members_size = 0;
|
||||
restore_offset += sizeof(struct ip_set_restore);
|
||||
restore_offset += ALIGNED(sizeof(struct ip_set_restore));
|
||||
DP("restore marker, restore_offset: %zu", restore_offset);
|
||||
}
|
||||
if (restore_size != restore_offset)
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
@@ -1550,8 +1458,10 @@ static struct set *set_adt_get(const char *name)
|
||||
|
||||
DP("%s", name);
|
||||
|
||||
check_protocolversion();
|
||||
|
||||
req_adt_get.op = IP_SET_OP_ADT_GET;
|
||||
req_adt_get.version = IP_SET_PROTOCOL_VERSION;
|
||||
req_adt_get.version = protocol_version;
|
||||
strcpy(req_adt_get.set.name, name);
|
||||
size = sizeof(struct ip_set_req_adt_get);
|
||||
|
||||
@@ -1579,15 +1489,15 @@ static int set_adtip(struct set *set, const char *adt,
|
||||
DP("%s -> %s", set->name, adt);
|
||||
|
||||
/* Alloc memory for the data to send */
|
||||
size = sizeof(struct ip_set_req_adt) + set->settype->adt_size ;
|
||||
DP("alloc size %d", size);
|
||||
size = ALIGNED(sizeof(struct ip_set_req_adt)) + set->settype->adt_size ;
|
||||
DP("alloc size %zu", size);
|
||||
data = ipset_malloc(size);
|
||||
|
||||
/* Fill out the request */
|
||||
req_adt = (struct ip_set_req_adt *) data;
|
||||
req_adt->op = op;
|
||||
req_adt->index = set->index;
|
||||
memcpy(data + sizeof(struct ip_set_req_adt),
|
||||
memcpy(data + ALIGNED(sizeof(struct ip_set_req_adt)),
|
||||
set->settype->data, set->settype->adt_size);
|
||||
|
||||
if (kernel_sendto_handleerrno(cmd, data, size) == -1)
|
||||
@@ -1625,155 +1535,22 @@ static void set_restore_add(struct set *set, const char *adt UNUSED)
|
||||
{
|
||||
DP("%s %s", set->name, adt);
|
||||
/* Sanity checking */
|
||||
if (restore_offset + set->settype->adt_size > restore_size)
|
||||
if (restore_offset + ALIGNED(set->settype->adt_size) > restore_size)
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"Giving up, restore file is screwed up!");
|
||||
|
||||
memcpy(restore_data + restore_offset,
|
||||
set->settype->data, set->settype->adt_size);
|
||||
restore_set->members_size += set->settype->adt_size;
|
||||
restore_offset += set->settype->adt_size;
|
||||
}
|
||||
restore_set->members_size += ALIGNED(set->settype->adt_size);
|
||||
restore_offset += ALIGNED(set->settype->adt_size);
|
||||
|
||||
/*
|
||||
* Send bind/unbind/test binding order to kernel for a set
|
||||
*/
|
||||
static int set_bind(struct set *set, const char *adt,
|
||||
const char *binding,
|
||||
unsigned op, unsigned cmd)
|
||||
{
|
||||
struct ip_set_req_bind *req_bind;
|
||||
size_t size;
|
||||
void *data;
|
||||
int res = 0;
|
||||
|
||||
/* set may be null: '-U :all: :all:|:default:' */
|
||||
DP("(%s, %s) -> %s", set ? set->name : IPSET_TOKEN_ALL, adt, binding);
|
||||
|
||||
/* Ugly */
|
||||
if (set != NULL
|
||||
&& ((strcmp(set->settype->typename, "iptreemap") == 0)
|
||||
|| (strcmp(set->settype->typename, "ipportiphash") == 0)
|
||||
|| (strcmp(set->settype->typename, "ipportnethash") == 0)
|
||||
|| (strcmp(set->settype->typename, "setlist") == 0)))
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"%s type of sets cannot be used at binding operations\n",
|
||||
set->settype->typename);
|
||||
/* Alloc memory for the data to send */
|
||||
size = sizeof(struct ip_set_req_bind);
|
||||
if (op != IP_SET_OP_UNBIND_SET && adt[0] == ':')
|
||||
/* Set default binding */
|
||||
size += IP_SET_MAXNAMELEN;
|
||||
else if (!(op == IP_SET_OP_UNBIND_SET && set == NULL))
|
||||
size += set->settype->adt_size;
|
||||
DP("alloc size %d", size);
|
||||
data = ipset_malloc(size);
|
||||
|
||||
/* Fill out the request */
|
||||
req_bind = (struct ip_set_req_bind *) data;
|
||||
req_bind->op = op;
|
||||
req_bind->index = set ? set->index : IP_SET_INVALID_ID;
|
||||
if (adt[0] == ':') {
|
||||
/* ':default:' and ':all:' */
|
||||
strncpy(req_bind->binding, adt, IP_SET_MAXNAMELEN);
|
||||
if (op != IP_SET_OP_UNBIND_SET && adt[0] == ':')
|
||||
strncpy(data + sizeof(struct ip_set_req_bind),
|
||||
binding, IP_SET_MAXNAMELEN);
|
||||
} else {
|
||||
strncpy(req_bind->binding, binding, IP_SET_MAXNAMELEN);
|
||||
memcpy(data + sizeof(struct ip_set_req_bind),
|
||||
set->settype->data, set->settype->adt_size);
|
||||
}
|
||||
|
||||
if (op == IP_SET_OP_TEST_BIND_SET) {
|
||||
if (kernel_sendto_handleerrno(cmd, data, size) == -1) {
|
||||
ipset_printf("%s in set %s is bound to %s.",
|
||||
adt, set->name, binding);
|
||||
res = 0;
|
||||
} else {
|
||||
ipset_printf("%s in set %s is NOT bound to %s.",
|
||||
adt, set->name, binding);
|
||||
res = 1;
|
||||
}
|
||||
} else
|
||||
kernel_sendto(cmd, data, size);
|
||||
free(data);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void set_restore_bind(struct set *set,
|
||||
const char *adt,
|
||||
const char *binding)
|
||||
{
|
||||
struct ip_set_hash_save *hash_restore;
|
||||
|
||||
if (restore == 1) {
|
||||
/* Marker */
|
||||
struct ip_set_restore *marker =
|
||||
(struct ip_set_restore *) (restore_data + restore_offset);
|
||||
|
||||
DP("restore marker");
|
||||
if (restore_offset + sizeof(struct ip_set_restore)
|
||||
> restore_size)
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"Giving up, restore file is screwed up!");
|
||||
marker->index = IP_SET_INVALID_ID;
|
||||
marker->header_size = marker->members_size = 0;
|
||||
restore_offset += sizeof(struct ip_set_restore);
|
||||
restore = 2;
|
||||
}
|
||||
/* Sanity checking */
|
||||
if (restore_offset + sizeof(struct ip_set_hash_save) > restore_size)
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"Giving up, restore file is screwed up!");
|
||||
|
||||
hash_restore = (struct ip_set_hash_save *) (restore_data + restore_offset);
|
||||
DP("%s -> %s", adt, binding);
|
||||
if (strcmp(adt, IPSET_TOKEN_DEFAULT) == 0)
|
||||
hash_restore->ip = 0;
|
||||
else {
|
||||
if (!set->settype->bindip_parse)
|
||||
exit_error(OTHER_PROBLEM,
|
||||
"Internal error, binding is not supported with set %s"
|
||||
" of settype %s\n",
|
||||
set->name, set->settype->typename);
|
||||
set->settype->bindip_parse(adt, &hash_restore->ip);
|
||||
}
|
||||
hash_restore->id = set->index;
|
||||
hash_restore->binding = (set_find_byname(binding))->index;
|
||||
DP("id %u, ip %u, binding %u",
|
||||
hash_restore->id, hash_restore->ip, hash_restore->binding);
|
||||
restore_offset += sizeof(struct ip_set_hash_save);
|
||||
DP("restore_offset: %zu", restore_offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print operation
|
||||
*/
|
||||
|
||||
static void print_bindings(struct set *set,
|
||||
void *data, size_t size, unsigned options,
|
||||
char * (*printip)(struct set *set,
|
||||
ip_set_ip_t ip, unsigned options))
|
||||
{
|
||||
size_t offset = 0;
|
||||
struct ip_set_hash_list *hash;
|
||||
|
||||
if (offset < size && !printip)
|
||||
exit_error(OTHER_PROBLEM,
|
||||
"Internal error, binding is not supported with set %s"
|
||||
" of settype %s\n",
|
||||
set->name, set->settype->typename);
|
||||
|
||||
while (offset < size) {
|
||||
hash = (struct ip_set_hash_list *) (data + offset);
|
||||
printf("%s -> %s\n",
|
||||
printip(set, hash->ip, options),
|
||||
set_list[hash->binding]->name);
|
||||
offset += sizeof(struct ip_set_hash_list);
|
||||
}
|
||||
}
|
||||
|
||||
/* Help function to set_list() */
|
||||
static size_t print_set(void *data, unsigned options)
|
||||
{
|
||||
@@ -1783,15 +1560,14 @@ static size_t print_set(void *data, unsigned options)
|
||||
size_t offset;
|
||||
|
||||
/* Pretty print the set */
|
||||
DP("header size: %u, members size: %u",
|
||||
setlist->header_size, setlist->members_size);
|
||||
printf("Name: %s\n", set->name);
|
||||
printf("Type: %s\n", settype->typename);
|
||||
printf("References: %d\n", setlist->ref);
|
||||
printf("Default binding: %s\n",
|
||||
setlist->binding == IP_SET_INVALID_ID ? ""
|
||||
: set_list[setlist->binding]->name);
|
||||
|
||||
/* Init header */
|
||||
offset = sizeof(struct ip_set_list);
|
||||
offset = ALIGNED(sizeof(struct ip_set_list));
|
||||
settype->initheader(set, data + offset);
|
||||
|
||||
/* Pretty print the type header */
|
||||
@@ -1801,24 +1577,20 @@ static size_t print_set(void *data, unsigned options)
|
||||
/* Pretty print all IPs */
|
||||
printf("Members:\n");
|
||||
offset += setlist->header_size;
|
||||
DP("Aligned: %u, offset: %zu, members_size %u\n", !DONT_ALIGN, offset,
|
||||
setlist->members_size);
|
||||
if (options & OPT_SORTED)
|
||||
settype->printips_sorted(set, data + offset,
|
||||
setlist->members_size, options);
|
||||
setlist->members_size, options,
|
||||
DONT_ALIGN);
|
||||
else
|
||||
settype->printips(set, data + offset,
|
||||
setlist->members_size, options);
|
||||
|
||||
/* Print bindings */
|
||||
printf("Bindings:\n");
|
||||
offset += setlist->members_size;
|
||||
if (set->settype->bindip_tostring)
|
||||
print_bindings(set,
|
||||
data + offset, setlist->bindings_size, options,
|
||||
settype->bindip_tostring);
|
||||
setlist->members_size, options,
|
||||
DONT_ALIGN);
|
||||
|
||||
printf("\n"); /* One newline between sets */
|
||||
|
||||
return (offset + setlist->bindings_size);
|
||||
return (offset + setlist->members_size);
|
||||
}
|
||||
|
||||
static int try_list_sets(const char name[IP_SET_MAXNAMELEN],
|
||||
@@ -1889,9 +1661,9 @@ static void set_help(const struct settype *settype)
|
||||
"Usage: %s -N new-set settype [options]\n"
|
||||
" %s -[XFLSH] [set] [options]\n"
|
||||
" %s -[EW] from-set to-set\n"
|
||||
" %s -[ADTU] set IP\n"
|
||||
" %s -B set IP option\n"
|
||||
" %s -[ADT] set IP\n"
|
||||
" %s -R\n"
|
||||
" %s -v\n"
|
||||
" %s -h (print this help information)\n\n",
|
||||
program_name, program_version,
|
||||
program_name, program_name, program_name,
|
||||
@@ -1922,13 +1694,6 @@ static void set_help(const struct settype *settype)
|
||||
" Deletes an IP from a set\n"
|
||||
" --test -T setname IP \n"
|
||||
" Tests if an IP exists in a set.\n"
|
||||
" --bind -B setname IP|:default: -b bind-setname\n"
|
||||
" Bind the IP in setname to bind-setname.\n"
|
||||
" --unbind -U setname IP|:all:|:default:\n"
|
||||
" Delete binding belonging to IP,\n"
|
||||
" all bindings or default binding of setname.\n"
|
||||
" --unbind -U :all: :all:|:default:\n"
|
||||
" Delete all bindings or all default bindings.\n"
|
||||
" --help -H [settype]\n"
|
||||
" Prints this help, and settype specific help\n"
|
||||
" --version -V\n"
|
||||
@@ -1937,8 +1702,7 @@ static void set_help(const struct settype *settype)
|
||||
" --sorted -s Numeric sort of the IPs in -L\n"
|
||||
" --numeric -n Numeric output of addresses in a -L (default)\n"
|
||||
" --resolve -r Try to resolve addresses in a -L\n"
|
||||
" --quiet -q Suppress any output to stdout and stderr.\n"
|
||||
" --binding -b Specifies the binding for -B\n");
|
||||
" --quiet -q Suppress any output to stdout and stderr.\n");
|
||||
#ifdef IPSET_DEBUG
|
||||
printf(" --debug -z Enable debugging\n\n");
|
||||
#else
|
||||
@@ -1970,40 +1734,13 @@ static int parse_adt_cmdline(int command,
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
/* -U :all: :all:|:default: */
|
||||
if (command == CMD_UNBIND) {
|
||||
if (strcmp(name, IPSET_TOKEN_ALL) == 0) {
|
||||
if (strcmp(adt, IPSET_TOKEN_DEFAULT) == 0
|
||||
|| strcmp(adt, IPSET_TOKEN_ALL) == 0) {
|
||||
*set = NULL;
|
||||
*settype = NULL;
|
||||
return 1;
|
||||
} else
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"-U %s requires %s or %s as binding name",
|
||||
IPSET_TOKEN_ALL,
|
||||
IPSET_TOKEN_DEFAULT,
|
||||
IPSET_TOKEN_ALL);
|
||||
}
|
||||
}
|
||||
*set = restore ? set_find_byname(name)
|
||||
: set_adt_get(name);
|
||||
*set = restore ? set_find_byname(name) : set_adt_get(name);
|
||||
|
||||
/* Reset space for adt data */
|
||||
*settype = (*set)->settype;
|
||||
memset((*settype)->data, 0, (*settype)->adt_size);
|
||||
|
||||
if ((command == CMD_TEST
|
||||
|| command == CMD_BIND
|
||||
|| command == CMD_UNBIND)
|
||||
&& (strcmp(adt, IPSET_TOKEN_DEFAULT) == 0
|
||||
|| strcmp(adt, IPSET_TOKEN_ALL) == 0))
|
||||
res = 1;
|
||||
else
|
||||
res = (*settype)->adt_parser(
|
||||
command,
|
||||
adt,
|
||||
(*settype)->data);
|
||||
res = (*settype)->adt_parser(command, adt, (*settype)->data);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -2018,9 +1755,8 @@ int parse_commandline(int argc, char *argv[])
|
||||
|
||||
char *name = NULL; /* All except -H, -R */
|
||||
char *newname = NULL; /* -E, -W */
|
||||
char *adt = NULL; /* -A, -D, -T, -B, -U */
|
||||
char *binding = NULL; /* -B */
|
||||
struct set *set = NULL; /* -A, -D, -T, -B, -U */
|
||||
char *adt = NULL; /* -A, -D, -T */
|
||||
struct set *set = NULL; /* -A, -D, -T */
|
||||
struct settype *settype = NULL; /* -N, -H */
|
||||
char all_sets[] = IPSET_TOKEN_ALL;
|
||||
|
||||
@@ -2054,11 +1790,14 @@ int parse_commandline(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
|
||||
case 'V':{ /* Version */
|
||||
printf("%s v%s Protocol version %u.\n",
|
||||
case 'V':
|
||||
case 'v': { /* Version */
|
||||
printf("%s v%s, protocol version %u.\n",
|
||||
program_name, program_version,
|
||||
IP_SET_PROTOCOL_VERSION);
|
||||
check_protocolversion();
|
||||
printf("Kernel module protocol version %u.\n",
|
||||
protocol_version);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -2067,7 +1806,7 @@ int parse_commandline(int argc, char *argv[])
|
||||
|
||||
name = check_set_name(optarg);
|
||||
|
||||
/* Protect reserved names (binding) */
|
||||
/* Protect reserved names */
|
||||
if (name[0] == ':')
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"setname might not start with colon",
|
||||
@@ -2142,9 +1881,7 @@ int parse_commandline(int argc, char *argv[])
|
||||
|
||||
case 'A': /* Add IP */
|
||||
case 'D': /* Del IP */
|
||||
case 'T': /* Test IP */
|
||||
case 'B': /* Bind IP */
|
||||
case 'U':{ /* Unbind IP */
|
||||
case 'T':{ /* Test IP */
|
||||
set_command(&command, find_cmd(c));
|
||||
|
||||
name = check_set_name(optarg);
|
||||
@@ -2197,11 +1934,6 @@ int parse_commandline(int argc, char *argv[])
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'b':
|
||||
add_option(&options, OPT_BINDING);
|
||||
binding = check_set_name(optarg);
|
||||
break;
|
||||
|
||||
case 1: /* non option */
|
||||
printf("Bad argument `%s'\n", optarg);
|
||||
exit_tryhelp(PARAMETER_PROBLEM);
|
||||
@@ -2248,6 +1980,8 @@ int parse_commandline(int argc, char *argv[])
|
||||
generic_opt_check(command, options);
|
||||
|
||||
DP("cmd: %c", cmd2char(command));
|
||||
|
||||
check_protocolversion();
|
||||
|
||||
switch (command) {
|
||||
case CMD_CREATE:
|
||||
@@ -2298,26 +2032,7 @@ int parse_commandline(int argc, char *argv[])
|
||||
break;
|
||||
|
||||
case CMD_TEST:
|
||||
if (binding)
|
||||
res = set_bind(set, adt, binding,
|
||||
IP_SET_OP_TEST_BIND_SET, CMD_TEST);
|
||||
else
|
||||
res = set_adtip(set, adt,
|
||||
IP_SET_OP_TEST_IP, CMD_TEST);
|
||||
break;
|
||||
|
||||
case CMD_BIND:
|
||||
fprintf(stderr, "Warning: binding will be removed from the next release.\n"
|
||||
"Please replace bindigs with sets of ipportmap and ipportiphash types\n");
|
||||
if (restore)
|
||||
set_restore_bind(set, adt, binding);
|
||||
else
|
||||
set_bind(set, adt, binding,
|
||||
IP_SET_OP_BIND_SET, CMD_BIND);
|
||||
break;
|
||||
|
||||
case CMD_UNBIND:
|
||||
set_bind(set, adt, "", IP_SET_OP_UNBIND_SET, CMD_UNBIND);
|
||||
res = set_adtip(set, adt, IP_SET_OP_TEST_IP, CMD_TEST);
|
||||
break;
|
||||
|
||||
case CMD_HELP:
|
||||
|
@@ -56,8 +56,6 @@ enum set_commands {
|
||||
CMD_ADD, /* -A */
|
||||
CMD_DEL, /* -D */
|
||||
CMD_TEST, /* -T */
|
||||
CMD_BIND, /* -B */
|
||||
CMD_UNBIND, /* -U */
|
||||
CMD_HELP, /* -H */
|
||||
CMD_VERSION, /* -V */
|
||||
NUMBER_OF_CMD = CMD_VERSION,
|
||||
@@ -134,22 +132,19 @@ struct settype {
|
||||
void (*printheader) (struct set *set, unsigned options);
|
||||
|
||||
/* Pretty print all IPs */
|
||||
void (*printips) (struct set *set, void *data, u_int32_t len, unsigned options);
|
||||
void (*printips) (struct set *set, void *data, u_int32_t len,
|
||||
unsigned options, char dont_align);
|
||||
|
||||
/* Pretty print all IPs sorted */
|
||||
void (*printips_sorted) (struct set *set, void *data, u_int32_t len, unsigned options);
|
||||
void (*printips_sorted) (struct set *set, void *data, u_int32_t len,
|
||||
unsigned options, char dont_align);
|
||||
|
||||
/* Print save arguments for creating the set */
|
||||
void (*saveheader) (struct set *set, unsigned options);
|
||||
|
||||
/* Print save for all IPs */
|
||||
void (*saveips) (struct set *set, void *data, u_int32_t len, unsigned options);
|
||||
|
||||
/* Conver a single IP (binding) to string */
|
||||
char * (*bindip_tostring)(struct set *set, ip_set_ip_t ip, unsigned options);
|
||||
|
||||
/* Parse an IP at restoring bindings. FIXME */
|
||||
void (*bindip_parse) (const char *str, ip_set_ip_t * ip);
|
||||
void (*saveips) (struct set *set, void *data, u_int32_t len,
|
||||
unsigned options, char dont_align);
|
||||
|
||||
/* Print usage */
|
||||
void (*usage) (void);
|
||||
@@ -189,12 +184,12 @@ extern struct set *set_find_byid(ip_set_id_t id);
|
||||
|
||||
extern unsigned warn_once;
|
||||
|
||||
#define BITS_PER_LONG (8*sizeof(unsigned long))
|
||||
#define BITS_PER_LONG (8*sizeof(ip_set_ip_t))
|
||||
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
|
||||
|
||||
static inline int test_bit(int nr, const unsigned long *addr)
|
||||
static inline int test_bit(int nr, const ip_set_ip_t *addr)
|
||||
{
|
||||
return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
|
||||
return 1 & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
|
||||
}
|
||||
|
||||
#define UNUSED __attribute__ ((unused))
|
||||
|
@@ -32,7 +32,7 @@
|
||||
|
||||
/* Initialize the create. */
|
||||
static void
|
||||
create_init(void *data)
|
||||
iphash_create_init(void *data)
|
||||
{
|
||||
struct ip_set_req_iphash_create *mydata = data;
|
||||
|
||||
@@ -48,7 +48,7 @@ create_init(void *data)
|
||||
|
||||
/* Function which parses command options; returns true if it ate an option */
|
||||
static int
|
||||
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
iphash_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
{
|
||||
struct ip_set_req_iphash_create *mydata =
|
||||
(struct ip_set_req_iphash_create *) data;
|
||||
@@ -117,7 +117,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
|
||||
/* Final check; exit if not ok. */
|
||||
static void
|
||||
create_final(void *data UNUSED, unsigned int flags UNUSED)
|
||||
iphash_create_final(void *data UNUSED, unsigned int flags UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ static const struct option create_opts[] = {
|
||||
|
||||
/* Add, del, test parser */
|
||||
static ip_set_ip_t
|
||||
adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
iphash_adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
{
|
||||
struct ip_set_req_iphash *mydata = data;
|
||||
|
||||
@@ -149,7 +149,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
*/
|
||||
|
||||
static void
|
||||
initheader(struct set *set, const void *data)
|
||||
iphash_initheader(struct set *set, const void *data)
|
||||
{
|
||||
const struct ip_set_req_iphash_create *header = data;
|
||||
struct ip_set_iphash *map = set->settype->header;
|
||||
@@ -178,7 +178,7 @@ mask_to_bits(ip_set_ip_t mask)
|
||||
}
|
||||
|
||||
static void
|
||||
printheader(struct set *set, unsigned options UNUSED)
|
||||
iphash_printheader(struct set *set, unsigned options UNUSED)
|
||||
{
|
||||
struct ip_set_iphash *mysetdata = set->settype->header;
|
||||
|
||||
@@ -192,7 +192,8 @@ printheader(struct set *set, unsigned options UNUSED)
|
||||
}
|
||||
|
||||
static void
|
||||
printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
|
||||
iphash_printips(struct set *set UNUSED, void *data, u_int32_t len,
|
||||
unsigned options, char dont_align)
|
||||
{
|
||||
size_t offset = 0;
|
||||
ip_set_ip_t *ip;
|
||||
@@ -201,12 +202,12 @@ printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
|
||||
ip = data + offset;
|
||||
if (*ip)
|
||||
printf("%s\n", ip_tostring(*ip, options));
|
||||
offset += sizeof(ip_set_ip_t);
|
||||
offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
saveheader(struct set *set, unsigned options UNUSED)
|
||||
iphash_saveheader(struct set *set, unsigned options UNUSED)
|
||||
{
|
||||
struct ip_set_iphash *mysetdata = set->settype->header;
|
||||
|
||||
@@ -221,7 +222,8 @@ saveheader(struct set *set, unsigned options UNUSED)
|
||||
|
||||
/* Print save for an IP */
|
||||
static void
|
||||
saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
|
||||
iphash_saveips(struct set *set UNUSED, void *data, u_int32_t len,
|
||||
unsigned options, char dont_align)
|
||||
{
|
||||
size_t offset = 0;
|
||||
ip_set_ip_t *ip;
|
||||
@@ -231,11 +233,12 @@ saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
|
||||
if (*ip)
|
||||
printf("-A %s %s\n", set->name,
|
||||
ip_tostring(*ip, options));
|
||||
offset += sizeof(ip_set_ip_t);
|
||||
offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
static void
|
||||
iphash_usage(void)
|
||||
{
|
||||
printf
|
||||
("-N set iphash [--hashsize hashsize] [--probes probes ]\n"
|
||||
@@ -251,29 +254,25 @@ static struct settype settype_iphash = {
|
||||
|
||||
/* Create */
|
||||
.create_size = sizeof(struct ip_set_req_iphash_create),
|
||||
.create_init = &create_init,
|
||||
.create_parse = &create_parse,
|
||||
.create_final = &create_final,
|
||||
.create_init = iphash_create_init,
|
||||
.create_parse = iphash_create_parse,
|
||||
.create_final = iphash_create_final,
|
||||
.create_opts = create_opts,
|
||||
|
||||
/* Add/del/test */
|
||||
.adt_size = sizeof(struct ip_set_req_iphash),
|
||||
.adt_parser = &adt_parser,
|
||||
.adt_parser = iphash_adt_parser,
|
||||
|
||||
/* Printing */
|
||||
.header_size = sizeof(struct ip_set_iphash),
|
||||
.initheader = &initheader,
|
||||
.printheader = &printheader,
|
||||
.printips = &printips, /* We only have the unsorted version */
|
||||
.printips_sorted = &printips,
|
||||
.saveheader = &saveheader,
|
||||
.saveips = &saveips,
|
||||
.initheader = iphash_initheader,
|
||||
.printheader = iphash_printheader,
|
||||
.printips = iphash_printips,
|
||||
.printips_sorted = iphash_printips,
|
||||
.saveheader = iphash_saveheader,
|
||||
.saveips = iphash_saveips,
|
||||
|
||||
/* Bindings */
|
||||
.bindip_tostring = &binding_ip_tostring,
|
||||
.bindip_parse = &parse_ip,
|
||||
|
||||
.usage = &usage,
|
||||
.usage = iphash_usage,
|
||||
};
|
||||
|
||||
CONSTRUCTOR(iphash)
|
||||
|
@@ -35,7 +35,7 @@
|
||||
|
||||
/* Initialize the create. */
|
||||
static void
|
||||
create_init(void *data)
|
||||
ipmap_create_init(void *data)
|
||||
{
|
||||
struct ip_set_req_ipmap_create *mydata = data;
|
||||
|
||||
@@ -45,7 +45,7 @@ create_init(void *data)
|
||||
|
||||
/* Function which parses command options; returns true if it ate an option */
|
||||
static int
|
||||
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
ipmap_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
{
|
||||
struct ip_set_req_ipmap_create *mydata = data;
|
||||
unsigned int bits;
|
||||
@@ -115,7 +115,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
|
||||
/* Final check; exit if not ok. */
|
||||
static void
|
||||
create_final(void *data, unsigned int flags)
|
||||
ipmap_create_final(void *data, unsigned int flags)
|
||||
{
|
||||
struct ip_set_req_ipmap_create *mydata = data;
|
||||
ip_set_ip_t range;
|
||||
@@ -188,7 +188,7 @@ static const struct option create_opts[] = {
|
||||
|
||||
/* Add, del, test parser */
|
||||
static ip_set_ip_t
|
||||
adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
ipmap_adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
{
|
||||
struct ip_set_req_ipmap *mydata = data;
|
||||
|
||||
@@ -205,7 +205,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
*/
|
||||
|
||||
static void
|
||||
initheader(struct set *set, const void *data)
|
||||
ipmap_initheader(struct set *set, const void *data)
|
||||
{
|
||||
const struct ip_set_req_ipmap_create *header = data;
|
||||
struct ip_set_ipmap *map = set->settype->header;
|
||||
@@ -234,7 +234,7 @@ initheader(struct set *set, const void *data)
|
||||
}
|
||||
|
||||
static void
|
||||
printheader(struct set *set, unsigned options)
|
||||
ipmap_printheader(struct set *set, unsigned options)
|
||||
{
|
||||
struct ip_set_ipmap *mysetdata = set->settype->header;
|
||||
|
||||
@@ -246,9 +246,9 @@ printheader(struct set *set, unsigned options)
|
||||
printf(" netmask: %d\n", mask_to_bits(mysetdata->netmask));
|
||||
}
|
||||
|
||||
static void
|
||||
printips_sorted(struct set *set, void *data,
|
||||
u_int32_t len UNUSED, unsigned options)
|
||||
static inline void
|
||||
__ipmap_printips_sorted(struct set *set, void *data,
|
||||
u_int32_t len UNUSED, unsigned options)
|
||||
{
|
||||
struct ip_set_ipmap *mysetdata = set->settype->header;
|
||||
ip_set_ip_t id;
|
||||
@@ -262,7 +262,26 @@ printips_sorted(struct set *set, void *data,
|
||||
}
|
||||
|
||||
static void
|
||||
saveheader(struct set *set, unsigned options)
|
||||
ipmap_printips_sorted(struct set *set, void *data,
|
||||
u_int32_t len, unsigned options,
|
||||
char dont_align)
|
||||
{
|
||||
ip_set_ip_t *ip;
|
||||
size_t offset = 0;
|
||||
|
||||
if (dont_align)
|
||||
return __ipmap_printips_sorted(set, data, len, options);
|
||||
|
||||
while (offset < len) {
|
||||
DP("offset: %zu, len %u\n", offset, len);
|
||||
ip = data + offset;
|
||||
printf("%s\n", ip_tostring(*ip, options));
|
||||
offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ipmap_saveheader(struct set *set, unsigned options)
|
||||
{
|
||||
struct ip_set_ipmap *mysetdata = set->settype->header;
|
||||
|
||||
@@ -278,8 +297,9 @@ saveheader(struct set *set, unsigned options)
|
||||
mask_to_bits(mysetdata->netmask));
|
||||
}
|
||||
|
||||
static void
|
||||
saveips(struct set *set, void *data, u_int32_t len UNUSED, unsigned options)
|
||||
static inline void
|
||||
__ipmap_saveips(struct set *set, void *data, u_int32_t len UNUSED,
|
||||
unsigned options)
|
||||
{
|
||||
struct ip_set_ipmap *mysetdata = set->settype->header;
|
||||
ip_set_ip_t id;
|
||||
@@ -294,7 +314,25 @@ saveips(struct set *set, void *data, u_int32_t len UNUSED, unsigned options)
|
||||
options));
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
static void
|
||||
ipmap_saveips(struct set *set, void *data, u_int32_t len,
|
||||
unsigned options, char dont_align)
|
||||
{
|
||||
ip_set_ip_t *ip;
|
||||
size_t offset = 0;
|
||||
|
||||
if (dont_align)
|
||||
return __ipmap_saveips(set, data, len, options);
|
||||
|
||||
while (offset < len) {
|
||||
ip = data + offset;
|
||||
printf("-A %s %s\n", set->name, ip_tostring(*ip, options));
|
||||
offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ipmap_usage(void)
|
||||
{
|
||||
printf
|
||||
("-N set ipmap --from IP --to IP [--netmask CIDR-netmask]\n"
|
||||
@@ -310,29 +348,25 @@ static struct settype settype_ipmap = {
|
||||
|
||||
/* Create */
|
||||
.create_size = sizeof(struct ip_set_req_ipmap_create),
|
||||
.create_init = &create_init,
|
||||
.create_parse = &create_parse,
|
||||
.create_final = &create_final,
|
||||
.create_init = ipmap_create_init,
|
||||
.create_parse = ipmap_create_parse,
|
||||
.create_final = ipmap_create_final,
|
||||
.create_opts = create_opts,
|
||||
|
||||
/* Add/del/test */
|
||||
.adt_size = sizeof(struct ip_set_req_ipmap),
|
||||
.adt_parser = &adt_parser,
|
||||
.adt_parser = ipmap_adt_parser,
|
||||
|
||||
/* Printing */
|
||||
.header_size = sizeof(struct ip_set_ipmap),
|
||||
.initheader = &initheader,
|
||||
.printheader = &printheader,
|
||||
.printips = &printips_sorted, /* We only have sorted version */
|
||||
.printips_sorted = &printips_sorted,
|
||||
.saveheader = &saveheader,
|
||||
.saveips = &saveips,
|
||||
.initheader = ipmap_initheader,
|
||||
.printheader = ipmap_printheader,
|
||||
.printips = ipmap_printips_sorted,
|
||||
.printips_sorted = ipmap_printips_sorted,
|
||||
.saveheader = ipmap_saveheader,
|
||||
.saveips = ipmap_saveips,
|
||||
|
||||
/* Bindings */
|
||||
.bindip_tostring = &binding_ip_tostring,
|
||||
.bindip_parse = &parse_ip,
|
||||
|
||||
.usage = &usage,
|
||||
.usage = ipmap_usage,
|
||||
};
|
||||
|
||||
CONSTRUCTOR(ipmap)
|
||||
|
@@ -32,7 +32,7 @@
|
||||
|
||||
/* Initialize the create. */
|
||||
static void
|
||||
create_init(void *data)
|
||||
ipporthash_create_init(void *data)
|
||||
{
|
||||
struct ip_set_req_ipporthash_create *mydata = data;
|
||||
|
||||
@@ -46,7 +46,8 @@ create_init(void *data)
|
||||
|
||||
/* Function which parses command options; returns true if it ate an option */
|
||||
static int
|
||||
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
ipporthash_create_parse(int c, char *argv[] UNUSED, void *data,
|
||||
unsigned *flags)
|
||||
{
|
||||
struct ip_set_req_ipporthash_create *mydata = data;
|
||||
ip_set_ip_t value;
|
||||
@@ -137,7 +138,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
|
||||
/* Final check; exit if not ok. */
|
||||
static void
|
||||
create_final(void *data, unsigned int flags)
|
||||
ipporthash_create_final(void *data, unsigned int flags)
|
||||
{
|
||||
struct ip_set_req_ipporthash_create *mydata = data;
|
||||
|
||||
@@ -189,7 +190,7 @@ static const struct option create_opts[] = {
|
||||
|
||||
/* Add, del, test parser */
|
||||
static ip_set_ip_t
|
||||
adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
ipporthash_adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
{
|
||||
struct ip_set_req_ipporthash *mydata = data;
|
||||
char *saved = ipset_strdup(arg);
|
||||
@@ -222,7 +223,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
*/
|
||||
|
||||
static void
|
||||
initheader(struct set *set, const void *data)
|
||||
ipporthash_initheader(struct set *set, const void *data)
|
||||
{
|
||||
const struct ip_set_req_ipporthash_create *header = data;
|
||||
struct ip_set_ipporthash *map = set->settype->header;
|
||||
@@ -236,7 +237,7 @@ initheader(struct set *set, const void *data)
|
||||
}
|
||||
|
||||
static void
|
||||
printheader(struct set *set, unsigned options)
|
||||
ipporthash_printheader(struct set *set, unsigned options)
|
||||
{
|
||||
struct ip_set_ipporthash *mysetdata = set->settype->header;
|
||||
|
||||
@@ -248,7 +249,8 @@ printheader(struct set *set, unsigned options)
|
||||
}
|
||||
|
||||
static void
|
||||
printips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||
ipporthash_printips(struct set *set, void *data, u_int32_t len,
|
||||
unsigned options, char dont_align)
|
||||
{
|
||||
struct ip_set_ipporthash *mysetdata = set->settype->header;
|
||||
size_t offset = 0;
|
||||
@@ -264,12 +266,12 @@ printips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||
ip_tostring(ip, options),
|
||||
port_tostring(port, options));
|
||||
}
|
||||
offset += sizeof(ip_set_ip_t);
|
||||
offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
saveheader(struct set *set, unsigned options)
|
||||
ipporthash_saveheader(struct set *set, unsigned options)
|
||||
{
|
||||
struct ip_set_ipporthash *mysetdata = set->settype->header;
|
||||
|
||||
@@ -284,7 +286,8 @@ saveheader(struct set *set, unsigned options)
|
||||
|
||||
/* Print save for an IP */
|
||||
static void
|
||||
saveips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||
ipporthash_saveips(struct set *set, void *data, u_int32_t len,
|
||||
unsigned options, char dont_align)
|
||||
{
|
||||
struct ip_set_ipporthash *mysetdata = set->settype->header;
|
||||
size_t offset = 0;
|
||||
@@ -300,27 +303,12 @@ saveips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||
ip_tostring(ip, options),
|
||||
port_tostring(port, options));
|
||||
}
|
||||
offset += sizeof(ip_set_ip_t);
|
||||
offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
|
||||
}
|
||||
}
|
||||
|
||||
static char buffer[22];
|
||||
|
||||
static char *
|
||||
unpack_ipport_tostring(struct set *set, ip_set_ip_t bip, unsigned options)
|
||||
{
|
||||
struct ip_set_ipporthash *mysetdata = set->settype->header;
|
||||
ip_set_ip_t ip, port;
|
||||
|
||||
ip = (bip>>16) + mysetdata->first_ip;
|
||||
port = (uint16_t) bip;
|
||||
sprintf(buffer, "%s,%s",
|
||||
ip_tostring(ip, options), port_tostring(port, options));
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
static void
|
||||
ipporthash_usage(void)
|
||||
{
|
||||
printf
|
||||
("-N set ipporthash --from IP --to IP\n"
|
||||
@@ -338,29 +326,25 @@ static struct settype settype_ipporthash = {
|
||||
|
||||
/* Create */
|
||||
.create_size = sizeof(struct ip_set_req_ipporthash_create),
|
||||
.create_init = &create_init,
|
||||
.create_parse = &create_parse,
|
||||
.create_final = &create_final,
|
||||
.create_init = ipporthash_create_init,
|
||||
.create_parse = ipporthash_create_parse,
|
||||
.create_final = ipporthash_create_final,
|
||||
.create_opts = create_opts,
|
||||
|
||||
/* Add/del/test */
|
||||
.adt_size = sizeof(struct ip_set_req_ipporthash),
|
||||
.adt_parser = &adt_parser,
|
||||
.adt_parser = ipporthash_adt_parser,
|
||||
|
||||
/* Printing */
|
||||
.header_size = sizeof(struct ip_set_ipporthash),
|
||||
.initheader = &initheader,
|
||||
.printheader = &printheader,
|
||||
.printips = &printips, /* We only have the unsorted version */
|
||||
.printips_sorted = &printips,
|
||||
.saveheader = &saveheader,
|
||||
.saveips = &saveips,
|
||||
.initheader = ipporthash_initheader,
|
||||
.printheader = ipporthash_printheader,
|
||||
.printips = ipporthash_printips,
|
||||
.printips_sorted = ipporthash_printips,
|
||||
.saveheader = ipporthash_saveheader,
|
||||
.saveips = ipporthash_saveips,
|
||||
|
||||
/* Bindings */
|
||||
.bindip_tostring = &unpack_ipport_tostring,
|
||||
.bindip_parse = &parse_ip,
|
||||
|
||||
.usage = &usage,
|
||||
.usage = ipporthash_usage,
|
||||
};
|
||||
|
||||
CONSTRUCTOR(ipporthash)
|
||||
|
@@ -32,7 +32,7 @@
|
||||
|
||||
/* Initialize the create. */
|
||||
static void
|
||||
create_init(void *data)
|
||||
ipportiphash_create_init(void *data)
|
||||
{
|
||||
struct ip_set_req_ipportiphash_create *mydata = data;
|
||||
|
||||
@@ -46,7 +46,8 @@ create_init(void *data)
|
||||
|
||||
/* Function which parses command options; returns true if it ate an option */
|
||||
static int
|
||||
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
ipportiphash_create_parse(int c, char *argv[] UNUSED, void *data,
|
||||
unsigned *flags)
|
||||
{
|
||||
struct ip_set_req_ipportiphash_create *mydata = data;
|
||||
ip_set_ip_t value;
|
||||
@@ -137,7 +138,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
|
||||
/* Final check; exit if not ok. */
|
||||
static void
|
||||
create_final(void *data, unsigned int flags)
|
||||
ipportiphash_create_final(void *data, unsigned int flags)
|
||||
{
|
||||
struct ip_set_req_ipportiphash_create *mydata = data;
|
||||
|
||||
@@ -189,7 +190,7 @@ static const struct option create_opts[] = {
|
||||
|
||||
/* Add, del, test parser */
|
||||
static ip_set_ip_t
|
||||
adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
ipportiphash_adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
{
|
||||
struct ip_set_req_ipportiphash *mydata = data;
|
||||
char *saved = ipset_strdup(arg);
|
||||
@@ -227,7 +228,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
*/
|
||||
|
||||
static void
|
||||
initheader(struct set *set, const void *data)
|
||||
ipportiphash_initheader(struct set *set, const void *data)
|
||||
{
|
||||
const struct ip_set_req_ipportiphash_create *header = data;
|
||||
struct ip_set_ipportiphash *map = set->settype->header;
|
||||
@@ -241,7 +242,7 @@ initheader(struct set *set, const void *data)
|
||||
}
|
||||
|
||||
static void
|
||||
printheader(struct set *set, unsigned options)
|
||||
ipportiphash_printheader(struct set *set, unsigned options)
|
||||
{
|
||||
struct ip_set_ipportiphash *mysetdata = set->settype->header;
|
||||
|
||||
@@ -253,7 +254,8 @@ printheader(struct set *set, unsigned options)
|
||||
}
|
||||
|
||||
static void
|
||||
printips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||
ipportiphash_printips(struct set *set, void *data, u_int32_t len,
|
||||
unsigned options, char dont_align)
|
||||
{
|
||||
struct ip_set_ipportiphash *mysetdata = set->settype->header;
|
||||
size_t offset = 0;
|
||||
@@ -272,12 +274,12 @@ printips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||
printf("%s\n",
|
||||
ip_tostring(ipptr->ip1, options));
|
||||
}
|
||||
offset += sizeof(struct ipportip);
|
||||
offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
saveheader(struct set *set, unsigned options)
|
||||
ipportiphash_saveheader(struct set *set, unsigned options)
|
||||
{
|
||||
struct ip_set_ipportiphash *mysetdata = set->settype->header;
|
||||
|
||||
@@ -292,7 +294,8 @@ saveheader(struct set *set, unsigned options)
|
||||
|
||||
/* Print save for an IP */
|
||||
static void
|
||||
saveips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||
ipportiphash_saveips(struct set *set, void *data, u_int32_t len,
|
||||
unsigned options, char dont_align)
|
||||
{
|
||||
struct ip_set_ipportiphash *mysetdata = set->settype->header;
|
||||
size_t offset = 0;
|
||||
@@ -311,11 +314,12 @@ saveips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||
printf("%s\n",
|
||||
ip_tostring(ipptr->ip1, options));
|
||||
}
|
||||
offset += sizeof(struct ipportip);
|
||||
offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
static void
|
||||
ipportiphash_usage(void)
|
||||
{
|
||||
printf
|
||||
("-N set ipportiphash --from IP --to IP\n"
|
||||
@@ -333,25 +337,25 @@ static struct settype settype_ipportiphash = {
|
||||
|
||||
/* Create */
|
||||
.create_size = sizeof(struct ip_set_req_ipportiphash_create),
|
||||
.create_init = &create_init,
|
||||
.create_parse = &create_parse,
|
||||
.create_final = &create_final,
|
||||
.create_init = ipportiphash_create_init,
|
||||
.create_parse = ipportiphash_create_parse,
|
||||
.create_final = ipportiphash_create_final,
|
||||
.create_opts = create_opts,
|
||||
|
||||
/* Add/del/test */
|
||||
.adt_size = sizeof(struct ip_set_req_ipportiphash),
|
||||
.adt_parser = &adt_parser,
|
||||
.adt_parser = ipportiphash_adt_parser,
|
||||
|
||||
/* Printing */
|
||||
.header_size = sizeof(struct ip_set_ipportiphash),
|
||||
.initheader = &initheader,
|
||||
.printheader = &printheader,
|
||||
.printips = &printips, /* We only have the unsorted version */
|
||||
.printips_sorted = &printips,
|
||||
.saveheader = &saveheader,
|
||||
.saveips = &saveips,
|
||||
.initheader = ipportiphash_initheader,
|
||||
.printheader = ipportiphash_printheader,
|
||||
.printips = ipportiphash_printips,
|
||||
.printips_sorted = ipportiphash_printips,
|
||||
.saveheader = ipportiphash_saveheader,
|
||||
.saveips = ipportiphash_saveips,
|
||||
|
||||
.usage = &usage,
|
||||
.usage = ipportiphash_usage,
|
||||
};
|
||||
|
||||
CONSTRUCTOR(ipportiphash)
|
||||
|
@@ -32,7 +32,7 @@
|
||||
|
||||
/* Initialize the create. */
|
||||
static void
|
||||
create_init(void *data)
|
||||
ipportnethash_create_init(void *data)
|
||||
{
|
||||
struct ip_set_req_ipportnethash_create *mydata = data;
|
||||
|
||||
@@ -46,7 +46,8 @@ create_init(void *data)
|
||||
|
||||
/* Function which parses command options; returns true if it ate an option */
|
||||
static int
|
||||
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
ipportnethash_create_parse(int c, char *argv[] UNUSED, void *data,
|
||||
unsigned *flags)
|
||||
{
|
||||
struct ip_set_req_ipportnethash_create *mydata = data;
|
||||
ip_set_ip_t value;
|
||||
@@ -137,7 +138,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
|
||||
/* Final check; exit if not ok. */
|
||||
static void
|
||||
create_final(void *data, unsigned int flags)
|
||||
ipportnethash_create_final(void *data, unsigned int flags)
|
||||
{
|
||||
struct ip_set_req_ipportnethash_create *mydata = data;
|
||||
|
||||
@@ -189,7 +190,7 @@ static const struct option create_opts[] = {
|
||||
|
||||
/* Add, del, test parser */
|
||||
static ip_set_ip_t
|
||||
adt_parser(int cmd, const char *arg, void *data)
|
||||
ipportnethash_adt_parser(int cmd, const char *arg, void *data)
|
||||
{
|
||||
struct ip_set_req_ipportnethash *mydata = data;
|
||||
char *saved = ipset_strdup(arg);
|
||||
@@ -238,7 +239,7 @@ adt_parser(int cmd, const char *arg, void *data)
|
||||
*/
|
||||
|
||||
static void
|
||||
initheader(struct set *set, const void *data)
|
||||
ipportnethash_initheader(struct set *set, const void *data)
|
||||
{
|
||||
const struct ip_set_req_ipportnethash_create *header = data;
|
||||
struct ip_set_ipportnethash *map = set->settype->header;
|
||||
@@ -252,7 +253,7 @@ initheader(struct set *set, const void *data)
|
||||
}
|
||||
|
||||
static void
|
||||
printheader(struct set *set, unsigned options)
|
||||
ipportnethash_printheader(struct set *set, unsigned options)
|
||||
{
|
||||
struct ip_set_ipportnethash *mysetdata = set->settype->header;
|
||||
|
||||
@@ -318,7 +319,8 @@ unpack_ip_tostring(ip_set_ip_t ip, unsigned options UNUSED)
|
||||
}
|
||||
|
||||
static void
|
||||
printips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||
ipportnethash_printips(struct set *set, void *data, u_int32_t len,
|
||||
unsigned options, char dont_align)
|
||||
{
|
||||
struct ip_set_ipportnethash *mysetdata = set->settype->header;
|
||||
size_t offset = 0;
|
||||
@@ -337,12 +339,12 @@ printips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||
printf("%s\n",
|
||||
unpack_ip_tostring(ipptr->ip1, options));
|
||||
}
|
||||
offset += sizeof(struct ipportip);
|
||||
offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
saveheader(struct set *set, unsigned options)
|
||||
ipportnethash_saveheader(struct set *set, unsigned options)
|
||||
{
|
||||
struct ip_set_ipportnethash *mysetdata = set->settype->header;
|
||||
|
||||
@@ -357,7 +359,8 @@ saveheader(struct set *set, unsigned options)
|
||||
|
||||
/* Print save for an IP */
|
||||
static void
|
||||
saveips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||
ipportnethash_saveips(struct set *set, void *data, u_int32_t len,
|
||||
unsigned options, char dont_align)
|
||||
{
|
||||
struct ip_set_ipportnethash *mysetdata = set->settype->header;
|
||||
size_t offset = 0;
|
||||
@@ -376,11 +379,12 @@ saveips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||
printf("%s\n",
|
||||
unpack_ip_tostring(ipptr->ip, options));
|
||||
}
|
||||
offset += sizeof(struct ipportip);
|
||||
offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
static void
|
||||
ipportnethash_usage(void)
|
||||
{
|
||||
printf
|
||||
("-N set ipportnethash --from IP --to IP\n"
|
||||
@@ -398,25 +402,25 @@ static struct settype settype_ipportnethash = {
|
||||
|
||||
/* Create */
|
||||
.create_size = sizeof(struct ip_set_req_ipportnethash_create),
|
||||
.create_init = &create_init,
|
||||
.create_parse = &create_parse,
|
||||
.create_final = &create_final,
|
||||
.create_init = ipportnethash_create_init,
|
||||
.create_parse = ipportnethash_create_parse,
|
||||
.create_final = ipportnethash_create_final,
|
||||
.create_opts = create_opts,
|
||||
|
||||
/* Add/del/test */
|
||||
.adt_size = sizeof(struct ip_set_req_ipportnethash),
|
||||
.adt_parser = &adt_parser,
|
||||
.adt_parser = ipportnethash_adt_parser,
|
||||
|
||||
/* Printing */
|
||||
.header_size = sizeof(struct ip_set_ipportnethash),
|
||||
.initheader = &initheader,
|
||||
.printheader = &printheader,
|
||||
.printips = &printips, /* We only have the unsorted version */
|
||||
.printips_sorted = &printips,
|
||||
.saveheader = &saveheader,
|
||||
.saveips = &saveips,
|
||||
.initheader = ipportnethash_initheader,
|
||||
.printheader = ipportnethash_printheader,
|
||||
.printips = ipportnethash_printips,
|
||||
.printips_sorted = ipportnethash_printips,
|
||||
.saveheader = ipportnethash_saveheader,
|
||||
.saveips = ipportnethash_saveips,
|
||||
|
||||
.usage = &usage,
|
||||
.usage = ipportnethash_usage,
|
||||
};
|
||||
|
||||
CONSTRUCTOR(ipportnethash)
|
||||
|
@@ -29,7 +29,7 @@
|
||||
|
||||
/* Initialize the create. */
|
||||
static void
|
||||
create_init(void *data)
|
||||
iptree_create_init(void *data)
|
||||
{
|
||||
struct ip_set_req_iptree_create *mydata = data;
|
||||
|
||||
@@ -39,7 +39,7 @@ create_init(void *data)
|
||||
|
||||
/* Function which parses command options; returns true if it ate an option */
|
||||
static int
|
||||
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
iptree_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
{
|
||||
struct ip_set_req_iptree_create *mydata = data;
|
||||
|
||||
@@ -63,7 +63,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
|
||||
/* Final check; exit if not ok. */
|
||||
static void
|
||||
create_final(void *data UNUSED, unsigned int flags UNUSED)
|
||||
iptree_create_final(void *data UNUSED, unsigned int flags UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ static const struct option create_opts[] = {
|
||||
|
||||
/* Add, del, test parser */
|
||||
static ip_set_ip_t
|
||||
adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
iptree_adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
{
|
||||
struct ip_set_req_iptree *mydata = data;
|
||||
char *saved = ipset_strdup(arg);
|
||||
@@ -104,7 +104,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
*/
|
||||
|
||||
static void
|
||||
initheader(struct set *set, const void *data)
|
||||
iptree_initheader(struct set *set, const void *data)
|
||||
{
|
||||
const struct ip_set_req_iptree_create *header = data;
|
||||
struct ip_set_iptree *map = set->settype->header;
|
||||
@@ -113,7 +113,7 @@ initheader(struct set *set, const void *data)
|
||||
}
|
||||
|
||||
static void
|
||||
printheader(struct set *set, unsigned options UNUSED)
|
||||
iptree_printheader(struct set *set, unsigned options UNUSED)
|
||||
{
|
||||
struct ip_set_iptree *mysetdata = set->settype->header;
|
||||
|
||||
@@ -123,7 +123,8 @@ printheader(struct set *set, unsigned options UNUSED)
|
||||
}
|
||||
|
||||
static void
|
||||
printips_sorted(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||
iptree_printips_sorted(struct set *set, void *data, u_int32_t len,
|
||||
unsigned options, char dont_align)
|
||||
{
|
||||
struct ip_set_iptree *mysetdata = set->settype->header;
|
||||
struct ip_set_req_iptree *req;
|
||||
@@ -136,12 +137,12 @@ printips_sorted(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||
req->timeout);
|
||||
else
|
||||
printf("%s\n", ip_tostring(req->ip, options));
|
||||
offset += sizeof(struct ip_set_req_iptree);
|
||||
offset += IPSET_VALIGN(sizeof(struct ip_set_req_iptree), dont_align);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
saveheader(struct set *set, unsigned options UNUSED)
|
||||
iptree_saveheader(struct set *set, unsigned options UNUSED)
|
||||
{
|
||||
struct ip_set_iptree *mysetdata = set->settype->header;
|
||||
|
||||
@@ -155,7 +156,8 @@ saveheader(struct set *set, unsigned options UNUSED)
|
||||
}
|
||||
|
||||
static void
|
||||
saveips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||
iptree_saveips(struct set *set, void *data, u_int32_t len,
|
||||
unsigned options, char dont_align)
|
||||
{
|
||||
struct ip_set_iptree *mysetdata = set->settype->header;
|
||||
struct ip_set_req_iptree *req;
|
||||
@@ -174,11 +176,12 @@ saveips(struct set *set, void *data, u_int32_t len, unsigned options)
|
||||
printf("-A %s %s\n",
|
||||
set->name,
|
||||
ip_tostring(req->ip, options));
|
||||
offset += sizeof(struct ip_set_req_iptree);
|
||||
offset += IPSET_VALIGN(sizeof(struct ip_set_req_iptree), dont_align);
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
static void
|
||||
iptree_usage(void)
|
||||
{
|
||||
printf
|
||||
("-N set iptree [--timeout value]\n"
|
||||
@@ -193,29 +196,25 @@ static struct settype settype_iptree = {
|
||||
|
||||
/* Create */
|
||||
.create_size = sizeof(struct ip_set_req_iptree_create),
|
||||
.create_init = &create_init,
|
||||
.create_parse = &create_parse,
|
||||
.create_final = &create_final,
|
||||
.create_init = iptree_create_init,
|
||||
.create_parse = iptree_create_parse,
|
||||
.create_final = iptree_create_final,
|
||||
.create_opts = create_opts,
|
||||
|
||||
/* Add/del/test */
|
||||
.adt_size = sizeof(struct ip_set_req_iptree),
|
||||
.adt_parser = &adt_parser,
|
||||
.adt_parser = iptree_adt_parser,
|
||||
|
||||
/* Printing */
|
||||
.header_size = sizeof(struct ip_set_iptree),
|
||||
.initheader = &initheader,
|
||||
.printheader = &printheader,
|
||||
.printips = &printips_sorted, /* We only have sorted version */
|
||||
.printips_sorted = &printips_sorted,
|
||||
.saveheader = &saveheader,
|
||||
.saveips = &saveips,
|
||||
.initheader = iptree_initheader,
|
||||
.printheader = iptree_printheader,
|
||||
.printips = iptree_printips_sorted, /* We only have sorted version */
|
||||
.printips_sorted = iptree_printips_sorted,
|
||||
.saveheader = iptree_saveheader,
|
||||
.saveips = iptree_saveips,
|
||||
|
||||
/* Bindings */
|
||||
.bindip_tostring = &binding_ip_tostring,
|
||||
.bindip_parse = &parse_ip,
|
||||
|
||||
.usage = &usage,
|
||||
.usage = iptree_usage,
|
||||
};
|
||||
|
||||
CONSTRUCTOR(iptree)
|
||||
|
@@ -26,7 +26,7 @@
|
||||
#define OPT_CREATE_GC 0x1
|
||||
|
||||
static void
|
||||
create_init(void *data)
|
||||
iptreemap_create_init(void *data)
|
||||
{
|
||||
struct ip_set_req_iptreemap_create *mydata = data;
|
||||
|
||||
@@ -34,7 +34,8 @@ create_init(void *data)
|
||||
}
|
||||
|
||||
static int
|
||||
create_parse(int c, char *argv[] UNUSED, void *data, unsigned int *flags)
|
||||
iptreemap_create_parse(int c, char *argv[] UNUSED, void *data,
|
||||
unsigned int *flags)
|
||||
{
|
||||
struct ip_set_req_iptreemap_create *mydata = data;
|
||||
|
||||
@@ -53,7 +54,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned int *flags)
|
||||
}
|
||||
|
||||
static void
|
||||
create_final(void *data UNUSED, unsigned int flags UNUSED)
|
||||
iptreemap_create_final(void *data UNUSED, unsigned int flags UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -63,7 +64,7 @@ static const struct option create_opts[] = {
|
||||
};
|
||||
|
||||
static ip_set_ip_t
|
||||
adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
iptreemap_adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
{
|
||||
struct ip_set_req_iptreemap *mydata = data;
|
||||
ip_set_ip_t mask;
|
||||
@@ -94,7 +95,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
}
|
||||
|
||||
static void
|
||||
initheader(struct set *set, const void *data)
|
||||
iptreemap_initheader(struct set *set, const void *data)
|
||||
{
|
||||
const struct ip_set_req_iptreemap_create *header = data;
|
||||
struct ip_set_iptreemap *map = set->settype->header;
|
||||
@@ -103,7 +104,7 @@ initheader(struct set *set, const void *data)
|
||||
}
|
||||
|
||||
static void
|
||||
printheader(struct set *set, unsigned int options UNUSED)
|
||||
iptreemap_printheader(struct set *set, unsigned int options UNUSED)
|
||||
{
|
||||
struct ip_set_iptreemap *mysetdata = set->settype->header;
|
||||
|
||||
@@ -114,8 +115,8 @@ printheader(struct set *set, unsigned int options UNUSED)
|
||||
}
|
||||
|
||||
static void
|
||||
printips_sorted(struct set *set UNUSED, void *data,
|
||||
u_int32_t len, unsigned int options)
|
||||
iptreemap_printips_sorted(struct set *set UNUSED, void *data,
|
||||
u_int32_t len, unsigned int options, char dont_align)
|
||||
{
|
||||
struct ip_set_req_iptreemap *req;
|
||||
size_t offset = 0;
|
||||
@@ -128,12 +129,12 @@ printips_sorted(struct set *set UNUSED, void *data,
|
||||
printf("-%s", ip_tostring(req->end, options));
|
||||
printf("\n");
|
||||
|
||||
offset += sizeof(struct ip_set_req_iptreemap);
|
||||
offset += IPSET_VALIGN(sizeof(struct ip_set_req_iptreemap), dont_align);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
saveheader(struct set *set, unsigned int options UNUSED)
|
||||
iptreemap_saveheader(struct set *set, unsigned int options UNUSED)
|
||||
{
|
||||
struct ip_set_iptreemap *mysetdata = set->settype->header;
|
||||
|
||||
@@ -146,8 +147,8 @@ saveheader(struct set *set, unsigned int options UNUSED)
|
||||
}
|
||||
|
||||
static void
|
||||
saveips(struct set *set UNUSED, void *data,
|
||||
u_int32_t len, unsigned int options)
|
||||
iptreemap_saveips(struct set *set UNUSED, void *data,
|
||||
u_int32_t len, unsigned int options, char dont_align)
|
||||
{
|
||||
struct ip_set_req_iptreemap *req;
|
||||
size_t offset = 0;
|
||||
@@ -162,12 +163,12 @@ saveips(struct set *set UNUSED, void *data,
|
||||
|
||||
printf("\n");
|
||||
|
||||
offset += sizeof(struct ip_set_req_iptreemap);
|
||||
offset += IPSET_VALIGN(sizeof(struct ip_set_req_iptreemap), dont_align);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
iptreemap_usage(void)
|
||||
{
|
||||
printf(
|
||||
"-N set iptreemap --gc interval\n"
|
||||
@@ -182,26 +183,23 @@ static struct settype settype_iptreemap = {
|
||||
.protocol_version = IP_SET_PROTOCOL_VERSION,
|
||||
|
||||
.create_size = sizeof(struct ip_set_req_iptreemap_create),
|
||||
.create_init = &create_init,
|
||||
.create_parse = &create_parse,
|
||||
.create_final = &create_final,
|
||||
.create_init = iptreemap_create_init,
|
||||
.create_parse = iptreemap_create_parse,
|
||||
.create_final = iptreemap_create_final,
|
||||
.create_opts = create_opts,
|
||||
|
||||
.adt_size = sizeof(struct ip_set_req_iptreemap),
|
||||
.adt_parser = &adt_parser,
|
||||
.adt_parser = iptreemap_adt_parser,
|
||||
|
||||
.header_size = sizeof(struct ip_set_iptreemap),
|
||||
.initheader = &initheader,
|
||||
.printheader = &printheader,
|
||||
.printips = &printips_sorted,
|
||||
.printips_sorted = &printips_sorted,
|
||||
.saveheader = &saveheader,
|
||||
.saveips = &saveips,
|
||||
.initheader = iptreemap_initheader,
|
||||
.printheader = iptreemap_printheader,
|
||||
.printips = iptreemap_printips_sorted,
|
||||
.printips_sorted = iptreemap_printips_sorted,
|
||||
.saveheader = iptreemap_saveheader,
|
||||
.saveips = iptreemap_saveips,
|
||||
|
||||
.bindip_tostring = &binding_ip_tostring,
|
||||
.bindip_parse = &parse_ip,
|
||||
|
||||
.usage = &usage,
|
||||
.usage = iptreemap_usage,
|
||||
};
|
||||
|
||||
CONSTRUCTOR(iptreemap)
|
||||
|
@@ -39,7 +39,7 @@
|
||||
|
||||
/* Initialize the create. */
|
||||
static void
|
||||
create_init(void *data UNUSED)
|
||||
macipmap_create_init(void *data UNUSED)
|
||||
{
|
||||
DP("create INIT");
|
||||
/* Nothing */
|
||||
@@ -47,7 +47,7 @@ create_init(void *data UNUSED)
|
||||
|
||||
/* Function which parses command options; returns true if it ate an option */
|
||||
static int
|
||||
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
macipmap_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
{
|
||||
struct ip_set_req_macipmap_create *mydata = data;
|
||||
|
||||
@@ -107,7 +107,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
|
||||
/* Final check; exit if not ok. */
|
||||
static void
|
||||
create_final(void *data, unsigned int flags)
|
||||
macipmap_create_final(void *data, unsigned int flags)
|
||||
{
|
||||
struct ip_set_req_macipmap_create *mydata = data;
|
||||
|
||||
@@ -176,7 +176,7 @@ parse_mac(const char *mac, unsigned char *ethernet)
|
||||
|
||||
/* Add, del, test parser */
|
||||
static ip_set_ip_t
|
||||
adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
macipmap_adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
{
|
||||
struct ip_set_req_macipmap *mydata = data;
|
||||
char *saved = ipset_strdup(arg);
|
||||
@@ -209,7 +209,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
*/
|
||||
|
||||
static void
|
||||
initheader(struct set *set, const void *data)
|
||||
macipmap_initheader(struct set *set, const void *data)
|
||||
{
|
||||
const struct ip_set_req_macipmap_create *header = data;
|
||||
struct ip_set_macipmap *map = set->settype->header;
|
||||
@@ -221,7 +221,7 @@ initheader(struct set *set, const void *data)
|
||||
}
|
||||
|
||||
static void
|
||||
printheader(struct set *set, unsigned options)
|
||||
macipmap_printheader(struct set *set, unsigned options)
|
||||
{
|
||||
struct ip_set_macipmap *mysetdata = set->settype->header;
|
||||
|
||||
@@ -243,9 +243,9 @@ print_mac(unsigned char macaddress[ETH_ALEN])
|
||||
printf(":%02X", macaddress[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
printips_sorted(struct set *set, void *data,
|
||||
u_int32_t len UNUSED, unsigned options)
|
||||
static inline void
|
||||
__macipmap_printips_sorted(struct set *set, void *data,
|
||||
u_int32_t len UNUSED, unsigned options)
|
||||
{
|
||||
struct ip_set_macipmap *mysetdata = set->settype->header;
|
||||
struct ip_set_macip *table = data;
|
||||
@@ -263,7 +263,27 @@ printips_sorted(struct set *set, void *data,
|
||||
}
|
||||
|
||||
static void
|
||||
saveheader(struct set *set, unsigned options)
|
||||
macipmap_printips_sorted(struct set *set, void *data,
|
||||
u_int32_t len, unsigned options,
|
||||
char dont_align)
|
||||
{
|
||||
struct ip_set_req_macipmap *d;
|
||||
size_t offset = 0;
|
||||
|
||||
if (dont_align)
|
||||
return __macipmap_printips_sorted(set, data, len, options);
|
||||
|
||||
while (offset < len) {
|
||||
d = data + offset;
|
||||
printf("%s,", ip_tostring(d->ip, options));
|
||||
print_mac(d->ethernet);
|
||||
printf("\n");
|
||||
offset += IPSET_ALIGN(sizeof(struct ip_set_req_macipmap));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
macipmap_saveheader(struct set *set, unsigned options)
|
||||
{
|
||||
struct ip_set_macipmap *mysetdata = set->settype->header;
|
||||
|
||||
@@ -277,9 +297,9 @@ saveheader(struct set *set, unsigned options)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
saveips(struct set *set, void *data,
|
||||
u_int32_t len UNUSED, unsigned options)
|
||||
static inline void
|
||||
__macipmap_saveips(struct set *set, void *data,
|
||||
u_int32_t len UNUSED, unsigned options)
|
||||
{
|
||||
struct ip_set_macipmap *mysetdata = set->settype->header;
|
||||
struct ip_set_macip *table = data;
|
||||
@@ -297,7 +317,28 @@ saveips(struct set *set, void *data,
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
static void
|
||||
macipmap_saveips(struct set *set, void *data,
|
||||
u_int32_t len, unsigned options,
|
||||
char dont_align)
|
||||
{
|
||||
struct ip_set_req_macipmap *d;
|
||||
size_t offset = 0;
|
||||
|
||||
if (dont_align)
|
||||
return __macipmap_saveips(set, data, len, options);
|
||||
|
||||
while (offset < len) {
|
||||
d = data + offset;
|
||||
printf("-A %s %s,", set->name, ip_tostring(d->ip, options));
|
||||
print_mac(d->ethernet);
|
||||
printf("\n");
|
||||
offset += IPSET_ALIGN(sizeof(struct ip_set_req_macipmap));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
macipmap_usage(void)
|
||||
{
|
||||
printf
|
||||
("-N set macipmap --from IP --to IP [--matchunset]\n"
|
||||
@@ -313,29 +354,25 @@ static struct settype settype_macipmap = {
|
||||
|
||||
/* Create */
|
||||
.create_size = sizeof(struct ip_set_req_macipmap_create),
|
||||
.create_init = &create_init,
|
||||
.create_parse = &create_parse,
|
||||
.create_final = &create_final,
|
||||
.create_init = macipmap_create_init,
|
||||
.create_parse = macipmap_create_parse,
|
||||
.create_final = macipmap_create_final,
|
||||
.create_opts = create_opts,
|
||||
|
||||
/* Add/del/test */
|
||||
.adt_size = sizeof(struct ip_set_req_macipmap),
|
||||
.adt_parser = &adt_parser,
|
||||
.adt_parser = macipmap_adt_parser,
|
||||
|
||||
/* Printing */
|
||||
.header_size = sizeof(struct ip_set_macipmap),
|
||||
.initheader = &initheader,
|
||||
.printheader = &printheader,
|
||||
.printips = &printips_sorted, /* We only have sorted version */
|
||||
.printips_sorted = &printips_sorted,
|
||||
.saveheader = &saveheader,
|
||||
.saveips = &saveips,
|
||||
.initheader = macipmap_initheader,
|
||||
.printheader = macipmap_printheader,
|
||||
.printips = macipmap_printips_sorted,
|
||||
.printips_sorted = macipmap_printips_sorted,
|
||||
.saveheader = macipmap_saveheader,
|
||||
.saveips = macipmap_saveips,
|
||||
|
||||
/* Bindings */
|
||||
.bindip_tostring = &binding_ip_tostring,
|
||||
.bindip_parse = &parse_ip,
|
||||
|
||||
.usage = &usage,
|
||||
.usage = macipmap_usage,
|
||||
};
|
||||
|
||||
CONSTRUCTOR(macipmap)
|
||||
|
@@ -31,7 +31,7 @@
|
||||
|
||||
/* Initialize the create. */
|
||||
static void
|
||||
create_init(void *data)
|
||||
nethash_create_init(void *data)
|
||||
{
|
||||
struct ip_set_req_nethash_create *mydata = data;
|
||||
|
||||
@@ -45,7 +45,7 @@ create_init(void *data)
|
||||
|
||||
/* Function which parses command options; returns true if it ate an option */
|
||||
static int
|
||||
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
nethash_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
{
|
||||
struct ip_set_req_nethash_create *mydata = data;
|
||||
ip_set_ip_t value;
|
||||
@@ -97,7 +97,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
|
||||
/* Final check; exit if not ok. */
|
||||
static void
|
||||
create_final(void *data UNUSED, unsigned int flags UNUSED)
|
||||
nethash_create_final(void *data UNUSED, unsigned int flags UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ static const struct option create_opts[] = {
|
||||
|
||||
/* Add, del, test parser */
|
||||
static ip_set_ip_t
|
||||
adt_parser(int cmd, const char *arg, void *data)
|
||||
nethash_adt_parser(int cmd, const char *arg, void *data)
|
||||
{
|
||||
struct ip_set_req_nethash *mydata = data;
|
||||
char *saved = ipset_strdup(arg);
|
||||
@@ -148,7 +148,7 @@ adt_parser(int cmd, const char *arg, void *data)
|
||||
*/
|
||||
|
||||
static void
|
||||
initheader(struct set *set, const void *data)
|
||||
nethash_initheader(struct set *set, const void *data)
|
||||
{
|
||||
const struct ip_set_req_nethash_create *header = data;
|
||||
struct ip_set_nethash *map = set->settype->header;
|
||||
@@ -160,7 +160,7 @@ initheader(struct set *set, const void *data)
|
||||
}
|
||||
|
||||
static void
|
||||
printheader(struct set *set, unsigned options UNUSED)
|
||||
nethash_printheader(struct set *set, unsigned options UNUSED)
|
||||
{
|
||||
struct ip_set_nethash *mysetdata = set->settype->header;
|
||||
|
||||
@@ -224,7 +224,8 @@ unpack_ip_tostring(ip_set_ip_t ip, unsigned options UNUSED)
|
||||
}
|
||||
|
||||
static void
|
||||
printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
|
||||
nethash_printips(struct set *set UNUSED, void *data, u_int32_t len,
|
||||
unsigned options, char dont_align)
|
||||
{
|
||||
size_t offset = 0;
|
||||
ip_set_ip_t *ip;
|
||||
@@ -233,12 +234,12 @@ printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
|
||||
ip = data + offset;
|
||||
if (*ip)
|
||||
printf("%s\n", unpack_ip_tostring(*ip, options));
|
||||
offset += sizeof(ip_set_ip_t);
|
||||
offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
saveheader(struct set *set, unsigned options UNUSED)
|
||||
nethash_saveheader(struct set *set, unsigned options UNUSED)
|
||||
{
|
||||
struct ip_set_nethash *mysetdata = set->settype->header;
|
||||
|
||||
@@ -249,7 +250,8 @@ saveheader(struct set *set, unsigned options UNUSED)
|
||||
|
||||
/* Print save for an IP */
|
||||
static void
|
||||
saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
|
||||
nethash_saveips(struct set *set UNUSED, void *data, u_int32_t len,
|
||||
unsigned options, char dont_align)
|
||||
{
|
||||
size_t offset = 0;
|
||||
ip_set_ip_t *ip;
|
||||
@@ -259,40 +261,12 @@ saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
|
||||
if (*ip)
|
||||
printf("-A %s %s\n", set->name,
|
||||
unpack_ip_tostring(*ip, options));
|
||||
offset += sizeof(ip_set_ip_t);
|
||||
offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
net_tostring(struct set *set UNUSED, ip_set_ip_t ip, unsigned options)
|
||||
{
|
||||
return unpack_ip_tostring(ip, options);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_net(const char *str, ip_set_ip_t *ip)
|
||||
{
|
||||
char *saved = ipset_strdup(str);
|
||||
char *ptr, *tmp = saved;
|
||||
ip_set_ip_t cidr;
|
||||
|
||||
ptr = strsep(&tmp, "/");
|
||||
|
||||
if (tmp == NULL)
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"Missing cidr from `%s'", str);
|
||||
|
||||
if (string_to_number(tmp, 1, 31, &cidr))
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"Out of range cidr `%s' specified", str);
|
||||
|
||||
parse_ip(ptr, ip);
|
||||
ipset_free(saved);
|
||||
|
||||
*ip = pack_ip_cidr(*ip, cidr);
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
nethash_usage(void)
|
||||
{
|
||||
printf
|
||||
("-N set nethash [--hashsize hashsize] [--probes probes ]\n"
|
||||
@@ -308,29 +282,25 @@ static struct settype settype_nethash = {
|
||||
|
||||
/* Create */
|
||||
.create_size = sizeof(struct ip_set_req_nethash_create),
|
||||
.create_init = &create_init,
|
||||
.create_parse = &create_parse,
|
||||
.create_final = &create_final,
|
||||
.create_init = nethash_create_init,
|
||||
.create_parse = nethash_create_parse,
|
||||
.create_final = nethash_create_final,
|
||||
.create_opts = create_opts,
|
||||
|
||||
/* Add/del/test */
|
||||
.adt_size = sizeof(struct ip_set_req_nethash),
|
||||
.adt_parser = &adt_parser,
|
||||
.adt_parser = nethash_adt_parser,
|
||||
|
||||
/* Printing */
|
||||
.header_size = sizeof(struct ip_set_nethash),
|
||||
.initheader = &initheader,
|
||||
.printheader = &printheader,
|
||||
.printips = &printips, /* We only have the unsorted version */
|
||||
.printips_sorted = &printips,
|
||||
.saveheader = &saveheader,
|
||||
.saveips = &saveips,
|
||||
.initheader = nethash_initheader,
|
||||
.printheader = nethash_printheader,
|
||||
.printips = nethash_printips,
|
||||
.printips_sorted = nethash_printips,
|
||||
.saveheader = nethash_saveheader,
|
||||
.saveips = nethash_saveips,
|
||||
|
||||
/* Bindings */
|
||||
.bindip_tostring = &net_tostring,
|
||||
.bindip_parse = &parse_net,
|
||||
|
||||
.usage = &usage,
|
||||
.usage = nethash_usage,
|
||||
};
|
||||
|
||||
CONSTRUCTOR(nethash)
|
||||
|
@@ -32,7 +32,7 @@
|
||||
|
||||
/* Initialize the create. */
|
||||
static void
|
||||
create_init(void *data UNUSED)
|
||||
portmap_create_init(void *data UNUSED)
|
||||
{
|
||||
DP("create INIT");
|
||||
/* Nothing */
|
||||
@@ -40,7 +40,7 @@ create_init(void *data UNUSED)
|
||||
|
||||
/* Function which parses command options; returns true if it ate an option */
|
||||
static int
|
||||
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
portmap_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
{
|
||||
struct ip_set_req_portmap_create *mydata = data;
|
||||
|
||||
@@ -76,7 +76,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
|
||||
|
||||
/* Final check; exit if not ok. */
|
||||
static void
|
||||
create_final(void *data, unsigned int flags)
|
||||
portmap_create_final(void *data, unsigned int flags)
|
||||
{
|
||||
struct ip_set_req_portmap_create *mydata = data;
|
||||
|
||||
@@ -113,7 +113,7 @@ static const struct option create_opts[] = {
|
||||
|
||||
/* Add, del, test parser */
|
||||
static ip_set_ip_t
|
||||
adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
portmap_adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
{
|
||||
struct ip_set_req_portmap *mydata = data;
|
||||
|
||||
@@ -128,7 +128,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
*/
|
||||
|
||||
static void
|
||||
initheader(struct set *set, const void *data)
|
||||
portmap_initheader(struct set *set, const void *data)
|
||||
{
|
||||
const struct ip_set_req_portmap_create *header = data;
|
||||
struct ip_set_portmap *map = set->settype->header;
|
||||
@@ -139,7 +139,7 @@ initheader(struct set *set, const void *data)
|
||||
}
|
||||
|
||||
static void
|
||||
printheader(struct set *set, unsigned options)
|
||||
portmap_printheader(struct set *set, unsigned options)
|
||||
{
|
||||
struct ip_set_portmap *mysetdata = set->settype->header;
|
||||
|
||||
@@ -147,12 +147,12 @@ printheader(struct set *set, unsigned options)
|
||||
printf(" to: %s\n", port_tostring(mysetdata->last_ip, options));
|
||||
}
|
||||
|
||||
static void
|
||||
printports_sorted(struct set *set, void *data,
|
||||
u_int32_t len UNUSED, unsigned options)
|
||||
static inline void
|
||||
__portmap_printips_sorted(struct set *set, void *data,
|
||||
u_int32_t len UNUSED, unsigned options)
|
||||
{
|
||||
struct ip_set_portmap *mysetdata = set->settype->header;
|
||||
u_int32_t addr = mysetdata->first_ip;
|
||||
ip_set_ip_t addr = mysetdata->first_ip;
|
||||
|
||||
DP("%u -- %u", mysetdata->first_ip, mysetdata->last_ip);
|
||||
while (addr <= mysetdata->last_ip) {
|
||||
@@ -162,15 +162,26 @@ printports_sorted(struct set *set, void *data,
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
binding_port_tostring(struct set *set UNUSED,
|
||||
ip_set_ip_t ip, unsigned options)
|
||||
static void
|
||||
portmap_printips_sorted(struct set *set, void *data,
|
||||
u_int32_t len, unsigned options,
|
||||
char dont_align)
|
||||
{
|
||||
return port_tostring(ip, options);
|
||||
ip_set_ip_t *ip;
|
||||
size_t offset = 0;
|
||||
|
||||
if (dont_align)
|
||||
return __portmap_printips_sorted(set, data, len, options);
|
||||
|
||||
while (offset < len) {
|
||||
ip = data + offset;
|
||||
printf("%s\n", port_tostring(*ip, options));
|
||||
offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
saveheader(struct set *set, unsigned options)
|
||||
portmap_saveheader(struct set *set, unsigned options)
|
||||
{
|
||||
struct ip_set_portmap *mysetdata = set->settype->header;
|
||||
|
||||
@@ -182,14 +193,15 @@ saveheader(struct set *set, unsigned options)
|
||||
port_tostring(mysetdata->last_ip, options));
|
||||
}
|
||||
|
||||
static void
|
||||
saveports(struct set *set, void *data,
|
||||
u_int32_t len UNUSED, unsigned options)
|
||||
static inline void
|
||||
__portmap_saveips(struct set *set, void *data,
|
||||
u_int32_t len UNUSED, unsigned options)
|
||||
{
|
||||
struct ip_set_portmap *mysetdata = set->settype->header;
|
||||
u_int32_t addr = mysetdata->first_ip;
|
||||
ip_set_ip_t addr = mysetdata->first_ip;
|
||||
|
||||
while (addr <= mysetdata->last_ip) {
|
||||
DP("addr: %lu, last_ip %lu", (long unsigned)addr, (long unsigned)mysetdata->last_ip);
|
||||
if (test_bit(addr - mysetdata->first_ip, data))
|
||||
printf("-A %s %s\n",
|
||||
set->name,
|
||||
@@ -198,7 +210,26 @@ saveports(struct set *set, void *data,
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
static void
|
||||
portmap_saveips(struct set *set, void *data,
|
||||
u_int32_t len, unsigned options,
|
||||
char dont_align)
|
||||
{
|
||||
ip_set_ip_t *ip;
|
||||
size_t offset = 0;
|
||||
|
||||
if (dont_align)
|
||||
return __portmap_saveips(set, data, len, options);
|
||||
|
||||
while (offset < len) {
|
||||
ip = data + offset;
|
||||
printf("-A %s %s\n", set->name, port_tostring(*ip, options));
|
||||
offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
portmap_usage(void)
|
||||
{
|
||||
printf
|
||||
("-N set portmap --from PORT --to PORT\n"
|
||||
@@ -213,29 +244,25 @@ static struct settype settype_portmap = {
|
||||
|
||||
/* Create */
|
||||
.create_size = sizeof(struct ip_set_req_portmap_create),
|
||||
.create_init = &create_init,
|
||||
.create_parse = &create_parse,
|
||||
.create_final = &create_final,
|
||||
.create_init = portmap_create_init,
|
||||
.create_parse = portmap_create_parse,
|
||||
.create_final = portmap_create_final,
|
||||
.create_opts = create_opts,
|
||||
|
||||
/* Add/del/test */
|
||||
.adt_size = sizeof(struct ip_set_req_portmap),
|
||||
.adt_parser = &adt_parser,
|
||||
.adt_parser = portmap_adt_parser,
|
||||
|
||||
/* Printing */
|
||||
.header_size = sizeof(struct ip_set_portmap),
|
||||
.initheader = &initheader,
|
||||
.printheader = &printheader,
|
||||
.printips = &printports_sorted, /* We only have sorted version */
|
||||
.printips_sorted = &printports_sorted,
|
||||
.saveheader = &saveheader,
|
||||
.saveips = &saveports,
|
||||
.initheader = portmap_initheader,
|
||||
.printheader = portmap_printheader,
|
||||
.printips = portmap_printips_sorted,
|
||||
.printips_sorted = portmap_printips_sorted,
|
||||
.saveheader = portmap_saveheader,
|
||||
.saveips = portmap_saveips,
|
||||
|
||||
/* Bindings */
|
||||
.bindip_tostring = &binding_port_tostring,
|
||||
.bindip_parse = &parse_port,
|
||||
|
||||
.usage = &usage,
|
||||
.usage = portmap_usage,
|
||||
};
|
||||
|
||||
CONSTRUCTOR(portmap)
|
||||
|
@@ -27,7 +27,7 @@
|
||||
|
||||
/* Initialize the create. */
|
||||
static void
|
||||
create_init(void *data)
|
||||
setlist_create_init(void *data)
|
||||
{
|
||||
struct ip_set_req_setlist_create *mydata = data;
|
||||
|
||||
@@ -36,7 +36,8 @@ create_init(void *data)
|
||||
|
||||
/* Function which parses command options; returns true if it ate an option */
|
||||
static int
|
||||
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags UNUSED)
|
||||
setlist_create_parse(int c, char *argv[] UNUSED, void *data,
|
||||
unsigned *flags UNUSED)
|
||||
{
|
||||
struct ip_set_req_setlist_create *mydata = data;
|
||||
unsigned int size;
|
||||
@@ -57,7 +58,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags UNUSED)
|
||||
|
||||
/* Final check; exit if not ok. */
|
||||
static void
|
||||
create_final(void *data UNUSED, unsigned int flags UNUSED)
|
||||
setlist_create_final(void *data UNUSED, unsigned int flags UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -67,7 +68,8 @@ static const struct option create_opts[] = {
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void check_setname(const char *name)
|
||||
static void
|
||||
check_setname(const char *name)
|
||||
{
|
||||
if (strlen(name) > IP_SET_MAXNAMELEN - 1)
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
@@ -77,7 +79,7 @@ static void check_setname(const char *name)
|
||||
|
||||
/* Add, del, test parser */
|
||||
static ip_set_ip_t
|
||||
adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
setlist_adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
{
|
||||
struct ip_set_req_setlist *mydata = data;
|
||||
char *saved = ipset_strdup(arg);
|
||||
@@ -115,7 +117,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
|
||||
*/
|
||||
|
||||
static void
|
||||
initheader(struct set *set, const void *data)
|
||||
setlist_initheader(struct set *set, const void *data)
|
||||
{
|
||||
const struct ip_set_req_setlist_create *header = data;
|
||||
struct ip_set_setlist *map = set->settype->header;
|
||||
@@ -125,7 +127,7 @@ initheader(struct set *set, const void *data)
|
||||
}
|
||||
|
||||
static void
|
||||
printheader(struct set *set, unsigned options UNUSED)
|
||||
setlist_printheader(struct set *set, unsigned options UNUSED)
|
||||
{
|
||||
struct ip_set_setlist *mysetdata = set->settype->header;
|
||||
|
||||
@@ -133,25 +135,29 @@ printheader(struct set *set, unsigned options UNUSED)
|
||||
}
|
||||
|
||||
static void
|
||||
printips_sorted(struct set *set, void *data,
|
||||
u_int32_t len UNUSED, unsigned options UNUSED)
|
||||
setlist_printips_sorted(struct set *set, void *data,
|
||||
u_int32_t len UNUSED, unsigned options UNUSED,
|
||||
char dont_align)
|
||||
{
|
||||
struct ip_set_setlist *mysetdata = set->settype->header;
|
||||
int i;
|
||||
ip_set_id_t id;
|
||||
int i, asize;
|
||||
ip_set_id_t *id;
|
||||
struct set *elem;
|
||||
|
||||
asize = IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
|
||||
for (i = 0; i < mysetdata->size; i++ ) {
|
||||
id = *((ip_set_id_t *)data + i);
|
||||
if (id == IP_SET_INVALID_ID)
|
||||
DP("Try %u", i);
|
||||
id = (ip_set_id_t *)(data + i * asize);
|
||||
DP("Try %u, check", i);
|
||||
if (*id == IP_SET_INVALID_ID)
|
||||
return;
|
||||
elem = set_find_byid(id);
|
||||
elem = set_find_byid(*id);
|
||||
printf("%s\n", elem->name);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
saveheader(struct set *set, unsigned options UNUSED)
|
||||
setlist_saveheader(struct set *set, unsigned options UNUSED)
|
||||
{
|
||||
struct ip_set_setlist *mysetdata = set->settype->header;
|
||||
|
||||
@@ -161,24 +167,26 @@ saveheader(struct set *set, unsigned options UNUSED)
|
||||
}
|
||||
|
||||
static void
|
||||
saveips(struct set *set, void *data,
|
||||
u_int32_t len UNUSED, unsigned options UNUSED)
|
||||
setlist_saveips(struct set *set, void *data,
|
||||
u_int32_t len UNUSED, unsigned options UNUSED, char dont_align)
|
||||
{
|
||||
struct ip_set_setlist *mysetdata = set->settype->header;
|
||||
int i;
|
||||
ip_set_id_t id;
|
||||
int i, asize;
|
||||
ip_set_id_t *id;
|
||||
struct set *elem;
|
||||
|
||||
asize = IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
|
||||
for (i = 0; i < mysetdata->size; i++ ) {
|
||||
id = *((ip_set_id_t *)data + i);
|
||||
if (id == IP_SET_INVALID_ID)
|
||||
id = (ip_set_id_t *)(data + i * asize);
|
||||
if (*id == IP_SET_INVALID_ID)
|
||||
return;
|
||||
elem = set_find_byid(id);
|
||||
elem = set_find_byid(*id);
|
||||
printf("-A %s %s\n", set->name, elem->name);
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
static void
|
||||
setlist_usage(void)
|
||||
{
|
||||
printf
|
||||
("-N set setlist --size size\n"
|
||||
@@ -193,25 +201,25 @@ static struct settype settype_setlist = {
|
||||
|
||||
/* Create */
|
||||
.create_size = sizeof(struct ip_set_req_setlist_create),
|
||||
.create_init = &create_init,
|
||||
.create_parse = &create_parse,
|
||||
.create_final = &create_final,
|
||||
.create_init = setlist_create_init,
|
||||
.create_parse = setlist_create_parse,
|
||||
.create_final = setlist_create_final,
|
||||
.create_opts = create_opts,
|
||||
|
||||
/* Add/del/test */
|
||||
.adt_size = sizeof(struct ip_set_req_setlist),
|
||||
.adt_parser = &adt_parser,
|
||||
.adt_parser = setlist_adt_parser,
|
||||
|
||||
/* Printing */
|
||||
.header_size = sizeof(struct ip_set_setlist),
|
||||
.initheader = &initheader,
|
||||
.printheader = &printheader,
|
||||
.printips = &printips_sorted, /* We only have sorted version */
|
||||
.printips_sorted = &printips_sorted,
|
||||
.saveheader = &saveheader,
|
||||
.saveips = &saveips,
|
||||
.initheader = setlist_initheader,
|
||||
.printheader = setlist_printheader,
|
||||
.printips = setlist_printips_sorted,
|
||||
.printips_sorted = setlist_printips_sorted,
|
||||
.saveheader = setlist_saveheader,
|
||||
.saveips = setlist_saveips,
|
||||
|
||||
.usage = &usage,
|
||||
.usage = setlist_usage,
|
||||
};
|
||||
|
||||
CONSTRUCTOR(setlist)
|
||||
|
@@ -1,13 +1,13 @@
|
||||
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:
|
||||
.TP
|
||||
\fB--delude\fP
|
||||
\fB\-\-delude\fP
|
||||
Use the REJECT and DELUDE targets as a base to do a sudden or deferred
|
||||
connection reset, fooling some network scanners to return non-deterministic
|
||||
(randomly open/closed) results, and in case it is deemed open, it is actually
|
||||
closed/filtered.
|
||||
.TP
|
||||
\fB--tarpit\fP
|
||||
\fB\-\-tarpit\fP
|
||||
Use the REJECT and TARPIT target as a base to hold the connection until it
|
||||
times out. This consumes conntrack entries when connection tracking is loaded
|
||||
(which usually is on most machines), and routers inbetween you and the Internet
|
||||
|
@@ -4,7 +4,7 @@ VMware does not allow to set a non-VMware MAC address before an operating
|
||||
system is booted (and the MAC be changed with `ip link set eth0 address
|
||||
aa:bb..`).
|
||||
.TP
|
||||
\fB--set-mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
|
||||
\fB\-\-set\-mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
|
||||
Replace the client host MAC address field in the DHCP message with the given
|
||||
MAC address. This option is mandatory. The \fImask\fP parameter specifies the
|
||||
prefix length of bits to change.
|
||||
@@ -12,13 +12,13 @@ prefix length of bits to change.
|
||||
EXAMPLE, replacing all addresses from one of VMware's assigned vendor IDs
|
||||
(00:50:56) addresses with something else:
|
||||
.PP
|
||||
iptables -t mangle -A FORWARD -p udp --dport 67 -m physdev --physdev-in vmnet1
|
||||
-m dhcpmac --mac 00:50:56:00:00:00/24 -j DHCPMAC --set-mac
|
||||
ab:cd:ef:00:00:00/24
|
||||
iptables \-t mangle \-A FORWARD \-p udp \-\-dport 67 \-m physdev
|
||||
\-\-physdev\-in vmnet1 \-m dhcpmac \-\-mac 00:50:56:00:00:00/24 \-j DHCPMAC
|
||||
\-\-set\-mac ab:cd:ef:00:00:00/24
|
||||
.PP
|
||||
iptables -t mangle -A FORWARD -p udp --dport 68 -m physdev --physdev-out vmnet1
|
||||
-m dhcpmac --mac ab:cd:ef:00:00:00/24 -j DHCPMAC --set-mac
|
||||
00:50:56:00:00:00/24
|
||||
iptables \-t mangle \-A FORWARD \-p udp \-\-dport 68 \-m physdev
|
||||
\-\-physdev\-out vmnet1 \-m dhcpmac \-\-mac ab:cd:ef:00:00:00/24 \-j DHCPMAC
|
||||
\-\-set\-mac 00:50:56:00:00:00/24
|
||||
.PP
|
||||
(This assumes there is a bridge interface that has vmnet1 as a port. You will
|
||||
also need to add appropriate ebtables rules to change the MAC address of the
|
||||
|
@@ -4,16 +4,16 @@ firewall based classifier.
|
||||
|
||||
This target is to be used inside the \fBmangle\fP table.
|
||||
.TP
|
||||
\fB--addr\fP {\fBsrc\fP|\fBdst\fP}
|
||||
\fB\-\-addr\fP {\fBsrc\fP|\fBdst\fP}
|
||||
Select source or destination IP address as a basis for the mark.
|
||||
.TP
|
||||
\fB--and-mask\fP \fImask\fP
|
||||
\fB\-\-and\-mask\fP \fImask\fP
|
||||
Perform bitwise AND on the IP address and this bitmask.
|
||||
.TP
|
||||
\fB--or-mask\fP \fImask\fP
|
||||
\fB\-\-or\-mask\fP \fImask\fP
|
||||
Perform bitwise OR on the IP address and this bitmask.
|
||||
.TP
|
||||
\fB--shift\fP \fIvalue\fP
|
||||
\fB\-\-shift\fP \fIvalue\fP
|
||||
Shift addresses to the right by the given number of bits before taking it
|
||||
as a mark. (This is done before ANDing or ORing it.) This option is needed
|
||||
to select part of an IPv6 address, because marks are only 32 bits in size.
|
||||
@@ -34,16 +34,16 @@ tc filter add dev eth3 parent 1:0 protocol ip fw
|
||||
.PP
|
||||
Earlier we had many rules just like below:
|
||||
.IP
|
||||
iptables -t mangle -A POSTROUTING -o eth3 -d 192.168.5.2 -j MARK
|
||||
--set-mark 0x10502
|
||||
iptables \-t mangle \-A POSTROUTING \-o eth3 \-d 192.168.5.2 \-j MARK
|
||||
\-\-set\-mark 0x10502
|
||||
.IP
|
||||
iptables -t mangle -A POSTROUTING -o eth3 -d 192.168.5.3 -j MARK
|
||||
--set-mark 0x10503
|
||||
iptables \-t mangle \-A POSTROUTING \-o eth3 \-d 192.168.5.3 \-j MARK
|
||||
\-\-set\-mark 0x10503
|
||||
.PP
|
||||
Using IPMARK target we can replace all the mangle/mark rules with only one:
|
||||
.IP
|
||||
iptables -t mangle -A POSTROUTING -o eth3 -j IPMARK --addr dst
|
||||
--and-mask 0xffff --or-mask 0x10000
|
||||
iptables \-t mangle \-A POSTROUTING \-o eth3 \-j IPMARK \-\-addr dst
|
||||
\-\-and\-mask 0xffff \-\-or\-mask 0x10000
|
||||
.PP
|
||||
On the routers with hundreds of users there should be significant load
|
||||
decrease (e.g. twice).
|
||||
@@ -52,5 +52,5 @@ decrease (e.g. twice).
|
||||
2001:db8:45:1d:20d:93ff:fe9b:e443 and the resulting mark should be 0x93ff,
|
||||
then a right-shift of 16 is needed first:
|
||||
.IP
|
||||
-t mangle -A PREROUTING -s 2001:db8::/32 -j IPMARK --addr src --shift 16
|
||||
--and-mask 0xFFFF
|
||||
\-t mangle \-A PREROUTING \-s 2001:db8::/32 \-j IPMARK \-\-addr src \-\-shift
|
||||
16 \-\-and\-mask 0xFFFF
|
||||
|
@@ -1,17 +1,8 @@
|
||||
The LOGMARK target will log packet and connection marks to syslog.
|
||||
.TP
|
||||
\fB--log-level\fR \fIlevel\fR
|
||||
\fB\-\-log\-level\fR \fIlevel\fR
|
||||
A logging level between 0 and 8 (inclusive).
|
||||
.TP
|
||||
\fB--log-prefix\fR \fIstring\fR
|
||||
\fB\-\-log\-prefix\fR \fIstring\fR
|
||||
Prefix log messages with the specified prefix; up to 29 bytes long, and useful
|
||||
for distinguishing messages in the logs.
|
||||
.TP
|
||||
\fB--log-nfmark\fR
|
||||
Include the packet mark in the log.
|
||||
.TP
|
||||
\fB--log-ctmark\fR
|
||||
Include the connection mark in the log.
|
||||
.TP
|
||||
\fB--log-secmark\fR
|
||||
Include the packet secmark in the log.
|
||||
|
@@ -1,7 +1,7 @@
|
||||
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]
|
||||
\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
|
||||
|
@@ -8,7 +8,7 @@ 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]
|
||||
\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
|
||||
@@ -17,13 +17,13 @@ original address.
|
||||
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
|
||||
\-t raw \-A PREROUTING \-i lan0 \-d 212.201.100.135 \-j RAWDNAT \-\-to\-destination 199.181.132.250;
|
||||
\-t rawpost \-A POSTROUTING \-o lan0 \-s 199.181.132.250 \-j RAWSNAT \-\-to\-source 212.201.100.135;
|
||||
.PP
|
||||
Note that changing addresses may influence the route selection! Specifically,
|
||||
it statically NATs packets, not connections, like the normal DNAT/SNAT targets
|
||||
would do. Also note that it can transform already-NATed connections -- as said,
|
||||
it is completely external to Netfilter's connection tracking/NAT.
|
||||
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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
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
|
||||
an oops in a filesystem causing locks to be not released and processes to get
|
||||
stuck as a result - if still possible, use /proc/sysrq-trigger. Even when
|
||||
stuck as a result \(em if still possible, use /proc/sysrq-trigger. Even when
|
||||
processes are stuck, interrupts are likely to be still processed, and as such,
|
||||
sysrq can be triggered through incoming network packets.
|
||||
.PP
|
||||
@@ -11,30 +11,30 @@ requests. The initial sequence number comes from the time of day so you will
|
||||
have a small window of vulnerability should time go backwards at a reboot.
|
||||
However, the file /sys/module/xt_SYSREQ/seqno can be used to both query and
|
||||
update the current sequence number. Also, you should limit as to who can issue
|
||||
commands using \fB-s\fP and/or \fB-m mac\fP, and also that the destination is
|
||||
correct using \fB-d\fP (to protect against potential broadcast packets), noting
|
||||
that it is still short of MAC/IP spoofing:
|
||||
commands using \fB\-s\fP and/or \fB\-m mac\fP, and also that the destination is
|
||||
correct using \fB\-d\fP (to protect against potential broadcast packets),
|
||||
noting that it is still short of MAC/IP spoofing:
|
||||
.IP
|
||||
-A INPUT -s 10.10.25.1 -m mac --mac-source aa:bb:cc:dd:ee:ff -d 10.10.25.7
|
||||
-p udp --dport 9 -j SYSRQ
|
||||
\-A INPUT \-s 10.10.25.1 \-m mac \-\-mac\-source aa:bb:cc:dd:ee:ff \-d
|
||||
10.10.25.7 \-p udp \-\-dport 9 \-j SYSRQ
|
||||
.IP
|
||||
(with IPsec) -A INPUT -s 10.10.25.1 -d 10.10.25.7 -m policy --dir in --pol
|
||||
ipsec --proto esp --tunnel-src 10.10.25.1 --tunnel-dst 10.10.25.7
|
||||
-p udp --dport 9 -j SYSRQ
|
||||
(with IPsec) \-A INPUT \-s 10.10.25.1 \-d 10.10.25.7 \-m policy \-\-dir in
|
||||
\-\-pol ipsec \-\-proto esp \-\-tunnel\-src 10.10.25.1 \-\-tunnel\-dst
|
||||
10.10.25.7 \-p udp \-\-dport 9 \-j SYSRQ
|
||||
.PP
|
||||
You should also limit the rate at which connections can be received to limit
|
||||
the CPU time taken by illegal requests, for example:
|
||||
.IP
|
||||
-A INPUT -s 10.10.25.1 -m mac --mac-source aa:bb:cc:dd:ee:ff -d 10.10.25.7
|
||||
-p udp --dport 9 -m limit --limit 5/minute -j SYSRQ
|
||||
\-A INPUT \-s 10.10.25.1 \-m mac \-\-mac\-source aa:bb:cc:dd:ee:ff \-d
|
||||
10.10.25.7 \-p udp \-\-dport 9 \-m limit \-\-limit 5/minute \-j SYSRQ
|
||||
.PP
|
||||
This extension does not take any options. The \fB-p udp\fP options are
|
||||
This extension does not take any options. The \fB\-p udp\fP options are
|
||||
required.
|
||||
.PP
|
||||
The SYSRQ password can be changed through
|
||||
/sys/module/xt_SYSRQ/parameters/password, for example:
|
||||
.IP
|
||||
echo -n "password" >/sys/module/xt_SYSRQ/parameters/password
|
||||
echo \-n "password" >/sys/module/xt_SYSRQ/parameters/password
|
||||
.PP
|
||||
Alternatively, the password may be specified at modprobe time, but this is
|
||||
insecure as people can possible see it through ps(1). You can use an option
|
||||
@@ -59,17 +59,17 @@ sysrq_key="s" # the SysRq key(s)
|
||||
password="password"
|
||||
seqno="$(date +%s)"
|
||||
salt="$(dd bs=12 count=1 if=/dev/urandom 2>/dev/null |
|
||||
openssl enc -base64)"
|
||||
openssl enc \-base64)"
|
||||
req="$sysrq_key,$seqno,$salt"
|
||||
req="$req,$(echo -n "$req,$password" | sha1sum | cut -c1-40)"
|
||||
req="$req,$(echo \-n "$req,$password" | sha1sum | cut \-c1\-40)"
|
||||
|
||||
echo "$req" | socat stdin udp-sendto:10.10.25.7:9
|
||||
echo "$req" | socat stdin udp\-sendto:10.10.25.7:9
|
||||
# or
|
||||
echo "$req" | netcat -uw1 10.10.25.7 9
|
||||
echo "$req" | netcat \-uw1 10.10.25.7 9
|
||||
.fi
|
||||
.PP
|
||||
See the Linux docs for possible sysrq keys. Important ones are: re(b)oot,
|
||||
power(o)ff, (s)ync filesystems, (u)mount and remount readonly. More than one
|
||||
power(o)ff, (s)ync filesystems, (u)mount and remount readonly. More than one
|
||||
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.
|
||||
.PP
|
||||
|
@@ -11,16 +11,16 @@ tarpit.
|
||||
|
||||
To tarpit connections to TCP port 80 destined for the current machine:
|
||||
.IP
|
||||
-A INPUT -p tcp -m tcp --dport 80 -j TARPIT
|
||||
.P
|
||||
\-A INPUT \-p tcp \-m tcp \-\-dport 80 \-j TARPIT
|
||||
.PP
|
||||
To significantly slow down Code Red/Nimda-style scans of unused address space,
|
||||
forward unused ip addresses to a Linux box not acting as a router (e.g. "ip
|
||||
route 10.0.0.0 255.0.0.0 ip.of.linux.box" on a Cisco), enable IP forwarding on
|
||||
the Linux box, and add:
|
||||
.IP
|
||||
-A FORWARD -p tcp -j TARPIT
|
||||
\-A FORWARD \-p tcp \-j TARPIT
|
||||
.IP
|
||||
-A FORWARD -j DROP
|
||||
\-A FORWARD \-j DROP
|
||||
.PP
|
||||
NOTE:
|
||||
If you use the conntrack module while you are using TARPIT, you should also use
|
||||
@@ -28,6 +28,6 @@ the NOTRACK target, or the kernel will unnecessarily allocate resources for
|
||||
each TARPITted connection. To TARPIT incoming connections to the standard IRC
|
||||
port while using conntrack, you could:
|
||||
.IP
|
||||
-t raw -A PREROUTING -p tcp --dport 6667 -j NOTRACK
|
||||
\-t raw \-A PREROUTING \-p tcp \-\-dport 6667 \-j NOTRACK
|
||||
.IP
|
||||
-A INPUT -p tcp --dport 6667 -j TARPIT
|
||||
\-A INPUT \-p tcp \-\-dport 6667 \-j TARPIT
|
||||
|
@@ -3,6 +3,6 @@ machine on the \fBlocal\fP network segment. In other words, the nexthop
|
||||
must be the target, or you will have to configure the nexthop to forward it
|
||||
further if so desired.
|
||||
.TP
|
||||
\fB--gw\fP \fIipaddr\fP
|
||||
\fB\-\-gw\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.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
This matches if a specific condition variable is (un)set.
|
||||
.TP
|
||||
[\fB!\fP] \fB--condition\fP \fIname\fP
|
||||
[\fB!\fP] \fB\-\-condition\fP \fIname\fP
|
||||
Match on boolean value stored in /proc/net/nf_condition/\fIname\fP.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
.TP
|
||||
\fB--mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
|
||||
\fB\-\-mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
|
||||
Matches the DHCP "Client Host" address (a MAC address) in a DHCP message.
|
||||
\fImask\fP specifies the prefix length of the initial portion to match.
|
||||
|
@@ -1,7 +1,7 @@
|
||||
This module matches a rate limit based on a fuzzy logic controller (FLC).
|
||||
.TP
|
||||
\fB--lower-limit\fP \fInumber\fP
|
||||
\fB\-\-lower\-limit\fP \fInumber\fP
|
||||
Specifies the lower limit, in packets per second.
|
||||
.TP
|
||||
\fB--upper-limit\fP \fInumber\fP
|
||||
\fB\-\-upper\-limit\fP \fInumber\fP
|
||||
Specifies the upper limit, also in packets per second.
|
||||
|
@@ -1,9 +1,9 @@
|
||||
Match a packet by its source or destination country.
|
||||
.TP
|
||||
[\fB!\fP] \fB--src-cc\fP, \fB--source-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
|
||||
[\fB!\fP] \fB\-\-src\-cc\fP, \fB\-\-source\-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
|
||||
Match packet coming from (one of) the specified country(ies)
|
||||
.TP
|
||||
[\fB!\fP] \fB--dst-cc\fP, \fB--destination-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
|
||||
[\fB!\fP] \fB\-\-dst\-cc\fP, \fB\-\-destination\-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
|
||||
Match packet going to (one of) the specified country(ies)
|
||||
.TP
|
||||
NOTE:
|
||||
|
@@ -30,7 +30,7 @@ Check the MULTICAST flag.
|
||||
[\fB!\fP] \fB\-\-dynamic\fP
|
||||
Check the DYNAMIC flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-lower-up\fP
|
||||
[\fB!\fP] \fB\-\-lower\-up\fP
|
||||
Check the LOWER_UP flag.
|
||||
.TP
|
||||
[\fB!\fP] \fB\-\-dormant\fP
|
||||
|
@@ -1,41 +1,41 @@
|
||||
This module matches certain packets in P2P flows. It is not
|
||||
designed to match all packets belonging to a P2P connection -
|
||||
designed to match all packets belonging to a P2P connection \(em
|
||||
use IPP2P together with CONNMARK for this purpose.
|
||||
.PP
|
||||
Use it together with -p tcp or -p udp to search these protocols
|
||||
only or without -p switch to search packets of both protocols.
|
||||
Use it together with \-p tcp or \-p udp to search these protocols
|
||||
only or without \-p switch to search packets of both protocols.
|
||||
.PP
|
||||
IPP2P provides the following options, of which one or more may be specified
|
||||
on the command line:
|
||||
.TP
|
||||
.B "--edk "
|
||||
\fB\-\-edk\fP
|
||||
Matches as many eDonkey/eMule packets as possible.
|
||||
.TP
|
||||
.B "--kazaa "
|
||||
\fB\-\-kazaa\fP
|
||||
Matches as many KaZaA packets as possible.
|
||||
.TP
|
||||
.B "--gnu "
|
||||
\fB\-\-gnu\fP
|
||||
Matches as many Gnutella packets as possible.
|
||||
.TP
|
||||
.B "--dc "
|
||||
\fB\-\-dc\fP
|
||||
Matches as many Direct Connect packets as possible.
|
||||
.TP
|
||||
.B "--bit "
|
||||
\fB\-\-bit\fP
|
||||
Matches BitTorrent packets.
|
||||
.TP
|
||||
.B "--apple "
|
||||
\fB\-\-apple\fP
|
||||
Matches AppleJuice packets.
|
||||
.TP
|
||||
.B "--soul "
|
||||
\fB\-\-soul\fP
|
||||
Matches some SoulSeek packets. Considered as beta, use careful!
|
||||
.TP
|
||||
.B "--winmx "
|
||||
\fB\-\-winmx\fP
|
||||
Matches some WinMX packets. Considered as beta, use careful!
|
||||
.TP
|
||||
.B "--ares "
|
||||
Matches Ares and AresLite packets. Use together with -j DROP only.
|
||||
\fB\-\-ares\fP
|
||||
Matches Ares and AresLite packets. Use together with \-j DROP only.
|
||||
.TP
|
||||
.B "--debug "
|
||||
\fB\-\-debug\fP
|
||||
Prints some information about each hit into kernel logfile. May
|
||||
produce huge logfiles so beware!
|
||||
.PP
|
||||
@@ -44,5 +44,5 @@ exchanged as a result of running filesharing programs.
|
||||
.PP
|
||||
There is more information on http://ipp2p.org/ , but it has not been updated
|
||||
since September 2006, and the syntax there is different from the ipp2p.c
|
||||
provided in Xtables-addons; most importantly, the --ipp2p flag was removed due
|
||||
to its ambiguity to match "all known" protocols.
|
||||
provided in Xtables-addons; most importantly, the \-\-ipp2p flag was removed
|
||||
due to its ambiguity to match "all known" protocols.
|
||||
|
@@ -13,25 +13,25 @@ where only at least one symbol spec must be true.
|
||||
.PP
|
||||
Known symbol names (and their number):
|
||||
.PP
|
||||
1 - \fBnop\fP
|
||||
1 \(em \fBnop\fP
|
||||
.PP
|
||||
2 - \fBsecurity\fP - RFC 1108
|
||||
2 \(em \fBsecurity\fP \(em RFC 1108
|
||||
.PP
|
||||
3 - \fBlsrr\fP - Loose Source Routing, RFC 791
|
||||
3 \(em \fBlsrr\fP \(em Loose Source Routing, RFC 791
|
||||
.PP
|
||||
4 - \fBtimestamp\fP - RFC 781, 791
|
||||
4 \(em \fBtimestamp\fP \(em RFC 781, 791
|
||||
.PP
|
||||
7 - \fBrecord\-route\fP - RFC 791
|
||||
7 \(em \fBrecord\-route\fP \em RFC 791
|
||||
.PP
|
||||
9 - \fBssrr\fP - Strict Source Routing, RFC 791
|
||||
9 \(em \fBssrr\fP \(em Strict Source Routing, RFC 791
|
||||
.PP
|
||||
11 - \fBmtu\-probe\fP - RFC 1063
|
||||
11 \(em \fBmtu\-probe\fP \(em RFC 1063
|
||||
.PP
|
||||
12 - \fBmtu\-reply\fP - RFC 1063
|
||||
12 \(em \fBmtu\-reply\fP \(em RFC 1063
|
||||
.PP
|
||||
18 - \fBtraceroute\fP - RFC 1393
|
||||
18 \(em \fBtraceroute\fP \(em RFC 1393
|
||||
.PP
|
||||
20 - \fBrouter-alert\fP - RFC 2113
|
||||
20 \(em \fBrouter-alert\fP \(em RFC 2113
|
||||
.PP
|
||||
Examples:
|
||||
.PP
|
||||
|
@@ -1,18 +1,19 @@
|
||||
This module matches the length of a packet against a specific value or range of
|
||||
values.
|
||||
.TP
|
||||
[\fB!\fR] \fB--length\fR \fIlength\fR[\fB:\fR\fIlength\fR]
|
||||
[\fB!\fR] \fB\-\-length\fR \fIlength\fR[\fB:\fR\fIlength\fR]
|
||||
Match exact length or length range.
|
||||
.TP
|
||||
\fB--layer3\fR
|
||||
\fB\-\-layer3\fR
|
||||
Match the layer3 frame size (e.g. IPv4/v6 header plus payload).
|
||||
.TP
|
||||
\fB--layer4\fR
|
||||
\fB\-\-layer4\fR
|
||||
Match the layer4 frame size (e.g. TCP/UDP header plus payload).
|
||||
.TP
|
||||
\fB--layer5\fR
|
||||
\fB\-\-layer5\fR
|
||||
Match the layer5 frame size (e.g. TCP/UDP payload, often called layer7).
|
||||
.PP
|
||||
If no --layer* option is given, --layer3 is assumed by default. Note that using
|
||||
--layer5 may not match a packet if it is not one of the recognized types
|
||||
(currently TCP, UDP, UDPLite, ICMP, AH and ESP) or which has no 5th layer.
|
||||
If no \-\-layer* option is given, \-\-layer3 is assumed by default. Note that
|
||||
using \-\-layer5 may not match a packet if it is not one of the recognized
|
||||
types (currently TCP, UDP, UDPLite, ICMP, AH and ESP) or which has no 5th
|
||||
layer.
|
||||
|
@@ -6,19 +6,19 @@ out, but this information can be used in conjunction with other rules to block
|
||||
the remote host's future connections. So this match module will match on the
|
||||
(probably) last packet the remote side will send to your machine.
|
||||
.TP
|
||||
\fB--stealth\fR
|
||||
\fB\-\-stealth\fR
|
||||
Match if the packet did not belong to any known TCP connection
|
||||
(Stealth/FIN/XMAS/NULL scan).
|
||||
.TP
|
||||
\fB--synscan\fR
|
||||
\fB\-\-synscan\fR
|
||||
Match if the connection was a TCP half-open discovery (SYN scan), i.e. the
|
||||
connection was torn down after the 2nd packet in the 3-way handshake.
|
||||
.TP
|
||||
\fB--cnscan\fR
|
||||
\fB\-\-cnscan\fR
|
||||
Match if the connection was a TCP full open discovery (connect scan), i.e. the
|
||||
connection was torn down after completion of the 3-way handshake.
|
||||
.TP
|
||||
\fB--grscan\fR
|
||||
\fB\-\-grscan\fR
|
||||
Match if data in the connection only flew in the direction of the remote side,
|
||||
e.g. if the connection was terminated after a locally running daemon sent its
|
||||
identification. (E.g. openssh, smtp, ftpd.) This may falsely trigger on
|
||||
|
@@ -1,18 +1,18 @@
|
||||
Attempt to detect TCP and UDP port scans. This match was derived from
|
||||
Solar Designer's scanlogd.
|
||||
.TP
|
||||
.BI "--psd-weight-threshold " "threshold"
|
||||
\fB\-\-psd\-weight\-threshold\fP \fIthreshold\fP
|
||||
Total weight of the latest TCP/UDP packets with different
|
||||
destination ports coming from the same host to be treated as port
|
||||
scan sequence.
|
||||
.TP
|
||||
.BI "--psd-delay-threshold " "delay"
|
||||
\fB\-\-psd\-delay\-threshold\fP \fIdelay\fP
|
||||
Delay (in hundredths of second) for the packets with different
|
||||
destination ports coming from the same host to be treated as
|
||||
possible port scan subsequence.
|
||||
.TP
|
||||
.BI "--psd-lo-ports-weight " "weight"
|
||||
\fB\-\-psd\-lo\-ports\-weight\fP \fIweight\fP
|
||||
Weight of the packet with privileged (<=1024) destination port.
|
||||
.TP
|
||||
.BI "--psd-hi-ports-weight " "weight"
|
||||
\fB\-\-psd\-hi\-ports\-weight\fP \fIweight\fP
|
||||
Weight of the packet with non-priviliged destination port.
|
||||
|
@@ -7,25 +7,25 @@ When counting down from the initial quota, the counter will stop at 0 and
|
||||
the match will return false, just like the original "quota" match. In growing
|
||||
(upcounting) mode, it will always return true.
|
||||
.TP
|
||||
\fB--grow\fP
|
||||
\fB\-\-grow\fP
|
||||
Count upwards instead of downwards.
|
||||
.TP
|
||||
\fB--name\fP \fIname\fP
|
||||
\fB\-\-name\fP \fIname\fP
|
||||
Assign the counter a specific name. This option must be present, as an empty
|
||||
name is not allowed. Names starting with a dot or names containing a slash are
|
||||
prohibited.
|
||||
.TP
|
||||
[\fB!\fP] \fB--quota\fP \fIiq\fP
|
||||
[\fB!\fP] \fB\-\-quota\fP \fIiq\fP
|
||||
Specify the initial quota for this counter. If the counter already exists,
|
||||
it is not reset. An "!" may be used to invert the result of the match. The
|
||||
negation has no effect when \fB--grow\fP is used.
|
||||
negation has no effect when \fB\-\-grow\fP is used.
|
||||
.TP
|
||||
\fB--packets\fP
|
||||
\fB\-\-packets\fP
|
||||
Count packets instead of bytes that passed the quota2 match.
|
||||
.PP
|
||||
Because counters in quota2 can be shared, you can combine them for various
|
||||
purposes, for example, a bytebucket filter that only lets as much traffic go
|
||||
out as has come in:
|
||||
.PP
|
||||
-A INPUT -p tcp --dport 6881 -m quota --name bt --grow
|
||||
-A OUTPUT -p tcp --sport 6881 -m quota --name bt
|
||||
\-A INPUT \-p tcp \-\-dport 6881 \-m quota \-\-name bt \-\-grow;
|
||||
\-A OUTPUT \-p tcp \-\-sport 6881 \-m quota \-\-name bt;
|
||||
|
1
extensions/pknock/.gitignore
vendored
Normal file
1
extensions/pknock/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/pknlusr
|
5
extensions/pknock/Kbuild
Normal file
5
extensions/pknock/Kbuild
Normal file
@@ -0,0 +1,5 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
EXTRA_CFLAGS = -I${src}/..
|
||||
|
||||
obj-m += xt_pknock.o
|
5
extensions/pknock/Makefile.am
Normal file
5
extensions/pknock/Makefile.am
Normal file
@@ -0,0 +1,5 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
include ../../Makefile.extra
|
||||
|
||||
noinst_PROGRAMS = pknlusr
|
3
extensions/pknock/Mbuild
Normal file
3
extensions/pknock/Mbuild
Normal file
@@ -0,0 +1,3 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
obj-${build_pknock} += libxt_pknock.so
|
343
extensions/pknock/libxt_pknock.c
Normal file
343
extensions/pknock/libxt_pknock.c
Normal file
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
* Shared library add-on to iptables to add Port Knocking and SPA matching
|
||||
* support.
|
||||
*
|
||||
* (C) 2006-2009 J. Federico Hernandez <fede.hernandez@gmail.com>
|
||||
* (C) 2006 Luis Floreani <luis.floreani@gmail.com>
|
||||
*
|
||||
* This program is released under the terms of GNU GPL version 2.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include "xt_pknock.h"
|
||||
|
||||
static const struct option pknock_mt_opts[] = {
|
||||
/* .name, .has_arg, .flag, .val */
|
||||
{.name = "knockports", .has_arg = true, .val = 'k'},
|
||||
{.name = "time", .has_arg = true, .val = 't'},
|
||||
{.name = "autoclose", .has_arg = true, .val = 'a'},
|
||||
{.name = "name", .has_arg = true, .val = 'n'},
|
||||
{.name = "opensecret", .has_arg = true, .val = 'o'},
|
||||
{.name = "closesecret", .has_arg = true, .val = 'z'},
|
||||
{.name = "strict", .has_arg = false, .val = 'x'},
|
||||
{.name = "checkip", .has_arg = false, .val = 'c'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void pknock_mt_help(void)
|
||||
{
|
||||
printf("pknock match options:\n"
|
||||
" --knockports port[,port,port,...] "
|
||||
"Matches destination port(s).\n"
|
||||
" --time seconds\n"
|
||||
"Max allowed time between knocks.\n"
|
||||
" --autoclose minutes\n"
|
||||
"Time after which to automatically close opened\n"
|
||||
"\t\t\t\t\tport(s).\n"
|
||||
" --strict "
|
||||
"Knocks sequence must be exact.\n"
|
||||
" --name rule_name "
|
||||
"Rule name.\n"
|
||||
" --checkip "
|
||||
"Matches if the source ip is in the list.\n"
|
||||
);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
parse_ports(const char *portstring, uint16_t *ports, const char *proto)
|
||||
{
|
||||
char *buffer, *cp, *next;
|
||||
unsigned int i;
|
||||
|
||||
buffer = strdup(portstring);
|
||||
if (buffer == NULL)
|
||||
xtables_error(OTHER_PROBLEM, "strdup failed");
|
||||
|
||||
for (cp = buffer, i = 0; cp != NULL && i < XT_PKNOCK_MAX_PORTS; cp = next, ++i)
|
||||
{
|
||||
next=strchr(cp, ',');
|
||||
if (next != NULL)
|
||||
*next++ = '\0';
|
||||
ports[i] = xtables_parse_port(cp, proto);
|
||||
}
|
||||
|
||||
if (cp != NULL)
|
||||
xtables_error(PARAMETER_PROBLEM, "too many ports specified");
|
||||
|
||||
free(buffer);
|
||||
return i;
|
||||
}
|
||||
|
||||
static char *
|
||||
proto_to_name(uint8_t proto)
|
||||
{
|
||||
switch (proto) {
|
||||
case IPPROTO_TCP:
|
||||
return "tcp";
|
||||
case IPPROTO_UDP:
|
||||
return "udp";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
check_proto(uint16_t pnum, uint8_t invflags)
|
||||
{
|
||||
char *proto;
|
||||
|
||||
if (invflags & XT_INV_PROTO)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK "only works with TCP and UDP.");
|
||||
|
||||
if ((proto = proto_to_name(pnum)) != NULL)
|
||||
return proto;
|
||||
else if (pnum == 0)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK "needs `-p tcp' or `-p udp'");
|
||||
else
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK "only works with TCP and UDP.");
|
||||
}
|
||||
|
||||
static int
|
||||
__pknock_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
struct xt_entry_match **match, uint16_t pnum,
|
||||
uint16_t invflags)
|
||||
{
|
||||
const char *proto;
|
||||
struct xt_pknock_mtinfo *info = (void *)(*match)->data;
|
||||
unsigned int tmp;
|
||||
|
||||
switch (c) {
|
||||
case 'k': /* --knockports */
|
||||
if (*flags & XT_PKNOCK_KNOCKPORT)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot use --knockports twice.\n");
|
||||
proto = check_proto(pnum, invflags);
|
||||
|
||||
info->ports_count = parse_ports(optarg, info->port, proto);
|
||||
info->option |= XT_PKNOCK_KNOCKPORT;
|
||||
*flags |= XT_PKNOCK_KNOCKPORT;
|
||||
#if DEBUG
|
||||
printf("ports_count: %d\n", info->ports_count);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 't': /* --time */
|
||||
if (*flags & XT_PKNOCK_TIME)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot use --time twice.\n");
|
||||
info->max_time = atoi(optarg);
|
||||
if (info->max_time == 0)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"--time number must be > 0.\n");
|
||||
info->option |= XT_PKNOCK_TIME;
|
||||
*flags |= XT_PKNOCK_TIME;
|
||||
break;
|
||||
|
||||
case 'a': /* --autoclose */
|
||||
if (*flags & XT_PKNOCK_AUTOCLOSE)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot use --autoclose twice.\n");
|
||||
if (!xtables_strtoui(optarg, NULL, &tmp, 0, ~0U))
|
||||
xtables_param_act(XTF_BAD_VALUE, PKNOCK,
|
||||
"--autoclose", optarg);
|
||||
info->autoclose_time = tmp;
|
||||
info->option |= XT_PKNOCK_AUTOCLOSE;
|
||||
*flags |= XT_PKNOCK_AUTOCLOSE;
|
||||
break;
|
||||
|
||||
case 'n': /* --name */
|
||||
if (*flags & XT_PKNOCK_NAME)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot use --name twice.\n");
|
||||
memset(info->rule_name, 0, sizeof(info->rule_name));
|
||||
strncpy(info->rule_name, optarg, sizeof(info->rule_name) - 1);
|
||||
|
||||
info->rule_name_len = strlen(info->rule_name);
|
||||
info->option |= XT_PKNOCK_NAME;
|
||||
*flags |= XT_PKNOCK_NAME;
|
||||
#if DEBUG
|
||||
printf("info->rule_name: %s\n", info->rule_name);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'o': /* --opensecret */
|
||||
if (*flags & XT_PKNOCK_OPENSECRET)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot use --opensecret twice.\n");
|
||||
memset(info->open_secret, 0, sizeof(info->open_secret));
|
||||
strncpy(info->open_secret, optarg, sizeof(info->open_secret) - 1);
|
||||
|
||||
info->open_secret_len = strlen(info->open_secret);
|
||||
info->option |= XT_PKNOCK_OPENSECRET;
|
||||
*flags |= XT_PKNOCK_OPENSECRET;
|
||||
break;
|
||||
|
||||
case 'z': /* --closesecret */
|
||||
if (*flags & XT_PKNOCK_CLOSESECRET)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot use --closesecret twice.\n");
|
||||
memset(info->close_secret, 0, sizeof(info->close_secret));
|
||||
strncpy(info->close_secret, optarg, sizeof(info->close_secret) - 1);
|
||||
|
||||
info->close_secret_len = strlen(info->close_secret);
|
||||
info->option |= XT_PKNOCK_CLOSESECRET;
|
||||
*flags |= XT_PKNOCK_CLOSESECRET;
|
||||
break;
|
||||
|
||||
case 'c': /* --checkip */
|
||||
if (*flags & XT_PKNOCK_CHECKIP)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot use --checkip twice.\n");
|
||||
info->option |= XT_PKNOCK_CHECKIP;
|
||||
*flags |= XT_PKNOCK_CHECKIP;
|
||||
break;
|
||||
|
||||
case 'x': /* --strict */
|
||||
if (*flags & XT_PKNOCK_STRICT)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot use --strict twice.\n");
|
||||
info->option |= XT_PKNOCK_STRICT;
|
||||
*flags |= XT_PKNOCK_STRICT;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (invert)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK "does not support invert.");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pknock_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *e, struct xt_entry_match **match)
|
||||
{
|
||||
const struct ipt_entry *entry = e;
|
||||
return __pknock_parse(c, argv, invert, flags, match,
|
||||
entry->ip.proto, entry->ip.invflags);
|
||||
}
|
||||
|
||||
static void pknock_mt_check(unsigned int flags)
|
||||
{
|
||||
if (!(flags & XT_PKNOCK_NAME))
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"--name option is required.\n");
|
||||
|
||||
if (flags & XT_PKNOCK_KNOCKPORT) {
|
||||
if (flags & XT_PKNOCK_CHECKIP)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot specify --knockports with --checkip.\n");
|
||||
if ((flags & XT_PKNOCK_OPENSECRET)
|
||||
&& !(flags & XT_PKNOCK_CLOSESECRET))
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"--opensecret must go with --closesecret.\n");
|
||||
if ((flags & XT_PKNOCK_CLOSESECRET)
|
||||
&& !(flags & XT_PKNOCK_OPENSECRET))
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"--closesecret must go with --opensecret.\n");
|
||||
}
|
||||
|
||||
if (flags & XT_PKNOCK_CHECKIP) {
|
||||
if (flags & XT_PKNOCK_KNOCKPORT)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot specify --checkip with --knockports.\n");
|
||||
if ((flags & XT_PKNOCK_OPENSECRET)
|
||||
|| (flags & XT_PKNOCK_CLOSESECRET))
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot specify --opensecret and"
|
||||
" --closesecret with --checkip.\n");
|
||||
if (flags & XT_PKNOCK_TIME)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot specify --time with --checkip.\n");
|
||||
if (flags & XT_PKNOCK_AUTOCLOSE)
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"cannot specify --autoclose with --checkip.\n");
|
||||
} else if (!(flags & (XT_PKNOCK_OPENSECRET | XT_PKNOCK_TIME))) {
|
||||
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||
"you must specify --time.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void pknock_mt_print(const void *ip,
|
||||
const struct xt_entry_match *match, int numeric)
|
||||
{
|
||||
const struct xt_pknock_mtinfo *info = (void *)match->data;
|
||||
int i;
|
||||
|
||||
printf("pknock ");
|
||||
if (info->option & XT_PKNOCK_KNOCKPORT) {
|
||||
printf("knockports ");
|
||||
for (i = 0; i < info->ports_count; ++i)
|
||||
printf("%s%d", i ? "," : "", info->port[i]);
|
||||
printf(" ");
|
||||
}
|
||||
if (info->option & XT_PKNOCK_TIME)
|
||||
printf("time %ld ", (long)info->max_time);
|
||||
if (info->option & XT_PKNOCK_AUTOCLOSE)
|
||||
printf("autoclose %lu ", (unsigned long)info->autoclose_time);
|
||||
if (info->option & XT_PKNOCK_NAME)
|
||||
printf("name %s ", info->rule_name);
|
||||
if (info->option & XT_PKNOCK_OPENSECRET)
|
||||
printf("opensecret ");
|
||||
if (info->option & XT_PKNOCK_CLOSESECRET)
|
||||
printf("closesecret ");
|
||||
if (info->option & XT_PKNOCK_STRICT)
|
||||
printf("strict ");
|
||||
if (info->option & XT_PKNOCK_CHECKIP)
|
||||
printf("checkip ");
|
||||
}
|
||||
|
||||
static void pknock_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
int i;
|
||||
const struct xt_pknock_mtinfo *info = (void *)match->data;
|
||||
|
||||
if (info->option & XT_PKNOCK_KNOCKPORT) {
|
||||
printf("--knockports ");
|
||||
for (i = 0; i < info->ports_count; ++i)
|
||||
printf("%s%d", i ? "," : "", info->port[i]);
|
||||
printf(" ");
|
||||
}
|
||||
if (info->option & XT_PKNOCK_TIME)
|
||||
printf("--time %ld ", (long)info->max_time);
|
||||
if (info->option & XT_PKNOCK_AUTOCLOSE)
|
||||
printf("--autoclose %lu ",
|
||||
(unsigned long)info->autoclose_time);
|
||||
if (info->option & XT_PKNOCK_NAME)
|
||||
printf("--name %s ", info->rule_name);
|
||||
if (info->option & XT_PKNOCK_OPENSECRET)
|
||||
printf("--opensecret ");
|
||||
if (info->option & XT_PKNOCK_CLOSESECRET)
|
||||
printf("--closesecret ");
|
||||
if (info->option & XT_PKNOCK_STRICT)
|
||||
printf("--strict ");
|
||||
if (info->option & XT_PKNOCK_CHECKIP)
|
||||
printf("--checkip ");
|
||||
}
|
||||
|
||||
static struct xtables_match pknock_mt_reg = {
|
||||
.name = "pknock",
|
||||
.version = XTABLES_VERSION,
|
||||
.revision = 1,
|
||||
.family = AF_INET,
|
||||
.size = XT_ALIGN(sizeof(struct xt_pknock_mtinfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_pknock_mtinfo)),
|
||||
.help = pknock_mt_help,
|
||||
.parse = pknock_mt_parse,
|
||||
.final_check = pknock_mt_check,
|
||||
.print = pknock_mt_print,
|
||||
.save = pknock_mt_save,
|
||||
.extra_opts = pknock_mt_opts,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void pknock_mt_ldr(void)
|
||||
{
|
||||
xtables_register_match(&pknock_mt_reg);
|
||||
}
|
113
extensions/pknock/libxt_pknock.man
Normal file
113
extensions/pknock/libxt_pknock.man
Normal file
@@ -0,0 +1,113 @@
|
||||
Pknock match implements so-called "port knocking", a stealthy system
|
||||
for network authentication: a client sends packets to selected
|
||||
ports in a specific sequence (= simple mode, see example 1 below), or a HMAC
|
||||
payload to a single port (= complex mode, see example 2 below),
|
||||
to a target machine that has pknock rule(s) installed. The target machine
|
||||
then decides whether to unblock or block (again) the pknock-protected port(s).
|
||||
This can be used, for instance, to avoid brute force
|
||||
attacks on ssh or ftp services.
|
||||
.PP
|
||||
Example prerequisites:
|
||||
.IP
|
||||
modprobe cn
|
||||
.IP
|
||||
modprobe xt_pknock
|
||||
.PP
|
||||
Example 1 (TCP mode, manual closing of opened port not possible):
|
||||
.IP
|
||||
iptables -P INPUT DROP
|
||||
.IP
|
||||
iptables -A INPUT -p tcp -m pknock --knockports 4002,4001,4004 --strict
|
||||
--name SSH --time 10 --autoclose 60 --dport 22 -j ACCEPT
|
||||
.PP
|
||||
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).
|
||||
Port numbers in the connect sequence must follow the exact specification, no
|
||||
other ports may be "knocked" inbetween. The rule is named '\fBSSH\fP' \(em a file of
|
||||
the same name for tracking port knocking states will be created in
|
||||
\fB/proc/net/xt_pknock\fP .
|
||||
Successive port knocks must occur with delay of at most 10 seconds. Port 22 (from the example) will
|
||||
be automatiaclly dropped after 60 minutes after it was previously allowed.
|
||||
.PP
|
||||
Example 2 (UDP mode \(em non-replayable and non-spoofable, manual closing
|
||||
of opened port possible, secure, also called "SPA" = Secure Port
|
||||
Authorization):
|
||||
.IP
|
||||
iptables -A INPUT -p udp -m pknock --knockports 4000 --name FTP
|
||||
--opensecret foo --closesecret bar --autoclose 240 -j DROP
|
||||
.IP
|
||||
iptables -A INPUT -p tcp -m pknock --checkip --name FTP --dport 21 -j ACCEPT
|
||||
.PP
|
||||
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
|
||||
constructed as a HMAC256 using "foo" as a key. The HMAC content is the particular client's IP address as a 32-bit network byteorder quantity,
|
||||
plus the number of minutes since the Unix epoch, also as a 32-bit value.
|
||||
(This is known as Simple Packet Authorization, also called "SPA".)
|
||||
In such case, any subsequent attempt to connect to port 21 from the client's IP
|
||||
address will cause such packets to be accepted in the second rule.
|
||||
.PP
|
||||
Similarly, upon reception of an UDP packet constructed the same way, but with
|
||||
the key "bar", the first rule will remove a previously installed "ALLOWED" state
|
||||
record from /proc/net/xt_pknock/FTP, which means that the second rule will
|
||||
stop matching for subsequent connection attempts to port 21.
|
||||
In case no close-secret packet is received within 4 hours, the first rule
|
||||
will remove "ALLOWED" record from /proc/net/xt_pknock/FTP itself.
|
||||
.PP
|
||||
Things worth noting:
|
||||
.PP
|
||||
\fBGeneral\fP:
|
||||
.PP
|
||||
Specifying \fB--autoclose 0\fP means that no automatic close will be performed at all.
|
||||
.PP
|
||||
xt_pknock is capable of sending information about successful matches
|
||||
via a netlink socket to userspace, should you need to implement your own
|
||||
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
|
||||
\fBTCP mode\fP:
|
||||
.PP
|
||||
This mode is not immune against eavesdropping, spoofing and
|
||||
replaying of the port knock sequence by someone else (but its use may still
|
||||
be sufficient for scenarios where these factors are not necessarily
|
||||
this important, such as bare shielding of the SSH port from brute-force attacks).
|
||||
However, if you need these features, you should use UDP mode.
|
||||
.PP
|
||||
It is always wise to specify three or more ports that are not monotonically
|
||||
increasing or decreasing with a small stepsize (e.g. 1024,1025,1026)
|
||||
to avoid accidentally triggering
|
||||
the rule by a portscan.
|
||||
.PP
|
||||
Specifying the inter-knock timeout with \fB--time\fP is mandatory in TCP mode,
|
||||
to avoid permanent denial of services by clogging up the peer knock-state tracking table
|
||||
that xt_pknock internally keeps, should there be a DDoS on the
|
||||
first-in-row knock port from more hostile IP addresses than what the actual size
|
||||
of this table is (defaults to 16, can be changed via the "peer_hasht_ents" module parameter).
|
||||
It is also wise to use as short a time as possible (1 second) for \fB--time\fP
|
||||
for this very reason. You may also consider increasing the size
|
||||
of the peer knock-state tracking table. Using \fB--strict\fP also helps,
|
||||
as it requires the knock sequence to be exact. This means that if the
|
||||
hostile client sends more knocks to the same port, xt_pknock will
|
||||
mark such attempt as failed knock sequence and will forget it immediately.
|
||||
To completely thwart this kind of DDoS, knock-ports would need to have
|
||||
an additional rate-limit protection. Or you may consider using UDP mode.
|
||||
.PP
|
||||
\fBUDP mode\fP:
|
||||
.PP
|
||||
This mode is immune against eavesdropping, replaying and spoofing attacks.
|
||||
It is also immune against DDoS attack on the knockport.
|
||||
.PP
|
||||
For this mode to work, the clock difference on the client and on the server
|
||||
must be below 1 minute. Synchronizing time on both ends by means
|
||||
of NTP or rdate is strongly suggested.
|
||||
.PP
|
||||
There is a rate limiter built into xt_pknock which blocks any subsequent
|
||||
open attempt in UDP mode should the request arrive within less than one
|
||||
minute since the first successful open. This is intentional;
|
||||
it thwarts eventual spoofing attacks.
|
||||
.PP
|
||||
Because the payload value of an UDP knock packet is influenced by client's IP address,
|
||||
UDP mode cannot be used across NAT.
|
||||
.PP
|
||||
For sending UDP "SPA" packets, you may use either \fBknock.sh\fP or
|
||||
\fBknock-orig.sh\fP. These may be found in doc/pknock/util.
|
93
extensions/pknock/pknlusr.c
Normal file
93
extensions/pknock/pknlusr.c
Normal file
@@ -0,0 +1,93 @@
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/connector.h>
|
||||
|
||||
#include "xt_pknock.h"
|
||||
|
||||
#define GROUP 1
|
||||
|
||||
static struct sockaddr_nl src_addr, dest_addr;
|
||||
static struct msghdr msg;
|
||||
static int sock_fd;
|
||||
|
||||
static unsigned char *buf;
|
||||
|
||||
static struct xt_pknock_nl_msg *nlmsg;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
socklen_t addrlen;
|
||||
int status;
|
||||
int group = GROUP;
|
||||
struct cn_msg *cnmsg;
|
||||
|
||||
int i, buf_size;
|
||||
|
||||
const char *ip;
|
||||
char ipbuf[48];
|
||||
|
||||
sock_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
|
||||
|
||||
if (sock_fd == -1) {
|
||||
perror("socket()");
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(&src_addr, 0, sizeof(src_addr));
|
||||
src_addr.nl_family = AF_NETLINK;
|
||||
src_addr.nl_pid = getpid();
|
||||
src_addr.nl_groups = group;
|
||||
|
||||
status = bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr));
|
||||
|
||||
if (status == -1) {
|
||||
close(sock_fd);
|
||||
perror("bind()");
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(&dest_addr, 0, sizeof(dest_addr));
|
||||
dest_addr.nl_family = AF_NETLINK;
|
||||
dest_addr.nl_pid = 0;
|
||||
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()");
|
||||
return 1;
|
||||
}
|
||||
|
||||
addrlen = sizeof(dest_addr);
|
||||
|
||||
while(1) {
|
||||
|
||||
memset(buf, 0, buf_size);
|
||||
|
||||
status = recvfrom(sock_fd, buf, buf_size, 0, (struct sockaddr *)&dest_addr, &addrlen);
|
||||
|
||||
if (status <= 0) {
|
||||
perror("recvfrom()");
|
||||
return 1;
|
||||
}
|
||||
|
||||
nlmsg = (struct xt_pknock_nl_msg *) (buf + sizeof(struct cn_msg) + sizeof(struct nlmsghdr));
|
||||
|
||||
ip = inet_ntop(AF_INET, &nlmsg->peer_ip, ipbuf, sizeof(ipbuf));
|
||||
printf("rule_name: %s - ip %s\n", nlmsg->rule_name, ip);
|
||||
|
||||
}
|
||||
|
||||
close(sock_fd);
|
||||
|
||||
free(buf);
|
||||
|
||||
return 0;
|
||||
}
|
13
extensions/pknock/xt_pknock.Kconfig
Normal file
13
extensions/pknock/xt_pknock.Kconfig
Normal file
@@ -0,0 +1,13 @@
|
||||
config NETFILTER_XT_MATCH_PKNOCK
|
||||
tristate "Port knocking match support"
|
||||
depends on NETFILTER_XTABLES && CONNECTOR
|
||||
---help---
|
||||
pknock match implements so-called Port Knocking, a stealthy system
|
||||
for network authentication: client sends packets to selected, closed
|
||||
ports on target machine in a specific sequence. The target machine
|
||||
(which has pknock match rule set up) then decides whether to
|
||||
unblock or block (again) its protected port with listening
|
||||
service. This can be, for instance, used to avoid brute force attacks
|
||||
on ssh or ftp services.
|
||||
|
||||
For more informations go to: http://portknocko.berlios.de/
|
1202
extensions/pknock/xt_pknock.c
Normal file
1202
extensions/pknock/xt_pknock.c
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user