Tue Jan 24 20:24:59 2017 UTC ()
output every 5 seconds instead of 60 or every 100 packets


(christos)
diff -r1.6 -r1.7 src/usr.sbin/npf/npfd/npfd.c

cvs diff -r1.6 -r1.7 src/usr.sbin/npf/npfd/npfd.c (switch to unified diff)

--- src/usr.sbin/npf/npfd/npfd.c 2017/01/07 16:48:03 1.6
+++ src/usr.sbin/npf/npfd/npfd.c 2017/01/24 20:24:59 1.7
@@ -1,230 +1,237 @@ @@ -1,230 +1,237 @@
1/* $NetBSD: npfd.c,v 1.6 2017/01/07 16:48:03 christos Exp $ */ 1/* $NetBSD: npfd.c,v 1.7 2017/01/24 20:24:59 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2015 The NetBSD Foundation, Inc. 4 * Copyright (c) 2015 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Mindaugas Rasiukevicius. 8 * by Mindaugas Rasiukevicius.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__RCSID("$NetBSD: npfd.c,v 1.6 2017/01/07 16:48:03 christos Exp $"); 33__RCSID("$NetBSD: npfd.c,v 1.7 2017/01/24 20:24:59 christos Exp $");
34 34
35#include <stdio.h> 35#include <stdio.h>
36#include <string.h> 36#include <string.h>
37#include <fcntl.h> 37#include <fcntl.h>
38#include <signal.h> 38#include <signal.h>
39#include <stdlib.h> 39#include <stdlib.h>
40#include <unistd.h> 40#include <unistd.h>
41#include <stdbool.h> 41#include <stdbool.h>
42#include <poll.h> 42#include <poll.h>
43#include <errno.h> 43#include <errno.h>
44#include <err.h> 44#include <err.h>
45#include <syslog.h> 45#include <syslog.h>
46#include <util.h> 46#include <util.h>
47 47
48#include <net/npf.h> 48#include <net/npf.h>
49 49
50#include "npfd.h" 50#include "npfd.h"
51 51
52static volatile sig_atomic_t hup, stats, done, flush; 52static volatile sig_atomic_t hup, stats, done, flush;
53 53
54static int 54static int
55npfd_getctl(void) 55npfd_getctl(void)
56{ 56{
57 int fd, ver; 57 int fd, ver;
58 58
59 fd = open(NPF_DEV_PATH, O_RDONLY); 59 fd = open(NPF_DEV_PATH, O_RDONLY);
60 if (fd == -1) { 60 if (fd == -1) {
61 err(EXIT_FAILURE, "cannot open '%s'", NPF_DEV_PATH); 61 err(EXIT_FAILURE, "cannot open '%s'", NPF_DEV_PATH);
62 } 62 }
63 if (ioctl(fd, IOC_NPF_VERSION, &ver) == -1) { 63 if (ioctl(fd, IOC_NPF_VERSION, &ver) == -1) {
64 err(EXIT_FAILURE, "ioctl(IOC_NPF_VERSION)"); 64 err(EXIT_FAILURE, "ioctl(IOC_NPF_VERSION)");
65 } 65 }
66 if (ver != NPF_VERSION) { 66 if (ver != NPF_VERSION) {
67 errx(EXIT_FAILURE, 67 errx(EXIT_FAILURE,
68 "Incompatible NPF interface version (%d, kernel %d)\n" 68 "Incompatible NPF interface version (%d, kernel %d)\n"
69 "Hint: update userland?", NPF_VERSION, ver); 69 "Hint: update userland?", NPF_VERSION, ver);
70 } 70 }
71 return fd; 71 return fd;
72} 72}
73 73
74static void 74static void
75npfd_event_loop(npfd_log_t *log, int delay) 75npfd_event_loop(npfd_log_t *log, int delay)
76{ 76{
77 struct pollfd pfd; 77 struct pollfd pfd;
 78 size_t count = 0;
78 79
79 pfd.fd = npfd_log_getsock(log); 80 pfd.fd = npfd_log_getsock(log);
80 pfd.events = POLLHUP | POLLIN; 81 pfd.events = POLLHUP | POLLIN;
81 82
82 while (!done) { 83 while (!done) {
83 if (hup) { 84 if (hup) {
84 hup = false; 85 hup = false;
85 npfd_log_reopen(log, false); 86 npfd_log_reopen(log, false);
86 } 87 }
87 if (stats) { 88 if (stats) {
88 stats = false; 89 stats = false;
89 npfd_log_stats(log); 90 npfd_log_stats(log);
90 } 91 }
91 if (flush) { 92 if (flush) {
92 flush = false; 93 flush = false;
93 npfd_log_flush(log); 94 npfd_log_flush(log);
 95 count = 0;
94 } 96 }
95 switch (poll(&pfd, 1, delay)) { 97 switch (poll(&pfd, 1, delay)) {
96 case -1: 98 case -1:
97 if (errno == EINTR) 99 if (errno == EINTR)
98 continue; 100 continue;
99 syslog(LOG_ERR, "poll failed: %m"); 101 syslog(LOG_ERR, "poll failed: %m");
100 exit(EXIT_FAILURE); 102 exit(EXIT_FAILURE);
101 /*NOTREACHED*/ 103 /*NOTREACHED*/
102 case 0: 104 case 0:
103 npfd_log_flush(log); 105 npfd_log_flush(log);
 106 count = 0;
104 continue; 107 continue;
105 default: 108 default:
 109 if (count++ >= 100) {
 110 npfd_log_flush(log);
 111 count = 0;
 112 }
106 npfd_log(log); 113 npfd_log(log);
107 } 114 }
108 115
109 } 116 }
110 npfd_log_destroy(log); 117 npfd_log_destroy(log);
111} 118}
112 119
113static void 120static void
114sighandler(int sig) 121sighandler(int sig)
115{ 122{
116 switch (sig) { 123 switch (sig) {
117 case SIGHUP: 124 case SIGHUP:
118 hup = true; 125 hup = true;
119 break; 126 break;
120 case SIGTERM: 127 case SIGTERM:
121 case SIGINT: 128 case SIGINT:
122 done = true; 129 done = true;
123 break; 130 break;
124 case SIGINFO: 131 case SIGINFO:
125 stats = true; 132 stats = true;
126 break; 133 break;
127 case SIGALRM: 134 case SIGALRM:
128 flush = true; 135 flush = true;
129 break; 136 break;
130 default: 137 default:
131 syslog(LOG_ERR, "Unhandled signal %d", sig); 138 syslog(LOG_ERR, "Unhandled signal %d", sig);
132 break; 139 break;
133 } 140 }
134} 141}
135 142
136static __dead void 143static __dead void
137usage(void) 144usage(void)
138{ 145{
139 fprintf(stderr, "Usage: %s [-D] [-d <delay>] [-i <interface>]" 146 fprintf(stderr, "Usage: %s [-D] [-d <delay>] [-i <interface>]"
140 " [-f <filename>] [-p <pidfile>] [-s <snaplen>] expression\n", 147 " [-f <filename>] [-p <pidfile>] [-s <snaplen>] expression\n",
141 getprogname()); 148 getprogname());
142 exit(EXIT_FAILURE); 149 exit(EXIT_FAILURE);
143} 150}
144 151
145static char * 152static char *
146copyargs(int argc, char **argv) 153copyargs(int argc, char **argv)
147{ 154{
148 if (argc == 0) 155 if (argc == 0)
149 return NULL; 156 return NULL;
150 157
151 size_t len = 0, p = 0; 158 size_t len = 0, p = 0;
152 char *buf = NULL; 159 char *buf = NULL;
153 160
154 for (int i = 0; i < argc; i++) { 161 for (int i = 0; i < argc; i++) {
155 size_t l = strlen(argv[i]); 162 size_t l = strlen(argv[i]);
156 if (p + l + 1 >= len) 163 if (p + l + 1 >= len)
157 buf = erealloc(buf, len = p + l + 1); 164 buf = erealloc(buf, len = p + l + 1);
158 memcpy(buf + p, argv[i], l); 165 memcpy(buf + p, argv[i], l);
159 p += l; 166 p += l;
160 buf[p++] = i == argc - 1 ? '\0' : ' '; 167 buf[p++] = i == argc - 1 ? '\0' : ' ';
161 } 168 }
162 return buf; 169 return buf;
163} 170}
164 171
165int 172int
166main(int argc, char **argv) 173main(int argc, char **argv)
167{ 174{
168 bool daemon_off = false; 175 bool daemon_off = false;
169 int ch; 176 int ch;
170 177
171 int delay = 60 * 1000; 178 int delay = 5 * 1000;
172 const char *iface = "npflog0"; 179 const char *iface = "npflog0";
173 int snaplen = 116; 180 int snaplen = 116;
174 char *pidname = NULL; 181 char *pidname = NULL;
175 char *filename = NULL; 182 char *filename = NULL;
176 183
177 int fd = npfd_getctl(); 184 int fd = npfd_getctl();
178 (void)close(fd); 185 (void)close(fd);
179 186
180 while ((ch = getopt(argc, argv, "Dd:f:i:p:s:")) != -1) { 187 while ((ch = getopt(argc, argv, "Dd:f:i:p:s:")) != -1) {
181 switch (ch) { 188 switch (ch) {
182 case 'D': 189 case 'D':
183 daemon_off = true; 190 daemon_off = true;
184 break; 191 break;
185 case 'd': 192 case 'd':
186 delay = atoi(optarg) * 1000; 193 delay = atoi(optarg) * 1000;
187 break; 194 break;
188 case 'f': 195 case 'f':
189 filename = optarg; 196 filename = optarg;
190 break; 197 break;
191 case 'i': 198 case 'i':
192 iface = optarg; 199 iface = optarg;
193 break; 200 break;
194 case 'p': 201 case 'p':
195 pidname = optarg; 202 pidname = optarg;
196 break; 203 break;
197 case 's': 204 case 's':
198 snaplen = atoi(optarg); 205 snaplen = atoi(optarg);
199 break; 206 break;
200 default: 207 default:
201 usage(); 208 usage();
202 } 209 }
203 } 210 }
204 211
205 argc -= optind; 212 argc -= optind;
206 argv += optind; 213 argv += optind;
207 214
208 char *filter = copyargs(argc, argv); 215 char *filter = copyargs(argc, argv);
209 216
210 npfd_log_t *log = npfd_log_create(filename, iface, filter, snaplen); 217 npfd_log_t *log = npfd_log_create(filename, iface, filter, snaplen);
211 218
212 if (!daemon_off) { 219 if (!daemon_off) {
213 if (daemon(0, 0) == -1) 220 if (daemon(0, 0) == -1)
214 err(EXIT_FAILURE, "daemon"); 221 err(EXIT_FAILURE, "daemon");
215 pidfile(pidname); 222 pidfile(pidname);
216 } 223 }
217 224
218 openlog(argv[0], LOG_PID | LOG_NDELAY | LOG_CONS, LOG_DAEMON); 225 openlog(argv[0], LOG_PID | LOG_NDELAY | LOG_CONS, LOG_DAEMON);
219 signal(SIGHUP, sighandler); 226 signal(SIGHUP, sighandler);
220 signal(SIGINT, sighandler); 227 signal(SIGINT, sighandler);
221 signal(SIGTERM, sighandler); 228 signal(SIGTERM, sighandler);
222 signal(SIGINFO, sighandler); 229 signal(SIGINFO, sighandler);
223 signal(SIGQUIT, sighandler); 230 signal(SIGQUIT, sighandler);
224 231
225 npfd_event_loop(log, delay); 232 npfd_event_loop(log, delay);
226 233
227 closelog(); 234 closelog();
228 235
229 return 0; 236 return 0;
230} 237}