Compare commits

...

24 Commits

Author SHA1 Message Date
Jan Engelhardt
463dceb709 Xtables-addons 1.5.3 2008-03-22 05:17:04 +01:00
Jan Engelhardt
cd323565d7 Merge reworked geoip extension 2008-03-22 05:16:53 +01:00
Jan Engelhardt
a39bfdf98e Add xt_ECHO sample target 2008-03-22 05:16:47 +01:00
Jan Engelhardt
cd7c8fc4fa geoip: minor cleanups in help, opts and logic 2008-03-22 03:59:58 +01:00
Jan Engelhardt
5d431b45f1 geoip: use simpler, preprocessed integer vector lists and fix endian issue
The old database format was in unknown byteorder -- if you run the
converter program yourself, you got a host order file, but if you
downloaded the preprocessed DB file (geoipdb.bin), you got a
little-endian file.

Use a new database format. Instead of having an index and a DB file,
do away with the index and let the filesystem do the indexing, using
one file per country. Also access the database files with a known
endianess type. The converter script now produces two distinct
variants (especially needed for IA-64).

All of this reduces the touched code by half.
2008-03-22 03:59:57 +01:00
Jan Engelhardt
f4c4208e75 geoip: use appropriate and normal types
For the header file, we need __u32 and so on because they are exported
to userspace and rather constitute a kernel header.

Use normal types instead of uintXX_t in the main code.
2008-03-22 03:59:57 +01:00
Jan Engelhardt
52a0ed7f15 geoip: use rcu to reduce time spinlocks are held
spin_lock_bh does not look safe (only disables preempt on current
CPU?). Change to spin_lock, that also avoids the management overhead
of spin_lock_bh. to spin_lock to avoid management overhead.

Use rcu in match and destroy function.
2008-03-22 03:59:57 +01:00
Jan Engelhardt
000d813171 geoip: use real atomic_t and remove casts from uint32_t 2008-03-22 03:59:57 +01:00
Jan Engelhardt
e45cb21ad6 geoip: use struct list_head instead of self-cooked list 2008-03-22 03:59:57 +01:00
Jan Engelhardt
7aae90da5a geoip: use local-portable aligned_u64 pointer values
A 64-bit kernel will interpret the pointer with 64 bits width, while
a 32-bit userspace filled in only 32 of it, leaving the other 32
undefined. This must be avoided.
2008-03-22 03:59:56 +01:00
Jan Engelhardt
fd5321c7d8 geoip: split user/kernel-visible parts of struct geoip_info 2008-03-22 03:59:56 +01:00
Jan Engelhardt
65eeb7f1f6 geoip: use vmalloc due to potential list size
The subnet list may become really large (United States: ~15000
entries), which means a use of roughly 120 KB, and kmalloc may fail
to find a contiguous block in physical memory. Virtual contiguity is
enough, so use vmalloc/vfree.

vfree may not be called within a spin_lock_bh area, so release the
lock first, it is safe to do so.
2008-03-22 03:59:55 +01:00
Jan Engelhardt
848484c08c geoip: use a binary search to replace the current linear one
Certain countries have lots (around 10000) of IP address ranges
(US,GB,DE,...). The current linear search is really bad:

No firewall:
3000 packets transmitted, 3000 received, 0% packet loss, time 1992ms

Testing against the countries with top 50 IP ranges:
3000 packets transmitted, 3000 received, 0% packet loss, time 8998ms

With binary search:
3000 packets transmitted, 3000 received, 0% packet loss, time 2358ms
2008-03-22 03:59:45 +01:00
Jan Engelhardt
8c58a61f52 geoip: address comparison is inclusive
subnet is somewhat a wrong term, geoip actually uses ipranges. Either
way, the comparison needs to be >= and <= instead of > <.
2008-03-22 03:59:45 +01:00
Jan Engelhardt
93c7d0ac47 geoip: lock timing correctness
find_node: The reference count needs to be increased while the lock
is held. Otherwise, the node may disappear right after the lock was
released and increase was attempted, leading to an oops.

remove_node: The reference count needs to be checked while the lock
is held. Otherwise, the node may be used in the match function or
returned from find_node while it has a zero refcount.
2008-03-22 03:59:45 +01:00
Jan Engelhardt
df063ab61c geoip: add missing kfree in error path 2008-03-22 03:59:44 +01:00
Jan Engelhardt
d480ea2b1f geoip: sort #include list 2008-03-22 03:59:44 +01:00
Jan Engelhardt
205a006ac9 geoip: use tabs not spaces and indent 2008-03-22 03:59:44 +01:00
Jan Engelhardt
9f45aa737a geoip: remove redundant casts 2008-03-22 03:59:44 +01:00
Jan Engelhardt
f1615a03f3 geoip: remove unused code and unneeded per-info refcount
- freeing userspace memory is not the kernel's job, really.
- checkentry is called exactly once, as is destroy.
2008-03-22 03:59:44 +01:00
Jan Engelhardt
3554e348bc geoip: import 20080214 code base 2008-03-22 03:59:42 +01:00
Jan Engelhardt
5fd97e9973 compat update: allow building from 2.6.18 onwards 2008-03-12 04:28:40 +01:00
Jan Engelhardt
10e3d8fe0d Update .gitignore 2008-03-12 04:28:38 +01:00
Jan Engelhardt
6c06796e3b Makefile: add missing xtables_CFLAGS variable
If xtables.h is to be found in a directory other than included in the
default preprocessor search path, compilation failed because the path
specified with --with-xtables= was not passed to gcc.
2008-03-05 00:19:15 +01:00
23 changed files with 944 additions and 55 deletions

