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 #define bhp ((AirpcapBpfHeader *)bp) 632 n = 0; 633 ep = bp + cc; 634 for (;;) { 635 register u_int caplen, hdrlen; 636 637 /* 638 * Has "pcap_breakloop()" been called? 639 * If so, return immediately - if we haven't read any 640 * packets, clear the flag and return PCAP_ERROR_BREAK 641 * to indicate that we were told to break out of the loop, 642 * otherwise leave the flag set, so that the *next* call 643 * will break out of the loop without having read any 644 * packets, and return the number of packets we've 645 * processed so far. 646 */ 647 if (p->break_loop) { 648 if (n == 0) { 649 p->break_loop = 0; 650 return (PCAP_ERROR_BREAK); 651 } else { 652 p->bp = bp; 653 p->cc = (int) (ep - bp); 654 return (n); 655 } 656 } 657 if (bp >= ep) 658 break; 659 660 caplen = bhp->Caplen; 661 hdrlen = bhp->Hdrlen; 662 datap = bp + hdrlen; 663 /* 664 * Short-circuit evaluation: if using BPF filter 665 * in the AirPcap adapter, no need to do it now - 666 * we already know the packet passed the filter. 667 */ 668 if (pa->filtering_in_kernel || 669 p->fcode.bf_insns == NULL || 670 pcap_filter(p->fcode.bf_insns, datap, bhp->Originallen, caplen)) { 671 struct pcap_pkthdr pkthdr; 672 673 pkthdr.ts.tv_sec = bhp->TsSec; 674 pkthdr.ts.tv_usec = bhp->TsUsec; 675 pkthdr.caplen = caplen; 676 pkthdr.len = bhp->Originallen; 677 (*callback)(user, &pkthdr, datap); 678 bp += AIRPCAP_WORDALIGN(caplen + hdrlen); 679 if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) { 680 p->bp = bp; 681 p->cc = (int)(ep - bp); 682 return (n); 683 } 684 } else { 685 /* 686 * Skip this packet. 687 */ 688 bp += AIRPCAP_WORDALIGN(caplen + hdrlen); 689 } 690 } 691 #undef bhp 692 p->cc = 0; 693 return (n); 694 } 695 696 static int 697 airpcap_inject(pcap_t *p, const void *buf, int size) 698 { 699 struct pcap_airpcap *pa = p->priv; 700 701 /* 702 * XXX - the second argument to AirpcapWrite() *should* have 703 * been declared as a const pointer - a write function that 704 * stomps on what it writes is *extremely* rude - but such 705 * is life. We assume it is, in fact, not going to write on 706 * our buffer. 707 */ 708 if (!p_AirpcapWrite(pa->adapter, (void *)buf, size)) { 709 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 710 "AirpcapWrite() failed: %s", 711 p_AirpcapGetLastError(pa->adapter)); 712 return (-1); 713 } 714 715 /* 716 * We assume it all got sent if "AirpcapWrite()" succeeded. 717 * "pcap_inject()" is expected to return the number of bytes 718 * sent. 719 */ 720 return (size); 721 } 722 723 static void 724 airpcap_cleanup(pcap_t *p) 725 { 726 struct pcap_airpcap *pa = p->priv; 727 728 if (pa->adapter != NULL) { 729 p_AirpcapClose(pa->adapter); 730 pa->adapter = NULL; 731 } 732 pcap_cleanup_live_common(p); 733 } 734 735 static void 736 airpcap_breakloop(pcap_t *p) 737 { 738 HANDLE read_event; 739 740 pcap_breakloop_common(p); 741 struct pcap_airpcap *pa = p->priv; 742 743 /* XXX - what if either of these fail? */ 744 /* 745 * XXX - will SetEvent() force a wakeup and, if so, will 746 * the AirPcap read code handle that sanely? 747 */ 748 if (!p_AirpcapGetReadEvent(pa->adapter, &read_event)) 749 return; 750 SetEvent(read_event); 751 } 752 753 static int 754 airpcap_activate(pcap_t *p) 755 { 756 struct pcap_airpcap *pa = p->priv; 757 char *device = p->opt.device; 758 char airpcap_errbuf[AIRPCAP_ERRBUF_SIZE]; 759 BOOL status; 760 AirpcapLinkType link_type; 761 762 pa->adapter = p_AirpcapOpen(device, airpcap_errbuf); 763 if (pa->adapter == NULL) { 764 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s", airpcap_errbuf); 765 return (PCAP_ERROR); 766 } 767 768 /* 769 * Set monitor mode appropriately. 770 * Always turn off the "ACK frames sent to the card" mode. 771 */ 772 if (p->opt.rfmon) { 773 status = p_AirpcapSetDeviceMacFlags(pa->adapter, 774 AIRPCAP_MF_MONITOR_MODE_ON); 775 } else 776 status = p_AirpcapSetDeviceMacFlags(pa->adapter, 777 AIRPCAP_MF_ACK_FRAMES_ON); 778 if (!status) { 779 p_AirpcapClose(pa->adapter); 780 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 781 "AirpcapSetDeviceMacFlags() failed: %s", 782 p_AirpcapGetLastError(pa->adapter)); 783 return (PCAP_ERROR); 784 } 785 786 /* 787 * Turn a negative snapshot value (invalid), a snapshot value of 788 * 0 (unspecified), or a value bigger than the normal maximum 789 * value, into the maximum allowed value. 790 * 791 * If some application really *needs* a bigger snapshot 792 * length, we should just increase MAXIMUM_SNAPLEN. 793 */ 794 if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) 795 p->snapshot = MAXIMUM_SNAPLEN; 796 797 /* 798 * If the buffer size wasn't explicitly set, default to 799 * AIRPCAP_DEFAULT_KERNEL_BUFFER_SIZE. 800 */ 801 if (p->opt.buffer_size == 0) 802 p->opt.buffer_size = AIRPCAP_DEFAULT_KERNEL_BUFFER_SIZE; 803 804 if (!p_AirpcapSetKernelBuffer(pa->adapter, p->opt.buffer_size)) { 805 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 806 "AirpcapSetKernelBuffer() failed: %s", 807 p_AirpcapGetLastError(pa->adapter)); 808 goto bad; 809 } 810 811 if(!p_AirpcapGetReadEvent(pa->adapter, &pa->read_event)) { 812 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 813 "AirpcapGetReadEvent() failed: %s", 814 p_AirpcapGetLastError(pa->adapter)); 815 goto bad; 816 } 817 818 /* Set the buffer size */ 819 p->bufsize = AIRPCAP_DEFAULT_USER_BUFFER_SIZE; 820 p->buffer = malloc(p->bufsize); 821 if (p->buffer == NULL) { 822 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 823 errno, "malloc"); 824 goto bad; 825 } 826 827 if (p->opt.immediate) { 828 /* Tell the driver to copy the buffer as soon as data arrives. */ 829 if (!p_AirpcapSetMinToCopy(pa->adapter, 0)) { 830 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 831 "AirpcapSetMinToCopy() failed: %s", 832 p_AirpcapGetLastError(pa->adapter)); 833 goto bad; 834 } 835 } else { 836 /* 837 * Tell the driver to copy the buffer only if it contains 838 * at least 16K. 839 */ 840 if (!p_AirpcapSetMinToCopy(pa->adapter, 16000)) { 841 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 842 "AirpcapSetMinToCopy() failed: %s", 843 p_AirpcapGetLastError(pa->adapter)); 844 goto bad; 845 } 846 } 847 848 /* 849 * Find out what the default link-layer header type is, 850 * and set p->datalink to that. 851 * 852 * We don't force it to another value because there 853 * might be some programs using WinPcap/Npcap that, 854 * when capturing on AirPcap devices, assume the 855 * default value set with the AirPcap configuration 856 * program is what you get. 857 * 858 * The out-of-the-box default appears to be radiotap. 859 */ 860 if (!p_AirpcapGetLinkType(pa->adapter, &link_type)) { 861 /* That failed. */ 862 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 863 "AirpcapGetLinkType() failed: %s", 864 p_AirpcapGetLastError(pa->adapter)); 865 goto bad; 866 } 867 switch (link_type) { 868 869 case AIRPCAP_LT_802_11_PLUS_RADIO: 870 p->linktype = DLT_IEEE802_11_RADIO; 871 break; 872 873 case AIRPCAP_LT_802_11_PLUS_PPI: 874 p->linktype = DLT_PPI; 875 break; 876 877 case AIRPCAP_LT_802_11: 878 p->linktype = DLT_IEEE802_11; 879 break; 880 881 case AIRPCAP_LT_UNKNOWN: 882 default: 883 /* OK, what? */ 884 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 885 "AirpcapGetLinkType() returned unknown link type %u", 886 link_type); 887 goto bad; 888 } 889 890 /* 891 * Now provide a list of all the supported types; we 892 * assume they all work. We put radiotap at the top, 893 * followed by PPI, followed by "no radio metadata". 894 */ 895 p->dlt_list = (u_int *) malloc(sizeof(u_int) * 3); 896 if (p->dlt_list == NULL) 897 goto bad; 898 p->dlt_list[0] = DLT_IEEE802_11_RADIO; 899 p->dlt_list[1] = DLT_PPI; 900 p->dlt_list[2] = DLT_IEEE802_11; 901 p->dlt_count = 3; 902 903 p->read_op = airpcap_read; 904 p->inject_op = airpcap_inject; 905 p->setfilter_op = airpcap_setfilter; 906 p->setdirection_op = NULL; /* Not implemented. */ 907 p->set_datalink_op = airpcap_set_datalink; 908 p->getnonblock_op = airpcap_getnonblock; 909 p->setnonblock_op = airpcap_setnonblock; 910 p->breakloop_op = airpcap_breakloop; 911 p->stats_op = airpcap_stats; 912 p->stats_ex_op = airpcap_stats_ex; 913 p->setbuff_op = airpcap_setbuff; 914 p->setmode_op = airpcap_setmode; 915 p->setmintocopy_op = airpcap_setmintocopy; 916 p->getevent_op = airpcap_getevent; 917 p->oid_get_request_op = airpcap_oid_get_request; 918 p->oid_set_request_op = airpcap_oid_set_request; 919 p->sendqueue_transmit_op = airpcap_sendqueue_transmit; 920 p->setuserbuffer_op = airpcap_setuserbuffer; 921 p->live_dump_op = airpcap_live_dump; 922 p->live_dump_ended_op = airpcap_live_dump_ended; 923 p->get_airpcap_handle_op = airpcap_get_airpcap_handle; 924 p->cleanup_op = airpcap_cleanup; 925 926 return (0); 927 bad: 928 airpcap_cleanup(p); 929 return (PCAP_ERROR); 930 } 931 932 /* 933 * Monitor mode is supported. 934 */ 935 static int 936 airpcap_can_set_rfmon(pcap_t *p) 937 { 938 return (1); 939 } 940 941 int 942 device_is_airpcap(const char *device, char *ebuf) 943 { 944 static const char airpcap_prefix[] = "\\\\.\\airpcap"; 945 946 /* 947 * We don't determine this by calling AirpcapGetDeviceList() 948 * and looking at the list, as that appears to be a costly 949 * operation. 950 * 951 * Instead, we just check whether it begins with "\\.\airpcap". 952 */ 953 if (strncmp(device, airpcap_prefix, sizeof airpcap_prefix - 1) == 0) { 954 /* 955 * Yes, it's an AirPcap device. 956 */ 957 return (1); 958 } 959 960 /* 961 * No, it's not an AirPcap device. 962 */ 963 return (0); 964 } 965 966 pcap_t * 967 airpcap_create(const char *device, char *ebuf, int *is_ours) 968 { 969 int ret; 970 pcap_t *p; 971 972 /* 973 * This can be called before we've tried loading the library, 974 * so do so if we haven't already tried to do so. 975 */ 976 if (load_airpcap_functions() != AIRPCAP_API_LOADED) { 977 /* 978 * We assume this means that we don't have the AirPcap 979 * software installed, which probably means we don't 980 * have an AirPcap device. 981 * 982 * Don't treat that as an error. 983 */ 984 *is_ours = 0; 985 return (NULL); 986 } 987 988 /* 989 * Is this an AirPcap device? 990 */ 991 ret = device_is_airpcap(device, ebuf); 992 if (ret == 0) { 993 /* No. */ 994 *is_ours = 0; 995 return (NULL); 996 } 997 998 /* 999 * Yes. 1000 */ 1001 *is_ours = 1; 1002 p = PCAP_CREATE_COMMON(ebuf, struct pcap_airpcap); 1003 if (p == NULL) 1004 return (NULL); 1005 1006 p->activate_op = airpcap_activate; 1007 p->can_set_rfmon_op = airpcap_can_set_rfmon; 1008 return (p); 1009 } 1010 1011 /* 1012 * Add all AirPcap devices. 1013 */ 1014 int 1015 airpcap_findalldevs(pcap_if_list_t *devlistp, char *errbuf) 1016 { 1017 AirpcapDeviceDescription *airpcap_devices, *airpcap_device; 1018 char airpcap_errbuf[AIRPCAP_ERRBUF_SIZE]; 1019 1020 /* 1021 * This can be called before we've tried loading the library, 1022 * so do so if we haven't already tried to do so. 1023 */ 1024 if (load_airpcap_functions() != AIRPCAP_API_LOADED) { 1025 /* 1026 * XXX - unless the error is "no such DLL", report this 1027 * as an error rather than as "no AirPcap devices"? 1028 */ 1029 return (0); 1030 } 1031 1032 if (!p_AirpcapGetDeviceList(&airpcap_devices, airpcap_errbuf)) { 1033 snprintf(errbuf, PCAP_ERRBUF_SIZE, 1034 "AirpcapGetDeviceList() failed: %s", airpcap_errbuf); 1035 return (-1); 1036 } 1037 1038 for (airpcap_device = airpcap_devices; airpcap_device != NULL; 1039 airpcap_device = airpcap_device->next) { 1040 if (add_dev(devlistp, airpcap_device->Name, 0, 1041 airpcap_device->Description, errbuf) == NULL) { 1042 /* 1043 * Failure. 1044 */ 1045 p_AirpcapFreeDeviceList(airpcap_devices); 1046 return (-1); 1047 } 1048 } 1049 p_AirpcapFreeDeviceList(airpcap_devices); 1050 return (0); 1051 } 1052