Module Name:    src
Committed By:   christos
Date:           Fri Dec 30 19:55:46 UTC 2016

Modified Files:
        src/usr.sbin/npf/npfd: Makefile npfd.c npfd.h npfd_log.c

Log Message:
flesh this out more.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/usr.sbin/npf/npfd/Makefile \
    src/usr.sbin/npf/npfd/npfd.h
cvs rdiff -u -r1.3 -r1.4 src/usr.sbin/npf/npfd/npfd.c \
    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.2 src/usr.sbin/npf/npfd/Makefile:1.3
--- src/usr.sbin/npf/npfd/Makefile:1.2	Tue Dec 27 20:25:48 2016
+++ src/usr.sbin/npf/npfd/Makefile	Fri Dec 30 14:55:46 2016
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.2 2016/12/28 01:25:48 christos Exp $
+# $NetBSD: Makefile,v 1.3 2016/12/30 19:55:46 christos Exp $
 #
 # Public Domain
 #
@@ -6,11 +6,12 @@
 NOMAN=
 PROG=		npfd
 
+#DBG=-g
 SRCS=		npfd.c npfd_log.c
 CPPFLAGS+=	-I${.CURDIR}
 
-LDADD+=		-lnpf -lpcap
-DPADD+=		${LIBNPF} ${LIBPCAP}
+LDADD+=		-lnpf -lpcap -lutil
+DPADD+=		${LIBNPF} ${LIBPCAP} ${LIBUTIL}
 
 WARNS=		5
 NOLINT=		# disabled deliberately
