]> The Tcpdump Group git mirrors - libpcap/blob - pcap-npf.c
Call AirPcap-related routines only if we have them.
[libpcap] / pcap-npf.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 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 #include <errno.h>
39 #define PCAP_DONT_INCLUDE_PCAP_BPF_H
40 #include <Packet32.h>
41 #include <pcap-int.h>
42 #include <pcap/dlt.h>
43
44 /* Old-school MinGW have these headers in a different place.
45 */
46 #if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
47 #include <ddk/ntddndis.h>
48 #include <ddk/ndis.h>
49 #else
50 #include <ntddndis.h> /* MSVC/TDM-MinGW/MinGW64 */
51 #endif
52
53 #ifdef HAVE_DAG_API
54 #include <dagnew.h>
55 #include <dagapi.h>
56 #endif /* HAVE_DAG_API */
57
58 #include "diag-control.h"
59
60 #include "pcap-airpcap.h"
61
62 static int pcap_setfilter_npf(pcap_t *, struct bpf_program *);
63 static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *);
64 static int pcap_getnonblock_npf(pcap_t *);
65 static int pcap_setnonblock_npf(pcap_t *, int);
66
67 /*dimension of the buffer in the pcap_t structure*/
68 #define WIN32_DEFAULT_USER_BUFFER_SIZE 256000
69
70 /*dimension of the buffer in the kernel driver NPF */
71 #define WIN32_DEFAULT_KERNEL_BUFFER_SIZE 1000000
72
73 /* Equivalent to ntohs(), but a lot faster under Windows */
74 #define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8)
75
76 /*
77 * Private data for capturing on WinPcap/Npcap devices.
78 */
79 struct pcap_win {
80 ADAPTER *adapter; /* the packet32 ADAPTER for the device */
81 int nonblock;
82 int rfmon_selfstart; /* a flag tells whether the monitor mode is set by itself */
83 int filtering_in_kernel; /* using kernel filter */
84
85 #ifdef HAVE_DAG_API
86 int dag_fcs_bits; /* Number of checksum bits from link layer */
87 #endif
88
89 #ifdef ENABLE_REMOTE
90 int samp_npkt; /* parameter needed for sampling, with '1 out of N' method has been requested */
91 struct timeval samp_time; /* parameter needed for sampling, with '1 every N ms' method has been requested */
92 #endif
93 };
94
95 /*
96 * Define stub versions of the monitor-mode support routines if this
97 * isn't Npcap. HAVE_NPCAP_PACKET_API is defined by Npcap but not
98 * WinPcap.
99 */
100 #ifndef HAVE_NPCAP_PACKET_API
101 static int
102 PacketIsMonitorModeSupported(PCHAR AdapterName _U_)
103 {
104 /*
105 * We don't support monitor mode.
106 */
107 return (0);
108 }
109
110 static int
111 PacketSetMonitorMode(PCHAR AdapterName _U_, int mode _U_)
112 {
113 /*
114 * This should never be called, as PacketIsMonitorModeSupported()
115 * will return 0, meaning "we don't support monitor mode, so
116 * don't try to turn it on or off".
117 */
118 return (0);
119 }
120
121 static int
122 PacketGetMonitorMode(PCHAR AdapterName _U_)
123 {
124 /*
125 * This should fail, so that pcap_activate_npf() returns
126 * PCAP_ERROR_RFMON_NOTSUP if our caller requested monitor
127 * mode.
128 */
129 return (-1);
130 }
131 #endif
132
133 /*
134 * Sigh. PacketRequest() will have made a DeviceIoControl()
135 * call to the NPF driver to perform the OID request, with a
136 * BIOCQUERYOID ioctl. The kernel code should get back one
137 * of NDIS_STATUS_INVALID_OID, NDIS_STATUS_NOT_SUPPORTED,
138 * or NDIS_STATUS_NOT_RECOGNIZED if the OID request isn't
139 * supported by the OS or the driver, but that doesn't seem
140 * to make it to the caller of PacketRequest() in a
141 * reliable fashion.
142 */
143 #define NDIS_STATUS_INVALID_OID 0xc0010017
144 #define NDIS_STATUS_NOT_SUPPORTED 0xc00000bb /* STATUS_NOT_SUPPORTED */
145 #define NDIS_STATUS_NOT_RECOGNIZED 0x00010001
146
147 static int
148 oid_get_request(ADAPTER *adapter, bpf_u_int32 oid, void *data, size_t *lenp,
149 char *errbuf)
150 {
151 PACKET_OID_DATA *oid_data_arg;
152
153 /*
154 * Allocate a PACKET_OID_DATA structure to hand to PacketRequest().
155 * It should be big enough to hold "*lenp" bytes of data; it
156 * will actually be slightly larger, as PACKET_OID_DATA has a
157 * 1-byte data array at the end, standing in for the variable-length
158 * data that's actually there.
159 */
160 oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp);
161 if (oid_data_arg == NULL) {
162 snprintf(errbuf, PCAP_ERRBUF_SIZE,
163 "Couldn't allocate argument buffer for PacketRequest");
164 return (PCAP_ERROR);
165 }
166
167 /*
168 * No need to copy the data - we're doing a fetch.
169 */
170 oid_data_arg->Oid = oid;
171 oid_data_arg->Length = (ULONG)(*lenp); /* XXX - check for ridiculously large value? */
172 if (!PacketRequest(adapter, FALSE, oid_data_arg)) {
173 pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
174 GetLastError(), "Error calling PacketRequest");
175 free(oid_data_arg);
176 return (-1);
177 }
178
179 /*
180 * Get the length actually supplied.
181 */
182 *lenp = oid_data_arg->Length;
183
184 /*
185 * Copy back the data we fetched.
186 */
187 memcpy(data, oid_data_arg->Data, *lenp);
188 free(oid_data_arg);
189 return (0);
190 }
191
192 static int
193 pcap_stats_npf(pcap_t *p, struct pcap_stat *ps)
194 {
195 struct pcap_win *pw = p->priv;
196 struct bpf_stat bstats;
197
198 /*
199 * Try to get statistics.
200 *
201 * (Please note - "struct pcap_stat" is *not* the same as
202 * WinPcap's "struct bpf_stat". It might currently have the
203 * same layout, but let's not cheat.
204 *
205 * Note also that we don't fill in ps_capt, as we might have
206 * been called by code compiled against an earlier version of
207 * WinPcap that didn't have ps_capt, in which case filling it
208 * in would stomp on whatever comes after the structure passed
209 * to us.
210 */
211 if (!PacketGetStats(pw->adapter, &bstats)) {
212 pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
213 GetLastError(), "PacketGetStats error");
214 return (-1);
215 }
216 ps->ps_recv = bstats.bs_recv;
217 ps->ps_drop = bstats.bs_drop;
218
219 /*
220 * XXX - PacketGetStats() doesn't fill this in, so we just
221 * return 0.
222 */
223 #if 0
224 ps->ps_ifdrop = bstats.ps_ifdrop;
225 #else
226 ps->ps_ifdrop = 0;
227 #endif
228
229 return (0);
230 }
231
232 /*
233 * Win32-only routine for getting statistics.
234 *
235 * This way is definitely safer than passing the pcap_stat * from the userland.
236 * In fact, there could happen than the user allocates a variable which is not
237 * big enough for the new structure, and the library will write in a zone
238 * which is not allocated to this variable.
239 *
240 * In this way, we're pretty sure we are writing on memory allocated to this
241 * variable.
242 *
243 * XXX - but this is the wrong way to handle statistics. Instead, we should
244 * have an API that returns data in a form like the Options section of a
245 * pcapng Interface Statistics Block:
246 *
247 * 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
248 *
249 * which would let us add new statistics straightforwardly and indicate which
250 * statistics we are and are *not* providing, rather than having to provide
251 * possibly-bogus values for statistics we can't provide.
252 */
253 static struct pcap_stat *
254 pcap_stats_ex_npf(pcap_t *p, int *pcap_stat_size)
255 {
256 struct pcap_win *pw = p->priv;
257 struct bpf_stat bstats;
258
259 *pcap_stat_size = sizeof (p->stat);
260
261 /*
262 * Try to get statistics.
263 *
264 * (Please note - "struct pcap_stat" is *not* the same as
265 * WinPcap's "struct bpf_stat". It might currently have the
266 * same layout, but let's not cheat.)
267 */
268 if (!PacketGetStatsEx(pw->adapter, &bstats)) {
269 pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
270 GetLastError(), "PacketGetStatsEx error");
271 return (NULL);
272 }
273 p->stat.ps_recv = bstats.bs_recv;
274 p->stat.ps_drop = bstats.bs_drop;
275 p->stat.ps_ifdrop = bstats.ps_ifdrop;
276 #ifdef ENABLE_REMOTE
277 p->stat.ps_capt = bstats.bs_capt;
278 #endif
279 return (&p->stat);
280 }
281
282 /* Set the dimension of the kernel-level capture buffer */
283 static int
284 pcap_setbuff_npf(pcap_t *p, int dim)
285 {
286 struct pcap_win *pw = p->priv;
287
288 if(PacketSetBuff(pw->adapter,dim)==FALSE)
289 {
290 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
291 return (-1);
292 }
293 return (0);
294 }
295
296 /* Set the driver working mode */
297 static int
298 pcap_setmode_npf(pcap_t *p, int mode)
299 {
300 struct pcap_win *pw = p->priv;
301
302 if(PacketSetMode(pw->adapter,mode)==FALSE)
303 {
304 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized");
305 return (-1);
306 }
307
308 return (0);
309 }
310
311 /*set the minimum amount of data that will release a read call*/
312 static int
313 pcap_setmintocopy_npf(pcap_t *p, int size)
314 {
315 struct pcap_win *pw = p->priv;
316
317 if(PacketSetMinToCopy(pw->adapter, size)==FALSE)
318 {
319 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size");
320 return (-1);
321 }
322 return (0);
323 }
324
325 static HANDLE
326 pcap_getevent_npf(pcap_t *p)
327 {
328 struct pcap_win *pw = p->priv;
329
330 return (PacketGetReadEvent(pw->adapter));
331 }
332
333 static int
334 pcap_oid_get_request_npf(pcap_t *p, bpf_u_int32 oid, void *data, size_t *lenp)
335 {
336 struct pcap_win *pw = p->priv;
337
338 return (oid_get_request(pw->adapter, oid, data, lenp, p->errbuf));
339 }
340
341 static int
342 pcap_oid_set_request_npf(pcap_t *p, bpf_u_int32 oid, const void *data,
343 size_t *lenp)
344 {
345 struct pcap_win *pw = p->priv;
346 PACKET_OID_DATA *oid_data_arg;
347
348 /*
349 * Allocate a PACKET_OID_DATA structure to hand to PacketRequest().
350 * It should be big enough to hold "*lenp" bytes of data; it
351 * will actually be slightly larger, as PACKET_OID_DATA has a
352 * 1-byte data array at the end, standing in for the variable-length
353 * data that's actually there.
354 */
355 oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp);
356 if (oid_data_arg == NULL) {
357 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
358 "Couldn't allocate argument buffer for PacketRequest");
359 return (PCAP_ERROR);
360 }
361
362 oid_data_arg->Oid = oid;
363 oid_data_arg->Length = (ULONG)(*lenp); /* XXX - check for ridiculously large value? */
364 memcpy(oid_data_arg->Data, data, *lenp);
365 if (!PacketRequest(pw->adapter, TRUE, oid_data_arg)) {
366 pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
367 GetLastError(), "Error calling PacketRequest");
368 free(oid_data_arg);
369 return (PCAP_ERROR);
370 }
371
372 /*
373 * Get the length actually copied.
374 */
375 *lenp = oid_data_arg->Length;
376
377 /*
378 * No need to copy the data - we're doing a set.
379 */
380 free(oid_data_arg);
381 return (0);
382 }
383
384 static u_int
385 pcap_sendqueue_transmit_npf(pcap_t *p, pcap_send_queue *queue, int sync)
386 {
387 struct pcap_win *pw = p->priv;
388 u_int res;
389
390 res = PacketSendPackets(pw->adapter,
391 queue->buffer,
392 queue->len,
393 (BOOLEAN)sync);
394
395 if(res != queue->len){
396 pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
397 GetLastError(), "Error queueing packets");
398 }
399
400 return (res);
401 }
402
403 static int
404 pcap_setuserbuffer_npf(pcap_t *p, int size)
405 {
406 unsigned char *new_buff;
407
408 if (size<=0) {
409 /* Bogus parameter */
410 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
411 "Error: invalid size %d",size);
412 return (-1);
413 }
414
415 /* Allocate the buffer */
416 new_buff=(unsigned char*)malloc(sizeof(char)*size);
417
418 if (!new_buff) {
419 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
420 "Error: not enough memory");
421 return (-1);
422 }
423
424 free(p->buffer);
425
426 p->buffer=new_buff;
427 p->bufsize=size;
428
429 return (0);
430 }
431
432 static int
433 pcap_live_dump_npf(pcap_t *p, char *filename, int maxsize, int maxpacks)
434 {
435 struct pcap_win *pw = p->priv;
436 BOOLEAN res;
437
438 /* Set the packet driver in dump mode */
439 res = PacketSetMode(pw->adapter, PACKET_MODE_DUMP);
440 if(res == FALSE){
441 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
442 "Error setting dump mode");
443 return (-1);
444 }
445
446 /* Set the name of the dump file */
447 res = PacketSetDumpName(pw->adapter, filename, (int)strlen(filename));
448 if(res == FALSE){
449 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
450 "Error setting kernel dump file name");
451 return (-1);
452 }
453
454 /* Set the limits of the dump file */
455 res = PacketSetDumpLimits(pw->adapter, maxsize, maxpacks);
456 if(res == FALSE) {
457 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
458 "Error setting dump limit");
459 return (-1);
460 }
461
462 return (0);
463 }
464
465 static int
466 pcap_live_dump_ended_npf(pcap_t *p, int sync)
467 {
468 struct pcap_win *pw = p->priv;
469
470 return (PacketIsDumpEnded(pw->adapter, (BOOLEAN)sync));
471 }
472
473 #ifdef HAVE_AIRPCAP_API
474 static PAirpcapHandle
475 pcap_get_airpcap_handle_npf(pcap_t *p)
476 {
477 struct pcap_win *pw = p->priv;
478
479 return (PacketGetAirPcapHandle(pw->adapter));
480 }
481 #else /* HAVE_AIRPCAP_API */
482 static PAirpcapHandle
483 pcap_get_airpcap_handle_npf(pcap_t *p _U_)
484 {
485 return (NULL);
486 }
487 #endif /* HAVE_AIRPCAP_API */
488
489 static int
490 pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
491 {
492 PACKET Packet;
493 int cc;
494 int n;
495 register u_char *bp, *ep;
496 u_char *datap;
497 struct pcap_win *pw = p->priv;
498
499 cc = p->cc;
500 if (cc == 0) {
501 /*
502 * Has "pcap_breakloop()" been called?
503 */
504 if (p->break_loop) {
505 /*
506 * Yes - clear the flag that indicates that it
507 * has, and return PCAP_ERROR_BREAK to indicate
508 * that we were told to break out of the loop.
509 */
510 p->break_loop = 0;
511 return (PCAP_ERROR_BREAK);
512 }
513
514 /*
515 * Capture the packets.
516 *
517 * The PACKET structure had a bunch of extra stuff for
518 * Windows 9x/Me, but the only interesting data in it
519 * in the versions of Windows that we support is just
520 * a copy of p->buffer, a copy of p->buflen, and the
521 * actual number of bytes read returned from
522 * PacketReceivePacket(), none of which has to be
523 * retained from call to call, so we just keep one on
524 * the stack.
525 */
526 PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
527 if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
528 /*
529 * Did the device go away?
530 * If so, the error we get is ERROR_GEN_FAILURE.
531 */
532 DWORD errcode = GetLastError();
533
534 if (errcode == ERROR_GEN_FAILURE) {
535 /*
536 * The device on which we're capturing
537 * went away, or it became unusable
538 * by NPF due to a suspend/resume.
539 *
540 * XXX - hopefully no other error
541 * conditions are indicated by this.
542 *
543 * XXX - we really should return an
544 * appropriate error for that, but
545 * pcap_dispatch() etc. aren't
546 * documented as having error returns
547 * other than PCAP_ERROR or PCAP_ERROR_BREAK.
548 */
549 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
550 "The interface disappeared");
551 } else {
552 pcap_fmt_errmsg_for_win32_err(p->errbuf,
553 PCAP_ERRBUF_SIZE, errcode,
554 "PacketReceivePacket error");
555 }
556 return (PCAP_ERROR);
557 }
558
559 cc = Packet.ulBytesReceived;
560
561 bp = p->buffer;
562 }
563 else
564 bp = p->bp;
565
566 /*
567 * Loop through each packet.
568 */
569 #define bhp ((struct bpf_hdr *)bp)
570 n = 0;
571 ep = bp + cc;
572 for (;;) {
573 register u_int caplen, hdrlen;
574
575 /*
576 * Has "pcap_breakloop()" been called?
577 * If so, return immediately - if we haven't read any
578 * packets, clear the flag and return PCAP_ERROR_BREAK
579 * to indicate that we were told to break out of the loop,
580 * otherwise leave the flag set, so that the *next* call
581 * will break out of the loop without having read any
582 * packets, and return the number of packets we've
583 * processed so far.
584 */
585 if (p->break_loop) {
586 if (n == 0) {
587 p->break_loop = 0;
588 return (PCAP_ERROR_BREAK);
589 } else {
590 p->bp = bp;
591 p->cc = (int) (ep - bp);
592 return (n);
593 }
594 }
595 if (bp >= ep)
596 break;
597
598 caplen = bhp->bh_caplen;
599 hdrlen = bhp->bh_hdrlen;
600 datap = bp + hdrlen;
601
602 /*
603 * Short-circuit evaluation: if using BPF filter
604 * in kernel, no need to do it now - we already know
605 * the packet passed the filter.
606 *
607 * XXX - pcap_filter() should always return TRUE if
608 * handed a null pointer for the program, but it might
609 * just try to "run" the filter, so we check here.
610 */
611 if (pw->filtering_in_kernel ||
612 p->fcode.bf_insns == NULL ||
613 pcap_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) {
614 #ifdef ENABLE_REMOTE
615 switch (p->rmt_samp.method) {
616
617 case PCAP_SAMP_1_EVERY_N:
618 pw->samp_npkt = (pw->samp_npkt + 1) % p->rmt_samp.value;
619
620 /* Discard all packets that are not '1 out of N' */
621 if (pw->samp_npkt != 0) {
622 bp += Packet_WORDALIGN(caplen + hdrlen);
623 continue;
624 }
625 break;
626
627 case PCAP_SAMP_FIRST_AFTER_N_MS:
628 {
629 struct pcap_pkthdr *pkt_header = (struct pcap_pkthdr*) bp;
630
631 /*
632 * Check if the timestamp of the arrived
633 * packet is smaller than our target time.
634 */
635 if (pkt_header->ts.tv_sec < pw->samp_time.tv_sec ||
636 (pkt_header->ts.tv_sec == pw->samp_time.tv_sec && pkt_header->ts.tv_usec < pw->samp_time.tv_usec)) {
637 bp += Packet_WORDALIGN(caplen + hdrlen);
638 continue;
639 }
640
641 /*
642 * The arrived packet is suitable for being
643 * delivered to our caller, so let's update
644 * the target time.
645 */
646 pw->samp_time.tv_usec = pkt_header->ts.tv_usec + p->rmt_samp.value * 1000;
647 if (pw->samp_time.tv_usec > 1000000) {
648 pw->samp_time.tv_sec = pkt_header->ts.tv_sec + pw->samp_time.tv_usec / 1000000;
649 pw->samp_time.tv_usec = pw->samp_time.tv_usec % 1000000;
650 }
651 }
652 }
653 #endif /* ENABLE_REMOTE */
654
655 /*
656 * XXX A bpf_hdr matches a pcap_pkthdr.
657 */
658 (*callback)(user, (struct pcap_pkthdr*)bp, datap);
659 bp += Packet_WORDALIGN(caplen + hdrlen);
660 if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) {
661 p->bp = bp;
662 p->cc = (int) (ep - bp);
663 return (n);
664 }
665 } else {
666 /*
667 * Skip this packet.
668 */
669 bp += Packet_WORDALIGN(caplen + hdrlen);
670 }
671 }
672 #undef bhp
673 p->cc = 0;
674 return (n);
675 }
676
677 #ifdef HAVE_DAG_API
678 static int
679 pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
680 {
681 struct pcap_win *pw = p->priv;
682 PACKET Packet;
683 u_char *dp = NULL;
684 int packet_len = 0, caplen = 0;
685 struct pcap_pkthdr pcap_header;
686 u_char *endofbuf;
687 int n = 0;
688 dag_record_t *header;
689 unsigned erf_record_len;
690 ULONGLONG ts;
691 int cc;
692 unsigned swt;
693 unsigned dfp = pw->adapter->DagFastProcess;
694
695 cc = p->cc;
696 if (cc == 0) /* Get new packets only if we have processed all the ones of the previous read */
697 {
698 /*
699 * Get new packets from the network.
700 *
701 * The PACKET structure had a bunch of extra stuff for
702 * Windows 9x/Me, but the only interesting data in it
703 * in the versions of Windows that we support is just
704 * a copy of p->buffer, a copy of p->buflen, and the
705 * actual number of bytes read returned from
706 * PacketReceivePacket(), none of which has to be
707 * retained from call to call, so we just keep one on
708 * the stack.
709 */
710 PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
711 if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
712 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
713 return (-1);
714 }
715
716 cc = Packet.ulBytesReceived;
717 if(cc == 0)
718 /* The timeout has expired but we no packets arrived */
719 return (0);
720 header = (dag_record_t*)pw->adapter->DagBuffer;
721 }
722 else
723 header = (dag_record_t*)p->bp;
724
725 endofbuf = (char*)header + cc;
726
727 /*
728 * Cycle through the packets
729 */
730 do
731 {
732 erf_record_len = SWAPS(header->rlen);
733 if((char*)header + erf_record_len > endofbuf)
734 break;
735
736 /* Increase the number of captured packets */
737 p->stat.ps_recv++;
738
739 /* Find the beginning of the packet */
740 dp = ((u_char *)header) + dag_record_size;
741
742 /* Determine actual packet len */
743 switch(header->type)
744 {
745 case TYPE_ATM:
746 packet_len = ATM_SNAPLEN;
747 caplen = ATM_SNAPLEN;
748 dp += 4;
749
750 break;
751
752 case TYPE_ETH:
753 swt = SWAPS(header->wlen);
754 packet_len = swt - (pw->dag_fcs_bits);
755 caplen = erf_record_len - dag_record_size - 2;
756 if (caplen > packet_len)
757 {
758 caplen = packet_len;
759 }
760 dp += 2;
761
762 break;
763
764 case TYPE_HDLC_POS:
765 swt = SWAPS(header->wlen);
766 packet_len = swt - (pw->dag_fcs_bits);
767 caplen = erf_record_len - dag_record_size;
768 if (caplen > packet_len)
769 {
770 caplen = packet_len;
771 }
772
773 break;
774 }
775
776 if(caplen > p->snapshot)
777 caplen = p->snapshot;
778
779 /*
780 * Has "pcap_breakloop()" been called?
781 * If so, return immediately - if we haven't read any
782 * packets, clear the flag and return -2 to indicate
783 * that we were told to break out of the loop, otherwise
784 * leave the flag set, so that the *next* call will break
785 * out of the loop without having read any packets, and
786 * return the number of packets we've processed so far.
787 */
788 if (p->break_loop)
789 {
790 if (n == 0)
791 {
792 p->break_loop = 0;
793 return (-2);
794 }
795 else
796 {
797 p->bp = (char*)header;
798 p->cc = endofbuf - (char*)header;
799 return (n);
800 }
801 }
802
803 if(!dfp)
804 {
805 /* convert between timestamp formats */
806 ts = header->ts;
807 pcap_header.ts.tv_sec = (int)(ts >> 32);
808 ts = (ts & 0xffffffffi64) * 1000000;
809 ts += 0x80000000; /* rounding */
810 pcap_header.ts.tv_usec = (int)(ts >> 32);
811 if (pcap_header.ts.tv_usec >= 1000000) {
812 pcap_header.ts.tv_usec -= 1000000;
813 pcap_header.ts.tv_sec++;
814 }
815 }
816
817 /* No underlaying filtering system. We need to filter on our own */
818 if (p->fcode.bf_insns)
819 {
820 if (pcap_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0)
821 {
822 /* Move to next packet */
823 header = (dag_record_t*)((char*)header + erf_record_len);
824 continue;
825 }
826 }
827
828 /* Fill the header for the user suppplied callback function */
829 pcap_header.caplen = caplen;
830 pcap_header.len = packet_len;
831
832 /* Call the callback function */
833 (*callback)(user, &pcap_header, dp);
834
835 /* Move to next packet */
836 header = (dag_record_t*)((char*)header + erf_record_len);
837
838 /* Stop if the number of packets requested by user has been reached*/
839 if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt))
840 {
841 p->bp = (char*)header;
842 p->cc = endofbuf - (char*)header;
843 return (n);
844 }
845 }
846 while((u_char*)header < endofbuf);
847
848 return (1);
849 }
850 #endif /* HAVE_DAG_API */
851
852 /* Send a packet to the network */
853 static int
854 pcap_inject_npf(pcap_t *p, const void *buf, int size)
855 {
856 struct pcap_win *pw = p->priv;
857 PACKET pkt;
858
859 PacketInitPacket(&pkt, (PVOID)buf, size);
860 if(PacketSendPacket(pw->adapter,&pkt,TRUE) == FALSE) {
861 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketSendPacket failed");
862 return (-1);
863 }
864
865 /*
866 * We assume it all got sent if "PacketSendPacket()" succeeded.
867 * "pcap_inject()" is expected to return the number of bytes
868 * sent.
869 */
870 return (size);
871 }
872
873 static void
874 pcap_cleanup_npf(pcap_t *p)
875 {
876 struct pcap_win *pw = p->priv;
877
878 if (pw->adapter != NULL) {
879 PacketCloseAdapter(pw->adapter);
880 pw->adapter = NULL;
881 }
882 if (pw->rfmon_selfstart)
883 {
884 PacketSetMonitorMode(p->opt.device, 0);
885 }
886 pcap_cleanup_live_common(p);
887 }
888
889 static void
890 pcap_breakloop_npf(pcap_t *p)
891 {
892 pcap_breakloop_common(p);
893 struct pcap_win *pw = p->priv;
894
895 /* XXX - what if this fails? */
896 SetEvent(PacketGetReadEvent(pw->adapter));
897 }
898
899 static int
900 pcap_activate_npf(pcap_t *p)
901 {
902 struct pcap_win *pw = p->priv;
903 NetType type;
904 int res;
905 int status = 0;
906
907 if (p->opt.rfmon) {
908 /*
909 * Monitor mode is supported on Windows Vista and later.
910 */
911 if (PacketGetMonitorMode(p->opt.device) == 1)
912 {
913 pw->rfmon_selfstart = 0;
914 }
915 else
916 {
917 if ((res = PacketSetMonitorMode(p->opt.device, 1)) != 1)
918 {
919 pw->rfmon_selfstart = 0;
920 // Monitor mode is not supported.
921 if (res == 0)
922 {
923 return PCAP_ERROR_RFMON_NOTSUP;
924 }
925 else
926 {
927 return PCAP_ERROR;
928 }
929 }
930 else
931 {
932 pw->rfmon_selfstart = 1;
933 }
934 }
935 }
936
937 /* Init Winsock if it hasn't already been initialized */
938 pcap_wsockinit();
939
940 pw->adapter = PacketOpenAdapter(p->opt.device);
941
942 if (pw->adapter == NULL)
943 {
944 DWORD errcode = GetLastError();
945
946 /*
947 * What error did we get when trying to open the adapter?
948 */
949 switch (errcode) {
950
951 case ERROR_BAD_UNIT:
952 /*
953 * There's no such device.
954 */
955 return (PCAP_ERROR_NO_SUCH_DEVICE);
956
957 case ERROR_ACCESS_DENIED:
958 /*
959 * There is, but we don't have permission to
960 * use it.
961 */
962 return (PCAP_ERROR_PERM_DENIED);
963
964 default:
965 /*
966 * Unknown - report details.
967 */
968 pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
969 errcode, "Error opening adapter");
970 if (pw->rfmon_selfstart)
971 {
972 PacketSetMonitorMode(p->opt.device, 0);
973 }
974 return (PCAP_ERROR);
975 }
976 }
977
978 /*get network type*/
979 if(PacketGetNetType (pw->adapter,&type) == FALSE)
980 {
981 pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
982 GetLastError(), "Cannot determine the network type");
983 goto bad;
984 }
985
986 /*Set the linktype*/
987 switch (type.LinkType)
988 {
989 case NdisMediumWan:
990 p->linktype = DLT_EN10MB;
991 break;
992
993 case NdisMedium802_3:
994 p->linktype = DLT_EN10MB;
995 /*
996 * This is (presumably) a real Ethernet capture; give it a
997 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
998 * that an application can let you choose it, in case you're
999 * capturing DOCSIS traffic that a Cisco Cable Modem
1000 * Termination System is putting out onto an Ethernet (it
1001 * doesn't put an Ethernet header onto the wire, it puts raw
1002 * DOCSIS frames out on the wire inside the low-level
1003 * Ethernet framing).
1004 */
1005 p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
1006 /*
1007 * If that fails, just leave the list empty.
1008 */
1009 if (p->dlt_list != NULL) {
1010 p->dlt_list[0] = DLT_EN10MB;
1011 p->dlt_list[1] = DLT_DOCSIS;
1012 p->dlt_count = 2;
1013 }
1014 break;
1015
1016 case NdisMediumFddi:
1017 p->linktype = DLT_FDDI;
1018 break;
1019
1020 case NdisMedium802_5:
1021 p->linktype = DLT_IEEE802;
1022 break;
1023
1024 case NdisMediumArcnetRaw:
1025 p->linktype = DLT_ARCNET;
1026 break;
1027
1028 case NdisMediumArcnet878_2:
1029 p->linktype = DLT_ARCNET;
1030 break;
1031
1032 case NdisMediumAtm:
1033 p->linktype = DLT_ATM_RFC1483;
1034 break;
1035
1036 case NdisMediumCHDLC:
1037 p->linktype = DLT_CHDLC;
1038 break;
1039
1040 case NdisMediumPPPSerial:
1041 p->linktype = DLT_PPP_SERIAL;
1042 break;
1043
1044 case NdisMediumNull:
1045 p->linktype = DLT_NULL;
1046 break;
1047
1048 case NdisMediumBare80211:
1049 p->linktype = DLT_IEEE802_11;
1050 break;
1051
1052 case NdisMediumRadio80211:
1053 p->linktype = DLT_IEEE802_11_RADIO;
1054 break;
1055
1056 case NdisMediumPpi:
1057 p->linktype = DLT_PPI;
1058 break;
1059
1060 case NdisMediumWirelessWan:
1061 p->linktype = DLT_RAW;
1062 break;
1063
1064 default:
1065 /*
1066 * An unknown medium type is assumed to supply Ethernet
1067 * headers; if not, the user will have to report it,
1068 * so that the medium type and link-layer header type
1069 * can be determined. If we were to fail here, we
1070 * might get the link-layer type in the error, but
1071 * the user wouldn't get a capture, so we wouldn't
1072 * be able to determine the link-layer type; we report
1073 * a warning with the link-layer type, so at least
1074 * some programs will report the warning.
1075 */
1076 p->linktype = DLT_EN10MB;
1077 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1078 "Unknown NdisMedium value %d, defaulting to DLT_EN10MB",
1079 type.LinkType);
1080 status = PCAP_WARNING;
1081 break;
1082 }
1083
1084 /*
1085 * Turn a negative snapshot value (invalid), a snapshot value of
1086 * 0 (unspecified), or a value bigger than the normal maximum
1087 * value, into the maximum allowed value.
1088 *
1089 * If some application really *needs* a bigger snapshot
1090 * length, we should just increase MAXIMUM_SNAPLEN.
1091 */
1092 if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
1093 p->snapshot = MAXIMUM_SNAPLEN;
1094
1095 /* Set promiscuous mode */
1096 if (p->opt.promisc)
1097 {
1098
1099 if (PacketSetHwFilter(pw->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
1100 {
1101 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode");
1102 goto bad;
1103 }
1104 }
1105 else
1106 {
1107 /* NDIS_PACKET_TYPE_ALL_LOCAL selects "All packets sent by installed
1108 * protocols and all packets indicated by the NIC" but if no protocol
1109 * drivers (like TCP/IP) are installed, NDIS_PACKET_TYPE_DIRECTED,
1110 * NDIS_PACKET_TYPE_BROADCAST, and NDIS_PACKET_TYPE_MULTICAST are needed to
1111 * capture incoming frames.
1112 */
1113 if (PacketSetHwFilter(pw->adapter,
1114 NDIS_PACKET_TYPE_ALL_LOCAL |
1115 NDIS_PACKET_TYPE_DIRECTED |
1116 NDIS_PACKET_TYPE_BROADCAST |
1117 NDIS_PACKET_TYPE_MULTICAST) == FALSE)
1118 {
1119 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode");
1120 goto bad;
1121 }
1122 }
1123
1124 /* Set the buffer size */
1125 p->bufsize = WIN32_DEFAULT_USER_BUFFER_SIZE;
1126
1127 if(!(pw->adapter->Flags & INFO_FLAG_DAG_CARD))
1128 {
1129 /*
1130 * Traditional Adapter
1131 */
1132 /*
1133 * If the buffer size wasn't explicitly set, default to
1134 * WIN32_DEFAULT_KERNEL_BUFFER_SIZE.
1135 */
1136 if (p->opt.buffer_size == 0)
1137 p->opt.buffer_size = WIN32_DEFAULT_KERNEL_BUFFER_SIZE;
1138
1139 if(PacketSetBuff(pw->adapter,p->opt.buffer_size)==FALSE)
1140 {
1141 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
1142 goto bad;
1143 }
1144
1145 p->buffer = malloc(p->bufsize);
1146 if (p->buffer == NULL)
1147 {
1148 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
1149 errno, "malloc");
1150 goto bad;
1151 }
1152
1153 if (p->opt.immediate)
1154 {
1155 /* tell the driver to copy the buffer as soon as data arrives */
1156 if(PacketSetMinToCopy(pw->adapter,0)==FALSE)
1157 {
1158 pcap_fmt_errmsg_for_win32_err(p->errbuf,
1159 PCAP_ERRBUF_SIZE, GetLastError(),
1160 "Error calling PacketSetMinToCopy");
1161 goto bad;
1162 }
1163 }
1164 else
1165 {
1166 /* tell the driver to copy the buffer only if it contains at least 16K */
1167 if(PacketSetMinToCopy(pw->adapter,16000)==FALSE)
1168 {
1169 pcap_fmt_errmsg_for_win32_err(p->errbuf,
1170 PCAP_ERRBUF_SIZE, GetLastError(),
1171 "Error calling PacketSetMinToCopy");
1172 goto bad;
1173 }
1174 }
1175 } else {
1176 /*
1177 * Dag Card
1178 */
1179 #ifdef HAVE_DAG_API
1180 /*
1181 * We have DAG support.
1182 */
1183 LONG status;
1184 HKEY dagkey;
1185 DWORD lptype;
1186 DWORD lpcbdata;
1187 int postype = 0;
1188 char keyname[512];
1189
1190 snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s",
1191 "SYSTEM\\CurrentControlSet\\Services\\DAG",
1192 strstr(_strlwr(p->opt.device), "dag"));
1193 do
1194 {
1195 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey);
1196 if(status != ERROR_SUCCESS)
1197 break;
1198
1199 status = RegQueryValueEx(dagkey,
1200 "PosType",
1201 NULL,
1202 &lptype,
1203 (char*)&postype,
1204 &lpcbdata);
1205
1206 if(status != ERROR_SUCCESS)
1207 {
1208 postype = 0;
1209 }
1210
1211 RegCloseKey(dagkey);
1212 }
1213 while(FALSE);
1214
1215
1216 p->snapshot = PacketSetSnapLen(pw->adapter, p->snapshot);
1217
1218 /* Set the length of the FCS associated to any packet. This value
1219 * will be subtracted to the packet length */
1220 pw->dag_fcs_bits = pw->adapter->DagFcsLen;
1221 #else /* HAVE_DAG_API */
1222 /*
1223 * No DAG support.
1224 */
1225 goto bad;
1226 #endif /* HAVE_DAG_API */
1227 }
1228
1229 PacketSetReadTimeout(pw->adapter, p->opt.timeout);
1230
1231 /* disable loopback capture if requested */
1232 if (p->opt.nocapture_local)
1233 {
1234 if (!PacketSetLoopbackBehavior(pw->adapter, NPF_DISABLE_LOOPBACK))
1235 {
1236 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1237 "Unable to disable the capture of loopback packets.");
1238 goto bad;
1239 }
1240 }
1241
1242 #ifdef HAVE_DAG_API
1243 if(pw->adapter->Flags & INFO_FLAG_DAG_CARD)
1244 {
1245 /* install dag specific handlers for read and setfilter */
1246 p->read_op = pcap_read_win32_dag;
1247 p->setfilter_op = pcap_setfilter_win32_dag;
1248 }
1249 else
1250 {
1251 #endif /* HAVE_DAG_API */
1252 /* install traditional npf handlers for read and setfilter */
1253 p->read_op = pcap_read_npf;
1254 p->setfilter_op = pcap_setfilter_npf;
1255 #ifdef HAVE_DAG_API
1256 }
1257 #endif /* HAVE_DAG_API */
1258 p->setdirection_op = NULL; /* Not implemented. */
1259 /* XXX - can this be implemented on some versions of Windows? */
1260 p->inject_op = pcap_inject_npf;
1261 p->set_datalink_op = NULL; /* can't change data link type */
1262 p->getnonblock_op = pcap_getnonblock_npf;
1263 p->setnonblock_op = pcap_setnonblock_npf;
1264 p->stats_op = pcap_stats_npf;
1265 p->breakloop_op = pcap_breakloop_npf;
1266 p->stats_ex_op = pcap_stats_ex_npf;
1267 p->setbuff_op = pcap_setbuff_npf;
1268 p->setmode_op = pcap_setmode_npf;
1269 p->setmintocopy_op = pcap_setmintocopy_npf;
1270 p->getevent_op = pcap_getevent_npf;
1271 p->oid_get_request_op = pcap_oid_get_request_npf;
1272 p->oid_set_request_op = pcap_oid_set_request_npf;
1273 p->sendqueue_transmit_op = pcap_sendqueue_transmit_npf;
1274 p->setuserbuffer_op = pcap_setuserbuffer_npf;
1275 p->live_dump_op = pcap_live_dump_npf;
1276 p->live_dump_ended_op = pcap_live_dump_ended_npf;
1277 p->get_airpcap_handle_op = pcap_get_airpcap_handle_npf;
1278 p->cleanup_op = pcap_cleanup_npf;
1279
1280 /*
1281 * XXX - this is only done because WinPcap supported
1282 * pcap_fileno() returning the hFile HANDLE from the
1283 * ADAPTER structure. We make no general guarantees
1284 * that the caller can do anything useful with it.
1285 *
1286 * (Not that we make any general guarantee of that
1287 * sort on UN*X, either, any more, given that not
1288 * all capture devices are regular OS network
1289 * interfaces.)
1290 */
1291 p->handle = pw->adapter->hFile;
1292
1293 return (status);
1294 bad:
1295 pcap_cleanup_npf(p);
1296 return (PCAP_ERROR);
1297 }
1298
1299 /*
1300 * Check if rfmon mode is supported on the pcap_t for Windows systems.
1301 */
1302 static int
1303 pcap_can_set_rfmon_npf(pcap_t *p)
1304 {
1305 return (PacketIsMonitorModeSupported(p->opt.device) == 1);
1306 }
1307
1308 pcap_t *
1309 pcap_create_interface(const char *device _U_, char *ebuf)
1310 {
1311 pcap_t *p;
1312
1313 p = pcap_create_common(ebuf, sizeof(struct pcap_win));
1314 if (p == NULL)
1315 return (NULL);
1316
1317 p->activate_op = pcap_activate_npf;
1318 p->can_set_rfmon_op = pcap_can_set_rfmon_npf;
1319 return (p);
1320 }
1321
1322 static int
1323 pcap_setfilter_npf(pcap_t *p, struct bpf_program *fp)
1324 {
1325 struct pcap_win *pw = p->priv;
1326
1327 if(PacketSetBpf(pw->adapter,fp)==FALSE){
1328 /*
1329 * Kernel filter not installed.
1330 *
1331 * XXX - we don't know whether this failed because:
1332 *
1333 * the kernel rejected the filter program as invalid,
1334 * in which case we should fall back on userland
1335 * filtering;
1336 *
1337 * the kernel rejected the filter program as too big,
1338 * in which case we should again fall back on
1339 * userland filtering;
1340 *
1341 * there was some other problem, in which case we
1342 * should probably report an error.
1343 *
1344 * For NPF devices, the Win32 status will be
1345 * STATUS_INVALID_DEVICE_REQUEST for invalid
1346 * filters, but I don't know what it'd be for
1347 * other problems, and for some other devices
1348 * it might not be set at all.
1349 *
1350 * So we just fall back on userland filtering in
1351 * all cases.
1352 */
1353
1354 /*
1355 * install_bpf_program() validates the program.
1356 *
1357 * XXX - what if we already have a filter in the kernel?
1358 */
1359 if (install_bpf_program(p, fp) < 0)
1360 return (-1);
1361 pw->filtering_in_kernel = 0; /* filtering in userland */
1362 return (0);
1363 }
1364
1365 /*
1366 * It worked.
1367 */
1368 pw->filtering_in_kernel = 1; /* filtering in the kernel */
1369
1370 /*
1371 * Discard any previously-received packets, as they might have
1372 * passed whatever filter was formerly in effect, but might
1373 * not pass this filter (BIOCSETF discards packets buffered
1374 * in the kernel, so you can lose packets in any case).
1375 */
1376 p->cc = 0;
1377 return (0);
1378 }
1379
1380 /*
1381 * We filter at user level, since the kernel driver does't process the packets
1382 */
1383 static int
1384 pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {
1385
1386 if(!fp)
1387 {
1388 pcap_strlcpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf));
1389 return (-1);
1390 }
1391
1392 /* Install a user level filter */
1393 if (install_bpf_program(p, fp) < 0)
1394 return (-1);
1395
1396 return (0);
1397 }
1398
1399 static int
1400 pcap_getnonblock_npf(pcap_t *p)
1401 {
1402 struct pcap_win *pw = p->priv;
1403
1404 /*
1405 * XXX - if there were a PacketGetReadTimeout() call, we
1406 * would use it, and return 1 if the timeout is -1
1407 * and 0 otherwise.
1408 */
1409 return (pw->nonblock);
1410 }
1411
1412 static int
1413 pcap_setnonblock_npf(pcap_t *p, int nonblock)
1414 {
1415 struct pcap_win *pw = p->priv;
1416 int newtimeout;
1417
1418 if (nonblock) {
1419 /*
1420 * Set the packet buffer timeout to -1 for non-blocking
1421 * mode.
1422 */
1423 newtimeout = -1;
1424 } else {
1425 /*
1426 * Restore the timeout set when the device was opened.
1427 * (Note that this may be -1, in which case we're not
1428 * really leaving non-blocking mode. However, although
1429 * the timeout argument to pcap_set_timeout() and
1430 * pcap_open_live() is an int, you're not supposed to
1431 * supply a negative value, so that "shouldn't happen".)
1432 */
1433 newtimeout = p->opt.timeout;
1434 }
1435 if (!PacketSetReadTimeout(pw->adapter, newtimeout)) {
1436 pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
1437 GetLastError(), "PacketSetReadTimeout");
1438 return (-1);
1439 }
1440 pw->nonblock = (newtimeout == -1);
1441 return (0);
1442 }
1443
1444 static int
1445 pcap_add_if_npf(pcap_if_list_t *devlistp, char *name, bpf_u_int32 flags,
1446 const char *description, char *errbuf)
1447 {
1448 pcap_if_t *curdev;
1449 npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
1450 LONG if_addr_size;
1451 int res = 0;
1452
1453 if_addr_size = MAX_NETWORK_ADDRESSES;
1454
1455 /*
1456 * Add an entry for this interface, with no addresses.
1457 */
1458 curdev = add_dev(devlistp, name, flags, description, errbuf);
1459 if (curdev == NULL) {
1460 /*
1461 * Failure.
1462 */
1463 return (-1);
1464 }
1465
1466 /*
1467 * Get the list of addresses for the interface.
1468 */
1469 if (!PacketGetNetInfoEx((void *)name, if_addrs, &if_addr_size)) {
1470 /*
1471 * Failure.
1472 *
1473 * We don't return an error, because this can happen with
1474 * NdisWan interfaces, and we want to supply them even
1475 * if we can't supply their addresses.
1476 *
1477 * We return an entry with an empty address list.
1478 */
1479 return (0);
1480 }
1481
1482 /*
1483 * Now add the addresses.
1484 */
1485 while (if_addr_size-- > 0) {
1486 /*
1487 * "curdev" is an entry for this interface; add an entry for
1488 * this address to its list of addresses.
1489 */
1490 res = add_addr_to_dev(curdev,
1491 (struct sockaddr *)&if_addrs[if_addr_size].IPAddress,
1492 sizeof (struct sockaddr_storage),
1493 (struct sockaddr *)&if_addrs[if_addr_size].SubnetMask,
1494 sizeof (struct sockaddr_storage),
1495 (struct sockaddr *)&if_addrs[if_addr_size].Broadcast,
1496 sizeof (struct sockaddr_storage),
1497 NULL,
1498 0,
1499 errbuf);
1500 if (res == -1) {
1501 /*
1502 * Failure.
1503 */
1504 break;
1505 }
1506 }
1507
1508 return (res);
1509 }
1510
1511 static int
1512 get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
1513 {
1514 char *name_copy;
1515 ADAPTER *adapter;
1516 int status;
1517 size_t len;
1518 NDIS_HARDWARE_STATUS hardware_status;
1519 #ifdef OID_GEN_PHYSICAL_MEDIUM
1520 NDIS_PHYSICAL_MEDIUM phys_medium;
1521 bpf_u_int32 gen_physical_medium_oids[] = {
1522 #ifdef OID_GEN_PHYSICAL_MEDIUM_EX
1523 OID_GEN_PHYSICAL_MEDIUM_EX,
1524 #endif
1525 OID_GEN_PHYSICAL_MEDIUM
1526 };
1527 #define N_GEN_PHYSICAL_MEDIUM_OIDS (sizeof gen_physical_medium_oids / sizeof gen_physical_medium_oids[0])
1528 size_t i;
1529 #endif /* OID_GEN_PHYSICAL_MEDIUM */
1530 #ifdef OID_GEN_LINK_STATE
1531 NDIS_LINK_STATE link_state;
1532 #endif
1533 int connect_status;
1534
1535 if (*flags & PCAP_IF_LOOPBACK) {
1536 /*
1537 * Loopback interface, so the connection status doesn't
1538 * apply. and it's not wireless (or wired, for that
1539 * matter...). We presume it's up and running.
1540 */
1541 *flags |= PCAP_IF_UP | PCAP_IF_RUNNING | PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
1542 return (0);
1543 }
1544
1545 /*
1546 * We need to open the adapter to get this information.
1547 *
1548 * XXX - PacketOpenAdapter() takes a non-const pointer
1549 * as an argument, so we make a copy of the argument and
1550 * pass that to it.
1551 */
1552 name_copy = strdup(name);
1553 adapter = PacketOpenAdapter(name_copy);
1554 free(name_copy);
1555 if (adapter == NULL) {
1556 /*
1557 * Give up; if they try to open this device, it'll fail.
1558 */
1559 return (0);
1560 }
1561
1562 #ifdef HAVE_AIRPCAP_API
1563 /*
1564 * Airpcap.sys do not support the below 'OID_GEN_x' values.
1565 * Just set these flags (and none of the '*flags' entered with).
1566 */
1567 if (PacketGetAirPcapHandle(adapter)) {
1568 /*
1569 * Must be "up" and "running" if the above if succeeded.
1570 */
1571 *flags = PCAP_IF_UP | PCAP_IF_RUNNING;
1572
1573 /*
1574 * An airpcap device is a wireless device (duh!)
1575 */
1576 *flags |= PCAP_IF_WIRELESS;
1577
1578 /*
1579 * A "network assosiation state" makes no sense for airpcap.
1580 */
1581 *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE;
1582 PacketCloseAdapter(adapter);
1583 return (0);
1584 }
1585 #endif
1586
1587 /*
1588 * Get the hardware status, and derive "up" and "running" from
1589 * that.
1590 */
1591 len = sizeof (hardware_status);
1592 status = oid_get_request(adapter, OID_GEN_HARDWARE_STATUS,
1593 &hardware_status, &len, errbuf);
1594 if (status == 0) {
1595 switch (hardware_status) {
1596
1597 case NdisHardwareStatusReady:
1598 /*
1599 * "Available and capable of sending and receiving
1600 * data over the wire", so up and running.
1601 */
1602 *flags |= PCAP_IF_UP | PCAP_IF_RUNNING;
1603 break;
1604
1605 case NdisHardwareStatusInitializing:
1606 case NdisHardwareStatusReset:
1607 /*
1608 * "Initializing" or "Resetting", so up, but
1609 * not running.
1610 */
1611 *flags |= PCAP_IF_UP;
1612 break;
1613
1614 case NdisHardwareStatusClosing:
1615 case NdisHardwareStatusNotReady:
1616 /*
1617 * "Closing" or "Not ready", so neither up nor
1618 * running.
1619 */
1620 break;
1621
1622 default:
1623 /*
1624 * Unknown.
1625 */
1626 break;
1627 }
1628 } else {
1629 /*
1630 * Can't get the hardware status, so assume both up and
1631 * running.
1632 */
1633 *flags |= PCAP_IF_UP | PCAP_IF_RUNNING;
1634 }
1635
1636 /*
1637 * Get the network type.
1638 */
1639 #ifdef OID_GEN_PHYSICAL_MEDIUM
1640 /*
1641 * Try the OIDs we have for this, in order.
1642 */
1643 for (i = 0; i < N_GEN_PHYSICAL_MEDIUM_OIDS; i++) {
1644 len = sizeof (phys_medium);
1645 status = oid_get_request(adapter, gen_physical_medium_oids[i],
1646 &phys_medium, &len, errbuf);
1647 if (status == 0) {
1648 /*
1649 * Success.
1650 */
1651 break;
1652 }
1653 /*
1654 * Failed. We can't determine whether it failed
1655 * because that particular OID isn't supported
1656 * or because some other problem occurred, so we
1657 * just drive on and try the next OID.
1658 */
1659 }
1660 if (status == 0) {
1661 /*
1662 * We got the physical medium.
1663 */
1664 switch (phys_medium) {
1665
1666 case NdisPhysicalMediumWirelessLan:
1667 case NdisPhysicalMediumWirelessWan:
1668 case NdisPhysicalMediumNative802_11:
1669 case NdisPhysicalMediumBluetooth:
1670 case NdisPhysicalMediumUWB:
1671 case NdisPhysicalMediumIrda:
1672 /*
1673 * Wireless.
1674 */
1675 *flags |= PCAP_IF_WIRELESS;
1676 break;
1677
1678 default:
1679 /*
1680 * Not wireless.
1681 */
1682 break;
1683 }
1684 }
1685 #endif
1686
1687 /*
1688 * Get the connection status.
1689 */
1690 #ifdef OID_GEN_LINK_STATE
1691 len = sizeof(link_state);
1692 status = oid_get_request(adapter, OID_GEN_LINK_STATE, &link_state,
1693 &len, errbuf);
1694 if (status == 0) {
1695 /*
1696 * NOTE: this also gives us the receive and transmit
1697 * link state.
1698 */
1699 switch (link_state.MediaConnectState) {
1700
1701 case MediaConnectStateConnected:
1702 /*
1703 * It's connected.
1704 */
1705 *flags |= PCAP_IF_CONNECTION_STATUS_CONNECTED;
1706 break;
1707
1708 case MediaConnectStateDisconnected:
1709 /*
1710 * It's disconnected.
1711 */
1712 *flags |= PCAP_IF_CONNECTION_STATUS_DISCONNECTED;
1713 break;
1714
1715 default:
1716 /*
1717 * It's unknown whether it's connected or not.
1718 */
1719 break;
1720 }
1721 }
1722 #else
1723 /*
1724 * OID_GEN_LINK_STATE isn't supported because it's not in our SDK.
1725 */
1726 status = -1;
1727 #endif
1728 if (status == -1) {
1729 /*
1730 * OK, OID_GEN_LINK_STATE didn't work, try
1731 * OID_GEN_MEDIA_CONNECT_STATUS.
1732 */
1733 status = oid_get_request(adapter, OID_GEN_MEDIA_CONNECT_STATUS,
1734 &connect_status, &len, errbuf);
1735 if (status == 0) {
1736 switch (connect_status) {
1737
1738 case NdisMediaStateConnected:
1739 /*
1740 * It's connected.
1741 */
1742 *flags |= PCAP_IF_CONNECTION_STATUS_CONNECTED;
1743 break;
1744
1745 case NdisMediaStateDisconnected:
1746 /*
1747 * It's disconnected.
1748 */
1749 *flags |= PCAP_IF_CONNECTION_STATUS_DISCONNECTED;
1750 break;
1751 }
1752 }
1753 }
1754 PacketCloseAdapter(adapter);
1755 return (0);
1756 }
1757
1758 int
1759 pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
1760 {
1761 int ret = 0;
1762 const char *desc;
1763 char *AdaptersName;
1764 ULONG NameLength;
1765 char *name;
1766
1767 /*
1768 * Find out how big a buffer we need.
1769 *
1770 * This call should always return FALSE; if the error is
1771 * ERROR_INSUFFICIENT_BUFFER, NameLength will be set to
1772 * the size of the buffer we need, otherwise there's a
1773 * problem, and NameLength should be set to 0.
1774 *
1775 * It shouldn't require NameLength to be set, but,
1776 * at least as of WinPcap 4.1.3, it checks whether
1777 * NameLength is big enough before it checks for a
1778 * NULL buffer argument, so, while it'll still do
1779 * the right thing if NameLength is uninitialized and
1780 * whatever junk happens to be there is big enough
1781 * (because the pointer argument will be null), it's
1782 * still reading an uninitialized variable.
1783 */
1784 NameLength = 0;
1785 if (!PacketGetAdapterNames(NULL, &NameLength))
1786 {
1787 DWORD last_error = GetLastError();
1788
1789 if (last_error != ERROR_INSUFFICIENT_BUFFER)
1790 {
1791 pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
1792 last_error, "PacketGetAdapterNames");
1793 return (-1);
1794 }
1795 }
1796
1797 if (NameLength <= 0)
1798 return 0;
1799 AdaptersName = (char*) malloc(NameLength);
1800 if (AdaptersName == NULL)
1801 {
1802 snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters.");
1803 return (-1);
1804 }
1805
1806 if (!PacketGetAdapterNames(AdaptersName, &NameLength)) {
1807 pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
1808 GetLastError(), "PacketGetAdapterNames");
1809 free(AdaptersName);
1810 return (-1);
1811 }
1812
1813 /*
1814 * "PacketGetAdapterNames()" returned a list of
1815 * null-terminated ASCII interface name strings,
1816 * terminated by a null string, followed by a list
1817 * of null-terminated ASCII interface description
1818 * strings, terminated by a null string.
1819 * This means there are two ASCII nulls at the end
1820 * of the first list.
1821 *
1822 * Find the end of the first list; that's the
1823 * beginning of the second list.
1824 */
1825 desc = &AdaptersName[0];
1826 while (*desc != '\0' || *(desc + 1) != '\0')
1827 desc++;
1828
1829 /*
1830 * Found it - "desc" points to the first of the two
1831 * nulls at the end of the list of names, so the
1832 * first byte of the list of descriptions is two bytes
1833 * after it.
1834 */
1835 desc += 2;
1836
1837 /*
1838 * Loop over the elements in the first list.
1839 */
1840 name = &AdaptersName[0];
1841 while (*name != '\0') {
1842 bpf_u_int32 flags = 0;
1843
1844 #ifdef HAVE_AIRPCAP_API
1845 /*
1846 * Is this an AirPcap device?
1847 * If so, ignore it; it'll get added later, by the
1848 * AirPcap code.
1849 */
1850 if (device_is_airpcap(name, errbuf) == 1) {
1851 name += strlen(name) + 1;
1852 desc += strlen(desc) + 1;
1853 continue;
1854 }
1855 #endif
1856
1857 #ifdef HAVE_PACKET_IS_LOOPBACK_ADAPTER
1858 /*
1859 * Is this a loopback interface?
1860 */
1861 if (PacketIsLoopbackAdapter(name)) {
1862 /* Yes */
1863 flags |= PCAP_IF_LOOPBACK;
1864 }
1865 #endif
1866 /*
1867 * Get additional flags.
1868 */
1869 if (get_if_flags(name, &flags, errbuf) == -1) {
1870 /*
1871 * Failure.
1872 */
1873 ret = -1;
1874 break;
1875 }
1876
1877 /*
1878 * Add an entry for this interface.
1879 */
1880 if (pcap_add_if_npf(devlistp, name, flags, desc,
1881 errbuf) == -1) {
1882 /*
1883 * Failure.
1884 */
1885 ret = -1;
1886 break;
1887 }
1888 name += strlen(name) + 1;
1889 desc += strlen(desc) + 1;
1890 }
1891
1892 free(AdaptersName);
1893 return (ret);
1894 }
1895
1896 /*
1897 * Return the name of a network interface attached to the system, or NULL
1898 * if none can be found. The interface must be configured up; the
1899 * lowest unit number is preferred; loopback is ignored.
1900 *
1901 * In the best of all possible worlds, this would be the same as on
1902 * UN*X, but there may be software that expects this to return a
1903 * full list of devices after the first device.
1904 */
1905 #define ADAPTERSNAME_LEN 8192
1906 char *
1907 pcap_lookupdev(char *errbuf)
1908 {
1909 DWORD dwVersion;
1910 DWORD dwWindowsMajorVersion;
1911
1912 /*
1913 * We disable this in "new API" mode, because 1) in WinPcap/Npcap,
1914 * it may return UTF-16 strings, for backwards-compatibility
1915 * reasons, and we're also disabling the hack to make that work,
1916 * for not-going-past-the-end-of-a-string reasons, and 2) we
1917 * want its behavior to be consistent.
1918 *
1919 * In addition, it's not thread-safe, so we've marked it as
1920 * deprecated.
1921 */
1922 if (pcap_new_api) {
1923 snprintf(errbuf, PCAP_ERRBUF_SIZE,
1924 "pcap_lookupdev() is deprecated and is not supported in programs calling pcap_init()");
1925 return (NULL);
1926 }
1927
1928 /* disable MSVC's GetVersion() deprecated warning here */
1929 DIAG_OFF_DEPRECATION
1930 dwVersion = GetVersion(); /* get the OS version */
1931 DIAG_ON_DEPRECATION
1932 dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
1933
1934 if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
1935 /*
1936 * Windows 95, 98, ME.
1937 */
1938 ULONG NameLength = ADAPTERSNAME_LEN;
1939 static char AdaptersName[ADAPTERSNAME_LEN];
1940
1941 if (PacketGetAdapterNames(AdaptersName,&NameLength) )
1942 return (AdaptersName);
1943 else
1944 return NULL;
1945 } else {
1946 /*
1947 * Windows NT (NT 4.0 and later).
1948 * Convert the names to Unicode for backward compatibility.
1949 */
1950 ULONG NameLength = ADAPTERSNAME_LEN;
1951 static WCHAR AdaptersName[ADAPTERSNAME_LEN];
1952 size_t BufferSpaceLeft;
1953 char *tAstr;
1954 WCHAR *Unameptr;
1955 char *Adescptr;
1956 size_t namelen, i;
1957 WCHAR *TAdaptersName = (WCHAR*)malloc(ADAPTERSNAME_LEN * sizeof(WCHAR));
1958 int NAdapts = 0;
1959
1960 if(TAdaptersName == NULL)
1961 {
1962 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
1963 return NULL;
1964 }
1965
1966 if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
1967 {
1968 pcap_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
1969 GetLastError(), "PacketGetAdapterNames");
1970 free(TAdaptersName);
1971 return NULL;
1972 }
1973
1974
1975 BufferSpaceLeft = ADAPTERSNAME_LEN * sizeof(WCHAR);
1976 tAstr = (char*)TAdaptersName;
1977 Unameptr = AdaptersName;
1978
1979 /*
1980 * Convert the device names to Unicode into AdapterName.
1981 */
1982 do {
1983 /*
1984 * Length of the name, including the terminating
1985 * NUL.
1986 */
1987 namelen = strlen(tAstr) + 1;
1988
1989 /*
1990 * Do we have room for the name in the Unicode
1991 * buffer?
1992 */
1993 if (BufferSpaceLeft < namelen * sizeof(WCHAR)) {
1994 /*
1995 * No.
1996 */
1997 goto quit;
1998 }
1999 BufferSpaceLeft -= namelen * sizeof(WCHAR);
2000
2001 /*
2002 * Copy the name, converting ASCII to Unicode.
2003 * namelen includes the NUL, so we copy it as
2004 * well.
2005 */
2006 for (i = 0; i < namelen; i++)
2007 *Unameptr++ = *tAstr++;
2008
2009 /*
2010 * Count this adapter.
2011 */
2012 NAdapts++;
2013 } while (namelen != 1);
2014
2015 /*
2016 * Copy the descriptions, but don't convert them from
2017 * ASCII to Unicode.
2018 */
2019 Adescptr = (char *)Unameptr;
2020 while(NAdapts--)
2021 {
2022 size_t desclen;
2023
2024 desclen = strlen(tAstr) + 1;
2025
2026 /*
2027 * Do we have room for the name in the Unicode
2028 * buffer?
2029 */
2030 if (BufferSpaceLeft < desclen) {
2031 /*
2032 * No.
2033 */
2034 goto quit;
2035 }
2036
2037 /*
2038 * Just copy the ASCII string.
2039 * namelen includes the NUL, so we copy it as
2040 * well.
2041 */
2042 memcpy(Adescptr, tAstr, desclen);
2043 Adescptr += desclen;
2044 tAstr += desclen;
2045 BufferSpaceLeft -= desclen;
2046 }
2047
2048 quit:
2049 free(TAdaptersName);
2050 return (char *)(AdaptersName);
2051 }
2052 }
2053
2054 /*
2055 * We can't use the same code that we use on UN*X, as that's doing
2056 * UN*X-specific calls.
2057 *
2058 * We don't just fetch the entire list of devices, search for the
2059 * particular device, and use its first IPv4 address, as that's too
2060 * much work to get just one device's netmask.
2061 */
2062 int
2063 pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
2064 char *errbuf)
2065 {
2066 /*
2067 * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo()
2068 * in order to skip non IPv4 (i.e. IPv6 addresses)
2069 */
2070 npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
2071 LONG if_addr_size = MAX_NETWORK_ADDRESSES;
2072 struct sockaddr_in *t_addr;
2073 LONG i;
2074
2075 if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) {
2076 *netp = *maskp = 0;
2077 return (0);
2078 }
2079
2080 for(i = 0; i < if_addr_size; i++)
2081 {
2082 if(if_addrs[i].IPAddress.ss_family == AF_INET)
2083 {
2084 t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress);
2085 *netp = t_addr->sin_addr.S_un.S_addr;
2086 t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask);
2087 *maskp = t_addr->sin_addr.S_un.S_addr;
2088
2089 *netp &= *maskp;
2090 return (0);
2091 }
2092
2093 }
2094
2095 *netp = *maskp = 0;
2096 return (0);
2097 }
2098
2099 static const char *pcap_lib_version_string;
2100
2101 #ifdef HAVE_VERSION_H
2102 /*
2103 * libpcap being built for Windows, as part of a WinPcap/Npcap source
2104 * tree. Include version.h from that source tree to get the WinPcap/Npcap
2105 * version.
2106 *
2107 * XXX - it'd be nice if we could somehow generate the WinPcap/Npcap version
2108 * number when building as part of WinPcap/Npcap. (It'd be nice to do so
2109 * for the packet.dll version number as well.)
2110 */
2111 #include "../../version.h"
2112
2113 static const char pcap_version_string[] =
2114 WINPCAP_PRODUCT_NAME " version " WINPCAP_VER_STRING ", based on " PCAP_VERSION_STRING;
2115
2116 const char *
2117 pcap_lib_version(void)
2118 {
2119 if (pcap_lib_version_string == NULL) {
2120 /*
2121 * Generate the version string.
2122 */
2123 char *packet_version_string = PacketGetVersion();
2124
2125 if (strcmp(WINPCAP_VER_STRING, packet_version_string) == 0) {
2126 /*
2127 * WinPcap/Npcap version string and packet.dll version
2128 * string are the same; just report the WinPcap/Npcap
2129 * version.
2130 */
2131 pcap_lib_version_string = pcap_version_string;
2132 } else {
2133 /*
2134 * WinPcap/Npcap version string and packet.dll version
2135 * string are different; that shouldn't be the
2136 * case (the two libraries should come from the
2137 * same version of WinPcap/Npcap), so we report both
2138 * versions.
2139 */
2140 char *full_pcap_version_string;
2141
2142 if (pcap_asprintf(&full_pcap_version_string,
2143 WINPCAP_PRODUCT_NAME " version " WINPCAP_VER_STRING " (packet.dll version %s), based on " PCAP_VERSION_STRING,
2144 packet_version_string) != -1) {
2145 /* Success */
2146 pcap_lib_version_string = full_pcap_version_string;
2147 }
2148 }
2149 }
2150 return (pcap_lib_version_string);
2151 }
2152
2153 #else /* HAVE_VERSION_H */
2154
2155 /*
2156 * libpcap being built for Windows, not as part of a WinPcap/Npcap source
2157 * tree.
2158 */
2159 const char *
2160 pcap_lib_version(void)
2161 {
2162 if (pcap_lib_version_string == NULL) {
2163 /*
2164 * Generate the version string. Report the packet.dll
2165 * version.
2166 */
2167 char *full_pcap_version_string;
2168
2169 if (pcap_asprintf(&full_pcap_version_string,
2170 PCAP_VERSION_STRING " (packet.dll version %s)",
2171 PacketGetVersion()) != -1) {
2172 /* Success */
2173 pcap_lib_version_string = full_pcap_version_string;
2174 }
2175 }
2176 return (pcap_lib_version_string);
2177 }
2178 #endif /* HAVE_VERSION_H */