All of lore.kernel.org
 help / color / mirror / Atom feed
* patch: Port- and netscan detection for netfilter
@ 2007-03-15 13:29 Gladewitz, Robert (FH)
  2007-03-16 15:40 ` Patrick McHardy
  0 siblings, 1 reply; 12+ messages in thread
From: Gladewitz, Robert (FH) @ 2007-03-15 13:29 UTC (permalink / raw)
  To: netfilter-devel

[-- Attachment #1: Type: text/plain, Size: 552 bytes --]

Helo,

in my Master-Theses I designed a new kernel- and netfilter module for
detection of net- and portscans. Now, the module is tested on more then
10 different firewall-installations. It's working without any problems
during the last 8 months.

Your can read the documentation on
http://ipt-portnetscan.sourceforge.net/. There is also a possibility to
download all versions of Kernel- and IpTables-Patches.

I would be pleased to see you integrated these patches into IpTables of
your use.
Looking forward to your answer

regards



[-- Attachment #2: iptables-1.3.7.patch --]
[-- Type: application/octet-stream, Size: 13654 bytes --]

diff -Naur iptables-1.3.7.org/extensions/.PORTNETSCAN-test iptables-1.3.7/extensions/.PORTNETSCAN-test
--- iptables-1.3.7.org/extensions/.PORTNETSCAN-test	1970-01-01 01:00:00.000000000 +0100
+++ iptables-1.3.7/extensions/.PORTNETSCAN-test	2007-03-10 14:48:21.000000000 +0100
@@ -0,0 +1,3 @@
+#!/bin/sh
+# True if PORTNETSCAN is applied.
+[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_PORTNETSCAN.h ] && echo PORTNETSCAN
diff -Naur iptables-1.3.7.org/extensions/libipt_PORTNETSCAN.c iptables-1.3.7/extensions/libipt_PORTNETSCAN.c
--- iptables-1.3.7.org/extensions/libipt_PORTNETSCAN.c	1970-01-01 01:00:00.000000000 +0100
+++ iptables-1.3.7/extensions/libipt_PORTNETSCAN.c	2007-03-10 14:51:10.000000000 +0100
@@ -0,0 +1,330 @@
+/* 
+	Name:            libipt_PORTNETSCAN.h
+	Date:            16.05.2006
+	Last change:     03.03.2007
+	Version:         0.3
+
+
+  Shared library add-on to iptables to add port- and netscan detection
+
+  Copyright (C) Robert Gladewitz
+  Fachhochschule Heidelberg
+
+  This file is distributed under the terms of the GNU General Public
+  License (GPL). Copies of the GPL can be obtained from:
+     ftp://prep.ai.mit.edu/pub/gnu/GPL
+
+  2006-05-26 Robert Gladewitz <gladewitz@gmx.de> : initial
+  2006-08-03 Robert Gladewitz <gladewitz@gmx.de> : Correct wrong parameter deep to depth (misunderstanding parameter deep)
+  2006-11-10 Robert Gladewitz <gladewitz@gmx.de> : Correct some spelling-mistakes
+  2007-03-03 Robert Gladewitz <gladewitz@gmx.de> : Structure and documention correction
+*/
+
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <syslog.h>
+#include <getopt.h>
+#include <iptables.h>
+#include <linux/netfilter_ipv4/ipt_PORTNETSCAN.h>
+/*
+########################################################################################################################
+######## local structs #################################################################################################
+########################################################################################################################
+*/
+static struct option opts[] = {
+	{ "tree-depth",          1, 0, '1'  },
+	{ "trace-time",         1, 0, '2'  },
+	{ "clean-interval",     1, 0, '3'  },
+	{ "port-scan-quota",    1, 0, '4'  },
+	{ "net-scan-quota",     1, 0, '5'  },
+	{ "max-deny-entries",   1, 0, '6'  },
+	{ "max-trace-entries",  1, 0, '7'  },
+	{ "block-time",         1, 0, '8'  },
+	{ "combined-quota",     1, 0, '9'  },
+	{ "check-deny-entries", 0, 0, 'A' },
+	{ 0 }
+};
+/* Initialize the target. */
+static void
+init(struct ipt_entry_match *m, unsigned int *nfcache)
+{
+	struct ipt_PORTNETSCAN_info *PNINFO = (struct ipt_PORTNETSCAN_info *)m->data;
+
+	PNINFO->tree_depth         = DEFAULTTREEDEPTH;
+	PNINFO->trace_time         = DEFAULTTRACETIME;
+	PNINFO->clean_interval     = DEFAULTCLEANINTERVAL;
+	PNINFO->port_scan_quota    = DEFAULTPORTSCANQUOTA;
+	PNINFO->net_scan_quota     = DEFAULTNETSCANQUOTA;
+	PNINFO->max_deny_entries   = DEFAULTDENYLISTCOUNT;
+	PNINFO->max_trace_entries  = DEFAULTENDNODECOUNT;
+	PNINFO->block_time         = DEFAULTBLOCKTIME;
+	PNINFO->combined_quota     = DEFAULTCOMBINEDQUOTA;
+	PNINFO->check_deny_entries = DEFAULTCHECKDENYENTRIES;
+}
+typedef struct _code {
+	char	*c_name;
+	int	c_val;
+} CODE;
+/*
+######## local defines ################################################################################################
+*/
+/* I know, its a very easy way without differend names */
+#define OPTSET01 1
+#define OPTSET02 2
+#define OPTSET03 4
+#define OPTSET04 8
+#define OPTSET05 16
+#define OPTSET06 32
+#define OPTSET07 64
+#define OPTSET08 128
+#define OPTSET09 256
+#define OPTSET10 512
+/*
+######## string_to_tree_depth ##########################################################################################
+*/
+static unsigned int string_to_tree_depth (char * STRING)
+{
+	unsigned int RC = DEFAULTTREEDEPTH;
+	unsigned int TEMPRC = 0;
+	
+	if ( string_to_number (STRING,1,32,&TEMPRC) != -1 )
+	{
+		if ( TEMPRC == 1  || TEMPRC == 2 ||
+		     TEMPRC == 4  || TEMPRC == 8 ||
+		     TEMPRC == 16 || TEMPRC == 32 )
+			RC = TEMPRC;
+		else printf ("Warning: bad --tree-depth %s, use default %d\n",STRING,RC);
+	}
+	return RC;
+}
+/*
+######## parse ########################################################################################################
+*/
+static int parse(  int c, 
+		   char **argv, 
+		   int invert, 
+		   unsigned int *flags,
+                   const struct ipt_entry *entry,
+                   unsigned int *nfcache,
+                   struct ipt_entry_match **m)
+{
+	struct ipt_PORTNETSCAN_info *PNINFO = (struct ipt_PORTNETSCAN_info *)(*m)->data;
+	unsigned int num;
+	
+	switch (c) {
+	/* depth-tree OPTSET01*/
+	case '1':
+		if (*flags & OPTSET01)
+			exit_error(PARAMETER_PROBLEM,
+				   "Can't specify --tree-depth twice");
+		PNINFO->tree_depth = string_to_tree_depth(optarg);;
+		*flags |= OPTSET01;
+		break;
+
+	case '2':
+		if (*flags & OPTSET02)
+			exit_error(PARAMETER_PROBLEM,
+				   "Can't specify --trace-time twice");
+                if (string_to_number(optarg, 10, 36000, &num) == -1)
+                        exit_error(PARAMETER_PROBLEM,
+                                   "bad --trace-time `%s' (10-3600)", optarg);
+		PNINFO->trace_time = num;
+		*flags |= OPTSET02;
+		break;
+
+	case '3':
+		if (*flags & OPTSET03)
+			exit_error(PARAMETER_PROBLEM,
+				   "Can't specify --clean-interval twice");
+                if (string_to_number(optarg, 1, 60, &num) == -1)
+                        exit_error(PARAMETER_PROBLEM,
+                                   "bad --clean-interval `%s' (1-60)", optarg);
+		PNINFO->clean_interval = num;
+		*flags |= OPTSET03;
+		break;
+
+	case '4':
+		if (*flags & OPTSET04)
+			exit_error(PARAMETER_PROBLEM,
+				   "Can't specify --port-scan-quota twice");
+                if (string_to_number(optarg, 3, 1000, &num) == -1)
+                        exit_error(PARAMETER_PROBLEM,
+                                   "bad --port-scan-quota `%s' (3-1000)", optarg);
+		PNINFO->port_scan_quota = num;
+		*flags |= OPTSET04;
+		break;
+
+	case '5':
+		if (*flags & OPTSET05)
+			exit_error(PARAMETER_PROBLEM,
+				   "Can't specify --net-scan-quota twice");
+                if (string_to_number(optarg, 3, 1000, &num) == -1)
+                        exit_error(PARAMETER_PROBLEM,
+                                   "bad --net-scan-quota `%s' (3-1000)", optarg);
+		PNINFO->net_scan_quota = num;
+		*flags |= OPTSET05;
+		break;
+
+
+	case '6':
+		if (*flags & OPTSET06)
+			exit_error(PARAMETER_PROBLEM,
+				   "Can't specify --max-deny-entries twice");
+                if (string_to_number(optarg, 10, 2000, &num) == -1)
+                        exit_error(PARAMETER_PROBLEM,
+                                   "bad --max-deny-entries `%s' (10-2000)", optarg);
+		PNINFO->max_deny_entries = num;
+		*flags |= OPTSET06;
+		break;
+
+
+	case '7':
+		if (*flags & OPTSET07)
+			exit_error(PARAMETER_PROBLEM,
+				   "Can't specify --max-trace-entries twice");
+                if (string_to_number(optarg, 10, 20000, &num) == -1)
+                        exit_error(PARAMETER_PROBLEM,
+                                   "bad --max-trace-entries `%s'(10-20000)", optarg);
+		PNINFO->max_trace_entries = num;
+		*flags |= OPTSET07;
+		break;
+
+	case '8':
+		if (*flags & OPTSET08)
+			exit_error(PARAMETER_PROBLEM,
+				   "Can't specify --block-time twice");
+                if (string_to_number(optarg, 0, 172800, &num) == -1)
+                        exit_error(PARAMETER_PROBLEM,
+                                   "bad --block-time `%s' (0-172800)", optarg);
+		PNINFO->block_time = num;
+		*flags |= OPTSET08;
+		break;
+
+	case '9':
+		if (*flags & OPTSET09)
+			exit_error(PARAMETER_PROBLEM,
+				   "Can't specify --combined-quota twice");
+                if (string_to_number(optarg, 6, 10000, &num) == -1)
+                        exit_error(PARAMETER_PROBLEM,
+                                   "bad --combined-quota `%s' (6-1000)", optarg);
+		PNINFO->combined_quota = num;
+		*flags |= OPTSET09;
+		break;
+
+	case 'A':
+		if (*flags & OPTSET10)
+			exit_error(PARAMETER_PROBLEM,
+				   "Can't specify --check_deny_entries");
+		PNINFO->check_deny_entries = 1;
+		*flags |= OPTSET10;
+		break;
+
+
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+/*
+######## final_ceck ###################################################################################################
+*/
+static void final_check(unsigned int flags)
+{
+	/*
+		we dont need in this configuration
+	*/
+}
+/*
+######## print ########################################################################################################
+Using is: print options
+*/
+static void
+print(const struct ipt_ip *ip,
+      const struct ipt_entry_match *m,
+      int numeric)
+{
+	const struct ipt_PORTNETSCAN_info *PNINFO = (struct ipt_PORTNETSCAN_info *)m->data;
+
+	printf("PORTNETSCAN ");
+	printf("tree-depth: %u ",        PNINFO->tree_depth);
+	printf("trace-time: %u ",        PNINFO->trace_time);
+	printf("clean-interval: %u ",    PNINFO->clean_interval);
+	printf("port-scan-quota: %u ",   PNINFO->port_scan_quota);
+	printf("net-scan-quota: %u ",    PNINFO->net_scan_quota);
+	printf("max-deny-entries: %u ",  PNINFO->max_deny_entries);
+	printf("max-trace-entries: %u ", PNINFO->max_trace_entries);
+	printf("block-time: %u ",        PNINFO->block_time);
+	printf("combined-quota: %u ",    PNINFO->combined_quota);
+	if ( PNINFO->check_deny_entries != 0 ) 
+		printf("check-deny-entries ");
+}
+/*
+######## save #########################################################################################################
+Using: save iptables rules, we can parse for confuguring back
+*/
+static void
+save(const struct ipt_ip *ip, const struct ipt_entry_match *m)
+{
+	const struct ipt_PORTNETSCAN_info *PNINFO = (struct ipt_PORTNETSCAN_info *)m->data;
+
+	printf("--tree-depth %u ",        PNINFO->tree_depth);
+	printf("--trace-time %u ",        PNINFO->trace_time);
+	printf("--clean-interval %u ",    PNINFO->clean_interval);
+	printf("--port-scan-quota %u ",   PNINFO->port_scan_quota);
+	printf("--net-scan-quota %u ",    PNINFO->net_scan_quota);
+	printf("--max-deny-entries %u ",  PNINFO->max_deny_entries);
+	printf("--max-trace-entries %u ", PNINFO->max_trace_entries);
+	printf("--block-time %u ",        PNINFO->block_time);
+	printf("--combined-quota %u ",    PNINFO->combined_quota);
+	if ( PNINFO->check_deny_entries != 0 ) 
+		printf("--check-deny-entries ");
+}
+/*
+######## help #########################################################################################################
+Using: print help (iptables --help)
+*/
+static void help(void)
+{
+	printf(
+"PORTNETSCAN v%s options:\n"
+" --tree-depth           treedepth (default:4)     Use this treedepth for trace tree\n\n"
+" --trace-time           tracetime (default:120)   Timeinterval in seconds for source-entries (120 =P 2 minutes)\n\n"
+" --clean-interval       cleanint  (default:1)     Timeinterval in seconds for checking end deleting old entries\n\n"
+" --port-scan-quota      portscanq (default:10)    if per source count_dstports/count_dst > portscanq src is positive\n\n"
+" --net-scan-quota       netscanq  (default:10)    if per source count_dst/count_dstport > netscanq src is positive\n\n"
+" --combined-quota       compinedq (default:50)    if per source count_dst+count_dstport > combinedq src is positive\n\n"
+" --max-deny-entries     maxdenyc  (default:500)   Max entries in denylist\n\n"
+" --max-trace-entries    mactracec (default:20000) Max entries in trace-tree/trace-list\n\n"
+" --block-time           blocktime (default:3600)  Timeinterval in seconds where the src ist blocked, if we found a port- or netscan or overtaken combined-quota\n\n"
+" --check-deny-entries                             If set, only Check denylist (don't lock vor trace-entries)\n\n",
+IPTABLES_VERSION);
+}
+/*
+########################################################################################################################
+######## iptables ######################################################################################################
+########################################################################################################################
+*/
+static struct iptables_match PORTNETSCAN = { 
+	.next		= NULL,
+	.name		= "PORTNETSCAN",
+	.version	= IPTABLES_VERSION,
+	.size		= IPT_ALIGN(sizeof(struct ipt_PORTNETSCAN_info)),
+	.userspacesize	= IPT_ALIGN(sizeof(struct ipt_PORTNETSCAN_info)),
+	.help		= &help,
+	.init		= &init,
+	.parse		= &parse,
+	.final_check	= &final_check,
+	.print		= &print,
+	.save		= &save,
+	.extra_opts	= opts
+};
+/*
+######## init #########################################################################################################
+*/
+void _init(void)
+{
+	register_match(&PORTNETSCAN);
+}
diff -Naur iptables-1.3.7.org/extensions/libipt_PORTNETSCAN.man iptables-1.3.7/extensions/libipt_PORTNETSCAN.man
--- iptables-1.3.7.org/extensions/libipt_PORTNETSCAN.man	1970-01-01 01:00:00.000000000 +0100
+++ iptables-1.3.7/extensions/libipt_PORTNETSCAN.man	2007-03-10 14:48:21.000000000 +0100
@@ -0,0 +1,7 @@
+This modul can find port-, net- and compinedscan situations for protocol types udp and tcp. At the moment, it support only ipv4 protocols. It works whith enviroment-set per parameter-set.
+Using:
+iptables -A FORWARD -p tcp -m PORTNETSCAN --trace-time 3000 --check-deny-entries -j DROP
+# ...
+# Allow-Rules
+# ...
+iptables -A FORWARD -p tcp -m PORTNETSCAN --trace-time 3000 -j DROP

