--- /dev/null
+diff -ruN iptables-1.3.5.orig/extensions/.CHAOS-test iptables-1.3.5/extensions/.CHAOS-test
+--- iptables-1.3.5.orig/extensions/.CHAOS-test 1970-01-01 01:00:00.000000000 +0100
++++ iptables-1.3.5/extensions/.CHAOS-test 2007-01-09 16:05:23.251885840 +0100
+@@ -0,0 +1,2 @@
++#!/bin/sh
++[ -f "$KERNEL_DIR/include/linux/netfilter/xt_CHAOS.h" ] && echo "CHAOS";
+diff -ruN iptables-1.3.5.orig/extensions/.DELUDE-test iptables-1.3.5/extensions/.DELUDE-test
+--- iptables-1.3.5.orig/extensions/.DELUDE-test 1970-01-01 01:00:00.000000000 +0100
++++ iptables-1.3.5/extensions/.DELUDE-test 2007-01-09 16:05:18.104057722 +0100
+@@ -0,0 +1,2 @@
++#!/bin/sh
++echo "DELUDE";
+diff -ruN iptables-1.3.5.orig/extensions/libipt_CHAOS.c iptables-1.3.5/extensions/libipt_CHAOS.c
+--- iptables-1.3.5.orig/extensions/libipt_CHAOS.c 1970-01-01 01:00:00.000000000 +0100
++++ iptables-1.3.5/extensions/libipt_CHAOS.c 2007-01-09 16:05:23.251885840 +0100
+@@ -0,0 +1,111 @@
++/*
++ CHAOS target for iptables
++
++ Copyright © Jan Engelhardt <jengelh [at] gmx de>, 2006 - 2007
++ released under the terms of the GNU General Public
++ License version 2.x and only versions 2.x.
++*/
++#include <getopt.h>
++#include <stdio.h>
++#include <string.h>
++
++#include <iptables.h>
++#include <linux/netfilter_ipv4/ip_tables.h>
++#include <linux/netfilter/xt_CHAOS.h>
++
++static void libipt_chaos_help(void)
++{
++ printf(
++ "CHAOS target v%s options:\n"
++ " --delude Enable DELUDE processing for TCP\n"
++ " --tarpit Enable TARPIT processing for TCP\n",
++ IPTABLES_VERSION);
++ return;
++}
++
++static int libipt_chaos_parse(int c, char **argv, int invert,
++ unsigned int *flags, const struct ipt_entry *entry,
++ struct ipt_entry_target **target)
++{
++ struct xt_chaos_info *info = (void *)((*target)->data);
++ switch(c) {
++ case 'd':
++ info->variant = XTCHAOS_DELUDE;
++ *flags |= 0x02;
++ return 1;
++ case 't':
++ info->variant = XTCHAOS_TARPIT;
++ *flags |= 0x01;
++ return 1;
++ }
++ return 0;
++}
++
++static void libipt_chaos_check(unsigned int flags)
++{
++ if(flags != 0x03)
++ return;
++ /* If flags == 0x03, both were specified, which should not be. */
++ exit_error(PARAMETER_PROBLEM,
++ "CHAOS: only one of --tarpit or --delude may be specified");
++ return;
++}
++
++static void libipt_chaos_print(const struct ipt_ip *ip,
++ const struct ipt_entry_target *target, int numeric)
++{
++ const struct xt_chaos_info *info = (const void *)target->data;
++ switch(info->variant) {
++ case XTCHAOS_DELUDE:
++ printf("DELUDE ");
++ break;
++ case XTCHAOS_TARPIT:
++ printf("TARPIT ");
++ break;
++ default:
++ break;
++ }
++ return;
++}
++
++static void libipt_chaos_save(const struct ipt_ip *ip,
++ const struct ipt_entry_target *target)
++{
++ const struct xt_chaos_info *info = (const void *)target->data;
++ switch(info->variant) {
++ case XTCHAOS_DELUDE:
++ printf("--delude ");
++ break;
++ case XTCHAOS_TARPIT:
++ printf("--tarpit ");
++ break;
++ default:
++ break;
++ }
++ return;
++}
++
++static struct option libipt_chaos_opts[] = {
++ {"delude", 0, NULL, 'd'},
++ {"tarpit", 0, NULL, 't'},
++ {NULL},
++};
++
++static struct iptables_target libipt_chaos_info = {
++ .name = "CHAOS",
++ .version = IPTABLES_VERSION,
++ .size = IPT_ALIGN(sizeof(struct xt_chaos_info)),
++ .userspacesize = IPT_ALIGN(sizeof(struct xt_chaos_info)),
++ .help = libipt_chaos_help,
++ .parse = libipt_chaos_parse,
++ .final_check = libipt_chaos_check,
++ .print = libipt_chaos_print,
++ .save = libipt_chaos_save,
++ .extra_opts = libipt_chaos_opts,
++};
++
++static __attribute__((constructor)) void libipt_chaos_init(void)
++{
++ register_target(&libipt_chaos_info);
++ return;
++}
+diff -ruN iptables-1.3.5.orig/extensions/libipt_DELUDE.c iptables-1.3.5/extensions/libipt_DELUDE.c
+--- iptables-1.3.5.orig/extensions/libipt_DELUDE.c 1970-01-01 01:00:00.000000000 +0100
++++ iptables-1.3.5/extensions/libipt_DELUDE.c 2007-01-09 16:05:18.104057722 +0100
+@@ -0,0 +1,66 @@
++/*
++ DELUDE target for iptables
++
++ Copyright © Jan Engelhardt <jengelh [at] gmx de>, 2006 - 2007
++ released under the terms of the GNU General Public
++ License version 2.x and only versions 2.x.
++*/
++#include <getopt.h>
++#include <stdio.h>
++#include <string.h>
++
++#include <iptables.h>
++#include <linux/netfilter_ipv4/ip_tables.h>
++
++static void libipt_delude_help(void)
++{
++ printf("DELUDE takes no options\n");
++ return;
++}
++
++static int libipt_delude_parse(int c, char **argv, int invert,
++ unsigned int *flags, const struct ipt_entry *entry,
++ struct ipt_entry_target **target)
++{
++ return 0;
++}
++
++static void libipt_delude_check(unsigned int flags)
++{
++ return;
++}
++
++static void libipt_delude_print(const struct ipt_ip *ip,
++ const struct ipt_entry_target *target, int numeric)
++{
++ return;
++}
++
++static void libipt_delude_save(const struct ipt_ip *ip,
++ const struct ipt_entry_target *target)
++{
++ return;
++}
++
++static struct option libipt_delude_opts[] = {
++ {NULL},
++};
++
++static struct iptables_target libipt_delude_info = {
++ .name = "DELUDE",
++ .version = IPTABLES_VERSION,
++ .size = IPT_ALIGN(0),
++ .userspacesize = IPT_ALIGN(0),
++ .help = libipt_delude_help,
++ .parse = libipt_delude_parse,
++ .final_check = libipt_delude_check,
++ .print = libipt_delude_print,
++ .save = libipt_delude_save,
++ .extra_opts = libipt_delude_opts,
++};
++
++static __attribute__((constructor)) void libipt_delude_init(void)
++{
++ register_target(&libipt_delude_info);
++ return;
++}
+diff -ruN iptables-1.3.5.orig/extensions/libipt_portscan.c iptables-1.3.5/extensions/libipt_portscan.c
+--- iptables-1.3.5.orig/extensions/libipt_portscan.c 1970-01-01 01:00:00.000000000 +0100
++++ iptables-1.3.5/extensions/libipt_portscan.c 2007-01-09 16:05:14.228187134 +0100
+@@ -0,0 +1,129 @@
++/*
++ portscan match for iptables
++
++ Copyright © Jan Engelhardt <jengelh [at] gmx de>, 2006 - 2007
++ released under the terms of the GNU General Public
++ License version 2.x and only versions 2.x.
++*/
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++#include <getopt.h>
++
++#include <iptables.h>
++#include <linux/netfilter_ipv4/ip_tables.h>
++#include <linux/netfilter/xt_portscan.h>
++
++static void libipt_portscan_help(void)
++{
++ printf(
++ "portscan match v%s options:\n"
++ "(Combining them will make them match by OR-logic)\n"
++ " --stealth Match TCP Stealth packets\n"
++ " --synscan Match TCP SYN scans\n"
++ " --cnscan Match TCP Connect scans\n"
++ " --grscan Match Banner Grabbing scans\n",
++ IPTABLES_VERSION);
++ return;
++}
++
++static void libipt_portscan_mtinit(struct ipt_entry_match *match,
++ unsigned int *nfcache)
++{
++ /* Cannot cache this */
++ *nfcache |= NFC_UNKNOWN;
++ return;
++}
++
++static int libipt_portscan_parse(int c, char **argv, int invert,
++ unsigned int *flags, const struct ipt_entry *entry, unsigned int *nfc,
++ struct ipt_entry_match **match)
++{
++ struct xt_portscan_info *info = (void *)((*match)->data);
++
++ switch(c) {
++ case 'c':
++ info->match_cn = 1;
++ return 1;
++ case 'g':
++ info->match_gr = 1;
++ return 1;
++ case 's':
++ info->match_syn = 1;
++ return 1;
++ case 'x':
++ info->match_stealth = 1;
++ return 1;
++ default:
++ return 0;
++ }
++}
++
++static void libipt_portscan_check(unsigned int flags)
++{
++ return;
++}
++
++static void libipt_portscan_print(const struct ipt_ip *ip,
++ const struct ipt_entry_match *match, int numeric)
++{
++ const struct xt_portscan_info *info = (const void *)(match->data);
++ const char *s = "";
++
++ printf("portscan ");
++ if(info->match_stealth) {
++ printf("STEALTH");
++ s = ",";
++ }
++ if(info->match_syn) {
++ printf("%sSYNSCAN", s);
++ s = ",";
++ }
++ if(info->match_cn) {
++ printf("%sCNSCAN", s);
++ s = ",";
++ }
++ if(info->match_gr)
++ printf("%sGRSCAN", s);
++ printf(" ");
++ return;
++}
++
++static void libipt_portscan_save(const struct ipt_ip *ip,
++ const struct ipt_entry_match *match)
++{
++ const struct xt_portscan_info *info = (const void *)(match->data);
++ if(info->match_stealth) printf("--stealth ");
++ if(info->match_syn) printf("--synscan ");
++ if(info->match_cn) printf("--cnscan ");
++ if(info->match_gr) printf("--grscan ");
++ return;
++}
++
++static struct option libipt_portscan_opts[] = {
++ {"stealth", 0, NULL, 'x'},
++ {"synscan", 0, NULL, 's'},
++ {"cnscan", 0, NULL, 'c'},
++ {"grscan", 0, NULL, 'g'},
++ {NULL},
++};
++
++static struct iptables_match libipt_portscan_info = {
++ .name = "portscan",
++ .version = IPTABLES_VERSION,
++ .size = IPT_ALIGN(sizeof(struct xt_portscan_info)),
++ .userspacesize = IPT_ALIGN(sizeof(struct xt_portscan_info)),
++ .help = libipt_portscan_help,
++ .init = libipt_portscan_mtinit,
++ .parse = libipt_portscan_parse,
++ .final_check = libipt_portscan_check,
++ .print = libipt_portscan_print,
++ .save = libipt_portscan_save,
++ .extra_opts = libipt_portscan_opts,
++};
++
++static __attribute__((constructor)) void libipt_portscan_init(void)
++{
++ register_match(&libipt_portscan_info);
++ return;
++}
+diff -ruN iptables-1.3.5.orig/extensions/Makefile iptables-1.3.5/extensions/Makefile
+--- iptables-1.3.5.orig/extensions/Makefile 2007-01-09 16:03:37.000000000 +0100
++++ iptables-1.3.5/extensions/Makefile 2007-01-09 16:06:34.501506743 +0100
+@@ -5,7 +5,7 @@
+ # header files are present in the include/linux directory of this iptables
+ # package (HW)
+ #
+-PF_EXT_SLIB:=ah addrtype comment connlimit connmark conntrack dscp ecn esp hashlimit helper icmp iprange length limit mac mark multiport owner physdev pkttype policy realm rpc sctp standard state tcp tcpmss tos ttl udp unclean CLASSIFY CONNMARK DNAT DSCP ECN LOG MARK MASQUERADE MIRROR NETMAP NFQUEUE NOTRACK REDIRECT REJECT SAME SNAT TARPIT TCPMSS TOS TRACE TTL ULOG
++PF_EXT_SLIB:=ah addrtype comment connlimit connmark conntrack dscp ecn esp hashlimit helper icmp iprange length limit mac mark multiport owner physdev pkttype policy portscan realm rpc sctp standard state tcp tcpmss tos ttl udp unclean CHAOS CLASSIFY CONNMARK DELUDE DNAT DSCP ECN LOG MARK MASQUERADE MIRROR NETMAP NFQUEUE NOTRACK REDIRECT REJECT SAME SNAT TARPIT TCPMSS TOS TRACE TTL ULOG
+ PF6_EXT_SLIB:=connmark eui64 hl icmpv6 length limit mac mark multiport owner physdev policy standard state tcp udp CONNMARK HL LOG NFQUEUE MARK TRACE
+
+
+diff -ruN iptables-1.3.5.orig/extensions/.portscan-test iptables-1.3.5/extensions/.portscan-test
+--- iptables-1.3.5.orig/extensions/.portscan-test 1970-01-01 01:00:00.000000000 +0100
++++ iptables-1.3.5/extensions/.portscan-test 2007-01-09 16:05:14.228187134 +0100
+@@ -0,0 +1,2 @@
++#!/bin/sh
++[ -f "$KERNEL_DIR/include/linux/netfilter/xt_portscan.h" ] && echo "portscan";
--- /dev/null
+diff -ruN linux-2.6.19.1.orig/include/linux/netfilter/xt_CHAOS.h linux-2.6.19.1/include/linux/netfilter/xt_CHAOS.h
+--- linux-2.6.19.1.orig/include/linux/netfilter/xt_CHAOS.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.1/include/linux/netfilter/xt_CHAOS.h 2007-01-11 13:28:07.656144799 +0100
+@@ -0,0 +1,14 @@
++#ifndef _LINUX_XT_CHAOS_H
++#define _LINUX_XT_CHAOS_H 1
++
++enum xt_chaos_variant {
++ XTCHAOS_NORMAL,
++ XTCHAOS_TARPIT,
++ XTCHAOS_DELUDE,
++};
++
++struct xt_chaos_info {
++ enum xt_chaos_variant variant;
++};
++
++#endif /* _LINUX_XT_CHAOS_H */
+diff -ruN linux-2.6.19.1.orig/include/linux/netfilter/xt_portscan.h linux-2.6.19.1/include/linux/netfilter/xt_portscan.h
+--- linux-2.6.19.1.orig/include/linux/netfilter/xt_portscan.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.1/include/linux/netfilter/xt_portscan.h 2007-01-11 13:28:07.656144799 +0100
+@@ -0,0 +1,8 @@
++#ifndef _LINUX_XT_PORTSCAN_H
++#define _LINUX_XT_PORTSCAN_H 1
++
++struct xt_portscan_info {
++ unsigned int match_stealth, match_syn, match_cn, match_gr;
++};
++
++#endif /* _LINUX_XT_PORTSCAN_H */
+diff -ruN linux-2.6.19.1.orig/net/netfilter/find_match.c linux-2.6.19.1/net/netfilter/find_match.c
+--- linux-2.6.19.1.orig/net/netfilter/find_match.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.1/net/netfilter/find_match.c 2007-01-11 13:28:12.191994379 +0100
+@@ -0,0 +1,37 @@
++/*
++ xt_request_find_match
++ by Jan Engelhardt <jengelh [at] gmx de>, 2006 - 2007
++
++ Based upon linux-2.6.18.5/net/netfilter/x_tables.c:
++ Copyright (C) 2006-2006 Harald Welte <laforge@netfilter.org>
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License version 2 as
++ published by the Free Software Foundation.
++*/
++
++#include <linux/err.h>
++#include <linux/netfilter_arp.h>
++#include <linux/socket.h>
++#include <linux/netfilter/x_tables.h>
++
++/*
++ * Yeah this code is sub-optimal, but the function is missing in
++ * mainline so far. -jengelh
++ */
++static struct xt_match *xt_request_find_match(int af, const char *name,
++ u8 revision)
++{
++ static const char *const xt_prefix[] = {
++ [AF_INET] = "ip",
++ [AF_INET6] = "ip6",
++ [NF_ARP] = "arp",
++ };
++ struct xt_match *match;
++
++ match = try_then_request_module(xt_find_match(af, name, revision),
++ "%st_%s", xt_prefix[af], name);
++ if(IS_ERR(match) || match == NULL)
++ return NULL;
++
++ return match;
++}
+diff -ruN linux-2.6.19.1.orig/net/netfilter/Kconfig linux-2.6.19.1/net/netfilter/Kconfig
+--- linux-2.6.19.1.orig/net/netfilter/Kconfig 2007-01-11 13:27:24.445577700 +0100
++++ linux-2.6.19.1/net/netfilter/Kconfig 2007-01-11 13:28:09.092097179 +0100
+@@ -122,6 +122,14 @@
+
+ # alphabetically ordered list of targets
+
++config NETFILTER_XT_TARGET_CHAOS
++ tristate '"CHAOS" target support'
++ depends on NETFILTER_XTABLES
++ help
++ This option adds a `CHAOS' target.
++
++ To compile it as a module, choose M here. If unsure, say N.
++
+ config NETFILTER_XT_TARGET_CLASSIFY
+ tristate '"CLASSIFY" target support'
+ depends on NETFILTER_XTABLES
+@@ -148,6 +156,14 @@
+ <file:Documentation/modules.txt>. The module will be called
+ ipt_CONNMARK.o. If unsure, say `N'.
+
++config NETFILTER_XT_TARGET_DELUDE
++ tristate '"DELUDE" target support'
++ depends on NETFILTER_XTABLES
++ help
++ This option adds a `DELUDE' target.
++
++ To compile it as a module, choose M here. If unsure, say N.
++
+ config NETFILTER_XT_TARGET_DSCP
+ tristate '"DSCP" target support'
+ depends on NETFILTER_XTABLES
+@@ -355,6 +371,14 @@
+
+ To compile it as a module, choose M here. If unsure, say N.
+
++config NETFILTER_XT_MATCH_PORTSCAN
++ tristate '"portscan" match support'
++ depends on NETFILTER_XTABLES
++ help
++ This option adds a 'portscan' match support.
++
++ To compile it as a module, choose M here. If unsure, say N.
++
+ config NETFILTER_XT_MATCH_MULTIPORT
+ tristate "Multiple port match support"
+ depends on NETFILTER_XTABLES
+diff -ruN linux-2.6.19.1.orig/net/netfilter/Makefile linux-2.6.19.1/net/netfilter/Makefile
+--- linux-2.6.19.1.orig/net/netfilter/Makefile 2007-01-11 13:27:24.445577700 +0100
++++ linux-2.6.19.1/net/netfilter/Makefile 2007-01-11 13:28:07.656144799 +0100
+@@ -23,8 +23,10 @@
+ obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
+
+ # targets
++obj-$(CONFIG_NETFILTER_XT_TARGET_CHAOS) += xt_CHAOS.o
+ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o
+ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o
++obj-$(CONFIG_NETFILTER_XT_TARGET_DELUDE) += xt_DELUDE.o
+ obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
+ obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
+ obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
+@@ -47,6 +49,7 @@
+ obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o
+ obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o
+ obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o
++obj-$(CONFIG_NETFILTER_XT_MATCH_PORTSCAN) += xt_portscan.o
+ obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o
+ obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o
+ obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
+diff -ruN linux-2.6.19.1.orig/net/netfilter/xt_CHAOS.c linux-2.6.19.1/net/netfilter/xt_CHAOS.c
+--- linux-2.6.19.1.orig/net/netfilter/xt_CHAOS.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.1/net/netfilter/xt_CHAOS.c 2007-01-11 13:28:14.407920893 +0100
+@@ -0,0 +1,180 @@
++/*
++ CHAOS target for netfilter
++
++ Copyright © Jan Engelhardt <jengelh [at] gmx de>, 2006 - 2007
++ released under the terms of the GNU General Public
++ License version 2.x and only versions 2.x.
++*/
++#include <linux/icmp.h>
++#include <linux/in.h>
++#include <linux/ip.h>
++#include <linux/module.h>
++#include <linux/skbuff.h>
++#include <linux/stat.h>
++#include <linux/netfilter/x_tables.h>
++#include <linux/netfilter/xt_tcpudp.h>
++#include <linux/netfilter_ipv4/ipt_REJECT.h>
++#include <net/ip.h>
++#include <linux/netfilter/xt_CHAOS.h>
++#include "find_match.c"
++#define PFX KBUILD_MODNAME ": "
++
++/* Out of tree workarounds */
++#include <linux/version.h>
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
++# define HAVE_TARGUSERINFO 1
++#endif
++
++/* Module parameters */
++static unsigned int reject_percentage = ~0U * .01;
++static unsigned int delude_percentage = ~0U * .0101;
++module_param(reject_percentage, uint, S_IRUGO | S_IWUSR);
++module_param(delude_percentage, uint, S_IRUGO | S_IWUSR);
++
++/* References to other matches/targets */
++static struct xt_match *xm_tcp;
++static struct xt_target *xt_delude, *xt_reject, *xt_tarpit;
++
++/* Static data for other matches/targets */
++static const struct ipt_reject_info reject_params = {
++ .with = ICMP_HOST_UNREACH,
++};
++
++static const struct xt_tcp tcp_params = {
++ .spts = {0, ~0},
++ .dpts = {0, ~0},
++};
++
++/* CHAOS functions */
++static void xt_chaos_total(const struct xt_chaos_info *info,
++ struct sk_buff **pskb, const struct net_device *in,
++ const struct net_device *out, unsigned int hooknum)
++{
++ const int protoff = 4 * (*pskb)->nh.iph->ihl;
++ const int offset = ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET;
++ const struct xt_target *destiny;
++ int hotdrop = 0, ret;
++
++ ret = xm_tcp->match(*pskb, in, out, xm_tcp, &tcp_params,
++ offset, protoff, &hotdrop);
++ if(!ret || hotdrop || (unsigned int)net_random() > delude_percentage)
++ return;
++
++ destiny = (info->variant == XTCHAOS_TARPIT) ? xt_tarpit : xt_delude;
++#ifdef HAVE_TARGUSERINFO
++ destiny->target(pskb, in, out, hooknum, destiny, NULL, NULL);
++#else
++ destiny->target(pskb, in, out, hooknum, destiny, NULL);
++#endif
++ return;
++}
++
++static unsigned int xt_chaos_target(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
++#ifdef HAVE_TARGUSERINFO
++ ,
++ void *userinfo
++#endif
++ )
++{
++ /* Equivalent to:
++ * -A chaos -m statistic --mode random --probability \
++ * $reject_percentage -j REJECT --reject-with host-unreach;
++ * -A chaos -m statistic --mode random --probability \
++ * $delude_percentage -j DELUDE;
++ * -A chaos -j DROP;
++ */
++ const struct xt_chaos_info *info = targinfo;
++
++ if((unsigned int)net_random() <= reject_percentage)
++#ifdef HAVE_TARGUSERINFO
++ return xt_reject->target(pskb, in, out, hooknum, target,
++ &reject_params, userinfo);
++#else
++ return xt_reject->target(pskb, in, out, hooknum, target,
++ &reject_params);
++#endif
++
++ /* TARPIT/DELUDE may not be called from the OUTPUT chain */
++ if((*pskb)->nh.iph->protocol == IPPROTO_TCP &&
++ info->variant != XTCHAOS_NORMAL && hooknum != NF_IP_LOCAL_OUT)
++ xt_chaos_total(info, pskb, in, out, hooknum);
++
++ return NF_DROP;
++}
++
++static struct xt_target xt_chaos_info = {
++ .name = "CHAOS",
++ .target = xt_chaos_target,
++ .table = "filter",
++ .targetsize = sizeof(struct xt_chaos_info),
++ .hooks = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) |
++ (1 << NF_IP_LOCAL_OUT),
++ .family = AF_INET,
++ .me = THIS_MODULE,
++};
++
++static int __init xt_chaos_init(void)
++{
++ int ret = -EINVAL;
++
++ xm_tcp = xt_request_find_match(AF_INET, "tcp", 0);
++ if(xm_tcp == NULL) {
++ printk(KERN_WARNING PFX "Could not find \"tcp\" match\n");
++ return -EINVAL;
++ }
++
++ xt_reject = xt_request_find_target(AF_INET, "REJECT", 0);
++ if(xt_reject == NULL) {
++ printk(KERN_WARNING PFX "Could not find \"REJECT\" target\n");
++ goto out2;
++ }
++
++ xt_tarpit = xt_request_find_target(AF_INET, "TARPIT", 0);
++ if(xt_tarpit == NULL) {
++ printk(KERN_WARNING PFX "Could not find \"TARPIT\" target\n");
++ goto out3;
++ }
++
++ xt_delude = xt_request_find_target(AF_INET, "DELUDE", 0);
++ if(xt_delude == NULL) {
++ printk(KERN_WARNING PFX "Could not find \"DELUDE\" target\n");
++ goto out4;
++ }
++
++ if((ret = xt_register_target(&xt_chaos_info)) != 0) {
++ printk(KERN_WARNING PFX "xt_register_target returned "
++ "error %d\n", ret);
++ goto out5;
++ }
++
++ return 0;
++
++ out5:
++ module_put(xt_delude->me);
++ out4:
++ module_put(xt_tarpit->me);
++ out3:
++ module_put(xt_reject->me);
++ out2:
++ module_put(xm_tcp->me);
++ return ret;
++}
++
++static void __exit xt_chaos_exit(void)
++{
++ xt_unregister_target(&xt_chaos_info);
++ module_put(xm_tcp->me);
++ module_put(xt_reject->me);
++ module_put(xt_delude->me);
++ module_put(xt_tarpit->me);
++ return;
++}
++
++module_init(xt_chaos_init);
++module_exit(xt_chaos_exit);
++MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>");
++MODULE_DESCRIPTION("netfilter CHAOS target");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("ipt_CHAOS");
+diff -ruN linux-2.6.19.1.orig/net/netfilter/xt_DELUDE.c linux-2.6.19.1/net/netfilter/xt_DELUDE.c
+--- linux-2.6.19.1.orig/net/netfilter/xt_DELUDE.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.1/net/netfilter/xt_DELUDE.c 2007-01-11 13:28:07.656144799 +0100
+@@ -0,0 +1,265 @@
++/*
++ DELUDE target
++ Copyright © Jan Engelhardt <jengelh [at] gmx de>, 2007
++
++ Based upon linux-2.6.18.5/net/ipv4/netfilter/ipt_REJECT.c:
++ (C) 1999-2001 Paul `Rusty' Russell
++ (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License version 2 as
++ published by the Free Software Foundation.
++*/
++
++#include <linux/module.h>
++#include <linux/skbuff.h>
++#include <linux/ip.h>
++#include <linux/tcp.h>
++#include <linux/udp.h>
++#include <linux/icmp.h>
++#include <net/icmp.h>
++#include <net/ip.h>
++#include <net/tcp.h>
++#include <net/route.h>
++#include <net/dst.h>
++#include <linux/netfilter_ipv4/ip_tables.h>
++#ifdef CONFIG_BRIDGE_NETFILTER
++#include <linux/netfilter_bridge.h>
++#endif
++#define PFX KBUILD_MODNAME ": "
++
++/* Out of tree workarounds */
++#include <linux/version.h>
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
++# define HAVE_TARGINFOSIZE 1
++# define HAVE_TARGUSERINFO 1
++#endif
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
++# define nfmark mark
++#endif
++
++static inline struct rtable *route_reverse(struct sk_buff *skb,
++ struct tcphdr *tcph, int hook)
++{
++ struct iphdr *iph = skb->nh.iph;
++ struct dst_entry *odst;
++ struct flowi fl = {};
++ struct rtable *rt;
++
++ /* We don't require ip forwarding to be enabled to be able to
++ * send a RST reply for bridged traffic. */
++ if (hook != NF_IP_FORWARD
++#ifdef CONFIG_BRIDGE_NETFILTER
++ || (skb->nf_bridge && skb->nf_bridge->mask & BRNF_BRIDGED)
++#endif
++ ) {
++ fl.nl_u.ip4_u.daddr = iph->saddr;
++ if (hook == NF_IP_LOCAL_IN)
++ fl.nl_u.ip4_u.saddr = iph->daddr;
++ fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
++
++ if (ip_route_output_key(&rt, &fl) != 0)
++ return NULL;
++ } else {
++ /* non-local src, find valid iif to satisfy
++ * rp-filter when calling ip_route_input. */
++ fl.nl_u.ip4_u.daddr = iph->daddr;
++ if (ip_route_output_key(&rt, &fl) != 0)
++ return NULL;
++
++ odst = skb->dst;
++ if (ip_route_input(skb, iph->saddr, iph->daddr,
++ RT_TOS(iph->tos), rt->u.dst.dev) != 0) {
++ dst_release(&rt->u.dst);
++ return NULL;
++ }
++ dst_release(&rt->u.dst);
++ rt = (struct rtable *)skb->dst;
++ skb->dst = odst;
++
++ fl.nl_u.ip4_u.daddr = iph->saddr;
++ fl.nl_u.ip4_u.saddr = iph->daddr;
++ fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
++ }
++
++ if (rt->u.dst.error) {
++ dst_release(&rt->u.dst);
++ return NULL;
++ }
++
++ fl.proto = IPPROTO_TCP;
++ fl.fl_ip_sport = tcph->dest;
++ fl.fl_ip_dport = tcph->source;
++
++ xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0);
++
++ return rt;
++}
++
++static void send_reset(struct sk_buff *oldskb, int hook)
++{
++ struct sk_buff *nskb;
++ struct iphdr *iph = oldskb->nh.iph;
++ struct tcphdr _otcph, *oth, *tcph;
++ struct rtable *rt;
++ u_int16_t tmp_port;
++ u_int32_t tmp_addr;
++ int hh_len;
++
++ /* IP header checks: fragment. */
++ if (oldskb->nh.iph->frag_off & htons(IP_OFFSET))
++ return;
++
++ oth = skb_header_pointer(oldskb, oldskb->nh.iph->ihl * 4,
++ sizeof(_otcph), &_otcph);
++ if (oth == NULL)
++ return;
++
++ /* DELUDE only answers SYN. */
++ if(!oth->syn || oth->ack || oth->fin || oth->rst)
++ return;
++
++ /* Check checksum */
++ if (nf_ip_checksum(oldskb, hook, iph->ihl * 4, IPPROTO_TCP))
++ return;
++
++ if ((rt = route_reverse(oldskb, oth, hook)) == NULL)
++ return;
++
++ hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
++
++ /* We need a linear, writeable skb. We also need to expand
++ headroom in case hh_len of incoming interface < hh_len of
++ outgoing interface */
++ nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb),
++ GFP_ATOMIC);
++ if (!nskb) {
++ dst_release(&rt->u.dst);
++ return;
++ }
++
++ dst_release(nskb->dst);
++ nskb->dst = &rt->u.dst;
++
++ /* This packet will not be the same as the other: clear nf fields */
++ nf_reset(nskb);
++ nskb->nfmark = 0;
++ skb_init_secmark(nskb);
++
++ tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
++
++ /* Swap source and dest */
++ tmp_addr = nskb->nh.iph->saddr;
++ nskb->nh.iph->saddr = nskb->nh.iph->daddr;
++ nskb->nh.iph->daddr = tmp_addr;
++ tmp_port = tcph->source;
++ tcph->source = tcph->dest;
++ tcph->dest = tmp_port;
++
++ /* Truncate to length (no data) */
++ tcph->doff = sizeof(struct tcphdr)/4;
++ skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
++ nskb->nh.iph->tot_len = htons(nskb->len);
++
++ tcph->seq = oth->ack_seq;
++ tcph->ack_seq = 0;
++
++ /* Reset flags */
++ ((u_int8_t *)tcph)[13] = 0;
++ tcph->syn = tcph->ack = 1;
++
++ tcph->window = 0;
++ tcph->urg_ptr = 0;
++
++ /* Adjust TCP checksum */
++ tcph->check = 0;
++ tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
++ nskb->nh.iph->saddr,
++ nskb->nh.iph->daddr,
++ csum_partial((char *)tcph,
++ sizeof(struct tcphdr), 0));
++
++ /* Adjust IP TTL, DF */
++ nskb->nh.iph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
++ /* Set DF, id = 0 */
++ nskb->nh.iph->frag_off = htons(IP_DF);
++ nskb->nh.iph->id = 0;
++
++ /* Adjust IP checksum */
++ nskb->nh.iph->check = 0;
++ nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,
++ nskb->nh.iph->ihl);
++
++ /* "Never happens" */
++ if (nskb->len > dst_mtu(nskb->dst))
++ goto free_nskb;
++
++ nf_ct_attach(nskb, oldskb);
++
++ NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
++ dst_output);
++ return;
++
++ free_nskb:
++ kfree_skb(nskb);
++ return;
++}
++
++static unsigned int xt_delude_target(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
++#ifdef HAVE_TARGUSERINFO
++ ,
++ void *userinfo
++#endif
++ )
++{
++ /* WARNING: This code causes reentry within iptables.
++ This means that the iptables jump stack is now crap. We
++ must return an absolute verdict. --RR */
++ send_reset(*pskb, hooknum);
++ return NF_DROP;
++}
++
++static int xt_delude_check(const char *tablename, const void *e_void,
++ const struct xt_target *target, void *targinfo,
++#ifdef HAVE_TARGINFOSIZE
++ unsigned int targinfosize,
++#endif
++ unsigned int hook_mask)
++{
++ if(hook_mask & ~((1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD))) {
++ printk(KERN_WARNING PFX "DELUDE may not be used in chains "
++ "other than INPUT and FORWARD\n");
++ return 0;
++ }
++ return 1;
++}
++
++static struct xt_target xt_delude_info = {
++ .name = "DELUDE",
++ .target = xt_delude_target,
++ .checkentry = xt_delude_check,
++ .table = "filter",
++ .hooks = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) |
++ (1 << NF_IP_LOCAL_OUT),
++ .proto = IPPROTO_TCP,
++ .family = AF_INET,
++ .me = THIS_MODULE,
++};
++
++static int __init xt_delude_init(void)
++{
++ return xt_register_target(&xt_delude_info);
++}
++
++static void __exit xt_delude_exit(void)
++{
++ xt_unregister_target(&xt_delude_info);
++}
++
++module_init(xt_delude_init);
++module_exit(xt_delude_exit);
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>");
++MODULE_DESCRIPTION("netfilter DELUDE target");
+diff -ruN linux-2.6.19.1.orig/net/netfilter/xt_portscan.c linux-2.6.19.1/net/netfilter/xt_portscan.c
+--- linux-2.6.19.1.orig/net/netfilter/xt_portscan.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.19.1/net/netfilter/xt_portscan.c 2007-01-11 13:28:14.407920893 +0100
+@@ -0,0 +1,282 @@
++/*
++ portscan match for netfilter
++
++ Written by Jan Engelhardt, 2006 - 2007
++ released under the terms of the GNU General Public
++ License version 2.x and only versions 2.x.
++*/
++#include <linux/in.h>
++#include <linux/ip.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/skbuff.h>
++#include <linux/stat.h>
++#include <linux/tcp.h>
++#include <linux/types.h>
++#include <linux/version.h>
++#include <linux/netfilter/x_tables.h>
++#include <linux/netfilter/xt_tcpudp.h>
++#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
++# include <linux/netfilter_ipv4/ip_conntrack.h>
++#else /* linux-2.6.20+ */
++# include <net/netfilter/nf_nat_rule.h>
++#endif
++#include <linux/netfilter/xt_portscan.h>
++#define PFX KBUILD_MODNAME ": "
++
++/* Out of tree workarounds */
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
++# define HAVE_MATCHINFOSIZE 1
++#endif
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
++# define nfmark mark
++#endif
++
++enum {
++ TCP_FLAGS_ALL3 = TCP_FLAG_FIN | TCP_FLAG_RST | TCP_FLAG_SYN,
++ TCP_FLAGS_ALL4 = TCP_FLAGS_ALL3 | TCP_FLAG_ACK,
++ TCP_FLAGS_ALL6 = TCP_FLAGS_ALL4 | TCP_FLAG_PSH | TCP_FLAG_URG,
++};
++
++/* Module parameters */
++static unsigned int
++ connmark_mask = ~0,
++ packet_mask = ~0,
++ mark_seen = 0x9,
++ mark_synrcv = 0x1,
++ mark_closed = 0x2,
++ mark_synscan = 0x3,
++ mark_estab1 = 0x4,
++ mark_estab2 = 0x5,
++ mark_cnscan = 0x6,
++ mark_grscan = 0x7,
++ mark_valid = 0x8;
++
++module_param(connmark_mask, uint, S_IRUGO | S_IWUSR);
++module_param(packet_mask, uint, S_IRUGO | S_IWUSR);
++module_param(mark_seen, uint, S_IRUGO | S_IWUSR);
++module_param(mark_synrcv, uint, S_IRUGO | S_IWUSR);
++module_param(mark_closed, uint, S_IRUGO | S_IWUSR);
++module_param(mark_synscan, uint, S_IRUGO | S_IWUSR);
++module_param(mark_estab1, uint, S_IRUGO | S_IWUSR);
++module_param(mark_estab2, uint, S_IRUGO | S_IWUSR);
++module_param(mark_cnscan, uint, S_IRUGO | S_IWUSR);
++module_param(mark_grscan, uint, S_IRUGO | S_IWUSR);
++module_param(mark_valid, uint, S_IRUGO | S_IWUSR);
++MODULE_PARM_DESC(connmark_mask, "only set specified bits in connection mark");
++MODULE_PARM_DESC(packet_mask, "only set specified bits in packet mark");
++MODULE_PARM_DESC(mark_seen, "nfmark value for packet-seen state");
++MODULE_PARM_DESC(mark_synrcv, "connmark value for SYN Received state");
++MODULE_PARM_DESC(mark_closed, "connmark value for closed state");
++MODULE_PARM_DESC(mark_synscan, "connmark value for SYN Scan state");
++MODULE_PARM_DESC(mark_estab1, "connmark value for Established-1 state");
++MODULE_PARM_DESC(mark_estab2, "connmark value for Established-2 state");
++MODULE_PARM_DESC(mark_cnscan, "connmark value for Connect Scan state");
++MODULE_PARM_DESC(mark_grscan, "connmark value for Grab Scan state");
++MODULE_PARM_DESC(mark_valid, "connmark value for Valid state");
++
++/* TCP flag functions */
++static inline int tflg_ack4(const struct tcphdr *th)
++{
++ return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_ACK;
++}
++
++static inline int tflg_ack6(const struct tcphdr *th)
++{
++ return (tcp_flag_word(th) & TCP_FLAGS_ALL6) == TCP_FLAG_ACK;
++}
++
++static inline int tflg_fin(const struct tcphdr *th)
++{
++ return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_FIN;
++}
++
++static inline int tflg_rst(const struct tcphdr *th)
++{
++ return (tcp_flag_word(th) & TCP_FLAGS_ALL3) == TCP_FLAG_RST;
++}
++
++static inline int tflg_rstack(const struct tcphdr *th)
++{
++ return (tcp_flag_word(th) & TCP_FLAGS_ALL4) ==
++ (TCP_FLAG_ACK | TCP_FLAG_RST);
++}
++
++static inline int tflg_syn(const struct tcphdr *th)
++{
++ return (tcp_flag_word(th) & TCP_FLAGS_ALL4) == TCP_FLAG_SYN;
++}
++
++static inline int tflg_synack(const struct tcphdr *th)
++{
++ return (tcp_flag_word(th) & TCP_FLAGS_ALL4) ==
++ (TCP_FLAG_SYN | TCP_FLAG_ACK);
++}
++
++/* portscan functions */
++static inline int xt_portscan_stealth(const struct tcphdr *th)
++{
++ /*
++ * "Connection refused" replies to our own probes must not be matched.
++ */
++ if(tflg_rstack(th))
++ return 0;
++
++ if(tflg_rst(th) && printk_ratelimit()) {
++ printk(KERN_WARNING PFX "Warning: Pure RST received\n");
++ return 0;
++ }
++
++ /*
++ * -p tcp ! --syn -m conntrack --ctstate INVALID: Looking for non-start
++ * packets that are not associated with any connection -- this will
++ * match most scan types (NULL, XMAS, FIN) and ridiculous flag
++ * combinations (SYN-RST, SYN-FIN, SYN-FIN-RST, FIN-RST, etc.).
++ */
++ return !tflg_syn(th);
++}
++
++static inline int xt_portscan_full(int mark, enum ip_conntrack_info ctstate,
++ int loopback, const struct tcphdr *tcph, int payload_len)
++{
++ if(mark == mark_estab2) {
++ /*
++ * -m connmark --mark $ESTAB2
++ */
++ if(tflg_ack4(tcph) && payload_len == 0)
++ return mark; /* keep mark */
++ else if(tflg_rst(tcph) || tflg_fin(tcph))
++ return mark_grscan;
++ else
++ return mark_valid;
++ } else if(mark == mark_estab1) {
++ /*
++ * -m connmark --mark $ESTAB1
++ */
++ if(tflg_rst(tcph) || tflg_fin(tcph))
++ return mark_cnscan;
++ else if(!loopback && tflg_ack4(tcph) && payload_len == 0)
++ return mark_estab2;
++ else
++ return mark_valid;
++ } else if(mark == mark_synrcv) {
++ /*
++ * -m connmark --mark $SYN
++ */
++ if(loopback && tflg_synack(tcph))
++ return mark; /* keep mark */
++ else if(loopback && tflg_rstack(tcph))
++ return mark_closed;
++ else if(tflg_ack6(tcph))
++ return mark_estab1;
++ else
++ return mark_synscan;
++ } else if(ctstate == IP_CT_NEW && tflg_syn(tcph)) {
++ /*
++ * -p tcp --syn --ctstate NEW
++ */
++ return mark_synrcv;
++ }
++ return mark;
++}
++
++static int xt_portscan_match(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, int *hotdrop)
++{
++ const struct xt_portscan_info *info = matchinfo;
++ enum ip_conntrack_info ctstate;
++ struct ip_conntrack *ctdata;
++ const struct tcphdr *tcph;
++ struct tcphdr tcph_buf;
++
++ tcph = skb_header_pointer(skb, protoff, sizeof(tcph_buf), &tcph_buf);
++ if(tcph == NULL)
++ return 0;
++
++ /* Check for invalid packets: -m conntrack --ctstate INVALID */
++ if((ctdata = ip_conntrack_get(skb, &ctstate)) == NULL) {
++ if(info->match_stealth)
++ return xt_portscan_stealth(tcph);
++ /*
++ * If @ctdata is NULL, we cannot match the other scan
++ * types, return.
++ */
++ return 0;
++ }
++
++ /*
++ * If -m portscan was previously applied to this packet, the rules we
++ * simulate must not be run through again. And for speedup, do not call
++ * it either when the connection is already VALID.
++ */
++ if((ctdata->mark & connmark_mask) == mark_valid ||
++ (skb->nfmark & packet_mask) != mark_seen)
++ {
++ unsigned int n;
++ n = xt_portscan_full(ctdata->mark & connmark_mask, ctstate,
++ in == &loopback_dev, tcph,
++ skb->len - protoff - 4 * tcph->doff);
++
++ ctdata->mark = (ctdata->mark & ~connmark_mask) | n;
++ ((struct sk_buff *)skb)->nfmark =
++ (skb->nfmark & ~packet_mask) | mark_seen;
++ }
++
++ return (info->match_syn && ctdata->mark == mark_synscan) ||
++ (info->match_cn && ctdata->mark == mark_cnscan) ||
++ (info->match_gr && ctdata->mark == mark_grscan);
++}
++
++static int xt_portscan_checkentry(const char *tablename, const void *entry,
++ const struct xt_match *match, void *matchinfo,
++#ifdef HAVE_MATCHINFOSIZE
++ unsigned int matchinfosize,
++#endif
++ unsigned int hook_mask)
++{
++ const struct xt_portscan_info *info = matchinfo;
++#ifdef HAVE_MATCHINFOSIZE
++ if(matchinfosize != XT_ALIGN(sizeof(struct xt_portscan_info))) {
++ printk(KERN_WARNING PFX "matchinfosize %u != %Zu\n",
++ matchinfosize,
++ XT_ALIGN(sizeof(struct xt_portscan_info)));
++ return 0;
++ }
++#endif
++ if((info->match_stealth & ~1) || (info->match_syn & ~1) ||
++ (info->match_cn & ~1) || (info->match_gr & ~1)) {
++ printk(KERN_WARNING PFX "Invalid flags\n");
++ return 0;
++ }
++ return 1;
++}
++
++static struct xt_match xt_portscan = {
++ .name = "portscan",
++ .match = xt_portscan_match,
++ .checkentry = xt_portscan_checkentry,
++ .matchsize = sizeof(struct xt_portscan_info),
++ .proto = IPPROTO_TCP,
++ .family = AF_INET,
++ .me = THIS_MODULE,
++};
++
++static int __init xt_portscan_init(void)
++{
++ return xt_register_match(&xt_portscan);
++}
++
++static void __exit xt_portscan_exit(void)
++{
++ xt_unregister_match(&xt_portscan);
++ return;
++}
++
++module_init(xt_portscan_init);
++module_exit(xt_portscan_exit);
++MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>");
++MODULE_DESCRIPTION("netfilter portscan match module");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("ipt_portscan");