Module Name:    src
Committed By:   rmind
Date:           Wed May 30 21:30:07 UTC 2012

Modified Files:
        src/usr.sbin/npf/npfctl: Makefile npf.conf.5 npf_data.c
            npf_disassemble.c npf_ncgen.c npf_parse.y npf_scan.l npf_var.c
            npfctl.c npfctl.h

Log Message:
npfctl(8): add show-config command.  Also, update syntax.


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/usr.sbin/npf/npfctl/Makefile \
    src/usr.sbin/npf/npfctl/npf_parse.y
cvs rdiff -u -r1.9 -r1.10 src/usr.sbin/npf/npfctl/npf.conf.5
cvs rdiff -u -r1.11 -r1.12 src/usr.sbin/npf/npfctl/npf_data.c
cvs rdiff -u -r1.3 -r1.4 src/usr.sbin/npf/npfctl/npf_disassemble.c
cvs rdiff -u -r1.8 -r1.9 src/usr.sbin/npf/npfctl/npf_ncgen.c
cvs rdiff -u -r1.1 -r1.2 src/usr.sbin/npf/npfctl/npf_scan.l
cvs rdiff -u -r1.4 -r1.5 src/usr.sbin/npf/npfctl/npf_var.c
cvs rdiff -u -r1.10 -r1.11 src/usr.sbin/npf/npfctl/npfctl.c
cvs rdiff -u -r1.13 -r1.14 src/usr.sbin/npf/npfctl/npfctl.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.sbin/npf/npfctl/Makefile
diff -u src/usr.sbin/npf/npfctl/Makefile:1.6 src/usr.sbin/npf/npfctl/Makefile:1.7
--- src/usr.sbin/npf/npfctl/Makefile:1.6	Sat Mar 10 22:21:50 2012
+++ src/usr.sbin/npf/npfctl/Makefile	Wed May 30 21:30:07 2012
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.6 2012/03/10 22:21:50 christos Exp $
+# $NetBSD: Makefile,v 1.7 2012/05/30 21:30:07 rmind Exp $
 
 PROG=		npfctl
 MAN=		npfctl.8 npf.conf.5
@@ -9,7 +9,6 @@ SRCS=		npfctl.c npf_var.c npf_data.c npf
 CPPFLAGS+=	-I${.CURDIR}
 SRCS+=		npf_scan.l npf_parse.y
 YHEADER=	1
-YFLAGS+=	-v
 
 LDADD+=		-lnpf -lprop -lutil -ly
 DPADD+=		${LIBNPF} ${LIBPROP} ${LIBUTIL}
Index: src/usr.sbin/npf/npfctl/npf_parse.y
diff -u src/usr.sbin/npf/npfctl/npf_parse.y:1.6 src/usr.sbin/npf/npfctl/npf_parse.y:1.7
--- src/usr.sbin/npf/npfctl/npf_parse.y:1.6	Sun Feb 26 22:04:42 2012
+++ src/usr.sbin/npf/npfctl/npf_parse.y	Wed May 30 21:30:07 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_parse.y,v 1.6 2012/02/26 22:04:42 christos Exp $	*/
+/*	$NetBSD: npf_parse.y,v 1.7 2012/05/30 21:30:07 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@@ -95,7 +95,6 @@ yyerror(const char *fmt, ...)
 %token			INET
 %token			INET6
 %token			INTERFACE
-%token			KEEP
 %token			MINUS
 %token			NAT
 %token			NAME
@@ -108,14 +107,14 @@ yyerror(const char *fmt, ...)
 %token			PROCEDURE
 %token			PROTO
 %token			FAMILY
-%token			QUICK
+%token			FINAL
 %token			RDR
 %token			RETURN
 %token			RETURNICMP
 %token			RETURNRST
 %token			SEPLINE
 %token			SLASH
-%token			STATE
+%token			STATEFUL
 %token			TABLE
 %token			TCP
 %token			TO
@@ -135,9 +134,9 @@ yyerror(const char *fmt, ...)
 
 %type	<str>		addr, iface_name, moduleargname, list_elem, table_store
 %type	<str>		opt_apply
-%type	<num>		ifindex, port, opt_quick, on_iface
+%type	<num>		ifindex, port, opt_final, on_iface
 %type	<num>		block_or_pass, rule_dir, block_opts, family, opt_family
-%type	<num>		opt_keep_state, icmp_type, table_type
+%type	<num>		opt_stateful, icmp_type, table_type
 %type	<var>		addr_or_iface, port_range, icmp_type_and_code
 %type	<var>		filt_addr, addr_and_mask, tcp_flags, tcp_flags_and_mask
 %type	<var>		modulearg_opts, procs, proc_op, modulearg, moduleargs
@@ -421,15 +420,15 @@ rules
 	;
 
 rule
-	: block_or_pass rule_dir opt_quick on_iface opt_family
-	  opt_proto all_or_filt_opts opt_keep_state opt_apply
+	: block_or_pass opt_stateful rule_dir opt_final on_iface opt_family
+	  opt_proto all_or_filt_opts opt_apply
 	{
 		/*
 		 * Arguments: attributes, interface index, address
 		 * family, protocol options, filter options.
 		 */
