diff -Nurb iptables-1.3.8/extensions/Makefile iptables-1.3.8.new/extensions/Makefile
--- iptables-1.3.8/extensions/Makefile	2007-03-22 00:04:36.000000000 +0000
+++ iptables-1.3.8.new/extensions/Makefile	2007-09-26 14:37:49.000000000 +0100
@@ -5,7 +5,7 @@
 # header files are present in the include/linux directory of this iptables
 # package (HW)
 #
-PF_EXT_SLIB:=ah addrtype comment 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
+PF_EXT_SLIB:=ah addrtype comment connmark conntrack dscp ecn esp hashlimit helper icmp iprange length limit mac mark mod 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)
diff -Nurb iptables-1.3.8/extensions/libipt_mod.c iptables-1.3.8.new/extensions/libipt_mod.c
--- iptables-1.3.8/extensions/libipt_mod.c	1970-01-01 01:00:00.000000000 +0100
+++ iptables-1.3.8.new/extensions/libipt_mod.c	2007-09-26 17:15:23.000000000 +0100
@@ -0,0 +1,184 @@
+/* Shared library add-on to iptables to add port modulus support. */
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include <iptables.h>
+#include <linux/netfilter_ipv4/ipt_mod.h>
+
+/* Function which prints out usage message. */
+static void
+help(void)
+{
+	printf(
+"mod match v%s options:\n"
+"    --src-mod-port       Match source port\n"
+"    --dst-mod-port       Match destination port\n"
+"    --src-mod-addr       Match source address\n"
+"    --dst-mod-addr       Match destination address\n"
+"    --mod                Sets the modulus (default 2)\n"
+"    --result             Sets the low band result to test against (default 0)\n"
+"    --weight             Sets the weighting (default 1)\n"
+"\n",
+IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+	{ "src-mod-port", 0, 0, '1' },
+	{ "dst-mod-port", 0, 0, '2' },
+	{ "src-mod-addr", 0, 0, '3' },
+	{ "dst-mod-addr", 0, 0, '4' },
+	{ "mod",          1, 0, '5' },
+	{ "result",       1, 0, '6' },
+	{ "weight",       1, 0, '7' },
+	{0}
+};
+
+/* Initialize the match. */
+static void
+init(struct ipt_entry_match *m, unsigned int *nfcache)
+{
+	struct ipt_mod_info *info = (struct ipt_mod_info *)m->data;
+
+	/* Can't cache this. */
+	*nfcache |= NFC_UNKNOWN;
+
+	info->mod = 2;
+	info->result = 0;
+	info->weight = 1;
+}
+
+/* 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_mod_info *info = (struct ipt_mod_info *)(*match)->data;
+
+	switch (c) {
+	case '1':
+		if (*flags & MOD_SRC_PORT)
+			exit_error(PARAMETER_PROBLEM,
+				   "mod match: Only use --src-mod-port ONCE!");
+		info->flags |= MOD_SRC_PORT;
+
+		break;
+
+	case '2':
+		if (*flags & MOD_DST_PORT)
+			exit_error(PARAMETER_PROBLEM,
+				   "mod match: Only use --dst-mod-port ONCE!");
+		info->flags |= MOD_DST_PORT;
+
+		break;
+
+	case '3':
+		if (*flags & MOD_SRC_ADDR)
+			exit_error(PARAMETER_PROBLEM,
+				   "mod match: Only use --src-mod-addr ONCE!");
+		info->flags |= MOD_SRC_ADDR;
+
+		break;
+
+	case '4':
+		if (*flags & MOD_DST_ADDR)
+			exit_error(PARAMETER_PROBLEM,
+				   "mod match: Only use --dst-mod-addr ONCE!");
+		info->flags |= MOD_DST_ADDR;
+
+		break;
+
+	case '5':
+		if (!atol(argv[optind-1]))
+			exit_error(PARAMETER_PROBLEM,
+				   "mod match: modulus cannot be zero!");
+		
+		info->mod = atol(argv[optind-1]);
+		
+		break;
+
+	case '6':
+		info->result = atol(argv[optind-1]);
+		
+		break;
+
+	case '7':
+		info->weight = atol(argv[optind-1]);
+		
+		break;
+
+	default:
+		return 0;
+	}
+	return 1;
+}
+
+/* Final check; we don't care. */
+static void
+final_check(unsigned int flags)
+{
+}
+
+/* Prints out the info. */
+static void
+print(const struct ipt_ip *ip,
+      const struct ipt_entry_match *match,
+      int numeric)
+{
+	struct ipt_mod_info *info = (struct ipt_mod_info *)match->data;
+
+	if (info->flags & MOD_SRC_PORT)
+		printf("src port ");
+	if (info->flags & MOD_DST_PORT)
+		printf("dst port ");
+	if (info->flags & MOD_SRC_ADDR)
+		printf("src addr ");
+	if (info->flags & MOD_DST_ADDR)
+		printf("dst addr ");
+	
+	printf("mod %d res %d weight %d ", info->mod, info->result, info->weight);
+}
+
+/* Saves the union ipt_info in parsable form to stdout. */
+static void
+save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+{
+	struct ipt_mod_info *info = (struct ipt_mod_info *)match->data;
+
+	if (info->flags & MOD_SRC_PORT)
+		printf("--src-mod-port ");
+	if (info->flags & MOD_DST_PORT)
+		printf("--dst-mod-port ");
+	if (info->flags & MOD_SRC_ADDR)
+		printf("--src-mod-addr ");
+	if (info->flags & MOD_DST_ADDR)
+		printf("--dst-mod-addr ");
+	
+	printf("--mod %d --result %d --weight %d", info->mod, info->result, info->weight);
+}
+
+static struct iptables_match mod = { 
+	.init           = &init,
+	.next           = NULL,
+	.name           = "mod",
+	.version        = IPTABLES_VERSION,
+	.size           = IPT_ALIGN(sizeof(struct ipt_mod_info)),
+	.userspacesize  = IPT_ALIGN(sizeof(struct ipt_mod_info)),
+	.help           = &help,
+	.parse          = &parse,
+	.final_check    = &final_check,
+	.print          = &print,
+	.save           = &save,
+	.extra_opts     = opts
+};
+
+void _init(void)
+{
+	register_match(&mod);
+}
+
