[PATCH] Iptables addrtype match limited to incoming interface

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Userspace part of the addrtype extension that limits source and
destination address type check to the incoming interface.

Signed-off-by: Laszlo Attila Toth <panther@xxxxxxxxxx>

Index: include/linux/netfilter_ipv4/ipt_addrtype.h
===================================================================
--- include/linux/netfilter_ipv4/ipt_addrtype.h	(revision 7065)
+++ include/linux/netfilter_ipv4/ipt_addrtype.h	(working copy)
@@ -1,9 +1,24 @@
 #ifndef _IPT_ADDRTYPE_H
 #define _IPT_ADDRTYPE_H
 
+#define IPT_ADDRTYPE_REVISION        0x0001
+
+enum
+{
+	IPT_ADDRTYPE_INVERT_SOURCE = 0x0001,
+	IPT_ADDRTYPE_INVERT_DEST   = 0x0002,
+	IPT_ADDRTYPE_LIMIT_IFACE   = 0x0004,
+};
+
 struct ipt_addrtype_info {
 	u_int16_t	source;		/* source-type mask */
 	u_int16_t	dest;		/* dest-type mask */
+	u_int32_t       flags;
+};
+
+struct ipt_addrtype_info_v0 {
+	u_int16_t	source;		/* source-type mask */
+	u_int16_t	dest;		/* dest-type mask */
 	u_int32_t	invert_source;
 	u_int32_t	invert_dest;
 };
Index: extensions/libipt_addrtype.c
===================================================================
--- extensions/libipt_addrtype.c	(revision 7065)
+++ extensions/libipt_addrtype.c	(working copy)
@@ -28,6 +28,10 @@
 	NULL
 };
 
+#ifndef IPT_ADDRTYPE_REVISION
+# define ipt_addrtype_info_v0 ipt_addrtype_info
+#endif /* IPT_ADDRTYPE_REVISION */
+ 
 static void addrtype_help_types(void)
 {
 	int i;
@@ -36,20 +40,36 @@
 		printf("                                %s\n", rtn_names[i]);
 }
 
+#ifdef IPT_ADDRTYPE_REVISION 
 static void addrtype_help(void)
 {
 	printf(
 "Address type match v%s options:\n"
 " [!] --src-type type[,...]      Match source address type\n"
 " [!] --dst-type type[,...]      Match destination address type\n"
+"     --limit-iface              Match on the incoming interface only\n"
 "\n"
 "Valid types:           \n"
 , IPTABLES_VERSION);
 	addrtype_help_types();
 }
 
+#endif /* IPT_ADDTYPE_REVISION */
+
+static void addrtype_help_v0(void)
+{
+	printf(
+"Address type match v%s options:\n"
+" [!] --src-type type[,...]      Match source address type\n"
+" [!] --dst-type type[,...]      Match destination address type\n"
+"\n"
+"Valid types:           \n"
+, IPTABLES_VERSION);
+	addrtype_help_types();
+}
+
 static int
-parse_type(const char *name, size_t strlen, u_int16_t *mask)
+addrtype_parse_type(const char *name, size_t strlen, u_int16_t *mask)
 {
 	int i;
 
@@ -63,24 +83,26 @@
 	return 0;
 }
 
-static void parse_types(const char *arg, u_int16_t *mask)
+static void addrtype_parse_types(const char *arg, u_int16_t *mask)
 {
 	const char *comma;
 
 	while ((comma = strchr(arg, ',')) != NULL) {
-		if (comma == arg || !parse_type(arg, comma-arg, mask))
+		if (comma == arg || !addrtype_parse_type(arg, comma-arg, mask))
 			exit_error(PARAMETER_PROBLEM,
 			           "addrtype: bad type `%s'", arg);
 		arg = comma + 1;
 	}
 
-	if (strlen(arg) == 0 || !parse_type(arg, strlen(arg), mask))
+	if (strlen(arg) == 0 || !addrtype_parse_type(arg, strlen(arg), mask))
 		exit_error(PARAMETER_PROBLEM, "addrtype: bad type `%s'", arg);
 }
 	
 #define IPT_ADDRTYPE_OPT_SRCTYPE	0x1
 #define IPT_ADDRTYPE_OPT_DSTTYPE	0x2
+#define IPT_ADDRTYPE_OPT_LIMIT_IFACE     0x4
 
+#ifdef IPT_ADDRTYPE_REVISION
 static int
 addrtype_parse(int c, char **argv, int invert, unsigned int *flags,
                const void *entry, struct xt_entry_match **match)
@@ -90,21 +112,64 @@
 
 	switch (c) {
 	case '1':
-		if (*flags&IPT_ADDRTYPE_OPT_SRCTYPE)
+		if (*flags & IPT_ADDRTYPE_OPT_SRCTYPE)
 			exit_error(PARAMETER_PROBLEM,
 			           "addrtype: can't specify src-type twice");
 		check_inverse(optarg, &invert, &optind, 0);
-		parse_types(argv[optind-1], &info->source);
+		addrtype_parse_types(argv[optind-1], &info->source);
 		if (invert)
+			info->flags |= IPT_ADDRTYPE_INVERT_SOURCE;
+		*flags |= IPT_ADDRTYPE_OPT_SRCTYPE;
+		break;
+	case '2':
+		if (*flags & IPT_ADDRTYPE_OPT_DSTTYPE)
+			exit_error(PARAMETER_PROBLEM,
+			           "addrtype: can't specify dst-type twice");
+		check_inverse(optarg, &invert, &optind, 0);
+		addrtype_parse_types(argv[optind-1], &info->dest);
+		if (invert)
+			info->flags |= IPT_ADDRTYPE_INVERT_DEST;
+		*flags |= IPT_ADDRTYPE_OPT_DSTTYPE;
+		break;
+	case '3':
+		if (*flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE)
+			exit_error(PARAMETER_PROBLEM,
+			           "addrtype: can't specify limit-iface twice");
+		info->flags |= IPT_ADDRTYPE_LIMIT_IFACE;
+		*flags |= IPT_ADDRTYPE_OPT_LIMIT_IFACE;
+		break;
+	default:
+		return 0;
+	}
+	
+	return 1;
+}
+#endif
+
+static int
+addrtype_parse_v0(int c, char **argv, int invert, unsigned int *flags,
+               const void *entry, struct xt_entry_match **match)
+{
+	struct ipt_addrtype_info_v0 *info =
+		(struct ipt_addrtype_info_v0 *) (*match)->data;
+
+	switch (c) {
+	case '1':
+		if (*flags & IPT_ADDRTYPE_OPT_SRCTYPE)
+			exit_error(PARAMETER_PROBLEM,
+			           "addrtype: can't specify src-type twice");
+		check_inverse(optarg, &invert, &optind, 0);
+		addrtype_parse_types(argv[optind-1], &info->source);
+		if (invert)
 			info->invert_source = 1;
 		*flags |= IPT_ADDRTYPE_OPT_SRCTYPE;
 		break;
 	case '2':
-		if (*flags&IPT_ADDRTYPE_OPT_DSTTYPE)
+		if (*flags & IPT_ADDRTYPE_OPT_DSTTYPE)
 			exit_error(PARAMETER_PROBLEM,
 			           "addrtype: can't specify dst-type twice");
 		check_inverse(optarg, &invert, &optind, 0);
-		parse_types(argv[optind-1], &info->dest);
+		addrtype_parse_types(argv[optind-1], &info->dest);
 		if (invert)
 			info->invert_dest = 1;
 		*flags |= IPT_ADDRTYPE_OPT_DSTTYPE;
@@ -116,14 +181,23 @@
 	return 1;
 }
 
+#ifdef IPT_ADDRTYPE_REVISION
 static void addrtype_check(unsigned int flags)
 {
 	if (!(flags & (IPT_ADDRTYPE_OPT_SRCTYPE|IPT_ADDRTYPE_OPT_DSTTYPE)))
 		exit_error(PARAMETER_PROBLEM,
 			   "addrtype: you must specify --src-type or --dst-type");
 }
+#endif /* IPT_ADDRTYPE_REVISION */
+ 
+static void addrtype_check_v0(unsigned int flags)
+{
+	if (!(flags & (IPT_ADDRTYPE_OPT_SRCTYPE|IPT_ADDRTYPE_OPT_DSTTYPE)))
+		exit_error(PARAMETER_PROBLEM,
+			   "addrtype: you must specify --src-type or --dst-type");
+}
 
-static void print_types(u_int16_t mask)
+static void addrtype_print_types(u_int16_t mask)
 {
 	const char *sep = "";
 	int i;
@@ -137,6 +211,7 @@
 	printf(" ");
 }
 
+#ifdef IPT_ADDRTYPE_REVISION 
 static void addrtype_print(const void *ip, const struct xt_entry_match *match,
                            int numeric)
 {
@@ -146,18 +221,44 @@
 	printf("ADDRTYPE match ");
 	if (info->source) {
 		printf("src-type ");
+		if (info->flags & IPT_ADDRTYPE_INVERT_SOURCE)
+			printf("!");
+		addrtype_print_types(info->source);
+	}
+	if (info->dest) {
+		printf("dst-type ");
+		if (info->flags & IPT_ADDRTYPE_INVERT_DEST)
+			printf("!");
+		addrtype_print_types(info->dest);
+	}
+	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE) {
+		printf("limit-iface ");
+	}
+}
+#endif /* IPT_ADDRTYPE_REVISION */
+
+static void addrtype_print_v0(const void *ip, const struct xt_entry_match *match,
+                           int numeric)
+{
+	const struct ipt_addrtype_info_v0 *info = 
+		(struct ipt_addrtype_info_v0 *) match->data;
+
+	printf("ADDRTYPE match ");
+	if (info->source) {
+		printf("src-type ");
 		if (info->invert_source)
 			printf("!");
-		print_types(info->source);
+		addrtype_print_types(info->source);
 	}
 	if (info->dest) {
 		printf("dst-type ");
 		if (info->invert_dest)
 			printf("!");
-		print_types(info->dest);
+		addrtype_print_types(info->dest);
 	}
 }
 