-		npfctl_build_rule($1 | $2 | $3 | $8, $4,
-		    $5, &$6, &$7, $9);
+		npfctl_build_rule($1 | $2 | $3 | $4, $5,
+		    $6, &$7, &$8, $9);
 	}
 	|
 	;
@@ -445,8 +444,8 @@ rule_dir
 	|			{ $$ = NPF_RULE_IN | NPF_RULE_OUT; }
 	;
 
-opt_quick
-	: QUICK			{ $$ = NPF_RULE_FINAL; }
+opt_final
+	: FINAL			{ $$ = NPF_RULE_FINAL; }
 	|			{ $$ = 0; }
 	;
 
@@ -499,8 +498,8 @@ all_or_filt_opts
 	| filt_opts	{ $$ = $1; }
 	;
 
-opt_keep_state
-	: KEEP STATE	{ $$ = NPF_RULE_KEEPSTATE; }
+opt_stateful
+	: STATEFUL	{ $$ = NPF_RULE_KEEPSTATE; }
 	|		{ $$ = 0; }
 	;
 
@@ -621,7 +620,7 @@ port_range
 	;
 
 port
-	: NUM		{ $$ = htons($1); }
+	: NUM		{ $$ = $1; }
 	| IDENTIFIER	{ $$ = npfctl_portno($1); }
 	;
 

Index: src/usr.sbin/npf/npfctl/npf.conf.5
diff -u src/usr.sbin/npf/npfctl/npf.conf.5:1.9 src/usr.sbin/npf/npfctl/npf.conf.5:1.10
--- src/usr.sbin/npf/npfctl/npf.conf.5:1.9	Mon Feb  6 00:41:36 2012
+++ src/usr.sbin/npf/npfctl/npf.conf.5	Wed May 30 21:30:07 2012
@@ -1,4 +1,4 @@
-.\"    $NetBSD: npf.conf.5,v 1.9 2012/02/06 00:41:36 rmind Exp $
+.\"    $NetBSD: npf.conf.5,v 1.10 2012/05/30 21:30:07 rmind Exp $
 .\"
 .\" Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd February 5, 2012
+.Dd May 27, 2012
 .Dt NPF.CONF 5
 .Os
 .Sh NAME
@@ -64,13 +64,13 @@ Each rule has a priority, which is set a
 Rules defined first are accordingly inspected first.
 All rules in the group are inspected sequentially, and the last matching
 dictates the action to be taken.
-Rules, however, may be explicitly marked as final (that is, "quick").
+Rules, however, may be explicitly marked as final.
 In such cases, processing stops after encountering the first matching rule
 marked as final.
 If there is no matching rule in the custom group, then rules in the default
 group will be inspected.
 .Pp
-Stateful filtering is supported using the "keep state" keyword.
+Stateful filtering is supported using the "stateful" keyword.
 In such cases, state (a session) is created and any further packets
 of the connection are tracked.
 Packets in backwards stream, after having been confirmed to belong to