Index: src/usr.sbin/npf/npfd/npfd.h
diff -u src/usr.sbin/npf/npfd/npfd.h:1.2 src/usr.sbin/npf/npfd/npfd.h:1.3
--- src/usr.sbin/npf/npfd/npfd.h:1.2	Tue Dec 27 20:25:48 2016
+++ src/usr.sbin/npf/npfd/npfd.h	Fri Dec 30 14:55:46 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: npfd.h,v 1.2 2016/12/28 01:25:48 christos Exp $	*/
+/*	$NetBSD: npfd.h,v 1.3 2016/12/30 19:55:46 christos Exp $	*/
 
 /*-
  * Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -42,12 +42,13 @@
 struct npf_log;
 typedef struct npfd_log npfd_log_t;
 
-npfd_log_t *	npfd_log_create(unsigned);
+npfd_log_t *	npfd_log_create(const char *, const char *, int);
 void		npfd_log_destroy(npfd_log_t *);
 int		npfd_log_getsock(npfd_log_t *);
-bool		npfd_log_reopen(npfd_log_t *);
+bool		npfd_log_reopen(npfd_log_t *, bool);
 void		npfd_log(npfd_log_t *);
 void		npfd_log_stats(npfd_log_t *);
+void		npfd_log_flush(npfd_log_t *);
 
 
 #endif

Index: src/usr.sbin/npf/npfd/npfd.c
diff -u src/usr.sbin/npf/npfd/npfd.c:1.3 src/usr.sbin/npf/npfd/npfd.c:1.4
--- src/usr.sbin/npf/npfd/npfd.c:1.3	Tue Dec 27 22:02:54 2016
+++ src/usr.sbin/npf/npfd/npfd.c	Fri Dec 30 14:55:46 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: npfd.c,v 1.3 2016/12/28 03:02:54 christos Exp $	*/
+/*	$NetBSD: npfd.c,v 1.4 2016/12/30 19:55:46 christos Exp $	*/
 
 /*-
  * Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -30,9 +30,10 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npfd.c,v 1.3 2016/12/28 03:02:54 christos Exp $");
+__RCSID("$NetBSD: npfd.c,v 1.4 2016/12/30 19:55:46 christos Exp $");
 
 #include <stdio.h>
+#include <string.h>
 #include <fcntl.h>
 #include <signal.h>
 #include <stdlib.h>
@@ -42,6 +43,7 @@ __RCSID("$NetBSD: npfd.c,v 1.3 2016/12/2
 #include <errno.h>
 #include <err.h>
 #include <syslog.h>
+#include <util.h>
 
 #include <net/npf.h>
 
@@ -70,33 +72,31 @@ npfd_getctl(void)
 }
 
 static void
-npfd_event_loop(void)
+npfd_event_loop(npfd_log_t *log, int delay)
 {
 	struct pollfd pfd;
-	npfd_log_t *log;
 
-	log = npfd_log_create(0);
-	if (log == NULL)
-		exit(EXIT_FAILURE);
 	pfd.fd = npfd_log_getsock(log);
 	pfd.events = POLLHUP | POLLIN;
 
 	while  (!done) {
 		if (hup) {
 			hup = false;
-			npfd_log_reopen(log);
+			npfd_log_reopen(log, false);
 		}
 		if (stats) {
 			stats = false;
 			npfd_log_stats(log);
+			npfd_log_flush(log);
 		}
-		switch (poll(&pfd, 1, 1000)) {
+		switch (poll(&pfd, 1, delay)) {
 		case -1:
 			if (errno == EINTR)
 				continue;
 			syslog(LOG_ERR, "poll failed: %m");
 			exit(EXIT_FAILURE);
 		case 0:
+			npfd_log_flush(log);
 			continue;
 		default:
 			npfd_log(log);
@@ -115,7 +115,7 @@ sighandler(int sig)
 		break;
 	case SIGTERM:
 	case SIGINT:
-		hup = true;
+		done = true;
 		break;
 	case SIGINFO:
 	case SIGQUIT:
@@ -123,38 +123,96 @@ sighandler(int sig)
 		break;
 	default:
 		syslog(LOG_ERR, "Unhandled signal %d", sig);
+		break;
 	}
 }
 
+static __dead void
+usage(void)
+{
+	fprintf(stderr, "Usage: %s [-D] [-d <delay>] [-i <interface>]"
+	    " [-p <pidfile>] [-s <snaplen>] expression\n", getprogname());
+	exit(EXIT_FAILURE);
+}
+
+static char *
+copyargs(int argc, char **argv)
+{
+	if (argc == 0)
+		return NULL;
+
+	size_t len = 0, p = 0;
+	char *buf = NULL;
+
+	for (int i = 0; i < argc; i++) {
+		size_t l = strlen(argv[i]);
+		if (p + l + 1 >= len)
+			buf = erealloc(buf, len = p + l + 1);
+		memcpy(buf + p, argv[i], l);
+		p += l;
+		buf[p++] = i == argc - 1 ? '\0' : ' ';
+	}
+	return buf;
+}
+
 int
 main(int argc, char **argv)
 {
 	bool daemon_off = false;
 	int ch;
 
-	while ((ch = getopt(argc, argv, "d")) != -1) {
+	int delay = 60 * 1000;
+	const char *iface = "npflog0";
+	int snaplen = 116;
+	char *pidname = NULL;
+
+	int fd = npfd_getctl();
+	(void)close(fd);
+
+	while ((ch = getopt(argc, argv, "Dd:i:p:s:")) != -1) {
 		switch (ch) {
-		case 'd':
+		case 'D':
 			daemon_off = true;
 			break;
+		case 'd':
+			delay = atoi(optarg) * 1000;
+			break;
+		case 'i':
+			iface = optarg;
+			break;
+		case 'p':
+			pidname = optarg;
+			break;
+		case 's':
+			snaplen = atoi(optarg);
+			break;
 		default:
-			fprintf(stderr, "Usage: %s [-d]\n", getprogname());
-			exit(EXIT_FAILURE);
+			usage();
 		}
 	}
-	int fd = npfd_getctl();
-	(void)close(fd);
 
-	if (!daemon_off && daemon(0, 0) == -1) {
-		err(EXIT_FAILURE, "daemon");
+	argc -= optind;
+	argv += optind;
+
+	char *filter = copyargs(argc, argv);
+
+	npfd_log_t *log = npfd_log_create(iface, filter, snaplen);
+
+	if (!daemon_off) {
+		if (daemon(0, 0) == -1)
+			err(EXIT_FAILURE, "daemon");
+		pidfile(pidname);
 	}
+
 	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();
+
+	npfd_event_loop(log, delay);
+
 	closelog();
 
 	return 0;
Index: src/usr.sbin/npf/npfd/npfd_log.c
diff -u src/usr.sbin/npf/npfd/npfd_log.c:1.3 src/usr.sbin/npf/npfd/npfd_log.c:1.4
--- src/usr.sbin/npf/npfd/npfd_log.c:1.3	Tue Dec 27 22:02:54 2016
+++ src/usr.sbin/npf/npfd/npfd_log.c	Fri Dec 30 14:55:46 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: npfd_log.c,v 1.3 2016/12/28 03:02:54 christos Exp $	*/
+/*	$NetBSD: npfd_log.c,v 1.4 2016/12/30 19:55:46 christos Exp $	*/
 
 /*-
  * Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -30,13 +30,14 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npfd_log.c,v 1.3 2016/12/28 03:02:54 christos Exp $");
+__RCSID("$NetBSD: npfd_log.c,v 1.4 2016/12/30 19:55:46 christos Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
 #include <net/if.h>
 
 #include <stdio.h>
+#include <err.h>
 #include <inttypes.h>
 #include <limits.h>
 #include <stdlib.h>
@@ -54,52 +55,60 @@ struct npfd_log {
 	pcap_dumper_t *dumper;
 };
 
+static void
+npfd_log_setfilter(npfd_log_t *ctx, const char *filter)
+{
+	struct bpf_program bprog;
+
+	if (pcap_compile(ctx->pcap, &bprog, filter, 1, 0) == -1)
+		errx(EXIT_FAILURE, "pcap_compile failed for `%s': %s", filter,
+		    pcap_geterr(ctx->pcap));
+	if (pcap_setfilter(ctx->pcap, &bprog) == -1)
+		errx(EXIT_FAILURE, "pcap_setfilter failed: %s",
+		    pcap_geterr(ctx->pcap));
+	pcap_freecode(&bprog);
+}
+
 npfd_log_t *
-npfd_log_create(unsigned if_idx)
+npfd_log_create(const char *ifname, const char *filter, int snaplen)
 {
 	npfd_log_t *ctx;
 	char errbuf[PCAP_ERRBUF_SIZE];
 
-	if ((ctx = calloc(1, sizeof(*ctx))) == NULL) {
-		syslog(LOG_ERR, "malloc failed: %m");
-		return NULL;
-	}
+	if ((ctx = calloc(1, sizeof(*ctx))) == NULL)
+		err(EXIT_FAILURE, "malloc failed");
 
 	/*
 	 * Open a live capture handle in non-blocking mode.
 	 */
-	snprintf(ctx->ifname, sizeof(ctx->ifname), NPFD_NPFLOG "%u", if_idx);
+	snprintf(ctx->ifname, sizeof(ctx->ifname), "%s", ifname);
 	ctx->pcap = pcap_create(ctx->ifname, errbuf);
-	if (ctx->pcap == NULL) {
-		syslog(LOG_ERR, "pcap_create failed: %s", errbuf);
-		goto err;
-	}
-	if (pcap_setnonblock(ctx->pcap, 1, errbuf) == -1) {
-		syslog(LOG_ERR, "pcap_setnonblock failed: %s", errbuf);
-		goto err;
-	}
+	if (ctx->pcap == NULL)
+		errx(EXIT_FAILURE, "pcap_create failed: %s", errbuf);
 
-	pcap_set_snaplen(ctx->pcap, 10240);
+	if (pcap_setnonblock(ctx->pcap, 1, errbuf) == -1)
+		errx(EXIT_FAILURE, "pcap_setnonblock failed: %s", errbuf);
 
-	if (pcap_activate(ctx->pcap) == -1) {
-		syslog(LOG_ERR, "pcap_activate failed: %s",
+	if (pcap_set_snaplen(ctx->pcap, snaplen) == -1)
+		errx(EXIT_FAILURE, "pcap_set_snaplen failed: %s",
 		    pcap_geterr(ctx->pcap));
-		goto err;
-	}
-	snprintf(ctx->path, sizeof(ctx->path), "%s/%s%s",
-	    NPFD_LOG_PATH, ctx->ifname, ".pcap");
 
-	if (!npfd_log_reopen(ctx))
-		goto err;
+	if (pcap_activate(ctx->pcap) == -1)
+		errx(EXIT_FAILURE, "pcap_activate failed: %s",
+		    pcap_geterr(ctx->pcap));
+
+	if (filter)
+		npfd_log_setfilter(ctx, filter);
+
+	snprintf(ctx->path, sizeof(ctx->path), NPFD_LOG_PATH "/%s.pcap",
+	    ctx->ifname);
 
+	npfd_log_reopen(ctx, true);
 	return ctx;
-err:
-	npfd_log_destroy(ctx);
-	return NULL;
 }
 
 bool
-npfd_log_reopen(npfd_log_t *ctx)
+npfd_log_reopen(npfd_log_t *ctx, bool die)
 {
 	if (ctx->dumper)
 		pcap_dump_close(ctx->dumper);
@@ -111,6 +120,9 @@ npfd_log_reopen(npfd_log_t *ctx)
 	else
 		ctx->dumper = pcap_dump_open(ctx->pcap, ctx->path);
 	if (ctx->dumper == NULL) {
+		if (die)
+			errx(EXIT_FAILURE, "pcap_dump_open failed for `%s': %s",
+			    ctx->path, pcap_geterr(ctx->pcap));
 		syslog(LOG_ERR, "pcap_dump_open failed for `%s': %s",
 		    ctx->path, pcap_geterr(ctx->pcap));
 		return false;
@@ -135,6 +147,17 @@ npfd_log_getsock(npfd_log_t *ctx)
 }
 
 void
+npfd_log_flush(npfd_log_t *ctx)
+{
+	if (!ctx->dumper)
+		return;
+	if (pcap_dump_flush(ctx->dumper) == -1)
+		syslog(LOG_ERR, "pcap_dump_flush failed for `%s': %m",
+		    ctx->path);
+}
+
+
+void
 npfd_log(npfd_log_t *ctx)
 {
 	pcap_dumper_t *dumper = ctx->dumper;
@@ -152,6 +175,6 @@ npfd_log_stats(npfd_log_t *ctx)
 		syslog(LOG_ERR, "pcap_stats failed: %s", pcap_geterr(pcap));
 		return;
 	}
-	syslog(LOG_NOTICE, "packet statistics: %u received, %u dropped",
-	    ps.ps_recv, ps.ps_drop);
+	syslog(LOG_INFO, "packet statistics: %s: %u received, %u dropped",
+	    ctx->ifname, ps.ps_recv, ps.ps_drop);
 }

Reply via email to