mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-21 20:14:56 +02:00
Compare commits
19 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e87dc5d5e1 | ||
![]() |
a0d3ee45ea | ||
![]() |
38343af9e6 | ||
![]() |
53abb1e735 | ||
![]() |
8a7354d8d5 | ||
![]() |
f30793f591 | ||
![]() |
ab27472eb4 | ||
![]() |
213acdffda | ||
![]() |
a47e6623b8 | ||
![]() |
d894a3dd15 | ||
![]() |
75e9afbc4a | ||
![]() |
003591fe6f | ||
![]() |
fd83fefad1 | ||
![]() |
e601fd61f9 | ||
![]() |
8fe612e43f | ||
![]() |
6737682e82 | ||
![]() |
fd9c6ffb03 | ||
![]() |
4f25eab39d | ||
![]() |
006147a21e |
@@ -11,10 +11,13 @@ xtables-addons.8: ${srcdir}/xtables-addons.8.in extensions/matches.man extension
|
||||
extensions/%:
|
||||
${MAKE} ${AM_MAKEFLAGS} -C $(@D) $(@F)
|
||||
|
||||
install-exec-local:
|
||||
depmod -a || :;
|
||||
|
||||
.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 ${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};
|
||||
|
@@ -1,5 +1,5 @@
|
||||
|
||||
AC_INIT([xtables-addons], [1.5.5])
|
||||
AC_INIT([xtables-addons], [1.5.7])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_PROG_INSTALL
|
||||
AM_INIT_AUTOMAKE
|
||||
@@ -27,8 +27,6 @@ AC_ARG_WITH([xtlibdir],
|
||||
[xtlibdir="$withval"],
|
||||
[xtlibdir='${libexecdir}/xtables'])
|
||||
|
||||
AC_CHECK_HEADER([netinet/ip6.h], [], [AC_MSG_ERROR(but we need that for IPv6)])
|
||||
|
||||
AC_MSG_CHECKING([xtables.h presence])
|
||||
if [[ -n "$xtables_location" ]]; then
|
||||
if [[ -f "$xtables_location/xtables.h" ]]; then
|
||||
|
@@ -7,6 +7,7 @@ obj-m += compat_xtables.o
|
||||
|
||||
obj-${build_CHAOS} += xt_CHAOS.o
|
||||
obj-${build_DELUDE} += xt_DELUDE.o
|
||||
obj-${build_DHCPADDR} += xt_DHCPADDR.o
|
||||
obj-${build_ECHO} += xt_ECHO.o
|
||||
obj-${build_IPMARK} += xt_IPMARK.o
|
||||
obj-${build_LOGMARK} += xt_LOGMARK.o
|
||||
@@ -14,6 +15,7 @@ obj-${build_SYSRQ} += xt_SYSRQ.o
|
||||
obj-${build_TARPIT} += xt_TARPIT.o
|
||||
obj-${build_TEE} += xt_TEE.o
|
||||
obj-${build_condition} += xt_condition.o
|
||||
obj-${build_fuzzy} += xt_fuzzy.o
|
||||
obj-${build_geoip} += xt_geoip.o
|
||||
obj-${build_ipp2p} += xt_ipp2p.o
|
||||
obj-${build_ipset} += ipset/
|
||||
|
@@ -1,5 +1,6 @@
|
||||
obj-${build_CHAOS} += libxt_CHAOS.so
|
||||
obj-${build_DELUDE} += libxt_DELUDE.so
|
||||
obj-${build_DHCPADDR} += libxt_DHCPADDR.so libxt_dhcpaddr.so
|
||||
obj-${build_ECHO} += libxt_ECHO.so
|
||||
obj-${build_IPMARK} += libxt_IPMARK.so
|
||||
obj-${build_LOGMARK} += libxt_LOGMARK.so
|
||||
@@ -7,6 +8,7 @@ obj-${build_SYSRQ} += libxt_SYSRQ.so
|
||||
obj-${build_TARPIT} += libxt_TARPIT.so
|
||||
obj-${build_TEE} += libxt_TEE.so
|
||||
obj-${build_condition} += libxt_condition.so
|
||||
obj-${build_fuzzy} += libxt_fuzzy.so
|
||||
obj-${build_geoip} += libxt_geoip.so
|
||||
obj-${build_ipp2p} += libxt_ipp2p.so
|
||||
obj-${build_portscan} += libxt_portscan.so
|
||||
|
@@ -20,15 +20,6 @@
|
||||
#include "compat_skbuff.h"
|
||||
#include "compat_xtnu.h"
|
||||
|
||||
static inline int unable(const char *cause, unsigned int c)
|
||||
{
|
||||
if (net_ratelimit())
|
||||
printk(KERN_ERR KBUILD_MODNAME
|
||||
": compat layer limits reached (%s) - "
|
||||
"dropping packets (%u so far)\n", cause, c);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#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,
|
||||
@@ -36,7 +27,7 @@ static int xtnu_match_run(const struct sk_buff *skb,
|
||||
unsigned int protoff, int *hotdrop)
|
||||
{
|
||||
struct xtnu_match *nm = xtcompat_numatch(cm);
|
||||
bool lo_drop, lo_ret;
|
||||
bool lo_drop = false, lo_ret;
|
||||
|
||||
if (nm == NULL || nm->match == NULL)
|
||||
return false;
|
||||
@@ -161,15 +152,21 @@ static unsigned int xtnu_target_run(struct sk_buff **pskb,
|
||||
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)
|
||||
#else
|
||||
static unsigned int xtnu_target_run(struct sk_buff *skb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
unsigned int hooknum, const struct xt_target *ct, const void *targinfo)
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
{
|
||||
struct xtnu_target *nt = xtcompat_nutarget(ct);
|
||||
if (nt != NULL && nt->target != NULL)
|
||||
return nt->target(*pskb, in, out, hooknum, nt, targinfo);
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
return nt->target(pskb, in, out, hooknum, nt, targinfo);
|
||||
#else
|
||||
return nt->target(&skb, in, out, hooknum, nt, targinfo);
|
||||
#endif
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
|
||||
static int xtnu_target_check(const char *table, const void *entry,
|
||||
@@ -178,11 +175,10 @@ static int xtnu_target_check(const char *table, const void *entry,
|
||||
#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)
|
||||
#else
|
||||
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)
|
||||
@@ -192,23 +188,19 @@ static bool xtnu_target_check(const char *table, const void *entry,
|
||||
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)
|
||||
#else
|
||||
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;
|
||||
@@ -276,7 +268,6 @@ void xtnu_unregister_targets(struct xtnu_target *nt, unsigned int num)
|
||||
xtnu_unregister_target(&nt[i]);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_unregister_targets);
|
||||
#endif
|
||||
|
||||
struct xt_match *xtnu_request_find_match(unsigned int af, const char *name,
|
||||
uint8_t revision)
|
||||
@@ -302,38 +293,28 @@ struct xt_match *xtnu_request_find_match(unsigned int af, const char *name,
|
||||
}
|
||||
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)
|
||||
int xtnu_ip_route_me_harder(struct sk_buff **pskb, unsigned int addr_type)
|
||||
{
|
||||
static unsigned int rmh_counter;
|
||||
struct sk_buff *nskb = skb;
|
||||
int ret;
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 17)
|
||||
/* Actually this one is valid up to 2.6.18.4, but changed in 2.6.18.5 */
|
||||
ret = ip_route_me_harder(&skb);
|
||||
return ip_route_me_harder(pskb);
|
||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
ret = ip_route_me_harder(&nskb, addr_type);
|
||||
return ip_route_me_harder(pskb, addr_type);
|
||||
#else
|
||||
return ip_route_me_harder(*pskb, addr_type);
|
||||
#endif
|
||||
if (nskb != skb)
|
||||
return unable(__func__, ++rmh_counter);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_ip_route_me_harder);
|
||||
|
||||
int xtnu_skb_make_writable(struct sk_buff *skb, unsigned int len)
|
||||
int xtnu_skb_make_writable(struct sk_buff **pskb, unsigned int len)
|
||||
{
|
||||
static unsigned int mkw_counter;
|
||||
struct sk_buff *nskb = skb;
|
||||
int ret;
|
||||
|
||||
ret = skb_make_writable(&skb, len);
|
||||
if (nskb != skb)
|
||||
return unable(__func__, ++mkw_counter) <= 0 ? false : true;
|
||||
return ret;
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
return skb_make_writable(pskb, len);
|
||||
#else
|
||||
return skb_make_writable(*pskb, len);
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_skb_make_writable);
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 24)
|
||||
static int __xtnu_ip_local_out(struct sk_buff *skb)
|
||||
@@ -402,6 +383,19 @@ int xtnu_neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb)
|
||||
return hh->hh_output(skb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_neigh_hh_output);
|
||||
|
||||
static inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to)
|
||||
{
|
||||
__be32 diff[] = {~from, to};
|
||||
*sum = csum_fold(csum_partial((char *)diff, sizeof(diff),
|
||||
~csum_unfold(*sum)));
|
||||
}
|
||||
|
||||
void xtnu_csum_replace2(__sum16 *sum, __be16 from, __be16 to)
|
||||
{
|
||||
csum_replace4(sum, (__force __be32)from, (__force __be32)to);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xtnu_csum_replace2);
|
||||
#endif
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@@ -6,7 +6,7 @@
|
||||
#include "compat_xtnu.h"
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
|
||||
# warning Kernels below 2.6.18 not supported.
|
||||
# warning Kernels below 2.6.18.5 not supported.
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
||||
# define neigh_hh_output xtnu_neigh_hh_output
|
||||
# define IPPROTO_UDPLITE 136
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
|
||||
@@ -58,15 +59,19 @@
|
||||
# define xt_unregister_matches xtnu_unregister_matches
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
|
||||
# define xt_target xtnu_target
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
||||
# define csum_replace2 xtnu_csum_replace2
|
||||
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
|
||||
# define csum_replace2 nf_csum_replace2
|
||||
#endif
|
||||
|
||||
#define ip_route_me_harder xtnu_ip_route_me_harder
|
||||
#define skb_make_writable xtnu_skb_make_writable
|
||||
#define xt_target xtnu_target
|
||||
#define xt_register_target xtnu_register_target
|
||||
#define xt_unregister_target xtnu_unregister_target
|
||||
#define xt_register_targets xtnu_register_targets
|
||||
#define xt_unregister_targets xtnu_unregister_targets
|
||||
#endif
|
||||
|
||||
#define xt_request_find_match xtnu_request_find_match
|
||||
|
||||
|
@@ -38,7 +38,7 @@ struct xtnu_match {
|
||||
struct xtnu_target {
|
||||
struct list_head list;
|
||||
char name[XT_FUNCTION_MAXNAMELEN - 1 - sizeof(void *)];
|
||||
unsigned int (*target)(struct sk_buff *, const struct net_device *,
|
||||
unsigned int (*target)(struct sk_buff **, const struct net_device *,
|
||||
const struct net_device *, unsigned int,
|
||||
const struct xtnu_target *, const void *);
|
||||
bool (*checkentry)(const char *, const void *,
|
||||
@@ -68,8 +68,8 @@ static inline struct xtnu_target *xtcompat_nutarget(const struct xt_target *t)
|
||||
}
|
||||
|
||||
extern int xtnu_ip_local_out(struct sk_buff *);
|
||||
extern int xtnu_ip_route_me_harder(struct sk_buff *, unsigned int);
|
||||
extern int xtnu_skb_make_writable(struct sk_buff *, unsigned int);
|
||||
extern int xtnu_ip_route_me_harder(struct sk_buff **, unsigned int);
|
||||
extern int xtnu_skb_make_writable(struct sk_buff **, unsigned int);
|
||||
extern int xtnu_register_match(struct xtnu_match *);
|
||||
extern int xtnu_ip_route_output_key(void *, struct rtable **, struct flowi *);
|
||||
extern void xtnu_unregister_match(struct xtnu_match *);
|
||||
|
@@ -24,7 +24,11 @@
|
||||
#include <linux/errno.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/bitops.h>
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
|
||||
# include <linux/semaphore.h>
|
||||
#else
|
||||
# include <asm/semaphore.h>
|
||||
#endif
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
|
@@ -76,7 +76,6 @@ static void chaos_tg_print(const void *ip,
|
||||
printf("TARPIT ");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void chaos_tg_save(const void *ip, const struct xt_entry_target *target)
|
||||
@@ -91,7 +90,6 @@ static void chaos_tg_save(const void *ip, const struct xt_entry_target *target)
|
||||
printf("--tarpit ");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static struct xtables_target chaos_tg_reg = {
|
||||
|
101
extensions/libxt_DHCPADDR.c
Normal file
101
extensions/libxt_DHCPADDR.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* "DHCPADDR" target extension for iptables
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_DHCPADDR.h"
|
||||
#include "mac.c"
|
||||
|
||||
enum {
|
||||
F_MAC = 1 << 0,
|
||||
};
|
||||
|
||||
static const struct option dhcpaddr_tg_opts[] = {
|
||||
{.name = "set-mac", .has_arg = true, .val = 'M'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void dhcpaddr_tg_help(void)
|
||||
{
|
||||
printf(
|
||||
"DHCPADDDR target options:\n"
|
||||
" --set-mac lladdr[/mask] Set MAC address in DHCP Client Host field\n"
|
||||
);
|
||||
}
|
||||
|
||||
static int dhcpaddr_tg_parse(int c, char **argv, int invert,
|
||||
unsigned int *flags, const void *entry, struct xt_entry_target **target)
|
||||
{
|
||||
struct dhcpaddr_info *info = (void *)(*target)->data;
|
||||
|
||||
switch (c) {
|
||||
case 'M':
|
||||
param_act(P_ONLY_ONCE, "DHCPADDR", "--set-mac", *flags & F_MAC);
|
||||
param_act(P_NO_INVERT, "DHCPADDR", "--set-mac", invert);
|
||||
if (!mac_parse(optarg, info->addr, &info->mask))
|
||||
param_act(P_BAD_VALUE, "DHCPADDR", "--set-mac", optarg);
|
||||
*flags |= F_MAC;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void dhcpaddr_tg_check(unsigned int flags)
|
||||
{
|
||||
if (flags == 0)
|
||||
exit_error(PARAMETER_PROBLEM, "DHCPADDR target: "
|
||||
"--set-mac parameter required");
|
||||
}
|
||||
|
||||
static void dhcpaddr_tg_print(const void *ip,
|
||||
const struct xt_entry_target *target, int numeric)
|
||||
{
|
||||
const struct dhcpaddr_info *info = (void *)target->data;
|
||||
|
||||
printf("DHCPADDR %s" DH_MAC_FMT "/%u ",
|
||||
info->invert ? "!" : "", DH_MAC_HEX(info->addr), info->mask);
|
||||
}
|
||||
|
||||
static void dhcpaddr_tg_save(const void *ip,
|
||||
const struct xt_entry_target *target)
|
||||
{
|
||||
const struct dhcpaddr_info *info = (const void *)target->data;
|
||||
|
||||
if (info->invert)
|
||||
printf("! ");
|
||||
printf("--set-mac " DH_MAC_FMT "/%u ",
|
||||
DH_MAC_HEX(info->addr), info->mask);
|
||||
}
|
||||
|
||||
static struct xtables_target dhcpaddr_tg_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "DHCPADDR",
|
||||
.revision = 0,
|
||||
.family = PF_INET,
|
||||
.size = XT_ALIGN(sizeof(struct dhcpaddr_info)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct dhcpaddr_info)),
|
||||
.help = dhcpaddr_tg_help,
|
||||
.parse = dhcpaddr_tg_parse,
|
||||
.final_check = dhcpaddr_tg_check,
|
||||
.print = dhcpaddr_tg_print,
|
||||
.save = dhcpaddr_tg_save,
|
||||
.extra_opts = dhcpaddr_tg_opts,
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
{
|
||||
xtables_register_target(&dhcpaddr_tg_reg);
|
||||
}
|
25
extensions/libxt_DHCPADDR.man
Normal file
25
extensions/libxt_DHCPADDR.man
Normal file
@@ -0,0 +1,25 @@
|
||||
In conjunction with ebtables, DHCPADDR can be used to completely change all MAC
|
||||
addresses from and to a VMware-based virtual machine. This is needed because
|
||||
VMware does not allow to set a non-VMware MAC address before an operating
|
||||
system is booted (and the MAC be changed with `ip link set eth0 address
|
||||
aa:bb..`).
|
||||
.TP
|
||||
\fB--set-mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
|
||||
Replace the client host MAC address field in the DHCP message with the given
|
||||
MAC address. This option is mandatory. The \fImask\fP parameter specifies the
|
||||
prefix length of bits to change.
|
||||
.PP
|
||||
EXAMPLE, replacing all addresses from one of VMware's assigned vendor IDs
|
||||
(00:50:56) addresses with something else:
|
||||
.PP
|
||||
iptables -t mangle -A FORWARD -p udp --dport 67 -m physdev --physdev-in vmnet1
|
||||
-m dhcpaddr --mac 00:50:56:00:00:00/24 -j DHCPADDR --set-mac
|
||||
ab:cd:ef:00:00:00/24
|
||||
.PP
|
||||
iptables -t mangle -A FORWARD -p udp --dport 68 -m physdev --physdev-out vmnet1
|
||||
-m dhcpaddr --mac ab:cd:ef:00:00:00/24 -j DHCPADDR --set-mac
|
||||
00:50:56:00:00:00/24
|
||||
.PP
|
||||
(This assumes there is a bridge interface that has vmnet1 as a port. You will
|
||||
also need to add appropriate ebtables rules to change the MAC address of the
|
||||
Ethernet headers.)
|
102
extensions/libxt_dhcpaddr.c
Normal file
102
extensions/libxt_dhcpaddr.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* "dhcpaddr" match extension for iptables
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_DHCPADDR.h"
|
||||
#include "mac.c"
|
||||
|
||||
enum {
|
||||
F_MAC = 1 << 0,
|
||||
};
|
||||
|
||||
static const struct option dhcpaddr_mt_opts[] = {
|
||||
{.name = "mac", .has_arg = true, .val = 'M'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void dhcpaddr_mt_help(void)
|
||||
{
|
||||
printf(
|
||||
"dhcpaddr match options:\n"
|
||||
"[!] --mac lladdr[/mask] Match on MAC address in DHCP Client Host field\n"
|
||||
);
|
||||
}
|
||||
|
||||
static int dhcpaddr_mt_parse(int c, char **argv, int invert,
|
||||
unsigned int *flags, const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct dhcpaddr_info *info = (void *)(*match)->data;
|
||||
|
||||
switch (c) {
|
||||
case 'M':
|
||||
param_act(P_ONLY_ONCE, "dhcpaddr", "--mac", *flags & F_MAC);
|
||||
param_act(P_NO_INVERT, "dhcpaddr", "--mac", invert);
|
||||
if (!mac_parse(optarg, info->addr, &info->mask))
|
||||
param_act(P_BAD_VALUE, "dhcpaddr", "--mac", optarg);
|
||||
if (invert)
|
||||
info->invert = true;
|
||||
*flags |= F_MAC;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void dhcpaddr_mt_check(unsigned int flags)
|
||||
{
|
||||
if (flags == 0)
|
||||
exit_error(PARAMETER_PROBLEM, "dhcpaddr match: "
|
||||
"--mac parameter required");
|
||||
}
|
||||
|
||||
static void dhcpaddr_mt_print(const void *ip,
|
||||
const struct xt_entry_match *match, int numeric)
|
||||
{
|
||||
const struct dhcpaddr_info *info = (void *)match->data;
|
||||
|
||||
printf("dhcpaddr %s" DH_MAC_FMT "/%u ",
|
||||
info->invert ? "!" : "", DH_MAC_HEX(info->addr), info->mask);
|
||||
}
|
||||
|
||||
static void dhcpaddr_mt_save(const void *ip,
|
||||
const struct xt_entry_match *match)
|
||||
{
|
||||
const struct dhcpaddr_info *info = (void *)match->data;
|
||||
|
||||
if (info->invert)
|
||||
printf("! ");
|
||||
printf("--mac " DH_MAC_FMT "/%u ",
|
||||
DH_MAC_HEX(info->addr), info->mask);
|
||||
}
|
||||
|
||||
static struct xtables_match dhcpaddr_mt_reg = {
|
||||
.version = XTABLES_VERSION,
|
||||
.name = "dhcpaddr",
|
||||
.revision = 0,
|
||||
.family = PF_INET,
|
||||
.size = XT_ALIGN(sizeof(struct dhcpaddr_info)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct dhcpaddr_info)),
|
||||
.help = dhcpaddr_mt_help,
|
||||
.parse = dhcpaddr_mt_parse,
|
||||
.final_check = dhcpaddr_mt_check,
|
||||
.print = dhcpaddr_mt_print,
|
||||
.save = dhcpaddr_mt_save,
|
||||
.extra_opts = dhcpaddr_mt_opts,
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
{
|
||||
xtables_register_match(&dhcpaddr_mt_reg);
|
||||
}
|
4
extensions/libxt_dhcpaddr.man
Normal file
4
extensions/libxt_dhcpaddr.man
Normal file
@@ -0,0 +1,4 @@
|
||||
.TP
|
||||
\fB--mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
|
||||
Matches the DHCP Client Host address in a DHCP message. \fImask\fP specifies
|
||||
the prefix length of the initial portion to match.
|
118
extensions/libxt_fuzzy.c
Normal file
118
extensions/libxt_fuzzy.c
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* "fuzzy" match extension for iptables
|
||||
* Hime Aguiar e Oliveira Jr. <hime@engineer.com>, 2002 - 2003
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License;
|
||||
* either version 2 of the License, or any later version, as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <getopt.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <xtables.h>
|
||||
#include "xt_fuzzy.h"
|
||||
|
||||
static void fuzzy_mt_help(void)
|
||||
{
|
||||
printf(
|
||||
"fuzzy match options:\n"
|
||||
" --lower-limit number (in packets per second)\n"
|
||||
" --upper-limit number\n");
|
||||
};
|
||||
|
||||
static const struct option fuzzy_mt_opts[] = {
|
||||
{.name = "lower-limit", .has_arg = true, .val = '1'},
|
||||
{.name = "upper-limit", .has_arg = true, .val = '2'},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
/* Initialize data structures */
|
||||
static void fuzzy_mt_init(struct xt_entry_match *m)
|
||||
{
|
||||
struct xt_fuzzy_mtinfo *info = (void *)m->data;
|
||||
|
||||
/*
|
||||
* Default rates (I will improve this very soon with something based
|
||||
* on real statistics of the running machine).
|
||||
*/
|
||||
info->minimum_rate = 1000;
|
||||
info->maximum_rate = 2000;
|
||||
}
|
||||
|
||||
#define IPT_FUZZY_OPT_MINIMUM 0x01
|
||||
#define IPT_FUZZY_OPT_MAXIMUM 0x02
|
||||
|
||||
static int fuzzy_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
const void *entry, struct xt_entry_match **match)
|
||||
{
|
||||
struct xt_fuzzy_mtinfo *info = (void *)(*match)->data;
|
||||
uint32_t num;
|
||||
|
||||
switch (c) {
|
||||
case '1':
|
||||
if (invert)
|
||||
exit_error(PARAMETER_PROBLEM,"Can't specify ! --lower-limit");
|
||||
if (*flags & IPT_FUZZY_OPT_MINIMUM)
|
||||
exit_error(PARAMETER_PROBLEM,"Can't specify --lower-limit twice");
|
||||
if (string_to_number(optarg,1,FUZZY_MAX_RATE,&num) == -1 || num < 1)
|
||||
exit_error(PARAMETER_PROBLEM,"BAD --lower-limit");
|
||||
info->minimum_rate = num;
|
||||
*flags |= IPT_FUZZY_OPT_MINIMUM;
|
||||
return true;
|
||||
|
||||
case '2':
|
||||
if (invert)
|
||||
exit_error(PARAMETER_PROBLEM,"Can't specify ! --upper-limit");
|
||||
if (*flags & IPT_FUZZY_OPT_MAXIMUM)
|
||||
exit_error(PARAMETER_PROBLEM,"Can't specify --upper-limit twice");
|
||||
if (string_to_number(optarg,1,FUZZY_MAX_RATE,&num) == -1 || num < 1)
|
||||
exit_error(PARAMETER_PROBLEM,"BAD --upper-limit");
|
||||
info->maximum_rate = num;
|
||||
*flags |= IPT_FUZZY_OPT_MAXIMUM;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void fuzzy_mt_check(unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
static void fuzzy_mt_print(const void *ip, const struct xt_entry_match *match,
|
||||
int numeric)
|
||||
{
|
||||
const struct xt_fuzzy_mtinfo *info = (const void *)match->data;
|
||||
|
||||
printf("fuzzy: lower limit = %u pps - upper limit = %u pps ",
|
||||
info->minimum_rate, info->maximum_rate);
|
||||
}
|
||||
|
||||
static void fuzzy_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||
{
|
||||
const struct xt_fuzzy_mtinfo *info = (const void *)match->data;
|
||||
|
||||
printf("--lower-limit %u ", info->minimum_rate);
|
||||
printf("--upper-limit %u ", info->maximum_rate);
|
||||
}
|
||||
|
||||
static struct xtables_match fuzzy_mt_reg = {
|
||||
.name = "fuzzy",
|
||||
.version = XTABLES_VERSION,
|
||||
.size = XT_ALIGN(sizeof(struct xt_fuzzy_mtinfo)),
|
||||
.userspacesize = XT_ALIGN(sizeof(struct xt_fuzzy_mtinfo)),
|
||||
.help = fuzzy_mt_help,
|
||||
.init = fuzzy_mt_init,
|
||||
.parse = fuzzy_mt_parse,
|
||||
.final_check = fuzzy_mt_check,
|
||||
.print = fuzzy_mt_print,
|
||||
.save = fuzzy_mt_save,
|
||||
.extra_opts = fuzzy_mt_opts,
|
||||
};
|
||||
|
||||
static void _init(void)
|
||||
{
|
||||
xtables_register_match(&fuzzy_mt_reg);
|
||||
}
|
7
extensions/libxt_fuzzy.man
Normal file
7
extensions/libxt_fuzzy.man
Normal file
@@ -0,0 +1,7 @@
|
||||
This module matches a rate limit based on a fuzzy logic controller (FLC).
|
||||
.TP
|
||||
\fB--lower-limit\fP \fInumber\fP
|
||||
Specifies the lower limit, in packets per second.
|
||||
.TP
|
||||
\fB--upper-limit\fP \fInumber\fP
|
||||
Specifies the upper limit, also in packets per second.
|
@@ -175,33 +175,35 @@ static int geoip_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||
|
||||
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!");
|
||||
"geoip: Only exactly one of --source-country "
|
||||
"or --destination-country must be specified!");
|
||||
|
||||
*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;
|
||||
return true;
|
||||
|
||||
case '2':
|
||||
if (*flags & (XT_GEOIP_SRC | XT_GEOIP_DST))
|
||||
exit_error(PARAMETER_PROBLEM,
|
||||
"geoip: Only exactly one of --source-country "
|
||||
"or --destination-country must be specified!");
|
||||
|
||||
*flags |= XT_GEOIP_DST;
|
||||
if (invert)
|
||||
*flags |= XT_GEOIP_INV;
|
||||
|
||||
info->count = parse_geoip_cc(argv[optind-1], info->cc, info->mem);
|
||||
info->flags = *flags;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
|
29
extensions/mac.c
Normal file
29
extensions/mac.c
Normal file
@@ -0,0 +1,29 @@
|
||||
static bool mac_parse(const char *addr, unsigned char *dest, uint8_t *mask)
|
||||
{
|
||||
unsigned int i = 0, value;
|
||||
char *end;
|
||||
|
||||
for (i = 0; i < ETH_ALEN; ++i) {
|
||||
value = strtoul(addr, &end, 16);
|
||||
if (addr == end || value > 0xFF)
|
||||
return false;
|
||||
if (i == ETH_ALEN - 1) {
|
||||
if (*end != '\0' && *end != '/')
|
||||
return false;
|
||||
} else if (*end != ':') {
|
||||
return false;
|
||||
}
|
||||
dest[i] = value;
|
||||
addr = end + 1;
|
||||
}
|
||||
|
||||
*mask = 48;
|
||||
if (*end == '/') {
|
||||
if (!strtonum(end + 1, &end, &value, 0, 48))
|
||||
return false;
|
||||
if (*end != '\0')
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@@ -72,12 +72,11 @@ static void xt_chaos_total(const struct xt_chaos_tginfo *info,
|
||||
#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)
|
||||
static unsigned int chaos_tg(struct sk_buff **pskb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
unsigned int hooknum, const struct xt_target *target, const void *targinfo)
|
||||
{
|
||||
/*
|
||||
* Equivalent to:
|
||||
@@ -88,18 +87,19 @@ static unsigned int chaos_tg(struct sk_buff *skb, const struct net_device *in,
|
||||
* -A chaos -j DROP;
|
||||
*/
|
||||
const struct xt_chaos_tginfo *info = targinfo;
|
||||
struct sk_buff *skb = *pskb;
|
||||
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,
|
||||
return xt_reject->target(pskb, 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,
|
||||
return xt_reject->target(pskb, in, out, hooknum,
|
||||
target->__compat_target, &reject_params);
|
||||
#else
|
||||
return xt_reject->target(skb, in, out, hooknum, target,
|
||||
&reject_params);
|
||||
return xt_reject->target(skb, in, out, hooknum,
|
||||
target->__compat_target, &reject_params);
|
||||
#endif
|
||||
|
||||
/* TARPIT/DELUDE may not be called from the OUTPUT chain */
|
||||
@@ -199,7 +199,6 @@ static void __exit chaos_tg_exit(void)
|
||||
module_put(xt_delude->me);
|
||||
if (have_tarpit)
|
||||
module_put(xt_tarpit->me);
|
||||
return;
|
||||
}
|
||||
|
||||
module_init(chaos_tg_init);
|
||||
|
@@ -122,8 +122,10 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
|
||||
dst_hold(oldskb->dst);
|
||||
nskb->dst = oldskb->dst;
|
||||
|
||||
if (ip_route_me_harder(nskb, addr_type))
|
||||
if (ip_route_me_harder(&nskb, addr_type))
|
||||
goto free_nskb;
|
||||
else
|
||||
niph = ip_hdr(nskb);
|
||||
|
||||
niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
|
||||
nskb->ip_summed = CHECKSUM_NONE;
|
||||
@@ -141,14 +143,14 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
|
||||
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)
|
||||
static unsigned int delude_tg(struct sk_buff **pskb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
unsigned int hooknum, const struct xt_target *target, const void *targinfo)
|
||||
{
|
||||
/* 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);
|
||||
delude_send_reset(*pskb, hooknum);
|
||||
return NF_DROP;
|
||||
}
|
||||
|
||||
|
175
extensions/xt_DHCPADDR.c
Normal file
175
extensions/xt_DHCPADDR.c
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* "DHCPADDR" extensions for Xtables
|
||||
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
* version 2 of the License, or any later version, as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <linux/ip.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/udp.h>
|
||||
#include <net/ip.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include "xt_DHCPADDR.h"
|
||||
#include "compat_xtables.h"
|
||||
|
||||
struct dhcp_message {
|
||||
uint8_t op, htype, hlen, hops;
|
||||
__be32 xid;
|
||||
__be16 secs, flags;
|
||||
__be32 ciaddr, yiaddr, siaddr, giaddr;
|
||||
char chaddr[16];
|
||||
/* Omitting all unneeded fields saves runtime memory */
|
||||
/* char sname[64], file[128]; */
|
||||
};
|
||||
|
||||
static void ether_set(unsigned char *addr, const unsigned char *op,
|
||||
uint8_t mask)
|
||||
{
|
||||
uint8_t lo_mask;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ETH_ALEN && mask > 0; ++i) {
|
||||
lo_mask = mask % 8;
|
||||
/* FF << 4 >> 4 = 0F */
|
||||
lo_mask = ~(uint8_t)0U << lo_mask >> lo_mask;
|
||||
addr[i] &= lo_mask;
|
||||
addr[i] |= op[i] & ~lo_mask;
|
||||
if (mask >= 8)
|
||||
mask -= 8;
|
||||
else
|
||||
mask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ether_cmp(const unsigned char *lh, const unsigned char *rh,
|
||||
uint8_t mask)
|
||||
{
|
||||
uint8_t lo_mask;
|
||||
unsigned int i;
|
||||
#define ZMAC_FMT "%02X:%02X:%02X:%02X:%02X:%02X"
|
||||
#define ZMACHEX(s) s[0], s[1], s[2], s[3], s[4], s[5]
|
||||
|
||||
for (i = 0; i < ETH_ALEN && mask > 0; ++i) {
|
||||
lo_mask = mask % 8;
|
||||
/* ~(0xFF << 4 >> 4) = ~0x0F = 0xF0 */
|
||||
lo_mask = ~(~(uint8_t)0U << lo_mask >> lo_mask);
|
||||
if ((lh[i] ^ rh[i]) & lo_mask)
|
||||
return false;
|
||||
if (mask >= 8)
|
||||
mask -= 8;
|
||||
else
|
||||
mask = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool dhcpaddr_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 dhcpaddr_info *info = matchinfo;
|
||||
const struct dhcp_message *dh;
|
||||
struct dhcp_message dhcpbuf;
|
||||
|
||||
dh = skb_header_pointer(skb, protoff + sizeof(struct udphdr),
|
||||
sizeof(dhcpbuf), &dhcpbuf);
|
||||
if (dh == NULL)
|
||||
/*
|
||||
* No hotdrop. This packet does not look like DHCP, but other
|
||||
* matches may still have a valid reason to get their chance
|
||||
* to match on this.
|
||||
*/
|
||||
return false;
|
||||
|
||||
return ether_cmp((const void *)dh->chaddr, info->addr, info->mask);
|
||||
}
|
||||
|
||||
static unsigned int dhcpaddr_tg(struct sk_buff **pskb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
unsigned int hooknum, const struct xt_target *target, const void *targinfo)
|
||||
{
|
||||
const struct dhcpaddr_info *info = targinfo;
|
||||
struct dhcp_message dhcpbuf, *dh;
|
||||
struct udphdr udpbuf, *udph;
|
||||
struct sk_buff *skb = *pskb;
|
||||
unsigned int i;
|
||||
|
||||
if (!skb_make_writable(pskb, 0))
|
||||
return NF_DROP;
|
||||
|
||||
udph = skb_header_pointer(skb, ip_hdrlen(skb),
|
||||
sizeof(udpbuf), &udpbuf);
|
||||
if (udph == NULL)
|
||||
return NF_DROP;
|
||||
|
||||
dh = skb_header_pointer(skb, ip_hdrlen(skb) + sizeof(udpbuf),
|
||||
sizeof(dhcpbuf), &dhcpbuf);
|
||||
if (dh == NULL)
|
||||
return NF_DROP;
|
||||
|
||||
for (i = 0; i < sizeof(dh->chaddr); i += 2)
|
||||
csum_replace2(&udph->check, *(const __be16 *)dh->chaddr, 0);
|
||||
|
||||
memset(dh->chaddr, 0, sizeof(dh->chaddr));
|
||||
ether_set(dh->chaddr, info->addr, info->mask);
|
||||
|
||||
for (i = 0; i < sizeof(dh->chaddr); i += 2)
|
||||
csum_replace2(&udph->check, 0, *(const __be16 *)dh->chaddr);
|
||||
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
||||
static struct xt_target dhcpaddr_tg_reg __read_mostly = {
|
||||
.name = "DHCPADDR",
|
||||
.revision = 0,
|
||||
.family = PF_INET,
|
||||
.proto = IPPROTO_UDP,
|
||||
.table = "mangle",
|
||||
.target = dhcpaddr_tg,
|
||||
.targetsize = XT_ALIGN(sizeof(struct dhcpaddr_info)),
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct xt_match dhcpaddr_mt_reg __read_mostly = {
|
||||
.name = "dhcpaddr",
|
||||
.revision = 0,
|
||||
.family = PF_INET,
|
||||
.proto = IPPROTO_UDP,
|
||||
.match = dhcpaddr_mt,
|
||||
.matchsize = XT_ALIGN(sizeof(struct dhcpaddr_info)),
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init dhcpaddr_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = xt_register_target(&dhcpaddr_tg_reg);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = xt_register_match(&dhcpaddr_mt_reg);
|
||||
if (ret != 0) {
|
||||
xt_unregister_target(&dhcpaddr_tg_reg);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit dhcpaddr_exit(void)
|
||||
{
|
||||
xt_unregister_target(&dhcpaddr_tg_reg);
|
||||
xt_unregister_match(&dhcpaddr_mt_reg);
|
||||
}
|
||||
|
||||
module_init(dhcpaddr_init);
|
||||
module_exit(dhcpaddr_exit);
|
||||
MODULE_DESCRIPTION("Xtables: Clamp DHCP MAC to packet MAC addresses");
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_DHCPADDR");
|
||||
MODULE_ALIAS("ipt_dhcpaddr");
|
12
extensions/xt_DHCPADDR.h
Normal file
12
extensions/xt_DHCPADDR.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef _LINUX_NETFILTER_XT_DHCPADDR_H
|
||||
#define _LINUX_NETFILTER_XT_DHCPADDR_H 1
|
||||
|
||||
#define DH_MAC_FMT "%02X:%02X:%02X:%02X:%02X:%02X"
|
||||
#define DH_MAC_HEX(z) z[0], z[1], z[2], z[3], z[4], z[5]
|
||||
|
||||
struct dhcpaddr_info {
|
||||
unsigned char addr[ETH_ALEN];
|
||||
uint8_t mask, invert;
|
||||
};
|
||||
|
||||
#endif /* _LINUX_NETFILTER_XT_DHCPADDR_H */
|
@@ -20,10 +20,11 @@
|
||||
#include <net/ip.h>
|
||||
#include "compat_xtables.h"
|
||||
|
||||
static unsigned int echo_tg4(struct sk_buff *oldskb,
|
||||
static unsigned int echo_tg4(struct sk_buff **poldskb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
unsigned int hooknum, const struct xt_target *target, const void *targinfo)
|
||||
{
|
||||
const struct sk_buff *oldskb = *poldskb;
|
||||
const struct udphdr *oldudp;
|
||||
const struct iphdr *oldip;
|
||||
struct udphdr *newudp, oldudp_buf;
|
||||
|
@@ -25,11 +25,12 @@ MODULE_ALIAS("ipt_IPMARK");
|
||||
MODULE_ALIAS("ip6t_IPMARK");
|
||||
|
||||
static unsigned int
|
||||
ipmark_tg4(struct sk_buff *skb, const struct net_device *in,
|
||||
ipmark_tg4(struct sk_buff **pskb, const struct net_device *in,
|
||||
const struct net_device *out, unsigned int hooknum,
|
||||
const struct xt_target *target, const void *targinfo)
|
||||
{
|
||||
const struct xt_ipmark_tginfo *ipmarkinfo = targinfo;
|
||||
const struct sk_buff *skb = *pskb;
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
__u32 mark;
|
||||
|
||||
@@ -62,11 +63,12 @@ static __u32 ipmark_from_ip6(const struct in6_addr *a, unsigned int s)
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
ipmark_tg6(struct sk_buff *skb, const struct net_device *in,
|
||||
ipmark_tg6(struct sk_buff **pskb, const struct net_device *in,
|
||||
const struct net_device *out, unsigned int hooknum,
|
||||
const struct xt_target *target, const void *targinfo)
|
||||
{
|
||||
const struct xt_ipmark_tginfo *info = targinfo;
|
||||
const struct sk_buff *skb = *pskb;
|
||||
const struct ipv6hdr *iph = ipv6_hdr(skb);
|
||||
__u32 mark;
|
||||
|
||||
|
@@ -30,10 +30,11 @@ static const char *const dir_names[] = {
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
logmark_tg(struct sk_buff *skb, const struct net_device *in,
|
||||
logmark_tg(struct sk_buff **pskb, const struct net_device *in,
|
||||
const struct net_device *out, unsigned int hooknum,
|
||||
const struct xt_target *target, const void *targinfo)
|
||||
{
|
||||
const struct sk_buff *skb = *pskb;
|
||||
const struct xt_logmark_tginfo *info = targinfo;
|
||||
const struct nf_conn *ct;
|
||||
enum ip_conntrack_info ctinfo;
|
||||
|
@@ -50,14 +50,19 @@ static unsigned int sysrq_tg(const void *pdata, uint16_t len)
|
||||
return NF_DROP;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
|
||||
handle_sysrq(c, NULL);
|
||||
#else
|
||||
handle_sysrq(c, NULL, NULL);
|
||||
#endif
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
static unsigned int sysrq_tg4(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)
|
||||
static unsigned int sysrq_tg4(struct sk_buff **pskb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
unsigned int hooknum, const struct xt_target *target, const void *targinfo)
|
||||
{
|
||||
struct sk_buff *skb = *pskb;
|
||||
const struct iphdr *iph;
|
||||
const struct udphdr *udph;
|
||||
uint16_t len;
|
||||
@@ -75,10 +80,11 @@ static unsigned int sysrq_tg4(struct sk_buff *skb, const struct net_device *in,
|
||||
return sysrq_tg((void *)udph + sizeof(struct udphdr), len);
|
||||
}
|
||||
|
||||
static unsigned int sysrq_tg6(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)
|
||||
static unsigned int sysrq_tg6(struct sk_buff **pskb,
|
||||
const struct net_device *in, const struct net_device *out,
|
||||
unsigned int hooknum, const struct xt_target *target, const void *targinfo)
|
||||
{
|
||||
struct sk_buff *skb = *pskb;
|
||||
const struct ipv6hdr *iph;
|
||||
const struct udphdr *udph;
|
||||
uint16_t len;
|
||||
@@ -156,3 +162,5 @@ module_exit(sysrq_tg_exit);
|
||||
MODULE_DESCRIPTION("Xtables: triggering SYSRQ remotely");
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_SYSRQ");
|
||||
MODULE_ALIAS("ip6t_SYSRQ");
|
||||
|
@@ -49,7 +49,7 @@
|
||||
#include <net/tcp.h>
|
||||
#include "compat_xtables.h"
|
||||
|
||||
static inline void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
|
||||
static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
|
||||
{
|
||||
struct tcphdr _otcph, *oth, *tcph;
|
||||
unsigned int addr_type;
|
||||
@@ -157,8 +157,10 @@ static inline void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
|
||||
#endif
|
||||
addr_type = RTN_LOCAL;
|
||||
|
||||
if (ip_route_me_harder(nskb, addr_type))
|
||||
if (ip_route_me_harder(&nskb, addr_type))
|
||||
goto free_nskb;
|
||||
else
|
||||
niph = ip_hdr(nskb);
|
||||
|
||||
nskb->ip_summed = CHECKSUM_NONE;
|
||||
|
||||
@@ -184,10 +186,11 @@ static inline void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
tarpit_tg(struct sk_buff *skb, const struct net_device *in,
|
||||
tarpit_tg(struct sk_buff **pskb, const struct net_device *in,
|
||||
const struct net_device *out, unsigned int hooknum,
|
||||
const struct xt_target *target, const void *targinfo)
|
||||
{
|
||||
const struct sk_buff *skb = *pskb;
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
const struct rtable *rt = (const void *)skb->dst;
|
||||
|
||||
@@ -215,7 +218,7 @@ tarpit_tg(struct sk_buff *skb, const struct net_device *in,
|
||||
if (iph->frag_off & htons(IP_OFFSET))
|
||||
return NF_DROP;
|
||||
|
||||
tarpit_tcp(skb, hooknum);
|
||||
tarpit_tcp(*pskb, hooknum);
|
||||
return NF_DROP;
|
||||
}
|
||||
|
||||
|
@@ -142,11 +142,12 @@ static void tee_ip_direct_send(struct sk_buff *skb)
|
||||
* packets when we see they already have that ->nfct.
|
||||
*/
|
||||
static unsigned int
|
||||
tee_tg(struct sk_buff *skb, const struct net_device *in,
|
||||
tee_tg(struct sk_buff **pskb, const struct net_device *in,
|
||||
const struct net_device *out, unsigned int hooknum,
|
||||
const struct xt_target *target, const void *targinfo)
|
||||
{
|
||||
const struct xt_tee_tginfo *info = targinfo;
|
||||
struct sk_buff *skb = *pskb;
|
||||
|
||||
#ifdef WITH_CONNTRACK
|
||||
if (skb->nfct == &tee_track.ct_general) {
|
||||
@@ -160,8 +161,9 @@ tee_tg(struct sk_buff *skb, const struct net_device *in,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!skb_make_writable(skb, sizeof(struct iphdr)))
|
||||
if (!skb_make_writable(pskb, sizeof(struct iphdr)))
|
||||
return NF_DROP;
|
||||
skb = *pskb;
|
||||
|
||||
/*
|
||||
* If we are in INPUT, the checksum must be recalculated since
|
||||
|
@@ -27,9 +27,6 @@
|
||||
#ifndef CONFIG_PROC_FS
|
||||
# error "proc file system support is required for this module"
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
|
||||
# define proc_net init_net.proc_net
|
||||
#endif
|
||||
|
||||
/* Defaults, these can be overridden on the module command-line. */
|
||||
static unsigned int condition_list_perms = S_IRUGO | S_IWUSR;
|
||||
@@ -159,7 +156,8 @@ condition_mt_check(const char *tablename, const void *entry,
|
||||
}
|
||||
|
||||
/* Create the condition variable's proc file entry. */
|
||||
var->status_proc = create_proc_entry(info->name, condition_list_perms, proc_net_condition);
|
||||
var->status_proc = create_proc_entry(info->name, condition_list_perms,
|
||||
proc_net_condition);
|
||||
|
||||
if (var->status_proc == NULL) {
|
||||
kfree(var);
|
||||
@@ -238,13 +236,13 @@ static int __init condition_mt_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
proc_net_condition = proc_mkdir(dir_name, proc_net);
|
||||
proc_net_condition = proc_mkdir(dir_name, init_net__proc_net);
|
||||
if (proc_net_condition == NULL)
|
||||
return -EACCES;
|
||||
|
||||
ret = xt_register_matches(condition_mt_reg, ARRAY_SIZE(condition_mt_reg));
|
||||
if (ret < 0) {
|
||||
remove_proc_entry(dir_name, proc_net);
|
||||
remove_proc_entry(dir_name, init_net__proc_net);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -254,7 +252,7 @@ static int __init condition_mt_init(void)
|
||||
static void __exit condition_mt_exit(void)
|
||||
{
|
||||
xt_unregister_matches(condition_mt_reg, ARRAY_SIZE(condition_mt_reg));
|
||||
remove_proc_entry(dir_name, proc_net);
|
||||
remove_proc_entry(dir_name, init_net__proc_net);
|
||||
}
|
||||
|
||||
module_init(condition_mt_init);
|
||||
|
6
extensions/xt_fuzzy.Kconfig
Normal file
6
extensions/xt_fuzzy.Kconfig
Normal file
@@ -0,0 +1,6 @@
|
||||
config NETFILTER_XT_MATCH_FUZZY
|
||||
tristate '"fuzzy" match support'
|
||||
depends on NETFILTER_XTABLES && NETFILTER_ADVANCED
|
||||
---help---
|
||||
This extension allows you to match on packets according to a fuzzy
|
||||
logic based law.
|
179
extensions/xt_fuzzy.c
Normal file
179
extensions/xt_fuzzy.c
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* This module implements a simple TSK FLC (Takagi-Sugeno-Kang Fuzzy Logic
|
||||
* Controller) that aims to limit, in an adaptive and flexible way, the
|
||||
* packet rate crossing a given stream. It serves as an initial and very
|
||||
* simple (but effective) example of how Fuzzy Logic techniques can be
|
||||
* applied to defeat DoS attacks.
|
||||
*
|
||||
* As a matter of fact, Fuzzy Logic can help us to insert any "behavior"
|
||||
* into our code in a precise, adaptive and efficient manner.
|
||||
*
|
||||
* The goal is very similar to that of "limit" match, but using techniques
|
||||
* of Fuzzy Control, that allow us to shape the transfer functions
|
||||
* precisely, avoiding over and undershoots - and stuff like that.
|
||||
*
|
||||
* 2002-08-10 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
|
||||
* 2002-08-17 : Changed to eliminate floating point operations .
|
||||
* 2002-08-23 : Coding style changes .
|
||||
* 2003-04-08 Maciej Soltysiak <solt@dns.toxicilms.tv> : IPv6 Port
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/random.h>
|
||||
#include <net/tcp.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include "xt_fuzzy.h"
|
||||
#include "compat_xtables.h"
|
||||
|
||||
/*
|
||||
* Packet Acceptance Rate - LOW and Packet Acceptance Rate - HIGH
|
||||
* Expressed in percentage.
|
||||
*/
|
||||
|
||||
#define PAR_LOW 1/100
|
||||
#define PAR_HIGH 1
|
||||
|
||||
MODULE_AUTHOR("Hime Aguiar e Oliveira Junior <hime@engineer.com>");
|
||||
MODULE_DESCRIPTION("Xtables: Fuzzy Logic Controller match");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_fuzzy");
|
||||
MODULE_ALIAS("ip6t_fuzzy");
|
||||
|
||||
static uint8_t mf_high(uint32_t tx, uint32_t mini, uint32_t maxi)
|
||||
{
|
||||
if (tx >= maxi)
|
||||
return 100;
|
||||
if (tx <= mini)
|
||||
return 0;
|
||||
return 100 * (tx - mini) / (maxi - mini);
|
||||
}
|
||||
|
||||
static uint8_t mf_low(uint32_t tx, uint32_t mini, uint32_t maxi)
|
||||
{
|
||||
if (tx <= mini)
|
||||
return 100;
|
||||
if (tx >= maxi)
|
||||
return 0;
|
||||
return 100 * (maxi - tx) / (maxi - mini);
|
||||
|
||||
}
|
||||
|
||||
static bool
|
||||
fuzzy_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)
|
||||
{
|
||||
struct xt_fuzzy_mtinfo *info = (void *)matchinfo;
|
||||
unsigned long amount;
|
||||
uint8_t howhigh, howlow, random_number;
|
||||
|
||||
info->bytes_total += skb->len;
|
||||
++info->packets_total;
|
||||
info->present_time = jiffies;
|
||||
|
||||
if (info->present_time >= info->previous_time) {
|
||||
amount = info->present_time - info->previous_time;
|
||||
} else {
|
||||
/*
|
||||
* There was a transition: I choose to re-sample
|
||||
* and keep the old acceptance rate...
|
||||
*/
|
||||
amount = 0;
|
||||
info->previous_time = info->present_time;
|
||||
info->bytes_total = info->packets_total = 0;
|
||||
}
|
||||
|
||||
if (amount > HZ / 10) {
|
||||
/* More than 100 ms elapsed ... */
|
||||
|
||||
info->mean_rate = HZ * info->packets_total / amount;
|
||||
info->previous_time = info->present_time;
|
||||
info->bytes_total = info->packets_total = 0;
|
||||
|
||||
howhigh = mf_high(info->mean_rate, info->minimum_rate,
|
||||
info->maximum_rate);
|
||||
howlow = mf_low(info->mean_rate, info->minimum_rate,
|
||||
info->maximum_rate);
|
||||
|
||||
info->acceptance_rate = howhigh * PAR_LOW + PAR_HIGH * howlow;
|
||||
|
||||
/*
|
||||
* In fact, the above defuzzification would require a
|
||||
* denominator proportional to (howhigh+howlow) but, in this
|
||||
* particular case, that expression is constant.
|
||||
*
|
||||
* An imediate consequence is that it is not necessary to call
|
||||
* both mf_high and mf_low - but to keep things understandable,
|
||||
* I did so.
|
||||
*/
|
||||
}
|
||||
|
||||
if (info->acceptance_rate < 100) {
|
||||
get_random_bytes(&random_number, sizeof(random_number));
|
||||
|
||||
if (random_number <= 255 * info->acceptance_rate / 100)
|
||||
/*
|
||||
* If within the acceptance, it can pass
|
||||
* => do not match.
|
||||
*/
|
||||
return false;
|
||||
else
|
||||
/* It cannot pass (it matches) */
|
||||
return true;
|
||||
};
|
||||
|
||||
/* acceptance_rate == 100 % => Everything passes ... */
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
fuzzy_mt_check(const char *table, const void *ip, const struct xt_match *match,
|
||||
void *matchinfo, unsigned int hook_mask)
|
||||
{
|
||||
const struct xt_fuzzy_mtinfo *info = matchinfo;
|
||||
|
||||
if (info->minimum_rate < FUZZY_MIN_RATE ||
|
||||
info->maximum_rate > FUZZY_MAX_RATE ||
|
||||
info->minimum_rate >= info->maximum_rate) {
|
||||
printk(KERN_INFO KBUILD_MODNAME ": bad values, please check.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct xt_match fuzzy_mt_reg[] __read_mostly = {
|
||||
{
|
||||
.name = "fuzzy",
|
||||
.revision = 0,
|
||||
.family = PF_INET,
|
||||
.match = fuzzy_mt,
|
||||
.checkentry = fuzzy_mt_check,
|
||||
.matchsize = XT_ALIGN(sizeof(struct xt_fuzzy_mtinfo)),
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
{
|
||||
.name = "fuzzy",
|
||||
.revision = 0,
|
||||
.family = PF_INET6,
|
||||
.match = fuzzy_mt,
|
||||
.checkentry = fuzzy_mt_check,
|
||||
.matchsize = XT_ALIGN(sizeof(struct xt_fuzzy_mtinfo)),
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init fuzzy_mt_init(void)
|
||||
{
|
||||
return xt_register_matches(fuzzy_mt_reg, ARRAY_SIZE(fuzzy_mt_reg));
|
||||
}
|
||||
|
||||
static void __exit fuzzy_mt_exit(void)
|
||||
{
|
||||
xt_unregister_matches(fuzzy_mt_reg, ARRAY_SIZE(fuzzy_mt_reg));
|
||||
}
|
||||
|
||||
module_init(fuzzy_mt_init);
|
||||
module_exit(fuzzy_mt_exit);
|
20
extensions/xt_fuzzy.h
Normal file
20
extensions/xt_fuzzy.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef _LINUX_NETFILTER_XT_FUZZY_H
|
||||
#define _LINUX_NETFILTER_XT_FUZZY_H 1
|
||||
|
||||
enum {
|
||||
FUZZY_MIN_RATE = 3,
|
||||
FUZZY_MAX_RATE = 10000000,
|
||||
};
|
||||
|
||||
struct xt_fuzzy_mtinfo {
|
||||
uint32_t minimum_rate;
|
||||
uint32_t maximum_rate;
|
||||
uint32_t packets_total;
|
||||
uint32_t bytes_total;
|
||||
uint32_t previous_time;
|
||||
uint32_t present_time;
|
||||
uint32_t mean_rate;
|
||||
uint8_t acceptance_rate;
|
||||
};
|
||||
|
||||
#endif /* _LINUX_NETFILTER_XT_FUZZY_H */
|
@@ -232,31 +232,44 @@ static bool portscan_mt_check(const char *tablename, const void *entry,
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct xt_match portscan_mt_reg __read_mostly = {
|
||||
static struct xt_match portscan_mt_reg[] __read_mostly = {
|
||||
{
|
||||
.name = "portscan",
|
||||
.revision = 0,
|
||||
.family = AF_INET,
|
||||
.family = PF_INET,
|
||||
.match = portscan_mt,
|
||||
.checkentry = portscan_mt_check,
|
||||
.matchsize = sizeof(struct xt_portscan_mtinfo),
|
||||
.proto = IPPROTO_TCP,
|
||||
.me = THIS_MODULE,
|
||||
},
|
||||
{
|
||||
.name = "portscan",
|
||||
.revision = 0,
|
||||
.family = PF_INET6,
|
||||
.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);
|
||||
return xt_register_matches(portscan_mt_reg,
|
||||
ARRAY_SIZE(portscan_mt_reg));
|
||||
}
|
||||
|
||||
static void __exit portscan_mt_exit(void)
|
||||
{
|
||||
xt_unregister_match(&portscan_mt_reg);
|
||||
return;
|
||||
xt_unregister_matches(portscan_mt_reg, ARRAY_SIZE(portscan_mt_reg));
|
||||
}
|
||||
|
||||
module_init(portscan_mt_init);
|
||||
module_exit(portscan_mt_exit);
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
|
||||
MODULE_DESCRIPTION("netfilter \"portscan\" match");
|
||||
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
|
||||
MODULE_DESCRIPTION("Xtables: \"portscan\" match");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ipt_portscan");
|
||||
MODULE_ALIAS("ip6t_portscan");
|
||||
|
Reference in New Issue
Block a user