Module Name:    src
Committed By:   christos
Date:           Tue Dec 27 20:14:35 UTC 2016

Modified Files:
        src/usr.sbin/npf/npfctl: npf_show.c npfctl.c npfctl.h

Log Message:
Add a list command to iterate over connection and nat endpoints.


To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 src/usr.sbin/npf/npfctl/npf_show.c
cvs rdiff -u -r1.49 -r1.50 src/usr.sbin/npf/npfctl/npfctl.c
cvs rdiff -u -r1.40 -r1.41 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/npf_show.c
diff -u src/usr.sbin/npf/npfctl/npf_show.c:1.20 src/usr.sbin/npf/npfctl/npf_show.c:1.21
--- src/usr.sbin/npf/npfctl/npf_show.c:1.20	Mon Dec 26 18:05:05 2016
+++ src/usr.sbin/npf/npfctl/npf_show.c	Tue Dec 27 15:14:35 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_show.c,v 1.20 2016/12/26 23:05:05 christos Exp $	*/
+/*	$NetBSD: npf_show.c,v 1.21 2016/12/27 20:14:35 christos Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_show.c,v 1.20 2016/12/26 23:05:05 christos Exp $");
+__RCSID("$NetBSD: npf_show.c,v 1.21 2016/12/27 20:14:35 christos Exp $");
 
 #include <sys/socket.h>
 #define	__FAVOR_BSD
@@ -153,7 +153,7 @@ print_address(npf_conf_info_t *ctx, cons
 		errx(EXIT_FAILURE, "invalid byte-code mark (address)");
 	}
 	addr = (const npf_addr_t *)words;
-	return npfctl_print_addrmask(alen, addr, mask);
+	return npfctl_print_addrmask(alen, "%a", addr, mask);
 }
 
 static char *
@@ -437,7 +437,7 @@ npfctl_print_nat(npf_conf_info_t *ctx, n
 
 	/* Get the translation address (and port, if used). */
 	npf_nat_getmap(nt, &addr, &alen, &port);