6
.gitignore vendored
View File

@@ -1,17 +1,11 @@
.*.cmd
*.ko
*.la
*.lo
*.loT
*.mod.c
*.o
.deps
.libs
.tmp_versions
Makefile
Makefile.in
Module.symvers
modules.order
/downloads

View File

@@ -12,9 +12,9 @@ in combination with the kernel's Kbuild system.
Prerequirements
===============
* xtables(-devel) 1.5.0
* xtables(-devel) 1.5.2
* kernel-source >= 2.6.22 with prepared output directory
* kernel-source >= 2.6.18 with prepared build/output directory
Selecting extensions

View File

@@ -8,5 +8,5 @@ tarball:
rm -Rf /tmp/xtables-addons-${PACKAGE_VERSION};
pushd ${top_srcdir} && git-archive --prefix=xtables-addons-${PACKAGE_VERSION}/ HEAD | tar -C /tmp -x && popd;
pushd /tmp/xtables-addons-${PACKAGE_VERSION} && ./autogen.sh && popd;
tar -C /tmp -cjf xtables-addons-${PACKAGE_VERSION}.tar.bz2 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};

View File

@@ -1,5 +1,5 @@
AC_INIT([xtables-addons], [1.5.2])
AC_INIT([xtables-addons], [1.5.3])
AC_CONFIG_HEADERS([config.h])
AC_PROG_INSTALL
AM_INIT_AUTOMAKE

10
extensions/.gitignore vendored Normal file
View File

@@ -0,0 +1,10 @@
.*.cmd
.*.d
.tmp_versions
*.ko
*.mod.c
*.so
*.oo
GNUmakefile
Module.symvers
modules.order

View File

@@ -25,8 +25,9 @@ CFLAGS := @CFLAGS@
LDFLAGS := @LDFLAGS@
regular_CFLAGS := @regular_CFLAGS@
kinclude_CFLAGS := @kinclude_CFLAGS@
xtables_CFLAGS := @xtables_CFLAGS@
AM_CFLAGS := ${regular_CFLAGS} -I${top_srcdir}/include ${kinclude_CFLAGS}
AM_CFLAGS := ${regular_CFLAGS} -I${top_srcdir}/include ${xtables_CFLAGS} ${kinclude_CFLAGS}
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
ifeq (${V},)

View File

@@ -7,9 +7,11 @@ obj-m += compat_xtables.o
obj-${build_CHAOS} += xt_CHAOS.o
obj-${build_DELUDE} += xt_DELUDE.o
obj-${build_ECHO} += xt_ECHO.o
obj-${build_LOGMARK} += xt_LOGMARK.o
obj-${build_TARPIT} += xt_TARPIT.o
obj-${build_TEE} += xt_TEE.o
obj-${build_geoip} += xt_geoip.o
obj-${build_portscan} += xt_portscan.o
-include ${M}/*.Kbuild

View File

@@ -0,0 +1,20 @@
#ifndef COMPAT_SKBUFF_H
#define COMPAT_SKBUFF_H 1
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
# define skb_nfmark(skb) (((struct sk_buff *)(skb))->nfmark)
#else
# define skb_nfmark(skb) (((struct sk_buff *)(skb))->mark)
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 21)
# define ip_hdr(skb) ((skb)->nh.iph)
# define ip_hdrlen(skb) (ip_hdr(skb)->ihl * 4)
# define skb_network_header(skb) ((skb)->nh.raw)
static inline void skb_reset_network_header(struct sk_buff *skb)
{
skb->nh.raw = skb->data;
}
#endif
#endif /* COMPAT_SKBUFF_H */

View File

