Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.sbin/npf/npfd Add log validation
details: https://anonhg.NetBSD.org/src/rev/f55cf3683a96
branches: trunk
changeset: 350163:f55cf3683a96
user: christos <christos%NetBSD.org@localhost>
date: Fri Jan 06 19:20:24 2017 +0000
description:
Add log validation
diffstat:
usr.sbin/npf/npfd/Makefile | 4 +-
usr.sbin/npf/npfd/npfd.c | 24 ++++-
usr.sbin/npf/npfd/npfd.h | 4 +-
usr.sbin/npf/npfd/npfd_log.c | 173 ++++++++++++++++++++++++++++++++++++++++--
4 files changed, 185 insertions(+), 20 deletions(-)
diffs (truncated from 350 to 300 lines):
diff -r 0d3a58f4efba -r f55cf3683a96 usr.sbin/npf/npfd/Makefile
--- a/usr.sbin/npf/npfd/Makefile Fri Jan 06 17:26:41 2017 +0000
+++ b/usr.sbin/npf/npfd/Makefile Fri Jan 06 19:20:24 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.3 2016/12/30 19:55:46 christos Exp $
+# $NetBSD: Makefile,v 1.4 2017/01/06 19:20:24 christos Exp $
#
# Public Domain
#
@@ -6,7 +6,7 @@
NOMAN=
PROG= npfd
-#DBG=-g
+DBG=-g
SRCS= npfd.c npfd_log.c
CPPFLAGS+= -I${.CURDIR}
diff -r 0d3a58f4efba -r f55cf3683a96 usr.sbin/npf/npfd/npfd.c
--- a/usr.sbin/npf/npfd/npfd.c Fri Jan 06 17:26:41 2017 +0000
+++ b/usr.sbin/npf/npfd/npfd.c Fri Jan 06 19:20:24 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: npfd.c,v 1.4 2016/12/30 19:55:46 christos Exp $ */
+/* $NetBSD: npfd.c,v 1.5 2017/01/06 19:20:24 christos Exp $ */
/*-
* Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: npfd.c,v 1.4 2016/12/30 19:55:46 christos Exp $");
+__RCSID("$NetBSD: npfd.c,v 1.5 2017/01/06 19:20:24 christos Exp $");
#include <stdio.h>
#include <string.h>
@@ -49,7 +49,7 @@
#include "npfd.h"
-static volatile sig_atomic_t hup, stats, done;
+static volatile sig_atomic_t hup, stats, done, flush;
static int
npfd_getctl(void)
@@ -87,6 +87,9 @@
if (stats) {
stats = false;
npfd_log_stats(log);
+ }
+ if (flush) {
+ flush = false;
npfd_log_flush(log);
}
switch (poll(&pfd, 1, delay)) {
@@ -118,9 +121,11 @@
done = true;
break;
case SIGINFO:
- case SIGQUIT:
stats = true;
break;
+ case SIGALRM:
+ flush = true;
+ break;
default:
syslog(LOG_ERR, "Unhandled signal %d", sig);
break;
@@ -131,7 +136,8 @@
usage(void)
{
fprintf(stderr, "Usage: %s [-D] [-d <delay>] [-i <interface>]"
- " [-p <pidfile>] [-s <snaplen>] expression\n", getprogname());
+ " [-f <filename>] [-p <pidfile>] [-s <snaplen>] expression\n",
+ getprogname());
exit(EXIT_FAILURE);
}
@@ -165,11 +171,12 @@
const char *iface = "npflog0";
int snaplen = 116;
char *pidname = NULL;
+ char *filename = NULL;
int fd = npfd_getctl();
(void)close(fd);
- while ((ch = getopt(argc, argv, "Dd:i:p:s:")) != -1) {
+ while ((ch = getopt(argc, argv, "Dd:f:i:p:s:")) != -1) {
switch (ch) {
case 'D':
daemon_off = true;
@@ -177,6 +184,9 @@
case 'd':
delay = atoi(optarg) * 1000;
break;
+ case 'f':
+ filename = optarg;
+ break;
case 'i':
iface = optarg;
break;
@@ -196,7 +206,7 @@
char *filter = copyargs(argc, argv);
- npfd_log_t *log = npfd_log_create(iface, filter, snaplen);
+ npfd_log_t *log = npfd_log_create(filename, iface, filter, snaplen);
if (!daemon_off) {
if (daemon(0, 0) == -1)
diff -r 0d3a58f4efba -r f55cf3683a96 usr.sbin/npf/npfd/npfd.h
--- a/usr.sbin/npf/npfd/npfd.h Fri Jan 06 17:26:41 2017 +0000
+++ b/usr.sbin/npf/npfd/npfd.h Fri Jan 06 19:20:24 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: npfd.h,v 1.3 2016/12/30 19:55:46 christos Exp $ */
+/* $NetBSD: npfd.h,v 1.4 2017/01/06 19:20:24 christos Exp $ */
/*-
* Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
struct npf_log;
typedef struct npfd_log npfd_log_t;
-npfd_log_t * npfd_log_create(const char *, const char *, int);
+npfd_log_t * npfd_log_create(const char *, 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);
diff -r 0d3a58f4efba -r f55cf3683a96 usr.sbin/npf/npfd/npfd_log.c
--- a/usr.sbin/npf/npfd/npfd_log.c Fri Jan 06 17:26:41 2017 +0000
+++ b/usr.sbin/npf/npfd/npfd_log.c Fri Jan 06 19:20:24 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: npfd_log.c,v 1.5 2017/01/05 16:23:31 christos Exp $ */
+/* $NetBSD: npfd_log.c,v 1.6 2017/01/06 19:20:24 christos Exp $ */
/*-
* Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -30,10 +30,12 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: npfd_log.c,v 1.5 2017/01/05 16:23:31 christos Exp $");
+__RCSID("$NetBSD: npfd_log.c,v 1.6 2017/01/06 19:20:24 christos Exp $");
#include <sys/types.h>
#include <sys/param.h>
+#include <sys/stat.h>
+
#include <net/if.h>
#include <stdio.h>
@@ -69,8 +71,138 @@
pcap_freecode(&bprog);
}
+static FILE *
+npfd_log_gethdr(npfd_log_t *ctx, struct pcap_file_header*hdr)
+{
+ FILE *fp = fopen(ctx->path, "r");
+
+ hdr->magic = 0;
+ if (fp == NULL)
+ return NULL;
+
+#define TCPDUMP_MAGIC 0xa1b2c3d4
+
+ switch (fread(hdr, sizeof(*hdr), 1, fp)) {
+ case 0:
+ hdr->magic = 0;
+ fclose(fp);
+ return NULL;
+ case 1:
+ if (hdr->magic != TCPDUMP_MAGIC ||
+ hdr->version_major != PCAP_VERSION_MAJOR ||
+ hdr->version_minor != PCAP_VERSION_MINOR)
+ goto out;
+ break;
+ default:
+ goto out;
+ }
+
+ return fp;
+out:
+ fclose(fp);
+ hdr->magic = -1;
+ return NULL;
+}
+
+static int
+npfd_log_getsnaplen(npfd_log_t *ctx)
+{
+ struct pcap_file_header hdr;
+ FILE *fp = npfd_log_gethdr(ctx, &hdr);
+ if (fp == NULL)
+ return hdr.magic == (uint32_t)-1 ? -1 : 0;
+ fclose(fp);
+ return hdr.snaplen;
+}
+
+static int
+npfd_log_validate(npfd_log_t *ctx)
+{
+ struct pcap_file_header hdr;
+ FILE *fp = npfd_log_gethdr(ctx, &hdr);
+ size_t o, no;
+
+ if (fp == NULL) {
+ if (hdr.magic == 0)
+ return 0;
+ goto rename;
+ }
+
+ struct stat st;
+ if (fstat(fileno(fp), &st) == -1)
+ goto rename;
+
+ size_t count = 0;
+ for (o = sizeof(hdr);; count++) {
+ struct {
+ uint32_t sec;
+ uint32_t usec;
+ uint32_t caplen;
+ uint32_t len;
+ } pkt;
+ switch (fread(&pkt, sizeof(pkt), 1, fp)) {
+ case 0:
+ syslog(LOG_INFO, "%zu packets read from `%s'", count,
+ ctx->path);
+ fclose(fp);
+ return hdr.snaplen;
+ case 1:
+ no = o + sizeof(pkt) + pkt.caplen;
+ if (pkt.caplen > hdr.snaplen)
+ goto fix;
+ if (no > (size_t)st.st_size)
+ goto fix;
+ if (fseeko(fp, pkt.caplen, SEEK_CUR) != 0)
+ goto fix;
+ o = no;
+ break;
+ default:
+ goto fix;
+ }
+ }
+
+fix:
+ fclose(fp);
+ no = st.st_size - o;
+ syslog(LOG_INFO, "%zu packets read from `%s', %zu extra bytes",
+ count, ctx->path, no);
+ if (no < 10240) {
+ syslog(LOG_WARNING,
+ "Incomplete last packet in `%s', truncating",
+ ctx->path);
+ if (truncate(ctx->path, o) == -1) {
+ syslog(LOG_ERR, "Cannot truncate `%s': %m", ctx->path);
+ goto rename;
+ }
+ } else {
+ syslog(LOG_ERR, "Corrupt file `%s'", ctx->path);
+ goto rename;
+ }
+ fclose(fp);
+ return hdr.snaplen;
+rename:
+ fclose(fp);
+ char tmp[MAXPATHLEN];
+ snprintf(tmp, sizeof(tmp), "%s.XXXXXX", ctx->path);
+ int fd;
+ if ((fd = mkstemp(tmp)) == -1) {
+ syslog(LOG_ERR, "Can't make temp file `%s': %m", tmp);
+ return -1;
+ }
+ close(fd);
+ if (rename(ctx->path, tmp) == -1) {
+ syslog(LOG_ERR, "Can't rename `%s' to `%s': %m",
+ ctx->path, tmp);
+ return -1;
+ }
+ syslog(LOG_ERR, "Renamed to `%s'", tmp);
+ return 0;
+}
+
+
npfd_log_t *
-npfd_log_create(const char *ifname, const char *filter, int snaplen)
+npfd_log_create(const char *filename, const char *ifname, const char *filter,
+ int snaplen)
{
npfd_log_t *ctx;
char errbuf[PCAP_ERRBUF_SIZE];
@@ -89,6 +221,22 @@
if (pcap_setnonblock(ctx->pcap, 1, errbuf) == -1)
errx(EXIT_FAILURE, "pcap_setnonblock failed: %s", errbuf);
+ if (filename == NULL)
+ snprintf(ctx->path, sizeof(ctx->path), NPFD_LOG_PATH "/%s.pcap",
+ ctx->ifname);
+ else
Home |
Main Index |
Thread Index |
Old Index