-	seg = npfctl_print_addrmask(alen, &addr, NPF_NO_NETMASK);
+	seg = npfctl_print_addrmask(alen, "%a", &addr, NPF_NO_NETMASK);
 	if (port) {
 		char *p;
 		easprintf(&p, "%s port %u", seg, ntohs(port));

Index: src/usr.sbin/npf/npfctl/npfctl.c
diff -u src/usr.sbin/npf/npfctl/npfctl.c:1.49 src/usr.sbin/npf/npfctl/npfctl.c:1.50
--- src/usr.sbin/npf/npfctl/npfctl.c:1.49	Tue Dec 27 08:43:38 2016
+++ src/usr.sbin/npf/npfctl/npfctl.c	Tue Dec 27 15:14:35 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: npfctl.c,v 1.49 2016/12/27 13:43:38 christos Exp $	*/
+/*	$NetBSD: npfctl.c,v 1.50 2016/12/27 20:14:35 christos Exp $	*/
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npfctl.c,v 1.49 2016/12/27 13:43:38 christos Exp $");
+__RCSID("$NetBSD: npfctl.c,v 1.50 2016/12/27 20:14:35 christos Exp $");
 
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -70,6 +70,7 @@ enum {
 	NPFCTL_STATS,
 	NPFCTL_SAVE,
 	NPFCTL_LOAD,
+	NPFCTL_CONN_LIST,
 };
 
 static const struct operations_s {
@@ -92,6 +93,7 @@ static const struct operations_s {
 	/* Full state save/load */
 	{	"save",		NPFCTL_SAVE		},
 	{	"load",		NPFCTL_LOAD		},
+	{	"list",		NPFCTL_CONN_LIST	},
 	/* --- */
 	{	NULL,		0			}
 };
@@ -147,6 +149,9 @@ usage(void)
 	fprintf(stderr,
 	    "\t%s save | load\n",
 	    progname);
+	fprintf(stderr,
+	    "\t%s list [-46hnNw] [-i <ifname>]\n",
+	    progname);
 	exit(EXIT_FAILURE);
 }
 
@@ -230,9 +235,10 @@ npfctl_print_error(const npf_error_t *ne
 }
 
 char *
-npfctl_print_addrmask(int alen, const npf_addr_t *addr, npf_netmask_t mask)
+npfctl_print_addrmask(int alen, const char *fmt, const npf_addr_t *addr,
+    npf_netmask_t mask)
 {
-	const unsigned buflen = 64;
+	const unsigned buflen = 256;
 	char *buf = ecalloc(1, buflen);
 	struct sockaddr_storage ss;
 
@@ -241,12 +247,14 @@ npfctl_print_addrmask(int alen, const np
 	switch (alen) {
 	case 4: {
 		struct sockaddr_in *sin = (void *)&ss;
+		sin->sin_len = sizeof(*sin);
 		sin->sin_family = AF_INET;
 		memcpy(&sin->sin_addr, addr, sizeof(sin->sin_addr));
 		break;
 	}
 	case 16: {
 		struct sockaddr_in6 *sin6 = (void *)&ss;
+		sin6->sin6_len = sizeof(*sin6);
 		sin6->sin6_family = AF_INET6;
 		memcpy(&sin6->sin6_addr, addr, sizeof(sin6->sin6_addr));
 		break;
@@ -254,7 +262,7 @@ npfctl_print_addrmask(int alen, const np
 	default:
 		assert(false);
 	}
-	inet_ntop(ss.ss_family, (const void *)&ss, buf, buflen);
+	sockaddr_snprintf(buf, buflen, fmt, (const void *)&ss);
 	if (mask && mask != NPF_NO_NETMASK) {
 		const unsigned len = strlen(buf);
 		snprintf(&buf[len], buflen - len, "/%u", mask);
@@ -359,7 +367,7 @@ again:
 		while (nct.nct_data.buf.len--) {
 			if (!ent->alen)
 				break;
-			buf = npfctl_print_addrmask(ent->alen,
+			buf = npfctl_print_addrmask(ent->alen, "%a",
 			    &ent->addr, ent->mask);
 			puts(buf);
 			ent++;
@@ -574,6 +582,103 @@ npfctl_load(int fd)
 	return error;
 }
 
+struct npf_conn_filter {
+	uint16_t alen;
+	const char *ifname;
+	bool nat;
+	bool wide;
+	bool name;
+	int width;
+	FILE *fp;
+};
+
+static int
+npfctl_conn_print(unsigned alen, const npf_addr_t *a, const in_port_t *p, 
+    const char *ifname, void *v)
+{
+	struct npf_conn_filter *fil = v;
+	FILE *fp = fil->fp;
+	char *src, *dst;
+
+	if (fil->ifname && strcmp(ifname, fil->ifname) != 0)
+		return 0;
+	if (fil->alen && alen != fil->alen)
+		return 0;
+	if (fil->nat && !p[2])
+		return 0;
+
+	int w = fil->width;
+	const char *fmt = fil->name ? "%A" :
+	    (alen == sizeof(struct in_addr) ? "%a" : "[%a]");
+	src = npfctl_print_addrmask(alen, fmt, &a[0], NPF_NO_NETMASK);
+	dst = npfctl_print_addrmask(alen, fmt, &a[1], NPF_NO_NETMASK);
+	if (fil->wide)
+		fprintf(fp, "%s:%d %s:%d", src, p[0], dst, p[1]);
+	else
+		fprintf(fp, "%*.*s:%-5d %*.*s:%-5d", w, w, src, p[0],
+		    w, w, dst, p[1]);
+	free(src);
+	free(dst);
+	if (!p[2]) {
+		fputc('\n', fp);
+		return 1;
+	}
+	fprintf(fp, " via %s:%d\n", ifname, ntohs(p[2]));
+	return 1;
+}
+
+
+static int
+npfctl_conn_list(int fd, int argc, char **argv)
+{
+	struct npf_conn_filter f;
+	int c;
+	int header = true;
+	memset(&f, 0, sizeof(f));
+
+	argc--;
+	argv++;
+
+	while ((c = getopt(argc, argv, "46hi:nNw")) != -1) {
+		switch (c) {
+		case '4':
+			f.alen = sizeof(struct in_addr);
+			break;
+		case '6':
+			f.alen = sizeof(struct in6_addr);
+			break;
+		case 'h':
+			header = false;
+		case 'i':
+			f.ifname = optarg;
+			break;
+		case 'n':
+			f.nat = true;
+			break;
+		case 'N':
+			f.name = true;
+			break;
+		case 'w':
+			f.wide = true;
+			break;
+		default:
+			fprintf(stderr,
+			    "Usage: %s list [-46hnNw] [-i <ifname>]\n",
+			    getprogname());
+			exit(EXIT_FAILURE);
+		}
+	}
+	f.width = f.alen == sizeof(struct in_addr) ? 25 : 41;
+	int w = f.width + 6;
+	f.fp = stdout;
+	if (header)
+		fprintf(f.fp, "%*.*s %*.*s\n",
+		    w, w, "From address:port ", w, w, "To address:port ");
+		
+	npf_conn_list(fd, npfctl_conn_print, &f);
+	return 0;
+}
+
 static void
 npfctl(int action, int argc, char **argv)
 {
@@ -659,6 +764,10 @@ npfctl(int action, int argc, char **argv
 		ret = npfctl_print_stats(fd);
 		fun = "npfctl_print_stats";
 		break;
+	case NPFCTL_CONN_LIST:
+		ret = npfctl_conn_list(fd, argc, argv);
+		fun = "npfctl_conn_list";
+		break;
 	}
 	if (ret) {
 		err(EXIT_FAILURE, "%s", fun);

Index: src/usr.sbin/npf/npfctl/npfctl.h
diff -u src/usr.sbin/npf/npfctl/npfctl.h:1.40 src/usr.sbin/npf/npfctl/npfctl.h:1.41
--- src/usr.sbin/npf/npfctl/npfctl.h:1.40	Mon Dec 26 18:05:05 2016
+++ src/usr.sbin/npf/npfctl/npfctl.h	Tue Dec 27 15:14:35 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: npfctl.h,v 1.40 2016/12/26 23:05:05 christos Exp $	*/
+/*	$NetBSD: npfctl.h,v 1.41 2016/12/27 20:14:35 christos Exp $	*/
 
 /*-
  * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -111,7 +111,8 @@ void		npfctl_parse_file(const char *);
 void		npfctl_parse_string(const char *);
 
 void		npfctl_print_error(const npf_error_t *);
-char *		npfctl_print_addrmask(int, const npf_addr_t *, npf_netmask_t);
+char *		npfctl_print_addrmask(int, const char *, const npf_addr_t *,
+		    npf_netmask_t);
 void		npfctl_note_interface(const char *);
 unsigned	npfctl_table_getid(const char *);
 int		npfctl_protono(const char *);

Reply via email to