@@ -1,3 +1,4 @@
#include <linux/ip.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/slab.h>
@@ -8,9 +9,10 @@
#include <linux/netfilter_arp.h>
#include <net/ip.h>
#include <net/route.h>
#include "compat_skbuff.h"
#include "compat_xtnu.h"
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 22)
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
static int xtnu_match_run(const struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
const struct xt_match *cm, const void *matchinfo, int offset,
@@ -26,9 +28,17 @@ static int xtnu_match_run(const struct sk_buff *skb,
*hotdrop = lo_drop;
return lo_ret;
}
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
static int xtnu_match_check(const char *table, const void *entry,
const struct xt_match *cm, void *matchinfo, unsigned int matchinfosize,
unsigned int hook_mask)
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
static int xtnu_match_check(const char *table, const void *entry,
const struct xt_match *cm, void *matchinfo, unsigned int hook_mask)
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
{
struct xtnu_match *nm = xtcompat_numatch(cm);
@@ -38,15 +48,24 @@ static int xtnu_match_check(const char *table, const void *entry,
return true;
return nm->checkentry(table, entry, nm, matchinfo, hook_mask);
}
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
static void xtnu_match_destroy(const struct xt_match *cm, void *matchinfo,
unsigned int matchinfosize)
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
static void xtnu_match_destroy(const struct xt_match *cm, void *matchinfo)
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
{
struct xtnu_match *nm = xtcompat_numatch(cm);
if (nm != NULL && nm->destroy != NULL)
nm->destroy(nm, matchinfo);
}
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
int xtnu_register_match(struct xtnu_match *nt)
{
struct xt_match *ct;
@@ -114,52 +133,65 @@ void xtnu_unregister_matches(struct xtnu_match *nt, unsigned int num)
xtnu_unregister_match(&nt[i]);
}
EXPORT_SYMBOL_GPL(xtnu_unregister_matches);
static int xtnu_target_check(const char *table, const void *entry,
const struct xt_target *ct, void *targinfo, unsigned int hook_mask)
{
struct xtnu_target *nt = xtcompat_nutarget(ct);
if (nt == NULL)
return false;
if (nt->checkentry == NULL)
/* this is valid, just like if there was no function */
return true;
return nt->checkentry(table, entry, nt, targinfo, hook_mask);
}
#endif
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 23)
static bool xtnu_target_check(const char *table, const void *entry,
const struct xt_target *ct, void *targinfo, unsigned int hook_mask)
{
struct xtnu_target *nt = xtcompat_nutarget(ct);
if (nt == NULL)
return false;
if (nt->checkentry == NULL)
/* this is valid, just like if there was no function */
return true;
return nt->checkentry(table, entry, nt, targinfo, hook_mask);
}
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
static unsigned int xtnu_target_run(struct sk_buff **pskb,
const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *ct, const void *targinfo,
void *userdata)
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
static unsigned int xtnu_target_run(struct sk_buff **pskb,
const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *ct, const void *targinfo)
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
{
struct xtnu_target *nt = xtcompat_nutarget(ct);
if (nt != NULL && nt->target != NULL)
return nt->target(*pskb, in, out, hooknum, nt, targinfo);
return XT_CONTINUE;
}
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
static int xtnu_target_check(const char *table, const void *entry,
const struct xt_target *ct, void *targinfo,
unsigned int targinfosize, unsigned int hook_mask)
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
static int xtnu_target_check(const char *table, const void *entry,
const struct xt_target *ct, void *targinfo, unsigned int hook_mask)
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
static bool xtnu_target_check(const char *table, const void *entry,
const struct xt_target *ct, void *targinfo, unsigned int hook_mask)
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
{
struct xtnu_target *nt = xtcompat_nutarget(ct);
if (nt == NULL)
return false;
if (nt->checkentry == NULL)
/* this is valid, just like if there was no function */
return true;
return nt->checkentry(table, entry, nt, targinfo, hook_mask);
}
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
static void xtnu_target_destroy(const struct xt_target *ct, void *targinfo,
unsigned int targinfosize)
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
static void xtnu_target_destroy(const struct xt_target *ct, void *targinfo)
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
{
struct xtnu_target *nt = xtcompat_nutarget(ct);
if (nt != NULL && nt->destroy != NULL)
nt->destroy(nt, targinfo);
}
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
int xtnu_register_target(struct xtnu_target *nt)
{
struct xt_target *ct;
@@ -233,9 +265,14 @@ struct xt_match *xtnu_request_find_match(unsigned int af, const char *name,
uint8_t revision)
{
static const char *const xt_prefix[] = {
[AF_UNSPEC] = "x",
[AF_INET] = "ip",
[AF_INET6] = "ip6",
#ifdef AF_ARP
[AF_ARP] = "arp",
#elif defined(NF_ARP) && NF_ARP != AF_UNSPEC
[NF_ARP] = "arp",
#endif
};
struct xt_match *match;
@@ -251,7 +288,11 @@ EXPORT_SYMBOL_GPL(xtnu_request_find_match);
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
int xtnu_ip_route_me_harder(struct sk_buff *skb, unsigned int addr_type)
{
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
return ip_route_me_harder(&skb);
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
return ip_route_me_harder(&skb, addr_type);
#endif
}
EXPORT_SYMBOL_GPL(xtnu_ip_route_me_harder);
#endif
@@ -310,4 +351,19 @@ int xtnu_ip_route_output_key(void *net, struct rtable **rp, struct flowi *flp)
EXPORT_SYMBOL_GPL(xtnu_ip_route_output_key);
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
int xtnu_neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb)
{
unsigned int hh_alen;
read_lock_bh(&hh->hh_lock);
hh_alen = HH_DATA_ALIGN(hh->hh_len);
memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
read_unlock_bh(&hh->hh_lock);
skb_push(skb, hh->hh_len);
return hh->hh_output(skb);
}
EXPORT_SYMBOL_GPL(xtnu_neigh_hh_output);
#endif
MODULE_LICENSE("GPL");

View File

@@ -2,10 +2,32 @@
#define _XTABLES_COMPAT_H 1
#include <linux/version.h>
#include "compat_skbuff.h"
#include "compat_xtnu.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
# warning Kernels below 2.6.22 not supported anymore
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
# warning Kernels below 2.6.18 not supported.
#endif
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
# if !defined(CONFIG_NF_CONNTRACK_MARK) || !defined(CONFIG_NF_CONNTRACK_SECMARK)
# warning You have CONFIG_NF_CONNTRACK enabled, but CONFIG_NF_CONNTRACK_MARK or CONFIG_NF_CONNTRACK_SECMARK are not (please enable).
# endif
# include <net/netfilter/nf_conntrack.h>
#elif defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
# if !defined(CONFIG_IP_NF_CONNTRACK_MARK) || !defined(CONFIG_IP_NF_CONNTRACK_SECMARK)
# warning You have CONFIG_IP_NF_CONNTRACK enabled, but CONFIG_IP_NF_CONNTRACK_MARK or CONFIG_IP_NF_CONNTRACK_SECMARK are not (please enable).
# endif
# include <linux/netfilter_ipv4/ip_conntrack.h>
# define nf_conn ip_conntrack
# define nf_ct_get ip_conntrack_get
# define nf_conntrack_untracked ip_conntrack_untracked
#else
# warning You need either CONFIG_NF_CONNTRACK or CONFIG_IP_NF_CONNTRACK.
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
# define neigh_hh_output xtnu_neigh_hh_output
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
@@ -26,7 +48,7 @@
# define init_net__loopback_dev init_net.loopback_dev
#endif
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 22)
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
# define xt_match xtnu_match
# define xt_register_match xtnu_register_match
# define xt_unregister_match xtnu_unregister_match

View File

@@ -5,7 +5,13 @@
#include <linux/netfilter/x_tables.h>
#include <linux/spinlock.h>
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
typedef _Bool bool;
enum { false = 0, true = 1, };
#endif
struct flowi;
struct hh_cache;
struct module;
struct net_device;
struct rtable;
@@ -74,5 +80,6 @@ extern int xtnu_register_targets(struct xtnu_target *, unsigned int);
extern void xtnu_unregister_targets(struct xtnu_target *, unsigned int);
extern struct xt_match *xtnu_request_find_match(unsigned int,
const char *, uint8_t);
extern int xtnu_neigh_hh_output(struct hh_cache *, struct sk_buff *);
#endif /* _COMPAT_XTNU_H */

34
extensions/libxt_ECHO.c Normal file
View File

@@ -0,0 +1,34 @@
#include <stdio.h>
#include <getopt.h>
#include <xtables.h>
static void echo_tg_help(void)
{
printf("ECHO takes no options\n\n");
}
static int echo_tg_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_target **target)
{
return 0;
}
static void echo_tg_check(unsigned int flags)
{
}
static struct xtables_target echo_tg_reg = {
.version = XTABLES_VERSION,
.name = "ECHO",
.family = AF_UNSPEC,
.size = XT_ALIGN(0),
.userspacesize = XT_ALIGN(0),
.help = echo_tg_help,
.parse = echo_tg_parse,
.final_check = echo_tg_check,
};
static void _init(void)
{
xtables_register_target(&echo_tg_reg);
}

