[netfilter-cvslog] r6442 - trunk/iptables/extensions

laforge at netfilter.org laforge at netfilter.org
Thu Jan 26 15:43:52 CET 2006


Author: laforge at netfilter.org
Date: 2006-01-26 15:43:52 +0100 (Thu, 26 Jan 2006)
New Revision: 6442

Added:
   trunk/iptables/extensions/libip6t_CONNMARK.c
   trunk/iptables/extensions/libip6t_connmark.c
   trunk/iptables/extensions/libip6t_state.c
Modified:
   trunk/iptables/extensions/Makefile
Log:
Add 'copy+paste' support for 'state' and 'connmark' match, as well as
'CONNMARK' target for ip6tables / nf_conntrack_l3proto_ipv6.  This is a temporary solution for the iptables-1.3.x branch, since the 1.4.x branch will have proper support.


Modified: trunk/iptables/extensions/Makefile
===================================================================
--- trunk/iptables/extensions/Makefile	2006-01-26 14:43:01 UTC (rev 6441)
+++ trunk/iptables/extensions/Makefile	2006-01-26 14:43:52 UTC (rev 6442)
@@ -6,7 +6,7 @@
 # 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 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:=eui64 hl icmpv6 length limit mac mark multiport owner physdev standard tcp udp HL LOG NFQUEUE MARK TRACE
+PF6_EXT_SLIB:=connmark eui64 hl icmpv6 length limit mac mark multiport owner physdev standard state tcp udp CONNMARK HL LOG NFQUEUE MARK TRACE
 
 # Optionals
 PF_EXT_SLIB_OPTS:=$(foreach T,$(wildcard extensions/.*-test),$(shell KERNEL_DIR=$(KERNEL_DIR) $(T)))

