pcap-bpf.c revision 167035
117683Spst/*
239291Sfenner * Copyright (c) 1993, 1994, 1995, 1996, 1998
317683Spst *	The Regents of the University of California.  All rights reserved.
417683Spst *
517683Spst * Redistribution and use in source and binary forms, with or without
617683Spst * modification, are permitted provided that: (1) source code distributions
717683Spst * retain the above copyright notice and this paragraph in its entirety, (2)
817683Spst * distributions including binary code include the above copyright notice and
917683Spst * this paragraph in its entirety in the documentation or other materials
1017683Spst * provided with the distribution, and (3) all advertising materials mentioning
1117683Spst * features or use of this software display the following acknowledgement:
1217683Spst * ``This product includes software developed by the University of California,
1317683Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1417683Spst * the University nor the names of its contributors may be used to endorse
1517683Spst * or promote products derived from this software without specific prior
1617683Spst * written permission.
1717683Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1817683Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1917683Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20162020Ssam *
21162020Ssam * $FreeBSD: head/contrib/libpcap/pcap-bpf.c 167035 2007-02-26 22:24:14Z jkim $
2217683Spst */
2317683Spst#ifndef lint
24127664Sbmsstatic const char rcsid[] _U_ =
25162012Ssam    "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.86.2.8 2005/07/10 10:55:31 guy Exp $ (LBL)";
2617683Spst#endif
2717683Spst
2875107Sfenner#ifdef HAVE_CONFIG_H
2975107Sfenner#include "config.h"
3075107Sfenner#endif
3175107Sfenner
3217683Spst#include <sys/param.h>			/* optionally get BSD define */
3317683Spst#include <sys/time.h>
3417683Spst#include <sys/timeb.h>
3517683Spst#include <sys/socket.h>
3617683Spst#include <sys/file.h>
3717683Spst#include <sys/ioctl.h>
38127664Sbms#include <sys/utsname.h>
3917683Spst
4017683Spst#include <net/if.h>
41127664Sbms
4298530Sfenner#ifdef _AIX
43127664Sbms
4498530Sfenner/*
45127664Sbms * Make "pcap.h" not include "pcap-bpf.h"; we are going to include the
46127664Sbms * native OS version, as we need "struct bpf_config" from it.
4798530Sfenner */
48127664Sbms#define PCAP_DONT_INCLUDE_PCAP_BPF_H
49127664Sbms
50127664Sbms#include <sys/types.h>
51127664Sbms
52127664Sbms/*
53127664Sbms * Prevent bpf.h from redefining the DLT_ values to their
54127664Sbms * IFT_ values, as we're going to return the standard libpcap
55127664Sbms * values, not IBM's non-standard IFT_ values.
56127664Sbms */
57127664Sbms#undef _AIX
58127664Sbms#include <net/bpf.h>
59127664Sbms#define _AIX
60127664Sbms
6198530Sfenner#include <net/if_types.h>		/* for IFT_ values */
62127664Sbms#include <sys/sysconfig.h>
63127664Sbms#include <sys/device.h>
64147894Ssam#include <sys/cfgodm.h>
65127664Sbms#include <cf.h>
6617683Spst
67127664Sbms#ifdef __64BIT__
68127664Sbms#define domakedev makedev64
69127664Sbms#define getmajor major64
70127664Sbms#define bpf_hdr bpf_hdr32
71127664Sbms#else /* __64BIT__ */
72127664Sbms#define domakedev makedev
73127664Sbms#define getmajor major
74127664Sbms#endif /* __64BIT__ */
75127664Sbms
76127664Sbms#define BPF_NAME "bpf"
77127664Sbms#define BPF_MINORS 4
78127664Sbms#define DRIVER_PATH "/usr/lib/drivers"
79127664Sbms#define BPF_NODE "/dev/bpf"
80127664Sbmsstatic int bpfloadedflag = 0;
81127664Sbmsstatic int odmlockid = 0;
82127664Sbms
83127664Sbms#else /* _AIX */
84127664Sbms
85127664Sbms#include <net/bpf.h>
86127664Sbms
87127664Sbms#endif /* _AIX */
88127664Sbms
8917683Spst#include <ctype.h>
9017683Spst#include <errno.h>
9117683Spst#include <netdb.h>
9217683Spst#include <stdio.h>
9317683Spst#include <stdlib.h>
9417683Spst#include <string.h>
9517683Spst#include <unistd.h>
9617683Spst
9717683Spst#include "pcap-int.h"
9817683Spst
99127664Sbms#ifdef HAVE_DAG_API
100127664Sbms#include "pcap-dag.h"
101127664Sbms#endif /* HAVE_DAG_API */
102127664Sbms
10317683Spst#ifdef HAVE_OS_PROTO_H
10417683Spst#include "os-proto.h"
10517683Spst#endif
10617683Spst
107127664Sbms#include "gencode.h"	/* for "no_optimize" */
10856889Sfenner
109127664Sbmsstatic int pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp);
110162012Ssamstatic int pcap_setdirection_bpf(pcap_t *, pcap_direction_t);
111127664Sbmsstatic int pcap_set_datalink_bpf(pcap_t *p, int dlt);
112127664Sbms
113127664Sbmsstatic int
114127664Sbmspcap_stats_bpf(pcap_t *p, struct pcap_stat *ps)
11517683Spst{
11617683Spst	struct bpf_stat s;
11717683Spst
11898530Sfenner	/*
11998530Sfenner	 * "ps_recv" counts packets handed to the filter, not packets
12098530Sfenner	 * that passed the filter.  This includes packets later dropped
12198530Sfenner	 * because we ran out of buffer space.
12298530Sfenner	 *
12398530Sfenner	 * "ps_drop" counts packets dropped inside the BPF device
12498530Sfenner	 * because we ran out of buffer space.  It doesn't count
12598530Sfenner	 * packets dropped by the interface driver.  It counts
12698530Sfenner	 * only packets that passed the filter.
12798530Sfenner	 *
12898530Sfenner	 * Both statistics include packets not yet read from the kernel
12998530Sfenner	 * by libpcap, and thus not yet seen by the application.
13098530Sfenner	 */
13117683Spst	if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) {
13275107Sfenner		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGSTATS: %s",
13375107Sfenner		    pcap_strerror(errno));
13417683Spst		return (-1);
13517683Spst	}
13617683Spst
13717683Spst	ps->ps_recv = s.bs_recv;
13817683Spst	ps->ps_drop = s.bs_drop;
13917683Spst	return (0);
14017683Spst}
14117683Spst
142127664Sbmsstatic int
143127664Sbmspcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
14417683Spst{
14517683Spst	int cc;
14617683Spst	int n = 0;
14717683Spst	register u_char *bp, *ep;
148146768Ssam	u_char *datap;
149127664Sbms	struct bpf_insn *fcode;
150146768Ssam#ifdef PCAP_FDDIPAD
151146768Ssam	register int pad;
152146768Ssam#endif
15317683Spst
154127664Sbms	fcode = p->md.use_bpf ? NULL : p->fcode.bf_insns;
15517683Spst again:
156127664Sbms	/*
157127664Sbms	 * Has "pcap_breakloop()" been called?
158127664Sbms	 */
159127664Sbms	if (p->break_loop) {
160127664Sbms		/*
161127664Sbms		 * Yes - clear the flag that indicates that it
162127664Sbms		 * has, and return -2 to indicate that we were
163127664Sbms		 * told to break out of the loop.
164127664Sbms		 */
165127664Sbms		p->break_loop = 0;
166127664Sbms		return (-2);
167127664Sbms	}
16817683Spst	cc = p->cc;
16917683Spst	if (p->cc == 0) {
17017683Spst		cc = read(p->fd, (char *)p->buffer, p->bufsize);
17117683Spst		if (cc < 0) {
17217683Spst			/* Don't choke when we get ptraced */
17317683Spst			switch (errno) {
17417683Spst
17517683Spst			case EINTR:
17617683Spst				goto again;
17717683Spst
178127664Sbms#ifdef _AIX
179127664Sbms			case EFAULT:
180127664Sbms				/*
181127664Sbms				 * Sigh.  More AIX wonderfulness.
182127664Sbms				 *
183127664Sbms				 * For some unknown reason the uiomove()
184127664Sbms				 * operation in the bpf kernel extension
185127664Sbms				 * used to copy the buffer into user
186127664Sbms				 * space sometimes returns EFAULT. I have
187127664Sbms				 * no idea why this is the case given that
188127664Sbms				 * a kernel debugger shows the user buffer
189127664Sbms				 * is correct. This problem appears to
190127664Sbms				 * be mostly mitigated by the memset of
191127664Sbms				 * the buffer before it is first used.
192127664Sbms				 * Very strange.... Shaun Clowes
193127664Sbms				 *
194127664Sbms				 * In any case this means that we shouldn't
195127664Sbms				 * treat EFAULT as a fatal error; as we
196127664Sbms				 * don't have an API for returning
197127664Sbms				 * a "some packets were dropped since
198127664Sbms				 * the last packet you saw" indication,
199127664Sbms				 * we just ignore EFAULT and keep reading.
200127664Sbms				 */
201127664Sbms				goto again;
202127664Sbms#endif
203127664Sbms
20417683Spst			case EWOULDBLOCK:
20517683Spst				return (0);
20617683Spst#if defined(sun) && !defined(BSD)
20717683Spst			/*
20817683Spst			 * Due to a SunOS bug, after 2^31 bytes, the kernel
20917683Spst			 * file offset overflows and read fails with EINVAL.
21017683Spst			 * The lseek() to 0 will fix things.
21117683Spst			 */
21217683Spst			case EINVAL:
21317683Spst				if (lseek(p->fd, 0L, SEEK_CUR) +
21417683Spst				    p->bufsize < 0) {
21517683Spst					(void)lseek(p->fd, 0L, SEEK_SET);
21617683Spst					goto again;
21717683Spst				}
21817683Spst				/* fall through */
21917683Spst#endif
22017683Spst			}
22175107Sfenner			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read: %s",
22275107Sfenner			    pcap_strerror(errno));
22317683Spst			return (-1);
22417683Spst		}
22517683Spst		bp = p->buffer;
22617683Spst	} else
22717683Spst		bp = p->bp;
22817683Spst
22917683Spst	/*
23017683Spst	 * Loop through each packet.
23117683Spst	 */
23217683Spst#define bhp ((struct bpf_hdr *)bp)
23317683Spst	ep = bp + cc;
234146768Ssam#ifdef PCAP_FDDIPAD
235146768Ssam	pad = p->fddipad;
236146768Ssam#endif
23717683Spst	while (bp < ep) {
23817683Spst		register int caplen, hdrlen;
239127664Sbms
240127664Sbms		/*
241127664Sbms		 * Has "pcap_breakloop()" been called?
242127664Sbms		 * If so, return immediately - if we haven't read any
243127664Sbms		 * packets, clear the flag and return -2 to indicate
244127664Sbms		 * that we were told to break out of the loop, otherwise
245127664Sbms		 * leave the flag set, so that the *next* call will break
246127664Sbms		 * out of the loop without having read any packets, and
247127664Sbms		 * return the number of packets we've processed so far.
248127664Sbms		 */
249127664Sbms		if (p->break_loop) {
250127664Sbms			if (n == 0) {
251127664Sbms				p->break_loop = 0;
252127664Sbms				return (-2);
253127664Sbms			} else {
254127664Sbms				p->bp = bp;
255127664Sbms				p->cc = ep - bp;
256127664Sbms				return (n);
257127664Sbms			}
258127664Sbms		}
259127664Sbms
26017683Spst		caplen = bhp->bh_caplen;
26117683Spst		hdrlen = bhp->bh_hdrlen;
262146768Ssam		datap = bp + hdrlen;
26317683Spst		/*
264127664Sbms		 * Short-circuit evaluation: if using BPF filter
265127664Sbms		 * in kernel, no need to do it now.
266146768Ssam		 *
267146768Ssam#ifdef PCAP_FDDIPAD
268146768Ssam		 * Note: the filter code was generated assuming
269146768Ssam		 * that p->fddipad was the amount of padding
270146768Ssam		 * before the header, as that's what's required
271146768Ssam		 * in the kernel, so we run the filter before
272146768Ssam		 * skipping that padding.
273146768Ssam#endif
27417683Spst		 */
275127664Sbms		if (fcode == NULL ||
276146768Ssam		    bpf_filter(fcode, datap, bhp->bh_datalen, caplen)) {
277146768Ssam			struct pcap_pkthdr pkthdr;
278146768Ssam
279146768Ssam			pkthdr.ts.tv_sec = bhp->bh_tstamp.tv_sec;
28098530Sfenner#ifdef _AIX
281127664Sbms			/*
282127664Sbms			 * AIX's BPF returns seconds/nanoseconds time
283127664Sbms			 * stamps, not seconds/microseconds time stamps.
284127664Sbms			 */
285146768Ssam			pkthdr.ts.tv_usec = bhp->bh_tstamp.tv_usec/1000;
286146768Ssam#else
287146768Ssam			pkthdr.ts.tv_usec = bhp->bh_tstamp.tv_usec;
28898530Sfenner#endif
289146768Ssam#ifdef PCAP_FDDIPAD
290146768Ssam			if (caplen > pad)
291146768Ssam				pkthdr.caplen = caplen - pad;
292146768Ssam			else
293146768Ssam				pkthdr.caplen = 0;
294146768Ssam			if (bhp->bh_datalen > pad)
295146768Ssam				pkthdr.len = bhp->bh_datalen - pad;
296146768Ssam			else
297146768Ssam				pkthdr.len = 0;
298146768Ssam			datap += pad;
299146768Ssam#else
300146768Ssam			pkthdr.caplen = caplen;
301146768Ssam			pkthdr.len = bhp->bh_datalen;
302146768Ssam#endif
303146768Ssam			(*callback)(user, &pkthdr, datap);
304127664Sbms			bp += BPF_WORDALIGN(caplen + hdrlen);
305127664Sbms			if (++n >= cnt && cnt > 0) {
306127664Sbms				p->bp = bp;
307127664Sbms				p->cc = ep - bp;
308127664Sbms				return (n);
309127664Sbms			}
310127664Sbms		} else {
311127664Sbms			/*
312127664Sbms			 * Skip this packet.
313127664Sbms			 */
314127664Sbms			bp += BPF_WORDALIGN(caplen + hdrlen);
31517683Spst		}
31617683Spst	}
31717683Spst#undef bhp
31817683Spst	p->cc = 0;
31917683Spst	return (n);
32017683Spst}
32117683Spst
322146768Ssamstatic int
323146768Ssampcap_inject_bpf(pcap_t *p, const void *buf, size_t size)
324146768Ssam{
325146768Ssam	int ret;
326146768Ssam
327146768Ssam	ret = write(p->fd, buf, size);
328146768Ssam#ifdef __APPLE__
329146768Ssam	if (ret == -1 && errno == EAFNOSUPPORT) {
330146768Ssam		/*
331146768Ssam		 * In Mac OS X, there's a bug wherein setting the
332146768Ssam		 * BIOCSHDRCMPLT flag causes writes to fail; see,
333146768Ssam		 * for example:
334146768Ssam		 *
335146768Ssam		 *	http://cerberus.sourcefire.com/~jeff/archives/patches/macosx/BIOCSHDRCMPLT-10.3.3.patch
336146768Ssam		 *
337146768Ssam		 * So, if, on OS X, we get EAFNOSUPPORT from the write, we
338146768Ssam		 * assume it's due to that bug, and turn off that flag
339146768Ssam		 * and try again.  If we succeed, it either means that
340146768Ssam		 * somebody applied the fix from that URL, or other patches
341146768Ssam		 * for that bug from
342146768Ssam		 *
343146768Ssam		 *	http://cerberus.sourcefire.com/~jeff/archives/patches/macosx/
344146768Ssam		 *
345146768Ssam		 * and are running a Darwin kernel with those fixes, or
346146768Ssam		 * that Apple fixed the problem in some OS X release.
347146768Ssam		 */
348146768Ssam		u_int spoof_eth_src = 0;
349146768Ssam
350146768Ssam		if (ioctl(p->fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) {
351146768Ssam			(void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
352146768Ssam			    "send: can't turn off BIOCSHDRCMPLT: %s",
353146768Ssam			    pcap_strerror(errno));
354146768Ssam			return (-1);
355146768Ssam		}
356146768Ssam
357146768Ssam		/*
358146768Ssam		 * Now try the write again.
359146768Ssam		 */
360146768Ssam		ret = write(p->fd, buf, size);
361146768Ssam	}
362146768Ssam#endif /* __APPLE__ */
363146768Ssam	if (ret == -1) {
364146768Ssam		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
365146768Ssam		    pcap_strerror(errno));
366146768Ssam		return (-1);
367146768Ssam	}
368146768Ssam	return (ret);
369146768Ssam}
370146768Ssam
371127664Sbms#ifdef _AIX
372127664Sbmsstatic int
373127664Sbmsbpf_odminit(char *errbuf)
374127664Sbms{
375127664Sbms	char *errstr;
376127664Sbms
377127664Sbms	if (odm_initialize() == -1) {
378127664Sbms		if (odm_err_msg(odmerrno, &errstr) == -1)
379127664Sbms			errstr = "Unknown error";
380127664Sbms		snprintf(errbuf, PCAP_ERRBUF_SIZE,
381127664Sbms		    "bpf_load: odm_initialize failed: %s",
382127664Sbms		    errstr);
383127664Sbms		return (-1);
384127664Sbms	}
385127664Sbms
386127664Sbms	if ((odmlockid = odm_lock("/etc/objrepos/config_lock", ODM_WAIT)) == -1) {
387127664Sbms		if (odm_err_msg(odmerrno, &errstr) == -1)
388127664Sbms			errstr = "Unknown error";
389127664Sbms		snprintf(errbuf, PCAP_ERRBUF_SIZE,
390127664Sbms		    "bpf_load: odm_lock of /etc/objrepos/config_lock failed: %s",
391127664Sbms		    errstr);
392127664Sbms		return (-1);
393127664Sbms	}
394127664Sbms
395127664Sbms	return (0);
396127664Sbms}
397127664Sbms
398127664Sbmsstatic int
399127664Sbmsbpf_odmcleanup(char *errbuf)
400127664Sbms{
401127664Sbms	char *errstr;
402127664Sbms
403127664Sbms	if (odm_unlock(odmlockid) == -1) {
404127664Sbms		if (odm_err_msg(odmerrno, &errstr) == -1)
405127664Sbms			errstr = "Unknown error";
406127664Sbms		snprintf(errbuf, PCAP_ERRBUF_SIZE,
407127664Sbms		    "bpf_load: odm_unlock failed: %s",
408127664Sbms		    errstr);
409127664Sbms		return (-1);
410127664Sbms	}
411127664Sbms
412127664Sbms	if (odm_terminate() == -1) {
413127664Sbms		if (odm_err_msg(odmerrno, &errstr) == -1)
414127664Sbms			errstr = "Unknown error";
415127664Sbms		snprintf(errbuf, PCAP_ERRBUF_SIZE,
416127664Sbms		    "bpf_load: odm_terminate failed: %s",
417127664Sbms		    errstr);
418127664Sbms		return (-1);
419127664Sbms	}
420127664Sbms
421127664Sbms	return (0);
422127664Sbms}
423127664Sbms
424127664Sbmsstatic int
425127664Sbmsbpf_load(char *errbuf)
426127664Sbms{
427127664Sbms	long major;
428127664Sbms	int *minors;
429127664Sbms	int numminors, i, rc;
430127664Sbms	char buf[1024];
431127664Sbms	struct stat sbuf;
432127664Sbms	struct bpf_config cfg_bpf;
433127664Sbms	struct cfg_load cfg_ld;
434127664Sbms	struct cfg_kmod cfg_km;
435127664Sbms
436127664Sbms	/*
437127664Sbms	 * This is very very close to what happens in the real implementation
438127664Sbms	 * but I've fixed some (unlikely) bug situations.
439127664Sbms	 */
440127664Sbms	if (bpfloadedflag)
441127664Sbms		return (0);
442127664Sbms
443127664Sbms	if (bpf_odminit(errbuf) != 0)
444127664Sbms		return (-1);
445127664Sbms
446127664Sbms	major = genmajor(BPF_NAME);
447127664Sbms	if (major == -1) {
448127664Sbms		snprintf(errbuf, PCAP_ERRBUF_SIZE,
449127664Sbms		    "bpf_load: genmajor failed: %s", pcap_strerror(errno));
450127664Sbms		return (-1);
451127664Sbms	}
452127664Sbms
453127664Sbms	minors = getminor(major, &numminors, BPF_NAME);
454127664Sbms	if (!minors) {
455127664Sbms		minors = genminor("bpf", major, 0, BPF_MINORS, 1, 1);
456127664Sbms		if (!minors) {
457127664Sbms			snprintf(errbuf, PCAP_ERRBUF_SIZE,
458127664Sbms			    "bpf_load: genminor failed: %s",
459127664Sbms			    pcap_strerror(errno));
460127664Sbms			return (-1);
461127664Sbms		}
462127664Sbms	}
463127664Sbms
464127664Sbms	if (bpf_odmcleanup(errbuf))
465127664Sbms		return (-1);
466127664Sbms
467127664Sbms	rc = stat(BPF_NODE "0", &sbuf);
468127664Sbms	if (rc == -1 && errno != ENOENT) {
469127664Sbms		snprintf(errbuf, PCAP_ERRBUF_SIZE,
470127664Sbms		    "bpf_load: can't stat %s: %s",
471127664Sbms		    BPF_NODE "0", pcap_strerror(errno));
472127664Sbms		return (-1);
473127664Sbms	}
474127664Sbms
475127664Sbms	if (rc == -1 || getmajor(sbuf.st_rdev) != major) {
476127664Sbms		for (i = 0; i < BPF_MINORS; i++) {
477127664Sbms			sprintf(buf, "%s%d", BPF_NODE, i);
478127664Sbms			unlink(buf);
479127664Sbms			if (mknod(buf, S_IRUSR | S_IFCHR, domakedev(major, i)) == -1) {
480127664Sbms				snprintf(errbuf, PCAP_ERRBUF_SIZE,
481127664Sbms				    "bpf_load: can't mknod %s: %s",
482127664Sbms				    buf, pcap_strerror(errno));
483127664Sbms				return (-1);
484127664Sbms			}
485127664Sbms		}
486127664Sbms	}
487127664Sbms
488127664Sbms	/* Check if the driver is loaded */
489127664Sbms	memset(&cfg_ld, 0x0, sizeof(cfg_ld));
490127664Sbms	cfg_ld.path = buf;
491127664Sbms	sprintf(cfg_ld.path, "%s/%s", DRIVER_PATH, BPF_NAME);
492127664Sbms	if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) ||
493127664Sbms	    (cfg_ld.kmid == 0)) {
494127664Sbms		/* Driver isn't loaded, load it now */
495127664Sbms		if (sysconfig(SYS_SINGLELOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) {
496127664Sbms			snprintf(errbuf, PCAP_ERRBUF_SIZE,
497127664Sbms			    "bpf_load: could not load driver: %s",
498127664Sbms			    strerror(errno));
499127664Sbms			return (-1);
500127664Sbms		}
501127664Sbms	}
502127664Sbms
503127664Sbms	/* Configure the driver */
504127664Sbms	cfg_km.cmd = CFG_INIT;
505127664Sbms	cfg_km.kmid = cfg_ld.kmid;
506127664Sbms	cfg_km.mdilen = sizeof(cfg_bpf);
507127664Sbms	cfg_km.mdiptr = (void *)&cfg_bpf;
508127664Sbms	for (i = 0; i < BPF_MINORS; i++) {
509127664Sbms		cfg_bpf.devno = domakedev(major, i);
510127664Sbms		if (sysconfig(SYS_CFGKMOD, (void *)&cfg_km, sizeof(cfg_km)) == -1) {
511127664Sbms			snprintf(errbuf, PCAP_ERRBUF_SIZE,
512127664Sbms			    "bpf_load: could not configure driver: %s",
513127664Sbms			    strerror(errno));
514127664Sbms			return (-1);
515127664Sbms		}
516127664Sbms	}
517127664Sbms
518127664Sbms	bpfloadedflag = 1;
519127664Sbms
520127664Sbms	return (0);
521127664Sbms}
522127664Sbms#endif
523127664Sbms
52417683Spststatic inline int
52517683Spstbpf_open(pcap_t *p, char *errbuf)
52617683Spst{
52717683Spst	int fd;
52817683Spst	int n = 0;
52975107Sfenner	char device[sizeof "/dev/bpf0000000000"];
53017683Spst
531127664Sbms#ifdef _AIX
53217683Spst	/*
533127664Sbms	 * Load the bpf driver, if it isn't already loaded,
534127664Sbms	 * and create the BPF device entries, if they don't
535127664Sbms	 * already exist.
536127664Sbms	 */
537127664Sbms	if (bpf_load(errbuf) == -1)
538127664Sbms		return (-1);
539127664Sbms#endif
540127664Sbms
541127664Sbms	/*
54217683Spst	 * Go through all the minors and find one that isn't in use.
54317683Spst	 */
54417683Spst	do {
54575107Sfenner		(void)snprintf(device, sizeof(device), "/dev/bpf%d", n++);
546146768Ssam		/*
547146768Ssam		 * Initially try a read/write open (to allow the inject
548146768Ssam		 * method to work).  If that fails due to permission
549146768Ssam		 * issues, fall back to read-only.  This allows a
550146768Ssam		 * non-root user to be granted specific access to pcap
551146768Ssam		 * capabilities via file permissions.
552146768Ssam		 *
553146768Ssam		 * XXX - we should have an API that has a flag that
554146768Ssam		 * controls whether to open read-only or read-write,
555146768Ssam		 * so that denial of permission to send (or inability
556146768Ssam		 * to send, if sending packets isn't supported on
557146768Ssam		 * the device in question) can be indicated at open
558146768Ssam		 * time.
559146768Ssam		 */
560146768Ssam		fd = open(device, O_RDWR);
561146768Ssam		if (fd == -1 && errno == EACCES)
562146768Ssam			fd = open(device, O_RDONLY);
56317683Spst	} while (fd < 0 && errno == EBUSY);
56417683Spst
56517683Spst	/*
56617683Spst	 * XXX better message for all minors used
56717683Spst	 */
56817683Spst	if (fd < 0)
56975107Sfenner		snprintf(errbuf, PCAP_ERRBUF_SIZE, "(no devices found) %s: %s",
57075107Sfenner		    device, pcap_strerror(errno));
57117683Spst
57217683Spst	return (fd);
57317683Spst}
57417683Spst
575127664Sbms/*
576146768Ssam * We include the OS's <net/bpf.h>, not our "pcap-bpf.h", so we probably
577146768Ssam * don't get DLT_DOCSIS defined.
578127664Sbms */
579146768Ssam#ifndef DLT_DOCSIS
580146768Ssam#define DLT_DOCSIS	143
581146768Ssam#endif
582146768Ssam
58317683Spstpcap_t *
584127664Sbmspcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
585127664Sbms    char *ebuf)
58617683Spst{
58717683Spst	int fd;
58817683Spst	struct ifreq ifr;
58917683Spst	struct bpf_version bv;
590127664Sbms#ifdef BIOCGDLTLIST
591109839Sfenner	struct bpf_dltlist bdl;
592127664Sbms#endif
593146768Ssam#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT)
594146768Ssam	u_int spoof_eth_src = 1;
595146768Ssam#endif
59617683Spst	u_int v;
59717683Spst	pcap_t *p;
598146768Ssam	struct bpf_insn total_insn;
599146768Ssam	struct bpf_program total_prog;
600127664Sbms	struct utsname osinfo;
60117683Spst
602127664Sbms#ifdef HAVE_DAG_API
603127664Sbms	if (strstr(device, "dag")) {
604127664Sbms		return dag_open_live(device, snaplen, promisc, to_ms, ebuf);
605127664Sbms	}
606127664Sbms#endif /* HAVE_DAG_API */
607109839Sfenner
608127664Sbms#ifdef BIOCGDLTLIST
609127664Sbms	memset(&bdl, 0, sizeof(bdl));
610127664Sbms#endif
611127664Sbms
61217683Spst	p = (pcap_t *)malloc(sizeof(*p));
61317683Spst	if (p == NULL) {
61475107Sfenner		snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
61575107Sfenner		    pcap_strerror(errno));
61617683Spst		return (NULL);
61717683Spst	}
61875107Sfenner	memset(p, 0, sizeof(*p));
61917683Spst	fd = bpf_open(p, ebuf);
62017683Spst	if (fd < 0)
62117683Spst		goto bad;
62217683Spst
62317683Spst	p->fd = fd;
62417683Spst	p->snapshot = snaplen;
62517683Spst
62617683Spst	if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) {
62775107Sfenner		snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s",
62875107Sfenner		    pcap_strerror(errno));
62917683Spst		goto bad;
63017683Spst	}
63117683Spst	if (bv.bv_major != BPF_MAJOR_VERSION ||
63217683Spst	    bv.bv_minor < BPF_MINOR_VERSION) {
63375107Sfenner		snprintf(ebuf, PCAP_ERRBUF_SIZE,
63475107Sfenner		    "kernel bpf filter out of date");
63517683Spst		goto bad;
63617683Spst	}
63775107Sfenner
63875107Sfenner	/*
63975107Sfenner	 * Try finding a good size for the buffer; 32768 may be too
64075107Sfenner	 * big, so keep cutting it in half until we find a size
641127664Sbms	 * that works, or run out of sizes to try.  If the default
642127664Sbms	 * is larger, don't make it smaller.
64375107Sfenner	 *
64475107Sfenner	 * XXX - there should be a user-accessible hook to set the
64575107Sfenner	 * initial buffer size.
64639291Sfenner	 */
647127664Sbms	if ((ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) || v < 32768)
648127664Sbms		v = 32768;
649127664Sbms	for ( ; v != 0; v >>= 1) {
65075107Sfenner		/* Ignore the return value - this is because the call fails
65175107Sfenner		 * on BPF systems that don't have kernel malloc.  And if
65275107Sfenner		 * the call fails, it's no big deal, we just continue to
65375107Sfenner		 * use the standard buffer size.
65475107Sfenner		 */
65575107Sfenner		(void) ioctl(fd, BIOCSBLEN, (caddr_t)&v);
65639291Sfenner
65775107Sfenner		(void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
65875107Sfenner		if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0)
65975107Sfenner			break;	/* that size worked; we're done */
66075107Sfenner
66175107Sfenner		if (errno != ENOBUFS) {
66275107Sfenner			snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s",
66375107Sfenner			    device, pcap_strerror(errno));
66475107Sfenner			goto bad;
66575107Sfenner		}
66675107Sfenner	}
66775107Sfenner
66875107Sfenner	if (v == 0) {
66975107Sfenner		snprintf(ebuf, PCAP_ERRBUF_SIZE,
67075107Sfenner			 "BIOCSBLEN: %s: No buffer size worked", device);
67117683Spst		goto bad;
67217683Spst	}
67375107Sfenner
67417683Spst	/* Get the data link layer type. */
67517683Spst	if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
67675107Sfenner		snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s",
67775107Sfenner		    pcap_strerror(errno));
67817683Spst		goto bad;
67917683Spst	}
68098530Sfenner#ifdef _AIX
68198530Sfenner	/*
68298530Sfenner	 * AIX's BPF returns IFF_ types, not DLT_ types, in BIOCGDLT.
68398530Sfenner	 */
68456889Sfenner	switch (v) {
68598530Sfenner
68698530Sfenner	case IFT_ETHER:
68798530Sfenner	case IFT_ISO88023:
68898530Sfenner		v = DLT_EN10MB;
68998530Sfenner		break;
69098530Sfenner
69198530Sfenner	case IFT_FDDI:
69298530Sfenner		v = DLT_FDDI;
69398530Sfenner		break;
69498530Sfenner
69598530Sfenner	case IFT_ISO88025:
69698530Sfenner		v = DLT_IEEE802;
69798530Sfenner		break;
69898530Sfenner
699127664Sbms	case IFT_LOOP:
700127664Sbms		v = DLT_NULL;
701127664Sbms		break;
702127664Sbms
70398530Sfenner	default:
70475107Sfenner		/*
70598530Sfenner		 * We don't know what to map this to yet.
70675107Sfenner		 */
707127664Sbms		snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown interface type %u",
70898530Sfenner		    v);
70998530Sfenner		goto bad;
71056889Sfenner	}
71156889Sfenner#endif
71239291Sfenner#if _BSDI_VERSION - 0 >= 199510
71339291Sfenner	/* The SLIP and PPP link layer header changed in BSD/OS 2.1 */
71439291Sfenner	switch (v) {
71539291Sfenner
71639291Sfenner	case DLT_SLIP:
71739291Sfenner		v = DLT_SLIP_BSDOS;
71839291Sfenner		break;
71939291Sfenner
72039291Sfenner	case DLT_PPP:
72139291Sfenner		v = DLT_PPP_BSDOS;
72239291Sfenner		break;
72356889Sfenner
72456889Sfenner	case 11:	/*DLT_FR*/
725127664Sbms		v = DLT_FRELAY;
72656889Sfenner		break;
72756889Sfenner
72856889Sfenner	case 12:	/*DLT_C_HDLC*/
72956889Sfenner		v = DLT_CHDLC;
73056889Sfenner		break;
73139291Sfenner	}
73239291Sfenner#endif
733146768Ssam#ifdef PCAP_FDDIPAD
734146768Ssam	if (v == DLT_FDDI)
735147894Ssam		p->fddipad = PCAP_FDDIPAD;
736146768Ssam	else
737146768Ssam		p->fddipad = 0;
738146768Ssam#endif
73917683Spst	p->linktype = v;
74017683Spst
741127664Sbms#ifdef BIOCGDLTLIST
742109839Sfenner	/*
743127664Sbms	 * We know the default link type -- now determine all the DLTs
744127664Sbms	 * this interface supports.  If this fails with EINVAL, it's
745127664Sbms	 * not fatal; we just don't get to use the feature later.
746109839Sfenner	 */
747127664Sbms	if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) == 0) {
748146768Ssam		u_int i;
749146768Ssam		int is_ethernet;
750146768Ssam
751162020Ssam		bdl.bfl_list = (u_int *) malloc(sizeof(u_int) * (bdl.bfl_len + 1));
752109839Sfenner		if (bdl.bfl_list == NULL) {
753109839Sfenner			(void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
754109839Sfenner			    pcap_strerror(errno));
755109839Sfenner			goto bad;
756109839Sfenner		}
757109839Sfenner
758127664Sbms		if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) < 0) {
759109839Sfenner			(void)snprintf(ebuf, PCAP_ERRBUF_SIZE,
760109839Sfenner			    "BIOCGDLTLIST: %s", pcap_strerror(errno));
761146768Ssam			free(bdl.bfl_list);
762109839Sfenner			goto bad;
763109839Sfenner		}
764109839Sfenner
765146768Ssam		/*
766146768Ssam		 * OK, for real Ethernet devices, add DLT_DOCSIS to the
767146768Ssam		 * list, so that an application can let you choose it,
768146768Ssam		 * in case you're capturing DOCSIS traffic that a Cisco
769146768Ssam		 * Cable Modem Termination System is putting out onto
770146768Ssam		 * an Ethernet (it doesn't put an Ethernet header onto
771146768Ssam		 * the wire, it puts raw DOCSIS frames out on the wire
772146768Ssam		 * inside the low-level Ethernet framing).
773146768Ssam		 *
774146768Ssam		 * A "real Ethernet device" is defined here as a device
775146768Ssam		 * that has a link-layer type of DLT_EN10MB and that has
776146768Ssam		 * no alternate link-layer types; that's done to exclude
777146768Ssam		 * 802.11 interfaces (which might or might not be the
778146768Ssam		 * right thing to do, but I suspect it is - Ethernet <->
779146768Ssam		 * 802.11 bridges would probably badly mishandle frames
780146768Ssam		 * that don't have Ethernet headers).
781146768Ssam		 */
782146768Ssam		if (p->linktype == DLT_EN10MB) {
783146768Ssam			is_ethernet = 1;
784146768Ssam			for (i = 0; i < bdl.bfl_len; i++) {
785146768Ssam				if (bdl.bfl_list[i] != DLT_EN10MB) {
786146768Ssam					is_ethernet = 0;
787146768Ssam					break;
788146768Ssam				}
789146768Ssam			}
790146768Ssam			if (is_ethernet) {
791146768Ssam				/*
792146768Ssam				 * We reserved one more slot at the end of
793146768Ssam				 * the list.
794146768Ssam				 */
795146768Ssam				bdl.bfl_list[bdl.bfl_len] = DLT_DOCSIS;
796146768Ssam				bdl.bfl_len++;
797146768Ssam			}
798146768Ssam		}
799109839Sfenner		p->dlt_count = bdl.bfl_len;
800109839Sfenner		p->dlt_list = bdl.bfl_list;
801127664Sbms	} else {
802127664Sbms		if (errno != EINVAL) {
803127664Sbms			(void)snprintf(ebuf, PCAP_ERRBUF_SIZE,
804127664Sbms			    "BIOCGDLTLIST: %s", pcap_strerror(errno));
805127664Sbms			goto bad;
806127664Sbms		}
807109839Sfenner	}
808127664Sbms#endif
809109839Sfenner
810146768Ssam	/*
811146768Ssam	 * If this is an Ethernet device, and we don't have a DLT_ list,
812146768Ssam	 * give it a list with DLT_EN10MB and DLT_DOCSIS.  (That'd give
813146768Ssam	 * 802.11 interfaces DLT_DOCSIS, which isn't the right thing to
814146768Ssam	 * do, but there's not much we can do about that without finding
815146768Ssam	 * some other way of determining whether it's an Ethernet or 802.11
816146768Ssam	 * device.)
817146768Ssam	 */
818146768Ssam	if (p->linktype == DLT_EN10MB && p->dlt_count == 0) {
819146768Ssam		p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
820146768Ssam		/*
821146768Ssam		 * If that fails, just leave the list empty.
822146768Ssam		 */
823146768Ssam		if (p->dlt_list != NULL) {
824146768Ssam			p->dlt_list[0] = DLT_EN10MB;
825146768Ssam			p->dlt_list[1] = DLT_DOCSIS;
826146768Ssam			p->dlt_count = 2;
827146768Ssam		}
828146768Ssam	}
829146768Ssam
830146768Ssam#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT)
831146768Ssam	/*
832146768Ssam	 * Do a BIOCSHDRCMPLT, if defined, to turn that flag on, so
833146768Ssam	 * the link-layer source address isn't forcibly overwritten.
834146768Ssam	 * (Should we ignore errors?  Should we do this only if
835146768Ssam	 * we're open for writing?)
836146768Ssam	 *
837146768Ssam	 * XXX - I seem to remember some packet-sending bug in some
838146768Ssam	 * BSDs - check CVS log for "bpf.c"?
839146768Ssam	 */
840146768Ssam	if (ioctl(fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) {
841146768Ssam		(void)snprintf(ebuf, PCAP_ERRBUF_SIZE,
842146768Ssam		    "BIOCSHDRCMPLT: %s", pcap_strerror(errno));
843146768Ssam		goto bad;
844146768Ssam	}
845146768Ssam#endif
84617683Spst	/* set timeout */
84717683Spst	if (to_ms != 0) {
848127664Sbms		/*
849127664Sbms		 * XXX - is this seconds/nanoseconds in AIX?
850127664Sbms		 * (Treating it as such doesn't fix the timeout
851127664Sbms		 * problem described below.)
852127664Sbms		 */
85317683Spst		struct timeval to;
85417683Spst		to.tv_sec = to_ms / 1000;
85517683Spst		to.tv_usec = (to_ms * 1000) % 1000000;
85617683Spst		if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) {
85775107Sfenner			snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s",
85875107Sfenner			    pcap_strerror(errno));
85917683Spst			goto bad;
86017683Spst		}
86117683Spst	}
86275107Sfenner
86375107Sfenner#ifdef _AIX
86475107Sfenner#ifdef	BIOCIMMEDIATE
86575107Sfenner	/*
86675107Sfenner	 * Darren Reed notes that
86775107Sfenner	 *
86875107Sfenner	 *	On AIX (4.2 at least), if BIOCIMMEDIATE is not set, the
86975107Sfenner	 *	timeout appears to be ignored and it waits until the buffer
87075107Sfenner	 *	is filled before returning.  The result of not having it
87175107Sfenner	 *	set is almost worse than useless if your BPF filter
87275107Sfenner	 *	is reducing things to only a few packets (i.e. one every
87375107Sfenner	 *	second or so).
87475107Sfenner	 *
87575107Sfenner	 * so we turn BIOCIMMEDIATE mode on if this is AIX.
87675107Sfenner	 *
87775107Sfenner	 * We don't turn it on for other platforms, as that means we
87875107Sfenner	 * get woken up for every packet, which may not be what we want;
87975107Sfenner	 * in the Winter 1993 USENIX paper on BPF, they say:
88075107Sfenner	 *
88175107Sfenner	 *	Since a process might want to look at every packet on a
88275107Sfenner	 *	network and the time between packets can be only a few
88375107Sfenner	 *	microseconds, it is not possible to do a read system call
88475107Sfenner	 *	per packet and BPF must collect the data from several
88575107Sfenner	 *	packets and return it as a unit when the monitoring
88675107Sfenner	 *	application does a read.
88775107Sfenner	 *
88875107Sfenner	 * which I infer is the reason for the timeout - it means we
88975107Sfenner	 * wait that amount of time, in the hopes that more packets
89075107Sfenner	 * will arrive and we'll get them all with one read.
89175107Sfenner	 *
89275107Sfenner	 * Setting BIOCIMMEDIATE mode on FreeBSD (and probably other
89375107Sfenner	 * BSDs) causes the timeout to be ignored.
89475107Sfenner	 *
89575107Sfenner	 * On the other hand, some platforms (e.g., Linux) don't support
89675107Sfenner	 * timeouts, they just hand stuff to you as soon as it arrives;
89775107Sfenner	 * if that doesn't cause a problem on those platforms, it may
89875107Sfenner	 * be OK to have BIOCIMMEDIATE mode on BSD as well.
89975107Sfenner	 *
90075107Sfenner	 * (Note, though, that applications may depend on the read
90175107Sfenner	 * completing, even if no packets have arrived, when the timeout
90275107Sfenner	 * expires, e.g. GUI applications that have to check for input
90375107Sfenner	 * while waiting for packets to arrive; a non-zero timeout
90475107Sfenner	 * prevents "select()" from working right on FreeBSD and
90575107Sfenner	 * possibly other BSDs, as the timer doesn't start until a
90675107Sfenner	 * "read()" is done, so the timer isn't in effect if the
90775107Sfenner	 * application is blocked on a "select()", and the "select()"
90875107Sfenner	 * doesn't get woken up for a BPF device until the buffer
90975107Sfenner	 * fills up.)
91075107Sfenner	 */
91175107Sfenner	v = 1;
91275107Sfenner	if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) {
91375107Sfenner		snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s",
91475107Sfenner		    pcap_strerror(errno));
91575107Sfenner		goto bad;
91675107Sfenner	}
91775107Sfenner#endif	/* BIOCIMMEDIATE */
91875107Sfenner#endif	/* _AIX */
91975107Sfenner
92098530Sfenner	if (promisc) {
92117683Spst		/* set promiscuous mode, okay if it fails */
92298530Sfenner		if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) {
92398530Sfenner			snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s",
92498530Sfenner			    pcap_strerror(errno));
92598530Sfenner		}
92698530Sfenner	}
92717683Spst
92817683Spst	if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
92975107Sfenner		snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s",
93075107Sfenner		    pcap_strerror(errno));
93117683Spst		goto bad;
93217683Spst	}
93317683Spst	p->bufsize = v;
93417683Spst	p->buffer = (u_char *)malloc(p->bufsize);
93517683Spst	if (p->buffer == NULL) {
93675107Sfenner		snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
93775107Sfenner		    pcap_strerror(errno));
93817683Spst		goto bad;
93917683Spst	}
940127664Sbms#ifdef _AIX
941127664Sbms	/* For some strange reason this seems to prevent the EFAULT
942127664Sbms	 * problems we have experienced from AIX BPF. */
943127664Sbms	memset(p->buffer, 0x0, p->bufsize);
944127664Sbms#endif
94517683Spst
946127664Sbms	/*
947146768Ssam	 * If there's no filter program installed, there's
948146768Ssam	 * no indication to the kernel of what the snapshot
949146768Ssam	 * length should be, so no snapshotting is done.
950146768Ssam	 *
951146768Ssam	 * Therefore, when we open the device, we install
952146768Ssam	 * an "accept everything" filter with the specified
953146768Ssam	 * snapshot length.
954146768Ssam	 */
955146768Ssam	total_insn.code = (u_short)(BPF_RET | BPF_K);
956146768Ssam	total_insn.jt = 0;
957146768Ssam	total_insn.jf = 0;
958146768Ssam	total_insn.k = snaplen;
959146768Ssam
960146768Ssam	total_prog.bf_len = 1;
961146768Ssam	total_prog.bf_insns = &total_insn;
962146768Ssam	if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) {
963146768Ssam		snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
964146768Ssam		    pcap_strerror(errno));
965146768Ssam		goto bad;
966146768Ssam	}
967146768Ssam
968146768Ssam	/*
969127664Sbms	 * On most BPF platforms, either you can do a "select()" or
970127664Sbms	 * "poll()" on a BPF file descriptor and it works correctly,
971127664Sbms	 * or you can do it and it will return "readable" if the
972127664Sbms	 * hold buffer is full but not if the timeout expires *and*
973127664Sbms	 * a non-blocking read will, if the hold buffer is empty
974127664Sbms	 * but the store buffer isn't empty, rotate the buffers
975127664Sbms	 * and return what packets are available.
976127664Sbms	 *
977127664Sbms	 * In the latter case, the fact that a non-blocking read
978127664Sbms	 * will give you the available packets means you can work
979127664Sbms	 * around the failure of "select()" and "poll()" to wake up
980127664Sbms	 * and return "readable" when the timeout expires by using
981127664Sbms	 * the timeout as the "select()" or "poll()" timeout, putting
982127664Sbms	 * the BPF descriptor into non-blocking mode, and read from
983127664Sbms	 * it regardless of whether "select()" reports it as readable
984127664Sbms	 * or not.
985127664Sbms	 *
986127664Sbms	 * However, in FreeBSD 4.3 and 4.4, "select()" and "poll()"
987127664Sbms	 * won't wake up and return "readable" if the timer expires
988127664Sbms	 * and non-blocking reads return EWOULDBLOCK if the hold
989127664Sbms	 * buffer is empty, even if the store buffer is non-empty.
990127664Sbms	 *
991127664Sbms	 * This means the workaround in question won't work.
992127664Sbms	 *
993127664Sbms	 * Therefore, on FreeBSD 4.3 and 4.4, we set "p->selectable_fd"
994127664Sbms	 * to -1, which means "sorry, you can't use 'select()' or 'poll()'
995127664Sbms	 * here".  On all other BPF platforms, we set it to the FD for
996127664Sbms	 * the BPF device; in NetBSD, OpenBSD, and Darwin, a non-blocking
997127664Sbms	 * read will, if the hold buffer is empty and the store buffer
998127664Sbms	 * isn't empty, rotate the buffers and return what packets are
999127664Sbms	 * there (and in sufficiently recent versions of OpenBSD
1000127664Sbms	 * "select()" and "poll()" should work correctly).
1001127664Sbms	 *
1002127664Sbms	 * XXX - what about AIX?
1003127664Sbms	 */
1004147894Ssam	p->selectable_fd = p->fd;	/* assume select() works until we know otherwise */
1005127664Sbms	if (uname(&osinfo) == 0) {
1006127664Sbms		/*
1007127664Sbms		 * We can check what OS this is.
1008127664Sbms		 */
1009147894Ssam		if (strcmp(osinfo.sysname, "FreeBSD") == 0) {
1010147894Ssam			if (strncmp(osinfo.release, "4.3-", 4) == 0 ||
1011147894Ssam			     strncmp(osinfo.release, "4.4-", 4) == 0)
1012147894Ssam				p->selectable_fd = -1;
1013147894Ssam		}
1014127664Sbms	}
1015127664Sbms
1016127664Sbms	p->read_op = pcap_read_bpf;
1017146768Ssam	p->inject_op = pcap_inject_bpf;
1018127664Sbms	p->setfilter_op = pcap_setfilter_bpf;
1019147894Ssam	p->setdirection_op = pcap_setdirection_bpf;
1020127664Sbms	p->set_datalink_op = pcap_set_datalink_bpf;
1021127664Sbms	p->getnonblock_op = pcap_getnonblock_fd;
1022127664Sbms	p->setnonblock_op = pcap_setnonblock_fd;
1023127664Sbms	p->stats_op = pcap_stats_bpf;
1024146768Ssam	p->close_op = pcap_close_common;
1025127664Sbms
102617683Spst	return (p);
102717683Spst bad:
102817683Spst	(void)close(fd);
1029146768Ssam	if (p->dlt_list != NULL)
1030146768Ssam		free(p->dlt_list);
103117683Spst	free(p);
103217683Spst	return (NULL);
103317683Spst}
103417683Spst
103517683Spstint
1036127664Sbmspcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
103717683Spst{
1038127664Sbms#ifdef HAVE_DAG_API
1039127664Sbms	if (dag_platform_finddevs(alldevsp, errbuf) < 0)
1040127664Sbms		return (-1);
1041127664Sbms#endif /* HAVE_DAG_API */
1042127664Sbms
1043127664Sbms	return (0);
1044127664Sbms}
1045127664Sbms
1046127664Sbmsstatic int
1047127664Sbmspcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
1048127664Sbms{
104956889Sfenner	/*
105056889Sfenner	 * It looks that BPF code generated by gen_protochain() is not
105156889Sfenner	 * compatible with some of kernel BPF code (for example BSD/OS 3.1).
105256889Sfenner	 * Take a safer side for now.
105356889Sfenner	 */
105475107Sfenner	if (no_optimize) {
1055127664Sbms		/*
1056127664Sbms		 * XXX - what if we already have a filter in the kernel?
1057127664Sbms		 */
105875107Sfenner		if (install_bpf_program(p, fp) < 0)
105975107Sfenner			return (-1);
1060127664Sbms		p->md.use_bpf = 0;	/* filtering in userland */
1061127664Sbms		return (0);
1062127664Sbms	}
1063127664Sbms
1064127664Sbms	/*
1065127664Sbms	 * Free any user-mode filter we might happen to have installed.
1066127664Sbms	 */
1067127664Sbms	pcap_freecode(&p->fcode);
1068127664Sbms
1069127664Sbms	/*
1070127664Sbms	 * Try to install the kernel filter.
1071127664Sbms	 */
1072127664Sbms	if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
107375107Sfenner		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
107475107Sfenner		    pcap_strerror(errno));
107517683Spst		return (-1);
107617683Spst	}
1077127664Sbms	p->md.use_bpf = 1;	/* filtering in the kernel */
1078146768Ssam
1079146768Ssam	/*
1080146768Ssam	 * Discard any previously-received packets, as they might have
1081146768Ssam	 * passed whatever filter was formerly in effect, but might
1082146768Ssam	 * not pass this filter (BIOCSETF discards packets buffered
1083146768Ssam	 * in the kernel, so you can lose packets in any case).
1084146768Ssam	 */
1085146768Ssam	p->cc = 0;
108617683Spst	return (0);
108717683Spst}
1088109839Sfenner
1089147894Ssam/*
1090147894Ssam * Set direction flag: Which packets do we accept on a forwarding
1091147894Ssam * single device? IN, OUT or both?
1092147894Ssam */
1093127664Sbmsstatic int
1094162012Ssampcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
1095147894Ssam{
1096167035Sjkim#if defined(BIOCSDIRECTION)
1097167035Sjkim	u_int direction;
1098167035Sjkim
1099167035Sjkim	direction = (d == PCAP_D_IN) ? BPF_D_IN :
1100167035Sjkim	    ((d == PCAP_D_OUT) ? BPF_D_OUT : BPF_D_INOUT);
1101167035Sjkim	if (ioctl(p->fd, BIOCSDIRECTION, &direction) == -1) {
1102167035Sjkim		(void) snprintf(p->errbuf, sizeof(p->errbuf),
1103167035Sjkim		    "Cannot set direction to %s: %s",
1104167035Sjkim		        (d == PCAP_D_IN) ? "PCAP_D_IN" :
1105167035Sjkim			((d == PCAP_D_OUT) ? "PCAP_D_OUT" : "PCAP_D_INOUT"),
1106167035Sjkim			strerror(errno));
1107167035Sjkim		return (-1);
1108167035Sjkim	}
1109167035Sjkim	return (0);
1110167035Sjkim#elif defined(BIOCSSEESENT)
1111147894Ssam	u_int seesent;
1112147894Ssam
1113147894Ssam	/*
1114162012Ssam	 * We don't support PCAP_D_OUT.
1115147894Ssam	 */
1116162012Ssam	if (d == PCAP_D_OUT) {
1117147894Ssam		snprintf(p->errbuf, sizeof(p->errbuf),
1118162012Ssam		    "Setting direction to PCAP_D_OUT is not supported on BPF");
1119147894Ssam		return -1;
1120147894Ssam	}
1121167035Sjkim
1122162012Ssam	seesent = (d == PCAP_D_INOUT);
1123147894Ssam	if (ioctl(p->fd, BIOCSSEESENT, &seesent) == -1) {
1124147894Ssam		(void) snprintf(p->errbuf, sizeof(p->errbuf),
1125147894Ssam		    "Cannot set direction to %s: %s",
1126162012Ssam		        (d == PCAP_D_INOUT) ? "PCAP_D_INOUT" : "PCAP_D_IN",
1127147894Ssam			strerror(errno));
1128147894Ssam		return (-1);
1129147894Ssam	}
1130147894Ssam	return (0);
1131147894Ssam#else
1132147894Ssam	(void) snprintf(p->errbuf, sizeof(p->errbuf),
1133147894Ssam	    "This system doesn't support BIOCSSEESENT, so the direction can't be set");
1134147894Ssam	return (-1);
1135147894Ssam#endif
1136147894Ssam}
1137147894Ssam
1138147894Ssamstatic int
1139127664Sbmspcap_set_datalink_bpf(pcap_t *p, int dlt)
1140109839Sfenner{
1141127664Sbms#ifdef BIOCSDLT
1142109839Sfenner	if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) {
1143109839Sfenner		(void) snprintf(p->errbuf, sizeof(p->errbuf),
1144109839Sfenner		    "Cannot set DLT %d: %s", dlt, strerror(errno));
1145127664Sbms		return (-1);
1146109839Sfenner	}
1147127664Sbms#endif
1148127664Sbms	return (0);
1149109839Sfenner}
1150