I think this will help pflogd sleep better at night...

My understanding of the pcap/bpf timeout is that it will always wait that
long, even if packets are received, so that you don't get one read() per
packet. But using this timeout doesn't mean wait forever until you get
something.

We can put a "long" poll() in front of pcap to wait until there are packets
(maybe never if you aren't using pf logging), and then let the timeout work
it's magic.


Index: pflogd.c
===================================================================
RCS file: /cvs/src/sbin/pflogd/pflogd.c,v
retrieving revision 1.51
diff -u -p -r1.51 pflogd.c
--- pflogd.c    7 Feb 2015 02:09:13 -0000       1.51
+++ pflogd.c    22 Sep 2015 00:08:16 -0000
@@ -35,6 +35,8 @@
 #include <sys/stat.h>
 #include <sys/socket.h>
 #include <net/if.h>
+
+#include <poll.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -575,6 +577,7 @@ main(int argc, char **argv)
        int ch, np, ret, Xflag = 0;
        pcap_handler phandler = dump_packet;
        const char *errstr = NULL;
+       struct pollfd pfd;
 
        ret = 0;
 
@@ -685,9 +688,16 @@ main(int argc, char **argv)
        } else if (Xflag)
                return (0);
 
+       pfd.fd = pcap_get_selectable_fd(hpcap);
+       pfd.events = POLLIN;
        while (1) {
-               np = pcap_dispatch(hpcap, PCAP_NUM_PKTS,
-                   phandler, (u_char *)dpcap);
+               np = 0;
+               if (poll(&pfd, 1, INFTIM) == 1) {
+                       np = pcap_dispatch(hpcap, PCAP_NUM_PKTS,
+                           phandler, (u_char *)dpcap);
+               } else if (pfd.revents & (POLLERR|POLLHUP)) {
+                       np = -1;
+               }
                if (np < 0) {
                        if (!if_exists(interface)) {
                                logmsg(LOG_NOTICE, "interface %s went away",

Reply via email to