summaryrefslogtreecommitdiff
path: root/package/iptables
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2007-06-05 22:46:02 +0000
committerFelix Fietkau <nbd@openwrt.org>2007-06-05 22:46:02 +0000
commit04324c48cfc7ea3aad8f95552e6349c42537ccdc (patch)
tree7499eed31bb77462d1260406ece6464886087eb7 /package/iptables
parent72823077cdabdb6b3432a254d413000d00630634 (diff)
downloadmtk-20170518-04324c48cfc7ea3aad8f95552e6349c42537ccdc.zip
mtk-20170518-04324c48cfc7ea3aad8f95552e6349c42537ccdc.tar.gz
mtk-20170518-04324c48cfc7ea3aad8f95552e6349c42537ccdc.tar.bz2
upgrade a few packages to newer versions (includes patch by kaloz) - preparation for 2.6.22
SVN-Revision: 7507
Diffstat (limited to 'package/iptables')
-rw-r--r--package/iptables/patches/100-svn_r6848.patch8854
-rw-r--r--package/iptables/patches/110-2.6.22_compatibility.patch12
2 files changed, 8866 insertions, 0 deletions
diff --git a/package/iptables/patches/100-svn_r6848.patch b/package/iptables/patches/100-svn_r6848.patch
new file mode 100644
index 0000000..ec51206
--- /dev/null
+++ b/package/iptables/patches/100-svn_r6848.patch
@@ -0,0 +1,8854 @@
+diff -x .svn -Nur iptables-1.3.7/extensions/.account-test iptables-svn/extensions/.account-test
+--- iptables-1.3.7/extensions/.account-test 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/.account-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,3 +0,0 @@
+-#!/bin/sh
+-# True if account match patch is applied.
+-[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_account.h ] && echo account
+diff -x .svn -Nur iptables-1.3.7/extensions/.BALANCE-test iptables-svn/extensions/.BALANCE-test
+--- iptables-1.3.7/extensions/.BALANCE-test 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/.BALANCE-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,2 +0,0 @@
+-#! /bin/sh
+-[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_BALANCE.c ] && echo BALANCE
+diff -x .svn -Nur iptables-1.3.7/extensions/.childlevel-test iptables-svn/extensions/.childlevel-test
+--- iptables-1.3.7/extensions/.childlevel-test 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/.childlevel-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,2 +0,0 @@
+-#! /bin/sh
+-[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_childlevel.h ] && echo childlevel
+diff -x .svn -Nur iptables-1.3.7/extensions/.connrate-test iptables-svn/extensions/.connrate-test
+--- iptables-1.3.7/extensions/.connrate-test 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/.connrate-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,2 +0,0 @@
+-#! /bin/sh
+-[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_connrate.h ] && echo connrate
+diff -x .svn -Nur iptables-1.3.7/extensions/.dstlimit-test iptables-svn/extensions/.dstlimit-test
+--- iptables-1.3.7/extensions/.dstlimit-test 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/.dstlimit-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,2 +0,0 @@
+-#! /bin/sh
+-[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_dstlimit.c ] && echo dstlimit
+diff -x .svn -Nur iptables-1.3.7/extensions/.FTOS-test iptables-svn/extensions/.FTOS-test
+--- iptables-1.3.7/extensions/.FTOS-test 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/.FTOS-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,2 +0,0 @@
+-#! /bin/sh
+-[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_FTOS.h ] && echo FTOS
+diff -x .svn -Nur iptables-1.3.7/extensions/.fuzzy-test iptables-svn/extensions/.fuzzy-test
+--- iptables-1.3.7/extensions/.fuzzy-test 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/.fuzzy-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,2 +0,0 @@
+-#! /bin/sh
+-[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_fuzzy.h ] && echo fuzzy
+diff -x .svn -Nur iptables-1.3.7/extensions/.fuzzy-test6 iptables-svn/extensions/.fuzzy-test6
+--- iptables-1.3.7/extensions/.fuzzy-test6 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/.fuzzy-test6 1970-01-01 01:00:00.000000000 +0100
+@@ -1,2 +0,0 @@
+-#!/bin/sh
+-[ -f $KERNEL_DIR/net/ipv6/netfilter/ip6t_fuzzy.c -a -f $KERNEL_DIR/include/linux/netfilter_ipv6/ip6t_fuzzy.h ] && echo fuzzy
+diff -x .svn -Nur iptables-1.3.7/extensions/.IPMARK-test iptables-svn/extensions/.IPMARK-test
+--- iptables-1.3.7/extensions/.IPMARK-test 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/.IPMARK-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,3 +0,0 @@
+-#!/bin/sh
+-# True if IPMARK patch is applied.
+-[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_IPMARK.h ] && echo IPMARK
+diff -x .svn -Nur iptables-1.3.7/extensions/.ipv4options-test iptables-svn/extensions/.ipv4options-test
+--- iptables-1.3.7/extensions/.ipv4options-test 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/.ipv4options-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,3 +0,0 @@
+-#!/bin/sh
+-# True if ipv4options is applied.
+-[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_ipv4options.h ] && echo ipv4options
+diff -x .svn -Nur iptables-1.3.7/extensions/.IPV4OPTSSTRIP-test iptables-svn/extensions/.IPV4OPTSSTRIP-test
+--- iptables-1.3.7/extensions/.IPV4OPTSSTRIP-test 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/.IPV4OPTSSTRIP-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,3 +0,0 @@
+-#!/bin/sh
+-# True if IPV4OPTSSTRIP patch is applied.
+-[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.c ] && echo IPV4OPTSSTRIP
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_eui64.man iptables-svn/extensions/libip6t_eui64.man
+--- iptables-1.3.7/extensions/libip6t_eui64.man 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libip6t_eui64.man 2007-05-31 12:46:30.000000000 +0200
+@@ -1,5 +1,5 @@
+ This module matches the EUI-64 part of a stateless autoconfigured IPv6 address.
+-It compares the EUI-64 derived from the source MAC address in Ehternet frame
++It compares the EUI-64 derived from the source MAC address in Ethernet frame
+ with the lower 64 bits of the IPv6 source address. But "Universal/Local"
+ bit is not compared. This module doesn't match other link layer frame, and
+ is only valid in the
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_fuzzy.c iptables-svn/extensions/libip6t_fuzzy.c
+--- iptables-1.3.7/extensions/libip6t_fuzzy.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libip6t_fuzzy.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,156 +0,0 @@
+-/*
+- Shared library add-on to iptables to add match support for the fuzzy match.
+-
+- 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
+-
+-2002-08-07 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
+-2003-04-08 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 Port
+-2003-06-09 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Bug corrections in
+-the save function , thanks to information given by Jean-Francois Patenaude.
+-
+-*/
+-
+-#include <stdio.h>
+-#include <netdb.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <syslog.h>
+-#include <getopt.h>
+-#include <ip6tables.h>
+-#include <linux/netfilter_ipv6/ip6_tables.h>
+-#include <linux/netfilter_ipv6/ip6t_fuzzy.h>
+-
+-
+-static void
+-help(void)
+-{
+- printf(
+-"fuzzy v%s options:\n"
+-" --lower-limit number (in packets per second)\n"
+-" --upper-limit number\n"
+-,IPTABLES_VERSION);
+-};
+-
+-static struct option opts[] = {
+- { .name = "lower-limit", .has_arg = 1, .flag = 0, .val = '1' },
+- { .name = "upper-limit", .has_arg = 1, .flag = 0, .val = '2' },
+- { .name = 0 }
+-};
+-
+-/* Initialize data structures */
+-static void
+-init(struct ip6t_entry_match *m, unsigned int *nfcache)
+-{
+- struct ip6t_fuzzy_info *presentinfo = (struct ip6t_fuzzy_info *)(m)->data;
+- /*
+- * Default rates ( I'll improve this very soon with something based
+- * on real statistics of the running machine ) .
+- */
+-
+- presentinfo->minimum_rate = 1000;
+- presentinfo->maximum_rate = 2000;
+-}
+-
+-#define IP6T_FUZZY_OPT_MINIMUM 0x01
+-#define IP6T_FUZZY_OPT_MAXIMUM 0x02
+-
+-static int
+-parse(int c, char **argv, int invert, unsigned int *flags,
+- const struct ip6t_entry *entry,
+- unsigned int *nfcache,
+- struct ip6t_entry_match **match)
+-{
+- struct ip6t_fuzzy_info *fuzzyinfo =
+- (struct ip6t_fuzzy_info *)(*match)->data;
+-
+- u_int32_t num;
+-
+- switch (c) {
+-
+- case '1':
+-
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,"Can't specify ! --lower-limit");
+-
+- if (*flags & IP6T_FUZZY_OPT_MINIMUM)
+- exit_error(PARAMETER_PROBLEM,"Can't specify --lower-limit twice");
+-
+- if (string_to_number(optarg,1,MAXFUZZYRATE,&num) == -1 || num < 1)
+- exit_error(PARAMETER_PROBLEM,"BAD --lower-limit");
+-
+- fuzzyinfo->minimum_rate = num ;
+-
+- *flags |= IP6T_FUZZY_OPT_MINIMUM;
+-
+- break;
+-
+- case '2':
+-
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,"Can't specify ! --upper-limit");
+-
+- if (*flags & IP6T_FUZZY_OPT_MAXIMUM)
+- exit_error(PARAMETER_PROBLEM,"Can't specify --upper-limit twice");
+-
+- if (string_to_number(optarg,1,MAXFUZZYRATE,&num) == -1 || num < 1)
+- exit_error(PARAMETER_PROBLEM,"BAD --upper-limit");
+-
+- fuzzyinfo->maximum_rate = num;
+-
+- *flags |= IP6T_FUZZY_OPT_MAXIMUM;
+-
+- break ;
+-
+- default:
+- return 0;
+- }
+- return 1;
+-}
+-
+-static void final_check(unsigned int flags)
+-{
+-}
+-
+-static void
+-print(const struct ip6t_ip6 *ipv6,
+- const struct ip6t_entry_match *match,
+- int numeric)
+-{
+- const struct ip6t_fuzzy_info *fuzzyinfo
+- = (const struct ip6t_fuzzy_info *)match->data;
+-
+- printf(" fuzzy: lower limit = %u pps - upper limit = %u pps ",
+- fuzzyinfo->minimum_rate, fuzzyinfo->maximum_rate);
+-}
+-
+-/* Saves the union ip6t_targinfo in parsable form to stdout. */
+-static void
+-save(const struct ip6t_ip6 *ipv6, const struct ip6t_entry_match *match)
+-{
+- const struct ip6t_fuzzy_info *fuzzyinfo
+- = (const struct ip6t_fuzzy_info *)match->data;
+-
+- printf("--lower-limit %u --upper-limit %u ",
+- fuzzyinfo->minimum_rate, fuzzyinfo->maximum_rate);
+-}
+-
+-struct ip6tables_match fuzzy_match = {
+- .name = "fuzzy",
+- .version = IPTABLES_VERSION,
+- .size = IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info)),
+- .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_fuzzy_info)),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_match6(&fuzzy_match);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_fuzzy.man iptables-svn/extensions/libip6t_fuzzy.man
+--- iptables-1.3.7/extensions/libip6t_fuzzy.man 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libip6t_fuzzy.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,7 +0,0 @@
+-This module matches a rate limit based on a fuzzy logic controller [FLC]
+-.TP
+-.BI "--lower-limit " "number"
+-Specifies the lower limit (in packets per second).
+-.TP
+-.BI "--upper-limit " "number"
+-Specifies the upper limit (in packets per second).
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_icmp6.man iptables-svn/extensions/libip6t_icmp6.man
+--- iptables-1.3.7/extensions/libip6t_icmp6.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libip6t_icmp6.man 2007-05-31 12:46:30.000000000 +0200
+@@ -1,4 +1,4 @@
+-This extension is loaded if `--protocol ipv6-icmp' or `--protocol icmpv6' is
++This extension can be used if `--protocol ipv6-icmp' or `--protocol icmpv6' is
+ specified. It provides the following option:
+ .TP
+ .BR "--icmpv6-type " "[!] \fItype\fP[/\fIcode\fP]|\fItypename\fP"
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_mh.c iptables-svn/extensions/libip6t_mh.c
+--- iptables-1.3.7/extensions/libip6t_mh.c 1970-01-01 01:00:00.000000000 +0100
++++ iptables-svn/extensions/libip6t_mh.c 2007-05-31 12:46:30.000000000 +0200
+@@ -0,0 +1,252 @@
++/* Shared library add-on to ip6tables to add mobility header support. */
++/*
++ * Copyright (C)2006 USAGI/WIDE Project
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * Author:
++ * Masahide NAKAMURA @USAGI <masahide.nakamura.cz@hitachi.com>
++ *
++ * Based on libip6t_{icmpv6,udp}.c
++ */
++#include <stdio.h>
++#include <netdb.h>
++#include <string.h>
++#include <stdlib.h>
++#include <getopt.h>
++#include <ip6tables.h>
++#include <linux/netfilter_ipv6/ip6_tables.h>
++#include <linux/netfilter_ipv6/ip6t_mh.h>
++
++struct mh_name {
++ const char *name;
++ u_int8_t type;
++};
++
++static const struct mh_name mh_names[] = {
++ { "binding-refresh-request", 0, },
++ /* Alias */ { "brr", 0, },
++ { "home-test-init", 1, },
++ /* Alias */ { "hoti", 1, },
++ { "careof-test-init", 2, },
++ /* Alias */ { "coti", 2, },
++ { "home-test", 3, },
++ /* Alias */ { "hot", 3, },
++ { "careof-test", 4, },
++ /* Alias */ { "cot", 4, },
++ { "binding-update", 5, },
++ /* Alias */ { "bu", 5, },
++ { "binding-acknowledgement", 6, },
++ /* Alias */ { "ba", 6, },
++ { "binding-error", 7, },
++ /* Alias */ { "be", 7, },
++};
++
++static void print_types_all(void)
++{
++ unsigned int i;
++ printf("Valid MH types:");
++
++ for (i = 0; i < sizeof(mh_names)/sizeof(struct mh_name); i++) {
++ if (i && mh_names[i].type == mh_names[i-1].type)
++ printf(" (%s)", mh_names[i].name);
++ else
++ printf("\n%s", mh_names[i].name);
++ }
++ printf("\n");
++}
++
++static void help(void)
++{
++ printf(
++"MH v%s options:\n"
++" --mh-type [!] type[:type] match mh type\n",
++IPTABLES_VERSION);
++ print_types_all();
++}
++
++static void init(struct ip6t_entry_match *m, unsigned int *nfcache)
++{
++ struct ip6t_mh *mhinfo = (struct ip6t_mh *)m->data;
++
++ mhinfo->types[1] = 0xFF;
++}
++
++static unsigned int name_to_type(const char *name)
++{
++ int namelen = strlen(name);
++ unsigned int limit = sizeof(mh_names)/sizeof(struct mh_name);
++ unsigned int match = limit;
++ unsigned int i;
++
++ for (i = 0; i < limit; i++) {
++ if (strncasecmp(mh_names[i].name, name, namelen) == 0) {
++ int len = strlen(mh_names[i].name);
++ if (match == limit || len == namelen)
++ match = i;
++ }
++ }
++
++ if (match != limit) {
++ return mh_names[match].type;
++ } else {
++ unsigned int number;
++
++ if (string_to_number(name, 0, 255, &number) == -1)
++ exit_error(PARAMETER_PROBLEM,
++ "Invalid MH type `%s'\n", name);
++ return number;
++ }
++}
++
++static void parse_mh_types(const char *mhtype, u_int8_t *types)
++{
++ char *buffer;
++ char *cp;
++
++ buffer = strdup(mhtype);
++ if ((cp = strchr(buffer, ':')) == NULL)
++ types[0] = types[1] = name_to_type(buffer);
++ else {
++ *cp = '\0';
++ cp++;
++
++ types[0] = buffer[0] ? name_to_type(buffer) : 0;
++ types[1] = cp[0] ? name_to_type(cp) : 0xFF;
++
++ if (types[0] > types[1])
++ exit_error(PARAMETER_PROBLEM,
++ "Invalid MH type range (min > max)");
++ }
++ free(buffer);
++}
++
++#define MH_TYPES 0x01
++
++static int parse(int c, char **argv, int invert, unsigned int *flags,
++ const struct ip6t_entry *entry,
++ unsigned int *nfcache,
++ struct ip6t_entry_match **match)
++{
++ struct ip6t_mh *mhinfo = (struct ip6t_mh *)(*match)->data;
++
++ switch (c) {
++ case '1':
++ if (*flags & MH_TYPES)
++ exit_error(PARAMETER_PROBLEM,
++ "Only one `--mh-type' allowed");
++ check_inverse(optarg, &invert, &optind, 0);
++ parse_mh_types(argv[optind-1], mhinfo->types);
++ if (invert)
++ mhinfo->invflags |= IP6T_MH_INV_TYPE;
++ *flags |= MH_TYPES;
++ break;
++
++ default:
++ return 0;
++ }
++
++ return 1;
++}
++
++/* Final check; we don't care. */
++static void final_check(unsigned int flags)
++{
++}
++
++static const char *type_to_name(u_int8_t type)
++{
++ unsigned int i;
++
++ for (i = 0; i < sizeof(mh_names)/sizeof(struct mh_name); i++) {
++ if (mh_names[i].type == type)
++ return mh_names[i].name;
++ }
++
++ return NULL;
++}
++
++static void print_type(u_int8_t type, int numeric)
++{
++ const char *name;
++ if (numeric || !(name = type_to_name(type)))
++ printf("%u", type);
++ else
++ printf("%s", name);
++}
++
++static void print_types(u_int8_t min, u_int8_t max, int invert, int numeric)
++{
++ const char *inv = invert ? "!" : "";
++
++ if (min != 0 || max != 0xFF || invert) {
++ if (min == max) {
++ printf("%s", inv);
++ print_type(min, numeric);
++ } else {
++ printf("%s", inv);
++ print_type(min, numeric);
++ printf(":");
++ print_type(max, numeric);
++ }
++ printf(" ");
++ }
++}
++
++static void print(const struct ip6t_ip6 *ip,
++ const struct ip6t_entry_match *match,
++ int numeric)
++{
++ const struct ip6t_mh *mhinfo = (struct ip6t_mh *)match->data;
++
++ printf("mh ");
++ print_types(mhinfo->types[0], mhinfo->types[1],
++ mhinfo->invflags & IP6T_MH_INV_TYPE,
++ numeric);
++ if (mhinfo->invflags & ~IP6T_MH_INV_MASK)
++ printf("Unknown invflags: 0x%X ",
++ mhinfo->invflags & ~IP6T_MH_INV_MASK);
++}
++
++static void save(const struct ip6t_ip6 *ip,
++ const struct ip6t_entry_match *match)
++{
++ const struct ip6t_mh *mhinfo = (struct ip6t_mh *)match->data;
++
++ if (mhinfo->types[0] == 0 && mhinfo->types[1] == 0xFF)
++ return;
++
++ if (mhinfo->invflags & IP6T_MH_INV_TYPE)
++ printf("! ");
++
++ if (mhinfo->types[0] != mhinfo->types[1])
++ printf("--mh-type %u:%u ", mhinfo->types[0], mhinfo->types[1]);
++ else
++ printf("--mh-type %u ", mhinfo->types[0]);
++}
++
++static struct option opts[] = {
++ { "mh-type", 1, 0, '1' },
++ {0}
++};
++
++static struct ip6tables_match mh = {
++ .name = "mh",
++ .version = IPTABLES_VERSION,
++ .size = IP6T_ALIGN(sizeof(struct ip6t_mh)),
++ .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_mh)),
++ .help = &help,
++ .init = &init,
++ .parse = &parse,
++ .final_check = &final_check,
++ .print = &print,
++ .save = &save,
++ .extra_opts = opts,
++};
++
++void _init(void)
++{
++ register_match6(&mh);
++}
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_mh.man iptables-svn/extensions/libip6t_mh.man
+--- iptables-1.3.7/extensions/libip6t_mh.man 1970-01-01 01:00:00.000000000 +0100
++++ iptables-svn/extensions/libip6t_mh.man 2007-05-31 12:46:30.000000000 +0200
+@@ -0,0 +1,12 @@
++This extension is loaded if `--protocol ipv6-mh' or `--protocol mh' is
++specified. It provides the following option:
++.TP
++.BR "--mh-type " "[!] \fItype\fP[:\fItype\fP]"
++This allows specification of the Mobility Header(MH) type, which can be
++a numeric MH
++.IR type ,
++.IR type
++or one of the MH type names shown by the command
++.nf
++ ip6tables -p ipv6-mh -h
++.fi
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_NFLOG.c iptables-svn/extensions/libip6t_NFLOG.c
+--- iptables-1.3.7/extensions/libip6t_NFLOG.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libip6t_NFLOG.c 2007-05-31 12:46:30.000000000 +0200
+@@ -35,7 +35,7 @@
+ {
+ struct xt_nflog_info *info = (struct xt_nflog_info *)t->data;
+
+- info->group = XT_NFLOG_DEFAULT_GROUP;
++ info->group = 0;
+ info->threshold = XT_NFLOG_DEFAULT_THRESHOLD;
+ }
+
+@@ -56,10 +56,10 @@
+ "Unexpected `!' after --nflog-group");
+
+ n = atoi(optarg);
+- if (n < 1 || n > 32)
++ if (n < 0)
+ exit_error(PARAMETER_PROBLEM,
+- "--nflog-group has to be between 1 and 32");
+- info->group = 1 << (n - 1);
++ "--nflog-group can not be negative");
++ info->group = n;
+ break;
+ case NFLOG_PREFIX:
+ if (*flags & NFLOG_PREFIX)
+@@ -118,8 +118,8 @@
+ {
+ if (info->prefix[0] != '\0')
+ printf("%snflog-prefix \"%s\" ", prefix, info->prefix);
+- if (info->group != XT_NFLOG_DEFAULT_GROUP)
+- printf("%snflog-group %u ", prefix, ffs(info->group));
++ if (info->group)
++ printf("%snflog-group %u ", prefix, info->group);
+ if (info->len)
+ printf("%snflog-range %u ", prefix, info->len);
+ if (info->threshold != XT_NFLOG_DEFAULT_THRESHOLD)
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_nth.c iptables-svn/extensions/libip6t_nth.c
+--- iptables-1.3.7/extensions/libip6t_nth.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libip6t_nth.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,229 +0,0 @@
+-/*
+- Shared library add-on to iptables to add match support for every Nth packet
+-
+- 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
+-
+- 2001-07-17 Fabrice MARIE <fabrice@netfilter.org> : initial development.
+- 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
+- * added support for multiple counters
+- * added support for matching on individual packets
+- in the counter cycle
+-*/
+-
+-#include <stdio.h>
+-#include <netdb.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <syslog.h>
+-#include <getopt.h>
+-#include <ip6tables.h>
+-#include <linux/netfilter_ipv6/ip6_tables.h>
+-#include <linux/netfilter_ipv6/ip6t_nth.h>
+-
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf(
+-"nth v%s options:\n"
+-" --every Nth Match every Nth packet\n"
+-" [--counter] num Use counter 0-%u (default:0)\n"
+-" [--start] num Initialize the counter at the number 'num'\n"
+-" instead of 0. Must be between 0 and Nth-1\n"
+-" [--packet] num Match on 'num' packet. Must be between 0\n"
+-" and Nth-1.\n\n"
+-" If --packet is used for a counter than\n"
+-" there must be Nth number of --packet\n"
+-" rules, covering all values between 0 and\n"
+-" Nth-1 inclusively.\n",
+-IPTABLES_VERSION, IP6T_NTH_NUM_COUNTERS-1);
+-}
+-
+-static struct option opts[] = {
+- { "every", 1, 0, '1' },
+- { "start", 1, 0, '2' },
+- { "counter", 1, 0, '3' },
+- { "packet", 1, 0, '4' },
+- { 0 }
+-};
+-
+-#define IP6T_NTH_OPT_EVERY 0x01
+-#define IP6T_NTH_OPT_NOT_EVERY 0x02
+-#define IP6T_NTH_OPT_START 0x04
+-#define IP6T_NTH_OPT_COUNTER 0x08
+-#define IP6T_NTH_OPT_PACKET 0x10
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-static int
+-parse(int c, char **argv, int invert, unsigned int *flags,
+- const struct ip6t_entry *entry,
+- unsigned int *nfcache,
+- struct ip6t_entry_match **match)
+-{
+- struct ip6t_nth_info *nthinfo = (struct ip6t_nth_info *)(*match)->data;
+- unsigned int num;
+-
+- switch (c) {
+- case '1':
+- /* check for common mistakes... */
+- if ((!invert) && (*flags & IP6T_NTH_OPT_EVERY))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --every twice");
+- if (invert && (*flags & IP6T_NTH_OPT_NOT_EVERY))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify ! --every twice");
+- if ((!invert) && (*flags & IP6T_NTH_OPT_NOT_EVERY))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --every with ! --every");
+- if (invert && (*flags & IP6T_NTH_OPT_EVERY))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify ! --every with --every");
+-
+- /* Remember, this function will interpret a leading 0 to be
+- Octal, a leading 0x to be hexdecimal... */
+- if (string_to_number(optarg, 2, 100, &num) == -1 || num < 2)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --every `%s', must be between 2 and 100", optarg);
+-
+- /* assign the values */
+- nthinfo->every = num-1;
+- nthinfo->startat = 0;
+- nthinfo->packet = 0xFF;
+- if(!(*flags & IP6T_NTH_OPT_EVERY))
+- {
+- nthinfo->counter = 0;
+- }
+- if (invert)
+- {
+- *flags |= IP6T_NTH_OPT_NOT_EVERY;
+- nthinfo->not = 1;
+- }
+- else
+- {
+- *flags |= IP6T_NTH_OPT_EVERY;
+- nthinfo->not = 0;
+- }
+- break;
+- case '2':
+- /* check for common mistakes... */
+- if (!((*flags & IP6T_NTH_OPT_EVERY) ||
+- (*flags & IP6T_NTH_OPT_NOT_EVERY)))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --start before --every");
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify with ! --start");
+- if (*flags & IP6T_NTH_OPT_START)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --start twice");
+- if (string_to_number(optarg, 0, nthinfo->every, &num) == -1)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --start `%s', must between 0 and %u", optarg, nthinfo->every);
+- *flags |= IP6T_NTH_OPT_START;
+- nthinfo->startat = num;
+- break;
+- case '3':
+- /* check for common mistakes... */
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify with ! --counter");
+- if (*flags & IP6T_NTH_OPT_COUNTER)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --counter twice");
+- if (string_to_number(optarg, 0, IP6T_NTH_NUM_COUNTERS-1, &num) == -1)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --counter `%s', must between 0 and %u", optarg, IP6T_NTH_NUM_COUNTERS-1);
+- /* assign the values */
+- *flags |= IP6T_NTH_OPT_COUNTER;
+- nthinfo->counter = num;
+- break;
+- case '4':
+- /* check for common mistakes... */
+- if (!((*flags & IP6T_NTH_OPT_EVERY) ||
+- (*flags & IP6T_NTH_OPT_NOT_EVERY)))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --packet before --every");
+- if ((*flags & IP6T_NTH_OPT_NOT_EVERY))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --packet with ! --every");
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify with ! --packet");
+- if (*flags & IP6T_NTH_OPT_PACKET)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --packet twice");
+- if (string_to_number(optarg, 0, nthinfo->every, &num) == -1)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --packet `%s', must between 0 and %u", optarg, nthinfo->every);
+- *flags |= IP6T_NTH_OPT_PACKET;
+- nthinfo->packet = num;
+- break;
+- default:
+- return 0;
+- }
+- return 1;
+-}
+-
+-/* Final check; nothing. */
+-static void final_check(unsigned int flags)
+-{
+-}
+-
+-/* Prints out the targinfo. */
+-static void
+-print(const struct ip6t_ip6 *ip,
+- const struct ip6t_entry_match *match,
+- int numeric)
+-{
+- const struct ip6t_nth_info *nthinfo
+- = (const struct ip6t_nth_info *)match->data;
+-
+- if (nthinfo->not == 1)
+- printf(" !");
+- printf("every %uth ", (nthinfo->every +1));
+- if (nthinfo->counter != 0)
+- printf("counter #%u ", (nthinfo->counter));
+- if (nthinfo->packet != 0xFF)
+- printf("packet #%u ", nthinfo->packet);
+- if (nthinfo->startat != 0)
+- printf("start at %u ", nthinfo->startat);
+-}
+-
+-/* Saves the union ip6t_targinfo in parsable form to stdout. */
+-static void
+-save(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match)
+-{
+- const struct ip6t_nth_info *nthinfo
+- = (const struct ip6t_nth_info *)match->data;
+-
+- if (nthinfo->not == 1)
+- printf("! ");
+- printf("--every %u ", (nthinfo->every +1));
+- printf("--counter %u ", (nthinfo->counter));
+- if (nthinfo->startat != 0)
+- printf("--start %u ", nthinfo->startat );
+- if (nthinfo->packet != 0xFF)
+- printf("--packet %u ", nthinfo->packet );
+-}
+-
+-struct ip6tables_match nth = {
+- .name = "nth",
+- .version = IPTABLES_VERSION,
+- .size = IP6T_ALIGN(sizeof(struct ip6t_nth_info)),
+- .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_nth_info)),
+- .help = &help,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts,
+-};
+-
+-void _init(void)
+-{
+- register_match6(&nth);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_nth.man iptables-svn/extensions/libip6t_nth.man
+--- iptables-1.3.7/extensions/libip6t_nth.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libip6t_nth.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,14 +0,0 @@
+-This module matches every `n'th packet
+-.TP
+-.BI "--every " "value"
+-Match every `value' packet
+-.TP
+-.BI "[" "--counter " "num" "]"
+-Use internal counter number `num'. Default is `0'.
+-.TP
+-.BI "[" "--start " "num" "]"
+-Initialize the counter at the number `num' insetad of `0'. Most between `0'
+-and `value'-1.
+-.TP
+-.BI "[" "--packet " "num" "]"
+-Match on `num' packet. Most be between `0' and `value'-1.
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_random.c iptables-svn/extensions/libip6t_random.c
+--- iptables-1.3.7/extensions/libip6t_random.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libip6t_random.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,150 +0,0 @@
+-/*
+- Shared library add-on to iptables to add match support for random match.
+-
+- 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
+-
+- 2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial development.
+- 2003-04-30 Maciej Soltysiak <solt@dns.toxicfilms.tv> : IPv6 port.
+-*/
+-
+-#include <stdio.h>
+-#include <netdb.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <syslog.h>
+-#include <getopt.h>
+-#include <ip6tables.h>
+-#include <linux/netfilter_ipv6/ip6_tables.h>
+-#include <linux/netfilter_ipv6/ip6t_random.h>
+-
+-/**
+- * The kernel random routing returns numbers between 0 and 255.
+- * To ease the task of the user in choosing the probability
+- * of matching, we want him to be able to use percentages.
+- * Therefore we have to accept numbers in percentage here,
+- * turn them into number between 0 and 255 for the kernel module,
+- * and turn them back to percentages when we print/save
+- * the rule.
+- */
+-
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf(
+-"random v%s options:\n"
+-" [--average] percent The probability in percentage of the match\n"
+-" If ommited, a probability of 50%% percent is set.\n"
+-" Percentage must be within : 1 <= percent <= 99.\n\n",
+-IPTABLES_VERSION);
+-}
+-
+-static struct option opts[] = {
+- { "average", 1, 0, '1' },
+- { 0 }
+-};
+-
+-/* Initialize the target. */
+-static void
+-init(struct ip6t_entry_match *m, unsigned int *nfcache)
+-{
+- struct ip6t_rand_info *randinfo = (struct ip6t_rand_info *)(m)->data;
+-
+- /* We assign the average to be 50 which is our default value */
+- /* 50 * 2.55 = 128 */
+- randinfo->average = 128;
+-}
+-
+-#define IP6T_RAND_OPT_AVERAGE 0x01
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-static int
+-parse(int c, char **argv, int invert, unsigned int *flags,
+- const struct ip6t_entry *entry,
+- unsigned int *nfcache,
+- struct ip6t_entry_match **match)
+-{
+- struct ip6t_rand_info *randinfo = (struct ip6t_rand_info *)(*match)->data;
+- unsigned int num;
+-
+- switch (c) {
+- case '1':
+- /* check for common mistakes... */
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify ! --average");
+- if (*flags & IP6T_RAND_OPT_AVERAGE)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --average twice");
+-
+- /* Remember, this function will interpret a leading 0 to be
+- Octal, a leading 0x to be hexdecimal... */
+- if (string_to_number(optarg, 1, 99, &num) == -1 || num < 1)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --average `%s', must be between 1 and 99", optarg);
+-
+- /* assign the values */
+- randinfo->average = (int)(num * 2.55);
+- *flags |= IP6T_RAND_OPT_AVERAGE;
+- break;
+- default:
+- return 0;
+- }
+- return 1;
+-}
+-
+-/* Final check; nothing. */
+-static void final_check(unsigned int flags)
+-{
+-}
+-
+-/* Prints out the targinfo. */
+-static void
+-print(const struct ip6t_ip6 *ip,
+- const struct ip6t_entry_match *match,
+- int numeric)
+-{
+- const struct ip6t_rand_info *randinfo
+- = (const struct ip6t_rand_info *)match->data;
+- div_t result = div((randinfo->average*100), 255);
+- if (result.rem > 127) /* round up... */
+- ++result.quot;
+-
+- printf(" random %u%% ", result.quot);
+-}
+-
+-/* Saves the union ip6t_targinfo in parsable form to stdout. */
+-static void
+-save(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match)
+-{
+- const struct ip6t_rand_info *randinfo
+- = (const struct ip6t_rand_info *)match->data;
+- div_t result = div((randinfo->average *100), 255);
+- if (result.rem > 127) /* round up... */
+- ++result.quot;
+-
+- printf("--average %u ", result.quot);
+-}
+-
+-struct ip6tables_match rand_match = {
+- .name = "random",
+- .version = IPTABLES_VERSION,
+- .size = IP6T_ALIGN(sizeof(struct ip6t_rand_info)),
+- .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_rand_info)),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts,
+-};
+-
+-void _init(void)
+-{
+- register_match6(&rand_match);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_random.man iptables-svn/extensions/libip6t_random.man
+--- iptables-1.3.7/extensions/libip6t_random.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libip6t_random.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,4 +0,0 @@
+-This module randomly matches a certain percentage of all packets.
+-.TP
+-.BI "--average " "percent"
+-Matches the given percentage. If omitted, a probability of 50% is set.
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_ROUTE.c iptables-svn/extensions/libip6t_ROUTE.c
+--- iptables-1.3.7/extensions/libip6t_ROUTE.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libip6t_ROUTE.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,240 +0,0 @@
+-/* Shared library add-on to iptables to add ROUTE v6 target support.
+- * Author : Cedric de Launois, <delaunois@info.ucl.ac.be>
+- * v 1.1 2004/11/23
+- */
+-
+-#include <stdio.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <getopt.h>
+-#include <sys/types.h>
+-#include <sys/socket.h>
+-#include <arpa/inet.h>
+-
+-#include <ip6tables.h>
+-#include <linux/netfilter_ipv6/ip6_tables.h>
+-#include <linux/netfilter_ipv6/ip6t_ROUTE.h>
+-
+-/* compile IP6T_ROUTE_TEE support even if kernel headers are unpatched */
+-#ifndef IP6T_ROUTE_TEE
+-#define IP6T_ROUTE_TEE 0x02
+-#endif
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf(
+-"ROUTE target v%s options:\n"
+-" --oif \tifname \t\tRoute the packet through `ifname' network interface\n"
+-" --gw \tip \t\tRoute the packet via this gateway\n"
+-" --continue\t \t\tRoute packet and continue traversing the\n"
+-" \t \t\trules. Not valid with --iif or --tee.\n"
+-" --tee\t \t\tDuplicate packet, route the duplicate,\n"
+-" \t \t\tcontinue traversing with original packet.\n"
+-" \t \t\tNot valid with --iif or --continue.\n"
+-"\n",
+-"1.1");
+-}
+-
+-static struct option opts[] = {
+- { "oif", 1, 0, '1' },
+- { "iif", 1, 0, '2' },
+- { "gw", 1, 0, '3' },
+- { "continue", 0, 0, '4' },
+- { "tee", 0, 0, '5' },
+- { 0 }
+-};
+-
+-/* Initialize the target. */
+-static void
+-init(struct ip6t_entry_target *t, unsigned int *nfcache)
+-{
+- struct ip6t_route_target_info *route_info =
+- (struct ip6t_route_target_info*)t->data;
+-
+- route_info->oif[0] = '\0';
+- route_info->iif[0] = '\0';
+- route_info->gw[0] = 0;
+- route_info->gw[1] = 0;
+- route_info->gw[2] = 0;
+- route_info->gw[3] = 0;
+- route_info->flags = 0;
+-}
+-
+-
+-#define IP6T_ROUTE_OPT_OIF 0x01
+-#define IP6T_ROUTE_OPT_IIF 0x02
+-#define IP6T_ROUTE_OPT_GW 0x04
+-#define IP6T_ROUTE_OPT_CONTINUE 0x08
+-#define IP6T_ROUTE_OPT_TEE 0x10
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-static int
+-parse(int c, char **argv, int invert, unsigned int *flags,
+- const struct ip6t_entry *entry,
+- struct ip6t_entry_target **target)
+-{
+- struct ip6t_route_target_info *route_info =
+- (struct ip6t_route_target_info*)(*target)->data;
+-
+- switch (c) {
+- case '1':
+- if (*flags & IP6T_ROUTE_OPT_OIF)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --oif twice");
+-
+- if (check_inverse(optarg, &invert, NULL, 0))
+- exit_error(PARAMETER_PROBLEM,
+- "Unexpected `!' after --oif");
+-
+- if (strlen(optarg) > sizeof(route_info->oif) - 1)
+- exit_error(PARAMETER_PROBLEM,
+- "Maximum interface name length %u",
+- sizeof(route_info->oif) - 1);
+-
+- strcpy(route_info->oif, optarg);
+- *flags |= IP6T_ROUTE_OPT_OIF;
+- break;
+-
+- case '2':
+- exit_error(PARAMETER_PROBLEM,
+- "--iif option not implemented");
+- break;
+-
+- case '3':
+- if (*flags & IP6T_ROUTE_OPT_GW)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --gw twice");
+-
+- if (check_inverse(optarg, &invert, NULL, 0))
+- exit_error(PARAMETER_PROBLEM,
+- "Unexpected `!' after --gw");
+-
+- if (!inet_pton(AF_INET6, optarg, (struct in6_addr*)&route_info->gw)) {
+- exit_error(PARAMETER_PROBLEM,
+- "Invalid IPv6 address %s",
+- optarg);
+- }
+-
+- *flags |= IP6T_ROUTE_OPT_GW;
+- break;
+-
+- case '4':
+- if (*flags & IP6T_ROUTE_OPT_CONTINUE)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --continue twice");
+- if (*flags & IP6T_ROUTE_OPT_TEE)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --continue AND --tee");
+-
+- route_info->flags |= IP6T_ROUTE_CONTINUE;
+- *flags |= IP6T_ROUTE_OPT_CONTINUE;
+-
+- break;
+-
+- case '5':
+- if (*flags & IP6T_ROUTE_OPT_TEE)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --tee twice");
+- if (*flags & IP6T_ROUTE_OPT_CONTINUE)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --tee AND --continue");
+-
+- route_info->flags |= IP6T_ROUTE_TEE;
+- *flags |= IP6T_ROUTE_OPT_TEE;
+-
+- break;
+-
+- default:
+- return 0;
+- }
+-
+- return 1;
+-}
+-
+-
+-static void
+-final_check(unsigned int flags)
+-{
+- if (!flags)
+- exit_error(PARAMETER_PROBLEM,
+- "ROUTE target: oif or gw option required");
+-}
+-
+-
+-/* Prints out the targinfo. */
+-static void
+-print(const struct ip6t_ip6 *ip,
+- const struct ip6t_entry_target *target,
+- int numeric)
+-{
+- const struct ip6t_route_target_info *route_info
+- = (const struct ip6t_route_target_info *)target->data;
+-
+- printf("ROUTE ");
+-
+- if (route_info->oif[0])
+- printf("oif:%s ", route_info->oif);
+-
+- if (route_info->gw[0]
+- || route_info->gw[1]
+- || route_info->gw[2]
+- || route_info->gw[3]) {
+- char address[INET6_ADDRSTRLEN];
+- printf("gw:%s ", inet_ntop(AF_INET6, route_info->gw, address, INET6_ADDRSTRLEN));
+- }
+-
+- if (route_info->flags & IP6T_ROUTE_CONTINUE)
+- printf("continue");
+-
+- if (route_info->flags & IP6T_ROUTE_TEE)
+- printf("tee");
+-
+-}
+-
+-
+-static void save(const struct ip6t_ip6 *ip,
+- const struct ip6t_entry_target *target)
+-{
+- const struct ip6t_route_target_info *route_info
+- = (const struct ip6t_route_target_info *)target->data;
+-
+- if (route_info->oif[0])
+- printf("--oif %s ", route_info->oif);
+-
+- if (route_info->gw[0]
+- || route_info->gw[1]
+- || route_info->gw[2]
+- || route_info->gw[3]) {
+- char address[INET6_ADDRSTRLEN];
+- printf("--gw %s ", inet_ntop(AF_INET6, route_info->gw, address, INET6_ADDRSTRLEN));
+- }
+-
+- if (route_info->flags & IP6T_ROUTE_CONTINUE)
+- printf("--continue ");
+-
+- if (route_info->flags & IP6T_ROUTE_TEE)
+- printf("--tee ");
+-}
+-
+-
+-static struct ip6tables_target route = {
+- .name = "ROUTE",
+- .version = IPTABLES_VERSION,
+- .size = IP6T_ALIGN(sizeof(struct ip6t_route_target_info)),
+- .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_route_target_info)),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts,
+-};
+-
+-void _init(void)
+-{
+- register_target6(&route);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_ROUTE.man iptables-svn/extensions/libip6t_ROUTE.man
+--- iptables-1.3.7/extensions/libip6t_ROUTE.man 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libip6t_ROUTE.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,15 +0,0 @@
+-This is used to explicitly override the core network stack's routing decision.
+-.B mangle
+-table.
+-.TP
+-.BI "--oif " "ifname"
+-Route the packet through `ifname' network interface
+-.TP
+-.BI "--gw " "IPv6_address"
+-Route the packet via this gateway
+-.TP
+-.BI "--continue "
+-Behave like a non-terminating target and continue traversing the rules. Not valid in combination with `--tee'
+-.TP
+-.BI "--tee "
+-Make a copy of the packet, and route that copy to the given destination. For the original, uncopied packet, behave like a non-terminating target and continue traversing the rules. Not valid in combination with `--continue'
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_state.c iptables-svn/extensions/libip6t_state.c
+--- iptables-1.3.7/extensions/libip6t_state.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libip6t_state.c 2007-05-31 12:46:30.000000000 +0200
+@@ -5,7 +5,7 @@
+ #include <stdlib.h>
+ #include <getopt.h>
+ #include <ip6tables.h>
+-#include <linux/netfilter_ipv4/ip_conntrack.h>
++#include <linux/netfilter/nf_conntrack_common.h>
+ #include <linux/netfilter_ipv4/ipt_state.h>
+
+ #ifndef IPT_STATE_UNTRACKED
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_tcp.man iptables-svn/extensions/libip6t_tcp.man
+--- iptables-1.3.7/extensions/libip6t_tcp.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libip6t_tcp.man 2007-05-31 12:46:30.000000000 +0200
+@@ -1,4 +1,4 @@
+-These extensions are loaded if `--protocol tcp' is specified. It
++These extensions can be used if `--protocol tcp' is specified. It
+ provides the following options:
+ .TP
+ .BR "--source-port " "[!] \fIport\fP[:\fIport\fP]"
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_TCPMSS.c iptables-svn/extensions/libip6t_TCPMSS.c
+--- iptables-1.3.7/extensions/libip6t_TCPMSS.c 1970-01-01 01:00:00.000000000 +0100
++++ iptables-svn/extensions/libip6t_TCPMSS.c 2007-05-31 12:46:30.000000000 +0200
+@@ -0,0 +1,134 @@
++/* Shared library add-on to iptables to add TCPMSS target support.
++ *
++ * Copyright (c) 2000 Marc Boucher
++*/
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++#include <getopt.h>
++
++#include <ip6tables.h>
++#include <linux/netfilter_ipv6/ip6_tables.h>
++#include <linux/netfilter_ipv6/ip6t_TCPMSS.h>
++
++struct mssinfo {
++ struct ip6t_entry_target t;
++ struct ip6t_tcpmss_info mss;
++};
++
++/* Function which prints out usage message. */
++static void
++help(void)
++{
++ printf(
++"TCPMSS target v%s mutually-exclusive options:\n"
++" --set-mss value explicitly set MSS option to specified value\n"
++" --clamp-mss-to-pmtu automatically clamp MSS value to (path_MTU - 60)\n",
++IPTABLES_VERSION);
++}
++
++static struct option opts[] = {
++ { "set-mss", 1, 0, '1' },
++ { "clamp-mss-to-pmtu", 0, 0, '2' },
++ { 0 }
++};
++
++/* Initialize the target. */
++static void
++init(struct ip6t_entry_target *t, unsigned int *nfcache)
++{
++}
++
++/* Function which parses command options; returns true if it
++ ate an option */
++static int
++parse(int c, char **argv, int invert, unsigned int *flags,
++ const struct ip6t_entry *entry,
++ struct ip6t_entry_target **target)
++{
++ struct ip6t_tcpmss_info *mssinfo
++ = (struct ip6t_tcpmss_info *)(*target)->data;
++
++ switch (c) {
++ unsigned int mssval;
++
++ case '1':
++ if (*flags)
++ exit_error(PARAMETER_PROBLEM,
++ "TCPMSS target: Only one option may be specified");
++ if (string_to_number(optarg, 0, 65535 - 60, &mssval) == -1)
++ exit_error(PARAMETER_PROBLEM, "Bad TCPMSS value `%s'", optarg);
++
++ mssinfo->mss = mssval;
++ *flags = 1;
++ break;
++
++ case '2':
++ if (*flags)
++ exit_error(PARAMETER_PROBLEM,
++ "TCPMSS target: Only one option may be specified");
++ mssinfo->mss = IP6T_TCPMSS_CLAMP_PMTU;
++ *flags = 1;
++ break;
++
++ default:
++ return 0;
++ }
++
++ return 1;
++}
++
++static void
++final_check(unsigned int flags)
++{
++ if (!flags)
++ exit_error(PARAMETER_PROBLEM,
++ "TCPMSS target: At least one parameter is required");
++}
++
++/* Prints out the targinfo. */
++static void
++print(const struct ip6t_ip6 *ip6,
++ const struct ip6t_entry_target *target,
++ int numeric)
++{
++ const struct ip6t_tcpmss_info *mssinfo =
++ (const struct ip6t_tcpmss_info *)target->data;
++ if(mssinfo->mss == IP6T_TCPMSS_CLAMP_PMTU)
++ printf("TCPMSS clamp to PMTU ");
++ else
++ printf("TCPMSS set %u ", mssinfo->mss);
++}
++
++/* Saves the union ip6t_targinfo in parsable form to stdout. */
++static void
++save(const struct ip6t_ip6 *ip, const struct ip6t_entry_target *target)
++{
++ const struct ip6t_tcpmss_info *mssinfo =
++ (const struct ip6t_tcpmss_info *)target->data;
++
++ if(mssinfo->mss == IP6T_TCPMSS_CLAMP_PMTU)
++ printf("--clamp-mss-to-pmtu ");
++ else
++ printf("--set-mss %u ", mssinfo->mss);
++}
++
++static struct ip6tables_target mss = {
++ .next = NULL,
++ .name = "TCPMSS",
++ .version = IPTABLES_VERSION,
++ .size = IP6T_ALIGN(sizeof(struct ip6t_tcpmss_info)),
++ .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_tcpmss_info)),
++ .help = &help,
++ .init = &init,
++ .parse = &parse,
++ .final_check = &final_check,
++ .print = &print,
++ .save = &save,
++ .extra_opts = opts
++};
++
++void _init(void)
++{
++ register_target6(&mss);
++}
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_TCPMSS.man iptables-svn/extensions/libip6t_TCPMSS.man
+--- iptables-1.3.7/extensions/libip6t_TCPMSS.man 1970-01-01 01:00:00.000000000 +0100
++++ iptables-svn/extensions/libip6t_TCPMSS.man 2007-05-31 12:46:30.000000000 +0200
+@@ -0,0 +1,42 @@
++This target allows 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 60). Of course, it can only be used
++in conjunction with
++.BR "-p tcp" .
++It is only valid in the
++.BR mangle
++table.
++.br
++This target is used to overcome criminally braindead ISPs or servers
++which block ICMPv6 Packet Too Big packets or are unable to send them.
++The symptoms of this problem are that everything works fine from your
++Linux firewall/router, but machines behind it can never exchange large
++packets:
++.PD 0
++.RS 0.1i
++.TP 0.3i
++1)
++Web browsers connect, then hang with no data received.
++.TP
++2)
++Small mail works fine, but large emails hang.
++.TP
++3)
++ssh works fine, but scp hangs after initial handshaking.
++.RE
++.PD
++Workaround: activate this option and add a rule to your firewall
++configuration like:
++.nf
++ ip6tables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \\
++ -j TCPMSS --clamp-mss-to-pmtu
++.fi
++.TP
++.BI "--set-mss " "value"
++Explicitly set MSS option to specified value.
++.TP
++.B "--clamp-mss-to-pmtu"
++Automatically clamp MSS value to (path_MTU - 60).
++.TP
++These options are mutually exclusive.
++
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_TRACE.c iptables-svn/extensions/libip6t_TRACE.c
+--- iptables-1.3.7/extensions/libip6t_TRACE.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libip6t_TRACE.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,63 +0,0 @@
+-/* Shared library add-on to iptables to add TRACE target support. */
+-#include <stdio.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <getopt.h>
+-
+-#include <ip6tables.h>
+-#include <linux/netfilter_ipv6/ip6_tables.h>
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf(
+-"TRACE target v%s takes no options\n",
+-IPTABLES_VERSION);
+-}
+-
+-static struct option opts[] = {
+- { 0 }
+-};
+-
+-/* Initialize the target. */
+-static void
+-init(struct ip6t_entry_target *t, unsigned int *nfcache)
+-{
+-}
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-static int
+-parse(int c, char **argv, int invert, unsigned int *flags,
+- const struct ip6t_entry *entry,
+- struct ip6t_entry_target **target)
+-{
+- return 0;
+-}
+-
+-static void
+-final_check(unsigned int flags)
+-{
+-}
+-
+-static
+-struct ip6tables_target trace
+-= { .next = NULL,
+- .name = "TRACE",
+- .version = IPTABLES_VERSION,
+- .size = IP6T_ALIGN(0),
+- .userspacesize = IP6T_ALIGN(0),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = NULL, /* print */
+- .save = NULL, /* save */
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_target6(&trace);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_TRACE.man iptables-svn/extensions/libip6t_TRACE.man
+--- iptables-1.3.7/extensions/libip6t_TRACE.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libip6t_TRACE.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,3 +0,0 @@
+-This target has no options. It just turns on
+-.B packet tracing
+-for all packets that match this rule.
+diff -x .svn -Nur iptables-1.3.7/extensions/libip6t_udp.man iptables-svn/extensions/libip6t_udp.man
+--- iptables-1.3.7/extensions/libip6t_udp.man 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libip6t_udp.man 2007-05-31 12:46:30.000000000 +0200
+@@ -1,4 +1,4 @@
+-These extensions are loaded if `--protocol udp' is specified. It
++These extensions can be used if `--protocol udp' is specified. It
+ provides the following options:
+ .TP
+ .BR "--source-port " "[!] \fIport\fP[:\fIport\fP]"
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_account.c iptables-svn/extensions/libipt_account.c
+--- iptables-1.3.7/extensions/libipt_account.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_account.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,277 +0,0 @@
+-/*
+- * accounting match helper (libipt_account.c)
+- * (C) 2003,2004 by Piotr Gasid³o (quaker@barbara.eu.org)
+- *
+- * Version: 0.1.6
+- *
+- * This software is distributed under the terms of GNU GPL
+- */
+-
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <iptables.h>
+-#include <string.h>
+-#include <getopt.h>
+-
+-#include <linux/netfilter_ipv4/ipt_account.h>
+-
+-#ifndef HIPQUAD
+-#define HIPQUAD(addr) \
+- ((unsigned char *)&addr)[3], \
+- ((unsigned char *)&addr)[2], \
+- ((unsigned char *)&addr)[1], \
+- ((unsigned char *)&addr)[0]
+-#endif
+-
+-static void help(void) {
+- printf(
+- "account v%s options:\n"
+- "--aaddr network/netmask\n"
+- " defines network/netmask for which make statistics.\n"
+- "--aname name\n"
+- " defines name of list where statistics will be kept. If no is\n"
+- " specified DEFAULT will be used.\n"
+- "--ashort\n"
+- " table will colect only short statistics (only total counters\n"
+- " without splitting it into protocols.\n"
+- ,
+- IPTABLES_VERSION);
+-};
+-
+-static struct option opts[] = {
+- { .name = "aaddr", .has_arg = 1, .flag = NULL, .val = 201 },
+- { .name = "aname", .has_arg = 1, .flag = NULL, .val = 202 },
+- { .name = "ashort", .has_arg = 0, .flag = NULL, .val = 203 },
+- { .name = 0, .has_arg = 0, .flag = 0, .val = 0 }
+-};
+-
+-/* Helper functions for parse_network */
+-int parseip(const char *parameter, u_int32_t *ip) {
+-
+- char buffer[16], *bufferptr, *dot;
+- unsigned int i, shift, part;
+-
+- if (strlen(parameter) > 15)
+- return 0;
+-
+- strncpy(buffer, parameter, 15);
+- buffer[15] = 0;
+-
+- bufferptr = buffer;
+-
+- for (i = 0, shift = 24, *ip = 0; i < 3; i++, shift -= 8) {
+- /* no dot */
+- if ((dot = strchr(bufferptr, '.')) == NULL)
+- return 0;
+- /* not a number */
+- if ((part = strtol(bufferptr, (char**)NULL, 10)) < 0)
+- return 0;
+- /* to big number */
+- if (part > 255)
+- return 0;
+- *ip |= part << shift;
+- bufferptr = dot + 1;
+- }
+- /* not a number */
+- if ((part = strtol(bufferptr, (char**)NULL, 10)) < 0)
+- return 0;
+- /* to big number */
+- if (part > 255)
+- return 0;
+- *ip |= part;
+- return 1;
+-}
+-
+-static void parsenetwork(const char *parameter, u_int32_t *network) {
+- if (!parseip(parameter, network))
+- exit_error(PARAMETER_PROBLEM, "account: wrong ip in network");
+-}
+-
+-static void parsenetmaskasbits(const char *parameter, u_int32_t *netmask) {
+-
+- u_int32_t bits;
+-
+- if ((bits = strtol(parameter, (char **)NULL, 10)) < 0 || bits > 32)
+- exit_error(PARAMETER_PROBLEM, "account: wrong netmask");
+-
+- *netmask = 0xffffffff << (32 - bits);
+-}
+-
+-static void parsenetmaskasip(const char *parameter, u_int32_t *netmask) {
+- if (!parseip(parameter, netmask))
+- exit_error(PARAMETER_PROBLEM, "account: wrong ip in netmask");
+-}
+-
+-static void parsenetmask(const char *parameter, u_int32_t *netmask)
+-{
+- if (strchr(parameter, '.') != NULL)
+- parsenetmaskasip(parameter, netmask);
+- else
+- parsenetmaskasbits(parameter, netmask);
+-}
+-
+-static void parsenetworkandnetmask(const char *parameter, u_int32_t *network, u_int32_t *netmask)
+-{
+-
+- char buffer[32], *slash;
+-
+- if (strlen(parameter) > 31)
+- /* text is to long, even for 255.255.255.255/255.255.255.255 */
+- exit_error(PARAMETER_PROBLEM, "account: wrong network/netmask");
+-
+- strncpy(buffer, parameter, 31);
+- buffer[31] = 0;
+-
+- /* check whether netmask is given */
+- if ((slash = strchr(buffer, '/')) != NULL) {
+- parsenetmask(slash + 1, netmask);
+- *slash = 0;
+- } else
+- *netmask = 0xffffffff;
+- parsenetwork(buffer, network);
+-
+- if ((*network & *netmask) != *network)
+- exit_error(PARAMETER_PROBLEM, "account: wrong network/netmask");
+-}
+-
+-
+-/* Function gets network & netmask from argument after --aaddr */
+-static void parse_network(const char *parameter, struct t_ipt_account_info *info) {
+-
+- parsenetworkandnetmask(parameter, &info->network, &info->netmask);
+-
+-}
+-
+-/* validate netmask */
+-inline int valid_netmask(u_int32_t netmask) {
+- while (netmask & 0x80000000)
+- netmask <<= 1;
+- if (netmask != 0)
+- return 0;
+- return 1;
+-}
+-
+-/* validate network/netmask pair */
+-inline int valid_network_and_netmask(struct t_ipt_account_info *info) {
+- if (!valid_netmask(info->netmask))
+- return 0;
+- if ((info->network & info->netmask) != info->network)
+- return 0;
+- return 1;
+-}
+-
+-
+-
+-/* Function initializes match */
+-static void init(struct ipt_entry_match *match,
+- unsigned int *nfcache) {
+-
+- struct t_ipt_account_info *info = (struct t_ipt_account_info *)(match)->data;
+-
+-
+- /* set default table name to DEFAULT */
+- strncpy(info->name, "DEFAULT", IPT_ACCOUNT_NAME_LEN);
+- info->shortlisting = 0;
+-
+-}
+-
+-/* Function parses match's arguments */
+-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) {
+-
+- struct t_ipt_account_info *info = (struct t_ipt_account_info *)(*match)->data;
+-
+- switch (c) {
+-
+- /* --aaddr */
+- case 201:
+- parse_network(optarg, info);
+- if (!valid_network_and_netmask(info))
+- exit_error(PARAMETER_PROBLEM, "account: wrong network/netmask");
+- *flags = 1;
+- break;
+-
+- /* --aname */
+- case 202:
+- if (strlen(optarg) < IPT_ACCOUNT_NAME_LEN)
+- strncpy(info->name, optarg, IPT_ACCOUNT_NAME_LEN);
+- else
+- exit_error(PARAMETER_PROBLEM, "account: Too long table name");
+- break;
+- /* --ashort */
+- case 203:
+- info->shortlisting = 1;
+- break;
+- default:
+- return 0;
+- }
+- return 1;
+-}
+-
+-/* Final check whether network/netmask was specified */
+-static void final_check(unsigned int flags) {
+- if (!flags)
+- exit_error(PARAMETER_PROBLEM, "account: You need specify '--aaddr' parameter");
+-}
+-
+-/* Function used for printing rule with account match for iptables -L */
+-static void print(const struct ipt_ip *ip,
+- const struct ipt_entry_match *match,
+- int numeric) {
+-
+- struct t_ipt_account_info *info = (struct t_ipt_account_info *)match->data;
+-
+- printf("account: ");
+- printf("network/netmask: ");
+- printf("%u.%u.%u.%u/%u.%u.%u.%u ",
+- HIPQUAD(info->network),
+- HIPQUAD(info->netmask)
+- );
+-
+- printf("name: %s ", info->name);
+- if (info->shortlisting)
+- printf("short-listing ");
+-}
+-
+-/* Function used for saving rule containing account match */
+-static void save(const struct ipt_ip *ip,
+- const struct ipt_entry_match *match) {
+-
+- struct t_ipt_account_info *info = (struct t_ipt_account_info *)match->data;
+-
+- printf("--aaddr ");
+- printf("%u.%u.%u.%u/%u.%u.%u.%u ",
+- HIPQUAD(info->network),
+- HIPQUAD(info->netmask)
+- );
+-
+- printf("--aname %s ", info->name);
+- if (info->shortlisting)
+- printf("--ashort ");
+-}
+-
+-static struct iptables_match account = {
+- .next = NULL,
+- .name = "account",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct t_ipt_account_info)),
+- .userspacesize = IPT_ALIGN(sizeof(struct t_ipt_account_info)),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-/* Function which registers match */
+-void _init(void)
+-{
+- register_match(&account);
+-}
+-
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_account.man iptables-svn/extensions/libipt_account.man
+--- iptables-1.3.7/extensions/libipt_account.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_account.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,47 +0,0 @@
+-Account traffic for all hosts in defined network/netmask.
+-
+-Features:
+-
+-- long (one counter per protocol TCP/UDP/IMCP/Other) and short statistics
+-
+-- one iptables rule for all hosts in network/netmask
+-
+-- loading/saving counters (by reading/writting to procfs entries)
+-
+-.TP
+-.BI "--aaddr " "network/netmask"
+-defines network/netmask for which make statistics.
+-.TP
+-.BI "--aname " "name"
+-defines name of list where statistics will be kept. If no is
+-specified DEFAULT will be used.
+-.TP
+-.B "--ashort"
+-table will colect only short statistics (only total counters
+-without splitting it into protocols.
+-.P
+-Example usage:
+-
+-account traffic for/to 192.168.0.0/24 network into table mynetwork:
+-
+-# iptables -A FORWARD -m account --aname mynetwork --aaddr 192.168.0.0/24
+-
+-account traffic for/to WWW serwer for 192.168.0.0/24 network into table mywwwserver:
+-
+-# iptables -A INPUT -p tcp --dport 80
+- -m account --aname mywwwserver --aaddr 192.168.0.0/24 --ashort
+-
+-# iptables -A OUTPUT -p tcp --sport 80
+- -m account --aname mywwwserver --aaddr 192.168.0.0/24 --ashort
+-
+-read counters:
+-
+-# cat /proc/net/ipt_account/mynetwork
+-# cat /proc/net/ipt_account/mywwwserver
+-
+-set counters:
+-
+-# echo "ip = 192.168.0.1 packets_src = 0" > /proc/net/ipt_account/mywwserver
+-
+-Webpage:
+- http://www.barbara.eu.org/~quaker/ipt_account/
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_BALANCE.c iptables-svn/extensions/libipt_BALANCE.c
+--- iptables-1.3.7/extensions/libipt_BALANCE.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_BALANCE.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,150 +0,0 @@
+-/* Shared library add-on to iptables to add simple load-balance support. */
+-#include <stdio.h>
+-#include <netdb.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <getopt.h>
+-#include <iptables.h>
+-#include <linux/netfilter_ipv4/ip_tables.h>
+-#include <linux/netfilter_ipv4/ip_nat_rule.h>
+-
+-#define BREAKUP_IP(x) (x)>>24, ((x)>>16) & 0xFF, ((x)>>8) & 0xFF, (x) & 0xFF
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf(
+-"BALANCE v%s options:\n"
+-" --to-destination <ipaddr>-<ipaddr>\n"
+-" Addresses to map destination to.\n",
+-IPTABLES_VERSION);
+-}
+-
+-static struct option opts[] = {
+- { "to-destination", 1, 0, '1' },
+- { 0 }
+-};
+-
+-/* Initialize the target. */
+-static void
+-init(struct ipt_entry_target *t, unsigned int *nfcache)
+-{
+- struct ip_nat_multi_range *mr = (struct ip_nat_multi_range *)t->data;
+-
+- /* Actually, it's 0, but it's ignored at the moment. */
+- mr->rangesize = 1;
+-
+-}
+-
+-/* Parses range of IPs */
+-static void
+-parse_to(char *arg, struct ip_nat_range *range)
+-{
+- char *dash;
+- struct in_addr *ip;
+-
+- range->flags |= IP_NAT_RANGE_MAP_IPS;
+- dash = strchr(arg, '-');
+- if (dash)
+- *dash = '\0';
+- else
+- exit_error(PARAMETER_PROBLEM, "Bad IP range `%s'\n", arg);
+-
+- ip = dotted_to_addr(arg);
+- if (!ip)
+- exit_error(PARAMETER_PROBLEM, "Bad IP address `%s'\n",
+- arg);
+- range->min_ip = ip->s_addr;
+- ip = dotted_to_addr(dash+1);
+- if (!ip)
+- exit_error(PARAMETER_PROBLEM, "Bad IP address `%s'\n",
+- dash+1);
+- range->max_ip = ip->s_addr;
+-}
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-static int
+-parse(int c, char **argv, int invert, unsigned int *flags,
+- const struct ipt_entry *entry,
+- struct ipt_entry_target **target)
+-{
+- struct ip_nat_multi_range *mr
+- = (struct ip_nat_multi_range *)(*target)->data;
+-
+- switch (c) {
+- case '1':
+- if (check_inverse(optarg, &invert, NULL, 0))
+- exit_error(PARAMETER_PROBLEM,
+- "Unexpected `!' after --to-destination");
+-
+- parse_to(optarg, &mr->range[0]);
+- *flags = 1;
+- return 1;
+-
+- default:
+- return 0;
+- }
+-}
+-
+-/* Final check; need --to-dest. */
+-static void final_check(unsigned int flags)
+-{
+- if (!flags)
+- exit_error(PARAMETER_PROBLEM,
+- "BALANCE needs --to-destination");
+-}
+-
+-/* Prints out the targinfo. */
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_target *target,
+- int numeric)
+-{
+- struct ip_nat_multi_range *mr
+- = (struct ip_nat_multi_range *)target->data;
+- struct ip_nat_range *r = &mr->range[0];
+- struct in_addr a;
+-
+- a.s_addr = r->min_ip;
+-
+- printf("balance %s", addr_to_dotted(&a));
+- a.s_addr = r->max_ip;
+- printf("-%s ", addr_to_dotted(&a));
+-}
+-
+-/* Saves the union ipt_targinfo in parsable form to stdout. */
+-static void
+-save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
+-{
+- struct ip_nat_multi_range *mr
+- = (struct ip_nat_multi_range *)target->data;
+- struct ip_nat_range *r = &mr->range[0];
+- struct in_addr a;
+-
+- a.s_addr = r->min_ip;
+- printf("--to-destination %s", addr_to_dotted(&a));
+- a.s_addr = r->max_ip;
+- printf("-%s ", addr_to_dotted(&a));
+-}
+-
+-static struct iptables_target balance = {
+- .next = NULL,
+- .name = "BALANCE",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ip_nat_multi_range)),
+- .userspacesize = IPT_ALIGN(sizeof(struct ip_nat_multi_range)),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_target(&balance);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_BALANCE.man iptables-svn/extensions/libipt_BALANCE.man
+--- iptables-1.3.7/extensions/libipt_BALANCE.man 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_BALANCE.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,4 +0,0 @@
+-This allows you to DNAT connections in a round-robin way over a given range of destination addresses.
+-.TP
+-.BI "--to-destination " "ipaddr-ipaddr"
+-Address range to round-robin over.
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_childlevel.c iptables-svn/extensions/libipt_childlevel.c
+--- iptables-1.3.7/extensions/libipt_childlevel.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_childlevel.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,115 +0,0 @@
+-/*
+- Shared library add-on to iptables to add layer 7 matching support.
+-
+- http://l7-filter.sf.net
+-
+- By Matthew Strait <quadong@users.sf.net>, Dec 2003.
+-
+- This program is free software; you can redistribute it and/or
+- modify it under the terms of the GNU General Public License
+- as published by the Free Software Foundation; either version
+- 2 of the License, or (at your option) any later version.
+- http://www.gnu.org/licenses/gpl.txt
+-*/
+-
+-#define _GNU_SOURCE
+-#include <stdio.h>
+-#include <netdb.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <getopt.h>
+-#include <ctype.h>
+-#include <dirent.h>
+-
+-#include <iptables.h>
+-#include <linux/netfilter_ipv4/ipt_childlevel.h>
+-
+-/* Function which prints out usage message. */
+-static void help(void)
+-{
+- printf(
+- "CHILDLEVEL match v%s options:\n"
+- "--level <n> : Match childlevel n (0 == master)\n",
+- IPTABLES_VERSION);
+- fputc('\n', stdout);
+-}
+-
+-static struct option opts[] = {
+- { .name = "level", .has_arg = 1, .flag = 0, .val = '1' },
+- { .name = 0 }
+-};
+-
+-/* Function which parses command options; returns true if it ate an option */
+-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)
+-{
+- struct ipt_childlevel_info *childlevelinfo =
+- (struct ipt_childlevel_info *)(*match)->data;
+-
+- switch (c) {
+- case '1':
+- check_inverse(optarg, &invert, &optind, 0);
+- childlevelinfo->childlevel = atoi(argv[optind-1]);
+- if (invert)
+- childlevelinfo->invert = 1;
+- *flags = 1;
+- break;
+- default:
+- return 0;
+- }
+-
+- return 1;
+-}
+-
+-/* Final check; must have specified --level. */
+-static void final_check(unsigned int flags)
+-{
+- if (!flags)
+- exit_error(PARAMETER_PROBLEM,
+- "CHILDLEVEL match: You must specify `--level'");
+-}
+-
+-static void print_protocol(int n, int invert, int numeric)
+-{
+- fputs("childlevel ", stdout);
+- if (invert) fputc('!', stdout);
+- printf("%d ", n);
+-}
+-
+-/* Prints out the matchinfo. */
+-static void print(const struct ipt_ip *ip,
+- const struct ipt_entry_match *match,
+- int numeric)
+-{
+- printf("CHILDLEVEL ");
+-
+- print_protocol(((struct ipt_childlevel_info *)match->data)->childlevel,
+- ((struct ipt_childlevel_info *)match->data)->invert, numeric);
+-}
+-/* Saves the union ipt_matchinfo in parsable form to stdout. */
+-static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+-{
+- const struct ipt_childlevel_info *info =
+- (const struct ipt_childlevel_info*) match->data;
+-
+- printf("--childlevel %s%d ", (info->invert) ? "! ": "", info->childlevel);
+-}
+-
+-static struct iptables_match childlevel = {
+- .name = "childlevel",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_childlevel_info)),
+- .userspacesize = IPT_ALIGN(sizeof(struct ipt_childlevel_info)),
+- .help = &help,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_match(&childlevel);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_childlevel.man iptables-svn/extensions/libipt_childlevel.man
+--- iptables-1.3.7/extensions/libipt_childlevel.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_childlevel.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,5 +0,0 @@
+-This is an experimental module. It matches on whether the
+-packet is part of a master connection or one of its children (or grandchildren,
+-etc). For instance, most packets are level 0. FTP data transfer is level 1.
+-.TP
+-.BR "--childlevel " "[!] \fIlevel\fP"
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_connbytes.c iptables-svn/extensions/libipt_connbytes.c
+--- iptables-1.3.7/extensions/libipt_connbytes.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_connbytes.c 2007-05-31 12:46:30.000000000 +0200
+@@ -5,7 +5,7 @@
+ #include <stdlib.h>
+ #include <getopt.h>
+ #include <iptables.h>
+-#include <linux/netfilter_ipv4/ip_conntrack.h>
++#include <linux/netfilter/nf_conntrack_common.h>
+ #include <linux/netfilter_ipv4/ipt_connbytes.h>
+
+ /* Function which prints out usage message. */
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_connlimit.c iptables-svn/extensions/libipt_connlimit.c
+--- iptables-1.3.7/extensions/libipt_connlimit.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_connlimit.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,132 +0,0 @@
+-/* Shared library add-on to iptables to add connection limit support. */
+-#include <stdio.h>
+-#include <netdb.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <stddef.h>
+-#include <getopt.h>
+-#include <iptables.h>
+-#include <linux/netfilter_ipv4/ip_conntrack.h>
+-#include <linux/netfilter_ipv4/ipt_connlimit.h>
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf(
+-"connlimit v%s options:\n"
+-"[!] --connlimit-above n match if the number of existing tcp connections is (not) above n\n"
+-" --connlimit-mask n group hosts using mask\n"
+-"\n", IPTABLES_VERSION);
+-}
+-
+-static struct option opts[] = {
+- { "connlimit-above", 1, 0, '1' },
+- { "connlimit-mask", 1, 0, '2' },
+- {0}
+-};
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-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)
+-{
+- struct ipt_connlimit_info *info = (struct ipt_connlimit_info*)(*match)->data;
+- int i;
+-
+- if (0 == (*flags & 2)) {
+- /* set default mask unless we've already seen a mask option */
+- info->mask = htonl(0xFFFFFFFF);
+- }
+-
+- switch (c) {
+- case '1':
+- check_inverse(optarg, &invert, &optind, 0);
+- info->limit = atoi(argv[optind-1]);
+- info->inverse = invert;
+- *flags |= 1;
+- break;
+-
+- case '2':
+- i = atoi(argv[optind-1]);
+- if ((i < 0) || (i > 32))
+- exit_error(PARAMETER_PROBLEM,
+- "--connlimit-mask must be between 0 and 32");
+-
+- if (i == 0)
+- info->mask = 0;
+- else
+- info->mask = htonl(0xFFFFFFFF << (32 - i));
+- *flags |= 2;
+- break;
+-
+- default:
+- return 0;
+- }
+-
+- return 1;
+-}
+-
+-/* Final check */
+-static void final_check(unsigned int flags)
+-{
+- if (!flags & 1)
+- exit_error(PARAMETER_PROBLEM, "You must specify `--connlimit-above'");
+-}
+-
+-static int
+-count_bits(u_int32_t mask)
+-{
+- int i, bits;
+-
+- for (bits = 0, i = 31; i >= 0; i--) {
+- if (mask & htonl((u_int32_t)1 << i)) {
+- bits++;
+- continue;
+- }
+- break;
+- }
+- return bits;
+-}
+-
+-/* Prints out the matchinfo. */
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_match *match,
+- int numeric)
+-{
+- struct ipt_connlimit_info *info = (struct ipt_connlimit_info*)match->data;
+-
+- printf("#conn/%d %s %d ", count_bits(info->mask),
+- info->inverse ? "<" : ">", info->limit);
+-}
+-
+-/* Saves the matchinfo in parsable form to stdout. */
+-static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+-{
+- struct ipt_connlimit_info *info = (struct ipt_connlimit_info*)match->data;
+-
+- printf("%s--connlimit-above %d ",info->inverse ? "! " : "",info->limit);
+- printf("--connlimit-mask %d ",count_bits(info->mask));
+-}
+-
+-static struct iptables_match connlimit = {
+- .name = "connlimit",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_connlimit_info)),
+- .userspacesize = offsetof(struct ipt_connlimit_info,data),
+- .help = help,
+- .parse = parse,
+- .final_check = final_check,
+- .print = print,
+- .save = save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_match(&connlimit);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_connlimit.man iptables-svn/extensions/libipt_connlimit.man
+--- iptables-1.3.7/extensions/libipt_connlimit.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_connlimit.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,21 +0,0 @@
+-Allows you to restrict the number of parallel TCP connections to a
+-server per client IP address (or address block).
+-.TP
+-[\fB!\fR] \fB--connlimit-above \fIn\fR
+-match if the number of existing tcp connections is (not) above n
+-.TP
+-.BI "--connlimit-mask " "bits"
+-group hosts using mask
+-.P
+-Examples:
+-.TP
+-# allow 2 telnet connections per client host
+-iptables -A INPUT -p tcp --syn --dport 23 -m connlimit --connlimit-above 2 -j REJECT
+-.TP
+-# you can also match the other way around:
+-iptables -A INPUT -p tcp --syn --dport 23 -m connlimit ! --connlimit-above 2 -j ACCEPT
+-.TP
+-# limit the nr of parallel http requests to 16 per class C sized \
+-network (24 bit netmask)
+-iptables -p tcp --syn --dport 80 -m connlimit --connlimit-above 16
+---connlimit-mask 24 -j REJECT
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_connrate.c iptables-svn/extensions/libipt_connrate.c
+--- iptables-1.3.7/extensions/libipt_connrate.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_connrate.c 2007-05-31 12:46:30.000000000 +0200
+@@ -13,7 +13,7 @@
+ #include <stdlib.h>
+ #include <getopt.h>
+ #include <iptables.h>
+-#include <linux/netfilter_ipv4/ip_conntrack.h>
++#include <linux/netfilter/nf_conntrack_common.h>
+ #include <linux/netfilter_ipv4/ipt_connrate.h>
+
+ /* Function which prints out usage message. */
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_conntrack.c iptables-svn/extensions/libipt_conntrack.c
+--- iptables-1.3.7/extensions/libipt_conntrack.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_conntrack.c 2007-05-31 12:46:30.000000000 +0200
+@@ -9,7 +9,7 @@
+ #include <getopt.h>
+ #include <ctype.h>
+ #include <iptables.h>
+-#include <linux/netfilter_ipv4/ip_conntrack.h>
++#include <linux/netfilter/nf_conntrack_common.h>
+ #include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
+ /* For 64bit kernel / 32bit userspace */
+ #include "../include/linux/netfilter_ipv4/ipt_conntrack.h"
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_DNAT.c iptables-svn/extensions/libipt_DNAT.c
+--- iptables-1.3.7/extensions/libipt_DNAT.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_DNAT.c 2007-05-31 12:46:30.000000000 +0200
+@@ -6,7 +6,10 @@
+ #include <getopt.h>
+ #include <iptables.h>
+ #include <linux/netfilter_ipv4/ip_tables.h>
+-#include <linux/netfilter_ipv4/ip_nat_rule.h>
++#include <linux/netfilter/nf_nat.h>
++
++#define IPT_DNAT_OPT_DEST 0x1
++#define IPT_DNAT_OPT_RANDOM 0x2
+
+ /* Dest NAT data consists of a multi-range, indicating where to map
+ to. */
+@@ -24,12 +27,14 @@
+ "DNAT v%s options:\n"
+ " --to-destination <ipaddr>[-<ipaddr>][:port-port]\n"
+ " Address to map destination to.\n"
+-" (You can use this more than once)\n\n",
++"[--random]\n"
++"\n",
+ IPTABLES_VERSION);
+ }
+
+ static struct option opts[] = {
+ { "to-destination", 1, 0, '1' },
++ { "random", 0, 0, '2' },
+ { 0 }
+ };
+
+@@ -163,9 +168,18 @@
+ "Multiple --to-destination not supported");
+ }
+ *target = parse_to(optarg, portok, info);
+- *flags = 1;
++ /* WTF do we need this for?? */
++ if (*flags & IPT_DNAT_OPT_RANDOM)
++ info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
++ *flags |= IPT_DNAT_OPT_DEST;
+ return 1;
+
++ case '2':
++ if (*flags & IPT_DNAT_OPT_DEST) {
++ info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
++ *flags |= IPT_DNAT_OPT_RANDOM;
++ } else
++ *flags |= IPT_DNAT_OPT_RANDOM;
+ default:
+ return 0;
+ }
+@@ -212,6 +226,8 @@
+ for (i = 0; i < info->mr.rangesize; i++) {
+ print_range(&info->mr.range[i]);
+ printf(" ");
++ if (info->mr.range[i].flags & IP_NAT_RANGE_PROTO_RANDOM)
++ printf("random ");
+ }
+ }
+
+@@ -226,6 +242,8 @@
+ printf("--to-destination ");
+ print_range(&info->mr.range[i]);
+ printf(" ");
++ if (info->mr.range[i].flags & IP_NAT_RANGE_PROTO_RANDOM)
++ printf("--random ");
+ }
+ }
+
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_DNAT.man iptables-svn/extensions/libipt_DNAT.man
+--- iptables-1.3.7/extensions/libipt_DNAT.man 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_DNAT.man 2007-05-31 12:46:30.000000000 +0200
+@@ -20,12 +20,17 @@
+ If no port range is specified, then the destination port will never be
+ modified. If no IP address is specified then only the destination port
+ will be modified.
+-.RS
+-.PP
++
+ In Kernels up to 2.6.10 you can add several --to-destination options. For
+ those kernels, if you specify more than one destination address, either via an
+ address range or multiple --to-destination options, a simple round-robin (one
+ after another in cycle) load balancing takes place between these addresses.
+ Later Kernels (>= 2.6.11-rc1) don't have the ability to NAT to multiple ranges
+ anymore.
+-
++.TP
++.BR "--random"
++If option
++.B "--random"
++is used then port mapping will be randomized (kernel >= 2.6.22).
++.RS
++.PP
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_dstlimit.c iptables-svn/extensions/libipt_dstlimit.c
+--- iptables-1.3.7/extensions/libipt_dstlimit.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_dstlimit.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,340 +0,0 @@
+-/* iptables match extension for limiting packets per destination
+- *
+- * (C) 2003 by Harald Welte <laforge@netfilter.org>
+- *
+- * Development of this code was funded by Astaro AG, http://www.astaro.com/
+- *
+- * Based on ipt_limit.c by
+- * Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
+- * Hervé Eychenne <rv@wallfire.org>
+- */
+-
+-#include <stdio.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <getopt.h>
+-#include <iptables.h>
+-#include <stddef.h>
+-#include <linux/netfilter_ipv4/ip_tables.h>
+-#include <linux/netfilter_ipv4/ipt_dstlimit.h>
+-
+-#define IPT_DSTLIMIT_BURST 5
+-
+-/* miliseconds */
+-#define IPT_DSTLIMIT_GCINTERVAL 1000
+-#define IPT_DSTLIMIT_EXPIRE 10000
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf(
+-"dstlimit v%s options:\n"
+-"--dstlimit <avg> max average match rate\n"
+-" [Packets per second unless followed by \n"
+-" /sec /minute /hour /day postfixes]\n"
+-"--dstlimit-mode <mode> mode\n"
+-" dstip\n"
+-" dstip-dstport\n"
+-" srcip-dstip\n"
+-" srcip-dstip-dstport\n"
+-"--dstlimit-name <name> name for /proc/net/ipt_dstlimit/\n"
+-"[--dstlimit-burst <num>] number to match in a burst, default %u\n"
+-"[--dstlimit-htable-size <num>] number of hashtable buckets\n"
+-"[--dstlimit-htable-max <num>] number of hashtable entries\n"
+-"[--dstlimit-htable-gcinterval] interval between garbage collection runs\n"
+-"[--dstlimit-htable-expire] after which time are idle entries expired?\n"
+-"\n", IPTABLES_VERSION, IPT_DSTLIMIT_BURST);
+-}
+-
+-static struct option opts[] = {
+- { "dstlimit", 1, 0, '%' },
+- { "dstlimit-burst", 1, 0, '$' },
+- { "dstlimit-htable-size", 1, 0, '&' },
+- { "dstlimit-htable-max", 1, 0, '*' },
+- { "dstlimit-htable-gcinterval", 1, 0, '(' },
+- { "dstlimit-htable-expire", 1, 0, ')' },
+- { "dstlimit-mode", 1, 0, '_' },
+- { "dstlimit-name", 1, 0, '"' },
+- { 0 }
+-};
+-
+-static
+-int parse_rate(const char *rate, u_int32_t *val)
+-{
+- const char *delim;
+- u_int32_t r;
+- u_int32_t mult = 1; /* Seconds by default. */
+-
+- delim = strchr(rate, '/');
+- if (delim) {
+- if (strlen(delim+1) == 0)
+- return 0;
+-
+- if (strncasecmp(delim+1, "second", strlen(delim+1)) == 0)
+- mult = 1;
+- else if (strncasecmp(delim+1, "minute", strlen(delim+1)) == 0)
+- mult = 60;
+- else if (strncasecmp(delim+1, "hour", strlen(delim+1)) == 0)
+- mult = 60*60;
+- else if (strncasecmp(delim+1, "day", strlen(delim+1)) == 0)
+- mult = 24*60*60;
+- else
+- return 0;
+- }
+- r = atoi(rate);
+- if (!r)
+- return 0;
+-
+- /* This would get mapped to infinite (1/day is minimum they
+- can specify, so we're ok at that end). */
+- if (r / mult > IPT_DSTLIMIT_SCALE)
+- exit_error(PARAMETER_PROBLEM, "Rate too fast `%s'\n", rate);
+-
+- *val = IPT_DSTLIMIT_SCALE * mult / r;
+- return 1;
+-}
+-
+-/* Initialize the match. */
+-static void
+-init(struct ipt_entry_match *m, unsigned int *nfcache)
+-{
+- struct ipt_dstlimit_info *r = (struct ipt_dstlimit_info *)m->data;
+-
+- r->cfg.burst = IPT_DSTLIMIT_BURST;
+- r->cfg.gc_interval = IPT_DSTLIMIT_GCINTERVAL;
+- r->cfg.expire = IPT_DSTLIMIT_EXPIRE;
+-
+-}
+-
+-#define PARAM_LIMIT 0x00000001
+-#define PARAM_BURST 0x00000002
+-#define PARAM_MODE 0x00000004
+-#define PARAM_NAME 0x00000008
+-#define PARAM_SIZE 0x00000010
+-#define PARAM_MAX 0x00000020
+-#define PARAM_GCINTERVAL 0x00000040
+-#define PARAM_EXPIRE 0x00000080
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-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)
+-{
+- struct ipt_dstlimit_info *r =
+- (struct ipt_dstlimit_info *)(*match)->data;
+- unsigned int num;
+-
+- switch(c) {
+- case '%':
+- if (check_inverse(argv[optind-1], &invert, &optind, 0)) break;
+- if (!parse_rate(optarg, &r->cfg.avg))
+- exit_error(PARAMETER_PROBLEM,
+- "bad rate `%s'", optarg);
+- *flags |= PARAM_LIMIT;
+- break;
+-
+- case '$':
+- if (check_inverse(argv[optind-1], &invert, &optind, 0)) break;
+- if (string_to_number(optarg, 0, 10000, &num) == -1)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --dstlimit-burst `%s'", optarg);
+- r->cfg.burst = num;
+- *flags |= PARAM_BURST;
+- break;
+- case '&':
+- if (check_inverse(argv[optind-1], &invert, &optind, 0)) break;
+- if (string_to_number(optarg, 0, 0xffffffff, &num) == -1)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --dstlimit-htable-size: `%s'", optarg);
+- r->cfg.size = num;
+- *flags |= PARAM_SIZE;
+- break;
+- case '*':
+- if (check_inverse(argv[optind-1], &invert, &optind, 0)) break;
+- if (string_to_number(optarg, 0, 0xffffffff, &num) == -1)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --dstlimit-htable-max: `%s'", optarg);
+- r->cfg.max = num;
+- *flags |= PARAM_MAX;
+- break;
+- case '(':
+- if (check_inverse(argv[optind-1], &invert, &optind, 0)) break;
+- if (string_to_number(optarg, 0, 0xffffffff, &num) == -1)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --dstlimit-htable-gcinterval: `%s'",
+- optarg);
+- /* FIXME: not HZ dependent!! */
+- r->cfg.gc_interval = num;
+- *flags |= PARAM_GCINTERVAL;
+- break;
+- case ')':
+- if (check_inverse(argv[optind-1], &invert, &optind, 0)) break;
+- if (string_to_number(optarg, 0, 0xffffffff, &num) == -1)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --dstlimit-htable-expire: `%s'", optarg);
+- /* FIXME: not HZ dependent */
+- r->cfg.expire = num;
+- *flags |= PARAM_EXPIRE;
+- break;
+- case '_':
+- if (check_inverse(argv[optind-1], &invert, &optind, 0)) break;
+- if (!strcmp(optarg, "dstip"))
+- r->cfg.mode = IPT_DSTLIMIT_HASH_DIP;
+- else if (!strcmp(optarg, "dstip-destport") ||
+- !strcmp(optarg, "dstip-dstport"))
+- r->cfg.mode = IPT_DSTLIMIT_HASH_DIP|IPT_DSTLIMIT_HASH_DPT;
+- else if (!strcmp(optarg, "srcip-dstip"))
+- r->cfg.mode = IPT_DSTLIMIT_HASH_SIP|IPT_DSTLIMIT_HASH_DIP;
+- else if (!strcmp(optarg, "srcip-dstip-destport") ||
+- !strcmp(optarg, "srcip-dstip-dstport"))
+- r->cfg.mode = IPT_DSTLIMIT_HASH_SIP|IPT_DSTLIMIT_HASH_DIP|IPT_DSTLIMIT_HASH_DPT;
+- else
+- exit_error(PARAMETER_PROBLEM,
+- "bad --dstlimit-mode: `%s'\n", optarg);
+- *flags |= PARAM_MODE;
+- break;
+- case '"':
+- if (check_inverse(argv[optind-1], &invert, &optind, 0)) break;
+- if (strlen(optarg) == 0)
+- exit_error(PARAMETER_PROBLEM, "Zero-length name?");
+- strncpy(r->name, optarg, sizeof(r->name));
+- *flags |= PARAM_NAME;
+- break;
+- default:
+- return 0;
+- }
+-
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "dstlimit does not support invert");
+-
+- return 1;
+-}
+-
+-/* Final check; nothing. */
+-static void final_check(unsigned int flags)
+-{
+- if (!(flags & PARAM_LIMIT))
+- exit_error(PARAMETER_PROBLEM,
+- "You have to specify --dstlimit");
+- if (!(flags & PARAM_MODE))
+- exit_error(PARAMETER_PROBLEM,
+- "You have to specify --dstlimit-mode");
+- if (!(flags & PARAM_NAME))
+- exit_error(PARAMETER_PROBLEM,
+- "You have to specify --dstlimit-name");
+-}
+-
+-static struct rates
+-{
+- const char *name;
+- u_int32_t mult;
+-} rates[] = { { "day", IPT_DSTLIMIT_SCALE*24*60*60 },
+- { "hour", IPT_DSTLIMIT_SCALE*60*60 },
+- { "min", IPT_DSTLIMIT_SCALE*60 },
+- { "sec", IPT_DSTLIMIT_SCALE } };
+-
+-static void print_rate(u_int32_t period)
+-{
+- unsigned int i;
+-
+- for (i = 1; i < sizeof(rates)/sizeof(struct rates); i++) {
+- if (period > rates[i].mult
+- || rates[i].mult/period < rates[i].mult%period)
+- break;
+- }
+-
+- printf("%u/%s ", rates[i-1].mult / period, rates[i-1].name);
+-}
+-
+-/* Prints out the matchinfo. */
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_match *match,
+- int numeric)
+-{
+- struct ipt_dstlimit_info *r =
+- (struct ipt_dstlimit_info *)match->data;
+- printf("limit: avg "); print_rate(r->cfg.avg);
+- printf("burst %u ", r->cfg.burst);
+- switch (r->cfg.mode) {
+- case (IPT_DSTLIMIT_HASH_DIP):
+- printf("mode dstip ");
+- break;
+- case (IPT_DSTLIMIT_HASH_DIP|IPT_DSTLIMIT_HASH_DPT):
+- printf("mode dstip-dstport ");
+- break;
+- case (IPT_DSTLIMIT_HASH_SIP|IPT_DSTLIMIT_HASH_DIP):
+- printf("mode srcip-dstip ");
+- break;
+- case (IPT_DSTLIMIT_HASH_SIP|IPT_DSTLIMIT_HASH_DIP|IPT_DSTLIMIT_HASH_DPT):
+- printf("mode srcip-dstip-dstport ");
+- break;
+- }
+- if (r->cfg.size)
+- printf("htable-size %u ", r->cfg.size);
+- if (r->cfg.max)
+- printf("htable-max %u ", r->cfg.max);
+- if (r->cfg.gc_interval != IPT_DSTLIMIT_GCINTERVAL)
+- printf("htable-gcinterval %u ", r->cfg.gc_interval);
+- if (r->cfg.expire != IPT_DSTLIMIT_EXPIRE)
+- printf("htable-expire %u ", r->cfg.expire);
+-}
+-
+-/* FIXME: Make minimalist: only print rate if not default --RR */
+-static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+-{
+- struct ipt_dstlimit_info *r =
+- (struct ipt_dstlimit_info *)match->data;
+-
+- printf("--dstlimit "); print_rate(r->cfg.avg);
+- if (r->cfg.burst != IPT_DSTLIMIT_BURST)
+- printf("--dstlimit-burst %u ", r->cfg.burst);
+- switch (r->cfg.mode) {
+- case (IPT_DSTLIMIT_HASH_DIP):
+- printf("--mode dstip ");
+- break;
+- case (IPT_DSTLIMIT_HASH_DIP|IPT_DSTLIMIT_HASH_DPT):
+- printf("--mode dstip-dstport ");
+- break;
+- case (IPT_DSTLIMIT_HASH_SIP|IPT_DSTLIMIT_HASH_DIP):
+- printf("--mode srcip-dstip ");
+- break;
+- case (IPT_DSTLIMIT_HASH_SIP|IPT_DSTLIMIT_HASH_DIP|IPT_DSTLIMIT_HASH_DPT):
+- printf("--mode srcip-dstip-dstport ");
+- break;
+- }
+- if (r->cfg.size)
+- printf("--dstlimit-htable-size %u ", r->cfg.size);
+- if (r->cfg.max)
+- printf("--dstlimit-htable-max %u ", r->cfg.max);
+- if (r->cfg.gc_interval != IPT_DSTLIMIT_GCINTERVAL)
+- printf("--dstlimit-htable-gcinterval %u", r->cfg.gc_interval);
+- if (r->cfg.expire != IPT_DSTLIMIT_EXPIRE)
+- printf("--dstlimit-htable-expire %u ", r->cfg.expire);
+-}
+-
+-static struct iptables_match dstlimit = {
+- .next = NULL,
+- .name = "dstlimit",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_dstlimit_info)),
+- .userspacesize = IPT_ALIGN(sizeof(struct ipt_dstlimit_info)),
+- //offsetof(struct ipt_dstlimit_info, prev),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_match(&dstlimit);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_dstlimit.man iptables-svn/extensions/libipt_dstlimit.man
+--- iptables-1.3.7/extensions/libipt_dstlimit.man 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_dstlimit.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,37 +0,0 @@
+-This module allows you to limit the packet per second (pps) rate on a per
+-destination IP or per destination port base. As opposed to the `limit' match,
+-every destination ip / destination port has it's own limit.
+-.TP
+-THIS MODULE IS DEPRECATED AND HAS BEEN REPLACED BY ``hashlimit''
+-.TP
+-.BI "--dstlimit " "avg"
+-Maximum average match rate (packets per second unless followed by /sec /minute /hour /day postfixes).
+-.TP
+-.BI "--dstlimit-mode " "mode"
+-The limiting hashmode. Is the specified limit per
+-.B dstip, dstip-dstport
+-tuple,
+-.B srcip-dstip
+-tuple, or per
+-.B srcipdstip-dstport
+-tuple.
+-.TP
+-.BI "--dstlimit-name " "name"
+-Name for /proc/net/ipt_dstlimit/* file entry
+-.TP
+-.BI "[" "--dstlimit-burst " "burst" "]"
+-Number of packets to match in a burst. Default: 5
+-.TP
+-.BI "[" "--dstlimit-htable-size " "size" "]"
+-Number of buckets in the hashtable
+-.TP
+-.BI "[" "--dstlimit-htable-max " "max" "]"
+-Maximum number of entries in the hashtable
+-.TP
+-.BI "[" "--dstlimit-htable-gcinterval " "interval" "]"
+-Interval between garbage collection runs of the hashtable (in miliseconds).
+-Default is 1000 (1 second).
+-.TP
+-.BI "[" "--dstlimit-htable-expire " "time"
+-After which time are idle entries expired from hashtable (in miliseconds)?
+-Default is 10000 (10 seconds).
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_FTOS.c iptables-svn/extensions/libipt_FTOS.c
+--- iptables-1.3.7/extensions/libipt_FTOS.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_FTOS.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,133 +0,0 @@
+-/* Shared library add-on to iptables for FTOS
+- *
+- * (C) 2000 by Matthew G. Marsh <mgm@paktronix.com>
+- *
+- * This program is distributed under the terms of GNU GPL v2, 1991
+- *
+- * libipt_FTOS.c borrowed heavily from libipt_TOS.c 11/09/2000
+- *
+- */
+-#include <stdio.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <getopt.h>
+-
+-#include <iptables.h>
+-#include <linux/netfilter_ipv4/ip_tables.h>
+-#include <linux/netfilter_ipv4/ipt_FTOS.h>
+-
+-struct finfo {
+- struct ipt_entry_target t;
+- u_int8_t ftos;
+-};
+-
+-static void init(struct ipt_entry_target *t, unsigned int *nfcache)
+-{
+-}
+-
+-static void help(void)
+-{
+- printf(
+-"FTOS target options\n"
+-" --set-ftos value Set TOS field in packet header to value\n"
+-" This value can be in decimal (ex: 32)\n"
+-" or in hex (ex: 0x20)\n"
+-);
+-}
+-
+-static struct option opts[] = {
+- { "set-ftos", 1, 0, 'F' },
+- { 0 }
+-};
+-
+-static void
+-parse_ftos(const unsigned char *s, struct ipt_FTOS_info *finfo)
+-{
+- unsigned int ftos;
+-
+- if (string_to_number(s, 0, 255, &ftos) == -1)
+- exit_error(PARAMETER_PROBLEM,
+- "Invalid ftos `%s'\n", s);
+- finfo->ftos = (u_int8_t )ftos;
+- return;
+-}
+-
+-static int
+-parse(int c, char **argv, int invert, unsigned int *flags,
+- const struct ipt_entry *entry,
+- struct ipt_entry_target **target)
+-{
+- struct ipt_FTOS_info *finfo
+- = (struct ipt_FTOS_info *)(*target)->data;
+-
+- switch (c) {
+- case 'F':
+- if (*flags)
+- exit_error(PARAMETER_PROBLEM,
+- "FTOS target: Only use --set-ftos ONCE!");
+- parse_ftos(optarg, finfo);
+- *flags = 1;
+- break;
+-
+- default:
+- return 0;
+- }
+-
+- return 1;
+-}
+-
+-static void
+-final_check(unsigned int flags)
+-{
+- if (!flags)
+- exit_error(PARAMETER_PROBLEM,
+- "FTOS target: Parameter --set-ftos is required");
+-}
+-
+-static void
+-print_ftos(u_int8_t ftos, int numeric)
+-{
+- printf("0x%02x ", ftos);
+-}
+-
+-/* Prints out the targinfo. */
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_target *target,
+- int numeric)
+-{
+- const struct ipt_FTOS_info *finfo =
+- (const struct ipt_FTOS_info *)target->data;
+- printf("TOS set ");
+- print_ftos(finfo->ftos, numeric);
+-}
+-
+-/* Saves the union ipt_targinfo in parsable form to stdout. */
+-static void
+-save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
+-{
+- const struct ipt_FTOS_info *finfo =
+- (const struct ipt_FTOS_info *)target->data;
+-
+- printf("--set-ftos 0x%02x ", finfo->ftos);
+-}
+-
+-static struct iptables_target ftos = {
+- .next = NULL,
+- .name = "FTOS",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_FTOS_info)),
+- .userspacesize = IPT_ALIGN(sizeof(struct ipt_FTOS_info)),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_target(&ftos);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_fuzzy.c iptables-svn/extensions/libipt_fuzzy.c
+--- iptables-1.3.7/extensions/libipt_fuzzy.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_fuzzy.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,158 +0,0 @@
+-/*
+- Shared library add-on to iptables to add match support for the fuzzy match.
+-
+- 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
+-
+-2002-08-07 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version.
+-2003-06-09 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Bug corrections in
+-the save function , thanks to information given by Jean-Francois Patenaude .
+-
+-*/
+-
+-#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/ip_tables.h>
+-#include <linux/netfilter_ipv4/ipt_fuzzy.h>
+-
+-
+-static void
+-help(void)
+-{
+- printf(
+-"fuzzy v%s options:\n"
+-" --lower-limit number (in packets per second)\n"
+-" --upper-limit number\n"
+-,IPTABLES_VERSION);
+-};
+-
+-static struct option opts[] = {
+- { "lower-limit", 1 , 0 , '1' } ,
+- { "upper-limit", 1 , 0 , '2' } ,
+- { 0 }
+-};
+-
+-/* Initialize data structures */
+-static void
+-init(struct ipt_entry_match *m, unsigned int *nfcache)
+-{
+- struct ipt_fuzzy_info *presentinfo = (struct ipt_fuzzy_info *)(m)->data;
+-
+- /*
+- * Default rates ( I'll improve this very soon with something based
+- * on real statistics of the running machine ) .
+- */
+-
+- presentinfo->minimum_rate = 1000;
+- presentinfo->maximum_rate = 2000;
+-}
+-
+-#define IPT_FUZZY_OPT_MINIMUM 0x01
+-#define IPT_FUZZY_OPT_MAXIMUM 0x02
+-
+-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)
+-{
+-
+-struct ipt_fuzzy_info *fuzzyinfo = (struct ipt_fuzzy_info *)(*match)->data;
+-
+- u_int32_t num;
+-
+- switch (c) {
+-
+- case '1':
+-
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,"Can't specify ! --lower-limit");
+-
+- if (*flags & IPT_FUZZY_OPT_MINIMUM)
+- exit_error(PARAMETER_PROBLEM,"Can't specify --lower-limit twice");
+-
+- if (string_to_number(optarg,1,MAXFUZZYRATE,&num) == -1 || num < 1)
+- exit_error(PARAMETER_PROBLEM,"BAD --lower-limit");
+-
+- fuzzyinfo->minimum_rate = num ;
+-
+- *flags |= IPT_FUZZY_OPT_MINIMUM;
+-
+- break;
+-
+- case '2':
+-
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,"Can't specify ! --upper-limit");
+-
+- if (*flags & IPT_FUZZY_OPT_MAXIMUM)
+- exit_error(PARAMETER_PROBLEM,"Can't specify --upper-limit twice");
+-
+- if (string_to_number(optarg,1,MAXFUZZYRATE,&num) == -1 || num < 1)
+- exit_error(PARAMETER_PROBLEM,"BAD --upper-limit");
+-
+- fuzzyinfo->maximum_rate = num ;
+-
+- *flags |= IPT_FUZZY_OPT_MAXIMUM;
+-
+- break ;
+-
+- default:
+- return 0;
+- }
+- return 1;
+-}
+-
+-static void final_check(unsigned int flags)
+-{
+-}
+-
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_match *match,
+- int numeric)
+-{
+- const struct ipt_fuzzy_info *fuzzyinfo
+- = (const struct ipt_fuzzy_info *)match->data;
+-
+- printf(" fuzzy: lower limit = %u pps - upper limit = %u pps ",fuzzyinfo->minimum_rate,fuzzyinfo->maximum_rate);
+-
+-}
+-
+-/* Saves the union ipt_targinfo in parsable form to stdout. */
+-static void
+-save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+-{
+- const struct ipt_fuzzy_info *fuzzyinfo
+- = (const struct ipt_fuzzy_info *)match->data;
+-
+- printf("--lower-limit %u ",fuzzyinfo->minimum_rate);
+- printf("--upper-limit %u ",fuzzyinfo->maximum_rate);
+-
+-}
+-
+-static struct iptables_match fuzzy_match = {
+- .next = NULL,
+- .name = "fuzzy",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_fuzzy_info)),
+- .userspacesize = IPT_ALIGN(sizeof(struct ipt_fuzzy_info)),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_match(&fuzzy_match);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_fuzzy.man iptables-svn/extensions/libipt_fuzzy.man
+--- iptables-1.3.7/extensions/libipt_fuzzy.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_fuzzy.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,7 +0,0 @@
+-This module matches a rate limit based on a fuzzy logic controller [FLC]
+-.TP
+-.BI "--lower-limit " "number"
+-Specifies the lower limit (in packets per second).
+-.TP
+-.BI "--upper-limit " "number"
+-Specifies the upper limit (in packets per second).
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_icmp.c iptables-svn/extensions/libipt_icmp.c
+--- iptables-1.3.7/extensions/libipt_icmp.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_icmp.c 2007-05-31 12:46:30.000000000 +0200
+@@ -281,7 +281,7 @@
+ }
+ }
+
+-/* Final check; we don't care. */
++/* Final check; we don't care. We can pass 0xFF to match any type */
+ static void final_check(unsigned int flags)
+ {
+ }
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_icmp.man iptables-svn/extensions/libipt_icmp.man
+--- iptables-1.3.7/extensions/libipt_icmp.man 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_icmp.man 2007-05-31 12:46:30.000000000 +0200
+@@ -1,4 +1,4 @@
+-This extension is loaded if `--protocol icmp' is specified. It
++This extension can be used if `--protocol icmp' is specified. It
+ provides the following option:
+ .TP
+ .BR "--icmp-type " "[!] \fItypename\fP"
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_IPMARK.c iptables-svn/extensions/libipt_IPMARK.c
+--- iptables-1.3.7/extensions/libipt_IPMARK.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_IPMARK.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,168 +0,0 @@
+-/* Shared library add-on to iptables to add IPMARK target support.
+- * (C) 2003 by Grzegorz Janoszka <Grzegorz.Janoszka@pro.onet.pl>
+- *
+- * based on original MARK target
+- *
+- * This program is distributed under the terms of GNU GPL
+- */
+-#include <stdio.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <getopt.h>
+-
+-#include <iptables.h>
+-#include <linux/netfilter_ipv4/ip_tables.h>
+-#include <linux/netfilter_ipv4/ipt_IPMARK.h>
+-
+-#define IPT_ADDR_USED 1
+-#define IPT_AND_MASK_USED 2
+-#define IPT_OR_MASK_USED 4
+-
+-struct ipmarkinfo {
+- struct ipt_entry_target t;
+- struct ipt_ipmark_target_info ipmark;
+-};
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf(
+-"IPMARK target v%s options:\n"
+-" --addr src/dst use source or destination ip address\n"
+-" --and-mask value logical AND ip address with this value becomes MARK\n"
+-" --or-mask value logical OR ip address with this value becomes MARK\n"
+-"\n",
+-IPTABLES_VERSION);
+-}
+-
+-static struct option opts[] = {
+- { "addr", 1, 0, '1' },
+- { "and-mask", 1, 0, '2' },
+- { "or-mask", 1, 0, '3' },
+- { 0 }
+-};
+-
+-/* Initialize the target. */
+-static void
+-init(struct ipt_entry_target *t, unsigned int *nfcache)
+-{
+- struct ipt_ipmark_target_info *ipmarkinfo =
+- (struct ipt_ipmark_target_info *)t->data;
+-
+- ipmarkinfo->andmask=0xffffffff;
+- ipmarkinfo->ormask=0;
+-
+-}
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-static int
+-parse(int c, char **argv, int invert, unsigned int *flags,
+- const struct ipt_entry *entry,
+- struct ipt_entry_target **target)
+-{
+- struct ipt_ipmark_target_info *ipmarkinfo
+- = (struct ipt_ipmark_target_info *)(*target)->data;
+-
+- switch (c) {
+- char *end;
+- case '1':
+- if(!strcmp(optarg, "src")) ipmarkinfo->addr=IPT_IPMARK_SRC;
+- else if(!strcmp(optarg, "dst")) ipmarkinfo->addr=IPT_IPMARK_DST;
+- else exit_error(PARAMETER_PROBLEM, "Bad addr value `%s' - should be `src' or `dst'", optarg);
+- if (*flags & IPT_ADDR_USED)
+- exit_error(PARAMETER_PROBLEM,
+- "IPMARK target: Can't specify --addr twice");
+- *flags |= IPT_ADDR_USED;
+- break;
+-
+- case '2':
+- ipmarkinfo->andmask = strtoul(optarg, &end, 0);
+- if (*end != '\0' || end == optarg)
+- exit_error(PARAMETER_PROBLEM, "Bad and-mask value `%s'", optarg);
+- if (*flags & IPT_AND_MASK_USED)
+- exit_error(PARAMETER_PROBLEM,
+- "IPMARK target: Can't specify --and-mask twice");
+- *flags |= IPT_AND_MASK_USED;
+- break;
+- case '3':
+- ipmarkinfo->ormask = strtoul(optarg, &end, 0);
+- if (*end != '\0' || end == optarg)
+- exit_error(PARAMETER_PROBLEM, "Bad or-mask value `%s'", optarg);
+- if (*flags & IPT_OR_MASK_USED)
+- exit_error(PARAMETER_PROBLEM,
+- "IPMARK target: Can't specify --or-mask twice");
+- *flags |= IPT_OR_MASK_USED;
+- break;
+-
+- default:
+- return 0;
+- }
+-
+- return 1;
+-}
+-
+-static void
+-final_check(unsigned int flags)
+-{
+- if (!(flags & IPT_ADDR_USED))
+- exit_error(PARAMETER_PROBLEM,
+- "IPMARK target: Parameter --addr is required");
+- if (!(flags & (IPT_AND_MASK_USED | IPT_OR_MASK_USED)))
+- exit_error(PARAMETER_PROBLEM,
+- "IPMARK target: Parameter --and-mask or --or-mask is required");
+-}
+-
+-/* Prints out the targinfo. */
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_target *target,
+- int numeric)
+-{
+- const struct ipt_ipmark_target_info *ipmarkinfo =
+- (const struct ipt_ipmark_target_info *)target->data;
+-
+- if(ipmarkinfo->addr == IPT_IPMARK_SRC)
+- printf("IPMARK src");
+- else
+- printf("IPMARK dst");
+- printf(" ip and 0x%lx or 0x%lx", ipmarkinfo->andmask, ipmarkinfo->ormask);
+-}
+-
+-/* Saves the union ipt_targinfo in parsable form to stdout. */
+-static void
+-save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
+-{
+- const struct ipt_ipmark_target_info *ipmarkinfo =
+- (const struct ipt_ipmark_target_info *)target->data;
+-
+- if(ipmarkinfo->addr == IPT_IPMARK_SRC)
+- printf("--addr=src ");
+- else
+- printf("--addr=dst ");
+- if(ipmarkinfo->andmask != 0xffffffff)
+- printf("--and-mask 0x%lx ", ipmarkinfo->andmask);
+- if(ipmarkinfo->ormask != 0)
+- printf("--or-mask 0x%lx ", ipmarkinfo->ormask);
+-}
+-
+-static struct iptables_target ipmark = {
+- .next = NULL,
+- .name = "IPMARK",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_ipmark_target_info)),
+- .userspacesize = IPT_ALIGN(sizeof(struct ipt_ipmark_target_info)),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_target(&ipmark);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_IPMARK.man iptables-svn/extensions/libipt_IPMARK.man
+--- iptables-1.3.7/extensions/libipt_IPMARK.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_IPMARK.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,45 +0,0 @@
+-Allows you to mark a received packet basing on its IP address. This
+-can replace many mangle/mark entries with only one, if you use
+-firewall based classifier.
+-
+-This target is to be used inside the mangle table, in the PREROUTING,
+-POSTROUTING or FORWARD hooks.
+-.TP
+-.BI "--addr " "src/dst"
+-Use source or destination IP address.
+-.TP
+-.BI "--and-mask " "mask"
+-Perform bitwise `and' on the IP address and this mask.
+-.TP
+-.BI "--or-mask " "mask"
+-Perform bitwise `or' on the IP address and this mask.
+-.P
+-The order of IP address bytes is reversed to meet "human order of bytes":
+-192.168.0.1 is 0xc0a80001. At first the `and' operation is performed, then
+-`or'.
+-
+-Examples:
+-
+-We create a queue for each user, the queue number is adequate
+-to the IP address of the user, e.g.: all packets going to/from 192.168.5.2
+-are directed to 1:0502 queue, 192.168.5.12 -> 1:050c etc.
+-
+-We have one classifier rule:
+-.IP
+-tc filter add dev eth3 parent 1:0 protocol ip fw
+-.P
+-Earlier we had many rules just like below:
+-.IP
+-iptables -t mangle -A POSTROUTING -o eth3 -d 192.168.5.2 -j MARK
+---set-mark 0x10502
+-.IP
+-iptables -t mangle -A POSTROUTING -o eth3 -d 192.168.5.3 -j MARK
+---set-mark 0x10503
+-.P
+-Using IPMARK target we can replace all the mangle/mark rules with only one:
+-.IP
+-iptables -t mangle -A POSTROUTING -o eth3 -j IPMARK --addr=dst
+---and-mask=0xffff --or-mask=0x10000
+-.P
+-On the routers with hundreds of users there should be significant load
+-decrease (e.g. twice).
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_ipv4options.c iptables-svn/extensions/libipt_ipv4options.c
+--- iptables-1.3.7/extensions/libipt_ipv4options.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_ipv4options.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,311 +0,0 @@
+-/* Shared library add-on to iptables to add ipv4 options matching support. */
+-#include <stdio.h>
+-#include <netdb.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <getopt.h>
+-
+-#include <iptables.h>
+-#include <linux/netfilter_ipv4/ipt_ipv4options.h>
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf(
+-"ipv4options v%s options:\n"
+-" --ssrr (match strict source routing flag)\n"
+-" --lsrr (match loose source routing flag)\n"
+-" --no-srr (match packets with no source routing)\n\n"
+-" [!] --rr (match record route flag)\n\n"
+-" [!] --ts (match timestamp flag)\n\n"
+-" [!] --ra (match router-alert option)\n\n"
+-" [!] --any-opt (match any option or no option at all if used with '!')\n",
+-IPTABLES_VERSION);
+-}
+-
+-static struct option opts[] = {
+- { "ssrr", 0, 0, '1' },
+- { "lsrr", 0, 0, '2' },
+- { "no-srr", 0, 0, '3'},
+- { "rr", 0, 0, '4'},
+- { "ts", 0, 0, '5'},
+- { "ra", 0, 0, '6'},
+- { "any-opt", 0, 0, '7'},
+- {0}
+-};
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-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)
+-{
+- struct ipt_ipv4options_info *info = (struct ipt_ipv4options_info *)(*match)->data;
+-
+- switch (c)
+- {
+- /* strict-source-routing */
+- case '1':
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "ipv4options: unexpected `!' with --ssrr");
+- if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --ssrr twice");
+- if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --ssrr with --lsrr");
+- if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --ssrr with --no-srr");
+-
+- info->options |= IPT_IPV4OPTION_MATCH_SSRR;
+- *flags |= IPT_IPV4OPTION_MATCH_SSRR;
+- break;
+-
+- /* loose-source-routing */
+- case '2':
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "ipv4options: unexpected `!' with --lsrr");
+- if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --lsrr twice");
+- if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --lsrr with --ssrr");
+- if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --lsrr with --no-srr");
+- info->options |= IPT_IPV4OPTION_MATCH_LSRR;
+- *flags |= IPT_IPV4OPTION_MATCH_LSRR;
+- break;
+-
+- /* no-source-routing */
+- case '3':
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "ipv4options: unexpected `!' with --no-srr");
+- if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --no-srr twice");
+- if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --no-srr with --ssrr");
+- if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --no-srr with --lsrr");
+- info->options |= IPT_IPV4OPTION_DONT_MATCH_SRR;
+- *flags |= IPT_IPV4OPTION_DONT_MATCH_SRR;
+- break;
+-
+- /* record-route */
+- case '4':
+- if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_RR))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --rr twice");
+- if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_RR))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify ! --rr twice");
+- if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_RR))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --rr with ! --rr");
+- if (invert && (*flags & IPT_IPV4OPTION_MATCH_RR))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify ! --rr with --rr");
+- if (invert) {
+- info->options |= IPT_IPV4OPTION_DONT_MATCH_RR;
+- *flags |= IPT_IPV4OPTION_DONT_MATCH_RR;
+- }
+- else {
+- info->options |= IPT_IPV4OPTION_MATCH_RR;
+- *flags |= IPT_IPV4OPTION_MATCH_RR;
+- }
+- break;
+-
+- /* timestamp */
+- case '5':
+- if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --ts twice");
+- if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify ! --ts twice");
+- if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --ts with ! --ts");
+- if (invert && (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify ! --ts with --ts");
+- if (invert) {
+- info->options |= IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP;
+- *flags |= IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP;
+- }
+- else {
+- info->options |= IPT_IPV4OPTION_MATCH_TIMESTAMP;
+- *flags |= IPT_IPV4OPTION_MATCH_TIMESTAMP;
+- }
+- break;
+-
+- /* router-alert */
+- case '6':
+- if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --ra twice");
+- if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify ! --rr twice");
+- if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --ra with ! --ra");
+- if (invert && (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify ! --ra with --ra");
+- if (invert) {
+- info->options |= IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT;
+- *flags |= IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT;
+- }
+- else {
+- info->options |= IPT_IPV4OPTION_MATCH_ROUTER_ALERT;
+- *flags |= IPT_IPV4OPTION_MATCH_ROUTER_ALERT;
+- }
+- break;
+-
+- /* any option */
+- case '7' :
+- if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_ANY_OPT))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --any-opt twice");
+- if (invert && (*flags & IPT_IPV4OPTION_MATCH_ANY_OPT))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify ! --any-opt with --any-opt");
+- if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify ! --any-opt twice");
+- if ((!invert) &&
+- ((*flags & IPT_IPV4OPTION_DONT_MATCH_SRR) ||
+- (*flags & IPT_IPV4OPTION_DONT_MATCH_RR) ||
+- (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) ||
+- (*flags & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --any-opt with any other negative ipv4options match");
+- if (invert &&
+- ((*flags & IPT_IPV4OPTION_MATCH_LSRR) ||
+- (*flags & IPT_IPV4OPTION_MATCH_SSRR) ||
+- (*flags & IPT_IPV4OPTION_MATCH_RR) ||
+- (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP) ||
+- (*flags & IPT_IPV4OPTION_MATCH_ROUTER_ALERT)))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify ! --any-opt with any other positive ipv4options match");
+- if (invert) {
+- info->options |= IPT_IPV4OPTION_DONT_MATCH_ANY_OPT;
+- *flags |= IPT_IPV4OPTION_DONT_MATCH_ANY_OPT;
+- }
+- else {
+- info->options |= IPT_IPV4OPTION_MATCH_ANY_OPT;
+- *flags |= IPT_IPV4OPTION_MATCH_ANY_OPT;
+- }
+- break;
+-
+- default:
+- return 0;
+- }
+- return 1;
+-}
+-
+-static void
+-final_check(unsigned int flags)
+-{
+- if (flags == 0)
+- exit_error(PARAMETER_PROBLEM,
+- "ipv4options match: you must specify some parameters. See iptables -m ipv4options --help for help.'");
+-}
+-
+-/* Prints out the matchinfo. */
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_match *match,
+- int numeric)
+-{
+- struct ipt_ipv4options_info *info = ((struct ipt_ipv4options_info *)match->data);
+-
+- printf(" IPV4OPTS");
+- if (info->options & IPT_IPV4OPTION_MATCH_SSRR)
+- printf(" SSRR");
+- else if (info->options & IPT_IPV4OPTION_MATCH_LSRR)
+- printf(" LSRR");
+- else if (info->options & IPT_IPV4OPTION_DONT_MATCH_SRR)
+- printf(" !SRR");
+- if (info->options & IPT_IPV4OPTION_MATCH_RR)
+- printf(" RR");
+- else if (info->options & IPT_IPV4OPTION_DONT_MATCH_RR)
+- printf(" !RR");
+- if (info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP)
+- printf(" TS");
+- else if (info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP)
+- printf(" !TS");
+- if (info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT)
+- printf(" RA");
+- else if (info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)
+- printf(" !RA");
+- if (info->options & IPT_IPV4OPTION_MATCH_ANY_OPT)
+- printf(" ANYOPT ");
+- else if (info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
+- printf(" NOOPT");
+-
+- printf(" ");
+-}
+-
+-/* Saves the data in parsable form to stdout. */
+-static void
+-save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+-{
+- struct ipt_ipv4options_info *info = ((struct ipt_ipv4options_info *)match->data);
+-
+- if (info->options & IPT_IPV4OPTION_MATCH_SSRR)
+- printf(" --ssrr");
+- else if (info->options & IPT_IPV4OPTION_MATCH_LSRR)
+- printf(" --lsrr");
+- else if (info->options & IPT_IPV4OPTION_DONT_MATCH_SRR)
+- printf(" --no-srr");
+- if (info->options & IPT_IPV4OPTION_MATCH_RR)
+- printf(" --rr");
+- else if (info->options & IPT_IPV4OPTION_DONT_MATCH_RR)
+- printf(" ! --rr");
+- if (info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP)
+- printf(" --ts");
+- else if (info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP)
+- printf(" ! --ts");
+- if (info->options & IPT_IPV4OPTION_MATCH_ROUTER_ALERT)
+- printf(" --ra");
+- else if (info->options & IPT_IPV4OPTION_DONT_MATCH_ROUTER_ALERT)
+- printf(" ! --ra");
+- if (info->options & IPT_IPV4OPTION_MATCH_ANY_OPT)
+- printf(" --any-opt");
+- if (info->options & IPT_IPV4OPTION_DONT_MATCH_ANY_OPT)
+- printf(" ! --any-opt");
+-
+- printf(" ");
+-}
+-
+-static struct iptables_match ipv4options_struct = {
+- .next = NULL,
+- .name = "ipv4options",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_ipv4options_info)),
+- .userspacesize = IPT_ALIGN(sizeof(struct ipt_ipv4options_info)),
+- .help = &help,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_match(&ipv4options_struct);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_ipv4options.man iptables-svn/extensions/libipt_ipv4options.man
+--- iptables-1.3.7/extensions/libipt_ipv4options.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_ipv4options.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,32 +0,0 @@
+-Match on IPv4 header options like source routing, record route,
+-timestamp and router-alert.
+-.TP
+-.B "--ssrr"
+-To match packets with the flag strict source routing.
+-.TP
+-.B "--lsrr"
+-To match packets with the flag loose source routing.
+-.TP
+-.B "--no-srr"
+-To match packets with no flag for source routing.
+-.TP
+-.B "\fR[\fB!\fR]\fB --rr"
+-To match packets with the RR flag.
+-.TP
+-.B "\fR[\fB!\fR]\fB --ts"
+-To match packets with the TS flag.
+-.TP
+-.B "\fR[\fB!\fR]\fB --ra"
+-To match packets with the router-alert option.
+-.TP
+-.B "\fR[\fB!\fR]\fB --any-opt"
+-To match a packet with at least one IP option, or no IP option
+-at all if ! is chosen.
+-.TP
+-Examples:
+-.TP
+-$ iptables -A input -m ipv4options --rr -j DROP
+-will drop packets with the record-route flag.
+-.TP
+-$ iptables -A input -m ipv4options --ts -j DROP
+-will drop packets with the timestamp flag.
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_IPV4OPTSSTRIP.c iptables-svn/extensions/libipt_IPV4OPTSSTRIP.c
+--- iptables-1.3.7/extensions/libipt_IPV4OPTSSTRIP.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_IPV4OPTSSTRIP.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,74 +0,0 @@
+-/* Shared library add-on to iptables for IPV4OPTSSTRIP
+- * This modules strip all the IP options.
+- *
+- * (C) 2001 by Fabrice MARIE <fabrice@netfilter.org>
+- * This program is distributed under the terms of GNU GPL v2, 1991
+- */
+-
+-#include <stdio.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <getopt.h>
+-
+-#include <iptables.h>
+-#include <linux/netfilter_ipv4/ip_tables.h>
+-
+-static void help(void)
+-{
+- printf("IPV4OPTSSTRIP v%s target takes no option !! Make sure you use it in the mangle table.\n",
+- IPTABLES_VERSION);
+-}
+-
+-static struct option opts[] = {
+- { 0 }
+-};
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-static int
+-parse(int c, char **argv, int invert, unsigned int *flags,
+- const struct ipt_entry *entry,
+- struct ipt_entry_target **target)
+-{
+- return 0;
+-}
+-
+-static void
+-final_check(unsigned int flags)
+-{
+-}
+-
+-/* Prints out the targinfo. */
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_target *target,
+- int numeric)
+-{
+- /* nothing to print, we don't take option... */
+-}
+-
+-/* Saves the stuff in parsable form to stdout. */
+-static void
+-save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
+-{
+- /* nothing to print, we don't take option... */
+-}
+-
+-static struct iptables_target IPV4OPTSSTRIP = {
+- .next = NULL,
+- .name = "IPV4OPTSSTRIP",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(0),
+- .userspacesize = IPT_ALIGN(0),
+- .help = &help,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_target(&IPV4OPTSSTRIP);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_IPV4OPTSSTRIP.man iptables-svn/extensions/libipt_IPV4OPTSSTRIP.man
+--- iptables-1.3.7/extensions/libipt_IPV4OPTSSTRIP.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_IPV4OPTSSTRIP.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,5 +0,0 @@
+-Strip all the IP options from a packet.
+-
+-The target doesn't take any option, and therefore is extremly easy to use :
+-
+-# iptables -t mangle -A PREROUTING -j IPV4OPTSSTRIP
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_MASQUERADE.c iptables-svn/extensions/libipt_MASQUERADE.c
+--- iptables-1.3.7/extensions/libipt_MASQUERADE.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_MASQUERADE.c 2007-05-31 12:46:30.000000000 +0200
+@@ -6,7 +6,7 @@
+ #include <getopt.h>
+ #include <iptables.h>
+ #include <linux/netfilter_ipv4/ip_tables.h>
+-#include <linux/netfilter_ipv4/ip_nat_rule.h>
++#include <linux/netfilter/nf_nat.h>
+
+ /* Function which prints out usage message. */
+ static void
+@@ -15,12 +15,17 @@
+ printf(
+ "MASQUERADE v%s options:\n"
+ " --to-ports <port>[-<port>]\n"
+-" Port (range) to map to.\n\n",
++" Port (range) to map to.\n"
++" --random\n"
++" Randomize source port.\n"
++"\n"
++,
+ IPTABLES_VERSION);
+ }
+
+ static struct option opts[] = {
+ { "to-ports", 1, 0, '1' },
++ { "random", 0, 0, '2' },
+ { 0 }
+ };
+
+@@ -100,6 +105,10 @@
+ parse_ports(optarg, mr);
+ return 1;
+
++ case '2':
++ mr->range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
++ return 1;
++
+ default:
+ return 0;
+ }
+@@ -127,6 +136,9 @@
+ printf("-%hu", ntohs(r->max.tcp.port));
+ printf(" ");
+ }
++
++ if (r->flags & IP_NAT_RANGE_PROTO_RANDOM)
++ printf("random ");
+ }
+
+ /* Saves the union ipt_targinfo in parsable form to stdout. */
+@@ -143,6 +155,9 @@
+ printf("-%hu", ntohs(r->max.tcp.port));
+ printf(" ");
+ }
++
++ if (r->flags & IP_NAT_RANGE_PROTO_RANDOM)
++ printf("--random ");
+ }
+
+ static struct iptables_target masq = { NULL,
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_MASQUERADE.man iptables-svn/extensions/libipt_MASQUERADE.man
+--- iptables-1.3.7/extensions/libipt_MASQUERADE.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_MASQUERADE.man 2007-05-31 12:46:30.000000000 +0200
+@@ -20,3 +20,11 @@
+ .B "-p tcp"
+ or
+ .BR "-p udp" .
++.TP
++.BR "--random"
++Randomize source port mapping
++If option
++.B "--random"
++is used then port mapping will be randomized (kernel >= 2.6.21).
++.RS
++.PP
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_mport.c iptables-svn/extensions/libipt_mport.c
+--- iptables-1.3.7/extensions/libipt_mport.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_mport.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,287 +0,0 @@
+-/* Shared library add-on to iptables to add multiple TCP port support. */
+-#include <stdio.h>
+-#include <netdb.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <getopt.h>
+-#include <iptables.h>
+-#include <linux/netfilter_ipv4/ipt_mport.h>
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf(
+-"mport v%s options:\n"
+-" --source-ports port[,port:port,port...]\n"
+-" --sports ...\n"
+-" match source port(s)\n"
+-" --destination-ports port[,port:port,port...]\n"
+-" --dports ...\n"
+-" match destination port(s)\n"
+-" --ports port[,port:port,port]\n"
+-" match both source and destination port(s)\n",
+-IPTABLES_VERSION);
+-}
+-
+-static struct option opts[] = {
+- { "source-ports", 1, 0, '1' },
+- { "sports", 1, 0, '1' }, /* synonym */
+- { "destination-ports", 1, 0, '2' },
+- { "dports", 1, 0, '2' }, /* synonym */
+- { "ports", 1, 0, '3' },
+- {0}
+-};
+-
+-static void
+-parse_multi_ports(const char *portstring, struct ipt_mport *minfo,
+- const char *proto)
+-{
+- char *buffer, *cp, *next, *range;
+- unsigned int i;
+- u_int16_t m;
+-
+- buffer = strdup(portstring);
+- if (!buffer) exit_error(OTHER_PROBLEM, "strdup failed");
+-
+- minfo->pflags = 0;
+-
+- for (cp=buffer, i=0, m=1; cp && i<IPT_MULTI_PORTS; cp=next,i++,m<<=1)
+- {
+- next=strchr(cp, ',');
+- if (next) *next++='\0';
+- range = strchr(cp, ':');
+- if (range) {
+- if (i == IPT_MULTI_PORTS-1)
+- exit_error(PARAMETER_PROBLEM,
+- "too many ports specified");
+- *range++ = '\0';
+- }
+- minfo->ports[i] = parse_port(cp, proto);
+- if (range) {
+- minfo->pflags |= m;
+- minfo->ports[++i] = parse_port(range, proto);
+- if (minfo->ports[i-1] >= minfo->ports[i])
+- exit_error(PARAMETER_PROBLEM,
+- "invalid portrange specified");
+- m <<= 1;
+- }
+- }
+- if (cp) exit_error(PARAMETER_PROBLEM, "too many ports specified");
+- if (i == IPT_MULTI_PORTS-1)
+- minfo->ports[i] = minfo->ports[i-1];
+- else if (i < IPT_MULTI_PORTS-1) {
+- minfo->ports[i] = ~0;
+- minfo->pflags |= 1<<i;
+- }
+- free(buffer);
+-}
+-
+-/* Initialize the match. */
+-static void
+-init(struct ipt_entry_match *m, unsigned int *nfcache)
+-{
+-}
+-
+-static const char *
+-check_proto(const struct ipt_entry *entry)
+-{
+- if (entry->ip.proto == IPPROTO_TCP)
+- return "tcp";
+- else if (entry->ip.proto == IPPROTO_UDP)
+- return "udp";
+- else if (!entry->ip.proto)
+- exit_error(PARAMETER_PROBLEM,
+- "multiport needs `-p tcp' or `-p udp'");
+- else
+- exit_error(PARAMETER_PROBLEM,
+- "multiport only works with TCP or UDP");
+-}
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-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)
+-{
+- const char *proto;
+- struct ipt_mport *minfo
+- = (struct ipt_mport *)(*match)->data;
+-
+- switch (c) {
+- case '1':
+- check_inverse(argv[optind-1], &invert, &optind, 0);
+- proto = check_proto(entry);
+- parse_multi_ports(argv[optind-1], minfo, proto);
+- minfo->flags = IPT_MPORT_SOURCE;
+- break;
+-
+- case '2':
+- check_inverse(argv[optind-1], &invert, &optind, 0);
+- proto = check_proto(entry);
+- parse_multi_ports(argv[optind-1], minfo, proto);
+- minfo->flags = IPT_MPORT_DESTINATION;
+- break;
+-
+- case '3':
+- check_inverse(argv[optind-1], &invert, &optind, 0);
+- proto = check_proto(entry);
+- parse_multi_ports(argv[optind-1], minfo, proto);
+- minfo->flags = IPT_MPORT_EITHER;
+- break;
+-
+- default:
+- return 0;
+- }
+-
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "multiport does not support invert");
+-
+- if (*flags)
+- exit_error(PARAMETER_PROBLEM,
+- "multiport can only have one option");
+- *flags = 1;
+- return 1;
+-}
+-
+-/* Final check; must specify something. */
+-static void
+-final_check(unsigned int flags)
+-{
+- if (!flags)
+- exit_error(PARAMETER_PROBLEM, "mport expects an option");
+-}
+-
+-static char *
+-port_to_service(int port, u_int8_t proto)
+-{
+- struct servent *service;
+-
+- if ((service = getservbyport(htons(port),
+- proto == IPPROTO_TCP ? "tcp" : "udp")))
+- return service->s_name;
+-
+- return NULL;
+-}
+-
+-static void
+-print_port(u_int16_t port, u_int8_t protocol, int numeric)
+-{
+- char *service;
+-
+- if (numeric || (service = port_to_service(port, protocol)) == NULL)
+- printf("%u", port);
+- else
+- printf("%s", service);
+-}
+-
+-/* Prints out the matchinfo. */
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_match *match,
+- int numeric)
+-{
+- const struct ipt_mport *minfo
+- = (const struct ipt_mport *)match->data;
+- unsigned int i;
+- u_int16_t pflags = minfo->pflags;
+-
+- printf("mport ");
+-
+- switch (minfo->flags) {
+- case IPT_MPORT_SOURCE:
+- printf("sports ");
+- break;
+-
+- case IPT_MPORT_DESTINATION:
+- printf("dports ");
+- break;
+-
+- case IPT_MPORT_EITHER:
+- printf("ports ");
+- break;
+-
+- default:
+- printf("ERROR ");
+- break;
+- }
+-
+- for (i=0; i < IPT_MULTI_PORTS; i++) {
+- if (pflags & (1<<i)
+- && minfo->ports[i] == 65535)
+- break;
+- if (i == IPT_MULTI_PORTS-1
+- && minfo->ports[i-1] == minfo->ports[i])
+- break;
+- printf("%s", i ? "," : "");
+- print_port(minfo->ports[i], ip->proto, numeric);
+- if (pflags & (1<<i)) {
+- printf(":");
+- print_port(minfo->ports[++i], ip->proto, numeric);
+- }
+- }
+- printf(" ");
+-}
+-
+-/* Saves the union ipt_matchinfo in parsable form to stdout. */
+-static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+-{
+- const struct ipt_mport *minfo
+- = (const struct ipt_mport *)match->data;
+- unsigned int i;
+- u_int16_t pflags = minfo->pflags;
+-
+- switch (minfo->flags) {
+- case IPT_MPORT_SOURCE:
+- printf("--sports ");
+- break;
+-
+- case IPT_MPORT_DESTINATION:
+- printf("--dports ");
+- break;
+-
+- case IPT_MPORT_EITHER:
+- printf("--ports ");
+- break;
+- }
+-
+- for (i=0; i < IPT_MULTI_PORTS; i++) {
+- if (pflags & (1<<i)
+- && minfo->ports[i] == 65535)
+- break;
+- if (i == IPT_MULTI_PORTS-1
+- && minfo->ports[i-1] == minfo->ports[i])
+- break;
+- printf("%s", i ? "," : "");
+- print_port(minfo->ports[i], ip->proto, 1);
+- if (pflags & (1<<i)) {
+- printf(":");
+- print_port(minfo->ports[++i], ip->proto, 1);
+- }
+- }
+- printf(" ");
+-}
+-
+-static struct iptables_match mport = {
+- .next = NULL,
+- .name = "mport",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_mport)),
+- .userspacesize = IPT_ALIGN(sizeof(struct ipt_mport)),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void
+-_init(void)
+-{
+- register_match(&mport);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_mport.man iptables-svn/extensions/libipt_mport.man
+--- iptables-1.3.7/extensions/libipt_mport.man 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_mport.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,19 +0,0 @@
+-This module matches a set of source or destination ports. Up to 15
+-ports can be specified. It can only be used in conjunction with
+-.B "-p tcp"
+-or
+-.BR "-p udp" .
+-.TP
+-.BR "--source-ports " "\fIport\fP[,\fIport\fP[,\fIport\fP...]]"
+-Match if the source port is one of the given ports. The flag
+-.B --sports
+-is a convenient alias for this option.
+-.TP
+-.BR "--destination-ports " "\fIport\fP[,\fIport\fP[,\fIport\fP...]]"
+-Match if the destination port is one of the given ports. The flag
+-.B --dports
+-is a convenient alias for this option.
+-.TP
+-.BR "--ports " "\fIport\fP[,\fIport\fP[,\fIport\fP...]]"
+-Match if the both the source and destination ports are equal to each
+-other and to one of the given ports.
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_multiport.c iptables-svn/extensions/libipt_multiport.c
+--- iptables-1.3.7/extensions/libipt_multiport.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_multiport.c 2007-05-31 12:46:30.000000000 +0200
+@@ -59,6 +59,8 @@
+ return "tcp";
+ case IPPROTO_UDP:
+ return "udp";
++ case IPPROTO_UDPLITE:
++ return "udplite";
+ case IPPROTO_SCTP:
+ return "sctp";
+ case IPPROTO_DCCP:
+@@ -141,16 +143,17 @@
+
+ if (entry->ip.invflags & IPT_INV_PROTO)
+ exit_error(PARAMETER_PROBLEM,
+- "multiport only works with TCP or UDP");
++ "multiport only works with TCP, UDP, UDPLITE, SCTP and DCCP");
+
+ if ((proto = proto_to_name(entry->ip.proto)) != NULL)
+ return proto;
+ else if (!entry->ip.proto)
+ exit_error(PARAMETER_PROBLEM,
+- "multiport needs `-p tcp', `-p udp', `-p sctp' or `-p dccp'");
++ "multiport needs `-p tcp', `-p udp', `-p udplite', "
++ "`-p sctp' or `-p dccp'");
+ else
+ exit_error(PARAMETER_PROBLEM,
+- "multiport only works with TCP, UDP, SCTP and DCCP");
++ "multiport only works with TCP, UDP, UDPLITE, SCTP and DCCP");
+ }
+
+ /* Function which parses command options; returns true if it
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_NETLINK.c iptables-svn/extensions/libipt_NETLINK.c
+--- iptables-1.3.7/extensions/libipt_NETLINK.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_NETLINK.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,157 +0,0 @@
+-/* Provides a NETLINK target, identical to that of the ipchains -o flag */
+-/* AUTHOR: Gianni Tedesco <gianni@ecsc.co.uk> */
+-#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/ip_tables.h>
+-#include <linux/netfilter_ipv4/ipt_NETLINK.h>
+-
+-static void help(void)
+-{
+- printf("NETLINK v%s options:\n"
+- " --nldrop Drop the packet too\n"
+- " --nlmark <number> Mark the packet\n"
+- " --nlsize <bytes> Limit packet size\n",
+- IPTABLES_VERSION);
+-}
+-
+-static struct option opts[] = {
+- {"nldrop", 0, 0, 'd'},
+- {"nlmark", 1, 0, 'm'},
+- {"nlsize", 1, 0, 's'},
+- {0}
+-};
+-
+-static void init(struct ipt_entry_target *t, unsigned int *nfcache)
+-{
+- struct ipt_nldata *nld = (struct ipt_nldata *) t->data;
+-
+- nld->flags=0;
+-
+-}
+-
+-/* Parse command options */
+-static int parse(int c, char **argv, int invert, unsigned int *flags,
+- const struct ipt_entry *entry,
+- struct ipt_entry_target **target)
+-{
+- struct ipt_nldata *nld=(struct ipt_nldata *)(*target)->data;
+-
+- switch (c) {
+- case 'd':
+- if (MASK(*flags, USE_DROP))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --nldrop twice");
+-
+- if ( check_inverse(optarg, &invert, NULL, 0) ) {
+- MASK_UNSET(nld->flags, USE_DROP);
+- } else {
+- MASK_SET(nld->flags, USE_DROP);
+- }
+-
+- MASK_SET(*flags, USE_DROP);
+-
+- break;
+- case 'm':
+- if (MASK(*flags, USE_MARK))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --nlmark twice");
+-
+- if (check_inverse(optarg, &invert, NULL, 0)) {
+- MASK_UNSET(nld->flags, USE_MARK);
+- }else{
+- MASK_SET(nld->flags, USE_MARK);
+- nld->mark=atoi(optarg);
+- }
+-
+- MASK_SET(*flags, USE_MARK);
+- break;
+- case 's':
+- if (MASK(*flags, USE_SIZE))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --nlsize twice");
+-
+- if ( atoi(optarg) <= 0 )
+- exit_error(PARAMETER_PROBLEM,
+- "--nlsize must be larger than zero");
+-
+-
+- if (check_inverse(optarg, &invert, NULL, 0)) {
+- MASK_UNSET(nld->flags, USE_SIZE);
+- }else{
+- MASK_SET(nld->flags, USE_SIZE);
+- nld->size=atoi(optarg);
+- }
+- MASK_SET(*flags, USE_SIZE);
+- break;
+-
+- default:
+- return 0;
+- }
+- return 1;
+-}
+-
+-static void final_check(unsigned int flags)
+-{
+- /* ?? */
+-}
+-
+-/* Saves the union ipt_targinfo in parsable form to stdout. */
+-static void save(const struct ipt_ip *ip,
+- const struct ipt_entry_target *target)
+-{
+- const struct ipt_nldata *nld
+- = (const struct ipt_nldata *) target->data;
+-
+- if ( MASK(nld->flags, USE_DROP) )
+- printf("--nldrop ");
+-
+- if ( MASK(nld->flags, USE_MARK) )
+- printf("--nlmark %i ", nld->mark);
+-
+- if ( MASK(nld->flags, USE_SIZE) )
+- printf("--nlsize %i ", nld->size);
+-}
+-
+-/* Prints out the targinfo. */
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_target *target, int numeric)
+-{
+- const struct ipt_nldata *nld
+- = (const struct ipt_nldata *) target->data;
+-
+- if ( MASK(nld->flags, USE_DROP) )
+- printf("nldrop ");
+-
+- if ( MASK(nld->flags, USE_MARK) )
+- printf("nlmark %i ", nld->mark);
+-
+- if ( MASK(nld->flags, USE_SIZE) )
+- printf("nlsize %i ", nld->size);
+-}
+-
+-static struct iptables_target netlink = {
+- .next = NULL,
+- .name = "NETLINK",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_nldata)),
+- .userspacesize = IPT_ALIGN(sizeof(struct ipt_nldata)),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_target(&netlink);
+-}
+-
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_NETMAP.c iptables-svn/extensions/libipt_NETMAP.c
+--- iptables-1.3.7/extensions/libipt_NETMAP.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_NETMAP.c 2007-05-31 12:46:30.000000000 +0200
+@@ -9,7 +9,7 @@
+ #include <getopt.h>
+ #include <iptables.h>
+ #include <linux/netfilter_ipv4/ip_tables.h>
+-#include <linux/netfilter_ipv4/ip_nat_rule.h>
++#include <linux/netfilter/nf_nat.h>
+
+ #define MODULENAME "NETMAP"
+
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_NFLOG.c iptables-svn/extensions/libipt_NFLOG.c
+--- iptables-1.3.7/extensions/libipt_NFLOG.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_NFLOG.c 2007-05-31 12:46:30.000000000 +0200
+@@ -35,7 +35,7 @@
+ {
+ struct xt_nflog_info *info = (struct xt_nflog_info *)t->data;
+
+- info->group = XT_NFLOG_DEFAULT_GROUP;
++ info->group = 0;
+ info->threshold = XT_NFLOG_DEFAULT_THRESHOLD;
+ }
+
+@@ -56,10 +56,10 @@
+ "Unexpected `!' after --nflog-group");
+
+ n = atoi(optarg);
+- if (n < 1 || n > 32)
++ if (n < 0)
+ exit_error(PARAMETER_PROBLEM,
+- "--nflog-group has to be between 1 and 32");
+- info->group = 1 << (n - 1);
++ "--nflog-group can not be negative");
++ info->group = n;
+ break;
+ case NFLOG_PREFIX:
+ if (*flags & NFLOG_PREFIX)
+@@ -118,8 +118,8 @@
+ {
+ if (info->prefix[0] != '\0')
+ printf("%snflog-prefix \"%s\" ", prefix, info->prefix);
+- if (info->group != XT_NFLOG_DEFAULT_GROUP)
+- printf("%snflog-group %u ", prefix, ffs(info->group));
++ if (info->group)
++ printf("%snflog-group %u ", prefix, info->group);
+ if (info->len)
+ printf("%snflog-range %u ", prefix, info->len);
+ if (info->threshold != XT_NFLOG_DEFAULT_THRESHOLD)
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_nth.c iptables-svn/extensions/libipt_nth.c
+--- iptables-1.3.7/extensions/libipt_nth.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_nth.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,230 +0,0 @@
+-/*
+- Shared library add-on to iptables to add match support for every Nth packet
+-
+- 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
+-
+- 2001-07-17 Fabrice MARIE <fabrice@netfilter.org> : initial development.
+- 2001-09-20 Richard Wagner (rwagner@cloudnet.com)
+- * added support for multiple counters
+- * added support for matching on individual packets
+- in the counter cycle
+-*/
+-
+-#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/ip_tables.h>
+-#include <linux/netfilter_ipv4/ipt_nth.h>
+-
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf(
+-"nth v%s options:\n"
+-" --every Nth Match every Nth packet\n"
+-" [--counter num ] Use counter 0-%u (default:0)\n"
+-" [--start num ] Initialize the counter at the number 'num'\n"
+-" instead of 0. Must be between 0 and Nth-1\n"
+-" [--packet num ] Match on 'num' packet. Must be between 0\n"
+-" and Nth-1.\n\n"
+-" If --packet is used for a counter than\n"
+-" there must be Nth number of --packet\n"
+-" rules, covering all values between 0 and\n"
+-" Nth-1 inclusively.\n",
+-IPTABLES_VERSION, IPT_NTH_NUM_COUNTERS-1);
+-}
+-
+-static struct option opts[] = {
+- { "every", 1, 0, '1' },
+- { "start", 1, 0, '2' },
+- { "counter", 1, 0, '3' },
+- { "packet", 1, 0, '4' },
+- { 0 }
+-};
+-
+-#define IPT_NTH_OPT_EVERY 0x01
+-#define IPT_NTH_OPT_NOT_EVERY 0x02
+-#define IPT_NTH_OPT_START 0x04
+-#define IPT_NTH_OPT_COUNTER 0x08
+-#define IPT_NTH_OPT_PACKET 0x10
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-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)
+-{
+- struct ipt_nth_info *nthinfo = (struct ipt_nth_info *)(*match)->data;
+- unsigned int num;
+-
+- switch (c) {
+- case '1':
+- /* check for common mistakes... */
+- if ((!invert) && (*flags & IPT_NTH_OPT_EVERY))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --every twice");
+- if (invert && (*flags & IPT_NTH_OPT_NOT_EVERY))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify ! --every twice");
+- if ((!invert) && (*flags & IPT_NTH_OPT_NOT_EVERY))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --every with ! --every");
+- if (invert && (*flags & IPT_NTH_OPT_EVERY))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify ! --every with --every");
+-
+- /* Remember, this function will interpret a leading 0 to be
+- Octal, a leading 0x to be hexdecimal... */
+- if (string_to_number(optarg, 2, 100, &num) == -1 || num < 2)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --every `%s', must be between 2 and 100", optarg);
+-
+- /* assign the values */
+- nthinfo->every = num-1;
+- nthinfo->startat = 0;
+- nthinfo->packet = 0xFF;
+- if(!(*flags & IPT_NTH_OPT_EVERY))
+- {
+- nthinfo->counter = 0;
+- }
+- if (invert)
+- {
+- *flags |= IPT_NTH_OPT_NOT_EVERY;
+- nthinfo->not = 1;
+- }
+- else
+- {
+- *flags |= IPT_NTH_OPT_EVERY;
+- nthinfo->not = 0;
+- }
+- break;
+- case '2':
+- /* check for common mistakes... */
+- if (!((*flags & IPT_NTH_OPT_EVERY) ||
+- (*flags & IPT_NTH_OPT_NOT_EVERY)))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --start before --every");
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify with ! --start");
+- if (*flags & IPT_NTH_OPT_START)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --start twice");
+- if (string_to_number(optarg, 0, nthinfo->every, &num) == -1)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --start `%s', must between 0 and %u", optarg, nthinfo->every);
+- *flags |= IPT_NTH_OPT_START;
+- nthinfo->startat = num;
+- break;
+- case '3':
+- /* check for common mistakes... */
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify with ! --counter");
+- if (*flags & IPT_NTH_OPT_COUNTER)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --counter twice");
+- if (string_to_number(optarg, 0, IPT_NTH_NUM_COUNTERS-1, &num) == -1)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --counter `%s', must between 0 and %u", optarg, IPT_NTH_NUM_COUNTERS-1);
+- /* assign the values */
+- *flags |= IPT_NTH_OPT_COUNTER;
+- nthinfo->counter = num;
+- break;
+- case '4':
+- /* check for common mistakes... */
+- if (!((*flags & IPT_NTH_OPT_EVERY) ||
+- (*flags & IPT_NTH_OPT_NOT_EVERY)))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --packet before --every");
+- if ((*flags & IPT_NTH_OPT_NOT_EVERY))
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --packet with ! --every");
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify with ! --packet");
+- if (*flags & IPT_NTH_OPT_PACKET)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --packet twice");
+- if (string_to_number(optarg, 0, nthinfo->every, &num) == -1)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --packet `%s', must between 0 and %u", optarg, nthinfo->every);
+- *flags |= IPT_NTH_OPT_PACKET;
+- nthinfo->packet = num;
+- break;
+- default:
+- return 0;
+- }
+- return 1;
+-}
+-
+-/* Final check; nothing. */
+-static void final_check(unsigned int flags)
+-{
+-}
+-
+-/* Prints out the targinfo. */
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_match *match,
+- int numeric)
+-{
+- const struct ipt_nth_info *nthinfo
+- = (const struct ipt_nth_info *)match->data;
+-
+- if (nthinfo->not == 1)
+- printf(" !");
+- printf("every %uth ", (nthinfo->every +1));
+- if (nthinfo->counter != 0)
+- printf("counter #%u ", (nthinfo->counter));
+- if (nthinfo->packet != 0xFF)
+- printf("packet #%u ", nthinfo->packet);
+- if (nthinfo->startat != 0)
+- printf("start at %u ", nthinfo->startat);
+-}
+-
+-/* Saves the union ipt_targinfo in parsable form to stdout. */
+-static void
+-save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+-{
+- const struct ipt_nth_info *nthinfo
+- = (const struct ipt_nth_info *)match->data;
+-
+- if (nthinfo->not == 1)
+- printf("! ");
+- printf("--every %u ", (nthinfo->every +1));
+- printf("--counter %u ", (nthinfo->counter));
+- if (nthinfo->startat != 0)
+- printf("--start %u ", nthinfo->startat );
+- if (nthinfo->packet != 0xFF)
+- printf("--packet %u ", nthinfo->packet );
+-}
+-
+-static struct iptables_match nth = {
+- .next = NULL,
+- .name = "nth",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_nth_info)),
+- .userspacesize = IPT_ALIGN(sizeof(struct ipt_nth_info)),
+- .help = &help,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_match(&nth);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_nth.man iptables-svn/extensions/libipt_nth.man
+--- iptables-1.3.7/extensions/libipt_nth.man 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_nth.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,14 +0,0 @@
+-This module matches every `n'th packet
+-.TP
+-.BI "--every " "value"
+-Match every `value' packet
+-.TP
+-.BI "[" "--counter " "num" "]"
+-Use internal counter number `num'. Default is `0'.
+-.TP
+-.BI "[" "--start " "num" "]"
+-Initialize the counter at the number `num' insetad of `0'. Most between `0'
+-and `value'-1.
+-.TP
+-.BI "[" "--packet " "num" "]"
+-Match on `num' packet. Most be between `0' and `value'-1.
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_osf.c iptables-svn/extensions/libipt_osf.c
+--- iptables-1.3.7/extensions/libipt_osf.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_osf.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,165 +0,0 @@
+-/*
+- * libipt_osf.c
+- *
+- * Copyright (c) 2003 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+- *
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*
+- * iptables interface for OS fingerprint matching module.
+- */
+-
+-#include <stdio.h>
+-#include <netdb.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <getopt.h>
+-#include <ctype.h>
+-
+-#include <iptables.h>
+-#include <linux/netfilter_ipv4/ipt_osf.h>
+-
+-static void help(void)
+-{
+- printf("OS fingerprint match options:\n"
+- "--genre [!] string Match a OS genre by passive fingerprinting.\n"
+- "--smart Use some smart extensions to determine OS (do not use TTL).\n"
+- "--log level Log all(or only first) determined genres even if "
+- "they do not match desired one. "
+- "Level may be 0(all) or 1(only first entry).\n"
+- "--netlink Log through netlink(NETLINK_NFLOG).\n",
+- "--connector Log through kernel connector [in 2.6.12-mm+].\n"
+- );
+-}
+-
+-
+-static struct option opts[] = {
+- { .name = "genre", .has_arg = 1, .flag = 0, .val = '1' },
+- { .name = "smart", .has_arg = 0, .flag = 0, .val = '2' },
+- { .name = "log", .has_arg = 1, .flag = 0, .val = '3' },
+- { .name = "netlink", .has_arg = 0, .flag = 0, .val = '4' },
+- { .name = "connector", .has_arg = 0, .flag = 0, .val = '5' },
+- { .name = 0 }
+-};
+-
+-static void parse_string(const unsigned char *s, struct ipt_osf_info *info)
+-{
+- if (strlen(s) < MAXGENRELEN)
+- strcpy(info->genre, s);
+- else
+- exit_error(PARAMETER_PROBLEM, "Genre string too long `%s' [%d], max=%d",
+- s, strlen(s), MAXGENRELEN);
+-}
+-
+-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)
+-{
+- struct ipt_osf_info *info = (struct ipt_osf_info *)(*match)->data;
+-
+- switch(c)
+- {
+- case '1': /* --genre */
+- if (*flags & IPT_OSF_GENRE)
+- exit_error(PARAMETER_PROBLEM, "Can't specify multiple genre parameter");
+- check_inverse(optarg, &invert, &optind, 0);
+- parse_string(argv[optind-1], info);
+- if (invert)
+- info->invert = 1;
+- info->len=strlen((char *)info->genre);
+- *flags |= IPT_OSF_GENRE;
+- break;
+- case '2': /* --smart */
+- if (*flags & IPT_OSF_SMART)
+- exit_error(PARAMETER_PROBLEM, "Can't specify multiple smart parameter");
+- *flags |= IPT_OSF_SMART;
+- info->flags |= IPT_OSF_SMART;
+- break;
+- case '3': /* --log */
+- if (*flags & IPT_OSF_LOG)
+- exit_error(PARAMETER_PROBLEM, "Can't specify multiple log parameter");
+- *flags |= IPT_OSF_LOG;
+- info->loglevel = atoi(argv[optind-1]);
+- info->flags |= IPT_OSF_LOG;
+- break;
+- case '4': /* --netlink */
+- if (*flags & IPT_OSF_NETLINK)
+- exit_error(PARAMETER_PROBLEM, "Can't specify multiple netlink parameter");
+- *flags |= IPT_OSF_NETLINK;
+- info->flags |= IPT_OSF_NETLINK;
+- break;
+- case '5': /* --connector */
+- if (*flags & IPT_OSF_CONNECTOR)
+- exit_error(PARAMETER_PROBLEM, "Can't specify multiple connector parameter");
+- *flags |= IPT_OSF_CONNECTOR;
+- info->flags |= IPT_OSF_CONNECTOR;
+- break;
+- default:
+- return 0;
+- }
+-
+- return 1;
+-}
+-
+-static void final_check(unsigned int flags)
+-{
+- if (!flags)
+- exit_error(PARAMETER_PROBLEM, "OS fingerprint match: You must specify `--genre'");
+-}
+-
+-static void print(const struct ipt_ip *ip, const struct ipt_entry_match *match, int numeric)
+-{
+- const struct ipt_osf_info *info = (const struct ipt_osf_info*) match->data;
+-
+- printf("OS fingerprint match %s%s ", (info->invert) ? "!" : "", info->genre);
+-}
+-
+-static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+-{
+- const struct ipt_osf_info *info = (const struct ipt_osf_info*) match->data;
+-
+- printf("--genre %s%s ", (info->invert) ? "! ": "", info->genre);
+- if (info->flags & IPT_OSF_SMART)
+- printf("--smart ");
+- if (info->flags & IPT_OSF_LOG)
+- printf("--log %d ", info->loglevel);
+- if (info->flags & IPT_OSF_NETLINK)
+- printf("--netlink ");
+- if (info->flags & IPT_OSF_CONNECTOR)
+- printf("--connector ");
+-}
+-
+-
+-static struct iptables_match osf_match = {
+- .name = "osf",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_osf_info)),
+- .userspacesize = IPT_ALIGN(sizeof(struct ipt_osf_info)),
+- .help = &help,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-
+-void _init(void)
+-{
+- register_match(&osf_match);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_osf.man iptables-svn/extensions/libipt_osf.man
+--- iptables-1.3.7/extensions/libipt_osf.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_osf.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,47 +0,0 @@
+-The idea of passive OS fingerprint matching exists for quite a long time,
+-but was created as extension fo OpenBSD pf only some weeks ago.
+-Original idea was lurked in some OpenBSD mailing list (thanks
+-grange@open...) and than adopted for Linux netfilter in form of this code.
+-
+-Original fingerprint table was created by Michal Zalewski <lcamtuf@coredump.cx>.
+-
+-This module compares some data(WS, MSS, options and it's order, ttl,
+-df and others) from first SYN packet (actually from packets with SYN
+-bit set) with dynamically loaded OS fingerprints.
+-.TP
+-.B "--log 1/0"
+-If present, OSF will log determined genres even if they don't match
+-desired one.
+-0 - log all determined entries,
+-1 - only first one.
+-
+-In syslog you find something like this:
+-.IP
+-ipt_osf: Windows [2000:SP3:Windows XP Pro SP1, 2000 SP3]: 11.22.33.55:4024 -> 11.22.33.44:139
+-.IP
+-ipt_osf: Unknown: 16384:106:1:48:020405B401010402 44.33.22.11:1239 -> 11.22.33.44:80
+-.TP
+-.B "--smart"
+-if present, OSF will use some smartness to determine remote OS.
+-OSF will use initial TTL only if source of connection is in our local network.
+-.TP
+-.B "--netlink"
+-If present, OSF will log all events also through netlink NETLINK_NFLOG groupt 1.
+-.TP
+-.BI "--genre " "[!] string"
+-Match a OS genre by passive fingerprinting
+-.P
+-Example:
+-
+-#iptables -I INPUT -j ACCEPT -p tcp -m osf --genre Linux --log 1 --smart
+-
+-NOTE: -p tcp is obviously required as it is a TCP match.
+-
+-Fingerprints can be loaded and read through /proc/sys/net/ipv4/osf file.
+-One can flush all fingerprints with following command:
+-.IP
+-echo -en FLUSH > /proc/sys/net/ipv4/osf
+-.P
+-Only one fingerprint per open/write/close.
+-
+-Fingerprints can be downloaded from http://www.openbsd.org/cgi-bin/cvsweb/src/etc/pf.os
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_psd.c iptables-svn/extensions/libipt_psd.c
+--- iptables-1.3.7/extensions/libipt_psd.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_psd.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,194 +0,0 @@
+-/*
+- Shared library add-on to iptables to add PSD support
+-
+- Copyright (C) 2000,2001 astaro AG
+-
+- 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
+-
+- 2000-05-04 Markus Hennig <hennig@astaro.de> : initial
+- 2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
+- 2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
+- 2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
+- 2003-03-02 Harald Welte <laforge@netfilter.org>: fix 'storage' bug
+-*/
+-
+-#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/ip_tables.h>
+-#include <linux/netfilter_ipv4/ipt_psd.h>
+-
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf(
+-"psd v%s options:\n"
+-" --psd-weight-threshold threshhold Portscan detection weight threshold\n\n"
+-" --psd-delay-threshold delay Portscan detection delay threshold\n\n"
+-" --psd-lo-ports-weight lo Privileged ports weight\n\n"
+-" --psd-hi-ports-weight hi High ports weight\n\n",
+-IPTABLES_VERSION);
+-}
+-
+-static struct option opts[] = {
+- { "psd-weight-threshold", 1, 0, '1' },
+- { "psd-delay-threshold", 1, 0, '2' },
+- { "psd-lo-ports-weight", 1, 0, '3' },
+- { "psd-hi-ports-weight", 1, 0, '4' },
+- { 0 }
+-};
+-
+-/* Initialize the target. */
+-static void
+-init(struct ipt_entry_match *m, unsigned int *nfcache)
+-{
+- struct ipt_psd_info *psdinfo = (struct ipt_psd_info *)m->data;
+-
+- psdinfo->weight_threshold = SCAN_WEIGHT_THRESHOLD;
+- psdinfo->delay_threshold = SCAN_DELAY_THRESHOLD;
+- psdinfo->lo_ports_weight = PORT_WEIGHT_PRIV;
+- psdinfo->hi_ports_weight = PORT_WEIGHT_HIGH;
+-}
+-
+-
+-typedef struct _code {
+- char *c_name;
+- int c_val;
+-} CODE;
+-
+-
+-
+-#define IPT_PSD_OPT_CTRESH 0x01
+-#define IPT_PSD_OPT_DTRESH 0x02
+-#define IPT_PSD_OPT_LPWEIGHT 0x04
+-#define IPT_PSD_OPT_HPWEIGHT 0x08
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-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)
+-{
+- struct ipt_psd_info *psdinfo = (struct ipt_psd_info *)(*match)->data;
+- unsigned int num;
+-
+- switch (c) {
+- /* PSD-weight-threshold */
+- case '1':
+- if (*flags & IPT_PSD_OPT_CTRESH)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --psd-weight-threshold "
+- "twice");
+- if (string_to_number(optarg, 0, 10000, &num) == -1)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --psd-weight-threshold `%s'", optarg);
+- psdinfo->weight_threshold = num;
+- *flags |= IPT_PSD_OPT_CTRESH;
+- break;
+-
+- /* PSD-delay-threshold */
+- case '2':
+- if (*flags & IPT_PSD_OPT_DTRESH)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --psd-delay-threshold twice");
+- if (string_to_number(optarg, 0, 10000, &num) == -1)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --psd-delay-threshold `%s'", optarg);
+- psdinfo->delay_threshold = num;
+- *flags |= IPT_PSD_OPT_DTRESH;
+- break;
+-
+- /* PSD-lo-ports-weight */
+- case '3':
+- if (*flags & IPT_PSD_OPT_LPWEIGHT)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --psd-lo-ports-weight twice");
+- if (string_to_number(optarg, 0, 10000, &num) == -1)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --psd-lo-ports-weight `%s'", optarg);
+- psdinfo->lo_ports_weight = num;
+- *flags |= IPT_PSD_OPT_LPWEIGHT;
+- break;
+-
+- /* PSD-hi-ports-weight */
+- case '4':
+- if (*flags & IPT_PSD_OPT_HPWEIGHT)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --psd-hi-ports-weight twice");
+- if (string_to_number(optarg, 0, 10000, &num) == -1)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --psd-hi-ports-weight `%s'", optarg);
+- psdinfo->hi_ports_weight = num;
+- *flags |= IPT_PSD_OPT_HPWEIGHT;
+- break;
+-
+- default:
+- return 0;
+- }
+-
+- return 1;
+-}
+-
+-/* Final check; nothing. */
+-static void final_check(unsigned int flags)
+-{
+-}
+-
+-/* Prints out the targinfo. */
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_match *match,
+- int numeric)
+-{
+- const struct ipt_psd_info *psdinfo
+- = (const struct ipt_psd_info *)match->data;
+-
+- printf("psd ");
+- printf("weight-threshold: %u ", psdinfo->weight_threshold);
+- printf("delay-threshold: %u ", psdinfo->delay_threshold);
+- printf("lo-ports-weight: %u ", psdinfo->lo_ports_weight);
+- printf("hi-ports-weight: %u ", psdinfo->hi_ports_weight);
+-}
+-
+-/* Saves the union ipt_targinfo in parsable form to stdout. */
+-static void
+-save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+-{
+- const struct ipt_psd_info *psdinfo
+- = (const struct ipt_psd_info *)match->data;
+-
+- printf("--psd-weight-threshold %u ", psdinfo->weight_threshold);
+- printf("--psd-delay-threshold %u ", psdinfo->delay_threshold);
+- printf("--psd-lo-ports-weight %u ", psdinfo->lo_ports_weight);
+- printf("--psd-hi-ports-weight %u ", psdinfo->hi_ports_weight);
+-}
+-
+-static struct iptables_match psd = {
+- .next = NULL,
+- .name = "psd",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_psd_info)),
+- .userspacesize = IPT_ALIGN(sizeof(struct ipt_psd_info)),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_match(&psd);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_psd.man iptables-svn/extensions/libipt_psd.man
+--- iptables-1.3.7/extensions/libipt_psd.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_psd.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,18 +0,0 @@
+-Attempt to detect TCP and UDP port scans. This match was derived from
+-Solar Designer's scanlogd.
+-.TP
+-.BI "--psd-weight-threshold " "threshold"
+-Total weight of the latest TCP/UDP packets with different
+-destination ports coming from the same host to be treated as port
+-scan sequence.
+-.TP
+-.BI "--psd-delay-threshold " "delay"
+-Delay (in hundredths of second) for the packets with different
+-destination ports coming from the same host to be treated as
+-possible port scan subsequence.
+-.TP
+-.BI "--psd-lo-ports-weight " "weight"
+-Weight of the packet with privileged (<=1024) destination port.
+-.TP
+-.BI "--psd-hi-ports-weight " "weight"
+-Weight of the packet with non-priviliged destination port.
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_quota.man iptables-svn/extensions/libipt_quota.man
+--- iptables-1.3.7/extensions/libipt_quota.man 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_quota.man 2007-05-31 12:46:30.000000000 +0200
+@@ -4,4 +4,3 @@
+ .BI "--quota " "bytes"
+ The quota in bytes.
+ .P
+-KNOWN BUGS: this does not work on SMP systems.
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_random.c iptables-svn/extensions/libipt_random.c
+--- iptables-1.3.7/extensions/libipt_random.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_random.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,150 +0,0 @@
+-/*
+- Shared library add-on to iptables to add match support for random match.
+-
+- 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
+-
+- 2001-10-14 Fabrice MARIE <fabrice@netfilter.org> : initial development.
+-*/
+-
+-#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/ip_tables.h>
+-#include <linux/netfilter_ipv4/ipt_random.h>
+-
+-/**
+- * The kernel random routing returns numbers between 0 and 255.
+- * To ease the task of the user in choosing the probability
+- * of matching, we want him to be able to use percentages.
+- * Therefore we have to accept numbers in percentage here,
+- * turn them into number between 0 and 255 for the kernel module,
+- * and turn them back to percentages when we print/save
+- * the rule.
+- */
+-
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf(
+-"random v%s options:\n"
+-" [--average percent ] The probability in percentage of the match\n"
+-" If ommited, a probability of 50%% percent is set.\n"
+-" Percentage must be within : 1 <= percent <= 99.\n\n",
+-IPTABLES_VERSION);
+-}
+-
+-static struct option opts[] = {
+- { "average", 1, 0, '1' },
+- { 0 }
+-};
+-
+-/* Initialize the target. */
+-static void
+-init(struct ipt_entry_match *m, unsigned int *nfcache)
+-{
+- struct ipt_rand_info *randinfo = (struct ipt_rand_info *)(m)->data;
+-
+- /* We assign the average to be 50 which is our default value */
+- /* 50 * 2.55 = 128 */
+- randinfo->average = 128;
+-}
+-
+-#define IPT_RAND_OPT_AVERAGE 0x01
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-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)
+-{
+- struct ipt_rand_info *randinfo = (struct ipt_rand_info *)(*match)->data;
+- unsigned int num;
+-
+- switch (c) {
+- case '1':
+- /* check for common mistakes... */
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify ! --average");
+- if (*flags & IPT_RAND_OPT_AVERAGE)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --average twice");
+-
+- /* Remember, this function will interpret a leading 0 to be
+- Octal, a leading 0x to be hexdecimal... */
+- if (string_to_number(optarg, 1, 99, &num) == -1 || num < 1)
+- exit_error(PARAMETER_PROBLEM,
+- "bad --average `%s', must be between 1 and 99", optarg);
+-
+- /* assign the values */
+- randinfo->average = (int)(num * 2.55);
+- *flags |= IPT_RAND_OPT_AVERAGE;
+- break;
+- default:
+- return 0;
+- }
+- return 1;
+-}
+-
+-/* Final check; nothing. */
+-static void final_check(unsigned int flags)
+-{
+-}
+-
+-/* Prints out the targinfo. */
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_match *match,
+- int numeric)
+-{
+- const struct ipt_rand_info *randinfo
+- = (const struct ipt_rand_info *)match->data;
+- div_t result = div((randinfo->average*100), 255);
+- if (result.rem > 127) /* round up... */
+- ++result.quot;
+-
+- printf(" random %u%% ", result.quot);
+-}
+-
+-/* Saves the union ipt_targinfo in parsable form to stdout. */
+-static void
+-save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+-{
+- const struct ipt_rand_info *randinfo
+- = (const struct ipt_rand_info *)match->data;
+- div_t result = div((randinfo->average *100), 255);
+- if (result.rem > 127) /* round up... */
+- ++result.quot;
+-
+- printf("--average %u ", result.quot);
+-}
+-
+-struct iptables_match rand_match = {
+- .next = NULL,
+- .name = "random",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_rand_info)),
+- .userspacesize = IPT_ALIGN(sizeof(struct ipt_rand_info)),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_match(&rand_match);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_random.man iptables-svn/extensions/libipt_random.man
+--- iptables-1.3.7/extensions/libipt_random.man 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_random.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,4 +0,0 @@
+-This module randomly matches a certain percentage of all packets.
+-.TP
+-.BI "--average " "percent"
+-Matches the given percentage. If omitted, a probability of 50% is set.
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_record_rpc.c iptables-svn/extensions/libipt_record_rpc.c
+--- iptables-1.3.7/extensions/libipt_record_rpc.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_record_rpc.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,65 +0,0 @@
+-/* Shared library add-on to iptables for rpc match */
+-#include <stdio.h>
+-#include <getopt.h>
+-#include <iptables.h>
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf(
+-"record_rpc v%s takes no options\n"
+-"\n", IPTABLES_VERSION);
+-}
+-
+-static struct option opts[] = {
+- {0}
+-};
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-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)
+-{
+- return 0;
+-}
+-
+-/* Final check; must have specified --mac. */
+-static void final_check(unsigned int flags)
+-{
+-}
+-
+-/* Prints out the union ipt_matchinfo. */
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_match *match,
+- int numeric)
+-{
+-}
+-
+-static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+-{
+-}
+-
+-static
+-struct iptables_match record_rpc = {
+- .next = NULL,
+- .name = "record_rpc",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(0),
+- .userspacesize = IPT_ALIGN(0),
+- .help = &help,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_match(&record_rpc);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_REDIRECT.c iptables-svn/extensions/libipt_REDIRECT.c
+--- iptables-1.3.7/extensions/libipt_REDIRECT.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_REDIRECT.c 2007-05-31 12:46:30.000000000 +0200
+@@ -6,7 +6,10 @@
+ #include <getopt.h>
+ #include <iptables.h>
+ #include <linux/netfilter_ipv4/ip_tables.h>
+-#include <linux/netfilter_ipv4/ip_nat_rule.h>
++#include <linux/netfilter/nf_nat.h>
++
++#define IPT_REDIRECT_OPT_DEST 0x01
++#define IPT_REDIRECT_OPT_RANDOM 0x02
+
+ /* Function which prints out usage message. */
+ static void
+@@ -21,6 +24,7 @@
+
+ static struct option opts[] = {
+ { "to-ports", 1, 0, '1' },
++ { "random", 1, 0, '2' },
+ { 0 }
+ };
+
+@@ -101,6 +105,17 @@
+ "Unexpected `!' after --to-ports");
+
+ parse_ports(optarg, mr);
++ if (*flags & IPT_REDIRECT_OPT_RANDOM)
++ mr->range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
++ *flags |= IPT_REDIRECT_OPT_DEST;
++ return 1;
++
++ case '2':
++ if (*flags & IPT_REDIRECT_OPT_DEST) {
++ mr->range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
++ *flags |= IPT_REDIRECT_OPT_RANDOM;
++ } else
++ *flags |= IPT_REDIRECT_OPT_RANDOM;
+ return 1;
+
+ default:
+@@ -129,6 +144,8 @@
+ if (r->max.tcp.port != r->min.tcp.port)
+ printf("-%hu", ntohs(r->max.tcp.port));
+ printf(" ");
++ if (mr->range[0].flags & IP_NAT_RANGE_PROTO_RANDOM)
++ printf("random ");
+ }
+ }
+
+@@ -146,6 +163,8 @@
+ if (r->max.tcp.port != r->min.tcp.port)
+ printf("-%hu", ntohs(r->max.tcp.port));
+ printf(" ");
++ if (mr->range[0].flags & IP_NAT_RANGE_PROTO_RANDOM)
++ printf("--random ");
+ }
+ }
+
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_REDIRECT.man iptables-svn/extensions/libipt_REDIRECT.man
+--- iptables-1.3.7/extensions/libipt_REDIRECT.man 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_REDIRECT.man 2007-05-31 12:46:30.000000000 +0200
+@@ -17,3 +17,10 @@
+ .B "-p tcp"
+ or
+ .BR "-p udp" .
++.TP
++.BR "--random"
++If option
++.B "--random"
++is used then port mapping will be randomized (kernel >= 2.6.22).
++.RS
++.PP
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_ROUTE.c iptables-svn/extensions/libipt_ROUTE.c
+--- iptables-1.3.7/extensions/libipt_ROUTE.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_ROUTE.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,264 +0,0 @@
+-/* Shared library add-on to iptables to add ROUTE target support.
+- * Author : Cedric de Launois, <delaunois@info.ucl.ac.be>
+- * v 1.11 2004/11/23
+- */
+-
+-#include <stdio.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <getopt.h>
+-#include <iptables.h>
+-#include <net/if.h>
+-#include <sys/socket.h>
+-#include <netinet/in.h>
+-#include <arpa/inet.h>
+-#include <linux/netfilter_ipv4/ip_tables.h>
+-#include <linux/netfilter_ipv4/ipt_ROUTE.h>
+-
+-/* compile IPT_ROUTE_TEE support even if kernel headers are unpatched */
+-#ifndef IPT_ROUTE_TEE
+-#define IPT_ROUTE_TEE 0x02
+-#endif
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf(
+-"ROUTE target v%s options:\n"
+-" --oif \tifname \t\tRoute packet through `ifname' network interface\n"
+-" --iif \tifname \t\tChange packet's incoming interface to `ifname'\n"
+-" --gw \tip \t\tRoute packet via this gateway `ip'\n"
+-" --continue\t \t\tRoute packet and continue traversing the\n"
+-" \t \t\trules. Not valid with --iif or --tee.\n"
+-" --tee\t \t\tDuplicate packet, route the duplicate,\n"
+-" \t \t\tcontinue traversing with original packet.\n"
+-" \t \t\tNot valid with --iif or --continue.\n"
+-"\n",
+-"1.11");
+-}
+-
+-static struct option opts[] = {
+- { "oif", 1, 0, '1' },
+- { "iif", 1, 0, '2' },
+- { "gw", 1, 0, '3' },
+- { "continue", 0, 0, '4' },
+- { "tee", 0, 0, '5' },
+- { 0 }
+-};
+-
+-/* Initialize the target. */
+-static void
+-init(struct ipt_entry_target *t, unsigned int *nfcache)
+-{
+- struct ipt_route_target_info *route_info =
+- (struct ipt_route_target_info*)t->data;
+-
+- route_info->oif[0] = '\0';
+- route_info->iif[0] = '\0';
+- route_info->gw = 0;
+- route_info->flags = 0;
+-}
+-
+-
+-#define IPT_ROUTE_OPT_OIF 0x01
+-#define IPT_ROUTE_OPT_IIF 0x02
+-#define IPT_ROUTE_OPT_GW 0x04
+-#define IPT_ROUTE_OPT_CONTINUE 0x08
+-#define IPT_ROUTE_OPT_TEE 0x10
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-static int
+-parse(int c, char **argv, int invert, unsigned int *flags,
+- const struct ipt_entry *entry,
+- struct ipt_entry_target **target)
+-{
+- struct ipt_route_target_info *route_info =
+- (struct ipt_route_target_info*)(*target)->data;
+-
+- switch (c) {
+- case '1':
+- if (*flags & IPT_ROUTE_OPT_OIF)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --oif twice");
+-
+- if (*flags & IPT_ROUTE_OPT_IIF)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't use --oif and --iif together");
+-
+- if (check_inverse(optarg, &invert, NULL, 0))
+- exit_error(PARAMETER_PROBLEM,
+- "Unexpected `!' after --oif");
+-
+- if (strlen(optarg) > sizeof(route_info->oif) - 1)
+- exit_error(PARAMETER_PROBLEM,
+- "Maximum interface name length %u",
+- sizeof(route_info->oif) - 1);
+-
+- strcpy(route_info->oif, optarg);
+- *flags |= IPT_ROUTE_OPT_OIF;
+- break;
+-
+- case '2':
+- if (*flags & IPT_ROUTE_OPT_IIF)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --iif twice");
+-
+- if (*flags & IPT_ROUTE_OPT_OIF)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't use --iif and --oif together");
+-
+- if (check_inverse(optarg, &invert, NULL, 0))
+- exit_error(PARAMETER_PROBLEM,
+- "Unexpected `!' after --iif");
+-
+- if (strlen(optarg) > sizeof(route_info->iif) - 1)
+- exit_error(PARAMETER_PROBLEM,
+- "Maximum interface name length %u",
+- sizeof(route_info->iif) - 1);
+-
+- strcpy(route_info->iif, optarg);
+- *flags |= IPT_ROUTE_OPT_IIF;
+- break;
+-
+- case '3':
+- if (*flags & IPT_ROUTE_OPT_GW)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --gw twice");
+-
+- if (check_inverse(optarg, &invert, NULL, 0))
+- exit_error(PARAMETER_PROBLEM,
+- "Unexpected `!' after --gw");
+-
+- if (!inet_aton(optarg, (struct in_addr*)&route_info->gw)) {
+- exit_error(PARAMETER_PROBLEM,
+- "Invalid IP address %s",
+- optarg);
+- }
+-
+- *flags |= IPT_ROUTE_OPT_GW;
+- break;
+-
+- case '4':
+- if (*flags & IPT_ROUTE_OPT_CONTINUE)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --continue twice");
+- if (*flags & IPT_ROUTE_OPT_TEE)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --continue AND --tee");
+-
+- route_info->flags |= IPT_ROUTE_CONTINUE;
+- *flags |= IPT_ROUTE_OPT_CONTINUE;
+-
+- break;
+-
+- case '5':
+- if (*flags & IPT_ROUTE_OPT_TEE)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --tee twice");
+- if (*flags & IPT_ROUTE_OPT_CONTINUE)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --tee AND --continue");
+-
+- route_info->flags |= IPT_ROUTE_TEE;
+- *flags |= IPT_ROUTE_OPT_TEE;
+-
+- break;
+-
+- default:
+- return 0;
+- }
+-
+- return 1;
+-}
+-
+-
+-static void
+-final_check(unsigned int flags)
+-{
+- if (!flags)
+- exit_error(PARAMETER_PROBLEM,
+- "ROUTE target: oif, iif or gw option required");
+-
+- if ((flags & (IPT_ROUTE_OPT_CONTINUE|IPT_ROUTE_OPT_TEE)) && (flags & IPT_ROUTE_OPT_IIF))
+- exit_error(PARAMETER_PROBLEM,
+- "ROUTE target: can't continue traversing the rules with iif option");
+-}
+-
+-
+-/* Prints out the targinfo. */
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_target *target,
+- int numeric)
+-{
+- const struct ipt_route_target_info *route_info
+- = (const struct ipt_route_target_info *)target->data;
+-
+- printf("ROUTE ");
+-
+- if (route_info->oif[0])
+- printf("oif:%s ", route_info->oif);
+-
+- if (route_info->iif[0])
+- printf("iif:%s ", route_info->iif);
+-
+- if (route_info->gw) {
+- struct in_addr ip = { route_info->gw };
+- printf("gw:%s ", inet_ntoa(ip));
+- }
+-
+- if (route_info->flags & IPT_ROUTE_CONTINUE)
+- printf("continue");
+-
+- if (route_info->flags & IPT_ROUTE_TEE)
+- printf("tee");
+-
+-}
+-
+-
+-static void save(const struct ipt_ip *ip,
+- const struct ipt_entry_target *target)
+-{
+- const struct ipt_route_target_info *route_info
+- = (const struct ipt_route_target_info *)target->data;
+-
+- if (route_info->oif[0])
+- printf("--oif %s ", route_info->oif);
+-
+- if (route_info->iif[0])
+- printf("--iif %s ", route_info->iif);
+-
+- if (route_info->gw) {
+- struct in_addr ip = { route_info->gw };
+- printf("--gw %s ", inet_ntoa(ip));
+- }
+-
+- if (route_info->flags & IPT_ROUTE_CONTINUE)
+- printf("--continue ");
+-
+- if (route_info->flags & IPT_ROUTE_TEE)
+- printf("--tee ");
+-}
+-
+-
+-static struct iptables_target route = {
+- .next = NULL,
+- .name = "ROUTE",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_route_target_info)),
+- .userspacesize = IPT_ALIGN(sizeof(struct ipt_route_target_info)),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_target(&route);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_ROUTE.man iptables-svn/extensions/libipt_ROUTE.man
+--- iptables-1.3.7/extensions/libipt_ROUTE.man 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_ROUTE.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,18 +0,0 @@
+-This is used to explicitly override the core network stack's routing decision.
+-.B mangle
+-table.
+-.TP
+-.BI "--oif " "ifname"
+-Route the packet through `ifname' network interface
+-.TP
+-.BI "--iif " "ifname"
+-Change the packet's incoming interface to `ifname'
+-.TP
+-.BI "--gw " "IP_address"
+-Route the packet via this gateway
+-.TP
+-.BI "--continue "
+-Behave like a non-terminating target and continue traversing the rules. Not valid in combination with `--iif' or `--tee'
+-.TP
+-.BI "--tee "
+-Make a copy of the packet, and route that copy to the given destination. For the original, uncopied packet, behave like a non-terminating target and continue traversing the rules. Not valid in combination with `--iif' or `--continue'
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_rpc.c iptables-svn/extensions/libipt_rpc.c
+--- iptables-1.3.7/extensions/libipt_rpc.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_rpc.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,373 +0,0 @@
+-/* RPC extension for IP connection matching, Version 2.2
+- * (C) 2000 by Marcelo Barbosa Lima <marcelo.lima@dcc.unicamp.br>
+- * - original rpc tracking module
+- * - "recent" connection handling for kernel 2.3+ netfilter
+- *
+- * (C) 2001 by Rusty Russell <rusty@rustcorp.com.au>
+- * - upgraded conntrack modules to oldnat api - kernel 2.4.0+
+- *
+- * (C) 2002,2003 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
+- * - upgraded conntrack modules to newnat api - kernel 2.4.20+
+- * - extended matching to support filtering on procedures
+- *
+- * libipt_rpc.c,v 2.2 2003/01/12 18:30:00
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version
+- * 2 of the License, or (at your option) any later version.
+- **
+- * Userspace library syntax:
+- * --rpc [--rpcs procedure1,procedure2,...procedure128] [--static]
+- *
+- * Procedures can be supplied in either numeric or named formats.
+- * Without --rpcs, this module will behave as the old record-rpc.
+- **
+- * Note to all:
+- *
+- * RPCs should not be exposed to the internet - ask the Pentagon;
+- *
+- * "The unidentified crackers pleaded guilty in July to charges
+- * of juvenile delinquency stemming from a string of Pentagon
+- * network intrusions in February.
+- *
+- * The youths, going by the names TooShort and Makaveli, used
+- * a common server security hole to break in, according to
+- * Dane Jasper, owner of the California Internet service
+- * provider, Sonic. They used the hole, known as the 'statd'
+- * exploit, to attempt more than 800 break-ins, Jasper said."
+- *
+- * From: Wired News; "Pentagon Kids Kicked Off Grid" - Nov 6, 1998
+- * URL: http://www.wired.com/news/politics/0,1283,16098,00.html
+- **
+- */
+-
+-#include <stdio.h>
+-#include <netdb.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <getopt.h>
+-#include <rpc/rpc.h>
+-
+-#include <iptables.h>
+-#include <linux/netfilter_ipv4/ipt_rpc.h>
+-#include <time.h>
+-
+-
+-const int IPT_RPC_RPCS = 1;
+-const int IPT_RPC_STRC = 2;
+-
+-const int IPT_RPC_INT_LBL = 1;
+-const int IPT_RPC_INT_NUM = 2;
+-const int IPT_RPC_INT_BTH = 3;
+-
+-const int IPT_RPC_CHAR_LEN = 11;
+-const int IPT_RPC_MAX_ENTS = 128;
+-
+-const char preerr[11] = "RPC match:";
+-
+-
+-static int k_itoa(char *string, int number)
+-{
+- int maxoctet = IPT_RPC_CHAR_LEN - 1;
+- int store[IPT_RPC_CHAR_LEN];
+- int counter;
+-
+-
+- for (counter=0 ; maxoctet != 0 && number != 0; counter++, maxoctet--) {
+- store[counter] = number / 10;
+- store[counter] = number - ( store[counter] * 10 );
+- number = number / 10;
+- }
+-
+- for ( ; counter != 0; counter--, string++)
+- *string = store[counter - 1] + 48;
+-
+- *string = 0;
+-
+- return(0);
+-}
+-
+-
+-static int k_atoi(char *string)
+-{
+- unsigned int result = 0;
+- int maxoctet = IPT_RPC_CHAR_LEN;
+-
+-
+- for ( ; *string != 0 && maxoctet != 0; maxoctet--, string++) {
+- if (*string < 0)
+- return(0);
+- if (*string == 0)
+- break;
+- if (*string < 48 || *string > 57) {
+- return(0);
+- }
+- result = result * 10 + ( *string - 48 );
+- }
+-
+- return(result);
+-}
+-
+-
+-static void print_rpcs(char *c_procs, int i_procs, int labels)
+-{
+- int proc_ctr;
+- char *proc_ptr;
+- unsigned int proc_num;
+- struct rpcent *rpcent;
+-
+-
+- for (proc_ctr=0; proc_ctr <= i_procs; proc_ctr++) {
+-
+- if ( proc_ctr != 0 )
+- printf(",");
+-
+- proc_ptr = c_procs;
+- proc_ptr += proc_ctr * IPT_RPC_CHAR_LEN;
+- proc_num = k_atoi(proc_ptr);
+-
+- /* labels(1) == no labels, only numbers
+- * labels(2) == no numbers, only labels
+- * labels(3) == both labels and numbers
+- */
+-
+- if (labels == IPT_RPC_INT_LBL || labels == IPT_RPC_INT_BTH ) {
+- if ( (rpcent = getrpcbynumber(proc_num)) == NULL )
+- printf("unknown");
+- else
+- printf("%s", rpcent->r_name);
+- }
+-
+- if (labels == IPT_RPC_INT_BTH )
+- printf("(");
+-
+- if (labels == IPT_RPC_INT_NUM || labels == IPT_RPC_INT_BTH )
+- printf("%i", proc_num);
+-
+- if (labels == IPT_RPC_INT_BTH )
+- printf(")");
+-
+- }
+-
+-}
+-
+-
+-static void help(void)
+-{
+- printf(
+- "RPC v%s options:\n"
+- " --rpcs list,of,procedures"
+- "\ta list of rpc program numbers to apply\n"
+- "\t\t\t\tie. 100003,mountd,rquotad (numeric or\n"
+- "\t\t\t\tname form; see /etc/rpc).\n"
+- " --strict"
+- "\t\t\ta flag to force the drop of packets\n"
+- "\t\t\t\tnot containing \"get\" portmapper requests.\n",
+- IPTABLES_VERSION);
+-}
+-
+-
+-static struct option opts[] = {
+- { "rpcs", 1, 0, '1'},
+- { "strict", 0, 0, '2'},
+- {0}
+-};
+-
+-
+-static void init(struct ipt_entry_match *match, unsigned int *nfcache)
+-{
+- struct ipt_rpc_info *rpcinfo = ((struct ipt_rpc_info *)match->data);
+-
+-
+-
+- /* initialise those funky user vars */
+- rpcinfo->i_procs = -1;
+- rpcinfo->strict = 0;
+- memset((char *)rpcinfo->c_procs, 0, sizeof(rpcinfo->c_procs));
+-}
+-
+-
+-static void parse_rpcs_string(char *string, struct ipt_entry_match **match)
+-{
+- char err1[64] = "%s invalid --rpcs option-set: `%s' (at character %i)";
+- char err2[64] = "%s unable to resolve rpc name entry: `%s'";
+- char err3[64] = "%s maximum number of --rpc options (%i) exceeded";
+- char buf[256];
+- char *dup = buf;
+- int idup = 0;
+- int term = 0;
+- char *src, *dst;
+- char *c_procs;
+- struct rpcent *rpcent_ptr;
+- struct ipt_rpc_info *rpcinfo = (struct ipt_rpc_info *)(*match)->data;
+-
+-
+- memset(buf, 0, sizeof(buf));
+-
+- for (src=string, dst=buf; term != 1 ; src++, dst++) {
+-
+- if ( *src != ',' && *src != '\0' ) {
+- if ( ( *src >= 65 && *src <= 90 ) || ( *src >= 97 && *src <= 122) ) {
+- *dst = *src;
+- idup = 1;
+-
+- } else if ( *src >= 48 && *src <= 57 ) {
+- *dst = *src;
+-
+- } else {
+- exit_error(PARAMETER_PROBLEM, err1, preerr,
+- string, src - string + 1);
+-
+- }
+-
+- } else {
+- *dst = '\0';
+- if ( idup == 1 ) {
+- if ( (rpcent_ptr = getrpcbyname(dup)) == NULL )
+- exit_error(PARAMETER_PROBLEM, err2,
+- preerr, dup);
+- idup = rpcent_ptr->r_number;
+- } else {
+- idup = k_atoi(dup);
+- }
+-
+- rpcinfo->i_procs++;
+- if ( rpcinfo->i_procs > IPT_RPC_MAX_ENTS )
+- exit_error(PARAMETER_PROBLEM, err3, preerr,
+- IPT_RPC_MAX_ENTS);
+-
+- c_procs = (char *)rpcinfo->c_procs;
+- c_procs += rpcinfo->i_procs * IPT_RPC_CHAR_LEN;
+-
+- memset(buf, 0, sizeof(buf));
+- k_itoa((char *)dup, idup);
+-
+- strcpy(c_procs, dup);
+-
+- if ( *src == '\0')
+- term = 1;
+-
+- idup = 0;
+- memset(buf, 0, sizeof(buf));
+- dst = (char *)buf - 1;
+- }
+- }
+-
+- return;
+-}
+-
+-
+-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)
+-{
+- struct ipt_rpc_info *rpcinfo = (struct ipt_rpc_info *)(*match)->data;
+-
+-
+- switch (c)
+- {
+- case '1':
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "%s unexpected '!' with --rpcs\n", preerr);
+- if (*flags & IPT_RPC_RPCS)
+- exit_error(PARAMETER_PROBLEM,
+- "%s repeated use of --rpcs\n", preerr);
+- parse_rpcs_string(optarg, match);
+-
+- *flags |= IPT_RPC_RPCS;
+- break;
+-
+- case '2':
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "%s unexpected '!' with --strict\n", preerr);
+- if (*flags & IPT_RPC_STRC)
+- exit_error(PARAMETER_PROBLEM,
+- "%s repeated use of --strict\n", preerr);
+- rpcinfo->strict = 1;
+- *flags |= IPT_RPC_STRC;
+- break;
+-
+- default:
+- return 0;
+- }
+-
+- return 1;
+-
+-}
+-
+-
+-static void final_check(unsigned int flags)
+-{
+- if (flags != (flags | IPT_RPC_RPCS)) {
+- printf("%s option \"--rpcs\" was not used ... reverting ", preerr);
+- printf("to old \"record-rpc\" functionality ..\n");
+- }
+-}
+-
+-
+-static void print(const struct ipt_ip *ip,
+- const struct ipt_entry_match *match,
+- int numeric)
+-{
+- struct ipt_rpc_info *rpcinfo = ((struct ipt_rpc_info *)match->data);
+-
+-
+- printf("RPCs");
+- if(rpcinfo->strict == 1)
+- printf("[strict]");
+-
+- printf(": ");
+-
+- if(rpcinfo->i_procs == -1) {
+- printf("any(*)");
+-
+- } else {
+- print_rpcs((char *)&rpcinfo->c_procs, rpcinfo->i_procs, IPT_RPC_INT_BTH);
+- }
+- printf(" ");
+-
+-}
+-
+-
+-static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+-{
+- struct ipt_rpc_info *rpcinfo = ((struct ipt_rpc_info *)match->data);
+-
+-
+- if(rpcinfo->i_procs > -1) {
+- printf("--rpcs ");
+- print_rpcs((char *)&rpcinfo->c_procs, rpcinfo->i_procs, IPT_RPC_INT_NUM);
+- printf(" ");
+- }
+-
+- if(rpcinfo->strict == 1)
+- printf("--strict ");
+-
+-}
+-
+-
+-static struct iptables_match rpcstruct = {
+- .next = NULL,
+- .name = "rpc",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_rpc_info)),
+- .userspacesize = IPT_ALIGN(sizeof(struct ipt_rpc_info)),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-
+-void _init(void)
+-{
+- register_match(&rpcstruct);
+-}
+-
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_SAME.c iptables-svn/extensions/libipt_SAME.c
+--- iptables-1.3.7/extensions/libipt_SAME.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_SAME.c 2007-05-31 12:46:30.000000000 +0200
+@@ -6,7 +6,7 @@
+ #include <getopt.h>
+ #include <iptables.h>
+ #include <linux/netfilter_ipv4/ip_tables.h>
+-#include <linux/netfilter_ipv4/ip_nat_rule.h>
++#include <linux/netfilter/nf_nat.h>
+ /* For 64bit kernel / 32bit userspace */
+ #include "../include/linux/netfilter_ipv4/ipt_SAME.h"
+
+@@ -22,13 +22,17 @@
+ " once for multiple ranges.\n"
+ " --nodst\n"
+ " Don't use destination-ip in\n"
+-" source selection\n",
++" source selection\n"
++" --random\n"
++" Randomize source port\n"
++,
+ IPTABLES_VERSION);
+ }
+
+ static struct option opts[] = {
+ { "to", 1, 0, '1' },
+ { "nodst", 0, 0, '2'},
++ { "random", 0, 0, '3' },
+ { 0 }
+ };
+
+@@ -79,6 +83,7 @@
+
+ #define IPT_SAME_OPT_TO 0x01
+ #define IPT_SAME_OPT_NODST 0x02
++#define IPT_SAME_OPT_RANDOM 0x04
+
+ /* Function which parses command options; returns true if it
+ ate an option */
+@@ -89,6 +94,7 @@
+ {
+ struct ipt_same_info *mr
+ = (struct ipt_same_info *)(*target)->data;
++ int count;
+
+ switch (c) {
+ case '1':
+@@ -102,6 +108,10 @@
+ "Unexpected `!' after --to");
+
+ parse_to(optarg, &mr->range[mr->rangesize]);
++ /* WTF do we need this for? */
++ if (*flags & IPT_SAME_OPT_RANDOM)
++ mr->range[mr->rangesize].flags
++ |= IP_NAT_RANGE_PROTO_RANDOM;
+ mr->rangesize++;
+ *flags |= IPT_SAME_OPT_TO;
+ break;
+@@ -114,7 +124,13 @@
+ mr->info |= IPT_SAME_NODST;
+ *flags |= IPT_SAME_OPT_NODST;
+ break;
+-
++
++ case '3':
++ *flags |= IPT_SAME_OPT_RANDOM;
++ for (count=0; count < mr->rangesize; count++)
++ mr->range[count].flags |= IP_NAT_RANGE_PROTO_RANDOM;
++ break;
++
+ default:
+ return 0;
+ }
+@@ -139,6 +155,7 @@
+ int count;
+ struct ipt_same_info *mr
+ = (struct ipt_same_info *)target->data;
++ int random = 0;
+
+ printf("same:");
+
+@@ -155,10 +172,15 @@
+ printf(" ");
+ else
+ printf("-%s ", addr_to_dotted(&a));
++ if (r->flags & IP_NAT_RANGE_PROTO_RANDOM)
++ random = 1;
+ }
+
+ if (mr->info & IPT_SAME_NODST)
+ printf("nodst ");
++
++ if (random)
++ printf("random ");
+ }
+
+ /* Saves the union ipt_targinfo in parsable form to stdout. */
+@@ -168,6 +190,7 @@
+ int count;
+ struct ipt_same_info *mr
+ = (struct ipt_same_info *)target->data;
++ int random = 0;
+
+ for (count = 0; count < mr->rangesize; count++) {
+ struct ip_nat_range *r = &mr->range[count];
+@@ -181,10 +204,15 @@
+ printf(" ");
+ else
+ printf("-%s ", addr_to_dotted(&a));
++ if (r->flags & IP_NAT_RANGE_PROTO_RANDOM)
++ random = 1;
+ }
+
+ if (mr->info & IPT_SAME_NODST)
+ printf("--nodst ");
++
++ if (random)
++ printf("--random ");
+ }
+
+ static struct iptables_target same = {
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_SAME.man iptables-svn/extensions/libipt_SAME.man
+--- iptables-1.3.7/extensions/libipt_SAME.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_SAME.man 2007-05-31 12:46:30.000000000 +0200
+@@ -9,3 +9,7 @@
+ .B "--nodst"
+ Don't use the destination-ip in the calculations when selecting the
+ new source-ip
++.TP
++.B "--random"
++Port mapping will be forcely randomized to avoid attacks based on
++port prediction (kernel >= 2.6.21).
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_set.c iptables-svn/extensions/libipt_set.c
+--- iptables-1.3.7/extensions/libipt_set.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_set.c 2007-05-31 12:46:30.000000000 +0200
+@@ -18,7 +18,6 @@
+ #include <errno.h>
+
+ #include <iptables.h>
+-#include <linux/netfilter_ipv4/ip_conntrack.h>
+ #include <linux/netfilter_ipv4/ipt_set.h>
+ #include "libipt_set.h"
+
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_SET.c iptables-svn/extensions/libipt_SET.c
+--- iptables-1.3.7/extensions/libipt_SET.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_SET.c 2007-05-31 12:46:30.000000000 +0200
+@@ -18,7 +18,6 @@
+
+ #include <iptables.h>
+ #include <linux/netfilter_ipv4/ip_tables.h>
+-#include <linux/netfilter_ipv4/ip_nat_rule.h>
+ #include <linux/netfilter_ipv4/ip_set.h>
+ #include <linux/netfilter_ipv4/ipt_set.h>
+ #include "libipt_set.h"
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_SNAT.c iptables-svn/extensions/libipt_SNAT.c
+--- iptables-1.3.7/extensions/libipt_SNAT.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_SNAT.c 2007-05-31 12:46:30.000000000 +0200
+@@ -6,7 +6,10 @@
+ #include <getopt.h>
+ #include <iptables.h>
+ #include <linux/netfilter_ipv4/ip_tables.h>
+-#include <linux/netfilter_ipv4/ip_nat_rule.h>
++#include <linux/netfilter/nf_nat.h>
++
++#define IPT_SNAT_OPT_SOURCE 0x01
++#define IPT_SNAT_OPT_RANDOM 0x02
+
+ /* Source NAT data consists of a multi-range, indicating where to map
+ to. */
+@@ -24,12 +27,14 @@
+ "SNAT v%s options:\n"
+ " --to-source <ipaddr>[-<ipaddr>][:port-port]\n"
+ " Address to map source to.\n"
+-" (You can use this more than once)\n\n",
++"[--random]\n"
++"\n",
+ IPTABLES_VERSION);
+ }
+
+ static struct option opts[] = {
+ { "to-source", 1, 0, '1' },
++ { "random", 0, 0, '2' },
+ { 0 }
+ };
+
+@@ -155,7 +160,7 @@
+ exit_error(PARAMETER_PROBLEM,
+ "Unexpected `!' after --to-source");
+
+- if (*flags) {
++ if (*flags & IPT_SNAT_OPT_SOURCE) {
+ if (!kernel_version)
+ get_kernel_version();
+ if (kernel_version > LINUX_VERSION(2, 6, 10))
+@@ -163,7 +168,18 @@
+ "Multiple --to-source not supported");
+ }
+ *target = parse_to(optarg, portok, info);
+- *flags = 1;
++ /* WTF do we need this for?? */
++ if (*flags & IPT_SNAT_OPT_RANDOM)
++ info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
++ *flags |= IPT_SNAT_OPT_SOURCE;
++ return 1;
++
++ case '2':
++ if (*flags & IPT_SNAT_OPT_SOURCE) {
++ info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
++ *flags |= IPT_SNAT_OPT_RANDOM;
++ } else
++ *flags |= IPT_SNAT_OPT_RANDOM;
+ return 1;
+
+ default:
+@@ -174,7 +190,7 @@
+ /* Final check; must have specfied --to-source. */
+ static void final_check(unsigned int flags)
+ {
+- if (!flags)
++ if (!(flags & IPT_SNAT_OPT_SOURCE))
+ exit_error(PARAMETER_PROBLEM,
+ "You must specify --to-source");
+ }
+@@ -212,6 +228,8 @@
+ for (i = 0; i < info->mr.rangesize; i++) {
+ print_range(&info->mr.range[i]);
+ printf(" ");
++ if (info->mr.range[i].flags & IP_NAT_RANGE_PROTO_RANDOM)
++ printf("random ");
+ }
+ }
+
+@@ -226,6 +244,8 @@
+ printf("--to-source ");
+ print_range(&info->mr.range[i]);
+ printf(" ");
++ if (info->mr.range[i].flags & IP_NAT_RANGE_PROTO_RANDOM)
++ printf("--random ");
+ }
+ }
+
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_SNAT.man iptables-svn/extensions/libipt_SNAT.man
+--- iptables-1.3.7/extensions/libipt_SNAT.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_SNAT.man 2007-05-31 12:46:30.000000000 +0200
+@@ -17,12 +17,18 @@
+ If no port range is specified, then source ports below 512 will be
+ mapped to other ports below 512: those between 512 and 1023 inclusive
+ will be mapped to ports below 1024, and other ports will be mapped to
+-1024 or above. Where possible, no port alteration will occur.
+-.RS
+-.PP
++1024 or above. Where possible, no port alteration will
++
+ In Kernels up to 2.6.10, you can add several --to-source options. For those
+ kernels, if you specify more than one source address, either via an address
+ range or multiple --to-source options, a simple round-robin (one after another
+ in cycle) takes place between these addresses.
+ Later Kernels (>= 2.6.11-rc1) don't have the ability to NAT to multiple ranges
+ anymore.
++.TP
++.BR "--random"
++If option
++.B "--random"
++is used then port mapping will be randomized (kernel >= 2.6.21).
++.RS
++.PP
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_state.c iptables-svn/extensions/libipt_state.c
+--- iptables-1.3.7/extensions/libipt_state.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_state.c 2007-05-31 12:46:30.000000000 +0200
+@@ -5,7 +5,7 @@
+ #include <stdlib.h>
+ #include <getopt.h>
+ #include <iptables.h>
+-#include <linux/netfilter_ipv4/ip_conntrack.h>
++#include <linux/netfilter/nf_conntrack_common.h>
+ #include <linux/netfilter_ipv4/ipt_state.h>
+
+ #ifndef IPT_STATE_UNTRACKED
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_string.c iptables-svn/extensions/libipt_string.c
+--- iptables-1.3.7/extensions/libipt_string.c 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_string.c 2007-05-31 12:46:30.000000000 +0200
+@@ -307,7 +307,7 @@
+ if (info->from_offset != 0)
+ printf("FROM %u ", info->from_offset);
+ if (info->to_offset != 0)
+- printf("TO %u", info->to_offset);
++ printf("TO %u ", info->to_offset);
+ }
+
+
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_TARPIT.c iptables-svn/extensions/libipt_TARPIT.c
+--- iptables-1.3.7/extensions/libipt_TARPIT.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_TARPIT.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,58 +0,0 @@
+-/* Shared library add-on to iptables for TARPIT support */
+-#include <stdio.h>
+-#include <getopt.h>
+-#include <iptables.h>
+-
+-static void
+-help(void)
+-{
+- fputs(
+-"TARPIT takes no options\n"
+-"\n", stdout);
+-}
+-
+-static struct option opts[] = {
+- { 0 }
+-};
+-
+-static int
+-parse(int c, char **argv, int invert, unsigned int *flags,
+- const struct ipt_entry *entry,
+- struct ipt_entry_target **target)
+-{
+- return 0;
+-}
+-
+-static void final_check(unsigned int flags)
+-{
+-}
+-
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_target *target,
+- int numeric)
+-{
+-}
+-
+-static void save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
+-{
+-}
+-
+-static struct iptables_target tarpit = {
+- .next = NULL,
+- .name = "TARPIT",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(0),
+- .userspacesize = IPT_ALIGN(0),
+- .help = &help,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_target(&tarpit);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_TARPIT.man iptables-svn/extensions/libipt_TARPIT.man
+--- iptables-1.3.7/extensions/libipt_TARPIT.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_TARPIT.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,34 +0,0 @@
+-Captures and holds incoming TCP connections using no local
+-per-connection resources. Connections are accepted, but immediately
+-switched to the persist state (0 byte window), in which the remote
+-side stops sending data and asks to continue every 60-240 seconds.
+-Attempts to close the connection are ignored, forcing the remote side
+-to time out the connection in 12-24 minutes.
+-
+-This offers similar functionality to LaBrea
+-<http://www.hackbusters.net/LaBrea/> but doesn't require dedicated
+-hardware or IPs. Any TCP port that you would normally DROP or REJECT
+-can instead become a tarpit.
+-
+-To tarpit connections to TCP port 80 destined for the current machine:
+-.IP
+-iptables -A INPUT -p tcp -m tcp --dport 80 -j TARPIT
+-.P
+-To significantly slow down Code Red/Nimda-style scans of unused address
+-space, forward unused ip addresses to a Linux box not acting as a router
+-(e.g. "ip route 10.0.0.0 255.0.0.0 ip.of.linux.box" on a Cisco), enable IP
+-forwarding on the Linux box, and add:
+-.IP
+-iptables -A FORWARD -p tcp -j TARPIT
+-.IP
+-iptables -A FORWARD -j DROP
+-.TP
+-NOTE:
+-If you use the conntrack module while you are using TARPIT, you should
+-also use the NOTRACK target, or the kernel will unnecessarily allocate
+-resources for each TARPITted connection. To TARPIT incoming
+-connections to the standard IRC port while using conntrack, you could:
+-.IP
+-iptables -t raw -A PREROUTING -p tcp --dport 6667 -j NOTRACK
+-.IP
+-iptables -A INPUT -p tcp --dport 6667 -j TARPIT
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_TCPLAG.c iptables-svn/extensions/libipt_TCPLAG.c
+--- iptables-1.3.7/extensions/libipt_TCPLAG.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_TCPLAG.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,215 +0,0 @@
+-/* libipt_TCPLAG.c -- module for iptables to interface with TCPLAG target
+- * Copyright (C) 2002 Telford Tendys <telford@triode.net.au>
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*
+- * Shared library add-on to iptables for TCPLAG target control
+- *
+- * This allows installation and removal of the TCPLAG target
+- * Note that there is a lot more commentary in this file than
+- * the average libipt target (i.e. more than none) but these
+- * are just my deductions based on examination of the source
+- * and
+- */
+-#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/ip_tables.h>
+-#include <linux/netfilter_ipv4/ipt_TCPLAG.h>
+-
+-/*
+- * This merely dumps out text for the user
+- * (saves keeping the manpage up to date)
+- */
+-static void help( void )
+-{
+- printf( "TCPLAG options:\n"
+- " --log-level=n Set the syslog level to n (integer 0 to 7)\n\n"
+- " --log-prefix=xx Prefix log messages with xx\n" );
+-}
+-
+-/*
+- * See "man getopt_long" for an explanation of this structure
+- *
+- * If one of our options DOES happen to come up then we get
+- * a callback into parse(), our vals must not overlap with any
+- * normal iptables short options (I think) because there is only
+- * one actual options handler and it can't tell whose options it
+- * is really looking at unless they are all distinct.
+- *
+- * These are exactly the same as the LOG target options
+- * and have the same purpose.
+- */
+-static const struct option opts[] =
+-{
+- { "log-level", 1, 0, '!' },
+- { "log-prefix", 1, 0, '#' },
+- { 0 }
+-};
+-
+-/*
+- * This gives us a chance to install some initial values in
+- * our own private data structure (which is at t->data).
+- * Probably we could fiddle with t->tflags too but there is
+- * no great advantage in doing so.
+- */
+-static void init( struct ipt_entry_target *t, unsigned int *nfcache )
+-{
+- struct ipt_tcplag *el = (struct ipt_tcplag *)t->data;
+- memset( el, 0, sizeof( struct ipt_tcplag ));
+- el->level = 4; /* Default to warning level */
+- strcpy( el->prefix, "TCPLAG:" ); /* Give a reasonable default prefix */
+-}
+-
+-/*
+- * It doesn't take much thought to see how little thought has gone into
+- * this particular API. However, to add to that I'd just like to say that
+- * it can be made to work and small miracles are still miracles.
+- *
+- * The input parameters are as follows:
+- *
+- * c -- the 'val' from opts[] above, could possibly be something
+- * we cannot recognise in which case return(0).
+- * If we do recognise it then return(1).
+- *
+- * argv -- in case we want to take parameters from the command line,
+- * not sure how to safely ensure that the parameter that
+- * we want to take will really exist, presumably getopt_long()
+- * will have already checked such things (what about optional
+- * parameters huh?).
+- *
+- * invert -- if the option parameter had '!' in front of it, usually this
+- * would inversion of the matching sense but I don't think it
+- * is useful in the case of targets.
+- *
+- * flags -- always (*target)->tflags for those who feel it is better
+- * to access this field indirectly <shrug> starts of
+- * zero for a fresh target, gets fed into final_check().
+- *
+- * entry -- apparently useless
+- *
+- * target -- the record that holds data about this target,
+- * most importantly, our private data is (*target)->data
+- * (this has already been malloced for us).
+- */
+-static int parse( int c, char **argv, int invert, unsigned int *flags,
+- const struct ipt_entry *entry, struct ipt_entry_target **target )
+-{
+- struct ipt_tcplag *el = (struct ipt_tcplag *)( *target )->data;
+-/*
+- * Yeah, we could complain about options being issued twice but
+- * is it really worth the trouble? Will it make the world a better place?
+- */
+- switch( c )
+- {
+-/*
+- * I really can't be bothered with the syslog naming convention,
+- * it isn't terribly useful anyhow.
+- */
+- case '!':
+- el->level = strtol( optarg, 0, 10 );
+- return( 1 );
+-/*
+- * 15 chars should be plenty
+- */
+- case '#':
+- strncpy( el->prefix, optarg, 15 );
+- el->prefix[ 14 ] = 0; /* Force termination */
+- return( 1 );
+- }
+- return( 0 );
+-}
+-
+-/*
+- * This gets given the (*target)->tflags value from
+- * the parse() above and it gets called after all the
+- * parsing of options is completed. Thus if one option
+- * requires another option you can test the flags and
+- * decide whether everything is in order.
+- *
+- * If there is a problem then do something like:
+- * exit_error( PARAMETER_PROBLEM, "foobar parameters detected in TCPLAG target");
+- *
+- * In this case, no errors are possible
+- */
+-static void final_check( unsigned int flags ) { }
+-/*
+- * This print is for the purpose of user-readable display
+- * such as what "iptables -L" would give. The notes in
+- * iptables.h say that target could possibly be a null pointer
+- * but coding of the various libipt_XX.c modules suggests
+- * that it is safe to presume target is correctly initialised.
+- */
+-static void print(const struct ipt_ip *ip, const struct ipt_entry_target *target, int numeric)
+-{
+- const struct ipt_tcplag *el = (const struct ipt_tcplag *)target->data;
+- printf("TCPLAG <%d>", el->level );
+- if( el->prefix[ 0 ])
+- {
+- printf( "%s", el->prefix );
+- }
+-}
+-
+-/*
+- * As above but command-line style printout
+- * (machine-readable for restoring table)
+- */
+-static void save( const struct ipt_ip *ip, const struct ipt_entry_target *target )
+-{
+- const struct ipt_tcplag *el = (const struct ipt_tcplag *)target->data;
+- printf("TCPLAG --log-level=%d", el->level );
+- if( el->prefix[ 0 ])
+- {
+-/*
+- * FIXME: Should have smarter quoting
+- */
+- printf( " --log-prefix='%s'", el->prefix );
+- }
+-}
+-
+-/*
+- * The version must match the iptables version exactly
+- * which is a big pain, could use `iptables -V` in makefile
+- * but we can't guarantee compatibility with all iptables
+- * so we are stuck with only supporting one particular version.
+- */
+-static struct iptables_target targ =
+-{
+-next: 0,
+-name: "TCPLAG",
+-version: IPTABLES_VERSION,
+-size: IPT_ALIGN( sizeof( struct ipt_tcplag )),
+-userspacesize: IPT_ALIGN( sizeof( struct ipt_tcplag )),
+-help: &help,
+-init: &init,
+-parse: &parse,
+-final_check: &final_check,
+-print: &print,
+-save: &save,
+-extra_opts: opts
+-};
+-
+-/*
+- * Always nervous trusting _init() but oh well that is the standard
+- * so have to go ahead and use it. This registers your target into
+- * the list of available targets so that your options become available.
+- */
+-void _init( void ) { register_target( &targ ); }
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_tcp.man iptables-svn/extensions/libipt_tcp.man
+--- iptables-1.3.7/extensions/libipt_tcp.man 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_tcp.man 2007-05-31 12:46:30.000000000 +0200
+@@ -1,4 +1,4 @@
+-These extensions are loaded if `--protocol tcp' is specified. It
++These extensions can be used if `--protocol tcp' is specified. It
+ provides the following options:
+ .TP
+ .BR "--source-port " "[!] \fIport\fP[:\fIport\fP]"
+@@ -43,7 +43,3 @@
+ .TP
+ .BR "--tcp-option " "[!] \fInumber\fP"
+ Match if TCP option set.
+-.TP
+-.BR "--mss " "\fIvalue\fP[:\fIvalue\fP]"
+-Match TCP SYN or SYN/ACK packets with the specified MSS value (or range),
+-which control the maximum packet size for that connection.
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_tcpmss.man iptables-svn/extensions/libipt_tcpmss.man
+--- iptables-1.3.7/extensions/libipt_tcpmss.man 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_tcpmss.man 2007-05-31 12:46:30.000000000 +0200
+@@ -1,4 +1,4 @@
+ This matches the TCP MSS (maximum segment size) field of the TCP header. You can only use this on TCP SYN or SYN/ACK packets, since the MSS is only negotiated during the TCP handshake at connection startup time.
+ .TP
+-.BI "[!] "--mss " "value[:value]"
++.BI "[!] "--mss " value[:value]"
+ Match a given TCP MSS value or range.
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_time.c iptables-svn/extensions/libipt_time.c
+--- iptables-1.3.7/extensions/libipt_time.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_time.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,549 +0,0 @@
+-/* Shared library add-on to iptables to add TIME matching support. */
+-#include <stdio.h>
+-#include <netdb.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <stddef.h> /* for 'offsetof' */
+-#include <getopt.h>
+-
+-#include <iptables.h>
+-#include <linux/netfilter_ipv4/ipt_time.h>
+-#include <time.h>
+-
+-static int globaldays;
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf(
+-"TIME v%s options:\n"
+-" [ --timestart value ] [ --timestop value] [ --days listofdays ] [ --datestart value ] [ --datestop value ]\n"
+-" timestart value : HH:MM (default 00:00)\n"
+-" timestop value : HH:MM (default 23:59)\n"
+-" Note: daylight savings time changes are not tracked\n"
+-" listofdays value: a list of days to apply\n"
+-" from Mon,Tue,Wed,Thu,Fri,Sat,Sun\n"
+-" Coma speparated, no space, case sensitive.\n"
+-" Defaults to all days.\n"
+-" datestart value : YYYY[:MM[:DD[:hh[:mm[:ss]]]]]\n"
+-" If any of month, day, hour, minute or second is\n"
+-" not specified, then defaults to their smallest\n"
+-" 1900 <= YYYY < 2037\n"
+-" 1 <= MM <= 12\n"
+-" 1 <= DD <= 31\n"
+-" 0 <= hh <= 23\n"
+-" 0 <= mm <= 59\n"
+-" 0 <= ss <= 59\n"
+-" datestop value : YYYY[:MM[:DD[:hh[:mm[:ss]]]]]\n"
+-" If the whole option is ommited, default to never stop\n"
+-" If any of month, day, hour, minute or second is\n"
+-" not specified, then default to their smallest\n",
+-IPTABLES_VERSION);
+-}
+-
+-static struct option opts[] = {
+- { "timestart", 1, 0, '1' },
+- { "timestop", 1, 0, '2' },
+- { "days", 1, 0, '3'},
+- { "datestart", 1, 0, '4' },
+- { "datestop", 1, 0, '5' },
+- {0}
+-};
+-
+-/* Initialize the match. */
+-static void
+-init(struct ipt_entry_match *m, unsigned int *nfcache)
+-{
+- struct ipt_time_info *info = (struct ipt_time_info *)m->data;
+- globaldays = 0;
+- /* By default, we match on everyday */
+- info->days_match = 127;
+- /* By default, we match on every hour:min of the day */
+- info->time_start = 0;
+- info->time_stop = 1439; /* (23*60+59 = 1439 */
+- /* By default, we don't have any date-begin or date-end boundaries */
+- info->date_start = 0;
+- info->date_stop = LONG_MAX;
+-}
+-
+-/**
+- * param: part1, a pointer on a string 2 chars maximum long string, that will contain the hours.
+- * param: part2, a pointer on a string 2 chars maximum long string, that will contain the minutes.
+- * param: str_2_parse, the string to parse.
+- * return: 1 if ok, 0 if error.
+- */
+-static int
+-split_time(char **part1, char **part2, const char *str_2_parse)
+-{
+- unsigned short int i,j=0;
+- char *rpart1 = *part1;
+- char *rpart2 = *part2;
+- unsigned char found_column = 0;
+-
+- /* Check the length of the string */
+- if (strlen(str_2_parse) > 5)
+- return 0;
+- /* parse the first part until the ':' */
+- for (i=0; i<2; i++)
+- {
+- if (str_2_parse[i] == ':')
+- found_column = 1;
+- else
+- rpart1[i] = str_2_parse[i];
+- }
+- if (!found_column)
+- i++;
+- j=i;
+- /* parse the second part */
+- for (; i<strlen(str_2_parse); i++)
+- {
+- rpart2[i-j] = str_2_parse[i];
+- }
+- /* if we are here, format should be ok. */
+- return 1;
+-}
+-
+-static int
+-parse_number(char *str, int num_min, int num_max, int *number)
+-{
+- /* if the number starts with 0, replace it with a space else
+- string_to_number() will interpret it as octal !! */
+- if (strlen(str) == 0)
+- return 0;
+-
+- if ((str[0] == '0') && (str[1] != '\0'))
+- str[0] = ' ';
+-
+- return string_to_number(str, num_min, num_max, number);
+-}
+-
+-static void
+-parse_time_string(int *hour, int *minute, const char *time)
+-{
+- char *hours;
+- char *minutes;
+- hours = (char *)malloc(3);
+- minutes = (char *)malloc(3);
+- memset(hours, 0, 3);
+- memset(minutes, 0, 3);
+-
+- if (split_time((char **)&hours, (char **)&minutes, time) == 1)
+- {
+- *hour = 0;
+- *minute = 0;
+- if ((parse_number((char *)hours, 0, 23, hour) != -1) &&
+- (parse_number((char *)minutes, 0, 59, minute) != -1))
+- {
+- free(hours);
+- free(minutes);
+- return;
+- }
+- }
+-
+- free(hours);
+- free(minutes);
+-
+- /* If we are here, there was a problem ..*/
+- exit_error(PARAMETER_PROBLEM,
+- "invalid time `%s' specified, should be HH:MM format", time);
+-}
+-
+-/* return 1->ok, return 0->error */
+-static int
+-parse_day(int *days, int from, int to, const char *string)
+-{
+- char *dayread;
+- char *days_str[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+- unsigned short int days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
+- unsigned int i;
+-
+- dayread = (char *)malloc(4);
+- bzero(dayread, 4);
+- if ((to-from) != 3) {
+- free(dayread);
+- return 0;
+- }
+- for (i=from; i<to; i++)
+- dayread[i-from] = string[i];
+- for (i=0; i<7; i++)
+- if (strcmp(dayread, days_str[i]) == 0)
+- {
+- *days |= days_of_week[i];
+- free(dayread);
+- return 1;
+- }
+- /* if we are here, we didn't read a valid day */
+- free(dayread);
+- return 0;
+-}
+-
+-static void
+-parse_days_string(int *days, const char *daystring)
+-{
+- int len;
+- int i=0;
+- char *err = "invalid days `%s' specified, should be Sun,Mon,Tue... format";
+-
+- len = strlen(daystring);
+- if (len < 3)
+- exit_error(PARAMETER_PROBLEM, err, daystring);
+- while(i<len)
+- {
+- if (parse_day(days, i, i+3, daystring) == 0)
+- exit_error(PARAMETER_PROBLEM, err, daystring);
+- i += 4;
+- }
+-}
+-
+-static int
+-parse_date_field(const char *str_to_parse, int str_to_parse_s, int start_pos,
+- char *dest, int *next_pos)
+-{
+- unsigned char found_value = 0;
+- unsigned char found_column = 0;
+- int i;
+-
+- for (i=0; i<2; i++)
+- {
+- if ((i+start_pos) >= str_to_parse_s) /* don't exit boundaries of the string.. */
+- break;
+- if (str_to_parse[i+start_pos] == ':')
+- found_column = 1;
+- else
+- {
+- found_value = 1;
+- dest[i] = str_to_parse[i+start_pos];
+- }
+- }
+- if (found_value == 0)
+- return 0;
+- *next_pos = i + start_pos;
+- if (found_column == 0)
+- ++(*next_pos);
+- return 1;
+-}
+-
+-static int
+-split_date(char *year, char *month, char *day,
+- char *hour, char *minute, char *second,
+- const char *str_to_parse)
+-{
+- int i;
+- unsigned char found_column = 0;
+- int str_to_parse_s = strlen(str_to_parse);
+-
+- /* Check the length of the string */
+- if ((str_to_parse_s > 19) || /* YYYY:MM:DD:HH:MM:SS */
+- (str_to_parse_s < 4)) /* YYYY*/
+- return 0;
+-
+- /* Clear the buffers */
+- memset(year, 0, 4);
+- memset(month, 0, 2);
+- memset(day, 0, 2);
+- memset(hour, 0, 2);
+- memset(minute, 0, 2);
+- memset(second, 0, 2);
+-
+- /* parse the year YYYY */
+- found_column = 0;
+- for (i=0; i<5; i++)
+- {
+- if (i >= str_to_parse_s)
+- break;
+- if (str_to_parse[i] == ':')
+- {
+- found_column = 1;
+- break;
+- }
+- else
+- year[i] = str_to_parse[i];
+- }
+- if (found_column == 1)
+- ++i;
+-
+- /* parse the month if it exists */
+- if (! parse_date_field(str_to_parse, str_to_parse_s, i, month, &i))
+- return 1;
+-
+- if (! parse_date_field(str_to_parse, str_to_parse_s, i, day, &i))
+- return 1;
+-
+- if (! parse_date_field(str_to_parse, str_to_parse_s, i, hour, &i))
+- return 1;
+-
+- if (! parse_date_field(str_to_parse, str_to_parse_s, i, minute, &i))
+- return 1;
+-
+- parse_date_field(str_to_parse, str_to_parse_s, i, second, &i);
+-
+- /* if we are here, format should be ok. */
+- return 1;
+-}
+-
+-static time_t
+-parse_date_string(const char *str_to_parse)
+-{
+- char year[5];
+- char month[3];
+- char day[3];
+- char hour[3];
+- char minute[3];
+- char second[3];
+- struct tm t;
+- time_t temp_time;
+-
+- memset(year, 0, 5);
+- memset(month, 0, 3);
+- memset(day, 0, 3);
+- memset(hour, 0, 3);
+- memset(minute, 0, 3);
+- memset(second, 0, 3);
+-
+- if (split_date(year, month, day, hour, minute, second, str_to_parse) == 1)
+- {
+- memset((void *)&t, 0, sizeof(struct tm));
+- t.tm_isdst = -1;
+- t.tm_mday = 1;
+- if (!((parse_number(year, 1900, 2037, &(t.tm_year)) == -1) ||
+- (parse_number(month, 1, 12, &(t.tm_mon)) == -1) ||
+- (parse_number(day, 1, 31, &(t.tm_mday)) == -1) ||
+- (parse_number(hour, 0, 9999, &(t.tm_hour)) == -1) ||
+- (parse_number(minute, 0, 59, &(t.tm_min)) == -1) ||
+- (parse_number(second, 0, 59, &(t.tm_sec)) == -1)))
+- {
+- t.tm_year -= 1900;
+- --(t.tm_mon);
+- temp_time = mktime(&t);
+- if (temp_time != -1)
+- return temp_time;
+- }
+- }
+- exit_error(PARAMETER_PROBLEM,
+- "invalid date `%s' specified, should be YYYY[:MM[:DD[:hh[:mm[:ss]]]]] format", str_to_parse);
+-}
+-
+-#define IPT_TIME_START 0x01
+-#define IPT_TIME_STOP 0x02
+-#define IPT_TIME_DAYS 0x04
+-#define IPT_DATE_START 0x08
+-#define IPT_DATE_STOP 0x10
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-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)
+-{
+- struct ipt_time_info *timeinfo = (struct ipt_time_info *)(*match)->data;
+- int hours, minutes;
+- time_t temp_date;
+-
+- switch (c)
+- {
+- /* timestart */
+- case '1':
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "unexpected '!' with --timestart");
+- if (*flags & IPT_TIME_START)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --timestart twice");
+- parse_time_string(&hours, &minutes, optarg);
+- timeinfo->time_start = (hours * 60) + minutes;
+- *flags |= IPT_TIME_START;
+- break;
+- /* timestop */
+- case '2':
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "unexpected '!' with --timestop");
+- if (*flags & IPT_TIME_STOP)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --timestop twice");
+- parse_time_string(&hours, &minutes, optarg);
+- timeinfo->time_stop = (hours * 60) + minutes;
+- *flags |= IPT_TIME_STOP;
+- break;
+-
+- /* days */
+- case '3':
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "unexpected '!' with --days");
+- if (*flags & IPT_TIME_DAYS)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --days twice");
+- parse_days_string(&globaldays, optarg);
+- timeinfo->days_match = globaldays;
+- *flags |= IPT_TIME_DAYS;
+- break;
+-
+- /* datestart */
+- case '4':
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "unexpected '!' with --datestart");
+- if (*flags & IPT_DATE_START)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --datestart twice");
+- temp_date = parse_date_string(optarg);
+- timeinfo->date_start = temp_date;
+- *flags |= IPT_DATE_START;
+- break;
+-
+- /* datestop*/
+- case '5':
+- if (invert)
+- exit_error(PARAMETER_PROBLEM,
+- "unexpected '!' with --datestop");
+- if (*flags & IPT_DATE_STOP)
+- exit_error(PARAMETER_PROBLEM,
+- "Can't specify --datestop twice");
+- temp_date = parse_date_string(optarg);
+- timeinfo->date_stop = temp_date;
+- *flags |= IPT_DATE_STOP;
+- break;
+- default:
+- return 0;
+- }
+- return 1;
+-}
+-
+-/* Final check */
+-static void
+-final_check(unsigned int flags)
+-{
+- /* Nothing to do */
+-}
+-
+-
+-static void
+-print_days(int daynum)
+-{
+- char *days[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+- unsigned short int days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
+- unsigned short int i, nbdays=0;
+-
+- for (i=0; i<7; i++) {
+- if ((days_of_week[i] & daynum) == days_of_week[i])
+- {
+- if (nbdays>0)
+- printf(",%s", days[i]);
+- else
+- printf("%s", days[i]);
+- ++nbdays;
+- }
+- }
+- printf(" ");
+-}
+-
+-static void
+-divide_time(int fulltime, int *hours, int *minutes)
+-{
+- *hours = fulltime / 60;
+- *minutes = fulltime % 60;
+-}
+-
+-static void
+-print_date(time_t date, char *command)
+-{
+- struct tm *t;
+-
+- /* If it's default value, don't print..*/
+- if (((date == 0) || (date == LONG_MAX)) && (command != NULL))
+- return;
+- t = localtime(&date);
+- if (command != NULL)
+- printf("%s %d:%d:%d:%d:%d:%d ", command, (t->tm_year + 1900), (t->tm_mon + 1),
+- t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
+- else
+- printf("%d-%d-%d %d:%d:%d ", (t->tm_year + 1900), (t->tm_mon + 1),
+- t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
+-}
+-
+-/* Prints out the matchinfo. */
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_match *match,
+- int numeric)
+-{
+- struct ipt_time_info *time = ((struct ipt_time_info *)match->data);
+- int hour_start, hour_stop, minute_start, minute_stop;
+-
+- divide_time(time->time_start, &hour_start, &minute_start);
+- divide_time(time->time_stop, &hour_stop, &minute_stop);
+- printf("TIME ");
+- if (time->time_start != 0)
+- printf("from %d:%d ", hour_start, minute_start);
+- if (time->time_stop != 1439) /* 23*60+59 = 1439 */
+- printf("to %d:%d ", hour_stop, minute_stop);
+- printf("on ");
+- if (time->days_match == 127)
+- printf("all days ");
+- else
+- print_days(time->days_match);
+- if (time->date_start != 0)
+- {
+- printf("starting from ");
+- print_date(time->date_start, NULL);
+- }
+- if (time->date_stop != LONG_MAX)
+- {
+- printf("until date ");
+- print_date(time->date_stop, NULL);
+- }
+-}
+-
+-/* Saves the data in parsable form to stdout. */
+-static void
+-save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+-{
+- struct ipt_time_info *time = ((struct ipt_time_info *)match->data);
+- int hour_start, hour_stop, minute_start, minute_stop;
+-
+- divide_time(time->time_start, &hour_start, &minute_start);
+- divide_time(time->time_stop, &hour_stop, &minute_stop);
+- if (time->time_start != 0)
+- printf("--timestart %.2d:%.2d ",
+- hour_start, minute_start);
+-
+- if (time->time_stop != 1439) /* 23*60+59 = 1439 */
+- printf("--timestop %.2d:%.2d ",
+- hour_stop, minute_stop);
+-
+- if (time->days_match != 127)
+- {
+- printf("--days ");
+- print_days(time->days_match);
+- printf(" ");
+- }
+- print_date(time->date_start, "--datestart");
+- print_date(time->date_stop, "--datestop");
+-}
+-
+-/* have to use offsetof() instead of IPT_ALIGN(), since kerneltime must not
+- * be compared when user deletes rule with '-D' */
+-static
+-struct iptables_match timestruct = {
+- .next = NULL,
+- .name = "time",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_time_info)),
+- .userspacesize = offsetof(struct ipt_time_info, kerneltime),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_match(&timestruct);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_time.man iptables-svn/extensions/libipt_time.man
+--- iptables-1.3.7/extensions/libipt_time.man 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_time.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,16 +0,0 @@
+-This matches if the packet arrival time/date is within a given range. All options are facultative.
+-.TP
+-.BI " --timestart " "value"
+-Match only if it is after `value' (Inclusive, format: HH:MM ; default 00:00).
+-.TP
+-.BI "--timestop " "value"
+-Match only if it is before `value' (Inclusive, format: HH:MM ; default 23:59).
+-.TP
+-.BI "--days " "listofdays"
+-Match only if today is one of the given days. (format: Mon,Tue,Wed,Thu,Fri,Sat,Sun ; default everyday)
+-.TP
+-.BI "--datestart " "date"
+-Match only if it is after `date' (Inclusive, format: YYYY[:MM[:DD[:hh[:mm[:ss]]]]] ; h,m,s start from 0 ; default to 1970)
+-.TP
+-.BI "--datestop " "date"
+-Match only if it is before `date' (Inclusive, format: YYYY[:MM[:DD[:hh[:mm[:ss]]]]] ; h,m,s start from 0 ; default to 2037)
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_TRACE.c iptables-svn/extensions/libipt_TRACE.c
+--- iptables-1.3.7/extensions/libipt_TRACE.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_TRACE.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,63 +0,0 @@
+-/* Shared library add-on to iptables to add TRACE target support. */
+-#include <stdio.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <getopt.h>
+-
+-#include <iptables.h>
+-#include <linux/netfilter_ipv4/ip_tables.h>
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf(
+-"TRACE target v%s takes no options\n",
+-IPTABLES_VERSION);
+-}
+-
+-static struct option opts[] = {
+- { 0 }
+-};
+-
+-/* Initialize the target. */
+-static void
+-init(struct ipt_entry_target *t, unsigned int *nfcache)
+-{
+-}
+-
+-/* Function which parses command options; returns true if it
+- ate an option */
+-static int
+-parse(int c, char **argv, int invert, unsigned int *flags,
+- const struct ipt_entry *entry,
+- struct ipt_entry_target **target)
+-{
+- return 0;
+-}
+-
+-static void
+-final_check(unsigned int flags)
+-{
+-}
+-
+-static
+-struct iptables_target trace
+-= { .next = NULL,
+- .name = "TRACE",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(0),
+- .userspacesize = IPT_ALIGN(0),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = NULL, /* print */
+- .save = NULL, /* save */
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_target(&trace);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_TRACE.man iptables-svn/extensions/libipt_TRACE.man
+--- iptables-1.3.7/extensions/libipt_TRACE.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_TRACE.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,3 +0,0 @@
+-This target has no options. It just turns on
+-.B packet tracing
+-for all packets that match this rule.
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_u32.c iptables-svn/extensions/libipt_u32.c
+--- iptables-1.3.7/extensions/libipt_u32.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_u32.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,264 +0,0 @@
+-/* Shared library add-on to iptables to add u32 matching,
+- * generalized matching on values found at packet offsets
+- *
+- * Detailed doc is in the kernel module source
+- * net/ipv4/netfilter/ipt_u32.c
+- *
+- * (C) 2002 by Don Cohen <don-netf@isis.cs3-inc.com>
+- * Released under the terms of GNU GPL v2
+- */
+-#include <stdio.h>
+-#include <netdb.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <getopt.h>
+-#include <iptables.h>
+-#include <linux/netfilter_ipv4/ipt_u32.h>
+-#include <errno.h>
+-#include <ctype.h>
+-
+-/* Function which prints out usage message. */
+-static void
+-help(void)
+-{
+- printf( "u32 v%s options:\n"
+- " --u32 tests\n"
+- " tests := location = value | tests && location = value\n"
+- " value := range | value , range\n"
+- " range := number | number : number\n"
+- " location := number | location operator number\n"
+- " operator := & | << | >> | @\n"
+- ,IPTABLES_VERSION);
+-}
+-
+-/* defined in /usr/include/getopt.h maybe in man getopt */
+-static struct option opts[] = {
+- { "u32", 1, 0, '1' },
+- { 0 }
+-};
+-
+-/* shared printing code */
+-static void print_u32(struct ipt_u32 *data)
+-{
+- unsigned int testind;
+-
+- for (testind=0; testind < data->ntests; testind++) {
+- if (testind) printf("&&");
+- {
+- unsigned int i;
+-
+- printf("0x%x", data->tests[testind].location[0].number);
+- for (i = 1; i < data->tests[testind].nnums; i++) {
+- switch (data->tests[testind].location[i].nextop) {
+- case IPT_U32_AND: printf("&"); break;
+- case IPT_U32_LEFTSH: printf("<<"); break;
+- case IPT_U32_RIGHTSH: printf(">>"); break;
+- case IPT_U32_AT: printf("@"); break;
+- }
+- printf("0x%x", data->tests[testind].location[i].number);
+- }
+- printf("=");
+- for (i = 0; i < data->tests[testind].nvalues; i++) {
+- if (i) printf(",");
+- if (data->tests[testind].value[i].min
+- == data->tests[testind].value[i].max)
+- printf("0x%x", data->tests[testind].value[i].min);
+- else printf("0x%x:0x%x", data->tests[testind].value[i].min,
+- data->tests[testind].value[i].max);
+- }
+- }
+- }
+- printf(" ");
+-}
+-
+-/* string_to_number is not quite what we need here ... */
+-u_int32_t parse_number(char **s, int pos)
+-{
+- u_int32_t number;
+- char *end;
+- errno = 0;
+-
+- number = strtoul(*s, &end, 0);
+- if (end == *s)
+- exit_error(PARAMETER_PROBLEM,
+- "u32: at char %d expected number", pos);
+- if (errno)
+- exit_error(PARAMETER_PROBLEM,
+- "u32: at char %d error reading number", pos);
+- *s = end;
+- return number;
+-}
+-
+-/* Function which parses command options; returns true if it ate an option */
+-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)
+-{
+- struct ipt_u32 *data = (struct ipt_u32 *)(*match)->data;
+- char *arg = argv[optind-1]; /* the argument string */
+- char *start = arg;
+- int state=0, testind=0, locind=0, valind=0;
+-
+- if (c != '1') return 0;
+- /* states: 0 = looking for numbers and operations, 1 = looking for ranges */
+- while (1) { /* read next operand/number or range */
+- while (isspace(*arg))
+- arg++; /* skip white space */
+- if (! *arg) { /* end of argument found */
+- if (state == 0)
+- exit_error(PARAMETER_PROBLEM,
+- "u32: input ended in location spec");
+- if (valind == 0)
+- exit_error(PARAMETER_PROBLEM,
+- "u32: test ended with no value spec");
+- data->tests[testind].nnums = locind;
+- data->tests[testind].nvalues = valind;
+- testind++;
+- data->ntests=testind;
+- if (testind > U32MAXSIZE)
+- exit_error(PARAMETER_PROBLEM,
+- "u32: at char %d too many &&'s",
+- arg-start);
+- /* debugging
+- print_u32(data);printf("\n");
+- exit_error(PARAMETER_PROBLEM, "debugging output done"); */
+- return 1;
+- }
+- if (state == 0) {
+- /* reading location: read a number if nothing read yet,
+- otherwise either op number or = to end location spec */
+- if (*arg == '=') {
+- if (locind == 0)
+- exit_error(PARAMETER_PROBLEM,
+- "u32: at char %d location spec missing", arg-start);
+- else {
+- arg++;
+- state=1;
+- }
+- }
+- else {
+- if (locind) { /* need op before number */
+- if (*arg == '&') {
+- data->tests[testind].location[locind].nextop = IPT_U32_AND;
+- }
+- else if (*arg == '<') {
+- arg++;
+- if (*arg != '<')
+- exit_error(PARAMETER_PROBLEM,
+- "u32: at char %d a second < expected", arg-start);
+- data->tests[testind].location[locind].nextop = IPT_U32_LEFTSH;
+- }
+- else if (*arg == '>') {
+- arg++;
+- if (*arg != '>')
+- exit_error(PARAMETER_PROBLEM,
+- "u32: at char %d a second > expected", arg-start);
+- data->tests[testind].location[locind].nextop = IPT_U32_RIGHTSH;
+- }
+- else if (*arg == '@') {
+- data->tests[testind].location[locind].nextop = IPT_U32_AT;
+- }
+- else exit_error(PARAMETER_PROBLEM,
+- "u32: at char %d operator expected", arg-start);
+- arg++;
+- }
+- /* now a number; string_to_number skips white space? */
+- data->tests[testind].location[locind].number =
+- parse_number(&arg, arg-start);
+- locind++;
+- if (locind > U32MAXSIZE)
+- exit_error(PARAMETER_PROBLEM,
+- "u32: at char %d too many operators", arg-start);
+- }
+- }
+- else {
+- /* state 1 - reading values: read a range if nothing read yet,
+- otherwise either ,range or && to end test spec */
+- if (*arg == '&') {
+- arg++;
+- if (*arg != '&')
+- exit_error(PARAMETER_PROBLEM,
+- "u32: at char %d a second & expected", arg-start);
+- if (valind == 0)
+- exit_error(PARAMETER_PROBLEM,
+- "u32: at char %d value spec missing", arg-start);
+- else {
+- data->tests[testind].nnums = locind;
+- data->tests[testind].nvalues = valind;
+- testind++;
+- if (testind > U32MAXSIZE)
+- exit_error(PARAMETER_PROBLEM,
+- "u32: at char %d too many &&'s", arg-start);
+- arg++; state=0; locind=0; valind=0;
+- }
+- }
+- else { /* read value range */
+- if (valind) { /* need , before number */
+- if (*arg != ',')
+- exit_error(PARAMETER_PROBLEM,
+- "u32: at char %d expected , or &&", arg-start);
+- arg++;
+- }
+- data->tests[testind].value[valind].min = parse_number(&arg, arg-start);
+- while (isspace(*arg))
+- arg++; /* another place white space could be */
+- if (*arg==':') {
+- arg++;
+- data->tests[testind].value[valind].max
+- = parse_number(&arg, arg-start);
+- }
+- else data->tests[testind].value[valind].max
+- = data->tests[testind].value[valind].min;
+- valind++;
+- if (valind > U32MAXSIZE)
+- exit_error(PARAMETER_PROBLEM,
+- "u32: at char %d too many ,'s", arg-start);
+- }
+- }
+- }
+-}
+-
+-/* Final check; must specify something. */
+-static void
+-final_check(unsigned int flags)
+-{
+-}
+-
+-/* Prints out the matchinfo. */
+-static void
+-print(const struct ipt_ip *ip,
+- const struct ipt_entry_match *match,
+- int numeric)
+-{
+- printf("u32 ");
+- print_u32((struct ipt_u32 *)match->data);
+-}
+-
+-/* Saves the union ipt_matchinfo in parsable form to stdout. */
+-static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+-{
+- printf("--u32 ");
+- print_u32((struct ipt_u32 *)match->data);
+-}
+-
+-struct iptables_match u32 = {
+- .next = NULL,
+- .name = "u32",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_u32)),
+- .userspacesize = IPT_ALIGN(sizeof(struct ipt_u32)),
+- .help = &help,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void
+-_init(void)
+-{
+- register_match(&u32);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_u32.man iptables-svn/extensions/libipt_u32.man
+--- iptables-1.3.7/extensions/libipt_u32.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_u32.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,8 +0,0 @@
+-U32 allows you to extract quantities of up to 4 bytes from a packet,
+-AND them with specified masks, shift them by specified amounts and
+-test whether the results are in any of a set of specified ranges.
+-The specification of what to extract is general enough to skip over
+-headers with lengths stored in the packet, as in IP or TCP header
+-lengths.
+-
+-Details and examples are in the kernel module source.
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_udp.man iptables-svn/extensions/libipt_udp.man
+--- iptables-1.3.7/extensions/libipt_udp.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_udp.man 2007-05-31 12:46:30.000000000 +0200
+@@ -1,4 +1,4 @@
+-These extensions are loaded if `--protocol udp' is specified. It
++These extensions can be used if `--protocol udp' is specified. It
+ provides the following options:
+ .TP
+ .BR "--source-port " "[!] \fIport\fP[:\fIport\fP]"
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_XOR.c iptables-svn/extensions/libipt_XOR.c
+--- iptables-1.3.7/extensions/libipt_XOR.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/libipt_XOR.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,114 +0,0 @@
+-/* Shared library add-on to iptables for the XOR target
+- * (C) 2000 by Tim Vandermeersch <Tim.Vandermeersch@pandora.be>
+- * Based on libipt_TTL.c
+- *
+- * Version 1.0
+- *
+- * This program is distributed under the terms of GNU GPL
+- */
+-
+-#include <stdio.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <getopt.h>
+-#include <iptables.h>
+-
+-#include <linux/netfilter_ipv4/ip_tables.h>
+-#include <linux/netfilter_ipv4/ipt_XOR.h>
+-
+-#define IPT_KEY_SET 1
+-#define IPT_BLOCKSIZE_SET 2
+-
+-static void init(struct ipt_entry_target *t, unsigned int *nfcache)
+-{
+-}
+-
+-static void help(void)
+-{
+- printf(
+- "XOR target v%s options\n"
+- " --key string Set key to \"string\"\n"
+- " --block-size Set block size\n",
+- IPTABLES_VERSION);
+-}
+-
+-static int parse(int c, char **argv, int invert, unsigned int *flags,
+- const struct ipt_entry *entry,
+- struct ipt_entry_target **target)
+-{
+- struct ipt_XOR_info *info = (struct ipt_XOR_info *) (*target)->data;
+-
+- if (!optarg)
+- exit_error(PARAMETER_PROBLEM, "XOR: too few arguments");
+-
+- if (check_inverse(optarg, &invert, NULL, 0))
+- exit_error(PARAMETER_PROBLEM, "XOR: unexpected '!'");
+-
+- switch (c) {
+- case '1':
+- strncpy(info->key, optarg, 30);
+- info->key[29] = '\0';
+- *flags |= IPT_KEY_SET;
+- break;
+- case '2':
+- info->block_size = atoi(optarg);
+- *flags |= IPT_BLOCKSIZE_SET;
+- break;
+- default:
+- return 0;
+- }
+-
+- return 1;
+-}
+-
+-static void final_check(unsigned int flags)
+-{
+- if (!(flags & IPT_KEY_SET))
+- exit_error(PARAMETER_PROBLEM, "XOR: You must specify a key");
+- if (!(flags & IPT_BLOCKSIZE_SET))
+- exit_error(PARAMETER_PROBLEM, "XOR: You must specify a block-size");
+-}
+-
+-static void save (const struct ipt_ip *ip,
+- const struct ipt_entry_target *target)
+-{
+- const struct ipt_XOR_info *info = (struct ipt_XOR_info *) target->data;
+-
+- printf("--key %s ", info->key);
+- printf("--block-size %u ", info->block_size);
+-}
+-
+-static void print (const struct ipt_ip *ip,
+- const struct ipt_entry_target *target, int numeric)
+-{
+- const struct ipt_XOR_info *info = (struct ipt_XOR_info *) target->data;
+-
+- printf("key: %s ", info->key);
+- printf("block-size: %u ", info->block_size);
+-}
+-
+-static struct option opts[] = {
+- { "key", 1, 0, '1' },
+- { "block-size", 1, 0, '2' },
+- { 0 }
+-};
+-
+-static struct iptables_target XOR = {
+- .next = NULL,
+- .name = "XOR",
+- .version = IPTABLES_VERSION,
+- .size = IPT_ALIGN(sizeof(struct ipt_XOR_info)),
+- .userspacesize = IPT_ALIGN(sizeof(struct ipt_XOR_info)),
+- .help = &help,
+- .init = &init,
+- .parse = &parse,
+- .final_check = &final_check,
+- .print = &print,
+- .save = &save,
+- .extra_opts = opts
+-};
+-
+-void _init(void)
+-{
+- register_target(&XOR);
+-}
+diff -x .svn -Nur iptables-1.3.7/extensions/libipt_XOR.man iptables-svn/extensions/libipt_XOR.man
+--- iptables-1.3.7/extensions/libipt_XOR.man 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/libipt_XOR.man 1970-01-01 01:00:00.000000000 +0100
+@@ -1,7 +0,0 @@
+-Encrypt TCP and UDP traffic using a simple XOR encryption
+-.TP
+-.BI "--key " "string"
+-Set key to "string"
+-.TP
+-.BI "--block-size"
+-Set block size
+diff -x .svn -Nur iptables-1.3.7/extensions/Makefile iptables-svn/extensions/Makefile
+--- iptables-1.3.7/extensions/Makefile 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/Makefile 2007-05-31 12:46:30.000000000 +0200
+@@ -5,8 +5,8 @@
+ # header files are present in the include/linux directory of this iptables
+ # package (HW)
+ #
+-PF_EXT_SLIB:=ah addrtype comment connlimit connmark conntrack dscp ecn esp hashlimit helper icmp iprange length limit mac mark multiport owner physdev pkttype policy realm rpc sctp standard state tcp tcpmss tos ttl udp unclean CLASSIFY CONNMARK DNAT DSCP ECN LOG MARK MASQUERADE MIRROR NETMAP NFQUEUE NOTRACK REDIRECT REJECT SAME SNAT TARPIT TCPMSS TOS TRACE TTL ULOG
+-PF6_EXT_SLIB:=connmark eui64 hl icmp6 length limit mac mark multiport owner physdev policy standard state tcp udp CONNMARK HL LOG NFQUEUE MARK TRACE
++PF_EXT_SLIB:=ah addrtype comment connmark conntrack dscp ecn esp hashlimit helper icmp iprange length limit mac mark multiport owner physdev pkttype policy realm sctp standard state tcp tcpmss tos ttl udp unclean CLASSIFY CONNMARK DNAT DSCP ECN LOG MARK MASQUERADE MIRROR NETMAP NFQUEUE NOTRACK REDIRECT REJECT SAME SNAT TCPMSS TOS TTL ULOG
++PF6_EXT_SLIB:=connmark eui64 hl icmp6 length limit mac mark multiport owner physdev policy standard state tcp udp CONNMARK HL LOG NFQUEUE MARK TCPMSS
+
+ ifeq ($(DO_SELINUX), 1)
+ PF_EXT_SE_SLIB:=SECMARK CONNSECMARK
+diff -x .svn -Nur iptables-1.3.7/extensions/.mh-test6 iptables-svn/extensions/.mh-test6
+--- iptables-1.3.7/extensions/.mh-test6 1970-01-01 01:00:00.000000000 +0100
++++ iptables-svn/extensions/.mh-test6 2007-05-31 12:46:30.000000000 +0200
+@@ -0,0 +1,2 @@
++#!/bin/sh
++[ -f $KERNEL_DIR/include/linux/netfilter_ipv6/ip6t_mh.h ] && echo mh
+diff -x .svn -Nur iptables-1.3.7/extensions/.mport-test iptables-svn/extensions/.mport-test
+--- iptables-1.3.7/extensions/.mport-test 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/.mport-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,2 +0,0 @@
+-#! /bin/sh
+-[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_mport.c ] && echo mport
+diff -x .svn -Nur iptables-1.3.7/extensions/.NETLINK-test iptables-svn/extensions/.NETLINK-test
+--- iptables-1.3.7/extensions/.NETLINK-test 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/.NETLINK-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,2 +0,0 @@
+-#! /bin/sh
+-[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_NETLINK.c ] && echo NETLINK
+diff -x .svn -Nur iptables-1.3.7/extensions/.nth-test iptables-svn/extensions/.nth-test
+--- iptables-1.3.7/extensions/.nth-test 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/.nth-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,3 +0,0 @@
+-#!/bin/sh
+-# True if nth is applied.
+-[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_nth.h ] && echo nth
+diff -x .svn -Nur iptables-1.3.7/extensions/.nth-test6 iptables-svn/extensions/.nth-test6
+--- iptables-1.3.7/extensions/.nth-test6 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/.nth-test6 1970-01-01 01:00:00.000000000 +0100
+@@ -1,3 +0,0 @@
+-#!/bin/sh
+-# True if nth is applied.
+-[ -f $KERNEL_DIR/include/linux/netfilter_ipv6/ip6t_nth.h ] && echo nth
+diff -x .svn -Nur iptables-1.3.7/extensions/.osf-test iptables-svn/extensions/.osf-test
+--- iptables-1.3.7/extensions/.osf-test 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/.osf-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,3 +0,0 @@
+-#!/bin/sh
+-# True if osf is applied.
+-[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_osf.h ] && echo osf
+diff -x .svn -Nur iptables-1.3.7/extensions/.psd-test iptables-svn/extensions/.psd-test
+--- iptables-1.3.7/extensions/.psd-test 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/.psd-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,3 +0,0 @@
+-#!/bin/sh
+-# True if psd is applied.
+-[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_psd.h ] && echo psd
+diff -x .svn -Nur iptables-1.3.7/extensions/.random-test iptables-svn/extensions/.random-test
+--- iptables-1.3.7/extensions/.random-test 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/.random-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,3 +0,0 @@
+-#!/bin/sh
+-# True if random is applied.
+-[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_random.h ] && echo random
+diff -x .svn -Nur iptables-1.3.7/extensions/.random-test6 iptables-svn/extensions/.random-test6
+--- iptables-1.3.7/extensions/.random-test6 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/.random-test6 1970-01-01 01:00:00.000000000 +0100
+@@ -1,3 +0,0 @@
+-#!/bin/sh
+-# True if random is applied.
+-[ -f $KERNEL_DIR/include/linux/netfilter_ipv6/ip6t_random.h ] && echo random
+diff -x .svn -Nur iptables-1.3.7/extensions/.record-rpc-test iptables-svn/extensions/.record-rpc-test
+--- iptables-1.3.7/extensions/.record-rpc-test 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/.record-rpc-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,3 +0,0 @@
+-#! /bin/sh
+-# True if record rpc is applied.
+-[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_record_rpc.c ] && echo record_rpc
+diff -x .svn -Nur iptables-1.3.7/extensions/.ROUTE-test iptables-svn/extensions/.ROUTE-test
+--- iptables-1.3.7/extensions/.ROUTE-test 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/.ROUTE-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,2 +0,0 @@
+-#! /bin/sh
+-[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_ROUTE.c ] && echo ROUTE
+diff -x .svn -Nur iptables-1.3.7/extensions/.ROUTE-test6 iptables-svn/extensions/.ROUTE-test6
+--- iptables-1.3.7/extensions/.ROUTE-test6 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/.ROUTE-test6 1970-01-01 01:00:00.000000000 +0100
+@@ -1,2 +0,0 @@
+-#! /bin/sh
+-[ -f $KERNEL_DIR/include/linux/netfilter_ipv6/ip6t_ROUTE.h ] && echo ROUTE
+diff -x .svn -Nur iptables-1.3.7/extensions/.TCPLAG-test iptables-svn/extensions/.TCPLAG-test
+--- iptables-1.3.7/extensions/.TCPLAG-test 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/.TCPLAG-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,2 +0,0 @@
+-#! /bin/sh
+-[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_TCPLAG.c ] && echo TCPLAG
+diff -x .svn -Nur iptables-1.3.7/extensions/.time-test iptables-svn/extensions/.time-test
+--- iptables-1.3.7/extensions/.time-test 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/extensions/.time-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,3 +0,0 @@
+-#!/bin/sh
+-# True if time is applied.
+-[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_time.h ] && echo time
+diff -x .svn -Nur iptables-1.3.7/extensions/.u32-test iptables-svn/extensions/.u32-test
+--- iptables-1.3.7/extensions/.u32-test 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/.u32-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,3 +0,0 @@
+-#!/bin/sh
+-# True if u32 is applied.
+-[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_u32.h ] && echo u32
+diff -x .svn -Nur iptables-1.3.7/extensions/.XOR-test iptables-svn/extensions/.XOR-test
+--- iptables-1.3.7/extensions/.XOR-test 2006-12-04 12:15:19.000000000 +0100
++++ iptables-svn/extensions/.XOR-test 1970-01-01 01:00:00.000000000 +0100
+@@ -1,2 +0,0 @@
+-#! /bin/sh
+-[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_XOR.c ] && echo XOR
+diff -x .svn -Nur iptables-1.3.7/include/ip6tables.h iptables-svn/include/ip6tables.h
+--- iptables-1.3.7/include/ip6tables.h 2006-12-04 12:15:16.000000000 +0100
++++ iptables-svn/include/ip6tables.h 2007-05-31 12:46:27.000000000 +0200
+@@ -14,6 +14,9 @@
+ #ifndef IPPROTO_DCCP
+ #define IPPROTO_DCCP 33
+ #endif
++#ifndef IPPROTO_UDPLITE
++#define IPPROTO_UDPLITE 136
++#endif
+
+ #ifndef IP6T_SO_GET_REVISION_MATCH /* Old kernel source. */
+ #define IP6T_SO_GET_REVISION_MATCH 68
+@@ -171,7 +174,8 @@
+ extern int for_each_chain(int (*fn)(const ip6t_chainlabel, int, ip6tc_handle_t *), int verbose, int builtinstoo, ip6tc_handle_t *handle);
+ extern int flush_entries(const ip6t_chainlabel chain, int verbose, ip6tc_handle_t *handle);
+ extern int delete_chain(const ip6t_chainlabel chain, int verbose, ip6tc_handle_t *handle);
+-extern int ip6tables_insmod(const char *modname, const char *modprobe);
+-extern int load_ip6tables_ko(const char *modprobe);
++extern int
++ip6tables_insmod(const char *modname, const char *modprobe, int quiet);
++extern int load_ip6tables_ko(const char *modprobe, int quiet);
+
+ #endif /*_IP6TABLES_USER_H*/
+diff -x .svn -Nur iptables-1.3.7/include/iptables_common.h iptables-svn/include/iptables_common.h
+--- iptables-1.3.7/include/iptables_common.h 2006-12-04 12:15:16.000000000 +0100
++++ iptables-svn/include/iptables_common.h 2007-05-31 12:46:27.000000000 +0200
+@@ -27,8 +27,9 @@
+ unsigned long long int,
+ unsigned long long int,
+ unsigned long long *);
+-extern int iptables_insmod(const char *modname, const char *modprobe);
+-extern int load_iptables_ko(const char *modprobe);
++extern int
++iptables_insmod(const char *modname, const char *modprobe, int quiet);
++extern int load_iptables_ko(const char *modprobe, int quiet);
+ void exit_error(enum exittype, char *, ...)__attribute__((noreturn,
+ format(printf,2,3)));
+ extern const char *program_name, *program_version;
+diff -x .svn -Nur iptables-1.3.7/include/iptables.h iptables-svn/include/iptables.h
+--- iptables-1.3.7/include/iptables.h 2006-12-04 12:15:16.000000000 +0100
++++ iptables-svn/include/iptables.h 2007-05-31 12:46:27.000000000 +0200
+@@ -14,6 +14,9 @@
+ #ifndef IPPROTO_DCCP
+ #define IPPROTO_DCCP 33
+ #endif
++#ifndef IPPROTO_UDPLITE
++#define IPPROTO_UDPLITE 136
++#endif
+
+ #ifndef IPT_SO_GET_REVISION_MATCH /* Old kernel source. */
+ #define IPT_SO_GET_REVISION_MATCH (IPT_BASE_CTL + 2)
+diff -x .svn -Nur iptables-1.3.7/include/linux/netfilter/nf_conntrack_common.h iptables-svn/include/linux/netfilter/nf_conntrack_common.h
+--- iptables-1.3.7/include/linux/netfilter/nf_conntrack_common.h 1970-01-01 01:00:00.000000000 +0100
++++ iptables-svn/include/linux/netfilter/nf_conntrack_common.h 2007-05-31 12:46:26.000000000 +0200
+@@ -0,0 +1,135 @@
++#ifndef _NF_CONNTRACK_COMMON_H
++#define _NF_CONNTRACK_COMMON_H
++/* Connection state tracking for netfilter. This is separated from,
++ but required by, the NAT layer; it can also be used by an iptables
++ extension. */
++enum ip_conntrack_info
++{
++ /* Part of an established connection (either direction). */
++ IP_CT_ESTABLISHED,
++
++ /* Like NEW, but related to an existing connection, or ICMP error
++ (in either direction). */
++ IP_CT_RELATED,
++
++ /* Started a new connection to track (only
++ IP_CT_DIR_ORIGINAL); may be a retransmission. */
++ IP_CT_NEW,
++
++ /* >= this indicates reply direction */
++ IP_CT_IS_REPLY,
++
++ /* Number of distinct IP_CT types (no NEW in reply dirn). */
++ IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1
++};
++
++/* Bitset representing status of connection. */
++enum ip_conntrack_status {
++ /* It's an expected connection: bit 0 set. This bit never changed */
++ IPS_EXPECTED_BIT = 0,
++ IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
++
++ /* We've seen packets both ways: bit 1 set. Can be set, not unset. */
++ IPS_SEEN_REPLY_BIT = 1,
++ IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT),
++
++ /* Conntrack should never be early-expired. */
++ IPS_ASSURED_BIT = 2,
++ IPS_ASSURED = (1 << IPS_ASSURED_BIT),
++
++ /* Connection is confirmed: originating packet has left box */
++ IPS_CONFIRMED_BIT = 3,
++ IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
++
++ /* Connection needs src nat in orig dir. This bit never changed. */
++ IPS_SRC_NAT_BIT = 4,
++ IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT),
++
++ /* Connection needs dst nat in orig dir. This bit never changed. */
++ IPS_DST_NAT_BIT = 5,
++ IPS_DST_NAT = (1 << IPS_DST_NAT_BIT),
++
++ /* Both together. */
++ IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
++
++ /* Connection needs TCP sequence adjusted. */
++ IPS_SEQ_ADJUST_BIT = 6,
++ IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
++
++ /* NAT initialization bits. */
++ IPS_SRC_NAT_DONE_BIT = 7,
++ IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT),
++
++ IPS_DST_NAT_DONE_BIT = 8,
++ IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT),
++
++ /* Both together */
++ IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
++
++ /* Connection is dying (removed from lists), can not be unset. */
++ IPS_DYING_BIT = 9,
++ IPS_DYING = (1 << IPS_DYING_BIT),
++
++ /* Connection has fixed timeout. */
++ IPS_FIXED_TIMEOUT_BIT = 10,
++ IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT),
++};
++
++/* Connection tracking event bits */
++enum ip_conntrack_events
++{
++ /* New conntrack */
++ IPCT_NEW_BIT = 0,
++ IPCT_NEW = (1 << IPCT_NEW_BIT),
++
++ /* Expected connection */
++ IPCT_RELATED_BIT = 1,
++ IPCT_RELATED = (1 << IPCT_RELATED_BIT),
++
++ /* Destroyed conntrack */
++ IPCT_DESTROY_BIT = 2,
++ IPCT_DESTROY = (1 << IPCT_DESTROY_BIT),
++
++ /* Timer has been refreshed */
++ IPCT_REFRESH_BIT = 3,
++ IPCT_REFRESH = (1 << IPCT_REFRESH_BIT),
++
++ /* Status has changed */
++ IPCT_STATUS_BIT = 4,
++ IPCT_STATUS = (1 << IPCT_STATUS_BIT),
++
++ /* Update of protocol info */
++ IPCT_PROTOINFO_BIT = 5,
++ IPCT_PROTOINFO = (1 << IPCT_PROTOINFO_BIT),
++
++ /* Volatile protocol info */
++ IPCT_PROTOINFO_VOLATILE_BIT = 6,
++ IPCT_PROTOINFO_VOLATILE = (1 << IPCT_PROTOINFO_VOLATILE_BIT),
++
++ /* New helper for conntrack */
++ IPCT_HELPER_BIT = 7,
++ IPCT_HELPER = (1 << IPCT_HELPER_BIT),
++
++ /* Update of helper info */
++ IPCT_HELPINFO_BIT = 8,
++ IPCT_HELPINFO = (1 << IPCT_HELPINFO_BIT),
++
++ /* Volatile helper info */
++ IPCT_HELPINFO_VOLATILE_BIT = 9,
++ IPCT_HELPINFO_VOLATILE = (1 << IPCT_HELPINFO_VOLATILE_BIT),
++
++ /* NAT info */
++ IPCT_NATINFO_BIT = 10,
++ IPCT_NATINFO = (1 << IPCT_NATINFO_BIT),
++
++ /* Counter highest bit has been set */
++ IPCT_COUNTER_FILLING_BIT = 11,
++ IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT),
++};
++
++enum ip_conntrack_expect_events {
++ IPEXP_NEW_BIT = 0,
++ IPEXP_NEW = (1 << IPEXP_NEW_BIT),
++};
++
++#endif /* _NF_CONNTRACK_COMMON_H */
+diff -x .svn -Nur iptables-1.3.7/include/linux/netfilter/nf_conntrack_tuple_common.h iptables-svn/include/linux/netfilter/nf_conntrack_tuple_common.h
+--- iptables-1.3.7/include/linux/netfilter/nf_conntrack_tuple_common.h 1970-01-01 01:00:00.000000000 +0100
++++ iptables-svn/include/linux/netfilter/nf_conntrack_tuple_common.h 2007-05-31 12:46:26.000000000 +0200
+@@ -0,0 +1,13 @@
++#ifndef _NF_CONNTRACK_TUPLE_COMMON_H
++#define _NF_CONNTRACK_TUPLE_COMMON_H
++
++enum ip_conntrack_dir
++{
++ IP_CT_DIR_ORIGINAL,
++ IP_CT_DIR_REPLY,
++ IP_CT_DIR_MAX
++};
++
++#define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL)
++
++#endif /* _NF_CONNTRACK_TUPLE_COMMON_H */
+diff -x .svn -Nur iptables-1.3.7/include/linux/netfilter/nf_conntrack_tuple.h iptables-svn/include/linux/netfilter/nf_conntrack_tuple.h
+--- iptables-1.3.7/include/linux/netfilter/nf_conntrack_tuple.h 1970-01-01 01:00:00.000000000 +0100
++++ iptables-svn/include/linux/netfilter/nf_conntrack_tuple.h 2007-05-31 12:46:26.000000000 +0200
+@@ -0,0 +1,103 @@
++/*
++ * Definitions and Declarations for tuple.
++ *
++ * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
++ * - generalize L3 protocol dependent part.
++ *
++ * Derived from include/linux/netfiter_ipv4/ip_conntrack_tuple.h
++ */
++
++#ifndef _NF_CONNTRACK_TUPLE_H
++#define _NF_CONNTRACK_TUPLE_H
++
++#include <linux/netfilter/nf_conntrack_tuple_common.h>
++
++/* A `tuple' is a structure containing the information to uniquely
++ identify a connection. ie. if two packets have the same tuple, they
++ are in the same connection; if not, they are not.
++
++ We divide the structure along "manipulatable" and
++ "non-manipulatable" lines, for the benefit of the NAT code.
++*/
++
++#define NF_CT_TUPLE_L3SIZE 4
++
++/* The l3 protocol-specific manipulable parts of the tuple: always in
++ network order! */
++union nf_conntrack_address {
++ u_int32_t all[NF_CT_TUPLE_L3SIZE];
++ __be32 ip;
++ __be32 ip6[4];
++};
++
++/* The protocol-specific manipulable parts of the tuple: always in
++ network order! */
++union nf_conntrack_man_proto
++{
++ /* Add other protocols here. */
++ u_int16_t all;
++
++ struct {
++ __be16 port;
++ } tcp;
++ struct {
++ __be16 port;
++ } udp;
++ struct {
++ __be16 id;
++ } icmp;
++ struct {
++ __be16 port;
++ } sctp;
++ struct {
++ __be16 key; /* GRE key is 32bit, PPtP only uses 16bit */
++ } gre;
++};
++
++/* The manipulable part of the tuple. */
++struct nf_conntrack_man
++{
++ union nf_conntrack_address u3;
++ union nf_conntrack_man_proto u;
++ /* Layer 3 protocol */
++ u_int16_t l3num;
++};
++
++/* This contains the information to distinguish a connection. */
++struct nf_conntrack_tuple
++{
++ struct nf_conntrack_man src;
++
++ /* These are the parts of the tuple which are fixed. */
++ struct {
++ union nf_conntrack_address u3;
++ union {
++ /* Add other protocols here. */
++ u_int16_t all;
++
++ struct {
++ __be16 port;
++ } tcp;
++ struct {
++ __be16 port;
++ } udp;
++ struct {
++ u_int8_t type, code;
++ } icmp;
++ struct {
++ __be16 port;
++ } sctp;
++ struct {
++ __be16 key;
++ } gre;
++ } u;
++
++ /* The protocol. */
++ u_int8_t protonum;
++
++ /* The direction (for tuplehash) */
++ u_int8_t dir;
++ } dst;
++};
++
++#endif /* _NF_CONNTRACK_TUPLE_H */
+diff -x .svn -Nur iptables-1.3.7/include/linux/netfilter/nf_nat.h iptables-svn/include/linux/netfilter/nf_nat.h
+--- iptables-1.3.7/include/linux/netfilter/nf_nat.h 1970-01-01 01:00:00.000000000 +0100
++++ iptables-svn/include/linux/netfilter/nf_nat.h 2007-05-31 12:46:26.000000000 +0200
+@@ -0,0 +1,45 @@
++#ifndef _NF_NAT_H
++#define _NF_NAT_H
++#include <linux/netfilter_ipv4.h>
++#include <linux/netfilter/nf_conntrack_tuple.h>
++
++#define NF_NAT_MAPPING_TYPE_MAX_NAMELEN 16
++
++enum nf_nat_manip_type
++{
++ IP_NAT_MANIP_SRC,
++ IP_NAT_MANIP_DST
++};
++
++/* SRC manip occurs POST_ROUTING or LOCAL_IN */
++#define HOOK2MANIP(hooknum) ((hooknum) != NF_IP_POST_ROUTING && (hooknum) != NF_IP_LOCAL_IN)
++
++#define IP_NAT_RANGE_MAP_IPS 1
++#define IP_NAT_RANGE_PROTO_SPECIFIED 2
++#define IP_NAT_RANGE_PROTO_RANDOM 4
++
++/* Single range specification. */
++struct nf_nat_range
++{
++ /* Set to OR of flags above. */
++ unsigned int flags;
++
++ /* Inclusive: network order. */
++ __be32 min_ip, max_ip;
++
++ /* Inclusive: network order */
++ union nf_conntrack_man_proto min, max;
++};
++
++/* For backwards compat: don't use in modern code. */
++struct nf_nat_multi_range_compat
++{
++ unsigned int rangesize; /* Must be 1. */
++
++ /* hangs off end. */
++ struct nf_nat_range range[1];
++};
++
++#define ip_nat_range nf_nat_range
++#define ip_nat_multi_range nf_nat_multi_range_compat
++#endif
+diff -x .svn -Nur iptables-1.3.7/include/linux/netfilter_ipv4/ipt_conntrack.h iptables-svn/include/linux/netfilter_ipv4/ipt_conntrack.h
+--- iptables-1.3.7/include/linux/netfilter_ipv4/ipt_conntrack.h 2006-12-04 12:15:16.000000000 +0100
++++ iptables-svn/include/linux/netfilter_ipv4/ipt_conntrack.h 2007-05-31 12:46:26.000000000 +0200
+@@ -5,7 +5,7 @@
+ #ifndef _IPT_CONNTRACK_H
+ #define _IPT_CONNTRACK_H
+
+-#include <linux/netfilter_ipv4/ip_conntrack.h>
++#include <linux/netfilter/nf_conntrack_common.h>
+
+ /* backwards compatibility crap. only exists in userspace - HW */
+ #include <linux/version.h>
+diff -x .svn -Nur iptables-1.3.7/include/linux/netfilter_ipv6/ip6t_TCPMSS.h iptables-svn/include/linux/netfilter_ipv6/ip6t_TCPMSS.h
+--- iptables-1.3.7/include/linux/netfilter_ipv6/ip6t_TCPMSS.h 1970-01-01 01:00:00.000000000 +0100
++++ iptables-svn/include/linux/netfilter_ipv6/ip6t_TCPMSS.h 2007-05-31 12:46:26.000000000 +0200
+@@ -0,0 +1,10 @@
++#ifndef _IP6T_TCPMSS_H
++#define _IP6T_TCPMSS_H
++
++struct ip6t_tcpmss_info {
++ u_int16_t mss;
++};
++
++#define IP6T_TCPMSS_CLAMP_PMTU 0xffff
++
++#endif /*_IP6T_TCPMSS_H*/
+diff -x .svn -Nur iptables-1.3.7/ip6tables.8.in iptables-svn/ip6tables.8.in
+--- iptables-1.3.7/ip6tables.8.in 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/ip6tables.8.in 2007-05-31 12:46:31.000000000 +0200
+@@ -480,8 +480,9 @@
+ .PP
+ Harald Welte wrote the ULOG and NFQUEUE target, the new libiptc, aswell as TTL match+target and libipulog.
+ .PP
+-The Netfilter Core Team is: Marc Boucher, Martin Josefsson, Jozsef Kadlecsik,
+-James Morris, Harald Welte and Rusty Russell.
++The Netfilter Core Team is: Marc Boucher, Martin Josefsson, Yasuyuki Kozakai,
++Jozsef Kadlecsik, Patrick McHardy, James Morris, Pablo Neira Ayuso,
++Harald Welte and Rusty Russell.
+ .PP
+ ip6tables man page created by Andras Kis-Szabo, based on
+ iptables man page written by Herve Eychenne <rv@wallfire.org>.
+diff -x .svn -Nur iptables-1.3.7/ip6tables.c iptables-svn/ip6tables.c
+--- iptables-1.3.7/ip6tables.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/ip6tables.c 2007-05-31 12:46:31.000000000 +0200
+@@ -219,14 +219,21 @@
+ #define IPPROTO_AH 51
+ #endif
+ #endif
++#ifndef IPPROTO_MH
++#define IPPROTO_MH 135
++#endif
+
+ static const struct pprot chain_protos[] = {
+ { "tcp", IPPROTO_TCP },
+ { "udp", IPPROTO_UDP },
++ { "udplite", IPPROTO_UDPLITE },
+ { "icmpv6", IPPROTO_ICMPV6 },
+ { "ipv6-icmp", IPPROTO_ICMPV6 },
+ { "esp", IPPROTO_ESP },
+ { "ah", IPPROTO_AH },
++ { "ipv6-mh", IPPROTO_MH },
++ { "mh", IPPROTO_MH },
++ { "all", 0 },
+ };
+
+ static char *
+@@ -1120,7 +1127,7 @@
+ strcpy(rev.name, name);
+ rev.revision = revision;
+
+- load_ip6tables_ko(modprobe);
++ load_ip6tables_ko(modprobe, 1);
+
+ max_rev = getsockopt(sockfd, IPPROTO_IPV6, opt, &rev, &s);
+ if (max_rev < 0) {
+@@ -1745,10 +1752,10 @@
+ return NULL;
+ }
+
+-int ip6tables_insmod(const char *modname, const char *modprobe)
++int ip6tables_insmod(const char *modname, const char *modprobe, int quiet)
+ {
+ char *buf = NULL;
+- char *argv[3];
++ char *argv[4];
+ int status;
+
+ /* If they don't explicitly set it, read out of kernel */
+@@ -1763,7 +1770,13 @@
+ case 0:
+ argv[0] = (char *)modprobe;
+ argv[1] = (char *)modname;
+- argv[2] = NULL;
++ if (quiet) {
++ argv[2] = "-q";
++ argv[3] = NULL;
++ } else {
++ argv[2] = NULL;
++ argv[3] = NULL;
++ }
+ execv(argv[0], argv);
+
+ /* not usually reached */
+@@ -1781,14 +1794,14 @@
+ return -1;
+ }
+
+-int load_ip6tables_ko(const char *modprobe)
++int load_ip6tables_ko(const char *modprobe, int quiet)
+ {
+ static int loaded = 0;
+ static int ret = -1;
+
+ if (!loaded) {
+- ret = ip6tables_insmod("ip6_tables", modprobe);
+- loaded = 1;
++ ret = ip6tables_insmod("ip6_tables", modprobe, quiet);
++ loaded = (ret == 0);
+ }
+
+ return ret;
+@@ -2349,7 +2362,7 @@
+ *handle = ip6tc_init(*table);
+
+ /* try to insmod the module if iptc_init failed */
+- if (!*handle && load_ip6tables_ko(modprobe) != -1)
++ if (!*handle && load_ip6tables_ko(modprobe, 0) != -1)
+ *handle = ip6tc_init(*table);
+
+ if (!*handle)
+diff -x .svn -Nur iptables-1.3.7/ip6tables-restore.c iptables-svn/ip6tables-restore.c
+--- iptables-1.3.7/ip6tables-restore.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/ip6tables-restore.c 2007-05-31 12:46:31.000000000 +0200
+@@ -7,7 +7,7 @@
+ * Rusty Russell <rusty@linuxcare.com.au>
+ * This code is distributed under the terms of GNU GPL v2
+ *
+- * $Id: ip6tables-restore.c 6460 2006-02-09 14:35:38Z /C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=laforge/emailAddress=laforge@netfilter.org $
++ * $Id: ip6tables-restore.c 6828 2007-05-10 15:00:39Z /C=EU/ST=EU/CN=Patrick McHardy/emailAddress=kaber@trash.net $
+ */
+
+ #include <getopt.h>
+@@ -62,19 +62,19 @@
+
+ if (!handle) {
+ /* try to insmod the module if iptc_init failed */
+- ip6tables_insmod("ip6_tables", modprobe);
++ ip6tables_insmod("ip6_tables", modprobe, 0);
+ handle = ip6tc_init(tablename);
+ }
+
+ if (!handle) {
+- exit_error(PARAMETER_PROBLEM, "%s: unable to initialize"
++ exit_error(PARAMETER_PROBLEM, "%s: unable to initialize "
+ "table '%s'\n", program_name, tablename);
+ exit(1);
+ }
+ return handle;
+ }
+
+-int parse_counters(char *string, struct ip6t_counters *ctr)
++static int parse_counters(char *string, struct ip6t_counters *ctr)
+ {
+ return (sscanf(string, "[%llu:%llu]", (unsigned long long *)&ctr->pcnt, (unsigned long long *)&ctr->bcnt) == 2);
+ }
+@@ -154,13 +154,13 @@
+ if (optind == argc - 1) {
+ in = fopen(argv[optind], "r");
+ if (!in) {
+- fprintf(stderr, "Can't open %s: %s", argv[optind],
++ fprintf(stderr, "Can't open %s: %s\n", argv[optind],
+ strerror(errno));
+ exit(1);
+ }
+ }
+ else if (optind < argc) {
+- fprintf(stderr, "Unknown arguments found on commandline");
++ fprintf(stderr, "Unknown arguments found on commandline\n");
+ exit(1);
+ }
+ else in = stdin;
+diff -x .svn -Nur iptables-1.3.7/ip6tables-save.c iptables-svn/ip6tables-save.c
+--- iptables-1.3.7/ip6tables-save.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/ip6tables-save.c 2007-05-31 12:46:31.000000000 +0200
+@@ -351,7 +351,7 @@
+ }
+
+ if (optind < argc) {
+- fprintf(stderr, "Unknown arguments found on commandline");
++ fprintf(stderr, "Unknown arguments found on commandline\n");
+ exit(1);
+ }
+
+diff -x .svn -Nur iptables-1.3.7/iptables.8.in iptables-svn/iptables.8.in
+--- iptables-1.3.7/iptables.8.in 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/iptables.8.in 2007-05-31 12:46:31.000000000 +0200
+@@ -486,8 +486,9 @@
+ .PP
+ Harald Welte wrote the ULOG and NFQUEUE target, the new libiptc, as well as the TTL, DSCP, ECN matches and targets.
+ .PP
+-The Netfilter Core Team is: Marc Boucher, Martin Josefsson, Jozsef Kadlecsik,
+-Patrick McHardy, James Morris, Harald Welte and Rusty Russell.
++The Netfilter Core Team is: Marc Boucher, Martin Josefsson, Yasuyuki Kozakai,
++Jozsef Kadlecsik, Patrick McHardy, James Morris, Pablo Neira Ayuso,
++Harald Welte and Rusty Russell.
+ .PP
+ Man page originally written by Herve Eychenne <rv@wallfire.org>.
+ .\" .. and did I mention that we are incredibly cool people?
+diff -x .svn -Nur iptables-1.3.7/iptables.c iptables-svn/iptables.c
+--- iptables-1.3.7/iptables.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/iptables.c 2007-05-31 12:46:31.000000000 +0200
+@@ -227,10 +227,12 @@
+ static const struct pprot chain_protos[] = {
+ { "tcp", IPPROTO_TCP },
+ { "udp", IPPROTO_UDP },
++ { "udplite", IPPROTO_UDPLITE },
+ { "icmp", IPPROTO_ICMP },
+ { "esp", IPPROTO_ESP },
+ { "ah", IPPROTO_AH },
+ { "sctp", IPPROTO_SCTP },
++ { "all", 0 },
+ };
+
+ static char *
+@@ -1148,7 +1150,7 @@
+ exit(1);
+ }
+
+- load_iptables_ko(modprobe);
++ load_iptables_ko(modprobe, 1);
+
+ strcpy(rev.name, name);
+ rev.revision = revision;
+@@ -1812,10 +1814,10 @@
+ return NULL;
+ }
+
+-int iptables_insmod(const char *modname, const char *modprobe)
++int iptables_insmod(const char *modname, const char *modprobe, int quiet)
+ {
+ char *buf = NULL;
+- char *argv[3];
++ char *argv[4];
+ int status;
+
+ /* If they don't explicitly set it, read out of kernel */
+@@ -1830,7 +1832,13 @@
+ case 0:
+ argv[0] = (char *)modprobe;
+ argv[1] = (char *)modname;
+- argv[2] = NULL;
++ if (quiet) {
++ argv[2] = "-q";
++ argv[3] = NULL;
++ } else {
++ argv[2] = NULL;
++ argv[3] = NULL;
++ }
+ execv(argv[0], argv);
+
+ /* not usually reached */
+@@ -1848,14 +1856,14 @@
+ return -1;
+ }
+
+-int load_iptables_ko(const char *modprobe)
++int load_iptables_ko(const char *modprobe, int quiet)
+ {
+ static int loaded = 0;
+ static int ret = -1;
+
+ if (!loaded) {
+- ret = iptables_insmod("ip_tables", NULL);
+- loaded = 1;
++ ret = iptables_insmod("ip_tables", modprobe, quiet);
++ loaded = (ret == 0);
+ }
+
+ return ret;
+@@ -2441,7 +2449,7 @@
+ *handle = iptc_init(*table);
+
+ /* try to insmod the module if iptc_init failed */
+- if (!*handle && load_iptables_ko(modprobe) != -1)
++ if (!*handle && load_iptables_ko(modprobe, 0) != -1)
+ *handle = iptc_init(*table);
+
+ if (!*handle)
+diff -x .svn -Nur iptables-1.3.7/iptables-multi.c iptables-svn/iptables-multi.c
+--- iptables-1.3.7/iptables-multi.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/iptables-multi.c 2007-05-31 12:46:31.000000000 +0200
+@@ -6,6 +6,7 @@
+ int iptables_main(int argc, char **argv);
+ int iptables_save_main(int argc, char **argv);
+ int iptables_restore_main(int argc, char **argv);
++int iptables_xml_main(int argc, char **argv);
+
+ int main(int argc, char **argv) {
+ char *progname;
+@@ -25,6 +26,9 @@
+ if (!strcmp(progname, "iptables-restore"))
+ return iptables_restore_main(argc, argv);
+
++ if (!strcmp(progname, "iptables-xml"))
++ return iptables_xml_main(argc, argv);
++
+ fprintf(stderr, "iptables multi-purpose version: unknown applet name %s\n", progname);
+ exit(1);
+ }
+diff -x .svn -Nur iptables-1.3.7/iptables-restore.c iptables-svn/iptables-restore.c
+--- iptables-1.3.7/iptables-restore.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/iptables-restore.c 2007-05-31 12:46:31.000000000 +0200
+@@ -4,7 +4,7 @@
+ *
+ * This code is distributed under the terms of GNU GPL v2
+ *
+- * $Id: iptables-restore.c 6460 2006-02-09 14:35:38Z /C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=laforge/emailAddress=laforge@netfilter.org $
++ * $Id: iptables-restore.c 6828 2007-05-10 15:00:39Z /C=EU/ST=EU/CN=Patrick McHardy/emailAddress=kaber@trash.net $
+ */
+
+ #include <getopt.h>
+@@ -59,19 +59,19 @@
+
+ if (!handle) {
+ /* try to insmod the module if iptc_init failed */
+- iptables_insmod("ip_tables", modprobe);
++ iptables_insmod("ip_tables", modprobe, 0);
+ handle = iptc_init(tablename);
+ }
+
+ if (!handle) {
+- exit_error(PARAMETER_PROBLEM, "%s: unable to initialize"
++ exit_error(PARAMETER_PROBLEM, "%s: unable to initialize "
+ "table '%s'\n", program_name, tablename);
+ exit(1);
+ }
+ return handle;
+ }
+
+-int parse_counters(char *string, struct ipt_counters *ctr)
++static int parse_counters(char *string, struct ipt_counters *ctr)
+ {
+ return (sscanf(string, "[%llu:%llu]", (unsigned long long *)&ctr->pcnt, (unsigned long long *)&ctr->bcnt) == 2);
+ }
+@@ -157,13 +157,13 @@
+ if (optind == argc - 1) {
+ in = fopen(argv[optind], "r");
+ if (!in) {
+- fprintf(stderr, "Can't open %s: %s", argv[optind],
++ fprintf(stderr, "Can't open %s: %s\n", argv[optind],
+ strerror(errno));
+ exit(1);
+ }
+ }
+ else if (optind < argc) {
+- fprintf(stderr, "Unknown arguments found on commandline");
++ fprintf(stderr, "Unknown arguments found on commandline\n");
+ exit(1);
+ }
+ else in = stdin;
+@@ -301,8 +301,9 @@
+ char *parsestart;
+
+ /* the parser */
+- char *param_start, *curchar;
++ char *curchar;
+ int quote_open;
++ int param_len;
+
+ /* reset the newargv */
+ newargc = 0;
+@@ -349,9 +350,11 @@
+ * longer a real hacker, but I can live with that */
+
+ quote_open = 0;
+- param_start = parsestart;
++ param_len = 0;
+
+ for (curchar = parsestart; *curchar; curchar++) {
++ char param_buffer[1024];
++
+ if (*curchar == '"') {
+ /* quote_open cannot be true if there
+ * was no previous character. Thus,
+@@ -360,30 +363,27 @@
+ *(curchar-1) != '\\') {
+ quote_open = 0;
+ *curchar = ' ';
+- } else {
++ } else if (!quote_open) {
+ quote_open = 1;
+- param_start++;
++ continue;
+ }
+ }
+ if (*curchar == ' '
+ || *curchar == '\t'
+ || * curchar == '\n') {
+- char param_buffer[1024];
+- int param_len = curchar-param_start;
+
+- if (quote_open)
++ if (quote_open) {
++ param_buffer[param_len++] =
++ *curchar;
+ continue;
++ }
+
+ if (!param_len) {
+ /* two spaces? */
+- param_start++;
+ continue;
+ }
+-
+- /* end of one parameter */
+- strncpy(param_buffer, param_start,
+- param_len);
+- *(param_buffer+param_len) = '\0';
++
++ param_buffer[param_len] = '\0';
+
+ /* check if table name specified */
+ if (!strncmp(param_buffer, "-t", 3)
+@@ -395,9 +395,26 @@
+ }
+
+ add_argv(param_buffer);
+- param_start += param_len + 1;
++ param_len = 0;
+ } else {
+- /* regular character, skip */
++ /* Skip backslash that escapes quote:
++ * the standard input does not require
++ * escaping. However, the output
++ * generated by iptables-save
++ * introduces bashlash to keep
++ * consistent with iptables
++ */
++ if (quote_open &&
++ *curchar == '\\' &&
++ *(curchar+1) == '"')
++ continue;
++
++ /* regular character, copy to buffer */
++ param_buffer[param_len++] = *curchar;
++
++ if (param_len >= sizeof(param_buffer))
++ exit_error(PARAMETER_PROBLEM,
++ "Parameter too long!");
+ }
+ }
+
+diff -x .svn -Nur iptables-1.3.7/iptables-save.c iptables-svn/iptables-save.c
+--- iptables-1.3.7/iptables-save.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/iptables-save.c 2007-05-31 12:46:31.000000000 +0200
+@@ -368,7 +368,7 @@
+ }
+
+ if (optind < argc) {
+- fprintf(stderr, "Unknown arguments found on commandline");
++ fprintf(stderr, "Unknown arguments found on commandline\n");
+ exit(1);
+ }
+
+diff -x .svn -Nur iptables-1.3.7/iptables-xml.c iptables-svn/iptables-xml.c
+--- iptables-1.3.7/iptables-xml.c 2006-12-04 12:15:20.000000000 +0100
++++ iptables-svn/iptables-xml.c 2007-05-31 12:46:31.000000000 +0200
+@@ -26,10 +26,10 @@
+ /* no need to link with iptables.o */
+ const char *program_name;
+ const char *program_version;
+-int line = 0;
+
+-void
+-exit_error(enum exittype status, char *msg, ...)
++#ifndef IPTABLES_MULTI
++int line = 0;
++void exit_error(enum exittype status, char *msg, ...)
+ {
+ va_list args;
+
+@@ -41,6 +41,7 @@
+ /* On error paths, make sure that we don't leak memory */
+ exit(status);
+ }
++#endif
+
+ static void print_usage(const char *name, const char *version)
+ __attribute__ ((noreturn));
+@@ -66,7 +67,7 @@
+ exit(1);
+ }
+
+-int
++static int
+ parse_counters(char *string, struct ipt_counters *ctr)
+ {
+ if (string != NULL)
+@@ -605,7 +606,7 @@
+
+ #ifdef IPTABLES_MULTI
+ int
+-iptables_restore_main(int argc, char *argv[])
++iptables_xml_main(int argc, char *argv[])
+ #else
+ int
+ main(int argc, char *argv[])
+diff -x .svn -Nur iptables-1.3.7/Makefile iptables-svn/Makefile
+--- iptables-1.3.7/Makefile 2006-12-04 12:16:01.000000000 +0100
++++ iptables-svn/Makefile 2007-05-31 12:46:31.000000000 +0200
+@@ -79,7 +79,7 @@
+ # Generic test if arch wasn't found above
+ ifneq ($(POINTERTEST),1)
+ # Try to determine if kernel is 64bit and we are compiling for 32bit
+- ifeq ($(shell [ -a $(KERNEL_DIR)/include/asm ] && echo YES), YES)
++ ifeq ($(shell [ -d $(KERNEL_DIR)/include/asm ] && echo YES), YES)
+ 64bitkernel := $(shell echo -e "\#include <asm/types.h>\n\#if BITS_PER_LONG == 64\nkernel_is_64bits\n\#endif" | $(CC) $(CFLAGS) -D__KERNEL__ -E - | grep kernel_is_64bits)
+ ifdef 64bitkernel
+ 32bituser := $(shell echo -e "\#include <stdio.h>\n\#if !defined(__arch64__) && !defined(_LP64)\nuserspace_is_32bit\n\#endif" | $(CC) $(CFLAGS) -E - | grep userspace_is_32bit)
+@@ -103,7 +103,7 @@
+ STATIC_LIBS =
+ STATIC6_LIBS =
+ LDFLAGS = -rdynamic
+-LDLIBS = -ldl -lnsl
++LDLIBS = -ldl
+ ifeq ($(DO_SELINUX), 1)
+ LDLIBS += -lselinux
+ endif
+@@ -170,7 +170,7 @@
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
+
+ ifeq ($(DO_MULTI), 1)
+-$(DESTDIR)$(BINDIR)/iptables-xml: iptables-xml
++$(DESTDIR)$(BINDIR)/iptables-xml: iptables
+ @[ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR)
+ ln -sf $< $@
+ else
+@@ -249,7 +249,7 @@
+ # -g -pg -DIPTC_DEBUG
+ .PHONY: check
+ check:
+- @if echo $(CFLAGS) | egrep -e '-g|-pg|IPTC_DEBUG' >/dev/null; then echo Remove debugging flags; exit 1; else exit 0; fi
++ @if echo $(CFLAGS) | egrep -e '(^|[[:space:]])(-g|-pg|-DIPTC_DEBUG)([[:space:]]|$)' >/dev/null; then echo Remove debugging flags; exit 1; else exit 0; fi
+
+ .PHONY: nowhitespace
+ nowhitespace:
diff --git a/package/iptables/patches/110-2.6.22_compatibility.patch b/package/iptables/patches/110-2.6.22_compatibility.patch
new file mode 100644
index 0000000..572d365
--- /dev/null
+++ b/package/iptables/patches/110-2.6.22_compatibility.patch
@@ -0,0 +1,12 @@
+diff -Nur iptables-svn/extensions/libipt_conntrack.c iptables-22/extensions/libipt_conntrack.c
+--- iptables-svn/extensions/libipt_conntrack.c 2007-05-31 12:46:30.000000000 +0200
++++ iptables-22/extensions/libipt_conntrack.c 2007-05-31 13:06:09.000000000 +0200
+@@ -10,7 +10,7 @@
+ #include <ctype.h>
+ #include <iptables.h>
+ #include <linux/netfilter/nf_conntrack_common.h>
+-#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
++#include <linux/netfilter/nf_conntrack_tuple_common.h>
+ /* For 64bit kernel / 32bit userspace */
+ #include "../include/linux/netfilter_ipv4/ipt_conntrack.h"
+