1 /* 2 * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) 3 * Copyright (c) 2005 - 2010 CACE Technologies, Davis (California) 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the Politecnico di Torino, CACE Technologies 16 * nor the names of its contributors may be used to endorse or promote 17 * products derived from this software without specific prior written 18 * permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 */ 33 34 #ifdef HAVE_CONFIG_H 35 #include <config.h> 36 #endif 37 38 #include "pcap-int.h" 39 40 #include <airpcap.h> 41 42 #include "pcap-airpcap.h" 43 44 /* Default size of the buffer we allocate in userland. */ 45 #define AIRPCAP_DEFAULT_USER_BUFFER_SIZE 256000 46 47 /* Default size of the buffer for the AirPcap adapter. */ 48 #define AIRPCAP_DEFAULT_KERNEL_BUFFER_SIZE 1000000 49 50 // 51 // We load the AirPcap DLL dynamically, so that the code will 52 // work whether you have it installed or not, and there don't 53 // have to be two different versions of the library, one linked 54 // to the AirPcap library and one not linked to it. 55 // 56 static pcap_code_handle_t airpcap_lib; 57 58 typedef PCHAR (*AirpcapGetLastErrorHandler)(PAirpcapHandle); 59 typedef BOOL (*AirpcapGetDeviceListHandler)(PAirpcapDeviceDescription *, PCHAR); 60 typedef VOID (*AirpcapFreeDeviceListHandler)(PAirpcapDeviceDescription); 61 typedef PAirpcapHandle (*AirpcapOpenHandler)(PCHAR, PCHAR); 62 typedef VOID (*AirpcapCloseHandler)(PAirpcapHandle); 63 typedef BOOL (*AirpcapSetDeviceMacFlagsHandler)(PAirpcapHandle, UINT); 64 typedef BOOL (*AirpcapSetLinkTypeHandler)(PAirpcapHandle, AirpcapLinkType); 65 typedef BOOL (*AirpcapGetLinkTypeHandler)(PAirpcapHandle, PAirpcapLinkType); 66 typedef BOOL (*AirpcapSetKernelBufferHandler)(PAirpcapHandle, UINT); 67 typedef BOOL (*AirpcapSetFilterHandler)(PAirpcapHandle, PVOID, UINT); 68 typedef BOOL (*AirpcapSetMinToCopyHandler)(PAirpcapHandle, UINT); 69 typedef BOOL (*AirpcapGetReadEventHandler)(PAirpcapHandle, HANDLE *); 70 typedef BOOL (*AirpcapReadHandler)(PAirpcapHandle, PBYTE, UINT, PUINT); 71 typedef BOOL (*AirpcapWriteHandler)(PAirpcapHandle, PCHAR, ULONG); 72 typedef BOOL (*AirpcapGetStatsHandler)(PAirpcapHandle, PAirpcapStats); 73 74 static AirpcapGetLastErrorHandler p_AirpcapGetLastError; 75 static AirpcapGetDeviceListHandler p_AirpcapGetDeviceList; 76 static AirpcapFreeDeviceListHandler p_AirpcapFreeDeviceList; 77 static AirpcapOpenHandler p_AirpcapOpen; 78 static AirpcapCloseHandler p_AirpcapClose; 79 static AirpcapSetDeviceMacFlagsHandler p_AirpcapSetDeviceMacFlags; 80 static AirpcapSetLinkTypeHandler p_AirpcapSetLinkType; 81 static AirpcapGetLinkTypeHandler p_AirpcapGetLinkType; 82 static AirpcapSetKernelBufferHandler p_AirpcapSetKernelBuffer; 83 static AirpcapSetFilterHandler p_AirpcapSetFilter; 84 static AirpcapSetMinToCopyHandler p_AirpcapSetMinToCopy; 85 static AirpcapGetReadEventHandler p_AirpcapGetReadEvent; 86 static AirpcapReadHandler p_AirpcapRead; 87 static AirpcapWriteHandler p_AirpcapWrite; 88 static AirpcapGetStatsHandler p_AirpcapGetStats; 89 90 typedef enum LONG 91 { 92 AIRPCAP_API_UNLOADED = 0, 93 AIRPCAP_API_LOADED, 94 AIRPCAP_API_CANNOT_LOAD, 95 AIRPCAP_API_LOADING 96 } AIRPCAP_API_LOAD_STATUS; 97 98 static AIRPCAP_API_LOAD_STATUS airpcap_load_status; 99 100 /* 101 * NOTE: this function should be called by the pcap functions that can 102 * theoretically deal with the AirPcap library for the first time, 103 * namely listing the adapters and creating a pcap_t for an adapter. 104 * All the other ones (activate, close, read, write, set parameters) 105 * work on a pcap_t for an AirPcap device, meaning we've already 106 * created the pcap_t and thus have loaded the functions, so we do 107 * not need to call this function. 108 */ 109 static AIRPCAP_API_LOAD_STATUS 110 load_airpcap_functions(void) 111 { 112 AIRPCAP_API_LOAD_STATUS current_status; 113 114 /* 115 * We don't use a mutex because there's no place that 116 * we can guarantee we'll be called before any threads 117 * other than the main thread exists. (For example, 118 * this might be a static library, so we can't arrange 119 * to be called by DllMain(), and there's no guarantee 120 * that the application called pcap_init() - which is 121 * supposed to be called only from one thread - so 122 * we can't arrange to be called from it.) 123 * 124 * If nobody's tried to load it yet, mark it as 125 * loading; in any case, return the status before 126 * we modified it. 127 */ 128 current_status = InterlockedCompareExchange((LONG *)&airpcap_load_status, 129 AIRPCAP_API_LOADING, AIRPCAP_API_UNLOADED); 130 131 /* 132 * If the status was AIRPCAP_API_UNLOADED, we've set it 133 * to AIRPCAP_API_LOADING, because we're going to be 134 * the ones to load the library but current_status is 135 * AIRPCAP_API_UNLOADED. 136 * 137 * if it was AIRPCAP_API_LOADING, meaning somebody else 138 * was trying to load it, spin until they finish and 139 * set the status to a value reflecting whether they 140 * succeeded. 141 */ 142 while (current_status == AIRPCAP_API_LOADING) { 143 current_status = InterlockedCompareExchange((LONG*)&airpcap_load_status, 144 AIRPCAP_API_LOADING, AIRPCAP_API_LOADING); 145 Sleep(10); 146 } 147 148 /* 149 * At this point, current_status is either: 150 * 151 * AIRPCAP_API_LOADED, in which case another thread 152 * loaded the library, so we're done; 153 * 154 * AIRPCAP_API_CANNOT_LOAD, in which another thread 155 * tried and failed to load the library, so we're 156 * done - we won't try it ourselves; 157 * 158 * AIRPCAP_API_LOADING, in which case *we're* the 159 * ones loading it, and should now try to do so. 160 */ 161 if (current_status == AIRPCAP_API_LOADED) 162 return AIRPCAP_API_LOADED; 163 164 if (current_status == AIRPCAP_API_CANNOT_LOAD) 165 return AIRPCAP_API_CANNOT_LOAD; 166 167 /* 168 * Start out assuming we can't load it. 169 */ 170 current_status = AIRPCAP_API_CANNOT_LOAD; 171 172 airpcap_lib = pcap_load_code("airpcap.dll"); 173 if (airpcap_lib != NULL) { 174 /* 175 * OK, we've loaded the library; now try to find the 176 * functions we need in it. 177 */ 178 p_AirpcapGetLastError = (AirpcapGetLastErrorHandler) pcap_find_function(airpcap_lib, "AirpcapGetLastError"); 179 p_AirpcapGetDeviceList = (AirpcapGetDeviceListHandler) pcap_find_function(airpcap_lib, "AirpcapGetDeviceList"); 180 p_AirpcapFreeDeviceList = (AirpcapFreeDeviceListHandler) pcap_find_function(airpcap_lib, "AirpcapFreeDeviceList"); 181 p_AirpcapOpen = (AirpcapOpenHandler) pcap_find_function(airpcap_lib, "AirpcapOpen"); 182 p_AirpcapClose = (AirpcapCloseHandler) pcap_find_function(airpcap_lib, "AirpcapClose"); 183 p_AirpcapSetDeviceMacFlags = (AirpcapSetDeviceMacFlagsHandler) pcap_find_function(airpcap_lib, "AirpcapSetDeviceMacFlags"); 184 p_AirpcapSetLinkType = (AirpcapSetLinkTypeHandler) pcap_find_function(airpcap_lib, "AirpcapSetLinkType"); 185 p_AirpcapGetLinkType = (AirpcapGetLinkTypeHandler) pcap_find_function(airpcap_lib, "AirpcapGetLinkType"); 186 p_AirpcapSetKernelBuffer = (AirpcapSetKernelBufferHandler) pcap_find_function(airpcap_lib, "AirpcapSetKernelBuffer"); 187 p_AirpcapSetFilter = (AirpcapSetFilterHandler) pcap_find_function(airpcap_lib, "AirpcapSetFilter"); 188 p_AirpcapSetMinToCopy = (AirpcapSetMinToCopyHandler) pcap_find_function(airpcap_lib, "AirpcapSetMinToCopy"); 189 p_AirpcapGetReadEvent = (AirpcapGetReadEventHandler) pcap_find_function(airpcap_lib, "AirpcapGetReadEvent"); 190 p_AirpcapRead = (AirpcapReadHandler) pcap_find_function(airpcap_lib, "AirpcapRead"); 191 p_AirpcapWrite = (AirpcapWriteHandler) pcap_find_function(airpcap_lib, "AirpcapWrite"); 192 p_AirpcapGetStats = (AirpcapGetStatsHandler) pcap_find_function(airpcap_lib, "AirpcapGetStats"); 193 194 // 195 // Make sure that we found everything 196 // 197 if (p_AirpcapGetLastError != NULL && 198 p_AirpcapGetDeviceList != NULL && 199 p_AirpcapFreeDeviceList != NULL && 200 p_AirpcapOpen != NULL && 201 p_AirpcapClose != NULL && 202 p_AirpcapSetDeviceMacFlags != NULL && 203 p_AirpcapSetLinkType != NULL && 204 p_AirpcapGetLinkType != NULL && 205 p_AirpcapSetKernelBuffer != NULL && 206 p_AirpcapSetFilter != NULL && 207 p_AirpcapSetMinToCopy != NULL && 208 p_AirpcapGetReadEvent != NULL && 209 p_AirpcapRead != NULL && 210 p_AirpcapWrite != NULL && 211 p_AirpcapGetStats != NULL) { 212 /* 213 * We have all we need. 214 */ 215 current_status = AIRPCAP_API_LOADED; 216 } 217 } 218 219 if (current_status != AIRPCAP_API_LOADED) { 220 /* 221 * We failed; if we found the DLL, close the 222 * handle for it. 223 */ 224 if (airpcap_lib != NULL) { 225 FreeLibrary(airpcap_lib); 226 airpcap_lib = NULL; 227 } 228 } 229 230 /* 231 * Now set the status appropriately - and atomically. 232 */ 233 InterlockedExchange((LONG *)&airpcap_load_status, current_status); 234 235 return current_status; 236 } 237 238 /* 239 * Private data for capturing on AirPcap devices. 240 */ 241 struct pcap_airpcap { 242 PAirpcapHandle adapter; 243 int filtering_in_kernel; 244 int nonblock; 245 int read_timeout; 246 HANDLE read_event; 247 struct pcap_stat stat; 248 }; 249 250 static int 251 airpcap_setfilter(pcap_t *p, struct bpf_program *fp) 252 { 253 struct pcap_airpcap *pa = p->priv; 254 255 if (!p_AirpcapSetFilter(pa->adapter, fp->bf_insns, 256 fp->bf_len * sizeof(struct bpf_insn))) { 257 /* 258 * Kernel filter not installed. 259 * 260 * XXX - we don't know whether this failed because: 261 * 262 * the kernel rejected the filter program as invalid, 263 * in which case we should fall back on userland 264 * filtering; 265 * 266 * the kernel rejected the filter program as too big, 267 * in which case we should again fall back on 268 * userland filtering; 269 * 270 * there was some other problem, in which case we 271 * should probably report an error; 272 * 273 * So we just fall back on userland filtering in 274 * all cases. 275 */ 276 277 /* 278 * install_bpf_program() validates the program. 279 * 280 * XXX - what if we already have a filter in the kernel? 281 */ 282 if (install_bpf_program(p, fp) < 0) 283 return (-1); 284 pa->filtering_in_kernel = 0; /* filtering in userland */ 285 return (0); 286 } 287 288 /* 289 * It worked. 290 */ 291 pa->filtering_in_kernel = 1; /* filtering in the kernel */ 292 293 /* 294 * Discard any previously-received packets, as they might have 295 * passed whatever filter was formerly in effect, but might 296 * not pass this filter (BIOCSETF discards packets buffered 297 * in the kernel, so you can lose packets in any case). 298 */ 299 p->cc = 0; 300 return (0); 301 } 302 303 static int 304 airpcap_set_datalink(pcap_t *p, int dlt) 305 { 306 struct pcap_airpcap *pa = p->priv; 307 AirpcapLinkType type; 308 309 switch (dlt) { 310 311 case DLT_IEEE802_11_RADIO: 312 type = AIRPCAP_LT_802_11_PLUS_RADIO; 313 break; 314 315 case DLT_PPI: 316 type = AIRPCAP_LT_802_11_PLUS_PPI; 317 break; 318 319 case DLT_IEEE802_11: 320 type = AIRPCAP_LT_802_11; 321 break; 322 323 default: 324 /* This can't happen; just return. */ 325 return (0); 326 } 327 if (!p_AirpcapSetLinkType(pa->adapter, type)) { 328 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 329 "AirpcapSetLinkType() failed: %s", 330 p_AirpcapGetLastError(pa->adapter)); 331 return (-1); 332 } 333 p->linktype = dlt; 334 return (0); 335 } 336 337 static int 338 airpcap_getnonblock(pcap_t *p) 339 { 340 struct pcap_airpcap *pa = p->priv; 341 342 return (pa->nonblock); 343 } 344 345 static int 346 airpcap_setnonblock(pcap_t *p, int nonblock) 347 { 348 struct pcap_airpcap *pa = p->priv; 349 int newtimeout; 350 351 if (nonblock) { 352 /* 353 * Set the packet buffer timeout to -1 for non-blocking 354 * mode. 355 */ 356 newtimeout = -1; 357 } else { 358 /* 359 * Restore the timeout set when the device was opened. 360 * (Note that this may be -1, in which case we're not 361 * really leaving non-blocking mode. However, although 362 * the timeout argument to pcap_set_timeout() and 363 * pcap_open_live() is an int, you're not supposed to 364 * supply a negative value, so that "shouldn't happen".) 365 */ 366 newtimeout = p->opt.timeout; 367 } 368 pa->read_timeout = newtimeout; 369 pa->nonblock = (newtimeout == -1); 370 return (0); 371 } 372 373 static int 374 airpcap_stats(pcap_t *p, struct pcap_stat *ps) 375 { 376 struct pcap_airpcap *pa = p->priv; 377 AirpcapStats tas; 378 379 /* 380 * Try to get statistics. 381 */ 382 if (!p_AirpcapGetStats(pa->adapter, &tas)) { 383 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 384 "AirpcapGetStats() failed: %s", 385 p_AirpcapGetLastError(pa->adapter)); 386 return (-1); 387 } 388 389 ps->ps_drop = tas.Drops; 390 ps->ps_recv = tas.Recvs; 391 ps->ps_ifdrop = tas.IfDrops; 392 393 return (0); 394 } 395 396 /* 397 * Win32-only routine for getting statistics. 398 * 399 * This way is definitely safer than passing the pcap_stat * from the userland. 400 * In fact, there could happen than the user allocates a variable which is not 401 * big enough for the new structure, and the library will write in a zone 402 * which is not allocated to this variable. 403 * 404 * In this way, we're pretty sure we are writing on memory allocated to this 405 * variable. 406 * 407 * XXX - but this is the wrong way to handle statistics. Instead, we should 408 * have an API that returns data in a form like the Options section of a 409 * pcapng Interface Statistics Block: 410 * 411 * https://xml2rfc.tools.ietf.org/cgi-bin/xml2rfc.cgi?url=https://raw.githubusercontent.com/pcapng/pcapng/master/draft-tuexen-opsawg-pcapng.xml&modeAsFormat=html/ascii&type=ascii#rfc.section.4.6 412 * 413 * which would let us add new statistics straightforwardly and indicate which 414 * statistics we are and are *not* providing, rather than having to provide 415 * possibly-bogus values for statistics we can't provide. 416 */ 417 static struct pcap_stat * 418 airpcap_stats_ex(pcap_t *p, int *pcap_stat_size) 419 { 420 struct pcap_airpcap *pa = p->priv; 421 AirpcapStats tas; 422 423 *pcap_stat_size = sizeof (p->stat); 424 425 /* 426 * Try to get statistics. 427 */ 428 if (!p_AirpcapGetStats(pa->adapter, &tas)) { 429 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 430 "AirpcapGetStats() failed: %s", 431 p_AirpcapGetLastError(pa->adapter)); 432 return (NULL); 433 } 434 435 p->stat.ps_recv = tas.Recvs; 436 p->stat.ps_drop = tas.Drops; 437 p->stat.ps_ifdrop = tas.IfDrops; 438 /* 439 * Just in case this is ever compiled for a target other than 440 * Windows, which is extremely unlikely at best. 441 */ 442 #ifdef _WIN32 443 p->stat.ps_capt = tas.Capt; 444 #endif 445 return (&p->stat); 446 } 447 448 /* Set the dimension of the kernel-level capture buffer */ 449 static int 450 airpcap_setbuff(pcap_t *p, int dim) 451 { 452 struct pcap_airpcap *pa = p->priv; 453 454 if (!p_AirpcapSetKernelBuffer(pa->adapter, dim)) { 455 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 456 "AirpcapSetKernelBuffer() failed: %s", 457 p_AirpcapGetLastError(pa->adapter)); 458 return (-1); 459 } 460 return (0); 461 } 462 463 /* Set the driver working mode */ 464 static int 465 airpcap_setmode(pcap_t *p, int mode) 466 { 467 if (mode != MODE_CAPT) { 468 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 469 "Only MODE_CAPT is supported on an AirPcap adapter"); 470 return (-1); 471 } 472 return (0); 473 } 474 475 /*set the minimum amount of data that will release a read call*/ 476 static int 477 airpcap_setmintocopy(pcap_t *p, int size) 478 { 479 struct pcap_airpcap *pa = p->priv; 480 481 if (!p_AirpcapSetMinToCopy(pa->adapter, size)) { 482 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 483 "AirpcapSetMinToCopy() failed: %s", 484 p_AirpcapGetLastError(pa->adapter)); 485 return (-1); 486 } 487 return (0); 488 } 489 490 static HANDLE 491 airpcap_getevent(pcap_t *p) 492 { 493 struct pcap_airpcap *pa = p->priv; 494 495 return (pa->read_event); 496 } 497 498 static int 499 airpcap_oid_get_request(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_, 500 size_t *lenp _U_) 501 { 502 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 503 "Getting OID values is not supported on an AirPcap adapter"); 504 return (PCAP_ERROR); 505 } 506 507 static int 508 airpcap_oid_set_request(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_, 509 size_t *lenp _U_) 510 { 511 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 512 "Setting OID values is not supported on an AirPcap adapter"); 513 return (PCAP_ERROR); 514 } 515 516 static u_int 517 airpcap_sendqueue_transmit(pcap_t *p, pcap_send_queue *queue _U_, int sync _U_) 518 { 519 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 520 "Cannot queue packets for transmission on an AirPcap adapter"); 521 return (0); 522 } 523 524 static int 525 airpcap_setuserbuffer(pcap_t *p, int size) 526 { 527 unsigned char *new_buff; 528 529 if (size <= 0) { 530 /* Bogus parameter */ 531 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 532 "Error: invalid size %d",size); 533 return (-1); 534 } 535 536 /* Allocate the buffer */ 537 new_buff = (unsigned char *)malloc(sizeof(char)*size); 538 539 if (!new_buff) { 540 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 541 "Error: not enough memory"); 542 return (-1); 543 } 544 545 free(p->buffer); 546 547 p->buffer = new_buff; 548 p->bufsize = size; 549 550 return (0); 551 } 552 553 static int 554 airpcap_live_dump(pcap_t *p, char *filename _U_, int maxsize _U_, 555 int maxpacks _U_) 556 { 557 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 558 "AirPcap adapters don't support live dump"); 559 return (-1); 560 } 561 562 static int 563 airpcap_live_dump_ended(pcap_t *p, int sync _U_) 564 { 565 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 566 "AirPcap adapters don't support live dump"); 567 return (-1); 568 } 569 570 static PAirpcapHandle 571 airpcap_get_airpcap_handle(pcap_t *p) 572 { 573 struct pcap_airpcap *pa = p->priv; 574 575 return (pa->adapter); 576 } 577 578 static int 579 airpcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 580 { 581 struct pcap_airpcap *pa = p->priv; 582 int cc; 583 int n; 584 register u_char *bp, *ep; 585 UINT bytes_read; 586 u_char *datap; 587 588 cc = p->cc; 589 if (cc == 0) { 590 /* 591 * Has "pcap_breakloop()" been called? 592 */ 593 if (p->break_loop) { 594 /* 595 * Yes - clear the flag that indicates that it 596 * has, and return PCAP_ERROR_BREAK to indicate 597 * that we were told to break out of the loop. 598 */ 599 p->break_loop = 0; 600 return (PCAP_ERROR_BREAK); 601 } 602 603 // 604 // If we're not in non-blocking mode, wait for data to 605 // arrive. 606 // 607 if (pa->read_timeout != -1) { 608 WaitForSingleObject(pa->read_event, 609 (pa->read_timeout ==0 )? INFINITE: pa->read_timeout); 610 } 611 612 // 613 // Read the data. 614 // p_AirpcapRead doesn't block. 615 // 616 if (!p_AirpcapRead(pa->adapter, (PBYTE)p->buffer, 617 p->bufsize, &bytes_read)) { 618 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 619 "AirpcapRead() failed: %s", 620 p_AirpcapGetLastError(pa->adapter)); 621 return (-1); 622 } 623 cc = bytes_read; 624 bp = (u_char *)p->buffer; 625 } else 626 bp = p->bp; 627 628 /* 629 * Loop through each packet. 630 * 631 * This assumes that a single buffer of packets will have 632 * <= INT_MAX packets, so the packet count doesn't overflow. 633 */ 634 #define bhp ((AirpcapBpfHeader *)bp) 635 n = 0; 636 ep = bp + cc; 637 for (;;) { 638 register u_int caplen, hdrlen; 639 640 /* 641 * Has "pcap_breakloop()" been called? 642 * If so, return immediately - if we haven't read any 643 * packets, clear the flag and return PCAP_ERROR_BREAK 644 * to indicate that we were told to break out of the loop, 645 * otherwise leave the flag set, so that the *next* call 646 * will break out of the loop without having read any 647 * packets, and return the number of packets we've 648 * processed so far. 649 */ 650 if (p->break_loop) { 651 if (n == 0) { 652 p->break_loop = 0; 653 return (PCAP_ERROR_BREAK); 654 } else { 655 p->bp = bp; 656 p->cc = (int) (ep - bp); 657 return (n); 658 } 659 } 660 if (bp >= ep) 661 break; 662 663 caplen = bhp->Caplen; 664 hdrlen = bhp->Hdrlen; 665 datap = bp + hdrlen; 666 /* 667 * Short-circuit evaluation: if using BPF filter 668 * in the AirPcap adapter, no need to do it now - 669 * we already know the packet passed the filter. 670 */ 671 if (pa->filtering_in_kernel || 672 p->fcode.bf_insns == NULL || 673 pcap_filter(p->fcode.bf_insns, datap, bhp->Originallen, caplen)) { 674 struct pcap_pkthdr pkthdr; 675 676 pkthdr.ts.tv_sec = bhp->TsSec; 677 pkthdr.ts.tv_usec = bhp->TsUsec; 678 pkthdr.caplen = caplen; 679 pkthdr.len = bhp->Originallen; 680 (*callback)(user, &pkthdr, datap); 681 bp += AIRPCAP_WORDALIGN(caplen + hdrlen); 682 if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) { 683 p->bp = bp; 684 p->cc = (int)(ep - bp); 685 return (n); 686 } 687 } else { 688 /* 689 * Skip this packet. 690 */ 691 bp += AIRPCAP_WORDALIGN(caplen + hdrlen); 692 } 693 } 694 #undef bhp 695 p->cc = 0; 696 return (n); 697 } 698 699 static int 700 airpcap_inject(pcap_t *p, const void *buf, int size) 701 { 702 struct pcap_airpcap *pa = p->priv; 703 704 /* 705 * XXX - the second argument to AirpcapWrite() *should* have 706 * been declared as a const pointer - a write function that 707 * stomps on what it writes is *extremely* rude - but such 708 * is life. We assume it is, in fact, not going to write on 709 * our buffer. 710 */ 711 if (!p_AirpcapWrite(pa->adapter, (void *)buf, size)) { 712 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 713 "AirpcapWrite() failed: %s", 714 p_AirpcapGetLastError(pa->adapter)); 715 return (-1); 716 } 717 718 /* 719 * We assume it all got sent if "AirpcapWrite()" succeeded. 720 * "pcap_inject()" is expected to return the number of bytes 721 * sent. 722 */ 723 return (size); 724 } 725 726 static void 727 airpcap_cleanup(pcap_t *p) 728 { 729 struct pcap_airpcap *pa = p->priv; 730 731 if (pa->adapter != NULL) { 732 p_AirpcapClose(pa->adapter); 733 pa->adapter = NULL; 734 } 735 pcap_cleanup_live_common(p); 736 } 737 738 static void 739 airpcap_breakloop(pcap_t *p) 740 { 741 HANDLE read_event; 742 743 pcap_breakloop_common(p); 744 struct pcap_airpcap *pa = p->priv; 745 746 /* XXX - what if either of these fail? */ 747 /* 748 * XXX - will SetEvent() force a wakeup and, if so, will 749 * the AirPcap read code handle that sanely? 750 */ 751 if (!p_AirpcapGetReadEvent(pa->adapter, &read_event)) 752 return; 753 SetEvent(read_event); 754 } 755 756 static int 757 airpcap_activate(pcap_t *p) 758 { 759 struct pcap_airpcap *pa = p->priv; 760 char *device = p->opt.device; 761 char airpcap_errbuf[AIRPCAP_ERRBUF_SIZE]; 762 BOOL status; 763 AirpcapLinkType link_type; 764 765 pa->adapter = p_AirpcapOpen(device, airpcap_errbuf); 766 if (pa->adapter == NULL) { 767 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s", airpcap_errbuf); 768 return (PCAP_ERROR); 769 } 770 771 /* 772 * Set monitor mode appropriately. 773 * Always turn off the "ACK frames sent to the card" mode. 774 */ 775 if (p->opt.rfmon) { 776 status = p_AirpcapSetDeviceMacFlags(pa->adapter, 777 AIRPCAP_MF_MONITOR_MODE_ON); 778 } else 779 status = p_AirpcapSetDeviceMacFlags(pa->adapter, 780 AIRPCAP_MF_ACK_FRAMES_ON); 781 if (!status) { 782 p_AirpcapClose(pa->adapter); 783 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 784 "AirpcapSetDeviceMacFlags() failed: %s", 785 p_AirpcapGetLastError(pa->adapter)); 786 return (PCAP_ERROR); 787 } 788 789 /* 790 * Turn a negative snapshot value (invalid), a snapshot value of 791 * 0 (unspecified), or a value bigger than the normal maximum 792 * value, into the maximum allowed value. 793 * 794 * If some application really *needs* a bigger snapshot 795 * length, we should just increase MAXIMUM_SNAPLEN. 796 */ 797 if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) 798 p->snapshot = MAXIMUM_SNAPLEN; 799 800 /* 801 * If the buffer size wasn't explicitly set, default to 802 * AIRPCAP_DEFAULT_KERNEL_BUFFER_SIZE. 803 */ 804 if (p->opt.buffer_size == 0) 805 p->opt.buffer_size = AIRPCAP_DEFAULT_KERNEL_BUFFER_SIZE; 806 807 if (!p_AirpcapSetKernelBuffer(pa->adapter, p->opt.buffer_size)) { 808 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 809 "AirpcapSetKernelBuffer() failed: %s", 810 p_AirpcapGetLastError(pa->adapter)); 811 goto bad; 812 } 813 814 if(!p_AirpcapGetReadEvent(pa->adapter, &pa->read_event)) { 815 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 816 "AirpcapGetReadEvent() failed: %s", 817 p_AirpcapGetLastError(pa->adapter)); 818 goto bad; 819 } 820 821 /* Set the buffer size */ 822 p->bufsize = AIRPCAP_DEFAULT_USER_BUFFER_SIZE; 823 p->buffer = malloc(p->bufsize); 824 if (p->buffer == NULL) { 825 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 826 errno, "malloc"); 827 goto bad; 828 } 829 830 if (p->opt.immediate) { 831 /* Tell the driver to copy the buffer as soon as data arrives. */ 832 if (!p_AirpcapSetMinToCopy(pa->adapter, 0)) { 833 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 834 "AirpcapSetMinToCopy() failed: %s", 835 p_AirpcapGetLastError(pa->adapter)); 836 goto bad; 837 } 838 } else { 839 /* 840 * Tell the driver to copy the buffer only if it contains 841 * at least 16K. 842 */ 843 if (!p_AirpcapSetMinToCopy(pa->adapter, 16000)) { 844 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 845 "AirpcapSetMinToCopy() failed: %s", 846 p_AirpcapGetLastError(pa->adapter)); 847 goto bad; 848 } 849 } 850 851 /* 852 * Find out what the default link-layer header type is, 853 * and set p->datalink to that. 854 * 855 * We don't force it to another value because there 856 * might be some programs using WinPcap/Npcap that, 857 * when capturing on AirPcap devices, assume the 858 * default value set with the AirPcap configuration 859 * program is what you get. 860 * 861 * The out-of-the-box default appears to be radiotap. 862 */ 863 if (!p_AirpcapGetLinkType(pa->adapter, &link_type)) { 864 /* That failed. */ 865 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 866 "AirpcapGetLinkType() failed: %s", 867 p_AirpcapGetLastError(pa->adapter)); 868 goto bad; 869 } 870 switch (link_type) { 871 872 case AIRPCAP_LT_802_11_PLUS_RADIO: 873 p->linktype = DLT_IEEE802_11_RADIO; 874 break; 875 876 case AIRPCAP_LT_802_11_PLUS_PPI: 877 p->linktype = DLT_PPI; 878 break; 879 880 case AIRPCAP_LT_802_11: 881 p->linktype = DLT_IEEE802_11; 882 break; 883 884 case AIRPCAP_LT_UNKNOWN: 885 default: 886 /* OK, what? */ 887 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 888 "AirpcapGetLinkType() returned unknown link type %u", 889 link_type); 890 goto bad; 891 } 892 893 /* 894 * Now provide a list of all the supported types; we 895 * assume they all work. We put radiotap at the top, 896 * followed by PPI, followed by "no radio metadata". 897 */ 898 p->dlt_list = (u_int *) malloc(sizeof(u_int) * 3); 899 if (p->dlt_list == NULL) 900 goto bad; 901 p->dlt_list[0] = DLT_IEEE802_11_RADIO; 902 p->dlt_list[1] = DLT_PPI; 903 p->dlt_list[2] = DLT_IEEE802_11; 904 p->dlt_count = 3; 905 906 p->read_op = airpcap_read; 907 p->inject_op = airpcap_inject; 908 p->setfilter_op = airpcap_setfilter; 909 p->setdirection_op = NULL; /* Not implemented. */ 910 p->set_datalink_op = airpcap_set_datalink; 911 p->getnonblock_op = airpcap_getnonblock; 912 p->setnonblock_op = airpcap_setnonblock; 913 p->breakloop_op = airpcap_breakloop; 914 p->stats_op = airpcap_stats; 915 p->stats_ex_op = airpcap_stats_ex; 916 p->setbuff_op = airpcap_setbuff; 917 p->setmode_op = airpcap_setmode; 918 p->setmintocopy_op = airpcap_setmintocopy; 919 p->getevent_op = airpcap_getevent; 920 p->oid_get_request_op = airpcap_oid_get_request; 921 p->oid_set_request_op = airpcap_oid_set_request; 922 p->sendqueue_transmit_op = airpcap_sendqueue_transmit; 923 p->setuserbuffer_op = airpcap_setuserbuffer; 924 p->live_dump_op = airpcap_live_dump; 925 p->live_dump_ended_op = airpcap_live_dump_ended; 926 p->get_airpcap_handle_op = airpcap_get_airpcap_handle; 927 p->cleanup_op = airpcap_cleanup; 928 929 return (0); 930 bad: 931 airpcap_cleanup(p); 932 return (PCAP_ERROR); 933 } 934 935 /* 936 * Monitor mode is supported. 937 */ 938 static int 939 airpcap_can_set_rfmon(pcap_t *p) 940 { 941 return (1); 942 } 943 944 int 945 device_is_airpcap(const char *device, char *ebuf) 946 { 947 static const char airpcap_prefix[] = "\\\\.\\airpcap"; 948 949 /* 950 * We don't determine this by calling AirpcapGetDeviceList() 951 * and looking at the list, as that appears to be a costly 952 * operation. 953 * 954 * Instead, we just check whether it begins with "\\.\airpcap". 955 */ 956 if (strncmp(device, airpcap_prefix, sizeof airpcap_prefix - 1) == 0) { 957 /* 958 * Yes, it's an AirPcap device. 959 */ 960 return (1); 961 } 962 963 /* 964 * No, it's not an AirPcap device. 965 */ 966 return (0); 967 } 968 969 pcap_t * 970 airpcap_create(const char *device, char *ebuf, int *is_ours) 971 { 972 int ret; 973 pcap_t *p; 974 975 /* 976 * This can be called before we've tried loading the library, 977 * so do so if we haven't already tried to do so. 978 */ 979 if (load_airpcap_functions() != AIRPCAP_API_LOADED) { 980 /* 981 * We assume this means that we don't have the AirPcap 982 * software installed, which probably means we don't 983 * have an AirPcap device. 984 * 985 * Don't treat that as an error. 986 */ 987 *is_ours = 0; 988 return (NULL); 989 } 990 991 /* 992 * Is this an AirPcap device? 993 */ 994 ret = device_is_airpcap(device, ebuf); 995 if (ret == 0) { 996 /* No. */ 997 *is_ours = 0; 998 return (NULL); 999 } 1000 1001 /* 1002 * Yes. 1003 */ 1004 *is_ours = 1; 1005 p = PCAP_CREATE_COMMON(ebuf, struct pcap_airpcap); 1006 if (p == NULL) 1007 return (NULL); 1008 1009 p->activate_op = airpcap_activate; 1010 p->can_set_rfmon_op = airpcap_can_set_rfmon; 1011 return (p); 1012 } 1013 1014 /* 1015 * Add all AirPcap devices. 1016 */ 1017 int 1018 airpcap_findalldevs(pcap_if_list_t *devlistp, char *errbuf) 1019 { 1020 AirpcapDeviceDescription *airpcap_devices, *airpcap_device; 1021 char airpcap_errbuf[AIRPCAP_ERRBUF_SIZE]; 1022 1023 /* 1024 * This can be called before we've tried loading the library, 1025 * so do so if we haven't already tried to do so. 1026 */ 1027 if (load_airpcap_functions() != AIRPCAP_API_LOADED) { 1028 /* 1029 * XXX - unless the error is "no such DLL", report this 1030 * as an error rather than as "no AirPcap devices"? 1031 */ 1032 return (0); 1033 } 1034 1035 if (!p_AirpcapGetDeviceList(&airpcap_devices, airpcap_errbuf)) { 1036 snprintf(errbuf, PCAP_ERRBUF_SIZE, 1037 "AirpcapGetDeviceList() failed: %s", airpcap_errbuf); 1038 return (-1); 1039 } 1040 1041 for (airpcap_device = airpcap_devices; airpcap_device != NULL; 1042 airpcap_device = airpcap_device->next) { 1043 if (add_dev(devlistp, airpcap_device->Name, 0, 1044 airpcap_device->Description, errbuf) == NULL) { 1045 /* 1046 * Failure. 1047 */ 1048 p_AirpcapFreeDeviceList(airpcap_devices); 1049 return (-1); 1050 } 1051 } 1052 p_AirpcapFreeDeviceList(airpcap_devices); 1053 return (0); 1054 } 1055