summaryrefslogtreecommitdiffstats
path: root/contrib/pf/pflogd/pflogd.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/pf/pflogd/pflogd.c')
-rw-r--r--contrib/pf/pflogd/pflogd.c134
1 files changed, 106 insertions, 28 deletions
diff --git a/contrib/pf/pflogd/pflogd.c b/contrib/pf/pflogd/pflogd.c
index b470ae1..2fc2338 100644
--- a/contrib/pf/pflogd/pflogd.c
+++ b/contrib/pf/pflogd/pflogd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pflogd.c,v 1.37 2006/10/26 13:34:47 jmc Exp $ */
+/* $OpenBSD: pflogd.c,v 1.46 2008/10/22 08:16:49 henning Exp $ */
/*
* Copyright (c) 2001 Theo de Raadt
@@ -37,9 +37,8 @@ __FBSDID("$FreeBSD$");
#include <sys/ioctl.h>
#include <sys/file.h>
#include <sys/stat.h>
-#ifdef __FreeBSD__
-#include <net/bpf.h> /* BIOCLOCK */
-#endif
+#include <sys/socket.h>
+#include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -48,15 +47,16 @@ __FBSDID("$FreeBSD$");
#include <pcap.h>
#include <syslog.h>
#include <signal.h>
+#include <err.h>
#include <errno.h>
#include <stdarg.h>
#include <fcntl.h>
#ifdef __FreeBSD__
+#include <ifaddrs.h>
#include "pidfile.h"
#else
#include <util.h>
#endif
-
#include "pflogd.h"
pcap_t *hpcap;
@@ -66,7 +66,7 @@ int Debug = 0;
static int snaplen = DEF_SNAPLEN;
static int cur_snaplen = DEF_SNAPLEN;
-volatile sig_atomic_t gotsig_close, gotsig_alrm, gotsig_hup;
+volatile sig_atomic_t gotsig_close, gotsig_alrm, gotsig_hup, gotsig_usr1;
char *filename = PFLOGD_LOG_FILE;
char *interface = PFLOGD_DEFAULT_IF;
@@ -80,7 +80,9 @@ unsigned int delay = FLUSH_DELAY;
char *copy_argv(char * const *);
void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
void dump_packet_nobuf(u_char *, const struct pcap_pkthdr *, const u_char *);
+void log_pcap_stats(void);
int flush_buffer(FILE *);
+int if_exists(char *);
int init_pcap(void);
void logmsg(int, const char *, ...);
void purge_buffer(void);
@@ -89,6 +91,7 @@ int scan_dump(FILE *, off_t);
int set_snaplen(int);
void set_suspended(int);
void sig_alrm(int);
+void sig_usr1(int);
void sig_close(int);
void sig_hup(int);
void usage(void);
@@ -166,8 +169,8 @@ __dead void
usage(void)
{
fprintf(stderr, "usage: pflogd [-Dx] [-d delay] [-f filename]");
- fprintf(stderr, " [-i interface] [-s snaplen]\n");
- fprintf(stderr, " [expression]\n");
+ fprintf(stderr, " [-i interface] [-p pidfile]\n");
+ fprintf(stderr, " [-s snaplen] [expression]\n");
exit(1);
}
@@ -190,6 +193,12 @@ sig_alrm(int sig)
}
void
+sig_usr1(int sig)
+{
+ gotsig_usr1 = 1;
+}
+
+void
set_pcap_filter(void)
{
struct bpf_program bprog;
@@ -204,6 +213,51 @@ set_pcap_filter(void)
}
int
+if_exists(char *ifname)
+{
+#ifdef __FreeBSD__
+ struct ifaddrs *ifdata, *mb;
+ int exists = 0;
+
+ getifaddrs(&ifdata);
+ if (ifdata == NULL)
+ return (0);
+
+ for (mb = ifdata; mb != NULL; mb = mb->ifa_next) {
+ if (mb == NULL)
+ continue;
+ if (strlen(ifname) != strlen(mb->ifa_name))
+ continue;
+ if (strncmp(ifname, mb->ifa_name, strlen(ifname)) != 0)
+ continue;
+ exists = 1;
+ break;
+ }
+ freeifaddrs(ifdata);
+
+ return (exists);
+#else
+ int s;
+ struct ifreq ifr;
+ struct if_data ifrdat;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+ err(1, "socket");
+ bzero(&ifr, sizeof(ifr));
+ if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)) >=
+ sizeof(ifr.ifr_name))
+ errx(1, "main ifr_name: strlcpy");
+ ifr.ifr_data = (caddr_t)&ifrdat;
+ if (ioctl(s, SIOCGIFDATA, (caddr_t)&ifr) == -1)
+ return (0);
+ if (close(s))
+ err(1, "close");
+
+ return (1);
+#endif
+}
+
+int
init_pcap(void)
{
hpcap = pcap_open_live(interface, snaplen, 1, PCAP_TO_MS, errbuf);
@@ -554,10 +608,10 @@ dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
return;
}
- append:
+ append:
#ifdef __FreeBSD__
- sh.ts.tv_sec = (bpf_int32)h->ts.tv_sec;
- sh.ts.tv_usec = (bpf_int32)h->ts.tv_usec;
+ sh.ts.tv_sec = (bpf_int32)h->ts.tv_sec;
+ sh.ts.tv_usec = (bpf_int32)h->ts.tv_usec;
sh.caplen = h->caplen;
sh.len = h->len;
@@ -575,17 +629,31 @@ dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
return;
}
+void
+log_pcap_stats(void)
+{
+ struct pcap_stat pstat;
+ if (pcap_stats(hpcap, &pstat) < 0)
+ logmsg(LOG_WARNING, "Reading stats: %s", pcap_geterr(hpcap));
+ else
+ logmsg(LOG_NOTICE,
+ "%u packets received, %u/%u dropped (kernel/pflogd)",
+ pstat.ps_recv, pstat.ps_drop, packets_dropped);
+}
+
int
main(int argc, char **argv)
{
- struct pcap_stat pstat;
- int ch, np, Xflag = 0;
+ int ch, np, ret, Xflag = 0;
pcap_handler phandler = dump_packet;
const char *errstr = NULL;
+ char *pidf = NULL;
+
+ ret = 0;
closefrom(STDERR_FILENO + 1);
- while ((ch = getopt(argc, argv, "Dxd:f:i:s:")) != -1) {
+ while ((ch = getopt(argc, argv, "Dxd:f:i:p:s:")) != -1) {
switch (ch) {
case 'D':
Debug = 1;
@@ -601,6 +669,9 @@ main(int argc, char **argv)
case 'i':
interface = optarg;
break;
+ case 'p':
+ pidf = optarg;
+ break;
case 's':
snaplen = strtonum(optarg, 0, PFLOGD_MAXSNAPLEN,
&errstr);
@@ -622,13 +693,21 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
+ /* does interface exist */
+ if (!if_exists(interface)) {
+ warn("Failed to initialize: %s", interface);
+ logmsg(LOG_ERR, "Failed to initialize: %s", interface);
+ logmsg(LOG_ERR, "Exiting, init failure");
+ exit(1);
+ }
+
if (!Debug) {
openlog("pflogd", LOG_PID | LOG_CONS, LOG_DAEMON);
if (daemon(0, 0)) {
logmsg(LOG_WARNING, "Failed to become daemon: %s",
strerror(errno));
}
- pidfile(NULL);
+ pidfile(pidf);
}
tzset();
@@ -659,6 +738,7 @@ main(int argc, char **argv)
signal(SIGINT, sig_close);
signal(SIGQUIT, sig_close);
signal(SIGALRM, sig_alrm);
+ signal(SIGUSR1, sig_usr1);
signal(SIGHUP, sig_hup);
alarm(delay);
@@ -686,13 +766,12 @@ main(int argc, char **argv)
np = pcap_dispatch(hpcap, PCAP_NUM_PKTS,
phandler, (u_char *)dpcap);
if (np < 0) {
-#ifdef __FreeBSD__
- if (errno == ENXIO) {
- logmsg(LOG_ERR,
- "Device not/no longer configured");
+ if (!if_exists(interface) == -1) {
+ logmsg(LOG_NOTICE, "interface %s went away",
+ interface);
+ ret = -1;
break;
}
-#endif
logmsg(LOG_NOTICE, "%s", pcap_geterr(hpcap));
}
@@ -715,6 +794,11 @@ main(int argc, char **argv)
gotsig_alrm = 0;
alarm(delay);
}
+
+ if (gotsig_usr1) {
+ log_pcap_stats();
+ gotsig_usr1 = 0;
+ }
}
logmsg(LOG_NOTICE, "Exiting");
@@ -724,15 +808,9 @@ main(int argc, char **argv)
}
purge_buffer();
- if (pcap_stats(hpcap, &pstat) < 0)
- logmsg(LOG_WARNING, "Reading stats: %s", pcap_geterr(hpcap));
- else
- logmsg(LOG_NOTICE,
- "%u packets received, %u/%u dropped (kernel/pflogd)",
- pstat.ps_recv, pstat.ps_drop, packets_dropped);
-
+ log_pcap_stats();
pcap_close(hpcap);
if (!Debug)
closelog();
- return (0);
+ return (ret);
}
OpenPOWER on IntegriCloud