aboutsummaryrefslogtreecommitdiffstats
path: root/capture/capture-wpcap.c
diff options
context:
space:
mode:
Diffstat (limited to 'capture/capture-wpcap.c')
-rw-r--r--capture/capture-wpcap.c253
1 files changed, 150 insertions, 103 deletions
diff --git a/capture/capture-wpcap.c b/capture/capture-wpcap.c
index 45098e7be4..4f7d1dca99 100644
--- a/capture/capture-wpcap.c
+++ b/capture/capture-wpcap.c
@@ -13,18 +13,20 @@
#include "config.h"
+#include <wireshark.h>
+
#include <windows.h>
#include <wchar.h>
#include <tchar.h>
#include <stdio.h>
-#include <glib.h>
#include <ws_attributes.h>
#include "capture/capture-wpcap.h"
+#include <wsutil/feature_list.h>
-gboolean has_wpcap = FALSE;
+bool has_wpcap = false;
#ifdef HAVE_LIBPCAP
@@ -37,21 +39,14 @@ gboolean has_wpcap = FALSE;
#include "capture/capture-pcap-util-int.h"
#include <wsutil/file_util.h>
+#include <wsutil/strtoi.h>
#include <wsutil/ws_assert.h>
-/* XXX - yes, I know, I should move cppmagic.h to a generic location. */
-#include "tools/lemon/cppmagic.h"
-
#define MAX_WIN_IF_NAME_LEN 511
-/*
- * XXX - should we require at least WinPcap 3.1 both for building an
- * for using Wireshark?
- */
-
static void (*p_pcap_close) (pcap_t *);
static int (*p_pcap_stats) (pcap_t *, struct pcap_stat *);
-static int (*p_pcap_dispatch) (pcap_t *, int, pcap_handler, guchar *);
+static int (*p_pcap_dispatch) (pcap_t *, int, pcap_handler, unsigned char *);
static int (*p_pcap_snapshot) (pcap_t *);
static int (*p_pcap_datalink) (pcap_t *);
static int (*p_pcap_setfilter) (pcap_t *, struct bpf_program *);
@@ -63,7 +58,7 @@ static int (*p_pcap_compile_nopcap) (int, int, struct bpf_program *, const c
static int (*p_pcap_lookupnet) (const char *, bpf_u_int32 *, bpf_u_int32 *,
char *);
static pcap_t* (*p_pcap_open_live) (const char *, int, int, int, char *);
-static int (*p_pcap_loop) (pcap_t *, int, pcap_handler, guchar *);
+static int (*p_pcap_loop) (pcap_t *, int, pcap_handler, unsigned char *);
static pcap_t* (*p_pcap_open_dead) (int, int);
static void (*p_pcap_freecode) (struct bpf_program *);
static int (*p_pcap_findalldevs) (pcap_if_t **, char *);
@@ -121,11 +116,11 @@ static const char * (*p_pcap_tstamp_type_val_to_description)(int);
typedef struct {
const char *name;
- gpointer *ptr;
- gboolean optional;
+ void * *ptr;
+ bool optional;
} symbol_table_t;
-#define SYM(x, y) { G_STRINGIFY(x) , (gpointer) &CONCAT(p_,x), y }
+#define SYM(x, y) { G_STRINGIFY(x) , (void *) &G_PASTE(p_,x), y }
void
load_wpcap(void)
@@ -133,71 +128,71 @@ load_wpcap(void)
/* These are the symbols I need or want from Wpcap */
static const symbol_table_t symbols[] = {
- SYM(pcap_close, FALSE),
- SYM(pcap_stats, FALSE),
- SYM(pcap_dispatch, FALSE),
- SYM(pcap_snapshot, FALSE),
- SYM(pcap_datalink, FALSE),
- SYM(pcap_setfilter, FALSE),
- SYM(pcap_geterr, FALSE),
- SYM(pcap_compile, FALSE),
- SYM(pcap_compile_nopcap, FALSE),
- SYM(pcap_lookupnet, FALSE),
+ SYM(pcap_close, false),
+ SYM(pcap_stats, false),
+ SYM(pcap_dispatch, false),
+ SYM(pcap_snapshot, false),
+ SYM(pcap_datalink, false),
+ SYM(pcap_setfilter, false),
+ SYM(pcap_geterr, false),
+ SYM(pcap_compile, false),
+ SYM(pcap_compile_nopcap, false),
+ SYM(pcap_lookupnet, false),
#ifdef HAVE_PCAP_REMOTE
- SYM(pcap_open, FALSE),
- SYM(pcap_findalldevs_ex, FALSE),
- SYM(pcap_createsrcstr, FALSE),
+ SYM(pcap_open, false),
+ SYM(pcap_findalldevs_ex, false),
+ SYM(pcap_createsrcstr, false),
#endif
- SYM(pcap_open_live, FALSE),
- SYM(pcap_open_dead, FALSE),
+ SYM(pcap_open_live, false),
+ SYM(pcap_open_dead, false),
#ifdef HAVE_PCAP_SETSAMPLING
- SYM(pcap_setsampling, TRUE),
+ SYM(pcap_setsampling, true),
#endif
- SYM(pcap_loop, FALSE),
- SYM(pcap_freecode, FALSE),
- SYM(pcap_findalldevs, FALSE),
- SYM(pcap_freealldevs, FALSE),
- SYM(pcap_datalink_name_to_val, FALSE),
- SYM(pcap_datalink_val_to_name, FALSE),
- SYM(pcap_datalink_val_to_description, FALSE),
- SYM(pcap_breakloop, FALSE),
- SYM(pcap_lib_version, FALSE),
- SYM(pcap_setbuff, TRUE),
- SYM(pcap_next_ex, TRUE),
- SYM(pcap_list_datalinks, FALSE),
- SYM(pcap_set_datalink, FALSE),
+ SYM(pcap_loop, false),
+ SYM(pcap_freecode, false),
+ SYM(pcap_findalldevs, false),
+ SYM(pcap_freealldevs, false),
+ SYM(pcap_datalink_name_to_val, false),
+ SYM(pcap_datalink_val_to_name, false),
+ SYM(pcap_datalink_val_to_description, false),
+ SYM(pcap_breakloop, false),
+ SYM(pcap_lib_version, false),
+ SYM(pcap_setbuff, true),
+ SYM(pcap_next_ex, true),
+ SYM(pcap_list_datalinks, false),
+ SYM(pcap_set_datalink, false),
#ifdef HAVE_PCAP_FREE_DATALINKS
- SYM(pcap_free_datalinks, TRUE),
+ SYM(pcap_free_datalinks, true),
#endif
- SYM(bpf_image, FALSE),
+ SYM(bpf_image, false),
#ifdef HAVE_PCAP_CREATE
- SYM(pcap_create, TRUE),
- SYM(pcap_set_snaplen, TRUE),
- SYM(pcap_set_promisc, TRUE),
- SYM(pcap_can_set_rfmon, TRUE),
- SYM(pcap_set_rfmon, TRUE),
- SYM(pcap_set_timeout, FALSE),
- SYM(pcap_set_buffer_size, FALSE),
- SYM(pcap_activate, TRUE),
- SYM(pcap_statustostr, TRUE),
+ SYM(pcap_create, true),
+ SYM(pcap_set_snaplen, true),
+ SYM(pcap_set_promisc, true),
+ SYM(pcap_can_set_rfmon, true),
+ SYM(pcap_set_rfmon, true),
+ SYM(pcap_set_timeout, false),
+ SYM(pcap_set_buffer_size, false),
+ SYM(pcap_activate, true),
+ SYM(pcap_statustostr, true),
#endif
#ifdef HAVE_PCAP_SET_TSTAMP_TYPE
- SYM(pcap_set_tstamp_type, TRUE),
- SYM(pcap_set_tstamp_precision, TRUE),
- SYM(pcap_get_tstamp_precision, TRUE),
- SYM(pcap_list_tstamp_types, TRUE),
- SYM(pcap_free_tstamp_types, TRUE),
- SYM(pcap_tstamp_type_name_to_val, TRUE),
- SYM(pcap_tstamp_type_val_to_name, TRUE),
- SYM(pcap_tstamp_type_val_to_description, TRUE),
+ SYM(pcap_set_tstamp_type, true),
+ SYM(pcap_set_tstamp_precision, true),
+ SYM(pcap_get_tstamp_precision, true),
+ SYM(pcap_list_tstamp_types, true),
+ SYM(pcap_free_tstamp_types, true),
+ SYM(pcap_tstamp_type_name_to_val, true),
+ SYM(pcap_tstamp_type_val_to_name, true),
+ SYM(pcap_tstamp_type_val_to_description, true),
#endif
- { NULL, NULL, FALSE }
+ { NULL, NULL, false }
};
GModule *wh; /* wpcap handle */
const symbol_table_t *sym;
- wh = ws_module_open("wpcap.dll", 0);
+ wh = load_wpcap_module();
if (!wh) {
return;
@@ -223,7 +218,62 @@ load_wpcap(void)
}
- has_wpcap = TRUE;
+ has_wpcap = true;
+}
+
+bool
+caplibs_have_npcap(void)
+{
+ return has_wpcap && g_str_has_prefix(p_pcap_lib_version(), "Npcap");
+}
+
+bool
+caplibs_get_npcap_version(unsigned int *major, unsigned int *minor)
+{
+ const char *version;
+ static const char prefix[] = "Npcap version ";
+
+ if (!has_wpcap)
+ return false; /* we don't have any pcap */
+
+ version = p_pcap_lib_version();
+ if (!g_str_has_prefix(version, prefix))
+ return false; /* we have it, but it's not Npcap */
+
+ /*
+ * This is Npcap; return the major and minor version numbers.
+ * First, skip pas the "Npcap version " prefix.
+ */
+ const char *major_version_number;
+ const char *minor_version_number;
+ const char *p;
+
+ /*
+ * Get the major version number.
+ */
+ major_version_number = version + sizeof prefix - 1;
+ if (!ws_strtou(major_version_number, &p, major))
+ return false; /* not a number */
+ if (*p != '.')
+ return false; /* not followed by a "." */
+ p++; /* skip over the '.' */
+
+ /*
+ * Get the minor version number.
+ */
+ minor_version_number = p;
+ if (!ws_strtou(minor_version_number, &p, minor))
+ return false; /* not a number */
+ if (*p != ',' && *p != '.' && *p != '\0') {
+ /*
+ * Not followed by a comma (to separate from "based on
+ * libpcap ..."), not followed by a period (in case Npcap
+ * ever has a dot-dot release), and not followed by a
+ * '\0' (in case it has only the Npcap version number).
+ */
+ return false;
+ }
+ return true;
}
static char *
@@ -257,26 +307,26 @@ prepare_errbuf(char *errbuf)
static void
convert_errbuf_to_utf8(char *errbuf)
{
- gchar *utf8_err;
+ char *utf8_err;
if (errbuf[0] == '\0') {
return;
}
errbuf[PCAP_ERRBUF_SIZE - 1] = '\0';
utf8_err = local_code_page_str_to_utf8(errbuf);
- g_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s", utf8_err);
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s", utf8_err);
g_free(utf8_err);
}
static char *
cant_load_winpcap_err(const char *app_name)
{
- return g_strdup_printf(
+ return ws_strdup_printf(
"Unable to load Npcap or WinPcap (wpcap.dll); %s will not be able to\n"
"capture packets.\n"
"\n"
"In order to capture packets Npcap or WinPcap must be installed. See\n"
"\n"
-" https://nmap.org/npcap/\n"
+" https://npcap.com/\n"
"\n"
"for a downloadable version of Npcap and for instructions on how to\n"
"install it.",
@@ -298,7 +348,7 @@ pcap_stats(pcap_t *a, struct pcap_stat *b)
}
int
-pcap_dispatch(pcap_t *a, int b, pcap_handler c, guchar *d)
+pcap_dispatch(pcap_t *a, int b, pcap_handler c, unsigned char *d)
{
ws_assert(has_wpcap);
return p_pcap_dispatch(a, b, c, d);
@@ -374,7 +424,7 @@ pcap_open_live(const char *a, int b, int c, int d, char *errbuf)
{
pcap_t *p;
if (!has_wpcap) {
- g_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
"unable to load Npcap or WinPcap (wpcap.dll); can't open %s to capture",
a);
return NULL;
@@ -409,7 +459,7 @@ pcap_open(const char *a, int b, int c, int d, struct pcap_rmtauth *e, char *errb
{
pcap_t *ret;
if (!has_wpcap) {
- g_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
"unable to load Npcap or WinPcap (wpcap.dll); can't open %s to capture",
a);
return NULL;
@@ -421,7 +471,7 @@ pcap_open(const char *a, int b, int c, int d, struct pcap_rmtauth *e, char *errb
}
int
-pcap_findalldevs_ex(const char *a, struct pcap_rmtauth *b, pcap_if_t **c, char *errbuf)
+ws_pcap_findalldevs_ex(const char *a, struct pcap_rmtauth *b, pcap_if_t **c, char *errbuf)
{
int ret;
ws_assert(has_wpcap);
@@ -457,7 +507,7 @@ pcap_setsampling(pcap_t *a)
#endif
int
-pcap_loop(pcap_t *a, int b, pcap_handler c, guchar *d)
+pcap_loop(pcap_t *a, int b, pcap_handler c, unsigned char *d)
{
ws_assert(has_wpcap);
return p_pcap_loop(a, b, c, d);
@@ -563,7 +613,7 @@ pcap_statustostr(int a)
}
/* XXX copy routine from pcap.c ??? */
- (void)g_snprintf(ebuf, sizeof ebuf, "Don't have pcap_statustostr(), can't translate error: %d", a);
+ (void)snprintf(ebuf, sizeof ebuf, "Don't have pcap_statustostr(), can't translate error: %d", a);
return(ebuf);
}
@@ -710,8 +760,6 @@ int pcap_setbuff(pcap_t *a, int b)
return p_pcap_setbuff(a, b);
}
-/* pcap_next_ex is available since libpcap 0.8 / WinPcap 3.0! */
-/* (if you get a declaration warning here, try to update to at least WinPcap 3.1b4 develpack) */
int pcap_next_ex(pcap_t *a, struct pcap_pkthdr **b, const u_char **c)
{
ws_assert(has_wpcap);
@@ -761,7 +809,7 @@ get_interface_list(int *err, char **err_str)
* Get an error message string for a CANT_GET_INTERFACE_LIST error from
* "get_interface_list()".
*/
-gchar *
+char *
cant_get_if_list_error_message(const char *err_str)
{
/*
@@ -771,12 +819,12 @@ cant_get_if_list_error_message(const char *err_str)
*/
if (strstr(err_str, "Not enough storage is available to process this command") != NULL ||
strstr(err_str, "The operation completed successfully") != NULL) {
- return g_strdup_printf("Can't get list of interfaces: %s\n"
+ return ws_strdup_printf("Can't get list of interfaces: %s\n"
"This might be a problem with WinPcap 3.0. You should try updating to\n"
-"Npcap. See https://nmap.org/npcap/ for more information.",
+"Npcap. See https://npcap.com/ for more information.",
err_str);
}
- return g_strdup_printf("Can't get list of interfaces: %s", err_str);
+ return ws_strdup_printf("Can't get list of interfaces: %s", err_str);
}
if_capabilities_t *
@@ -821,16 +869,13 @@ open_capture_device_local(capture_options *capture_opts,
* Append the WinPcap or Npcap SDK version with which we were compiled to a GString.
*/
void
-get_compiled_caplibs_version(GString *str)
+gather_caplibs_compile_info(feature_list l)
{
- g_string_append(str, "with libpcap");
+ with_feature(l, "libpcap");
}
-/*
- * Append the version of Npcap with which we we're running to a GString.
- */
void
-get_runtime_caplibs_version(GString *str)
+gather_caplibs_runtime_info(feature_list l)
{
/*
* On Windows, we might have been compiled with WinPcap/Npcap but
@@ -838,16 +883,15 @@ get_runtime_caplibs_version(GString *str)
* not and, if we have it, what version we have.
*/
if (has_wpcap) {
- g_string_append_printf(str, "with ");
- g_string_append_printf(str, p_pcap_lib_version());
+ with_feature(l, "%s", p_pcap_lib_version());
} else
- g_string_append(str, "without Npcap or WinPcap");
+ without_feature(l, "Npcap or WinPcap");
}
/*
- * If npf.sys is running, return TRUE.
+ * If npf.sys is running, return true.
*/
-gboolean
+bool
npf_sys_is_running(void)
{
SC_HANDLE h_scm, h_serv;
@@ -855,14 +899,14 @@ npf_sys_is_running(void)
h_scm = OpenSCManager(NULL, NULL, 0);
if (!h_scm)
- return FALSE;
+ return false;
h_serv = OpenService(h_scm, _T("npcap"), SC_MANAGER_CONNECT|SERVICE_QUERY_STATUS);
if (!h_serv) {
h_serv = OpenService(h_scm, _T("npf"), SC_MANAGER_CONNECT|SERVICE_QUERY_STATUS);
if (!h_serv) {
CloseServiceHandle(h_scm);
- return FALSE;
+ return false;
}
}
@@ -870,12 +914,12 @@ npf_sys_is_running(void)
if (ss.dwCurrentState & SERVICE_RUNNING) {
CloseServiceHandle(h_serv);
CloseServiceHandle(h_scm);
- return TRUE;
+ return true;
}
}
CloseServiceHandle(h_serv);
CloseServiceHandle(h_scm);
- return FALSE;
+ return false;
}
#else /* HAVE_LIBPCAP */
@@ -891,17 +935,20 @@ load_wpcap(void)
* to a GString.
*/
void
-get_compiled_caplibs_version(GString *str)
+gather_caplibs_compile_info(feature_list l)
{
- g_string_append(str, "without Npcap or WinPcap");
+ without_feature(l, "libpcap");
}
-/*
- * Don't append anything, as we weren't even compiled to use WinPcap/Npcap.
- */
void
-get_runtime_caplibs_version(GString *str _U_)
+gather_caplibs_runtime_info(feature_list l _U_)
+{
+}
+
+bool
+caplibs_have_npcap(void)
{
+ return false;
}
#endif /* HAVE_LIBPCAP */