278
extensions/libxt_geoip.c Normal file
View File

@@ -0,0 +1,278 @@
/* Shared library add-on to iptables to add geoip match support.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (c) 2004, 2005, 2006, 2007, 2008
* Samuel Jean & Nicolas Bouliane
*
* For comments, bugs or suggestions, please contact
* Samuel Jean <peejix@people.netfilter.org>
* Nicolas Bouliane <peejix@people.netfilter.org>
*/
#include <sys/stat.h>
#include <sys/types.h>
#include <ctype.h>
#include <endian.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <xtables.h>
#include "xt_geoip.h"
#define GEOIP_DB_DIR "/var/geoip"
static void geoip_help(void)
{
printf (
"geoip match options:\n"
"[!] --src-cc, --source-country country[,country...]\n"
" Match packet coming from (one of) the specified country(ies)\n"
"[!] --dst-cc, --destination-country country[,country...]\n"
" Match packet going to (one of) the specified country(ies)\n"
"\n"
"NOTE: The country is inputed by its ISO3166 code.\n"
"\n"
);
}
static struct option geoip_opts[] = {
{.name = "dst-cc", .has_arg = true, .val = '2'},
{.name = "destination-country", .has_arg = true, .val = '2'},
{.name = "src-cc", .has_arg = true, .val = '1'},
{.name = "source-country", .has_arg = true, .val = '1'},
{NULL},
};
static struct geoip_subnet *geoip_get_subnets(const char *code, uint32_t *count)
{
struct geoip_subnet *subnets;
struct stat sb;
char buf[256];
int fd;
/* Use simple integer vector files */
#if __BYTE_ORDER == _BIG_ENDIAN
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/BE/%s.iv0", code);
#else
snprintf(buf, sizeof(buf), GEOIP_DB_DIR "/LE/%s.iv0", code);
#endif
if ((fd = open(buf, O_RDONLY)) < 0) {
fprintf(stderr, "Could not open %s: %s\n", buf, strerror(errno));
exit_error(OTHER_PROBLEM, "Could not read geoip database");
}
fstat(fd, &sb);
if (sb.st_size % sizeof(struct geoip_subnet) != 0)
exit_error(OTHER_PROBLEM, "Database file %s seems to be "
"corrupted", buf);
subnets = malloc(sb.st_size);
if (subnets == NULL)
exit_error(OTHER_PROBLEM, "geoip: insufficient memory");
read(fd, subnets, sb.st_size);
close(fd);
*count = sb.st_size / sizeof(struct geoip_subnet);
return subnets;
}
static struct geoip_country_user *geoip_load_cc(const char *code,
unsigned short cc)
{
struct geoip_country_user *ginfo;
ginfo = malloc(sizeof(struct geoip_country_user));
if (!ginfo)
return NULL;
ginfo->subnets = (unsigned long)geoip_get_subnets(code, &ginfo->count);
ginfo->cc = cc;
return ginfo;
}
static u_int16_t
check_geoip_cc(char *cc, u_int16_t cc_used[], u_int8_t count)
{
u_int8_t i;
u_int16_t cc_int16;
if (strlen(cc) != 2) /* Country must be 2 chars long according
to the ISO3166 standard */
exit_error(PARAMETER_PROBLEM,
"geoip: invalid country code '%s'", cc);
// Verification will fail if chars aren't uppercased.
// Make sure they are..
for (i = 0; i < 2; i++)
if (isalnum(cc[i]) != 0)
cc[i] = toupper(cc[i]);
else
exit_error(PARAMETER_PROBLEM,
"geoip: invalid country code '%s'", cc);
/* Convert chars into a single 16 bit integer.
* FIXME: This assumes that a country code is
* exactly 2 chars long. If this is
* going to change someday, this whole
* match will need to be rewritten, anyway.
* - SJ */
cc_int16 = (cc[0] << 8) | cc[1];
// Check for presence of value in cc_used
for (i = 0; i < count; i++)
if (cc_int16 == cc_used[i])
return 0; // Present, skip it!
return cc_int16;
}
static unsigned int parse_geoip_cc(const char *ccstr, uint16_t *cc,
union geoip_country_group *mem)
{
char *buffer, *cp, *next;
u_int8_t i, count = 0;
u_int16_t cctmp;
buffer = strdup(ccstr);
if (!buffer)
exit_error(OTHER_PROBLEM,
"geoip: insufficient memory available");
for (cp = buffer, i = 0; cp && i < XT_GEOIP_MAX; cp = next, i++)
{
next = strchr(cp, ',');
if (next) *next++ = '\0';
if ((cctmp = check_geoip_cc(cp, cc, count)) != 0) {
if ((mem[count++].user = (unsigned long)geoip_load_cc(cp, cctmp)) == 0)
exit_error(OTHER_PROBLEM,
"geoip: insufficient memory available");
cc[count-1] = cctmp;
}
}
if (cp)
exit_error(PARAMETER_PROBLEM,
"geoip: too many countries specified");
free(buffer);
if (count == 0)
exit_error(PARAMETER_PROBLEM,
"geoip: don't know what happened");
return count;
}
static int geoip_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_match **match)
{
struct xt_geoip_match_info *info = (void *)(*match)->data;
switch(c) {
case '1':
// Ensure that XT_GEOIP_SRC *OR* XT_GEOIP_DST haven't been used yet.
if (*flags & (XT_GEOIP_SRC | XT_GEOIP_DST))
exit_error(PARAMETER_PROBLEM,
"geoip: only use --source-country *OR* --destination-country once!");
*flags |= XT_GEOIP_SRC;
break;
case '2':
// Ensure that XT_GEOIP_SRC *OR* XT_GEOIP_DST haven't been used yet.
if (*flags & (XT_GEOIP_SRC | XT_GEOIP_DST))
exit_error(PARAMETER_PROBLEM,
"geoip: only use --source-country *OR* --destination-country once!");
*flags |= XT_GEOIP_DST;
break;
default:
return 0;
}
if (invert)
*flags |= XT_GEOIP_INV;
info->count = parse_geoip_cc(argv[optind-1], info->cc, info->mem);
info->flags = *flags;
return 1;
}
static void
geoip_final_check(unsigned int flags)
{
if (!flags)
exit_error(PARAMETER_PROBLEM,
"geoip: missing arguments");
}
static void
geoip_print(const void *ip, const struct xt_entry_match *match, int numeric)
{
const struct xt_geoip_match_info *info = (void*)match->data;
u_int8_t i;
if (info->flags & XT_GEOIP_SRC)
printf("Source ");
else
printf("Destination ");
if (info->count > 1)
printf("countries: ");
else
printf("country: ");
if (info->flags & XT_GEOIP_INV)
printf("! ");
for (i = 0; i < info->count; i++)
printf("%s%c%c", i ? "," : "", COUNTRY(info->cc[i]));
printf(" ");
}
static void
geoip_save(const void *ip, const struct xt_entry_match *match)
{
const struct xt_geoip_match_info *info = (void *)match->data;
u_int8_t i;
if (info->flags & XT_GEOIP_INV)
printf("! ");
if (info->flags & XT_GEOIP_SRC)
printf("--source-country ");
else
printf("--destination-country ");
for (i = 0; i < info->count; i++)
printf("%s%c%c", i ? "," : "", COUNTRY(info->cc[i]));
printf(" ");
}
static struct xtables_match geoip_match = {
.family = AF_INET,
.name = "geoip",
.version = XTABLES_VERSION,
.size = XT_ALIGN(sizeof(struct xt_geoip_match_info)),
.userspacesize = XT_ALIGN(offsetof(struct xt_geoip_match_info, mem)),
.help = geoip_help,
.parse = geoip_parse,
.final_check = geoip_final_check,
.print = geoip_print,
.save = geoip_save,
.extra_opts = geoip_opts,
};
static void _init(void)
{
xtables_register_match(&geoip_match);
}

View File

@@ -0,0 +1,16 @@
Match a packet by its source or destination country.
.TP
[\fB!\fP] \fB--src-cc\fP, \fB--source-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
Match packet coming from (one of) the specified country(ies)
.TP
[\fB!\fP] \fB--dst-cc\fP, \fB--destination-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
Match packet going to (one of) the specified country(ies)
.TP
NOTE:
The country is inputed by its ISO3166 code.
.P
The extra files you will need is the binary database files. They are generated
from a country-subnet database with the geoip_csv_iv0.pl tool, available at
http://jengelh.hopto.org/files/geoip/ . The files MUST be moved to /var/geoip/
as the shared library is statically looking for this pathname (e.g.
/var/geoip/LE/de.iv0).

View File

@@ -53,7 +53,7 @@ static void xt_chaos_total(const struct xt_chaos_tginfo *info,
const int offset = ntohs(iph->frag_off) & IP_OFFSET;
typeof(xt_tarpit) destiny;
bool ret;
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 22)
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
int hotdrop = false;
#else
bool hotdrop = false;
@@ -65,7 +65,9 @@ static void xt_chaos_total(const struct xt_chaos_tginfo *info,
return;
destiny = (info->variant == XTCHAOS_TARPIT) ? xt_tarpit : xt_delude;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
destiny->target(&skb, in, out, hooknum, destiny, NULL, NULL);
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
destiny->target(&skb, in, out, hooknum, destiny, NULL);
#else
destiny->target(skb, in, out, hooknum, destiny, NULL);
@@ -89,7 +91,10 @@ static unsigned int chaos_tg(struct sk_buff *skb, const struct net_device *in,
const struct iphdr *iph = ip_hdr(skb);
if ((unsigned int)net_random() <= reject_percentage)
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
return xt_reject->target(&skb, in, out, hooknum,
target->__compat_target, &reject_params, NULL);
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
return xt_reject->target(&skb, in, out, hooknum,
target->__compat_target, &reject_params);
#else

View File

@@ -99,9 +99,15 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
}
}
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 20)
tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr), niph->saddr,
niph->daddr, csum_partial((char *)tcph,
sizeof(struct tcphdr), 0));
#else
tcph->check = tcp_v4_check(sizeof(struct tcphdr), niph->saddr,
niph->daddr, csum_partial((char *)tcph,
sizeof(struct tcphdr), 0));
#endif
addr_type = RTN_UNSPEC;
#ifdef CONFIG_BRIDGE_NETFILTER

130
extensions/xt_ECHO.c Normal file
View File

@@ -0,0 +1,130 @@
/*
* ECHO target (RFC 862)
* Copyright © CC Computer Consultants GmbH, 2008
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 or 3 as published by the Free Software Foundation.
*/
#include <linux/ip.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/udp.h>
#include <linux/netfilter/x_tables.h>
#ifdef CONFIG_BRIDGE_NETFILTER
# include <linux/netfilter_bridge.h>
#endif
#include <net/ip.h>
#include "compat_xtables.h"
static unsigned int echo_tg4(struct sk_buff *oldskb,
const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *target, const void *targinfo)
{
const struct udphdr *oldudp;
const struct iphdr *oldip;
struct udphdr *newudp, oldudp_buf;
struct iphdr *newip;
struct sk_buff *newskb;
unsigned int addr_type, data_len;
void *payload;
/* This allows us to do the copy operation in fewer lines of code. */
skb_linearize(oldskb);
oldip = ip_hdr(oldskb);
oldudp = skb_header_pointer(oldskb, ip_hdrlen(oldskb),
sizeof(struct udphdr), &oldudp_buf);
if (oldudp == NULL)
return NF_DROP;
if (ntohs(oldudp->len) <= sizeof(struct udphdr))
return NF_DROP;
newskb = alloc_skb(LL_MAX_HEADER + sizeof(struct iphdr) +
ntohs(oldudp->len), GFP_ATOMIC);
if (newskb == NULL)
return NF_DROP;
skb_reserve(newskb, LL_MAX_HEADER);
skb_reset_network_header(newskb);
newip = (void *)skb_put(newskb, sizeof(struct iphdr));
newip->version = 4;
newip->ihl = sizeof(struct iphdr) / 4;
newip->tos = oldip->tos;
newip->id = 0;
newip->frag_off = htons(IP_DF);
newip->protocol = oldip->protocol;
newip->check = 0;
newip->saddr = oldip->daddr;
newip->daddr = oldip->saddr;
newudp = (void *)skb_put(newskb, sizeof(struct udphdr));
newudp->source = oldudp->dest;
newudp->dest = oldudp->source;
newudp->len = oldudp->len;
newudp->check = 0;
data_len = htons(oldudp->len) - sizeof(*oldudp);
payload = skb_header_pointer(oldskb, ip_hdrlen(oldskb) +
sizeof(*oldudp), data_len, NULL);
memcpy(skb_put(newskb, data_len), payload, data_len);
addr_type = RTN_UNSPEC;
#ifdef CONFIG_BRIDGE_NETFILTER
if (hooknum != NF_INET_FORWARD || (newskb->nf_bridge != NULL &&
newskb->nf_bridge->mask & BRNF_BRIDGED))
#else
if (hooknum != NF_INET_FORWARD)
#endif
addr_type = RTN_LOCAL;
/* ip_route_me_harder expects skb->dst to be set */
dst_hold(oldskb->dst);
newskb->dst = oldskb->dst;
if (ip_route_me_harder(newskb, addr_type) < 0)
goto free_nskb;
newip->ttl = dst_metric(newskb->dst, RTAX_HOPLIMIT);
newskb->ip_summed = CHECKSUM_NONE;
/* "Never happens" (?) */
if (newskb->len > dst_mtu(newskb->dst))
goto free_nskb;
nf_ct_attach(newskb, oldskb);
ip_local_out(newskb);
return NF_DROP;
free_nskb:
kfree_skb(newskb);
return NF_DROP;
}
static struct xt_target echo_tg_reg __read_mostly = {
.name = "ECHO",
.revision = 0,
.family = AF_INET,
.proto = IPPROTO_UDP,
.table = "filter",
.target = echo_tg4,
.targetsize = XT_ALIGN(0),
.me = THIS_MODULE,
};
static int __init echo_tg_init(void)
{
return xt_register_target(&echo_tg_reg);
}
static void __exit echo_tg_exit(void)
{
return xt_unregister_target(&echo_tg_reg);
}
module_init(echo_tg_init);
module_exit(echo_tg_exit);
MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
MODULE_DESCRIPTION("Xtables: ECHO diagnosis target");
MODULE_LICENSE("GPL");
MODULE_ALIAS("ipt_ECHO");

View File

