decryption works, but addid doesn't because of unique pointer layers
[wireshark-sm.git] / capture / capture-wpcap.c
blob792fef7088b585e24c8e75631d35bf39b72cb017
1 /* capture-wpcap.c
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
5 * or not.
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
14 #include "config.h"
16 #include <wireshark.h>
18 #include <windows.h>
19 #include <wchar.h>
20 #include <tchar.h>
22 #include <stdio.h>
24 #include <ws_attributes.h>
26 #include "capture/capture-wpcap.h"
27 #include <wsutil/feature_list.h>
29 bool has_wpcap;
31 #ifdef HAVE_LIBPCAP
33 #include <gmodule.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,
55 bpf_u_int32);
56 static int (*p_pcap_compile_nopcap) (int, int, struct bpf_program *, const char *, int,
57 bpf_u_int32);
58 static int (*p_pcap_lookupnet) (const char *, bpf_u_int32 *, bpf_u_int32 *,
59 char *);
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 *);
80 #endif
81 #ifdef HAVE_PCAP_SETSAMPLING
82 static struct pcap_samp* (*p_pcap_setsampling)(pcap_t *);
83 #endif
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 *);
90 #endif
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);
104 #endif
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);
115 #endif
117 typedef struct {
118 const char *name;
119 void * *ptr;
120 bool optional;
121 } symbol_table_t;
123 #define SYM(x, y) { G_STRINGIFY(x) , (void *) &G_PASTE(p_,x), y }
125 void
126 load_wpcap(void)
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),
145 #endif
146 SYM(pcap_open_live, false),
147 SYM(pcap_open_dead, false),
148 #ifdef HAVE_PCAP_SETSAMPLING
149 SYM(pcap_setsampling, true),
150 #endif
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),
166 #endif
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),
178 #endif
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),
188 #endif
189 { NULL, NULL, false }
192 GModule *wh; /* wpcap handle */
193 const symbol_table_t *sym;
195 wh = load_wpcap_module();
197 if (!wh) {
198 return;
201 sym = symbols;
202 while (sym->name) {
203 if (!g_module_symbol(wh, sym->name, sym->ptr)) {
204 if (sym->optional) {
206 * We don't care if it's missing; we just
207 * don't use it.
209 *sym->ptr = NULL;
210 } else {
212 * We require this symbol.
214 return;
217 sym++;
221 has_wpcap = true;
224 bool
225 caplibs_have_npcap(void)
227 return has_wpcap && g_str_has_prefix(p_pcap_lib_version(), "Npcap");
230 bool
231 caplibs_get_npcap_version(unsigned int *major, unsigned int *minor)
233 const char *version;
234 static const char prefix[] = "Npcap version ";
236 if (!has_wpcap)
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;
249 const char *p;
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 */
257 if (*p != '.')
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).
274 return false;
276 return true;
279 static char *
280 local_code_page_str_to_utf8(char *str)
282 ULONG utf16_len;
283 wchar_t *utf16_str;
284 char *utf8_str;
286 if (str == NULL) {
287 return NULL;
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);
296 g_free(utf16_str);
297 return utf8_str;
300 static void
301 prepare_errbuf(char *errbuf)
303 ws_assert(errbuf);
304 errbuf[0] = '\0';
307 static void
308 convert_errbuf_to_utf8(char *errbuf)
310 char *utf8_err;
311 if (errbuf[0] == '\0') {
312 return;
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);
317 g_free(utf8_err);
320 static char *
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"
325 "capture packets.\n"
326 "\n"
327 "In order to capture packets Npcap or WinPcap must be installed. See\n"
328 "\n"
329 " https://npcap.com/\n"
330 "\n"
331 "for a downloadable version of Npcap and for instructions on how to\n"
332 "install it.",
333 app_name);
336 void
337 pcap_close(pcap_t *a)
339 ws_assert(has_wpcap);
340 p_pcap_close(a);
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);
385 char*
386 pcap_geterr(pcap_t *a)
388 char *errbuf;
389 ws_assert(has_wpcap);
390 errbuf = p_pcap_geterr(a);
391 convert_errbuf_to_utf8(errbuf);
392 return errbuf;
396 pcap_compile(pcap_t *a, struct bpf_program *b, const char *c, int d,
397 bpf_u_int32 e)
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,
405 bpf_u_int32 f)
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)
414 int ret;
415 ws_assert(has_wpcap);
416 ret = p_pcap_lookupnet(a, b, c, errbuf);
417 if (ret == -1)
418 convert_errbuf_to_utf8(errbuf);
419 return ret;
422 pcap_t*
423 pcap_open_live(const char *a, int b, int c, int d, char *errbuf)
425 pcap_t *p;
426 if (!has_wpcap) {
427 snprintf(errbuf, PCAP_ERRBUF_SIZE,
428 "unable to load Npcap or WinPcap (wpcap.dll); can't open %s to capture",
430 return NULL;
432 prepare_errbuf(errbuf);
433 p = p_pcap_open_live(a, b, c, d, errbuf);
434 convert_errbuf_to_utf8(errbuf);
435 return p;
438 pcap_t*
439 pcap_open_dead(int a, int b)
441 if (!has_wpcap) {
442 return NULL;
444 return p_pcap_open_dead(a, b);
447 char *
448 bpf_image(const struct bpf_insn *a, int b)
450 if (!has_wpcap) {
451 return NULL;
453 return p_bpf_image(a, b);
456 #ifdef HAVE_PCAP_REMOTE
457 pcap_t*
458 pcap_open(const char *a, int b, int c, int d, struct pcap_rmtauth *e, char *errbuf)
460 pcap_t *ret;
461 if (!has_wpcap) {
462 snprintf(errbuf, PCAP_ERRBUF_SIZE,
463 "unable to load Npcap or WinPcap (wpcap.dll); can't open %s to capture",
465 return NULL;
467 prepare_errbuf(errbuf);
468 ret = p_pcap_open(a, b, c, d, e, errbuf);
469 convert_errbuf_to_utf8(errbuf);
470 return ret;
474 ws_pcap_findalldevs_ex(const char *a, struct pcap_rmtauth *b, pcap_if_t **c, char *errbuf)
476 int ret;
477 ws_assert(has_wpcap);
478 ret = p_pcap_findalldevs_ex(a, b, c, errbuf);
479 if (ret == -1)
480 convert_errbuf_to_utf8(errbuf);
481 return ret;
485 pcap_createsrcstr(char *a, int b, const char *c, const char *d, const char *e,
486 char *errbuf)
488 int ret;
489 ws_assert(has_wpcap);
490 ret = p_pcap_createsrcstr(a, b, c, d, e, errbuf);
491 if (ret == -1)
492 convert_errbuf_to_utf8(errbuf);
493 return ret;
495 #endif
497 #ifdef HAVE_PCAP_SETSAMPLING
498 struct pcap_samp *
499 pcap_setsampling(pcap_t *a)
501 ws_assert(has_wpcap);
502 if (p_pcap_setsampling != NULL) {
503 return p_pcap_setsampling(a);
505 return NULL;
507 #endif
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);
516 void
517 pcap_freecode(struct bpf_program *a)
519 ws_assert(has_wpcap);
520 p_pcap_freecode(a);
524 pcap_findalldevs(pcap_if_t **a, char *errbuf)
526 int ret;
527 ws_assert(has_wpcap);
528 ret = p_pcap_findalldevs(a, errbuf);
529 if (ret == -1)
530 convert_errbuf_to_utf8(errbuf);
531 return ret;
534 void
535 pcap_freealldevs(pcap_if_t *a)
537 ws_assert(has_wpcap);
538 p_pcap_freealldevs(a);
541 #ifdef HAVE_PCAP_CREATE
542 pcap_t *
543 pcap_create(const char *a, char *errbuf)
545 pcap_t *p;
546 ws_assert(has_wpcap && p_pcap_create != NULL);
547 p = p_pcap_create(a, errbuf);
548 if (p == NULL)
549 convert_errbuf_to_utf8(errbuf);
550 return p;
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);
574 return 0;
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);
605 const char *
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);
617 return(ebuf);
620 #endif
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);
658 return PCAP_ERROR;
661 void
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);
675 return PCAP_ERROR;
678 const char *
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);
684 return NULL;
687 const char *
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);
693 return NULL;
695 #endif
698 pcap_datalink_name_to_val(const char *name)
700 if (has_wpcap)
701 return p_pcap_datalink_name_to_val(name);
702 else
703 return -1;
707 pcap_list_datalinks(pcap_t *p, int **ddlt)
709 if (has_wpcap)
710 return p_pcap_list_datalinks(p, ddlt);
711 else
712 return -1;
715 #ifdef HAVE_PCAP_FREE_DATALINKS
716 void
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);
732 #endif
734 const char *
735 pcap_datalink_val_to_name(int dlt)
737 if (has_wpcap)
738 return p_pcap_datalink_val_to_name(dlt);
739 else
740 return NULL;
743 const char *
744 pcap_datalink_val_to_description(int dlt)
746 if (has_wpcap)
747 return p_pcap_datalink_val_to_description(dlt);
748 return NULL;
751 void pcap_breakloop(pcap_t *a)
753 p_pcap_breakloop(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
770 GList *
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)
775 if (!has_wpcap) {
777 * We don't have Npcap or WinPcap, so we can't get a list of
778 * interfaces.
780 *err = DONT_HAVE_PCAP;
781 if (err_str != NULL)
782 *err_str = cant_load_winpcap_err("you");
783 return NULL;
786 return get_interface_list_findalldevs_ex(hostname, port, auth_type,
787 username, passwd, err, err_str);
789 #endif
791 GList *
792 get_interface_list(int *err, char **err_str)
794 if (!has_wpcap) {
796 * We don't have Npcap or WinPcap, so we can't get a list of
797 * interfaces.
799 *err = DONT_HAVE_PCAP;
800 if (err_str != NULL)
801 *err_str = cant_load_winpcap_err("you");
802 return NULL;
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()".
812 char *
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.",
825 err_str);
827 return ws_strdup_printf("Can't get list of interfaces: %s", err_str);
830 if_capabilities_t *
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,
842 status_str);
843 #endif
844 return get_if_capabilities_pcap_open_live(interface_opts, status,
845 status_str);
848 pcap_t *
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);
863 #endif
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.
871 void
872 gather_caplibs_compile_info(feature_list l)
874 with_feature(l, "libpcap");
877 void
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.
885 if (has_wpcap) {
886 with_feature(l, "%s", p_pcap_lib_version());
887 } else
888 without_feature(l, "Npcap or WinPcap");
892 * If npf.sys is running, return true.
894 bool
895 npf_sys_is_running(void)
897 SC_HANDLE h_scm, h_serv;
898 SERVICE_STATUS ss;
900 h_scm = OpenSCManager(NULL, NULL, 0);
901 if (!h_scm)
902 return false;
904 h_serv = OpenService(h_scm, _T("npcap"), SC_MANAGER_CONNECT|SERVICE_QUERY_STATUS);
905 if (!h_serv) {
906 h_serv = OpenService(h_scm, _T("npf"), SC_MANAGER_CONNECT|SERVICE_QUERY_STATUS);
907 if (!h_serv) {
908 CloseServiceHandle(h_scm);
909 return false;
913 if (QueryServiceStatus(h_serv, &ss)) {
914 if (ss.dwCurrentState & SERVICE_RUNNING) {
915 CloseServiceHandle(h_serv);
916 CloseServiceHandle(h_scm);
917 return true;
920 CloseServiceHandle(h_serv);
921 CloseServiceHandle(h_scm);
922 return false;
925 #else /* HAVE_LIBPCAP */
927 void
928 load_wpcap(void)
930 return;
934 * Append an indication that we were not compiled with WinPcap
935 * to a GString.
937 void
938 gather_caplibs_compile_info(feature_list l)
940 without_feature(l, "libpcap");
943 void
944 gather_caplibs_runtime_info(feature_list l _U_)
948 bool
949 caplibs_have_npcap(void)
951 return false;
954 #endif /* HAVE_LIBPCAP */
957 * Editor modelines - https://www.wireshark.org/tools/modelines.html
959 * Local variables:
960 * c-basic-offset: 8
961 * tab-width: 8
962 * indent-tabs-mode: t
963 * End:
965 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
966 * :indentSize=8:tabSize=8:noTabs=false: