mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-20 19:44:56 +02:00
Compare commits
32 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
515dd81d8f | ||
![]() |
a2d22c427f | ||
![]() |
7fcbbe7dee | ||
![]() |
b78a309bcc | ||
![]() |
c024c6b16e | ||
![]() |
19b15a5261 | ||
![]() |
df9d3c994e | ||
![]() |
bcdb7ed4e9 | ||
![]() |
8db01220fd | ||
![]() |
95ff9a2de3 | ||
![]() |
2f1e094125 | ||
![]() |
37b000182f | ||
![]() |
255a310536 | ||
![]() |
3a6e73e986 | ||
![]() |
0a97126f5b | ||
![]() |
2ba833fe47 | ||
![]() |
77240e0918 | ||
![]() |
651e60f8d7 | ||
![]() |
54ac2a899a | ||
![]() |
61d2be172d | ||
![]() |
093f3b0a97 | ||
![]() |
57d25f22f1 | ||
![]() |
2f18ab31ec | ||
![]() |
12d0a8702c | ||
![]() |
35ce1adf5e | ||
![]() |
e5fe0b9c14 | ||
![]() |
cd7fc84b29 | ||
![]() |
4ff5a8fbf6 | ||
![]() |
37e3a543a9 | ||
![]() |
5f6cbbc663 | ||
![]() |
a2676585da | ||
![]() |
4a8aab6aed |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
*.gcno
|
||||
*.la
|
||||
*.lo
|
||||
*.loT
|
||||
|
@@ -1,4 +1,4 @@
|
||||
AC_INIT([xtables-addons], [1.44])
|
||||
AC_INIT([xtables-addons], [1.47.1])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
@@ -31,7 +31,7 @@ xtlibdir="$(pkg-config --variable=xtlibdir xtables)"
|
||||
|
||||
AC_ARG_WITH([xtlibdir],
|
||||
AS_HELP_STRING([--with-xtlibdir=PATH],
|
||||
[Path where to install Xtables extensions [[autodetect]]]]),
|
||||
[Path where to install Xtables extensions [[autodetect]]]),
|
||||
[xtlibdir="$withval"])
|
||||
AC_MSG_CHECKING([Xtables module directory])
|
||||
AC_MSG_RESULT([$xtlibdir])
|
||||
@@ -63,8 +63,8 @@ if test -n "$kbuilddir"; then
|
||||
echo "WARNING: Version detection did not succeed. Continue at own luck.";
|
||||
else
|
||||
echo "$kmajor.$kminor.$kmicro.$kstable in $kbuilddir";
|
||||
if test "$kmajor" -gt 3 -o "$kmajor" -eq 3 -a "$kminor" -gt 4; then
|
||||
echo "WARNING: You are trying a newer kernel. Results may vary. :-)";
|
||||
if test "$kmajor" -gt 3 -o "$kmajor" -eq 3 -a "$kminor" -gt 6; then
|
||||
echo "WARNING: That kernel version is not officially supported.";
|
||||
elif test "$kmajor" -eq 3; then
|
||||
:;
|
||||
elif test "$kmajor" -eq 2 -a "$kminor" -eq 6 -a "$kmicro" -ge 32; then
|
||||
|
@@ -1,6 +1,84 @@
|
||||
|
||||
HEAD
|
||||
====
|
||||
Changes
|
||||
- remove unmaintained RAWSNAT/RAWDNAT code
|
||||
Fixes:
|
||||
- xt_quota2: --no-change should not alter quota to zero ever
|
||||
- xt_quota2: --packet should not be set to zero based on skb->len
|
||||
|
||||
|
||||
v2.3 (2013-06-18)
|
||||
=================
|
||||
Enhancements:
|
||||
- Support for Linux 3.10
|
||||
Fixes:
|
||||
- xt_DNETMAP, xt_condition, xt_quota2: resolve compile error when
|
||||
CONFIG_UIDGID_STRICT_TYPE_CHECKS=y
|
||||
- xt_RAWNAT: ensure correct operation in the presence of IPv4 options
|
||||
- xt_geoip: do not throw a warnings when country database is size 0
|
||||
- xt_quota2: print "!" at the correct position during iptables-save
|
||||
Changes:
|
||||
- Make print (iptables -L) output the same as save (-S)
|
||||
|
||||
|
||||
v2.2 (2013-03-31)
|
||||
=================
|
||||
Enhancements:
|
||||
- Support for Linux 3.9
|
||||
- iptaccount: fix entire program being erroneously optimized away on PPC
|
||||
|
||||
|
||||
v2.1 (2012-11-27)
|
||||
=================
|
||||
Fixes:
|
||||
- DNETMAP: fix compile error with Linux 3.7
|
||||
Enhancements:
|
||||
- Support for Linux 3.8
|
||||
|
||||
|
||||
v2.0 (2012-11-12)
|
||||
=================
|
||||
Changes:
|
||||
- remove support for Linux 2.6.17–3.6
|
||||
- remove xt_TEE (this is available upstream since 2.6.35)
|
||||
- remove xt_CHECKSUM (this is available upstream since 2.6.36)
|
||||
Enhancements:
|
||||
- Support for Linux 3.7
|
||||
|
||||
If you want to use Xtables-addons with kernels older than 3.7,
|
||||
use the addons 1.x series, which continues to be maintained for
|
||||
the time being.
|
||||
>>>>>>> fb3e550... doc: add xt_quota2 changelog items
|
||||
|
||||
|
||||
v1.47.1 (2010-10-15)
|
||||
====================
|
||||
Enhancements:
|
||||
- xt_psd gained IPv6 support
|
||||
Notes for this release:
|
||||
- Linux 3.7+ is expressly unsupported by this release.
|
||||
|
||||
|
||||
v1.46 (2012-08-23)
|
||||
==================
|
||||
Fixes:
|
||||
- length2, SYSRQ, RAWNAT: preinitialize values for ipv6_find_hdr
|
||||
- TARPIT: fix memory leak when tarpit_generic() fails
|
||||
- build: remove extraneous closing bracket in configure.ac
|
||||
- doc: update xt_SYSRQ.man to reflect that the full IPv6 address is needed
|
||||
Enhancements:
|
||||
- Support for Linux 3.6
|
||||
|
||||
|
||||
v1.45 (2012-07-16)
|
||||
==================
|
||||
Fixes:
|
||||
- build: export missing functions
|
||||
(fixes: "WARNING 'xtnu_ipv6_find_hdr' [xt_TARPIT.ko] not found")
|
||||
- build: avoid use of unexported functions
|
||||
(fixes: "WARNING 'ipv6_find_hdr' [xt_TARPIT.ko] not found"
|
||||
in <= linux-2.6.37)
|
||||
|
||||
|
||||
v1.44 (2012-07-15)
|
||||
|
@@ -16,12 +16,7 @@ obj-${build_ECHO} += xt_ECHO.o
|
||||
endif
|
||||
obj-${build_IPMARK} += xt_IPMARK.o
|
||||
obj-${build_LOGMARK} += xt_LOGMARK.o
|
||||
obj-${build_RAWNAT} += xt_RAWNAT.o iptable_rawpost.o
|
||||
ifneq (${CONFIG_IP6_NF_IPTABLES},)
|
||||
obj-${build_RAWNAT} += ip6table_rawpost.o
|
||||
endif
|
||||
obj-${build_SYSRQ} += xt_SYSRQ.o
|
||||
obj-${build_STEAL} += xt_STEAL.o
|
||||
obj-${build_TARPIT} += xt_TARPIT.o
|
||||
obj-${build_TEE} += xt_TEE.o
|
||||
obj-${build_condition} += xt_condition.o
|
||||
|
@@ -9,8 +9,6 @@ obj-${build_DNETMAP} += libxt_DNETMAP.so
|
||||
obj-${build_ECHO} += libxt_ECHO.so
|
||||
obj-${build_IPMARK} += libxt_IPMARK.so
|
||||
obj-${build_LOGMARK} += libxt_LOGMARK.so
|
||||
obj-${build_RAWNAT} += libxt_RAWDNAT.so libxt_RAWSNAT.so
|
||||
obj-${build_STEAL} += libxt_STEAL.so
|
||||
obj-${build_SYSRQ} += libxt_SYSRQ.so
|
||||
obj-${build_TARPIT} += libxt_TARPIT.so
|
||||
obj-${build_TEE} += libxt_TEE.so
|
||||
|
@@ -1,87 +0,0 @@
|
||||
#ifndef XTA_COMPAT_RAWPOST_H
|
||||
#define XTA_COMPAT_RAWPOST_H 1
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
|
||||
typedef struct sk_buff sk_buff_t;
|
||||
#else
|
||||
typedef struct sk_buff *sk_buff_t;
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 21)
|
||||
#define XT_TARGET_INIT(__name, __size) \
|
||||
{ \
|
||||
.target.u.user = { \
|
||||
.target_size = XT_ALIGN(__size), \
|
||||
.name = __name, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define IPT_ENTRY_INIT(__size) \
|
||||
{ \
|
||||
.target_offset = sizeof(struct ipt_entry), \
|
||||
.next_offset = (__size), \
|
||||
}
|
||||
|
||||
#define IPT_STANDARD_INIT(__verdict) \
|
||||
{ \
|
||||
.entry = IPT_ENTRY_INIT(sizeof(struct ipt_standard)), \
|
||||
.target = XT_TARGET_INIT(IPT_STANDARD_TARGET, \
|
||||
sizeof(struct xt_standard_target)), \
|
||||
.target.verdict = -(__verdict) - 1, \
|
||||
}
|
||||
|
||||
#define IPT_ERROR_INIT \
|
||||
{ \
|
||||
.entry = IPT_ENTRY_INIT(sizeof(struct ipt_error)), \
|
||||
.target = XT_TARGET_INIT(IPT_ERROR_TARGET, \
|
||||
sizeof(struct ipt_error_target)), \
|
||||
.target.errorname = "ERROR", \
|
||||
}
|
||||
|
||||
#define IP6T_ENTRY_INIT(__size) \
|
||||
{ \
|
||||
.target_offset = sizeof(struct ip6t_entry), \
|
||||
.next_offset = (__size), \
|
||||
}
|
||||
|
||||
#define IP6T_STANDARD_INIT(__verdict) \
|
||||
{ \
|
||||
.entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_standard)), \
|
||||
.target = XT_TARGET_INIT(IP6T_STANDARD_TARGET, \
|
||||
sizeof(struct ip6t_standard_target)), \
|
||||
.target.verdict = -(__verdict) - 1, \
|
||||
}
|
||||
|
||||
#define IP6T_ERROR_INIT \
|
||||
{ \
|
||||
.entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_error)), \
|
||||
.target = XT_TARGET_INIT(IP6T_ERROR_TARGET, \
|
||||
sizeof(struct ip6t_error_target)), \
|
||||
.target.errorname = "ERROR", \
|
||||
}
|
||||
|
||||
#endif /* 2.6.21 */
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 20)
|
||||
# include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
/* Standard entry */
|
||||
struct ip6t_standard
|
||||
{
|
||||
struct ip6t_entry entry;
|
||||
struct ip6t_standard_target target;
|
||||
};
|
||||
|
||||
struct ip6t_error_target
|
||||
{
|
||||
struct ip6t_entry_target target;
|
||||
char errorname[IP6T_FUNCTION_MAXNAMELEN];
|
||||
};
|
||||
|
||||
struct ip6t_error
|
||||
{
|
||||
struct ip6t_entry entry;
|
||||
struct ip6t_error_target target;
|
||||
};
|
||||
#endif /* 2.6.20 */
|
||||
|
||||
#endif /* XTA_COMPAT_RAWPOST_H */
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* API compat layer
|
||||
* written by Jan Engelhardt <jengelh [at] medozas de>, 2008 - 2010
|
||||
* written by Jan Engelhardt, 2008 - 2010
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License, either
|
||||
@@ -623,6 +623,7 @@ int xtnu_ipv6_skip_exthdr(const struct sk_buff *skb, int start,
|
||||
{
|
||||
return ipv6_skip_exthdr(skb, start, nexthdrp);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_ipv6_skip_exthdr);
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) && defined(WITH_IPV6)
|
||||
@@ -631,6 +632,7 @@ int xtnu_ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
|
||||
{
|
||||
return ipv6_find_hdr(skb, offset, target, fragoff);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_ipv6_find_hdr);
|
||||
#endif
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* rawpost table for ip6_tables
|
||||
* written by Jan Engelhardt <jengelh [at] medozas de>, 2008 - 2009
|
||||
* placed in the Public Domain
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
#include <net/ip.h>
|
||||
#include "compat_xtables.h"
|
||||
#include "compat_rawpost.h"
|
||||
|
||||
enum {
|
||||
RAWPOST_VALID_HOOKS = 1 << NF_INET_POST_ROUTING,
|
||||
};
|
||||
|
||||
static struct {
|
||||
struct ip6t_replace repl;
|
||||
struct ip6t_standard entries[1];
|
||||
struct ip6t_error term;
|
||||
} rawpost6_initial __initdata = {
|
||||
.repl = {
|
||||
.name = "rawpost",
|
||||
.valid_hooks = RAWPOST_VALID_HOOKS,
|
||||
.num_entries = 2,
|
||||
.size = sizeof(struct ip6t_standard) +
|
||||
sizeof(struct ip6t_error),
|
||||
.hook_entry = {
|
||||
[NF_INET_POST_ROUTING] = 0,
|
||||
},
|
||||
.underflow = {
|
||||
[NF_INET_POST_ROUTING] = 0,
|
||||
},
|
||||
},
|
||||
.entries = {
|
||||
IP6T_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */
|
||||
},
|
||||
.term = IP6T_ERROR_INIT, /* ERROR */
|
||||
};
|
||||
|
||||
static struct xt_table *rawpost6_ptable;
|
||||
|
||||
static struct xt_table rawpost6_itable = {
|
||||
.name = "rawpost",
|
||||
.af = NFPROTO_IPV6,
|
||||
.valid_hooks = RAWPOST_VALID_HOOKS,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static unsigned int rawpost6_hook_fn(unsigned int hook, sk_buff_t *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
|
||||
return ip6t_do_table(skb, hook, in, out, rawpost6_ptable);
|
||||
#else
|
||||
return ip6t_do_table(skb, hook, in, out, rawpost6_ptable, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct nf_hook_ops rawpost6_hook_ops __read_mostly = {
|
||||
.hook = rawpost6_hook_fn,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP6_PRI_LAST,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init rawpost6_table_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 29)
|
||||
rwlock_init(&rawpost6_itable.lock);
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
|
||||
rawpost6_ptable = ip6t_register_table(&init_net, &rawpost6_itable,
|
||||
&rawpost6_initial.repl);
|
||||
if (IS_ERR(rawpost6_ptable))
|
||||
return PTR_ERR(rawpost6_ptable);
|
||||
#else
|
||||
ret = ip6t_register_table(&rawpost6_itable, &rawpost6_initial.repl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
rawpost6_ptable = &rawpost6_itable;
|
||||
#endif
|
||||
|
||||
ret = nf_register_hook(&rawpost6_hook_ops);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
return ret;
|
||||
|
||||
out:
|
||||
ip6t_unregister_table(rawpost6_ptable);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit rawpost6_table_exit(void)
|
||||
{
|
||||
nf_unregister_hook(&rawpost6_hook_ops);
|
||||
ip6t_unregister_table(rawpost6_ptable);
|
||||
}
|
||||
|
||||
module_init(rawpost6_table_init);
|
||||
module_exit(rawpost6_table_exit);
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_LICENSE("GPL");
|
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* rawpost table for ip_tables
|
||||
* written by Jan Engelhardt <jengelh [at] medozas de>, 2008 - 2009
|
||||
* placed in the Public Domain
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/version.h>
|
||||
#include <net/ip.h>
|
||||
#include "compat_xtables.h"
|
||||
#include "compat_rawpost.h"
|
||||
|
||||
enum {
|
||||
RAWPOST_VALID_HOOKS = 1 << NF_INET_POST_ROUTING,
|
||||
};
|
||||
|
||||
static struct {
|
||||
struct ipt_replace repl;
|
||||
struct ipt_standard entries[1];
|
||||
struct ipt_error term;
|
||||
} rawpost4_initial __initdata = {
|
||||
.repl = {
|
||||
.name = "rawpost",
|
||||
.valid_hooks = RAWPOST_VALID_HOOKS,
|
||||
.num_entries = 2,
|
||||
.size = sizeof(struct ipt_standard) +
|
||||
sizeof(struct ipt_error),
|
||||
.hook_entry = {
|
||||
[NF_INET_POST_ROUTING] = 0,
|
||||
},
|
||||
.underflow = {
|
||||
[NF_INET_POST_ROUTING] = 0,
|
||||
},
|
||||
},
|
||||
.entries = {
|
||||
IPT_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */
|
||||
},
|
||||
.term = IPT_ERROR_INIT, /* ERROR */
|
||||
};
|
||||
|
||||
static struct xt_table *rawpost4_ptable;
|
||||
|
||||
static struct xt_table rawpost4_itable = {
|
||||
.name = "rawpost",
|
||||
.af = NFPROTO_IPV4,
|
||||
.valid_hooks = RAWPOST_VALID_HOOKS,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static unsigned int rawpost4_hook_fn(unsigned int hook, sk_buff_t *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
|
||||
return ipt_do_table(skb, hook, in, out, rawpost4_ptable);
|
||||
#else
|
||||
return ipt_do_table(skb, hook, in, out, rawpost4_ptable, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct nf_hook_ops rawpost4_hook_ops __read_mostly = {
|
||||
.hook = rawpost4_hook_fn,
|
||||
.pf = NFPROTO_IPV4,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP_PRI_LAST,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init rawpost4_table_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 29)
|
||||
rwlock_init(&rawpost4_itable.lock);
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
|
||||
rawpost4_ptable = ipt_register_table(&init_net, &rawpost4_itable,
|
||||
&rawpost4_initial.repl);
|
||||
if (IS_ERR(rawpost4_ptable))
|
||||
return PTR_ERR(rawpost4_ptable);
|
||||
#else
|
||||
ret = ipt_register_table(&rawpost4_itable, &rawpost4_initial.repl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
rawpost4_ptable = &rawpost4_itable;
|
||||
#endif
|
||||
|
||||
ret = nf_register_hook(&rawpost4_hook_ops);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
return ret;
|
||||
|
||||
out:
|
||||
ipt_unregister_table(rawpost4_ptable);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit rawpost4_table_exit(void)
|
||||
{
|
||||
nf_unregister_hook(&rawpost4_hook_ops);
|
||||
ipt_unregister_table(rawpost4_ptable);
|
||||
}
|
||||
|
||||
module_init(rawpost4_table_init);
|
||||
module_exit(rawpost4_table_exit);
|
||||
MODULE_DESCRIPTION("Xtables: rawpost table for use with RAWNAT");
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_LICENSE("GPL");
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* "CHAOS" target extension for iptables
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2006 - 2008
|
||||
* Copyright © Jan Engelhardt, 2006 - 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
|
@@ -17,5 +17,5 @@ connections than they can.
|
||||
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.
|
||||
.PP
|
||||
See http://jengelh.medozas.de/projects/chaostables/ for more information
|
||||
See http://inai.de/projects/chaostables/ for more information
|
||||
about CHAOS, DELUDE and lscan.
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* "DELUDE" target extension for iptables
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2006 - 2008
|
||||
* Copyright © Jan Engelhardt, 2006 - 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* "DHCPMAC" target extension for iptables
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
||||
* Copyright © Jan Engelhardt, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* "ECHO" target extension for iptables
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
||||
* Copyright © Jan Engelhardt, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* "IPMARK" target extension for iptables
|
||||
* Copyright © Grzegorz Janoszka <Grzegorz.Janoszka@pro.onet.pl>, 2003
|
||||
* Jan Engelhardt <jengelh [at] medozas de>, 2008
|
||||
* Jan Engelhardt, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* "LOGMARK" target extension for iptables
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
||||
* Copyright © Jan Engelhardt, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
|
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* "RAWNAT" target extension for iptables
|
||||
* Copyright © Jan Engelhardt, 2008 - 2009
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <netinet/in.h>
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include "xt_RAWNAT.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
enum {
|
||||
FLAGS_TO = 1 << 0,
|
||||
};
|
||||
|
||||
static const struct option rawdnat_tg_opts[] = {
|
||||
{.name = "to-destination", .has_arg = true, .val = 't'},
|
||||
{},
|
||||
};
|
||||
|
||||
static void rawdnat_tg_help(void)
|
||||
{
|
||||
printf(
|
||||
"RAWDNAT target options:\n"
|
||||
" --to-destination addr[/mask] Address or network to map to\n"
|
||||
);
|
||||
}
|
||||
|
||||
static int
|
||||
rawdnat_tg4_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_rawnat_tginfo *info = (void *)(*target)->data;
|
||||
struct in_addr *a;
|
||||
unsigned int mask;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case 't':
|
||||
info->mask = 32;
|
||||
end = strchr(optarg, '/');
|
||||
if (end != NULL) {
|
||||
*end++ = '\0';
|
||||
if (!xtables_strtoui(end, NULL, &mask, 0, 32))
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWDNAT",
|
||||
"--to-destination", optarg);
|
||||
info->mask = mask;
|
||||
}
|
||||
a = xtables_numeric_to_ipaddr(optarg);
|
||||
if (a == NULL)
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWDNAT",
|
||||
"--to-destination", optarg);
|
||||
memcpy(&info->addr.in, a, sizeof(*a));
|
||||
*flags |= FLAGS_TO;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
rawdnat_tg6_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_rawnat_tginfo *info = (void *)(*target)->data;
|
||||
struct in6_addr *a;
|
||||
unsigned int mask;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case 't':
|
||||
info->mask = 128;
|
||||
end = strchr(optarg, '/');
|
||||
if (end != NULL) {
|
||||
*end++ = '\0';
|
||||
if (!xtables_strtoui(end, NULL, &mask, 0, 128))
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWDNAT",
|
||||
"--to-destination", optarg);
|
||||
info->mask = mask;
|
||||
}
|
||||
a = xtables_numeric_to_ip6addr(optarg);
|
||||
if (a == NULL)
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWDNAT",
|
||||
"--to-destination", optarg);
|
||||
memcpy(&info->addr.in6, a, sizeof(*a));
|
||||
*flags |= FLAGS_TO;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void rawdnat_tg_check(unsigned int flags)
|
||||
{
|
||||
if (!(flags & FLAGS_TO))
|
||||
xtables_error(PARAMETER_PROBLEM, "RAWDNAT: "
|
||||
"\"--to-destination\" is required.");
|
||||
}
|
||||
|
||||
static void
|
||||
rawdnat_tg4_print(const void *entry, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
if (!numeric && info->mask == 32)
|
||||
printf(" to-destination %s ",
|
||||
xtables_ipaddr_to_anyname(&info->addr.in));
|
||||
else
|
||||
printf(" to-destination %s/%u ",
|
||||
xtables_ipaddr_to_numeric(&info->addr.in), info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawdnat_tg6_print(const void *entry, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
if (!numeric && info->mask == 128)
|
||||
printf(" to-destination %s ",
|
||||
xtables_ip6addr_to_anyname(&info->addr.in6));
|
||||
else
|
||||
printf(" to-destination %s/%u ",
|
||||
xtables_ip6addr_to_numeric(&info->addr.in6), info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawdnat_tg4_save(const void *entry, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
printf(" --to-destination %s/%u ",
|
||||
xtables_ipaddr_to_numeric(&info->addr.in),
|
||||
info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawdnat_tg6_save(const void *entry, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
printf(" --to-destination %s/%u ",
|
||||
xtables_ip6addr_to_numeric(&info->addr.in6),
|
||||
info->mask);
|
||||
}
|
||||
|
||||
static struct xtables_target rawdnat_tg_reg[] = {
|
||||
{
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "RAWDNAT",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.help = rawdnat_tg_help,
|
||||
.parse = rawdnat_tg4_parse,
|
||||
.final_check = rawdnat_tg_check,
|
||||
.print = rawdnat_tg4_print,
|
||||
.save = rawdnat_tg4_save,
|
||||
.extra_opts = rawdnat_tg_opts,
|
||||
},
|
||||
{
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "RAWDNAT",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV6,
|
||||
.size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.help = rawdnat_tg_help,
|
||||
.parse = rawdnat_tg6_parse,
|
||||
.final_check = rawdnat_tg_check,
|
||||
.print = rawdnat_tg6_print,
|
||||
.save = rawdnat_tg6_save,
|
||||
.extra_opts = rawdnat_tg_opts,
|
||||
},
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
{
|
||||
xtables_register_targets(rawdnat_tg_reg,
|
||||
sizeof(rawdnat_tg_reg) / sizeof(*rawdnat_tg_reg));
|
||||
}
|
@@ -1,10 +0,0 @@
|
||||
The \fBRAWDNAT\fR target will rewrite the destination address in the IP header,
|
||||
much like the \fBNETMAP\fR target.
|
||||
.TP
|
||||
\fB\-\-to\-destination\fR \fIaddr\fR[\fB/\fR\fImask\fR]
|
||||
Network address to map to. The resulting address will be constructed the
|
||||
following way: All 'one' bits in the \fImask\fR are filled in from the new
|
||||
\fIaddress\fR. All bits that are zero in the mask are filled in from the
|
||||
original address.
|
||||
.PP
|
||||
See the \fBRAWSNAT\fR help entry for examples and constraints.
|
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* "RAWNAT" target extension for iptables
|
||||
* Copyright © Jan Engelhardt, 2008 - 2009
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <netinet/in.h>
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <xtables.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include "xt_RAWNAT.h"
|
||||
#include "compat_user.h"
|
||||
|
||||
enum {
|
||||
FLAGS_TO = 1 << 0,
|
||||
};
|
||||
|
||||
static const struct option rawsnat_tg_opts[] = {
|
||||
{.name = "to-source", .has_arg = true, .val = 't'},
|
||||
{},
|
||||
};
|
||||
|
||||
static void rawsnat_tg_help(void)
|
||||
{
|
||||
printf(
|
||||
"RAWSNAT target options:\n"
|
||||
" --to-source addr[/mask] Address or network to map to\n"
|
||||
);
|
||||
}
|
||||
|
||||
static int
|
||||
rawsnat_tg4_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_rawnat_tginfo *info = (void *)(*target)->data;
|
||||
struct in_addr *a;
|
||||
unsigned int mask;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case 't':
|
||||
info->mask = 32;
|
||||
end = strchr(optarg, '/');
|
||||
if (end != NULL) {
|
||||
*end++ = '\0';
|
||||
if (!xtables_strtoui(end, NULL, &mask, 0, 32))
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWSNAT",
|
||||
"--to-source", optarg);
|
||||
info->mask = mask;
|
||||
}
|
||||
a = xtables_numeric_to_ipaddr(optarg);
|
||||
if (a == NULL)
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWSNAT",
|
||||
"--to-source", optarg);
|
||||
memcpy(&info->addr.in, a, sizeof(*a));
|
||||
*flags |= FLAGS_TO;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
rawsnat_tg6_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct xt_rawnat_tginfo *info = (void *)(*target)->data;
|
||||
struct in6_addr *a;
|
||||
unsigned int mask;
|
||||
char *end;
|
||||
|
||||
switch (c) {
|
||||
case 't':
|
||||
info->mask = 128;
|
||||
end = strchr(optarg, '/');
|
||||
if (end != NULL) {
|
||||
*end++ = '\0';
|
||||
if (!xtables_strtoui(end, NULL, &mask, 0, 128))
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWSNAT",
|
||||
"--to-source", optarg);
|
||||
info->mask = mask;
|
||||
}
|
||||
a = xtables_numeric_to_ip6addr(optarg);
|
||||
if (a == NULL)
|
||||
xtables_param_act(XTF_BAD_VALUE, "RAWSNAT",
|
||||
"--to-source", optarg);
|
||||
memcpy(&info->addr.in6, a, sizeof(*a));
|
||||
*flags |= FLAGS_TO;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void rawsnat_tg_check(unsigned int flags)
|
||||
{
|
||||
if (!(flags & FLAGS_TO))
|
||||
xtables_error(PARAMETER_PROBLEM, "RAWSNAT: "
|
||||
"\"--to-source\" is required.");
|
||||
}
|
||||
|
||||
static void
|
||||
rawsnat_tg4_print(const void *entry, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
if (!numeric && info->mask == 32)
|
||||
printf(" to-source %s ",
|
||||
xtables_ipaddr_to_anyname(&info->addr.in));
|
||||
else
|
||||
printf(" to-source %s/%u ",
|
||||
xtables_ipaddr_to_numeric(&info->addr.in), info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawsnat_tg6_print(const void *entry, const struct xt_entry_target *target,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
if (!numeric && info->mask == 128)
|
||||
printf(" to-source %s ",
|
||||
xtables_ip6addr_to_anyname(&info->addr.in6));
|
||||
else
|
||||
printf(" to-source %s/%u ",
|
||||
xtables_ip6addr_to_numeric(&info->addr.in6), info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawsnat_tg4_save(const void *entry, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
printf(" --to-source %s/%u ",
|
||||
xtables_ipaddr_to_numeric(&info->addr.in),
|
||||
info->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
rawsnat_tg6_save(const void *entry, const struct xt_entry_target *target)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = (const void *)target->data;
|
||||
|
||||
printf(" --to-source %s/%u ",
|
||||
xtables_ip6addr_to_numeric(&info->addr.in6),
|
||||
info->mask);
|
||||
}
|
||||
|
||||
static struct xtables_target rawsnat_tg_reg[] = {
|
||||
{
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "RAWSNAT",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV4,
|
||||
.size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.help = rawsnat_tg_help,
|
||||
.parse = rawsnat_tg4_parse,
|
||||
.final_check = rawsnat_tg_check,
|
||||
.print = rawsnat_tg4_print,
|
||||
.save = rawsnat_tg4_save,
|
||||
.extra_opts = rawsnat_tg_opts,
|
||||
},
|
||||
{
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "RAWSNAT",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV6,
|
||||
.size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
|
||||
.help = rawsnat_tg_help,
|
||||
.parse = rawsnat_tg6_parse,
|
||||
.final_check = rawsnat_tg_check,
|
||||
.print = rawsnat_tg6_print,
|
||||
.save = rawsnat_tg6_save,
|
||||
.extra_opts = rawsnat_tg_opts,
|
||||
},
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
{
|
||||
xtables_register_targets(rawsnat_tg_reg,
|
||||
sizeof(rawsnat_tg_reg) / sizeof(*rawsnat_tg_reg));
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
The \fBRAWSNAT\fR and \fBRAWDNAT\fP targets provide stateless network address
|
||||
translation.
|
||||
.PP
|
||||
The \fBRAWSNAT\fR target will rewrite the source address in the IP header, much
|
||||
like the \fBNETMAP\fP target. \fBRAWSNAT\fP (and \fBRAWDNAT\fP) may only be
|
||||
used in the \fBraw\fP or \fBrawpost\fP tables, but can be used in all chains,
|
||||
which makes it possible to change the source address either when the packet
|
||||
enters the machine or when it leaves it. The reason for this table constraint
|
||||
is that RAWNAT must happen outside of connection tracking.
|
||||
.TP
|
||||
\fB\-\-to\-source\fR \fIaddr\fR[\fB/\fR\fImask\fR]
|
||||
Network address to map to. The resulting address will be constructed the
|
||||
following way: All 'one' bits in the \fImask\fR are filled in from the new
|
||||
\fIaddress\fR. All bits that are zero in the mask are filled in from the
|
||||
original address.
|
||||
.PP
|
||||
As an example, changing the destination for packets forwarded from an internal
|
||||
LAN to the internet:
|
||||
.IP
|
||||
\-t raw \-A PREROUTING \-i lan0 \-d 212.201.100.135 \-j RAWDNAT \-\-to\-destination 199.181.132.250;
|
||||
\-t rawpost \-A POSTROUTING \-o lan0 \-s 199.181.132.250 \-j RAWSNAT \-\-to\-source 212.201.100.135;
|
||||
.PP
|
||||
Note that changing addresses may influence the route selection! Specifically,
|
||||
it statically NATs packets, not connections, like the normal DNAT/SNAT targets
|
||||
would do. Also note that it can transform already-NATed connections \(em as
|
||||
said, it is completely external to Netfilter's connection tracking/NAT.
|
||||
.PP
|
||||
If the machine itself generates packets that are to be rawnat'ed, you need a
|
||||
rule in the OUTPUT chain instead, just like you would with the stateful NAT
|
||||
targets.
|
||||
.PP
|
||||
It may be necessary that in doing so, you also need an extra RAWSNAT rule, to
|
||||
override the automatic source address selection that the routing code does
|
||||
before passing packets to iptables. If the connecting socket has not been
|
||||
explicitly bound to an address, as is the common mode of operation, the address
|
||||
that will be chosen is the primary address of the device through which the
|
||||
packet would be routed with its initial destination address - the address as
|
||||
seen before any RAWNAT takes place.
|
@@ -1,32 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <xtables.h>
|
||||
#include "compat_user.h"
|
||||
|
||||
static void steal_tg_help(void)
|
||||
{
|
||||
printf("STEAL takes no options\n\n");
|
||||
}
|
||||
|
||||
static int steal_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void steal_tg_check(unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
static struct xtables_target steal_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "STEAL",
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.help = steal_tg_help,
|
||||
.parse = steal_tg_parse,
|
||||
.final_check = steal_tg_check,
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
{
|
||||
xtables_register_target(&steal_tg_reg);
|
||||
}
|
@@ -1,2 +0,0 @@
|
||||
Like the DROP target, but does not throw an error like DROP when used in the
|
||||
\fBOUTPUT\fP chain.
|
@@ -62,7 +62,7 @@ password="password"
|
||||
seqno="$(date +%s)"
|
||||
salt="$(dd bs=12 count=1 if=/dev/urandom 2>/dev/null |
|
||||
openssl enc \-base64)"
|
||||
ipaddr=10.10.25.7
|
||||
ipaddr="2001:0db8:0000:0000:0000:ff00:0042:8329"
|
||||
req="$sysrq_key,$seqno,$salt"
|
||||
req="$req,$(echo \-n "$req,$ipaddr,$password" | sha1sum | cut \-c1\-40)"
|
||||
|
||||
@@ -75,8 +75,8 @@ sysrq key can be used at once, but bear in mind that, for example, a sync may
|
||||
not complete before a subsequent reboot or poweroff.
|
||||
.PP
|
||||
An IPv4 address should have no leading zeros, an IPv6 address should
|
||||
be in the form recommended by RFC 5952. The debug option will log the
|
||||
correct form of the address.
|
||||
be in the full expanded form (as shown above). The debug option will cause
|
||||
output to be emitted in the same form.
|
||||
.PP
|
||||
The hashing scheme should be enough to prevent mis-use of SYSRQ in many
|
||||
environments, but it is not perfect: take reasonable precautions to
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* "condition" match extension for iptables
|
||||
* Stephane Ouellette <ouellettes [at] videotron ca>, 2002-10-22
|
||||
* Massimiliano Hofer <max [at] nucleus it>, 2006-05-15
|
||||
* Jan Engelhardt <jengelh [at] medozas de>, 2008
|
||||
* Jan Engelhardt, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License; either version 2
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* "dhcpmac" match extension for iptables
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
||||
* Copyright © Jan Engelhardt, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* "geoip" match extension for iptables
|
||||
* Copyright © Samuel Jean <peejix [at] people netfilter org>, 2004 - 2008
|
||||
* Copyright © Nicolas Bouliane <acidfu [at] people netfilter org>, 2004 - 2008
|
||||
* Jan Engelhardt <jengelh [at] medozas de>, 2008-2011
|
||||
* Jan Engelhardt, 2008-2011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* "ipp2p" match extension for iptables
|
||||
* Eicke Friedrich/Klaus Degner <ipp2p@ipp2p.org>, 2005 - 2006
|
||||
* Jan Engelhardt <jengelh [at] medozas de>, 2008 - 2009
|
||||
* Jan Engelhardt, 2008 - 2009
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* LSCAN match extension for iptables
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2006 - 2009
|
||||
* Copyright © Jan Engelhardt, 2006 - 2009
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
|
@@ -142,7 +142,7 @@ static struct xtables_match psd_mt_reg = {
|
||||
.name = "psd",
|
||||
.version = XTABLES_VERSION,
|
||||
.revision = 1,
|
||||
.family = NFPROTO_IPV4,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.size = XT_ALIGN(sizeof(struct xt_psd_info)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_psd_info)),
|
||||
.help = psd_mt_help,
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* "quota2" match extension for iptables
|
||||
* Sam Johnston <samj [at] samj net>
|
||||
* Jan Engelhardt <jengelh [at] medozas de>, 2008
|
||||
* Jan Engelhardt, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* "CHAOS" target extension for Xtables
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2006 - 2008
|
||||
* Copyright © Jan Engelhardt, 2006 - 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
@@ -274,6 +274,6 @@ static void __exit chaos_tg_exit(void)
|
||||
module_init(chaos_tg_init);
|
||||
module_exit(chaos_tg_exit);
|
||||
MODULE_DESCRIPTION("Xtables: Network scan slowdown with non-deterministic results");
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_AUTHOR("Jan Engelhardt ");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_CHAOS");
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* "DELUDE" target extension for Xtables
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2007 - 2008
|
||||
* Copyright © Jan Engelhardt, 2007 - 2008
|
||||
*
|
||||
* Based upon linux-2.6.18.5/net/ipv4/netfilter/ipt_REJECT.c:
|
||||
* (C) 1999-2001 Paul `Rusty' Russell
|
||||
@@ -177,6 +177,6 @@ static void __exit delude_tg_exit(void)
|
||||
module_init(delude_tg_init);
|
||||
module_exit(delude_tg_exit);
|
||||
MODULE_DESCRIPTION("Xtables: Close TCP connections after handshake");
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_AUTHOR("Jan Engelhardt ");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_DELUDE");
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* "DHCPMAC" extensions for Xtables
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
||||
* Copyright © Jan Engelhardt, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
@@ -167,7 +167,7 @@ static void __exit dhcpmac_exit(void)
|
||||
module_init(dhcpmac_init);
|
||||
module_exit(dhcpmac_exit);
|
||||
MODULE_DESCRIPTION("Xtables: Clamp DHCP MAC to packet MAC addresses");
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_AUTHOR("Jan Engelhardt ");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_DHCPMAC");
|
||||
MODULE_ALIAS("ipt_dhcpmac");
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* "ECHO" (RFC 862) target extension for Xtables
|
||||
* Sample module for "Writing your own Netfilter Modules"
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008-2011
|
||||
* Copyright © Jan Engelhardt, 2008-2011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
@@ -252,7 +252,7 @@ static void __exit echo_tg_exit(void)
|
||||
|
||||
module_init(echo_tg_init);
|
||||
module_exit(echo_tg_exit);
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_AUTHOR("Jan Engelhardt ");
|
||||
MODULE_DESCRIPTION("Xtables: ECHO diagnosis target");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ip6t_ECHO");
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* "IPMARK" target extension for Xtables
|
||||
* Copyright © Grzegorz Janoszka <Grzegorz.Janoszka@pro.onet.pl>, 2003
|
||||
* Jan Engelhardt <jengelh [at] medozas de>, 2008
|
||||
* Jan Engelhardt, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* "LOGMARK" target extension to Xtables
|
||||
* useful for debugging
|
||||
*
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008-2010
|
||||
* Copyright © Jan Engelhardt, 2008-2010
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
@@ -141,7 +141,7 @@ static void __exit logmark_tg_exit(void)
|
||||
module_init(logmark_tg_init);
|
||||
module_exit(logmark_tg_exit);
|
||||
MODULE_DESCRIPTION("Xtables: netfilter mark logging to syslog");
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_AUTHOR("Jan Engelhardt ");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_LOGMARK");
|
||||
MODULE_ALIAS("ip6t_LOGMARK");
|
||||
|
@@ -1,358 +0,0 @@
|
||||
/*
|
||||
* "RAWNAT" target extension for Xtables - untracked NAT
|
||||
* Copyright © Jan Engelhardt, 2008 - 2009
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <linux/ip.h>
|
||||
#include <linux/ipv6.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/udp.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter/nf_conntrack_common.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/ipv6.h>
|
||||
#include "compat_xtables.h"
|
||||
#include "xt_RAWNAT.h"
|
||||
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
|
||||
# define WITH_IPV6 1
|
||||
#endif
|
||||
|
||||
static inline __be32
|
||||
remask(__be32 addr, __be32 repl, unsigned int shift)
|
||||
{
|
||||
uint32_t mask = (shift == 32) ? 0 : (~(uint32_t)0 >> shift);
|
||||
return htonl((ntohl(addr) & mask) | (ntohl(repl) & ~mask));
|
||||
}
|
||||
|
||||
#ifdef WITH_IPV6
|
||||
static void
|
||||
rawnat_ipv6_mask(__be32 *addr, const __be32 *repl, unsigned int mask)
|
||||
{
|
||||
switch (mask) {
|
||||
case 0:
|
||||
break;
|
||||
case 1 ... 31:
|
||||
addr[0] = remask(addr[0], repl[0], mask);
|
||||
break;
|
||||
case 32:
|
||||
addr[0] = repl[0];
|
||||
break;
|
||||
case 33 ... 63:
|
||||
addr[0] = repl[0];
|
||||
addr[1] = remask(addr[1], repl[1], mask - 32);
|
||||
break;
|
||||
case 64:
|
||||
addr[0] = repl[0];
|
||||
addr[1] = repl[1];
|
||||
break;
|
||||
case 65 ... 95:
|
||||
addr[0] = repl[0];
|
||||
addr[1] = repl[1];
|
||||
addr[2] = remask(addr[2], repl[2], mask - 64);
|
||||
case 96:
|
||||
addr[0] = repl[0];
|
||||
addr[1] = repl[1];
|
||||
addr[2] = repl[2];
|
||||
break;
|
||||
case 97 ... 127:
|
||||
addr[0] = repl[0];
|
||||
addr[1] = repl[1];
|
||||
addr[2] = repl[2];
|
||||
addr[3] = remask(addr[3], repl[3], mask - 96);
|
||||
break;
|
||||
case 128:
|
||||
addr[0] = repl[0];
|
||||
addr[1] = repl[1];
|
||||
addr[2] = repl[2];
|
||||
addr[3] = repl[3];
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void rawnat4_update_l4(struct sk_buff *skb, __be32 oldip, __be32 newip)
|
||||
{
|
||||
struct iphdr *iph = ip_hdr(skb);
|
||||
void *transport_hdr = (void *)iph + ip_hdrlen(skb);
|
||||
struct tcphdr *tcph;
|
||||
struct udphdr *udph;
|
||||
bool cond;
|
||||
|
||||
switch (iph->protocol) {
|
||||
case IPPROTO_TCP:
|
||||
tcph = transport_hdr;
|
||||
inet_proto_csum_replace4(&tcph->check, skb, oldip, newip, true);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
case IPPROTO_UDPLITE:
|
||||
udph = transport_hdr;
|
||||
cond = udph->check != 0;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
|
||||
cond |= skb->ip_summed == CHECKSUM_PARTIAL;
|
||||
#endif
|
||||
if (cond) {
|
||||
inet_proto_csum_replace4(&udph->check, skb,
|
||||
oldip, newip, true);
|
||||
if (udph->check == 0)
|
||||
udph->check = CSUM_MANGLED_0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int rawnat4_writable_part(const struct iphdr *iph)
|
||||
{
|
||||
unsigned int wlen = sizeof(*iph);
|
||||
|
||||
switch (iph->protocol) {
|
||||
case IPPROTO_TCP:
|
||||
wlen += sizeof(struct tcphdr);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
wlen += sizeof(struct udphdr);
|
||||
break;
|
||||
}
|
||||
return wlen;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
rawsnat_tg4(struct sk_buff **pskb, const struct xt_action_param *par)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = par->targinfo;
|
||||
struct iphdr *iph;
|
||||
__be32 new_addr;
|
||||
|
||||
iph = ip_hdr(*pskb);
|
||||
new_addr = remask(iph->saddr, info->addr.ip, info->mask);
|
||||
if (iph->saddr == new_addr)
|
||||
return XT_CONTINUE;
|
||||
|
||||
if (!skb_make_writable(pskb, rawnat4_writable_part(iph)))
|
||||
return NF_DROP;
|
||||
|
||||
iph = ip_hdr(*pskb);
|
||||
csum_replace4(&iph->check, iph->saddr, new_addr);
|
||||
rawnat4_update_l4(*pskb, iph->saddr, new_addr);
|
||||
iph->saddr = new_addr;
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
rawdnat_tg4(struct sk_buff **pskb, const struct xt_action_param *par)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = par->targinfo;
|
||||
struct iphdr *iph;
|
||||
__be32 new_addr;
|
||||
|
||||
iph = ip_hdr(*pskb);
|
||||
new_addr = remask(iph->daddr, info->addr.ip, info->mask);
|
||||
if (iph->daddr == new_addr)
|
||||
return XT_CONTINUE;
|
||||
|
||||
if (!skb_make_writable(pskb, rawnat4_writable_part(iph)))
|
||||
return NF_DROP;
|
||||
|
||||
iph = ip_hdr(*pskb);
|
||||
csum_replace4(&iph->check, iph->daddr, new_addr);
|
||||
rawnat4_update_l4(*pskb, iph->daddr, new_addr);
|
||||
iph->daddr = new_addr;
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
#ifdef WITH_IPV6
|
||||
static bool rawnat6_prepare_l4(struct sk_buff **pskb, unsigned int *l4offset,
|
||||
unsigned int *l4proto)
|
||||
{
|
||||
static const unsigned int types[] =
|
||||
{IPPROTO_TCP, IPPROTO_UDP, IPPROTO_UDPLITE};
|
||||
unsigned int i;
|
||||
int err;
|
||||
|
||||
*l4proto = NEXTHDR_MAX;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(types); ++i) {
|
||||
err = ipv6_find_hdr(*pskb, l4offset, types[i], NULL, NULL);
|
||||
if (err >= 0) {
|
||||
*l4proto = types[i];
|
||||
break;
|
||||
}
|
||||
if (err != -ENOENT)
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (*l4proto) {
|
||||
case IPPROTO_TCP:
|
||||
if (!skb_make_writable(pskb, *l4offset + sizeof(struct tcphdr)))
|
||||
return false;
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
case IPPROTO_UDPLITE:
|
||||
if (!skb_make_writable(pskb, *l4offset + sizeof(struct udphdr)))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void rawnat6_update_l4(struct sk_buff *skb, unsigned int l4proto,
|
||||
unsigned int l4offset, const struct in6_addr *oldip,
|
||||
const struct in6_addr *newip)
|
||||
{
|
||||
const struct ipv6hdr *iph = ipv6_hdr(skb);
|
||||
struct tcphdr *tcph;
|
||||
struct udphdr *udph;
|
||||
unsigned int i;
|
||||
bool cond;
|
||||
|
||||
switch (l4proto) {
|
||||
case IPPROTO_TCP:
|
||||
tcph = (void *)iph + l4offset;
|
||||
for (i = 0; i < 4; ++i)
|
||||
inet_proto_csum_replace4(&tcph->check, skb,
|
||||
oldip->s6_addr32[i], newip->s6_addr32[i], true);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
case IPPROTO_UDPLITE:
|
||||
udph = (void *)iph + l4offset;
|
||||
cond = udph->check;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
|
||||
cond |= skb->ip_summed == CHECKSUM_PARTIAL;
|
||||
#endif
|
||||
if (cond) {
|
||||
for (i = 0; i < 4; ++i)
|
||||
inet_proto_csum_replace4(&udph->check, skb,
|
||||
oldip->s6_addr32[i],
|
||||
newip->s6_addr32[i], true);
|
||||
if (udph->check == 0)
|
||||
udph->check = CSUM_MANGLED_0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
rawsnat_tg6(struct sk_buff **pskb, const struct xt_action_param *par)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = par->targinfo;
|
||||
unsigned int l4offset, l4proto;
|
||||
struct ipv6hdr *iph;
|
||||
struct in6_addr new_addr;
|
||||
|
||||
iph = ipv6_hdr(*pskb);
|
||||
memcpy(&new_addr, &iph->saddr, sizeof(new_addr));
|
||||
rawnat_ipv6_mask(new_addr.s6_addr32, info->addr.ip6, info->mask);
|
||||
if (ipv6_addr_cmp(&iph->saddr, &new_addr) == 0)
|
||||
return XT_CONTINUE;
|
||||
if (!rawnat6_prepare_l4(pskb, &l4offset, &l4proto))
|
||||
return NF_DROP;
|
||||
iph = ipv6_hdr(*pskb);
|
||||
rawnat6_update_l4(*pskb, l4proto, l4offset, &iph->saddr, &new_addr);
|
||||
memcpy(&iph->saddr, &new_addr, sizeof(new_addr));
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
rawdnat_tg6(struct sk_buff **pskb, const struct xt_action_param *par)
|
||||
{
|
||||
const struct xt_rawnat_tginfo *info = par->targinfo;
|
||||
unsigned int l4offset, l4proto;
|
||||
struct ipv6hdr *iph;
|
||||
struct in6_addr new_addr;
|
||||
|
||||
iph = ipv6_hdr(*pskb);
|
||||
memcpy(&new_addr, &iph->daddr, sizeof(new_addr));
|
||||
rawnat_ipv6_mask(new_addr.s6_addr32, info->addr.ip6, info->mask);
|
||||
if (ipv6_addr_cmp(&iph->daddr, &new_addr) == 0)
|
||||
return XT_CONTINUE;
|
||||
if (!rawnat6_prepare_l4(pskb, &l4offset, &l4proto))
|
||||
return NF_DROP;
|
||||
iph = ipv6_hdr(*pskb);
|
||||
rawnat6_update_l4(*pskb, l4proto, l4offset, &iph->daddr, &new_addr);
|
||||
memcpy(&iph->daddr, &new_addr, sizeof(new_addr));
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int rawnat_tg_check(const struct xt_tgchk_param *par)
|
||||
{
|
||||
if (strcmp(par->table, "raw") == 0 ||
|
||||
strcmp(par->table, "rawpost") == 0)
|
||||
return 0;
|
||||
|
||||
printk(KERN_ERR KBUILD_MODNAME " may only be used in the \"raw\" or "
|
||||
"\"rawpost\" table.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct xt_target rawnat_tg_reg[] __read_mostly = {
|
||||
{
|
||||
.name = "RAWSNAT",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV4,
|
||||
.target = rawsnat_tg4,
|
||||
.targetsize = sizeof(struct xt_rawnat_tginfo),
|
||||
.checkentry = rawnat_tg_check,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
#ifdef WITH_IPV6
|
||||
{
|
||||
.name = "RAWSNAT",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV6,
|
||||
.target = rawsnat_tg6,
|
||||
.targetsize = sizeof(struct xt_rawnat_tginfo),
|
||||
.checkentry = rawnat_tg_check,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.name = "RAWDNAT",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV4,
|
||||
.target = rawdnat_tg4,
|
||||
.targetsize = sizeof(struct xt_rawnat_tginfo),
|
||||
.checkentry = rawnat_tg_check,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
#ifdef WITH_IPV6
|
||||
{
|
||||
.name = "RAWDNAT",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV6,
|
||||
.target = rawdnat_tg6,
|
||||
.targetsize = sizeof(struct xt_rawnat_tginfo),
|
||||
.checkentry = rawnat_tg_check,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
static int __init rawnat_tg_init(void)
|
||||
{
|
||||
return xt_register_targets(rawnat_tg_reg, ARRAY_SIZE(rawnat_tg_reg));
|
||||
}
|
||||
|
||||
static void __exit rawnat_tg_exit(void)
|
||||
{
|
||||
xt_unregister_targets(rawnat_tg_reg, ARRAY_SIZE(rawnat_tg_reg));
|
||||
}
|
||||
|
||||
module_init(rawnat_tg_init);
|
||||
module_exit(rawnat_tg_exit);
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_DESCRIPTION("Xtables: conntrack-less raw NAT");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_RAWSNAT");
|
||||
MODULE_ALIAS("ipt_RAWDNAT");
|
||||
MODULE_ALIAS("ip6t_RAWSNAT");
|
||||
MODULE_ALIAS("ip6t_RAWDNAT");
|
@@ -1,9 +0,0 @@
|
||||
#ifndef _LINUX_NETFILTER_XT_TARGET_RAWNAT
|
||||
#define _LINUX_NETFILTER_XT_TARGET_RAWNAT 1
|
||||
|
||||
struct xt_rawnat_tginfo {
|
||||
union nf_inet_addr addr;
|
||||
__u8 mask;
|
||||
};
|
||||
|
||||
#endif /* _LINUX_NETFILTER_XT_TARGET_RAWNAT */
|
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* "STEAL" demo target extension for Xtables
|
||||
* written by Jan Engelhardt <jengelh [at] medozas de>, 2008 - 2009
|
||||
* placed in the Public Domain
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include "compat_xtables.h"
|
||||
|
||||
static unsigned int
|
||||
steal_tg(struct sk_buff **pskb, const struct xt_action_param *par)
|
||||
{
|
||||
kfree_skb(*pskb);
|
||||
return NF_STOLEN;
|
||||
}
|
||||
|
||||
static struct xt_target steal_tg_reg[] __read_mostly = {
|
||||
{
|
||||
.name = "STEAL",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_UNSPEC,
|
||||
.target = steal_tg,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
{
|
||||
.name = "STEAL",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_IPV6,
|
||||
.target = steal_tg,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
{
|
||||
.name = "STEAL",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_ARP,
|
||||
.target = steal_tg,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
{
|
||||
.name = "STEAL",
|
||||
.revision = 0,
|
||||
.family = NFPROTO_BRIDGE,
|
||||
.target = steal_tg,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init steal_tg_init(void)
|
||||
{
|
||||
return xt_register_targets(steal_tg_reg, ARRAY_SIZE(steal_tg_reg));
|
||||
}
|
||||
|
||||
static void __exit steal_tg_exit(void)
|
||||
{
|
||||
xt_unregister_targets(steal_tg_reg, ARRAY_SIZE(steal_tg_reg));
|
||||
}
|
||||
|
||||
module_init(steal_tg_init);
|
||||
module_exit(steal_tg_exit);
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_DESCRIPTION("Xtables: Silently DROP packets on output chain");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_STEAL");
|
||||
MODULE_ALIAS("ip6t_STEAL");
|
||||
MODULE_ALIAS("arpt_STEAL");
|
||||
MODULE_ALIAS("ebt_STEAL");
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* "SYSRQ" target extension for Xtables
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008 - 2010
|
||||
* Copyright © Jan Engelhardt, 2008 - 2010
|
||||
*
|
||||
* Based upon the ipt_SYSRQ idea by Marek Zalem <marek [at] terminus sk>
|
||||
*
|
||||
@@ -240,7 +240,7 @@ sysrq_tg6(struct sk_buff **pskb, const struct xt_action_param *par)
|
||||
const struct ipv6hdr *iph;
|
||||
const struct udphdr *udph;
|
||||
unsigned short frag_off;
|
||||
unsigned int th_off;
|
||||
unsigned int th_off = 0;
|
||||
uint16_t len;
|
||||
|
||||
if (skb_linearize(skb) < 0)
|
||||
@@ -386,7 +386,7 @@ static void __exit sysrq_tg_exit(void)
|
||||
module_init(sysrq_tg_init);
|
||||
module_exit(sysrq_tg_exit);
|
||||
MODULE_DESCRIPTION("Xtables: triggering SYSRQ remotely");
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_AUTHOR("Jan Engelhardt ");
|
||||
MODULE_AUTHOR("John Haxby <john.haxby@oracle.com");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_SYSRQ");
|
||||
|
@@ -237,7 +237,7 @@ static void tarpit_tcp4(struct sk_buff *oldskb, unsigned int hook,
|
||||
((u_int8_t *)tcph)[13] = 0;
|
||||
|
||||
if (!tarpit_generic(tcph, oth, payload, mode))
|
||||
return;
|
||||
goto free_nskb;
|
||||
|
||||
/* Adjust TCP checksum */
|
||||
tcph->check = 0;
|
||||
@@ -374,16 +374,15 @@ static void tarpit_tcp6(struct sk_buff *oldskb, unsigned int hook,
|
||||
ip6h->daddr = oip6h->saddr;
|
||||
|
||||
/* Adjust IP TTL */
|
||||
if (mode == XTTARPIT_HONEYPOT)
|
||||
if (mode == XTTARPIT_HONEYPOT) {
|
||||
ip6h->hop_limit = 128;
|
||||
else
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
|
||||
} else {
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
|
||||
ip6h->hop_limit = ip6_dst_hoplimit(skb_dst(nskb));
|
||||
#else
|
||||
ip6h->hop_limit = dst_metric(dst, RTAX_HOPLIMIT);
|
||||
if (ip6h->hop_limit < 0)
|
||||
ip6h->hop_limit = ipv6_get_hoplimit((skb_dst(nskb))->dev).
|
||||
ip6h->hop_limit = dst_metric(skb_dst(nskb), RTAX_HOPLIMIT);
|
||||
#endif
|
||||
}
|
||||
|
||||
tcph = (struct tcphdr *)(skb_network_header(nskb) +
|
||||
sizeof(struct ipv6hdr));
|
||||
@@ -399,7 +398,7 @@ static void tarpit_tcp6(struct sk_buff *oldskb, unsigned int hook,
|
||||
|
||||
payload = nskb->len - sizeof(struct ipv6hdr) - sizeof(struct tcphdr);
|
||||
if (!tarpit_generic(&oth, tcph, payload, mode))
|
||||
return;
|
||||
goto free_nskb;
|
||||
|
||||
ip6h->payload_len = htons(sizeof(struct tcphdr));
|
||||
tcph->check = 0;
|
||||
@@ -544,7 +543,7 @@ static void __exit tarpit_tg_exit(void)
|
||||
module_init(tarpit_tg_init);
|
||||
module_exit(tarpit_tg_exit);
|
||||
MODULE_DESCRIPTION("Xtables: \"TARPIT\", capture and hold TCP connections");
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_AUTHOR("Jan Engelhardt ");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_TARPIT");
|
||||
MODULE_ALIAS("ip6t_TARPIT");
|
||||
|
@@ -35,7 +35,7 @@ static unsigned int condition_gid_perms = 0;
|
||||
|
||||
MODULE_AUTHOR("Stephane Ouellette <ouellettes@videotron.ca>");
|
||||
MODULE_AUTHOR("Massimiliano Hofer <max@nucleus.it>");
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_AUTHOR("Jan Engelhardt ");
|
||||
MODULE_DESCRIPTION("Allows rules to match against condition variables");
|
||||
MODULE_LICENSE("GPL");
|
||||
module_param(condition_list_perms, uint, S_IRUSR | S_IWUSR);
|
||||
|
@@ -76,7 +76,7 @@ static void __exit ipv4options_mt_exit(void)
|
||||
}
|
||||
|
||||
MODULE_DESCRIPTION("Xatblse: IPv4 option match");
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_AUTHOR("Jan Engelhardt ");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_ipv4options");
|
||||
module_init(ipv4options_mt_init);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* xt_length - Xtables module to match packet length
|
||||
* Copyright © Jan Engelhardt <jengelh@medozas.de>, 2007 - 2009
|
||||
* Copyright © Jan Engelhardt , 2007 - 2009
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
@@ -29,7 +29,7 @@
|
||||
# define NEXTHDR_IPV4 4
|
||||
#endif
|
||||
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_AUTHOR("Jan Engelhardt ");
|
||||
MODULE_DESCRIPTION("Xtables: Packet length (Layer3,4,5) match");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_length2");
|
||||
@@ -203,7 +203,8 @@ length2_mt6(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
const struct xt_length_mtinfo2 *info = par->matchinfo;
|
||||
const struct ipv6hdr *iph = ipv6_hdr(skb);
|
||||
unsigned int len = 0, l4proto;
|
||||
unsigned int thoff = par->thoff;
|
||||
/* par->thoff would only set if ip6tables -p was used; so just use 0 */
|
||||
unsigned int thoff = 0;
|
||||
bool hit = true;
|
||||
|
||||
if (info->flags & XT_LENGTH_LAYER3) {
|
||||
|
@@ -264,7 +264,7 @@ static void __exit lscan_mt_exit(void)
|
||||
|
||||
module_init(lscan_mt_init);
|
||||
module_exit(lscan_mt_exit);
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_AUTHOR("Jan Engelhardt ");
|
||||
MODULE_DESCRIPTION("Xtables: Low-level scan (e.g. nmap) match");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_lscan");
|
||||
|
@@ -22,13 +22,15 @@
|
||||
|
||||
#define pr_fmt(x) KBUILD_MODNAME ": " x
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/ip.h>
|
||||
#include <net/tcp.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/ipv6.h>
|
||||
#include "xt_psd.h"
|
||||
#include "compat_xtables.h"
|
||||
|
||||
@@ -39,6 +41,7 @@ MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
|
||||
MODULE_AUTHOR(" Mohd Nawawi Mohamad Jamili <nawawi@tracenetworkcorporation.com>");
|
||||
MODULE_DESCRIPTION("Xtables: PSD - portscan detection");
|
||||
MODULE_ALIAS("ipt_psd");
|
||||
MODULE_ALIAS("ip6t_psd");
|
||||
|
||||
/*
|
||||
* Keep track of up to LIST_SIZE source addresses, using a hash table of
|
||||
@@ -50,6 +53,10 @@ MODULE_ALIAS("ipt_psd");
|
||||
#define HASH_SIZE (1 << HASH_LOG)
|
||||
#define HASH_MAX 0x10
|
||||
|
||||
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
|
||||
# define WITH_IPV6 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Information we keep per each target port
|
||||
*/
|
||||
@@ -68,8 +75,6 @@ struct port {
|
||||
struct host {
|
||||
struct host *next;
|
||||
unsigned long timestamp;
|
||||
struct in_addr src_addr;
|
||||
struct in_addr dest_addr;
|
||||
__be16 src_port;
|
||||
uint16_t count;
|
||||
uint8_t weight;
|
||||
@@ -77,27 +82,87 @@ struct host {
|
||||
};
|
||||
|
||||
/**
|
||||
* State information.
|
||||
* Information we keep per ipv4 source address.
|
||||
*/
|
||||
struct host4 {
|
||||
struct host host;
|
||||
__be32 saddr;
|
||||
};
|
||||
|
||||
static struct host4 *host_to_host4(const struct host *h)
|
||||
{
|
||||
return (struct host4 *)h;
|
||||
}
|
||||
|
||||
struct host6 {
|
||||
struct host host;
|
||||
struct in6_addr saddr;
|
||||
};
|
||||
|
||||
/**
|
||||
* State information for IPv4 portscan detection.
|
||||
* @list: list of source addresses
|
||||
* @hash: pointers into the list
|
||||
* @index: oldest entry to be replaced
|
||||
*/
|
||||
static struct {
|
||||
spinlock_t lock;
|
||||
struct host list[LIST_SIZE];
|
||||
struct host4 list[LIST_SIZE];
|
||||
struct host *hash[HASH_SIZE];
|
||||
int index;
|
||||
} state;
|
||||
|
||||
#ifdef WITH_IPV6
|
||||
/**
|
||||
* State information for IPv6 portscan detection.
|
||||
* @list: list of source addresses
|
||||
* @hash: pointers into the list
|
||||
* @index: oldest entry to be replaced
|
||||
*/
|
||||
static struct {
|
||||
spinlock_t lock;
|
||||
struct host6 *list;
|
||||
struct host **hash;
|
||||
int index;
|
||||
} state6;
|
||||
|
||||
static struct host6 *host_to_host6(const struct host *h)
|
||||
{
|
||||
return (struct host6 *) h;
|
||||
}
|
||||
|
||||
/**
|
||||
* allocate state6 memory only when needed
|
||||
*/
|
||||
static bool state6_alloc_mem(void)
|
||||
{
|
||||
if (state6.hash != NULL)
|
||||
return true;
|
||||
|
||||
state6.list = vmalloc(LIST_SIZE * sizeof(struct host6));
|
||||
if (state6.list == NULL)
|
||||
return false;
|
||||
memset(state6.list, 0, LIST_SIZE * sizeof(struct host6));
|
||||
|
||||
state6.hash = vmalloc(HASH_SIZE * sizeof(struct host*));
|
||||
if (state6.hash == NULL) {
|
||||
vfree(state6.list);
|
||||
return false;
|
||||
}
|
||||
memset(state6.hash, 0, HASH_SIZE * sizeof(struct host *));
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Convert an IP address into a hash table index.
|
||||
*/
|
||||
static inline int hashfunc(struct in_addr addr)
|
||||
static unsigned int hashfunc(__be32 addr)
|
||||
{
|
||||
unsigned int value;
|
||||
int hash;
|
||||
unsigned int hash;
|
||||
|
||||
value = addr.s_addr;
|
||||
value = addr;
|
||||
hash = 0;
|
||||
do {
|
||||
hash ^= value;
|
||||
@@ -106,133 +171,169 @@ static inline int hashfunc(struct in_addr addr)
|
||||
return hash & (HASH_SIZE - 1);
|
||||
}
|
||||
|
||||
static bool
|
||||
xt_psd_match(const struct sk_buff *pskb, struct xt_action_param *match)
|
||||
static inline unsigned int hashfunc6(const struct in6_addr *addr)
|
||||
{
|
||||
__be32 h = addr->s6_addr32[0] ^ addr->s6_addr32[1];
|
||||
return hashfunc(h ^ addr->s6_addr32[2] ^ addr->s6_addr32[3]);
|
||||
}
|
||||
|
||||
static bool port_in_list(struct host *host, uint8_t proto, uint16_t port)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < host->count; ++i) {
|
||||
if (host->ports[i].proto != proto)
|
||||
continue;
|
||||
if (host->ports[i].number == port)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint16_t get_port_weight(const struct xt_psd_info *psd, __be16 port)
|
||||
{
|
||||
return ntohs(port) < 1024 ? psd->lo_ports_weight : psd->hi_ports_weight;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_portscan(struct host *host, const struct xt_psd_info *psdinfo,
|
||||
const struct tcphdr *tcph, uint8_t proto)
|
||||
{
|
||||
if (port_in_list(host, proto, tcph->dest))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* TCP/ACK and/or TCP/RST to a new port? This could be an
|
||||
* outgoing connection.
|
||||
*/
|
||||
if (proto == IPPROTO_TCP && (tcph->ack || tcph->rst))
|
||||
return false;
|
||||
|
||||
host->timestamp = jiffies;
|
||||
|
||||
if (host->weight >= psdinfo->weight_threshold) /* already matched */
|
||||
return true;
|
||||
|
||||
/* Update the total weight */
|
||||
host->weight += get_port_weight(psdinfo, tcph->dest);
|
||||
|
||||
/* Got enough destination ports to decide that this is a scan? */
|
||||
if (host->weight >= psdinfo->weight_threshold)
|
||||
return true;
|
||||
|
||||
/* Remember the new port */
|
||||
if (host->count < ARRAY_SIZE(host->ports)) {
|
||||
host->ports[host->count].number = tcph->dest;
|
||||
host->ports[host->count].proto = proto;
|
||||
host->count++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct host *host_get_next(struct host *h, struct host **last)
|
||||
{
|
||||
if (h->next != NULL)
|
||||
*last = h;
|
||||
return h->next;
|
||||
}
|
||||
|
||||
static void ht_unlink(struct host **head, struct host *last)
|
||||
{
|
||||
if (last != NULL)
|
||||
last->next = last->next->next;
|
||||
else if (*head != NULL)
|
||||
*head = (*head)->next;
|
||||
}
|
||||
|
||||
static bool
|
||||
entry_is_recent(const struct host *h, unsigned long delay_threshold,
|
||||
unsigned long now)
|
||||
{
|
||||
return now - h->timestamp <= (delay_threshold * HZ) / 100 &&
|
||||
time_after_eq(now, h->timestamp);
|
||||
}
|
||||
|
||||
static void remove_oldest(struct host **head, struct host *curr)
|
||||
{
|
||||
struct host *h, *last = NULL;
|
||||
|
||||
/*
|
||||
* We are going to re-use the oldest list entry, so remove it from the
|
||||
* hash table first, if it is really already in use.
|
||||
*/
|
||||
h = *head;
|
||||
while (h != NULL) {
|
||||
if (curr == h)
|
||||
break;
|
||||
last = h;
|
||||
h = h->next;
|
||||
}
|
||||
|
||||
/* Then, remove it */
|
||||
if (h != NULL)
|
||||
ht_unlink(head, last);
|
||||
}
|
||||
|
||||
static void *
|
||||
get_header_pointer4(const struct sk_buff *skb, unsigned int thoff, void *mem)
|
||||
{
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
int hdrlen;
|
||||
|
||||
switch (iph->protocol) {
|
||||
case IPPROTO_TCP:
|
||||
hdrlen = sizeof(struct tcphdr);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
case IPPROTO_UDPLITE:
|
||||
hdrlen = sizeof(struct udphdr);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return skb_header_pointer(skb, thoff, hdrlen, mem);
|
||||
}
|
||||
|
||||
static bool
|
||||
handle_packet4(const struct iphdr *iph, const struct tcphdr *tcph,
|
||||
const struct xt_psd_info *psdinfo, unsigned int hash)
|
||||
{
|
||||
const struct iphdr *iph;
|
||||
const struct tcphdr *tcph = NULL;
|
||||
const struct udphdr *udph;
|
||||
union {
|
||||
struct tcphdr tcph;
|
||||
struct udphdr udph;
|
||||
} _buf;
|
||||
struct in_addr addr;
|
||||
u_int16_t src_port,dest_port;
|
||||
u_int8_t proto;
|
||||
unsigned long now;
|
||||
struct host *curr, *last, **head;
|
||||
int hash, index, count;
|
||||
/* Parameters from userspace */
|
||||
const struct xt_psd_info *psdinfo = match->matchinfo;
|
||||
|
||||
iph = ip_hdr(pskb);
|
||||
if (iph->frag_off & htons(IP_OFFSET)) {
|
||||
pr_debug("sanity check failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
proto = iph->protocol;
|
||||
addr.s_addr = iph->saddr;
|
||||
/* We're using IP address 0.0.0.0 for a special purpose here, so don't let
|
||||
* them spoof us. [DHCP needs this feature - HW] */
|
||||
if (addr.s_addr == 0) {
|
||||
pr_debug("spoofed source address (0.0.0.0)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (proto == IPPROTO_TCP) {
|
||||
tcph = skb_header_pointer(pskb, match->thoff,
|
||||
sizeof(_buf.tcph), &_buf.tcph);
|
||||
if (tcph == NULL)
|
||||
return false;
|
||||
|
||||
/* Yep, it's dirty */
|
||||
src_port = tcph->source;
|
||||
dest_port = tcph->dest;
|
||||
} else if (proto == IPPROTO_UDP || proto == IPPROTO_UDPLITE) {
|
||||
udph = skb_header_pointer(pskb, match->thoff,
|
||||
sizeof(_buf.udph), &_buf.udph);
|
||||
if (udph == NULL)
|
||||
return false;
|
||||
src_port = udph->source;
|
||||
dest_port = udph->dest;
|
||||
} else {
|
||||
pr_debug("protocol not supported\n");
|
||||
return false;
|
||||
}
|
||||
struct host *curr, *last = NULL, **head;
|
||||
struct host4 *curr4;
|
||||
int count = 0;
|
||||
|
||||
now = jiffies;
|
||||
|
||||
spin_lock(&state.lock);
|
||||
head = &state.hash[hash];
|
||||
|
||||
/* Do we know this source address already? */
|
||||
count = 0;
|
||||
last = NULL;
|
||||
if ((curr = *(head = &state.hash[hash = hashfunc(addr)])) != NULL)
|
||||
do {
|
||||
if (curr->src_addr.s_addr == addr.s_addr)
|
||||
break;
|
||||
count++;
|
||||
if (curr->next != NULL)
|
||||
last = curr;
|
||||
} while ((curr = curr->next) != NULL);
|
||||
curr = *head;
|
||||
while (curr != NULL) {
|
||||
curr4 = host_to_host4(curr);
|
||||
if (curr4->saddr == iph->saddr)
|
||||
break;
|
||||
count++;
|
||||
curr = host_get_next(curr, &last);
|
||||
}
|
||||
|
||||
if (curr != NULL) {
|
||||
/* We know this address, and the entry isn't too old. Update it. */
|
||||
if (now - curr->timestamp <= (psdinfo->delay_threshold*HZ)/100 &&
|
||||
time_after_eq(now, curr->timestamp)) {
|
||||
|
||||
/* Just update the appropriate list entry if we've seen this port already */
|
||||
for (index = 0; index < curr->count; index++) {
|
||||
if (curr->ports[index].number == dest_port) {
|
||||
curr->ports[index].proto = proto;
|
||||
goto out_no_match;
|
||||
}
|
||||
}
|
||||
|
||||
/* TCP/ACK and/or TCP/RST to a new port? This could be an outgoing connection. */
|
||||
if (proto == IPPROTO_TCP && (tcph->ack || tcph->rst))
|
||||
goto out_no_match;
|
||||
|
||||
/* Packet to a new port, and not TCP/ACK: update the timestamp */
|
||||
curr->timestamp = now;
|
||||
|
||||
/* Matched this scan already? Then Leave. */
|
||||
if (curr->weight >= psdinfo->weight_threshold)
|
||||
goto out_match;
|
||||
|
||||
/* Update the total weight */
|
||||
curr->weight += (ntohs(dest_port) < 1024) ?
|
||||
psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
|
||||
|
||||
/* Got enough destination ports to decide that this is a scan? */
|
||||
if (curr->weight >= psdinfo->weight_threshold)
|
||||
goto out_match;
|
||||
|
||||
/* Remember the new port */
|
||||
if (curr->count < ARRAY_SIZE(curr->ports)) {
|
||||
curr->ports[curr->count].number = dest_port;
|
||||
curr->ports[curr->count].proto = proto;
|
||||
curr->count++;
|
||||
}
|
||||
|
||||
goto out_no_match;
|
||||
}
|
||||
if (entry_is_recent(curr, psdinfo->delay_threshold, now))
|
||||
return is_portscan(curr, psdinfo, tcph, iph->protocol);
|
||||
|
||||
/* We know this address, but the entry is outdated. Mark it unused, and
|
||||
* remove from the hash table. We'll allocate a new entry instead since
|
||||
* this one might get re-used too soon. */
|
||||
curr->src_addr.s_addr = 0;
|
||||
if (last != NULL)
|
||||
last->next = last->next->next;
|
||||
else if (*head != NULL)
|
||||
*head = (*head)->next;
|
||||
curr4 = host_to_host4(curr);
|
||||
curr4->saddr = 0;
|
||||
ht_unlink(head, last);
|
||||
last = NULL;
|
||||
}
|
||||
|
||||
/* We don't need an ACK from a new source address */
|
||||
if (proto == IPPROTO_TCP && tcph->ack)
|
||||
goto out_no_match;
|
||||
if (iph->protocol == IPPROTO_TCP && tcph->ack)
|
||||
return false;
|
||||
|
||||
/* Got too many source addresses with the same hash value? Then remove the
|
||||
* oldest one from the hash table, so that they can't take too much of our
|
||||
@@ -240,33 +341,15 @@ xt_psd_match(const struct sk_buff *pskb, struct xt_action_param *match)
|
||||
if (count >= HASH_MAX && last != NULL)
|
||||
last->next = NULL;
|
||||
|
||||
/* We're going to re-use the oldest list entry, so remove it from the hash
|
||||
* table first (if it is really already in use, and isn't removed from the
|
||||
* hash table already because of the HASH_MAX check above). */
|
||||
|
||||
/* First, find it */
|
||||
if (state.list[state.index].src_addr.s_addr != 0)
|
||||
head = &state.hash[hashfunc(state.list[state.index].src_addr)];
|
||||
if (state.list[state.index].saddr != 0)
|
||||
head = &state.hash[hashfunc(state.list[state.index].saddr)];
|
||||
else
|
||||
head = &last;
|
||||
last = NULL;
|
||||
if ((curr = *head) != NULL)
|
||||
do {
|
||||
if (curr == &state.list[state.index])
|
||||
break;
|
||||
last = curr;
|
||||
} while ((curr = curr->next) != NULL);
|
||||
|
||||
/* Then, remove it */
|
||||
if (curr != NULL) {
|
||||
if (last != NULL)
|
||||
last->next = last->next->next;
|
||||
else if (*head != NULL)
|
||||
*head = (*head)->next;
|
||||
}
|
||||
|
||||
/* Get our list entry */
|
||||
curr = &state.list[state.index++];
|
||||
curr4 = &state.list[state.index++];
|
||||
curr = &curr4->host;
|
||||
remove_oldest(head, curr);
|
||||
if (state.index >= LIST_SIZE)
|
||||
state.index = 0;
|
||||
|
||||
@@ -276,24 +359,173 @@ xt_psd_match(const struct sk_buff *pskb, struct xt_action_param *match)
|
||||
*head = curr;
|
||||
|
||||
/* And fill in the fields */
|
||||
curr4 = host_to_host4(curr);
|
||||
curr4->saddr = iph->saddr;
|
||||
curr->timestamp = now;
|
||||
curr->src_addr = addr;
|
||||
curr->dest_addr.s_addr = iph->daddr;
|
||||
curr->src_port = src_port;
|
||||
curr->count = 1;
|
||||
curr->weight = (ntohs(dest_port) < 1024) ? psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
|
||||
curr->ports[0].number = dest_port;
|
||||
curr->ports[0].proto = proto;
|
||||
|
||||
out_no_match:
|
||||
spin_unlock(&state.lock);
|
||||
curr->weight = get_port_weight(psdinfo, tcph->dest);
|
||||
curr->ports[0].number = tcph->dest;
|
||||
curr->ports[0].proto = iph->protocol;
|
||||
return false;
|
||||
|
||||
out_match:
|
||||
spin_unlock(&state.lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
xt_psd_match(const struct sk_buff *pskb, struct xt_action_param *match)
|
||||
{
|
||||
struct iphdr *iph = ip_hdr(pskb);
|
||||
struct tcphdr _tcph;
|
||||
struct tcphdr *tcph;
|
||||
bool matched;
|
||||
unsigned int hash;
|
||||
/* Parameters from userspace */
|
||||
const struct xt_psd_info *psdinfo = match->matchinfo;
|
||||
|
||||
if (iph->frag_off & htons(IP_OFFSET)) {
|
||||
pr_debug("sanity check failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are using IP address 0.0.0.0 for a special purpose here, so do
|
||||
* not let them spoof us. [DHCP needs this feature - HW]
|
||||
*/
|
||||
if (iph->saddr == 0) {
|
||||
pr_debug("spoofed source address (0.0.0.0)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
tcph = get_header_pointer4(pskb, match->thoff, &_tcph);
|
||||
if (tcph == NULL)
|
||||
return false;
|
||||
|
||||
hash = hashfunc(iph->saddr);
|
||||
|
||||
spin_lock(&state.lock);
|
||||
matched = handle_packet4(iph, tcph, psdinfo, hash);
|
||||
spin_unlock(&state.lock);
|
||||
return matched;
|
||||
}
|
||||
|
||||
#ifdef WITH_IPV6
|
||||
static bool
|
||||
handle_packet6(const struct ipv6hdr *ip6h, const struct tcphdr *tcph,
|
||||
const struct xt_psd_info *psdinfo, uint8_t proto, int hash)
|
||||
{
|
||||
unsigned long now;
|
||||
struct host *curr, *last = NULL, **head;
|
||||
struct host6 *curr6;
|
||||
int count = 0;
|
||||
|
||||
now = jiffies;
|
||||
head = &state6.hash[hash];
|
||||
|
||||
curr = *head;
|
||||
while (curr != NULL) {
|
||||
curr6 = host_to_host6(curr);
|
||||
if (ipv6_addr_equal(&curr6->saddr, &ip6h->saddr))
|
||||
break;
|
||||
count++;
|
||||
curr = host_get_next(curr, &last);
|
||||
}
|
||||
|
||||
if (curr != NULL) {
|
||||
if (entry_is_recent(curr, psdinfo->delay_threshold, now))
|
||||
return is_portscan(curr, psdinfo, tcph, proto);
|
||||
curr6 = host_to_host6(curr);
|
||||
memset(&curr6->saddr, 0, sizeof(curr6->saddr));
|
||||
ht_unlink(head, last);
|
||||
last = NULL;
|
||||
}
|
||||
|
||||
if (proto == IPPROTO_TCP && tcph->ack)
|
||||
return false;
|
||||
|
||||
if (count >= HASH_MAX && last != NULL)
|
||||
last->next = NULL;
|
||||
|
||||
if (!ipv6_addr_any(&state6.list[state6.index].saddr))
|
||||
head = &state6.hash[hashfunc6(&state6.list[state6.index].saddr)];
|
||||
else
|
||||
head = &last;
|
||||
|
||||
curr6 = &state6.list[state6.index++];
|
||||
curr = &curr6->host;
|
||||
remove_oldest(head, curr);
|
||||
if (state6.index >= LIST_SIZE)
|
||||
state6.index = 0;
|
||||
|
||||
head = &state6.hash[hash];
|
||||
curr->next = *head;
|
||||
*head = curr;
|
||||
|
||||
curr6 = host_to_host6(curr);
|
||||
curr6->saddr = ip6h->saddr;
|
||||
curr->timestamp = now;
|
||||
curr->count = 1;
|
||||
curr->weight = get_port_weight(psdinfo, tcph->dest);
|
||||
curr->ports[0].number = tcph->dest;
|
||||
curr->ports[0].proto = proto;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void *
|
||||
get_header_pointer6(const struct sk_buff *skb, void *mem, uint8_t *proto)
|
||||
{
|
||||
static const uint8_t types[] = {IPPROTO_TCP,
|
||||
IPPROTO_UDP, IPPROTO_UDPLITE};
|
||||
unsigned int i, offset = 0;
|
||||
int err;
|
||||
size_t hdrlen;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(types); ++i) {
|
||||
err = ipv6_find_hdr(skb, &offset, types[i], NULL, NULL);
|
||||
if (err < 0)
|
||||
continue;
|
||||
|
||||
switch (types[i]) {
|
||||
case IPPROTO_TCP:
|
||||
hdrlen = sizeof(struct tcphdr);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
case IPPROTO_UDPLITE:
|
||||
hdrlen = sizeof(struct udphdr);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
*proto = types[i];
|
||||
return skb_header_pointer(skb, offset, hdrlen, mem);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
xt_psd_match6(const struct sk_buff *pskb, struct xt_action_param *match)
|
||||
{
|
||||
const struct ipv6hdr *ip6h = ipv6_hdr(pskb);
|
||||
struct tcphdr _tcph;
|
||||
struct tcphdr *tcph;
|
||||
uint8_t proto = 0;
|
||||
bool matched;
|
||||
int hash;
|
||||
const struct xt_psd_info *psdinfo = match->matchinfo;
|
||||
|
||||
if (ipv6_addr_any(&ip6h->saddr))
|
||||
return false;
|
||||
|
||||
tcph = get_header_pointer6(pskb, &_tcph, &proto);
|
||||
if (tcph == NULL)
|
||||
return false;
|
||||
|
||||
hash = hashfunc6(&ip6h->saddr);
|
||||
|
||||
spin_lock(&state6.lock);
|
||||
matched = handle_packet6(ip6h, tcph, psdinfo, proto, hash);
|
||||
spin_unlock(&state6.lock);
|
||||
return matched;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int psd_mt_check(const struct xt_mtchk_param *par)
|
||||
{
|
||||
const struct xt_psd_info *info = par->matchinfo;
|
||||
@@ -315,25 +547,53 @@ static int psd_mt_check(const struct xt_mtchk_param *par)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xt_match xt_psd_reg __read_mostly = {
|
||||
.name = "psd",
|
||||
.family = NFPROTO_IPV4,
|
||||
.revision = 1,
|
||||
.checkentry = psd_mt_check,
|
||||
.match = xt_psd_match,
|
||||
.matchsize = sizeof(struct xt_psd_info),
|
||||
.me = THIS_MODULE,
|
||||
#ifdef WITH_IPV6
|
||||
static int psd_mt_check6(const struct xt_mtchk_param *par)
|
||||
{
|
||||
if (!state6_alloc_mem())
|
||||
return -ENOMEM;
|
||||
return psd_mt_check(par);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct xt_match xt_psd_reg[] __read_mostly = {
|
||||
{
|
||||
.name = "psd",
|
||||
.family = NFPROTO_IPV4,
|
||||
.revision = 1,
|
||||
.checkentry = psd_mt_check,
|
||||
.match = xt_psd_match,
|
||||
.matchsize = sizeof(struct xt_psd_info),
|
||||
.me = THIS_MODULE,
|
||||
#ifdef WITH_IPV6
|
||||
}, {
|
||||
.name = "psd",
|
||||
.family = NFPROTO_IPV6,
|
||||
.revision = 1,
|
||||
.checkentry = psd_mt_check6,
|
||||
.match = xt_psd_match6,
|
||||
.matchsize = sizeof(struct xt_psd_info),
|
||||
.me = THIS_MODULE,
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
static int __init xt_psd_init(void)
|
||||
{
|
||||
spin_lock_init(&(state.lock));
|
||||
return xt_register_match(&xt_psd_reg);
|
||||
#ifdef WITH_IPV6
|
||||
spin_lock_init(&(state6.lock));
|
||||
#endif
|
||||
return xt_register_matches(xt_psd_reg, ARRAY_SIZE(xt_psd_reg));
|
||||
}
|
||||
|
||||
static void __exit xt_psd_exit(void)
|
||||
{
|
||||
xt_unregister_match(&xt_psd_reg);
|
||||
xt_unregister_matches(xt_psd_reg, ARRAY_SIZE(xt_psd_reg));
|
||||
#ifdef WITH_IPV6
|
||||
vfree(state6.list);
|
||||
vfree(state6.hash);
|
||||
#endif
|
||||
}
|
||||
|
||||
module_init(xt_psd_init);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* xt_quota2 - enhanced xt_quota that can count upwards and in packets
|
||||
* as a minimal accounting match.
|
||||
* by Jan Engelhardt <jengelh@medozas.de>, 2008
|
||||
* by Jan Engelhardt , 2008
|
||||
*
|
||||
* Originally based on xt_quota.c:
|
||||
* Xtables module to enforce network quotas
|
||||
@@ -69,6 +69,8 @@ static int quota_proc_write(struct file *file, const char __user *input,
|
||||
if (copy_from_user(buf, input, size) != 0)
|
||||
return -EFAULT;
|
||||
buf[sizeof(buf)-1] = '\0';
|
||||
if (size < sizeof(buf))
|
||||
buf[size] = '\0';
|
||||
|
||||
spin_lock_bh(&e->lock);
|
||||
e->quota = simple_strtoull(buf, NULL, 0);
|
||||
@@ -209,13 +211,14 @@ quota_mt2(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
}
|
||||
ret = true;
|
||||
} else {
|
||||
if (e->quota >= skb->len) {
|
||||
if (e->quota >= ((q->flags & XT_QUOTA_PACKET) ? 1 : skb->len)) {
|
||||
if (!(q->flags & XT_QUOTA_NO_CHANGE))
|
||||
e->quota -= (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;
|
||||
ret = !ret;
|
||||
} else {
|
||||
/* we do not allow even small packets from now on */
|
||||
e->quota = 0;
|
||||
if (!(q->flags & XT_QUOTA_NO_CHANGE))
|
||||
e->quota = 0;
|
||||
}
|
||||
q->quota = e->quota;
|
||||
}
|
||||
@@ -270,7 +273,7 @@ module_init(quota_mt2_init);
|
||||
module_exit(quota_mt2_exit);
|
||||
MODULE_DESCRIPTION("Xtables: countdown quota match; up counter");
|
||||
MODULE_AUTHOR("Sam Johnston <samj@samj.net>");
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_AUTHOR("Jan Engelhardt ");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_quota2");
|
||||
MODULE_ALIAS("ip6t_quota2");
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# Converter for MaxMind CSV database to binary, for xt_geoip
|
||||
# Copyright © Jan Engelhardt <jengelh@medozas.de>, 2008-2011
|
||||
# Copyright © Jan Engelhardt, 2008-2011
|
||||
#
|
||||
use Getopt::Long;
|
||||
use IO::Handle;
|
||||
|
2
mconfig
2
mconfig
@@ -9,8 +9,6 @@ build_DNETMAP=m
|
||||
build_ECHO=m
|
||||
build_IPMARK=m
|
||||
build_LOGMARK=m
|
||||
build_RAWNAT=m
|
||||
build_STEAL=m
|
||||
build_SYSRQ=m
|
||||
build_TARPIT=m
|
||||
build_TEE=
|
||||
|
@@ -1,4 +1,4 @@
|
||||
.TH xtables-addons 8 "v1.44 (2012-07-15)" "" "v1.44 (2012-07-15)"
|
||||
.TH xtables-addons 8 "v1.47.1 (2012-10-15)" "" "v1.47.1 (2012-10-15)"
|
||||
.SH Name
|
||||
Xtables-addons \(em additional extensions for iptables, ip6tables, etc.
|
||||
.SH Targets
|
||||
@@ -9,5 +9,5 @@ Xtables-addons \(em additional extensions for iptables, ip6tables, etc.
|
||||
\fBiptables\fP(8), \fBip6tables\fP(8), \fBiptaccount\fP(8)
|
||||
.PP
|
||||
For developers, the book "Writing Netfilter modules" at
|
||||
http://jengelh.medozas.de/documents/Netfilter_Modules.pdf provides detailed
|
||||
http://inai.de/documents/Netfilter_Modules.pdf provides detailed
|
||||
information on how to write such modules/extensions.
|
||||
|
Reference in New Issue
Block a user