[-- Attachment #3: linux-2.6.20.2.patch --]
[-- Type: application/octet-stream, Size: 148927 bytes --]

diff -Naur linux-2.6.20.2.org/Documentation/ipt_PORTNETSCAN.txt linux-2.6.20.2/Documentation/ipt_PORTNETSCAN.txt
--- linux-2.6.20.2.org/Documentation/ipt_PORTNETSCAN.txt	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.20.2/Documentation/ipt_PORTNETSCAN.txt	2007-03-10 14:33:15.000000000 +0100
@@ -0,0 +1,389 @@
+Allgemein Informationen zum Modul ipt_PORTNETSCAN
+-------------------------------------------------
+
+Erkennung von Port-, Net- oder Combinedscans.
+
+Synopsis Aufruf des Moduls ipt_PORTNETSCAN
+------------------------------------------
+
+Das Modul wird durch eine IpTables Filterregel mittels der Option 
+-m PORTNETSCAN aufgerufen.
+
+iptables [iptables Optionen]  -m PORTNETSCAN [Optionen]
+
+Einschränkungen oder Filtervorgaben können in IpTables durch alle 
+implementierten IpTables Optionen definiert werden. Das Modul wird
+nur aufgerufen, wenn die zuvor definierten Filter oder Einschränkungen
+in den IpTables Optionen gültig sind.
+
+
+Überblick über die Optionen
+---------------------------
+
+--tree-depth [1|2|4|8|16|32]
+Standard: --tree-depth 4
+Diese Option gibt die Baumtiefe des Suchbaumes (Suchindex) (trace-tree /
+Überwachungsliste) an. Bei einer angegeben Baumtiefe von 1  wird  eine 
+einfache  verkettete  Liste  als Suchindex verwendet. Bei eigenen
+Testreihen hat sich eine Baumtiefe von vier als Optimum herausgestellt.
+Bei den Tests wurde aber von mehr als 1000 gleichzeitigen Verbindungen
+ausgegangen.
+
+--trace-time [Sekunden] (10-3600)
+Standard: --trace-time 120 (2 Minuten)
+Die Option trace-time gibt die Zeit in Sekunden an, welche eine Quelladresse
+überwacht wird. Solange Pakete durch die Regel überprüft  werden, beginnt
+die Überwachungszeit von neuem. Dies bedeutet, dass z.B. bei einem Wert von
+20 in dieser Option der Überwachungseintrag der Quelladresse erst dann 
+entfernt wird, wenn dieser 120 Sekunden keine Prüfung mehr erfordert hat,
+d.h. dass in dieser Zeitspanne kein Paket durch die IpTables Regel zur 
+Überprüfung an das Modul gesendet wurde. Dies ist in der Regel der Fall,
+wenn der Rechner keine Verbindung mehr zum Zielsystem hat.
+
+--block-time [Sekunden] (0-172800)
+Standard: --block-time 3600 (1 Stunde)
+Die Option block-time gibt die Zeit in Sekunden an, die die Quelladresse eines
+Rechners gesperrt wird, falls eine der definierten Schwellwerte (Quotas) 
+erfüllt ist. Der Rechner wird im Falle des Überschreitens eines Schwellwertes
+(Quota) aus den überwachten Einträgen gelöscht und in die Ablehnungsliste 
+verschoben. Diese Liste ist eine normale verkettete Liste im Speicher und
+wird nicht zusätzlich indiziert.
+
+--clean-interval [Sekunden] (1-60)
+Standard: --clean-interval 1 (1 Sekunde)
+Diese Option legt das Intervall fest, nach dem veraltete Einträge aus den 
+Überwachungs- und Ablehnungslisten gelöscht werden. Zusätzlich ist im Kernel
+noch ein globales Intervall festgelegt, nach dem veraltete Einträge aller
+Konfigurationsumgebungen freigegeben werden.
+
+--max-deny-entries [Anzahl] (10-2000)
+Standard: --max-deny-entries 10
+Die Option max-deny-entries legt fest, wie viele Einträge maximal pro
+Konfigurationsumgebung in der Ablehnungsliste gespeichert werden. Wenn die die
+maximal definierte Anzahl überschritten ist, wird der älteste Eintrag aus der
+Ablehnungsliste entfernt und der neue hinzugefügt. Da diese Liste nicht durch
+einen Baum indiziert wird, darf der Wert nicht zu groß definiert werden, da
+dies sonst Einfluss auf die Netzwerkperformance nimmt.
+
+--max-trace-entries [Anzahl] (10-20000)
+Standard: --max-trace-entries 3000
+Durch die Option max-trace-entries wird festgelegt, wie viele Einträge maximal
+pro Konfigurationsumgebung in der Überwachungslisteliste gespeichert werden.
+Wenn dieser Wert überschritten wird, wird der älteste Eintrag aus der Liste
+entfernt und der neue hinzugefügt.
+
+--port-scan-quota [Quota] (3-1000)
+Standard: --port-scan-quota 10
+Diese Option legt fest, ab welchem Schwellwert (Quota) ein Portscan erkannt 
+wird. 
+Ein Portscan wird angenommen bei Erfüllung folgender Voraussetzung: 
+(Zielports   /  Zieladressen)  > port-scan-quota
+
+--net-scan-quota [Quota] (3-1000)
+Standard: --net-scan-quota 10
+Mittels dieser Option wird festgelegt, ab welchem Schwellwert (Quota) ein
+Netscan erkannt wird. 
+Ein Netscan wird angenommen bei Erfüllung folgender Voraussetzung: 
+(Zieladressen  /  Zielports)  > net-scan-quota
+
+--combined-quota [Quota] (6-1000)
+Standard: --combined-quota 50
+Durch diese Option wird festgelegt, ab welchem Schwellwert (Quota) ein
+Combined-Scan erkannt wird. 
+Ein Combined-Scan wird angenommen bei Erfüllung folgender Voraussetzung: 
+(Zieladressen  +  Zielports)  > combined-quota
+
+--check_deny_entries
+Standard <Kein Parameter>
+Wenn diese Option angegeben wird, wird geprüft, ob sich die Quelladresse
+in der  Ablehnungsliste befindet. Für diesen Fall wird ein positiver
+Rückgabewert an IpTables zurückgeliefert.
+
+Unterscheidung Einsatzgebiete
+Wichtig bei der Verwendung des Moduls ist die Reihenfolge der IpTables
+Regeln. Bei falscher Verwendung kann dies die Dienste oder Zugriffe zum
+und vom Internet stark einschränken.
+Für die Verwendung des Moduls werden zwei Szenarien vorgeschlagen. Diese
+unterscheiden sich grundlegend und werden nachfolgend genauer betrachtet.
+
+Anwendung des Moduls zur Überwachung abgelehnter Pakete
+In der ersten Betrachtung des Moduleinsatzes wird von einer Firewall mit
+bereits klar eingeschränkten Filterregeln für die genutzten Dienste und
+Anwendungen ausgegangen. Die Verwendung des Moduls erweitert die Firewall
+um die dynamische Erkennung und Ablehnung von Port-, Net- oder Combined-Scans.
+Dadurch können auch Dienste, die in der Firewall für bestimmte Server erlaubt
+sind, vor einem Angreifer verborgen werden. Gleichzeitig ist gewährleistet,
+dass die Dienste ohne Einschränkungen genutzt werden können.
+
+Für dieses Szenario müssen folgende Regeln eingehalten werden:
+
+1. Das Modul ist nur voll funktionsfähig, wenn die Firewall nach dem Konzept
+   "Alles was nicht explizit zugelassen wird ist verboten" aufgebaut ist.
+2. Vor den vorhanden Regeln muss die Option "--check-deny-entries" beim Aufrufen
+   des Module gesetzt werden.
+3. Nach diesen Regeln müssen alle Regeln für erlaubten Netzwerkverkehr folgen.
+4. Am Ende der abzuarbeitenden Regelliste von IpTables muss das Modul ohne die
+   Option "--check-deny-entries" aufgerufen werden.
+5. Ansonsten müssen die gleichen Konfigurationsparameter wie zuvor verwendet
+   werden, um die selbe Konfigurationsumgebung in allen Aufrufen des Moduls zu
+   besitzen.
+
+In der folgenden Skizze wird die korrekte Verwendung dargestellt:
+
+Abzuarbeitende
+IpTables
+Regeln
+
+ |  ---------------------------------------------------------------
+ |  | iptables -A ... -m PORTNETSCAN --check-deny-entries -j DROP | --
+ |  ---------------------------------------------------------------  |
+ |                                  |                                |
+ |                                  V                                |
+ |  ---------------------------------------                          |
+ |  | iptables -A ...                     | --                       |
+ |  ---------------------------------------  |                       |
+ |  ---------------------------------------  |                       |
+ |  | iptables -A ...                     | -|  --------             |
+ |  ---------------------------------------  |->|ACCEPT|             |
+ |  ---------------------------------------  |  --------             |
+ |  | iptables -A ...                     | -|                       |
+ |  ---------------------------------------  |                       |
+ |  ---------------------------------------  |                       |
+ |  | ...                                 | --                       |
+ |  ---------------------------------------                          |
+ |                                  |                                |
+ |                                  V                                |
+ |  ---------------------------------------------------------------  |
+ |  | iptables -A ... -m PORTNETSCAN  -j DROP                     | --
+ |  ---------------------------------------------------------------  |  ------
+ |  ---------------------------------------------------------------  |->|DROP|
+ |  | iptables -A ... -J DROP                                     | --  ------
+ |  ---------------------------------------------------------------
+ V
+ 
+Anwendung des Moduls zur Überwachung bestimmter Dienste oder Netzbereiche
+-------------------------------------------------------------------------
+
+Eine weitere Einsatzmöglichkeit  stellt die Verwendung des Moduls zur reinen
+Überwachung der Firewall dar. Andere Filterregeln, die für die benötigten
+Dienste in der Firewall gebraucht werden, werden erst nach dem Aufruf des
+Moduls PORTNETSCAN abgearbeitet.
+Vor diesen Regeln müssen Ausnahmen definiert werden, die Mehrfachverbindungen
+erlauben, um fehlerhaft abgelehnte Pakete zu verhindern.
+
+Das nachfolgende Schaubild beschreibt die Reihenfolge der Abarbeitung für
+diesen Einsatzzweck:
+
+Abzuarbeitende
+IpTables
+Regeln
+
+ |  ---------------------------------------
+ |  | iptables -A ... (Ausnahme1)         | --
+ |  ---------------------------------------  |
+ |  ---------------------------------------  |
+ |  | iptables -A ... (Ausnahme1)         | -|  --------
+ |  ---------------------------------------  |->|ACCEPT|
+ |  ---------------------------------------  |  --------
+ |  | iptables -A ... (AusnahmeXXX)       | --
+ |  ---------------------------------------
+ |                                  |
+ |                                  V
+ |  --------------------------------------------------------------- 
+ |  | iptables -A ...(Einschränkungen) -m PORTNETSCAN  -j DROP    | --
+ |  ---------------------------------------------------------------  |
+ |  ---------------------------------------                          |
+ |  | iptables -A ...                     | --                       |
+ |  ---------------------------------------  |                       |
+ |  ---------------------------------------  |                       |
+ |  | iptables -A ...                     | -|  --------             |
+ |  ---------------------------------------  |->|ACCEPT|             |
+ |  ---------------------------------------  |  --------             |
+ |  | iptables -A ...                     | -|                       |
+ |  ---------------------------------------  |                       |
+ |  ---------------------------------------  |                       |
+ |  | ...                                 | --                       |
+ |  ---------------------------------------                          |
+ |  ---------------------------------------------------------------  |  ------
+ |  | iptables -A ... -J DROP                                     | --->|DROP|
+ |  ---------------------------------------------------------------     ------
+
+Bei Verwendung des Moduls für dieses Szenario muss genau geprüft werden, für
+welche Server oder Clients im internen Netz Mehrfachverbindungen erlaubt sein
+müssen. Zudem sollte eine eindeutige Einschränkung in der aufgerufenen
+IpTables Regel erfolgen. Einschränkungen können zum Bespiel gesetztes SYN-Bit
+einer TCP Verbindung oder die Zielports einer Anwendung sein.
+
+Bei diesem Einsatzzweck empfiehlt sich die Verwendung mehrerer
+Konfigurationsumgebungen und eine Aufteilung in verschiedene Regeln, die die
+Zustände der Firewall erkennen lassen.
+
+Informationen über den Modulzustand im proc-Dateisystem
+-------------------------------------------------------
+In der aktuellen Implementierung des Kernelmoduls ipt_PORTNETSCAN wird beim
+Laden automatisch der Proc-Eintrag /proc/net/stat/portnetscan erstellt. In
+diesem befinden sich alle Informationen über den Status des Moduls.
+
+Durch die Anzahl der überwachten Einträge kann die Anzahl der ausgegebenen
+Zeilen sehr groß werden. Aus diesem Grund werden die Zeilen je nach
+Informationsinhalt mit einem definierten Anfangsbuchstaben zur Identifikation
+ausgegeben:
+
+       G  - Anzahl globale Konfigurationsumgebungen
+       U  - Aktuelle Zeit (Unixzeit)
+       J  - Aktuelle Kernelzeit (jiffies)
+       C  - Nächster Globaler Cleanup-Task (jiffies)
+       L  - Eintrag Konfigurationsumgebung
+       D  - Eintrag Ablehnungsliste
+       T  - Eintrag Überwachungsliste
+
+Nachfolgend wird eine Beispielausgabe mit nur einem überwachten Eintrag
+dargestellt:
+
+# IpTables PORTNETSCAN MODUL
+# --------------------------
+#
+G       Count_Global_Conf: 1
+U       Updating_Time(Unix): 1151670238
+#
+J       Updating_Time(jiffies): 170718608
+C       Next_Cleanup_Time(jiffies): 170725409
+#
+# Conf_Entries
+# ------------
+#
+#       confn/tree-depth/trace-time/clean-interval/port-scan-quota/net-scan-quota/combined-quota/max-deny-entries/max-trace-entries/block-time/tree-count/endnode-count/denylist-count
+L       0       4       3600    1       4       4       8       50      10000   36000   20      5       5
+#
+# Deny_Entries
+# ------------
+#
+#       confn/ipaddress/starttime/endtime/count/reason
+D       0       202.99.174.208  1151666423      1151702423      6       netscan_detected
+D       0       220.45.224.26   1151666512      1151702512      499     netscan_detected
+D       0       222.76.210.149  1151666756      1151702756      16      netscan_detected
+D       0       206.155.58.83   1151667516      1151703516      105     netscan_detected
+D       0       64.114.81.195   1151668641      1151704641      161     netscan_detected
+#
+# Trace_Entries
+# -------------
+#
+#       confn/ipaddress/firsttime/lasttime/count/countdst/countdpt
+T       0       219.136.206.12  1151665723      1151668290      6       3       1
+T       0       195.22.30.100   1151667986      1151667995      3       1       1
+T       0       80.247.193.215  1151668045      1151668488      2       2       1
+T       0       193.189.68.70   1151668446      1151668449      2       1       1
+T       0       65.214.44.227   1151669558      1151669567      3       1       1
+
+
+Alle Variablen werden mit dem Zeichen ":" getrennt, alle Listenwerte werden
+durch ein TAB getrennt. Somit können in Skripten oder externen Programmen leicht
+Aussagen über den Zustand des Moduls getroffen werden. Für die Listeneinträge
+der Ablehnungsliste (Deny_Entries) und der Überwachungsliste (Trace_Entries)
+wird immer die Konfigurationsumgebung (confn) mit ausgegeben. Wie weiter oben
+schon angemerkt, kann es durchaus vorkommen, dass eine  Quelladresse  mehrfach
+auftaucht, allerdings pro einer Konfigurationsumgebung nur einmal!
+
+Ein Beispiel für die praktische Anwendung
+-----------------------------------------
+Im diesem Beispiel werden nur Pakete und Verbindungen überwacht, die nach den
+Regeln zum Erlauben von Diensten und Anwendungen der Firewall nicht zugelassen
+wurden. Die folgende Umgebung wird folgende angenommen:
+
+Netz DMZ: 1.1.1.0/24
+Netzwerkkarten äußerer Router:
+	- eth0: zum Internet
+	- eth1: zur DMZ
+Webserver Standard http Port 80:
+	- 1.1.1.4
+	- 1.1.1.43
+DNS-Server
+	- 1.1.1.3
+Proxy-Server (http-Proxy)
+	-1.1.1.2
+
+Das nachfolgende Beispielskript der Firewall wird ohne Verwendung zusätzlich
+erstellter Ketten für IpTables oder Datenstrukturen in Skripten dargestellt,
+um die wesentlichen Inhalte hervorzuheben und die Lesbarkeit zu erhöhen.
+
+#!/bin/bash
+#...
+##############################################################################
+# PORTNETSCAN: Überprüfung Ablehnungsliste
+iptables -A FORWARD -i eth0 -o eth1 -m PORTNETSCAN --check-deny-entries\
+         --trace-entries 12000 -j DROP
+#
+# Standard Paketfilterregeln
+##############################################################################
+# Webserver 1.1.1.4
+iptables -A FORWARD -j ACCEPT -p TCP -i eth0 -o eth1 -d 1.1.1.4/32 --dport 80 \
+	--sport 1024:
+iptables -A FORWARD -j ACCEPT -p TCP -i eth1 -o eth0 -s 1.1.1.4/32 --sport 80 \
+	--dport 1024: !--syn
+# Webserver 1.1.1.43
+iptables -A FORWARD -j ACCEPT -p TCP -i eth0 -o eth1 -d 1.1.1.43/32 \
+	--dport 80 --sport 1024:
+iptables -A FORWARD -j ACCEPT -p TCP -i eth1 -o eth0 -s 1.1.1.43/32 \
+	--sport 80 --dport 1024: !--syn
+##############################################################################
+# DNS Server 1.1.1.3
+# DNS: Server - Server
+iptables -A FORWARD -j ACCEPT -p UDP -i eth0 -o eth1 -d 1.1.1.3/32 --sport 53 \
+	--dport 53
+iptables -A FORWARD -j ACCEPT -p UDP -i eth1 -o eth0 -s 1.1.1.3/32 --sport 53 \
+	--dport 53
+# DNS: Server - Client
+iptables -A FORWARD -j ACCEPT -p UDP -i eth0 -o eth1 -d 1.1.1.3/32 --sport 53 \
+	--dport 1024:
+iptables -A FORWARD -j ACCEPT -p UDP -i eth1 -o eth0 -s 1.1.1.3/32 \
+	--sport 1024: --dport 53
+# DNS: Client - Server
+iptables -A FORWARD -j ACCEPT -p UDP -i eth0 -o eth1 -d 1.1.1.3/32 \
+	--sport 1024: --dport 53
+iptables -A FORWARD -j ACCEPT -p UDP -i eth1 -o eth0 -s 1.1.1.3/32 \
+	--sport 53 --dport 1024:
+##############################################################################
+# Proxy Server (nur Standardverbindungen Port 80 und 443)
+iptables -A FORWARD -j ACCEPT -p TCP -i eth1 -o eth0 -s 1.1.1.2/32 \
+	--sport 1024: --dport 80
+iptables -A FORWARD -j ACCEPT -p TCP -i eth0 -o eth1 -s 1.1.1.2/32 \
+	--dport 1024: --sport 80 !--syn 
+iptables -A FORWARD -j ACCEPT -p TCP -i eth1 -o eth0 -s 1.1.1.2/32 \
+	--sport 1024: --dport 443
+iptables -A FORWARD -j ACCEPT -p TCP -i eth0 -o eth1 -s 1.1.1.2/32 \
+	--dport 1024: --sport 443 !--syn 
+# Ende aller Standard-Regeln
+##############################################################################
+# PORTNETSCAN Überprüfung Auffälligkeiten
+iptables -A FORWARD -i eth0 -o eth1 -m PORTNETSCAN --trace-entries 12000 \
+	-j DROP
+##############################################################################
+# Rest Ablehen
+iptables -A FORWARD -j DROP
+##############################################################################
+# Policy-Standard-Regel setzen (ist zwingend nicht norwendig, da die letzte 
+# Regel schon alle Pakete "DROP"
+IPTABLES -P FORWARD DROP't
+
+
+In diesem Skript wurde zusätzlich die Veränderung der Parametrisierung des
+Moduls dargestellt. Der Parameter "--trace-entries" wurde auf den Wert 12000
+gesetzt. Dies muss in beiden Aufrufen des Moduls geschehen, damit die beiden
+Aufrufe in derselben Konfigurationsumgebung durchgeführt werden.
+
+Im ersten Aufruf mit den Parametern 
+ -m PORTNETSCAN --check-deny-entries --trace-entries 12000
+wird nur geprüft, ob sich die Quelladresse des Rechners bereits in der
+Ablehnungsliste befindet. Hierbei wird nicht in den Überwachungseinträgen
+nachgesehen, ob eine Auffälligkeit wie Port-, Net-, oder Combinedscan
+vorhanden ist.
+
+Im zweiten Aufruf, der nach den Standardregeln ausgeführt wird, wird das
+Modul mit den Parametern 
+ -m PORTNETSCAN --trace-entries 12000 
+aufgerufen. Jetzt wird vom Modul geprüft, ob eine Auffälligkeit vorhanden
+ist und einer der gesetzten Schwellwerte überschritten wird. Sollte dies der
+Fall sein, wird der Eintrag in die Ablehnungsliste verschoben. Ab diesem
+Moment wird beim Aufrufen der Funktion des Moduls an IpTables ein positives
+Ereignis für diese Quelladresse zurückgemeldet. Bei Angabe von "-j DROP" wird
+das Paket ni diesem Fall von IpTables im Kernel verworfen.
diff -Naur linux-2.6.20.2.org/include/linux/netfilter_ipv4/ipt_PORTNETSCAN.h linux-2.6.20.2/include/linux/netfilter_ipv4/ipt_PORTNETSCAN.h
--- linux-2.6.20.2.org/include/linux/netfilter_ipv4/ipt_PORTNETSCAN.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.20.2/include/linux/netfilter_ipv4/ipt_PORTNETSCAN.h	2007-03-10 14:57:15.000000000 +0100
@@ -0,0 +1,388 @@
+/*
+	Name:            ipt_PORTNETSCAN.h
+	Date:            16.05.2006
+	Last change:     03.03.2007
+	Version:         0.3
+
+	Bemerkung:
+	Detect port- or netscans
+
+	Copyright (C) Robert Gladewitz
+	Fachhochschule Heidelberg
+
+	This file is distributed under the terms of the GNU General Public
+        License (GPL). Copies of the GPL can be obtained from:
+        http://www.gnu.org/licenses/gpl.html
+
+	2006-05-26 Robert Gladewitz <gladewitz@gmx.de> : initial
+	2006-05-30 Robert Gladewitz <gladewitz@gmx.de> : start testingseries in simulations networks in different situations
+	2006-06-05 Robert Gladewitz <gladewitz@gmx.de> : adding --check-deny-enttries
+	2006-06-22 Robert Gladewitz <gladewitz@gmx.de> : fix bug: no deleting emty conft-Entries
+	2006-06-22 Robert Gladewitz <gladewitz@gmx.de> : fix bug: no deleting emty conft-entries
+	2006-07-06 Robert Gladewitz <gladewitz@gmx.de> : Support fpr new structure for iptables in kernel 2.6.17
+	2006-08-03 Robert Gladewitz <gladewitz@gmx.de> : Correct wrong parameter deep to depth (misunderstanding parameter deep)
+	2007-03-03 Robert Gladewitz <gladewitz@gmx.de> : Change some structures and documentations
+*/
+
+/*
+############################################################################################################################################
+Global Defs
+############################################################################################################################################
+*/
+
+#ifndef portnetscan_H
+#define portnetscan_H
+/*
+############################################################################################################################################
+EigeneDefault-Definitionen
+############################################################################################################################################
+*/
+
+// Unabhängige Typdefinitionen
+typedef  u_int32_t  IpV4Address;            /* Typ für eine IP-Adresse (IPV4) ist ein 32 Bit Integer */ 
+typedef  u_int16_t  IpV4Port;               /* Typ für ein IP Port (IPV4) ist ein 16 Bit Integer */
+
+// StandardDefinitionen
+#define DEFAULTTREEDEPTH        4              /* StandardTiefe des verwendeten Baumes */
+#define DEFAULTDEBUGLEVEL       0              /* Debuglevel */
+#define DEFAULTTRACETIME        120            /* 10 Minuten Überwachen per Default (600 Sekunden = 10 Minuten) */
+#define MAXTRACETIME            3600           /* 1 Stunde Maximal Überwachungszeit (3600 Sekunden = 1 Stunde) */
+#define DEFAULTCLEANINTERVAL    1              /* Jede Sekunde soll geprüft werden, ob Einträge veraltet sind */
+#define MAXTCLEANINTERVAL       60             /* Maxmialer Wert für clean-interval */
+#define MAXUINT32               4294967295     /* Maximaler 32 BIT Unsigned Int */
+#define MAXENDNODEENTRY         9999           /* Maximale Länge in Vektoren der Werte DPT und DST einer EndNode */
+#define DEFAULTPORTSCANQUOTA    10             /* Portscan Erkennung: Standardwert für Verhältnis (Schwellwert) von Zieladresse zu Zielport (Zielports/Zieladressen) */
+#define MAXPORTSCANQUOTA        1000           /* Maximalwert für Schwellwert zur Portscan Erkennung */
+#define DEFAULTNETSCANQUOTA     10             /* Netscan Erkennung: Standardwert für Verhältnis (Schwellwert) von Zielport zur Zieladresse (Zieladressen/Zielports) */
+#define MAXNETSCANQUOTA         1000           /* Maximalwert für Schwellwert zur Netscan Erkennung */
+#define DEFAULTBLOCKTIME        3600           /* Zeit, die ein Host als blockiert gilt, falls ein Port- oder Netscan erkannt wird */
+#define MAXBLOCKTIME            172800         /* Maximale Zeit für blocken einer Quelladresse (172800 = 2 Tage) */
+#define DEFAULTDENYLISTCOUNT    10             /* Default Anzahl an Hosts in der DENY-LISTE (Blockierte Hosts) */
+#define MINDENYLISTCOUNT        10             /* Minimale Anzahl an Hosts in der DENY-LISTE (Blockierte Hosts) */
+#define MAXDENYLISTCOUNT        2000           /* Maximale Anzahl an Hosts in der DENY-LISTE (Blockierte Hosts) */
+#define MINENDNODECOUNT         10             /* Minimale Anzahl an überwachten Einträgen */
+#define MAXENDNODECOUNT         20000          /* Maximale Anzahl an überwachten Einträgen */
+#define DEFAULTENDNODECOUNT     10000          /* Standard Anzahl an überwachten Einträgen */
+#define GLOBALCLEANUP           30             /* Globaler Cleanup-Interval */
+#define DEFAULTCOMBINEDQUOTA    50             /* Schwellwert für Zielhost + Zielports eines Quellrechners */
+#define MAXCOMBINEDQUOTA        1000           /* Maximaler Schwellwert für Zielhost + Zielports eines Quellrechners */ 
+#define KERNELLINEMAX           1024           /* Maximale Länge einer Ausgabezeile für den Kernel (proc-Aufruf) */
+#define KERNELPAGESIZE          4096           /* Pagesize im Kernel */
+#define DEFAULTCHECKDENYENTRIES 0              /* Nur Deny-Liste überprüfen */
+
+// Erkannte Probleme
+#define REASONPORTSCAN       1                 /* Portscan wurde erkannt */
+#define REASONNETSCAN        2                 /* Netscan wurde erkannt */
+#define REASONCOMPINED       4                 /* Combined Scan wurde erkannt */
+#define REASONUNKNOWN        1024
+/*
+############################################################################################################################################
+Debuging and Testing
+############################################################################################################################################
+*/
+
+
+#ifdef __KERNEL__
+#define _malloc(ptr,prio) kmalloc (ptr, prio)
+#define _free(ptr)        kfree(ptr)
+#define _printf printk
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+
+#else
+#define _malloc(ptr,prio) malloc (ptr)
+#define _free(ptr)        free(ptr)
+#define _printf printf
+#endif
+
+
+
+
+
+
+/*
+############################################################################################################################################
+Definitionen für Netfilter / IpTables / Umgebungen
+############################################################################################################################################
+*/
+/*
+Beschreibung
+
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name: ipt_PORTNETSCAN_info
+	Conv: IPTABLES
+	Typ:  verkettete Liste
+	Info: Datenübergabe zwischen IpTables und dem Kernelmodul
+*/
+struct ipt_PORTNETSCAN_info
+{
+        unsigned int tree_depth;
+        unsigned int trace_time;
+        unsigned int clean_interval;
+        unsigned int port_scan_quota;
+        unsigned int net_scan_quota;
+        unsigned int max_deny_entries;
+        unsigned int max_trace_entries;
+        unsigned int block_time;
+	unsigned int combined_quota;
+	unsigned short check_deny_entries;
+};
+
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name: PortNetscanConf
+	Conv: PortNetScan
+	Typ:  Einfacher Struct (Angehängt an einer PortNetscanEnv-Liste)
+	Info: Für jede unterschiedliche Parameterübergabe wird eine Eigene
+	      Konfigurationsumgebung erstellt, die selbst auch alle Parameter (Einstellungen)
+	      enthällt. An diese angeknübft werden dann die SuchListen und Suchbäume
+*/
+struct PortNetscanConf
+{
+	struct TreeNode *    RootEntry;                  // Zeiger auf ersten Baumknoten (Siehe TreeNode)
+	struct TreeEndNode * FirstEndNode;               // Zeiger auf ersten überwachten Eintrag (Siehe TreeEndNode)
+	struct TreeEndNode * LastEndNode;                // Zeiger auf letzen überwachten Eintrag (Siehe TreeEndNode)
+	unsigned int         EndNodeCount;               // Anzahl von überwachten Einträgen
+	unsigned short       TreeDepth;                  // Baumtiefe in dieser Konfigurationsumgebung
+	unsigned int         TraceTime;                  // Überwachungszeit in dieser Konfigurationsumgebung
+	unsigned int         CleanInterval;              // Aufräum-Interval in dieser Konfigurationsumgebung
+	unsigned int         NetscanQuota;               // Verhältnis-Maximum zur Erkennung eines Netscans (Net/Port) in dieser Konfigurationsumgebung
+	unsigned int         PortscanQuota;              // Verhältnis-Maximum zur Erkennung eines Portscans (Port/Net) in dieser Konfigurationsumgebung
+	unsigned int         CombinedQuota;              // Kombiniertes Maximum in dieser Konfigurationsumgebung
+	unsigned int         BlockTime;                  // Blockierte Zeit eines gesperrten Rechners in dieser Konfigurationsumgebung
+	unsigned int         TreeCount;                  // Anzahl verwendeter Baumkonten in dieser Konfigurationsumgebung
+	unsigned int         DenyListCount;              // Einzahl Einträge in Liste blockierter Hosts in dieser Konfigurationsumgebung
+	unsigned int         MaxDenyListCount;           // Maximale Einträge in Liste blockierter Hosts in dieser Konfigurationsumgebung
+	unsigned int         MaxEndNodeCount;            // Maximale Einträge in Liste überwachter Einträge in dieser Konfigurationsumgebung
+	time_t               LastClean;                  // Letzter Aufräumvorgang in dieser Konfigurationsumgebung
+	struct DenyList *    FirstDenyListEntry;         // Zeiger auf ersten Eintrag in Liste blockierte Hosts in dieser Konfigurationsumgebung
+};
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name: struct PortNetscanEnv
+	Conv: PortNetScan / IpTables
+	Typ:  verkettete Liste
+	Info: Übergeordete verkettete Liste für PortNetscanConf. Die Attribute aus IpTables
+	      wurden hier mit Absicht in dem Namensraum von IpTables angegeben (klein, 
+	      mit _ getrennt, welches in IpTables selbst mit - getrennt wurde)
+*/
+struct PortNetscanEnv
+{
+	struct PortNetscanEnv * Next;                    // Nächster Eintrag in verketteter Liste ( NULL wenn letzter Eintrag)
+	struct PortNetscanEnv * Prior;                   // Vorheriger Eintrag in verketteter Liste ( NULL wenn erster Eintrag)
+	struct PortNetscanConf ConfEntries;              // Konfigurations-Struct
+	unsigned int tree_depth;                         // IpTables: tree-depth
+	unsigned int trace_time;                         // IpTables: trace-time
+	unsigned int clean_interval;                     // IpTables: clean-interval
+	unsigned int port_scan_quota;                    // IpTables: port-scan-quota
+	unsigned int net_scan_quota;                     // IpTables: net-scan-quota
+	unsigned int max_deny_entries;                   // IpTables: max-deny-entries
+	unsigned int max_trace_entries;                  // IpTables: max-trace-entries
+	unsigned int block_time;                         // IpTables: block-time
+	unsigned int combined_quota;                     // IpTables: combined-quota
+	time_t LastUse;                                  // Letzter Aufruf (Überprüfung Ablehnungsliste/Überwachungsliste)
+};
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name: struct KernelOutLinePuffer
+	Conv: Kernel/IpTables
+	Typ:  Einfacher Struct
+	Info: Speichert für ein proc_read die Zeilen zwischen
+		Interner Name: Kernelausgabeliste
+*/
+struct KernelOutLinePuffer
+{
+	char Line[KERNELLINEMAX];                        // Puffer für Inhalt der Kernelzeile (String)
+	struct KernelOutLinePuffer * Next;               // Zeiger auf nächstes Element in Kernelausgabeliste
+};
+
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name: struct IptGlobalConfStruct
+	Conv: PortNetScan
+	Typ:  Einfacher Struct
+	Info: Wird statisch initialisiert (in ModulInit) und speichert globale Einstellungen
+*/
+struct IptGlobalConfStruct
+{
+	struct PortNetscanEnv * FirstPortNetscan;        // Speichert den ersten Konfigurationeintrag (Konfigurationsumgebung)
+	struct KernelOutLinePuffer * FirstOutLine;       // Kernelausgabeliste: Bei proc_read-Aufruf ist dies der Zeiger auf das erste Element der noch auszugebenen Liste
+	struct KernelOutLinePuffer * LastPrintOutLine;   // Kernelausgabeliste: Letztes ausgegebenes Elemet
+	struct KernelOutLinePuffer * LastAddOutLine;     // Kernelausgabeliste: Letztes hinzugefügtes Element
+	unsigned int FailBuffer;                         // Kernelausgabeliste: Bei nicht ausreichenden Puffer, werden hier die Anzahl der bereits verarbeiteten Bytes angegeben
+	unsigned int Conf_Count;                         // Anzahl der Konfigurationseinträge
+	time_t LastCleanup;                              // Letzer globaler Aufräumablauf (Unix-Zeit)
+};
+
+
+
+
+// Beschreibung Unabhängige Stukturen
+/*
+                 TreeNode(Root)
+                     |
+	---------------------------
+        |                         |
+     TreeNode                  TreeNode
+    ....    ....             .... |
+                                  ---------
+                                          |
+                                       TreeNode
+                                     .... |
+                                          ----------
+                                                   |
+                                               TreeNode
+                                             ....  |
+                                                   ---------
+                                                           |
+     EndTreeNode <--> EndTreeNode <-->EndTreeNode <--> EndTreeNode 
+	| - TreeEndNodeEntries                             | - TreeEndNodeEntries 
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name: struct TreeEnd
+	Conv: PortNetScan
+	Typ:  verkettete BaumListe
+	Info: Suchbaum, mit angepasster Tiefe
+*/
+
+struct TreeNode 
+{ 
+		struct TreeNode *         Parent;        // übergeordneter Eintrag in Suchbaum (NULL, wenn in oberster Ebene)
+		void *                    Childs;        // untergeordneter Eintrag 
+		struct TreeNode *         Prior;         // vorheriges Element in gleicher Hierachieebene (NULL, wenn erster Eintrag in Hierachieebene)
+		struct TreeNode *         Next;          // nächstes Element in gleicher Hierachieebene (NULL, wenn letzer Eintrag)
+		u_int32_t                 TreeValue;     // Anteil an Suchbegriff
+};
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name: struct TreeEndNode
+	Conv: PortNetScan
+	Typ:  verkettete Liste
+	Info: für Einträge Zieladressen oder Zielports ind TreeEndNode
+*/
+struct TreeEndNodeEntry
+{
+		//Public Vars
+		u_int32_t                 Value;
+		struct TreeEndNodeEntry * Next;
+};
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name: struct TreeEndNode
+	Conv: PortNetScan
+	Typ:  verkettete Liste mit Verweis auf Suchbaum (Parent)
+	Info: Überwachte Einträge mit angehängten verketteten Listen
+	      für Zieladressen und Zielports. Zusätzlich werden
+	      Zähler für Zugriff, Zieladressen und Zielports gespeichert.
+*/
+struct TreeEndNode
+{	
+		//Public Vars
+		struct TreeNode *         Parent;        // letzte Treenode in der Such-Hierachie
+		time_t                    FirstTime;     // Erstes Auftreten
+		time_t                    LastTime;      // Letze Erfassung
+		IpV4Address               Src;           // Quelladresse
+		u_int32_t                 Count;         // Anzahl Pakete seit ersten Erfassen
+		u_int32_t                 CountDpt;      // Anzahl Ziel-Ports
+		u_int32_t                 CountDst;      // Anzahl Ziel-Adressen
+		struct TreeEndNodeEntry * EntriesDst;    // Einträge Zieladressen (Verweis auf eine verkettete Listen NULL wenn keine definiert wurde)
+		struct TreeEndNodeEntry * EntriesDpt;    // Einträge Zielports (Verweis auf eine verkettete Listen NULL wenn keine definiert wurde)
+		struct TreeEndNode *      Next;          // Nächster Eintrag in verketteter Liste ( NULL wenn letzter Eintrag)
+		struct TreeEndNode *      Prior;         // Vorheriger Eintrag in verketteter Liste ( NULL wenn erster Eintrag)
+};
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name: struct DenyList
+	Conv: PortNetScan
+	Typ:  verkettete Liste
+	Info: Gesperrte Einträge einer Konfigurationsumgebung
+*/
+struct DenyList	
+{
+		IpV4Address               Src;           // Quelladresse
+		time_t                    StartDenyTime; // Unix-Zeit, an welcher die Quelladresse gesperrt wurde
+		u_int32_t                 Count;         // Versuchte Zugriffe seit Sperrung
+		unsigned int              Reason;        // Grund für Sperrung ( Aktuell: REASONPORTSCAN, REASONNETSCAN, REASONCOMPINED, REASONUNKNOWN)
+		struct DenyList *         Next;          // Nächster Eintrag in verketteter Liste ( NULL wenn letzter Eintrag)
+		struct DenyList *         Prior;         // Vorheriger Eintrag in verketteter Liste ( NULL wenn erster Eintrag)
+};
+	
+
+/*
+	Init Funktionen sind Functionen, die nach dem
+	Allokieren (malloc/kalloc) ausgeführt werden sollte,
+	um alle verwendeten Variablen eines structs / virtuellen Klassen
+	auf Standardwerten zu setzen
+
+	Die Funktionen sind soweit notwendig in der ipt_PORTNETSCAN.c inline dokumentiert.
+*/
+// Supportfunctions
+unsigned int         powpos ( unsigned short A, unsigned short B );
+time_t               getunixtime(void);
+// Functions virt. Namespace PortNetscan
+void                 PortNetscan_Init(struct PortNetscanConf * ENV);
+void                 PortNetscan_Flush(struct PortNetscanConf * ENV);
+void                 DenyList_Init(struct PortNetscanConf * ENV,struct DenyList*);
+void                 DenyList_Flush(struct PortNetscanConf * ENV,struct DenyList*);
+void                 TreeEndNode_Init(struct PortNetscanConf * ENV,struct TreeEndNode*);
+void                 TreeEndNode_Flush(struct PortNetscanConf * ENV,struct TreeEndNode*);	
+void                 TreeEndNodeEntry_Init(struct PortNetscanConf * ENV,struct TreeEndNodeEntry*);
+void                 TreeEndNodeEntry_Flush(struct PortNetscanConf * ENV,struct TreeEndNodeEntry*);
+void                 TreeNode_Init(struct PortNetscanConf * ENV,struct TreeNode*);
+void                 TreeNode_Flush(struct PortNetscanConf * ENV,struct TreeNode*);
+// Functions
+void                 PortNetscan_Cleanup(struct PortNetscanConf * ENV);
+void                 PortNetscan_CleanupAll(struct PortNetscanConf * ENV);
+int                  PortNetscan_Check(struct PortNetscanConf * ENV,IpV4Address SRC, IpV4Address DST, IpV4Port DPT, unsigned short OnlyCheckDeny);
+int                  PortNetscan_SetTreeDepth(struct PortNetscanConf * ENV,const unsigned short DEPTH);
+int                  PortNetscan_SetTraceTime(struct PortNetscanConf * ENV,const unsigned int TRACETIME); 
+int                  PortNetscan_SetCleanInterval(struct PortNetscanConf * ENV,const unsigned int CLEANINTERVAL);
+int                  PortNetscan_SetPortscanQuota(struct PortNetscanConf * ENV,const unsigned int PORTSCANQUOTA);
+int                  PortNetscan_SetNetscanQuota(struct PortNetscanConf * ENV,const unsigned int NETSCANQUOTA);
+int                  PortNetscan_SetBlockTime(struct PortNetscanConf * ENV,const unsigned int BLOCKTIME);
+int                  PortNetscan_SetMaxDenyListCount(struct PortNetscanConf * ENV,const unsigned int MAXDEFINE);
+int                  PortNetscan_SetNodeCount(struct PortNetscanConf * ENV,const unsigned int MAXDEFINE);
+// Private Functions
+/*
+	Private Functions
+	Diese Funktionen sollten in keinem Fall direkt im Hauptprogramm angesprochen werden. Diese
+	Funktionen dienen nur für andere Funktionen, um interne Aktionen auszuführen.
+*/
+int                  PortNetscan_Add(struct PortNetscanConf * ENV,IpV4Address SRC, IpV4Address DST, IpV4Port DPT);
+struct TreeNode *    PortNetscan_AddTree(struct PortNetscanConf * ENV,struct TreeNode * TREENODE,const u_int32_t * IPPARTS,const unsigned short DEPTH);
+struct TreeEndNode * PortNetscan_AddTreeEndNode(struct PortNetscanConf * ENV,struct TreeNode * LastTreeNode, IpV4Address SRC, IpV4Address DST, IpV4Port DPT );
+int                  PortNetscan_GetIpV4Parts(struct PortNetscanConf * ENV,const u_int32_t IPV4ADDR,u_int32_t * IPPARTS);
+int                  PortNetscan_AddEndTreeEnty(struct PortNetscanConf * ENV,struct TreeEndNodeEntry * ENTRY, const u_int32_t VALUE);
+int                  PortNetscan_DelTreeEndNode(struct PortNetscanConf * ENV,struct TreeEndNode * ENTRY);
+int                  PortNetscan_DelTreeUnuses(struct PortNetscanConf * ENV,struct TreeNode *TREENODE);
+struct DenyList *    PortNetscan_AddDenyListEntry(struct PortNetscanConf * ENV,const IpV4Address SRC);
+int                  PortNetscan_DelDenyListEntry(struct PortNetscanConf * ENV,struct DenyList * ENTRY);
+int                  PortNetscan_CheckDenyList(struct PortNetscanConf * ENV,const IpV4Address SRC);
+
+
+
+#ifdef __KERNEL__
+// Kernel Static Structs
+static struct timer_list Kernel_CleanupTimer;
+// Kernel- and Modulfunctions
+void                 Kernel_CleanupAll(unsigned long FORCE);
+void                 Kernel_CreateProcEnv(void);
+void                 Kernel_DeleteProcEnv(void);
+int                  Kernel_WriteOutLinePufferToProc(char * BUFFER,int COUNT);
+int                  Kernel_ReadProcmem(char * BUFFER, char ** START, off_t OFFSET, int COUNT, int *EOF, void * DATA);
+int                  Kernel_FlushProcmemPuffer(void);
+int                  Kernel_CreateProcmemPuffer(void);
+int                  Kernel_CreateProcmemPufferAddEntry(char * LINE);
+#endif
+
+
+// End Global Defs
+#endif
+
diff -Naur linux-2.6.20.2.org/net/ipv4/netfilter/Kconfig linux-2.6.20.2/net/ipv4/netfilter/Kconfig
--- linux-2.6.20.2.org/net/ipv4/netfilter/Kconfig	2007-03-09 19:58:04.000000000 +0100
+++ linux-2.6.20.2/net/ipv4/netfilter/Kconfig	2007-03-10 14:33:15.000000000 +0100
@@ -312,6 +312,16 @@
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+config IP_NF_MATCH_PORTNETSCAN
+	tristate  'portnetscan detection match support'
+	depends on IP_NF_IPTABLES
+	help
+	  PORTNETSCAN is an iptables module for the detection of PORT-, NET 
+	  and COMBINEDSCANS using quotas. The usage is described in the 
+	  accompanying document located at Documentation/ipt_PORTNETSCAN.txt
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 # `filter', generic and specific targets
 config IP_NF_FILTER
 	tristate "Packet filtering"
diff -Naur linux-2.6.20.2.org/net/ipv4/netfilter/Kconfig.orig linux-2.6.20.2/net/ipv4/netfilter/Kconfig.orig
--- linux-2.6.20.2.org/net/ipv4/netfilter/Kconfig.orig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.20.2/net/ipv4/netfilter/Kconfig.orig	2007-03-09 19:58:04.000000000 +0100
@@ -0,0 +1,685 @@
+#
+# IP netfilter configuration
+#
+
+menu "IP: Netfilter Configuration"
+	depends on INET && NETFILTER
+
+config NF_CONNTRACK_IPV4
+	tristate "IPv4 connection tracking support (required for NAT)"
+	depends on NF_CONNTRACK
+	---help---
+	  Connection tracking keeps a record of what packets have passed
+	  through your machine, in order to figure out how they are related
+	  into connections.
+
+	  This is IPv4 support on Layer 3 independent connection tracking.
+	  Layer 3 independent connection tracking is experimental scheme
+	  which generalize ip_conntrack to support other layer 3 protocols.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config NF_CONNTRACK_PROC_COMPAT
+	bool "proc/sysctl compatibility with old connection tracking"
+	depends on NF_CONNTRACK_IPV4
+	default y
+	help
+	  This option enables /proc and sysctl compatibility with the old
+	  layer 3 dependant connection tracking. This is needed to keep
+	  old programs that have not been adapted to the new names working.
+
+	  If unsure, say Y.
+
+# connection tracking, helpers and protocols
+config IP_NF_CT_ACCT
+	bool "Connection tracking flow accounting"
+	depends on IP_NF_CONNTRACK
+	help
+	  If this option is enabled, the connection tracking code will
+	  keep per-flow packet and byte counters.
+
+	  Those counters can be used for flow-based accounting or the
+	  `connbytes' match.
+
+	  If unsure, say `N'.
+
+config IP_NF_CONNTRACK_MARK
+	bool  'Connection mark tracking support'
+	depends on IP_NF_CONNTRACK
+	help
+	  This option enables support for connection marks, used by the
+	  `CONNMARK' target and `connmark' match. Similar to the mark value
+	  of packets, but this mark value is kept in the conntrack session
+	  instead of the individual packets.
+	
+config IP_NF_CONNTRACK_SECMARK
+	bool  'Connection tracking security mark support'
+	depends on IP_NF_CONNTRACK && NETWORK_SECMARK
+	help
+	  This option enables security markings to be applied to
+	  connections.  Typically they are copied to connections from
+	  packets using the CONNSECMARK target and copied back from
+	  connections to packets with the same target, with the packets
+	  being originally labeled via SECMARK.
+
+	  If unsure, say 'N'.
+
+config IP_NF_CONNTRACK_EVENTS
+	bool "Connection tracking events (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && IP_NF_CONNTRACK
+	help
+	  If this option is enabled, the connection tracking code will
+	  provide a notifier chain that can be used by other kernel code
+	  to get notified about changes in the connection tracking state.
+	  
+	  IF unsure, say `N'.
+
+config IP_NF_CONNTRACK_NETLINK
+	tristate 'Connection tracking netlink interface (EXPERIMENTAL)'
+	depends on EXPERIMENTAL && IP_NF_CONNTRACK && NETFILTER_NETLINK
+	depends on IP_NF_CONNTRACK!=y || NETFILTER_NETLINK!=m
+	depends on IP_NF_NAT=n || IP_NF_NAT
+	help
+	  This option enables support for a netlink-based userspace interface
+
+
+config IP_NF_CT_PROTO_SCTP
+	tristate  'SCTP protocol connection tracking support (EXPERIMENTAL)'
+	depends on IP_NF_CONNTRACK && EXPERIMENTAL
+	help
+	  With this option enabled, the connection tracking code will
+	  be able to do state tracking on SCTP connections.
+
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
+config IP_NF_FTP
+	tristate "FTP protocol support"
+	depends on IP_NF_CONNTRACK
+	help
+	  Tracking FTP connections is problematic: special helpers are
+	  required for tracking them, and doing masquerading and other forms
+	  of Network Address Translation on them.
+
+	  To compile it as a module, choose M here.  If unsure, say Y.
+
+config IP_NF_IRC
+	tristate "IRC protocol support"
+	depends on IP_NF_CONNTRACK
+	---help---
+	  There is a commonly-used extension to IRC called
+	  Direct Client-to-Client Protocol (DCC).  This enables users to send
+	  files to each other, and also chat to each other without the need
+	  of a server.  DCC Sending is used anywhere you send files over IRC,
+	  and DCC Chat is most commonly used by Eggdrop bots.  If you are
+	  using NAT, this extension will enable you to send files and initiate
+	  chats.  Note that you do NOT need this extension to get files or
+	  have others initiate chats, or everything else in IRC.
+
+	  To compile it as a module, choose M here.  If unsure, say Y.
+
+config IP_NF_NETBIOS_NS
+	tristate "NetBIOS name service protocol support (EXPERIMENTAL)"
+	depends on IP_NF_CONNTRACK && EXPERIMENTAL
+	help
+	  NetBIOS name service requests are sent as broadcast messages from an
+	  unprivileged port and responded to with unicast messages to the
+	  same port. This make them hard to firewall properly because connection
+	  tracking doesn't deal with broadcasts. This helper tracks locally
+	  originating NetBIOS name service requests and the corresponding
+	  responses. It relies on correct IP address configuration, specifically
+	  netmask and broadcast address. When properly configured, the output
+	  of "ip address show" should look similar to this:
+
+	  $ ip -4 address show eth0
+	  4: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
+	      inet 172.16.2.252/24 brd 172.16.2.255 scope global eth0
+	  
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_TFTP
+	tristate "TFTP protocol support"
+	depends on IP_NF_CONNTRACK
+	help
+	  TFTP connection tracking helper, this is required depending
+	  on how restrictive your ruleset is.
+	  If you are using a tftp client behind -j SNAT or -j MASQUERADING
+	  you will need this.
+
+	  To compile it as a module, choose M here.  If unsure, say Y.
+
+config IP_NF_AMANDA
+	tristate "Amanda backup protocol support"
+	depends on IP_NF_CONNTRACK
+	select TEXTSEARCH
+	select TEXTSEARCH_KMP
+	help
+	  If you are running the Amanda backup package <http://www.amanda.org/>
+	  on this machine or machines that will be MASQUERADED through this
+	  machine, then you may want to enable this feature.  This allows the
+	  connection tracking and natting code to allow the sub-channels that
+	  Amanda requires for communication of the backup data, messages and
+	  index.
+
+	  To compile it as a module, choose M here.  If unsure, say Y.
+
+config IP_NF_PPTP
+	tristate  'PPTP protocol support'
+	depends on IP_NF_CONNTRACK
+	help
+	  This module adds support for PPTP (Point to Point Tunnelling
+	  Protocol, RFC2637) connection tracking and NAT. 
+	
+	  If you are running PPTP sessions over a stateful firewall or NAT
+	  box, you may want to enable this feature.  
+	
+	  Please note that not all PPTP modes of operation are supported yet.
+	  For more info, read top of the file
+	  net/ipv4/netfilter/ip_conntrack_pptp.c
+	
+	  If you want to compile it as a module, say M here and read
+	  Documentation/modules.txt.  If unsure, say `N'.
+
+config IP_NF_H323
+	tristate  'H.323 protocol support (EXPERIMENTAL)'
+	depends on IP_NF_CONNTRACK && EXPERIMENTAL
+	help
+	  H.323 is a VoIP signalling protocol from ITU-T. As one of the most
+	  important VoIP protocols, it is widely used by voice hardware and
+	  software including voice gateways, IP phones, Netmeeting, OpenPhone,
+	  Gnomemeeting, etc.
+
+	  With this module you can support H.323 on a connection tracking/NAT
+	  firewall.
+
+	  This module supports RAS, Fast Start, H.245 Tunnelling, Call
+	  Forwarding, RTP/RTCP and T.120 based audio, video, fax, chat,
+	  whiteboard, file transfer, etc. For more information, please
+	  visit http://nath323.sourceforge.net/.
+
+	  If you want to compile it as a module, say 'M' here and read
+	  Documentation/modules.txt.  If unsure, say 'N'.
+
+config IP_NF_SIP
+	tristate "SIP protocol support (EXPERIMENTAL)"
+	depends on IP_NF_CONNTRACK && EXPERIMENTAL
+	help
+	  SIP is an application-layer control protocol that can establish,
+	  modify, and terminate multimedia sessions (conferences) such as
+	  Internet telephony calls. With the ip_conntrack_sip and
+	  the ip_nat_sip modules you can support the protocol on a connection
+	  tracking/NATing firewall.
+
+	  To compile it as a module, choose M here.  If unsure, say Y.
+
+config IP_NF_QUEUE
+	tristate "IP Userspace queueing via NETLINK (OBSOLETE)"
+	help
+	  Netfilter has the ability to queue packets to user space: the
+	  netlink device can be used to access them using this driver.
+
+	  This option enables the old IPv4-only "ip_queue" implementation
+	  which has been obsoleted by the new "nfnetlink_queue" code (see
+	  CONFIG_NETFILTER_NETLINK_QUEUE).
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_IPTABLES
+	tristate "IP tables support (required for filtering/masq/NAT)"
+	depends on NETFILTER_XTABLES
+	help
+	  iptables is a general, extensible packet identification framework.
+	  The packet filtering and full NAT (masquerading, port forwarding,
+	  etc) subsystems now use this: say `Y' or `M' here if you want to use
+	  either of those.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+# The matches.
+config IP_NF_MATCH_IPRANGE
+	tristate "IP range match support"
+	depends on IP_NF_IPTABLES
+	help
+	  This option makes possible to match IP addresses against IP address
+	  ranges.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_MATCH_TOS
+	tristate "TOS match support"
+	depends on IP_NF_IPTABLES
+	help
+	  TOS matching allows you to match packets based on the Type Of
+	  Service fields of the IP packet.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_MATCH_RECENT
+	tristate "recent match support"
+	depends on IP_NF_IPTABLES
+	help
+	  This match is used for creating one or many lists of recently
+	  used addresses and then matching against that/those list(s).
+
+	  Short options are available by using 'iptables -m recent -h'
+	  Official Website: <http://snowman.net/projects/ipt_recent/>
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_MATCH_ECN
+	tristate "ECN match support"
+	depends on IP_NF_IPTABLES
+	help
+	  This option adds a `ECN' match, which allows you to match against
+	  the IPv4 and TCP header ECN fields.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_MATCH_AH
+	tristate "AH match support"
+	depends on IP_NF_IPTABLES
+	help
+	  This match extension allows you to match a range of SPIs
+	  inside AH header of IPSec packets.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_MATCH_TTL
+	tristate "TTL match support"
+	depends on IP_NF_IPTABLES
+	help
+	  This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user
+	  to match packets by their TTL value.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_MATCH_OWNER
+	tristate "Owner match support"
+	depends on IP_NF_IPTABLES
+	help
+	  Packet owner matching allows you to match locally-generated packets
+	  based on who created them: the user, group, process or session.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_MATCH_ADDRTYPE
+	tristate  'address type match support'
+	depends on IP_NF_IPTABLES
+	help
+	  This option allows you to match what routing thinks of an address,
+	  eg. UNICAST, LOCAL, BROADCAST, ...
+	
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
+# `filter', generic and specific targets
+config IP_NF_FILTER
+	tristate "Packet filtering"
+	depends on IP_NF_IPTABLES
+	help
+	  Packet filtering defines a table `filter', which has a series of
+	  rules for simple packet filtering at local input, forwarding and
+	  local output.  See the man page for iptables(8).
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_TARGET_REJECT
+	tristate "REJECT target support"
+	depends on IP_NF_FILTER
+	help
+	  The REJECT target allows a filtering rule to specify that an ICMP
+	  error should be issued in response to an incoming packet, rather
+	  than silently being dropped.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_TARGET_LOG
+	tristate "LOG target support"
+	depends on IP_NF_IPTABLES
+	help
+	  This option adds a `LOG' target, which allows you to create rules in
+	  any iptables table which records the packet header to the syslog.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_TARGET_ULOG
+	tristate "ULOG target support"
+	depends on IP_NF_IPTABLES
+	---help---
+
+	  This option enables the old IPv4-only "ipt_ULOG" implementation
+	  which has been obsoleted by the new "nfnetlink_log" code (see
+	  CONFIG_NETFILTER_NETLINK_LOG).
+
+	  This option adds a `ULOG' target, which allows you to create rules in
+	  any iptables table. The packet is passed to a userspace logging
+	  daemon using netlink multicast sockets; unlike the LOG target
+	  which can only be viewed through syslog.
+
+	  The appropriate userspace logging daemon (ulogd) may be obtained from
+	  <http://www.gnumonks.org/projects/ulogd/>
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_TARGET_TCPMSS
+	tristate "TCPMSS target support"
+	depends on IP_NF_IPTABLES
+	---help---
+	  This option adds a `TCPMSS' target, which allows you to alter the
+	  MSS value of TCP SYN packets, to control the maximum size for that
+	  connection (usually limiting it to your outgoing interface's MTU
+	  minus 40).
+
+	  This is used to overcome criminally braindead ISPs or servers which
+	  block ICMP Fragmentation Needed packets.  The symptoms of this
+	  problem are that everything works fine from your Linux
+	  firewall/router, but machines behind it can never exchange large
+	  packets:
+	  	1) Web browsers connect, then hang with no data received.
+	  	2) Small mail works fine, but large emails hang.
+	  	3) ssh works fine, but scp hangs after initial handshaking.
+
+	  Workaround: activate this option and add a rule to your firewall
+	  configuration like:
+
+	  iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
+	  		 -j TCPMSS --clamp-mss-to-pmtu
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+# NAT + specific targets: ip_conntrack
+config IP_NF_NAT
+	tristate "Full NAT"
+	depends on IP_NF_IPTABLES && IP_NF_CONNTRACK
+	help
+	  The Full NAT option allows masquerading, port forwarding and other
+	  forms of full Network Address Port Translation.  It is controlled by
+	  the `nat' table in iptables: see the man page for iptables(8).
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+# NAT + specific targets: nf_conntrack
+config NF_NAT
+	tristate "Full NAT"
+	depends on IP_NF_IPTABLES && NF_CONNTRACK_IPV4
+	help
+	  The Full NAT option allows masquerading, port forwarding and other
+	  forms of full Network Address Port Translation.  It is controlled by
+	  the `nat' table in iptables: see the man page for iptables(8).
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_NAT_NEEDED
+	bool
+	depends on IP_NF_NAT
+	default y
+
+config NF_NAT_NEEDED
+	bool
+	depends on NF_NAT
+	default y
+
+config IP_NF_TARGET_MASQUERADE
+	tristate "MASQUERADE target support"
+	depends on (NF_NAT || IP_NF_NAT)
+	help
+	  Masquerading is a special case of NAT: all outgoing connections are
+	  changed to seem to come from a particular interface's address, and
+	  if the interface goes down, those connections are lost.  This is
+	  only useful for dialup accounts with dynamic IP address (ie. your IP
+	  address will be different on next dialup).
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_TARGET_REDIRECT
+	tristate "REDIRECT target support"
+	depends on (NF_NAT || IP_NF_NAT)
+	help
+	  REDIRECT is a special case of NAT: all incoming connections are
+	  mapped onto the incoming interface's address, causing the packets to
+	  come to the local machine instead of passing through.  This is
+	  useful for transparent proxies.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_TARGET_NETMAP
+	tristate "NETMAP target support"
+	depends on (NF_NAT || IP_NF_NAT)
+	help
+	  NETMAP is an implementation of static 1:1 NAT mapping of network
+	  addresses. It maps the network address part, while keeping the host
+	  address part intact. It is similar to Fast NAT, except that
+	  Netfilter's connection tracking doesn't work well with Fast NAT.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_TARGET_SAME
+	tristate "SAME target support"
+	depends on (NF_NAT || IP_NF_NAT)
+	help
+	  This option adds a `SAME' target, which works like the standard SNAT
+	  target, but attempts to give clients the same IP for all connections.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_NAT_SNMP_BASIC
+	tristate "Basic SNMP-ALG support (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && IP_NF_NAT
+	---help---
+
+	  This module implements an Application Layer Gateway (ALG) for
+	  SNMP payloads.  In conjunction with NAT, it allows a network
+	  management system to access multiple private networks with
+	  conflicting addresses.  It works by modifying IP addresses
+	  inside SNMP payloads to match IP-layer NAT mapping.
+
+	  This is the "basic" form of SNMP-ALG, as described in RFC 2962
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config NF_NAT_SNMP_BASIC
+	tristate "Basic SNMP-ALG support (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && NF_NAT
+	---help---
+
+	  This module implements an Application Layer Gateway (ALG) for
+	  SNMP payloads.  In conjunction with NAT, it allows a network
+	  management system to access multiple private networks with
+	  conflicting addresses.  It works by modifying IP addresses
+	  inside SNMP payloads to match IP-layer NAT mapping.
+
+	  This is the "basic" form of SNMP-ALG, as described in RFC 2962
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+# If they want FTP, set to $CONFIG_IP_NF_NAT (m or y),
+# or $CONFIG_IP_NF_FTP (m or y), whichever is weaker.
+# From kconfig-language.txt:
+#
+#           <expr> '&&' <expr>                   (6)
+#
+# (6) Returns the result of min(/expr/, /expr/).
+config NF_NAT_PROTO_GRE
+	tristate
+	depends on NF_NAT && NF_CT_PROTO_GRE
+
+config IP_NF_NAT_FTP
+	tristate
+	depends on IP_NF_IPTABLES && IP_NF_CONNTRACK && IP_NF_NAT
+	default IP_NF_NAT && IP_NF_FTP
+
+config NF_NAT_FTP
+	tristate
+	depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+	default NF_NAT && NF_CONNTRACK_FTP
+
+config IP_NF_NAT_IRC
+	tristate
+	depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
+	default IP_NF_NAT if IP_NF_IRC=y
+	default m if IP_NF_IRC=m
+
+config NF_NAT_IRC
+	tristate
+	depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+	default NF_NAT && NF_CONNTRACK_IRC
+
+config IP_NF_NAT_TFTP
+	tristate
+	depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
+	default IP_NF_NAT if IP_NF_TFTP=y
+	default m if IP_NF_TFTP=m
+
+config NF_NAT_TFTP
+	tristate
+	depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+	default NF_NAT && NF_CONNTRACK_TFTP
+
+config IP_NF_NAT_AMANDA
+	tristate
+	depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
+	default IP_NF_NAT if IP_NF_AMANDA=y
+	default m if IP_NF_AMANDA=m
+
+config NF_NAT_AMANDA
+	tristate
+	depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+	default NF_NAT && NF_CONNTRACK_AMANDA
+
+config IP_NF_NAT_PPTP
+	tristate
+	depends on IP_NF_NAT!=n && IP_NF_PPTP!=n
+	default IP_NF_NAT if IP_NF_PPTP=y
+	default m if IP_NF_PPTP=m
+
+config NF_NAT_PPTP
+	tristate
+	depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+	default NF_NAT && NF_CONNTRACK_PPTP
+	select NF_NAT_PROTO_GRE
+
+config IP_NF_NAT_H323
+	tristate
+	depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
+	default IP_NF_NAT if IP_NF_H323=y
+	default m if IP_NF_H323=m
+
+config NF_NAT_H323
+	tristate
+	depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+	default NF_NAT && NF_CONNTRACK_H323
+
+config IP_NF_NAT_SIP
+	tristate
+	depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
+	default IP_NF_NAT if IP_NF_SIP=y
+	default m if IP_NF_SIP=m
+
+config NF_NAT_SIP
+	tristate
+	depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
+	default NF_NAT && NF_CONNTRACK_SIP
+
+# mangle + specific targets
+config IP_NF_MANGLE
+	tristate "Packet mangling"
+	depends on IP_NF_IPTABLES
+	help
+	  This option adds a `mangle' table to iptables: see the man page for
+	  iptables(8).  This table is used for various packet alterations
+	  which can effect how the packet is routed.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_TARGET_TOS
+	tristate "TOS target support"
+	depends on IP_NF_MANGLE
+	help
+	  This option adds a `TOS' target, which allows you to create rules in
+	  the `mangle' table which alter the Type Of Service field of an IP
+	  packet prior to routing.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_TARGET_ECN
+	tristate "ECN target support"
+	depends on IP_NF_MANGLE
+	---help---
+	  This option adds a `ECN' target, which can be used in the iptables mangle
+	  table.  
+
+	  You can use this target to remove the ECN bits from the IPv4 header of
+	  an IP packet.  This is particularly useful, if you need to work around
+	  existing ECN blackholes on the internet, but don't want to disable
+	  ECN support in general.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_TARGET_TTL
+	tristate  'TTL target support'
+	depends on IP_NF_MANGLE
+	help
+	  This option adds a `TTL' target, which enables the user to modify
+	  the TTL value of the IP header.
+
+	  While it is safe to decrement/lower the TTL, this target also enables
+	  functionality to increment and set the TTL value of the IP header to
+	  arbitrary values.  This is EXTREMELY DANGEROUS since you can easily
+	  create immortal packets that loop forever on the network.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_TARGET_CLUSTERIP
+	tristate "CLUSTERIP target support (EXPERIMENTAL)"
+	depends on IP_NF_MANGLE && EXPERIMENTAL
+	depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
+	help
+	  The CLUSTERIP target allows you to build load-balancing clusters of
+	  network servers without having a dedicated load-balancing
+	  router/server/switch.
+	
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+# raw + specific targets
+config IP_NF_RAW
+	tristate  'raw table support (required for NOTRACK/TRACE)'
+	depends on IP_NF_IPTABLES
+	help
+	  This option adds a `raw' table to iptables. This table is the very
+	  first in the netfilter framework and hooks in at the PREROUTING
+	  and OUTPUT chains.
+	
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
+# ARP tables
+config IP_NF_ARPTABLES
+	tristate "ARP tables support"
+	depends on NETFILTER_XTABLES
+	help
+	  arptables is a general, extensible packet identification framework.
+	  The ARP packet filtering and mangling (manipulation)subsystems
+	  use this: say Y or M here if you want to use either of those.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_ARPFILTER
+	tristate "ARP packet filtering"
+	depends on IP_NF_ARPTABLES
+	help
+	  ARP packet filtering defines a table `filter', which has a series of
+	  rules for simple ARP packet filtering at local input and
+	  local output.  On a bridge, you can also specify filtering rules
+	  for forwarded ARP packets. See the man page for arptables(8).
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
+config IP_NF_ARP_MANGLE
+	tristate "ARP payload mangling"
+	depends on IP_NF_ARPTABLES
+	help
+	  Allows altering the ARP packet payload: source and destination
+	  hardware and network addresses.
+
+endmenu
+
diff -Naur linux-2.6.20.2.org/net/ipv4/netfilter/Makefile linux-2.6.20.2/net/ipv4/netfilter/Makefile
--- linux-2.6.20.2.org/net/ipv4/netfilter/Makefile	2007-03-09 19:58:04.000000000 +0100
+++ linux-2.6.20.2/net/ipv4/netfilter/Makefile	2007-03-10 14:33:15.000000000 +0100
@@ -91,6 +91,7 @@
 obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
