pcap-pf.c revision 190225
183828Sdfr/*
283828Sdfr * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
3164010Smarcel *	The Regents of the University of California.  All rights reserved.
483828Sdfr *
583828Sdfr * Redistribution and use in source and binary forms, with or without
683828Sdfr * modification, are permitted provided that: (1) source code distributions
783828Sdfr * retain the above copyright notice and this paragraph in its entirety, (2)
883828Sdfr * distributions including binary code include the above copyright notice and
983828Sdfr * this paragraph in its entirety in the documentation or other materials
1083828Sdfr * provided with the distribution, and (3) all advertising materials mentioning
1183828Sdfr * features or use of this software display the following acknowledgement:
1283828Sdfr * ``This product includes software developed by the University of California,
1383828Sdfr * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1483828Sdfr * the University nor the names of its contributors may be used to endorse
1583828Sdfr * or promote products derived from this software without specific prior
1683828Sdfr * written permission.
1783828Sdfr * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1883828Sdfr * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1983828Sdfr * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2083828Sdfr *
2183828Sdfr * packet filter subroutines for tcpdump
2283828Sdfr *	Extraction/creation by Jeffrey Mogul, DECWRL
2383828Sdfr */
2483828Sdfr
2583828Sdfr#ifndef lint
2683828Sdfrstatic const char rcsid[] _U_ =
2783828Sdfr    "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.94.2.3 2008-04-14 20:41:52 guy Exp $ (LBL)";
28124140Sobrien#endif
29124140Sobrien
30124140Sobrien#ifdef HAVE_CONFIG_H
3183828Sdfr#include "config.h"
3283828Sdfr#endif
3383828Sdfr
3483828Sdfr#include <sys/types.h>
3583828Sdfr#include <sys/time.h>
3683828Sdfr#include <sys/timeb.h>
3783828Sdfr#include <sys/socket.h>
3883828Sdfr#include <sys/file.h>
39164010Smarcel#include <sys/ioctl.h>
40164010Smarcel#include <net/pfilt.h>
4183828Sdfr
4283828Sdfrstruct mbuf;
4383828Sdfrstruct rtentry;
44164010Smarcel#include <net/if.h>
4583828Sdfr
46164010Smarcel#include <netinet/in.h>
47164010Smarcel#include <netinet/in_systm.h>
48164010Smarcel#include <netinet/ip.h>
49164010Smarcel#include <netinet/if_ether.h>
50164010Smarcel#include <netinet/ip_var.h>
51164010Smarcel#include <netinet/udp.h>
52164010Smarcel#include <netinet/udp_var.h>
53292625Semaste#include <netinet/tcp.h>
54164010Smarcel#include <netinet/tcpip.h>
55164010Smarcel
56164010Smarcel#include <ctype.h>
57164010Smarcel#include <errno.h>
58164010Smarcel#include <netdb.h>
59164010Smarcel#include <stdio.h>
60164010Smarcel#include <stdlib.h>
61164010Smarcel#include <string.h>
62164010Smarcel#include <unistd.h>
63164010Smarcel
64164010Smarcel/*
6593409Smarcel * Make "pcap.h" not include "pcap/bpf.h"; we are going to include the
6693409Smarcel * native OS version, as we need various BPF ioctls from it.
6793409Smarcel */
6893409Smarcel#define PCAP_DONT_INCLUDE_PCAP_BPF_H
6993409Smarcel#include <net/bpf.h>
7093409Smarcel
7193409Smarcel#include "pcap-int.h"
7293409Smarcel
7393409Smarcel#ifdef HAVE_OS_PROTO_H
7493409Smarcel#include "os-proto.h"
7593409Smarcel#endif
7693409Smarcel
7793409Smarcelstatic int pcap_setfilter_pf(pcap_t *, struct bpf_program *);
7893409Smarcel
7993409Smarcel/*
8093409Smarcel * BUFSPACE is the size in bytes of the packet read buffer.  Most tcpdump
8193409Smarcel * applications aren't going to need more than 200 bytes of packet header
8293409Smarcel * and the read shouldn't return more packets than packetfilter's internal
8393409Smarcel * queue limit (bounded at 256).
8493409Smarcel */
8593409Smarcel#define BUFSPACE (200 * 256)
8693409Smarcel
8793409Smarcelstatic int
8893409Smarcelpcap_read_pf(pcap_t *pc, int cnt, pcap_handler callback, u_char *user)
8993409Smarcel{
9093409Smarcel	register u_char *p, *bp;
9193409Smarcel	register int cc, n, buflen, inc;
9293409Smarcel	register struct enstamp *sp;
9393409Smarcel#ifdef LBL_ALIGN
9493409Smarcel	struct enstamp stamp;
9593409Smarcel#endif
9693409Smarcel#ifdef PCAP_FDDIPAD
9793409Smarcel	register int pad;
9893409Smarcel#endif
99164010Smarcel
10083828Sdfr again:
10183828Sdfr	cc = pc->cc;
102277943Sambrisko	if (cc == 0) {
10383828Sdfr		cc = read(pc->fd, (char *)pc->buffer + pc->offset, pc->bufsize);
104300810Sjhb		if (cc < 0) {
105277943Sambrisko			if (errno == EWOULDBLOCK)
106277943Sambrisko				return (0);
10783828Sdfr			if (errno == EINVAL &&
10883828Sdfr			    lseek(pc->fd, 0L, SEEK_CUR) + pc->bufsize < 0) {
109164010Smarcel				/*
11083828Sdfr				 * Due to a kernel bug, after 2^31 bytes,
11183828Sdfr				 * the kernel file offset overflows and
11283828Sdfr				 * read fails with EINVAL. The lseek()
11383828Sdfr				 * to 0 will fix things.
11483828Sdfr				 */
11583828Sdfr				(void)lseek(pc->fd, 0L, SEEK_SET);
116164010Smarcel				goto again;
11783828Sdfr			}
11883828Sdfr			snprintf(pc->errbuf, sizeof(pc->errbuf), "pf read: %s",
11993403Smarcel				pcap_strerror(errno));
12093403Smarcel			return (-1);
12183828Sdfr		}
12293403Smarcel		bp = pc->buffer + pc->offset;
12383828Sdfr	} else
12493403Smarcel		bp = pc->bp;
125300791Sjhb	/*
126300791Sjhb	 * Loop through each packet.
12793403Smarcel	 */
12883828Sdfr	n = 0;
12993403Smarcel#ifdef PCAP_FDDIPAD
130164010Smarcel	pad = pc->fddipad;
13193403Smarcel#endif
13293403Smarcel	while (cc > 0) {
13393403Smarcel		/*
134100389Speter		 * Has "pcap_breakloop()" been called?
13593403Smarcel		 * If so, return immediately - if we haven't read any
136100389Speter		 * packets, clear the flag and return -2 to indicate
137292625Semaste		 * that we were told to break out of the loop, otherwise
138100389Speter		 * leave the flag set, so that the *next* call will break
139100389Speter		 * out of the loop without having read any packets, and
140100389Speter		 * return the number of packets we've processed so far.
14193403Smarcel		 */
14293403Smarcel		if (pc->break_loop) {
143164010Smarcel			if (n == 0) {
14483828Sdfr				pc->break_loop = 0;
14583828Sdfr				return (-2);
146164010Smarcel			} else {
14783828Sdfr				pc->cc = cc;
14883828Sdfr				pc->bp = bp;
14993403Smarcel				return (n);
15093403Smarcel			}
15183828Sdfr		}
15283828Sdfr		if (cc < sizeof(*sp)) {
15383828Sdfr			snprintf(pc->errbuf, sizeof(pc->errbuf),
154100389Speter			    "pf short read (%d)", cc);
15583828Sdfr			return (-1);
15693403Smarcel		}
157300791Sjhb#ifdef LBL_ALIGN
158300791Sjhb		if ((long)bp & 3) {
15993403Smarcel			sp = &stamp;
16083828Sdfr			memcpy((char *)sp, (char *)bp, sizeof(*sp));
16183828Sdfr		} else
162100389Speter#endif
163100389Speter			sp = (struct enstamp *)bp;
164100389Speter		if (sp->ens_stamplen != sizeof(*sp)) {
165100389Speter			snprintf(pc->errbuf, sizeof(pc->errbuf),
166100389Speter			    "pf short stamplen (%d)",
167100389Speter			    sp->ens_stamplen);
168100389Speter			return (-1);
169100389Speter		}
170100389Speter
171100389Speter		p = bp + sp->ens_stamplen;
172100389Speter		buflen = sp->ens_count;
173100389Speter		if (buflen > pc->snapshot)
174164010Smarcel			buflen = pc->snapshot;
175100389Speter
17683828Sdfr		/* Calculate inc before possible pad update */
177164010Smarcel		inc = ENALIGN(buflen + sp->ens_stamplen);
17883828Sdfr		cc -= inc;
17983828Sdfr		bp += inc;
180164010Smarcel		pc->md.TotPkts++;
18183828Sdfr		pc->md.TotDrops += sp->ens_dropped;
18283828Sdfr		pc->md.TotMissed = sp->ens_ifoverflows;
183164010Smarcel		if (pc->md.OrigMissed < 0)
18483828Sdfr			pc->md.OrigMissed = pc->md.TotMissed;
18583828Sdfr
18693403Smarcel		/*
18793403Smarcel		 * Short-circuit evaluation: if using BPF filter
188164010Smarcel		 * in kernel, no need to do it now - we already know
18993409Smarcel		 * the packet passed the filter.
19083828Sdfr		 *
191295144Sandrew#ifdef PCAP_FDDIPAD
192295144Sandrew		 * Note: the filter code was generated assuming
193295144Sandrew		 * that pc->fddipad was the amount of padding
194295144Sandrew		 * before the header, as that's what's required
195295144Sandrew		 * in the kernel, so we run the filter before
196164010Smarcel		 * skipping that padding.
197164010Smarcel#endif
198164010Smarcel		 */
199300791Sjhb		if (pc->md.use_bpf ||
200295144Sandrew		    bpf_filter(pc->fcode.bf_insns, p, sp->ens_count, buflen)) {
201164010Smarcel			struct pcap_pkthdr h;
202164010Smarcel			pc->md.TotAccepted++;
20383828Sdfr			h.ts = sp->ens_tstamp;
204164010Smarcel#ifdef PCAP_FDDIPAD
20593409Smarcel			h.len = sp->ens_count - pad;
20693409Smarcel#else
20793409Smarcel			h.len = sp->ens_count;
208100390Speter#endif
209164010Smarcel#ifdef PCAP_FDDIPAD
21093409Smarcel			p += pad;
21193409Smarcel			buflen -= pad;
21293409Smarcel#endif
21383828Sdfr			h.caplen = buflen;
21493409Smarcel			(*callback)(user, &h, p);
21593409Smarcel			if (++n >= cnt && cnt > 0) {
21693409Smarcel				pc->cc = cc;
217100390Speter				pc->bp = bp;
218164010Smarcel				return (n);
21993409Smarcel			}
22093409Smarcel		}
22193409Smarcel	}
22293409Smarcel	pc->cc = 0;
22393409Smarcel	return (n);
22493409Smarcel}
22593409Smarcel
22693409Smarcelstatic int
22793409Smarcelpcap_inject_pf(pcap_t *p, const void *buf, size_t size)
22893409Smarcel{
229100390Speter	int ret;
230164010Smarcel
23193409Smarcel	ret = write(p->fd, buf, size);
23293409Smarcel	if (ret == -1) {
23393409Smarcel		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
23493409Smarcel		    pcap_strerror(errno));
23593409Smarcel		return (-1);
23693409Smarcel	}
23793409Smarcel	return (ret);
23893409Smarcel}
23983828Sdfr
24083828Sdfrstatic int
241164010Smarcelpcap_stats_pf(pcap_t *p, struct pcap_stat *ps)
24283828Sdfr{
243164010Smarcel
244164010Smarcel	/*
245164010Smarcel	 * If packet filtering is being done in the kernel:
246292625Semaste	 *
247164010Smarcel	 *	"ps_recv" counts only packets that passed the filter.
248300791Sjhb	 *	This does not include packets dropped because we
249300791Sjhb	 *	ran out of buffer space.  (XXX - perhaps it should,
250300791Sjhb	 *	by adding "ps_drop" to "ps_recv", for compatibility
251164010Smarcel	 *	with some other platforms.  On the other hand, on
25283828Sdfr	 *	some platforms "ps_recv" counts only packets that
25383828Sdfr	 *	passed the filter, and on others it counts packets
254164010Smarcel	 *	that didn't pass the filter....)
255164010Smarcel	 *
256164010Smarcel	 *	"ps_drop" counts packets that passed the kernel filter
257164010Smarcel	 *	(if any) but were dropped because the input queue was
258164010Smarcel	 *	full.
259164010Smarcel	 *
260164010Smarcel	 *	"ps_ifdrop" counts packets dropped by the network
261164010Smarcel	 *	inteface (regardless of whether they would have passed
262164010Smarcel	 *	the input filter, of course).
263164010Smarcel	 *
264164010Smarcel	 * If packet filtering is not being done in the kernel:
265164010Smarcel	 *
266164010Smarcel	 *	"ps_recv" counts only packets that passed the filter.
267164010Smarcel	 *
268164010Smarcel	 *	"ps_drop" counts packets that were dropped because the
269164010Smarcel	 *	input queue was full, regardless of whether they passed
270164010Smarcel	 *	the userland filter.
27183828Sdfr	 *
272164010Smarcel	 *	"ps_ifdrop" counts packets dropped by the network
273164010Smarcel	 *	inteface (regardless of whether they would have passed
274300810Sjhb	 *	the input filter, of course).
275300810Sjhb	 *
276300810Sjhb	 * These statistics don't include packets not yet read from
277164010Smarcel	 * the kernel by libpcap, but they may include packets not
278164010Smarcel	 * yet read from libpcap by the application.
279164010Smarcel	 */
28083828Sdfr	ps->ps_recv = p->md.TotAccepted;
28183828Sdfr	ps->ps_drop = p->md.TotDrops;
282217067Smarcel	ps->ps_ifdrop = p->md.TotMissed - p->md.OrigMissed;
283164010Smarcel	return (0);
284164010Smarcel}
285164010Smarcel
286164010Smarcel/*
287164010Smarcel * We include the OS's <net/bpf.h>, not our "pcap/bpf.h", so we probably
288164010Smarcel * don't get DLT_DOCSIS defined.
289164010Smarcel */
29083828Sdfr#ifndef DLT_DOCSIS
291164010Smarcel#define DLT_DOCSIS	143
292164010Smarcel#endif
293300810Sjhb
294300810Sjhbstatic int
295300810Sjhbpcap_activate_pf(pcap_t *p)
296300810Sjhb{
297300810Sjhb	short enmode;
298300810Sjhb	int backlog = -1;	/* request the most */
299300810Sjhb	struct enfilter Filter;
300300810Sjhb	struct endevp devparams;
301300810Sjhb
302300810Sjhb	/*
303300810Sjhb	 * Initially try a read/write open (to allow the inject
304300810Sjhb	 * method to work).  If that fails due to permission
305300810Sjhb	 * issues, fall back to read-only.  This allows a
306300810Sjhb	 * non-root user to be granted specific access to pcap
307300810Sjhb	 * capabilities via file permissions.
308300810Sjhb	 *
309300810Sjhb	 * XXX - we should have an API that has a flag that
310300810Sjhb	 * controls whether to open read-only or read-write,
311300810Sjhb	 * so that denial of permission to send (or inability
312300810Sjhb	 * to send, if sending packets isn't supported on
313300810Sjhb	 * the device in question) can be indicated at open
314300810Sjhb	 * time.
315300810Sjhb	 *
316300810Sjhb	 * XXX - we assume here that "pfopen()" does not, in fact, modify
317300810Sjhb	 * its argument, even though it takes a "char *" rather than a
318300810Sjhb	 * "const char *" as its first argument.  That appears to be
319164010Smarcel	 * the case, at least on Digital UNIX 4.0.
320300810Sjhb	 */
321300810Sjhb	p->fd = pfopen(p->opt.source, O_RDWR);
322300810Sjhb	if (p->fd == -1 && errno == EACCES)
323300810Sjhb		p->fd = pfopen(p->opt.source, O_RDONLY);
324300810Sjhb	if (p->fd < 0) {
325300810Sjhb		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "pf open: %s: %s\n\
326300810Sjhbyour system may not be properly configured; see the packetfilter(4) man page\n",
327300810Sjhb			p->opt.source, pcap_strerror(errno));
328164010Smarcel		goto bad;
329300810Sjhb	}
33083828Sdfr	p->md.OrigMissed = -1;
331164010Smarcel	enmode = ENTSTAMP|ENBATCH|ENNONEXCL;
332164010Smarcel	if (p->opt.promisc)
33383828Sdfr		enmode |= ENPROMISC;
334164010Smarcel	if (ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode) < 0) {
335164010Smarcel		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCMBIS: %s",
33683828Sdfr		    pcap_strerror(errno));
337295144Sandrew		goto bad;
338164010Smarcel	}
33983828Sdfr#ifdef	ENCOPYALL
34083828Sdfr	/* Try to set COPYALL mode so that we see packets to ourself */
34183828Sdfr	enmode = ENCOPYALL;
342300810Sjhb	(void)ioctl(p->fd, EIOCMBIS, (caddr_t)&enmode);/* OK if this fails */
34383828Sdfr#endif
344300810Sjhb	/* set the backlog */
34583828Sdfr	if (ioctl(p->fd, EIOCSETW, (caddr_t)&backlog) < 0) {
346164010Smarcel		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETW: %s",
34783828Sdfr		    pcap_strerror(errno));
34883828Sdfr		goto bad;
349164010Smarcel	}
350164010Smarcel	/* discover interface type */
35183828Sdfr	if (ioctl(p->fd, EIOCDEVP, (caddr_t)&devparams) < 0) {
352300782Sjhb		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCDEVP: %s",
353164010Smarcel		    pcap_strerror(errno));
354164010Smarcel		goto bad;
35583828Sdfr	}
356300117Simp	/* HACK: to compile prior to Ultrix 4.2 */
357164010Smarcel#ifndef	ENDT_FDDI
358164010Smarcel#define	ENDT_FDDI	4
359300782Sjhb#endif
360300782Sjhb	switch (devparams.end_dev_type) {
361300782Sjhb
362300782Sjhb	case ENDT_10MB:
363300782Sjhb		p->linktype = DLT_EN10MB;
364300782Sjhb		p->offset = 2;
365300782Sjhb		/*
366300117Simp		 * This is (presumably) a real Ethernet capture; give it a
367164010Smarcel		 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
368300117Simp		 * that an application can let you choose it, in case you're
36983828Sdfr		 * capturing DOCSIS traffic that a Cisco Cable Modem
370		 * Termination System is putting out onto an Ethernet (it
371		 * doesn't put an Ethernet header onto the wire, it puts raw
372		 * DOCSIS frames out on the wire inside the low-level
373		 * Ethernet framing).
374		 */
375		p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
376		/*
377		 * If that fails, just leave the list empty.
378		 */
379		if (p->dlt_list != NULL) {
380			p->dlt_list[0] = DLT_EN10MB;
381			p->dlt_list[1] = DLT_DOCSIS;
382			p->dlt_count = 2;
383		}
384		break;
385
386	case ENDT_FDDI:
387		p->linktype = DLT_FDDI;
388		break;
389
390#ifdef ENDT_SLIP
391	case ENDT_SLIP:
392		p->linktype = DLT_SLIP;
393		break;
394#endif
395
396#ifdef ENDT_PPP
397	case ENDT_PPP:
398		p->linktype = DLT_PPP;
399		break;
400#endif
401
402#ifdef ENDT_LOOPBACK
403	case ENDT_LOOPBACK:
404		/*
405		 * It appears to use Ethernet framing, at least on
406		 * Digital UNIX 4.0.
407		 */
408		p->linktype = DLT_EN10MB;
409		p->offset = 2;
410		break;
411#endif
412
413#ifdef ENDT_TRN
414	case ENDT_TRN:
415		p->linktype = DLT_IEEE802;
416		break;
417#endif
418
419	default:
420		/*
421		 * XXX - what about ENDT_IEEE802?  The pfilt.h header
422		 * file calls this "IEEE 802 networks (non-Ethernet)",
423		 * but that doesn't specify a specific link layer type;
424		 * it could be 802.4, or 802.5 (except that 802.5 is
425		 * ENDT_TRN), or 802.6, or 802.11, or....  That's why
426		 * DLT_IEEE802 was hijacked to mean Token Ring in various
427		 * BSDs, and why we went along with that hijacking.
428		 *
429		 * XXX - what about ENDT_HDLC and ENDT_NULL?
430		 * Presumably, as ENDT_OTHER is just "Miscellaneous
431		 * framing", there's not much we can do, as that
432		 * doesn't specify a particular type of header.
433		 */
434		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
435		    "unknown data-link type %u", devparams.end_dev_type);
436		goto bad;
437	}
438	/* set truncation */
439#ifdef PCAP_FDDIPAD
440	if (p->linktype == DLT_FDDI) {
441		p->fddipad = PCAP_FDDIPAD;
442
443		/* packetfilter includes the padding in the snapshot */
444		p->snapshot += PCAP_FDDIPAD;
445	} else
446		p->fddipad = 0;
447#endif
448	if (ioctl(p->fd, EIOCTRUNCATE, (caddr_t)&p->snapshot) < 0) {
449		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCTRUNCATE: %s",
450		    pcap_strerror(errno));
451		goto bad;
452	}
453	/* accept all packets */
454	memset(&Filter, 0, sizeof(Filter));
455	Filter.enf_Priority = 37;	/* anything > 2 */
456	Filter.enf_FilterLen = 0;	/* means "always true" */
457	if (ioctl(p->fd, EIOCSETF, (caddr_t)&Filter) < 0) {
458		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSETF: %s",
459		    pcap_strerror(errno));
460		goto bad;
461	}
462
463	if (p->md.timeout != 0) {
464		struct timeval timeout;
465		timeout.tv_sec = p->md.timeout / 1000;
466		timeout.tv_usec = (p->md.timeout * 1000) % 1000000;
467		if (ioctl(p->fd, EIOCSRTIMEOUT, (caddr_t)&timeout) < 0) {
468			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "EIOCSRTIMEOUT: %s",
469				pcap_strerror(errno));
470			goto bad;
471		}
472	}
473
474	p->bufsize = BUFSPACE;
475	p->buffer = (u_char*)malloc(p->bufsize + p->offset);
476	if (p->buffer == NULL) {
477		strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE);
478		goto bad;
479	}
480
481	/*
482	 * "select()" and "poll()" work on packetfilter devices.
483	 */
484	p->selectable_fd = p->fd;
485
486	p->read_op = pcap_read_pf;
487	p->inject_op = pcap_inject_pf;
488	p->setfilter_op = pcap_setfilter_pf;
489	p->setdirection_op = NULL;	/* Not implemented. */
490	p->set_datalink_op = NULL;	/* can't change data link type */
491	p->getnonblock_op = pcap_getnonblock_fd;
492	p->setnonblock_op = pcap_setnonblock_fd;
493	p->stats_op = pcap_stats_pf;
494
495	return (0);
496 bad:
497	return (PCAP_ERROR);
498}
499
500pcap_t *
501pcap_create(const char *device, char *ebuf)
502{
503	pcap_t *p;
504
505	p = pcap_create_common(device, ebuf);
506	if (p == NULL)
507		return (NULL);
508
509	p->activate_op = pcap_activate_pf;
510	return (p);
511}
512
513int
514pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
515{
516	return (0);
517}
518
519static int
520pcap_setfilter_pf(pcap_t *p, struct bpf_program *fp)
521{
522	struct bpf_version bv;
523
524	/*
525	 * See if BIOCVERSION works.  If not, we assume the kernel doesn't
526	 * support BPF-style filters (it's not documented in the bpf(7)
527	 * or packetfiler(7) man pages, but the code used to fail if
528	 * BIOCSETF worked but BIOCVERSION didn't, and I've seen it do
529	 * kernel filtering in DU 4.0, so presumably BIOCVERSION works
530	 * there, at least).
531	 */
532	if (ioctl(p->fd, BIOCVERSION, (caddr_t)&bv) >= 0) {
533		/*
534		 * OK, we have the version of the BPF interpreter;
535		 * is it the same major version as us, and the same
536		 * or better minor version?
537		 */
538		if (bv.bv_major == BPF_MAJOR_VERSION &&
539		    bv.bv_minor >= BPF_MINOR_VERSION) {
540			/*
541			 * Yes.  Try to install the filter.
542			 */
543			if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
544				snprintf(p->errbuf, sizeof(p->errbuf),
545				    "BIOCSETF: %s", pcap_strerror(errno));
546				return (-1);
547			}
548
549			/*
550			 * OK, that succeeded.  We're doing filtering in
551			 * the kernel.  (We assume we don't have a
552			 * userland filter installed - that'd require
553			 * a previous version check to have failed but
554			 * this one to succeed.)
555			 *
556			 * XXX - this message should be supplied to the
557			 * application as a warning of some sort,
558			 * except that if it's a GUI application, it's
559			 * not clear that it should be displayed in
560			 * a window to annoy the user.
561			 */
562			fprintf(stderr, "tcpdump: Using kernel BPF filter\n");
563			p->md.use_bpf = 1;
564
565			/*
566			 * Discard any previously-received packets,
567			 * as they might have passed whatever filter
568			 * was formerly in effect, but might not pass
569			 * this filter (BIOCSETF discards packets buffered
570			 * in the kernel, so you can lose packets in any
571			 * case).
572			 */
573			p->cc = 0;
574			return (0);
575		}
576
577		/*
578		 * We can't use the kernel's BPF interpreter; don't give
579		 * up, just log a message and be inefficient.
580		 *
581		 * XXX - this should really be supplied to the application
582		 * as a warning of some sort.
583		 */
584		fprintf(stderr,
585	    "tcpdump: Requires BPF language %d.%d or higher; kernel is %d.%d\n",
586		    BPF_MAJOR_VERSION, BPF_MINOR_VERSION,
587		    bv.bv_major, bv.bv_minor);
588	}
589
590	/*
591	 * We couldn't do filtering in the kernel; do it in userland.
592	 */
593	if (install_bpf_program(p, fp) < 0)
594		return (-1);
595
596	/*
597	 * XXX - this message should be supplied by the application as
598	 * a warning of some sort.
599	 */
600	fprintf(stderr, "tcpdump: Filtering in user process\n");
601	p->md.use_bpf = 0;
602	return (0);
603}
604