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