Module Name: src Committed By: christos Date: Wed Dec 28 01:25:48 UTC 2016
Modified Files: src/usr.sbin/npf/npfd: Makefile npfd.c npfd.h npfd_log.c Log Message: Add some flesh. To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/usr.sbin/npf/npfd/Makefile \ src/usr.sbin/npf/npfd/npfd.c src/usr.sbin/npf/npfd/npfd.h \ src/usr.sbin/npf/npfd/npfd_log.c 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/npfd/Makefile diff -u src/usr.sbin/npf/npfd/Makefile:1.1 src/usr.sbin/npf/npfd/Makefile:1.2 --- src/usr.sbin/npf/npfd/Makefile:1.1 Tue Dec 27 17:20:00 2016 +++ src/usr.sbin/npf/npfd/Makefile Tue Dec 27 20:25:48 2016 @@ -1,11 +1,12 @@ -# $NetBSD: Makefile,v 1.1 2016/12/27 22:20:00 rmind Exp $ +# $NetBSD: Makefile,v 1.2 2016/12/28 01:25:48 christos Exp $ # # Public Domain # +NOMAN= PROG= npfd -SRCS= npfd.c +SRCS= npfd.c npfd_log.c CPPFLAGS+= -I${.CURDIR} LDADD+= -lnpf -lpcap Index: src/usr.sbin/npf/npfd/npfd.c diff -u src/usr.sbin/npf/npfd/npfd.c:1.1 src/usr.sbin/npf/npfd/npfd.c:1.2 --- src/usr.sbin/npf/npfd/npfd.c:1.1 Tue Dec 27 17:20:00 2016 +++ src/usr.sbin/npf/npfd/npfd.c Tue Dec 27 20:25:48 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: npfd.c,v 1.1 2016/12/27 22:20:00 rmind Exp $ */ +/* $NetBSD: npfd.c,v 1.2 2016/12/28 01:25:48 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -30,21 +30,29 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: npfd.c,v 1.1 2016/12/27 22:20:00 rmind Exp $"); +__RCSID("$NetBSD: npfd.c,v 1.2 2016/12/28 01:25:48 christos Exp $"); #include <stdio.h> +#include <fcntl.h> +#include <signal.h> #include <stdlib.h> +#include <unistd.h> #include <stdbool.h> +#include <poll.h> +#include <errno.h> +#include <err.h> #include <syslog.h> +#include <net/npf.h> + #include "npfd.h" -static volatile sig_atomic_t hup = false; +static volatile sig_atomic_t hup, stats, done; -int +static int npfd_getctl(void) { - int fd; + int fd, ver; fd = open(NPF_DEV_PATH, O_RDONLY); if (fd == -1) { @@ -55,7 +63,7 @@ npfd_getctl(void) } if (ver != NPF_VERSION) { errx(EXIT_FAILURE, - "incompatible NPF interface version (%d, kernel %d)\n" + "Incompatible NPF interface version (%d, kernel %d)\n" "Hint: update userland?", NPF_VERSION, ver); } return fd; @@ -64,38 +72,57 @@ npfd_getctl(void) static void npfd_event_loop(void) { - int fds[8], fd, nfds = 0, maxfd = 0; - fd_set rfds; + struct pollfd pfd; + npfd_log_t *log; - FD_ZERO(&rfds); + log = npfd_log_create(0); + pfd.fd = npfd_log_getsock(log); + pfd.events = POLLHUP | POLLIN; - fd = npfd_log_create(0) - fds[nfds++] = fd; - FD_SET(fd, &rfds); - - for (int i = 0; i < nfds; i++) { - maxfd = MAX(maxfd, fds[i] + 1); - } - - while (!done) { - if ((ret = select(maxfd, &rfds, NULL, NULL, NULL)) == -1) { - syslog(LOG_ERR, "select failed: %m"); - err(EXIT_FAILURE, "select"); - } + while (!done) { if (hup) { hup = false; + npfd_log_reopen(log); } - - for (fd = 0; fd < maxfd; fd++) { - // TODO + if (stats) { + stats = false; + npfd_log_stats(log); } + switch (poll(&pfd, 1, 1000)) { + case -1: + if (errno == EINTR) + continue; + syslog(LOG_ERR, "poll failed: %m"); + exit(EXIT_FAILURE); + case 0: + continue; + default: + npfd_log(log); + } + } + npfd_log_destroy(log); } static void -sighup_handler(int sig) +/*###114 [cc] error: 'sighandler' defined but not used [-Werror=unused-function]%%%*/ +sighandler(int sig) { - hup = true; + switch (sig) { + case SIGHUP: + hup = true; + break; + case SIGTERM: + case SIGINT: + hup = true; + break; + case SIGINFO: + case SIGQUIT: + stats = true; + break; + default: + syslog(LOG_ERR, "Unhandled signal %d", sig); + } } int @@ -110,16 +137,22 @@ main(int argc, char **argv) daemon_off = true; break; default: - errx(EXIT_FAILURE, "usage:\n\t%s [ -d ]", argv[0]); + fprintf(stderr, "Usage: %s [-d]\n", getprogname()); + exit(EXIT_FAILURE); } } + int fd = npfd_getctl(); + (void)close(fd); - openlog(argv[0], LOG_PID | LOG_NDELAY | LOG_CONS, LOG_DAEMON); if (!daemon_off && daemon(0, 0) == -1) { - syslog(LOG_ERR, "daemon failed: %m"); err(EXIT_FAILURE, "daemon"); } - signal(SIGHUP, sighup_handler); + openlog(argv[0], LOG_PID | LOG_NDELAY | LOG_CONS, LOG_DAEMON); + signal(SIGHUP, sighandler); + signal(SIGINT, sighandler); + signal(SIGTERM, sighandler); + signal(SIGINFO, sighandler); + signal(SIGQUIT, sighandler); npfd_event_loop(); closelog(); Index: src/usr.sbin/npf/npfd/npfd.h diff -u src/usr.sbin/npf/npfd/npfd.h:1.1 src/usr.sbin/npf/npfd/npfd.h:1.2 --- src/usr.sbin/npf/npfd/npfd.h:1.1 Tue Dec 27 17:20:00 2016 +++ src/usr.sbin/npf/npfd/npfd.h Tue Dec 27 20:25:48 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: npfd.h,v 1.1 2016/12/27 22:20:00 rmind Exp $ */ +/* $NetBSD: npfd.h,v 1.2 2016/12/28 01:25:48 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -34,6 +34,7 @@ #define PCAP_NPACKETS 1024 #define NPFD_LOG_PATH "/var/log" +#define NPF_DEV_PATH "/dev/npf" #define NPFD_NPFLOG "npflog" #define NPFD_NPFLOG_LEN (sizeof(NPFD_NPFLOG) - 1) @@ -44,6 +45,9 @@ typedef struct npfd_log npfd_log_t; npfd_log_t * npfd_log_create(unsigned); void npfd_log_destroy(npfd_log_t *); int npfd_log_getsock(npfd_log_t *); +bool npfd_log_reopen(npfd_log_t *); void npfd_log(npfd_log_t *); +void npfd_log_stats(npfd_log_t *); + #endif Index: src/usr.sbin/npf/npfd/npfd_log.c diff -u src/usr.sbin/npf/npfd/npfd_log.c:1.1 src/usr.sbin/npf/npfd/npfd_log.c:1.2 --- src/usr.sbin/npf/npfd/npfd_log.c:1.1 Tue Dec 27 17:20:00 2016 +++ src/usr.sbin/npf/npfd/npfd_log.c Tue Dec 27 20:25:48 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: npfd_log.c,v 1.1 2016/12/27 22:20:00 rmind Exp $ */ +/* $NetBSD: npfd_log.c,v 1.2 2016/12/28 01:25:48 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -30,17 +30,27 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: npfd_log.c,v 1.1 2016/12/27 22:20:00 rmind Exp $"); +__RCSID("$NetBSD: npfd_log.c,v 1.2 2016/12/28 01:25:48 christos Exp $"); + +#include <sys/types.h> +#include <sys/param.h> +#include <net/if.h> #include <stdio.h> #include <inttypes.h> #include <limits.h> +#include <stdlib.h> +#include <syslog.h> +#include <stdbool.h> #include <pcap/pcap.h> +#include "npfd.h" struct npfd_log { - pcap_t * pcap; - pcap_dumper_t * dumper; + char ifname[IFNAMSIZ]; + char path[MAXPATHLEN]; + pcap_t *pcap; + pcap_dumper_t *dumper; }; npfd_log_t * @@ -48,10 +58,8 @@ npfd_log_create(unsigned if_idx) { npfd_log_t *ctx; char errbuf[PCAP_ERRBUF_SIZE]; - char ifname[IFNAMSIZ], path[PATH_MAX]; - FILE *fp; - if ((ctx = calloc(1, sizeof(npfd_log_t))) == NULL) { + if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { syslog(LOG_ERR, "malloc failed: %m"); return NULL; } @@ -59,39 +67,48 @@ npfd_log_create(unsigned if_idx) /* * Open a live capture handle in non-blocking mode. */ - snprintf(ifname, sizeof(ifname), NPFD_NPFLOG "%u", if_idx); - pcap = pcap_create(ifname, errbuf); - if ((ctx->pcap = pcap) == NULL) { + snprintf(ctx->ifname, sizeof(ctx->ifname), NPFD_NPFLOG "%u", if_idx); + ctx->pcap = pcap_create(ctx->ifname, errbuf); + if (ctx->pcap == NULL) { syslog(LOG_ERR, "pcap_create failed: %s", errbuf); goto err; } - if (pcap_setnonblock(pcap, 1, errbuf) == -1) { + if (pcap_setnonblock(ctx->pcap, 1, errbuf) == -1) { syslog(LOG_ERR, "pcap_setnonblock failed: %s", errbuf); goto err; } - pcap_set_snaplen(pcap, snaplen); - /* - * Open a log file to write for a given interface and dump there. - */ - snprintf(path, sizeof(path), "%s/%s%s", NPFD_LOG_PATH, ifname, ".pcap"); - if ((fp = fopen(path, "w")) == NULL) { - syslog(LOG_ERR, "open failed: %m"); - goto err; - } - if ((ctx->dumper = pcap_dump_fopen(pcap, fp)) == NULL) { - syslog(LOG_ERR, "pcap_dump_fopen failed: %s", errbuf); + pcap_set_snaplen(ctx->pcap, 10240); + + snprintf(ctx->path, sizeof(ctx->path), "%s/%s%s", + NPFD_LOG_PATH, ctx->ifname, ".pcap"); + + if (!npfd_log_reopen(ctx)) goto err; - } + return ctx; err: - if (!ctx->dumper && fp) { - fclose(fp); - } npfd_log_destroy(ctx); return NULL; } +bool +npfd_log_reopen(npfd_log_t *ctx) +{ + if (ctx->dumper) + pcap_dump_close(ctx->dumper); + /* + * Open a log file to write for a given interface and dump there. + */ + ctx->dumper = pcap_dump_open_append(ctx->pcap, ctx->path); + if (ctx->dumper == NULL) { + syslog(LOG_ERR, "pcap_dump_open_append failed for `%s': %s", + ctx->path, pcap_geterr(ctx->pcap)); + return false; + } + return true; +} + void npfd_log_destroy(npfd_log_t *ctx) { @@ -122,7 +139,7 @@ npfd_log_stats(npfd_log_t *ctx) pcap_t *pcap = ctx->pcap; struct pcap_stat ps; - if (pcap_stats(pcap, &ps) == -1) + if (pcap_stats(pcap, &ps) == -1) { syslog(LOG_ERR, "pcap_stats failed: %s", pcap_geterr(pcap)); return; }