- make each element of a variable hold a type trunk
authorchristos <christos@NetBSD.org>
Sun, 26 Feb 2012 21:50:05 +0000
branchtrunk
changeset 209494 356b586f1cb2
parent 209493 23ad268538c1
child 209495 131a155ce250
- make each element of a variable hold a type - change get_type to take an index, so we can get the individual types of each element (since primitive elements can be in lists) - make port_range primitive - add a routine to convert a variable of primitives to a variable containing - only port ranges.
usr.sbin/npf/npfctl/npf_build.c
usr.sbin/npf/npfctl/npf_data.c
usr.sbin/npf/npfctl/npf_parse.y
usr.sbin/npf/npfctl/npf_var.c
usr.sbin/npf/npfctl/npf_var.h
usr.sbin/npf/npfctl/npfctl.h
--- a/usr.sbin/npf/npfctl/npf_build.c	Sun Feb 26 21:14:50 2012 +0000
+++ b/usr.sbin/npf/npfctl/npf_build.c	Sun Feb 26 21:50:05 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_build.c,v 1.5 2012/02/20 00:18:19 rmind Exp $	*/
+/*	$NetBSD: npf_build.c,v 1.6 2012/02/26 21:50:05 christos Exp $	*/
 
 /*-
  * Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_build.c,v 1.5 2012/02/20 00:18:19 rmind Exp $");
+__RCSID("$NetBSD: npf_build.c,v 1.6 2012/02/26 21:50:05 christos Exp $");
 
 #include <sys/types.h>
 #include <sys/ioctl.h>
@@ -161,7 +161,7 @@
 static void
 npfctl_build_vars(nc_ctx_t *nc, sa_family_t family, npfvar_t *vars, int opts)
 {
-	const int type = npfvar_get_type(vars);
+	const int type = npfvar_get_type(vars, 0);
 	size_t i;
 
 	npfctl_ncgen_group(nc);
@@ -335,7 +335,7 @@
 			return;
 		}
 
-		const int type = npfvar_get_type(arg->ma_opts);
+		const int type = npfvar_get_type(arg->ma_opts, 0);
 		if (type != -1 && type != NPFVAR_NUM) {
 			yyerror("option '%s' is not numeric", aval);
 		}
--- a/usr.sbin/npf/npfctl/npf_data.c	Sun Feb 26 21:14:50 2012 +0000
+++ b/usr.sbin/npf/npfctl/npf_data.c	Sun Feb 26 21:50:05 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_data.c,v 1.10 2012/01/08 21:34:21 rmind Exp $	*/
+/*	$NetBSD: npf_data.c,v 1.11 2012/02/26 21:50:05 christos Exp $	*/
 
 /*-
  * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_data.c,v 1.10 2012/01/08 21:34:21 rmind Exp $");
+__RCSID("$NetBSD: npf_data.c,v 1.11 2012/02/26 21:50:05 christos Exp $");
 
 #include <sys/types.h>
 #include <sys/null.h>
@@ -232,6 +232,45 @@
 }
 
 npfvar_t *
+npfctl_parse_port_range_variable(const char *v)
+{
+	npfvar_t *vp = npfvar_lookup(v);
+	in_port_t p;
+	port_range_t *pr;
+	size_t count = npfvar_get_count(vp);
+	npfvar_t *pvp = npfvar_create(".port_range");
+
+	for (size_t i = 0; i < count; i++) {
+		int type = npfvar_get_type(vp, i);
+		void *data = npfvar_get_data(vp, type, i);
+		switch (type) {
+		case NPFVAR_IDENTIFIER:
+		case NPFVAR_STRING:
+			p = npfctl_portno(data);
+			npfvar_add_elements(pvp, npfctl_parse_port_range(p, p));
+			break;
+		case NPFVAR_PORT_RANGE:
+			pr = data;
+			npfvar_add_element(pvp, NPFVAR_PORT_RANGE, pr,
+			    sizeof(*pr));
+			break;
+		case NPFVAR_NUM:
+			p = *(unsigned long *)data;
+			npfvar_add_elements(pvp, npfctl_parse_port_range(p, p));
+			break;
+		default:
+			yyerror("wrong variable '%s' type '%s' for port range",
+			    v, npfvar_type(type));
+			goto out;
+		}
+	}
+	return pvp;
+out:
+	npfvar_destroy(pvp);
+	return NULL;
+}
+
+npfvar_t *
 npfctl_parse_iface(const char *ifname)
 {
 	npfvar_t *vp = npfvar_create(".iface");
--- a/usr.sbin/npf/npfctl/npf_parse.y	Sun Feb 26 21:14:50 2012 +0000
+++ b/usr.sbin/npf/npfctl/npf_parse.y	Sun Feb 26 21:50:05 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_parse.y,v 1.4 2012/02/26 21:14:50 rmind Exp $	*/
+/*	$NetBSD: npf_parse.y,v 1.5 2012/02/26 21:50:05 christos Exp $	*/
 
 /*-
  * Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@@ -213,6 +213,11 @@
 		npfvar_add_element(vp, NPFVAR_STRING, $1, strlen($1) + 1);
 		npfvar_add_elements(cvar, vp);
 	}
+	| NUM MINUS NUM
+	{
+		npfvar_t *vp = npfctl_parse_port_range($1, $3);
+		npfvar_add_elements(cvar, vp);
+	}
 	| NUM
 	{
 		npfvar_t *vp = npfvar_create(".num");
@@ -569,7 +574,7 @@
 	| VAR_ID
 	{
 		npfvar_t *vp = npfvar_lookup($1);
-		const int type = npfvar_get_type(vp);
+		const int type = npfvar_get_type(vp, 0);
 
 		switch (type) {
 		case NPFVAR_VAR_ID:
@@ -606,6 +611,9 @@
 	{
 		$$ = npfctl_parse_port_range($2, $4);
 	}
+	| PORT VAR_ID {
+		$$ = npfctl_parse_port_range_variable($2);
+	}
 	|
 	{
 		$$ = NULL;
@@ -683,7 +691,7 @@
 	| VAR_ID
 	{
 		npfvar_t *vp = npfvar_lookup($1);
-		const int type = npfvar_get_type(vp);
+		const int type = npfvar_get_type(vp, 0);
 
 		switch (type) {
 		case NPFVAR_VAR_ID:
--- a/usr.sbin/npf/npfctl/npf_var.c	Sun Feb 26 21:14:50 2012 +0000
+++ b/usr.sbin/npf/npfctl/npf_var.c	Sun Feb 26 21:50:05 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_var.c,v 1.3 2012/01/15 00:49:48 rmind Exp $	*/
+/*	$NetBSD: npf_var.c,v 1.4 2012/02/26 21:50:05 christos Exp $	*/
 
 /*-
  * Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_var.c,v 1.3 2012/01/15 00:49:48 rmind Exp $");
+__RCSID("$NetBSD: npf_var.c,v 1.4 2012/02/26 21:50:05 christos Exp $");
 
 #include <stdlib.h>
 #include <string.h>
@@ -41,6 +41,7 @@
 
 typedef struct npf_element {
 	void *		e_data;
+	int		e_type;
 	struct npf_element *e_next;
 } npf_element_t;
 
@@ -105,6 +106,7 @@
 	vp->v_count++;
 	el = zalloc(sizeof(*el));
 	el->e_data = zalloc(len);
+	el->e_type = type;
 	memcpy(el->e_data, data, len);
 
 	/* Preserve order of insertion. */
