Compare commits

..

19 Commits

Author SHA1 Message Date
Jan Engelhardt
e87dc5d5e1 Xtables-addons 1.5.7 2008-09-01 15:35:51 -04:00
Jan Engelhardt
a0d3ee45ea xt_SYSRQ: add missing aliases 2008-09-01 15:33:28 -04:00
Jan Engelhardt
38343af9e6 xt_portscan: IPv6 support 2008-09-01 15:32:15 -04:00
Jan Engelhardt
53abb1e735 src: remove redundant return statements 2008-09-01 15:31:10 -04:00
Jan Engelhardt
8a7354d8d5 build: remove dependency on netinet/in6.h 2008-09-01 15:27:43 -04:00
Jan Engelhardt
f30793f591 DHCP address match and mangler 2008-09-01 15:27:43 -04:00
Jan Engelhardt
ab27472eb4 src: move to a pskb-based API
It occurred that skb reallocation does happen on older kernels, and
those kernels should really be supported, since the patch is really
minimal.
2008-09-01 15:27:43 -04:00
Jan Engelhardt
213acdffda xt_condition: ues glue-provided init_net__proc_net 2008-09-01 15:27:43 -04:00
Jan Engelhardt
a47e6623b8 Merge reworked fuzzy extension 2008-09-01 15:27:11 -04:00
Jan Engelhardt
d894a3dd15 fuzzy: IPv6 support 2008-09-01 15:26:51 -04:00
Jan Engelhardt
75e9afbc4a fuzzy: misc cleanup 2008-09-01 15:26:47 -04:00
Jan Engelhardt
003591fe6f fuzzy: remove unneeded spinlock 2008-09-01 15:22:22 -04:00
Jan Engelhardt
fd83fefad1 fuzzy: import 20050627 code base 2008-09-01 15:22:16 -04:00
Jan Engelhardt
e601fd61f9 Automatically run depmod -a 2008-08-29 07:53:06 -04:00
James King
8fe612e43f ipset: adjust semaphore.h include for kernel >= 2.6.27
As of Linux kernel commit 2351ec533ed0dd56052ab96988d2161d5ecc8ed9,
semaphore.h was moved from asm/ to linux/, which breaks building of
ipset. Add compat glue to ip_set.c to fix building on 2.6.27 an
onwards.
2008-08-28 20:27:09 -04:00
Jan Engelhardt
6737682e82 xt_SYSRQ: fix compilation for Linux kernel version <= 2.6.19 2008-08-28 20:27:09 -04:00
Jan Engelhardt
fd9c6ffb03 Clear hotdrop before use
Must make sure that hotdrop is properly initialized. GCC
unfortunately did not warn.
2008-08-24 16:44:07 -04:00
Jan Engelhardt
4f25eab39d libxt_geoip: reorder option parsing code 2008-08-24 12:34:31 -04:00
Jan Engelhardt
006147a21e build: prepare make tarball for git 1.6.0 2008-08-21 09:26:05 -04:00
33 changed files with 945 additions and 128 deletions

View File

@@ -11,10 +11,13 @@ xtables-addons.8: ${srcdir}/xtables-addons.8.in extensions/matches.man extension
extensions/%: extensions/%:
${MAKE} ${AM_MAKEFLAGS} -C $(@D) $(@F) ${MAKE} ${AM_MAKEFLAGS} -C $(@D) $(@F)
install-exec-local:
depmod -a || :;
.PHONY: tarball .PHONY: tarball
tarball: tarball:
rm -Rf /tmp/xtables-addons-${PACKAGE_VERSION}; 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; 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}/; 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}; rm -Rf /tmp/xtables-addons-${PACKAGE_VERSION};

View File

@@ -1,5 +1,5 @@
AC_INIT([xtables-addons], [1.5.5]) AC_INIT([xtables-addons], [1.5.7])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
AC_PROG_INSTALL AC_PROG_INSTALL
AM_INIT_AUTOMAKE AM_INIT_AUTOMAKE
@@ -27,8 +27,6 @@ AC_ARG_WITH([xtlibdir],
[xtlibdir="$withval"], [xtlibdir="$withval"],
[xtlibdir='${libexecdir}/xtables']) [xtlibdir='${libexecdir}/xtables'])
AC_CHECK_HEADER([netinet/ip6.h], [], [AC_MSG_ERROR(but we need that for IPv6)])
AC_MSG_CHECKING([xtables.h presence]) AC_MSG_CHECKING([xtables.h presence])
if [[ -n "$xtables_location" ]]; then if [[ -n "$xtables_location" ]]; then
if [[ -f "$xtables_location/xtables.h" ]]; then if [[ -f "$xtables_location/xtables.h" ]]; then