@@ -155,9 +155,9 @@ group-opts	= "interface" iface "," [ "in
 
 ruleset		= "{" rule1 \*[Lt]newline\*[Gt], rule2 \*[Lt]newline\*[Gt], ... "}"
 
-rule		= ( "block" block-opts | "pass" ) [ "in" | out" ] [ "quick" ]
+rule		= ( "block" block-opts | "pass" ) [ "stateful" ] [ "in" | out" ] [ "final" ]
 		  [ "on" iface ] [ "family" fam-opt ] [ "proto" \*[Lt]protocol\*[Gt] ]
-		  ( "all" | filt-opts ) [ "keep state" ] [ "apply" rproc ] }
+		  ( "all" | filt-opts ) [ "apply" rproc ] }
 
 fam-opt		= [ "inet" | "inet6" ]
 block-opts	= [ "return-rst" | "return-icmp" | "return" ]
@@ -197,20 +197,20 @@ procedure "rid" {
 }
 
 group (name "external", interface $ext_if) {
-	block in quick from \*[Lt]1\*[Gt]
-	pass out quick from $ext_if keep state apply "rid"
+	block in final from \*[Lt]1\*[Gt]
+	pass stateful out final from $ext_if apply "rid"
 
-	pass in quick family inet proto tcp to $ext_if port ssh apply "log"
-	pass in quick proto tcp to $ext_if port $services_tcp
-	pass in quick proto udp to $ext_if port $services_udp
-	pass in quick proto tcp to $ext_if port 49151-65535	# Passive FTP
-	pass in quick proto udp to $ext_if port 33434-33600	# Traceroute
+	pass in final family inet proto tcp to $ext_if port ssh apply "log"
+	pass in final proto tcp to $ext_if port $services_tcp
+	pass in final proto udp to $ext_if port $services_udp
+	pass in final proto tcp to $ext_if port 49151-65535	# Passive FTP
+	pass in final proto udp to $ext_if port 33434-33600	# Traceroute
 }
 
 group (name "internal", interface $int_if) {
 	block in all
-	pass in quick from \*[Lt]2\*[Gt]
-	pass out quick all
+	pass in final from \*[Lt]2\*[Gt]
+	pass out final all
 }
 
 group (default) {

Index: src/usr.sbin/npf/npfctl/npf_data.c
diff -u src/usr.sbin/npf/npfctl/npf_data.c:1.11 src/usr.sbin/npf/npfctl/npf_data.c:1.12
--- src/usr.sbin/npf/npfctl/npf_data.c:1.11	Sun Feb 26 21:50:05 2012
+++ src/usr.sbin/npf/npfctl/npf_data.c	Wed May 30 21:30:07 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_data.c,v 1.11 2012/02/26 21:50:05 christos Exp $	*/
+/*	$NetBSD: npf_data.c,v 1.12 2012/05/30 21:30:07 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_data.c,v 1.11 2012/02/26 21:50:05 christos Exp $");
+__RCSID("$NetBSD: npf_data.c,v 1.12 2012/05/30 21:30:07 rmind Exp $");
 
 #include <sys/types.h>
 #include <sys/null.h>
@@ -211,7 +211,7 @@ out:
 
 /*
  * npfctl_parse_port_range: create a port-range variable.  Note that the
- * passed port numbers are in network byte order.
+ * passed port numbers should be in host byte order.
  */
 npfvar_t *
 npfctl_parse_port_range(in_port_t s, in_port_t e)
@@ -219,8 +219,8 @@ npfctl_parse_port_range(in_port_t s, in_
 	npfvar_t *vp = npfvar_create(".port_range");
 	port_range_t pr;
 
-	pr.pr_start = s;
-	pr.pr_end = e;
+	pr.pr_start = htons(s);
+	pr.pr_end = htons(e);
 
 	if (!npfvar_add_element(vp, NPFVAR_PORT_RANGE, &pr, sizeof(pr)))
 		goto out;
@@ -235,14 +235,15 @@ 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");
+	port_range_t *pr;
+	in_port_t p;
 
 	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:
@@ -261,13 +262,11 @@ npfctl_parse_port_range_variable(const c
 		default:
 			yyerror("wrong variable '%s' type '%s' for port range",
 			    v, npfvar_type(type));
-			goto out;
+			npfvar_destroy(pvp);
+			return NULL;
 		}
 	}
 	return pvp;
-out:
-	npfvar_destroy(pvp);
-	return NULL;
 }
 
 npfvar_t *
@@ -350,7 +349,7 @@ npfctl_parse_cidr(char *cidr)
 /*
  * npfctl_portno: convert port identifier (string) to a number.
  *
- * => Returns port number in network byte order.
+ * => Returns port number in host byte order.
  */
 in_port_t
 npfctl_portno(const char *port)
@@ -383,7 +382,7 @@ npfctl_portno(const char *port)
 	}
 out:
 	freeaddrinfo(rai);
-	return p;
+	return ntohs(p);
 }
 
 npfvar_t *

Index: src/usr.sbin/npf/npfctl/npf_disassemble.c
diff -u src/usr.sbin/npf/npfctl/npf_disassemble.c:1.3 src/usr.sbin/npf/npfctl/npf_disassemble.c:1.4
--- src/usr.sbin/npf/npfctl/npf_disassemble.c:1.3	Mon Mar 12 15:32:02 2012
+++ src/usr.sbin/npf/npfctl/npf_disassemble.c	Wed May 30 21:30:07 2012
@@ -36,9 +36,11 @@ __RCSID("$NetBSD$");
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <errno.h>
 #include <err.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <net/if.h>
 
 #include <util.h>
 
@@ -47,6 +49,21 @@ __RCSID("$NetBSD$");
 
 #include "npfctl.h"
 
