diff -u --new-file --recursive iptables-1.2.7-20020511_vanilla/extensions/Makefile iptables-1.2.7-20020511_special/extensions/Makefile
--- iptables-1.2.7-20020511_vanilla/extensions/Makefile	Tue Mar 19 18:16:49 2002
+++ iptables-1.2.7-20020511_special/extensions/Makefile	Sun May 12 02:42:40 2002
@@ -16,6 +16,10 @@
 OPTIONALS+=$(patsubst %,IPv4:%,$(PF_EXT_SLIB_OPTS))
 OPTIONALS+=$(patsubst %,IPv6:%,$(PF6_EXT_SLIB_OPTS))
 
+
+PF_EXT_SLIB+= SMASQ RMARK
+
+
 ifndef NO_SHARED_LIBS
 SHARED_LIBS+=$(foreach T,$(PF_EXT_SLIB),extensions/libipt_$(T).so)
 EXTRA_INSTALLS+=$(foreach T, $(PF_EXT_SLIB), $(DESTDIR)$(LIBDIR)/iptables/libipt_$(T).so)
diff -u --new-file --recursive iptables-1.2.7-20020511_vanilla/extensions/libipt_RMARK.c iptables-1.2.7-20020511_special/extensions/libipt_RMARK.c
--- iptables-1.2.7-20020511_vanilla/extensions/libipt_RMARK.c	Thu Jan  1 02:00:00 1970
+++ iptables-1.2.7-20020511_special/extensions/libipt_RMARK.c	Sun May 12 02:38:38 2002
@@ -0,0 +1,101 @@
+/* Shared library add-on to iptables to add MARK target support. */
+#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_RMARK.h>
+
+struct markinfo {
+	struct ipt_entry_target t;
+	struct ipt_rmark_target_info mark;
+};
+
+/* Function which prints out usage message. */
+static void help(void)
+{
+	printf(	"RMARK target v%s options:\n"
+			"  --table-id value                   Internal table id used for round robin balancing\n"
+			"  --limit value                      Maximum mark value (without offset)\n"
+			"  --offset value                     Number to which the limit is offset by to get the mark value\n"
+			"\n",
+			NETFILTER_VERSION
+	);
+}
+
+static struct option opts[] = {
+	{ "table-id", 1, 0, '1' },
+	{ "limit", 1, 0, '2' },
+	{ "offset", 1, 0, '3' },
+	{ 0 }
+};
+
+// Initialize
+static void init(struct ipt_entry_target *t, unsigned int *nfcache)
+{
+}
+
+// Parse our 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_rmark_target_info *markinfo = (struct ipt_rmark_target_info *)(*target)->data;
+
+	switch (c) {
+		case '1':
+			markinfo->table_id = atoi(optarg);
+			if (markinfo->table_id > MAX_RMARK_TABLES)
+				exit_error(PARAMETER_PROBLEM, "table-id is too high, max value is %d", MAX_RMARK_TABLES);
+			break;
+		case '2':
+			markinfo->limit = atoi(optarg);
+			if (markinfo->limit < 1)
+				exit_error(PARAMETER_PROBLEM, "limit must be > 1");
+			break;
+		case '3':
+			markinfo->offset = atoi(optarg);
+			break;
+		default:
+			return 0;
+	}
+	return 1;
+}
+
+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)
+{
+	const struct ipt_rmark_target_info *markinfo = (const struct ipt_rmark_target_info *)target->data;
+	printf("RMARK table_id: %d, limit: %d, offset: %d", markinfo->table_id, markinfo->limit, markinfo->offset);
+}
+
+/* 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_rmark_target_info *markinfo = (const struct ipt_rmark_target_info *)target->data;
+	printf("--table-id %d --limit %d --offset %d ", markinfo->table_id, markinfo->limit, markinfo->offset);
+}
+
+struct iptables_target mark = { 
+	NULL,
+    "RMARK",
+    NETFILTER_VERSION,
+    IPT_ALIGN(sizeof(struct ipt_rmark_target_info)),
+    IPT_ALIGN(sizeof(struct ipt_rmark_target_info)),
+    &help,
+    &init,
+    &parse,
+    &final_check,
+    &print,
+    &save,
+    opts
+};
+
+void _init(void)
+{
+	register_target(&mark);
+}
diff -u --new-file --recursive iptables-1.2.7-20020511_vanilla/extensions/libipt_SMASQ.c iptables-1.2.7-20020511_special/extensions/libipt_SMASQ.c
--- iptables-1.2.7-20020511_vanilla/extensions/libipt_SMASQ.c	Thu Jan  1 02:00:00 1970
+++ iptables-1.2.7-20020511_special/extensions/libipt_SMASQ.c	Sun May 12 02:38:38 2002
@@ -0,0 +1,186 @@
+/* Shared library add-on to iptables to add masquerade 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>
+#include <linux/netfilter_ipv4/ipt_SMASQ.h>
+
+/* Function which prints out usage message. */
+static void
+help(void)
+{
+	printf(
+"SMASQ v%s options:\n"
+" --to-ports <port>[-<port>]\n"
+"				Port (range) to map to.\n"
+" --via-dev <device>\n\n",
+NETFILTER_VERSION);
+}
+
+static struct option opts[] = {
+	{ "to-ports", 1, 0, '1' },
+	{ "via-dev", 1, 0, '2' },
+	{ 0 }
+};
+
+/* Initialize the target. */
+static void
+init(struct ipt_entry_target *t, unsigned int *nfcache)
+{
+	struct ipt_smasq_target_info *smasq_info = (struct ipt_smasq_target_info *)t->data;
+
+	/* Actually, it's 0, but it's ignored at the moment. */
+	smasq_info->multi_range.rangesize = 1;
+
+	/* Can't cache this */
+	*nfcache |= NFC_UNKNOWN;
+}
+
+/* Parses ports */
+static void
+parse_ports(const char *arg, struct ipt_smasq_target_info *smasq_info)
+{
+	const char *dash;
+	int port;
+
+	smasq_info->multi_range.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
+
+	port = atoi(arg);
+	if (port == 0 || port > 65535)
+		exit_error(PARAMETER_PROBLEM, "Port `%s' not valid\n", arg);
+
+	dash = strchr(arg, '-');
+	if (!dash) {
+		smasq_info->multi_range.range[0].min.tcp.port
+			= smasq_info->multi_range.range[0].max.tcp.port
+			= htons(port);
+	} else {
+		int maxport;
+
+		maxport = atoi(dash + 1);
+		if (maxport == 0 || maxport > 65535)
+			exit_error(PARAMETER_PROBLEM,
+				   "Port `%s' not valid\n", dash+1);
+		if (maxport < port)
+			/* People are stupid.  Present reader excepted. */
+			exit_error(PARAMETER_PROBLEM,
+				   "Port range `%s' funky\n", arg);
+		smasq_info->multi_range.range[0].min.tcp.port = htons(port);
+		smasq_info->multi_range.range[0].max.tcp.port = htons(maxport);
+	}
+}
+
+/* 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)
+{
+	int portok;
+	struct ipt_smasq_target_info *smasq_info = (struct ipt_smasq_target_info *)(*target)->data;
+
+	if (entry->ip.proto == IPPROTO_TCP
+	    || entry->ip.proto == IPPROTO_UDP)
+		portok = 1;
+	else
+		portok = 0;
+
+	switch (c) {
+	case '1':
+		if (!portok)
+			exit_error(PARAMETER_PROBLEM,
+				   "Need TCP or UDP with port specification");
+
+		if (check_inverse(optarg, &invert, NULL, 0))
+			exit_error(PARAMETER_PROBLEM,
+				   "Unexpected `!'");
+
+		parse_ports(optarg, smasq_info);
+		break;
+		
+	case '2':
+		if (*flags & IPT_SMASQ_DEVICENAME)
+			exit_error(PARAMETER_PROBLEM, "Can't specify --via-dev twice");	
+										
+		if (strlen(optarg) > sizeof(smasq_info->deviceName) - 1)
+			exit_error(PARAMETER_PROBLEM, "Maximum device length %u for --via-dev", sizeof(smasq_info->deviceName) - 1);
+			
+		strcpy(smasq_info->deviceName,optarg);
+		*flags |= IPT_SMASQ_DEVICENAME;
+		break;
+		
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+
+/* Final check; don't care. */
+static void final_check(unsigned int flags)
+{
+	if (! flags & IPT_SMASQ_DEVICENAME)
+		exit_error(PARAMETER_PROBLEM, "SMASQ: --via-dev is needed!\n");
+}
+
+/* Prints out the targinfo. */
+static void
+print(const struct ipt_ip *ip,
+      const struct ipt_entry_target *target,
+      int numeric)
+{
+	struct ipt_smasq_target_info *smasq_info = (struct ipt_smasq_target_info *)target->data;
+	struct ip_nat_range *r = &smasq_info->multi_range.range[0];
+	
+	printf("smasq via: %s ", smasq_info->deviceName);
+	
+	if (r->flags & IP_NAT_RANGE_PROTO_SPECIFIED) {
+		printf("ports: ");
+		printf("%hu", ntohs(r->min.tcp.port));
+		if (r->max.tcp.port != r->min.tcp.port)
+			printf("-%hu", ntohs(r->max.tcp.port));
+		printf(" ");
+	}
+}
+
+/* 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 ipt_smasq_target_info *smasq_info = (struct ipt_smasq_target_info *)target->data;
+	struct ip_nat_range *r = &smasq_info->multi_range.range[0];
+
+	printf("--via-dev %s ",smasq_info->deviceName);
+	
+	if (r->flags & IP_NAT_RANGE_PROTO_SPECIFIED) {
+		printf("--to-ports %hu", ntohs(r->min.tcp.port));
+		if (r->max.tcp.port != r->min.tcp.port)
+			printf("-%hu", ntohs(r->max.tcp.port));
+		printf(" ");
+	}
+}
+
+struct iptables_target smasq
+= { NULL,
+    "SMASQ",
+    NETFILTER_VERSION,
+    IPT_ALIGN(sizeof(struct ipt_smasq_target_info)),
+    IPT_ALIGN(sizeof(struct ipt_smasq_target_info)),
+    &help,
+    &init,
+    &parse,
+    &final_check,
+    &print,
+    &save,
+    opts
+};
+
+void _init(void)
+{
+	register_target(&smasq);
+}
diff -u --new-file --recursive iptables-1.2.7-20020511_vanilla/extensions/libipt_isdev.c iptables-1.2.7-20020511_special/extensions/libipt_isdev.c
--- iptables-1.2.7-20020511_vanilla/extensions/libipt_isdev.c	Thu Jan  1 02:00:00 1970
+++ iptables-1.2.7-20020511_special/extensions/libipt_isdev.c	Sun May 12 02:38:38 2002
@@ -0,0 +1,102 @@
+/* Shared library add-on to iptables to add NFMARK 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_isdev.h>
+
+/* Function which prints out usage message. */
+static void
+help(void)
+{
+	printf(
+"ISDEV match v%s options:\n"
+"[!] --dev <deviceName>         Match if deviceName exists\n"
+"\n",
+NETFILTER_VERSION);
+}
+
+static struct option opts[] = {
+	{ "dev", 1, 0, '1' },
+	{0}
+};
+
+/* Initialize the match. */
+static void
+init(struct ipt_entry_match *m, unsigned int *nfcache)
+{
+	/* Can't cache this. */
+	*nfcache |= NFC_UNKNOWN;
+}
+
+/* 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_isdev_info *isdevinfo = (struct ipt_isdev_info *)(*match)->data;
+
+	switch (c) {
+	case '1':
+                if (*flags & 1)
+       			exit_error(PARAMETER_PROBLEM, "Can't specify --dev twice");
+		strcpy(isdevinfo->deviceName,optarg);
+		*flags = 1;
+		break;
+
+	default:
+		return 0;
+	}
+	return 1;
+}
+
+/* Final check; must have specified --isdev. */
+static void
+final_check(unsigned int flags)
+{
+	if (!flags)
+		exit_error(PARAMETER_PROBLEM,
+			   "ISDEV match: You must specify `--dev'");
+}
+
+/* Prints out the matchinfo. */
+static void print(const struct ipt_ip *ip, const struct ipt_entry_match *match, int numeric)
+{
+	struct ipt_isdev_info *isdevinfo = (struct ipt_isdev_info *)match->data;
+	printf("ISDEV match device: %s ",isdevinfo->deviceName);
+}
+
+/* Saves the union ipt_matchinfo in parsable form to stdout. */
+static void
+save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+{
+	struct ipt_isdev_info *isdevinfo = (struct ipt_isdev_info *)match->data;
+	printf("--dev %s ",isdevinfo->deviceName);
+}
+
+static
+struct iptables_match isdev
+= { NULL,
+    "isdev",
+    NETFILTER_VERSION,
+    IPT_ALIGN(sizeof(struct ipt_isdev_info)),
+    IPT_ALIGN(sizeof(struct ipt_isdev_info)),
+    &help,
+    &init,
+    &parse,
+    &final_check,
+    &print,
+    &save,
+    opts
+};
+
+void _init(void)
+{
+	register_match(&isdev);
+}