View File

@@ -7,6 +7,7 @@ obj-m += compat_xtables.o
obj-${build_CHAOS} += xt_CHAOS.o obj-${build_CHAOS} += xt_CHAOS.o
obj-${build_DELUDE} += xt_DELUDE.o obj-${build_DELUDE} += xt_DELUDE.o
obj-${build_DHCPADDR} += xt_DHCPADDR.o
obj-${build_ECHO} += xt_ECHO.o obj-${build_ECHO} += xt_ECHO.o
obj-${build_IPMARK} += xt_IPMARK.o obj-${build_IPMARK} += xt_IPMARK.o
obj-${build_LOGMARK} += xt_LOGMARK.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_TARPIT} += xt_TARPIT.o
obj-${build_TEE} += xt_TEE.o obj-${build_TEE} += xt_TEE.o
obj-${build_condition} += xt_condition.o obj-${build_condition} += xt_condition.o
obj-${build_fuzzy} += xt_fuzzy.o
obj-${build_geoip} += xt_geoip.o obj-${build_geoip} += xt_geoip.o
obj-${build_ipp2p} += xt_ipp2p.o obj-${build_ipp2p} += xt_ipp2p.o
obj-${build_ipset} += ipset/ obj-${build_ipset} += ipset/

View File

@@ -1,5 +1,6 @@
obj-${build_CHAOS} += libxt_CHAOS.so obj-${build_CHAOS} += libxt_CHAOS.so
obj-${build_DELUDE} += libxt_DELUDE.so obj-${build_DELUDE} += libxt_DELUDE.so
obj-${build_DHCPADDR} += libxt_DHCPADDR.so libxt_dhcpaddr.so
obj-${build_ECHO} += libxt_ECHO.so obj-${build_ECHO} += libxt_ECHO.so
obj-${build_IPMARK} += libxt_IPMARK.so obj-${build_IPMARK} += libxt_IPMARK.so
obj-${build_LOGMARK} += libxt_LOGMARK.so obj-${build_LOGMARK} += libxt_LOGMARK.so
@@ -7,6 +8,7 @@ obj-${build_SYSRQ} += libxt_SYSRQ.so
obj-${build_TARPIT} += libxt_TARPIT.so obj-${build_TARPIT} += libxt_TARPIT.so
obj-${build_TEE} += libxt_TEE.so obj-${build_TEE} += libxt_TEE.so
obj-${build_condition} += libxt_condition.so obj-${build_condition} += libxt_condition.so
obj-${build_fuzzy} += libxt_fuzzy.so
obj-${build_geoip} += libxt_geoip.so obj-${build_geoip} += libxt_geoip.so
obj-${build_ipp2p} += libxt_ipp2p.so obj-${build_ipp2p} += libxt_ipp2p.so
obj-${build_portscan} += libxt_portscan.so obj-${build_portscan} += libxt_portscan.so

View File

