diff options
Diffstat (limited to 'capture/capture-wpcap.c')
-rw-r--r-- | capture/capture-wpcap.c | 253 |
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 */ |