+#ifdef IPT_ADDRTYPE_REVISION
 static void addrtype_save(const void *ip, const struct xt_entry_match *match)
 {
 	const struct ipt_addrtype_info *info =
@@ -165,27 +266,60 @@
 
 	if (info->source) {
 		printf("--src-type ");
+		if (info->flags & IPT_ADDRTYPE_INVERT_SOURCE)
+			printf("! ");
+		addrtype_print_types(info->source);
+	}
+	if (info->dest) {
+		printf("--dst-type ");
+		if (info->flags & IPT_ADDRTYPE_INVERT_DEST)
+			printf("! ");
+		addrtype_print_types(info->dest);
+	}
+	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE) {
+		printf("--limit-iface ");
+	}
+}
+#endif /* IPT_ADDRTYPE_REVISION */
+
+static void addrtype_save_v0(const void *ip, const struct xt_entry_match *match)
+{
+	const struct ipt_addrtype_info_v0 *info =
+		(struct ipt_addrtype_info_v0 *) match->data;
+
+	if (info->source) {
+		printf("--src-type ");
 		if (info->invert_source)
 			printf("! ");
-		print_types(info->source);
+		addrtype_print_types(info->source);
 	}
 	if (info->dest) {
 		printf("--dst-type ");
 		if (info->invert_dest)
 			printf("! ");
-		print_types(info->dest);
+		addrtype_print_types(info->dest);
 	}
 }
 
+
 static const struct option addrtype_opts[] = {
 	{ "src-type", 1, NULL, '1' },
 	{ "dst-type", 1, NULL, '2' },
+	{ "limit-iface", 0, NULL, '3' },
 	{ }
 };
 
+static const struct option addrtype_opts_v0[] = {
+	{ "src-type", 1, NULL, '1' },
+	{ "dst-type", 1, NULL, '2' },
+	{ }
+};
+
+#ifdef IPT_ADDRTYPE_REVISION
 static struct iptables_match addrtype_match = {
 	.name 		= "addrtype",
 	.version 	= IPTABLES_VERSION,
+	.revision	= 1,
 	.size 		= IPT_ALIGN(sizeof(struct ipt_addrtype_info)),
 	.userspacesize 	= IPT_ALIGN(sizeof(struct ipt_addrtype_info)),
 	.help 		= addrtype_help,
@@ -195,9 +329,27 @@
 	.save 		= addrtype_save,
 	.extra_opts 	= addrtype_opts,
 };
+#endif /* IPT_ADDRTYPE_REVISION */
+ 
+static struct iptables_match addrtype_match_v0 = {
+	.name 		= "addrtype",
+	.version 	= IPTABLES_VERSION,
+	.revision	= 0,
+	.size 		= IPT_ALIGN(sizeof(struct ipt_addrtype_info_v0)),
+	.userspacesize 	= IPT_ALIGN(sizeof(struct ipt_addrtype_info_v0)),
+	.help 		= addrtype_help_v0,
+	.parse 		= addrtype_parse_v0,
+	.final_check 	= addrtype_check_v0,
+	.print 		= addrtype_print_v0,
+	.save 		= addrtype_save_v0,
+	.extra_opts 	= addrtype_opts_v0,
+};
 
 
 void _init(void) 
 {
-	register_match(&addrtype_match);
+#ifdef IPT_ADDRTYPE_REVISION
+ 	register_match(&addrtype_match);
+#endif /* IPT_ADDRTYPE_REVISION */
+ 	register_match(&addrtype_match_v0);
 }
-
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux