Schreiben Ihres eigenen netfilter-Tests

ArticleCategory:

KernelCorner

AuthorImage:

Photo of Nicolas Bouliane

TranslationInfo:[Author + translation history. mailto: or http://homepage]

original in en Nicolas Bouliane

en to de Hermann J. Beckers

AboutTheAuthor:

Nicolas ist ein junger K�mpfer in der Gemeinschaft freier Software. Er ist ein GNU/Linux-Abh�ngiger, seit dem er es im Jahre 1998 auf seinem Rechner installierte. Er verbringt seine Zeit damit, den Linux Netzwerkstack zu untersuchen, freie Software zu schreiben und Linux-bezogene Konferenzen wie OLS zu besuchen. Wenn er nicht vor seinem Computer sitzt, schaut er SciFi-Filme an, spielt Schach und h�rt Richard Stallmans Reden.

Abstract:

Das iptables/netfilter-Rahmenwerk gibt uns die M�glichkeit, Eigenschaften hinzuzuf�gen. Dazu schreibt man Kernel-Module, die sich bei diesem Rahmenwerk registrieren. Abh�ngig von der Kategorie dieser neuen Eigenschaft schreiben wir auch ein iptables-Modul. Durch das Schreiben Ihrer neuen Erweiterung k�nnen Sie ein bestimmtes Paket testen, ver�ndern, akzeptieren und verfolgen. Tats�chlich k�nnen Sie im Bereich des Filterns fast alles tun, was Sie m�chten. Beachten Sie, dass ein kleiner Fehler in einem Kernel-Modul Ihren Computer abst�rzen lassen kann.

Aus Gr�nden der Einfachheit werde ich einen Mustertest erl�utern, den ich geschrieben habe. Auf diese Weise hoffe ich, dass die Interaktion mit dem Rahmenwerk leichter zu verstehen ist. Ich setze hier voraus, dass Sie bereits etwas �ber iptables wissen und auch die C-Programmierung kennen.

Dieses Beispiel wird Ihnen zeigen, wie man ein Paket entsprechend der Quell- und/oder Zieladresse verfolgt.

ArticleIllustration:

[Illustration]

ArticleBody:

Beschreibung

Die allgemeinen Schritte zum Erstellen eines iptables/netfilter-Moduls sind:

1.0 Das iptables-Modul

Zweck einer iptables-Bibliothek ist einfach die Interaktion mit dem Anwender. Sie behandelt die Argumente, die der Anwender an den Kernel-Teil weiterleiten will.

1.1 verf�gbare Strukturen und Funktionen

Zun�chst einige grundlegende Strukturen <iptables/include/iptables.h>
Weiter im Text werden wir sehen, was der Zweck eines jeden Feldes ist.
/* Include file for additions: new matches and targets. */
struct iptables_match
{
   struct iptables_match *next;

   ipt_chainlabel name;

   const char *version;

   /* Size of match data. */
   size_t size;

   /* Size of match data relevent for userspace comparison purposes */
   size_t userspacesize;

   /* Function which prints out usage message. */
   void (*help)(void);

   /* Initialize the match. */
   void (*init)(struct ipt_entry_match *m, unsigned int *nfcache);

   /* Function which parses command options; returns true if it
           ate an option */
   int (*parse)(int c, char **argv, int invert, unsigned int *flags,
           const struct ipt_entry *entry,
           unsigned int *nfcache,
           struct ipt_entry_match **match);

   /* Final check; exit if not ok. */
   void (*final_check)(unsigned int flags);

   /* Prints out the match iff non-NULL: put space at end */
   void (*print)(const struct ipt_ip *ip,
            const struct ipt_entry_match *match, int numeric);

   /* Saves the match info in parsable form to stdout. */
   void (*save)(const struct ipt_ip *ip,
           const struct ipt_entry_match *match);

   /* Pointer to list of extra command-line options */
   const struct option *extra_opts;

   /* Ignore these men behind the curtain: */
   unsigned int option_offset;
   struct ipt_entry_match *m;
   unsigned int mflags;
#ifdef NO_SHARED_LIBS
   unsigned int loaded; /* simulate loading so options are merged properly */
#endif
};

1.2 Innerhalb des Programm-Skeletts

1.2.1 Initialisierung

Wir initialisieren die allgemeinen Felder in der Struktur 'iptables_match'.
static struct iptables_match ipaddr
= {
'Name' ist die Zeichenkette mit dem Namen Ihrer Bibliothek (z. B. libipt_ipaddr).
Sie k�nnen keinen anderen Namen angeben, er wird f�r das automatische Laden Ihrer Bibliothek benutzt.
    .name            = "ipaddr",
Das n�chste Feld 'version' ist die Version von iptables. Die beiden n�chsten Felder werden benutzt, um eine Korelation zwischen der Gr��e der zwischen dem Benutzerbereich und dem Kernelbereich gemeinsam genutzten Struktur zu erhalten.
    .version         = IPTABLES_VERSION,
    .size            = IPT_ALIGN(sizeof(struct ipt_ipaddr_info)),
    .userspacesize   = IPT_ALIGN(sizeof(struct ipt_ipaddr_info)),
'Help' wird aufgerufen, wenn der Benutzer 'iptables -m module -h' eingibt. 'Parse' wird aufgerufen, wenn Sie eine neue Regel eingeben, es dient zur �berpr�fung der Argumente. 'print' wird von 'iptables -L' aufgerufen, um die vorher eingegebenen Regeln anzuzeigen.
    .help            = &help,
    .init            = &init,
    .parse           = &parse,
    .final_check     = &final_check,
    .print           = &print,
    .save            = &save,
    .extra_opts      = opts
};
Die iptables-Infrastruktur kann mehrere gemeinsam genutzte Bibliotheken unterst�tzen. Jede Bibliothek muss sich bei iptables durch Aufruf von 'register_match()' registrieren, welche in <iptables/iptables.c> definiert ist. Diese Funktion wird aufgerufen, wenn das Modul von iptables geladen wird. Zu weiteren Informationen hierzu siehe 'man dlopen'.
void _init(void)
{
   register_match(&ipaddr);
}

1.2.2 Speicher-Funktion

Wenn wir eine Regelmenge sichern wollen, bietet iptables das Werkzeug 'iptables-save', das alle Ihre Regeln ausgibt. Offensichtlich ben�tigt es die Hilfe Ihrer Erweiterung, um die richtigen Regeln auszugeben. Dies wird durch den Aufruf dieser Funktion erreicht.
static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
{
   const struct ipt_ipaddr_info *info = (const struct ipt_ipaddr_info *)match->data;
Wir geben die Quell-Adresse aus, wenn sie Teil der Regel ist.
   if (info->flags & IPADDR_SRC) {
      if (info->flags & IPADDR_SRC_INV)
         printf("! ");
      printf("--ipsrc ");
      print_ipaddr((u_int32_t *)&info->ipaddr.src);
   }
Wir geben die Ziel-Adresse aus, wenn sie Teil der Regel ist.
   if (info->flags & IPADDR_DST) {
      if (info->flags & IPADDR_DST_INV)
         printf("! ");
      printf("--ipdst ");
      print_ipaddr((u_int32_t *)&info->ipaddr.dst);
   }
}

1.2.3 Druckfunktion

Im gleichen Sinne wie die vorherige, versucht diese Funktion, Information �ber die Regel auszugeben. Sie wird von 'iptables -L' aufgerufen. Sp�ter im Text werden wir den Zweck von 'ipt_entry_match *match' sehen, aber Sie wissen bestimmt schon etwas dar�ber.
static void print(const struct ipt_ip *ip,
                  const struct ipt_entry_match *match,
                  int numeric)
{
   const struct ipt_ipaddr_info *info = (const struct ipt_ipaddr_info *)match->data;

   if (info->flags & IPADDR_SRC) {
         printf("src IP ");
      if (info->flags & IPADDR_SRC_INV)
         printf("! ");
      print_ipaddr((u_int32_t *)&info->ipaddr.src);
   }

   if (info->flags & IPADDR_DST) {
      printf("dst IP ");
      if (info->flags & IPADDR_DST_INV)
         printf("! ");
      print_ipaddr((u_int32_t *)&info->ipaddr.dst);
   }
}

1.2.4 Funktion letzter Test

Diese Funktion ist eine letzte Gelegenheit f�r Sicherheitspr�fungen. Sie wird direkt nach der Argumentauswertung aufgerufen, wenn der Anwender eine neue Regel eingibt.
static void final_check(unsigned int flags)
{
   if (!flags)
      exit_error(PARAMETER_PROBLEM, "ipt_ipaddr: Invalid parameters.");
}

1.2.5 Auswerte-Funktion

Dies ist die wichtigste Funktion, weil wir hier verifizieren, dass die Argumente korrekt benutzt werden und wir Informationen eintragen, die wir mit dem Kernel-Teil gemeinsam verwenden. Sie wird jedesmal aufgerufen, wenn ein Argument gefunden wird, d. h. wenn der Anwender zwei Argumente eingibt, wird sie zweimal mit dem Argument-Code in der Variablen 'c' aufgerufen.
static int parse(int c, char **argv, int invert, unsigned int *flags,
                 const struct ipt_entry *entry,
                 unsigned int *nfcache,
                 struct ipt_entry_match **match)
{
Wir benutzten diese spezielle Struktur, um Informationen zu erhalten, die wir mit dem Kernel-Teil teilen. Der 'Match'-Zeiger wird an einige Funktionen weitergereicht, damit wir mit der gleichen Datenstruktur arbeiten k�nnen. Sobald die Regel geladen ist, wird dieser Zeiger in den Kernel-Bereich geladen. Auf diese Weise weiss das Kernel-Modul, um welche Analyse der Anwender gebeten hat (und darum geht es doch, oder?).
   struct ipt_ipaddr_info *info = (struct ipt_ipaddr_info *)(*match)->data;
Jedes Argument korrespondiert mit einem einzelnen Wert, so dass wir spezielle Aktionen entsprechend den eingegebenen Argumenten durchf�hren k�nnen . Wir werden sp�ter im Text sehen, wie wir Argumente auf Werte abbilden.
   switch(c) {
Zun�chst testen wir, ob das Argument mehr als einmal benutzt wurde. Wenn dies der Fall zu sein scheint, rufen wir das in <iptables/iptables.c> definierte 'exit_error()', das unmittelbar mit dem Status-Flag 'PARAMETER_PROBLEM' (definiert in <iptables/include/iptables_common.h>), zur�ckkehrt. Ansonsten setzen wir 'flags' und 'info->flags' auf den in unserer Header-Datei definierten Wert 'IPADDR_SRC'. Diese Header-Datei werden wir sp�ter sehen.

Obwohl beide Flags offensichtlich den gleichen Zweck haben, ist dies wirklich nicht der Fall. Der Bereich von 'flags' ist nur diese Funktion und 'info->flags' ist ein Teilfeld unserer Struktur, die mit dem Kernel-Teil gemeinsam benutzt wird.
      case '1':
         if (*flags & IPADDR_SRC)
            exit_error(PARAMETER_PROBLEM, "ipt_ipaddr: Only use --ipsrc once!");
         *flags |= IPADDR_SRC;
         info->flags |= IPADDR_SRC;
Wir verifizieren, ob das Invert-Flag, '!', eingegeben wurde und setzen entsprechende Informationen in 'info->flags'.
Als n�chstes rufen wir 'parse_ipaddr', eine interne Funktion, die f�r dieses Programm-Skelett geschrieben wurde, um eine Zeichenkette mit der IP-Adresse in einen 32-Bit-Wert zu wandeln.
         if (invert)
            info->flags |= IPADDR_SRC_INV;

         parse_ipaddr(argv[optind-1], &info->ipaddr.src);
         break;
Auf die gleiche Art testen wir auf mehrfache Verwendung und setzen entsprechende Flags.
      case '2':
         if (*flags & IPADDR_DST)
            exit_error(PARAMETER_PROBLEM, "ipt_ipaddr: Only use --ipdst once!");
         *flags |= IPADDR_DST;
         info->flags |= IPADDR_DST;
         if (invert)
            info->flags |= IPADDR_DST_INV;

         parse_ipaddr(argv[optind-1], &info->ipaddr.dst);
         break;

      default:
         return 0;
   }

   return 1;
}

1.2.6 Optionen-Struktur

Wir haben bereits diskutiert, das jedes Argument auf einen einzelnen Wert abgebildet wird. Die 'struct option' ist der bessere Weg, dies zu erreichen. Zu weiteren Informationen �ber diese Struktur, empfehle ich Ihnen sehr, 'man 3 getopt' zu lesen.
static struct option opts[] = {
   { .name = "ipsrc",   .has_arg = 1,   .flag = 0,   .val = '1' },
   { .name = "ipdst",   .has_arg = 1,   .flag = 0,   .val = '2' },
   { .name = 0 }
};

1.2.7 Initialisierungs-Funktion

Diese Initialisierungsfunktion wird benutzt, um einige spezielle Sachen wie das netfilter-Cache-System einzurichten. Es ist jetzt nicht sehr wichtig zu wissen, wie das genau funktioniert.
static void init(struct ipt_entry_match *m, unsigned int *nfcache)
{
   /* Can't cache this */
   *nfcache |= NFC_UNKNOWN;
}

1.2.7 Hilfe-Funktion

Diese Funktion wird von 'iptables -m match_name -h' aufgerufen, um die verf�gbaren Argumente anzuzeigen.
static void help(void)
{
   printf (
            "IPADDR v%s options:\n"
            "[!] --ipsrc <ip>\t\t The incoming ip addr matches.\n"
            "[!] --ipdst <ip>\t\t The outgoing ip addr matches.\n"
            "\n", IPTABLES_VERSION
         );
}

1.2.8 Die Header-Datei 'ipt_ipaddr.h'

In dieser Datei definieren wir die von uns ben�tigten Sachen.
#ifndef _IPT_IPADDR_H
#define _IPT_IPADDR_H
Wir haben bereits gesehen, dass wir Flags auf bestimmte Werte setzen.
#define IPADDR_SRC   0x01     /* Match source IP addr */
#define IPADDR_DST   0x02     /* Match destination IP addr */

#define IPADDR_SRC_INV  0x10  /* Negate the condition */
#define IPADDR_DST_INV  0x20  /* Negate the condition */
Die Struktur 'ipt_ipaddr_info' ist diejenige, welche in den Kernel-Teil kopiert wird.
struct ipt_ipaddr {
   u_int32_t src, dst;
};

struct ipt_ipaddr_info {

   struct ipt_ipaddr ipaddr;

   /* Flags from above */
   u_int8_t flags;

};

#endif

1.3 Zusammenfassung Kapitel 1

Im ersten Teil haben wir den Zweck der iptables-Bibliothek diskutiert. Wir haben die Interna jeder Funktion besprochen und wie die Struktur 'ipt_ipaddr_info' benutzt wird, um Informationen zu speichern, die zur weiteren Verwendung in den Kernel-Teil kopiert werden. Wir schauten ausserdem auf die iptables-Struktur und wie wir unsere neue Bibliothek registrieren. Sie sollten bedenken, dass dies nur ein Programm-Beispiel ist, das mir hilft, Ihnen zu zeigen, wie dieses Rahmenwerk arbeitet. Weiterhin sind 'ipt_ipaddr_info' und �hnliche Sachen nicht Teil von iptables/netfilter, sondern Bestandteil dieses Beispiels.

2.0 Das netfilter-Modul

Zweck eines Match-Moduls ist es, jedes empfangene Paket zu inspizieren und zu entscheiden, ob es entsprechend unserer Kriterien �bereinstimmt oder nicht. Das Modul hat die folgenden M�glichkeiten, dieses zu tun:

2.1 verf�gbare Strukturen und Funktionen

Zun�chst einige grundlegende Strukturen. Diese Struktr ist definiert in <linux/netfilter_ipv4/ip_tables.h>.
Wenn Sie daran interessiert sind, mehr �ber diese und die vorher f�r iptables vorgestellte Struktur zu lernen, sollten Sie sich netfilter hacking howto ansehen, das von Rusty Russell und Harald Welte geschrieben wurde.
struct ipt_match
{
   struct list_head list;

   const char name[IPT_FUNCTION_MAXNAMELEN];

   /* Return true or false: return FALSE and set *hotdrop = 1 to
           force immediate packet drop. */
   /* Arguments changed since 2.4, as this must now handle
           non-linear skbs, using skb_copy_bits and
           skb_ip_make_writable. */
   int (*match)(const struct sk_buff *skb,
           const struct net_device *in,
           const struct net_device *out,
           const void *matchinfo,
           int offset,
           int *hotdrop);

   /* Called when user tries to insert an entry of this type. */
   /* Should return true or false. */
   int (*checkentry)(const char *tablename,
           const struct ipt_ip *ip,
           void *matchinfo,
           unsigned int matchinfosize,
           unsigned int hook_mask);

   /* Called when entry of this type deleted. */
   void (*destroy)(void *matchinfo, unsigned int matchinfosize);

   /* Set this to THIS_MODULE. */
   struct module *me;
};

2.2 Innerhalb des Programm-Skeletts

2.2.1 Initialisierung

Wir initialisieren die allgemeinen Felder in der Struktur 'ipt_match'.

static struct ipt_match ipaddr_match
= {
'Name' ist die Zeichenkette mit dem Dateinamen Ihres Moduls (z. B. ipt_ipaddr).
	.name       = "ipaddr",
Die n�chsten Felder enthalten R�cksprungfunktionen, die das Rahmenwerk benutzen wird. 'Match' wird aufgerufen, wenn ein Paket an Ihr Modul weitergereicht wird.
	.match      = match,
	.checkentry = checkentry,
	.me         = THIS_MODULE,
};
Die Init-Funktion Ihres Kernelmoduls muss 'ipt_register_match()' aufrufen mit einem Zeiger auf eine Struktur 'struct ipt_match', um sich beim netfiler-Rahmenwerk zu registrieren. Diese Funktion wird beim Laden des Moduls aufgerufen.
static int __init init(void)
{
	printk(KERN_INFO "ipt_ipaddr: init!\n");
	return ipt_register_match(&ipaddr_match);
}
Beim Entladen des Moduls wird diese Funktion aufgerufen. Hier deregistrieren wir unser Match-Modul.
static void __exit fini(void)
{
	printk(KERN_INFO "ipt_ipaddr: exit!\n");
	ipt_unregister_match(&ipaddr_match);
}
Wir �bergeben ihnen Funktionen, die beim Laden und Entladen des Moduls aufgerufen werden.
module_init(init);
module_exit(fini);

2.2.2 'match'-Funktion

Der Linux-TCP/IP-Stack verf�gt �ber 5 netfilter-Einsprungstellen. Wenn ein Paket hereinkommt, �bergibt der Stack das Paket an die entsprechende Einsprungstelle, welche dann jede Tabelle durchl�uft, die dann ihrerseits jede Regel testet. Wenn dann Ihr Modul mit dem Paket an die Reihe kommt, kann es endlich seine Aufgabe erf�llen.
static int match(const struct sk_buff *skb,
                 const struct net_device *in,
                 const struct net_device *out,
                 const void *matchinfo,
                 int offset,
                 const void *hdr,
                 u_int16_t datalen,
                 int *hotdrop)
{
Sie erinnern sich hoffentlich daran, was wir im Benutzerbereich getan haben! :). Nun �bertragen wir die vom Benutzerbereich kopierte Struktur in unsere eigene.
	const struct ipt_skeleton_info *info = matchinfo;
'skb' enth�lt das Paket, das wir untersuchen wollen. Zu weiteren Informationen �ber diese m�chtige Struktur, die �berall im LInux-TCP/IP-Stack benutzt wird, hat Harald Welte einen exzellenten Artikel (ftp://ftp.gnumonks.org/pub/doc/skb-doc.html) geschrieben.
   struct iphdr *iph = skb->nh.iph;
Hier geben wir nur einige lustige Sachen aus, um zu sehen, wie sie aussehen. Das Makro 'NIPQUAD' wird benutzt, um eine IP-Adresse in lesbarer Form auszugeben, definiert in <linux/include/linux/kernel.h>.
   printk(KERN_INFO "ipt_ipaddr: IN=%s OUT=%s TOS=0x%02X "
                    "TTL=%x SRC=%u.%u.%u.%u DST=%u.%u.%u.%u "
                    "ID=%u IPSRC=%u.%u.%u.%u IPDST=%u.%u.%u.%u\n",

                    in ? (char *)in : "", out ? (char *)out : "", iph->tos,
                    iph->ttl, NIPQUAD(iph->saddr), NIPQUAD(iph->daddr),
                    ntohs(iph->id), NIPQUAD(info->ipaddr.src), NIPQUAD(info->ipaddr.dst)
         );
Wenn das Argument '--ipsrc' �bergeben wurde, schauen wir, ob die Quelladresse mit der in der Regel angegebenen �bereinstimmt. Wir vergessen nicht, das Invert-Flag '!' zu ber�cksichtigen. Wenn es keine �bereinstimmung gibt, geben wir das Urteil 0 zur�ck.
   if (info->flags & IPADDR_SRC) {
      if ( (ntohl(iph->saddr) != ntohl(info->ipaddr.src)) ^ !!(info->flags & IPADDR_SRC_INV) ) {

         printk(KERN_NOTICE "src IP %u.%u.%u.%u is not matching %s.\n",
                            NIPQUAD(info->ipaddr.src),
                            info->flags & IPADDR_SRC_INV ? " (INV)" : "");
         return 0;
      }
   }
Hier machen wir das gleiche mit der Ausnahme, das wir auf die Zieladresse schauen, wenn '--ipdst' eingegeben wurde.
   if (info->flags & IPADDR_DST) {
      if ( (ntohl(iph->daddr) != ntohl(info->ipaddr.dst)) ^ !!(info->flags & IPADDR_DST_INV) )  {

         printk(KERN_NOTICE "dst IP %u.%u.%u.%u is not matching%s.\n",
                            NIPQUAD(info->ipaddr.dst),
                            info->flags & IPADDR_DST_INV ? " (INV)" : "");
         return 0;
      }
   }
Wenn beides nicht zutrifft, geben wir das Urteil 1 zur�ck, was bedeutet, dass das Paket �bereinstimmt.
   return 1;
}

2.2.3 Funktion 'checkentry'

Checkentry wird �berwiegend benutzt als letzte M�glichkeit f�r Sicherheitstest. Es ist etwas schwer zu verstehen, wenn es aufgerufen wird. Zur Erl�uterung siehe dieses Posting (http://www.mail-archive.com/[email protected]/msg00625.html). Dies wird auch im 'netfilter hacking howto' erl�utert.
static int checkentry(const char *tablename,
                             const struct ipt_ip *ip,
                             void *matchinfo,
                             unsigned int matchsize,
                             unsigned int hook_mask)
{
   const struct ipt_skeleton_info *info = matchinfo;

   if (matchsize != IPT_ALIGN(sizeof(struct ipt_skeleton_info))) {
      printk(KERN_ERR "ipt_skeleton: matchsize differ, you may have forgotten to recompile me.\n");
      return 0;
   }

   printk(KERN_INFO "ipt_skeleton: Registered in the %s table, hook=%x, proto=%u\n",
                    tablename, hook_mask, ip->proto);

   return 1;
}

2.3 Zusammenfassung Kapitel 2

In diesem zweiten Teil behandelten wir das netfilter-Modul und wie es mittels einer speziellen Struktur registriert wird. Zus�tzlich diskutierten wir, wie man eine spezifische Situation entsprechend der vom Benutzer-Teil bereitgestellten Kriterien auf �bereinstimmung testet.

3.0 mit iptables/netfilter spielen

Wir haben gesehen, wie man ein neues iptables/netfilter-Match-Modul schreibt. Nun wollen wir es unserem Kernel hinzuf�gen, um damit zu spielen. Hier setzte ich voraus, dass Sie einen Kernel erstellen bzw kompilieren k�nnen. Zun�chst holen Sie sich die match-Dateien f�r dieses Programm-Skelett von der Download-Seite f�r diesen Artikel.

3.1 iptables

Wenn Sie nicht �ber die iptables-Quellen verf�gen, k�nnen Sie sie von ftp://ftp.netfilter.org/pub/iptables/ abrufen. Dann m�ssen Sie 'libipt_ipaddr.c' nach <iptables/extensions/> kopieren.

Dies ist eine Zeile von <iptables/extensions/Makefile> in der Sie 'ipaddr' hinzuf�gen m�ssen.
PF_EXT_SLIB:=ah addrtype comment connlimit connmark conntrack dscp ecn
esp hashlimit helper icmp iprange length limit ipaddr mac mark
multiport owner physdev pkttype realm rpc sctp standard state tcp tcpmss
tos ttl udp unclean CLASSIFY CONNMARK DNAT DSCP ECN LOG MARK MASQUERADE
MIRROR NETMAP NOTRACK REDIRECT REJECT SAME SNAT TARPIT TCPMSS TOS TRACE
TTL ULOG

3.2 Kernel

Zun�chst m�ssen Sie 'ipt_ipaddr.c' in <linux/net/ipv4/netfilter/> und 'ipt_ipaddr.h' nach <linux/include/linux/netfilter_ipv4/> kopieren. Einige von Ihnen benutzen immer noch Linux 2.4, daher zeige ich die zu editierenden Dateien f�r 2.4 und 2.6.

F�r 2.4 editieren Sie <linux/net/ipv4/netfilter/Config.in> und f�gen die fett dargestellte Zeile hinzu.
# The simple matches.
  dep_tristate '  limit match support' CONFIG_IP_NF_MATCH_LIMIT $CONFIG_IP_NF_IPTABLES
  dep_tristate '  ipaddr match support' CONFIG_IP_NF_MATCH_IPADDR $CONFIG_IP_NF_IPTABLES
Dann editieren Sie <linux/Documentation/Configure.help> und f�gen den fett dargestellten Text hinzu. Ich habe etwas Text kopiert, um Ihnen dabei zu helfen, wo Sie Ihren hinzuf�gen k�nnen.
limit match support
CONFIG_IP_NF_MATCH_LIMIT
  limit matching allows you to control the rate at which a rule can be
  ...
ipaddr match support
CONFIG_IP_NF_MATCH_IPADDR
  ipaddr matching. etc etc.
Zum Schluss m�ssen Sie diese fett dargestellte Zeile in <linux/net/ipv4/netfilter/Makefile> einf�gen.
# matches
obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
obj-$(CONFIG_IP_NF_MATCH_IPADDR) += ipt_ipaddr.o
F�r 2.6 sind die zu editierenden Dateien <linux/net/ipv4/netfilter/Kconfig> und <linux/net/ipv4/netfilter/Makefile>.

Zusammenfassung

Nun m�ssen Sie nur noch rekompilieren und das hinzuf�gen, was ich vergessen habe, Ihnen zu erz�hlen.
Fr�hliches Hacken!!
Danke an Samuel Jean.