+enum {
+	NPF_SHOW_SRCADDR,
+	NPF_SHOW_DSTADDR,
+	NPF_SHOW_SRCPORT,
+	NPF_SHOW_DSTPORT,
+	NPF_SHOW_ICMP,
+	NPF_SHOW_TCPF,
+	NPF_SHOW_COUNT,
+};
+
+struct nc_inf {
+	npfvar_t *	nci_vlist[NPF_SHOW_COUNT];
+	bool		nci_srcdst;
+};
+
 #define ADVANCE(n, rv) \
 	do { \
 		if (len < sizeof(*pc) * (n)) { \
@@ -84,10 +101,24 @@ npfctl_ncode_add_target(const uint32_t *
 	return q;
 }
 
+static void
+npfctl_ncode_add_vp(char *buf, nc_inf_t *nci, unsigned idx)
+{
+	npfvar_t *vl = nci->nci_vlist[idx];
+
+	if (vl == NULL) {
+		vl = npfvar_create(".list");
+		nci->nci_vlist[idx] = vl;
+	}
+	npfvar_t *vp = npfvar_create(".string");
+	npfvar_add_element(vp, NPFVAR_STRING, buf, strlen(buf) + 1);
+	npfvar_add_elements(vl, vp);
+}
+
 static const char *
 npfctl_ncode_operand(char *buf, size_t bufsiz, uint8_t op, const uint32_t *st,
     const uint32_t *ipc, const uint32_t **pcv, size_t *lenv,
-    const uint32_t ***t, size_t *l, size_t *m)
+    const uint32_t ***t, size_t *l, size_t *m, nc_inf_t *nci)
 {
 	const uint32_t *pc = *pcv;
 	size_t len = *lenv;
@@ -99,14 +130,14 @@ npfctl_ncode_operand(char *buf, size_t b
 
 	case NPF_OPERAND_REGISTER:
 		if (*pc & ~0x3) {
-			warnx("Bad register operand 0x%x at offset %td",
+			warnx("invalid register operand 0x%x at offset %td",
 			    *pc, pc - st);
 			return NULL;
 		}
 		snprintf(buf, bufsiz, "R%d", *pc);
 		ADVANCE(1, NULL);
 		break;
-				
+
 	case NPF_OPERAND_KEY:
 		snprintf(buf, bufsiz, "key=<0x%x>", *pc);
 		ADVANCE(1, NULL);
@@ -119,12 +150,15 @@ npfctl_ncode_operand(char *buf, size_t b
 
 	case NPF_OPERAND_SD:
 		if (*pc & ~0x1) {
-			warnx("Bad src/dst operand 0x%x at offset %td",
+			warnx("invalid src/dst operand 0x%x at offset %td",
 			    *pc, pc - st);
 			return NULL;
 		}
-		snprintf(buf, bufsiz, "%s", *pc == NPF_OPERAND_SD_SRC ?
-		    "SRC" : "DST");
+		bool srcdst = (*pc == NPF_OPERAND_SD_SRC);
+		if (nci) {
+			nci->nci_srcdst = srcdst;
+		}
+		snprintf(buf, bufsiz, "%s", srcdst ? "SRC" : "DST");
 		ADVANCE(1, NULL);
 		break;
 
@@ -140,8 +174,11 @@ npfctl_ncode_operand(char *buf, size_t b
 		sin->sin_family = AF_INET;
 		sin->sin_port = 0;
 		memcpy(&sin->sin_addr, pc, sizeof(sin->sin_addr));
-		sockaddr_snprintf(buf, bufsiz, "%a", (struct sockaddr *)(void *)
-		    sin);
+		sockaddr_snprintf(buf, bufsiz, "%a", (struct sockaddr *)sin);
+		if (nci) {
+			npfctl_ncode_add_vp(buf, nci, nci->nci_srcdst ?
+			    NPF_SHOW_SRCADDR : NPF_SHOW_DSTADDR);
+		}
 		ADVANCE(sizeof(sin->sin_addr) / sizeof(*pc), NULL);
 		break;
 	}
@@ -151,8 +188,11 @@ npfctl_ncode_operand(char *buf, size_t b
 		sin6->sin6_family = AF_INET6;
 		sin6->sin6_port = 0;
 		memcpy(&sin6->sin6_addr, pc, sizeof(sin6->sin6_addr));
-		sockaddr_snprintf(buf, bufsiz, "%a", (struct sockaddr *)(void *)
-		    sin6);
+		sockaddr_snprintf(buf, bufsiz, "%a", (struct sockaddr *)sin6);
+		if (nci) {
+			npfctl_ncode_add_vp(buf, nci, nci->nci_srcdst ?
+			    NPF_SHOW_SRCADDR : NPF_SHOW_DSTADDR);
+		}
 		ADVANCE(sizeof(sin6->sin6_addr) / sizeof(*pc), NULL);
 		break;
 	}
@@ -161,47 +201,71 @@ npfctl_ncode_operand(char *buf, size_t b
 		ADVANCE(1, NULL);
 		break;
 
-	case NPF_OPERAND_SUBNET:
+	case NPF_OPERAND_SUBNET: {
 		snprintf(buf, bufsiz, "/%d", *pc);
+		if (nci) {
+			npfctl_ncode_add_vp(buf, nci, nci->nci_srcdst ?
+			    NPF_SHOW_SRCADDR : NPF_SHOW_DSTADDR);
+		}
 		ADVANCE(1, NULL);
 		break;
-
+	}
 	case NPF_OPERAND_LENGTH:
 		snprintf(buf, bufsiz, "length=%d", *pc);
 		ADVANCE(1, NULL);
 		break;
 
 	case NPF_OPERAND_TABLE_ID:
+		if (nci) {
+			snprintf(buf, bufsiz, "<%d>", *pc);
+			npfctl_ncode_add_vp(buf, nci, nci->nci_srcdst ?
+			    NPF_SHOW_SRCADDR : NPF_SHOW_DSTADDR);
+		}
 		snprintf(buf, bufsiz, "id=%d", *pc);
 		ADVANCE(1, NULL);
 		break;
 
 	case NPF_OPERAND_ICMP4_TYPE_CODE:
 		if (*pc & ~0xffff) {
-			warnx("Bad icmp/type operand 0x%x at offset %td",
+			warnx("invalid icmp/type operand 0x%x at offset %td",
 			    *pc, pc - st);
 			return NULL;
 		}
-		snprintf(buf, bufsiz, "type=%d, code=%d", *pc >> 8,
-		    *pc & 0xff);
+		snprintf(buf, bufsiz, "type=%d, code=%d", *pc >> 8, *pc & 0xff);
+		if (nci) {
+			npfctl_ncode_add_vp(buf, nci, NPF_SHOW_ICMP);
+		}
 		ADVANCE(1, NULL);
 		break;
 
 	case NPF_OPERAND_TCP_FLAGS_MASK:
 		if (*pc & ~0xffff) {
-			warnx("Bad flags/mask operand 0x%x at offset %td",
+			warnx("invalid flags/mask operand 0x%x at offset %td",
 			    *pc, pc - st);
 			return NULL;
 		}
-		snprintf(buf, bufsiz, "type=%d, code=%d", *pc >> 8,
-		    *pc & 0xff);
+		snprintf(buf, bufsiz, "type=%d, code=%d", *pc >> 8, *pc & 0xff);
+		if (nci) {
+			npfctl_ncode_add_vp(buf, nci, NPF_SHOW_TCPF);
+		}
 		ADVANCE(1, NULL);
 		break;
 
-	case NPF_OPERAND_PORT_RANGE:
-		snprintf(buf, bufsiz, "%d-%d", (*pc >> 16), *pc & 0xffff);
+	case NPF_OPERAND_PORT_RANGE: {
+		in_port_t p1 = ntohs(*pc >> 16), p2 = ntohs(*pc & 0xffff);
+
+		if (p1 == p2) {
+			snprintf(buf, bufsiz, "%d", p1);
+		} else {
+			snprintf(buf, bufsiz, "%d-%d", p1, p2);
+		}
+		if (nci) {
+			npfctl_ncode_add_vp(buf, nci, nci->nci_srcdst ?
+			    NPF_SHOW_SRCPORT : NPF_SHOW_DSTPORT);
+		}
 		ADVANCE(1, NULL);
 		break;
+	}
 	default:
 		warnx("invalid operand %d at offset %td", op, pc - st);
 		return NULL;
@@ -213,7 +277,7 @@ npfctl_ncode_operand(char *buf, size_t b
 }
 
 int
-npfctl_ncode_disassemble(FILE *fp, const void *v, size_t len)
+npfctl_ncode_disassemble(FILE *fp, const void *v, size_t len, nc_inf_t *nci)
 {
 	const uint32_t *ipc, *pc = v;
 	const uint32_t *st = v;
@@ -228,7 +292,7 @@ npfctl_ncode_disassemble(FILE *fp, const
 	while (len) {
 		/* Get the opcode */
 		if (*pc & ~0xff) {
-			warnx("bad opcode 0x%x at offset (%td)", *pc,
+			warnx("invalid opcode 0x%x at offset (%td)", *pc,
 			    pc - st);
 			goto out;
 		}
@@ -238,26 +302,186 @@ npfctl_ncode_disassemble(FILE *fp, const
 			    pc - st);
 			goto out;
 		}
+
 		ipc = pc;
 		target = npfctl_ncode_get_target(pc, targ, tlen);
-		if (target != (size_t)~0)
-			printf("%zu:", target);
-		fprintf(fp, "\t%s", ni->name);
+		if (fp) {
+			if (target != (size_t)~0)
+				fprintf(fp, "%zu:", target);
+			fprintf(fp, "\t%s", ni->name);
+		}
 		ADVANCE(1, -1);
+
 		for (size_t i = 0; i < __arraycount(ni->op); i++) {
 			const char *op;
 			if (ni->op[i] == NPF_OPERAND_NONE)
 				break;
 			op = npfctl_ncode_operand(buf, sizeof(buf), ni->op[i],
-			    st, ipc, &pc, &len, &targ, &tlen, &mlen);
+			    st, ipc, &pc, &len, &targ, &tlen, &mlen, nci);
 			if (op == NULL)
 				goto out;
-			fprintf(fp, "%s%s", i == 0 ? " " : ", ", op);
+			if (fp) {
+				fprintf(fp, "%s%s", i == 0 ? " " : ", ", op);
+			}
+		}
+		if (fp) {
+			fprintf(fp, "\n");
 		}
-		fprintf(fp, "\n");
 	}
 	error = 0;
 out:
 	free(targ);
 	return error;
 }
+
+static void
+npfctl_show_fromto(const char *name, npfvar_t *vl, bool showany)
+{
+	size_t count = npfvar_get_count(vl), last = count - 1;
+	bool one = (count == 1);
+
+	if (count == 0) {
+		if (showany) {
+			printf("%s all ", name);
+		}
+		return;
+	}
+	printf("%s%s ", name, one ? "" : " {");
+
+	for (size_t i = 0; i < count; i++) {
+		char *s = npfvar_get_data(vl, NPFVAR_STRING, i);
+		printf("%s%s ", s, i == last ? (one ? "" : " }") : ",");
+	}
+	npfvar_destroy(vl);
+}
+
+static void
+npfctl_show_ncode(const void *nc, size_t len)
+{
+	nc_inf_t nci;
+
+	memset(&nci, 0, sizeof(nc_inf_t));
+
+	if (npfctl_ncode_disassemble(NULL, nc, len, (void *)&nci) == 0) {
+		npfctl_show_fromto("from", nci.nci_vlist[NPF_SHOW_SRCADDR], true);
+		npfctl_show_fromto("port", nci.nci_vlist[NPF_SHOW_SRCPORT], false);
+		npfctl_show_fromto("to", nci.nci_vlist[NPF_SHOW_DSTADDR], true);
+		npfctl_show_fromto("port", nci.nci_vlist[NPF_SHOW_DSTPORT], false);
+	} else {
+		printf("<< ncode >> ");
+	}
+}
+
+#define	NPF_RSTICMP		(NPF_RULE_RETRST | NPF_RULE_RETICMP)
+
+static const struct attr_keyword_mapent {
+	uint32_t	mask;
+	uint32_t	flags;
+	const char *	onmatch;
+	const char *	nomatch;
+} attr_keyword_map[] = {
+	{ NPF_RULE_PASS,	NPF_RULE_PASS,	"pass",		"block"	},
+	{ NPF_RSTICMP,		NPF_RSTICMP,	"return",	NULL	},
+	{ NPF_RSTICMP,		NPF_RULE_RETRST,"return-rst",	NULL	},
+	{ NPF_RSTICMP,		NPF_RULE_RETICMP,"return-icmp",	NULL	},
+	{ NPF_RULE_KEEPSTATE,	NPF_RULE_KEEPSTATE,"stateful",	NULL	},
+	{ NPF_RULE_DIMASK,	NPF_RULE_IN,	"in",		NULL	},
+	{ NPF_RULE_DIMASK,	NPF_RULE_OUT,	"out",		NULL	},
+	{ NPF_RULE_FINAL,	NPF_RULE_FINAL,	"final",	NULL	},
+};
+
+static void
+npfctl_show_rule(nl_rule_t *nrl, unsigned nlevel)
+{
+	rule_group_t rg;
+	const char *rproc;
+	const void *nc;
+	size_t nclen;
+
+	_npf_rule_getinfo(nrl, &rg.rg_name, &rg.rg_attr, &rg.rg_ifnum);
+
+	/* Get the interface, if any. */
+	char ifnamebuf[IFNAMSIZ], *ifname = NULL;
+	if (rg.rg_ifnum) {
+		ifname = if_indextoname(rg.rg_ifnum, ifnamebuf);
+	}
+
+	/*
+	 * If zero level, then it is a group.
+	 */
+	if (nlevel == 0) {
+		static bool ingroup = false;
+		const char *rname = rg.rg_name;
+
+		if (ingroup) {
+			puts("}");
+		}
+		ingroup = true;
+		if (rg.rg_attr & NPF_RULE_DEFAULT) {
+			puts("group (default) {");
+			return;
+		}
+		printf("group (name \"%s\"", rname == NULL ? "" : rname);
+		if (ifname) {
+			printf(", interface %s", ifname);
+		}
+		puts(") {");
+		return;
+	}
+
+	/*
+	 * Rule case.  First, unparse the attributes.
+	 */
+	while (nlevel--) {
+		printf("\t");
+	}
+	for (unsigned i = 0; i < __arraycount(attr_keyword_map); i++) {
+		const struct attr_keyword_mapent *ak = &attr_keyword_map[i];
+
+		if ((rg.rg_attr & ak->mask) == ak->flags) {
+			printf("%s ", ak->onmatch);
+		} else if (ak->nomatch) {
+			printf("%s ", ak->nomatch);
+		}
+	}
+
+	if (ifname) {
+		printf("on %s ", ifname);
+	}
+
+	nc = _npf_rule_ncode(nrl, &nclen);
+	if (nc) {
+		npfctl_show_ncode(nc, nclen);
+	} else {
+		printf("all ");
+	}
+	/* apply <rproc> */
+
+	if ((rproc = _npf_rule_rproc(nrl)) != NULL) {
+		printf("apply \"%s\"", rproc);
+	}
+	puts("");
+}
+
+int
+npfctl_config_show(int fd)
+{
+	nl_config_t *ncf;
+	bool active, loaded;
+	int error = 0;
+
+	ncf = npf_config_retrieve(fd, &active, &loaded);
+	if (ncf == NULL) {
+		return errno;
+	}
+	printf("Filtering:\t%s\nConfiguration:\t%s\n\n",
+	    active ? "active" : "inactive",
+	    loaded ? "loaded" : "empty");
+
+	if (loaded) {
+		error = _npf_rule_foreach(ncf, npfctl_show_rule);
+		puts("}");
+	}
+	npf_config_destroy(ncf);
+	return error;
+}

Index: src/usr.sbin/npf/npfctl/npf_ncgen.c
diff -u src/usr.sbin/npf/npfctl/npf_ncgen.c:1.8 src/usr.sbin/npf/npfctl/npf_ncgen.c:1.9
--- src/usr.sbin/npf/npfctl/npf_ncgen.c:1.8	Sat Mar 10 22:21:50 2012
+++ src/usr.sbin/npf/npfctl/npf_ncgen.c	Wed May 30 21:30:07 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_ncgen.c,v 1.8 2012/03/10 22:21:50 christos Exp $	*/
+/*	$NetBSD: npf_ncgen.c,v 1.9 2012/05/30 21:30:07 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_ncgen.c,v 1.8 2012/03/10 22:21:50 christos Exp $");
+__RCSID("$NetBSD: npf_ncgen.c,v 1.9 2012/05/30 21:30:07 rmind Exp $");
 
 #include <stdlib.h>
 #include <stddef.h>
@@ -388,14 +388,5 @@ npfctl_gennc_tcpfl(nc_ctx_t *ctx, uint8_
 void
 npfctl_ncgen_print(const void *code, size_t len)
 {
-#if 0
-	const uint32_t *op = code;
-
-	while (len) {
-		printf("\t> |0x%02x|\n", (u_int)*op++);
-		len -= sizeof(*op);
-	}
-#else
-	npfctl_ncode_disassemble(stdout, code, len);
-#endif
+	npfctl_ncode_disassemble(stdout, code, len, NULL);
 }

Index: src/usr.sbin/npf/npfctl/npf_scan.l
diff -u src/usr.sbin/npf/npfctl/npf_scan.l:1.1 src/usr.sbin/npf/npfctl/npf_scan.l:1.2
--- src/usr.sbin/npf/npfctl/npf_scan.l:1.1	Sun Jan  8 21:34:21 2012
+++ src/usr.sbin/npf/npfctl/npf_scan.l	Wed May 30 21:30:07 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_scan.l,v 1.1 2012/01/08 21:34:21 rmind Exp $	*/
+/*	$NetBSD: npf_scan.l,v 1.2 2012/05/30 21:30:07 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@@ -72,10 +72,10 @@ interface		return INTERFACE;
 all			return ALL;
 block			return BLOCK;
 pass			return PASS;
-keep			return KEEP;
-state			return STATE;
+stateful		return STATEFUL;
 apply			return APPLY;
-quick			return QUICK;
+final			return FINAL;
+quick			return FINAL;
 on			return ON;
 inet6			return INET6;
 inet4			return INET;

Index: src/usr.sbin/npf/npfctl/npf_var.c
diff -u src/usr.sbin/npf/npfctl/npf_var.c:1.4 src/usr.sbin/npf/npfctl/npf_var.c:1.5
--- src/usr.sbin/npf/npfctl/npf_var.c:1.4	Sun Feb 26 21:50:05 2012
+++ src/usr.sbin/npf/npfctl/npf_var.c	Wed May 30 21:30:07 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_var.c,v 1.4 2012/02/26 21:50:05 christos Exp $	*/
+/*	$NetBSD: npf_var.c,v 1.5 2012/05/30 21:30:07 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_var.c,v 1.4 2012/02/26 21:50:05 christos Exp $");
+__RCSID("$NetBSD: npf_var.c,v 1.5 2012/05/30 21:30:07 rmind Exp $");
 
 #include <stdlib.h>
 #include <string.h>
@@ -62,6 +62,7 @@ npfvar_create(const char *name)
 {
 	npfvar_t *vp = zalloc(sizeof(*vp));
 	vp->v_key = xstrdup(name);
+	var_num++;
 	return vp;
 }
 
@@ -88,7 +89,6 @@ npfvar_add(npfvar_t *vp)
 {
 	vp->v_next = var_list;
 	var_list = vp;
-	var_num++;
 }
 
 npfvar_t *
@@ -169,6 +169,7 @@ npfvar_destroy(npfvar_t *vp)
 	npfvar_free_elements(vp->v_elements);
 	free(vp->v_key);
 	free(vp);
+	var_num--;
 }
 
 char *

Index: src/usr.sbin/npf/npfctl/npfctl.c
diff -u src/usr.sbin/npf/npfctl/npfctl.c:1.10 src/usr.sbin/npf/npfctl/npfctl.c:1.11
--- src/usr.sbin/npf/npfctl/npfctl.c:1.10	Sun Feb  5 00:37:13 2012
+++ src/usr.sbin/npf/npfctl/npfctl.c	Wed May 30 21:30:07 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: npfctl.c,v 1.10 2012/02/05 00:37:13 rmind Exp $	*/
+/*	$NetBSD: npfctl.c,v 1.11 2012/05/30 21:30:07 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npfctl.c,v 1.10 2012/02/05 00:37:13 rmind Exp $");
+__RCSID("$NetBSD: npfctl.c,v 1.11 2012/05/30 21:30:07 rmind Exp $");
 
 #include <sys/ioctl.h>
 #include <sys/stat.h>
@@ -50,14 +50,17 @@ extern const char *	yyfilename;
 extern int		yyparse(void);
 extern void		yyrestart(FILE *);
 
-#define	NPFCTL_START		1
-#define	NPFCTL_STOP		2
-#define	NPFCTL_RELOAD		3
-#define	NPFCTL_FLUSH		4
-#define	NPFCTL_TABLE		5
-#define	NPFCTL_STATS		6
-#define	NPFCTL_SESSIONS_SAVE	7
-#define	NPFCTL_SESSIONS_LOAD	8
+enum {
+	NPFCTL_START,
+	NPFCTL_STOP,
+	NPFCTL_RELOAD,
+	NPFCTL_SHOWCONF,
+	NPFCTL_FLUSH,
+	NPFCTL_TABLE,
+	NPFCTL_STATS,
+	NPFCTL_SESSIONS_SAVE,
+	NPFCTL_SESSIONS_LOAD,
+};
 
 static struct operations_s {
 	const char *		cmd;
@@ -67,6 +70,7 @@ static struct operations_s {
 	{	"start",		NPFCTL_START		},
 	{	"stop",			NPFCTL_STOP		},
 	{	"reload",		NPFCTL_RELOAD		},
+	{	"show",			NPFCTL_SHOWCONF,	},
 	{	"flush",		NPFCTL_FLUSH		},
 	/* Table */
 	{	"table",		NPFCTL_TABLE		},
@@ -263,6 +267,9 @@ npfctl(int action, int argc, char **argv
 		npfctl_parsecfg(argc < 3 ? NPF_CONF_PATH : argv[2]);
 		ret = npfctl_config_send(fd);
 		break;
+	case NPFCTL_SHOWCONF:
+		ret = npfctl_config_show(fd);
+		break;
 	case NPFCTL_FLUSH:
 		ret = npf_config_flush(fd);
 		break;

Index: src/usr.sbin/npf/npfctl/npfctl.h
diff -u src/usr.sbin/npf/npfctl/npfctl.h:1.13 src/usr.sbin/npf/npfctl/npfctl.h:1.14
--- src/usr.sbin/npf/npfctl/npfctl.h:1.13	Sat Mar 10 22:21:50 2012
+++ src/usr.sbin/npf/npfctl/npfctl.h	Wed May 30 21:30:07 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: npfctl.h,v 1.13 2012/03/10 22:21:50 christos Exp $	*/
+/*	$NetBSD: npfctl.h,v 1.14 2012/05/30 21:30:07 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -71,7 +71,7 @@ typedef struct opt_proto {
 
 typedef struct rule_group {
 	const char *	rg_name;
-	int		rg_attr;
+	uint32_t	rg_attr;
 	u_int		rg_ifnum;
 } rule_group_t;
 
@@ -146,6 +146,7 @@ void		npfctl_gennc_tcpfl(nc_ctx_t *, uin
 
 void		npfctl_config_init(bool);
 int		npfctl_config_send(int);
+int		npfctl_config_show(int);
 
 void		npfctl_build_rproc(const char *, npfvar_t *);
 void		npfctl_build_group(const char *, int, u_int);
@@ -154,6 +155,13 @@ void		npfctl_build_rule(int, u_int, sa_f
 void		npfctl_build_nat(int, u_int, const filt_opts_t *,
 		    npfvar_t *, npfvar_t *);
 void		npfctl_build_table(const char *, u_int, const char *);
-int		npfctl_ncode_disassemble(FILE *, const void *, size_t);
+
+/*
+ * N-code disassembler.
+ */
+typedef struct nc_inf nc_inf_t;
+
+int		npfctl_ncode_disassemble(FILE *, const void *, size_t,
+		    nc_inf_t *);
 
 #endif

Reply via email to