Added: trunk/iptables/extensions/libip6t_CONNMARK.c
===================================================================
--- trunk/iptables/extensions/libip6t_CONNMARK.c	2006-01-26 14:43:01 UTC (rev 6441)
+++ trunk/iptables/extensions/libip6t_CONNMARK.c	2006-01-26 14:43:52 UTC (rev 6442)
@@ -0,0 +1,220 @@
+/* Shared library add-on to iptables to add CONNMARK target support.
+ *
+ * (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
+ * by Henrik Nordstrom <hno at marasystems.com>
+ *
+ * Version 1.1
+ *
+ * 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
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include <ip6tables.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include "../include/linux/netfilter_ipv4/ipt_CONNMARK.h"
+
+#if 0
+struct markinfo {
+	struct ipt_entry_target t;
+	struct ipt_connmark_target_info mark;
+};
+#endif
+
+/* Function which prints out usage message. */
+static void
+help(void)
+{
+	printf(
+"CONNMARK target v%s options:\n"
+"  --set-mark value[/mask]       Set conntrack mark value\n"
+"  --save-mark [--mask mask]     Save the packet nfmark in the connection\n"
+"  --restore-mark [--mask mask]  Restore saved nfmark value\n"
+"\n",
+IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+	{ "set-mark", 1, 0, '1' },
+	{ "save-mark", 0, 0, '2' },
+	{ "restore-mark", 0, 0, '3' },
+	{ "mask", 1, 0, '4' },
+	{ 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 ipt_connmark_target_info *markinfo
+		= (struct ipt_connmark_target_info *)(*target)->data;
+
+	markinfo->mask = 0xffffffffUL;
+
+	switch (c) {
+		char *end;
+	case '1':
+		markinfo->mode = IPT_CONNMARK_SET;
+
+		markinfo->mark = strtoul(optarg, &end, 0);
+		if (*end == '/' && end[1] != '\0')
+		    markinfo->mask = strtoul(end+1, &end, 0);
+
+		if (*end != '\0' || end == optarg)
+			exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
+		if (*flags)
+			exit_error(PARAMETER_PROBLEM,
+			           "CONNMARK target: Can't specify --set-mark twice");
+		*flags = 1;
+		break;
+	case '2':
+		markinfo->mode = IPT_CONNMARK_SAVE;
+		if (*flags)
+			exit_error(PARAMETER_PROBLEM,
+			           "CONNMARK target: Can't specify --save-mark twice");
+		*flags = 1;
+		break;
+	case '3':
+		markinfo->mode = IPT_CONNMARK_RESTORE;
+		if (*flags)
+			exit_error(PARAMETER_PROBLEM,
+			           "CONNMARK target: Can't specify --restore-mark twice");
+		*flags = 1;
+		break;
+	case '4':
+		if (!*flags)
+			exit_error(PARAMETER_PROBLEM,
+			           "CONNMARK target: Can't specify --mask without a operation");
+		markinfo->mask = strtoul(optarg, &end, 0);
+
+		if (*end != '\0' || end == optarg)
+			exit_error(PARAMETER_PROBLEM, "Bad MASK value `%s'", optarg);
+		break;
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+
+static void
+final_check(unsigned int flags)
+{
+	if (!flags)
+		exit_error(PARAMETER_PROBLEM,
+		           "CONNMARK target: No operation specified");
+}
+
+static void
+print_mark(unsigned long mark)
+{
+	printf("0x%lx", mark);
+}
+
+static void
+print_mask(const char *text, unsigned long mask)
+{
+	if (mask != 0xffffffffUL)
+		printf("%s0x%lx", text, mask);
+}
+
+
+/* Prints out the target info. */
+static void
+print(const struct ip6t_ip6 *ip,
+      const struct ip6t_entry_target *target,
+      int numeric)
+{
+	const struct ipt_connmark_target_info *markinfo =
+		(const struct ipt_connmark_target_info *)target->data;
+	switch (markinfo->mode) {
+	case IPT_CONNMARK_SET:
+	    printf("CONNMARK set ");
+	    print_mark(markinfo->mark);
+	    print_mask("/", markinfo->mask);
+	    printf(" ");
+	    break;
+	case IPT_CONNMARK_SAVE:
+	    printf("CONNMARK save ");
+	    print_mask("mask ", markinfo->mask);
+	    printf(" ");
+	    break;
+	case IPT_CONNMARK_RESTORE:
+	    printf("CONNMARK restore ");
+	    print_mask("mask ", markinfo->mask);
+	    break;
+	default:
+	    printf("ERROR: UNKNOWN CONNMARK MODE ");
+	    break;
+	}
+}
+
+/* Saves the target into in parsable form to stdout. */
+static void
+save(const struct ip6t_ip6 *ip, const struct ip6t_entry_target *target)
+{
+	const struct ipt_connmark_target_info *markinfo =
+		(const struct ipt_connmark_target_info *)target->data;
+
+	switch (markinfo->mode) {
+	case IPT_CONNMARK_SET:
+	    printf("--set-mark ");
+	    print_mark(markinfo->mark);
+	    print_mask("/", markinfo->mask);
+	    printf(" ");
+	    break;
+	case IPT_CONNMARK_SAVE:
+	    printf("--save-mark ");
+	    print_mask("--mask ", markinfo->mask);
+	    break;
+	case IPT_CONNMARK_RESTORE:
+	    printf("--restore-mark ");
+	    print_mask("--mask ", markinfo->mask);
+	    break;
+	default:
+	    printf("ERROR: UNKNOWN CONNMARK MODE ");
+	    break;
+	}
+}
+
+static struct ip6tables_target connmark_target = {
+    .name          = "CONNMARK",
+    .version       = IPTABLES_VERSION,
+    .size          = IP6T_ALIGN(sizeof(struct ipt_connmark_target_info)),
+    .userspacesize = IP6T_ALIGN(sizeof(struct ipt_connmark_target_info)),
+    .help          = &help,
+    .init          = &init,
+    .parse         = &parse,
+    .final_check   = &final_check,
+    .print         = &print,
+    .save          = &save,
+    .extra_opts    = opts
+};
+
+void _init(void)
+{
+	register_target6(&connmark_target);
+}

Added: trunk/iptables/extensions/libip6t_connmark.c
===================================================================
--- trunk/iptables/extensions/libip6t_connmark.c	2006-01-26 14:43:01 UTC (rev 6441)
+++ trunk/iptables/extensions/libip6t_connmark.c	2006-01-26 14:43:52 UTC (rev 6442)
@@ -0,0 +1,151 @@
+/* Shared library add-on to iptables to add connmark matching support.
+ *
+ * (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
+ * by Henrik Nordstrom <hno at marasystems.com>
+ *
+ * Version 1.1
+ *
+ * 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
+ */
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include <ip6tables.h>
+#include "../include/linux/netfilter_ipv4/ipt_connmark.h"
+
+/* Function which prints out usage message. */
+static void
+help(void)
+{
+	printf(
+"CONNMARK match v%s options:\n"
+"[!] --mark value[/mask]         Match nfmark value with optional mask\n"
+"\n",
+IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+	{ "mark", 1, 0, '1' },
+	{0}
+};
+
+/* Initialize the match. */
+static void
+init(struct ip6t_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 ip6t_entry *entry,
+      unsigned int *nfcache,
+      struct ip6t_entry_match **match)
+{
+	struct ipt_connmark_info *markinfo = (struct ipt_connmark_info *)(*match)->data;
+
+	switch (c) {
+		char *end;
+	case '1':
+		check_inverse(optarg, &invert, &optind, 0);
+
+		markinfo->mark = strtoul(optarg, &end, 0);
+		markinfo->mask = 0xffffffffUL;
+		
+		if (*end == '/')
+			markinfo->mask = strtoul(end+1, &end, 0);
+
+		if (*end != '\0' || end == optarg)
+			exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
+		if (invert)
+			markinfo->invert = 1;
+		*flags = 1;
+		break;
+
+	default:
+		return 0;
+	}
+	return 1;
+}
+
+static void
+print_mark(unsigned long mark, unsigned long mask, int numeric)
+{
+	if(mask != 0xffffffffUL)
+		printf("0x%lx/0x%lx ", mark, mask);
+	else
+		printf("0x%lx ", mark);
+}
+
+/* Final check; must have specified --mark. */
+static void
+final_check(unsigned int flags)
+{
+	if (!flags)
+		exit_error(PARAMETER_PROBLEM,
+			   "MARK match: You must specify `--mark'");
+}
+
+/* Prints out the matchinfo. */
+static void
+print(const struct ip6t_ip6 *ip,
+      const struct ip6t_entry_match *match,
+      int numeric)
+{
+	struct ipt_connmark_info *info = (struct ipt_connmark_info *)match->data;
+
+	printf("CONNMARK match ");
+	if (info->invert)
+		printf("!");
+	print_mark(info->mark, info->mask, numeric);
+}
+
+/* Saves the matchinfo in parsable form to stdout. */
+static void
+save(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match)
+{
+	struct ipt_connmark_info *info = (struct ipt_connmark_info *)match->data;
+
+	if (info->invert)
+		printf("! ");
+
+	printf("--mark ");
+	print_mark(info->mark, info->mask, 0);
+}
+
+static struct ip6tables_match connmark_match = {
+    .name          = "connmark",
+    .version       = IPTABLES_VERSION,
+    .size          = IP6T_ALIGN(sizeof(struct ipt_connmark_info)),
+    .userspacesize = IP6T_ALIGN(sizeof(struct ipt_connmark_info)),
+    .help          = &help,
+    .init          = &init,
+    .parse         = &parse,
+    .final_check   = &final_check,
+    .print         = &print,
+    .save          = &save,
+    .extra_opts    = opts
+};
+
+void _init(void)
+{
+	register_match6(&connmark_match);
+}

Added: trunk/iptables/extensions/libip6t_state.c
===================================================================
--- trunk/iptables/extensions/libip6t_state.c	2006-01-26 14:43:01 UTC (rev 6441)
+++ trunk/iptables/extensions/libip6t_state.c	2006-01-26 14:43:52 UTC (rev 6442)
@@ -0,0 +1,163 @@
+/* Ugly hack to make state matching for ipv6 work before iptables-1.4.x is finished */
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <ip6tables.h>
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <linux/netfilter_ipv4/ipt_state.h>
+
+#ifndef IPT_STATE_UNTRACKED
+#define IPT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1))
+#endif
+
+/* Function which prints out usage message. */
+static void
+help(void)
+{
+	printf(
+"state v%s options:\n"
+" [!] --state [INVALID|ESTABLISHED|NEW|RELATED|UNTRACKED][,...]\n"
+"				State(s) to match\n"
+"\n", IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+	{ "state", 1, 0, '1' },
+	{0}
+};
+
+static int
+parse_state(const char *state, size_t strlen, struct ipt_state_info *sinfo)
+{
+	if (strncasecmp(state, "INVALID", strlen) == 0)
+		sinfo->statemask |= IPT_STATE_INVALID;
+	else if (strncasecmp(state, "NEW", strlen) == 0)
+		sinfo->statemask |= IPT_STATE_BIT(IP_CT_NEW);
+	else if (strncasecmp(state, "ESTABLISHED", strlen) == 0)
+		sinfo->statemask |= IPT_STATE_BIT(IP_CT_ESTABLISHED);
+	else if (strncasecmp(state, "RELATED", strlen) == 0)
+		sinfo->statemask |= IPT_STATE_BIT(IP_CT_RELATED);
+	else if (strncasecmp(state, "UNTRACKED", strlen) == 0)
+		sinfo->statemask |= IPT_STATE_UNTRACKED;
+	else
+		return 0;
+	return 1;
+}
+
+static void
+parse_states(const char *arg, struct ipt_state_info *sinfo)
+{
+	const char *comma;
+
+	while ((comma = strchr(arg, ',')) != NULL) {
+		if (comma == arg || !parse_state(arg, comma-arg, sinfo))
+			exit_error(PARAMETER_PROBLEM, "Bad state `%s'", arg);
+		arg = comma+1;
+	}
+
+	if (strlen(arg) == 0 || !parse_state(arg, strlen(arg), sinfo))
+		exit_error(PARAMETER_PROBLEM, "Bad state `%s'", arg);
+}
+
+/* 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 ipt_state_info *sinfo = (struct ipt_state_info *)(*match)->data;
+
+	switch (c) {
+	case '1':
+		check_inverse(optarg, &invert, &optind, 0);
+
+		parse_states(argv[optind-1], sinfo);
+		if (invert)
+			sinfo->statemask = ~sinfo->statemask;
+		*flags = 1;
+		break;
+
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+
+/* Final check; must have specified --state. */
+static void final_check(unsigned int flags)
+{
+	if (!flags)
+		exit_error(PARAMETER_PROBLEM, "You must specify `--state'");
+}
+
+static void print_state(unsigned int statemask)
+{
+	const char *sep = "";
+
+	if (statemask & IPT_STATE_INVALID) {
+		printf("%sINVALID", sep);
+		sep = ",";
+	}
+	if (statemask & IPT_STATE_BIT(IP_CT_NEW)) {
+		printf("%sNEW", sep);
+		sep = ",";
+	}
+	if (statemask & IPT_STATE_BIT(IP_CT_RELATED)) {
+		printf("%sRELATED", sep);
+		sep = ",";
+	}
+	if (statemask & IPT_STATE_BIT(IP_CT_ESTABLISHED)) {
+		printf("%sESTABLISHED", sep);
+		sep = ",";
+	}
+	if (statemask & IPT_STATE_UNTRACKED) {
+		printf("%sUNTRACKED", sep);
+		sep = ",";
+	}
+	printf(" ");
+}
+
+/* Prints out the matchinfo. */
+static void
+print(const struct ip6t_ip6 *ip,
+      const struct ip6t_entry_match *match,
+      int numeric)
+{
+	struct ipt_state_info *sinfo = (struct ipt_state_info *)match->data;
+
+	printf("state ");
+	print_state(sinfo->statemask);
+}
+
+/* Saves the matchinfo in parsable form to stdout. */
+static void save(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match)
+{
+	struct ipt_state_info *sinfo = (struct ipt_state_info *)match->data;
+
+	printf("--state ");
+	print_state(sinfo->statemask);
+}
+
+static struct ip6tables_match state = { 
+	.next		= NULL,
+	.name		= "state",
+	.version	= IPTABLES_VERSION,
+	.size		= IP6T_ALIGN(sizeof(struct ipt_state_info)),
+	.userspacesize	= IP6T_ALIGN(sizeof(struct ipt_state_info)),
+	.help		= &help,
+	.parse		= &parse,
+	.final_check	= &final_check,
+	.print		= &print,
+	.save		= &save,
+	.extra_opts	= opts
+};
+
+void _init(void)
+{
+	register_match6(&state);
+}




More information about the netfilter-cvslog mailing list