@@ -20,15 +20,6 @@
#include "compat_skbuff.h" #include "compat_skbuff.h"
#include "compat_xtnu.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) #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
static int xtnu_match_run(const struct sk_buff *skb, static int xtnu_match_run(const struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, 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) unsigned int protoff, int *hotdrop)
{ {
struct xtnu_match *nm = xtcompat_numatch(cm); struct xtnu_match *nm = xtcompat_numatch(cm);
bool lo_drop, lo_ret; bool lo_drop = false, lo_ret;
if (nm == NULL || nm->match == NULL) if (nm == NULL || nm->match == NULL)
return false; 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, static unsigned int xtnu_target_run(struct sk_buff **pskb,
const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *ct, const void *targinfo) 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 #endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
{ {
struct xtnu_target *nt = xtcompat_nutarget(ct); struct xtnu_target *nt = xtcompat_nutarget(ct);
if (nt != NULL && nt->target != NULL) 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; return XT_CONTINUE;
} }
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
static int xtnu_target_check(const char *table, const void *entry, 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) #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
static int xtnu_target_check(const char *table, const void *entry, static int xtnu_target_check(const char *table, const void *entry,
const struct xt_target *ct, void *targinfo, unsigned int hook_mask) 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, static bool xtnu_target_check(const char *table, const void *entry,
const struct xt_target *ct, void *targinfo, unsigned int hook_mask) const struct xt_target *ct, void *targinfo, unsigned int hook_mask)
#endif #endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
{ {
struct xtnu_target *nt = xtcompat_nutarget(ct); struct xtnu_target *nt = xtcompat_nutarget(ct);
if (nt == NULL) if (nt == NULL)
@@ -192,23 +188,19 @@ static bool xtnu_target_check(const char *table, const void *entry,
return true; return true;
return nt->checkentry(table, entry, nt, targinfo, hook_mask); return nt->checkentry(table, entry, nt, targinfo, hook_mask);
} }
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
static void xtnu_target_destroy(const struct xt_target *ct, void *targinfo, static void xtnu_target_destroy(const struct xt_target *ct, void *targinfo,
unsigned int targinfosize) 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) static void xtnu_target_destroy(const struct xt_target *ct, void *targinfo)
#endif #endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
{ {
struct xtnu_target *nt = xtcompat_nutarget(ct); struct xtnu_target *nt = xtcompat_nutarget(ct);
if (nt != NULL && nt->destroy != NULL) if (nt != NULL && nt->destroy != NULL)
nt->destroy(nt, targinfo); nt->destroy(nt, targinfo);
} }
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
int xtnu_register_target(struct xtnu_target *nt) int xtnu_register_target(struct xtnu_target *nt)
{ {
struct xt_target *ct; struct xt_target *ct;
@@ -276,7 +268,6 @@ void xtnu_unregister_targets(struct xtnu_target *nt, unsigned int num)
xtnu_unregister_target(&nt[i]); xtnu_unregister_target(&nt[i]);
} }
EXPORT_SYMBOL_GPL(xtnu_unregister_targets); EXPORT_SYMBOL_GPL(xtnu_unregister_targets);
#endif
struct xt_match *xtnu_request_find_match(unsigned int af, const char *name, struct xt_match *xtnu_request_find_match(unsigned int af, const char *name,
uint8_t revision) 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); 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 **pskb, unsigned int addr_type)
int xtnu_ip_route_me_harder(struct sk_buff *skb, 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) #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 */ /* 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) #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 #endif
if (nskb != skb)
return unable(__func__, ++rmh_counter);
return ret;
} }
EXPORT_SYMBOL_GPL(xtnu_ip_route_me_harder); 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; #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
struct sk_buff *nskb = skb; return skb_make_writable(pskb, len);
int ret; #else
return skb_make_writable(*pskb, len);
ret = skb_make_writable(&skb, len); #endif
if (nskb != skb)
return unable(__func__, ++mkw_counter) <= 0 ? false : true;
return ret;
} }
EXPORT_SYMBOL_GPL(xtnu_skb_make_writable); EXPORT_SYMBOL_GPL(xtnu_skb_make_writable);
#endif
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 24) #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 24)
static int __xtnu_ip_local_out(struct sk_buff *skb) 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); return hh->hh_output(skb);
} }
EXPORT_SYMBOL_GPL(xtnu_neigh_hh_output); 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 #endif
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");

View File