+obj-$(CONFIG_IP_NF_MATCH_PORTNETSCAN) += ipt_PORTNETSCAN.o
 
 # targets
 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
diff -Naur linux-2.6.20.2.org/net/ipv4/netfilter/Makefile.orig linux-2.6.20.2/net/ipv4/netfilter/Makefile.orig
--- linux-2.6.20.2.org/net/ipv4/netfilter/Makefile.orig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.20.2/net/ipv4/netfilter/Makefile.orig	2007-03-09 19:58:04.000000000 +0100
@@ -0,0 +1,118 @@
+#
+# Makefile for the netfilter modules on top of IPv4.
+#
+
+# objects for the standalone - connection tracking / NAT
+ip_conntrack-objs	:= ip_conntrack_standalone.o ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o
+# objects for l3 independent conntrack
+nf_conntrack_ipv4-objs  :=  nf_conntrack_l3proto_ipv4.o nf_conntrack_proto_icmp.o
+ifeq ($(CONFIG_NF_CONNTRACK_PROC_COMPAT),y)
+ifeq ($(CONFIG_PROC_FS),y)
+nf_conntrack_ipv4-objs	+= nf_conntrack_l3proto_ipv4_compat.o
+endif
+endif
+
+ip_nat-objs	:= ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o
+nf_nat-objs	:= nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o
+ifneq ($(CONFIG_NF_NAT),)
+iptable_nat-objs	:= nf_nat_rule.o nf_nat_standalone.o
+else
+iptable_nat-objs	:= ip_nat_rule.o ip_nat_standalone.o
+endif
+
+ip_conntrack_pptp-objs	:= ip_conntrack_helper_pptp.o ip_conntrack_proto_gre.o
+ip_nat_pptp-objs	:= ip_nat_helper_pptp.o ip_nat_proto_gre.o
+
+ip_conntrack_h323-objs := ip_conntrack_helper_h323.o ../../netfilter/nf_conntrack_h323_asn1.o
+ip_nat_h323-objs := ip_nat_helper_h323.o
+
+# connection tracking
+obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
+obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
+
+obj-$(CONFIG_IP_NF_NAT) += ip_nat.o
+obj-$(CONFIG_NF_NAT) += nf_nat.o
+
+# conntrack netlink interface
+obj-$(CONFIG_IP_NF_CONNTRACK_NETLINK) += ip_conntrack_netlink.o
+
+
+# SCTP protocol connection tracking
+obj-$(CONFIG_IP_NF_CT_PROTO_SCTP) += ip_conntrack_proto_sctp.o
+
+# connection tracking helpers
+obj-$(CONFIG_IP_NF_H323) += ip_conntrack_h323.o
+obj-$(CONFIG_IP_NF_PPTP) += ip_conntrack_pptp.o
+obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o
+obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o
+obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o
+obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o
+obj-$(CONFIG_IP_NF_SIP) += ip_conntrack_sip.o
+obj-$(CONFIG_IP_NF_NETBIOS_NS) += ip_conntrack_netbios_ns.o
+
+# NAT helpers (ip_conntrack)
+obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o
+obj-$(CONFIG_IP_NF_NAT_PPTP) += ip_nat_pptp.o
+obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o
+obj-$(CONFIG_IP_NF_NAT_TFTP) += ip_nat_tftp.o
+obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o
+obj-$(CONFIG_IP_NF_NAT_IRC) += ip_nat_irc.o
+obj-$(CONFIG_IP_NF_NAT_SIP) += ip_nat_sip.o
+
+# NAT helpers (nf_conntrack)
+obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
+obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
+obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o
+obj-$(CONFIG_NF_NAT_IRC) += nf_nat_irc.o
+obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o
+obj-$(CONFIG_NF_NAT_SIP) += nf_nat_sip.o
+obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o
+obj-$(CONFIG_NF_NAT_TFTP) += nf_nat_tftp.o
+
+# NAT protocols (nf_nat)
+obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o
+
+# generic IP tables 
+obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
+
+# the three instances of ip_tables
+obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
+obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
+obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
+obj-$(CONFIG_NF_NAT) += iptable_nat.o
+obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
+
+# matches
+obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
+obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
+obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
+obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
+obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
+obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
+obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
+obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
+
+# targets
+obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
+obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o
+obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
+obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
+obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
+obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
+obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o
+obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
+obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
+obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
+obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o
+obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
+obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
+
+# generic ARP tables
+obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
+obj-$(CONFIG_IP_NF_ARP_MANGLE) += arpt_mangle.o
+
+# just filtering instance of ARP tables for now
+obj-$(CONFIG_IP_NF_ARPFILTER) += arptable_filter.o
+
+obj-$(CONFIG_IP_NF_QUEUE) += ip_queue.o
+
diff -Naur linux-2.6.20.2.org/net/ipv4/netfilter/ipt_PORTNETSCAN.c linux-2.6.20.2/net/ipv4/netfilter/ipt_PORTNETSCAN.c
--- linux-2.6.20.2.org/net/ipv4/netfilter/ipt_PORTNETSCAN.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.20.2/net/ipv4/netfilter/ipt_PORTNETSCAN.c	2007-03-10 14:54:55.000000000 +0100
@@ -0,0 +1,2227 @@
+/*
+	Name:            ipt_PORTNETSCAN.c
+	Date:            16.05.2006
+	Last change:     03.03.2007
+	Version:         0.3
+
+	Bemerkung:
+	Detect port- or netscans
+
+	Copyright (C) Robert Gladewitz
+	Fachhochschule Heidelberg
+
+	This file is distributed under the terms of the GNU General Public
+        License (GPL). Copies of the GPL can be obtained from:
+        http://www.gnu.org/licenses/gpl.html
+
+	2006-05-26 Robert Gladewitz <gladewitz@gmx.de> : initial
+	2006-05-30 Robert Gladewitz <gladewitz@gmx.de> : start testingseries in simulations networks in different situations
+	2006-06-05 Robert Gladewitz <gladewitz@gmx.de> : adding --check-deny-enttries
+	2006-06-22 Robert Gladewitz <gladewitz@gmx.de> : fix bug: no deleting emty conft-entries (LastUse)
+	2006-07-06 Robert Gladewitz <gladewitz@gmx.de> : Support for new structure for iptables in kernel 2.6.17
+	2006-08-03 Robert Gladewitz <gladewitz@gmx.de> : Correct wrong parameter deep to depth (misunderstanding parameter deep)
+	2007-03-03 Robert Gladewitz <gladewitz@gmx.de> : Change some structures and documentations
+*/
+
+/*
+######################################################################################################################
+#### Includes ########################################################################################################
+######################################################################################################################
+*/
+
+#define _debug printk
+
+#ifdef __KERNEL__
+
+#include <linux/time.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+#include <linux/tcp.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+#include <net/ip.h>
+#include <net/tcp.h>
+#include <net/dst.h>
+#include <linux/spinlock.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_PORTNETSCAN.h>
+
+
+// Maybe for later functions, now here tcp and udp implemented
+//#include <linux/icmp.h>
+//#include <net/icmp.h>
+//#include <net/route.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Robert Gladewitz <gladewitz@gmx.de>");
+MODULE_DESCRIPTION("port- and netscan detection");
+
+#else
+
+// Testing
+#include <stdio.h>                           // Standard IO functions
+#include <stdlib.h>                          // Standard LIB functions
+#include <time.h>                            // Zeittypen - time functions
+
+#include "PortNetscan.h"
+
+#endif
+
+
+
+/*
+#######################################################################################################################
+#### Nich vorhandene Funktionen ersetzen ##############################################################################
+#######################################################################################################################
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   powpos
+	Conv:   Support Kernel
+	Typ:    function
+	return: unsigned int ( Ergebnis A hoch B )
+	Par 1:  unsigned short A
+	Par 2:  unsigned short B
+	Info:   Die Funktion errechnet A hoch B
+*/
+unsigned int powpos ( unsigned short A, unsigned short B )
+{
+	u_int32_t RC = 0;
+	if ( B == 0 )
+	{
+		RC = 1;
+	}
+	else if ( A == 0 )
+	{
+		RC = 0;
+	}
+	else
+	{
+		unsigned int I;
+		RC=A;
+		for (I=1; I<B; I++) RC = RC * A;
+	}
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   getunixtime
+	Conv:   Support Kernel
+	Typ:    function
+	return: time_t
+	Par 1:  void (Keine übergebenen Parameter)
+	Info:   Diese Funktion gibt die aktuelle Unix-Zeit zurück (nur Sekunden seit Start der Unix-Zeit)
+*/
+time_t getunixtime(void)
+{
+	/*
+	Leider werden die Funktionen der time.h nicht unterstützt - hier eine eigene
+	Imlementierung der Funtionen time(0).
+	*/ 
+	// Functionsvariablen
+	time_t RC = 0;
+#ifdef __KERNEL__
+	struct timeval TEMPTIMEVAL;
+	do_gettimeofday(&TEMPTIMEVAL);
+	RC = TEMPTIMEVAL.tv_sec;
+#else
+	RC = time(0);
+#endif
+	return RC;
+}
+
+/*
+######################################################################################################################
+#### TreeNode ########################################################################################################
+######################################################################################################################
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   TreeNode_Init
+	Conv:   PortNetscan
+	Typ:    function
+	return: void (keine Rückgabewerte)
+	Par 1:  PortNetscanConf (Konfigurationsumgebung, zwar nicht nötig, aber für einheitliche Programmierung wurde der Parameter mit einbezogen)
+	Par 2:  struct TreeNode ( Zu initialisierender struct TreeNode)
+	Info:   Diese Funktion initialsiert alle Inhalte des übergebenen Strukts TreeNode mit den Standardwerten. Diese
+	        Funktion sollte nach jedem malloc-Aufruf einer neuen TreeNode ausgeführt werden.
+*/
+void TreeNode_Init(struct PortNetscanConf * ENV,struct TreeNode* V)
+{
+	// Alle Zeigervariablen mit NULL initialisieren
+	V->Parent    = NULL;
+	V->Prior     = NULL;
+	V->Next      = NULL;
+	V->Childs    = NULL;
+	V->TreeValue = 0;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   TreeNode_Flush
+	Conv:   PortNetscan
+	Typ:    function
+	return: void (keine Rückgabewerte)
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  
+	Info:   
+*/
+void TreeNode_Flush(struct PortNetscanConf * ENV,struct TreeNode* V)
+{
+	// Alle Zeigervariablen mit NULL initialisieren
+	V->Parent    = NULL;
+	V->Prior     = NULL;
+	V->Next      = NULL;
+	V->Childs    = NULL;
+	V->TreeValue = 0;
+}
+/*
+######################################################################################################################
+#### Class: TreeEndNodeEntry #########################################################################################
+######################################################################################################################
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   TreeEndNodeEntry_Init
+	Conv:   PortNetscan
+	Typ:    function
+	return: void (keine Rückgabewerte)
+	Par 1:  PortNetscanConf (Konfigurationsumgebung, zwar nicht nötig, aber für einheitliche Programmierung wurde der Parameter mit einbezogen)
+	Par 2:  struct TreeEndNodeEntry ( Zu initialisierender struct TreeEndNodeEndtry)
+	Info:   Diese Funktion initialsiert alle Inhalte des übergebenen Strukts TreeEndNodeEntry mit den Standardwerten. Diese
+	        Funktion sollte nach jedem malloc-Aufruf einer neuen TreeEndNodeEntry ausgeführt werden.
+*/
+void TreeEndNodeEntry_Init(struct PortNetscanConf * ENV,struct TreeEndNodeEntry* V)
+{
+	V->Next     = NULL;
+	V->Value    = 0;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   TreeEndNodeEntry_Flush
+	Conv:   PortNetscan
+	Typ:    function
+	return: void (keine Rückgabewerte)
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  TreeEndNodeEntry
+	Info:   Zurücksetzen der Variablen fpr TreeEndNode auf die Standardwerte
+*/
+void TreeEndNodeEntry_Flush(struct PortNetscanConf * ENV,struct TreeEndNodeEntry* V)
+{
+	V->Next     = NULL;
+	V->Value    = 0;
+}
+/*
+######################################################################################################################
+#### Class: TreeEndNode ##############################################################################################
+######################################################################################################################
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   TreeEndNode_Init
+	Conv:   PortNetscan
+	Typ:    function
+	return: void (keine Rückgabewerte)
+	Par 1:  PortNetscanConf (Konfigurationsumgebung, zwar nicht nötig, aber für einheitliche Programmierung wurde der Parameter mit einbezogen)
+	Par 2:  struct TreeEndNode ( Zu initialisierender struct TreeNode)
+	Info:   Diese Funktion initialsiert alle Inahlte des übergebenen Strukts TreeEndNode mit den Standardwerten. Diese
+	        Funktion sollte nach jedem malloc-Aufruf einer neuen TreeEndNode ausgeführt werden.
+*/
+void TreeEndNode_Init(struct PortNetscanConf * ENV,struct TreeEndNode* V)
+{
+	// Alle Zeigervariablen mit NULL initialisieren
+	V->EntriesDst    = NULL;
+	V->EntriesDpt    = NULL;
+	V->Parent        = NULL;
+	V->Next          = NULL;
+	V->Prior         = NULL;
+	V->Count         = 0;
+	V->CountDst      = 0;
+	V->CountDpt      = 0;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   TreeEndNode_Flush
+	Conv:   PortNetscan
+	Typ:    function
+	return: void (keine Rückgabewerte)
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  
+	Info:   
+*/
+void TreeEndNode_Flush(struct PortNetscanConf * ENV,struct TreeEndNode* V)
+{
+	V->EntriesDst    = NULL;
+	V->EntriesDpt    = NULL;
+	V->Parent        = NULL;
+	V->Next          = NULL;
+	V->Prior         = NULL;
+	V->Count         = 0;
+	V->CountDst      = 0;
+	V->CountDpt      = 0;
+	V->FirstTime     = 0;
+	V->LastTime      = 0;
+}
+/*
+######################################################################################################################
+#### Class: PortNetscanDenyList ######################################################################################
+######################################################################################################################
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   DenyList_Init
+	Conv:   PortNetscan
+	Typ:    function
+	return: void (keine Rückgabewerte)
+	Par 1:  PortNetscanConf (Konfigurationsumgebung, zwar nicht nötig, aber für einheitliche Programmierung wurde der Parameter mit einbezogen)
+	Par 2:  struct DenyList ( Zu initialisierender struct DenyList)
+	Info:   Diese Funktion initialsiert alle Inahlte des übergebenen Strukts DenyList mit den Standardwerten. Diese
+	        Funktion sollte nach jedem malloc-Aufruf einer neuen DenyList ausgeführt werden.
+*/
+
+void DenyList_Init(struct PortNetscanConf * ENV,struct DenyList* V)
+{
+	V->Src           = 0;
+	V->Count         = 0;
+	V->Reason        = 0;
+	V->Next          = NULL;
+	V->Prior         = NULL;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   DenyList_Flush
+	Conv:   PortNetscan
+	Typ:    function
+	return: void (keine Rückgabewerte)
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  
+	Info:   
+*/
+void DenyList_Flush(struct PortNetscanConf * ENV,struct DenyList* V)
+{
+	V->Src           = 0;
+	V->Count         = 0;
+	V->Reason        = 0;
+	V->Next          = NULL;
+	V->Prior         = NULL;
+}
+/*
+######################################################################################################################
+#### Class: PortNetscanTree ##########################################################################################
+######################################################################################################################
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_Init
+	Conv:   PortNetscan
+	Typ:    function
+	return: void (keine Rückgabewerte)
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Info:   Diese Funktion initialsiert alle Inahlte des übergebenen Strukts PortNetscanConf mit den Standardwerten.
+	        Dieser Struct ist in sich eine Konfigurationsumegebung, die je nach Parametern von IpTables angelegt
+	        wird.
+*/
+void PortNetscan_Init(struct PortNetscanConf * ENV)
+{
+	// Alle Zeigervariablen mit NULL initialisieren
+	ENV->RootEntry          = NULL;
+	ENV->FirstEndNode       = NULL;
+	ENV->LastEndNode        = NULL;
+	ENV->FirstDenyListEntry = NULL;
+	ENV->TreeDepth          = DEFAULTTREEDEPTH;
+	ENV->TraceTime          = DEFAULTTRACETIME;
+	ENV->CleanInterval      = DEFAULTCLEANINTERVAL;
+	ENV->NetscanQuota       = DEFAULTNETSCANQUOTA;
+	ENV->PortscanQuota      = DEFAULTPORTSCANQUOTA;
+	ENV->CombinedQuota      = DEFAULTCOMBINEDQUOTA;
+	ENV->BlockTime          = DEFAULTBLOCKTIME;
+	ENV->MaxEndNodeCount    = DEFAULTENDNODECOUNT;
+	ENV->MaxDenyListCount   = DEFAULTDENYLISTCOUNT;
+	ENV->LastClean          = getunixtime();
+	ENV->EndNodeCount       = 0;
+	ENV->DenyListCount      = 0;
+	ENV->TreeCount          = 0;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_Flush
+	Conv:   PortNetscan
+	Typ:    function
+	return: void (keine Rückgabewerte)
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  
+	Info:   
+*/
+void PortNetscan_Flush(struct PortNetscanConf * ENV)
+{
+	// Alle Zeigervariablen mit NULL initialisieren
+	PortNetscan_CleanupAll(ENV);
+	ENV->RootEntry          = NULL;
+	ENV->FirstEndNode       = NULL;
+	ENV->LastEndNode        = NULL;
+	ENV->FirstDenyListEntry = NULL;
+	ENV->EndNodeCount       = 0;
+	ENV->TreeDepth          = 0;
+	ENV->TraceTime          = 0;
+	ENV->CleanInterval      = 0;
+	ENV->LastClean          = 0;
+	ENV->MaxDenyListCount   = 0;
+	ENV->NetscanQuota       = 0;
+	ENV->PortscanQuota      = 0;
+	ENV->CombinedQuota      = 0;
+	ENV->BlockTime          = 0;
+	ENV->DenyListCount      = 0;
+	ENV->MaxEndNodeCount    = 0;
+	ENV->TreeCount          = 0;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_Cleanup
+	Conv:   PortNetscan
+	Typ:    function
+	return: void (keine Rückgabewerte)
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Info:   Diese Funktion prüft, ob überwachte Einträge die Maximale Zeit der Überwachung überschritten haben und löscht 
+	        diese. Eoine Überschreitung dieser Zeit wird aus (Zeit letzer Zugriff) + TraceTime(Überwachungszeit) hergeleitet.
+*/
+void PortNetscan_Cleanup(struct PortNetscanConf * ENV)
+{
+	// Funktionsvariablen
+	struct TreeEndNode * TENTRY = ENV->FirstEndNode;
+	time_t               NOW    = getunixtime();
+	struct DenyList *    DENTRY = ENV->FirstDenyListEntry;
+
+	
+	// Überwachungsbaum/-einträge Aufräumen
+	if ( TENTRY != NULL )
+		while ( TENTRY != NULL )
+		{
+			struct TreeEndNode * NEXT = TENTRY->Next;
+			if ( (TENTRY->LastTime + ENV->TraceTime) < NOW)
+			{
+				PortNetscan_DelTreeUnuses(ENV,TENTRY->Parent);
+				PortNetscan_DelTreeEndNode(ENV,TENTRY);
+			}
+			TENTRY=NEXT;
+		}
+
+	// Ablehnungsliste Aufräumen
+	if ( DENTRY != NULL )
+	{
+		while ( DENTRY != NULL )
+		{
+			// Cleaning old Entries
+			if ( (DENTRY->StartDenyTime + ENV->BlockTime) < NOW )
+			{
+				struct DenyList * DNEXT = DENTRY;
+				DENTRY = DENTRY->Next;
+				PortNetscan_DelDenyListEntry(ENV,DNEXT);
+				DNEXT = NULL;
+				continue;
+			}
+			DENTRY = DENTRY->Next;
+		}
+	}
+
+
+	NOW   = 0;
+	TENTRY = NULL;
+	DENTRY = NULL;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_Check
+	Conv:   PortNetscan
+	Typ:    function
+	return: 0 (Ok) / > 0 Quelladdresse ist in DenyList oder wurde in DenyList verschoben
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  Quelladresse
+	Par 3:  Zieladresse
+	Par 4:  Zielport
+	Par 5:  Nur Denyliste überprüfen
+	Info:   Dies ist die erste Funktion, die aufgerufen werden sollte, wenn ein Packet geprüft werden
+	        soll. Hier wird erst aufgeräumt und dann PortNetscan_Add aufgerufen, wenn OnlyCheckDeny = 0 ist.
+*/
+int PortNetscan_Check(struct PortNetscanConf * ENV,IpV4Address SRC, IpV4Address DST, IpV4Port DPT, unsigned short OnlyCheckDeny)
+{
+	// Funktionsvariablen
+	int RC = 0;
+	
+	if ( PortNetscan_CheckDenyList(ENV,SRC) )
+	{
+		RC = 4;
+	}
+	else
+		if ( OnlyCheckDeny == 0 )
+		{	
+			time_t NOW = getunixtime();
+			if ( (ENV->LastClean + ENV->CleanInterval) < NOW ) 
+			{
+				PortNetscan_Cleanup(ENV); 
+				ENV->LastClean = NOW;
+			}
+
+			PortNetscan_Add(ENV,SRC,DST,DPT);
+		}
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_SetTreeDepth
+	Conv:   PortNetscan
+	Typ:    function
+	return: O (false) für FEHLER / 1 (true) für OK
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  unsigned short - Baumtiefe für Suchbaum
+	Info:   Diese Funktion setzt die Baumtiefe einer Konfigurationsumgebung.
+*/
+int PortNetscan_SetTreeDepth(struct PortNetscanConf * ENV,unsigned short DEPTH)
+{
+	// Baumtiefe setzen.100000
+	// Nach ausgiebiegen Tests hat sich die Baumtiefe von 4 
+	// als die schnellste Baumtiefe herausgestellt
+	int RC = 1;
+
+	if ( ENV->RootEntry != NULL )
+	{
+		// In diesem Fall ist der Baum schon vorhanden - Änderung nicht mehr möglich!!!
+		_printf("SetTreeDepth: Tree allready initialize!!");
+		RC = 0;
+	}
+	else
+	{
+		switch ( DEPTH )
+		{
+			case 1:    { ENV->TreeDepth=1;  break; }
+			case 2:    { ENV->TreeDepth=2;  break; }
+			case 4:    { ENV->TreeDepth=4;  break; }
+			case 8:    { ENV->TreeDepth=8;  break; }
+			case 16:   { ENV->TreeDepth=16; break; }
+			case 32:   { ENV->TreeDepth=32; break; }
+			default:
+			{ 
+				ENV->TreeDepth=DEFAULTTREEDEPTH; 
+				RC=0; 
+				_printf("SetTreeDepth: Only 1, 2, 4, 8, 16 or 32 values are possible!");
+				break; 
+			}
+		}
+	}
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_GetIpV4Parts
+	Conv:   PortNetscan
+	Typ:    function
+	return: 1 (true) / 0 (false)
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  
+	Info:   
+*/
+int PortNetscan_GetIpV4Parts(struct PortNetscanConf * ENV,const u_int32_t IPV4ADDR, u_int32_t * IPPARTS)
+{
+	int RC = 1;
+	unsigned short PARTSIZE = 32 / ENV->TreeDepth;
+	u_int32_t TEMP          = IPV4ADDR;
+	int I                   = 0;
+	
+	for ( I=0; I < ENV->TreeDepth; I++) 
+		IPPARTS[I] = (((u_int32_t)powpos((unsigned short)2,(unsigned short)PARTSIZE))-1) & (TEMP >> (ENV->TreeDepth-I-1)*PARTSIZE);
+	return RC;	
+}
+
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_CleanupAll
+	Conv:   PortNetscan
+	Typ:    function
+	return: void (keine Rückgabewerte)
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Info:   Vollständiges Aufräumen (Löschen) Aller Einträge in der Überwachungsliste und der Sperrliste
+*/
+void PortNetscan_CleanupAll(struct PortNetscanConf * ENV)
+{
+	// Funktionsvariablen
+	struct TreeEndNode * WORKENTRY = ENV->FirstEndNode;
+	struct DenyList    * DENYENTRY = ENV->FirstDenyListEntry;
+
+	if ( WORKENTRY != NULL )
+		while ( WORKENTRY != NULL )
+		{
+			struct TreeEndNode * NEXT = WORKENTRY->Next;
+			PortNetscan_DelTreeUnuses(ENV,WORKENTRY->Parent);
+			PortNetscan_DelTreeEndNode(ENV,WORKENTRY);
+			WORKENTRY=NEXT;
+			NEXT = NULL;
+		}
+
+
+	
+	WORKENTRY = NULL;
+
+	if ( DENYENTRY != NULL )
+	{
+		while ( DENYENTRY != NULL )
+		{
+			struct DenyList * NEXT = DENYENTRY->Next;
+			PortNetscan_DelDenyListEntry(ENV,DENYENTRY);
+			DENYENTRY=NEXT;
+			NEXT=NULL;
+		}
+	}
+
+	DENYENTRY = NULL;
+
+
+	if ( ENV->RootEntry != NULL )
+	{
+		_printf("CleanupAll: Fehler: RootEntry ist ungleich NULL!!\n");
+	}
+
+	if ( ENV->FirstEndNode != NULL )
+	{
+		_printf("CleanupAll: Fehler: FirstEndNode ist ungleich NULL!!\n");
+	}
+
+	if ( ENV->LastEndNode != NULL )
+	{
+		_printf("CleanupAll: Fehler: LastEndNode ist ungleich NULL!!\n");
+	}
+
+	if ( ENV->FirstDenyListEntry != NULL )
+	{
+		_printf("CleanupAll: Fehler: FirstDenyList ist ungleich NULL!!\n");
+	}
+
+
+	ENV->RootEntry          = NULL;
+	ENV->FirstEndNode       = NULL;
+	ENV->LastEndNode        = NULL;
+	ENV->FirstDenyListEntry = NULL;
+
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_SetTraceTime
+	Conv:   PortNetscan
+	Typ:    function
+	return: O (false) für FEHLER / 1 (true) für OK
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  Überwachungszeit in Sekunden
+	Info:   Diese Funktion setzt die Überwachungszeit eines Hosteintrags in TreeEndNode einer Konfigurationsumgebung.
+*/
+int PortNetscan_SetTraceTime(struct PortNetscanConf * ENV,const unsigned int TRACETIME)
+{
+	// Funktionsvariablen
+	int RC           = 1;
+	unsigned int MAX = MAXTRACETIME;
+	if ( TRACETIME <= MAX )
+		ENV->TraceTime = TRACETIME;
+	else
+	{	
+		_printf("SetTraceTime: Gesetzte Zeit überschreitet Maximum-Definition, Standardwert wird verwendet!");
+		ENV->TraceTime = DEFAULTTRACETIME;
+		RC = 0;
+	} // Ende if ( TRACETIME < MAX )
+
+	MAX = 0;
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_SetCleanInterval
+	Conv:   PortNetscan
+	Typ:    function
+	return: O (false) für FEHLER / 1 (true) für OK
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  Aufräuminterval in Sekunden
+	Info:   Diese Funktion setzt den Aufräuminterval einer Konfigurationsumgebung.
+*/
+int PortNetscan_SetCleanInterval(struct PortNetscanConf * ENV,const unsigned int CLEANINTERVAL)
+{
+	// Funktionsvariablen
+	int RC           = 1;
+	unsigned int MAX = MAXTCLEANINTERVAL;
+	if ( CLEANINTERVAL <= MAX )
+		ENV->CleanInterval = CLEANINTERVAL;
+	else
+	{	
+		_printf("SetCleanInterval: Gesetzte Zeit überschreitet Maximum-Definition, Standardwert wird verwendet!");
+		ENV->CleanInterval = DEFAULTCLEANINTERVAL;
+		RC = 0;
+	} // Ende if ( TRACETIME < MAX )
+
+	MAX = 0;
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_SetPortscanQuota
+	Conv:   PortNetscan
+	Typ:    function
+	return: O (false) für FEHLER / 1 (true) für OK
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  Verhältnis (Port/Dest)
+	Info:   Diese Funktion setzt den Verhältniswert, ab dem ein Portscan erkannt wird, einer Konfigurationsumgebung.
+*/
+int PortNetscan_SetPortscanQuota(struct PortNetscanConf * ENV,const unsigned int PORTSCANQUOTA)
+{
+	// Funktionsvariablen
+	int RC           = 1;
+	unsigned int MAX = MAXPORTSCANQUOTA;
+	if ( PORTSCANQUOTA <= MAX )
+		ENV->PortscanQuota = PORTSCANQUOTA;
+	else
+	{	
+		_printf("SetPortscanQuota: Gesetzter Wert überschreitet Maximum-Definition, Standardwert wird verwendet!");
+		ENV->CleanInterval = DEFAULTPORTSCANQUOTA;
+		RC = 0;
+	} // Ende if ( PORTSCANQUOTA < MAX )
+
+	MAX = 0;
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_SetNetscanQuota
+	Conv:   PortNetscan
+	Typ:    function
+	return: O (false) für FEHLER / 1 (true) für OK
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  Verhältnis (Dest/Port)
+	Info:   Diese Funktion setzt den Verhältniswert, ab dem ein Netscan erkannt wird, einer Konfigurationsumgebung.
+*/
+int PortNetscan_SetNetscanQuota(struct PortNetscanConf * ENV,const unsigned int NETSCANQUOTA)
+{
+	// Funktionsvariablen
+	int RC           = 1;
+	unsigned int MAX = MAXNETSCANQUOTA;
+	if ( NETSCANQUOTA <= MAX )
+		ENV->NetscanQuota = NETSCANQUOTA;
+	else
+	{	
+		_printf("SetNetscanQuota: Gesetzter Wert überschreitet Maximum-Definition, Standardwert wird verwendet!");
+		ENV->CleanInterval = DEFAULTNETSCANQUOTA;
+		RC = 0;
+	} // Ende if ( NETSCANQUOTA < MAX )
+
+	MAX = 0;
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_SetBlockTime
+	Conv:   PortNetscan
+	Typ:    function
+	return: O (false) für FEHLER / 1 (true) für OK
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  Sperrzeit (für einen Eintrag in der DenyList) in Sekunden
+	Info:   Setzt die Sperrzeit (für einen Eintrag in der DenyListe). Hier wird die StartZeit des Eintrags immer als Referenz 
+	        verwendet. Dies bedeutet, dass die Sperrzeit die Sperrzeit nicht verlängert wird, wenn der Rechner in dieser
+	        Sperrzeit zugreift.
+*/
+int PortNetscan_SetBlockTime(struct PortNetscanConf * ENV,const unsigned int BLOCKTIME)
+{
+	// Funktionsvariablen
+	int RC           = 1;
+	unsigned int MAX = MAXBLOCKTIME;
+
+	if ( BLOCKTIME <= MAX )
+		ENV->BlockTime = BLOCKTIME;
+	else
+	{	
+		_printf("SetBlockTime: Gesetzter Wert überschreitet Maximum-Definition, Standardwert wird verwendet!");
+		ENV->BlockTime = DEFAULTBLOCKTIME;
+		RC = 0;
+	} // Ende if ( BLOCKTIME < MAX )
+
+	MAX = 0;
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_SetMaxDenyListCount
+	Conv:   PortNetscan
+	Typ:    function
+	return: O (false) für FEHLER / 1 (true) für OK
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  Anzahl Einträge in DenyList
+	Info:   Setzt die maximale Anzahl an Einträgen in der DenyList. Wenn dieser
+	        später überschritten wird, wird das erste Element aus der Liste entfernt.
+*/
+int PortNetscan_SetMaxDenyListCount(struct PortNetscanConf * ENV,const unsigned int MAXDEFINE)
+{
+	// Funktionsvariablen
+	int RC           = 1;
+	unsigned int MAX = 0;
+	unsigned int MIN = 0;
+
+	MAX = MAXDENYLISTCOUNT;
+	MIN = MINDENYLISTCOUNT;
+	
+	if ( MAXDEFINE <= MAX && MAXDEFINE >= MIN)
+		ENV->MaxDenyListCount = MAXDEFINE;
+	else if ( MAXDEFINE < MAX )
+	{	
+		_printf("SetMaxDenyListCount: Gesetzter Wert überschreitet Maximum-Definition, Systemmax wird verwendet!");
+		ENV->MaxDenyListCount = MAX;
+		RC = 0;
+	} 
+	else
+	{
+		_printf("SetMaxDenyListCount: Gesetzter Wert unterschreitet Minimum-Definition, Systemmin wird verwendet!");
+		ENV->MaxDenyListCount = MIN;
+		RC = 0;
+	} // Ende if ( MAXDEFINE < MAX && MAXDEFINE > MIN )
+
+	MAX = 0;
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_SetNodeCount
+	Conv:   PortNetscan
+	Typ:    function
+	return: O (false) für FEHLER / 1 (true) für OK
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  Anzahl Einträge der Überwachungsliste
+	Info:   Setzt die maximale Anzahl an Einträgen in der Überwachungsliste. Wenn dieser
+	        später überschritten wird, wird das erste Element aus der Liste entfernt.
+*/
+int PortNetscan_SetNodeCount(struct PortNetscanConf * ENV,const unsigned int MAXDEFINE)
+{
+	// Funktionsvariablen
+	int RC           = 1;
+	unsigned int MAX = 0;
+	unsigned int MIN = 0;
+
+	MAX = MAXENDNODECOUNT;
+	MIN = MINENDNODECOUNT;
+	
+	if ( MAXDEFINE <= MAX && MAXDEFINE >= MIN)
+		ENV->MaxEndNodeCount = MAXDEFINE;
+	else if ( MAXDEFINE < MAX )
+	{	
+		_printf("SetEndNodeCount: Gesetzter Wert überschreitet Maximum-Definition, Systemmax wird verwendet!");
+		ENV->MaxEndNodeCount = MAX;
+		RC = 0;
+	} else
+	{
+		_printf("SetEndNodeCount: Gesetzter Wert unterschreitet Minimum-Definition, Systemmin wird verwendet!");
+		ENV->MaxEndNodeCount = MIN;
+		RC = 0;
+	} // Ende if ( MAXDEFINE < MAX && MAXDEFINE > MIN )
+
+	MAX = 0;
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_SetCombinedQuota
+	Conv:   PortNetscan
+	Typ:    function
+	return: O (false) für FEHLER / 1 (true) für OK
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  Quota
+	Info:   Setzt die CombinedQuota für einen überwachten Host, bevor ein CombinedScan erkannt wird. Dieser
+	        wird auf (Anzahl Zielhosts) + (Anzahl Zielports) ermittelt.
+*/
+int PortNetscan_SetCombinedQuota(struct PortNetscanConf * ENV,const unsigned int MAXDEFINE)
+{
+	// Funktionsvariablen
+	int RC           = 1;
+	unsigned int MAX = 0;
+
+	MAX = MAXCOMBINEDQUOTA;
+	
+	if ( MAXDEFINE <= MAX )
+		ENV->CombinedQuota = MAXDEFINE;
+	else
+	{
+		_printf("PortNetscan_SetCombinedQuota: Gesetzter Wert überschreitet Maximum-Definition, Systemmin wird verwendet!");
+		ENV->CombinedQuota = MAX;
+		RC = 0;
+	} // Ende if ( MAXDEFINE < MAX && MAXDEFINE > MIN )
+
+	MAX = 0;
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_AddDenyListEntry
+	Conv:   PortNetscan
+	Typ:    function
+	return: Erstellter DelyList Eintrag
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  
+	Info:   
+*/
+struct DenyList * PortNetscan_AddDenyListEntry(struct PortNetscanConf * ENV,const IpV4Address SRC)
+{
+	// Funktionsvariablen
+	struct DenyList * RC = NULL;
+
+	if ( ENV->FirstDenyListEntry == NULL )
+	{
+		RC = (struct DenyList *)_malloc(sizeof(struct DenyList), GFP_KERNEL);
+		DenyList_Init(ENV,RC);
+		ENV->FirstDenyListEntry = RC;
+		ENV->DenyListCount = 1;
+	}
+	else
+	{
+		RC = ENV->FirstDenyListEntry;
+		/*
+			Prüfung doppelter Einträge kann gesparrt werden, da im
+			normalen fall imm verher geprüft wird, ob der Wert schon
+			vorhanden ist.
+		*/
+		while ( RC->Next != NULL) RC = RC->Next;
+
+		if ( ENV->MaxDenyListCount < ENV->DenyListCount )
+		{
+			/*
+				Liste überschreitet Maximum an Einträgen --> erstes Element
+				wird gelöscht, um Platz zu schaffen
+			*/
+			_printf("PortNetscan_AddDenyListEntry:Maximale Anzahl an DenyList Einträgen erreicht, der älteste Entrag wird gelöscht und der neue hinzugefügt!");
+			PortNetscan_DelDenyListEntry(ENV,ENV->FirstDenyListEntry);
+		}
+		RC->Next = (struct DenyList *)_malloc(sizeof(struct DenyList), GFP_KERNEL);
+		DenyList_Init(ENV,RC->Next);
+		RC->Next->Prior = RC;
+		RC = RC->Next;
+		ENV->DenyListCount++;
+	}
+
+	RC->Src=SRC;
+	RC->StartDenyTime = getunixtime();
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_CheckDenyList
+	Conv:   PortNetscan
+	Typ:    function
+	return: 0 OK / > 0 Rechner ist in Sperrliste oder wurde dort hin verschoeben 
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  Quelladresse
+	Info:   Die Funktion überprüft, ab die angegebene Quelladdresse bereits in der Sperrliste
+	        vorhanden ist.
+*/
+int PortNetscan_CheckDenyList(struct PortNetscanConf * ENV,const IpV4Address SRC)
+{
+	// Funktionsvariablen
+	struct DenyList * TEMPENTRY = NULL;
+	int RC              = 0;
+
+	if ( ENV->FirstDenyListEntry != NULL )
+	{
+		TEMPENTRY = ENV->FirstDenyListEntry;
+		while ( TEMPENTRY != NULL )
+		{
+			if ( TEMPENTRY->Src == SRC ) 
+			{
+				RC = 1;
+				TEMPENTRY->Count++;
+				break;
+			}
+			TEMPENTRY = TEMPENTRY->Next;
+		}
+	}
+
+	TEMPENTRY = NULL;
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_AddTreeEndNode
+	Conv:   PortNetscan
+	Typ:    function
+	return: Erstellte TreeEndNode
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  Quelladresse
+	Par 3:  Zieladresse
+	Par 4:  Zielport
+	Info:   
+*/
+struct TreeEndNode * PortNetscan_AddTreeEndNode(struct PortNetscanConf * ENV,struct TreeNode * LASTTREENODE,IpV4Address SRC , IpV4Address DST, IpV4Port DPT )
+{
+	// Funktionsvariablen
+	struct TreeEndNode * RC = NULL;
+
+	if ( LASTTREENODE != NULL )
+	{
+		if ( LASTTREENODE->Childs != NULL )
+		{
+			RC = (struct TreeEndNode*)LASTTREENODE->Childs;
+			// Erst mal DST
+			// Wenn Fehler dann hier korrigieren
+			if ( RC->EntriesDst == NULL )
+			{
+				// Eintrag in Entries erstellen
+				RC->EntriesDst        = (struct TreeEndNodeEntry *)_malloc(sizeof(struct TreeEndNodeEntry), GFP_KERNEL);
+				TreeEndNodeEntry_Init(ENV,RC->EntriesDst);
+				RC->EntriesDst->Value = DST;
+				RC->CountDst          = 1;	
+			}
+			else
+				if (PortNetscan_AddEndTreeEnty(ENV,RC->EntriesDst,DST)) RC->CountDst++;
+
+
+			// Dann mal DPT
+			// Wenn Fehler dann hier korrigieren
+			if ( RC->EntriesDpt == NULL )
+			{
+				// Eintrag in Entries erstellen
+				RC->EntriesDpt = (struct TreeEndNodeEntry*)_malloc(sizeof(struct TreeEndNodeEntry), GFP_KERNEL);
+				TreeEndNodeEntry_Init(ENV,RC->EntriesDst);
+				RC->EntriesDpt->Value  = DPT;
+				RC->CountDpt           = 1;
+			} // Ende if ( RC->EntriesDpt == NULL )			
+			else
+				if (PortNetscan_AddEndTreeEnty(ENV,RC->EntriesDpt,DPT)) RC->CountDpt++;
+			
+			
+		}
+		else
+		{ 	// Noch nicht vorhanden - neuen Eintrag erstellen
+
+
+			ENV->EndNodeCount++;
+
+			if ( ENV->EndNodeCount > ENV->MaxEndNodeCount ) 
+			{
+				PortNetscan_DelTreeUnuses(ENV,ENV->FirstEndNode->Parent);
+				PortNetscan_DelTreeEndNode(ENV,ENV->FirstEndNode);
+			}
+
+			LASTTREENODE->Childs = (struct TreeEndNode*)_malloc(sizeof(struct TreeEndNode), GFP_KERNEL);
+			TreeEndNode_Init(ENV,LASTTREENODE->Childs);
+			RC = (struct TreeEndNode*)LASTTREENODE->Childs;
+			RC->Count              = 0;
+			RC->Src                = SRC;
+			RC->Parent             = LASTTREENODE;
+			RC->FirstTime          = getunixtime();
+			// Eintrag in Entries erstellen
+			RC->EntriesDst         = (struct TreeEndNodeEntry*)_malloc(sizeof(struct TreeEndNodeEntry), GFP_KERNEL);
+			RC->EntriesDpt         = (struct TreeEndNodeEntry*)_malloc(sizeof(struct TreeEndNodeEntry), GFP_KERNEL);
+			TreeEndNodeEntry_Init(ENV,RC->EntriesDst);
+			TreeEndNodeEntry_Init(ENV,RC->EntriesDpt);
+			RC->EntriesDpt->Value  = DPT;
+			RC->EntriesDst->Value  = DST;
+			RC->CountDpt           = 1;
+			RC->CountDst           = 1;
+			
+			if ( ENV->FirstEndNode == NULL )
+			{			
+				ENV->FirstEndNode = RC;
+				ENV->LastEndNode  = RC;
+			}
+			else
+			{
+				RC->Prior                   = ENV->LastEndNode;
+				ENV->LastEndNode->Next      = RC;
+				ENV->LastEndNode            = RC; 
+			}
+
+		} // Ende if ( LastTreeNode->Childs != NULL )
+		// Standardwerte zum guten Schluss		
+		RC->LastTime = getunixtime();
+		RC->Count++;
+
+	} // Ende if ( LastTreeNode != NULL )
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_AddTreeEndEntry
+	Conv:   PortNetscan
+	Typ:    function
+	return: 0, wenn Wert(Par 3) schon in der Liste / 1 wenn der Wert (Par 3) hinzugefügt wurde.
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  TreeEndNodeEntry
+	Par 3:  Wert, der Hinzugefügt werden soll
+	Info:   
+*/
+int PortNetscan_AddEndTreeEnty(struct PortNetscanConf * ENV,struct TreeEndNodeEntry * ENTRY, const u_int32_t VALUE)
+{
+	int RC                       = 0;
+	int MAXSEARCHLOOPS           = 0;
+	int COUNT                    = 0;
+	struct TreeEndNodeEntry * TEMPENTRY = ENTRY;
+
+	MAXSEARCHLOOPS           = MAXENDNODEENTRY;
+	
+	if ( ENTRY != NULL )
+	{
+		int ENTRYUSE = 0;
+		while ( MAXSEARCHLOOPS > COUNT ) // Sicherheit, falls andere Speicher überschrieben
+		{
+			if ( TEMPENTRY->Value == VALUE ) { ENTRYUSE = 1; break; }
+			if ( TEMPENTRY->Next  == NULL  ) break;
+			TEMPENTRY = TEMPENTRY->Next;
+			COUNT++;
+		} // Ende while (true)
+		if ( ! ENTRYUSE )
+		{
+			RC = 1;
+			TEMPENTRY->Next = (struct TreeEndNodeEntry*)_malloc(sizeof(struct TreeEndNodeEntry), GFP_KERNEL);
+			TreeEndNodeEntry_Init(ENV,TEMPENTRY->Next);
+			TEMPENTRY->Next->Value = VALUE;
+		} // Ende if ( ! ENTRYUSEDST )
+		
+	}
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_Add
+	Conv:   PortNetscan
+	Typ:    function
+	return: void (keine Rückgabewerte)
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  Quelladresse
+	Par 3:  Zieladresse
+	Par 4:  Zielport
+	Info:   Sollte durch PortNetscan_Check aufgerufen werden, nachdem alle alten Einträge
+	        aus den Listen (Sperrliste/Überwachungsliste) entfernt wurden.
+*/
+int PortNetscan_Add(struct PortNetscanConf * ENV,IpV4Address SRC, IpV4Address DST, IpV4Port DPT)
+{
+	// Funtionsvariablen
+	int RC = 0;
+	struct TreeNode * WORKTREE = NULL;
+	struct TreeEndNode * WORKENTRY = NULL;
+
+	
+	u_int32_t * IPPARTS  = NULL;
+	IPPARTS = (u_int32_t*)_malloc( sizeof(u_int32_t) * ENV->TreeDepth, GFP_KERNEL);
+
+ 	PortNetscan_GetIpV4Parts(ENV,SRC,IPPARTS);
+
+	WORKTREE = ENV->RootEntry;
+
+	WORKTREE  = PortNetscan_AddTree(ENV,WORKTREE,IPPARTS,0);
+	WORKENTRY = PortNetscan_AddTreeEndNode(ENV,WORKTREE,SRC,DST,DPT);
+	
+	if ( (WORKENTRY->CountDpt/WORKENTRY->CountDst) >= ENV->PortscanQuota ||
+	     (WORKENTRY->CountDst/WORKENTRY->CountDpt) >= ENV->NetscanQuota ||   
+	     (WORKENTRY->CountDst+WORKENTRY->CountDpt) >= ENV->CombinedQuota)
+	{
+		struct DenyList * TEMPDENY = PortNetscan_AddDenyListEntry(ENV,WORKENTRY->Src);
+		if ( TEMPDENY != NULL ) // Nur zur Sicherheit
+		{
+			TEMPDENY->Count++;
+			if      ( (WORKENTRY->CountDpt/WORKENTRY->CountDst) >= ENV->PortscanQuota ) TEMPDENY->Reason = REASONPORTSCAN;
+			else if ( (WORKENTRY->CountDst/WORKENTRY->CountDpt) >= ENV->NetscanQuota  ) TEMPDENY->Reason = REASONNETSCAN;
+			else if ( (WORKENTRY->CountDst+WORKENTRY->CountDpt) >= ENV->CombinedQuota ) TEMPDENY->Reason = REASONCOMPINED;
+			else TEMPDENY->Reason = REASONUNKNOWN;
+		}
+
+		PortNetscan_DelTreeUnuses(ENV,WORKENTRY->Parent);
+		PortNetscan_DelTreeEndNode(ENV,WORKENTRY);
+		TEMPDENY = NULL;
+		RC = 4;
+	}
+
+
+	WORKENTRY = NULL;
+	WORKTREE  = NULL;
+
+	_free(IPPARTS);
+	IPPARTS = NULL;
+	
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_AddTree
+	Conv:   PortNetscan
+	Typ:    function
+	return: Erstellter Baumknoten
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  Parent
+	Par 3:  Vektor Teile Quelladresse
+	Par 4:  Aktuell erreichte Tiefe
+	Info:   Hinweis: Diese Funktion wird rekusiv aufgerufen!
+*/
+struct TreeNode * PortNetscan_AddTree(struct PortNetscanConf * ENV,struct TreeNode * TREENODE,const u_int32_t * IPPARTS,const unsigned short DEPTH)
+{
+	struct TreeNode * RC = TREENODE;
+	int       USED = 0;
+	// Prüfen, ob eine Struktur schon initialisiert
+	if ( ENV->RootEntry == NULL )
+	{
+		RC = (struct TreeNode*)_malloc(sizeof(struct TreeNode), GFP_KERNEL);
+		ENV->TreeCount++;
+		TreeNode_Init(ENV,RC);
+		ENV->RootEntry = RC;
+		RC->TreeValue = IPPARTS[DEPTH];
+		if ( DEPTH < (ENV->TreeDepth-1) )
+		{
+			RC->Childs = (struct TreeNode*)_malloc(sizeof(struct TreeNode), GFP_KERNEL);
+			ENV->TreeCount++;
+			TreeNode_Init(ENV,(struct TreeNode*)RC->Childs);
+			((struct TreeNode*)RC->Childs)->Parent = RC;
+			((struct TreeNode*)RC->Childs)->TreeValue = IPPARTS[DEPTH+1];
+			RC=PortNetscan_AddTree(ENV,(struct TreeNode*)RC->Childs,IPPARTS,DEPTH+1);
+		}
+	} // Ende if ( FirstEntry == NULL )
+	else
+	{
+		while (1)
+		{
+			if ( RC->TreeValue == IPPARTS[DEPTH] ) { USED = 1; break; }
+			if ( RC->Next == NULL ) break;
+			else RC=RC->Next;
+		} // Ende while (true)
+
+		if ( USED == 0 )
+		{
+			RC->Next = (struct TreeNode*)_malloc(sizeof(struct TreeNode), GFP_KERNEL);
+			ENV->TreeCount++;
+			TreeNode_Init(ENV,RC->Next);
+			RC->Next->Prior = RC;
+			RC = RC->Next;
+			RC->TreeValue = IPPARTS[DEPTH];
+			
+			if ( DEPTH < (ENV->TreeDepth-1) )
+			{
+				RC->Childs = (struct TreeNode*)_malloc(sizeof(struct TreeNode), GFP_KERNEL);
+				ENV->TreeCount++;
+				TreeNode_Init(ENV,(struct TreeNode*)RC->Childs);
+				((struct TreeNode*)RC->Childs)->Parent = RC;
+				((struct TreeNode*)RC->Childs)->TreeValue = IPPARTS[DEPTH+1]; 
+				RC = PortNetscan_AddTree(ENV,(struct TreeNode*)RC->Childs,IPPARTS,DEPTH+1);
+			} // Ende if ( DEPTH < TreeDepth-1)
+		}
+		else
+		{
+			if ( DEPTH < (ENV->TreeDepth-1) )
+			{
+				if ( RC->Childs == NULL )
+				{
+					RC->Childs = (struct TreeNode*)_malloc(sizeof(struct TreeNode), GFP_KERNEL);
+					ENV->TreeCount++;
+					TreeNode_Init(ENV,(struct TreeNode*)RC->Childs);
+					((struct TreeNode*)RC->Childs)->Parent = RC;
+					((struct TreeNode*)RC->Childs)->TreeValue = IPPARTS[DEPTH+1]; 
+				}
+				RC = PortNetscan_AddTree(ENV,(struct TreeNode*)RC->Childs,IPPARTS,DEPTH+1);
+			} // Ende if ( DEPTH < TreeDepth-1)
+			
+			
+		} // Ende if ( USED )
+
+	} // Ende if ( RC == NULL )
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_DelDenyListEntry
+	Conv:   PortNetscan
+	Typ:    function
+	return: 0 (False) im Fehlerfall/ 1 (True) OK
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  Zeiger auf zu löschenden Sperreintrags
+	Info:   Löscht einen Eintrag aus der Sperrliste
+*/
+int PortNetscan_DelDenyListEntry(struct PortNetscanConf * ENV,struct DenyList * ENTRY)
+{
+	// Funktionsvariablen
+	int RC = 1;
+	
+	if ( (ENTRY != NULL) && (ENV->FirstDenyListEntry != NULL) )
+	{
+		if ( (ENTRY->Next != NULL) && (ENTRY->Prior != NULL) )
+		{
+			ENTRY->Next->Prior = ENTRY->Prior;
+			ENTRY->Prior->Next = ENTRY->Next;
+			
+		}
+		else if ( (ENTRY->Next != NULL) && (ENTRY->Prior == NULL) )
+		{
+			ENV->FirstDenyListEntry = ENTRY->Next;
+			ENTRY->Next->Prior = NULL;
+		}
+		else if ( (ENTRY->Next == NULL) && (ENTRY->Prior != NULL) )
+		{
+			ENTRY->Prior->Next = NULL;
+		}
+		else
+			ENV->FirstDenyListEntry = NULL;
+
+		DenyList_Flush(ENV,ENTRY);
+		_free(ENTRY);
+
+		ENV->DenyListCount--;
+		ENTRY = NULL;
+	}
+	else
+		RC = 0;
+
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_DelTreeEndNode
+	Conv:   PortNetscan
+	Typ:    function
+	return: 0 (False) im Fehlerfall / 1 (True) OK
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  Zeiger auf zu löschenden Überwachungeintrag
+	Info:   
+*/
+int PortNetscan_DelTreeEndNode ( struct PortNetscanConf * ENV,struct TreeEndNode * ENTRY )
+{
+	/*
+		Funktion: nicht verwendete Element aus EndKnoten Kette entfernen
+	*/
+	
+	// Funktionsvariablen
+	int RC = 1;
+	struct TreeEndNodeEntry * TEMPENDNODEENTRY = NULL;
+
+	if ( ENTRY != NULL )
+	{
+		struct TreeNode         * TREENODE      = ENTRY->Parent;
+		//struct TreeEndNodeEntry * TREENODEENTRY = NULL;	
+
+
+		// Prüfen auf lineare Kette EndNodes
+		if ( (ENTRY->Next  == NULL) && (ENTRY->Prior == NULL) )
+		{
+			ENV->LastEndNode  = NULL;
+			ENV->FirstEndNode = NULL;
+		}
+		else if ( ENTRY->Next  == NULL ) 
+		{
+			ENV->LastEndNode  = ENTRY->Prior;
+			ENTRY->Prior->Next = NULL;
+		}
+		else if ( ENTRY->Prior == NULL ) 
+		{
+			ENV->FirstEndNode = ENTRY->Next;
+			ENTRY->Next->Prior = NULL;
+		}
+		else
+		{
+			ENTRY->Next->Prior = ENTRY->Prior;
+			ENTRY->Prior->Next = ENTRY->Next;
+		}
+		
+		TEMPENDNODEENTRY = ENTRY->EntriesDpt;
+		while ( TEMPENDNODEENTRY != NULL )
+		{
+			struct TreeEndNodeEntry * NEXT = TEMPENDNODEENTRY->Next;
+			TreeEndNodeEntry_Flush(ENV,TEMPENDNODEENTRY);
+			_free(TEMPENDNODEENTRY); 
+			TEMPENDNODEENTRY=NULL;
+			TEMPENDNODEENTRY = NEXT;
+		}
+		ENTRY->EntriesDpt = NULL;
+
+		TEMPENDNODEENTRY = ENTRY->EntriesDst;
+		while ( TEMPENDNODEENTRY != NULL )
+		{
+			struct TreeEndNodeEntry * NEXT = TEMPENDNODEENTRY->Next;
+			TreeEndNodeEntry_Flush(ENV,TEMPENDNODEENTRY);
+			_free(TEMPENDNODEENTRY); 
+			TEMPENDNODEENTRY=NULL;
+			TEMPENDNODEENTRY = NEXT;
+		}
+		ENTRY->EntriesDst = NULL;
+		
+		TreeEndNode_Flush(ENV,ENTRY);
+		_free(ENTRY);
+		ENTRY = NULL;
+
+		ENV->EndNodeCount--;
+		TREENODE = NULL;
+	}
+
+	TEMPENDNODEENTRY = NULL;
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   PortNetscan_DelTreeUnuses
+	Conv:   PortNetscan
+	Typ:    function
+	return: 0 (False) im Fehlerfall / 1 (True) OK
+	Par 1:  PortNetscanConf (Konfigurationsumgebung)
+	Par 2:  Aktuell betreffender Baumknoten
+	Info:   Hinweis: Funktion wird rekusiv aufgerufen!
+	        Diese Funktion löscht nach einem Löschen eines Überwachungseintrag die
+	        die nicht mehr benötigten Einträge aus dem Suchbaum.
+*/
+int PortNetscan_DelTreeUnuses(struct PortNetscanConf * ENV,struct TreeNode *TREENODE)
+{
+	/*
+		Funktion: Nicht verwendete Elemente im Baum löschen.
+		Hinweis: rekusiver Aufruf zum Löschen der Elemente im Baum. Hierbei wird die
+		Tiefste (die bedeutet Ende, nicht das ROOT-Element) beim jeweiligen Aufruf verwendet.
+	*/
+	// Funktionsvariablen
+	int RC = 1;
+	if ( (TREENODE == NULL) || (ENV->RootEntry == NULL) )
+	{
+		RC = 0;
+		/*
+		static struct 	In diesem Fall wurde der Baum nicht sauber gelöscht - irgendeine Zeiger
+			auf ein abhängiges Element wurde versehendlich gelöscht oder 
+			auf NULL gesetzt
+		*/
+		_printf("PortNetscan_DelTreeUnuses:Fehler beim Aufräumen des Baumes");
+	}
+	else
+	{
+		if ( (TREENODE->Next == NULL) && (TREENODE->Prior == NULL) )
+		{ 	
+			/*
+				Dies ist der einzige Eintrag in dieser Baumebene. Dies bedeutet, dass
+				auch das Elternelement gelöscht werden kann - dieses muss aber ebenfalls ge
+			*/ 
+			if (TREENODE->Parent != NULL )
+			{ // Noch nicht die oberste Baumebene erreicht
+				PortNetscan_DelTreeUnuses(ENV,TREENODE->Parent);
+			}
+			else
+			{
+				ENV->RootEntry = NULL;
+			} // Ende if (TREENODE->Parent != NULL )
+
+			TreeNode_Flush(ENV,TREENODE);
+			_free(TREENODE);
+			ENV->TreeCount--;
+		}
+		else
+		{ 	/*
+				In diesem Fall sind noch andere Elemente auf dieser Ebene vorhanden. Dies
+				bedeutet, dass das Löschen vom Parent-Element nicht versucht wird. Das Element selbst
+				wird aber gelöscht.
+				
+				Zur Fehlerdiagnose wurden die Schritte sehr ausführlich ausprogrammiert. Nach Tests an
+				der Fachhochschule ist der Geschwindigkeitsverlust aber nicht messbar!
+			*/
+			if ( TREENODE->Next != NULL && TREENODE->Prior != NULL )
+			{
+				/*
+					Vorgänger- mit Nachfolgerelement sind vorhanden und 
+					werden miteinander verknüpft
+				*/
+				TREENODE->Next->Prior = TREENODE->Prior;
+				TREENODE->Prior->Next = TREENODE->Next;
+			}
+			else if ( TREENODE->Prior != NULL && TREENODE->Next == NULL )
+			{
+				/*
+					Ein Vorgängerelement, aber kein Nachfolgerelement vorhanden. Das
+					Nachfolgerelement des Vorgängerelements wird auf NULL gesetzt.
+				*/
+				TREENODE->Prior->Next = NULL;
+			}
+			else if ( TREENODE->Prior == NULL && TREENODE->Next != NULL )
+			{
+				/*
+					Kein Vorgängerelement, aber ein Nachfolgerelement vorhanden. Das
+					Vorgängerelement des Nachfolgerelements wird auf NULL gesetzt.
+				*/
+				TREENODE->Next->Prior = NULL;
+				if ( TREENODE->Parent == NULL )
+				{
+					/*
+						Wenn in der obersten Baumebene (RootEbene) muss der 
+						Zeiger für das Erste Element auf das Nachfolgerelement gesetzt werden.
+					*/
+					ENV->RootEntry = TREENODE->Next;
+					TREENODE->Next->Parent = NULL;
+				}
+				else
+				{
+					TREENODE->Next->Parent = TREENODE->Parent;
+					TREENODE->Parent->Childs = TREENODE->Next;
+				}
+
+			}
+ 			TreeNode_Flush(ENV,TREENODE);
+			_free(TREENODE);
+			ENV->TreeCount--;
+		} // Ende if ( TREENODE->Next == NULL && TREENODE->Prior == NULL )
+	}
+	
+	// Zurücksetzen verwendeter Funktionsvariablen
+	TREENODE = NULL;
+
+	return RC;
+}
+
+/*
+#######################################################################################################################
+Globaler Bereich - Funktionen außerhalb der virt. Namensräume
+#######################################################################################################################
+*/
+
+static struct IptGlobalConfStruct IptGlobalConf;
+
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   IptGetPortNetscanEnv
+	Conv:   Global
+	Typ:    function
+	return: void (keine Rückgabewerte)
+	Par 1:  Übergebener INFO-Strukt von IpTables
+	Info:   
+*/
+
+static struct PortNetscanEnv * IptGetPortNetscanEnv (struct ipt_PORTNETSCAN_info INFO)
+{
+	// Funktionsvariablen
+	struct PortNetscanEnv * RC = NULL;
+	int USE = 0;
+
+	if ( IptGlobalConf.FirstPortNetscan == NULL )
+	{
+		RC = (struct PortNetscanEnv*)_malloc(sizeof(struct PortNetscanEnv),GFP_KERNEL);
+		IptGlobalConf.FirstPortNetscan = RC;
+		RC->Next                   = NULL;
+		RC->Prior                  = NULL;
+		
+		PortNetscan_Init(&RC->ConfEntries);
+		RC->tree_depth             = INFO.tree_depth;
+        	RC->trace_time             = INFO.trace_time;
+        	RC->clean_interval         = INFO.clean_interval;
+		RC->port_scan_quota        = INFO.port_scan_quota;
+        	RC->net_scan_quota         = INFO.net_scan_quota;
+        	RC->max_deny_entries       = INFO.max_deny_entries;
+        	RC->max_trace_entries      = INFO.max_trace_entries;
+        	RC->block_time             = INFO.block_time;
+		RC->combined_quota         = INFO.combined_quota;
+		PortNetscan_SetTreeDepth        (&RC->ConfEntries,INFO.tree_depth);
+		PortNetscan_SetTraceTime        (&RC->ConfEntries,INFO.trace_time);
+		PortNetscan_SetCleanInterval    (&RC->ConfEntries,INFO.clean_interval);
+		PortNetscan_SetPortscanQuota    (&RC->ConfEntries,INFO.port_scan_quota);
+		PortNetscan_SetNetscanQuota     (&RC->ConfEntries,INFO.net_scan_quota);
+		PortNetscan_SetMaxDenyListCount (&RC->ConfEntries,INFO.max_deny_entries);
+		PortNetscan_SetNodeCount        (&RC->ConfEntries,INFO.max_trace_entries);
+		PortNetscan_SetBlockTime        (&RC->ConfEntries,INFO.block_time);
+		PortNetscan_SetCombinedQuota    (&RC->ConfEntries,INFO.combined_quota);
+		IptGlobalConf.Conf_Count++;
+	}
+	else
+	{
+		RC = IptGlobalConf.FirstPortNetscan;
+		while (1)
+		{
+			if ( RC->tree_depth         == INFO.tree_depth         &&
+                             RC->trace_time         == INFO.trace_time         &&
+                             RC->clean_interval     == INFO.clean_interval     &&
+                             RC->port_scan_quota    == INFO.port_scan_quota    &&
+                             RC->net_scan_quota     == INFO.net_scan_quota     &&
+                             RC->max_deny_entries   == INFO.max_deny_entries   &&
+                             RC->max_trace_entries  == INFO.max_trace_entries  &&
+                             RC->block_time         == INFO.block_time         &&
+                             RC->combined_quota     == INFO.combined_quota)
+			{
+				USE = 1;
+				break;
+			}
+			if ( RC->Next == NULL ) break;
+			RC = RC->Next;
+		}
+		if ( USE != 1 )
+		{
+			RC->Next                    = (struct PortNetscanEnv*)_malloc(sizeof(struct PortNetscanEnv),GFP_KERNEL);
+			RC->Next->Prior             = RC;
+			RC                          = RC->Next;
+			RC->Next                    = NULL;
+		
+			PortNetscan_Init(&RC->ConfEntries);
+			RC->tree_depth              = INFO.tree_depth;
+		 	RC->trace_time              = INFO.trace_time;
+		 	RC->clean_interval          = INFO.clean_interval;
+			RC->port_scan_quota         = INFO.port_scan_quota;
+			RC->net_scan_quota          = INFO.net_scan_quota;
+			RC->max_deny_entries        = INFO.max_deny_entries;
+			RC->max_trace_entries       = INFO.max_trace_entries;
+			RC->block_time              = INFO.block_time;
+			RC->combined_quota          = INFO.combined_quota;
+			PortNetscan_SetTreeDepth        (&RC->ConfEntries,INFO.tree_depth);
+			PortNetscan_SetTraceTime        (&RC->ConfEntries,INFO.trace_time);
+			PortNetscan_SetCleanInterval    (&RC->ConfEntries,INFO.clean_interval);
+			PortNetscan_SetPortscanQuota    (&RC->ConfEntries,INFO.port_scan_quota);
+			PortNetscan_SetNetscanQuota     (&RC->ConfEntries,INFO.net_scan_quota);
+			PortNetscan_SetMaxDenyListCount (&RC->ConfEntries,INFO.max_deny_entries);
+			PortNetscan_SetNodeCount        (&RC->ConfEntries,INFO.max_trace_entries);
+			PortNetscan_SetBlockTime        (&RC->ConfEntries,INFO.block_time);
+			PortNetscan_SetCombinedQuota    (&RC->ConfEntries,INFO.combined_quota);
+			IptGlobalConf.Conf_Count++;
+		}
+	}
+	
+
+	USE = 0;
+	RC->LastUse = getunixtime();
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   IptCleanupAll
+	Conv:   Global
+	Typ:    function
+	return: void (keine Rückgabewerte)
+	Par 1:  Alle Löschen
+	Info:   Globale Aufräumfunktion, bei über Par 1 = 1 werden alle Konfiguration mit allen angehängten Listen
+	        gelöscht. Wenn übergebener Par 1 = 0 ist, werden nur die Normalen Aufräumaktionen in den Einzelnen
+	        Konfigurationsumgebungen gelöscht.
+*/
+static void IptCleanupAll(int FORCE)
+{
+	// Funktionsvariablen
+	struct PortNetscanEnv * TEMP = IptGlobalConf.FirstPortNetscan;
+	struct PortNetscanEnv * NEXT = NULL;
+
+	if ( IptGlobalConf.FirstPortNetscan != NULL )
+	{
+		while ( TEMP != NULL )
+		{
+			NEXT = TEMP->Next;
+			if ( FORCE == 1 )
+				PortNetscan_Flush(&TEMP->ConfEntries);
+			else
+				PortNetscan_Cleanup(&TEMP->ConfEntries);
+
+			if ( (TEMP->LastUse + GLOBALCLEANUP) > getunixtime() && TEMP->ConfEntries.RootEntry == NULL && TEMP->ConfEntries.FirstEndNode == NULL && TEMP->ConfEntries.FirstDenyListEntry == NULL )
+			{
+				if ( TEMP->Prior == NULL && TEMP->Next == NULL )
+				{
+					IptGlobalConf.FirstPortNetscan = NULL;
+				}
+				else if ( TEMP->Prior == NULL && TEMP->Next != NULL )
+				{
+					TEMP->Next->Prior = NULL;
+					IptGlobalConf.FirstPortNetscan = TEMP->Next;
+				}
+				else if ( TEMP->Prior != NULL && TEMP->Next == NULL )
+				{
+					TEMP->Prior->Next = NULL;
+				}
+				else
+				{
+					TEMP->Next->Prior = TEMP->Prior;
+					TEMP->Prior->Next = TEMP->Next;
+				} // Ende if ( TEMP->Prior == NULL && TEMP->Next == NULL )
+				
+				_free(TEMP);
+				IptGlobalConf.Conf_Count--;
+			} // Ende if if ( TEMP->ConfEntries.RootEntry == NULL && TEMP->ConfEntries.FirstEndNode == NULL && TEMP->ConfEntries.FirstDenyListEntry == NULL )
+			TEMP = NEXT;
+
+		} // Ende while ( TEMP != NULL )
+
+	} // Ende if ( TEMP != NULL )
+
+	IptGlobalConf.LastCleanup = getunixtime();	
+
+	TEMP = NULL;
+	NEXT = NULL;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   IptCheckPacket
+	Conv:   Global
+	Typ:    function
+	return: int (> 0 weißt IpTables an, das Packet hat die Regel erfüllt)
+	Par 1:  Übergebener INFO-Strukt von IpTables
+	Par 2:  Quelladresse
+	Par 3:  Zieladresse
+	Par 4:  Zielport
+	Info:   Globale Aufräumfunktion, bei über Par 1 = 1 werden alle Konfiguration mit allen angehängten Listen
+	        gelöscht. Wenn übergebener Par 1 = 0 ist, werden nur die Normalen Aufräumaktionen in den Einzelnen
+	        Konfigurationsumgebungen gelöscht.
+*/
+static int IptCheckPacket(struct ipt_PORTNETSCAN_info INFO,IpV4Address SRC, IpV4Address DST, IpV4Port DPT)
+{
+	// Funktionsvariablen
+	int RC = 0;
+	struct PortNetscanEnv * ENV = NULL;
+
+	ENV = IptGetPortNetscanEnv(INFO);
+
+	RC = PortNetscan_Check(&ENV->ConfEntries,SRC,DST,DPT,INFO.check_deny_entries);
+
+	return RC;
+}
+
+// Ab hier Kernel
+
+//-------------------------------------------------------------------------------------------------------------------
+
+#ifdef __KERNEL__
+/*
+######################################################################################################################
+#### KernelFunktionen ################################################################################################
+######################################################################################################################
+*/
+
+// Standard Funktionen für IpTables
+
+static spinlock_t PORTNETSCAN_SPINLOCK = SPIN_LOCK_UNLOCKED;
+
+// IpTables: Registrierte Match-Funktion
+static int IptMatchEntry (
+	const struct sk_buff * SBK,
+	const struct net_device * INDEV,
+	const struct net_device * OUTDEV,
+	const struct xt_match *MATCH,
+	const void * MATCHINFO,
+	int OFFSET,
+	unsigned int PROTOOF,
+	int * HOTDROP)
+{
+	// Funktionsvariablen
+	int RC = 0;
+	struct iphdr * IP_HEADER = NULL;
+	struct tcphdr * TCP_UDP_HEADER = NULL;
+	const struct ipt_PORTNETSCAN_info * INFO;
+	u_int16_t DPT = 0;
+
+	INFO = MATCHINFO;
+
+	IP_HEADER = SBK->nh.iph;
+	/* Sanity check */
+        //if (ntohs(IP_HEADER->frag_off) & IP_OFFSET) 
+	//{
+	//	DEBUGP("PSD: sanity check failed\n");
+ 	//	return 0;
+	//}
+
+	if ( IP_HEADER->protocol == IPPROTO_TCP || IP_HEADER->protocol == IPPROTO_UDP )
+	{
+		TCP_UDP_HEADER = (struct tcphdr*)((u_int32_t *)IP_HEADER + IP_HEADER->ihl);
+		// its dirty
+		DPT = TCP_UDP_HEADER->dest;
+		// Object Sperren
+		spin_lock(&PORTNETSCAN_SPINLOCK);
+		if ( IptCheckPacket(*INFO,IP_HEADER->saddr,IP_HEADER->daddr,DPT) != 0 ) RC =1;
+	
+		// Object entsperren
+		spin_unlock(&PORTNETSCAN_SPINLOCK);
+	}
+	return RC;
+}
+/*
+######################################################################################################################
+#### IpTablesInitStruct ##############################################################################################
+######################################################################################################################
+*/
+static int IptCheckEntry (
+	const char * TABLENAME, 
+	const void * INF,
+	const struct xt_match *MATCH,
+	void * MATCHINFO, 
+	unsigned int MATCHSIZE, 
+	unsigned int HOOKMASK )
+{
+	// Funktionsvariablen
+	int RC = 1; // 1 = OK!!!
+
+	
+	
+	return RC;
+}
+
+
+// IpTables Init Struct
+static struct ipt_match ipt_portnetscan =
+{
+	.name          = "PORTNETSCAN",
+	.match         = IptMatchEntry,
+	.matchsize      = sizeof(struct ipt_PORTNETSCAN_info),
+	.proto          = IPPROTO_IP,
+	.checkentry    = IptCheckEntry,
+	.destroy       = NULL,
+	.me            = THIS_MODULE
+};
+/*
+######################################################################################################################
+#### End: IpTablesInitStruct #########################################################################################
+######################################################################################################################
+*/
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   Kernel_CreateProcmemPufferAddEntry
+	Conv:   Global/Kernel
+	Typ:    function
+	return: Anzahl der gespeicherten Text-Zeichen in der verketteten Liste
+	Par 1:  String, der in der Kette engehängt werden soll
+	Info:   Hinzufügen eines Elements zur Kernelausgabeliste, wenn eine "read_proc" Funktion
+	        Aufgerufen wurd
+*/
+int Kernel_CreateProcmemPufferAddEntry(char * LINE)
+{
+	int RC = 0;
+
+	if (IptGlobalConf.FirstOutLine == NULL )
+	{
+		/*
+			Verkettete Liste zur Kernelausgabe ist noch nicht vorhanden. Ersten Element wird 
+			im Speicher allokiert und die beiden LeseElemente werden auf den Sselben Speicherplatz verwiesen.
+		*/
+		IptGlobalConf.FirstOutLine     = (struct KernelOutLinePuffer*)_malloc(sizeof(struct KernelOutLinePuffer), GFP_KERNEL);
+		IptGlobalConf.LastAddOutLine   = IptGlobalConf.FirstOutLine;
+		IptGlobalConf.LastPrintOutLine = IptGlobalConf.FirstOutLine;
+		IptGlobalConf.FailBuffer       = 0;
+	}
+	else
+	{
+		/*
+			Es sind schon Elemente in der Kernelausgabe vorhanden. In diesem Fall muss ein Element
+			angehängt werden...
+		*/
+		IptGlobalConf.LastAddOutLine->Next = (struct KernelOutLinePuffer*)_malloc(sizeof(struct KernelOutLinePuffer), GFP_KERNEL);
+		IptGlobalConf.LastAddOutLine       = IptGlobalConf.LastAddOutLine->Next;
+	}
+
+	if ( IptGlobalConf.LastAddOutLine != NULL )
+	{
+		/*
+			Wenn alles glatt gegangen ist, sollte dieses Element nicht NULL sein. Die Daten (Strings) können also in die
+			Struct - Variable Line  geschrieben werden.
+		*/
+		RC = snprintf(IptGlobalConf.LastAddOutLine->Line,KERNELLINEMAX,"%s",LINE);
+		IptGlobalConf.LastAddOutLine->Next = NULL;
+	}
+
+	return RC;
+	
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   Kernel_CreateProcmemPuffer
+	Conv:   Global/Kernel
+	Typ:    function
+	return: Anzahl der Auszugebenen Zeichen
+	Par X:  void (keine)
+	Info:   Daten in eine verkettete Liste (Kernelausgabeliste) kopieren. Für
+	        jede Zeite wird die Funktion reateProcmemPufferAddEntry(String) aufgerufen, die
+	        wiederum das Element an die Liste hängt.
+*/
+int Kernel_CreateProcmemPuffer(void)
+{
+	// Functionsvariablen
+	struct PortNetscanEnv * TEMP = IptGlobalConf.FirstPortNetscan;
+	unsigned int COUNTER         = 0;
+	u_int32_t * IPPARTS          = (u_int32_t*)_malloc( sizeof(u_int32_t) * 4, GFP_KERNEL);
+	unsigned short PARTSIZE      = 8; /* 32/4* */
+	unsigned int TEXTLEN         = 0;
+	char STRINGBUFFER[KERNELLINEMAX];
+	
+
+	if (IptGlobalConf.FirstOutLine == NULL )
+	{
+
+		spin_lock(&PORTNETSCAN_SPINLOCK);
+
+		snprintf(STRINGBUFFER,KERNELLINEMAX-1,"# IpTables PORTNETSCAN MODUL\n# --------------------------\n#\n");
+		TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+		snprintf(STRINGBUFFER,KERNELLINEMAX-1,"G\tCount_Global_Conf: %d\n",IptGlobalConf.Conf_Count);
+		TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+		snprintf(STRINGBUFFER,KERNELLINEMAX-1,"U\tUpdating_Time(Unix): %u\n#\n",(unsigned int)getunixtime());	
+		TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+
+		snprintf(STRINGBUFFER,KERNELLINEMAX-1,"J\tUpdating_Time(jiffies): %u\n",(unsigned int)jiffies);	
+		TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+		snprintf(STRINGBUFFER,KERNELLINEMAX-1,"C\tNext_Cleanup_Time(jiffies): %u\n#\n",(unsigned int)Kernel_CleanupTimer.expires);	
+		TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+
+		snprintf(STRINGBUFFER,KERNELLINEMAX-1,"# Conf_Entries\n# ------------\n#\n");
+		TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+		snprintf(STRINGBUFFER,KERNELLINEMAX-1  ,"#\tconfn/tree-depth/trace-time/clean-interval/port-scan-quota/net-scan-quota/combined-quota/max-deny-entries/max-trace-entries/block-time/tree-count/endnode-count/denylist-count\n");
+		TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+
+		if ( TEMP != NULL )
+		{
+			COUNTER=0;
+			while ( TEMP != NULL )
+			{
+				snprintf(STRINGBUFFER,KERNELLINEMAX-1,"L\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
+						COUNTER,TEMP->tree_depth,TEMP->trace_time,TEMP->clean_interval,TEMP->port_scan_quota,
+						TEMP->net_scan_quota,TEMP->combined_quota,TEMP->max_deny_entries,TEMP->max_trace_entries,TEMP->block_time,
+						TEMP->ConfEntries.TreeCount,TEMP->ConfEntries.EndNodeCount,TEMP->ConfEntries.DenyListCount);
+				TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+		
+				TEMP = TEMP->Next;
+				COUNTER++;
+			} // Ende while ( TEMP != NULL )	
+
+			TEMP = IptGlobalConf.FirstPortNetscan;
+
+			snprintf(STRINGBUFFER,KERNELLINEMAX-1,"#\n# Deny_Entries\n# ------------\n#\n");
+			TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+			snprintf(STRINGBUFFER,KERNELLINEMAX-1,"#\tconfn/ipaddress/starttime/endtime/count/reason\n");
+			TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+			COUNTER=0;
+			while ( TEMP != NULL )
+			{
+				struct DenyList * TEMPDENYENTRY = TEMP->ConfEntries.FirstDenyListEntry;
+				unsigned short I                = 0;
+
+				if ( TEMPDENYENTRY != NULL  )
+				{
+					while ( TEMPDENYENTRY != NULL )
+					{
+						for ( I=0; I < 4; I++) 
+						{
+							IPPARTS[I] = (((unsigned int)powpos((unsigned short)2,(unsigned short)PARTSIZE))-1) & (TEMPDENYENTRY->Src >> (4-I-1)*PARTSIZE);
+						}
+
+						snprintf(STRINGBUFFER,KERNELLINEMAX-1,"D\t%d\t%d.%d.%d.%d\t%u\t%u\t%u\t",COUNTER,IPPARTS[3],IPPARTS[2],IPPARTS[1],IPPARTS[0],
+								(unsigned int)TEMPDENYENTRY->StartDenyTime,
+								(unsigned int)TEMPDENYENTRY->StartDenyTime+TEMP->ConfEntries.BlockTime,
+								(unsigned int)TEMPDENYENTRY->Count);
+						TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+						if      ( TEMPDENYENTRY->Reason == REASONPORTSCAN ) snprintf(STRINGBUFFER,KERNELLINEMAX-1,"portscan_detected\n");
+						else if ( TEMPDENYENTRY->Reason == REASONNETSCAN  ) snprintf(STRINGBUFFER,KERNELLINEMAX-1,"netscan_detected\n");
+						else if ( TEMPDENYENTRY->Reason == REASONCOMPINED ) snprintf(STRINGBUFFER,KERNELLINEMAX-1,"netscan_detected\n");
+						else snprintf(STRINGBUFFER,KERNELLINEMAX-1,"unknown\n");
+						TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+						TEMPDENYENTRY = TEMPDENYENTRY->Next;
+					}
+				}
+				TEMP = TEMP->Next;
+				TEMPDENYENTRY = NULL;
+				COUNTER++;
+			}
+
+			TEMP = IptGlobalConf.FirstPortNetscan;
+
+			snprintf(STRINGBUFFER,KERNELLINEMAX-1,"#\n# Trace_Entries\n# -------------\n#\n");
+			TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+			snprintf(STRINGBUFFER,KERNELLINEMAX-1,"#\tconfn/ipaddress/firsttime/lasttime/count/countdst/countdpt\n");
+			TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+			COUNTER=0;
+			while ( TEMP != NULL )
+			{
+				struct TreeEndNode * TEMPENDNODEENTRY = TEMP->ConfEntries.FirstEndNode;
+				unsigned short I                      = 0;
+
+				if ( TEMPENDNODEENTRY != NULL )
+				{
+					while ( TEMPENDNODEENTRY != NULL)
+					{
+						for ( I=0; I < 4; I++) 
+						{
+							IPPARTS[I] = (((unsigned int)powpos((unsigned short)2,(unsigned short)PARTSIZE))-1) & (TEMPENDNODEENTRY->Src >> (4-I-1)*PARTSIZE);
+						}
+						
+						snprintf(STRINGBUFFER,KERNELLINEMAX-1,"T\t%d\t%d.%d.%d.%d\t%u\t%u\t%d\t%d\t%d\n",COUNTER,IPPARTS[3],IPPARTS[2],IPPARTS[1],IPPARTS[0],
+								(unsigned int)TEMPENDNODEENTRY->FirstTime,
+								(unsigned int)TEMPENDNODEENTRY->LastTime,
+								(unsigned int)TEMPENDNODEENTRY->Count,
+								(unsigned int)TEMPENDNODEENTRY->CountDst,
+								(unsigned int)TEMPENDNODEENTRY->CountDpt);
+						TEXTLEN += Kernel_CreateProcmemPufferAddEntry(STRINGBUFFER);
+
+						TEMPENDNODEENTRY = TEMPENDNODEENTRY->Next;
+					}
+				}
+				TEMP = TEMP->Next;
+				TEMPENDNODEENTRY = NULL;
+				COUNTER++;
+			}
+
+		}// Ende if ( TEMP != NULL )
+		spin_unlock(&PORTNETSCAN_SPINLOCK);
+	} // Ende if (IptGlobalConf.FirstOutLine == NULL )
+	
+
+	// Freigeben lokaler Funktionsvariablen
+	_free(IPPARTS);
+
+	// Standardwerte für globale und Konfuguraions-Variablen zu setzen
+
+	
+	IPPARTS = NULL;
+	return TEXTLEN;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   Kernel_CleanupAll
+	Conv:   Global/Kernel
+	Typ:    function
+	return: void (keiner)
+	Par 1:  void (keine)
+	Info:   Nicht mehr verwendet verwendete Teile von Listen (alte IP-Quelladresse und alte DenyListe Einträge)
+	        sollten in regelmäßigen Abstängen gelöscht werden. Diese Funktion wird vom Kerneltimer in dem in GLOBALCLEANUP
+	        angegebenen Zeitinterval aufgerufen.
+*/
+void Kernel_CleanupAll(unsigned long FORCE)
+{
+	spin_lock(&PORTNETSCAN_SPINLOCK);
+	IptCleanupAll(FORCE);
+	spin_unlock(&PORTNETSCAN_SPINLOCK);
+	/*
+		Zeit neu einplanen
+		* Expires für Task setzen
+		* Task registrieren
+	*/
+	Kernel_CleanupTimer.expires       = jiffies + (GLOBALCLEANUP*HZ);
+	add_timer(&Kernel_CleanupTimer);
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   Kernel_FlushProcmemPuffer
+	Conv:   Global/Kernel
+	Typ:    function
+	return: 0 OK / 1 Fehler oder unnötig
+	Par 1:  void (keine)
+	Info:   Freigeben des reservierten Speichers für die Kernelausgabeliste (verkettete Liste), die
+	        durch ein proc_read und dessen Funktionen Erstellt wurde.
+*/
+int Kernel_FlushProcmemPuffer(void)
+{
+	int RC = 0;
+	struct KernelOutLinePuffer * NEXT = NULL;
+
+	if ( IptGlobalConf.FirstOutLine != NULL )
+	{
+		while (IptGlobalConf.FirstOutLine != NULL)
+		{
+			NEXT = IptGlobalConf.FirstOutLine->Next;
+			_free (IptGlobalConf.FirstOutLine);
+			IptGlobalConf.FirstOutLine = NEXT;
+		}
+	}
+	else RC = 1;
+
+	NEXT = NULL;
+	IptGlobalConf.FirstOutLine     = NULL;
+	IptGlobalConf.LastPrintOutLine = NULL;
+	IptGlobalConf.LastAddOutLine   = NULL;
+	IptGlobalConf.FailBuffer       = 0;
+
+	return RC;
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+	Name:   Kernel_WriteOutLinePufferToProc
+	Conv:   Global/Kernel
+	Typ:    function
+	return: Anzahl der Bytes, die in die Variable BUFFER geschrieben wurden
+	Par 1:  BUFFER ( zu beschreibender Puffer, der vom Kernel zur Verfügung gestellt wird)
+	Par 2:  COUNT ( Anzahl der freien Bytes für Variable BUFFER)
+	Info:   Diese Funtion liest Elemente aus der im Modul erstellten Kernelausgabeliste (verkettete Liste)
+	        und schreibt diese in der angegeben Pugger (BUFFER) zurück. Hierbei wird darauf geachtet, dass
+	        die geschriebenen Bytes den Werte in der Variable COUNT nicht überschreiten.
+*/
+int Kernel_WriteOutLinePufferToProc(char * BUFFER,int COUNT)
+{
+	// Functionsvariablen
+	int RC  = 0;
+
+	if ( IptGlobalConf.FirstOutLine != NULL && IptGlobalConf.LastPrintOutLine != NULL  )
+	{
+		/*
+			Schritte:
+			1. Länge der Strings im Element der verketteten Liste Auslesen
+			2. In BUFFER schreiben
+				a. Wenn genug freier Platz vorhanden ist, werden die Daten in BUFFER zurückgeschrieben
+				b. Wenn nicht genügend Platz vorhanden ist, werden COUNT-1 Bytes geschreiben (-1 für letztes Zeichen,
+				   anscheinend braucht der Kernel dies für die interne Verwaltung von Speicherseiten???
+			
+
+			Hinweis:
+			Es scheint in einigen Kernelversionen verschiedene Problem mit dem Ende einer Speicherseite zu 
+			geben. Aus diesem Grund wird in diesem Modul Ein maximal Zeichen weniger als COUNT ausgegeben. Zudem
+			scheint es gravierende Unterschiede in snprintf zu geben.(Bis glib 2.1 und ab glib 2.1) Deashalb hier 
+			eine manuelle Längenprüfung des string und die Rückgabe der Anzahl der geschreibenen Bytes im Fehlerfall
+			"zu wenig Bytes" selbst errechechten und zurückgeben.
+		*/
+
+		int L = strlen(IptGlobalConf.LastPrintOutLine->Line+IptGlobalConf.FailBuffer);
+
+		if ( COUNT > KERNELLINEMAX ) COUNT = KERNELLINEMAX;
+
+			
+		if ( L <= (COUNT-1)  )
+		{
+			RC = snprintf(BUFFER,COUNT,"%s",IptGlobalConf.LastPrintOutLine->Line+IptGlobalConf.FailBuffer);
+			IptGlobalConf.LastPrintOutLine = IptGlobalConf.LastPrintOutLine->Next;
+			IptGlobalConf.FailBuffer = 0;
+		}
+		else
+		{	
+			RC = snprintf(BUFFER,COUNT-1,"%s",IptGlobalConf.LastPrintOutLine->Line+IptGlobalConf.FailBuffer);
+			IptGlobalConf.FailBuffer = COUNT -1;
+			RC = COUNT-1;
+		}
+	}
+	return RC;
+}
+
+int Kernel_ReadProcmem(char * BUFFER, char ** START, off_t OFFSET, int COUNT, int *EOF, void * DATA)
+{
+	int LEN=0;
+	/*
+		Falls erster Aufruf, ist OFFSET = 0. In diesem Fall werden
+		die Daten gesammelt und in einer verketteten Liste hinterlegt.
+	*/
+	if ( OFFSET == 0 )
+	{
+		/*
+			Um die SpinLock-Zeit im Kernel so kurz wir nötig zu haten, werden die Daten
+			zuerst einmal in der Funktion Kernel_CreateProcmemPuffer() in einer einfachen Verketten Liste 
+			gesammelt und dann ausgegeben (Taufe für Kommetare Kernelausgabeliste). Wenn dies fehlschlägt, 
+			wird der Speicher eintweder gerade verwendet, oder es wurden nicht alle Zeilen in einem vorherigen Aufruf
+			nicht abgearbeitet. Dies kann zum Beispiel beim Aufruf mit less passieren, da less nur eine bestimmte Anzahl
+			von Zeilen in den eigenen Puffer liest.
+		*/
+		if (Kernel_CreateProcmemPuffer() == 0)
+		{
+			*EOF = 1;
+			return sprintf(BUFFER,"... more lines in old buffer ..\n");
+		}
+	}
+	
+	/*
+		Daten aus der verketteten Liste (Kernelausgabeliste) lesen und die geschriebenen
+		Bytes in LEN anspeichern.
+	*/
+	LEN = Kernel_WriteOutLinePufferToProc(BUFFER,COUNT);
+
+	/*
+		Im Fall, dass von der Funktion Kernel_WriteOutLinePufferToProc 0 zurückgegeben wird, sollte
+		das lesen der verketten Liste (Kernelausgabeliste) beendet sein. Falls der Speicher nicht ausreichen
+		sollte, wird allerdings ebenfalls 0 zurückgegeben, dies ist beabsichtigt, da die Ausgabe dann in jedem
+		Fall abgebrochen werden soll.
+	*/
+	if ( LEN == 0 )
+	{
+		// Fehler oder letztes Element
+		*EOF = 1;
+		Kernel_FlushProcmemPuffer();
+	}
+	else
+	{
+		*EOF=1;
+		*START=BUFFER;
+	}
+	return LEN;
+}
+// Kernel Proc Initionlize
+void Kernel_CreateProcEnv(void)
+{
+	create_proc_read_entry("portnetscan",0,proc_net_stat,Kernel_ReadProcmem,NULL);
+}
+
+void Kernel_DeleteProcEnv(void)
+{
+	remove_proc_entry("portnetscan",proc_net_stat);
+}
+/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+INIT / EXIT
+*/
+static int __init init(void)
+{
+	int RC = 0;
+	printk("RGL PORTNETSCAN INIT\n");
+	printk("PORTNETSCAN Version: 0.1\n");
+	printk("PORTNETSCAN Last Change: 20.06.2006\n");
+
+	memset (&IptGlobalConf,0,sizeof(struct IptGlobalConfStruct));
+	memset (&PORTNETSCAN_SPINLOCK,0,sizeof(spinlock_t));
+
+	/*
+		Initialisieren der Globalen Umgebung
+	*/
+	IptGlobalConf.FirstPortNetscan    = NULL;
+	IptGlobalConf.FirstOutLine        = NULL;
+	IptGlobalConf.LastPrintOutLine    = NULL;
+	IptGlobalConf.LastAddOutLine      = NULL;
+	IptGlobalConf.Conf_Count          = 0;
+	IptGlobalConf.FailBuffer          = 0;
+	spin_lock_init(&PORTNETSCAN_SPINLOCK);
+
+	/*
+		Tasks
+		Timer für Aufräum- und Cleanup setzen
+		1. Initialisieren des Timers
+		2. Funktion beim Timeraufrufs setzen
+		3. Übergabeparameter der aufgerufenen Funktion setzen
+		4. Nächsten Interval-Aufruf setzen
+		5. Timer im Kernel als Task hinzufügen
+
+	*/
+	init_timer(&Kernel_CleanupTimer);
+	Kernel_CleanupTimer.function      = Kernel_CleanupAll;
+	Kernel_CleanupTimer.data          = 0; // Kein FORCE=1 setzen!!! da sonst alle einträge immer gelöscht werden
+	Kernel_CleanupTimer.expires       = jiffies + (GLOBALCLEANUP*HZ);
+	add_timer(&Kernel_CleanupTimer);
+
+
+	RC =  ipt_register_match(&ipt_portnetscan);
+
+	/*
+		Initialisieren von Proc-Dateien und Verzeichnissen
+	*/
+	Kernel_CreateProcEnv();
+
+
+
+	return RC;	
+}
+
+
+static void __exit fini(void)
+{
+	/*
+		Erst Timer-Tasks Löschen
+	*/
+
+	del_timer_sync( &Kernel_CleanupTimer );
+
+	printk("RGL PORTNETSCAN FLUSH\n");
+	/*
+		Aufräumen aller Ressourcen
+		1. Proc-Einträge Löschen
+		2. Einträge in verketten Listen und Bäumen löschen
+		3. Unregister des Moduls
+	*/
+	Kernel_DeleteProcEnv();
+	spin_lock(&PORTNETSCAN_SPINLOCK);
+	IptCleanupAll(1);
+	spin_unlock(&PORTNETSCAN_SPINLOCK);
+	ipt_unregister_match(&ipt_portnetscan);
+
+	
+}
+/*
+######################################################################################################################
+#### KernelInit ######################################################################################################
+######################################################################################################################
+*/
+module_init(init);
+module_exit(fini);
+#endif
+

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2007-03-20 16:30 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-03-15 13:29 patch: Port- and netscan detection for netfilter Gladewitz, Robert (FH)
2007-03-16 15:40 ` Patrick McHardy
2007-03-16 16:37   ` Tim Gardner
2007-03-16 16:57     ` Patrick McHardy
2007-03-16 21:32     ` Jan Engelhardt
2007-03-16 22:17       ` Gladewitz, Robert (FH)
2007-03-17  0:37         ` Jan Engelhardt
2007-03-16 21:29   ` Jan Engelhardt
2007-03-16 22:29   ` AW: " Gladewitz, Robert (FH)
2007-03-19  4:59     ` Patrick McHardy
2007-03-19 13:12       ` AW: " Gladewitz, Robert (FH)
2007-03-20 16:30         ` Jan Engelhardt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.