pcap-bpf.c revision 127664
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.
2017683Spst */
2117683Spst#ifndef lint
22127664Sbmsstatic const char rcsid[] _U_ =
23127664Sbms    "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.67.2.4 2003/11/22 00:06:28 guy Exp $ (LBL)";
2417683Spst#endif
2517683Spst
2675107Sfenner#ifdef HAVE_CONFIG_H
2775107Sfenner#include "config.h"
2875107Sfenner#endif
2975107Sfenner
3017683Spst#include <sys/param.h>			/* optionally get BSD define */
3117683Spst#include <sys/time.h>
3217683Spst#include <sys/timeb.h>
3317683Spst#include <sys/socket.h>
3417683Spst#include <sys/file.h>
3517683Spst#include <sys/ioctl.h>
36127664Sbms#include <sys/utsname.h>
3717683Spst
3817683Spst#include <net/if.h>
39127664Sbms
4098530Sfenner#ifdef _AIX
41127664Sbms
4298530Sfenner/*
43127664Sbms * Make "pcap.h" not include "pcap-bpf.h"; we are going to include the
44127664Sbms * native OS version, as we need "struct bpf_config" from it.
4598530Sfenner */
46127664Sbms#define PCAP_DONT_INCLUDE_PCAP_BPF_H
47127664Sbms
48127664Sbms#include <sys/types.h>
49127664Sbms
50127664Sbms/*
51127664Sbms * Prevent bpf.h from redefining the DLT_ values to their
52127664Sbms * IFT_ values, as we're going to return the standard libpcap
53127664Sbms * values, not IBM's non-standard IFT_ values.
54127664Sbms */
55127664Sbms#undef _AIX
56127664Sbms#include <net/bpf.h>
57127664Sbms#define _AIX
58127664Sbms
5998530Sfenner#include <net/if_types.h>		/* for IFT_ values */
60127664Sbms#include <sys/sysconfig.h>
61127664Sbms#include <sys/device.h>
62127664Sbms#include <odmi.h>
63127664Sbms#include <cf.h>
6417683Spst
65127664Sbms#ifdef __64BIT__
66127664Sbms#define domakedev makedev64
67127664Sbms#define getmajor major64
68127664Sbms#define bpf_hdr bpf_hdr32
69127664Sbms#else /* __64BIT__ */
70127664Sbms#define domakedev makedev
71127664Sbms#define getmajor major
72127664Sbms#endif /* __64BIT__ */
73127664Sbms
74127664Sbms#define BPF_NAME "bpf"
75127664Sbms#define BPF_MINORS 4
76127664Sbms#define DRIVER_PATH "/usr/lib/drivers"
77127664Sbms#define BPF_NODE "/dev/bpf"
78127664Sbmsstatic int bpfloadedflag = 0;
79127664Sbmsstatic int odmlockid = 0;
80127664Sbms
81127664Sbms#else /* _AIX */
82127664Sbms
83127664Sbms#include <net/bpf.h>
84127664Sbms
85127664Sbms#endif /* _AIX */
86127664Sbms
8717683Spst#include <ctype.h>
8817683Spst#include <errno.h>
8917683Spst#include <netdb.h>
9017683Spst#include <stdio.h>
9117683Spst#include <stdlib.h>
9217683Spst#include <string.h>
9317683Spst#include <unistd.h>
9417683Spst
9517683Spst#include "pcap-int.h"
9617683Spst
97127664Sbms#ifdef HAVE_DAG_API
98127664Sbms#include "pcap-dag.h"
99127664Sbms#endif /* HAVE_DAG_API */
100127664Sbms
10117683Spst#ifdef HAVE_OS_PROTO_H
10217683Spst#include "os-proto.h"
10317683Spst#endif
10417683Spst
105127664Sbms#include "gencode.h"	/* for "no_optimize" */
10656889Sfenner
107127664Sbmsstatic int pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp);
108127664Sbmsstatic int pcap_set_datalink_bpf(pcap_t *p, int dlt);
109127664Sbms
110127664Sbmsstatic int
111127664Sbmspcap_stats_bpf(pcap_t *p, struct pcap_stat *ps)
11217683Spst{
11317683Spst	struct bpf_stat s;
11417683Spst
11598530Sfenner	/*
11698530Sfenner	 * "ps_recv" counts packets handed to the filter, not packets
11798530Sfenner	 * that passed the filter.  This includes packets later dropped
11898530Sfenner	 * because we ran out of buffer space.
11998530Sfenner	 *
12098530Sfenner	 * "ps_drop" counts packets dropped inside the BPF device
12198530Sfenner	 * because we ran out of buffer space.  It doesn't count
12298530Sfenner	 * packets dropped by the interface driver.  It counts
12398530Sfenner	 * only packets that passed the filter.
12498530Sfenner	 *
12598530Sfenner	 * Both statistics include packets not yet read from the kernel
12698530Sfenner	 * by libpcap, and thus not yet seen by the application.
12798530Sfenner	 */
12817683Spst	if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) {
12975107Sfenner		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGSTATS: %s",
13075107Sfenner		    pcap_strerror(errno));
13117683Spst		return (-1);
13217683Spst	}
13317683Spst
13417683Spst	ps->ps_recv = s.bs_recv;
13517683Spst	ps->ps_drop = s.bs_drop;
13617683Spst	return (0);
13717683Spst}
13817683Spst
139127664Sbmsstatic int
140127664Sbmspcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
14117683Spst{
14217683Spst	int cc;
14317683Spst	int n = 0;
14417683Spst	register u_char *bp, *ep;
145127664Sbms	struct bpf_insn *fcode;
14617683Spst
147127664Sbms	fcode = p->md.use_bpf ? NULL : p->fcode.bf_insns;
14817683Spst again:
149127664Sbms	/*
150127664Sbms	 * Has "pcap_breakloop()" been called?
151127664Sbms	 */
152127664Sbms	if (p->break_loop) {
153127664Sbms		/*
154127664Sbms		 * Yes - clear the flag that indicates that it
155127664Sbms		 * has, and return -2 to indicate that we were
156127664Sbms		 * told to break out of the loop.
157127664Sbms		 */
158127664Sbms		p->break_loop = 0;
159127664Sbms		return (-2);
160127664Sbms	}
16117683Spst	cc = p->cc;
16217683Spst	if (p->cc == 0) {
16317683Spst		cc = read(p->fd, (char *)p->buffer, p->bufsize);
16417683Spst		if (cc < 0) {
16517683Spst			/* Don't choke when we get ptraced */
16617683Spst			switch (errno) {
16717683Spst
16817683Spst			case EINTR:
16917683Spst				goto again;
17017683Spst
171127664Sbms#ifdef _AIX
172127664Sbms			case EFAULT:
173127664Sbms				/*
174127664Sbms				 * Sigh.  More AIX wonderfulness.
175127664Sbms				 *
176127664Sbms				 * For some unknown reason the uiomove()
177127664Sbms				 * operation in the bpf kernel extension
178127664Sbms				 * used to copy the buffer into user
179127664Sbms				 * space sometimes returns EFAULT. I have
180127664Sbms				 * no idea why this is the case given that
181127664Sbms				 * a kernel debugger shows the user buffer
182127664Sbms				 * is correct. This problem appears to
183127664Sbms				 * be mostly mitigated by the memset of
184127664Sbms				 * the buffer before it is first used.
185127664Sbms				 * Very strange.... Shaun Clowes
186127664Sbms				 *
187127664Sbms				 * In any case this means that we shouldn't
188127664Sbms				 * treat EFAULT as a fatal error; as we
189127664Sbms				 * don't have an API for returning
190127664Sbms				 * a "some packets were dropped since
191127664Sbms				 * the last packet you saw" indication,
192127664Sbms				 * we just ignore EFAULT and keep reading.
193127664Sbms				 */
194127664Sbms				goto again;
195127664Sbms#endif
196127664Sbms
19717683Spst			case EWOULDBLOCK:
19817683Spst				return (0);
19917683Spst#if defined(sun) && !defined(BSD)
20017683Spst			/*
20117683Spst			 * Due to a SunOS bug, after 2^31 bytes, the kernel
20217683Spst			 * file offset overflows and read fails with EINVAL.
20317683Spst			 * The lseek() to 0 will fix things.
20417683Spst			 */
20517683Spst			case EINVAL:
20617683Spst				if (lseek(p->fd, 0L, SEEK_CUR) +
20717683Spst				    p->bufsize < 0) {
20817683Spst					(void)lseek(p->fd, 0L, SEEK_SET);
20917683Spst					goto again;
21017683Spst				}
21117683Spst				/* fall through */
21217683Spst#endif
21317683Spst			}
21475107Sfenner			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read: %s",
21575107Sfenner			    pcap_strerror(errno));
21617683Spst			return (-1);
21717683Spst		}
21817683Spst		bp = p->buffer;
21917683Spst	} else
22017683Spst		bp = p->bp;
22117683Spst
22217683Spst	/*
22317683Spst	 * Loop through each packet.
22417683Spst	 */
22517683Spst#define bhp ((struct bpf_hdr *)bp)
22617683Spst	ep = bp + cc;
22717683Spst	while (bp < ep) {
22817683Spst		register int caplen, hdrlen;
229127664Sbms
230127664Sbms		/*
231127664Sbms		 * Has "pcap_breakloop()" been called?
232127664Sbms		 * If so, return immediately - if we haven't read any
233127664Sbms		 * packets, clear the flag and return -2 to indicate
234127664Sbms		 * that we were told to break out of the loop, otherwise
235127664Sbms		 * leave the flag set, so that the *next* call will break
236127664Sbms		 * out of the loop without having read any packets, and
237127664Sbms		 * return the number of packets we've processed so far.
238127664Sbms		 */
239127664Sbms		if (p->break_loop) {
240127664Sbms			if (n == 0) {
241127664Sbms				p->break_loop = 0;
242127664Sbms				return (-2);
243127664Sbms			} else {
244127664Sbms				p->bp = bp;
245127664Sbms				p->cc = ep - bp;
246127664Sbms				return (n);
247127664Sbms			}
248127664Sbms		}
249127664Sbms
25017683Spst		caplen = bhp->bh_caplen;
25117683Spst		hdrlen = bhp->bh_hdrlen;
25217683Spst		/*
253127664Sbms		 * Short-circuit evaluation: if using BPF filter
254127664Sbms		 * in kernel, no need to do it now.
25517683Spst		 */
256127664Sbms		if (fcode == NULL ||
257127664Sbms		    bpf_filter(fcode, bp + hdrlen, bhp->bh_datalen, caplen)) {
25898530Sfenner#ifdef _AIX
259127664Sbms			/*
260127664Sbms			 * AIX's BPF returns seconds/nanoseconds time
261127664Sbms			 * stamps, not seconds/microseconds time stamps.
262127664Sbms			 *
263127664Sbms			 * XXX - I'm guessing here that it's a "struct
264127664Sbms			 * timestamp"; if not, this code won't compile,
265127664Sbms			 * but, if not, you want to send us a bug report
266127664Sbms			 * and fall back on using DLPI.  It's not as if
267127664Sbms			 * BPF used to work right on AIX before this
268127664Sbms			 * change; this change attempts to fix the fact
269127664Sbms			 * that it didn't....
270127664Sbms			 */
271127664Sbms			bhp->bh_tstamp.tv_usec = bhp->bh_tstamp.tv_usec/1000;
27298530Sfenner#endif
273127664Sbms			/*
274127664Sbms			 * XXX A bpf_hdr matches a pcap_pkthdr.
275127664Sbms			 */
276127664Sbms			(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
277127664Sbms			bp += BPF_WORDALIGN(caplen + hdrlen);
278127664Sbms			if (++n >= cnt && cnt > 0) {
279127664Sbms				p->bp = bp;
280127664Sbms				p->cc = ep - bp;
281127664Sbms				return (n);
282127664Sbms			}
283127664Sbms		} else {
284127664Sbms			/*
285127664Sbms			 * Skip this packet.
286127664Sbms			 */
287127664Sbms			bp += BPF_WORDALIGN(caplen + hdrlen);
28817683Spst		}
28917683Spst	}
29017683Spst#undef bhp
29117683Spst	p->cc = 0;
29217683Spst	return (n);
29317683Spst}
29417683Spst
295127664Sbms#ifdef _AIX
296127664Sbmsstatic int
297127664Sbmsbpf_odminit(char *errbuf)
298127664Sbms{
299127664Sbms	char *errstr;
300127664Sbms
301127664Sbms	if (odm_initialize() == -1) {
302127664Sbms		if (odm_err_msg(odmerrno, &errstr) == -1)
303127664Sbms			errstr = "Unknown error";
304127664Sbms		snprintf(errbuf, PCAP_ERRBUF_SIZE,
305127664Sbms		    "bpf_load: odm_initialize failed: %s",
306127664Sbms		    errstr);
307127664Sbms		return (-1);
308127664Sbms	}
309127664Sbms
310127664Sbms	if ((odmlockid = odm_lock("/etc/objrepos/config_lock", ODM_WAIT)) == -1) {
311127664Sbms		if (odm_err_msg(odmerrno, &errstr) == -1)
312127664Sbms			errstr = "Unknown error";
313127664Sbms		snprintf(errbuf, PCAP_ERRBUF_SIZE,
314127664Sbms		    "bpf_load: odm_lock of /etc/objrepos/config_lock failed: %s",
315127664Sbms		    errstr);
316127664Sbms		return (-1);
317127664Sbms	}
318127664Sbms
319127664Sbms	return (0);
320127664Sbms}
321127664Sbms
322127664Sbmsstatic int
323127664Sbmsbpf_odmcleanup(char *errbuf)
324127664Sbms{
325127664Sbms	char *errstr;
326127664Sbms
327127664Sbms	if (odm_unlock(odmlockid) == -1) {
328127664Sbms		if (odm_err_msg(odmerrno, &errstr) == -1)
329127664Sbms			errstr = "Unknown error";
330127664Sbms		snprintf(errbuf, PCAP_ERRBUF_SIZE,
331127664Sbms		    "bpf_load: odm_unlock failed: %s",
332127664Sbms		    errstr);
333127664Sbms		return (-1);
334127664Sbms	}
335127664Sbms
336127664Sbms	if (odm_terminate() == -1) {
337127664Sbms		if (odm_err_msg(odmerrno, &errstr) == -1)
338127664Sbms			errstr = "Unknown error";
339127664Sbms		snprintf(errbuf, PCAP_ERRBUF_SIZE,
340127664Sbms		    "bpf_load: odm_terminate failed: %s",
341127664Sbms		    errstr);
342127664Sbms		return (-1);
343127664Sbms	}
344127664Sbms
345127664Sbms	return (0);
346127664Sbms}
347127664Sbms
348127664Sbmsstatic int
349127664Sbmsbpf_load(char *errbuf)
350127664Sbms{
351127664Sbms	long major;
352127664Sbms	int *minors;
353127664Sbms	int numminors, i, rc;
354127664Sbms	char buf[1024];
355127664Sbms	struct stat sbuf;
356127664Sbms	struct bpf_config cfg_bpf;
357127664Sbms	struct cfg_load cfg_ld;
358127664Sbms	struct cfg_kmod cfg_km;
359127664Sbms
360127664Sbms	/*
361127664Sbms	 * This is very very close to what happens in the real implementation
362127664Sbms	 * but I've fixed some (unlikely) bug situations.
363127664Sbms	 */
364127664Sbms	if (bpfloadedflag)
365127664Sbms		return (0);
366127664Sbms
367127664Sbms	if (bpf_odminit(errbuf) != 0)
368127664Sbms		return (-1);
369127664Sbms
370127664Sbms	major = genmajor(BPF_NAME);
371127664Sbms	if (major == -1) {
372127664Sbms		snprintf(errbuf, PCAP_ERRBUF_SIZE,
373127664Sbms		    "bpf_load: genmajor failed: %s", pcap_strerror(errno));
374127664Sbms		return (-1);
375127664Sbms	}
376127664Sbms
377127664Sbms	minors = getminor(major, &numminors, BPF_NAME);
378127664Sbms	if (!minors) {
379127664Sbms		minors = genminor("bpf", major, 0, BPF_MINORS, 1, 1);
380127664Sbms		if (!minors) {
381127664Sbms			snprintf(errbuf, PCAP_ERRBUF_SIZE,
382127664Sbms			    "bpf_load: genminor failed: %s",
383127664Sbms			    pcap_strerror(errno));
384127664Sbms			return (-1);
385127664Sbms		}
386127664Sbms	}
387127664Sbms
388127664Sbms	if (bpf_odmcleanup(errbuf))
389127664Sbms		return (-1);
390127664Sbms
391127664Sbms	rc = stat(BPF_NODE "0", &sbuf);
392127664Sbms	if (rc == -1 && errno != ENOENT) {
393127664Sbms		snprintf(errbuf, PCAP_ERRBUF_SIZE,
394127664Sbms		    "bpf_load: can't stat %s: %s",
395127664Sbms		    BPF_NODE "0", pcap_strerror(errno));
396127664Sbms		return (-1);
397127664Sbms	}
398127664Sbms
399127664Sbms	if (rc == -1 || getmajor(sbuf.st_rdev) != major) {
400127664Sbms		for (i = 0; i < BPF_MINORS; i++) {
401127664Sbms			sprintf(buf, "%s%d", BPF_NODE, i);
402127664Sbms			unlink(buf);
403127664Sbms			if (mknod(buf, S_IRUSR | S_IFCHR, domakedev(major, i)) == -1) {
404127664Sbms				snprintf(errbuf, PCAP_ERRBUF_SIZE,
405127664Sbms				    "bpf_load: can't mknod %s: %s",
406127664Sbms				    buf, pcap_strerror(errno));
407127664Sbms				return (-1);
408127664Sbms			}
409127664Sbms		}
410127664Sbms	}
411127664Sbms
412127664Sbms	/* Check if the driver is loaded */
413127664Sbms	memset(&cfg_ld, 0x0, sizeof(cfg_ld));
414127664Sbms	cfg_ld.path = buf;
415127664Sbms	sprintf(cfg_ld.path, "%s/%s", DRIVER_PATH, BPF_NAME);
416127664Sbms	if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) ||
417127664Sbms	    (cfg_ld.kmid == 0)) {
418127664Sbms		/* Driver isn't loaded, load it now */
419127664Sbms		if (sysconfig(SYS_SINGLELOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) {
420127664Sbms			snprintf(errbuf, PCAP_ERRBUF_SIZE,
421127664Sbms			    "bpf_load: could not load driver: %s",
422127664Sbms			    strerror(errno));
423127664Sbms			return (-1);
424127664Sbms		}
425127664Sbms	}
426127664Sbms
427127664Sbms	/* Configure the driver */
428127664Sbms	cfg_km.cmd = CFG_INIT;
429127664Sbms	cfg_km.kmid = cfg_ld.kmid;
430127664Sbms	cfg_km.mdilen = sizeof(cfg_bpf);
431127664Sbms	cfg_km.mdiptr = (void *)&cfg_bpf;
432127664Sbms	for (i = 0; i < BPF_MINORS; i++) {
433127664Sbms		cfg_bpf.devno = domakedev(major, i);
434127664Sbms		if (sysconfig(SYS_CFGKMOD, (void *)&cfg_km, sizeof(cfg_km)) == -1) {
435127664Sbms			snprintf(errbuf, PCAP_ERRBUF_SIZE,
436127664Sbms			    "bpf_load: could not configure driver: %s",
437127664Sbms			    strerror(errno));
438127664Sbms			return (-1);
439127664Sbms		}
440127664Sbms	}
441127664Sbms
442127664Sbms	bpfloadedflag = 1;
443127664Sbms
444127664Sbms	return (0);
445127664Sbms}
446127664Sbms#endif
447127664Sbms
44817683Spststatic inline int
44917683Spstbpf_open(pcap_t *p, char *errbuf)
45017683Spst{
45117683Spst	int fd;
45217683Spst	int n = 0;
45375107Sfenner	char device[sizeof "/dev/bpf0000000000"];
45417683Spst
455127664Sbms#ifdef _AIX
45617683Spst	/*
457127664Sbms	 * Load the bpf driver, if it isn't already loaded,
458127664Sbms	 * and create the BPF device entries, if they don't
459127664Sbms	 * already exist.
460127664Sbms	 */
461127664Sbms	if (bpf_load(errbuf) == -1)
462127664Sbms		return (-1);
463127664Sbms#endif
464127664Sbms
465127664Sbms	/*
46617683Spst	 * Go through all the minors and find one that isn't in use.
46717683Spst	 */
46817683Spst	do {
46975107Sfenner		(void)snprintf(device, sizeof(device), "/dev/bpf%d", n++);
47017683Spst		fd = open(device, O_RDONLY);
47117683Spst	} while (fd < 0 && errno == EBUSY);
47217683Spst
47317683Spst	/*
47417683Spst	 * XXX better message for all minors used
47517683Spst	 */
47617683Spst	if (fd < 0)
47775107Sfenner		snprintf(errbuf, PCAP_ERRBUF_SIZE, "(no devices found) %s: %s",
47875107Sfenner		    device, pcap_strerror(errno));
47917683Spst
48017683Spst	return (fd);
48117683Spst}
48217683Spst
483127664Sbmsstatic void
484127664Sbmspcap_close_bpf(pcap_t *p)
485127664Sbms{
486127664Sbms	if (p->buffer != NULL)
487127664Sbms		free(p->buffer);
488127664Sbms	if (p->fd >= 0)
489127664Sbms		close(p->fd);
490127664Sbms}
491127664Sbms
492127664Sbms/*
493127664Sbms * XXX - on AIX, IBM's tcpdump (and perhaps the incompatible-with-everybody-
494127664Sbms * else's libpcap in AIX 5.1) appears to forcibly load the BPF driver
495127664Sbms * if it's not already loaded, and to create the BPF devices if they
496127664Sbms * don't exist.
497127664Sbms *
498127664Sbms * It'd be nice if we could do the same, although the code to do so
499127664Sbms * might be version-dependent, alas (the way to do it isn't necessarily
500127664Sbms * documented).
501127664Sbms */
50217683Spstpcap_t *
503127664Sbmspcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
504127664Sbms    char *ebuf)
50517683Spst{
50617683Spst	int fd;
50717683Spst	struct ifreq ifr;
50817683Spst	struct bpf_version bv;
509127664Sbms#ifdef BIOCGDLTLIST
510109839Sfenner	struct bpf_dltlist bdl;
511127664Sbms#endif
51217683Spst	u_int v;
51317683Spst	pcap_t *p;
514127664Sbms	struct utsname osinfo;
51517683Spst
516127664Sbms#ifdef HAVE_DAG_API
517127664Sbms	if (strstr(device, "dag")) {
518127664Sbms		return dag_open_live(device, snaplen, promisc, to_ms, ebuf);
519127664Sbms	}
520127664Sbms#endif /* HAVE_DAG_API */
521109839Sfenner
522127664Sbms#ifdef BIOCGDLTLIST
523127664Sbms	memset(&bdl, 0, sizeof(bdl));
524127664Sbms#endif
525127664Sbms
52617683Spst	p = (pcap_t *)malloc(sizeof(*p));
52717683Spst	if (p == NULL) {
52875107Sfenner		snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
52975107Sfenner		    pcap_strerror(errno));
53017683Spst		return (NULL);
53117683Spst	}
53275107Sfenner	memset(p, 0, sizeof(*p));
53317683Spst	fd = bpf_open(p, ebuf);
53417683Spst	if (fd < 0)
53517683Spst		goto bad;
53617683Spst
53717683Spst	p->fd = fd;
53817683Spst	p->snapshot = snaplen;
53917683Spst
54017683Spst	if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) {
54175107Sfenner		snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s",
54275107Sfenner		    pcap_strerror(errno));
54317683Spst		goto bad;
54417683Spst	}
54517683Spst	if (bv.bv_major != BPF_MAJOR_VERSION ||
54617683Spst	    bv.bv_minor < BPF_MINOR_VERSION) {
54775107Sfenner		snprintf(ebuf, PCAP_ERRBUF_SIZE,
54875107Sfenner		    "kernel bpf filter out of date");
54917683Spst		goto bad;
55017683Spst	}
55175107Sfenner
55275107Sfenner	/*
55375107Sfenner	 * Try finding a good size for the buffer; 32768 may be too
55475107Sfenner	 * big, so keep cutting it in half until we find a size
555127664Sbms	 * that works, or run out of sizes to try.  If the default
556127664Sbms	 * is larger, don't make it smaller.
55775107Sfenner	 *
55875107Sfenner	 * XXX - there should be a user-accessible hook to set the
55975107Sfenner	 * initial buffer size.
56039291Sfenner	 */
561127664Sbms	if ((ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) || v < 32768)
562127664Sbms		v = 32768;
563127664Sbms	for ( ; v != 0; v >>= 1) {
56475107Sfenner		/* Ignore the return value - this is because the call fails
56575107Sfenner		 * on BPF systems that don't have kernel malloc.  And if
56675107Sfenner		 * the call fails, it's no big deal, we just continue to
56775107Sfenner		 * use the standard buffer size.
56875107Sfenner		 */
56975107Sfenner		(void) ioctl(fd, BIOCSBLEN, (caddr_t)&v);
57039291Sfenner
57175107Sfenner		(void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
57275107Sfenner		if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0)
57375107Sfenner			break;	/* that size worked; we're done */
57475107Sfenner
57575107Sfenner		if (errno != ENOBUFS) {
57675107Sfenner			snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s",
57775107Sfenner			    device, pcap_strerror(errno));
57875107Sfenner			goto bad;
57975107Sfenner		}
58075107Sfenner	}
58175107Sfenner
58275107Sfenner	if (v == 0) {
58375107Sfenner		snprintf(ebuf, PCAP_ERRBUF_SIZE,
58475107Sfenner			 "BIOCSBLEN: %s: No buffer size worked", device);
58517683Spst		goto bad;
58617683Spst	}
58775107Sfenner
58817683Spst	/* Get the data link layer type. */
58917683Spst	if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
59075107Sfenner		snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s",
59175107Sfenner		    pcap_strerror(errno));
59217683Spst		goto bad;
59317683Spst	}
59498530Sfenner#ifdef _AIX
59598530Sfenner	/*
59698530Sfenner	 * AIX's BPF returns IFF_ types, not DLT_ types, in BIOCGDLT.
59798530Sfenner	 */
59856889Sfenner	switch (v) {
59998530Sfenner
60098530Sfenner	case IFT_ETHER:
60198530Sfenner	case IFT_ISO88023:
60298530Sfenner		v = DLT_EN10MB;
60398530Sfenner		break;
60498530Sfenner
60598530Sfenner	case IFT_FDDI:
60698530Sfenner		v = DLT_FDDI;
60798530Sfenner		break;
60898530Sfenner
60998530Sfenner	case IFT_ISO88025:
61098530Sfenner		v = DLT_IEEE802;
61198530Sfenner		break;
61298530Sfenner
613127664Sbms	case IFT_LOOP:
614127664Sbms		v = DLT_NULL;
615127664Sbms		break;
616127664Sbms
61798530Sfenner	default:
61875107Sfenner		/*
61998530Sfenner		 * We don't know what to map this to yet.
62075107Sfenner		 */
621127664Sbms		snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown interface type %u",
62298530Sfenner		    v);
62398530Sfenner		goto bad;
62456889Sfenner	}
62556889Sfenner#endif
62639291Sfenner#if _BSDI_VERSION - 0 >= 199510
62739291Sfenner	/* The SLIP and PPP link layer header changed in BSD/OS 2.1 */
62839291Sfenner	switch (v) {
62939291Sfenner
63039291Sfenner	case DLT_SLIP:
63139291Sfenner		v = DLT_SLIP_BSDOS;
63239291Sfenner		break;
63339291Sfenner
63439291Sfenner	case DLT_PPP:
63539291Sfenner		v = DLT_PPP_BSDOS;
63639291Sfenner		break;
63756889Sfenner
63856889Sfenner	case 11:	/*DLT_FR*/
639127664Sbms		v = DLT_FRELAY;
64056889Sfenner		break;
64156889Sfenner
64256889Sfenner	case 12:	/*DLT_C_HDLC*/
64356889Sfenner		v = DLT_CHDLC;
64456889Sfenner		break;
64539291Sfenner	}
64639291Sfenner#endif
64717683Spst	p->linktype = v;
64817683Spst
649127664Sbms#ifdef BIOCGDLTLIST
650109839Sfenner	/*
651127664Sbms	 * We know the default link type -- now determine all the DLTs
652127664Sbms	 * this interface supports.  If this fails with EINVAL, it's
653127664Sbms	 * not fatal; we just don't get to use the feature later.
654109839Sfenner	 */
655127664Sbms	if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) == 0) {
656109839Sfenner		bdl.bfl_list = (u_int *) malloc(sizeof(u_int) * bdl.bfl_len);
657109839Sfenner		if (bdl.bfl_list == NULL) {
658109839Sfenner			(void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
659109839Sfenner			    pcap_strerror(errno));
660109839Sfenner			goto bad;
661109839Sfenner		}
662109839Sfenner
663127664Sbms		if (ioctl(fd, BIOCGDLTLIST, (caddr_t)&bdl) < 0) {
664109839Sfenner			(void)snprintf(ebuf, PCAP_ERRBUF_SIZE,
665109839Sfenner			    "BIOCGDLTLIST: %s", pcap_strerror(errno));
666109839Sfenner			goto bad;
667109839Sfenner		}
668109839Sfenner
669109839Sfenner		p->dlt_count = bdl.bfl_len;
670109839Sfenner		p->dlt_list = bdl.bfl_list;
671127664Sbms	} else {
672127664Sbms		if (errno != EINVAL) {
673127664Sbms			(void)snprintf(ebuf, PCAP_ERRBUF_SIZE,
674127664Sbms			    "BIOCGDLTLIST: %s", pcap_strerror(errno));
675127664Sbms			goto bad;
676127664Sbms		}
677109839Sfenner	}
678127664Sbms#endif
679109839Sfenner
68017683Spst	/* set timeout */
68117683Spst	if (to_ms != 0) {
682127664Sbms		/*
683127664Sbms		 * XXX - is this seconds/nanoseconds in AIX?
684127664Sbms		 * (Treating it as such doesn't fix the timeout
685127664Sbms		 * problem described below.)
686127664Sbms		 */
68717683Spst		struct timeval to;
68817683Spst		to.tv_sec = to_ms / 1000;
68917683Spst		to.tv_usec = (to_ms * 1000) % 1000000;
69017683Spst		if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) {
69175107Sfenner			snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s",
69275107Sfenner			    pcap_strerror(errno));
69317683Spst			goto bad;
69417683Spst		}
69517683Spst	}
69675107Sfenner
69775107Sfenner#ifdef _AIX
69875107Sfenner#ifdef	BIOCIMMEDIATE
69975107Sfenner	/*
70075107Sfenner	 * Darren Reed notes that
70175107Sfenner	 *
70275107Sfenner	 *	On AIX (4.2 at least), if BIOCIMMEDIATE is not set, the
70375107Sfenner	 *	timeout appears to be ignored and it waits until the buffer
70475107Sfenner	 *	is filled before returning.  The result of not having it
70575107Sfenner	 *	set is almost worse than useless if your BPF filter
70675107Sfenner	 *	is reducing things to only a few packets (i.e. one every
70775107Sfenner	 *	second or so).
70875107Sfenner	 *
70975107Sfenner	 * so we turn BIOCIMMEDIATE mode on if this is AIX.
71075107Sfenner	 *
71175107Sfenner	 * We don't turn it on for other platforms, as that means we
71275107Sfenner	 * get woken up for every packet, which may not be what we want;
71375107Sfenner	 * in the Winter 1993 USENIX paper on BPF, they say:
71475107Sfenner	 *
71575107Sfenner	 *	Since a process might want to look at every packet on a
71675107Sfenner	 *	network and the time between packets can be only a few
71775107Sfenner	 *	microseconds, it is not possible to do a read system call
71875107Sfenner	 *	per packet and BPF must collect the data from several
71975107Sfenner	 *	packets and return it as a unit when the monitoring
72075107Sfenner	 *	application does a read.
72175107Sfenner	 *
72275107Sfenner	 * which I infer is the reason for the timeout - it means we
72375107Sfenner	 * wait that amount of time, in the hopes that more packets
72475107Sfenner	 * will arrive and we'll get them all with one read.
72575107Sfenner	 *
72675107Sfenner	 * Setting BIOCIMMEDIATE mode on FreeBSD (and probably other
72775107Sfenner	 * BSDs) causes the timeout to be ignored.
72875107Sfenner	 *
72975107Sfenner	 * On the other hand, some platforms (e.g., Linux) don't support
73075107Sfenner	 * timeouts, they just hand stuff to you as soon as it arrives;
73175107Sfenner	 * if that doesn't cause a problem on those platforms, it may
73275107Sfenner	 * be OK to have BIOCIMMEDIATE mode on BSD as well.
73375107Sfenner	 *
73475107Sfenner	 * (Note, though, that applications may depend on the read
73575107Sfenner	 * completing, even if no packets have arrived, when the timeout
73675107Sfenner	 * expires, e.g. GUI applications that have to check for input
73775107Sfenner	 * while waiting for packets to arrive; a non-zero timeout
73875107Sfenner	 * prevents "select()" from working right on FreeBSD and
73975107Sfenner	 * possibly other BSDs, as the timer doesn't start until a
74075107Sfenner	 * "read()" is done, so the timer isn't in effect if the
74175107Sfenner	 * application is blocked on a "select()", and the "select()"
74275107Sfenner	 * doesn't get woken up for a BPF device until the buffer
74375107Sfenner	 * fills up.)
74475107Sfenner	 */
74575107Sfenner	v = 1;
74675107Sfenner	if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) {
74775107Sfenner		snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s",
74875107Sfenner		    pcap_strerror(errno));
74975107Sfenner		goto bad;
75075107Sfenner	}
75175107Sfenner#endif	/* BIOCIMMEDIATE */
75275107Sfenner#endif	/* _AIX */
75375107Sfenner
75498530Sfenner	if (promisc) {
75517683Spst		/* set promiscuous mode, okay if it fails */
75698530Sfenner		if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) {
75798530Sfenner			snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s",
75898530Sfenner			    pcap_strerror(errno));
75998530Sfenner		}
76098530Sfenner	}
76117683Spst
76217683Spst	if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
76375107Sfenner		snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s",
76475107Sfenner		    pcap_strerror(errno));
76517683Spst		goto bad;
76617683Spst	}
76717683Spst	p->bufsize = v;
76817683Spst	p->buffer = (u_char *)malloc(p->bufsize);
76917683Spst	if (p->buffer == NULL) {
77075107Sfenner		snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
77175107Sfenner		    pcap_strerror(errno));
77217683Spst		goto bad;
77317683Spst	}
774127664Sbms#ifdef _AIX
775127664Sbms	/* For some strange reason this seems to prevent the EFAULT
776127664Sbms	 * problems we have experienced from AIX BPF. */
777127664Sbms	memset(p->buffer, 0x0, p->bufsize);
778127664Sbms#endif
77917683Spst
780127664Sbms	/*
781127664Sbms	 * On most BPF platforms, either you can do a "select()" or
782127664Sbms	 * "poll()" on a BPF file descriptor and it works correctly,
783127664Sbms	 * or you can do it and it will return "readable" if the
784127664Sbms	 * hold buffer is full but not if the timeout expires *and*
785127664Sbms	 * a non-blocking read will, if the hold buffer is empty
786127664Sbms	 * but the store buffer isn't empty, rotate the buffers
787127664Sbms	 * and return what packets are available.
788127664Sbms	 *
789127664Sbms	 * In the latter case, the fact that a non-blocking read
790127664Sbms	 * will give you the available packets means you can work
791127664Sbms	 * around the failure of "select()" and "poll()" to wake up
792127664Sbms	 * and return "readable" when the timeout expires by using
793127664Sbms	 * the timeout as the "select()" or "poll()" timeout, putting
794127664Sbms	 * the BPF descriptor into non-blocking mode, and read from
795127664Sbms	 * it regardless of whether "select()" reports it as readable
796127664Sbms	 * or not.
797127664Sbms	 *
798127664Sbms	 * However, in FreeBSD 4.3 and 4.4, "select()" and "poll()"
799127664Sbms	 * won't wake up and return "readable" if the timer expires
800127664Sbms	 * and non-blocking reads return EWOULDBLOCK if the hold
801127664Sbms	 * buffer is empty, even if the store buffer is non-empty.
802127664Sbms	 *
803127664Sbms	 * This means the workaround in question won't work.
804127664Sbms	 *
805127664Sbms	 * Therefore, on FreeBSD 4.3 and 4.4, we set "p->selectable_fd"
806127664Sbms	 * to -1, which means "sorry, you can't use 'select()' or 'poll()'
807127664Sbms	 * here".  On all other BPF platforms, we set it to the FD for
808127664Sbms	 * the BPF device; in NetBSD, OpenBSD, and Darwin, a non-blocking
809127664Sbms	 * read will, if the hold buffer is empty and the store buffer
810127664Sbms	 * isn't empty, rotate the buffers and return what packets are
811127664Sbms	 * there (and in sufficiently recent versions of OpenBSD
812127664Sbms	 * "select()" and "poll()" should work correctly).
813127664Sbms	 *
814127664Sbms	 * XXX - what about AIX?
815127664Sbms	 */
816127664Sbms	if (uname(&osinfo) == 0) {
817127664Sbms		/*
818127664Sbms		 * We can check what OS this is.
819127664Sbms		 */
820127664Sbms		if (strcmp(osinfo.sysname, "FreeBSD") == 0 &&
821127664Sbms		    (strcmp(osinfo.release, "4.3") == 0 ||
822127664Sbms		     strcmp(osinfo.release, "4.4") == 0))
823127664Sbms			p->selectable_fd = -1;
824127664Sbms		else
825127664Sbms			p->selectable_fd = p->fd;
826127664Sbms	} else {
827127664Sbms		/*
828127664Sbms		 * We can't find out what OS this is, so assume we can
829127664Sbms		 * do a "select()" or "poll()".
830127664Sbms		 */
831127664Sbms		p->selectable_fd = p->fd;
832127664Sbms	}
833127664Sbms
834127664Sbms	p->read_op = pcap_read_bpf;
835127664Sbms	p->setfilter_op = pcap_setfilter_bpf;
836127664Sbms	p->set_datalink_op = pcap_set_datalink_bpf;
837127664Sbms	p->getnonblock_op = pcap_getnonblock_fd;
838127664Sbms	p->setnonblock_op = pcap_setnonblock_fd;
839127664Sbms	p->stats_op = pcap_stats_bpf;
840127664Sbms	p->close_op = pcap_close_bpf;
841127664Sbms
84217683Spst	return (p);
84317683Spst bad:
84417683Spst	(void)close(fd);
845127664Sbms#ifdef BIOCGDLTLIST
846109839Sfenner	if (bdl.bfl_list != NULL)
847109839Sfenner		free(bdl.bfl_list);
848127664Sbms#endif
84917683Spst	free(p);
85017683Spst	return (NULL);
85117683Spst}
85217683Spst
85317683Spstint
854127664Sbmspcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
85517683Spst{
856127664Sbms#ifdef HAVE_DAG_API
857127664Sbms	if (dag_platform_finddevs(alldevsp, errbuf) < 0)
858127664Sbms		return (-1);
859127664Sbms#endif /* HAVE_DAG_API */
860127664Sbms
861127664Sbms	return (0);
862127664Sbms}
863127664Sbms
864127664Sbmsstatic int
865127664Sbmspcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
866127664Sbms{
86756889Sfenner	/*
86856889Sfenner	 * It looks that BPF code generated by gen_protochain() is not
86956889Sfenner	 * compatible with some of kernel BPF code (for example BSD/OS 3.1).
87056889Sfenner	 * Take a safer side for now.
87156889Sfenner	 */
87275107Sfenner	if (no_optimize) {
873127664Sbms		/*
874127664Sbms		 * XXX - what if we already have a filter in the kernel?
875127664Sbms		 */
87675107Sfenner		if (install_bpf_program(p, fp) < 0)
87775107Sfenner			return (-1);
878127664Sbms		p->md.use_bpf = 0;	/* filtering in userland */
879127664Sbms		return (0);
880127664Sbms	}
881127664Sbms
882127664Sbms	/*
883127664Sbms	 * Free any user-mode filter we might happen to have installed.
884127664Sbms	 */
885127664Sbms	pcap_freecode(&p->fcode);
886127664Sbms
887127664Sbms	/*
888127664Sbms	 * Try to install the kernel filter.
889127664Sbms	 */
890127664Sbms	if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
89175107Sfenner		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
89275107Sfenner		    pcap_strerror(errno));
89317683Spst		return (-1);
89417683Spst	}
895127664Sbms	p->md.use_bpf = 1;	/* filtering in the kernel */
89617683Spst	return (0);
89717683Spst}
898109839Sfenner
899127664Sbmsstatic int
900127664Sbmspcap_set_datalink_bpf(pcap_t *p, int dlt)
901109839Sfenner{
902127664Sbms#ifdef BIOCSDLT
903109839Sfenner	if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) {
904109839Sfenner		(void) snprintf(p->errbuf, sizeof(p->errbuf),
905109839Sfenner		    "Cannot set DLT %d: %s", dlt, strerror(errno));
906127664Sbms		return (-1);
907109839Sfenner	}
908127664Sbms#endif
909127664Sbms	return (0);
910109839Sfenner}
911