[netfilter-cvslog] r3562 - in trunk/iptables: extensions include/linux/netfilter_ipv4

rusty at netfilter.org rusty at netfilter.org
Mon Jan 3 10:37:08 CET 2005


Author: rusty at netfilter.org
Date: 2005-01-03 10:37:07 +0100 (Mon, 03 Jan 2005)
New Revision: 3562

Added:
   trunk/iptables/include/linux/netfilter_ipv4/ipt_multiport.h
Modified:
   trunk/iptables/extensions/libipt_multiport.c
Log:
Pablo Neira:
	Multiport revision 1 userspace support.



Modified: trunk/iptables/extensions/libipt_multiport.c
===================================================================
--- trunk/iptables/extensions/libipt_multiport.c	2005-01-03 08:55:40 UTC (rev 3561)
+++ trunk/iptables/extensions/libipt_multiport.c	2005-01-03 09:37:07 UTC (rev 3562)
@@ -5,7 +5,8 @@
 #include <stdlib.h>
 #include <getopt.h>
 #include <iptables.h>
-#include <linux/netfilter_ipv4/ipt_multiport.h>
+/* To ensure that iptables compiles with an old kernel */
+#include "../include/linux/netfilter_ipv4/ipt_multiport.h"
 
 /* Function which prints out usage message. */
 static void
@@ -20,6 +21,23 @@
 " --dports ...\n"
 "				match destination port(s)\n"
 " --ports port[,port,port]\n"
+"				match both source and destination port(s)\n"
+" NOTE: this kernel does not support port ranges in multiport.\n",
+IPTABLES_VERSION);
+}
+
+static void
+help_v1(void)
+{
+	printf(
+"multiport 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);
 }
@@ -77,6 +95,46 @@
 	return i;
 }
 
+static void
+parse_multi_ports_v1(const char *portstring, 
+		     struct ipt_multiport_v1 *multiinfo,
+		     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");
+
+	for (i=0; i<IPT_MULTI_PORTS; i++)
+		multiinfo->pflags[i] = 0;
+ 
+	for (cp=buffer, i=0; cp && i<IPT_MULTI_PORTS; cp=next, i++) {
+		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';
+		}
+		multiinfo->ports[i] = parse_port(cp, proto);
+		if (range) {
+			multiinfo->pflags[i] = 1;
+			multiinfo->ports[++i] = parse_port(range, proto);
+			if (multiinfo->ports[i-1] >= multiinfo->ports[i])
+				exit_error(PARAMETER_PROBLEM,
+					   "invalid portrange specified");
+			m <<= 1;
+		}
+ 	}
+	multiinfo->count = i;
+ 	if (cp) exit_error(PARAMETER_PROBLEM, "too many ports specified");
+ 	free(buffer);
+}
+
 /* Initialize the match. */
 static void
 init(struct ipt_entry_match *m, unsigned int *nfcache)
@@ -153,6 +211,56 @@
 	return 1;
 }
 
+static int
+parse_v1(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_multiport_v1 *multiinfo
+		= (struct ipt_multiport_v1 *)(*match)->data;
+
+	switch (c) {
+	case '1':
+		check_inverse(argv[optind-1], &invert, &optind, 0);
+		proto = check_proto(entry);
+		parse_multi_ports_v1(argv[optind-1], multiinfo, proto);
+		multiinfo->flags = IPT_MULTIPORT_SOURCE;
+		*nfcache |= NFC_IP_SRC_PT;
+		break;
+
+	case '2':
+		check_inverse(argv[optind-1], &invert, &optind, 0);
+		proto = check_proto(entry);
+		parse_multi_ports_v1(argv[optind-1], multiinfo, proto);
+		multiinfo->flags = IPT_MULTIPORT_DESTINATION;
+		*nfcache |= NFC_IP_DST_PT;
+		break;
+
+	case '3':
+		check_inverse(argv[optind-1], &invert, &optind, 0);
+		proto = check_proto(entry);
+		parse_multi_ports_v1(argv[optind-1], multiinfo, proto);
+		multiinfo->flags = IPT_MULTIPORT_EITHER;
+		*nfcache |= NFC_IP_SRC_PT | NFC_IP_DST_PT;
+		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)
@@ -221,6 +329,46 @@
 	printf(" ");
 }
 