@@ -6,7 +6,7 @@
#include "compat_xtnu.h" #include "compat_xtnu.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) #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 #endif
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
@@ -28,6 +28,7 @@
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19) #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
# define neigh_hh_output xtnu_neigh_hh_output # define neigh_hh_output xtnu_neigh_hh_output
# define IPPROTO_UDPLITE 136
#endif #endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24) #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
@@ -58,15 +59,19 @@
# define xt_unregister_matches xtnu_unregister_matches # define xt_unregister_matches xtnu_unregister_matches
#endif #endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23) #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
# define xt_target xtnu_target # 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 ip_route_me_harder xtnu_ip_route_me_harder
#define skb_make_writable xtnu_skb_make_writable #define skb_make_writable xtnu_skb_make_writable
#define xt_target xtnu_target
#define xt_register_target xtnu_register_target #define xt_register_target xtnu_register_target
#define xt_unregister_target xtnu_unregister_target #define xt_unregister_target xtnu_unregister_target
#define xt_register_targets xtnu_register_targets #define xt_register_targets xtnu_register_targets
#define xt_unregister_targets xtnu_unregister_targets #define xt_unregister_targets xtnu_unregister_targets
#endif
#define xt_request_find_match xtnu_request_find_match #define xt_request_find_match xtnu_request_find_match

View File

@@ -38,7 +38,7 @@ struct xtnu_match {
struct xtnu_target { struct xtnu_target {
struct list_head list; struct list_head list;
char name[XT_FUNCTION_MAXNAMELEN - 1 - sizeof(void *)]; 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 net_device *, unsigned int,
const struct xtnu_target *, const void *); const struct xtnu_target *, const void *);
bool (*checkentry)(const char *, 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_local_out(struct sk_buff *);
extern int xtnu_ip_route_me_harder(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_skb_make_writable(struct sk_buff **, unsigned int);
extern int xtnu_register_match(struct xtnu_match *); extern int xtnu_register_match(struct xtnu_match *);
extern int xtnu_ip_route_output_key(void *, struct rtable **, struct flowi *); extern int xtnu_ip_route_output_key(void *, struct rtable **, struct flowi *);
extern void xtnu_unregister_match(struct xtnu_match *); extern void xtnu_unregister_match(struct xtnu_match *);

View File

@@ -24,7 +24,11 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
# include <linux/semaphore.h>
#else
# include <asm/semaphore.h> # include <asm/semaphore.h>
#endif
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>

View File

@@ -76,7 +76,6 @@ static void chaos_tg_print(const void *ip,
printf("TARPIT "); printf("TARPIT ");
break; break;
} }
return;
} }
static void chaos_tg_save(const void *ip, const struct xt_entry_target *target) static void chaos_tg_save(const void *ip, const struct xt_entry_target *target)
@@ -91,7 +90,6 @@ static void chaos_tg_save(const void *ip, const struct xt_entry_target *target)
printf("--tarpit "); printf("--tarpit ");
break; break;
} }
return;
} }
static struct xtables_target chaos_tg_reg = { static struct xtables_target chaos_tg_reg = {

101
extensions/libxt_DHCPADDR.c Normal file
View 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);
}

View 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
View 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);
}

View 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
View 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);
}

View 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.

View File

