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 *);