+static void
+print_v1(const struct ipt_ip *ip,
+	 const struct ipt_entry_match *match,
+	 int numeric)
+{
+	const struct ipt_multiport_v1 *multiinfo
+		= (const struct ipt_multiport_v1 *)match->data;
+	unsigned int i;
+
+	printf("multiport ");
+
+	switch (multiinfo->flags) {
+	case IPT_MULTIPORT_SOURCE:
+		printf("sports ");
+		break;
+
+	case IPT_MULTIPORT_DESTINATION:
+		printf("dports ");
+		break;
+
+	case IPT_MULTIPORT_EITHER:
+		printf("ports ");
+		break;
+
+	default:
+		printf("ERROR ");
+		break;
+	}
+
+	for (i=0; i < multiinfo->count; i++) {
+		printf("%s", i ? "," : "");
+		print_port(multiinfo->ports[i], ip->proto, numeric);
+		if (multiinfo->pflags[i]) {
+			printf(":");
+			print_port(multiinfo->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)
 {
@@ -249,9 +397,42 @@
 	printf(" ");
 }
 
+static void save_v1(const struct ipt_ip *ip, 
+		    const struct ipt_entry_match *match)
+{
+	const struct ipt_multiport_v1 *multiinfo
+		= (const struct ipt_multiport_v1 *)match->data;
+	unsigned int i;
+
+	switch (multiinfo->flags) {
+	case IPT_MULTIPORT_SOURCE:
+		printf("--sports ");
+		break;
+
+	case IPT_MULTIPORT_DESTINATION:
+		printf("--dports ");
+		break;
+
+	case IPT_MULTIPORT_EITHER:
+		printf("--ports ");
+		break;
+	}
+
+	for (i=0; i < multiinfo->count; i++) {
+		printf("%s", i ? "," : "");
+		print_port(multiinfo->ports[i], ip->proto, 1);
+		if (multiinfo->pflags[i]) {
+			printf(":");
+			print_port(multiinfo->ports[++i], ip->proto, 1);
+		}
+	}
+	printf(" ");
+}
+
 static struct iptables_match multiport = { 
 	.next		= NULL,
 	.name		= "multiport",
+	.revision	= 0,
 	.version	= IPTABLES_VERSION,
 	.size		= IPT_ALIGN(sizeof(struct ipt_multiport)),
 	.userspacesize	= IPT_ALIGN(sizeof(struct ipt_multiport)),
@@ -264,8 +445,25 @@
 	.extra_opts	= opts
 };
 
+static struct iptables_match multiport_v1 = { 
+	.next		= NULL,
+	.name		= "multiport",
+	.version	= IPTABLES_VERSION,
+	.revision	= 1,
+	.size		= IPT_ALIGN(sizeof(struct ipt_multiport_v1)),
+	.userspacesize	= IPT_ALIGN(sizeof(struct ipt_multiport_v1)),
+	.help		= &help_v1,
+	.init		= &init,
+	.parse		= &parse_v1,
+	.final_check	= &final_check,
+	.print		= &print_v1,
+	.save		= &save_v1,
+	.extra_opts	= opts
+};
+
 void
 _init(void)
 {
 	register_match(&multiport);
+	register_match(&multiport_v1);
 }

Added: trunk/iptables/include/linux/netfilter_ipv4/ipt_multiport.h
===================================================================
--- trunk/iptables/include/linux/netfilter_ipv4/ipt_multiport.h	2005-01-03 08:55:40 UTC (rev 3561)
+++ trunk/iptables/include/linux/netfilter_ipv4/ipt_multiport.h	2005-01-03 09:37:07 UTC (rev 3562)
@@ -0,0 +1,28 @@
+#ifndef _IPT_MULTIPORT_H
+#define _IPT_MULTIPORT_H
+
+enum ipt_multiport_flags
+{
+	IPT_MULTIPORT_SOURCE,
+	IPT_MULTIPORT_DESTINATION,
+	IPT_MULTIPORT_EITHER
+};
+
+#define IPT_MULTI_PORTS	15
+
+/* Must fit inside union ipt_matchinfo: 16 bytes */
+struct ipt_multiport
+{
+	u_int8_t flags;				/* Type of comparison */
+	u_int8_t count;				/* Number of ports */
+	u_int16_t ports[IPT_MULTI_PORTS];	/* Ports */
+};
+
+struct ipt_multiport_v1
+{
+	u_int8_t flags;				/* Type of comparison */
+	u_int8_t count;				/* Number of ports */
+	u_int16_t ports[IPT_MULTI_PORTS];	/* Ports */
+	u_int8_t pflags[IPT_MULTI_PORTS];	/* Port flags */
+};
+#endif /*_IPT_MULTIPORT_H*/




More information about the netfilter-cvslog mailing list