@@ -11,8 +11,9 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter/nf_conntrack_common.h>
#include <linux/netfilter/x_tables.h>
#include <net/netfilter/nf_conntrack.h>
//#include <net/netfilter/nf_conntrack.h>
#include "compat_xtables.h"
#include "xt_LOGMARK.h"
@@ -27,7 +28,7 @@ logmark_tg(struct sk_buff *skb, const struct net_device *in,
printk("<%u>%.*s""nfmark=0x%x secmark=0x%x classify=0x%x",
info->level, (unsigned int)sizeof(info->prefix), info->prefix,
skb->mark, skb->secmark, skb->priority);
skb_nfmark(skb), skb->secmark, skb->priority);
ct = nf_ct_get(skb, &ctinfo);
if (ct == NULL) {

View File

@@ -90,7 +90,7 @@ static inline void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
/* This packet will not be the same as the other: clear nf fields */
nf_reset(nskb);
nskb->mark = 0;
skb_nfmark(nskb) = 0;
skb_init_secmark(nskb);
skb_shinfo(nskb)->gso_size = 0;
@@ -132,9 +132,15 @@ static inline void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
/* Adjust TCP checksum */
tcph->check = 0;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 20)
tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr), niph->saddr,
niph->daddr, csum_partial((char *)tcph,
sizeof(struct tcphdr), 0));
#else
tcph->check = tcp_v4_check(sizeof(struct tcphdr), niph->saddr,
niph->daddr, csum_partial((char *)tcph,
sizeof(struct tcphdr), 0));
#endif
/* Set DF, id = 0 */
niph->frag_off = htons(IP_DF);

246
extensions/xt_geoip.c Normal file
View File