@@ -175,33 +175,35 @@ static int geoip_parse(int c, char **argv, int invert, unsigned int *flags,
switch (c) { switch (c) {
case '1': case '1':
// Ensure that XT_GEOIP_SRC *OR* XT_GEOIP_DST haven't been used yet.
if (*flags & (XT_GEOIP_SRC | XT_GEOIP_DST)) if (*flags & (XT_GEOIP_SRC | XT_GEOIP_DST))
exit_error(PARAMETER_PROBLEM, 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; *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) if (invert)
*flags |= XT_GEOIP_INV; *flags |= XT_GEOIP_INV;
info->count = parse_geoip_cc(argv[optind-1], info->cc, info->mem); info->count = parse_geoip_cc(argv[optind-1], info->cc, info->mem);
info->flags = *flags; 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 static void

29
extensions/mac.c Normal file
View 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;
}

View File

@@ -72,12 +72,11 @@ static void xt_chaos_total(const struct xt_chaos_tginfo *info,
#else #else
destiny->target(skb, in, out, hooknum, destiny, NULL); destiny->target(skb, in, out, hooknum, destiny, NULL);
#endif #endif
return;
} }
static unsigned int chaos_tg(struct sk_buff *skb, const struct net_device *in, static unsigned int chaos_tg(struct sk_buff **pskb,
const struct net_device *out, unsigned int hooknum, const struct net_device *in, const struct net_device *out,
const struct xt_target *target, const void *targinfo) unsigned int hooknum, const struct xt_target *target, const void *targinfo)
{ {
/* /*
* Equivalent to: * Equivalent to:
@@ -88,18 +87,19 @@ static unsigned int chaos_tg(struct sk_buff *skb, const struct net_device *in,
* -A chaos -j DROP; * -A chaos -j DROP;
*/ */
const struct xt_chaos_tginfo *info = targinfo; const struct xt_chaos_tginfo *info = targinfo;
struct sk_buff *skb = *pskb;
const struct iphdr *iph = ip_hdr(skb); const struct iphdr *iph = ip_hdr(skb);
if ((unsigned int)net_random() <= reject_percentage) if ((unsigned int)net_random() <= reject_percentage)
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) #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); target->__compat_target, &reject_params, NULL);
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23) #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); target->__compat_target, &reject_params);
#else #else
return xt_reject->target(skb, in, out, hooknum, target, return xt_reject->target(skb, in, out, hooknum,
&reject_params); target->__compat_target, &reject_params);
#endif #endif
/* TARPIT/DELUDE may not be called from the OUTPUT chain */ /* 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); module_put(xt_delude->me);
if (have_tarpit) if (have_tarpit)
module_put(xt_tarpit->me); module_put(xt_tarpit->me);
return;
} }
module_init(chaos_tg_init); module_init(chaos_tg_init);

View File

@@ -122,8 +122,10 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
dst_hold(oldskb->dst); dst_hold(oldskb->dst);
nskb->dst = 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; goto free_nskb;
else
niph = ip_hdr(nskb);
niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
nskb->ip_summed = CHECKSUM_NONE; nskb->ip_summed = CHECKSUM_NONE;
@@ -141,14 +143,14 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
kfree_skb(nskb); kfree_skb(nskb);
} }
static unsigned int delude_tg(struct sk_buff *skb, const struct net_device *in, static unsigned int delude_tg(struct sk_buff **pskb,
const struct net_device *out, unsigned int hooknum, const struct net_device *in, const struct net_device *out,
const struct xt_target *target, const void *targinfo) unsigned int hooknum, const struct xt_target *target, const void *targinfo)
{ {
/* WARNING: This code causes reentry within iptables. /* WARNING: This code causes reentry within iptables.
This means that the iptables jump stack is now crap. We This means that the iptables jump stack is now crap. We
must return an absolute verdict. --RR */ must return an absolute verdict. --RR */
delude_send_reset(skb, hooknum); delude_send_reset(*pskb, hooknum);
return NF_DROP; return NF_DROP;
} }

175
extensions/xt_DHCPADDR.c Normal file
View 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
View 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 */

View File

