]> The Tcpdump Group git mirrors - libpcap/blob - pcap-bpf.c
From Shaun <[email protected]>: on AIX, load the BPF driver and
[libpcap] / pcap-bpf.c
1 /*
2 * Copyright (c) 1993, 1994, 1995, 1996, 1998
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 */
21 #ifndef lint
22 static const char rcsid[] =
23 "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.56 2003-02-11 01:46:05 guy Exp $ (LBL)";
24 #endif
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include <sys/param.h> /* optionally get BSD define */
31 #include <sys/time.h>
32 #include <sys/timeb.h>
33 #include <sys/socket.h>
34 #include <sys/file.h>
35 #include <sys/ioctl.h>
36
37 #include <net/if.h>
38
39 #ifdef _AIX
40
41 /*
42 * Make "pcap.h" not include "pcap-bpf.h"; we are going to include the
43 * native OS version, as we need "struct bpf_config" from it.
44 */
45 #define PCAP_DONT_INCLUDE_PCAP_BPF_H
46
47 #include <sys/types.h>
48
49 /*
50 * Prevent bpf.h from redefining the DLT_ values to their
51 * IFT_ values, as we're going to return the standard libpcap
52 * values, not IBM's non-standard IFT_ values.
53 */
54 #undef _AIX
55 #include <net/bpf.h>
56 #define _AIX
57
58 #include <net/if_types.h> /* for IFT_ values */
59 #include <sys/sysconfig.h>
60 #include <sys/device.h>
61 #include <odmi.h>
62 #include <cf.h>
63
64 #ifdef __64BIT__
65 #define domakedev makedev64
66 #define getmajor major64
67 #define bpf_hdr bpf_hdr32
68 #else /* __64BIT__ */
69 #define domakedev makedev
70 #define getmajor major
71 #endif /* __64BIT__ */
72
73 #define BPF_NAME "bpf"
74 #define BPF_MINORS 4
75 #define DRIVER_PATH "/usr/lib/drivers"
76 #define BPF_NODE "/dev/bpf"
77 static int bpfloadedflag = 0;
78 static int odmlockid = 0;
79
80 #else /* _AIX */
81
82 #include <net/bpf.h>
83
84 #endif /* _AIX */
85
86 #include <ctype.h>
87 #include <errno.h>
88 #include <netdb.h>
89 #include <stdio.h>
90 #include <stdlib.h>
91 #include <string.h>
92 #include <unistd.h>
93
94 #include "pcap-int.h"
95
96 #ifdef HAVE_OS_PROTO_H
97 #include "os-proto.h"
98 #endif
99
100 #include "gencode.h"
101
102 int
103 pcap_stats(pcap_t *p, struct pcap_stat *ps)
104 {
105 struct bpf_stat s;
106
107 /*
108 * "ps_recv" counts packets handed to the filter, not packets
109 * that passed the filter. This includes packets later dropped
110 * because we ran out of buffer space.
111 *
112 * "ps_drop" counts packets dropped inside the BPF device
113 * because we ran out of buffer space. It doesn't count
114 * packets dropped by the interface driver. It counts
115 * only packets that passed the filter.
116 *
117 * Both statistics include packets not yet read from the kernel
118 * by libpcap, and thus not yet seen by the application.
119 */
120 if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) {
121 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGSTATS: %s",
122 pcap_strerror(errno));
123 return (-1);
124 }
125
126 ps->ps_recv = s.bs_recv;
127 ps->ps_drop = s.bs_drop;
128 return (0);
129 }
130
131 int
132 pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
133 {
134 int cc;
135 int n = 0;
136 register u_char *bp, *ep;
137
138 again:
139 cc = p->cc;
140 if (p->cc == 0) {
141 cc = read(p->fd, (char *)p->buffer, p->bufsize);
142 if (cc < 0) {
143 /* Don't choke when we get ptraced */
144 switch (errno) {
145
146 case EINTR:
147 goto again;
148
149 #ifdef _AIX
150 case EFAULT:
151 /*
152 * Sigh. More AIX wonderfulness.
153 *
154 * It appears, according to Don
155 * Ebright, that a read from a BPF
156 * device returns -1 with "errno"
157 * set to EFAULT as an indication
158 * that packets have been dropped
159 * since the last successful read.
160 *
161 * This means that we shouldn't treat
162 * EFAULT as a fatal error; as we
163 * don't have an API for returning
164 * a "some packets were dropped since
165 * the last packet you saw" indication,
166 * we just ignore EFAULT and keep reading.
167 */
168 goto again;
169 #endif
170
171 case EWOULDBLOCK:
172 return (0);
173 #if defined(sun) && !defined(BSD)
174 /*
175 * Due to a SunOS bug, after 2^31 bytes, the kernel
176 * file offset overflows and read fails with EINVAL.
177 * The lseek() to 0 will fix things.
178 */
179 case EINVAL:
180 if (lseek(p->fd, 0L, SEEK_CUR) +
181 p->bufsize < 0) {
182 (void)lseek(p->fd, 0L, SEEK_SET);
183 goto again;
184 }
185 /* fall through */
186 #endif
187 }
188 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read: %s",
189 pcap_strerror(errno));
190 return (-1);
191 }
192 bp = p->buffer;
193 } else
194 bp = p->bp;
195
196 /*
197 * Loop through each packet.
198 */
199 #define bhp ((struct bpf_hdr *)bp)
200 ep = bp + cc;
201 while (bp < ep) {
202 register int caplen, hdrlen;
203 caplen = bhp->bh_caplen;
204 hdrlen = bhp->bh_hdrlen;
205 /*
206 * XXX A bpf_hdr matches a pcap_pkthdr.
207 */
208 #ifdef _AIX
209 /*
210 * AIX's BPF returns seconds/nanoseconds time stamps, not
211 * seconds/microseconds time stamps.
212 *
213 * XXX - I'm guessing here that it's a "struct timestamp";
214 * if not, this code won't compile, but, if not, you
215 * want to send us a bug report and fall back on using
216 * DLPI. It's not as if BPF used to work right on
217 * AIX before this change; this change attempts to fix
218 * the fact that it didn't....
219 */
220 bhp->bh_tstamp.tv_usec = bhp->bh_tstamp.tv_usec/1000;
221 #endif
222 (*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
223 bp += BPF_WORDALIGN(caplen + hdrlen);
224 if (++n >= cnt && cnt > 0) {
225 p->bp = bp;
226 p->cc = ep - bp;
227 return (n);
228 }
229 }
230 #undef bhp
231 p->cc = 0;
232 return (n);
233 }
234
235 #ifdef _AIX
236 static int
237 bpf_odminit(char *errbuf)
238 {
239 if (odm_initialize() == -1) {
240 snprintf(errbuf, PCAP_ERRBUF_SIZE,
241 "bpf_load: odm_initialize failed: %s",
242 pcap_strerror(errno));
243 return (-1);
244 }
245
246 if ((odmlockid = odm_lock("/etc/objrepos/config_lock", ODM_WAIT)) == -1) {
247 snprintf(errbuf, PCAP_ERRBUF_SIZE,
248 "bpf_load: odm_lock of /etc/objrepos/config_lock failed: %s",
249 pcap_strerror(errno));
250 return (-1);
251 }
252
253 return (0);
254 }
255
256 static int
257 bpf_odmcleanup(char *errbuf)
258 {
259 if (odm_unlock(odmlockid) == -1) {
260 snprintf(errbuf, PCAP_ERRBUF_SIZE,
261 "bpf_load: odm_unlock failed: %s",
262 pcap_strerror(errno));
263 return (-1);
264 }
265
266 odm_terminate();
267
268 return (0);
269 }
270
271 static int
272 bpf_load(char *errbuf)
273 {
274 long major;
275 int *minors;
276 int numminors, i, rc;
277 char buf[1024];
278 struct stat sbuf;
279 struct bpf_config cfg_bpf;
280 struct cfg_load cfg_ld;
281 struct cfg_kmod cfg_km;
282
283 /*
284 * This is very very close to what happens in the real implementation
285 * but I've fixed some (unlikely) bug situations.
286 */
287 if (bpfloadedflag)
288 return (0);
289
290 if (bpf_odminit(errbuf) != 0)
291 return (-1);
292
293 major = genmajor(BPF_NAME);
294 if (major == -1) {
295 snprintf(errbuf, PCAP_ERRBUF_SIZE,
296 "bpf_load: genmajor failed: %s", pcap_strerror(errno));
297 return (-1);
298 }
299
300 minors = getminor(major, &numminors, BPF_NAME);
301 if (!minors) {
302 minors = genminor("bpf", major, 0, BPF_MINORS, 1, 1);
303 if (!minors) {
304 snprintf(errbuf, PCAP_ERRBUF_SIZE,
305 "bpf_load: genminor failed: %s",
306 pcap_strerror(errno));
307 return (-1);
308 }
309
310 }
311
312 if (bpf_odmcleanup(errbuf))
313 return (-1);
314
315 rc = stat(BPF_NODE "0", &sbuf);
316 if (rc == -1 && errno != ENOENT) {
317 snprintf(errbuf, PCAP_ERRBUF_SIZE,
318 "bpf_load: can't stat %s: %s",
319 BPF_NODE "0", pcap_strerror(errno));
320 return (-1);
321 }
322
323 if (rc == -1 || getmajor(sbuf.st_rdev) != major) {
324 for (i = 0; i < BPF_MINORS; i++) {
325 sprintf(buf, "%s%d", BPF_NODE, i);
326 unlink(buf);
327 if (mknod(buf, S_IRUSR | S_IFCHR, domakedev(major, i)) == -1) {
328 snprintf(errbuf, PCAP_ERRBUF_SIZE,
329 "bpf_load: can't mknod %s: %s",
330 buf pcap_strerror(errno));
331 return (-1);
332 }
333 }
334 }
335
336 /* Check if the driver is loaded */
337 memset(&cfg_ld, 0x0, sizeof(cfg_ld));
338 cfg_ld.path = buf;
339 sprintf(cfg_ld.path, "%s/%s", DRIVER_PATH, BPF_NAME);
340 if (sysconfig(SYS_QUERYLOAD, (void *) &cfg_ld, sizeof(cfg_ld) == -1) ||
341 (cfg_ld.kmid == 0)) {
342 /* Driver isn't loaded, load it now */
343 if (sysconfig(SYS_SINGLELOAD, (void *) &cfg_ld, sizeof(cfg_ld)) == -1) {
344 snprintf(errbuf, PCAP_ERRBUF_SIZE,
345 "bpf_load: could not load driver: %s",
346 strerror(errno));
347 return (-1);
348 }
349 }
350
351 /* Configure the driver */
352 cfg_km.cmd = CFG_INIT;
353 cfg_km.kmid = cfg_ld.kmid;
354 cfg_km.mdilen = sizeof(cfg_bpf);
355 cfg_km.mdiptr = (void *) &cfg_bpf;
356 for (i = 0; i < BPF_MINORS; i++) {
357 cfg_bpf.devno = domakedev(major, i);
358 if (sysconfig(SYS_CFGKMOD, (void *) &cfg_km, sizeof(cfg_km)) == -1) {
359 snprintf(errbuf, PCAP_ERRBUF_SIZE,
360 "bpf_load: could not configure driver: %s",
361 strerror(errno));
362 return (-1);
363 }
364 }
365
366 bpfloadedflag = 1;
367
368 return (0);
369 }
370 #endif
371
372 static inline int
373 bpf_open(pcap_t *p, char *errbuf)
374 {
375 int fd;
376 int n = 0;
377 char device[sizeof "/dev/bpf0000000000"];
378
379 #ifdef _AIX
380 /*
381 * Load the bpf driver, if it isn't already loaded,
382 * and create the BPF device entries, if they don't
383 * already exist.
384 */
385 if (bpf_load(errbuf) == -1)
386 return (-1);
387 #endif
388
389 /*
390 * Go through all the minors and find one that isn't in use.
391 */
392 do {
393 (void)snprintf(device, sizeof(device), "/dev/bpf%d", n++);
394 fd = open(device, O_RDONLY);
395 } while (fd < 0 && errno == EBUSY);
396
397 /*
398 * XXX better message for all minors used
399 */
400 if (fd < 0)
401 snprintf(errbuf, PCAP_ERRBUF_SIZE, "(no devices found) %s: %s",
402 device, pcap_strerror(errno));
403
404 return (fd);
405 }
406
407 /*
408 * XXX - on AIX, IBM's tcpdump (and perhaps the incompatible-with-everybody-
409 * else's libpcap in AIX 5.1) appears to forcibly load the BPF driver
410 * if it's not already loaded, and to create the BPF devices if they
411 * don't exist.
412 *
413 * It'd be nice if we could do the same, although the code to do so
414 * might be version-dependent, alas (the way to do it isn't necessarily
415 * documented).
416 */
417 pcap_t *
418 pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
419 char *ebuf)
420 {
421 int fd;
422 struct ifreq ifr;
423 struct bpf_version bv;
424 #ifdef BIOCGDLTLIST
425 struct bpf_dltlist bdl;
426 #endif
427 u_int v;
428 pcap_t *p;
429
430 #ifdef BIOCGDLTLIST
431 bzero(&bdl, sizeof(bdl));
432 #endif
433
434 p = (pcap_t *)malloc(sizeof(*p));
435 if (p == NULL) {
436 snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
437 pcap_strerror(errno));
438 return (NULL);
439 }
440 memset(p, 0, sizeof(*p));
441 fd = bpf_open(p, ebuf);
442 if (fd < 0)
443 goto bad;
444
445 p->fd = fd;
446 p->snapshot = snaplen;
447
448 if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) {
449 snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s",
450 pcap_strerror(errno));
451 goto bad;
452 }
453 if (bv.bv_major != BPF_MAJOR_VERSION ||
454 bv.bv_minor < BPF_MINOR_VERSION) {
455 snprintf(ebuf, PCAP_ERRBUF_SIZE,
456 "kernel bpf filter out of date");
457 goto bad;
458 }
459
460 /*
461 * Try finding a good size for the buffer; 32768 may be too
462 * big, so keep cutting it in half until we find a size
463 * that works, or run out of sizes to try.
464 *
465 * XXX - there should be a user-accessible hook to set the
466 * initial buffer size.
467 */
468 for (v = 32768; v != 0; v >>= 1) {
469 /* Ignore the return value - this is because the call fails
470 * on BPF systems that don't have kernel malloc. And if
471 * the call fails, it's no big deal, we just continue to
472 * use the standard buffer size.
473 */
474 (void) ioctl(fd, BIOCSBLEN, (caddr_t)&v);
475
476 (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
477 if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0)
478 break; /* that size worked; we're done */
479
480 if (errno != ENOBUFS) {
481 snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s",
482 device, pcap_strerror(errno));
483 goto bad;
484 }
485 }
486
487 if (v == 0) {
488 snprintf(ebuf, PCAP_ERRBUF_SIZE,
489 "BIOCSBLEN: %s: No buffer size worked", device);
490 goto bad;
491 }
492
493 /* Get the data link layer type. */
494 if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
495 snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s",
496 pcap_strerror(errno));
497 goto bad;
498 }
499 #ifdef _AIX
500 /*
501 * AIX's BPF returns IFF_ types, not DLT_ types, in BIOCGDLT.
502 */
503 switch (v) {
504
505 case IFT_ETHER:
506 case IFT_ISO88023:
507 v = DLT_EN10MB;
508 break;
509
510 case IFT_FDDI:
511 v = DLT_FDDI;
512 break;
513
514 case IFT_ISO88025:
515 v = DLT_IEEE802;
516 break;
517
518 default:
519 /*
520 * We don't know what to map this to yet.
521 */
522 snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown interface type %u",
523 v);
524 goto bad;
525 }
526 #endif
527 #if _BSDI_VERSION - 0 >= 199510
528 /* The SLIP and PPP link layer header changed in BSD/OS 2.1 */
529 switch (v) {
530
531 case DLT_SLIP:
532 v = DLT_SLIP_BSDOS;
533 break;
534
535 case DLT_PPP:
536 v = DLT_PPP_BSDOS;
537 break;
538
539 case 11: /*DLT_FR*/
540 v = DLT_FRELAY;
541 break;
542
543 case 12: /*DLT_C_HDLC*/
544 v = DLT_CHDLC;
545 break;
546 }
547 #endif
548 p->linktype = v;
549
550 #ifdef BIOCGDLTLIST
551 /*
552 * We know the default link type -- now determine all the DLTs
553 * this interface supports. If this fails with EINVAL, it's
554 * not fatal; we just don't get to use the feature later.
555 */
556 if (ioctl(fd, BIOCGDLTLIST, (caddr_t) &bdl) == 0) {
557 bdl.bfl_list = (u_int *) malloc(sizeof(u_int) * bdl.bfl_len);
558 if (bdl.bfl_list == NULL) {
559 (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
560 pcap_strerror(errno));
561 goto bad;
562 }
563
564 if (ioctl(fd, BIOCGDLTLIST, (caddr_t) &bdl) < 0) {
565 (void)snprintf(ebuf, PCAP_ERRBUF_SIZE,
566 "BIOCGDLTLIST: %s", pcap_strerror(errno));
567 goto bad;
568 }
569
570 p->dlt_count = bdl.bfl_len;
571 p->dlt_list = bdl.bfl_list;
572 } else {
573 if (errno != EINVAL) {
574 (void)snprintf(ebuf, PCAP_ERRBUF_SIZE,
575 "BIOCGDLTLIST: %s", pcap_strerror(errno));
576 goto bad;
577 }
578 }
579 #endif
580
581 /* set timeout */
582 if (to_ms != 0) {
583 /*
584 * XXX - is this seconds/nanoseconds in AIX?
585 * (Treating it as such doesn't fix the timeout
586 * problem described below.)
587 */
588 struct timeval to;
589 to.tv_sec = to_ms / 1000;
590 to.tv_usec = (to_ms * 1000) % 1000000;
591 if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) {
592 snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s",
593 pcap_strerror(errno));
594 goto bad;
595 }
596 }
597
598 #ifdef _AIX
599 #ifdef BIOCIMMEDIATE
600 /*
601 * Darren Reed notes that
602 *
603 * On AIX (4.2 at least), if BIOCIMMEDIATE is not set, the
604 * timeout appears to be ignored and it waits until the buffer
605 * is filled before returning. The result of not having it
606 * set is almost worse than useless if your BPF filter
607 * is reducing things to only a few packets (i.e. one every
608 * second or so).
609 *
610 * so we turn BIOCIMMEDIATE mode on if this is AIX.
611 *
612 * We don't turn it on for other platforms, as that means we
613 * get woken up for every packet, which may not be what we want;
614 * in the Winter 1993 USENIX paper on BPF, they say:
615 *
616 * Since a process might want to look at every packet on a
617 * network and the time between packets can be only a few
618 * microseconds, it is not possible to do a read system call
619 * per packet and BPF must collect the data from several
620 * packets and return it as a unit when the monitoring
621 * application does a read.
622 *
623 * which I infer is the reason for the timeout - it means we
624 * wait that amount of time, in the hopes that more packets
625 * will arrive and we'll get them all with one read.
626 *
627 * Setting BIOCIMMEDIATE mode on FreeBSD (and probably other
628 * BSDs) causes the timeout to be ignored.
629 *
630 * On the other hand, some platforms (e.g., Linux) don't support
631 * timeouts, they just hand stuff to you as soon as it arrives;
632 * if that doesn't cause a problem on those platforms, it may
633 * be OK to have BIOCIMMEDIATE mode on BSD as well.
634 *
635 * (Note, though, that applications may depend on the read
636 * completing, even if no packets have arrived, when the timeout
637 * expires, e.g. GUI applications that have to check for input
638 * while waiting for packets to arrive; a non-zero timeout
639 * prevents "select()" from working right on FreeBSD and
640 * possibly other BSDs, as the timer doesn't start until a
641 * "read()" is done, so the timer isn't in effect if the
642 * application is blocked on a "select()", and the "select()"
643 * doesn't get woken up for a BPF device until the buffer
644 * fills up.)
645 */
646 v = 1;
647 if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) {
648 snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s",
649 pcap_strerror(errno));
650 goto bad;
651 }
652 #endif /* BIOCIMMEDIATE */
653 #endif /* _AIX */
654
655 if (promisc) {
656 /* set promiscuous mode, okay if it fails */
657 if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) {
658 snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s",
659 pcap_strerror(errno));
660 }
661 }
662
663 if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
664 snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s",
665 pcap_strerror(errno));
666 goto bad;
667 }
668 p->bufsize = v;
669 p->buffer = (u_char *)malloc(p->bufsize);
670 if (p->buffer == NULL) {
671 snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
672 pcap_strerror(errno));
673 goto bad;
674 }
675
676 return (p);
677 bad:
678 (void)close(fd);
679 #ifdef BIOCGDLTLIST
680 if (bdl.bfl_list != NULL)
681 free(bdl.bfl_list);
682 #endif
683 free(p);
684 return (NULL);
685 }
686
687 int
688 pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
689 {
690 return (0);
691 }
692
693 int
694 pcap_setfilter(pcap_t *p, struct bpf_program *fp)
695 {
696 /*
697 * It looks that BPF code generated by gen_protochain() is not
698 * compatible with some of kernel BPF code (for example BSD/OS 3.1).
699 * Take a safer side for now.
700 */
701 if (no_optimize) {
702 if (install_bpf_program(p, fp) < 0)
703 return (-1);
704 } else if (p->sf.rfile != NULL) {
705 if (install_bpf_program(p, fp) < 0)
706 return (-1);
707 } else if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
708 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
709 pcap_strerror(errno));
710 return (-1);
711 }
712 return (0);
713 }
714
715 int
716 pcap_set_datalink_platform(pcap_t *p, int dlt)
717 {
718 #ifdef BIOCSDLT
719 if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) {
720 (void) snprintf(p->errbuf, sizeof(p->errbuf),
721 "Cannot set DLT %d: %s", dlt, strerror(errno));
722 return (-1);
723 }
724 #endif
725 return (0);
726 }