@@ -0,0 +1,246 @@
/* iptables kernel module for the geoip match
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (c) 2004, 2005, 2006, 2007, 2008
* Samuel Jean & Nicolas Bouliane
*/
#include <linux/ip.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/rcupdate.h>
#include <linux/skbuff.h>
#include <linux/version.h>
#include <linux/vmalloc.h>
#include <linux/netfilter/x_tables.h>
#include <asm/atomic.h>
#include <asm/uaccess.h>
#include "xt_geoip.h"
#include "compat_xtables.h"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Nicolas Bouliane");
MODULE_AUTHOR("Samuel Jean");
MODULE_DESCRIPTION("xtables module for geoip match");
MODULE_ALIAS("ipt_geoip");
struct geoip_country_kernel {
struct list_head list;
struct geoip_subnet *subnets;
atomic_t ref;
unsigned int count;
unsigned short cc;
};
static LIST_HEAD(geoip_head);
static DEFINE_SPINLOCK(geoip_lock);
static struct geoip_country_kernel *
geoip_add_node(const struct geoip_country_user __user *umem_ptr)
{
struct geoip_country_user umem;
struct geoip_country_kernel *p;
struct geoip_subnet *s;
if (copy_from_user(&umem, umem_ptr, sizeof(umem)) != 0)
return NULL;
p = kmalloc(sizeof(struct geoip_country_kernel), GFP_KERNEL);
if (p == NULL)
return NULL;
p->count = umem.count;
p->cc = umem.cc;
s = vmalloc(p->count * sizeof(struct geoip_subnet));
if (s == NULL)
goto free_p;
if (copy_from_user(s, (const void __user *)(unsigned long)umem.subnets,
p->count * sizeof(struct geoip_subnet)) != 0)
goto free_s;
p->subnets = s;
atomic_set(&p->ref, 1);
INIT_LIST_HEAD(&p->list);
spin_lock(&geoip_lock);
list_add_tail_rcu(&p->list, &geoip_head);
spin_unlock(&geoip_lock);
return p;
free_s:
vfree(s);
free_p:
kfree(p);
return NULL;
}
static void geoip_try_remove_node(struct geoip_country_kernel *p)
{
spin_lock(&geoip_lock);
if (!atomic_dec_and_test(&p->ref)) {
spin_unlock(&geoip_lock);
return;
}
/* So now am unlinked or the only one alive, right ?
* What are you waiting ? Free up some memory!
*/
list_del_rcu(&p->list);
spin_unlock(&geoip_lock);
synchronize_rcu();
vfree(p->subnets);
kfree(p);
}
static struct geoip_country_kernel *find_node(unsigned short cc)
{
struct geoip_country_kernel *p;
spin_lock(&geoip_lock);
list_for_each_entry_rcu(p, &geoip_head, list)
if (p->cc == cc) {
atomic_inc(&p->ref);
spin_unlock(&geoip_lock);
return p;
}
spin_unlock(&geoip_lock);
return NULL;
}
static bool geoip_bsearch(const struct geoip_subnet *range,
uint32_t addr, int lo, int hi)
{
int mid;
if (hi < lo)
return false;
mid = (lo + hi) / 2;
if (range[mid].begin <= addr && addr <= range[mid].end)
return true;
if (range[mid].begin > addr)
return geoip_bsearch(range, addr, lo, mid - 1);
else if (range[mid].end < addr)
return geoip_bsearch(range, addr, mid + 1, hi);
WARN_ON(true);
return false;
}
static bool xt_geoip_mt(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
{
const struct xt_geoip_match_info *info = matchinfo;
const struct geoip_country_kernel *node;
const struct iphdr *iph = ip_hdr(skb);
unsigned int i;
uint32_t ip;
if (info->flags & XT_GEOIP_SRC)
ip = ntohl(iph->saddr);
else
ip = ntohl(iph->daddr);
rcu_read_lock();
for (i = 0; i < info->count; i++) {
if ((node = info->mem[i].kernel) == NULL) {
printk(KERN_ERR "xt_geoip: what the hell ?? '%c%c' isn't loaded into memory... skip it!\n",
COUNTRY(info->cc[i]));
continue;
}
if (geoip_bsearch(node->subnets, ip, 0, node->count)) {
rcu_read_unlock();
return !(info->flags & XT_GEOIP_INV);
}
}
rcu_read_unlock();
return info->flags & XT_GEOIP_INV;
}
static bool xt_geoip_mt_checkentry(const char *table, const void *entry,
const struct xt_match *match, void *matchinfo, unsigned int hook_mask)
{
struct xt_geoip_match_info *info = matchinfo;
struct geoip_country_kernel *node;
unsigned int i;
for (i = 0; i < info->count; i++) {
node = find_node(info->cc[i]);
if (node == NULL)
if ((node = geoip_add_node((const void __user *)(unsigned long)info->mem[i].user)) == NULL) {
printk(KERN_ERR
"xt_geoip: unable to load '%c%c' into memory\n",
COUNTRY(info->cc[i]));
return false;
}
/* Overwrite the now-useless pointer info->mem[i] with
* a pointer to the node's kernelspace structure.
* This avoids searching for a node in the match() and
* destroy() functions.
*/
info->mem[i].kernel = node;
}
return true;
}
static void xt_geoip_mt_destroy(const struct xt_match *match, void *matchinfo)
{
struct xt_geoip_match_info *info = matchinfo;
struct geoip_country_kernel *node;
unsigned int i;
/* This entry has been removed from the table so
* decrease the refcount of all countries it is
* using.
*/
for (i = 0; i < info->count; i++)
if ((node = info->mem[i].kernel) != NULL) {
/* Free up some memory if that node isn't used
* anymore. */
geoip_try_remove_node(node);
}
else
/* Something strange happened. There's no memory allocated for this
* country. Please send this bug to the mailing list. */
printk(KERN_ERR
"xt_geoip: What happened peejix ? What happened acidfu ?\n"
"xt_geoip: please report this bug to the maintainers\n");
}
static struct xt_match xt_geoip_match __read_mostly = {
.family = AF_INET,
.name = "geoip",
.match = xt_geoip_mt,
.checkentry = xt_geoip_mt_checkentry,
.destroy = xt_geoip_mt_destroy,
.matchsize = sizeof(struct xt_geoip_match_info),
.me = THIS_MODULE,
};
static int __init xt_geoip_mt_init(void)
{
return xt_register_match(&xt_geoip_match);
}
static void __exit xt_geoip_mt_fini(void)
{
xt_unregister_match(&xt_geoip_match);
}
module_init(xt_geoip_mt_init);
module_exit(xt_geoip_mt_fini);

54
extensions/xt_geoip.h Normal file
View File

@@ -0,0 +1,54 @@
/* ipt_geoip.h header file for libipt_geoip.c and ipt_geoip.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (c) 2004, 2005, 2006, 2007, 2008
*
* Samuel Jean
* Nicolas Bouliane
*/
#ifndef _LINUX_NETFILTER_XT_GEOIP_H
#define _LINUX_NETFILTER_XT_GEOIP_H 1
enum {
XT_GEOIP_SRC = 1 << 0, /* Perform check on Source IP */
XT_GEOIP_DST = 1 << 1, /* Perform check on Destination IP */
XT_GEOIP_INV = 1 << 2, /* Negate the condition */
XT_GEOIP_MAX = 15, /* Maximum of countries */
};
/* Yup, an address range will be passed in with host-order */
struct geoip_subnet {
__u32 begin;
__u32 end;
};
struct geoip_country_user {
aligned_u64 subnets;
__u32 count;
__u16 cc;
};
struct geoip_country_kernel;
union geoip_country_group {
aligned_u64 user;
struct geoip_country_kernel *kernel;
};
struct xt_geoip_match_info {
__u8 flags;
__u8 count;
__u16 cc[XT_GEOIP_MAX];
/* Used internally by the kernel */
union geoip_country_group mem[XT_GEOIP_MAX];
};
#define COUNTRY(cc) (cc >> 8), (cc & 0x00FF)
#endif /* _LINUX_NETFILTER_XT_GEOIP_H */

View File

@@ -17,7 +17,7 @@
#include <linux/version.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_tcpudp.h>
#include <net/netfilter/nf_nat_rule.h>
//#include <net/netfilter/nf_conntrack.h>
#include "xt_portscan.h"
#include "compat_xtables.h"
#define PFX KBUILD_MODNAME ": "
@@ -203,7 +203,7 @@ static bool portscan_mt(const struct sk_buff *skb,
* it either when the connection is already VALID.
*/
if ((ctdata->mark & connmark_mask) == mark_valid ||
(skb->mark & packet_mask) != mark_seen) {
(skb_nfmark(skb) & packet_mask) != mark_seen) {
unsigned int n;
n = portscan_mt_full(ctdata->mark & connmark_mask, ctstate,
@@ -211,8 +211,7 @@ static bool portscan_mt(const struct sk_buff *skb,
skb->len - protoff - 4 * tcph->doff);
ctdata->mark = (ctdata->mark & ~connmark_mask) | n;
((struct sk_buff *)skb)->mark =
(skb->mark & ~packet_mask) ^ mark_seen;
skb_nfmark(skb) = (skb_nfmark(skb) & ~packet_mask) ^ mark_seen;
}
return (info->match_syn && ctdata->mark == mark_synscan) ||

View File

@@ -5,7 +5,9 @@
#
build_CHAOS=m
build_DELUDE=m
build_ECHO=
build_LOGMARK=m
build_TARPIT=m
build_TEE=m
build_geoip=m
build_portscan=m