@@ -20,10 +20,11 @@
#include <net/ip.h> #include <net/ip.h>
#include "compat_xtables.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, const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *target, const void *targinfo) unsigned int hooknum, const struct xt_target *target, const void *targinfo)
{ {
const struct sk_buff *oldskb = *poldskb;
const struct udphdr *oldudp; const struct udphdr *oldudp;
const struct iphdr *oldip; const struct iphdr *oldip;
struct udphdr *newudp, oldudp_buf; struct udphdr *newudp, oldudp_buf;

View File

@@ -25,11 +25,12 @@ MODULE_ALIAS("ipt_IPMARK");
MODULE_ALIAS("ip6t_IPMARK"); MODULE_ALIAS("ip6t_IPMARK");
static unsigned int 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 net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo) const struct xt_target *target, const void *targinfo)
{ {
const struct xt_ipmark_tginfo *ipmarkinfo = targinfo; const struct xt_ipmark_tginfo *ipmarkinfo = targinfo;
const struct sk_buff *skb = *pskb;
const struct iphdr *iph = ip_hdr(skb); const struct iphdr *iph = ip_hdr(skb);
__u32 mark; __u32 mark;
@@ -62,11 +63,12 @@ static __u32 ipmark_from_ip6(const struct in6_addr *a, unsigned int s)
} }
static unsigned int 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 net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo) const struct xt_target *target, const void *targinfo)
{ {
const struct xt_ipmark_tginfo *info = targinfo; const struct xt_ipmark_tginfo *info = targinfo;
const struct sk_buff *skb = *pskb;
const struct ipv6hdr *iph = ipv6_hdr(skb); const struct ipv6hdr *iph = ipv6_hdr(skb);
__u32 mark; __u32 mark;

View File

@@ -30,10 +30,11 @@ static const char *const dir_names[] = {
}; };
static unsigned int 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 net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo) const struct xt_target *target, const void *targinfo)
{ {
const struct sk_buff *skb = *pskb;
const struct xt_logmark_tginfo *info = targinfo; const struct xt_logmark_tginfo *info = targinfo;
const struct nf_conn *ct; const struct nf_conn *ct;
enum ip_conntrack_info ctinfo; enum ip_conntrack_info ctinfo;

View File

@@ -50,14 +50,19 @@ static unsigned int sysrq_tg(const void *pdata, uint16_t len)
return NF_DROP; return NF_DROP;
} }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
handle_sysrq(c, NULL); handle_sysrq(c, NULL);
#else
handle_sysrq(c, NULL, NULL);
#endif
return NF_ACCEPT; return NF_ACCEPT;
} }
static unsigned int sysrq_tg4(struct sk_buff *skb, const struct net_device *in, static unsigned int sysrq_tg4(struct sk_buff **pskb,
const struct net_device *out, unsigned int hooknum, const struct net_device *in, const struct net_device *out,
const struct xt_target *target, const void *targinfo) unsigned int hooknum, const struct xt_target *target, const void *targinfo)
{ {
struct sk_buff *skb = *pskb;
const struct iphdr *iph; const struct iphdr *iph;
const struct udphdr *udph; const struct udphdr *udph;
uint16_t len; 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); return sysrq_tg((void *)udph + sizeof(struct udphdr), len);
} }
static unsigned int sysrq_tg6(struct sk_buff *skb, const struct net_device *in, static unsigned int sysrq_tg6(struct sk_buff **pskb,
const struct net_device *out, unsigned int hooknum, const struct net_device *in, const struct net_device *out,
const struct xt_target *target, const void *targinfo) unsigned int hooknum, const struct xt_target *target, const void *targinfo)
{ {
struct sk_buff *skb = *pskb;
const struct ipv6hdr *iph; const struct ipv6hdr *iph;
const struct udphdr *udph; const struct udphdr *udph;
uint16_t len; uint16_t len;
@@ -156,3 +162,5 @@ module_exit(sysrq_tg_exit);
MODULE_DESCRIPTION("Xtables: triggering SYSRQ remotely"); MODULE_DESCRIPTION("Xtables: triggering SYSRQ remotely");
MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>"); MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("ipt_SYSRQ");
MODULE_ALIAS("ip6t_SYSRQ");

View File

@@ -49,7 +49,7 @@
#include <net/tcp.h> #include <net/tcp.h>
#include "compat_xtables.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; struct tcphdr _otcph, *oth, *tcph;
unsigned int addr_type; unsigned int addr_type;
@@ -157,8 +157,10 @@ static inline void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
#endif #endif
addr_type = RTN_LOCAL; addr_type = RTN_LOCAL;
if (ip_route_me_harder(nskb, addr_type)) if (ip_route_me_harder(&nskb, addr_type))
goto free_nskb; goto free_nskb;
else
niph = ip_hdr(nskb);
nskb->ip_summed = CHECKSUM_NONE; nskb->ip_summed = CHECKSUM_NONE;
@@ -184,10 +186,11 @@ static inline void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
} }
static unsigned int 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 net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo) const struct xt_target *target, const void *targinfo)
{ {
const struct sk_buff *skb = *pskb;
const struct iphdr *iph = ip_hdr(skb); const struct iphdr *iph = ip_hdr(skb);
const struct rtable *rt = (const void *)skb->dst; 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)) if (iph->frag_off & htons(IP_OFFSET))
return NF_DROP; return NF_DROP;
tarpit_tcp(skb, hooknum); tarpit_tcp(*pskb, hooknum);
return NF_DROP; return NF_DROP;
} }

View File