@@ -181,12 +183,6 @@
 	return vp ? vp->v_count : 0;
 }
 
-int
-npfvar_get_type(const npfvar_t *vp)
-{
-	return vp ? vp->v_type : -1;
-}
-
 static void *
 npfvar_get_data1(const npfvar_t *vp, int type, size_t idx, size_t level)
 {
@@ -224,6 +220,43 @@
 	return el->e_data;
 }
 
+static int
+npfvar_get_type1(const npfvar_t *vp, size_t idx, size_t level)
+{
+	npf_element_t *el;
+
+	if (level >= var_num) {
+		yyerror("variable loop for '%s'", vp->v_key);
+		return -1;
+	}
+
+	if (vp == NULL)
+		return -1;
+
+	if (vp->v_count <= idx) {
+		yyerror("variable '%s' has only %zu elements, requested %zu",
+		    vp->v_key, vp->v_count, idx);
+		return -1;
+	}
+
+	el = vp->v_elements;
+	while (idx--) {
+		el = el->e_next;
+	}
+
+	if (vp->v_type == NPFVAR_VAR_ID) {
+		npfvar_t *rvp = npfvar_lookup(el->e_data);
+		return npfvar_get_type1(rvp, 0, level + 1);
+	}
+	return el->e_type;
+}
+
+int
+npfvar_get_type(const npfvar_t *vp, size_t idx)
+{
+	return npfvar_get_type1(vp, idx, 0);
+}
+
 void *
 npfvar_get_data(const npfvar_t *vp, int type, size_t idx)
 {
--- a/usr.sbin/npf/npfctl/npf_var.h	Sun Feb 26 21:14:50 2012 +0000
+++ b/usr.sbin/npf/npfctl/npf_var.h	Sun Feb 26 21:50:05 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_var.h,v 1.1 2012/01/08 21:34:21 rmind Exp $	*/
+/*	$NetBSD: npf_var.h,v 1.2 2012/02/26 21:50:05 christos Exp $	*/
 
 /*-
  * Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@@ -36,14 +36,14 @@
 #define	NPFVAR_IDENTIFIER	1
 #define	NPFVAR_VAR_ID		2
 #define NPFVAR_NUM		3
+#define NPFVAR_PORT_RANGE	4
 
 /* Note: primitive types are equivalent. */
-#define NPFVAR_PRIM		NPFVAR_NUM
-#define NPFVAR_TYPE(x)		(((x) & ~NPFVAR_PRIM) ? (x) : 0)
+#define NPFVAR_PRIM		NPFVAR_PORT_RANGE
+#define NPFVAR_TYPE(x)		(((x) > NPFVAR_PRIM) ? (x) : 0)
 
-#define	NPFVAR_TABLE		4
-#define	NPFVAR_FAM		5
-#define	NPFVAR_PORT_RANGE	6
+#define	NPFVAR_TABLE		5
+#define	NPFVAR_FAM		6
 #define	NPFVAR_TCPFLAG		7
 #define	NPFVAR_ICMP		8
 #define	NPFVAR_PROC_OP		9
@@ -69,7 +69,7 @@
 
 char *		npfvar_expand_string(const npfvar_t *);
 size_t		npfvar_get_count(const npfvar_t *);
-int		npfvar_get_type(const npfvar_t *);
+int		npfvar_get_type(const npfvar_t *, size_t);
 void *		npfvar_get_data(const npfvar_t *, int, size_t);
 
 #endif
--- a/usr.sbin/npf/npfctl/npfctl.h	Sun Feb 26 21:14:50 2012 +0000
+++ b/usr.sbin/npf/npfctl/npfctl.h	Sun Feb 26 21:50:05 2012 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npfctl.h,v 1.11 2012/02/05 00:37:13 rmind Exp $	*/
+/*	$NetBSD: npfctl.h,v 1.12 2012/02/26 21:50:05 christos Exp $	*/
 
 /*-
  * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -103,6 +103,7 @@
 npfvar_t * 	npfctl_parse_icmp(uint8_t, uint8_t);
 npfvar_t *	npfctl_parse_iface(const char *);
 npfvar_t *	npfctl_parse_port_range(in_port_t, in_port_t);
+npfvar_t *	npfctl_parse_port_range_variable(const char *);
 npfvar_t *	npfctl_parse_fam_addr_mask(const char *, const char *,
 		    unsigned long *);
 fam_addr_mask_t *npfctl_parse_cidr(char *);