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