@@ -142,11 +142,12 @@ static void tee_ip_direct_send(struct sk_buff *skb)
* packets when we see they already have that ->nfct. * packets when we see they already have that ->nfct.
*/ */
static unsigned int 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 net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo) const struct xt_target *target, const void *targinfo)
{ {
const struct xt_tee_tginfo *info = targinfo; const struct xt_tee_tginfo *info = targinfo;
struct sk_buff *skb = *pskb;
#ifdef WITH_CONNTRACK #ifdef WITH_CONNTRACK
if (skb->nfct == &tee_track.ct_general) { if (skb->nfct == &tee_track.ct_general) {
@@ -160,8 +161,9 @@ tee_tg(struct sk_buff *skb, const struct net_device *in,
} }
#endif #endif
if (!skb_make_writable(skb, sizeof(struct iphdr))) if (!skb_make_writable(pskb, sizeof(struct iphdr)))
return NF_DROP; return NF_DROP;
skb = *pskb;
/* /*
* If we are in INPUT, the checksum must be recalculated since * If we are in INPUT, the checksum must be recalculated since

View File

@@ -27,9 +27,6 @@
#ifndef CONFIG_PROC_FS #ifndef CONFIG_PROC_FS
# error "proc file system support is required for this module" # error "proc file system support is required for this module"
#endif #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. */ /* Defaults, these can be overridden on the module command-line. */
static unsigned int condition_list_perms = S_IRUGO | S_IWUSR; 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. */ /* 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) { if (var->status_proc == NULL) {
kfree(var); kfree(var);
@@ -238,13 +236,13 @@ static int __init condition_mt_init(void)
{ {
int ret; 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) if (proc_net_condition == NULL)
return -EACCES; return -EACCES;
ret = xt_register_matches(condition_mt_reg, ARRAY_SIZE(condition_mt_reg)); ret = xt_register_matches(condition_mt_reg, ARRAY_SIZE(condition_mt_reg));
if (ret < 0) { if (ret < 0) {
remove_proc_entry(dir_name, proc_net); remove_proc_entry(dir_name, init_net__proc_net);
return ret; return ret;
} }
@@ -254,7 +252,7 @@ static int __init condition_mt_init(void)
static void __exit condition_mt_exit(void) static void __exit condition_mt_exit(void)
{ {
xt_unregister_matches(condition_mt_reg, ARRAY_SIZE(condition_mt_reg)); 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); module_init(condition_mt_init);

View 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
View 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
View 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 */

View File

@@ -232,31 +232,44 @@ static bool portscan_mt_check(const char *tablename, const void *entry,
return true; return true;
} }
static struct xt_match portscan_mt_reg __read_mostly = { static struct xt_match portscan_mt_reg[] __read_mostly = {
{
.name = "portscan", .name = "portscan",
.revision = 0, .revision = 0,
.family = AF_INET, .family = PF_INET,
.match = portscan_mt, .match = portscan_mt,
.checkentry = portscan_mt_check, .checkentry = portscan_mt_check,
.matchsize = sizeof(struct xt_portscan_mtinfo), .matchsize = sizeof(struct xt_portscan_mtinfo),
.proto = IPPROTO_TCP, .proto = IPPROTO_TCP,
.me = THIS_MODULE, .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) 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) static void __exit portscan_mt_exit(void)
{ {
xt_unregister_match(&portscan_mt_reg); xt_unregister_matches(portscan_mt_reg, ARRAY_SIZE(portscan_mt_reg));
return;
} }
module_init(portscan_mt_init); module_init(portscan_mt_init);
module_exit(portscan_mt_exit); module_exit(portscan_mt_exit);
MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
MODULE_DESCRIPTION("netfilter \"portscan\" match"); MODULE_DESCRIPTION("Xtables: \"portscan\" match");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("ipt_portscan"); MODULE_ALIAS("ipt_portscan");
MODULE_ALIAS("ip6t_portscan");

View File

@@ -2,6 +2,7 @@
# #
build_CHAOS=m build_CHAOS=m
build_DELUDE=m build_DELUDE=m
build_DHCPADDR=m
build_ECHO= build_ECHO=
build_IPMARK=m build_IPMARK=m
build_LOGMARK=m build_LOGMARK=m
@@ -9,6 +10,7 @@ build_SYSRQ=m
build_TARPIT=m build_TARPIT=m
build_TEE=m build_TEE=m
build_condition=m build_condition=m
build_fuzzy=m
build_geoip=m build_geoip=m
build_ipp2p=m build_ipp2p=m
build_ipset=m build_ipset=m