From e15f804c7b67f7cac4a68d0f6b6d0418e9f7309a Mon Sep 17 00:00:00 2001 From: bz Date: Tue, 28 Jun 2011 11:57:25 +0000 Subject: Update packet filter (pf) code to OpenBSD 4.5. You need to update userland (world and ports) tools to be in sync with the kernel. Submitted by: mlaier Submitted by: eri --- contrib/pf/pflogd/pflogd.8 | 22 ++++-- contrib/pf/pflogd/pflogd.c | 134 +++++++++++++++++++++++++++++-------- contrib/pf/pflogd/privsep.c | 8 +-- contrib/pf/pflogd/privsep_fdpass.c | 20 ++++-- 4 files changed, 138 insertions(+), 46 deletions(-) (limited to 'contrib/pf/pflogd') diff --git a/contrib/pf/pflogd/pflogd.8 b/contrib/pf/pflogd/pflogd.8 index 22643fc..38c954c 100644 --- a/contrib/pf/pflogd/pflogd.8 +++ b/contrib/pf/pflogd/pflogd.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pflogd.8,v 1.32 2006/12/08 10:26:38 joel Exp $ +.\" $OpenBSD: pflogd.8,v 1.37 2008/10/22 08:16:49 henning Exp $ .\" .\" Copyright (c) 2001 Can Erkin Acar. All rights reserved. .\" @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 9, 2001 +.Dd October 22 2008 .Dt PFLOGD 8 .Os .Sh NAME @@ -34,12 +34,14 @@ .Nd packet filter logging daemon .Sh SYNOPSIS .Nm pflogd +.Bk -words .Op Fl Dx .Op Fl d Ar delay .Op Fl f Ar filename .Op Fl i Ar interface .Op Fl s Ar snaplen .Op Ar expression +.Ek .Sh DESCRIPTION .Nm is a background daemon which reads packets logged by @@ -94,6 +96,13 @@ or a .Dv SIGALRM is received. .Pp +.Nm +will also log the pcap statistics for the +.Xr pflog 4 +interface to syslog when a +.Dv SIGUSR1 +is received. +.Pp The options are as follows: .Bl -tag -width Ds .It Fl D @@ -116,6 +125,11 @@ By default, .Nm will use .Ar pflog0 . +Writes a file containing the process ID of the program to +.Pa /var/run . +The file name has the form +The default is +.Ar pflogd . .It Fl s Ar snaplen Analyze at most the first .Ar snaplen @@ -204,12 +218,12 @@ the wi0 interface: # tcpdump -n -e -ttt -i pflog0 inbound and action block and on wi0 .Ed .Sh SEE ALSO -.Xr tcpdump 1 , .Xr pcap 3 , .Xr pf 4 , .Xr pflog 4 , .Xr pf.conf 5 , -.Xr newsyslog 8 +.Xr newsyslog 8 , +.Xr tcpdump 1 .Sh HISTORY The .Nm 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 #include #include -#ifdef __FreeBSD__ -#include /* BIOCLOCK */ -#endif +#include +#include #include #include #include @@ -48,15 +47,16 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include #ifdef __FreeBSD__ +#include #include "pidfile.h" #else #include #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); } diff --git a/contrib/pf/pflogd/privsep.c b/contrib/pf/pflogd/privsep.c index a07d141..2e3895d 100644 --- a/contrib/pf/pflogd/privsep.c +++ b/contrib/pf/pflogd/privsep.c @@ -23,6 +23,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -31,20 +32,13 @@ __FBSDID("$FreeBSD$"); #include #include #include -#ifndef __FreeBSD__ #include #include -#endif #include #include #include #include #include -#ifdef __FreeBSD__ -/* XXX: pcap pollutes namespace with strlcpy if not present previously */ -#include -#include -#endif #include #include #include "pflogd.h" diff --git a/contrib/pf/pflogd/privsep_fdpass.c b/contrib/pf/pflogd/privsep_fdpass.c index 50afdfc..0e6c3c4 100644 --- a/contrib/pf/pflogd/privsep_fdpass.c +++ b/contrib/pf/pflogd/privsep_fdpass.c @@ -1,4 +1,4 @@ -/* $OpenBSD: privsep_fdpass.c,v 1.2 2004/08/13 02:51:48 djm Exp $ */ +/* $OpenBSD: privsep_fdpass.c,v 1.5 2008/03/24 16:11:08 deraadt Exp $ */ /* * Copyright 2001 Niels Provos @@ -50,7 +50,10 @@ void send_fd(int sock, int fd) { struct msghdr msg; - char tmp[CMSG_SPACE(sizeof(int))]; + union { + struct cmsghdr hdr; + char buf[CMSG_SPACE(sizeof(int))]; + } cmsgbuf; struct cmsghdr *cmsg; struct iovec vec; int result = 0; @@ -59,8 +62,8 @@ send_fd(int sock, int fd) memset(&msg, 0, sizeof(msg)); if (fd >= 0) { - msg.msg_control = (caddr_t)tmp; - msg.msg_controllen = CMSG_LEN(sizeof(int)); + msg.msg_control = (caddr_t)&cmsgbuf.buf; + msg.msg_controllen = sizeof(cmsgbuf.buf); cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_len = CMSG_LEN(sizeof(int)); cmsg->cmsg_level = SOL_SOCKET; @@ -86,7 +89,10 @@ int receive_fd(int sock) { struct msghdr msg; - char tmp[CMSG_SPACE(sizeof(int))]; + union { + struct cmsghdr hdr; + char buf[CMSG_SPACE(sizeof(int))]; + } cmsgbuf; struct cmsghdr *cmsg; struct iovec vec; ssize_t n; @@ -98,8 +104,8 @@ receive_fd(int sock) vec.iov_len = sizeof(int); msg.msg_iov = &vec; msg.msg_iovlen = 1; - msg.msg_control = tmp; - msg.msg_controllen = sizeof(tmp); + msg.msg_control = &cmsgbuf.buf; + msg.msg_controllen = sizeof(cmsgbuf.buf); if ((n = recvmsg(sock, &msg, 0)) == -1) warn("%s: recvmsg", __func__); -- cgit v1.1