mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-20 19:44:56 +02:00
Compare commits
40 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
463dceb709 | ||
![]() |
cd323565d7 | ||
![]() |
a39bfdf98e | ||
![]() |
cd7c8fc4fa | ||
![]() |
5d431b45f1 | ||
![]() |
f4c4208e75 | ||
![]() |
52a0ed7f15 | ||
![]() |
000d813171 | ||
![]() |
e45cb21ad6 | ||
![]() |
7aae90da5a | ||
![]() |
fd5321c7d8 | ||
![]() |
65eeb7f1f6 | ||
![]() |
848484c08c | ||
![]() |
8c58a61f52 | ||
![]() |
93c7d0ac47 | ||
![]() |
df063ab61c | ||
![]() |
d480ea2b1f | ||
![]() |
205a006ac9 | ||
![]() |
9f45aa737a | ||
![]() |
f1615a03f3 | ||
![]() |
3554e348bc | ||
![]() |
5fd97e9973 | ||
![]() |
10e3d8fe0d | ||
![]() |
6c06796e3b | ||
![]() |
98f943cb6c | ||
![]() |
cedbb110e1 | ||
![]() |
c703be229a | ||
![]() |
c338e8f827 | ||
![]() |
7c09f5db2f | ||
![]() |
6177839a04 | ||
![]() |
4d22fbd97a | ||
![]() |
dd42c61581 | ||
![]() |
2fbfbe6cd4 | ||
![]() |
ec9663f680 | ||
![]() |
75e88a7321 | ||
![]() |
1e34f02034 | ||
![]() |
b69d3de40e | ||
![]() |
c1592673fb | ||
![]() |
da011c8871 | ||
![]() |
f360ec3c85 |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,16 +1,13 @@
|
||||
.*.cmd
|
||||
*.ko
|
||||
*.la
|
||||
*.lo
|
||||
*.loT
|
||||
*.mod.c
|
||||
*.o
|
||||
.deps
|
||||
.libs
|
||||
.tmp_versions
|
||||
Makefile
|
||||
Makefile.in
|
||||
Module.symvers
|
||||
|
||||
/downloads
|
||||
|
||||
/aclocal.m4
|
||||
/autom4te*.cache
|
||||
|
11
INSTALL
11
INSTALL
@@ -12,9 +12,16 @@ in combination with the kernel's Kbuild system.
|
||||
Prerequirements
|
||||
===============
|
||||
|
||||
* xtables(-devel) 1.5.0
|
||||
* xtables(-devel) 1.5.2
|
||||
|
||||
* kernel-source >= 2.6.19 with prepared output directory
|
||||
* kernel-source >= 2.6.18 with prepared build/output directory
|
||||
|
||||
|
||||
Selecting extensions
|
||||
====================
|
||||
|
||||
You can edit the "mconfig" file to select what modules to build and
|
||||
install. By default, all modules are enabled.
|
||||
|
||||
|
||||
Configuring and compiling
|
||||
|
@@ -2,3 +2,11 @@
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||
SUBDIRS = extensions
|
||||
|
||||
.PHONY: tarball
|
||||
tarball:
|
||||
rm -Rf /tmp/xtables-addons-${PACKAGE_VERSION};
|
||||
pushd ${top_srcdir} && git-archive --prefix=xtables-addons-${PACKAGE_VERSION}/ HEAD | tar -C /tmp -x && popd;
|
||||
pushd /tmp/xtables-addons-${PACKAGE_VERSION} && ./autogen.sh && popd;
|
||||
tar -C /tmp -cjf xtables-addons-${PACKAGE_VERSION}.tar.bz2 --owner=root --group=root xtables-addons-${PACKAGE_VERSION}/;
|
||||
rm -Rf /tmp/xtables-addons-${PACKAGE_VERSION};
|
||||
|
29
README
29
README
@@ -8,3 +8,32 @@ package.
|
||||
Xtables-addons is different from patch-o-matic in that you do not have
|
||||
to patch or recompile either kernel or Xtables(iptables). But please
|
||||
see the INSTALL file for the minimum requirements of this package.
|
||||
|
||||
|
||||
External extensions
|
||||
===================
|
||||
|
||||
The program "xa-download-more" can be used to download more extensions
|
||||
from 3rd parties into the source tree. The URLs are listed in the
|
||||
"sources" file. If the "sources" file contains an entry like
|
||||
|
||||
http://foobar.org/xa/
|
||||
|
||||
xa-download-more will inspect http://foobar.org/xa/xa-index.txt for files
|
||||
to download. That file may contain
|
||||
|
||||
foobar.tar.bz2
|
||||
|
||||
and xa-download-more will then retrieve and unpack
|
||||
http://foobar.org/xa/foobar.tar.bz2.
|
||||
|
||||
Files that should be contained in the tarball are an mconfig and Kbuild
|
||||
files to control building the extension, libxt_foobar.c for the userspace
|
||||
extension and xt_foobar.c for the kernel extension.
|
||||
|
||||
mconfig.foobar
|
||||
extensions/Kbuild.foobar
|
||||
extensions/libxt_foobar.c
|
||||
extensions/libxt_foobar.man
|
||||
extensions/xt_foobar.c
|
||||
extensions/xt_foobar.h
|
||||
|
16
configure.ac
16
configure.ac
@@ -1,5 +1,5 @@
|
||||
|
||||
AC_INIT([xtables-addons], [1.5.0])
|
||||
AC_INIT([xtables-addons], [1.5.3])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_PROG_INSTALL
|
||||
AM_INIT_AUTOMAKE
|
||||
@@ -9,7 +9,6 @@ AC_DISABLE_STATIC
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
kbuilddir="/lib/modules/$(uname -r)/build";
|
||||
ksourcedir="/lib/modules/$(uname -r)/source";
|
||||
AC_ARG_WITH([kbuild],
|
||||
AS_HELP_STRING([--with-kbuild=PATH],
|
||||
[Path to kernel build directory [[/lib/modules/CURRENT/build]]]),
|
||||
@@ -51,12 +50,17 @@ fi;
|
||||
regular_CFLAGS="-D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 \
|
||||
-D_REENTRANT -Wall -Waggregate-return -Wmissing-declarations \
|
||||
-Wmissing-prototypes -Wredundant-decls -Wshadow -Wstrict-prototypes \
|
||||
-Winline -pipe -DIPTABLES_VERSION=\\\"$PACKAGE_VERSION\\\" \
|
||||
-DXTABLES_LIBDIR=\\\"\${xtlibdir}\\\"";
|
||||
kinclude_CFLAGS="-I $kbuilddir/include -I $ksourcedir/include";
|
||||
-Winline -pipe -DXTABLES_LIBDIR=\\\"\${xtlibdir}\\\"";
|
||||
kinclude_CFLAGS="";
|
||||
if [[ -n "$kbuilddir" ]]; then
|
||||
kinclude_CFLAGS="$kinclude_CFLAGS -I $kbuilddir/include";
|
||||
fi;
|
||||
if [[ -n "$ksourcedir" ]]; then
|
||||
kinclude_CFLAGS="$kinclude_CFLAGS -I $ksourcedir/include";
|
||||
fi;
|
||||
|
||||
AC_SUBST([regular_CFLAGS xtables_CFLAGS kinclude_CFLAGS])
|
||||
AC_SUBST([kbuilddir])
|
||||
AC_SUBST([ksourcedir])
|
||||
AC_SUBST([xtlibdir])
|
||||
AC_OUTPUT([Makefile extensions/Makefile])
|
||||
AC_OUTPUT([Makefile extensions/GNUmakefile])
|
||||
|
10
extensions/.gitignore
vendored
Normal file
10
extensions/.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
.*.cmd
|
||||
.*.d
|
||||
.tmp_versions
|
||||
*.ko
|
||||
*.mod.c
|
||||
*.so
|
||||
*.oo
|
||||
GNUmakefile
|
||||
Module.symvers
|
||||
modules.order
|
100
extensions/GNUmakefile.in
Normal file
100
extensions/GNUmakefile.in
Normal file
@@ -0,0 +1,100 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
top_srcdir := @top_srcdir@
|
||||
srcdir := @srcdir@
|
||||
abstop_srcdir := $(shell readlink -e ${top_srcdir})
|
||||
abssrcdir := $(shell readlink -e ${srcdir})
|
||||
|
||||
ifeq (${abstop_srcdir},)
|
||||
$(error Path resolution of ${top_srcdir} failed)
|
||||
endif
|
||||
ifeq (${abssrcdir},)
|
||||
$(error Path resolution of ${srcdir} failed)
|
||||
endif
|
||||
|
||||
prefix := @prefix@
|
||||
exec_prefix := @exec_prefix@
|
||||
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,$@
|
||||
|
||||
ifeq (${V},)
|
||||
AM_LIBTOOL_SILENT = --silent
|
||||
AM_VERBOSE_CC = @echo " CC " $@;
|
||||
AM_VERBOSE_CCLD = @echo " CCLD " $@;
|
||||
AM_VERBOSE_CXX = @echo " CXX " $@;
|
||||
AM_VERBOSE_CXXLD = @echo " CXXLD " $@;
|
||||
AM_VERBOSE_AR = @echo " AR " $@;
|
||||
AM_VERBOSE_GEN = @echo " GEN " $@;
|
||||
endif
|
||||
|
||||
#
|
||||
# Wildcard module list
|
||||
#
|
||||
include ${top_srcdir}/mconfig
|
||||
-include ${top_srcdir}/mconfig.*
|
||||
pfx_all_mod := $(patsubst ${srcdir}/libxt_%.c,%,$(wildcard ${srcdir}/libxt_*.c))
|
||||
pfx_build_mod := $(foreach i,${pfx_all_mod},$(if ${build_${i}},${i},))
|
||||
pfx_solibs := $(patsubst %,libxt_%.so,${pfx_build_mod})
|
||||
|
||||
|
||||
#
|
||||
# Building blocks
|
||||
#
|
||||
targets := ${pfx_solibs}
|
||||
targets_install := ${pfx_solibs}
|
||||
|
||||
.SECONDARY:
|
||||
|
||||
.PHONY: all install clean distclean FORCE
|
||||
|
||||
all: modules ${targets}
|
||||
|
||||
install: modules_install ${targets_install}
|
||||
@mkdir -p "${DESTDIR}${xtlibdir}";
|
||||
install -pm0755 ${targets_install} "${DESTDIR}${xtlibdir}/";
|
||||
|
||||
clean: clean_modules
|
||||
rm -f *.oo *.so;
|
||||
|
||||
distclean: clean
|
||||
rm -f .*.d;
|
||||
|
||||
-include .*.d
|
||||
|
||||
|
||||
#
|
||||
# Call out to kbuild
|
||||
#
|
||||
.PHONY: modules modules_install clean_modules
|
||||
|
||||
modules:
|
||||
make -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} modules;
|
||||
|
||||
modules_install:
|
||||
make -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} INSTALL_MOD_PATH=${DESTDIR} modules_install;
|
||||
|
||||
clean_modules:
|
||||
make -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} clean;
|
||||
|
||||
|
||||
#
|
||||
# Shared libraries
|
||||
#
|
||||
lib%.so: lib%.oo
|
||||
${AM_VERBOSE_CCLD} ${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
|
||||
|
||||
lib%.oo: ${srcdir}/lib%.c
|
||||
${AM_VERBOSE_CC} ${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=lib$*_init -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
|
@@ -1,6 +1,17 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
obj-m += xt_LOGMARK.o
|
||||
obj-m += xt_TARPIT.o
|
||||
obj-m += xt_TEE.o
|
||||
obj-m += compat_xtables.o
|
||||
include ${XA_TOPSRCDIR}/mconfig
|
||||
-include ${XA_TOPSRCDIR}/mconfig.*
|
||||
|
||||
obj-m += compat_xtables.o
|
||||
|
||||
obj-${build_CHAOS} += xt_CHAOS.o
|
||||
obj-${build_DELUDE} += xt_DELUDE.o
|
||||
obj-${build_ECHO} += xt_ECHO.o
|
||||
obj-${build_LOGMARK} += xt_LOGMARK.o
|
||||
obj-${build_TARPIT} += xt_TARPIT.o
|
||||
obj-${build_TEE} += xt_TEE.o
|
||||
obj-${build_geoip} += xt_geoip.o
|
||||
obj-${build_portscan} += xt_portscan.o
|
||||
|
||||
-include ${M}/*.Kbuild
|
||||
|
@@ -1,36 +0,0 @@
|
||||
# -*- Makefile -*-
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||
abssrcdir = $(shell readlink -f ${srcdir})
|
||||
|
||||
regular_CFLAGS := @regular_CFLAGS@
|
||||
xtables_CFLAGS := @xtables_CFLAGS@
|
||||
kinclude_CFLAGS := @kinclude_CFLAGS@
|
||||
AM_CFLAGS = ${regular_CFLAGS} -I ${top_srcdir}/include \
|
||||
${xtables_CFLAGS} ${kinclude_CFLAGS} \
|
||||
-D_INIT=$*_init
|
||||
AM_LDFLAGS = -module -avoid-version
|
||||
xtlib_LTLIBRARIES = \
|
||||
libxt_LOGMARK.la \
|
||||
libxt_TARPIT.la \
|
||||
libxt_TEE.la
|
||||
|
||||
#
|
||||
# Call out to kbuild
|
||||
#
|
||||
.PHONY: modules modules_install clean_modules
|
||||
|
||||
all-local: modules
|
||||
|
||||
install-exec-local: modules_install
|
||||
|
||||
clean-local: clean_modules
|
||||
|
||||
modules:
|
||||
make -C ${kbuilddir} M=${abssrcdir} modules;
|
||||
|
||||
modules_install:
|
||||
make -C ${kbuilddir} M=${abssrcdir} INSTALL_MOD_PATH=${DESTDIR} modules_install;
|
||||
|
||||
clean_modules:
|
||||
make -C ${kbuilddir} M=${abssrcdir} clean;
|
20
extensions/compat_skbuff.h
Normal file
20
extensions/compat_skbuff.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef COMPAT_SKBUFF_H
|
||||
#define COMPAT_SKBUFF_H 1
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
||||
# define skb_nfmark(skb) (((struct sk_buff *)(skb))->nfmark)
|
||||
#else
|
||||
# define skb_nfmark(skb) (((struct sk_buff *)(skb))->mark)
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 21)
|
||||
# define ip_hdr(skb) ((skb)->nh.iph)
|
||||
# define ip_hdrlen(skb) (ip_hdr(skb)->ihl * 4)
|
||||
# define skb_network_header(skb) ((skb)->nh.raw)
|
||||
static inline void skb_reset_network_header(struct sk_buff *skb)
|
||||
{
|
||||
skb->nh.raw = skb->data;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* COMPAT_SKBUFF_H */
|
@@ -1,3 +1,4 @@
|
||||
#include <linux/ip.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -5,10 +6,13 @@
|
||||
#include <linux/version.h>
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter_arp.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/route.h>
|
||||
#include "compat_skbuff.h"
|
||||
#include "compat_xtnu.h"
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) && \
|
||||
LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
||||
static int xtnu_match_run(const struct sk_buff *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
const struct xt_match *cm, const void *matchinfo, int offset,
|
||||
@@ -24,9 +28,17 @@ static int xtnu_match_run(const struct sk_buff *skb,
|
||||
*hotdrop = lo_drop;
|
||||
return lo_ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
||||
static int xtnu_match_check(const char *table, const void *entry,
|
||||
const struct xt_match *cm, void *matchinfo, unsigned int matchinfosize,
|
||||
unsigned int hook_mask)
|
||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
||||
static int xtnu_match_check(const char *table, const void *entry,
|
||||
const struct xt_match *cm, void *matchinfo, unsigned int hook_mask)
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
||||
{
|
||||
struct xtnu_match *nm = xtcompat_numatch(cm);
|
||||
|
||||
@@ -36,15 +48,24 @@ static int xtnu_match_check(const char *table, const void *entry,
|
||||
return true;
|
||||
return nm->checkentry(table, entry, nm, matchinfo, hook_mask);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
||||
static void xtnu_match_destroy(const struct xt_match *cm, void *matchinfo,
|
||||
unsigned int matchinfosize)
|
||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
||||
static void xtnu_match_destroy(const struct xt_match *cm, void *matchinfo)
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
||||
{
|
||||
struct xtnu_match *nm = xtcompat_numatch(cm);
|
||||
|
||||
if (nm != NULL && nm->destroy != NULL)
|
||||
nm->destroy(nm, matchinfo);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
||||
int xtnu_register_match(struct xtnu_match *nt)
|
||||
{
|
||||
struct xt_match *ct;
|
||||
@@ -114,53 +135,63 @@ void xtnu_unregister_matches(struct xtnu_match *nt, unsigned int num)
|
||||
EXPORT_SYMBOL_GPL(xtnu_unregister_matches);
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
||||
static int xtnu_target_check(const char *table, const void *entry,
|
||||
const struct xt_target *ct, void *targinfo, unsigned int hook_mask)
|
||||
{
|
||||
struct xtnu_target *nt = xtcompat_nutarget(ct);
|
||||
if (nt == NULL)
|
||||
return false;
|
||||
if (nt->checkentry == NULL)
|
||||
/* this is valid, just like if there was no function */
|
||||
return true;
|
||||
return nt->checkentry(table, entry, nt, targinfo, hook_mask);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 23)
|
||||
static bool xtnu_target_check(const char *table, const void *entry,
|
||||
const struct xt_target *ct, void *targinfo, unsigned int hook_mask)
|
||||
{
|
||||
struct xtnu_target *nt = xtcompat_nutarget(ct);
|
||||
if (nt == NULL)
|
||||
return false;
|
||||
if (nt->checkentry == NULL)
|
||||
/* this is valid, just like if there was no function */
|
||||
return true;
|
||||
return nt->checkentry(table, entry, nt, targinfo, hook_mask);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) && \
|
||||
LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
||||
static unsigned int xtnu_target_run(struct sk_buff **pskb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
unsigned int hooknum, const struct xt_target *ct, const void *targinfo,
|
||||
void *userdata)
|
||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
static unsigned int xtnu_target_run(struct sk_buff **pskb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
unsigned int hooknum, const struct xt_target *ct, const void *targinfo)
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
{
|
||||
struct xtnu_target *nt = xtcompat_nutarget(ct);
|
||||
if (nt != NULL && nt->target != NULL)
|
||||
return nt->target(*pskb, in, out, hooknum, nt, targinfo);
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
||||
static int xtnu_target_check(const char *table, const void *entry,
|
||||
const struct xt_target *ct, void *targinfo,
|
||||
unsigned int targinfosize, unsigned int hook_mask)
|
||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
||||
static int xtnu_target_check(const char *table, const void *entry,
|
||||
const struct xt_target *ct, void *targinfo, unsigned int hook_mask)
|
||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
static bool xtnu_target_check(const char *table, const void *entry,
|
||||
const struct xt_target *ct, void *targinfo, unsigned int hook_mask)
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
{
|
||||
struct xtnu_target *nt = xtcompat_nutarget(ct);
|
||||
if (nt == NULL)
|
||||
return false;
|
||||
if (nt->checkentry == NULL)
|
||||
/* this is valid, just like if there was no function */
|
||||
return true;
|
||||
return nt->checkentry(table, entry, nt, targinfo, hook_mask);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
||||
static void xtnu_target_destroy(const struct xt_target *ct, void *targinfo,
|
||||
unsigned int targinfosize)
|
||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
static void xtnu_target_destroy(const struct xt_target *ct, void *targinfo)
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
{
|
||||
struct xtnu_target *nt = xtcompat_nutarget(ct);
|
||||
if (nt != NULL && nt->destroy != NULL)
|
||||
nt->destroy(nt, targinfo);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
int xtnu_register_target(struct xtnu_target *nt)
|
||||
{
|
||||
struct xt_target *ct;
|
||||
@@ -230,12 +261,109 @@ void xtnu_unregister_targets(struct xtnu_target *nt, unsigned int num)
|
||||
EXPORT_SYMBOL_GPL(xtnu_unregister_targets);
|
||||
#endif
|
||||
|
||||
struct xt_match *xtnu_request_find_match(unsigned int af, const char *name,
|
||||
uint8_t revision)
|
||||
{
|
||||
static const char *const xt_prefix[] = {
|
||||
[AF_UNSPEC] = "x",
|
||||
[AF_INET] = "ip",
|
||||
[AF_INET6] = "ip6",
|
||||
#ifdef AF_ARP
|
||||
[AF_ARP] = "arp",
|
||||
#elif defined(NF_ARP) && NF_ARP != AF_UNSPEC
|
||||
[NF_ARP] = "arp",
|
||||
#endif
|
||||
};
|
||||
struct xt_match *match;
|
||||
|
||||
match = try_then_request_module(xt_find_match(af, name, revision),
|
||||
"%st_%s", xt_prefix[af], name);
|
||||
if (IS_ERR(match) || match == NULL)
|
||||
return NULL;
|
||||
|
||||
return match;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_request_find_match);
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
int xtnu_ip_route_me_harder(struct sk_buff *skb, unsigned int addr_type)
|
||||
{
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
||||
return ip_route_me_harder(&skb);
|
||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
return ip_route_me_harder(&skb, addr_type);
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_ip_route_me_harder);
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 24)
|
||||
static int __xtnu_ip_local_out(struct sk_buff *skb)
|
||||
{
|
||||
struct iphdr *iph = ip_hdr(skb);
|
||||
|
||||
iph->tot_len = htons(skb->len);
|
||||
ip_send_check(iph);
|
||||
return nf_hook(PF_INET, NF_IP_LOCAL_OUT, skb, NULL,
|
||||
skb->dst->dev, dst_output);
|
||||
}
|
||||
|
||||
int xtnu_ip_local_out(struct sk_buff *skb)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = __xtnu_ip_local_out(skb);
|
||||
if (likely(err == 1))
|
||||
err = dst_output(skb);
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_ip_local_out);
|
||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
static int __xtnu_ip_local_out(struct sk_buff **pskb)
|
||||
{
|
||||
struct iphdr *iph = ip_hdr(*pskb);
|
||||
|
||||
iph->tot_len = htons((*pskb)->len);
|
||||
ip_send_check(iph);
|
||||
return nf_hook(PF_INET, NF_IP_LOCAL_OUT, pskb, NULL,
|
||||
(*pskb)->dst->dev, dst_output);
|
||||
}
|
||||
|
||||
int xtnu_ip_local_out(struct sk_buff *skb)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = __xtnu_ip_local_out(&skb);
|
||||
if (likely(err == 1))
|
||||
err = dst_output(skb);
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_ip_local_out);
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
|
||||
int xtnu_ip_route_output_key(void *net, struct rtable **rp, struct flowi *flp)
|
||||
{
|
||||
return ip_route_output_flow(rp, flp, NULL, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_ip_route_output_key);
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
||||
int xtnu_neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb)
|
||||
{
|
||||
unsigned int hh_alen;
|
||||
|
||||
read_lock_bh(&hh->hh_lock);
|
||||
hh_alen = HH_DATA_ALIGN(hh->hh_len);
|
||||
memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
|
||||
read_unlock_bh(&hh->hh_lock);
|
||||
skb_push(skb, hh->hh_len);
|
||||
return hh->hh_output(skb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_neigh_hh_output);
|
||||
#endif
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@@ -2,17 +2,50 @@
|
||||
#define _XTABLES_COMPAT_H 1
|
||||
|
||||
#include <linux/version.h>
|
||||
#include "compat_skbuff.h"
|
||||
#include "compat_xtnu.h"
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
|
||||
# warning Kernels below 2.6.18 not supported.
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
||||
# if !defined(CONFIG_NF_CONNTRACK_MARK) || !defined(CONFIG_NF_CONNTRACK_SECMARK)
|
||||
# warning You have CONFIG_NF_CONNTRACK enabled, but CONFIG_NF_CONNTRACK_MARK or CONFIG_NF_CONNTRACK_SECMARK are not (please enable).
|
||||
# endif
|
||||
# include <net/netfilter/nf_conntrack.h>
|
||||
#elif defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
|
||||
# if !defined(CONFIG_IP_NF_CONNTRACK_MARK) || !defined(CONFIG_IP_NF_CONNTRACK_SECMARK)
|
||||
# warning You have CONFIG_IP_NF_CONNTRACK enabled, but CONFIG_IP_NF_CONNTRACK_MARK or CONFIG_IP_NF_CONNTRACK_SECMARK are not (please enable).
|
||||
# endif
|
||||
# include <linux/netfilter_ipv4/ip_conntrack.h>
|
||||
# define nf_conn ip_conntrack
|
||||
# define nf_ct_get ip_conntrack_get
|
||||
# define nf_conntrack_untracked ip_conntrack_untracked
|
||||
#else
|
||||
# warning You need either CONFIG_NF_CONNTRACK or CONFIG_IP_NF_CONNTRACK.
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
||||
# define neigh_hh_output xtnu_neigh_hh_output
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
|
||||
# define NF_INET_PRE_ROUTING NF_IP_PRE_ROUTING
|
||||
# define NF_INET_LOCAL_IN NF_IP_LOCAL_IN
|
||||
# define NF_INET_FORWARD NF_IP_FORWARD
|
||||
# define NF_INET_LOCAL_OUT NF_IP_LOCAL_OUT
|
||||
# define NF_INET_POST_ROUTING NF_IP_POST_ROUTING
|
||||
# define ip_local_out xtnu_ip_local_out
|
||||
# define ip_route_output_key xtnu_ip_route_output_key
|
||||
# include "compat_nfinetaddr.h"
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
|
||||
# include "compat_nfinetaddr.h"
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
# define init_net xtnu_ip_route_output_key /* yes */
|
||||
# define init_net__loopback_dev (&loopback_dev)
|
||||
#else
|
||||
# define init_net__loopback_dev init_net.loopback_dev
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
||||
@@ -32,6 +65,6 @@
|
||||
# define xt_unregister_targets xtnu_unregister_targets
|
||||
#endif
|
||||
|
||||
#include "compat_xtnu.h"
|
||||
#define xt_request_find_match xtnu_request_find_match
|
||||
|
||||
#endif /* _XTABLES_COMPAT_H */
|
||||
|
@@ -5,8 +5,16 @@
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
||||
typedef _Bool bool;
|
||||
enum { false = 0, true = 1, };
|
||||
#endif
|
||||
|
||||
struct flowi;
|
||||
struct hh_cache;
|
||||
struct module;
|
||||
struct net_device;
|
||||
struct rtable;
|
||||
struct sk_buff;
|
||||
|
||||
struct xtnu_match {
|
||||
@@ -59,8 +67,10 @@ static inline struct xtnu_target *xtcompat_nutarget(const struct xt_target *t)
|
||||
return q;
|
||||
}
|
||||
|
||||
extern int xtnu_ip_local_out(struct sk_buff *);
|
||||
extern int xtnu_ip_route_me_harder(struct sk_buff *, unsigned int);
|
||||
extern int xtnu_register_match(struct xtnu_match *);
|
||||
extern int xtnu_ip_route_output_key(void *, struct rtable **, struct flowi *);
|
||||
extern void xtnu_unregister_match(struct xtnu_match *);
|
||||
extern int xtnu_register_matches(struct xtnu_match *, unsigned int);
|
||||
extern void xtnu_unregister_matches(struct xtnu_match *, unsigned int);
|
||||
@@ -68,5 +78,8 @@ extern int xtnu_register_target(struct xtnu_target *);
|
||||
extern void xtnu_unregister_target(struct xtnu_target *);
|
||||
extern int xtnu_register_targets(struct xtnu_target *, unsigned int);
|
||||
extern void xtnu_unregister_targets(struct xtnu_target *, unsigned int);
|
||||
extern struct xt_match *xtnu_request_find_match(unsigned int,
|
||||
const char *, uint8_t);
|
||||
extern int xtnu_neigh_hh_output(struct hh_cache *, struct sk_buff *);
|
||||
|
||||
#endif /* _COMPAT_XTNU_H */
|
||||
|
113
extensions/libxt_CHAOS.c
Normal file
113
extensions/libxt_CHAOS.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* CHAOS target for Xtables
|
||||
* Copyright © CC Computer Consultants GmbH, 2006 - 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License; either version
|
||||
* 2 or 3 as published by the Free Software Foundation.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include "xt_CHAOS.h"
|
||||
|
||||
enum {
|
||||
F_DELUDE = 1 << 0,
|
||||
F_TARPIT = 1 << 1,
|
||||
};
|
||||
|
||||
static const struct option chaos_tg_opts[] = {
|
||||
{.name = "delude", .has_arg = false, .val = 'd'},
|
||||
{.name = "tarpit", .has_arg = false, .val = 't'},
|
||||
{},
|
||||
};
|
||||
|
||||
static void chaos_tg_help(void)
|
||||
{
|
||||
printf(
|
||||
"CHAOS target options:\n"
|
||||
" --delude Enable DELUDE processing for TCP\n"
|
||||
" --tarpit Enable TARPIT processing for TCP\n");
|
||||
}
|
||||
|
||||
static int chaos_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_chaos_tginfo *info = (void *)((*target)->data);
|
||||
|
||||
switch (c) {
|
||||
case 'd':
|
||||
info->variant = XTCHAOS_DELUDE;
|
||||
*flags |= F_DELUDE;
|
||||
return true;
|
||||
case 't':
|
||||
info->variant = XTCHAOS_TARPIT;
|
||||
*flags |= F_TARPIT;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void chaos_tg_check(unsigned int flags)
|
||||
{
|
||||
if (flags == (F_DELUDE | F_TARPIT))
|
||||
/* If flags == 0x03, both were specified, which should not be. */
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"CHAOS: only one of --tarpit or --delude "
|
||||
"may be specified");
|
||||
}
|
||||
|
||||
static void chaos_tg_print(const void *ip,
|
||||
const struct xt_entry_target *target, int numeric)
|
||||
{
|
||||
const struct xt_chaos_tginfo *info = (const void *)target->data;
|
||||
|
||||
switch (info->variant) {
|
||||
case XTCHAOS_DELUDE:
|
||||
printf("DELUDE ");
|
||||
break;
|
||||
case XTCHAOS_TARPIT:
|
||||
printf("TARPIT ");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void chaos_tg_save(const void *ip, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_chaos_tginfo *info = (const void *)target->data;
|
||||
|
||||
switch (info->variant) {
|
||||
case XTCHAOS_DELUDE:
|
||||
printf("--delude ");
|
||||
break;
|
||||
case XTCHAOS_TARPIT:
|
||||
printf("--tarpit ");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static struct xtables_target chaos_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "CHAOS",
|
||||
.family = AF_INET,
|
||||
.size = XT_ALIGN(sizeof(struct xt_chaos_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_chaos_tginfo)),
|
||||
.help = chaos_tg_help,
|
||||
.parse = chaos_tg_parse,
|
||||
.final_check = chaos_tg_check,
|
||||
.print = chaos_tg_print,
|
||||
.save = chaos_tg_save,
|
||||
.extra_opts = chaos_tg_opts,
|
||||
};
|
||||
|
||||
void _init(void);
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_target(&chaos_tg_reg);
|
||||
}
|
18
extensions/libxt_CHAOS.man
Normal file
18
extensions/libxt_CHAOS.man
Normal file
@@ -0,0 +1,18 @@
|
||||
+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\fR
|
||||
+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\fR
|
||||
+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
|
||||
+may fail to do their connection tracking if they have to handle more
|
||||
+connections than they can.
|
||||
+.PP
|
||||
+The randomness factor of not replying vs. replying can be set during load-time
|
||||
+of the xt_CHAOS module or during runtime in /sys/modules/xt_CHAOS/parameters.
|
47
extensions/libxt_DELUDE.c
Normal file
47
extensions/libxt_DELUDE.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* DELUDE target for Xtables
|
||||
* Copyright © CC Computer Consultants GmbH, 2006 - 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License; either version
|
||||
* 2 or 3 as published by the Free Software Foundation.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
|
||||
static void delude_tg_help(void)
|
||||
{
|
||||
printf("DELUDE takes no options\n");
|
||||
}
|
||||
|
||||
static int delude_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void delude_tg_check(unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
static struct xtables_target delude_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "DELUDE",
|
||||
.revision = 0,
|
||||
.family = AF_INET,
|
||||
.size = XT_ALIGN(0),
|
||||
.userspacesize = XT_ALIGN(0),
|
||||
.help = delude_tg_help,
|
||||
.parse = delude_tg_parse,
|
||||
.final_check = delude_tg_check,
|
||||
};
|
||||
|
||||
void _init(void);
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_target(&delude_tg_reg);
|
||||
}
|
4
extensions/libxt_DELUDE.man
Normal file
4
extensions/libxt_DELUDE.man
Normal file
@@ -0,0 +1,4 @@
|
||||
The DELUDE target will reply to a SYN packet with SYN-ACK, and to all other
|
||||
packets with an RST. This will terminate the connection much like REJECT, but
|
||||
network scanners doing TCP half-open discovery can be spoofed to make them
|
||||
belive the port is open rather than closed/filtered.
|
34
extensions/libxt_ECHO.c
Normal file
34
extensions/libxt_ECHO.c
Normal file
@@ -0,0 +1,34 @@
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <xtables.h>
|
||||
|
||||
static void echo_tg_help(void)
|
||||
{
|
||||
printf("ECHO takes no options\n\n");
|
||||
}
|
||||
|
||||
static int echo_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void echo_tg_check(unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
static struct xtables_target echo_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "ECHO",
|
||||
.family = AF_UNSPEC,
|
||||
.size = XT_ALIGN(0),
|
||||
.userspacesize = XT_ALIGN(0),
|
||||
.help = echo_tg_help,
|
||||
.parse = echo_tg_parse,
|
||||
.final_check = echo_tg_check,
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
{
|
||||
xtables_register_target(&echo_tg_reg);
|
||||
}
|
@@ -6,19 +6,13 @@
|
||||
#include "xt_LOGMARK.h"
|
||||
|
||||
enum {
|
||||
F_LEVEL = 1 << 0,
|
||||
F_PREFIX = 1 << 1,
|
||||
F_NFMARK = 1 << 2,
|
||||
F_CTMARK = 1 << 3,
|
||||
F_SECMARK = 1 << 4,
|
||||
F_LEVEL = 1 << 0,
|
||||
F_PREFIX = 1 << 1,
|
||||
};
|
||||
|
||||
static const struct option logmark_tg_opts[] = {
|
||||
{.name = "log-level", .has_arg = true, .val = 'l'},
|
||||
{.name = "log-prefix", .has_arg = true, .val = 'p'},
|
||||
{.name = "log-nfmark", .has_arg = false, .val = 'n'},
|
||||
{.name = "log-ctmark", .has_arg = false, .val = 'c'},
|
||||
{.name = "log-secmark", .has_arg = false, .val = 's'},
|
||||
{},
|
||||
};
|
||||
|
||||
@@ -28,9 +22,6 @@ static void logmark_tg_help(void)
|
||||
"LOGMARK target options:\n"
|
||||
" --log-level level Level of logging (numeric, 0-8)\n"
|
||||
" --log-prefix prefix Prefix log messages with this string\n"
|
||||
" --log-nfmark Log the packet mark\n"
|
||||
" --log-ctmark Log the connection mark\n"
|
||||
" --log-secmark Log the security mark of the packet\n"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -72,27 +63,6 @@ logmark_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
strncpy(info->prefix, optarg, sizeof(info->prefix));
|
||||
*flags |= F_PREFIX;
|
||||
return true;
|
||||
|
||||
case 'n': /* --log-nfmark */
|
||||
param_act(P_ONLY_ONCE, "LOGMARK", "--log-nfmark", *flags & F_NFMARK);
|
||||
param_act(P_NO_INVERT, "LOGMARK", "--log-nfmark", invert);
|
||||
info->flags |= XT_LOGMARK_NFMARK;
|
||||
*flags |= F_NFMARK;
|
||||
return true;
|
||||
|
||||
case 'c': /* --log-ctmark */
|
||||
param_act(P_ONLY_ONCE, "LOGMARK", "--log-ctmark", *flags & F_CTMARK);
|
||||
param_act(P_NO_INVERT, "LOGMARK", "--log-ctmark", invert);
|
||||
info->flags |= XT_LOGMARK_CTMARK;
|
||||
*flags |= F_CTMARK;
|
||||
return true;
|
||||
|
||||
case 's': /* --log-secmark */
|
||||
param_act(P_ONLY_ONCE, "LOGMARK", "--log-secmark", *flags & F_SECMARK);
|
||||
param_act(P_NO_INVERT, "LOGMARK", "--log-secmark", invert);
|
||||
info->flags |= XT_LOGMARK_SECMARK;
|
||||
*flags |= F_SECMARK;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -103,14 +73,7 @@ logmark_tg_print(const void *ip, const struct xt_entry_target *target,
|
||||
{
|
||||
const struct xt_logmark_tginfo *info = (void *)target->data;
|
||||
|
||||
printf("LOGMARK level %u prefix \"%s\"", info->level, info->prefix);
|
||||
if (info->flags & XT_LOGMARK_NFMARK)
|
||||
printf(" nfmark");
|
||||
if (info->flags & XT_LOGMARK_CTMARK)
|
||||
printf(" ctmark");
|
||||
if (info->flags & XT_LOGMARK_SECMARK)
|
||||
printf(" secmark");
|
||||
printf("; ");
|
||||
printf("LOGMARK level %u prefix \"%s\" ", info->level, info->prefix);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -122,34 +85,13 @@ logmark_tg_save(const void *ip, const struct xt_entry_target *target)
|
||||
printf("--log-level %u ", info->level);
|
||||
if (*info->prefix != '\0')
|
||||
printf("--log-prefix \"%s\" ", info->prefix);
|
||||
if (info->flags & XT_LOGMARK_NFMARK)
|
||||
printf("--log-nfmark ");
|
||||
if (info->flags & XT_LOGMARK_CTMARK)
|
||||
printf("--log-ctmark ");
|
||||
if (info->flags & XT_LOGMARK_SECMARK)
|
||||
printf("--log-secmark ");
|
||||
}
|
||||
|
||||
static struct xtables_target logmark_tg_reg = {
|
||||
.version = IPTABLES_VERSION,
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "LOGMARK",
|
||||
.revision = 0,
|
||||
.family = AF_INET,
|
||||
.size = XT_ALIGN(sizeof(struct xt_logmark_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_logmark_tginfo)),
|
||||
.help = logmark_tg_help,
|
||||
.init = logmark_tg_init,
|
||||
.parse = logmark_tg_parse,
|
||||
.print = logmark_tg_print,
|
||||
.save = logmark_tg_save,
|
||||
.extra_opts = logmark_tg_opts,
|
||||
};
|
||||
|
||||
static struct xtables_target logmark_tg6_reg = {
|
||||
.version = IPTABLES_VERSION,
|
||||
.name = "LOGMARK",
|
||||
.revision = 0,
|
||||
.family = AF_INET6,
|
||||
.family = AF_UNSPEC,
|
||||
.size = XT_ALIGN(sizeof(struct xt_logmark_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_logmark_tginfo)),
|
||||
.help = logmark_tg_help,
|
||||
@@ -164,5 +106,4 @@ void _init(void);
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_target(&logmark_tg_reg);
|
||||
xtables_register_target(&logmark_tg6_reg);
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ static void tarpit_tg_check(unsigned int flags)
|
||||
}
|
||||
|
||||
static struct xtables_target tarpit_tg_reg = {
|
||||
.version = IPTABLES_VERSION,
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "TARPIT",
|
||||
.family = AF_INET,
|
||||
.size = XT_ALIGN(0),
|
||||
|
@@ -94,7 +94,7 @@ static void tee_tg_save(const void *ip, const struct xt_entry_target *target)
|
||||
|
||||
static struct xtables_target tee_tg_reg = {
|
||||
.name = "TEE",
|
||||
.version = IPTABLES_VERSION,
|
||||
.version = XTABLES_VERSION,
|
||||
.size = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_tee_tginfo)),
|
||||
.help = tee_tg_help,
|
||||
|
278
extensions/libxt_geoip.c
Normal file
278
extensions/libxt_geoip.c
Normal file
@@ -0,0 +1,278 @@
|
||||
/* Shared library add-on to iptables to add geoip match support.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (c) 2004, 2005, 2006, 2007, 2008
|
||||
* Samuel Jean & Nicolas Bouliane
|
||||
*
|
||||
* For comments, bugs or suggestions, please contact
|
||||
* Samuel Jean <peejix@people.netfilter.org>
|
||||
* Nicolas Bouliane <peejix@people.netfilter.org>
|
||||
*/
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <endian.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_geoip.h"
|
||||
#define GEOIP_DB_DIR "/var/geoip"
|
||||
|
||||
static void geoip_help(void)
|
||||
{
|
||||
printf (
|
||||
"geoip match options:\n"
|
||||
"[!] --src-cc, --source-country country[,country...]\n"
|
||||
" Match packet coming from (one of) the specified country(ies)\n"
|
||||
"[!] --dst-cc, --destination-country country[,country...]\n"
|
||||
" Match packet going to (one of) the specified country(ies)\n"
|
||||
"\n"
|
||||
"NOTE: The country is inputed by its ISO3166 code.\n"
|
||||
"\n"
|
||||
);
|
||||
}
|
||||
|
||||
static struct option geoip_opts[] = {
|
||||
{.name = "dst-cc", .has_arg = true, .val = '2'},
|
||||
{.name = "destination-country", .has_arg = true, .val = '2'},
|
||||
{.name = "src-cc", .has_arg = true, .val = '1'},
|
||||
{.name = "source-country", .has_arg = true, .val = '1'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static struct geoip_subnet *geoip_get_subnets(const char *code, uint32_t *count)
|
||||
{
|
||||
struct geoip_subnet *subnets;
|
||||
struct stat sb;
|
||||
char buf[256];
|
||||
int fd;
|
||||
|
||||
/* Use simple integer vector files */
|
||||
#if __BYTE_ORDER == _BIG_ENDIAN
|
||||
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/BE/%s.iv0", code);
|
||||
#else
|
||||
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/LE/%s.iv0", code);
|
||||
#endif
|
||||
|
||||
if ((fd = open(buf, O_RDONLY)) < 0) {
|
||||
fprintf(stderr, "Could not open %s: %s\n", buf, strerror(errno));
|
||||
exit_error(OTHER_PROBLEM, "Could not read geoip database");
|
||||
}
|
||||
|
||||
fstat(fd, &sb);
|
||||
if (sb.st_size % sizeof(struct geoip_subnet) != 0)
|
||||
exit_error(OTHER_PROBLEM, "Database file %s seems to be "
|
||||
"corrupted", buf);
|
||||
subnets = malloc(sb.st_size);
|
||||
if (subnets == NULL)
|
||||
exit_error(OTHER_PROBLEM, "geoip: insufficient memory");
|
||||
read(fd, subnets, sb.st_size);
|
||||
close(fd);
|
||||
*count = sb.st_size / sizeof(struct geoip_subnet);
|
||||
return subnets;
|
||||
}
|
||||
|
||||
static struct geoip_country_user *geoip_load_cc(const char *code,
|
||||
unsigned short cc)
|
||||
{
|
||||
struct geoip_country_user *ginfo;
|
||||
ginfo = malloc(sizeof(struct geoip_country_user));
|
||||
|
||||
if (!ginfo)
|
||||
return NULL;
|
||||
|
||||
ginfo->subnets = (unsigned long)geoip_get_subnets(code, &ginfo->count);
|
||||
ginfo->cc = cc;
|
||||
|
||||
return ginfo;
|
||||
}
|
||||
|
||||
static u_int16_t
|
||||
check_geoip_cc(char *cc, u_int16_t cc_used[], u_int8_t count)
|
||||
{
|
||||
u_int8_t i;
|
||||
u_int16_t cc_int16;
|
||||
|
||||
if (strlen(cc) != 2) /* Country must be 2 chars long according
|
||||
to the ISO3166 standard */
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"geoip: invalid country code '%s'", cc);
|
||||
|
||||
// Verification will fail if chars aren't uppercased.
|
||||
// Make sure they are..
|
||||
for (i = 0; i < 2; i++)
|
||||
if (isalnum(cc[i]) != 0)
|
||||
cc[i] = toupper(cc[i]);
|
||||
else
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"geoip: invalid country code '%s'", cc);
|
||||
|
||||
/* Convert chars into a single 16 bit integer.
|
||||
* FIXME: This assumes that a country code is
|
||||
* exactly 2 chars long. If this is
|
||||
* going to change someday, this whole
|
||||
* match will need to be rewritten, anyway.
|
||||
* - SJ */
|
||||
cc_int16 = (cc[0] << 8) | cc[1];
|
||||
|
||||
// Check for presence of value in cc_used
|
||||
for (i = 0; i < count; i++)
|
||||
if (cc_int16 == cc_used[i])
|
||||
return 0; // Present, skip it!
|
||||
|
||||
return cc_int16;
|
||||
}
|
||||
|
||||
static unsigned int parse_geoip_cc(const char *ccstr, uint16_t *cc,
|
||||
union geoip_country_group *mem)
|
||||
{
|
||||
char *buffer, *cp, *next;
|
||||
u_int8_t i, count = 0;
|
||||
u_int16_t cctmp;
|
||||
|
||||
buffer = strdup(ccstr);
|
||||
if (!buffer)
|
||||
exit_error(OTHER_PROBLEM,
|
||||
"geoip: insufficient memory available");
|
||||
|
||||
for (cp = buffer, i = 0; cp && i < XT_GEOIP_MAX; cp = next, i++)
|
||||
{
|
||||
next = strchr(cp, ',');
|
||||
if (next) *next++ = '\0';
|
||||
|
||||
if ((cctmp = check_geoip_cc(cp, cc, count)) != 0) {
|
||||
if ((mem[count++].user = (unsigned long)geoip_load_cc(cp, cctmp)) == 0)
|
||||
exit_error(OTHER_PROBLEM,
|
||||
"geoip: insufficient memory available");
|
||||
cc[count-1] = cctmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (cp)
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"geoip: too many countries specified");
|
||||
free(buffer);
|
||||
|
||||
if (count == 0)
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"geoip: don't know what happened");
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int geoip_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct xt_geoip_match_info *info = (void *)(*match)->data;
|
||||
|
||||
switch(c) {
|
||||
case '1':
|
||||
// Ensure that XT_GEOIP_SRC *OR* XT_GEOIP_DST haven't been used yet.
|
||||
if (*flags & (XT_GEOIP_SRC | XT_GEOIP_DST))
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"geoip: only use --source-country *OR* --destination-country once!");
|
||||
|
||||
*flags |= XT_GEOIP_SRC;
|
||||
break;
|
||||
|
||||
case '2':
|
||||
// Ensure that XT_GEOIP_SRC *OR* XT_GEOIP_DST haven't been used yet.
|
||||
if (*flags & (XT_GEOIP_SRC | XT_GEOIP_DST))
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"geoip: only use --source-country *OR* --destination-country once!");
|
||||
|
||||
*flags |= XT_GEOIP_DST;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (invert)
|
||||
*flags |= XT_GEOIP_INV;
|
||||
|
||||
info->count = parse_geoip_cc(argv[optind-1], info->cc, info->mem);
|
||||
info->flags = *flags;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
geoip_final_check(unsigned int flags)
|
||||
{
|
||||
if (!flags)
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"geoip: missing arguments");
|
||||
}
|
||||
|
||||
static void
|
||||
geoip_print(const void *ip, const struct xt_entry_match *match, int numeric)
|
||||
{
|
||||
const struct xt_geoip_match_info *info = (void*)match->data;
|
||||
|
||||
u_int8_t i;
|
||||
|
||||
if (info->flags & XT_GEOIP_SRC)
|
||||
printf("Source ");
|
||||
else
|
||||
printf("Destination ");
|
||||
|
||||
if (info->count > 1)
|
||||
printf("countries: ");
|
||||
else
|
||||
printf("country: ");
|
||||
|
||||
if (info->flags & XT_GEOIP_INV)
|
||||
printf("! ");
|
||||
|
||||
for (i = 0; i < info->count; i++)
|
||||
printf("%s%c%c", i ? "," : "", COUNTRY(info->cc[i]));
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static void
|
||||
geoip_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
const struct xt_geoip_match_info *info = (void *)match->data;
|
||||
u_int8_t i;
|
||||
|
||||
if (info->flags & XT_GEOIP_INV)
|
||||
printf("! ");
|
||||
|
||||
if (info->flags & XT_GEOIP_SRC)
|
||||
printf("--source-country ");
|
||||
else
|
||||
printf("--destination-country ");
|
||||
|
||||
for (i = 0; i < info->count; i++)
|
||||
printf("%s%c%c", i ? "," : "", COUNTRY(info->cc[i]));
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static struct xtables_match geoip_match = {
|
||||
.family = AF_INET,
|
||||
.name = "geoip",
|
||||
.version = XTABLES_VERSION,
|
||||
.size = XT_ALIGN(sizeof(struct xt_geoip_match_info)),
|
||||
.userspacesize = XT_ALIGN(offsetof(struct xt_geoip_match_info, mem)),
|
||||
.help = geoip_help,
|
||||
.parse = geoip_parse,
|
||||
.final_check = geoip_final_check,
|
||||
.print = geoip_print,
|
||||
.save = geoip_save,
|
||||
.extra_opts = geoip_opts,
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
{
|
||||
xtables_register_match(&geoip_match);
|
||||
}
|
16
extensions/libxt_geoip.man
Normal file
16
extensions/libxt_geoip.man
Normal file
@@ -0,0 +1,16 @@
|
||||
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]
|
||||
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]
|
||||
Match packet going to (one of) the specified country(ies)
|
||||
.TP
|
||||
NOTE:
|
||||
The country is inputed by its ISO3166 code.
|
||||
.P
|
||||
The extra files you will need is the binary database files. They are generated
|
||||
from a country-subnet database with the geoip_csv_iv0.pl tool, available at
|
||||
http://jengelh.hopto.org/files/geoip/ . The files MUST be moved to /var/geoip/
|
||||
as the shared library is statically looking for this pathname (e.g.
|
||||
/var/geoip/LE/de.iv0).
|
121
extensions/libxt_portscan.c
Normal file
121
extensions/libxt_portscan.c
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* portscan target for Xtables
|
||||
* Copyright © CC Computer Consultants GmbH, 2006 - 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License; either version
|
||||
* 2 or 3 as published by the Free Software Foundation.
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include "xt_portscan.h"
|
||||
|
||||
static const struct option portscan_mt_opts[] = {
|
||||
{.name = "stealth", .has_arg = false, .val = 'x'},
|
||||
{.name = "synscan", .has_arg = false, .val = 's'},
|
||||
{.name = "cnscan", .has_arg = false, .val = 'c'},
|
||||
{.name = "grscan", .has_arg = false, .val = 'g'},
|
||||
{},
|
||||
};
|
||||
|
||||
static void portscan_mt_help(void)
|
||||
{
|
||||
printf(
|
||||
"portscan match options:\n"
|
||||
"(Combining them will make them match by OR-logic)\n"
|
||||
" --stealth Match TCP Stealth packets\n"
|
||||
" --synscan Match TCP SYN scans\n"
|
||||
" --cnscan Match TCP Connect scans\n"
|
||||
" --grscan Match Banner Grabbing scans\n");
|
||||
}
|
||||
|
||||
static int portscan_mt_parse(int c, char **argv, int invert,
|
||||
unsigned int *flags, const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct xt_portscan_mtinfo *info = (void *)((*match)->data);
|
||||
|
||||
switch (c) {
|
||||
case 'c':
|
||||
info->match_cn = true;
|
||||
return true;
|
||||
case 'g':
|
||||
info->match_gr = true;
|
||||
return true;
|
||||
case 's':
|
||||
info->match_syn = true;
|
||||
return true;
|
||||
case 'x':
|
||||
info->match_stealth = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void portscan_mt_check(unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
static void portscan_mt_print(const void *ip,
|
||||
const struct xt_entry_match *match, int numeric)
|
||||
{
|
||||
const struct xt_portscan_mtinfo *info = (const void *)(match->data);
|
||||
const char *s = "";
|
||||
|
||||
printf("portscan ");
|
||||
if (info->match_stealth) {
|
||||
printf("STEALTH");
|
||||
s = ",";
|
||||
}
|
||||
if (info->match_syn) {
|
||||
printf("%sSYNSCAN", s);
|
||||
s = ",";
|
||||
}
|
||||
if (info->match_cn) {
|
||||
printf("%sCNSCAN", s);
|
||||
s = ",";
|
||||
}
|
||||
if (info->match_gr)
|
||||
printf("%sGRSCAN", s);
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static void portscan_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
const struct xt_portscan_mtinfo *info = (const void *)(match->data);
|
||||
|
||||
if (info->match_stealth)
|
||||
printf("--stealth ");
|
||||
if (info->match_syn)
|
||||
printf("--synscan ");
|
||||
if (info->match_cn)
|
||||
printf("--cnscan ");
|
||||
if (info->match_gr)
|
||||
printf("--grscan ");
|
||||
}
|
||||
|
||||
static struct xtables_match portscan_mt_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "portscan",
|
||||
.revision = 0,
|
||||
.family = AF_INET,
|
||||
.size = XT_ALIGN(sizeof(struct xt_portscan_mtinfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_portscan_mtinfo)),
|
||||
.help = portscan_mt_help,
|
||||
.parse = portscan_mt_parse,
|
||||
.final_check = portscan_mt_check,
|
||||
.print = portscan_mt_print,
|
||||
.save = portscan_mt_save,
|
||||
.extra_opts = portscan_mt_opts,
|
||||
};
|
||||
|
||||
void _init(void);
|
||||
void _init(void)
|
||||
{
|
||||
xtables_register_match(&portscan_mt_reg);
|
||||
}
|
27
extensions/libxt_portscan.man
Normal file
27
extensions/libxt_portscan.man
Normal file
@@ -0,0 +1,27 @@
|
||||
Detects simple port scan attemps based upon the packet's contents. (This is
|
||||
different from other implementations, which also try to match the rate of new
|
||||
connections.) Note that an attempt is only discovered after it has been carried
|
||||
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
|
||||
Match if the packet did not belong to any known TCP connection
|
||||
(Stealth/FIN/XMAS/NULL scan).
|
||||
.TP
|
||||
\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
|
||||
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
|
||||
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)
|
||||
.PP
|
||||
NOTE: Some clients (Windows XP for example) may do what looks like a SYN scan,
|
||||
so be advised to carefully use xt_portscan in conjunction with blocking rules,
|
||||
as it may lock out your very own internal network.
|
210
extensions/xt_CHAOS.c
Normal file
210
extensions/xt_CHAOS.c
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* CHAOS target for netfilter
|
||||
* Copyright © CC Computer Consultants GmbH, 2006 - 2007
|
||||
* Contact: Jan Engelhardt <jengelh@computergmbh.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License; either version
|
||||
* 2 or 3 as published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/icmp.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_tcpudp.h>
|
||||
#include <linux/netfilter_ipv4/ipt_REJECT.h>
|
||||
#include <net/ip.h>
|
||||
#include "xt_CHAOS.h"
|
||||
static struct xt_match *xm_tcp;
|
||||
static struct xt_target *xt_delude, *xt_reject, *xt_tarpit;
|
||||
#include "compat_xtables.h"
|
||||
#define PFX KBUILD_MODNAME ": "
|
||||
|
||||
/* Module parameters */
|
||||
static unsigned int reject_percentage = ~0U * .01;
|
||||
static unsigned int delude_percentage = ~0U * .0101;
|
||||
module_param(reject_percentage, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(delude_percentage, uint, S_IRUGO | S_IWUSR);
|
||||
|
||||
/* References to other matches/targets */
|
||||
|
||||
static int have_delude, have_tarpit;
|
||||
|
||||
/* Static data for other matches/targets */
|
||||
static const struct ipt_reject_info reject_params = {
|
||||
.with = ICMP_HOST_UNREACH,
|
||||
};
|
||||
|
||||
static const struct xt_tcp tcp_params = {
|
||||
.spts = {0, ~0},
|
||||
.dpts = {0, ~0},
|
||||
};
|
||||
|
||||
/* CHAOS functions */
|
||||
static void xt_chaos_total(const struct xt_chaos_tginfo *info,
|
||||
struct sk_buff *skb, const struct net_device *in,
|
||||
const struct net_device *out, unsigned int hooknum)
|
||||
{
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
const int protoff = 4 * iph->ihl;
|
||||
const int offset = ntohs(iph->frag_off) & IP_OFFSET;
|
||||
typeof(xt_tarpit) destiny;
|
||||
bool ret;
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
|
||||
int hotdrop = false;
|
||||
#else
|
||||
bool hotdrop = false;
|
||||
#endif
|
||||
|
||||
ret = xm_tcp->match(skb, in, out, xm_tcp, &tcp_params,
|
||||
offset, protoff, &hotdrop);
|
||||
if (!ret || hotdrop || (unsigned int)net_random() > delude_percentage)
|
||||
return;
|
||||
|
||||
destiny = (info->variant == XTCHAOS_TARPIT) ? xt_tarpit : xt_delude;
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
||||
destiny->target(&skb, in, out, hooknum, destiny, NULL, NULL);
|
||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
destiny->target(&skb, in, out, hooknum, destiny, NULL);
|
||||
#else
|
||||
destiny->target(skb, in, out, hooknum, destiny, NULL);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
static unsigned int chaos_tg(struct sk_buff *skb, const struct net_device *in,
|
||||
const struct net_device *out, unsigned int hooknum,
|
||||
const struct xt_target *target, const void *targinfo)
|
||||
{
|
||||
/*
|
||||
* Equivalent to:
|
||||
* -A chaos -m statistic --mode random --probability \
|
||||
* $reject_percentage -j REJECT --reject-with host-unreach;
|
||||
* -A chaos -p tcp -m statistic --mode random --probability \
|
||||
* $delude_percentage -j DELUDE;
|
||||
* -A chaos -j DROP;
|
||||
*/
|
||||
const struct xt_chaos_tginfo *info = targinfo;
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
|
||||
if ((unsigned int)net_random() <= reject_percentage)
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
||||
return xt_reject->target(&skb, in, out, hooknum,
|
||||
target->__compat_target, &reject_params, NULL);
|
||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
return xt_reject->target(&skb, in, out, hooknum,
|
||||
target->__compat_target, &reject_params);
|
||||
#else
|
||||
return xt_reject->target(skb, in, out, hooknum, target,
|
||||
&reject_params);
|
||||
#endif
|
||||
|
||||
/* TARPIT/DELUDE may not be called from the OUTPUT chain */
|
||||
if (iph->protocol == IPPROTO_TCP &&
|
||||
info->variant != XTCHAOS_NORMAL && hooknum != NF_INET_LOCAL_OUT)
|
||||
xt_chaos_total(info, skb, in, out, hooknum);
|
||||
|
||||
return NF_DROP;
|
||||
}
|
||||
|
||||
static bool chaos_tg_check(const char *tablename, const void *entry,
|
||||
const struct xt_target *target, void *targinfo, unsigned int hook_mask)
|
||||
{
|
||||
const struct xt_chaos_tginfo *info = targinfo;
|
||||
|
||||
if (info->variant == XTCHAOS_DELUDE && !have_delude) {
|
||||
printk(KERN_WARNING PFX "Error: Cannot use --delude when "
|
||||
"DELUDE module not available\n");
|
||||
return false;
|
||||
}
|
||||
if (info->variant == XTCHAOS_TARPIT && !have_tarpit) {
|
||||
printk(KERN_WARNING PFX "Error: Cannot use --tarpit when "
|
||||
"TARPIT module not available\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct xt_target chaos_tg_reg = {
|
||||
.name = "CHAOS",
|
||||
.family = AF_INET,
|
||||
.table = "filter",
|
||||
.hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD) |
|
||||
(1 << NF_INET_LOCAL_OUT),
|
||||
.target = chaos_tg,
|
||||
.checkentry = chaos_tg_check,
|
||||
.targetsize = sizeof(struct xt_chaos_tginfo),
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init chaos_tg_init(void)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
xm_tcp = xt_request_find_match(AF_INET, "tcp", 0);
|
||||
if (xm_tcp == NULL) {
|
||||
printk(KERN_WARNING PFX "Error: Could not find or load "
|
||||
"\"tcp\" match\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
xt_reject = xt_request_find_target(AF_INET, "REJECT", 0);
|
||||
if (xt_reject == NULL) {
|
||||
printk(KERN_WARNING PFX "Error: Could not find or load "
|
||||
"\"REJECT\" target\n");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
xt_tarpit = xt_request_find_target(AF_INET, "TARPIT", 0);
|
||||
have_tarpit = xt_tarpit != NULL;
|
||||
if (!have_tarpit)
|
||||
printk(KERN_WARNING PFX "Warning: Could not find or load "
|
||||
"\"TARPIT\" target\n");
|
||||
|
||||
xt_delude = xt_request_find_target(AF_INET, "DELUDE", 0);
|
||||
have_delude = xt_delude != NULL;
|
||||
if (!have_delude)
|
||||
printk(KERN_WARNING PFX "Warning: Could not find or load "
|
||||
"\"DELUDE\" target\n");
|
||||
|
||||
if ((ret = xt_register_target(&chaos_tg_reg)) != 0) {
|
||||
printk(KERN_WARNING PFX "xt_register_target returned "
|
||||
"error %d\n", ret);
|
||||
goto out3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out3:
|
||||
if (have_delude)
|
||||
module_put(xt_delude->me);
|
||||
if (have_tarpit)
|
||||
module_put(xt_tarpit->me);
|
||||
module_put(xt_reject->me);
|
||||
out2:
|
||||
module_put(xm_tcp->me);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit chaos_tg_exit(void)
|
||||
{
|
||||
xt_unregister_target(&chaos_tg_reg);
|
||||
module_put(xm_tcp->me);
|
||||
module_put(xt_reject->me);
|
||||
if (have_delude)
|
||||
module_put(xt_delude->me);
|
||||
if (have_tarpit)
|
||||
module_put(xt_tarpit->me);
|
||||
return;
|
||||
}
|
||||
|
||||
module_init(chaos_tg_init);
|
||||
module_exit(chaos_tg_exit);
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
|
||||
MODULE_DESCRIPTION("Xtables: Network scan slowdown with non-deterministic results");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_CHAOS");
|
14
extensions/xt_CHAOS.h
Normal file
14
extensions/xt_CHAOS.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _LINUX_NETFILTER_XT_CHAOS_H
|
||||
#define _LINUX_NETFILTER_XT_CHAOS_H 1
|
||||
|
||||
enum xt_chaos_target_variant {
|
||||
XTCHAOS_NORMAL,
|
||||
XTCHAOS_TARPIT,
|
||||
XTCHAOS_DELUDE,
|
||||
};
|
||||
|
||||
struct xt_chaos_tginfo {
|
||||
uint8_t variant;
|
||||
};
|
||||
|
||||
#endif /* _LINUX_NETFILTER_XT_CHAOS_H */
|
181
extensions/xt_DELUDE.c
Normal file
181
extensions/xt_DELUDE.c
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* DELUDE target
|
||||
* Copyright © CC Computer Consultants GmbH, 2007 - 2008
|
||||
*
|
||||
* Based upon linux-2.6.18.5/net/ipv4/netfilter/ipt_REJECT.c:
|
||||
* (C) 1999-2001 Paul `Rusty' Russell
|
||||
* (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
|
||||
*
|
||||
* xt_DELUDE acts like REJECT, but does reply with SYN-ACK on SYN.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||
# include <linux/netfilter_bridge.h>
|
||||
#endif
|
||||
#include <net/tcp.h>
|
||||
#include "compat_xtables.h"
|
||||
#define PFX KBUILD_MODNAME ": "
|
||||
|
||||
static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
|
||||
{
|
||||
struct tcphdr _otcph, *tcph;
|
||||
const struct tcphdr *oth;
|
||||
const struct iphdr *oiph;
|
||||
unsigned int addr_type;
|
||||
struct sk_buff *nskb;
|
||||
struct iphdr *niph;
|
||||
|
||||
oiph = ip_hdr(oldskb);
|
||||
|
||||
/* IP header checks: fragment. */
|
||||
if (oiph->frag_off & htons(IP_OFFSET))
|
||||
return;
|
||||
|
||||
oth = skb_header_pointer(oldskb, ip_hdrlen(oldskb),
|
||||
sizeof(_otcph), &_otcph);
|
||||
if (oth == NULL)
|
||||
return;
|
||||
|
||||
/* No RST for RST. */
|
||||
if (oth->rst)
|
||||
return;
|
||||
|
||||
/* Check checksum */
|
||||
if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP))
|
||||
return;
|
||||
|
||||
nskb = alloc_skb(sizeof(struct iphdr) + sizeof(struct tcphdr) +
|
||||
LL_MAX_HEADER, GFP_ATOMIC);
|
||||
if (nskb == NULL)
|
||||
return;
|
||||
|
||||
skb_reserve(nskb, LL_MAX_HEADER);
|
||||
skb_reset_network_header(nskb);
|
||||
niph = (struct iphdr *)skb_put(nskb, sizeof(struct iphdr));
|
||||
niph->version = 4;
|
||||
niph->ihl = sizeof(struct iphdr) / 4;
|
||||
niph->tos = 0;
|
||||
niph->id = 0;
|
||||
niph->frag_off = htons(IP_DF);
|
||||
niph->protocol = IPPROTO_TCP;
|
||||
niph->check = 0;
|
||||
niph->saddr = oiph->daddr;
|
||||
niph->daddr = oiph->saddr;
|
||||
|
||||
tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
|
||||
memset(tcph, 0, sizeof(*tcph));
|
||||
tcph->source = oth->dest;
|
||||
tcph->dest = oth->source;
|
||||
tcph->doff = sizeof(struct tcphdr) / 4;
|
||||
|
||||
/* DELUDE essential part */
|
||||
if (oth->syn && !oth->ack && !oth->rst && !oth->fin) {
|
||||
tcph->syn = true;
|
||||
tcph->seq = 0;
|
||||
tcph->ack = true;
|
||||
tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin +
|
||||
oldskb->len - ip_hdrlen(oldskb) -
|
||||
(oth->doff << 2));
|
||||
} else {
|
||||
tcph->rst = true;
|
||||
if (!oth->ack) {
|
||||
tcph->seq = 0;
|
||||
tcph->ack = true;
|
||||
tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn +
|
||||
oth->fin + oldskb->len -
|
||||
ip_hdrlen(oldskb) - (oth->doff << 2));
|
||||
} else {
|
||||
tcph->seq = oth->ack_seq;
|
||||
tcph->ack = false;
|
||||
tcph->ack_seq = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 20)
|
||||
tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr), niph->saddr,
|
||||
niph->daddr, csum_partial((char *)tcph,
|
||||
sizeof(struct tcphdr), 0));
|
||||
#else
|
||||
tcph->check = tcp_v4_check(sizeof(struct tcphdr), niph->saddr,
|
||||
niph->daddr, csum_partial((char *)tcph,
|
||||
sizeof(struct tcphdr), 0));
|
||||
#endif
|
||||
|
||||
addr_type = RTN_UNSPEC;
|
||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||
if (hook != NF_INET_FORWARD || (nskb->nf_bridge != NULL &&
|
||||
nskb->nf_bridge->mask & BRNF_BRIDGED))
|
||||
#else
|
||||
if (hook != NF_INET_FORWARD)
|
||||
#endif
|
||||
addr_type = RTN_LOCAL;
|
||||
|
||||
/* ip_route_me_harder expects skb->dst to be set */
|
||||
dst_hold(oldskb->dst);
|
||||
nskb->dst = oldskb->dst;
|
||||
|
||||
if (ip_route_me_harder(nskb, addr_type))
|
||||
goto free_nskb;
|
||||
|
||||
niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
|
||||
nskb->ip_summed = CHECKSUM_NONE;
|
||||
|
||||
/* "Never happens" */
|
||||
if (nskb->len > dst_mtu(nskb->dst))
|
||||
goto free_nskb;
|
||||
|
||||
nf_ct_attach(nskb, oldskb);
|
||||
|
||||
ip_local_out(nskb);
|
||||
return;
|
||||
|
||||
free_nskb:
|
||||
kfree_skb(nskb);
|
||||
}
|
||||
|
||||
static unsigned int delude_tg(struct sk_buff *skb, const struct net_device *in,
|
||||
const struct net_device *out, unsigned int hooknum,
|
||||
const struct xt_target *target, const void *targinfo)
|
||||
{
|
||||
/* WARNING: This code causes reentry within iptables.
|
||||
This means that the iptables jump stack is now crap. We
|
||||
must return an absolute verdict. --RR */
|
||||
delude_send_reset(skb, hooknum);
|
||||
return NF_DROP;
|
||||
}
|
||||
|
||||
static struct xt_target delude_tg_reg __read_mostly = {
|
||||
.name = "DELUDE",
|
||||
.revision = 0,
|
||||
.family = AF_INET,
|
||||
.table = "filter",
|
||||
.hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD),
|
||||
.proto = IPPROTO_TCP,
|
||||
.target = delude_tg,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init delude_tg_init(void)
|
||||
{
|
||||
return xt_register_target(&delude_tg_reg);
|
||||
}
|
||||
|
||||
static void __exit delude_tg_exit(void)
|
||||
{
|
||||
xt_unregister_target(&delude_tg_reg);
|
||||
}
|
||||
|
||||
module_init(delude_tg_init);
|
||||
module_exit(delude_tg_exit);
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
|
||||
MODULE_DESCRIPTION("Xtables: Close TCP connections after handshake");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_DELUDE");
|
130
extensions/xt_ECHO.c
Normal file
130
extensions/xt_ECHO.c
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* ECHO target (RFC 862)
|
||||
* Copyright © CC Computer Consultants GmbH, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 or 3 as published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/ip.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/udp.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||
# include <linux/netfilter_bridge.h>
|
||||
#endif
|
||||
#include <net/ip.h>
|
||||
#include "compat_xtables.h"
|
||||
|
||||
static unsigned int echo_tg4(struct sk_buff *oldskb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
unsigned int hooknum, const struct xt_target *target, const void *targinfo)
|
||||
{
|
||||
const struct udphdr *oldudp;
|
||||
const struct iphdr *oldip;
|
||||
struct udphdr *newudp, oldudp_buf;
|
||||
struct iphdr *newip;
|
||||
struct sk_buff *newskb;
|
||||
unsigned int addr_type, data_len;
|
||||
void *payload;
|
||||
|
||||
/* This allows us to do the copy operation in fewer lines of code. */
|
||||
skb_linearize(oldskb);
|
||||
|
||||
oldip = ip_hdr(oldskb);
|
||||
oldudp = skb_header_pointer(oldskb, ip_hdrlen(oldskb),
|
||||
sizeof(struct udphdr), &oldudp_buf);
|
||||
if (oldudp == NULL)
|
||||
return NF_DROP;
|
||||
if (ntohs(oldudp->len) <= sizeof(struct udphdr))
|
||||
return NF_DROP;
|
||||
|
||||
newskb = alloc_skb(LL_MAX_HEADER + sizeof(struct iphdr) +
|
||||
ntohs(oldudp->len), GFP_ATOMIC);
|
||||
if (newskb == NULL)
|
||||
return NF_DROP;
|
||||
|
||||
skb_reserve(newskb, LL_MAX_HEADER);
|
||||
skb_reset_network_header(newskb);
|
||||
newip = (void *)skb_put(newskb, sizeof(struct iphdr));
|
||||
newip->version = 4;
|
||||
newip->ihl = sizeof(struct iphdr) / 4;
|
||||
newip->tos = oldip->tos;
|
||||
newip->id = 0;
|
||||
newip->frag_off = htons(IP_DF);
|
||||
newip->protocol = oldip->protocol;
|
||||
newip->check = 0;
|
||||
newip->saddr = oldip->daddr;
|
||||
newip->daddr = oldip->saddr;
|
||||
|
||||
newudp = (void *)skb_put(newskb, sizeof(struct udphdr));
|
||||
newudp->source = oldudp->dest;
|
||||
newudp->dest = oldudp->source;
|
||||
newudp->len = oldudp->len;
|
||||
newudp->check = 0;
|
||||
|
||||
data_len = htons(oldudp->len) - sizeof(*oldudp);
|
||||
payload = skb_header_pointer(oldskb, ip_hdrlen(oldskb) +
|
||||
sizeof(*oldudp), data_len, NULL);
|
||||
memcpy(skb_put(newskb, data_len), payload, data_len);
|
||||
|
||||
addr_type = RTN_UNSPEC;
|
||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||
if (hooknum != NF_INET_FORWARD || (newskb->nf_bridge != NULL &&
|
||||
newskb->nf_bridge->mask & BRNF_BRIDGED))
|
||||
#else
|
||||
if (hooknum != NF_INET_FORWARD)
|
||||
#endif
|
||||
addr_type = RTN_LOCAL;
|
||||
|
||||
/* ip_route_me_harder expects skb->dst to be set */
|
||||
dst_hold(oldskb->dst);
|
||||
newskb->dst = oldskb->dst;
|
||||
|
||||
if (ip_route_me_harder(newskb, addr_type) < 0)
|
||||
goto free_nskb;
|
||||
|
||||
newip->ttl = dst_metric(newskb->dst, RTAX_HOPLIMIT);
|
||||
newskb->ip_summed = CHECKSUM_NONE;
|
||||
|
||||
/* "Never happens" (?) */
|
||||
if (newskb->len > dst_mtu(newskb->dst))
|
||||
goto free_nskb;
|
||||
|
||||
nf_ct_attach(newskb, oldskb);
|
||||
ip_local_out(newskb);
|
||||
return NF_DROP;
|
||||
|
||||
free_nskb:
|
||||
kfree_skb(newskb);
|
||||
return NF_DROP;
|
||||
}
|
||||
|
||||
static struct xt_target echo_tg_reg __read_mostly = {
|
||||
.name = "ECHO",
|
||||
.revision = 0,
|
||||
.family = AF_INET,
|
||||
.proto = IPPROTO_UDP,
|
||||
.table = "filter",
|
||||
.target = echo_tg4,
|
||||
.targetsize = XT_ALIGN(0),
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init echo_tg_init(void)
|
||||
{
|
||||
return xt_register_target(&echo_tg_reg);
|
||||
}
|
||||
|
||||
static void __exit echo_tg_exit(void)
|
||||
{
|
||||
return xt_unregister_target(&echo_tg_reg);
|
||||
}
|
||||
|
||||
module_init(echo_tg_init);
|
||||
module_exit(echo_tg_exit);
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
|
||||
MODULE_DESCRIPTION("Xtables: ECHO diagnosis target");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_ECHO");
|
@@ -11,8 +11,9 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netfilter/nf_conntrack_common.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
//#include <net/netfilter/nf_conntrack.h>
|
||||
#include "compat_xtables.h"
|
||||
#include "xt_LOGMARK.h"
|
||||
|
||||
@@ -22,25 +23,44 @@ logmark_tg(struct sk_buff *skb, const struct net_device *in,
|
||||
const struct xt_target *target, const void *targinfo)
|
||||
{
|
||||
const struct xt_logmark_tginfo *info = targinfo;
|
||||
const struct nf_conn *ct;
|
||||
enum ip_conntrack_info ctinfo;
|
||||
|
||||
printk("<%u>%.*s", info->level, sizeof(info->prefix), info->prefix);
|
||||
printk("<%u>%.*s""nfmark=0x%x secmark=0x%x classify=0x%x",
|
||||
info->level, (unsigned int)sizeof(info->prefix), info->prefix,
|
||||
skb_nfmark(skb), skb->secmark, skb->priority);
|
||||
|
||||
if (info->flags & XT_LOGMARK_NFMARK)
|
||||
printk(" nfmark=0x%x", skb->mark);
|
||||
if (info->flags & XT_LOGMARK_CTMARK) {
|
||||
const struct nf_conn *ct;
|
||||
enum ip_conntrack_info ctinfo;
|
||||
ct = nf_ct_get(skb, &ctinfo);
|
||||
if (ct == NULL) {
|
||||
printk(" ct=NULL ctmark=NULL ctstate=INVALID ctstatus=NONE");
|
||||
} else if (ct == &nf_conntrack_untracked) {
|
||||
printk(" ct=UNTRACKED ctmark=NULL ctstate=UNTRACKED ctstatus=NONE");
|
||||
} else {
|
||||
printk(" ct=0x%p ctmark=0x%x ctstate=", ct, ct->mark);
|
||||
ctinfo %= IP_CT_IS_REPLY;
|
||||
if (ctinfo == IP_CT_NEW)
|
||||
printk("NEW");
|
||||
else if (ctinfo == IP_CT_ESTABLISHED)
|
||||
printk("ESTABLISHED");
|
||||
else if (ctinfo == IP_CT_RELATED)
|
||||
printk("RELATED");
|
||||
if (test_bit(IPS_SRC_NAT_BIT, &ct->status))
|
||||
printk(",SNAT");
|
||||
if (test_bit(IPS_DST_NAT_BIT, &ct->status))
|
||||
printk(",DNAT");
|
||||
|
||||
ct = nf_ct_get(skb, &ctinfo);
|
||||
if (ct == NULL)
|
||||
printk(" ctmark=X");
|
||||
else
|
||||
printk(" ctmark=0x%x", ct->mark);
|
||||
printk(" ctstatus=");
|
||||
if (ct->status & IPS_EXPECTED)
|
||||
printk("EXPECTED");
|
||||
if (ct->status & IPS_SEEN_REPLY)
|
||||
printk(",SEEN_REPLY");
|
||||
if (ct->status & IPS_ASSURED)
|
||||
printk(",ASSURED");
|
||||
if (ct->status & IPS_CONFIRMED)
|
||||
printk(",CONFIRMED");
|
||||
}
|
||||
if (info->flags & XT_LOGMARK_SECMARK)
|
||||
printk(" secmark=0x%x", skb->secmark);
|
||||
printk("\n");
|
||||
|
||||
printk("\n");
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
|
@@ -1,16 +1,9 @@
|
||||
#ifndef _LINUX_NETFILTER_XT_LOGMARK_TARGET_H
|
||||
#define _LINUX_NETFILTER_XT_LOGMARK_TARGET_H 1
|
||||
|
||||
enum {
|
||||
XT_LOGMARK_NFMARK = 1 << 0,
|
||||
XT_LOGMARK_CTMARK = 1 << 1,
|
||||
XT_LOGMARK_SECMARK = 1 << 2,
|
||||
};
|
||||
|
||||
struct xt_logmark_tginfo {
|
||||
char prefix[14];
|
||||
u_int8_t level;
|
||||
u_int8_t flags;
|
||||
};
|
||||
|
||||
#endif /* _LINUX_NETFILTER_XT_LOGMARK_TARGET_H */
|
||||
|
@@ -90,7 +90,7 @@ static inline void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
|
||||
|
||||
/* This packet will not be the same as the other: clear nf fields */
|
||||
nf_reset(nskb);
|
||||
nskb->mark = 0;
|
||||
skb_nfmark(nskb) = 0;
|
||||
skb_init_secmark(nskb);
|
||||
|
||||
skb_shinfo(nskb)->gso_size = 0;
|
||||
@@ -132,9 +132,15 @@ static inline void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
|
||||
|
||||
/* Adjust TCP checksum */
|
||||
tcph->check = 0;
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 20)
|
||||
tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr), niph->saddr,
|
||||
niph->daddr, csum_partial((char *)tcph,
|
||||
sizeof(struct tcphdr), 0));
|
||||
#else
|
||||
tcph->check = tcp_v4_check(sizeof(struct tcphdr), niph->saddr,
|
||||
niph->daddr, csum_partial((char *)tcph,
|
||||
sizeof(struct tcphdr), 0));
|
||||
#endif
|
||||
|
||||
/* Set DF, id = 0 */
|
||||
niph->frag_off = htons(IP_DF);
|
||||
|
@@ -62,7 +62,7 @@ static bool tee_routing(struct sk_buff *skb,
|
||||
};
|
||||
|
||||
/* Trying to route the packet using the standard routing table. */
|
||||
err = ip_route_output_key(&rt, &fl);
|
||||
err = ip_route_output_key(&init_net, &rt, &fl);
|
||||
if (err != 0) {
|
||||
if (net_ratelimit())
|
||||
pr_debug(KBUILD_MODNAME
|
||||
|
246
extensions/xt_geoip.c
Normal file
246
extensions/xt_geoip.c
Normal file
@@ -0,0 +1,246 @@
|
||||
/* iptables kernel module for the geoip match
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (c) 2004, 2005, 2006, 2007, 2008
|
||||
* Samuel Jean & Nicolas Bouliane
|
||||
*/
|
||||
#include <linux/ip.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include "xt_geoip.h"
|
||||
#include "compat_xtables.h"
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Nicolas Bouliane");
|
||||
MODULE_AUTHOR("Samuel Jean");
|
||||
MODULE_DESCRIPTION("xtables module for geoip match");
|
||||
MODULE_ALIAS("ipt_geoip");
|
||||
|
||||
struct geoip_country_kernel {
|
||||
struct list_head list;
|
||||
struct geoip_subnet *subnets;
|
||||
atomic_t ref;
|
||||
unsigned int count;
|
||||
unsigned short cc;
|
||||
};
|
||||
|
||||
static LIST_HEAD(geoip_head);
|
||||
static DEFINE_SPINLOCK(geoip_lock);
|
||||
|
||||
static struct geoip_country_kernel *
|
||||
geoip_add_node(const struct geoip_country_user __user *umem_ptr)
|
||||
{
|
||||
struct geoip_country_user umem;
|
||||
struct geoip_country_kernel *p;
|
||||
struct geoip_subnet *s;
|
||||
|
||||
if (copy_from_user(&umem, umem_ptr, sizeof(umem)) != 0)
|
||||
return NULL;
|
||||
|
||||
p = kmalloc(sizeof(struct geoip_country_kernel), GFP_KERNEL);
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
p->count = umem.count;
|
||||
p->cc = umem.cc;
|
||||
|
||||
s = vmalloc(p->count * sizeof(struct geoip_subnet));
|
||||
if (s == NULL)
|
||||
goto free_p;
|
||||
if (copy_from_user(s, (const void __user *)(unsigned long)umem.subnets,
|
||||
p->count * sizeof(struct geoip_subnet)) != 0)
|
||||
goto free_s;
|
||||
|
||||
p->subnets = s;
|
||||
atomic_set(&p->ref, 1);
|
||||
INIT_LIST_HEAD(&p->list);
|
||||
|
||||
spin_lock(&geoip_lock);
|
||||
list_add_tail_rcu(&p->list, &geoip_head);
|
||||
spin_unlock(&geoip_lock);
|
||||
|
||||
return p;
|
||||
|
||||
free_s:
|
||||
vfree(s);
|
||||
free_p:
|
||||
kfree(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void geoip_try_remove_node(struct geoip_country_kernel *p)
|
||||
{
|
||||
spin_lock(&geoip_lock);
|
||||
if (!atomic_dec_and_test(&p->ref)) {
|
||||
spin_unlock(&geoip_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* So now am unlinked or the only one alive, right ?
|
||||
* What are you waiting ? Free up some memory!
|
||||
*/
|
||||
list_del_rcu(&p->list);
|
||||
spin_unlock(&geoip_lock);
|
||||
|
||||
synchronize_rcu();
|
||||
vfree(p->subnets);
|
||||
kfree(p);
|
||||
}
|
||||
|
||||
static struct geoip_country_kernel *find_node(unsigned short cc)
|
||||
{
|
||||
struct geoip_country_kernel *p;
|
||||
spin_lock(&geoip_lock);
|
||||
|
||||
list_for_each_entry_rcu(p, &geoip_head, list)
|
||||
if (p->cc == cc) {
|
||||
atomic_inc(&p->ref);
|
||||
spin_unlock(&geoip_lock);
|
||||
return p;
|
||||
}
|
||||
|
||||
spin_unlock(&geoip_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool geoip_bsearch(const struct geoip_subnet *range,
|
||||
uint32_t addr, int lo, int hi)
|
||||
{
|
||||
int mid;
|
||||
|
||||
if (hi < lo)
|
||||
return false;
|
||||
mid = (lo + hi) / 2;
|
||||
if (range[mid].begin <= addr && addr <= range[mid].end)
|
||||
return true;
|
||||
if (range[mid].begin > addr)
|
||||
return geoip_bsearch(range, addr, lo, mid - 1);
|
||||
else if (range[mid].end < addr)
|
||||
return geoip_bsearch(range, addr, mid + 1, hi);
|
||||
|
||||
WARN_ON(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool xt_geoip_mt(const struct sk_buff *skb, const struct net_device *in,
|
||||
const struct net_device *out, const struct xt_match *match,
|
||||
const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
|
||||
{
|
||||
const struct xt_geoip_match_info *info = matchinfo;
|
||||
const struct geoip_country_kernel *node;
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
unsigned int i;
|
||||
uint32_t ip;
|
||||
|
||||
if (info->flags & XT_GEOIP_SRC)
|
||||
ip = ntohl(iph->saddr);
|
||||
else
|
||||
ip = ntohl(iph->daddr);
|
||||
|
||||
rcu_read_lock();
|
||||
for (i = 0; i < info->count; i++) {
|
||||
if ((node = info->mem[i].kernel) == NULL) {
|
||||
printk(KERN_ERR "xt_geoip: what the hell ?? '%c%c' isn't loaded into memory... skip it!\n",
|
||||
COUNTRY(info->cc[i]));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (geoip_bsearch(node->subnets, ip, 0, node->count)) {
|
||||
rcu_read_unlock();
|
||||
return !(info->flags & XT_GEOIP_INV);
|
||||
}
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
return info->flags & XT_GEOIP_INV;
|
||||
}
|
||||
|
||||
static bool xt_geoip_mt_checkentry(const char *table, const void *entry,
|
||||
const struct xt_match *match, void *matchinfo, unsigned int hook_mask)
|
||||
{
|
||||
struct xt_geoip_match_info *info = matchinfo;
|
||||
struct geoip_country_kernel *node;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < info->count; i++) {
|
||||
node = find_node(info->cc[i]);
|
||||
if (node == NULL)
|
||||
if ((node = geoip_add_node((const void __user *)(unsigned long)info->mem[i].user)) == NULL) {
|
||||
printk(KERN_ERR
|
||||
"xt_geoip: unable to load '%c%c' into memory\n",
|
||||
COUNTRY(info->cc[i]));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Overwrite the now-useless pointer info->mem[i] with
|
||||
* a pointer to the node's kernelspace structure.
|
||||
* This avoids searching for a node in the match() and
|
||||
* destroy() functions.
|
||||
*/
|
||||
info->mem[i].kernel = node;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void xt_geoip_mt_destroy(const struct xt_match *match, void *matchinfo)
|
||||
{
|
||||
struct xt_geoip_match_info *info = matchinfo;
|
||||
struct geoip_country_kernel *node;
|
||||
unsigned int i;
|
||||
|
||||
/* This entry has been removed from the table so
|
||||
* decrease the refcount of all countries it is
|
||||
* using.
|
||||
*/
|
||||
|
||||
for (i = 0; i < info->count; i++)
|
||||
if ((node = info->mem[i].kernel) != NULL) {
|
||||
/* Free up some memory if that node isn't used
|
||||
* anymore. */
|
||||
geoip_try_remove_node(node);
|
||||
}
|
||||
else
|
||||
/* Something strange happened. There's no memory allocated for this
|
||||
* country. Please send this bug to the mailing list. */
|
||||
printk(KERN_ERR
|
||||
"xt_geoip: What happened peejix ? What happened acidfu ?\n"
|
||||
"xt_geoip: please report this bug to the maintainers\n");
|
||||
}
|
||||
|
||||
static struct xt_match xt_geoip_match __read_mostly = {
|
||||
.family = AF_INET,
|
||||
.name = "geoip",
|
||||
.match = xt_geoip_mt,
|
||||
.checkentry = xt_geoip_mt_checkentry,
|
||||
.destroy = xt_geoip_mt_destroy,
|
||||
.matchsize = sizeof(struct xt_geoip_match_info),
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init xt_geoip_mt_init(void)
|
||||
{
|
||||
return xt_register_match(&xt_geoip_match);
|
||||
}
|
||||
|
||||
static void __exit xt_geoip_mt_fini(void)
|
||||
{
|
||||
xt_unregister_match(&xt_geoip_match);
|
||||
}
|
||||
|
||||
module_init(xt_geoip_mt_init);
|
||||
module_exit(xt_geoip_mt_fini);
|
54
extensions/xt_geoip.h
Normal file
54
extensions/xt_geoip.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* ipt_geoip.h header file for libipt_geoip.c and ipt_geoip.c
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (c) 2004, 2005, 2006, 2007, 2008
|
||||
*
|
||||
* Samuel Jean
|
||||
* Nicolas Bouliane
|
||||
*/
|
||||
#ifndef _LINUX_NETFILTER_XT_GEOIP_H
|
||||
#define _LINUX_NETFILTER_XT_GEOIP_H 1
|
||||
|
||||
enum {
|
||||
XT_GEOIP_SRC = 1 << 0, /* Perform check on Source IP */
|
||||
XT_GEOIP_DST = 1 << 1, /* Perform check on Destination IP */
|
||||
XT_GEOIP_INV = 1 << 2, /* Negate the condition */
|
||||
|
||||
XT_GEOIP_MAX = 15, /* Maximum of countries */
|
||||
};
|
||||
|
||||
/* Yup, an address range will be passed in with host-order */
|
||||
struct geoip_subnet {
|
||||
__u32 begin;
|
||||
__u32 end;
|
||||
};
|
||||
|
||||
struct geoip_country_user {
|
||||
aligned_u64 subnets;
|
||||
__u32 count;
|
||||
__u16 cc;
|
||||
};
|
||||
|
||||
struct geoip_country_kernel;
|
||||
|
||||
union geoip_country_group {
|
||||
aligned_u64 user;
|
||||
struct geoip_country_kernel *kernel;
|
||||
};
|
||||
|
||||
struct xt_geoip_match_info {
|
||||
__u8 flags;
|
||||
__u8 count;
|
||||
__u16 cc[XT_GEOIP_MAX];
|
||||
|
||||
/* Used internally by the kernel */
|
||||
union geoip_country_group mem[XT_GEOIP_MAX];
|
||||
};
|
||||
|
||||
#define COUNTRY(cc) (cc >> 8), (cc & 0x00FF)
|
||||
|
||||
#endif /* _LINUX_NETFILTER_XT_GEOIP_H */
|
262
extensions/xt_portscan.c
Normal file
262
extensions/xt_portscan.c
Normal file
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* portscan match for netfilter
|
||||
* Copyright © CC Computer Consultants GmbH, 2006 - 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License; either version
|
||||
* 2 or 3 as published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/in.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_tcpudp.h>
|
||||
//#include <net/netfilter/nf_conntrack.h>
|
||||
#include "xt_portscan.h"
|
||||
#include "compat_xtables.h"
|
||||
#define PFX KBUILD_MODNAME ": "
|
||||
|
||||
enum {
|
||||
TCP_FLAGS_ALL3 = TCP_FLAG_FIN | TCP_FLAG_RST | TCP_FLAG_SYN,
|
||||
TCP_FLAGS_ALL4 = TCP_FLAGS_ALL3 | TCP_FLAG_ACK,
|
||||
TCP_FLAGS_ALL6 = TCP_FLAGS_ALL4 | TCP_FLAG_PSH | TCP_FLAG_URG,
|
||||
};
|
||||
|
||||
/* Module parameters */
|
||||
static unsigned int
|
||||
connmark_mask = ~0,
|
||||
packet_mask = ~0,
|
||||
mark_seen = 0x9,
|
||||
mark_synrcv = 0x1,
|
||||
mark_closed = 0x2,
|
||||
mark_synscan = 0x3,
|
||||
mark_estab1 = 0x4,
|
||||
mark_estab2 = 0x5,
|
||||
mark_cnscan = 0x6,
|
||||
mark_grscan = 0x7,
|
||||
mark_valid = 0x8;
|
||||
|
||||
module_param(connmark_mask, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(packet_mask, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_seen, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_synrcv, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_closed, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_synscan, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_estab1, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_estab2, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_cnscan, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_grscan, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(mark_valid, uint, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(connmark_mask, "only set specified bits in connection mark");
|
||||
MODULE_PARM_DESC(packet_mask, "only set specified bits in packet mark");
|
||||
MODULE_PARM_DESC(mark_seen, "nfmark value for packet-seen state");
|
||||
MODULE_PARM_DESC(mark_synrcv, "connmark value for SYN Received state");
|
||||
MODULE_PARM_DESC(mark_closed, "connmark value for closed state");
|
||||
MODULE_PARM_DESC(mark_synscan, "connmark value for SYN Scan state");
|
||||
MODULE_PARM_DESC(mark_estab1, "connmark value for Established-1 state");
|
||||
MODULE_PARM_DESC(mark_estab2, "connmark value for Established-2 state");
|
||||
MODULE_PARM_DESC(mark_cnscan, "connmark value for Connect Scan state");
|
||||
MODULE_PARM_DESC(mark_grscan, "connmark value for Grab Scan state");
|
||||
MODULE_PARM_DESC(mark_valid, "connmark value for Valid state");
|
||||
|
||||
/* TCP flag functions */
|
||||
static inline bool tflg_ack4(const struct tcphdr *th)
|
||||
{
|
||||
return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_ACK;
|
||||
}
|
||||
|
||||
static inline bool tflg_ack6(const struct tcphdr *th)
|
||||
{
|
||||
return (tcp_flag_word(th) & TCP_FLAGS_ALL6) == TCP_FLAG_ACK;
|
||||
}
|
||||
|
||||
static inline bool tflg_fin(const struct tcphdr *th)
|
||||
{
|
||||
return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_FIN;
|
||||
}
|
||||
|
||||
static inline bool tflg_rst(const struct tcphdr *th)
|
||||
{
|
||||
return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_RST;
|
||||
}
|
||||
|
||||
static inline bool tflg_rstack(const struct tcphdr *th)
|
||||
{
|
||||
return (tcp_flag_word(th) & TCP_FLAGS_ALL4) ==
|
||||
(TCP_FLAG_ACK | TCP_FLAG_RST);
|
||||
}
|
||||
|
||||
static inline bool tflg_syn(const struct tcphdr *th)
|
||||
{
|
||||
return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_SYN;
|
||||
}
|
||||
|
||||
static inline bool tflg_synack(const struct tcphdr *th)
|
||||
{
|
||||
return (tcp_flag_word(th) & TCP_FLAGS_ALL4) ==
|
||||
(TCP_FLAG_SYN | TCP_FLAG_ACK);
|
||||
}
|
||||
|
||||
/* portscan functions */
|
||||
static inline bool portscan_mt_stealth(const struct tcphdr *th)
|
||||
{
|
||||
/*
|
||||
* "Connection refused" replies to our own probes must not be matched.
|
||||
*/
|
||||
if (tflg_rstack(th))
|
||||
return false;
|
||||
|
||||
if (tflg_rst(th) && printk_ratelimit()) {
|
||||
printk(KERN_WARNING PFX "Warning: Pure RST received\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* -p tcp ! --syn -m conntrack --ctstate INVALID: Looking for non-start
|
||||
* packets that are not associated with any connection -- this will
|
||||
* match most scan types (NULL, XMAS, FIN) and ridiculous flag
|
||||
* combinations (SYN-RST, SYN-FIN, SYN-FIN-RST, FIN-RST, etc.).
|
||||
*/
|
||||
return !tflg_syn(th);
|
||||
}
|
||||
|
||||
static inline unsigned int portscan_mt_full(int mark,
|
||||
enum ip_conntrack_info ctstate, bool loopback, const struct tcphdr *tcph,
|
||||
unsigned int payload_len)
|
||||
{
|
||||
if (mark == mark_estab2) {
|
||||
/*
|
||||
* -m connmark --mark $ESTAB2
|
||||
*/
|
||||
if (tflg_ack4(tcph) && payload_len == 0)
|
||||
return mark; /* keep mark */
|
||||
else if (tflg_rst(tcph) || tflg_fin(tcph))
|
||||
return mark_grscan;
|
||||
else
|
||||
return mark_valid;
|
||||
} else if (mark == mark_estab1) {
|
||||
/*
|
||||
* -m connmark --mark $ESTAB1
|
||||
*/
|
||||
if (tflg_rst(tcph) || tflg_fin(tcph))
|
||||
return mark_cnscan;
|
||||
else if (!loopback && tflg_ack4(tcph) && payload_len == 0)
|
||||
return mark_estab2;
|
||||
else
|
||||
return mark_valid;
|
||||
} else if (mark == mark_synrcv) {
|
||||
/*
|
||||
* -m connmark --mark $SYN
|
||||
*/
|
||||
if (loopback && tflg_synack(tcph))
|
||||
return mark; /* keep mark */
|
||||
else if (loopback && tflg_rstack(tcph))
|
||||
return mark_closed;
|
||||
else if (tflg_ack6(tcph))
|
||||
return mark_estab1;
|
||||
else
|
||||
return mark_synscan;
|
||||
} else if (ctstate == IP_CT_NEW && tflg_syn(tcph)) {
|
||||
/*
|
||||
* -p tcp --syn --ctstate NEW
|
||||
*/
|
||||
return mark_synrcv;
|
||||
}
|
||||
return mark;
|
||||
}
|
||||
|
||||
static bool portscan_mt(const struct sk_buff *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
const struct xt_match *match, const void *matchinfo, int offset,
|
||||
unsigned int protoff, bool *hotdrop)
|
||||
{
|
||||
const struct xt_portscan_mtinfo *info = matchinfo;
|
||||
enum ip_conntrack_info ctstate;
|
||||
const struct tcphdr *tcph;
|
||||
struct nf_conn *ctdata;
|
||||
struct tcphdr tcph_buf;
|
||||
|
||||
tcph = skb_header_pointer(skb, protoff, sizeof(tcph_buf), &tcph_buf);
|
||||
if (tcph == NULL)
|
||||
return false;
|
||||
|
||||
/* Check for invalid packets: -m conntrack --ctstate INVALID */
|
||||
if ((ctdata = nf_ct_get(skb, &ctstate)) == NULL) {
|
||||
if (info->match_stealth)
|
||||
return portscan_mt_stealth(tcph);
|
||||
/*
|
||||
* If @ctdata is NULL, we cannot match the other scan
|
||||
* types, return.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If -m portscan was previously applied to this packet, the rules we
|
||||
* simulate must not be run through again. And for speedup, do not call
|
||||
* it either when the connection is already VALID.
|
||||
*/
|
||||
if ((ctdata->mark & connmark_mask) == mark_valid ||
|
||||
(skb_nfmark(skb) & packet_mask) != mark_seen) {
|
||||
unsigned int n;
|
||||
|
||||
n = portscan_mt_full(ctdata->mark & connmark_mask, ctstate,
|
||||
in == init_net__loopback_dev, tcph,
|
||||
skb->len - protoff - 4 * tcph->doff);
|
||||
|
||||
ctdata->mark = (ctdata->mark & ~connmark_mask) | n;
|
||||
skb_nfmark(skb) = (skb_nfmark(skb) & ~packet_mask) ^ mark_seen;
|
||||
}
|
||||
|
||||
return (info->match_syn && ctdata->mark == mark_synscan) ||
|
||||
(info->match_cn && ctdata->mark == mark_cnscan) ||
|
||||
(info->match_gr && ctdata->mark == mark_grscan);
|
||||
}
|
||||
|
||||
static bool portscan_mt_check(const char *tablename, const void *entry,
|
||||
const struct xt_match *match, void *matchinfo, unsigned int hook_mask)
|
||||
{
|
||||
const struct xt_portscan_mtinfo *info = matchinfo;
|
||||
|
||||
if ((info->match_stealth & ~1) || (info->match_syn & ~1) ||
|
||||
(info->match_cn & ~1) || (info->match_gr & ~1)) {
|
||||
printk(KERN_WARNING PFX "Invalid flags\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct xt_match portscan_mt_reg __read_mostly = {
|
||||
.name = "portscan",
|
||||
.revision = 0,
|
||||
.family = AF_INET,
|
||||
.match = portscan_mt,
|
||||
.checkentry = portscan_mt_check,
|
||||
.matchsize = sizeof(struct xt_portscan_mtinfo),
|
||||
.proto = IPPROTO_TCP,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init portscan_mt_init(void)
|
||||
{
|
||||
return xt_register_match(&portscan_mt_reg);
|
||||
}
|
||||
|
||||
static void __exit portscan_mt_exit(void)
|
||||
{
|
||||
xt_unregister_match(&portscan_mt_reg);
|
||||
return;
|
||||
}
|
||||
|
||||
module_init(portscan_mt_init);
|
||||
module_exit(portscan_mt_exit);
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
|
||||
MODULE_DESCRIPTION("netfilter \"portscan\" match");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_portscan");
|
8
extensions/xt_portscan.h
Normal file
8
extensions/xt_portscan.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef _LINUX_NETFILTER_XT_PORTSCAN_H
|
||||
#define _LINUX_NETFILTER_XT_PORTSCAN_H 1
|
||||
|
||||
struct xt_portscan_mtinfo {
|
||||
uint8_t match_stealth, match_syn, match_cn, match_gr;
|
||||
};
|
||||
|
||||
#endif /* _LINUX_NETFILTER_XT_PORTSCAN_H */
|
13
mconfig
Normal file
13
mconfig
Normal file
@@ -0,0 +1,13 @@
|
||||
# -*- Makefile -*-
|
||||
#
|
||||
# Only "build_${name}=m" (build extensions) or "build_${name}="
|
||||
# (do not build) are valid!
|
||||
#
|
||||
build_CHAOS=m
|
||||
build_DELUDE=m
|
||||
build_ECHO=
|
||||
build_LOGMARK=m
|
||||
build_TARPIT=m
|
||||
build_TEE=m
|
||||
build_geoip=m
|
||||
build_portscan=m
|
83
xa-download-more
Executable file
83
xa-download-more
Executable file
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use HTTP::Request;
|
||||
use LWP::UserAgent;
|
||||
use strict;
|
||||
|
||||
&main(\@ARGV);
|
||||
|
||||
sub main ($)
|
||||
{
|
||||
local *FH;
|
||||
|
||||
if (!-d "downloads") {
|
||||
if (!mkdir("downloads")) {
|
||||
die "Could not create downloads/ directory";
|
||||
}
|
||||
}
|
||||
|
||||
open(FH, "<sources");
|
||||
while (defined($_ = <FH>)) {
|
||||
chomp $_;
|
||||
$_ =~ s/#.*//gs;
|
||||
$_ =~ s/^\s+|\s+$//gs;
|
||||
if (length($_) == 0) {
|
||||
next;
|
||||
}
|
||||
&process_index($_);
|
||||
}
|
||||
|
||||
close FH;
|
||||
}
|
||||
|
||||
sub process_index ($)
|
||||
{
|
||||
my $top = shift @_;
|
||||
my($agent, $res, $url);
|
||||
local *FH;
|
||||
|
||||
$agent = LWP::UserAgent->new();
|
||||
$agent->env_proxy();
|
||||
|
||||
$url = &slash_remove("$top/xa-index.txt");
|
||||
print " GET $url\n";
|
||||
$res = $agent->get($url);
|
||||
if (!$res->is_success()) {
|
||||
print STDERR " `-> ", $res->status_line(), "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
foreach my $ext (split(/\s+/, $res->content())) {
|
||||
my($ex_url, $ex_res);
|
||||
|
||||
$ex_url = &slash_remove("$top/$ext");
|
||||
print " GET $ex_url\n";
|
||||
|
||||
$ex_res = $agent->mirror($ex_url, "downloads/$ext");
|
||||
if ($ex_res->code() == 304) {
|
||||
# "Not modified" = up to date
|
||||
next;
|
||||
}
|
||||
if (!$ex_res->is_success()) {
|
||||
print STDERR " `-> ", $ex_res->status_line(), "\n";
|
||||
next;
|
||||
}
|
||||
|
||||
print " UNPACK downloads/$ext\n";
|
||||
system "tar", "-xjf", "downloads/$ext";
|
||||
}
|
||||
}
|
||||
|
||||
sub slash_remove ($)
|
||||
{
|
||||
my $s = shift @_;
|
||||
$s =~ s{(\w+://)(.*)}{$1.&slash_remove2($2)}eg;
|
||||
return $s;
|
||||
}
|
||||
|
||||
sub slash_remove2 ($)
|
||||
{
|
||||
my $s = shift @_;
|
||||
$s =~ s{/+}{/}g;
|
||||
return $s;
|
||||
}
|
Reference in New Issue
Block a user