1335640Shselasky/* 2335640Shselasky * Copyright (c) 1993, 1994, 1995, 1996, 1998 3335640Shselasky * The Regents of the University of California. All rights reserved. 4335640Shselasky * 5335640Shselasky * Redistribution and use in source and binary forms, with or without 6335640Shselasky * modification, are permitted provided that: (1) source code distributions 7335640Shselasky * retain the above copyright notice and this paragraph in its entirety, (2) 8335640Shselasky * distributions including binary code include the above copyright notice and 9335640Shselasky * this paragraph in its entirety in the documentation or other materials 10335640Shselasky * provided with the distribution, and (3) all advertising materials mentioning 11335640Shselasky * features or use of this software display the following acknowledgement: 12335640Shselasky * ``This product includes software developed by the University of California, 13335640Shselasky * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14335640Shselasky * the University nor the names of its contributors may be used to endorse 15335640Shselasky * or promote products derived from this software without specific prior 16335640Shselasky * written permission. 17335640Shselasky * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18335640Shselasky * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19335640Shselasky * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20335640Shselasky */ 21335640Shselasky 22335640Shselasky#ifdef HAVE_CONFIG_H 23335640Shselasky#include <config.h> 24335640Shselasky#endif 25335640Shselasky 26335640Shselasky#include <sys/param.h> /* optionally get BSD define */ 27335640Shselasky#include <sys/socket.h> 28335640Shselasky#include <time.h> 29335640Shselasky/* 30335640Shselasky * <net/bpf.h> defines ioctls, but doesn't include <sys/ioccom.h>. 31335640Shselasky * 32335640Shselasky * We include <sys/ioctl.h> as it might be necessary to declare ioctl(); 33335640Shselasky * at least on *BSD and macOS, it also defines various SIOC ioctls - 34335640Shselasky * we could include <sys/sockio.h>, but if we're already including 35335640Shselasky * <sys/ioctl.h>, which includes <sys/sockio.h> on those platforms, 36335640Shselasky * there's not much point in doing so. 37335640Shselasky * 38335640Shselasky * If we have <sys/ioccom.h>, we include it as well, to handle systems 39335640Shselasky * such as Solaris which don't arrange to include <sys/ioccom.h> if you 40335640Shselasky * include <sys/ioctl.h> 41335640Shselasky */ 42335640Shselasky#include <sys/ioctl.h> 43335640Shselasky#ifdef HAVE_SYS_IOCCOM_H 44335640Shselasky#include <sys/ioccom.h> 45335640Shselasky#endif 46335640Shselasky#include <sys/utsname.h> 47335640Shselasky 48335640Shselasky#if defined(__FreeBSD__) && defined(SIOCIFCREATE2) 49335640Shselasky/* 50335640Shselasky * Add support for capturing on FreeBSD usbusN interfaces. 51335640Shselasky */ 52335640Shselaskystatic const char usbus_prefix[] = "usbus"; 53335640Shselasky#define USBUS_PREFIX_LEN (sizeof(usbus_prefix) - 1) 54335640Shselasky#include <dirent.h> 55335640Shselasky#endif 56335640Shselasky 57335640Shselasky#include <net/if.h> 58335640Shselasky 59335640Shselasky#ifdef _AIX 60335640Shselasky 61335640Shselasky/* 62335640Shselasky * Make "pcap.h" not include "pcap/bpf.h"; we are going to include the 63335640Shselasky * native OS version, as we need "struct bpf_config" from it. 64335640Shselasky */ 65335640Shselasky#define PCAP_DONT_INCLUDE_PCAP_BPF_H 66335640Shselasky 67335640Shselasky#include <sys/types.h> 68335640Shselasky 69335640Shselasky/* 70335640Shselasky * Prevent bpf.h from redefining the DLT_ values to their 71335640Shselasky * IFT_ values, as we're going to return the standard libpcap 72335640Shselasky * values, not IBM's non-standard IFT_ values. 73335640Shselasky */ 74335640Shselasky#undef _AIX 75335640Shselasky#include <net/bpf.h> 76335640Shselasky#define _AIX 77335640Shselasky 78335640Shselasky/* 79335640Shselasky * If both BIOCROTZBUF and BPF_BUFMODE_ZBUF are defined, we have 80335640Shselasky * zero-copy BPF. 81335640Shselasky */ 82335640Shselasky#if defined(BIOCROTZBUF) && defined(BPF_BUFMODE_ZBUF) 83335640Shselasky #define HAVE_ZEROCOPY_BPF 84335640Shselasky #include <sys/mman.h> 85335640Shselasky #include <machine/atomic.h> 86335640Shselasky#endif 87335640Shselasky 88335640Shselasky#include <net/if_types.h> /* for IFT_ values */ 89335640Shselasky#include <sys/sysconfig.h> 90335640Shselasky#include <sys/device.h> 91335640Shselasky#include <sys/cfgodm.h> 92335640Shselasky#include <cf.h> 93335640Shselasky 94335640Shselasky#ifdef __64BIT__ 95335640Shselasky#define domakedev makedev64 96335640Shselasky#define getmajor major64 97335640Shselasky#define bpf_hdr bpf_hdr32 98335640Shselasky#else /* __64BIT__ */ 99335640Shselasky#define domakedev makedev 100335640Shselasky#define getmajor major 101335640Shselasky#endif /* __64BIT__ */ 102335640Shselasky 103335640Shselasky#define BPF_NAME "bpf" 104335640Shselasky#define BPF_MINORS 4 105335640Shselasky#define DRIVER_PATH "/usr/lib/drivers" 106335640Shselasky#define BPF_NODE "/dev/bpf" 107335640Shselaskystatic int bpfloadedflag = 0; 108335640Shselaskystatic int odmlockid = 0; 109335640Shselasky 110335640Shselaskystatic int bpf_load(char *errbuf); 111335640Shselasky 112335640Shselasky#else /* _AIX */ 113335640Shselasky 114335640Shselasky#include <net/bpf.h> 115335640Shselasky 116335640Shselasky#endif /* _AIX */ 117335640Shselasky 118335640Shselasky#include <ctype.h> 119335640Shselasky#include <fcntl.h> 120335640Shselasky#include <errno.h> 121335640Shselasky#include <netdb.h> 122335640Shselasky#include <stdio.h> 123335640Shselasky#include <stdlib.h> 124335640Shselasky#include <string.h> 125335640Shselasky#include <unistd.h> 126335640Shselasky 127335640Shselasky#ifdef SIOCGIFMEDIA 128335640Shselasky# include <net/if_media.h> 129335640Shselasky#endif 130335640Shselasky 131335640Shselasky#include "pcap-int.h" 132335640Shselasky 133335640Shselasky#ifdef HAVE_OS_PROTO_H 134335640Shselasky#include "os-proto.h" 135335640Shselasky#endif 136335640Shselasky 137335640Shselasky/* 138335640Shselasky * Later versions of NetBSD stick padding in front of FDDI frames 139335640Shselasky * to align the IP header on a 4-byte boundary. 140335640Shselasky */ 141335640Shselasky#if defined(__NetBSD__) && __NetBSD_Version__ > 106000000 142335640Shselasky#define PCAP_FDDIPAD 3 143335640Shselasky#endif 144335640Shselasky 145335640Shselasky/* 146335640Shselasky * Private data for capturing on BPF devices. 147335640Shselasky */ 148335640Shselaskystruct pcap_bpf { 149335640Shselasky#ifdef HAVE_ZEROCOPY_BPF 150335640Shselasky /* 151335640Shselasky * Zero-copy read buffer -- for zero-copy BPF. 'buffer' above will 152335640Shselasky * alternative between these two actual mmap'd buffers as required. 153335640Shselasky * As there is a header on the front size of the mmap'd buffer, only 154335640Shselasky * some of the buffer is exposed to libpcap as a whole via bufsize; 155335640Shselasky * zbufsize is the true size. zbuffer tracks the current zbuf 156335640Shselasky * assocated with buffer so that it can be used to decide which the 157335640Shselasky * next buffer to read will be. 158335640Shselasky */ 159335640Shselasky u_char *zbuf1, *zbuf2, *zbuffer; 160335640Shselasky u_int zbufsize; 161335640Shselasky u_int zerocopy; 162335640Shselasky u_int interrupted; 163335640Shselasky struct timespec firstsel; 164335640Shselasky /* 165335640Shselasky * If there's currently a buffer being actively processed, then it is 166335640Shselasky * referenced here; 'buffer' is also pointed at it, but offset by the 167335640Shselasky * size of the header. 168335640Shselasky */ 169335640Shselasky struct bpf_zbuf_header *bzh; 170335640Shselasky int nonblock; /* true if in nonblocking mode */ 171335640Shselasky#endif /* HAVE_ZEROCOPY_BPF */ 172335640Shselasky 173335640Shselasky char *device; /* device name */ 174335640Shselasky int filtering_in_kernel; /* using kernel filter */ 175335640Shselasky int must_do_on_close; /* stuff we must do when we close */ 176335640Shselasky}; 177335640Shselasky 178335640Shselasky/* 179335640Shselasky * Stuff to do when we close. 180335640Shselasky */ 181335640Shselasky#define MUST_CLEAR_RFMON 0x00000001 /* clear rfmon (monitor) mode */ 182335640Shselasky#define MUST_DESTROY_USBUS 0x00000002 /* destroy usbusN interface */ 183335640Shselasky 184335640Shselasky#ifdef BIOCGDLTLIST 185335640Shselasky# if (defined(HAVE_NET_IF_MEDIA_H) && defined(IFM_IEEE80211)) && !defined(__APPLE__) 186335640Shselasky#define HAVE_BSD_IEEE80211 187335640Shselasky 188335640Shselasky/* 189335640Shselasky * The ifm_ulist member of a struct ifmediareq is an int * on most systems, 190335640Shselasky * but it's a uint64_t on newer versions of OpenBSD. 191335640Shselasky * 192335640Shselasky * We check this by checking whether IFM_GMASK is defined and > 2^32-1. 193335640Shselasky */ 194335640Shselasky# if defined(IFM_GMASK) && IFM_GMASK > 0xFFFFFFFF 195335640Shselasky# define IFM_ULIST_TYPE uint64_t 196335640Shselasky# else 197335640Shselasky# define IFM_ULIST_TYPE int 198335640Shselasky# endif 199335640Shselasky# endif 200335640Shselasky 201335640Shselasky# if defined(__APPLE__) || defined(HAVE_BSD_IEEE80211) 202335640Shselaskystatic int find_802_11(struct bpf_dltlist *); 203335640Shselasky 204335640Shselasky# ifdef HAVE_BSD_IEEE80211 205335640Shselaskystatic int monitor_mode(pcap_t *, int); 206335640Shselasky# endif 207335640Shselasky 208335640Shselasky# if defined(__APPLE__) 209356341Scystatic void remove_non_802_11(pcap_t *); 210335640Shselaskystatic void remove_802_11(pcap_t *); 211335640Shselasky# endif 212335640Shselasky 213335640Shselasky# endif /* defined(__APPLE__) || defined(HAVE_BSD_IEEE80211) */ 214335640Shselasky 215335640Shselasky#endif /* BIOCGDLTLIST */ 216335640Shselasky 217335640Shselasky#if defined(sun) && defined(LIFNAMSIZ) && defined(lifr_zoneid) 218335640Shselasky#include <zone.h> 219335640Shselasky#endif 220335640Shselasky 221335640Shselasky/* 222335640Shselasky * We include the OS's <net/bpf.h>, not our "pcap/bpf.h", so we probably 223335640Shselasky * don't get DLT_DOCSIS defined. 224335640Shselasky */ 225335640Shselasky#ifndef DLT_DOCSIS 226335640Shselasky#define DLT_DOCSIS 143 227335640Shselasky#endif 228335640Shselasky 229335640Shselasky/* 230335640Shselasky * In some versions of macOS, we might not even get any of the 231335640Shselasky * 802.11-plus-radio-header DLT_'s defined, even though some 232335640Shselasky * of them are used by various Airport drivers in those versions. 233335640Shselasky */ 234335640Shselasky#ifndef DLT_PRISM_HEADER 235335640Shselasky#define DLT_PRISM_HEADER 119 236335640Shselasky#endif 237335640Shselasky#ifndef DLT_AIRONET_HEADER 238335640Shselasky#define DLT_AIRONET_HEADER 120 239335640Shselasky#endif 240335640Shselasky#ifndef DLT_IEEE802_11_RADIO 241335640Shselasky#define DLT_IEEE802_11_RADIO 127 242335640Shselasky#endif 243335640Shselasky#ifndef DLT_IEEE802_11_RADIO_AVS 244335640Shselasky#define DLT_IEEE802_11_RADIO_AVS 163 245335640Shselasky#endif 246335640Shselasky 247335640Shselaskystatic int pcap_can_set_rfmon_bpf(pcap_t *p); 248335640Shselaskystatic int pcap_activate_bpf(pcap_t *p); 249335640Shselaskystatic int pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp); 250335640Shselaskystatic int pcap_setdirection_bpf(pcap_t *, pcap_direction_t); 251335640Shselaskystatic int pcap_set_datalink_bpf(pcap_t *p, int dlt); 252335640Shselasky 253335640Shselasky/* 254335640Shselasky * For zerocopy bpf, the setnonblock/getnonblock routines need to modify 255335640Shselasky * pb->nonblock so we don't call select(2) if the pcap handle is in non- 256335640Shselasky * blocking mode. 257335640Shselasky */ 258335640Shselaskystatic int 259335640Shselaskypcap_getnonblock_bpf(pcap_t *p) 260335640Shselasky{ 261335640Shselasky#ifdef HAVE_ZEROCOPY_BPF 262335640Shselasky struct pcap_bpf *pb = p->priv; 263335640Shselasky 264335640Shselasky if (pb->zerocopy) 265335640Shselasky return (pb->nonblock); 266335640Shselasky#endif 267335640Shselasky return (pcap_getnonblock_fd(p)); 268335640Shselasky} 269335640Shselasky 270335640Shselaskystatic int 271335640Shselaskypcap_setnonblock_bpf(pcap_t *p, int nonblock) 272335640Shselasky{ 273335640Shselasky#ifdef HAVE_ZEROCOPY_BPF 274335640Shselasky struct pcap_bpf *pb = p->priv; 275335640Shselasky 276335640Shselasky if (pb->zerocopy) { 277335640Shselasky pb->nonblock = nonblock; 278335640Shselasky return (0); 279335640Shselasky } 280335640Shselasky#endif 281335640Shselasky return (pcap_setnonblock_fd(p, nonblock)); 282335640Shselasky} 283335640Shselasky 284335640Shselasky#ifdef HAVE_ZEROCOPY_BPF 285335640Shselasky/* 286335640Shselasky * Zero-copy BPF buffer routines to check for and acknowledge BPF data in 287335640Shselasky * shared memory buffers. 288335640Shselasky * 289335640Shselasky * pcap_next_zbuf_shm(): Check for a newly available shared memory buffer, 290335640Shselasky * and set up p->buffer and cc to reflect one if available. Notice that if 291335640Shselasky * there was no prior buffer, we select zbuf1 as this will be the first 292335640Shselasky * buffer filled for a fresh BPF session. 293335640Shselasky */ 294335640Shselaskystatic int 295335640Shselaskypcap_next_zbuf_shm(pcap_t *p, int *cc) 296335640Shselasky{ 297335640Shselasky struct pcap_bpf *pb = p->priv; 298335640Shselasky struct bpf_zbuf_header *bzh; 299335640Shselasky 300335640Shselasky if (pb->zbuffer == pb->zbuf2 || pb->zbuffer == NULL) { 301335640Shselasky bzh = (struct bpf_zbuf_header *)pb->zbuf1; 302335640Shselasky if (bzh->bzh_user_gen != 303335640Shselasky atomic_load_acq_int(&bzh->bzh_kernel_gen)) { 304335640Shselasky pb->bzh = bzh; 305335640Shselasky pb->zbuffer = (u_char *)pb->zbuf1; 306335640Shselasky p->buffer = pb->zbuffer + sizeof(*bzh); 307335640Shselasky *cc = bzh->bzh_kernel_len; 308335640Shselasky return (1); 309335640Shselasky } 310335640Shselasky } else if (pb->zbuffer == pb->zbuf1) { 311335640Shselasky bzh = (struct bpf_zbuf_header *)pb->zbuf2; 312335640Shselasky if (bzh->bzh_user_gen != 313335640Shselasky atomic_load_acq_int(&bzh->bzh_kernel_gen)) { 314335640Shselasky pb->bzh = bzh; 315335640Shselasky pb->zbuffer = (u_char *)pb->zbuf2; 316335640Shselasky p->buffer = pb->zbuffer + sizeof(*bzh); 317335640Shselasky *cc = bzh->bzh_kernel_len; 318335640Shselasky return (1); 319335640Shselasky } 320335640Shselasky } 321335640Shselasky *cc = 0; 322335640Shselasky return (0); 323335640Shselasky} 324335640Shselasky 325335640Shselasky/* 326335640Shselasky * pcap_next_zbuf() -- Similar to pcap_next_zbuf_shm(), except wait using 327335640Shselasky * select() for data or a timeout, and possibly force rotation of the buffer 328335640Shselasky * in the event we time out or are in immediate mode. Invoke the shared 329335640Shselasky * memory check before doing system calls in order to avoid doing avoidable 330335640Shselasky * work. 331335640Shselasky */ 332335640Shselaskystatic int 333335640Shselaskypcap_next_zbuf(pcap_t *p, int *cc) 334335640Shselasky{ 335335640Shselasky struct pcap_bpf *pb = p->priv; 336335640Shselasky struct bpf_zbuf bz; 337335640Shselasky struct timeval tv; 338335640Shselasky struct timespec cur; 339335640Shselasky fd_set r_set; 340335640Shselasky int data, r; 341335640Shselasky int expire, tmout; 342335640Shselasky 343335640Shselasky#define TSTOMILLI(ts) (((ts)->tv_sec * 1000) + ((ts)->tv_nsec / 1000000)) 344335640Shselasky /* 345335640Shselasky * Start out by seeing whether anything is waiting by checking the 346335640Shselasky * next shared memory buffer for data. 347335640Shselasky */ 348335640Shselasky data = pcap_next_zbuf_shm(p, cc); 349335640Shselasky if (data) 350335640Shselasky return (data); 351335640Shselasky /* 352335640Shselasky * If a previous sleep was interrupted due to signal delivery, make 353335640Shselasky * sure that the timeout gets adjusted accordingly. This requires 354335640Shselasky * that we analyze when the timeout should be been expired, and 355335640Shselasky * subtract the current time from that. If after this operation, 356335640Shselasky * our timeout is less then or equal to zero, handle it like a 357335640Shselasky * regular timeout. 358335640Shselasky */ 359335640Shselasky tmout = p->opt.timeout; 360335640Shselasky if (tmout) 361335640Shselasky (void) clock_gettime(CLOCK_MONOTONIC, &cur); 362335640Shselasky if (pb->interrupted && p->opt.timeout) { 363335640Shselasky expire = TSTOMILLI(&pb->firstsel) + p->opt.timeout; 364335640Shselasky tmout = expire - TSTOMILLI(&cur); 365335640Shselasky#undef TSTOMILLI 366335640Shselasky if (tmout <= 0) { 367335640Shselasky pb->interrupted = 0; 368335640Shselasky data = pcap_next_zbuf_shm(p, cc); 369335640Shselasky if (data) 370335640Shselasky return (data); 371335640Shselasky if (ioctl(p->fd, BIOCROTZBUF, &bz) < 0) { 372335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, 373335640Shselasky PCAP_ERRBUF_SIZE, errno, "BIOCROTZBUF"); 374335640Shselasky return (PCAP_ERROR); 375335640Shselasky } 376335640Shselasky return (pcap_next_zbuf_shm(p, cc)); 377335640Shselasky } 378335640Shselasky } 379335640Shselasky /* 380335640Shselasky * No data in the buffer, so must use select() to wait for data or 381335640Shselasky * the next timeout. Note that we only call select if the handle 382335640Shselasky * is in blocking mode. 383335640Shselasky */ 384335640Shselasky if (!pb->nonblock) { 385335640Shselasky FD_ZERO(&r_set); 386335640Shselasky FD_SET(p->fd, &r_set); 387335640Shselasky if (tmout != 0) { 388335640Shselasky tv.tv_sec = tmout / 1000; 389335640Shselasky tv.tv_usec = (tmout * 1000) % 1000000; 390335640Shselasky } 391335640Shselasky r = select(p->fd + 1, &r_set, NULL, NULL, 392335640Shselasky p->opt.timeout != 0 ? &tv : NULL); 393335640Shselasky if (r < 0 && errno == EINTR) { 394335640Shselasky if (!pb->interrupted && p->opt.timeout) { 395335640Shselasky pb->interrupted = 1; 396335640Shselasky pb->firstsel = cur; 397335640Shselasky } 398335640Shselasky return (0); 399335640Shselasky } else if (r < 0) { 400335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 401335640Shselasky errno, "select"); 402335640Shselasky return (PCAP_ERROR); 403335640Shselasky } 404335640Shselasky } 405335640Shselasky pb->interrupted = 0; 406335640Shselasky /* 407335640Shselasky * Check again for data, which may exist now that we've either been 408335640Shselasky * woken up as a result of data or timed out. Try the "there's data" 409335640Shselasky * case first since it doesn't require a system call. 410335640Shselasky */ 411335640Shselasky data = pcap_next_zbuf_shm(p, cc); 412335640Shselasky if (data) 413335640Shselasky return (data); 414335640Shselasky /* 415335640Shselasky * Try forcing a buffer rotation to dislodge timed out or immediate 416335640Shselasky * data. 417335640Shselasky */ 418335640Shselasky if (ioctl(p->fd, BIOCROTZBUF, &bz) < 0) { 419335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 420335640Shselasky errno, "BIOCROTZBUF"); 421335640Shselasky return (PCAP_ERROR); 422335640Shselasky } 423335640Shselasky return (pcap_next_zbuf_shm(p, cc)); 424335640Shselasky} 425335640Shselasky 426335640Shselasky/* 427335640Shselasky * Notify kernel that we are done with the buffer. We don't reset zbuffer so 428335640Shselasky * that we know which buffer to use next time around. 429335640Shselasky */ 430335640Shselaskystatic int 431335640Shselaskypcap_ack_zbuf(pcap_t *p) 432335640Shselasky{ 433335640Shselasky struct pcap_bpf *pb = p->priv; 434335640Shselasky 435335640Shselasky atomic_store_rel_int(&pb->bzh->bzh_user_gen, 436335640Shselasky pb->bzh->bzh_kernel_gen); 437335640Shselasky pb->bzh = NULL; 438335640Shselasky p->buffer = NULL; 439335640Shselasky return (0); 440335640Shselasky} 441335640Shselasky#endif /* HAVE_ZEROCOPY_BPF */ 442335640Shselasky 443335640Shselaskypcap_t * 444335640Shselaskypcap_create_interface(const char *device _U_, char *ebuf) 445335640Shselasky{ 446335640Shselasky pcap_t *p; 447335640Shselasky 448335640Shselasky p = pcap_create_common(ebuf, sizeof (struct pcap_bpf)); 449335640Shselasky if (p == NULL) 450335640Shselasky return (NULL); 451335640Shselasky 452335640Shselasky p->activate_op = pcap_activate_bpf; 453335640Shselasky p->can_set_rfmon_op = pcap_can_set_rfmon_bpf; 454335640Shselasky#ifdef BIOCSTSTAMP 455335640Shselasky /* 456335640Shselasky * We claim that we support microsecond and nanosecond time 457335640Shselasky * stamps. 458335640Shselasky */ 459335640Shselasky p->tstamp_precision_count = 2; 460335640Shselasky p->tstamp_precision_list = malloc(2 * sizeof(u_int)); 461335640Shselasky if (p->tstamp_precision_list == NULL) { 462335640Shselasky pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, errno, 463335640Shselasky "malloc"); 464335640Shselasky free(p); 465335640Shselasky return (NULL); 466335640Shselasky } 467335640Shselasky p->tstamp_precision_list[0] = PCAP_TSTAMP_PRECISION_MICRO; 468335640Shselasky p->tstamp_precision_list[1] = PCAP_TSTAMP_PRECISION_NANO; 469335640Shselasky#endif /* BIOCSTSTAMP */ 470335640Shselasky return (p); 471335640Shselasky} 472335640Shselasky 473335640Shselasky/* 474335640Shselasky * On success, returns a file descriptor for a BPF device. 475335640Shselasky * On failure, returns a PCAP_ERROR_ value, and sets p->errbuf. 476335640Shselasky */ 477335640Shselaskystatic int 478335640Shselaskybpf_open(char *errbuf) 479335640Shselasky{ 480335640Shselasky int fd = -1; 481335640Shselasky static const char cloning_device[] = "/dev/bpf"; 482335640Shselasky int n = 0; 483335640Shselasky char device[sizeof "/dev/bpf0000000000"]; 484335640Shselasky static int no_cloning_bpf = 0; 485335640Shselasky 486335640Shselasky#ifdef _AIX 487335640Shselasky /* 488335640Shselasky * Load the bpf driver, if it isn't already loaded, 489335640Shselasky * and create the BPF device entries, if they don't 490335640Shselasky * already exist. 491335640Shselasky */ 492335640Shselasky if (bpf_load(errbuf) == PCAP_ERROR) 493335640Shselasky return (PCAP_ERROR); 494335640Shselasky#endif 495335640Shselasky 496335640Shselasky /* 497335640Shselasky * First, unless we've already tried opening /dev/bpf and 498335640Shselasky * gotten ENOENT, try opening /dev/bpf. 499335640Shselasky * If it fails with ENOENT, remember that, so we don't try 500335640Shselasky * again, and try /dev/bpfN. 501335640Shselasky */ 502335640Shselasky if (!no_cloning_bpf && 503335640Shselasky (fd = open(cloning_device, O_RDWR)) == -1 && 504335640Shselasky ((errno != EACCES && errno != ENOENT) || 505335640Shselasky (fd = open(cloning_device, O_RDONLY)) == -1)) { 506335640Shselasky if (errno != ENOENT) { 507335640Shselasky if (errno == EACCES) 508335640Shselasky fd = PCAP_ERROR_PERM_DENIED; 509335640Shselasky else 510335640Shselasky fd = PCAP_ERROR; 511335640Shselasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 512335640Shselasky errno, "(cannot open device) %s", cloning_device); 513335640Shselasky return (fd); 514335640Shselasky } 515335640Shselasky no_cloning_bpf = 1; 516335640Shselasky } 517335640Shselasky 518335640Shselasky if (no_cloning_bpf) { 519335640Shselasky /* 520335640Shselasky * We don't have /dev/bpf. 521335640Shselasky * Go through all the /dev/bpfN minors and find one 522335640Shselasky * that isn't in use. 523335640Shselasky */ 524335640Shselasky do { 525335640Shselasky (void)pcap_snprintf(device, sizeof(device), "/dev/bpf%d", n++); 526335640Shselasky /* 527335640Shselasky * Initially try a read/write open (to allow the inject 528335640Shselasky * method to work). If that fails due to permission 529335640Shselasky * issues, fall back to read-only. This allows a 530335640Shselasky * non-root user to be granted specific access to pcap 531335640Shselasky * capabilities via file permissions. 532335640Shselasky * 533335640Shselasky * XXX - we should have an API that has a flag that 534335640Shselasky * controls whether to open read-only or read-write, 535335640Shselasky * so that denial of permission to send (or inability 536335640Shselasky * to send, if sending packets isn't supported on 537335640Shselasky * the device in question) can be indicated at open 538335640Shselasky * time. 539335640Shselasky */ 540335640Shselasky fd = open(device, O_RDWR); 541335640Shselasky if (fd == -1 && errno == EACCES) 542335640Shselasky fd = open(device, O_RDONLY); 543335640Shselasky } while (fd < 0 && errno == EBUSY); 544335640Shselasky } 545335640Shselasky 546335640Shselasky /* 547335640Shselasky * XXX better message for all minors used 548335640Shselasky */ 549335640Shselasky if (fd < 0) { 550335640Shselasky switch (errno) { 551335640Shselasky 552335640Shselasky case ENOENT: 553335640Shselasky fd = PCAP_ERROR; 554335640Shselasky if (n == 1) { 555335640Shselasky /* 556335640Shselasky * /dev/bpf0 doesn't exist, which 557335640Shselasky * means we probably have no BPF 558335640Shselasky * devices. 559335640Shselasky */ 560335640Shselasky pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 561335640Shselasky "(there are no BPF devices)"); 562335640Shselasky } else { 563335640Shselasky /* 564335640Shselasky * We got EBUSY on at least one 565335640Shselasky * BPF device, so we have BPF 566335640Shselasky * devices, but all the ones 567335640Shselasky * that exist are busy. 568335640Shselasky */ 569335640Shselasky pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 570335640Shselasky "(all BPF devices are busy)"); 571335640Shselasky } 572335640Shselasky break; 573335640Shselasky 574335640Shselasky case EACCES: 575335640Shselasky /* 576335640Shselasky * Got EACCES on the last device we tried, 577335640Shselasky * and EBUSY on all devices before that, 578335640Shselasky * if any. 579335640Shselasky */ 580335640Shselasky fd = PCAP_ERROR_PERM_DENIED; 581335640Shselasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 582335640Shselasky errno, "(cannot open BPF device) %s", device); 583335640Shselasky break; 584335640Shselasky 585335640Shselasky default: 586335640Shselasky /* 587335640Shselasky * Some other problem. 588335640Shselasky */ 589335640Shselasky fd = PCAP_ERROR; 590335640Shselasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 591335640Shselasky errno, "(cannot open BPF device) %s", device); 592335640Shselasky break; 593335640Shselasky } 594335640Shselasky } 595335640Shselasky 596335640Shselasky return (fd); 597335640Shselasky} 598335640Shselasky 599335640Shselasky/* 600335640Shselasky * Open and bind to a device; used if we're not actually going to use 601335640Shselasky * the device, but are just testing whether it can be opened, or opening 602335640Shselasky * it to get information about it. 603335640Shselasky * 604335640Shselasky * Returns an error code on failure (always negative), and an FD for 605335640Shselasky * the now-bound BPF device on success (always non-negative). 606335640Shselasky */ 607335640Shselaskystatic int 608335640Shselaskybpf_open_and_bind(const char *name, char *errbuf) 609335640Shselasky{ 610335640Shselasky int fd; 611335640Shselasky struct ifreq ifr; 612335640Shselasky 613335640Shselasky /* 614335640Shselasky * First, open a BPF device. 615335640Shselasky */ 616335640Shselasky fd = bpf_open(errbuf); 617335640Shselasky if (fd < 0) 618335640Shselasky return (fd); /* fd is the appropriate error code */ 619335640Shselasky 620335640Shselasky /* 621335640Shselasky * Now bind to the device. 622335640Shselasky */ 623335640Shselasky (void)strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 624335640Shselasky if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) { 625335640Shselasky switch (errno) { 626335640Shselasky 627335640Shselasky case ENXIO: 628335640Shselasky /* 629335640Shselasky * There's no such device. 630335640Shselasky */ 631335640Shselasky close(fd); 632335640Shselasky return (PCAP_ERROR_NO_SUCH_DEVICE); 633335640Shselasky 634335640Shselasky case ENETDOWN: 635335640Shselasky /* 636335640Shselasky * Return a "network down" indication, so that 637335640Shselasky * the application can report that rather than 638335640Shselasky * saying we had a mysterious failure and 639335640Shselasky * suggest that they report a problem to the 640335640Shselasky * libpcap developers. 641335640Shselasky */ 642335640Shselasky close(fd); 643335640Shselasky return (PCAP_ERROR_IFACE_NOT_UP); 644335640Shselasky 645335640Shselasky default: 646335640Shselasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 647335640Shselasky errno, "BIOCSETIF: %s", name); 648335640Shselasky close(fd); 649335640Shselasky return (PCAP_ERROR); 650335640Shselasky } 651335640Shselasky } 652335640Shselasky 653335640Shselasky /* 654335640Shselasky * Success. 655335640Shselasky */ 656335640Shselasky return (fd); 657335640Shselasky} 658335640Shselasky 659335640Shselasky#ifdef BIOCGDLTLIST 660335640Shselaskystatic int 661335640Shselaskyget_dlt_list(int fd, int v, struct bpf_dltlist *bdlp, char *ebuf) 662335640Shselasky{ 663335640Shselasky memset(bdlp, 0, sizeof(*bdlp)); 664335640Shselasky if (ioctl(fd, BIOCGDLTLIST, (caddr_t)bdlp) == 0) { 665335640Shselasky u_int i; 666335640Shselasky int is_ethernet; 667335640Shselasky 668335640Shselasky bdlp->bfl_list = (u_int *) malloc(sizeof(u_int) * (bdlp->bfl_len + 1)); 669335640Shselasky if (bdlp->bfl_list == NULL) { 670335640Shselasky pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 671335640Shselasky errno, "malloc"); 672335640Shselasky return (PCAP_ERROR); 673335640Shselasky } 674335640Shselasky 675335640Shselasky if (ioctl(fd, BIOCGDLTLIST, (caddr_t)bdlp) < 0) { 676335640Shselasky pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 677335640Shselasky errno, "BIOCGDLTLIST"); 678335640Shselasky free(bdlp->bfl_list); 679335640Shselasky return (PCAP_ERROR); 680335640Shselasky } 681335640Shselasky 682335640Shselasky /* 683335640Shselasky * OK, for real Ethernet devices, add DLT_DOCSIS to the 684335640Shselasky * list, so that an application can let you choose it, 685335640Shselasky * in case you're capturing DOCSIS traffic that a Cisco 686335640Shselasky * Cable Modem Termination System is putting out onto 687335640Shselasky * an Ethernet (it doesn't put an Ethernet header onto 688335640Shselasky * the wire, it puts raw DOCSIS frames out on the wire 689335640Shselasky * inside the low-level Ethernet framing). 690335640Shselasky * 691335640Shselasky * A "real Ethernet device" is defined here as a device 692335640Shselasky * that has a link-layer type of DLT_EN10MB and that has 693335640Shselasky * no alternate link-layer types; that's done to exclude 694335640Shselasky * 802.11 interfaces (which might or might not be the 695335640Shselasky * right thing to do, but I suspect it is - Ethernet <-> 696335640Shselasky * 802.11 bridges would probably badly mishandle frames 697335640Shselasky * that don't have Ethernet headers). 698335640Shselasky * 699335640Shselasky * On Solaris with BPF, Ethernet devices also offer 700335640Shselasky * DLT_IPNET, so we, if DLT_IPNET is defined, we don't 701335640Shselasky * treat it as an indication that the device isn't an 702335640Shselasky * Ethernet. 703335640Shselasky */ 704335640Shselasky if (v == DLT_EN10MB) { 705335640Shselasky is_ethernet = 1; 706335640Shselasky for (i = 0; i < bdlp->bfl_len; i++) { 707335640Shselasky if (bdlp->bfl_list[i] != DLT_EN10MB 708335640Shselasky#ifdef DLT_IPNET 709335640Shselasky && bdlp->bfl_list[i] != DLT_IPNET 710335640Shselasky#endif 711335640Shselasky ) { 712335640Shselasky is_ethernet = 0; 713335640Shselasky break; 714335640Shselasky } 715335640Shselasky } 716335640Shselasky if (is_ethernet) { 717335640Shselasky /* 718335640Shselasky * We reserved one more slot at the end of 719335640Shselasky * the list. 720335640Shselasky */ 721335640Shselasky bdlp->bfl_list[bdlp->bfl_len] = DLT_DOCSIS; 722335640Shselasky bdlp->bfl_len++; 723335640Shselasky } 724335640Shselasky } 725335640Shselasky } else { 726335640Shselasky /* 727335640Shselasky * EINVAL just means "we don't support this ioctl on 728335640Shselasky * this device"; don't treat it as an error. 729335640Shselasky */ 730335640Shselasky if (errno != EINVAL) { 731335640Shselasky pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 732335640Shselasky errno, "BIOCGDLTLIST"); 733335640Shselasky return (PCAP_ERROR); 734335640Shselasky } 735335640Shselasky } 736335640Shselasky return (0); 737335640Shselasky} 738335640Shselasky#endif 739335640Shselasky 740356341Scy#if defined(__APPLE__) 741335640Shselaskystatic int 742335640Shselaskypcap_can_set_rfmon_bpf(pcap_t *p) 743335640Shselasky{ 744335640Shselasky struct utsname osinfo; 745335640Shselasky struct ifreq ifr; 746335640Shselasky int fd; 747335640Shselasky#ifdef BIOCGDLTLIST 748335640Shselasky struct bpf_dltlist bdl; 749335640Shselasky#endif 750335640Shselasky 751335640Shselasky /* 752335640Shselasky * The joys of monitor mode on Mac OS X/OS X/macOS. 753335640Shselasky * 754335640Shselasky * Prior to 10.4, it's not supported at all. 755335640Shselasky * 756335640Shselasky * In 10.4, if adapter enN supports monitor mode, there's a 757335640Shselasky * wltN adapter corresponding to it; you open it, instead of 758335640Shselasky * enN, to get monitor mode. You get whatever link-layer 759335640Shselasky * headers it supplies. 760335640Shselasky * 761335640Shselasky * In 10.5, and, we assume, later releases, if adapter enN 762335640Shselasky * supports monitor mode, it offers, among its selectable 763335640Shselasky * DLT_ values, values that let you get the 802.11 header; 764335640Shselasky * selecting one of those values puts the adapter into monitor 765335640Shselasky * mode (i.e., you can't get 802.11 headers except in monitor 766335640Shselasky * mode, and you can't get Ethernet headers in monitor mode). 767335640Shselasky */ 768335640Shselasky if (uname(&osinfo) == -1) { 769335640Shselasky /* 770335640Shselasky * Can't get the OS version; just say "no". 771335640Shselasky */ 772335640Shselasky return (0); 773335640Shselasky } 774335640Shselasky /* 775335640Shselasky * We assume osinfo.sysname is "Darwin", because 776335640Shselasky * __APPLE__ is defined. We just check the version. 777335640Shselasky */ 778335640Shselasky if (osinfo.release[0] < '8' && osinfo.release[1] == '.') { 779335640Shselasky /* 780335640Shselasky * 10.3 (Darwin 7.x) or earlier. 781335640Shselasky * Monitor mode not supported. 782335640Shselasky */ 783335640Shselasky return (0); 784335640Shselasky } 785335640Shselasky if (osinfo.release[0] == '8' && osinfo.release[1] == '.') { 786335640Shselasky /* 787335640Shselasky * 10.4 (Darwin 8.x). s/en/wlt/, and check 788335640Shselasky * whether the device exists. 789335640Shselasky */ 790335640Shselasky if (strncmp(p->opt.device, "en", 2) != 0) { 791335640Shselasky /* 792335640Shselasky * Not an enN device; no monitor mode. 793335640Shselasky */ 794335640Shselasky return (0); 795335640Shselasky } 796335640Shselasky fd = socket(AF_INET, SOCK_DGRAM, 0); 797335640Shselasky if (fd == -1) { 798335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 799335640Shselasky errno, "socket"); 800335640Shselasky return (PCAP_ERROR); 801335640Shselasky } 802356341Scy pcap_strlcpy(ifr.ifr_name, "wlt", sizeof(ifr.ifr_name)); 803356341Scy pcap_strlcat(ifr.ifr_name, p->opt.device + 2, sizeof(ifr.ifr_name)); 804335640Shselasky if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) { 805335640Shselasky /* 806335640Shselasky * No such device? 807335640Shselasky */ 808335640Shselasky close(fd); 809335640Shselasky return (0); 810335640Shselasky } 811335640Shselasky close(fd); 812335640Shselasky return (1); 813335640Shselasky } 814335640Shselasky 815335640Shselasky#ifdef BIOCGDLTLIST 816335640Shselasky /* 817335640Shselasky * Everything else is 10.5 or later; for those, 818335640Shselasky * we just open the enN device, and check whether 819335640Shselasky * we have any 802.11 devices. 820335640Shselasky * 821335640Shselasky * First, open a BPF device. 822335640Shselasky */ 823335640Shselasky fd = bpf_open(p->errbuf); 824335640Shselasky if (fd < 0) 825335640Shselasky return (fd); /* fd is the appropriate error code */ 826335640Shselasky 827335640Shselasky /* 828335640Shselasky * Now bind to the device. 829335640Shselasky */ 830335640Shselasky (void)strncpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name)); 831335640Shselasky if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) { 832335640Shselasky switch (errno) { 833335640Shselasky 834335640Shselasky case ENXIO: 835335640Shselasky /* 836335640Shselasky * There's no such device. 837335640Shselasky */ 838335640Shselasky close(fd); 839335640Shselasky return (PCAP_ERROR_NO_SUCH_DEVICE); 840335640Shselasky 841335640Shselasky case ENETDOWN: 842335640Shselasky /* 843335640Shselasky * Return a "network down" indication, so that 844335640Shselasky * the application can report that rather than 845335640Shselasky * saying we had a mysterious failure and 846335640Shselasky * suggest that they report a problem to the 847335640Shselasky * libpcap developers. 848335640Shselasky */ 849335640Shselasky close(fd); 850335640Shselasky return (PCAP_ERROR_IFACE_NOT_UP); 851335640Shselasky 852335640Shselasky default: 853335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 854335640Shselasky errno, "BIOCSETIF: %s", p->opt.device); 855335640Shselasky close(fd); 856335640Shselasky return (PCAP_ERROR); 857335640Shselasky } 858335640Shselasky } 859335640Shselasky 860335640Shselasky /* 861335640Shselasky * We know the default link type -- now determine all the DLTs 862335640Shselasky * this interface supports. If this fails with EINVAL, it's 863335640Shselasky * not fatal; we just don't get to use the feature later. 864335640Shselasky * (We don't care about DLT_DOCSIS, so we pass DLT_NULL 865335640Shselasky * as the default DLT for this adapter.) 866335640Shselasky */ 867335640Shselasky if (get_dlt_list(fd, DLT_NULL, &bdl, p->errbuf) == PCAP_ERROR) { 868335640Shselasky close(fd); 869335640Shselasky return (PCAP_ERROR); 870335640Shselasky } 871335640Shselasky if (find_802_11(&bdl) != -1) { 872335640Shselasky /* 873335640Shselasky * We have an 802.11 DLT, so we can set monitor mode. 874335640Shselasky */ 875335640Shselasky free(bdl.bfl_list); 876335640Shselasky close(fd); 877335640Shselasky return (1); 878335640Shselasky } 879335640Shselasky free(bdl.bfl_list); 880335640Shselasky close(fd); 881335640Shselasky#endif /* BIOCGDLTLIST */ 882335640Shselasky return (0); 883356341Scy} 884335640Shselasky#elif defined(HAVE_BSD_IEEE80211) 885356341Scystatic int 886356341Scypcap_can_set_rfmon_bpf(pcap_t *p) 887356341Scy{ 888335640Shselasky int ret; 889335640Shselasky 890335640Shselasky ret = monitor_mode(p, 0); 891335640Shselasky if (ret == PCAP_ERROR_RFMON_NOTSUP) 892335640Shselasky return (0); /* not an error, just a "can't do" */ 893335640Shselasky if (ret == 0) 894335640Shselasky return (1); /* success */ 895335640Shselasky return (ret); 896356341Scy} 897335640Shselasky#else 898356341Scystatic int 899356341Scypcap_can_set_rfmon_bpf(pcap_t *p _U_) 900356341Scy{ 901335640Shselasky return (0); 902356341Scy} 903335640Shselasky#endif 904335640Shselasky 905335640Shselaskystatic int 906335640Shselaskypcap_stats_bpf(pcap_t *p, struct pcap_stat *ps) 907335640Shselasky{ 908335640Shselasky struct bpf_stat s; 909335640Shselasky 910335640Shselasky /* 911335640Shselasky * "ps_recv" counts packets handed to the filter, not packets 912335640Shselasky * that passed the filter. This includes packets later dropped 913335640Shselasky * because we ran out of buffer space. 914335640Shselasky * 915335640Shselasky * "ps_drop" counts packets dropped inside the BPF device 916335640Shselasky * because we ran out of buffer space. It doesn't count 917335640Shselasky * packets dropped by the interface driver. It counts 918335640Shselasky * only packets that passed the filter. 919335640Shselasky * 920335640Shselasky * Both statistics include packets not yet read from the kernel 921335640Shselasky * by libpcap, and thus not yet seen by the application. 922335640Shselasky */ 923335640Shselasky if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) { 924335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 925335640Shselasky errno, "BIOCGSTATS"); 926335640Shselasky return (PCAP_ERROR); 927335640Shselasky } 928335640Shselasky 929335640Shselasky ps->ps_recv = s.bs_recv; 930335640Shselasky ps->ps_drop = s.bs_drop; 931335640Shselasky ps->ps_ifdrop = 0; 932335640Shselasky return (0); 933335640Shselasky} 934335640Shselasky 935335640Shselaskystatic int 936335640Shselaskypcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 937335640Shselasky{ 938335640Shselasky struct pcap_bpf *pb = p->priv; 939335640Shselasky int cc; 940335640Shselasky int n = 0; 941335640Shselasky register u_char *bp, *ep; 942335640Shselasky u_char *datap; 943335640Shselasky#ifdef PCAP_FDDIPAD 944335640Shselasky register u_int pad; 945335640Shselasky#endif 946335640Shselasky#ifdef HAVE_ZEROCOPY_BPF 947335640Shselasky int i; 948335640Shselasky#endif 949335640Shselasky 950335640Shselasky again: 951335640Shselasky /* 952335640Shselasky * Has "pcap_breakloop()" been called? 953335640Shselasky */ 954335640Shselasky if (p->break_loop) { 955335640Shselasky /* 956335640Shselasky * Yes - clear the flag that indicates that it 957335640Shselasky * has, and return PCAP_ERROR_BREAK to indicate 958335640Shselasky * that we were told to break out of the loop. 959335640Shselasky */ 960335640Shselasky p->break_loop = 0; 961335640Shselasky return (PCAP_ERROR_BREAK); 962335640Shselasky } 963335640Shselasky cc = p->cc; 964335640Shselasky if (p->cc == 0) { 965335640Shselasky /* 966335640Shselasky * When reading without zero-copy from a file descriptor, we 967335640Shselasky * use a single buffer and return a length of data in the 968335640Shselasky * buffer. With zero-copy, we update the p->buffer pointer 969335640Shselasky * to point at whatever underlying buffer contains the next 970335640Shselasky * data and update cc to reflect the data found in the 971335640Shselasky * buffer. 972335640Shselasky */ 973335640Shselasky#ifdef HAVE_ZEROCOPY_BPF 974335640Shselasky if (pb->zerocopy) { 975335640Shselasky if (p->buffer != NULL) 976335640Shselasky pcap_ack_zbuf(p); 977335640Shselasky i = pcap_next_zbuf(p, &cc); 978335640Shselasky if (i == 0) 979335640Shselasky goto again; 980335640Shselasky if (i < 0) 981335640Shselasky return (PCAP_ERROR); 982335640Shselasky } else 983335640Shselasky#endif 984335640Shselasky { 985335640Shselasky cc = read(p->fd, p->buffer, p->bufsize); 986335640Shselasky } 987335640Shselasky if (cc < 0) { 988335640Shselasky /* Don't choke when we get ptraced */ 989335640Shselasky switch (errno) { 990335640Shselasky 991335640Shselasky case EINTR: 992335640Shselasky goto again; 993335640Shselasky 994335640Shselasky#ifdef _AIX 995335640Shselasky case EFAULT: 996335640Shselasky /* 997335640Shselasky * Sigh. More AIX wonderfulness. 998335640Shselasky * 999335640Shselasky * For some unknown reason the uiomove() 1000335640Shselasky * operation in the bpf kernel extension 1001335640Shselasky * used to copy the buffer into user 1002335640Shselasky * space sometimes returns EFAULT. I have 1003335640Shselasky * no idea why this is the case given that 1004335640Shselasky * a kernel debugger shows the user buffer 1005335640Shselasky * is correct. This problem appears to 1006335640Shselasky * be mostly mitigated by the memset of 1007335640Shselasky * the buffer before it is first used. 1008335640Shselasky * Very strange.... Shaun Clowes 1009335640Shselasky * 1010335640Shselasky * In any case this means that we shouldn't 1011335640Shselasky * treat EFAULT as a fatal error; as we 1012335640Shselasky * don't have an API for returning 1013335640Shselasky * a "some packets were dropped since 1014335640Shselasky * the last packet you saw" indication, 1015335640Shselasky * we just ignore EFAULT and keep reading. 1016335640Shselasky */ 1017335640Shselasky goto again; 1018335640Shselasky#endif 1019335640Shselasky 1020335640Shselasky case EWOULDBLOCK: 1021335640Shselasky return (0); 1022335640Shselasky 1023356341Scy case ENXIO: /* FreeBSD, DragonFly BSD, and Darwin */ 1024356341Scy case EIO: /* OpenBSD */ 1025356341Scy /* NetBSD appears not to return an error in this case */ 1026335640Shselasky /* 1027335640Shselasky * The device on which we're capturing 1028335640Shselasky * went away. 1029335640Shselasky * 1030335640Shselasky * XXX - we should really return 1031356341Scy * an appropriate error for that, 1032356341Scy * but pcap_dispatch() etc. aren't 1033356341Scy * documented as having error returns 1034356341Scy * other than PCAP_ERROR or PCAP_ERROR_BREAK. 1035335640Shselasky */ 1036335640Shselasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1037356341Scy "The interface disappeared"); 1038335640Shselasky return (PCAP_ERROR); 1039335640Shselasky 1040335640Shselasky#if defined(sun) && !defined(BSD) && !defined(__svr4__) && !defined(__SVR4) 1041335640Shselasky /* 1042335640Shselasky * Due to a SunOS bug, after 2^31 bytes, the kernel 1043335640Shselasky * file offset overflows and read fails with EINVAL. 1044335640Shselasky * The lseek() to 0 will fix things. 1045335640Shselasky */ 1046335640Shselasky case EINVAL: 1047335640Shselasky if (lseek(p->fd, 0L, SEEK_CUR) + 1048335640Shselasky p->bufsize < 0) { 1049335640Shselasky (void)lseek(p->fd, 0L, SEEK_SET); 1050335640Shselasky goto again; 1051335640Shselasky } 1052335640Shselasky /* fall through */ 1053335640Shselasky#endif 1054335640Shselasky } 1055335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1056335640Shselasky errno, "read"); 1057335640Shselasky return (PCAP_ERROR); 1058335640Shselasky } 1059335640Shselasky bp = (u_char *)p->buffer; 1060335640Shselasky } else 1061335640Shselasky bp = p->bp; 1062335640Shselasky 1063335640Shselasky /* 1064335640Shselasky * Loop through each packet. 1065335640Shselasky */ 1066335640Shselasky#ifdef BIOCSTSTAMP 1067335640Shselasky#define bhp ((struct bpf_xhdr *)bp) 1068335640Shselasky#else 1069335640Shselasky#define bhp ((struct bpf_hdr *)bp) 1070335640Shselasky#endif 1071335640Shselasky ep = bp + cc; 1072335640Shselasky#ifdef PCAP_FDDIPAD 1073335640Shselasky pad = p->fddipad; 1074335640Shselasky#endif 1075335640Shselasky while (bp < ep) { 1076335640Shselasky register u_int caplen, hdrlen; 1077335640Shselasky 1078335640Shselasky /* 1079335640Shselasky * Has "pcap_breakloop()" been called? 1080335640Shselasky * If so, return immediately - if we haven't read any 1081335640Shselasky * packets, clear the flag and return PCAP_ERROR_BREAK 1082335640Shselasky * to indicate that we were told to break out of the loop, 1083335640Shselasky * otherwise leave the flag set, so that the *next* call 1084335640Shselasky * will break out of the loop without having read any 1085335640Shselasky * packets, and return the number of packets we've 1086335640Shselasky * processed so far. 1087335640Shselasky */ 1088335640Shselasky if (p->break_loop) { 1089335640Shselasky p->bp = bp; 1090335640Shselasky p->cc = ep - bp; 1091335640Shselasky /* 1092335640Shselasky * ep is set based on the return value of read(), 1093335640Shselasky * but read() from a BPF device doesn't necessarily 1094335640Shselasky * return a value that's a multiple of the alignment 1095335640Shselasky * value for BPF_WORDALIGN(). However, whenever we 1096335640Shselasky * increment bp, we round up the increment value by 1097335640Shselasky * a value rounded up by BPF_WORDALIGN(), so we 1098335640Shselasky * could increment bp past ep after processing the 1099335640Shselasky * last packet in the buffer. 1100335640Shselasky * 1101335640Shselasky * We treat ep < bp as an indication that this 1102335640Shselasky * happened, and just set p->cc to 0. 1103335640Shselasky */ 1104335640Shselasky if (p->cc < 0) 1105335640Shselasky p->cc = 0; 1106335640Shselasky if (n == 0) { 1107335640Shselasky p->break_loop = 0; 1108335640Shselasky return (PCAP_ERROR_BREAK); 1109335640Shselasky } else 1110335640Shselasky return (n); 1111335640Shselasky } 1112335640Shselasky 1113335640Shselasky caplen = bhp->bh_caplen; 1114335640Shselasky hdrlen = bhp->bh_hdrlen; 1115335640Shselasky datap = bp + hdrlen; 1116335640Shselasky /* 1117335640Shselasky * Short-circuit evaluation: if using BPF filter 1118335640Shselasky * in kernel, no need to do it now - we already know 1119335640Shselasky * the packet passed the filter. 1120335640Shselasky * 1121335640Shselasky#ifdef PCAP_FDDIPAD 1122335640Shselasky * Note: the filter code was generated assuming 1123335640Shselasky * that p->fddipad was the amount of padding 1124335640Shselasky * before the header, as that's what's required 1125335640Shselasky * in the kernel, so we run the filter before 1126335640Shselasky * skipping that padding. 1127335640Shselasky#endif 1128335640Shselasky */ 1129335640Shselasky if (pb->filtering_in_kernel || 1130335640Shselasky bpf_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) { 1131335640Shselasky struct pcap_pkthdr pkthdr; 1132335640Shselasky#ifdef BIOCSTSTAMP 1133335640Shselasky struct bintime bt; 1134335640Shselasky 1135335640Shselasky bt.sec = bhp->bh_tstamp.bt_sec; 1136335640Shselasky bt.frac = bhp->bh_tstamp.bt_frac; 1137335640Shselasky if (p->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO) { 1138335640Shselasky struct timespec ts; 1139335640Shselasky 1140335640Shselasky bintime2timespec(&bt, &ts); 1141335640Shselasky pkthdr.ts.tv_sec = ts.tv_sec; 1142335640Shselasky pkthdr.ts.tv_usec = ts.tv_nsec; 1143335640Shselasky } else { 1144335640Shselasky struct timeval tv; 1145335640Shselasky 1146335640Shselasky bintime2timeval(&bt, &tv); 1147335640Shselasky pkthdr.ts.tv_sec = tv.tv_sec; 1148335640Shselasky pkthdr.ts.tv_usec = tv.tv_usec; 1149335640Shselasky } 1150335640Shselasky#else 1151335640Shselasky pkthdr.ts.tv_sec = bhp->bh_tstamp.tv_sec; 1152335640Shselasky#ifdef _AIX 1153335640Shselasky /* 1154335640Shselasky * AIX's BPF returns seconds/nanoseconds time 1155335640Shselasky * stamps, not seconds/microseconds time stamps. 1156335640Shselasky */ 1157335640Shselasky pkthdr.ts.tv_usec = bhp->bh_tstamp.tv_usec/1000; 1158335640Shselasky#else 1159335640Shselasky pkthdr.ts.tv_usec = bhp->bh_tstamp.tv_usec; 1160335640Shselasky#endif 1161335640Shselasky#endif /* BIOCSTSTAMP */ 1162335640Shselasky#ifdef PCAP_FDDIPAD 1163335640Shselasky if (caplen > pad) 1164335640Shselasky pkthdr.caplen = caplen - pad; 1165335640Shselasky else 1166335640Shselasky pkthdr.caplen = 0; 1167335640Shselasky if (bhp->bh_datalen > pad) 1168335640Shselasky pkthdr.len = bhp->bh_datalen - pad; 1169335640Shselasky else 1170335640Shselasky pkthdr.len = 0; 1171335640Shselasky datap += pad; 1172335640Shselasky#else 1173335640Shselasky pkthdr.caplen = caplen; 1174335640Shselasky pkthdr.len = bhp->bh_datalen; 1175335640Shselasky#endif 1176335640Shselasky (*callback)(user, &pkthdr, datap); 1177335640Shselasky bp += BPF_WORDALIGN(caplen + hdrlen); 1178335640Shselasky if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) { 1179335640Shselasky p->bp = bp; 1180335640Shselasky p->cc = ep - bp; 1181335640Shselasky /* 1182335640Shselasky * See comment above about p->cc < 0. 1183335640Shselasky */ 1184335640Shselasky if (p->cc < 0) 1185335640Shselasky p->cc = 0; 1186335640Shselasky return (n); 1187335640Shselasky } 1188335640Shselasky } else { 1189335640Shselasky /* 1190335640Shselasky * Skip this packet. 1191335640Shselasky */ 1192335640Shselasky bp += BPF_WORDALIGN(caplen + hdrlen); 1193335640Shselasky } 1194335640Shselasky } 1195335640Shselasky#undef bhp 1196335640Shselasky p->cc = 0; 1197335640Shselasky return (n); 1198335640Shselasky} 1199335640Shselasky 1200335640Shselaskystatic int 1201335640Shselaskypcap_inject_bpf(pcap_t *p, const void *buf, size_t size) 1202335640Shselasky{ 1203335640Shselasky int ret; 1204335640Shselasky 1205335640Shselasky ret = write(p->fd, buf, size); 1206335640Shselasky#ifdef __APPLE__ 1207335640Shselasky if (ret == -1 && errno == EAFNOSUPPORT) { 1208335640Shselasky /* 1209335640Shselasky * In some versions of macOS, there's a bug wherein setting 1210335640Shselasky * the BIOCSHDRCMPLT flag causes writes to fail; see, for 1211335640Shselasky * example: 1212335640Shselasky * 1213335640Shselasky * http://cerberus.sourcefire.com/~jeff/archives/patches/macosx/BIOCSHDRCMPLT-10.3.3.patch 1214335640Shselasky * 1215335640Shselasky * So, if, on macOS, we get EAFNOSUPPORT from the write, we 1216335640Shselasky * assume it's due to that bug, and turn off that flag 1217335640Shselasky * and try again. If we succeed, it either means that 1218335640Shselasky * somebody applied the fix from that URL, or other patches 1219335640Shselasky * for that bug from 1220335640Shselasky * 1221335640Shselasky * http://cerberus.sourcefire.com/~jeff/archives/patches/macosx/ 1222335640Shselasky * 1223335640Shselasky * and are running a Darwin kernel with those fixes, or 1224335640Shselasky * that Apple fixed the problem in some macOS release. 1225335640Shselasky */ 1226335640Shselasky u_int spoof_eth_src = 0; 1227335640Shselasky 1228335640Shselasky if (ioctl(p->fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) { 1229335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1230335640Shselasky errno, "send: can't turn off BIOCSHDRCMPLT"); 1231335640Shselasky return (PCAP_ERROR); 1232335640Shselasky } 1233335640Shselasky 1234335640Shselasky /* 1235335640Shselasky * Now try the write again. 1236335640Shselasky */ 1237335640Shselasky ret = write(p->fd, buf, size); 1238335640Shselasky } 1239335640Shselasky#endif /* __APPLE__ */ 1240335640Shselasky if (ret == -1) { 1241335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1242335640Shselasky errno, "send"); 1243335640Shselasky return (PCAP_ERROR); 1244335640Shselasky } 1245335640Shselasky return (ret); 1246335640Shselasky} 1247335640Shselasky 1248335640Shselasky#ifdef _AIX 1249335640Shselaskystatic int 1250335640Shselaskybpf_odminit(char *errbuf) 1251335640Shselasky{ 1252335640Shselasky char *errstr; 1253335640Shselasky 1254335640Shselasky if (odm_initialize() == -1) { 1255335640Shselasky if (odm_err_msg(odmerrno, &errstr) == -1) 1256335640Shselasky errstr = "Unknown error"; 1257335640Shselasky pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 1258335640Shselasky "bpf_load: odm_initialize failed: %s", 1259335640Shselasky errstr); 1260335640Shselasky return (PCAP_ERROR); 1261335640Shselasky } 1262335640Shselasky 1263335640Shselasky if ((odmlockid = odm_lock("/etc/objrepos/config_lock", ODM_WAIT)) == -1) { 1264335640Shselasky if (odm_err_msg(odmerrno, &errstr) == -1) 1265335640Shselasky errstr = "Unknown error"; 1266335640Shselasky pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 1267335640Shselasky "bpf_load: odm_lock of /etc/objrepos/config_lock failed: %s", 1268335640Shselasky errstr); 1269335640Shselasky (void)odm_terminate(); 1270335640Shselasky return (PCAP_ERROR); 1271335640Shselasky } 1272335640Shselasky 1273335640Shselasky return (0); 1274335640Shselasky} 1275335640Shselasky 1276335640Shselaskystatic int 1277335640Shselaskybpf_odmcleanup(char *errbuf) 1278335640Shselasky{ 1279335640Shselasky char *errstr; 1280335640Shselasky 1281335640Shselasky if (odm_unlock(odmlockid) == -1) { 1282335640Shselasky if (errbuf != NULL) { 1283335640Shselasky if (odm_err_msg(odmerrno, &errstr) == -1) 1284335640Shselasky errstr = "Unknown error"; 1285335640Shselasky pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 1286335640Shselasky "bpf_load: odm_unlock failed: %s", 1287335640Shselasky errstr); 1288335640Shselasky } 1289335640Shselasky return (PCAP_ERROR); 1290335640Shselasky } 1291335640Shselasky 1292335640Shselasky if (odm_terminate() == -1) { 1293335640Shselasky if (errbuf != NULL) { 1294335640Shselasky if (odm_err_msg(odmerrno, &errstr) == -1) 1295335640Shselasky errstr = "Unknown error"; 1296335640Shselasky pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 1297335640Shselasky "bpf_load: odm_terminate failed: %s", 1298335640Shselasky errstr); 1299335640Shselasky } 1300335640Shselasky return (PCAP_ERROR); 1301335640Shselasky } 1302335640Shselasky 1303335640Shselasky return (0); 1304335640Shselasky} 1305335640Shselasky 1306335640Shselaskystatic int 1307335640Shselaskybpf_load(char *errbuf) 1308335640Shselasky{ 1309335640Shselasky long major; 1310335640Shselasky int *minors; 1311335640Shselasky int numminors, i, rc; 1312335640Shselasky char buf[1024]; 1313335640Shselasky struct stat sbuf; 1314335640Shselasky struct bpf_config cfg_bpf; 1315335640Shselasky struct cfg_load cfg_ld; 1316335640Shselasky struct cfg_kmod cfg_km; 1317335640Shselasky 1318335640Shselasky /* 1319335640Shselasky * This is very very close to what happens in the real implementation 1320335640Shselasky * but I've fixed some (unlikely) bug situations. 1321335640Shselasky */ 1322335640Shselasky if (bpfloadedflag) 1323335640Shselasky return (0); 1324335640Shselasky 1325335640Shselasky if (bpf_odminit(errbuf) == PCAP_ERROR) 1326335640Shselasky return (PCAP_ERROR); 1327335640Shselasky 1328335640Shselasky major = genmajor(BPF_NAME); 1329335640Shselasky if (major == -1) { 1330335640Shselasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1331335640Shselasky errno, "bpf_load: genmajor failed"); 1332335640Shselasky (void)bpf_odmcleanup(NULL); 1333335640Shselasky return (PCAP_ERROR); 1334335640Shselasky } 1335335640Shselasky 1336335640Shselasky minors = getminor(major, &numminors, BPF_NAME); 1337335640Shselasky if (!minors) { 1338335640Shselasky minors = genminor("bpf", major, 0, BPF_MINORS, 1, 1); 1339335640Shselasky if (!minors) { 1340335640Shselasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1341335640Shselasky errno, "bpf_load: genminor failed"); 1342335640Shselasky (void)bpf_odmcleanup(NULL); 1343335640Shselasky return (PCAP_ERROR); 1344335640Shselasky } 1345335640Shselasky } 1346335640Shselasky 1347335640Shselasky if (bpf_odmcleanup(errbuf) == PCAP_ERROR) 1348335640Shselasky return (PCAP_ERROR); 1349335640Shselasky 1350335640Shselasky rc = stat(BPF_NODE "0", &sbuf); 1351335640Shselasky if (rc == -1 && errno != ENOENT) { 1352335640Shselasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1353335640Shselasky errno, "bpf_load: can't stat %s", BPF_NODE "0"); 1354335640Shselasky return (PCAP_ERROR); 1355335640Shselasky } 1356335640Shselasky 1357335640Shselasky if (rc == -1 || getmajor(sbuf.st_rdev) != major) { 1358335640Shselasky for (i = 0; i < BPF_MINORS; i++) { 1359335640Shselasky pcap_snprintf(buf, sizeof(buf), "%s%d", BPF_NODE, i); 1360335640Shselasky unlink(buf); 1361335640Shselasky if (mknod(buf, S_IRUSR | S_IFCHR, domakedev(major, i)) == -1) { 1362335640Shselasky pcap_fmt_errmsg_for_errno(errbuf, 1363335640Shselasky PCAP_ERRBUF_SIZE, errno, 1364335640Shselasky "bpf_load: can't mknod %s", buf); 1365335640Shselasky return (PCAP_ERROR); 1366335640Shselasky } 1367335640Shselasky } 1368335640Shselasky } 1369335640Shselasky 1370335640Shselasky /* Check if the driver is loaded */ 1371335640Shselasky memset(&cfg_ld, 0x0, sizeof(cfg_ld)); 1372356341Scy pcap_snprintf(buf, sizeof(buf), "%s/%s", DRIVER_PATH, BPF_NAME); 1373335640Shselasky cfg_ld.path = buf; 1374335640Shselasky if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) || 1375335640Shselasky (cfg_ld.kmid == 0)) { 1376335640Shselasky /* Driver isn't loaded, load it now */ 1377335640Shselasky if (sysconfig(SYS_SINGLELOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) { 1378335640Shselasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1379335640Shselasky errno, "bpf_load: could not load driver"); 1380335640Shselasky return (PCAP_ERROR); 1381335640Shselasky } 1382335640Shselasky } 1383335640Shselasky 1384335640Shselasky /* Configure the driver */ 1385335640Shselasky cfg_km.cmd = CFG_INIT; 1386335640Shselasky cfg_km.kmid = cfg_ld.kmid; 1387335640Shselasky cfg_km.mdilen = sizeof(cfg_bpf); 1388335640Shselasky cfg_km.mdiptr = (void *)&cfg_bpf; 1389335640Shselasky for (i = 0; i < BPF_MINORS; i++) { 1390335640Shselasky cfg_bpf.devno = domakedev(major, i); 1391335640Shselasky if (sysconfig(SYS_CFGKMOD, (void *)&cfg_km, sizeof(cfg_km)) == -1) { 1392335640Shselasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 1393335640Shselasky errno, "bpf_load: could not configure driver"); 1394335640Shselasky return (PCAP_ERROR); 1395335640Shselasky } 1396335640Shselasky } 1397335640Shselasky 1398335640Shselasky bpfloadedflag = 1; 1399335640Shselasky 1400335640Shselasky return (0); 1401335640Shselasky} 1402335640Shselasky#endif 1403335640Shselasky 1404335640Shselasky/* 1405335640Shselasky * Undo any operations done when opening the device when necessary. 1406335640Shselasky */ 1407335640Shselaskystatic void 1408335640Shselaskypcap_cleanup_bpf(pcap_t *p) 1409335640Shselasky{ 1410335640Shselasky struct pcap_bpf *pb = p->priv; 1411335640Shselasky#ifdef HAVE_BSD_IEEE80211 1412335640Shselasky int sock; 1413335640Shselasky struct ifmediareq req; 1414335640Shselasky struct ifreq ifr; 1415335640Shselasky#endif 1416335640Shselasky 1417335640Shselasky if (pb->must_do_on_close != 0) { 1418335640Shselasky /* 1419335640Shselasky * There's something we have to do when closing this 1420335640Shselasky * pcap_t. 1421335640Shselasky */ 1422335640Shselasky#ifdef HAVE_BSD_IEEE80211 1423335640Shselasky if (pb->must_do_on_close & MUST_CLEAR_RFMON) { 1424335640Shselasky /* 1425335640Shselasky * We put the interface into rfmon mode; 1426335640Shselasky * take it out of rfmon mode. 1427335640Shselasky * 1428335640Shselasky * XXX - if somebody else wants it in rfmon 1429335640Shselasky * mode, this code cannot know that, so it'll take 1430335640Shselasky * it out of rfmon mode. 1431335640Shselasky */ 1432335640Shselasky sock = socket(AF_INET, SOCK_DGRAM, 0); 1433335640Shselasky if (sock == -1) { 1434335640Shselasky fprintf(stderr, 1435335640Shselasky "Can't restore interface flags (socket() failed: %s).\n" 1436335640Shselasky "Please adjust manually.\n", 1437335640Shselasky strerror(errno)); 1438335640Shselasky } else { 1439335640Shselasky memset(&req, 0, sizeof(req)); 1440335640Shselasky strncpy(req.ifm_name, pb->device, 1441335640Shselasky sizeof(req.ifm_name)); 1442335640Shselasky if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) { 1443335640Shselasky fprintf(stderr, 1444335640Shselasky "Can't restore interface flags (SIOCGIFMEDIA failed: %s).\n" 1445335640Shselasky "Please adjust manually.\n", 1446335640Shselasky strerror(errno)); 1447335640Shselasky } else { 1448335640Shselasky if (req.ifm_current & IFM_IEEE80211_MONITOR) { 1449335640Shselasky /* 1450335640Shselasky * Rfmon mode is currently on; 1451335640Shselasky * turn it off. 1452335640Shselasky */ 1453335640Shselasky memset(&ifr, 0, sizeof(ifr)); 1454335640Shselasky (void)strncpy(ifr.ifr_name, 1455335640Shselasky pb->device, 1456335640Shselasky sizeof(ifr.ifr_name)); 1457335640Shselasky ifr.ifr_media = 1458335640Shselasky req.ifm_current & ~IFM_IEEE80211_MONITOR; 1459335640Shselasky if (ioctl(sock, SIOCSIFMEDIA, 1460335640Shselasky &ifr) == -1) { 1461335640Shselasky fprintf(stderr, 1462335640Shselasky "Can't restore interface flags (SIOCSIFMEDIA failed: %s).\n" 1463335640Shselasky "Please adjust manually.\n", 1464335640Shselasky strerror(errno)); 1465335640Shselasky } 1466335640Shselasky } 1467335640Shselasky } 1468335640Shselasky close(sock); 1469335640Shselasky } 1470335640Shselasky } 1471335640Shselasky#endif /* HAVE_BSD_IEEE80211 */ 1472335640Shselasky 1473335640Shselasky#if defined(__FreeBSD__) && defined(SIOCIFCREATE2) 1474335640Shselasky /* 1475335640Shselasky * Attempt to destroy the usbusN interface that we created. 1476335640Shselasky */ 1477335640Shselasky if (pb->must_do_on_close & MUST_DESTROY_USBUS) { 1478335640Shselasky if (if_nametoindex(pb->device) > 0) { 1479335640Shselasky int s; 1480335640Shselasky 1481335640Shselasky s = socket(AF_LOCAL, SOCK_DGRAM, 0); 1482335640Shselasky if (s >= 0) { 1483356341Scy pcap_strlcpy(ifr.ifr_name, pb->device, 1484335640Shselasky sizeof(ifr.ifr_name)); 1485335640Shselasky ioctl(s, SIOCIFDESTROY, &ifr); 1486335640Shselasky close(s); 1487335640Shselasky } 1488335640Shselasky } 1489335640Shselasky } 1490335640Shselasky#endif /* defined(__FreeBSD__) && defined(SIOCIFCREATE2) */ 1491335640Shselasky /* 1492335640Shselasky * Take this pcap out of the list of pcaps for which we 1493335640Shselasky * have to take the interface out of some mode. 1494335640Shselasky */ 1495335640Shselasky pcap_remove_from_pcaps_to_close(p); 1496335640Shselasky pb->must_do_on_close = 0; 1497335640Shselasky } 1498335640Shselasky 1499335640Shselasky#ifdef HAVE_ZEROCOPY_BPF 1500335640Shselasky if (pb->zerocopy) { 1501335640Shselasky /* 1502335640Shselasky * Delete the mappings. Note that p->buffer gets 1503335640Shselasky * initialized to one of the mmapped regions in 1504335640Shselasky * this case, so do not try and free it directly; 1505335640Shselasky * null it out so that pcap_cleanup_live_common() 1506335640Shselasky * doesn't try to free it. 1507335640Shselasky */ 1508335640Shselasky if (pb->zbuf1 != MAP_FAILED && pb->zbuf1 != NULL) 1509335640Shselasky (void) munmap(pb->zbuf1, pb->zbufsize); 1510335640Shselasky if (pb->zbuf2 != MAP_FAILED && pb->zbuf2 != NULL) 1511335640Shselasky (void) munmap(pb->zbuf2, pb->zbufsize); 1512335640Shselasky p->buffer = NULL; 1513335640Shselasky } 1514335640Shselasky#endif 1515335640Shselasky if (pb->device != NULL) { 1516335640Shselasky free(pb->device); 1517335640Shselasky pb->device = NULL; 1518335640Shselasky } 1519335640Shselasky pcap_cleanup_live_common(p); 1520335640Shselasky} 1521335640Shselasky 1522335640Shselaskystatic int 1523335640Shselaskycheck_setif_failure(pcap_t *p, int error) 1524335640Shselasky{ 1525335640Shselasky#ifdef __APPLE__ 1526335640Shselasky int fd; 1527335640Shselasky struct ifreq ifr; 1528335640Shselasky int err; 1529335640Shselasky#endif 1530335640Shselasky 1531335640Shselasky if (error == ENXIO) { 1532335640Shselasky /* 1533335640Shselasky * No such device exists. 1534335640Shselasky */ 1535335640Shselasky#ifdef __APPLE__ 1536335640Shselasky if (p->opt.rfmon && strncmp(p->opt.device, "wlt", 3) == 0) { 1537335640Shselasky /* 1538335640Shselasky * Monitor mode was requested, and we're trying 1539335640Shselasky * to open a "wltN" device. Assume that this 1540335640Shselasky * is 10.4 and that we were asked to open an 1541335640Shselasky * "enN" device; if that device exists, return 1542335640Shselasky * "monitor mode not supported on the device". 1543335640Shselasky */ 1544335640Shselasky fd = socket(AF_INET, SOCK_DGRAM, 0); 1545335640Shselasky if (fd != -1) { 1546356341Scy pcap_strlcpy(ifr.ifr_name, "en", 1547335640Shselasky sizeof(ifr.ifr_name)); 1548356341Scy pcap_strlcat(ifr.ifr_name, p->opt.device + 3, 1549335640Shselasky sizeof(ifr.ifr_name)); 1550335640Shselasky if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) { 1551335640Shselasky /* 1552335640Shselasky * We assume this failed because 1553335640Shselasky * the underlying device doesn't 1554335640Shselasky * exist. 1555335640Shselasky */ 1556335640Shselasky err = PCAP_ERROR_NO_SUCH_DEVICE; 1557335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, 1558335640Shselasky PCAP_ERRBUF_SIZE, errno, 1559335640Shselasky "SIOCGIFFLAGS on %s failed", 1560335640Shselasky ifr.ifr_name); 1561335640Shselasky } else { 1562335640Shselasky /* 1563335640Shselasky * The underlying "enN" device 1564335640Shselasky * exists, but there's no 1565335640Shselasky * corresponding "wltN" device; 1566335640Shselasky * that means that the "enN" 1567335640Shselasky * device doesn't support 1568335640Shselasky * monitor mode, probably because 1569335640Shselasky * it's an Ethernet device rather 1570335640Shselasky * than a wireless device. 1571335640Shselasky */ 1572335640Shselasky err = PCAP_ERROR_RFMON_NOTSUP; 1573335640Shselasky } 1574335640Shselasky close(fd); 1575335640Shselasky } else { 1576335640Shselasky /* 1577335640Shselasky * We can't find out whether there's 1578335640Shselasky * an underlying "enN" device, so 1579335640Shselasky * just report "no such device". 1580335640Shselasky */ 1581335640Shselasky err = PCAP_ERROR_NO_SUCH_DEVICE; 1582335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, 1583335640Shselasky errno, PCAP_ERRBUF_SIZE, 1584335640Shselasky "socket() failed"); 1585335640Shselasky } 1586335640Shselasky return (err); 1587335640Shselasky } 1588335640Shselasky#endif 1589335640Shselasky /* 1590335640Shselasky * No such device. 1591335640Shselasky */ 1592335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1593335640Shselasky errno, "BIOCSETIF failed"); 1594335640Shselasky return (PCAP_ERROR_NO_SUCH_DEVICE); 1595335640Shselasky } else if (errno == ENETDOWN) { 1596335640Shselasky /* 1597335640Shselasky * Return a "network down" indication, so that 1598335640Shselasky * the application can report that rather than 1599335640Shselasky * saying we had a mysterious failure and 1600335640Shselasky * suggest that they report a problem to the 1601335640Shselasky * libpcap developers. 1602335640Shselasky */ 1603335640Shselasky return (PCAP_ERROR_IFACE_NOT_UP); 1604335640Shselasky } else { 1605335640Shselasky /* 1606335640Shselasky * Some other error; fill in the error string, and 1607335640Shselasky * return PCAP_ERROR. 1608335640Shselasky */ 1609335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1610335640Shselasky errno, "BIOCSETIF: %s", p->opt.device); 1611335640Shselasky return (PCAP_ERROR); 1612335640Shselasky } 1613335640Shselasky} 1614335640Shselasky 1615335640Shselasky/* 1616335640Shselasky * Default capture buffer size. 1617335640Shselasky * 32K isn't very much for modern machines with fast networks; we 1618335640Shselasky * pick .5M, as that's the maximum on at least some systems with BPF. 1619335640Shselasky * 1620335640Shselasky * However, on AIX 3.5, the larger buffer sized caused unrecoverable 1621335640Shselasky * read failures under stress, so we leave it as 32K; yet another 1622335640Shselasky * place where AIX's BPF is broken. 1623335640Shselasky */ 1624335640Shselasky#ifdef _AIX 1625335640Shselasky#define DEFAULT_BUFSIZE 32768 1626335640Shselasky#else 1627335640Shselasky#define DEFAULT_BUFSIZE 524288 1628335640Shselasky#endif 1629335640Shselasky 1630335640Shselaskystatic int 1631335640Shselaskypcap_activate_bpf(pcap_t *p) 1632335640Shselasky{ 1633335640Shselasky struct pcap_bpf *pb = p->priv; 1634335640Shselasky int status = 0; 1635335640Shselasky#ifdef HAVE_BSD_IEEE80211 1636335640Shselasky int retv; 1637335640Shselasky#endif 1638335640Shselasky int fd; 1639335640Shselasky#ifdef LIFNAMSIZ 1640335640Shselasky char *zonesep; 1641335640Shselasky struct lifreq ifr; 1642335640Shselasky char *ifrname = ifr.lifr_name; 1643335640Shselasky const size_t ifnamsiz = sizeof(ifr.lifr_name); 1644335640Shselasky#else 1645335640Shselasky struct ifreq ifr; 1646335640Shselasky char *ifrname = ifr.ifr_name; 1647335640Shselasky const size_t ifnamsiz = sizeof(ifr.ifr_name); 1648335640Shselasky#endif 1649335640Shselasky struct bpf_version bv; 1650335640Shselasky#ifdef __APPLE__ 1651335640Shselasky int sockfd; 1652335640Shselasky char *wltdev = NULL; 1653335640Shselasky#endif 1654335640Shselasky#ifdef BIOCGDLTLIST 1655335640Shselasky struct bpf_dltlist bdl; 1656335640Shselasky#if defined(__APPLE__) || defined(HAVE_BSD_IEEE80211) 1657335640Shselasky int new_dlt; 1658335640Shselasky#endif 1659335640Shselasky#endif /* BIOCGDLTLIST */ 1660335640Shselasky#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) 1661335640Shselasky u_int spoof_eth_src = 1; 1662335640Shselasky#endif 1663335640Shselasky u_int v; 1664335640Shselasky struct bpf_insn total_insn; 1665335640Shselasky struct bpf_program total_prog; 1666335640Shselasky struct utsname osinfo; 1667335640Shselasky int have_osinfo = 0; 1668335640Shselasky#ifdef HAVE_ZEROCOPY_BPF 1669335640Shselasky struct bpf_zbuf bz; 1670335640Shselasky u_int bufmode, zbufmax; 1671335640Shselasky#endif 1672335640Shselasky 1673335640Shselasky fd = bpf_open(p->errbuf); 1674335640Shselasky if (fd < 0) { 1675335640Shselasky status = fd; 1676335640Shselasky goto bad; 1677335640Shselasky } 1678335640Shselasky 1679335640Shselasky p->fd = fd; 1680335640Shselasky 1681335640Shselasky if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) { 1682335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1683335640Shselasky errno, "BIOCVERSION"); 1684335640Shselasky status = PCAP_ERROR; 1685335640Shselasky goto bad; 1686335640Shselasky } 1687335640Shselasky if (bv.bv_major != BPF_MAJOR_VERSION || 1688335640Shselasky bv.bv_minor < BPF_MINOR_VERSION) { 1689335640Shselasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1690335640Shselasky "kernel bpf filter out of date"); 1691335640Shselasky status = PCAP_ERROR; 1692335640Shselasky goto bad; 1693335640Shselasky } 1694335640Shselasky 1695335640Shselasky /* 1696335640Shselasky * Turn a negative snapshot value (invalid), a snapshot value of 1697335640Shselasky * 0 (unspecified), or a value bigger than the normal maximum 1698335640Shselasky * value, into the maximum allowed value. 1699335640Shselasky * 1700335640Shselasky * If some application really *needs* a bigger snapshot 1701335640Shselasky * length, we should just increase MAXIMUM_SNAPLEN. 1702335640Shselasky */ 1703335640Shselasky if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) 1704335640Shselasky p->snapshot = MAXIMUM_SNAPLEN; 1705335640Shselasky 1706335640Shselasky#if defined(LIFNAMSIZ) && defined(ZONENAME_MAX) && defined(lifr_zoneid) 1707335640Shselasky /* 1708335640Shselasky * Retrieve the zoneid of the zone we are currently executing in. 1709335640Shselasky */ 1710335640Shselasky if ((ifr.lifr_zoneid = getzoneid()) == -1) { 1711335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1712335640Shselasky errno, "getzoneid()"); 1713335640Shselasky status = PCAP_ERROR; 1714335640Shselasky goto bad; 1715335640Shselasky } 1716335640Shselasky /* 1717335640Shselasky * Check if the given source datalink name has a '/' separated 1718335640Shselasky * zonename prefix string. The zonename prefixed source datalink can 1719335640Shselasky * be used by pcap consumers in the Solaris global zone to capture 1720335640Shselasky * traffic on datalinks in non-global zones. Non-global zones 1721335640Shselasky * do not have access to datalinks outside of their own namespace. 1722335640Shselasky */ 1723335640Shselasky if ((zonesep = strchr(p->opt.device, '/')) != NULL) { 1724335640Shselasky char path_zname[ZONENAME_MAX]; 1725335640Shselasky int znamelen; 1726335640Shselasky char *lnamep; 1727335640Shselasky 1728335640Shselasky if (ifr.lifr_zoneid != GLOBAL_ZONEID) { 1729335640Shselasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1730335640Shselasky "zonename/linkname only valid in global zone."); 1731335640Shselasky status = PCAP_ERROR; 1732335640Shselasky goto bad; 1733335640Shselasky } 1734335640Shselasky znamelen = zonesep - p->opt.device; 1735356341Scy (void) pcap_strlcpy(path_zname, p->opt.device, znamelen + 1); 1736335640Shselasky ifr.lifr_zoneid = getzoneidbyname(path_zname); 1737335640Shselasky if (ifr.lifr_zoneid == -1) { 1738335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1739335640Shselasky errno, "getzoneidbyname(%s)", path_zname); 1740335640Shselasky status = PCAP_ERROR; 1741335640Shselasky goto bad; 1742335640Shselasky } 1743335640Shselasky lnamep = strdup(zonesep + 1); 1744335640Shselasky if (lnamep == NULL) { 1745335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1746335640Shselasky errno, "strdup"); 1747335640Shselasky status = PCAP_ERROR; 1748335640Shselasky goto bad; 1749335640Shselasky } 1750335640Shselasky free(p->opt.device); 1751335640Shselasky p->opt.device = lnamep; 1752335640Shselasky } 1753335640Shselasky#endif 1754335640Shselasky 1755335640Shselasky pb->device = strdup(p->opt.device); 1756335640Shselasky if (pb->device == NULL) { 1757335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1758335640Shselasky errno, "strdup"); 1759335640Shselasky status = PCAP_ERROR; 1760335640Shselasky goto bad; 1761335640Shselasky } 1762335640Shselasky 1763335640Shselasky /* 1764335640Shselasky * Attempt to find out the version of the OS on which we're running. 1765335640Shselasky */ 1766335640Shselasky if (uname(&osinfo) == 0) 1767335640Shselasky have_osinfo = 1; 1768335640Shselasky 1769335640Shselasky#ifdef __APPLE__ 1770335640Shselasky /* 1771335640Shselasky * See comment in pcap_can_set_rfmon_bpf() for an explanation 1772335640Shselasky * of why we check the version number. 1773335640Shselasky */ 1774335640Shselasky if (p->opt.rfmon) { 1775335640Shselasky if (have_osinfo) { 1776335640Shselasky /* 1777335640Shselasky * We assume osinfo.sysname is "Darwin", because 1778335640Shselasky * __APPLE__ is defined. We just check the version. 1779335640Shselasky */ 1780335640Shselasky if (osinfo.release[0] < '8' && 1781335640Shselasky osinfo.release[1] == '.') { 1782335640Shselasky /* 1783335640Shselasky * 10.3 (Darwin 7.x) or earlier. 1784335640Shselasky */ 1785335640Shselasky status = PCAP_ERROR_RFMON_NOTSUP; 1786335640Shselasky goto bad; 1787335640Shselasky } 1788335640Shselasky if (osinfo.release[0] == '8' && 1789335640Shselasky osinfo.release[1] == '.') { 1790335640Shselasky /* 1791335640Shselasky * 10.4 (Darwin 8.x). s/en/wlt/ 1792335640Shselasky */ 1793335640Shselasky if (strncmp(p->opt.device, "en", 2) != 0) { 1794335640Shselasky /* 1795335640Shselasky * Not an enN device; check 1796335640Shselasky * whether the device even exists. 1797335640Shselasky */ 1798335640Shselasky sockfd = socket(AF_INET, SOCK_DGRAM, 0); 1799335640Shselasky if (sockfd != -1) { 1800356341Scy pcap_strlcpy(ifrname, 1801335640Shselasky p->opt.device, ifnamsiz); 1802335640Shselasky if (ioctl(sockfd, SIOCGIFFLAGS, 1803335640Shselasky (char *)&ifr) < 0) { 1804335640Shselasky /* 1805335640Shselasky * We assume this 1806335640Shselasky * failed because 1807335640Shselasky * the underlying 1808335640Shselasky * device doesn't 1809335640Shselasky * exist. 1810335640Shselasky */ 1811335640Shselasky status = PCAP_ERROR_NO_SUCH_DEVICE; 1812335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, 1813335640Shselasky PCAP_ERRBUF_SIZE, 1814335640Shselasky errno, 1815335640Shselasky "SIOCGIFFLAGS failed"); 1816335640Shselasky } else 1817335640Shselasky status = PCAP_ERROR_RFMON_NOTSUP; 1818335640Shselasky close(sockfd); 1819335640Shselasky } else { 1820335640Shselasky /* 1821335640Shselasky * We can't find out whether 1822335640Shselasky * the device exists, so just 1823335640Shselasky * report "no such device". 1824335640Shselasky */ 1825335640Shselasky status = PCAP_ERROR_NO_SUCH_DEVICE; 1826335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, 1827335640Shselasky PCAP_ERRBUF_SIZE, errno, 1828335640Shselasky "socket() failed"); 1829335640Shselasky } 1830335640Shselasky goto bad; 1831335640Shselasky } 1832335640Shselasky wltdev = malloc(strlen(p->opt.device) + 2); 1833335640Shselasky if (wltdev == NULL) { 1834335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, 1835335640Shselasky PCAP_ERRBUF_SIZE, errno, 1836335640Shselasky "malloc"); 1837335640Shselasky status = PCAP_ERROR; 1838335640Shselasky goto bad; 1839335640Shselasky } 1840335640Shselasky strcpy(wltdev, "wlt"); 1841335640Shselasky strcat(wltdev, p->opt.device + 2); 1842335640Shselasky free(p->opt.device); 1843335640Shselasky p->opt.device = wltdev; 1844335640Shselasky } 1845335640Shselasky /* 1846335640Shselasky * Everything else is 10.5 or later; for those, 1847335640Shselasky * we just open the enN device, and set the DLT. 1848335640Shselasky */ 1849335640Shselasky } 1850335640Shselasky } 1851335640Shselasky#endif /* __APPLE__ */ 1852335640Shselasky 1853335640Shselasky /* 1854335640Shselasky * If this is FreeBSD, and the device name begins with "usbus", 1855335640Shselasky * try to create the interface if it's not available. 1856335640Shselasky */ 1857335640Shselasky#if defined(__FreeBSD__) && defined(SIOCIFCREATE2) 1858335640Shselasky if (strncmp(p->opt.device, usbus_prefix, USBUS_PREFIX_LEN) == 0) { 1859335640Shselasky /* 1860335640Shselasky * Do we already have an interface with that name? 1861335640Shselasky */ 1862335640Shselasky if (if_nametoindex(p->opt.device) == 0) { 1863335640Shselasky /* 1864335640Shselasky * No. We need to create it, and, if we 1865335640Shselasky * succeed, remember that we should destroy 1866335640Shselasky * it when the pcap_t is closed. 1867335640Shselasky */ 1868335640Shselasky int s; 1869335640Shselasky 1870335640Shselasky /* 1871335640Shselasky * Open a socket to use for ioctls to 1872335640Shselasky * create the interface. 1873335640Shselasky */ 1874335640Shselasky s = socket(AF_LOCAL, SOCK_DGRAM, 0); 1875335640Shselasky if (s < 0) { 1876335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, 1877335640Shselasky PCAP_ERRBUF_SIZE, errno, 1878335640Shselasky "Can't open socket"); 1879335640Shselasky status = PCAP_ERROR; 1880335640Shselasky goto bad; 1881335640Shselasky } 1882335640Shselasky 1883335640Shselasky /* 1884335640Shselasky * If we haven't already done so, arrange to have 1885335640Shselasky * "pcap_close_all()" called when we exit. 1886335640Shselasky */ 1887335640Shselasky if (!pcap_do_addexit(p)) { 1888335640Shselasky /* 1889335640Shselasky * "atexit()" failed; don't create the 1890335640Shselasky * interface, just give up. 1891335640Shselasky */ 1892335640Shselasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1893335640Shselasky "atexit failed"); 1894335640Shselasky close(s); 1895335640Shselasky status = PCAP_ERROR; 1896335640Shselasky goto bad; 1897335640Shselasky } 1898335640Shselasky 1899335640Shselasky /* 1900335640Shselasky * Create the interface. 1901335640Shselasky */ 1902356341Scy pcap_strlcpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name)); 1903335640Shselasky if (ioctl(s, SIOCIFCREATE2, &ifr) < 0) { 1904335640Shselasky if (errno == EINVAL) { 1905335640Shselasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 1906335640Shselasky "Invalid USB bus interface %s", 1907335640Shselasky p->opt.device); 1908335640Shselasky } else { 1909335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, 1910335640Shselasky PCAP_ERRBUF_SIZE, errno, 1911335640Shselasky "Can't create interface for %s", 1912335640Shselasky p->opt.device); 1913335640Shselasky } 1914335640Shselasky close(s); 1915335640Shselasky status = PCAP_ERROR; 1916335640Shselasky goto bad; 1917335640Shselasky } 1918335640Shselasky 1919335640Shselasky /* 1920335640Shselasky * Make sure we clean this up when we close. 1921335640Shselasky */ 1922335640Shselasky pb->must_do_on_close |= MUST_DESTROY_USBUS; 1923335640Shselasky 1924335640Shselasky /* 1925335640Shselasky * Add this to the list of pcaps to close when we exit. 1926335640Shselasky */ 1927335640Shselasky pcap_add_to_pcaps_to_close(p); 1928335640Shselasky } 1929335640Shselasky } 1930335640Shselasky#endif /* defined(__FreeBSD__) && defined(SIOCIFCREATE2) */ 1931335640Shselasky 1932335640Shselasky#ifdef HAVE_ZEROCOPY_BPF 1933335640Shselasky /* 1934335640Shselasky * If the BPF extension to set buffer mode is present, try setting 1935335640Shselasky * the mode to zero-copy. If that fails, use regular buffering. If 1936335640Shselasky * it succeeds but other setup fails, return an error to the user. 1937335640Shselasky */ 1938335640Shselasky bufmode = BPF_BUFMODE_ZBUF; 1939335640Shselasky if (ioctl(fd, BIOCSETBUFMODE, (caddr_t)&bufmode) == 0) { 1940335640Shselasky /* 1941335640Shselasky * We have zerocopy BPF; use it. 1942335640Shselasky */ 1943335640Shselasky pb->zerocopy = 1; 1944335640Shselasky 1945335640Shselasky /* 1946335640Shselasky * How to pick a buffer size: first, query the maximum buffer 1947335640Shselasky * size supported by zero-copy. This also lets us quickly 1948335640Shselasky * determine whether the kernel generally supports zero-copy. 1949335640Shselasky * Then, if a buffer size was specified, use that, otherwise 1950335640Shselasky * query the default buffer size, which reflects kernel 1951335640Shselasky * policy for a desired default. Round to the nearest page 1952335640Shselasky * size. 1953335640Shselasky */ 1954335640Shselasky if (ioctl(fd, BIOCGETZMAX, (caddr_t)&zbufmax) < 0) { 1955335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1956335640Shselasky errno, "BIOCGETZMAX"); 1957335640Shselasky status = PCAP_ERROR; 1958335640Shselasky goto bad; 1959335640Shselasky } 1960335640Shselasky 1961335640Shselasky if (p->opt.buffer_size != 0) { 1962335640Shselasky /* 1963335640Shselasky * A buffer size was explicitly specified; use it. 1964335640Shselasky */ 1965335640Shselasky v = p->opt.buffer_size; 1966335640Shselasky } else { 1967335640Shselasky if ((ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) || 1968335640Shselasky v < DEFAULT_BUFSIZE) 1969335640Shselasky v = DEFAULT_BUFSIZE; 1970335640Shselasky } 1971335640Shselasky#ifndef roundup 1972335640Shselasky#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */ 1973335640Shselasky#endif 1974335640Shselasky pb->zbufsize = roundup(v, getpagesize()); 1975335640Shselasky if (pb->zbufsize > zbufmax) 1976335640Shselasky pb->zbufsize = zbufmax; 1977335640Shselasky pb->zbuf1 = mmap(NULL, pb->zbufsize, PROT_READ | PROT_WRITE, 1978335640Shselasky MAP_ANON, -1, 0); 1979335640Shselasky pb->zbuf2 = mmap(NULL, pb->zbufsize, PROT_READ | PROT_WRITE, 1980335640Shselasky MAP_ANON, -1, 0); 1981335640Shselasky if (pb->zbuf1 == MAP_FAILED || pb->zbuf2 == MAP_FAILED) { 1982335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1983335640Shselasky errno, "mmap"); 1984335640Shselasky status = PCAP_ERROR; 1985335640Shselasky goto bad; 1986335640Shselasky } 1987335640Shselasky memset(&bz, 0, sizeof(bz)); /* bzero() deprecated, replaced with memset() */ 1988335640Shselasky bz.bz_bufa = pb->zbuf1; 1989335640Shselasky bz.bz_bufb = pb->zbuf2; 1990335640Shselasky bz.bz_buflen = pb->zbufsize; 1991335640Shselasky if (ioctl(fd, BIOCSETZBUF, (caddr_t)&bz) < 0) { 1992335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1993335640Shselasky errno, "BIOCSETZBUF"); 1994335640Shselasky status = PCAP_ERROR; 1995335640Shselasky goto bad; 1996335640Shselasky } 1997335640Shselasky (void)strncpy(ifrname, p->opt.device, ifnamsiz); 1998335640Shselasky if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) { 1999335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 2000335640Shselasky errno, "BIOCSETIF: %s", p->opt.device); 2001335640Shselasky status = PCAP_ERROR; 2002335640Shselasky goto bad; 2003335640Shselasky } 2004335640Shselasky v = pb->zbufsize - sizeof(struct bpf_zbuf_header); 2005335640Shselasky } else 2006335640Shselasky#endif 2007335640Shselasky { 2008335640Shselasky /* 2009335640Shselasky * We don't have zerocopy BPF. 2010335640Shselasky * Set the buffer size. 2011335640Shselasky */ 2012335640Shselasky if (p->opt.buffer_size != 0) { 2013335640Shselasky /* 2014335640Shselasky * A buffer size was explicitly specified; use it. 2015335640Shselasky */ 2016335640Shselasky if (ioctl(fd, BIOCSBLEN, 2017335640Shselasky (caddr_t)&p->opt.buffer_size) < 0) { 2018335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, 2019335640Shselasky PCAP_ERRBUF_SIZE, errno, 2020335640Shselasky "BIOCSBLEN: %s", p->opt.device); 2021335640Shselasky status = PCAP_ERROR; 2022335640Shselasky goto bad; 2023335640Shselasky } 2024335640Shselasky 2025335640Shselasky /* 2026335640Shselasky * Now bind to the device. 2027335640Shselasky */ 2028335640Shselasky (void)strncpy(ifrname, p->opt.device, ifnamsiz); 2029335640Shselasky#ifdef BIOCSETLIF 2030335640Shselasky if (ioctl(fd, BIOCSETLIF, (caddr_t)&ifr) < 0) 2031335640Shselasky#else 2032335640Shselasky if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) 2033335640Shselasky#endif 2034335640Shselasky { 2035335640Shselasky status = check_setif_failure(p, errno); 2036335640Shselasky goto bad; 2037335640Shselasky } 2038335640Shselasky } else { 2039335640Shselasky /* 2040335640Shselasky * No buffer size was explicitly specified. 2041335640Shselasky * 2042335640Shselasky * Try finding a good size for the buffer; 2043335640Shselasky * DEFAULT_BUFSIZE may be too big, so keep 2044335640Shselasky * cutting it in half until we find a size 2045335640Shselasky * that works, or run out of sizes to try. 2046335640Shselasky * If the default is larger, don't make it smaller. 2047335640Shselasky */ 2048335640Shselasky if ((ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) || 2049335640Shselasky v < DEFAULT_BUFSIZE) 2050335640Shselasky v = DEFAULT_BUFSIZE; 2051335640Shselasky for ( ; v != 0; v >>= 1) { 2052335640Shselasky /* 2053335640Shselasky * Ignore the return value - this is because the 2054335640Shselasky * call fails on BPF systems that don't have 2055335640Shselasky * kernel malloc. And if the call fails, it's 2056335640Shselasky * no big deal, we just continue to use the 2057335640Shselasky * standard buffer size. 2058335640Shselasky */ 2059335640Shselasky (void) ioctl(fd, BIOCSBLEN, (caddr_t)&v); 2060335640Shselasky 2061335640Shselasky (void)strncpy(ifrname, p->opt.device, ifnamsiz); 2062335640Shselasky#ifdef BIOCSETLIF 2063335640Shselasky if (ioctl(fd, BIOCSETLIF, (caddr_t)&ifr) >= 0) 2064335640Shselasky#else 2065335640Shselasky if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0) 2066335640Shselasky#endif 2067335640Shselasky break; /* that size worked; we're done */ 2068335640Shselasky 2069335640Shselasky if (errno != ENOBUFS) { 2070335640Shselasky status = check_setif_failure(p, errno); 2071335640Shselasky goto bad; 2072335640Shselasky } 2073335640Shselasky } 2074335640Shselasky 2075335640Shselasky if (v == 0) { 2076335640Shselasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 2077335640Shselasky "BIOCSBLEN: %s: No buffer size worked", 2078335640Shselasky p->opt.device); 2079335640Shselasky status = PCAP_ERROR; 2080335640Shselasky goto bad; 2081335640Shselasky } 2082335640Shselasky } 2083335640Shselasky } 2084335640Shselasky 2085335640Shselasky /* Get the data link layer type. */ 2086335640Shselasky if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) { 2087335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 2088335640Shselasky errno, "BIOCGDLT"); 2089335640Shselasky status = PCAP_ERROR; 2090335640Shselasky goto bad; 2091335640Shselasky } 2092335640Shselasky 2093335640Shselasky#ifdef _AIX 2094335640Shselasky /* 2095335640Shselasky * AIX's BPF returns IFF_ types, not DLT_ types, in BIOCGDLT. 2096335640Shselasky */ 2097335640Shselasky switch (v) { 2098335640Shselasky 2099335640Shselasky case IFT_ETHER: 2100335640Shselasky case IFT_ISO88023: 2101335640Shselasky v = DLT_EN10MB; 2102335640Shselasky break; 2103335640Shselasky 2104335640Shselasky case IFT_FDDI: 2105335640Shselasky v = DLT_FDDI; 2106335640Shselasky break; 2107335640Shselasky 2108335640Shselasky case IFT_ISO88025: 2109335640Shselasky v = DLT_IEEE802; 2110335640Shselasky break; 2111335640Shselasky 2112335640Shselasky case IFT_LOOP: 2113335640Shselasky v = DLT_NULL; 2114335640Shselasky break; 2115335640Shselasky 2116335640Shselasky default: 2117335640Shselasky /* 2118335640Shselasky * We don't know what to map this to yet. 2119335640Shselasky */ 2120335640Shselasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown interface type %u", 2121335640Shselasky v); 2122335640Shselasky status = PCAP_ERROR; 2123335640Shselasky goto bad; 2124335640Shselasky } 2125335640Shselasky#endif 2126335640Shselasky#if _BSDI_VERSION - 0 >= 199510 2127335640Shselasky /* The SLIP and PPP link layer header changed in BSD/OS 2.1 */ 2128335640Shselasky switch (v) { 2129335640Shselasky 2130335640Shselasky case DLT_SLIP: 2131335640Shselasky v = DLT_SLIP_BSDOS; 2132335640Shselasky break; 2133335640Shselasky 2134335640Shselasky case DLT_PPP: 2135335640Shselasky v = DLT_PPP_BSDOS; 2136335640Shselasky break; 2137335640Shselasky 2138335640Shselasky case 11: /*DLT_FR*/ 2139335640Shselasky v = DLT_FRELAY; 2140335640Shselasky break; 2141335640Shselasky 2142335640Shselasky case 12: /*DLT_C_HDLC*/ 2143335640Shselasky v = DLT_CHDLC; 2144335640Shselasky break; 2145335640Shselasky } 2146335640Shselasky#endif 2147335640Shselasky 2148335640Shselasky#ifdef BIOCGDLTLIST 2149335640Shselasky /* 2150335640Shselasky * We know the default link type -- now determine all the DLTs 2151335640Shselasky * this interface supports. If this fails with EINVAL, it's 2152335640Shselasky * not fatal; we just don't get to use the feature later. 2153335640Shselasky */ 2154335640Shselasky if (get_dlt_list(fd, v, &bdl, p->errbuf) == -1) { 2155335640Shselasky status = PCAP_ERROR; 2156335640Shselasky goto bad; 2157335640Shselasky } 2158335640Shselasky p->dlt_count = bdl.bfl_len; 2159335640Shselasky p->dlt_list = bdl.bfl_list; 2160335640Shselasky 2161335640Shselasky#ifdef __APPLE__ 2162335640Shselasky /* 2163335640Shselasky * Monitor mode fun, continued. 2164335640Shselasky * 2165335640Shselasky * For 10.5 and, we're assuming, later releases, as noted above, 2166335640Shselasky * 802.1 adapters that support monitor mode offer both DLT_EN10MB, 2167335640Shselasky * DLT_IEEE802_11, and possibly some 802.11-plus-radio-information 2168335640Shselasky * DLT_ value. Choosing one of the 802.11 DLT_ values will turn 2169335640Shselasky * monitor mode on. 2170335640Shselasky * 2171335640Shselasky * Therefore, if the user asked for monitor mode, we filter out 2172335640Shselasky * the DLT_EN10MB value, as you can't get that in monitor mode, 2173335640Shselasky * and, if the user didn't ask for monitor mode, we filter out 2174335640Shselasky * the 802.11 DLT_ values, because selecting those will turn 2175335640Shselasky * monitor mode on. Then, for monitor mode, if an 802.11-plus- 2176335640Shselasky * radio DLT_ value is offered, we try to select that, otherwise 2177335640Shselasky * we try to select DLT_IEEE802_11. 2178335640Shselasky */ 2179335640Shselasky if (have_osinfo) { 2180335640Shselasky if (isdigit((unsigned)osinfo.release[0]) && 2181335640Shselasky (osinfo.release[0] == '9' || 2182335640Shselasky isdigit((unsigned)osinfo.release[1]))) { 2183335640Shselasky /* 2184335640Shselasky * 10.5 (Darwin 9.x), or later. 2185335640Shselasky */ 2186335640Shselasky new_dlt = find_802_11(&bdl); 2187335640Shselasky if (new_dlt != -1) { 2188335640Shselasky /* 2189335640Shselasky * We have at least one 802.11 DLT_ value, 2190335640Shselasky * so this is an 802.11 interface. 2191335640Shselasky * new_dlt is the best of the 802.11 2192335640Shselasky * DLT_ values in the list. 2193335640Shselasky */ 2194335640Shselasky if (p->opt.rfmon) { 2195335640Shselasky /* 2196335640Shselasky * Our caller wants monitor mode. 2197335640Shselasky * Purge DLT_EN10MB from the list 2198335640Shselasky * of link-layer types, as selecting 2199335640Shselasky * it will keep monitor mode off. 2200335640Shselasky */ 2201356341Scy remove_non_802_11(p); 2202335640Shselasky 2203335640Shselasky /* 2204335640Shselasky * If the new mode we want isn't 2205335640Shselasky * the default mode, attempt to 2206335640Shselasky * select the new mode. 2207335640Shselasky */ 2208335640Shselasky if ((u_int)new_dlt != v) { 2209335640Shselasky if (ioctl(p->fd, BIOCSDLT, 2210335640Shselasky &new_dlt) != -1) { 2211335640Shselasky /* 2212335640Shselasky * We succeeded; 2213335640Shselasky * make this the 2214335640Shselasky * new DLT_ value. 2215335640Shselasky */ 2216335640Shselasky v = new_dlt; 2217335640Shselasky } 2218335640Shselasky } 2219335640Shselasky } else { 2220335640Shselasky /* 2221335640Shselasky * Our caller doesn't want 2222335640Shselasky * monitor mode. Unless this 2223335640Shselasky * is being done by pcap_open_live(), 2224335640Shselasky * purge the 802.11 link-layer types 2225335640Shselasky * from the list, as selecting 2226335640Shselasky * one of them will turn monitor 2227335640Shselasky * mode on. 2228335640Shselasky */ 2229335640Shselasky if (!p->oldstyle) 2230335640Shselasky remove_802_11(p); 2231335640Shselasky } 2232335640Shselasky } else { 2233335640Shselasky if (p->opt.rfmon) { 2234335640Shselasky /* 2235335640Shselasky * The caller requested monitor 2236335640Shselasky * mode, but we have no 802.11 2237335640Shselasky * link-layer types, so they 2238335640Shselasky * can't have it. 2239335640Shselasky */ 2240335640Shselasky status = PCAP_ERROR_RFMON_NOTSUP; 2241335640Shselasky goto bad; 2242335640Shselasky } 2243335640Shselasky } 2244335640Shselasky } 2245335640Shselasky } 2246335640Shselasky#elif defined(HAVE_BSD_IEEE80211) 2247335640Shselasky /* 2248335640Shselasky * *BSD with the new 802.11 ioctls. 2249335640Shselasky * Do we want monitor mode? 2250335640Shselasky */ 2251335640Shselasky if (p->opt.rfmon) { 2252335640Shselasky /* 2253335640Shselasky * Try to put the interface into monitor mode. 2254335640Shselasky */ 2255335640Shselasky retv = monitor_mode(p, 1); 2256335640Shselasky if (retv != 0) { 2257335640Shselasky /* 2258335640Shselasky * We failed. 2259335640Shselasky */ 2260335640Shselasky status = retv; 2261335640Shselasky goto bad; 2262335640Shselasky } 2263335640Shselasky 2264335640Shselasky /* 2265335640Shselasky * We're in monitor mode. 2266335640Shselasky * Try to find the best 802.11 DLT_ value and, if we 2267335640Shselasky * succeed, try to switch to that mode if we're not 2268335640Shselasky * already in that mode. 2269335640Shselasky */ 2270335640Shselasky new_dlt = find_802_11(&bdl); 2271335640Shselasky if (new_dlt != -1) { 2272335640Shselasky /* 2273335640Shselasky * We have at least one 802.11 DLT_ value. 2274335640Shselasky * new_dlt is the best of the 802.11 2275335640Shselasky * DLT_ values in the list. 2276335640Shselasky * 2277335640Shselasky * If the new mode we want isn't the default mode, 2278335640Shselasky * attempt to select the new mode. 2279335640Shselasky */ 2280335640Shselasky if ((u_int)new_dlt != v) { 2281335640Shselasky if (ioctl(p->fd, BIOCSDLT, &new_dlt) != -1) { 2282335640Shselasky /* 2283335640Shselasky * We succeeded; make this the 2284335640Shselasky * new DLT_ value. 2285335640Shselasky */ 2286335640Shselasky v = new_dlt; 2287335640Shselasky } 2288335640Shselasky } 2289335640Shselasky } 2290335640Shselasky } 2291335640Shselasky#endif /* various platforms */ 2292335640Shselasky#endif /* BIOCGDLTLIST */ 2293335640Shselasky 2294335640Shselasky /* 2295335640Shselasky * If this is an Ethernet device, and we don't have a DLT_ list, 2296335640Shselasky * give it a list with DLT_EN10MB and DLT_DOCSIS. (That'd give 2297335640Shselasky * 802.11 interfaces DLT_DOCSIS, which isn't the right thing to 2298335640Shselasky * do, but there's not much we can do about that without finding 2299335640Shselasky * some other way of determining whether it's an Ethernet or 802.11 2300335640Shselasky * device.) 2301335640Shselasky */ 2302335640Shselasky if (v == DLT_EN10MB && p->dlt_count == 0) { 2303335640Shselasky p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); 2304335640Shselasky /* 2305335640Shselasky * If that fails, just leave the list empty. 2306335640Shselasky */ 2307335640Shselasky if (p->dlt_list != NULL) { 2308335640Shselasky p->dlt_list[0] = DLT_EN10MB; 2309335640Shselasky p->dlt_list[1] = DLT_DOCSIS; 2310335640Shselasky p->dlt_count = 2; 2311335640Shselasky } 2312335640Shselasky } 2313335640Shselasky#ifdef PCAP_FDDIPAD 2314335640Shselasky if (v == DLT_FDDI) 2315335640Shselasky p->fddipad = PCAP_FDDIPAD; 2316335640Shselasky else 2317335640Shselasky#endif 2318335640Shselasky p->fddipad = 0; 2319335640Shselasky p->linktype = v; 2320335640Shselasky 2321335640Shselasky#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) 2322335640Shselasky /* 2323335640Shselasky * Do a BIOCSHDRCMPLT, if defined, to turn that flag on, so 2324335640Shselasky * the link-layer source address isn't forcibly overwritten. 2325335640Shselasky * (Should we ignore errors? Should we do this only if 2326335640Shselasky * we're open for writing?) 2327335640Shselasky * 2328335640Shselasky * XXX - I seem to remember some packet-sending bug in some 2329335640Shselasky * BSDs - check CVS log for "bpf.c"? 2330335640Shselasky */ 2331335640Shselasky if (ioctl(fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) { 2332335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 2333335640Shselasky errno, "BIOCSHDRCMPLT"); 2334335640Shselasky status = PCAP_ERROR; 2335335640Shselasky goto bad; 2336335640Shselasky } 2337335640Shselasky#endif 2338335640Shselasky /* set timeout */ 2339335640Shselasky#ifdef HAVE_ZEROCOPY_BPF 2340335640Shselasky /* 2341335640Shselasky * In zero-copy mode, we just use the timeout in select(). 2342335640Shselasky * XXX - what if we're in non-blocking mode and the *application* 2343335640Shselasky * is using select() or poll() or kqueues or....? 2344335640Shselasky */ 2345335640Shselasky if (p->opt.timeout && !pb->zerocopy) { 2346335640Shselasky#else 2347335640Shselasky if (p->opt.timeout) { 2348335640Shselasky#endif 2349335640Shselasky /* 2350335640Shselasky * XXX - is this seconds/nanoseconds in AIX? 2351335640Shselasky * (Treating it as such doesn't fix the timeout 2352335640Shselasky * problem described below.) 2353335640Shselasky * 2354335640Shselasky * XXX - Mac OS X 10.6 mishandles BIOCSRTIMEOUT in 2355335640Shselasky * 64-bit userland - it takes, as an argument, a 2356335640Shselasky * "struct BPF_TIMEVAL", which has 32-bit tv_sec 2357335640Shselasky * and tv_usec, rather than a "struct timeval". 2358335640Shselasky * 2359335640Shselasky * If this platform defines "struct BPF_TIMEVAL", 2360335640Shselasky * we check whether the structure size in BIOCSRTIMEOUT 2361335640Shselasky * is that of a "struct timeval" and, if not, we use 2362335640Shselasky * a "struct BPF_TIMEVAL" rather than a "struct timeval". 2363335640Shselasky * (That way, if the bug is fixed in a future release, 2364335640Shselasky * we will still do the right thing.) 2365335640Shselasky */ 2366335640Shselasky struct timeval to; 2367335640Shselasky#ifdef HAVE_STRUCT_BPF_TIMEVAL 2368335640Shselasky struct BPF_TIMEVAL bpf_to; 2369335640Shselasky 2370335640Shselasky if (IOCPARM_LEN(BIOCSRTIMEOUT) != sizeof(struct timeval)) { 2371335640Shselasky bpf_to.tv_sec = p->opt.timeout / 1000; 2372335640Shselasky bpf_to.tv_usec = (p->opt.timeout * 1000) % 1000000; 2373335640Shselasky if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&bpf_to) < 0) { 2374335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, 2375335640Shselasky errno, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT"); 2376335640Shselasky status = PCAP_ERROR; 2377335640Shselasky goto bad; 2378335640Shselasky } 2379335640Shselasky } else { 2380335640Shselasky#endif 2381335640Shselasky to.tv_sec = p->opt.timeout / 1000; 2382335640Shselasky to.tv_usec = (p->opt.timeout * 1000) % 1000000; 2383335640Shselasky if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) { 2384335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, 2385335640Shselasky errno, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT"); 2386335640Shselasky status = PCAP_ERROR; 2387335640Shselasky goto bad; 2388335640Shselasky } 2389335640Shselasky#ifdef HAVE_STRUCT_BPF_TIMEVAL 2390335640Shselasky } 2391335640Shselasky#endif 2392335640Shselasky } 2393335640Shselasky 2394335640Shselasky#ifdef BIOCIMMEDIATE 2395335640Shselasky /* 2396335640Shselasky * Darren Reed notes that 2397335640Shselasky * 2398335640Shselasky * On AIX (4.2 at least), if BIOCIMMEDIATE is not set, the 2399335640Shselasky * timeout appears to be ignored and it waits until the buffer 2400335640Shselasky * is filled before returning. The result of not having it 2401335640Shselasky * set is almost worse than useless if your BPF filter 2402335640Shselasky * is reducing things to only a few packets (i.e. one every 2403335640Shselasky * second or so). 2404335640Shselasky * 2405335640Shselasky * so we always turn BIOCIMMEDIATE mode on if this is AIX. 2406335640Shselasky * 2407335640Shselasky * For other platforms, we don't turn immediate mode on by default, 2408335640Shselasky * as that would mean we get woken up for every packet, which 2409335640Shselasky * probably isn't what you want for a packet sniffer. 2410335640Shselasky * 2411335640Shselasky * We set immediate mode if the caller requested it by calling 2412335640Shselasky * pcap_set_immediate() before calling pcap_activate(). 2413335640Shselasky */ 2414335640Shselasky#ifndef _AIX 2415335640Shselasky if (p->opt.immediate) { 2416335640Shselasky#endif /* _AIX */ 2417335640Shselasky v = 1; 2418335640Shselasky if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) { 2419335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 2420335640Shselasky errno, "BIOCIMMEDIATE"); 2421335640Shselasky status = PCAP_ERROR; 2422335640Shselasky goto bad; 2423335640Shselasky } 2424335640Shselasky#ifndef _AIX 2425335640Shselasky } 2426335640Shselasky#endif /* _AIX */ 2427335640Shselasky#else /* BIOCIMMEDIATE */ 2428335640Shselasky if (p->opt.immediate) { 2429335640Shselasky /* 2430335640Shselasky * We don't support immediate mode. Fail. 2431335640Shselasky */ 2432335640Shselasky pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Immediate mode not supported"); 2433335640Shselasky status = PCAP_ERROR; 2434335640Shselasky goto bad; 2435335640Shselasky } 2436335640Shselasky#endif /* BIOCIMMEDIATE */ 2437335640Shselasky 2438335640Shselasky if (p->opt.promisc) { 2439335640Shselasky /* set promiscuous mode, just warn if it fails */ 2440335640Shselasky if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) { 2441335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 2442335640Shselasky errno, "BIOCPROMISC"); 2443335640Shselasky status = PCAP_WARNING_PROMISC_NOTSUP; 2444335640Shselasky } 2445335640Shselasky } 2446335640Shselasky 2447335640Shselasky#ifdef BIOCSTSTAMP 2448335640Shselasky v = BPF_T_BINTIME; 2449335640Shselasky if (ioctl(p->fd, BIOCSTSTAMP, &v) < 0) { 2450335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 2451335640Shselasky errno, "BIOCSTSTAMP"); 2452335640Shselasky status = PCAP_ERROR; 2453335640Shselasky goto bad; 2454335640Shselasky } 2455335640Shselasky#endif /* BIOCSTSTAMP */ 2456335640Shselasky 2457335640Shselasky if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) { 2458335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 2459335640Shselasky errno, "BIOCGBLEN"); 2460335640Shselasky status = PCAP_ERROR; 2461335640Shselasky goto bad; 2462335640Shselasky } 2463335640Shselasky p->bufsize = v; 2464335640Shselasky#ifdef HAVE_ZEROCOPY_BPF 2465335640Shselasky if (!pb->zerocopy) { 2466335640Shselasky#endif 2467335640Shselasky p->buffer = malloc(p->bufsize); 2468335640Shselasky if (p->buffer == NULL) { 2469335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 2470335640Shselasky errno, "malloc"); 2471335640Shselasky status = PCAP_ERROR; 2472335640Shselasky goto bad; 2473335640Shselasky } 2474335640Shselasky#ifdef _AIX 2475335640Shselasky /* For some strange reason this seems to prevent the EFAULT 2476335640Shselasky * problems we have experienced from AIX BPF. */ 2477335640Shselasky memset(p->buffer, 0x0, p->bufsize); 2478335640Shselasky#endif 2479335640Shselasky#ifdef HAVE_ZEROCOPY_BPF 2480335640Shselasky } 2481335640Shselasky#endif 2482335640Shselasky 2483335640Shselasky /* 2484335640Shselasky * If there's no filter program installed, there's 2485335640Shselasky * no indication to the kernel of what the snapshot 2486335640Shselasky * length should be, so no snapshotting is done. 2487335640Shselasky * 2488335640Shselasky * Therefore, when we open the device, we install 2489335640Shselasky * an "accept everything" filter with the specified 2490335640Shselasky * snapshot length. 2491335640Shselasky */ 2492335640Shselasky total_insn.code = (u_short)(BPF_RET | BPF_K); 2493335640Shselasky total_insn.jt = 0; 2494335640Shselasky total_insn.jf = 0; 2495335640Shselasky total_insn.k = p->snapshot; 2496335640Shselasky 2497335640Shselasky total_prog.bf_len = 1; 2498335640Shselasky total_prog.bf_insns = &total_insn; 2499335640Shselasky if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) { 2500335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 2501335640Shselasky errno, "BIOCSETF"); 2502335640Shselasky status = PCAP_ERROR; 2503335640Shselasky goto bad; 2504335640Shselasky } 2505335640Shselasky 2506335640Shselasky /* 2507335640Shselasky * On most BPF platforms, either you can do a "select()" or 2508335640Shselasky * "poll()" on a BPF file descriptor and it works correctly, 2509335640Shselasky * or you can do it and it will return "readable" if the 2510335640Shselasky * hold buffer is full but not if the timeout expires *and* 2511335640Shselasky * a non-blocking read will, if the hold buffer is empty 2512335640Shselasky * but the store buffer isn't empty, rotate the buffers 2513335640Shselasky * and return what packets are available. 2514335640Shselasky * 2515335640Shselasky * In the latter case, the fact that a non-blocking read 2516335640Shselasky * will give you the available packets means you can work 2517335640Shselasky * around the failure of "select()" and "poll()" to wake up 2518335640Shselasky * and return "readable" when the timeout expires by using 2519335640Shselasky * the timeout as the "select()" or "poll()" timeout, putting 2520335640Shselasky * the BPF descriptor into non-blocking mode, and read from 2521335640Shselasky * it regardless of whether "select()" reports it as readable 2522335640Shselasky * or not. 2523335640Shselasky * 2524335640Shselasky * However, in FreeBSD 4.3 and 4.4, "select()" and "poll()" 2525335640Shselasky * won't wake up and return "readable" if the timer expires 2526335640Shselasky * and non-blocking reads return EWOULDBLOCK if the hold 2527335640Shselasky * buffer is empty, even if the store buffer is non-empty. 2528335640Shselasky * 2529335640Shselasky * This means the workaround in question won't work. 2530335640Shselasky * 2531335640Shselasky * Therefore, on FreeBSD 4.3 and 4.4, we set "p->selectable_fd" 2532335640Shselasky * to -1, which means "sorry, you can't use 'select()' or 'poll()' 2533335640Shselasky * here". On all other BPF platforms, we set it to the FD for 2534335640Shselasky * the BPF device; in NetBSD, OpenBSD, and Darwin, a non-blocking 2535335640Shselasky * read will, if the hold buffer is empty and the store buffer 2536335640Shselasky * isn't empty, rotate the buffers and return what packets are 2537335640Shselasky * there (and in sufficiently recent versions of OpenBSD 2538335640Shselasky * "select()" and "poll()" should work correctly). 2539335640Shselasky * 2540335640Shselasky * XXX - what about AIX? 2541335640Shselasky */ 2542335640Shselasky p->selectable_fd = p->fd; /* assume select() works until we know otherwise */ 2543335640Shselasky if (have_osinfo) { 2544335640Shselasky /* 2545335640Shselasky * We can check what OS this is. 2546335640Shselasky */ 2547335640Shselasky if (strcmp(osinfo.sysname, "FreeBSD") == 0) { 2548335640Shselasky if (strncmp(osinfo.release, "4.3-", 4) == 0 || 2549335640Shselasky strncmp(osinfo.release, "4.4-", 4) == 0) 2550335640Shselasky p->selectable_fd = -1; 2551335640Shselasky } 2552335640Shselasky } 2553335640Shselasky 2554335640Shselasky p->read_op = pcap_read_bpf; 2555335640Shselasky p->inject_op = pcap_inject_bpf; 2556335640Shselasky p->setfilter_op = pcap_setfilter_bpf; 2557335640Shselasky p->setdirection_op = pcap_setdirection_bpf; 2558335640Shselasky p->set_datalink_op = pcap_set_datalink_bpf; 2559335640Shselasky p->getnonblock_op = pcap_getnonblock_bpf; 2560335640Shselasky p->setnonblock_op = pcap_setnonblock_bpf; 2561335640Shselasky p->stats_op = pcap_stats_bpf; 2562335640Shselasky p->cleanup_op = pcap_cleanup_bpf; 2563335640Shselasky 2564335640Shselasky return (status); 2565335640Shselasky bad: 2566335640Shselasky pcap_cleanup_bpf(p); 2567335640Shselasky return (status); 2568335640Shselasky} 2569335640Shselasky 2570335640Shselasky/* 2571335640Shselasky * Not all interfaces can be bound to by BPF, so try to bind to 2572335640Shselasky * the specified interface; return 0 if we fail with 2573335640Shselasky * PCAP_ERROR_NO_SUCH_DEVICE (which means we got an ENXIO when we tried 2574335640Shselasky * to bind, which means this interface isn't in the list of interfaces 2575335640Shselasky * attached to BPF) and 1 otherwise. 2576335640Shselasky */ 2577335640Shselaskystatic int 2578335640Shselaskycheck_bpf_bindable(const char *name) 2579335640Shselasky{ 2580335640Shselasky int fd; 2581335640Shselasky char errbuf[PCAP_ERRBUF_SIZE]; 2582335640Shselasky 2583335640Shselasky /* 2584335640Shselasky * On macOS, we don't do this check if the device name begins 2585335640Shselasky * with "wlt"; at least some versions of macOS (actually, it 2586335640Shselasky * was called "Mac OS X" then...) offer monitor mode capturing 2587335640Shselasky * by having a separate "monitor mode" device for each wireless 2588335640Shselasky * adapter, rather than by implementing the ioctls that 2589335640Shselasky * {Free,Net,Open,DragonFly}BSD provide. Opening that device 2590335640Shselasky * puts the adapter into monitor mode, which, at least for 2591335640Shselasky * some adapters, causes them to deassociate from the network 2592335640Shselasky * with which they're associated. 2593335640Shselasky * 2594335640Shselasky * Instead, we try to open the corresponding "en" device (so 2595335640Shselasky * that we don't end up with, for users without sufficient 2596335640Shselasky * privilege to open capture devices, a list of adapters that 2597335640Shselasky * only includes the wlt devices). 2598335640Shselasky */ 2599335640Shselasky#ifdef __APPLE__ 2600335640Shselasky if (strncmp(name, "wlt", 3) == 0) { 2601335640Shselasky char *en_name; 2602335640Shselasky size_t en_name_len; 2603335640Shselasky 2604335640Shselasky /* 2605335640Shselasky * Try to allocate a buffer for the "en" 2606335640Shselasky * device's name. 2607335640Shselasky */ 2608335640Shselasky en_name_len = strlen(name) - 1; 2609335640Shselasky en_name = malloc(en_name_len + 1); 2610335640Shselasky if (en_name == NULL) { 2611335640Shselasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, 2612335640Shselasky errno, "malloc"); 2613335640Shselasky return (-1); 2614335640Shselasky } 2615335640Shselasky strcpy(en_name, "en"); 2616335640Shselasky strcat(en_name, name + 3); 2617335640Shselasky fd = bpf_open_and_bind(en_name, errbuf); 2618335640Shselasky free(en_name); 2619335640Shselasky } else 2620335640Shselasky#endif /* __APPLE */ 2621335640Shselasky fd = bpf_open_and_bind(name, errbuf); 2622335640Shselasky if (fd < 0) { 2623335640Shselasky /* 2624335640Shselasky * Error - was it PCAP_ERROR_NO_SUCH_DEVICE? 2625335640Shselasky */ 2626335640Shselasky if (fd == PCAP_ERROR_NO_SUCH_DEVICE) { 2627335640Shselasky /* 2628335640Shselasky * Yes, so we can't bind to this because it's 2629335640Shselasky * not something supported by BPF. 2630335640Shselasky */ 2631335640Shselasky return (0); 2632335640Shselasky } 2633335640Shselasky /* 2634335640Shselasky * No, so we don't know whether it's supported or not; 2635335640Shselasky * say it is, so that the user can at least try to 2636335640Shselasky * open it and report the error (which is probably 2637335640Shselasky * "you don't have permission to open BPF devices"; 2638335640Shselasky * reporting those interfaces means users will ask 2639335640Shselasky * "why am I getting a permissions error when I try 2640335640Shselasky * to capture" rather than "why am I not seeing any 2641335640Shselasky * interfaces", making the underlying problem clearer). 2642335640Shselasky */ 2643335640Shselasky return (1); 2644335640Shselasky } 2645335640Shselasky 2646335640Shselasky /* 2647335640Shselasky * Success. 2648335640Shselasky */ 2649335640Shselasky close(fd); 2650335640Shselasky return (1); 2651335640Shselasky} 2652335640Shselasky 2653335640Shselasky#if defined(__FreeBSD__) && defined(SIOCIFCREATE2) 2654335640Shselaskystatic int 2655335640Shselaskyget_usb_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_) 2656335640Shselasky{ 2657335640Shselasky /* 2658335640Shselasky * XXX - if there's a way to determine whether there's something 2659335640Shselasky * plugged into a given USB bus, use that to determine whether 2660335640Shselasky * this device is "connected" or not. 2661335640Shselasky */ 2662335640Shselasky return (0); 2663335640Shselasky} 2664335640Shselasky 2665335640Shselaskystatic int 2666335640Shselaskyfinddevs_usb(pcap_if_list_t *devlistp, char *errbuf) 2667335640Shselasky{ 2668335640Shselasky DIR *usbdir; 2669335640Shselasky struct dirent *usbitem; 2670335640Shselasky size_t name_max; 2671335640Shselasky char *name; 2672335640Shselasky 2673335640Shselasky /* 2674335640Shselasky * We might have USB sniffing support, so try looking for USB 2675335640Shselasky * interfaces. 2676335640Shselasky * 2677335640Shselasky * We want to report a usbusN device for each USB bus, but 2678335640Shselasky * usbusN interfaces might, or might not, exist for them - 2679335640Shselasky * we create one if there isn't already one. 2680335640Shselasky * 2681335640Shselasky * So, instead, we look in /dev/usb for all buses and create 2682335640Shselasky * a "usbusN" device for each one. 2683335640Shselasky */ 2684335640Shselasky usbdir = opendir("/dev/usb"); 2685335640Shselasky if (usbdir == NULL) { 2686335640Shselasky /* 2687335640Shselasky * Just punt. 2688335640Shselasky */ 2689335640Shselasky return (0); 2690335640Shselasky } 2691335640Shselasky 2692335640Shselasky /* 2693335640Shselasky * Leave enough room for a 32-bit (10-digit) bus number. 2694335640Shselasky * Yes, that's overkill, but we won't be using 2695335640Shselasky * the buffer very long. 2696335640Shselasky */ 2697335640Shselasky name_max = USBUS_PREFIX_LEN + 10 + 1; 2698335640Shselasky name = malloc(name_max); 2699335640Shselasky if (name == NULL) { 2700335640Shselasky closedir(usbdir); 2701335640Shselasky return (0); 2702335640Shselasky } 2703335640Shselasky while ((usbitem = readdir(usbdir)) != NULL) { 2704335640Shselasky char *p; 2705335640Shselasky size_t busnumlen; 2706335640Shselasky 2707335640Shselasky if (strcmp(usbitem->d_name, ".") == 0 || 2708335640Shselasky strcmp(usbitem->d_name, "..") == 0) { 2709335640Shselasky /* 2710335640Shselasky * Ignore these. 2711335640Shselasky */ 2712335640Shselasky continue; 2713335640Shselasky } 2714335640Shselasky p = strchr(usbitem->d_name, '.'); 2715335640Shselasky if (p == NULL) 2716335640Shselasky continue; 2717335640Shselasky busnumlen = p - usbitem->d_name; 2718335640Shselasky memcpy(name, usbus_prefix, USBUS_PREFIX_LEN); 2719335640Shselasky memcpy(name + USBUS_PREFIX_LEN, usbitem->d_name, busnumlen); 2720335640Shselasky *(name + USBUS_PREFIX_LEN + busnumlen) = '\0'; 2721335640Shselasky /* 2722335640Shselasky * There's an entry in this directory for every USB device, 2723335640Shselasky * not for every bus; if there's more than one device on 2724335640Shselasky * the bus, there'll be more than one entry for that bus, 2725335640Shselasky * so we need to avoid adding multiple capture devices 2726335640Shselasky * for each bus. 2727335640Shselasky */ 2728335640Shselasky if (find_or_add_dev(devlistp, name, PCAP_IF_UP, 2729335640Shselasky get_usb_if_flags, NULL, errbuf) == NULL) { 2730335640Shselasky free(name); 2731335640Shselasky closedir(usbdir); 2732335640Shselasky return (PCAP_ERROR); 2733335640Shselasky } 2734335640Shselasky } 2735335640Shselasky free(name); 2736335640Shselasky closedir(usbdir); 2737335640Shselasky return (0); 2738335640Shselasky} 2739335640Shselasky#endif 2740335640Shselasky 2741335640Shselasky/* 2742335640Shselasky * Get additional flags for a device, using SIOCGIFMEDIA. 2743335640Shselasky */ 2744335640Shselasky#ifdef SIOCGIFMEDIA 2745335640Shselaskystatic int 2746335640Shselaskyget_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf) 2747335640Shselasky{ 2748335640Shselasky int sock; 2749335640Shselasky struct ifmediareq req; 2750335640Shselasky 2751335640Shselasky sock = socket(AF_INET, SOCK_DGRAM, 0); 2752335640Shselasky if (sock == -1) { 2753335640Shselasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, errno, 2754335640Shselasky "Can't create socket to get media information for %s", 2755335640Shselasky name); 2756335640Shselasky return (-1); 2757335640Shselasky } 2758335640Shselasky memset(&req, 0, sizeof(req)); 2759335640Shselasky strncpy(req.ifm_name, name, sizeof(req.ifm_name)); 2760335640Shselasky if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) { 2761335640Shselasky if (errno == EOPNOTSUPP || errno == EINVAL || errno == ENOTTY || 2762356341Scy errno == ENODEV || errno == EPERM) { 2763335640Shselasky /* 2764335640Shselasky * Not supported, so we can't provide any 2765335640Shselasky * additional information. Assume that 2766335640Shselasky * this means that "connected" vs. 2767335640Shselasky * "disconnected" doesn't apply. 2768356341Scy * 2769356341Scy * The ioctl routine for Apple's pktap devices, 2770356341Scy * annoyingly, checks for "are you root?" before 2771356341Scy * checking whether the ioctl is valid, so it 2772356341Scy * returns EPERM, rather than ENOTSUP, for the 2773356341Scy * invalid SIOCGIFMEDIA, unless you're root. 2774356341Scy * So, just as we do for some ethtool ioctls 2775356341Scy * on Linux, which makes the same mistake, we 2776356341Scy * also treat EPERM as meaning "not supported". 2777335640Shselasky */ 2778335640Shselasky *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE; 2779335640Shselasky close(sock); 2780335640Shselasky return (0); 2781335640Shselasky } 2782335640Shselasky pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, errno, 2783335640Shselasky "SIOCGIFMEDIA on %s failed", name); 2784335640Shselasky close(sock); 2785335640Shselasky return (-1); 2786335640Shselasky } 2787335640Shselasky close(sock); 2788335640Shselasky 2789335640Shselasky /* 2790335640Shselasky * OK, what type of network is this? 2791335640Shselasky */ 2792335640Shselasky switch (IFM_TYPE(req.ifm_active)) { 2793335640Shselasky 2794335640Shselasky case IFM_IEEE80211: 2795335640Shselasky /* 2796335640Shselasky * Wireless. 2797335640Shselasky */ 2798335640Shselasky *flags |= PCAP_IF_WIRELESS; 2799335640Shselasky break; 2800335640Shselasky } 2801335640Shselasky 2802335640Shselasky /* 2803335640Shselasky * Do we know whether it's connected? 2804335640Shselasky */ 2805335640Shselasky if (req.ifm_status & IFM_AVALID) { 2806335640Shselasky /* 2807335640Shselasky * Yes. 2808335640Shselasky */ 2809335640Shselasky if (req.ifm_status & IFM_ACTIVE) { 2810335640Shselasky /* 2811335640Shselasky * It's connected. 2812335640Shselasky */ 2813335640Shselasky *flags |= PCAP_IF_CONNECTION_STATUS_CONNECTED; 2814335640Shselasky } else { 2815335640Shselasky /* 2816335640Shselasky * It's disconnected. 2817335640Shselasky */ 2818335640Shselasky *flags |= PCAP_IF_CONNECTION_STATUS_DISCONNECTED; 2819335640Shselasky } 2820335640Shselasky } 2821335640Shselasky return (0); 2822335640Shselasky} 2823335640Shselasky#else 2824335640Shselaskystatic int 2825335640Shselaskyget_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_) 2826335640Shselasky{ 2827335640Shselasky /* 2828335640Shselasky * Nothing we can do other than mark loopback devices as "the 2829335640Shselasky * connected/disconnected status doesn't apply". 2830335640Shselasky * 2831335640Shselasky * XXX - on Solaris, can we do what the dladm command does, 2832335640Shselasky * i.e. get a connected/disconnected indication from a kstat? 2833335640Shselasky * (Note that you can also get the link speed, and possibly 2834335640Shselasky * other information, from a kstat as well.) 2835335640Shselasky */ 2836335640Shselasky if (*flags & PCAP_IF_LOOPBACK) { 2837335640Shselasky /* 2838335640Shselasky * Loopback devices aren't wireless, and "connected"/ 2839335640Shselasky * "disconnected" doesn't apply to them. 2840335640Shselasky */ 2841335640Shselasky *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE; 2842335640Shselasky return (0); 2843335640Shselasky } 2844335640Shselasky return (0); 2845335640Shselasky} 2846335640Shselasky#endif 2847335640Shselasky 2848335640Shselaskyint 2849335640Shselaskypcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf) 2850335640Shselasky{ 2851335640Shselasky /* 2852335640Shselasky * Get the list of regular interfaces first. 2853335640Shselasky */ 2854335640Shselasky if (pcap_findalldevs_interfaces(devlistp, errbuf, check_bpf_bindable, 2855335640Shselasky get_if_flags) == -1) 2856335640Shselasky return (-1); /* failure */ 2857335640Shselasky 2858335640Shselasky#if defined(__FreeBSD__) && defined(SIOCIFCREATE2) 2859335640Shselasky if (finddevs_usb(devlistp, errbuf) == -1) 2860335640Shselasky return (-1); 2861335640Shselasky#endif 2862335640Shselasky 2863335640Shselasky return (0); 2864335640Shselasky} 2865335640Shselasky 2866335640Shselasky#ifdef HAVE_BSD_IEEE80211 2867335640Shselaskystatic int 2868335640Shselaskymonitor_mode(pcap_t *p, int set) 2869335640Shselasky{ 2870335640Shselasky struct pcap_bpf *pb = p->priv; 2871335640Shselasky int sock; 2872335640Shselasky struct ifmediareq req; 2873335640Shselasky IFM_ULIST_TYPE *media_list; 2874335640Shselasky int i; 2875335640Shselasky int can_do; 2876335640Shselasky struct ifreq ifr; 2877335640Shselasky 2878335640Shselasky sock = socket(AF_INET, SOCK_DGRAM, 0); 2879335640Shselasky if (sock == -1) { 2880335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 2881335640Shselasky errno, "can't open socket"); 2882335640Shselasky return (PCAP_ERROR); 2883335640Shselasky } 2884335640Shselasky 2885335640Shselasky memset(&req, 0, sizeof req); 2886335640Shselasky strncpy(req.ifm_name, p->opt.device, sizeof req.ifm_name); 2887335640Shselasky 2888335640Shselasky /* 2889335640Shselasky * Find out how many media types we have. 2890335640Shselasky */ 2891335640Shselasky if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) { 2892335640Shselasky /* 2893335640Shselasky * Can't get the media types. 2894335640Shselasky */ 2895335640Shselasky switch (errno) { 2896335640Shselasky 2897335640Shselasky case ENXIO: 2898335640Shselasky /* 2899335640Shselasky * There's no such device. 2900335640Shselasky */ 2901335640Shselasky close(sock); 2902335640Shselasky return (PCAP_ERROR_NO_SUCH_DEVICE); 2903335640Shselasky 2904335640Shselasky case EINVAL: 2905335640Shselasky /* 2906335640Shselasky * Interface doesn't support SIOC{G,S}IFMEDIA. 2907335640Shselasky */ 2908335640Shselasky close(sock); 2909335640Shselasky return (PCAP_ERROR_RFMON_NOTSUP); 2910335640Shselasky 2911335640Shselasky default: 2912335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 2913356341Scy errno, "SIOCGIFMEDIA"); 2914335640Shselasky close(sock); 2915335640Shselasky return (PCAP_ERROR); 2916335640Shselasky } 2917335640Shselasky } 2918335640Shselasky if (req.ifm_count == 0) { 2919335640Shselasky /* 2920335640Shselasky * No media types. 2921335640Shselasky */ 2922335640Shselasky close(sock); 2923335640Shselasky return (PCAP_ERROR_RFMON_NOTSUP); 2924335640Shselasky } 2925335640Shselasky 2926335640Shselasky /* 2927335640Shselasky * Allocate a buffer to hold all the media types, and 2928335640Shselasky * get the media types. 2929335640Shselasky */ 2930335640Shselasky media_list = malloc(req.ifm_count * sizeof(*media_list)); 2931335640Shselasky if (media_list == NULL) { 2932335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 2933335640Shselasky errno, "malloc"); 2934335640Shselasky close(sock); 2935335640Shselasky return (PCAP_ERROR); 2936335640Shselasky } 2937335640Shselasky req.ifm_ulist = media_list; 2938335640Shselasky if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) { 2939335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 2940335640Shselasky errno, "SIOCGIFMEDIA"); 2941335640Shselasky free(media_list); 2942335640Shselasky close(sock); 2943335640Shselasky return (PCAP_ERROR); 2944335640Shselasky } 2945335640Shselasky 2946335640Shselasky /* 2947335640Shselasky * Look for an 802.11 "automatic" media type. 2948335640Shselasky * We assume that all 802.11 adapters have that media type, 2949335640Shselasky * and that it will carry the monitor mode supported flag. 2950335640Shselasky */ 2951335640Shselasky can_do = 0; 2952335640Shselasky for (i = 0; i < req.ifm_count; i++) { 2953335640Shselasky if (IFM_TYPE(media_list[i]) == IFM_IEEE80211 2954335640Shselasky && IFM_SUBTYPE(media_list[i]) == IFM_AUTO) { 2955335640Shselasky /* OK, does it do monitor mode? */ 2956335640Shselasky if (media_list[i] & IFM_IEEE80211_MONITOR) { 2957335640Shselasky can_do = 1; 2958335640Shselasky break; 2959335640Shselasky } 2960335640Shselasky } 2961335640Shselasky } 2962335640Shselasky free(media_list); 2963335640Shselasky if (!can_do) { 2964335640Shselasky /* 2965335640Shselasky * This adapter doesn't support monitor mode. 2966335640Shselasky */ 2967335640Shselasky close(sock); 2968335640Shselasky return (PCAP_ERROR_RFMON_NOTSUP); 2969335640Shselasky } 2970335640Shselasky 2971335640Shselasky if (set) { 2972335640Shselasky /* 2973335640Shselasky * Don't just check whether we can enable monitor mode, 2974335640Shselasky * do so, if it's not already enabled. 2975335640Shselasky */ 2976335640Shselasky if ((req.ifm_current & IFM_IEEE80211_MONITOR) == 0) { 2977335640Shselasky /* 2978335640Shselasky * Monitor mode isn't currently on, so turn it on, 2979335640Shselasky * and remember that we should turn it off when the 2980335640Shselasky * pcap_t is closed. 2981335640Shselasky */ 2982335640Shselasky 2983335640Shselasky /* 2984335640Shselasky * If we haven't already done so, arrange to have 2985335640Shselasky * "pcap_close_all()" called when we exit. 2986335640Shselasky */ 2987335640Shselasky if (!pcap_do_addexit(p)) { 2988335640Shselasky /* 2989335640Shselasky * "atexit()" failed; don't put the interface 2990335640Shselasky * in monitor mode, just give up. 2991335640Shselasky */ 2992335640Shselasky close(sock); 2993335640Shselasky return (PCAP_ERROR); 2994335640Shselasky } 2995335640Shselasky memset(&ifr, 0, sizeof(ifr)); 2996335640Shselasky (void)strncpy(ifr.ifr_name, p->opt.device, 2997335640Shselasky sizeof(ifr.ifr_name)); 2998335640Shselasky ifr.ifr_media = req.ifm_current | IFM_IEEE80211_MONITOR; 2999335640Shselasky if (ioctl(sock, SIOCSIFMEDIA, &ifr) == -1) { 3000335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, 3001335640Shselasky PCAP_ERRBUF_SIZE, errno, "SIOCSIFMEDIA"); 3002335640Shselasky close(sock); 3003335640Shselasky return (PCAP_ERROR); 3004335640Shselasky } 3005335640Shselasky 3006335640Shselasky pb->must_do_on_close |= MUST_CLEAR_RFMON; 3007335640Shselasky 3008335640Shselasky /* 3009335640Shselasky * Add this to the list of pcaps to close when we exit. 3010335640Shselasky */ 3011335640Shselasky pcap_add_to_pcaps_to_close(p); 3012335640Shselasky } 3013335640Shselasky } 3014335640Shselasky return (0); 3015335640Shselasky} 3016335640Shselasky#endif /* HAVE_BSD_IEEE80211 */ 3017335640Shselasky 3018335640Shselasky#if defined(BIOCGDLTLIST) && (defined(__APPLE__) || defined(HAVE_BSD_IEEE80211)) 3019335640Shselasky/* 3020335640Shselasky * Check whether we have any 802.11 link-layer types; return the best 3021335640Shselasky * of the 802.11 link-layer types if we find one, and return -1 3022335640Shselasky * otherwise. 3023335640Shselasky * 3024335640Shselasky * DLT_IEEE802_11_RADIO, with the radiotap header, is considered the 3025335640Shselasky * best 802.11 link-layer type; any of the other 802.11-plus-radio 3026335640Shselasky * headers are second-best; 802.11 with no radio information is 3027335640Shselasky * the least good. 3028335640Shselasky */ 3029335640Shselaskystatic int 3030335640Shselaskyfind_802_11(struct bpf_dltlist *bdlp) 3031335640Shselasky{ 3032335640Shselasky int new_dlt; 3033335640Shselasky u_int i; 3034335640Shselasky 3035335640Shselasky /* 3036335640Shselasky * Scan the list of DLT_ values, looking for 802.11 values, 3037335640Shselasky * and, if we find any, choose the best of them. 3038335640Shselasky */ 3039335640Shselasky new_dlt = -1; 3040335640Shselasky for (i = 0; i < bdlp->bfl_len; i++) { 3041335640Shselasky switch (bdlp->bfl_list[i]) { 3042335640Shselasky 3043335640Shselasky case DLT_IEEE802_11: 3044335640Shselasky /* 3045335640Shselasky * 802.11, but no radio. 3046335640Shselasky * 3047335640Shselasky * Offer this, and select it as the new mode 3048335640Shselasky * unless we've already found an 802.11 3049335640Shselasky * header with radio information. 3050335640Shselasky */ 3051335640Shselasky if (new_dlt == -1) 3052335640Shselasky new_dlt = bdlp->bfl_list[i]; 3053335640Shselasky break; 3054335640Shselasky 3055356341Scy#ifdef DLT_PRISM_HEADER 3056335640Shselasky case DLT_PRISM_HEADER: 3057356341Scy#endif 3058356341Scy#ifdef DLT_AIRONET_HEADER 3059335640Shselasky case DLT_AIRONET_HEADER: 3060356341Scy#endif 3061335640Shselasky case DLT_IEEE802_11_RADIO_AVS: 3062335640Shselasky /* 3063335640Shselasky * 802.11 with radio, but not radiotap. 3064335640Shselasky * 3065335640Shselasky * Offer this, and select it as the new mode 3066335640Shselasky * unless we've already found the radiotap DLT_. 3067335640Shselasky */ 3068335640Shselasky if (new_dlt != DLT_IEEE802_11_RADIO) 3069335640Shselasky new_dlt = bdlp->bfl_list[i]; 3070335640Shselasky break; 3071335640Shselasky 3072335640Shselasky case DLT_IEEE802_11_RADIO: 3073335640Shselasky /* 3074335640Shselasky * 802.11 with radiotap. 3075335640Shselasky * 3076335640Shselasky * Offer this, and select it as the new mode. 3077335640Shselasky */ 3078335640Shselasky new_dlt = bdlp->bfl_list[i]; 3079335640Shselasky break; 3080335640Shselasky 3081335640Shselasky default: 3082335640Shselasky /* 3083335640Shselasky * Not 802.11. 3084335640Shselasky */ 3085335640Shselasky break; 3086335640Shselasky } 3087335640Shselasky } 3088335640Shselasky 3089335640Shselasky return (new_dlt); 3090335640Shselasky} 3091335640Shselasky#endif /* defined(BIOCGDLTLIST) && (defined(__APPLE__) || defined(HAVE_BSD_IEEE80211)) */ 3092335640Shselasky 3093335640Shselasky#if defined(__APPLE__) && defined(BIOCGDLTLIST) 3094335640Shselasky/* 3095356341Scy * Remove non-802.11 header types from the list of DLT_ values, as we're in 3096356341Scy * monitor mode, and those header types aren't supported in monitor mode. 3097335640Shselasky */ 3098335640Shselaskystatic void 3099356341Scyremove_non_802_11(pcap_t *p) 3100335640Shselasky{ 3101335640Shselasky int i, j; 3102335640Shselasky 3103335640Shselasky /* 3104356341Scy * Scan the list of DLT_ values and discard non-802.11 ones. 3105335640Shselasky */ 3106335640Shselasky j = 0; 3107335640Shselasky for (i = 0; i < p->dlt_count; i++) { 3108335640Shselasky switch (p->dlt_list[i]) { 3109335640Shselasky 3110335640Shselasky case DLT_EN10MB: 3111356341Scy case DLT_RAW: 3112335640Shselasky /* 3113356341Scy * Not 802.11. Don't offer this one. 3114335640Shselasky */ 3115335640Shselasky continue; 3116335640Shselasky 3117335640Shselasky default: 3118335640Shselasky /* 3119335640Shselasky * Just copy this mode over. 3120335640Shselasky */ 3121335640Shselasky break; 3122335640Shselasky } 3123335640Shselasky 3124335640Shselasky /* 3125335640Shselasky * Copy this DLT_ value to its new position. 3126335640Shselasky */ 3127335640Shselasky p->dlt_list[j] = p->dlt_list[i]; 3128335640Shselasky j++; 3129335640Shselasky } 3130335640Shselasky 3131335640Shselasky /* 3132335640Shselasky * Set the DLT_ count to the number of entries we copied. 3133335640Shselasky */ 3134335640Shselasky p->dlt_count = j; 3135335640Shselasky} 3136335640Shselasky 3137335640Shselasky/* 3138335640Shselasky * Remove 802.11 link-layer types from the list of DLT_ values, as 3139335640Shselasky * we're not in monitor mode, and those DLT_ values will switch us 3140335640Shselasky * to monitor mode. 3141335640Shselasky */ 3142335640Shselaskystatic void 3143335640Shselaskyremove_802_11(pcap_t *p) 3144335640Shselasky{ 3145335640Shselasky int i, j; 3146335640Shselasky 3147335640Shselasky /* 3148335640Shselasky * Scan the list of DLT_ values and discard 802.11 values. 3149335640Shselasky */ 3150335640Shselasky j = 0; 3151335640Shselasky for (i = 0; i < p->dlt_count; i++) { 3152335640Shselasky switch (p->dlt_list[i]) { 3153335640Shselasky 3154335640Shselasky case DLT_IEEE802_11: 3155356341Scy#ifdef DLT_PRISM_HEADER 3156335640Shselasky case DLT_PRISM_HEADER: 3157356341Scy#endif 3158356341Scy#ifdef DLT_AIRONET_HEADER 3159335640Shselasky case DLT_AIRONET_HEADER: 3160356341Scy#endif 3161335640Shselasky case DLT_IEEE802_11_RADIO: 3162335640Shselasky case DLT_IEEE802_11_RADIO_AVS: 3163356341Scy#ifdef DLT_PPI 3164356341Scy case DLT_PPI: 3165356341Scy#endif 3166335640Shselasky /* 3167335640Shselasky * 802.11. Don't offer this one. 3168335640Shselasky */ 3169335640Shselasky continue; 3170335640Shselasky 3171335640Shselasky default: 3172335640Shselasky /* 3173335640Shselasky * Just copy this mode over. 3174335640Shselasky */ 3175335640Shselasky break; 3176335640Shselasky } 3177335640Shselasky 3178335640Shselasky /* 3179335640Shselasky * Copy this DLT_ value to its new position. 3180335640Shselasky */ 3181335640Shselasky p->dlt_list[j] = p->dlt_list[i]; 3182335640Shselasky j++; 3183335640Shselasky } 3184335640Shselasky 3185335640Shselasky /* 3186335640Shselasky * Set the DLT_ count to the number of entries we copied. 3187335640Shselasky */ 3188335640Shselasky p->dlt_count = j; 3189335640Shselasky} 3190335640Shselasky#endif /* defined(__APPLE__) && defined(BIOCGDLTLIST) */ 3191335640Shselasky 3192335640Shselaskystatic int 3193335640Shselaskypcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp) 3194335640Shselasky{ 3195335640Shselasky struct pcap_bpf *pb = p->priv; 3196335640Shselasky 3197335640Shselasky /* 3198335640Shselasky * Free any user-mode filter we might happen to have installed. 3199335640Shselasky */ 3200335640Shselasky pcap_freecode(&p->fcode); 3201335640Shselasky 3202335640Shselasky /* 3203335640Shselasky * Try to install the kernel filter. 3204335640Shselasky */ 3205335640Shselasky if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) == 0) { 3206335640Shselasky /* 3207335640Shselasky * It worked. 3208335640Shselasky */ 3209335640Shselasky pb->filtering_in_kernel = 1; /* filtering in the kernel */ 3210335640Shselasky 3211335640Shselasky /* 3212335640Shselasky * Discard any previously-received packets, as they might 3213335640Shselasky * have passed whatever filter was formerly in effect, but 3214335640Shselasky * might not pass this filter (BIOCSETF discards packets 3215335640Shselasky * buffered in the kernel, so you can lose packets in any 3216335640Shselasky * case). 3217335640Shselasky */ 3218335640Shselasky p->cc = 0; 3219335640Shselasky return (0); 3220335640Shselasky } 3221335640Shselasky 3222335640Shselasky /* 3223335640Shselasky * We failed. 3224335640Shselasky * 3225335640Shselasky * If it failed with EINVAL, that's probably because the program 3226335640Shselasky * is invalid or too big. Validate it ourselves; if we like it 3227335640Shselasky * (we currently allow backward branches, to support protochain), 3228335640Shselasky * run it in userland. (There's no notion of "too big" for 3229335640Shselasky * userland.) 3230335640Shselasky * 3231335640Shselasky * Otherwise, just give up. 3232335640Shselasky * XXX - if the copy of the program into the kernel failed, 3233335640Shselasky * we will get EINVAL rather than, say, EFAULT on at least 3234335640Shselasky * some kernels. 3235335640Shselasky */ 3236335640Shselasky if (errno != EINVAL) { 3237335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 3238335640Shselasky errno, "BIOCSETF"); 3239335640Shselasky return (-1); 3240335640Shselasky } 3241335640Shselasky 3242335640Shselasky /* 3243335640Shselasky * install_bpf_program() validates the program. 3244335640Shselasky * 3245335640Shselasky * XXX - what if we already have a filter in the kernel? 3246335640Shselasky */ 3247335640Shselasky if (install_bpf_program(p, fp) < 0) 3248335640Shselasky return (-1); 3249335640Shselasky pb->filtering_in_kernel = 0; /* filtering in userland */ 3250335640Shselasky return (0); 3251335640Shselasky} 3252335640Shselasky 3253335640Shselasky/* 3254335640Shselasky * Set direction flag: Which packets do we accept on a forwarding 3255335640Shselasky * single device? IN, OUT or both? 3256335640Shselasky */ 3257356341Scy#if defined(BIOCSDIRECTION) 3258335640Shselaskystatic int 3259335640Shselaskypcap_setdirection_bpf(pcap_t *p, pcap_direction_t d) 3260335640Shselasky{ 3261335640Shselasky u_int direction; 3262335640Shselasky 3263335640Shselasky direction = (d == PCAP_D_IN) ? BPF_D_IN : 3264335640Shselasky ((d == PCAP_D_OUT) ? BPF_D_OUT : BPF_D_INOUT); 3265335640Shselasky if (ioctl(p->fd, BIOCSDIRECTION, &direction) == -1) { 3266335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf), 3267335640Shselasky errno, "Cannot set direction to %s", 3268335640Shselasky (d == PCAP_D_IN) ? "PCAP_D_IN" : 3269335640Shselasky ((d == PCAP_D_OUT) ? "PCAP_D_OUT" : "PCAP_D_INOUT")); 3270335640Shselasky return (-1); 3271335640Shselasky } 3272335640Shselasky return (0); 3273356341Scy} 3274335640Shselasky#elif defined(BIOCSSEESENT) 3275356341Scystatic int 3276356341Scypcap_setdirection_bpf(pcap_t *p, pcap_direction_t d) 3277356341Scy{ 3278335640Shselasky u_int seesent; 3279335640Shselasky 3280335640Shselasky /* 3281335640Shselasky * We don't support PCAP_D_OUT. 3282335640Shselasky */ 3283335640Shselasky if (d == PCAP_D_OUT) { 3284335640Shselasky pcap_snprintf(p->errbuf, sizeof(p->errbuf), 3285335640Shselasky "Setting direction to PCAP_D_OUT is not supported on BPF"); 3286335640Shselasky return -1; 3287335640Shselasky } 3288335640Shselasky 3289335640Shselasky seesent = (d == PCAP_D_INOUT); 3290335640Shselasky if (ioctl(p->fd, BIOCSSEESENT, &seesent) == -1) { 3291335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf), 3292335640Shselasky errno, "Cannot set direction to %s", 3293335640Shselasky (d == PCAP_D_INOUT) ? "PCAP_D_INOUT" : "PCAP_D_IN"); 3294335640Shselasky return (-1); 3295335640Shselasky } 3296335640Shselasky return (0); 3297356341Scy} 3298335640Shselasky#else 3299356341Scystatic int 3300356341Scypcap_setdirection_bpf(pcap_t *p, pcap_direction_t d _U_) 3301356341Scy{ 3302335640Shselasky (void) pcap_snprintf(p->errbuf, sizeof(p->errbuf), 3303335640Shselasky "This system doesn't support BIOCSSEESENT, so the direction can't be set"); 3304335640Shselasky return (-1); 3305356341Scy} 3306335640Shselasky#endif 3307335640Shselasky 3308356341Scy#ifdef BIOCSDLT 3309335640Shselaskystatic int 3310335640Shselaskypcap_set_datalink_bpf(pcap_t *p, int dlt) 3311335640Shselasky{ 3312335640Shselasky if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) { 3313335640Shselasky pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf), 3314335640Shselasky errno, "Cannot set DLT %d", dlt); 3315335640Shselasky return (-1); 3316335640Shselasky } 3317335640Shselasky return (0); 3318335640Shselasky} 3319356341Scy#else 3320356341Scystatic int 3321356341Scypcap_set_datalink_bpf(pcap_t *p _U_, int dlt _U_) 3322356341Scy{ 3323356341Scy return (0); 3324356341Scy} 3325356341Scy#endif 3326335640Shselasky 3327335640Shselasky/* 3328335640Shselasky * Platform-specific information. 3329335640Shselasky */ 3330335640Shselaskyconst char * 3331335640Shselaskypcap_lib_version(void) 3332335640Shselasky{ 3333335640Shselasky#ifdef HAVE_ZEROCOPY_BPF 3334335640Shselasky return (PCAP_VERSION_STRING " (with zerocopy support)"); 3335335640Shselasky#else 3336335640Shselasky return (PCAP_VERSION_STRING); 3337335640Shselasky#endif 3338335640Shselasky} 3339