2 * WinPcap/Npcap-specific interfaces for capturing. We load WinPcap/Npcap
3 * at run time, so that we only need one Wireshark binary and one TShark
4 * binary for Windows, regardless of whether WinPcap/Npcap is installed
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 2001 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include <wireshark.h>
24 #include <ws_attributes.h>
26 #include "capture/capture-wpcap.h"
27 #include <wsutil/feature_list.h>
35 #include <epan/strutil.h>
37 #include "capture/capture_ifinfo.h"
38 #include "capture/capture-pcap-util.h"
39 #include "capture/capture-pcap-util-int.h"
41 #include <wsutil/file_util.h>
42 #include <wsutil/strtoi.h>
43 #include <wsutil/ws_assert.h>
45 #define MAX_WIN_IF_NAME_LEN 511
47 static void (*p_pcap_close
) (pcap_t
*);
48 static int (*p_pcap_stats
) (pcap_t
*, struct pcap_stat
*);
49 static int (*p_pcap_dispatch
) (pcap_t
*, int, pcap_handler
, unsigned char *);
50 static int (*p_pcap_snapshot
) (pcap_t
*);
51 static int (*p_pcap_datalink
) (pcap_t
*);
52 static int (*p_pcap_setfilter
) (pcap_t
*, struct bpf_program
*);
53 static char* (*p_pcap_geterr
) (pcap_t
*);
54 static int (*p_pcap_compile
) (pcap_t
*, struct bpf_program
*, const char *, int,
56 static int (*p_pcap_compile_nopcap
) (int, int, struct bpf_program
*, const char *, int,
58 static int (*p_pcap_lookupnet
) (const char *, bpf_u_int32
*, bpf_u_int32
*,
60 static pcap_t
* (*p_pcap_open_live
) (const char *, int, int, int, char *);
61 static int (*p_pcap_loop
) (pcap_t
*, int, pcap_handler
, unsigned char *);
62 static pcap_t
* (*p_pcap_open_dead
) (int, int);
63 static void (*p_pcap_freecode
) (struct bpf_program
*);
64 static int (*p_pcap_findalldevs
) (pcap_if_t
**, char *);
65 static void (*p_pcap_freealldevs
) (pcap_if_t
*);
66 static int (*p_pcap_datalink_name_to_val
) (const char *);
67 static const char *(*p_pcap_datalink_val_to_name
) (int);
68 static const char *(*p_pcap_datalink_val_to_description
) (int);
69 static void (*p_pcap_breakloop
) (pcap_t
*);
70 static const char *(*p_pcap_lib_version
) (void);
71 static int (*p_pcap_setbuff
) (pcap_t
*, int dim
);
72 static int (*p_pcap_next_ex
) (pcap_t
*, struct pcap_pkthdr
**pkt_header
, const u_char
**pkt_data
);
73 #ifdef HAVE_PCAP_REMOTE
74 static pcap_t
* (*p_pcap_open
) (const char *, int, int, int,
75 struct pcap_rmtauth
*, char *);
76 static int (*p_pcap_findalldevs_ex
) (const char *, struct pcap_rmtauth
*,
77 pcap_if_t
**, char *);
78 static int (*p_pcap_createsrcstr
) (char *, int, const char *, const char *,
79 const char *, char *);
81 #ifdef HAVE_PCAP_SETSAMPLING
82 static struct pcap_samp
* (*p_pcap_setsampling
)(pcap_t
*);
85 static int (*p_pcap_list_datalinks
)(pcap_t
*, int **);
86 static int (*p_pcap_set_datalink
)(pcap_t
*, int);
88 #ifdef HAVE_PCAP_FREE_DATALINKS
89 static int (*p_pcap_free_datalinks
)(int *);
92 static char *(*p_bpf_image
)(const struct bpf_insn
*, int);
94 #ifdef HAVE_PCAP_CREATE
95 static pcap_t
*(*p_pcap_create
)(const char *, char *);
96 static int (*p_pcap_set_snaplen
)(pcap_t
*, int);
97 static int (*p_pcap_set_promisc
)(pcap_t
*, int);
98 static int (*p_pcap_can_set_rfmon
)(pcap_t
*);
99 static int (*p_pcap_set_rfmon
)(pcap_t
*, int);
100 static int (*p_pcap_set_timeout
)(pcap_t
*, int);
101 static int (*p_pcap_set_buffer_size
)(pcap_t
*, int);
102 static int (*p_pcap_activate
)(pcap_t
*);
103 static const char *(*p_pcap_statustostr
)(int);
106 #ifdef HAVE_PCAP_SET_TSTAMP_TYPE
107 static int (*p_pcap_set_tstamp_type
)(pcap_t
*, int);
108 static int (*p_pcap_set_tstamp_precision
)(pcap_t
*, int);
109 static int (*p_pcap_get_tstamp_precision
)(pcap_t
*);
110 static int (*p_pcap_list_tstamp_types
)(pcap_t
*, int **);
111 static void (*p_pcap_free_tstamp_types
)(int *);
112 static int (*p_pcap_tstamp_type_name_to_val
)(const char *);
113 static const char * (*p_pcap_tstamp_type_val_to_name
)(int);
114 static const char * (*p_pcap_tstamp_type_val_to_description
)(int);
123 #define SYM(x, y) { G_STRINGIFY(x) , (void *) &G_PASTE(p_,x), y }
129 /* These are the symbols I need or want from Wpcap */
130 static const symbol_table_t symbols
[] = {
131 SYM(pcap_close
, false),
132 SYM(pcap_stats
, false),
133 SYM(pcap_dispatch
, false),
134 SYM(pcap_snapshot
, false),
135 SYM(pcap_datalink
, false),
136 SYM(pcap_setfilter
, false),
137 SYM(pcap_geterr
, false),
138 SYM(pcap_compile
, false),
139 SYM(pcap_compile_nopcap
, false),
140 SYM(pcap_lookupnet
, false),
141 #ifdef HAVE_PCAP_REMOTE
142 SYM(pcap_open
, false),
143 SYM(pcap_findalldevs_ex
, false),
144 SYM(pcap_createsrcstr
, false),
146 SYM(pcap_open_live
, false),
147 SYM(pcap_open_dead
, false),
148 #ifdef HAVE_PCAP_SETSAMPLING
149 SYM(pcap_setsampling
, true),
151 SYM(pcap_loop
, false),
152 SYM(pcap_freecode
, false),
153 SYM(pcap_findalldevs
, false),
154 SYM(pcap_freealldevs
, false),
155 SYM(pcap_datalink_name_to_val
, false),
156 SYM(pcap_datalink_val_to_name
, false),
157 SYM(pcap_datalink_val_to_description
, false),
158 SYM(pcap_breakloop
, false),
159 SYM(pcap_lib_version
, false),
160 SYM(pcap_setbuff
, true),
161 SYM(pcap_next_ex
, true),
162 SYM(pcap_list_datalinks
, false),
163 SYM(pcap_set_datalink
, false),
164 #ifdef HAVE_PCAP_FREE_DATALINKS
165 SYM(pcap_free_datalinks
, true),
167 SYM(bpf_image
, false),
168 #ifdef HAVE_PCAP_CREATE
169 SYM(pcap_create
, true),
170 SYM(pcap_set_snaplen
, true),
171 SYM(pcap_set_promisc
, true),
172 SYM(pcap_can_set_rfmon
, true),
173 SYM(pcap_set_rfmon
, true),
174 SYM(pcap_set_timeout
, false),
175 SYM(pcap_set_buffer_size
, false),
176 SYM(pcap_activate
, true),
177 SYM(pcap_statustostr
, true),
179 #ifdef HAVE_PCAP_SET_TSTAMP_TYPE
180 SYM(pcap_set_tstamp_type
, true),
181 SYM(pcap_set_tstamp_precision
, true),
182 SYM(pcap_get_tstamp_precision
, true),
183 SYM(pcap_list_tstamp_types
, true),
184 SYM(pcap_free_tstamp_types
, true),
185 SYM(pcap_tstamp_type_name_to_val
, true),
186 SYM(pcap_tstamp_type_val_to_name
, true),
187 SYM(pcap_tstamp_type_val_to_description
, true),
189 { NULL
, NULL
, false }
192 GModule
*wh
; /* wpcap handle */
193 const symbol_table_t
*sym
;
195 wh
= load_wpcap_module();
203 if (!g_module_symbol(wh
, sym
->name
, sym
->ptr
)) {
206 * We don't care if it's missing; we just
212 * We require this symbol.
225 caplibs_have_npcap(void)
227 return has_wpcap
&& g_str_has_prefix(p_pcap_lib_version(), "Npcap");
231 caplibs_get_npcap_version(unsigned int *major
, unsigned int *minor
)
234 static const char prefix
[] = "Npcap version ";
237 return false; /* we don't have any pcap */
239 version
= p_pcap_lib_version();
240 if (!g_str_has_prefix(version
, prefix
))
241 return false; /* we have it, but it's not Npcap */
244 * This is Npcap; return the major and minor version numbers.
245 * First, skip pas the "Npcap version " prefix.
247 const char *major_version_number
;
248 const char *minor_version_number
;
252 * Get the major version number.
254 major_version_number
= version
+ sizeof prefix
- 1;
255 if (!ws_strtou(major_version_number
, &p
, major
))
256 return false; /* not a number */
258 return false; /* not followed by a "." */
259 p
++; /* skip over the '.' */
262 * Get the minor version number.
264 minor_version_number
= p
;
265 if (!ws_strtou(minor_version_number
, &p
, minor
))
266 return false; /* not a number */
267 if (*p
!= ',' && *p
!= '.' && *p
!= '\0') {
269 * Not followed by a comma (to separate from "based on
270 * libpcap ..."), not followed by a period (in case Npcap
271 * ever has a dot-dot release), and not followed by a
272 * '\0' (in case it has only the Npcap version number).
280 local_code_page_str_to_utf8(char *str
)
290 utf16_len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
291 utf16_str
= g_malloc_n(utf16_len
, sizeof(wchar_t));
292 MultiByteToWideChar(CP_ACP
, 0, str
, -1, utf16_str
, utf16_len
);
294 utf8_str
= g_utf16_to_utf8(utf16_str
, -1, NULL
, NULL
, NULL
);
301 prepare_errbuf(char *errbuf
)
308 convert_errbuf_to_utf8(char *errbuf
)
311 if (errbuf
[0] == '\0') {
314 errbuf
[PCAP_ERRBUF_SIZE
- 1] = '\0';
315 utf8_err
= local_code_page_str_to_utf8(errbuf
);
316 snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "%s", utf8_err
);
321 cant_load_winpcap_err(const char *app_name
)
323 return ws_strdup_printf(
324 "Unable to load Npcap or WinPcap (wpcap.dll); %s will not be able to\n"
327 "In order to capture packets Npcap or WinPcap must be installed. See\n"
329 " https://npcap.com/\n"
331 "for a downloadable version of Npcap and for instructions on how to\n"
337 pcap_close(pcap_t
*a
)
339 ws_assert(has_wpcap
);
344 pcap_stats(pcap_t
*a
, struct pcap_stat
*b
)
346 ws_assert(has_wpcap
);
347 return p_pcap_stats(a
, b
);
351 pcap_dispatch(pcap_t
*a
, int b
, pcap_handler c
, unsigned char *d
)
353 ws_assert(has_wpcap
);
354 return p_pcap_dispatch(a
, b
, c
, d
);
358 pcap_snapshot(pcap_t
*a
)
360 ws_assert(has_wpcap
);
361 return p_pcap_snapshot(a
);
365 pcap_datalink(pcap_t
*a
)
367 ws_assert(has_wpcap
);
368 return p_pcap_datalink(a
);
372 pcap_set_datalink(pcap_t
*p
, int dlt
)
374 ws_assert(has_wpcap
);
375 return p_pcap_set_datalink(p
, dlt
);
379 pcap_setfilter(pcap_t
*a
, struct bpf_program
*b
)
381 ws_assert(has_wpcap
);
382 return p_pcap_setfilter(a
, b
);
386 pcap_geterr(pcap_t
*a
)
389 ws_assert(has_wpcap
);
390 errbuf
= p_pcap_geterr(a
);
391 convert_errbuf_to_utf8(errbuf
);
396 pcap_compile(pcap_t
*a
, struct bpf_program
*b
, const char *c
, int d
,
399 ws_assert(has_wpcap
);
400 return p_pcap_compile(a
, b
, c
, d
, e
);
404 pcap_compile_nopcap(int a
, int b
, struct bpf_program
*c
, const char *d
, int e
,
407 ws_assert(has_wpcap
);
408 return p_pcap_compile_nopcap(a
, b
, c
, d
, e
, f
);
412 pcap_lookupnet(const char *a
, bpf_u_int32
*b
, bpf_u_int32
*c
, char *errbuf
)
415 ws_assert(has_wpcap
);
416 ret
= p_pcap_lookupnet(a
, b
, c
, errbuf
);
418 convert_errbuf_to_utf8(errbuf
);
423 pcap_open_live(const char *a
, int b
, int c
, int d
, char *errbuf
)
427 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
428 "unable to load Npcap or WinPcap (wpcap.dll); can't open %s to capture",
432 prepare_errbuf(errbuf
);
433 p
= p_pcap_open_live(a
, b
, c
, d
, errbuf
);
434 convert_errbuf_to_utf8(errbuf
);
439 pcap_open_dead(int a
, int b
)
444 return p_pcap_open_dead(a
, b
);
448 bpf_image(const struct bpf_insn
*a
, int b
)
453 return p_bpf_image(a
, b
);
456 #ifdef HAVE_PCAP_REMOTE
458 pcap_open(const char *a
, int b
, int c
, int d
, struct pcap_rmtauth
*e
, char *errbuf
)
462 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
463 "unable to load Npcap or WinPcap (wpcap.dll); can't open %s to capture",
467 prepare_errbuf(errbuf
);
468 ret
= p_pcap_open(a
, b
, c
, d
, e
, errbuf
);
469 convert_errbuf_to_utf8(errbuf
);
474 ws_pcap_findalldevs_ex(const char *a
, struct pcap_rmtauth
*b
, pcap_if_t
**c
, char *errbuf
)
477 ws_assert(has_wpcap
);
478 ret
= p_pcap_findalldevs_ex(a
, b
, c
, errbuf
);
480 convert_errbuf_to_utf8(errbuf
);
485 pcap_createsrcstr(char *a
, int b
, const char *c
, const char *d
, const char *e
,
489 ws_assert(has_wpcap
);
490 ret
= p_pcap_createsrcstr(a
, b
, c
, d
, e
, errbuf
);
492 convert_errbuf_to_utf8(errbuf
);
497 #ifdef HAVE_PCAP_SETSAMPLING
499 pcap_setsampling(pcap_t
*a
)
501 ws_assert(has_wpcap
);
502 if (p_pcap_setsampling
!= NULL
) {
503 return p_pcap_setsampling(a
);
510 pcap_loop(pcap_t
*a
, int b
, pcap_handler c
, unsigned char *d
)
512 ws_assert(has_wpcap
);
513 return p_pcap_loop(a
, b
, c
, d
);
517 pcap_freecode(struct bpf_program
*a
)
519 ws_assert(has_wpcap
);
524 pcap_findalldevs(pcap_if_t
**a
, char *errbuf
)
527 ws_assert(has_wpcap
);
528 ret
= p_pcap_findalldevs(a
, errbuf
);
530 convert_errbuf_to_utf8(errbuf
);
535 pcap_freealldevs(pcap_if_t
*a
)
537 ws_assert(has_wpcap
);
538 p_pcap_freealldevs(a
);
541 #ifdef HAVE_PCAP_CREATE
543 pcap_create(const char *a
, char *errbuf
)
546 ws_assert(has_wpcap
&& p_pcap_create
!= NULL
);
547 p
= p_pcap_create(a
, errbuf
);
549 convert_errbuf_to_utf8(errbuf
);
554 pcap_set_snaplen(pcap_t
*a
, int b
)
556 ws_assert(has_wpcap
&& p_pcap_set_snaplen
!= NULL
);
557 return p_pcap_set_snaplen(a
, b
);
561 pcap_set_promisc(pcap_t
*a
, int b
)
563 ws_assert(has_wpcap
&& p_pcap_set_promisc
!= NULL
);
564 return p_pcap_set_promisc(a
, b
);
568 pcap_can_set_rfmon(pcap_t
*a
)
570 ws_assert(has_wpcap
);
571 if (p_pcap_can_set_rfmon
!= NULL
) {
572 return p_pcap_can_set_rfmon(a
);
578 pcap_set_rfmon(pcap_t
*a
, int b
)
580 ws_assert(has_wpcap
&& p_pcap_set_rfmon
!= NULL
);
581 return p_pcap_set_rfmon(a
, b
);
585 pcap_set_timeout(pcap_t
*a
, int b
)
587 ws_assert(has_wpcap
&& p_pcap_set_timeout
!= NULL
);
588 return p_pcap_set_timeout(a
, b
);
591 pcap_set_buffer_size(pcap_t
*a
, int b
)
593 ws_assert(has_wpcap
&& p_pcap_set_buffer_size
!= NULL
);
594 return p_pcap_set_buffer_size(a
, b
);
598 pcap_activate(pcap_t
*a
)
600 ws_assert(has_wpcap
&& p_pcap_activate
!= NULL
);
601 return p_pcap_activate(a
);
606 pcap_statustostr(int a
)
608 static char ebuf
[15 + 10 + 1];
610 ws_assert(has_wpcap
);
611 if (p_pcap_statustostr
!= NULL
) {
612 return p_pcap_statustostr(a
);
615 /* XXX copy routine from pcap.c ??? */
616 (void)snprintf(ebuf
, sizeof ebuf
, "Don't have pcap_statustostr(), can't translate error: %d", a
);
622 #ifdef HAVE_PCAP_SET_TSTAMP_TYPE
624 pcap_set_tstamp_type(pcap_t
*a
, int b
) {
625 ws_assert(has_wpcap
);
626 if (p_pcap_set_tstamp_type
!= NULL
) {
627 return p_pcap_set_tstamp_type(a
, b
);
629 return PCAP_ERROR_CANTSET_TSTAMP_TYPE
;
633 pcap_set_tstamp_precision(pcap_t
*a
, int b
) {
634 ws_assert(has_wpcap
);
635 if (p_pcap_set_tstamp_precision
!= NULL
) {
636 return p_pcap_set_tstamp_precision(a
, b
);
638 // No error code defined so return NOTSUP.
639 return PCAP_ERROR_TSTAMP_PRECISION_NOTSUP
;
643 pcap_get_tstamp_precision(pcap_t
*a
) {
644 ws_assert(has_wpcap
);
645 if (p_pcap_get_tstamp_precision
!= NULL
) {
646 return p_pcap_get_tstamp_precision(a
);
648 // No error code defined so return MICRO.
649 return PCAP_TSTAMP_PRECISION_MICRO
;
653 pcap_list_tstamp_types(pcap_t
*a
, int **b
) {
654 ws_assert(has_wpcap
);
655 if (p_pcap_list_tstamp_types
!= NULL
) {
656 return p_pcap_list_tstamp_types(a
, b
);
662 pcap_free_tstamp_types(int *a
) {
663 ws_assert(has_wpcap
);
664 if (p_pcap_free_tstamp_types
!= NULL
) {
665 p_pcap_free_tstamp_types(a
);
670 pcap_tstamp_type_name_to_val(const char *a
) {
671 ws_assert(has_wpcap
);
672 if (p_pcap_tstamp_type_name_to_val
!= NULL
) {
673 return p_pcap_tstamp_type_name_to_val(a
);
679 pcap_tstamp_type_val_to_name(int a
) {
680 ws_assert(has_wpcap
);
681 if (p_pcap_tstamp_type_val_to_name
!= NULL
) {
682 return p_pcap_tstamp_type_val_to_name(a
);
688 pcap_tstamp_type_val_to_description(int a
) {
689 ws_assert(has_wpcap
);
690 if (p_pcap_tstamp_type_val_to_description
!= NULL
) {
691 return p_pcap_tstamp_type_val_to_description(a
);
698 pcap_datalink_name_to_val(const char *name
)
701 return p_pcap_datalink_name_to_val(name
);
707 pcap_list_datalinks(pcap_t
*p
, int **ddlt
)
710 return p_pcap_list_datalinks(p
, ddlt
);
715 #ifdef HAVE_PCAP_FREE_DATALINKS
717 pcap_free_datalinks(int *ddlt
)
719 ws_assert(has_wpcap
);
722 * If we don't have pcap_free_datalinks() in WinPcap,
723 * we don't free the memory - we can't use free(), as
724 * we might not have been built with the same version
725 * of the C runtime library as WinPcap was, and, if we're
726 * not, free() isn't guaranteed to work on something
727 * allocated by WinPcap.
729 if (p_pcap_free_datalinks
!= NULL
)
730 p_pcap_free_datalinks(ddlt
);
735 pcap_datalink_val_to_name(int dlt
)
738 return p_pcap_datalink_val_to_name(dlt
);
744 pcap_datalink_val_to_description(int dlt
)
747 return p_pcap_datalink_val_to_description(dlt
);
751 void pcap_breakloop(pcap_t
*a
)
756 /* setbuff is win32 specific! */
757 int pcap_setbuff(pcap_t
*a
, int b
)
759 ws_assert(has_wpcap
);
760 return p_pcap_setbuff(a
, b
);
763 int pcap_next_ex(pcap_t
*a
, struct pcap_pkthdr
**b
, const u_char
**c
)
765 ws_assert(has_wpcap
);
766 return p_pcap_next_ex(a
, b
, c
);
769 #ifdef HAVE_PCAP_REMOTE
771 get_remote_interface_list(const char *hostname
, const char *port
,
772 int auth_type
, const char *username
,
773 const char *passwd
, int *err
, char **err_str
)
777 * We don't have Npcap or WinPcap, so we can't get a list of
780 *err
= DONT_HAVE_PCAP
;
782 *err_str
= cant_load_winpcap_err("you");
786 return get_interface_list_findalldevs_ex(hostname
, port
, auth_type
,
787 username
, passwd
, err
, err_str
);
792 get_interface_list(int *err
, char **err_str
)
796 * We don't have Npcap or WinPcap, so we can't get a list of
799 *err
= DONT_HAVE_PCAP
;
801 *err_str
= cant_load_winpcap_err("you");
805 return get_interface_list_findalldevs(err
, err_str
);
809 * Get an error message string for a CANT_GET_INTERFACE_LIST error from
810 * "get_interface_list()".
813 cant_get_if_list_error_message(const char *err_str
)
816 * If the error message includes "Not enough storage is available
817 * to process this command" or "The operation completed successfully",
818 * suggest that they install a WinPcap version later than 3.0.
820 if (strstr(err_str
, "Not enough storage is available to process this command") != NULL
||
821 strstr(err_str
, "The operation completed successfully") != NULL
) {
822 return ws_strdup_printf("Can't get list of interfaces: %s\n"
823 "This might be a problem with WinPcap 3.0. You should try updating to\n"
824 "Npcap. See https://npcap.com/ for more information.",
827 return ws_strdup_printf("Can't get list of interfaces: %s", err_str
);
831 get_if_capabilities_local(interface_options
*interface_opts
,
832 cap_device_open_status
*status
, char **status_str
)
835 * We're not getting capaibilities for a remote device; use
836 * pcap_create() and pcap_activate() if we have them, so that
837 * we can set various options, otherwise use pcap_open_live().
839 #ifdef HAVE_PCAP_CREATE
840 if (p_pcap_create
!= NULL
)
841 return get_if_capabilities_pcap_create(interface_opts
, status
,
844 return get_if_capabilities_pcap_open_live(interface_opts
, status
,
849 open_capture_device_local(capture_options
*capture_opts
,
850 interface_options
*interface_opts
, int timeout
,
851 cap_device_open_status
*open_status
,
852 char (*open_status_str
)[PCAP_ERRBUF_SIZE
])
855 * We're not opening a remote device; use pcap_create() and
856 * pcap_activate() if we have them, so that we can set various
857 * options, otherwise use pcap_open_live().
859 #ifdef HAVE_PCAP_CREATE
860 if (p_pcap_create
!= NULL
)
861 return open_capture_device_pcap_create(capture_opts
,
862 interface_opts
, timeout
, open_status
, open_status_str
);
864 return open_capture_device_pcap_open_live(interface_opts
, timeout
,
865 open_status
, open_status_str
);
869 * Append the WinPcap or Npcap SDK version with which we were compiled to a GString.
872 gather_caplibs_compile_info(feature_list l
)
874 with_feature(l
, "libpcap");
878 gather_caplibs_runtime_info(feature_list l
)
881 * On Windows, we might have been compiled with WinPcap/Npcap but
882 * might not have it loaded; indicate whether we have it or
883 * not and, if we have it, what version we have.
886 with_feature(l
, "%s", p_pcap_lib_version());
888 without_feature(l
, "Npcap or WinPcap");
892 * If npf.sys is running, return true.
895 npf_sys_is_running(void)
897 SC_HANDLE h_scm
, h_serv
;
900 h_scm
= OpenSCManager(NULL
, NULL
, 0);
904 h_serv
= OpenService(h_scm
, _T("npcap"), SC_MANAGER_CONNECT
|SERVICE_QUERY_STATUS
);
906 h_serv
= OpenService(h_scm
, _T("npf"), SC_MANAGER_CONNECT
|SERVICE_QUERY_STATUS
);
908 CloseServiceHandle(h_scm
);
913 if (QueryServiceStatus(h_serv
, &ss
)) {
914 if (ss
.dwCurrentState
& SERVICE_RUNNING
) {
915 CloseServiceHandle(h_serv
);
916 CloseServiceHandle(h_scm
);
920 CloseServiceHandle(h_serv
);
921 CloseServiceHandle(h_scm
);
925 #else /* HAVE_LIBPCAP */
934 * Append an indication that we were not compiled with WinPcap
938 gather_caplibs_compile_info(feature_list l
)
940 without_feature(l
, "libpcap");
944 gather_caplibs_runtime_info(feature_list l _U_
)
949 caplibs_have_npcap(void)
954 #endif /* HAVE_LIBPCAP */
957 * Editor modelines - https://www.wireshark.org/tools/modelines.html
962 * indent-tabs-mode: t
965 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
966 * :indentSize=8:tabSize=8:noTabs=false: