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