wireshark/capture/capture-wpcap.c

921 lines
21 KiB
C
Raw Normal View History

/* capture-wpcap.c
* WinPcap/Npcap-specific interfaces for capturing. We load WinPcap/Npcap
* at run time, so that we only need one Wireshark binary and one TShark
* binary for Windows, regardless of whether WinPcap/Npcap is installed
* or not.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 2001 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config.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"
gboolean has_wpcap = FALSE;
#ifdef HAVE_LIBPCAP
#include <gmodule.h>
#include <epan/strutil.h>
#include "capture/capture_ifinfo.h"
#include "capture/capture-pcap-util.h"
#include "capture/capture-pcap-util-int.h"
#include <wsutil/file_util.h>
2021-06-18 18:21:42 +00:00
#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_snapshot) (pcap_t *);
static int (*p_pcap_datalink) (pcap_t *);
static int (*p_pcap_setfilter) (pcap_t *, struct bpf_program *);
static char* (*p_pcap_geterr) (pcap_t *);
static int (*p_pcap_compile) (pcap_t *, struct bpf_program *, const char *, int,
bpf_u_int32);
static int (*p_pcap_compile_nopcap) (int, int, struct bpf_program *, const char *, int,
bpf_u_int32);
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 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 *);
static void (*p_pcap_freealldevs) (pcap_if_t *);
static int (*p_pcap_datalink_name_to_val) (const char *);
static const char *(*p_pcap_datalink_val_to_name) (int);
static const char *(*p_pcap_datalink_val_to_description) (int);
static void (*p_pcap_breakloop) (pcap_t *);
static const char *(*p_pcap_lib_version) (void);
static int (*p_pcap_setbuff) (pcap_t *, int dim);
static int (*p_pcap_next_ex) (pcap_t *, struct pcap_pkthdr **pkt_header, const u_char **pkt_data);
#ifdef HAVE_PCAP_REMOTE
static pcap_t* (*p_pcap_open) (const char *, int, int, int,
struct pcap_rmtauth *, char *);
static int (*p_pcap_findalldevs_ex) (const char *, struct pcap_rmtauth *,
pcap_if_t **, char *);
static int (*p_pcap_createsrcstr) (char *, int, const char *, const char *,
const char *, char *);
#endif
#ifdef HAVE_PCAP_SETSAMPLING
static struct pcap_samp* (*p_pcap_setsampling)(pcap_t *);
#endif
static int (*p_pcap_list_datalinks)(pcap_t *, int **);
static int (*p_pcap_set_datalink)(pcap_t *, int);
#ifdef HAVE_PCAP_FREE_DATALINKS
Move more capture device handling to the caputils library. Move the code to open capture devices and get properties of capture devices there, joining the code to get a list of capture devices. This lets us do a better job of handling pcap_create() in WinPcap, including handling both WinPcap with pcap_create() and WinPcap without pcap_create() at run time, just in case somebody tries using WinPcap 3.x with a Wireshark built with WinPcap 4.x. It also could make it easier to use libpcap/WinPcap directly in Wireshark and TShark, if we have versions of libpcap/WinPcap that run small helper utilities to do privileged functions, allowing programs using them never to need elevated privileges themselves. That might make it easier to fix some issues with running TShark when not saving to a file (we could avoid the file entirely) and with delays when stopping a capture in Wireshark (Wireshark could stop writing to the file as soon as you click the stop button, rather than letting dumpcap do so when the signal gets to it). It might also make it easier to handle future versions of libpcap/WinPcap that support using pcap_create()/pcap_activate() for remote captures, and other future extensions to libpcap/WinPcap. Rename some XXX_linktype routines to XXX_datalink to indicate that they work with DLT_ values rather than LINKTYPE_ values; future versions of libpcap might use LINKTYPE_ values in newer APIs. Check for pcap_create() on all platforms in CMake. Change-Id: Ia12e1692c96ec945c07a135d246958771a29c817 Reviewed-on: https://code.wireshark.org/review/13062 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Guy Harris <guy@alum.mit.edu>
2016-01-05 21:54:02 +00:00
static int (*p_pcap_free_datalinks)(int *);
#endif
Move more capture device handling to the caputils library. Move the code to open capture devices and get properties of capture devices there, joining the code to get a list of capture devices. This lets us do a better job of handling pcap_create() in WinPcap, including handling both WinPcap with pcap_create() and WinPcap without pcap_create() at run time, just in case somebody tries using WinPcap 3.x with a Wireshark built with WinPcap 4.x. It also could make it easier to use libpcap/WinPcap directly in Wireshark and TShark, if we have versions of libpcap/WinPcap that run small helper utilities to do privileged functions, allowing programs using them never to need elevated privileges themselves. That might make it easier to fix some issues with running TShark when not saving to a file (we could avoid the file entirely) and with delays when stopping a capture in Wireshark (Wireshark could stop writing to the file as soon as you click the stop button, rather than letting dumpcap do so when the signal gets to it). It might also make it easier to handle future versions of libpcap/WinPcap that support using pcap_create()/pcap_activate() for remote captures, and other future extensions to libpcap/WinPcap. Rename some XXX_linktype routines to XXX_datalink to indicate that they work with DLT_ values rather than LINKTYPE_ values; future versions of libpcap might use LINKTYPE_ values in newer APIs. Check for pcap_create() on all platforms in CMake. Change-Id: Ia12e1692c96ec945c07a135d246958771a29c817 Reviewed-on: https://code.wireshark.org/review/13062 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Guy Harris <guy@alum.mit.edu>
2016-01-05 21:54:02 +00:00
static char *(*p_bpf_image)(const struct bpf_insn *, int);
#ifdef HAVE_PCAP_CREATE
Move more capture device handling to the caputils library. Move the code to open capture devices and get properties of capture devices there, joining the code to get a list of capture devices. This lets us do a better job of handling pcap_create() in WinPcap, including handling both WinPcap with pcap_create() and WinPcap without pcap_create() at run time, just in case somebody tries using WinPcap 3.x with a Wireshark built with WinPcap 4.x. It also could make it easier to use libpcap/WinPcap directly in Wireshark and TShark, if we have versions of libpcap/WinPcap that run small helper utilities to do privileged functions, allowing programs using them never to need elevated privileges themselves. That might make it easier to fix some issues with running TShark when not saving to a file (we could avoid the file entirely) and with delays when stopping a capture in Wireshark (Wireshark could stop writing to the file as soon as you click the stop button, rather than letting dumpcap do so when the signal gets to it). It might also make it easier to handle future versions of libpcap/WinPcap that support using pcap_create()/pcap_activate() for remote captures, and other future extensions to libpcap/WinPcap. Rename some XXX_linktype routines to XXX_datalink to indicate that they work with DLT_ values rather than LINKTYPE_ values; future versions of libpcap might use LINKTYPE_ values in newer APIs. Check for pcap_create() on all platforms in CMake. Change-Id: Ia12e1692c96ec945c07a135d246958771a29c817 Reviewed-on: https://code.wireshark.org/review/13062 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Guy Harris <guy@alum.mit.edu>
2016-01-05 21:54:02 +00:00
static pcap_t *(*p_pcap_create)(const char *, char *);
static int (*p_pcap_set_snaplen)(pcap_t *, int);
static int (*p_pcap_set_promisc)(pcap_t *, int);
static int (*p_pcap_can_set_rfmon)(pcap_t *);
static int (*p_pcap_set_rfmon)(pcap_t *, int);
static int (*p_pcap_set_timeout)(pcap_t *, int);
static int (*p_pcap_set_buffer_size)(pcap_t *, int);
static int (*p_pcap_activate)(pcap_t *);
static const char *(*p_pcap_statustostr)(int);
#endif
#ifdef HAVE_PCAP_SET_TSTAMP_TYPE
static int (*p_pcap_set_tstamp_type)(pcap_t *, int);
static int (*p_pcap_set_tstamp_precision)(pcap_t *, int);
static int (*p_pcap_get_tstamp_precision)(pcap_t *);
static int (*p_pcap_list_tstamp_types)(pcap_t *, int **);
static void (*p_pcap_free_tstamp_types)(int *);
static int (*p_pcap_tstamp_type_name_to_val)(const char *);
static const char * (*p_pcap_tstamp_type_val_to_name)(int);
static const char * (*p_pcap_tstamp_type_val_to_description)(int);
#endif
typedef struct {
const char *name;
gpointer *ptr;
gboolean optional;
} symbol_table_t;
#define SYM(x, y) { G_STRINGIFY(x) , (gpointer) &CONCAT(p_,x), y }
void
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),
#ifdef HAVE_PCAP_REMOTE
SYM(pcap_open, FALSE),
SYM(pcap_findalldevs_ex, FALSE),
SYM(pcap_createsrcstr, FALSE),
#endif
SYM(pcap_open_live, FALSE),
SYM(pcap_open_dead, FALSE),
#ifdef HAVE_PCAP_SETSAMPLING
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),
#ifdef HAVE_PCAP_FREE_DATALINKS
SYM(pcap_free_datalinks, TRUE),
#endif
SYM(bpf_image, FALSE),
#ifdef HAVE_PCAP_CREATE
Move more capture device handling to the caputils library. Move the code to open capture devices and get properties of capture devices there, joining the code to get a list of capture devices. This lets us do a better job of handling pcap_create() in WinPcap, including handling both WinPcap with pcap_create() and WinPcap without pcap_create() at run time, just in case somebody tries using WinPcap 3.x with a Wireshark built with WinPcap 4.x. It also could make it easier to use libpcap/WinPcap directly in Wireshark and TShark, if we have versions of libpcap/WinPcap that run small helper utilities to do privileged functions, allowing programs using them never to need elevated privileges themselves. That might make it easier to fix some issues with running TShark when not saving to a file (we could avoid the file entirely) and with delays when stopping a capture in Wireshark (Wireshark could stop writing to the file as soon as you click the stop button, rather than letting dumpcap do so when the signal gets to it). It might also make it easier to handle future versions of libpcap/WinPcap that support using pcap_create()/pcap_activate() for remote captures, and other future extensions to libpcap/WinPcap. Rename some XXX_linktype routines to XXX_datalink to indicate that they work with DLT_ values rather than LINKTYPE_ values; future versions of libpcap might use LINKTYPE_ values in newer APIs. Check for pcap_create() on all platforms in CMake. Change-Id: Ia12e1692c96ec945c07a135d246958771a29c817 Reviewed-on: https://code.wireshark.org/review/13062 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Guy Harris <guy@alum.mit.edu>
2016-01-05 21:54:02 +00:00
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),
Move more capture device handling to the caputils library. Move the code to open capture devices and get properties of capture devices there, joining the code to get a list of capture devices. This lets us do a better job of handling pcap_create() in WinPcap, including handling both WinPcap with pcap_create() and WinPcap without pcap_create() at run time, just in case somebody tries using WinPcap 3.x with a Wireshark built with WinPcap 4.x. It also could make it easier to use libpcap/WinPcap directly in Wireshark and TShark, if we have versions of libpcap/WinPcap that run small helper utilities to do privileged functions, allowing programs using them never to need elevated privileges themselves. That might make it easier to fix some issues with running TShark when not saving to a file (we could avoid the file entirely) and with delays when stopping a capture in Wireshark (Wireshark could stop writing to the file as soon as you click the stop button, rather than letting dumpcap do so when the signal gets to it). It might also make it easier to handle future versions of libpcap/WinPcap that support using pcap_create()/pcap_activate() for remote captures, and other future extensions to libpcap/WinPcap. Rename some XXX_linktype routines to XXX_datalink to indicate that they work with DLT_ values rather than LINKTYPE_ values; future versions of libpcap might use LINKTYPE_ values in newer APIs. Check for pcap_create() on all platforms in CMake. Change-Id: Ia12e1692c96ec945c07a135d246958771a29c817 Reviewed-on: https://code.wireshark.org/review/13062 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Guy Harris <guy@alum.mit.edu>
2016-01-05 21:54:02 +00:00
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),
#endif
{ NULL, NULL, FALSE }
};
GModule *wh; /* wpcap handle */
const symbol_table_t *sym;
wh = ws_module_open("wpcap.dll", 0);
if (!wh) {
return;
}
sym = symbols;
while (sym->name) {
if (!g_module_symbol(wh, sym->name, sym->ptr)) {
if (sym->optional) {
/*
* We don't care if it's missing; we just
* don't use it.
*/
*sym->ptr = NULL;
} else {
/*
* We require this symbol.
*/
return;
}
}
sym++;
}
has_wpcap = TRUE;
}
static char *
local_code_page_str_to_utf8(char *str)
{
ULONG utf16_len;
wchar_t *utf16_str;
char *utf8_str;
if (str == NULL) {
return NULL;
}
utf16_len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
utf16_str = g_malloc_n(utf16_len, sizeof(wchar_t));
MultiByteToWideChar(CP_ACP, 0, str, -1, utf16_str, utf16_len);
utf8_str = g_utf16_to_utf8(utf16_str, -1, NULL, NULL, NULL);
g_free(utf16_str);
return utf8_str;
}
static void
prepare_errbuf(char *errbuf)
{
2021-06-18 18:21:42 +00:00
ws_assert(errbuf);
errbuf[0] = '\0';
}
static void
convert_errbuf_to_utf8(char *errbuf)
{
gchar *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);
g_free(utf8_err);
}
static char *
cant_load_winpcap_err(const char *app_name)
{
return g_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"
"\n"
"for a downloadable version of Npcap and for instructions on how to\n"
"install it.",
app_name);
}
void
pcap_close(pcap_t *a)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
p_pcap_close(a);
}
int
pcap_stats(pcap_t *a, struct pcap_stat *b)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
return p_pcap_stats(a, b);
}
int
pcap_dispatch(pcap_t *a, int b, pcap_handler c, guchar *d)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
return p_pcap_dispatch(a, b, c, d);
}
int
pcap_snapshot(pcap_t *a)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
return p_pcap_snapshot(a);
}
int
pcap_datalink(pcap_t *a)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
return p_pcap_datalink(a);
}
int
pcap_set_datalink(pcap_t *p, int dlt)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
return p_pcap_set_datalink(p, dlt);
}
int
pcap_setfilter(pcap_t *a, struct bpf_program *b)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
return p_pcap_setfilter(a, b);
}
char*
pcap_geterr(pcap_t *a)
{
char *errbuf;
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
errbuf = p_pcap_geterr(a);
convert_errbuf_to_utf8(errbuf);
return errbuf;
}
int
pcap_compile(pcap_t *a, struct bpf_program *b, const char *c, int d,
bpf_u_int32 e)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
return p_pcap_compile(a, b, c, d, e);
}
int
pcap_compile_nopcap(int a, int b, struct bpf_program *c, const char *d, int e,
bpf_u_int32 f)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
return p_pcap_compile_nopcap(a, b, c, d, e, f);
}
int
pcap_lookupnet(const char *a, bpf_u_int32 *b, bpf_u_int32 *c, char *errbuf)
{
int ret;
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
ret = p_pcap_lookupnet(a, b, c, errbuf);
if (ret == -1)
convert_errbuf_to_utf8(errbuf);
return ret;
}
pcap_t*
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,
"unable to load Npcap or WinPcap (wpcap.dll); can't open %s to capture",
a);
return NULL;
}
prepare_errbuf(errbuf);
p = p_pcap_open_live(a, b, c, d, errbuf);
convert_errbuf_to_utf8(errbuf);
return p;
}
pcap_t*
pcap_open_dead(int a, int b)
{
if (!has_wpcap) {
return NULL;
}
return p_pcap_open_dead(a, b);
}
char *
bpf_image(const struct bpf_insn *a, int b)
{
if (!has_wpcap) {
return NULL;
}
return p_bpf_image(a, b);
}
#ifdef HAVE_PCAP_REMOTE
pcap_t*
pcap_open(const char *a, int b, int c, int d, struct pcap_rmtauth *e, char *errbuf)
{
pcap_t *ret;
if (!has_wpcap) {
g_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"unable to load Npcap or WinPcap (wpcap.dll); can't open %s to capture",
a);
return NULL;
}
prepare_errbuf(errbuf);
ret = p_pcap_open(a, b, c, d, e, errbuf);
convert_errbuf_to_utf8(errbuf);
return ret;
}
int
pcap_findalldevs_ex(const char *a, struct pcap_rmtauth *b, pcap_if_t **c, char *errbuf)
{
int ret;
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
ret = p_pcap_findalldevs_ex(a, b, c, errbuf);
if (ret == -1)
convert_errbuf_to_utf8(errbuf);
return ret;
}
int
pcap_createsrcstr(char *a, int b, const char *c, const char *d, const char *e,
char *errbuf)
{
int ret;
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
ret = p_pcap_createsrcstr(a, b, c, d, e, errbuf);
if (ret == -1)
convert_errbuf_to_utf8(errbuf);
return ret;
}
#endif
#ifdef HAVE_PCAP_SETSAMPLING
struct pcap_samp *
pcap_setsampling(pcap_t *a)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
if (p_pcap_setsampling != NULL) {
return p_pcap_setsampling(a);
}
return NULL;
}
#endif
int
pcap_loop(pcap_t *a, int b, pcap_handler c, guchar *d)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
return p_pcap_loop(a, b, c, d);
}
void
pcap_freecode(struct bpf_program *a)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
p_pcap_freecode(a);
}
int
pcap_findalldevs(pcap_if_t **a, char *errbuf)
{
int ret;
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
ret = p_pcap_findalldevs(a, errbuf);
if (ret == -1)
convert_errbuf_to_utf8(errbuf);
return ret;
}
void
pcap_freealldevs(pcap_if_t *a)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
p_pcap_freealldevs(a);
}
#ifdef HAVE_PCAP_CREATE
pcap_t *
pcap_create(const char *a, char *errbuf)
{
pcap_t *p;
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap && p_pcap_create != NULL);
p = p_pcap_create(a, errbuf);
if (p == NULL)
convert_errbuf_to_utf8(errbuf);
return p;
}
int
pcap_set_snaplen(pcap_t *a, int b)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap && p_pcap_set_snaplen != NULL);
return p_pcap_set_snaplen(a, b);
}
int
pcap_set_promisc(pcap_t *a, int b)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap && p_pcap_set_promisc != NULL);
return p_pcap_set_promisc(a, b);
}
int
pcap_can_set_rfmon(pcap_t *a)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
if (p_pcap_can_set_rfmon != NULL) {
return p_pcap_can_set_rfmon(a);
}
return 0;
}
int
pcap_set_rfmon(pcap_t *a, int b)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap && p_pcap_set_rfmon != NULL);
return p_pcap_set_rfmon(a, b);
}
int
pcap_set_timeout(pcap_t *a, int b)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap && p_pcap_set_timeout != NULL);
return p_pcap_set_timeout(a, b);
}
int
pcap_set_buffer_size(pcap_t *a, int b)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap && p_pcap_set_buffer_size != NULL);
return p_pcap_set_buffer_size(a, b);
}
int
pcap_activate(pcap_t *a)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap && p_pcap_activate != NULL);
return p_pcap_activate(a);
}
const char *
pcap_statustostr(int a)
{
static char ebuf[15 + 10 + 1];
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
if (p_pcap_statustostr != NULL) {
return p_pcap_statustostr(a);
}
/* XXX copy routine from pcap.c ??? */
(void)g_snprintf(ebuf, sizeof ebuf, "Don't have pcap_statustostr(), can't translate error: %d", a);
return(ebuf);
}
#endif
#ifdef HAVE_PCAP_SET_TSTAMP_TYPE
int
pcap_set_tstamp_type(pcap_t *a, int b) {
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
if (p_pcap_set_tstamp_type != NULL) {
return p_pcap_set_tstamp_type(a, b);
}
return PCAP_ERROR_CANTSET_TSTAMP_TYPE;
}
int
pcap_set_tstamp_precision(pcap_t *a, int b) {
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
if (p_pcap_set_tstamp_precision != NULL) {
return p_pcap_set_tstamp_precision(a, b);
}
// No error code defined so return NOTSUP.
return PCAP_ERROR_TSTAMP_PRECISION_NOTSUP;
}
int
pcap_get_tstamp_precision(pcap_t *a) {
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
if (p_pcap_get_tstamp_precision != NULL) {
return p_pcap_get_tstamp_precision(a);
}
// No error code defined so return MICRO.
return PCAP_TSTAMP_PRECISION_MICRO;
}
int
pcap_list_tstamp_types(pcap_t *a, int **b) {
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
if (p_pcap_list_tstamp_types != NULL) {
return p_pcap_list_tstamp_types(a, b);
}
return PCAP_ERROR;
}
void
pcap_free_tstamp_types(int *a) {
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
if (p_pcap_free_tstamp_types != NULL) {
p_pcap_free_tstamp_types(a);
}
}
int
pcap_tstamp_type_name_to_val(const char *a) {
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
if (p_pcap_tstamp_type_name_to_val != NULL) {
return p_pcap_tstamp_type_name_to_val(a);
}
return PCAP_ERROR;
}
const char *
pcap_tstamp_type_val_to_name(int a) {
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
if (p_pcap_tstamp_type_val_to_name != NULL) {
return p_pcap_tstamp_type_val_to_name(a);
}
return NULL;
}
const char *
pcap_tstamp_type_val_to_description(int a) {
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
if (p_pcap_tstamp_type_val_to_description != NULL) {
return p_pcap_tstamp_type_val_to_description(a);
}
return NULL;
}
#endif
int
pcap_datalink_name_to_val(const char *name)
{
if (has_wpcap)
return p_pcap_datalink_name_to_val(name);
else
return -1;
}
int
pcap_list_datalinks(pcap_t *p, int **ddlt)
{
if (has_wpcap)
return p_pcap_list_datalinks(p, ddlt);
else
return -1;
}
#ifdef HAVE_PCAP_FREE_DATALINKS
void
pcap_free_datalinks(int *ddlt)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
/*
* If we don't have pcap_free_datalinks() in WinPcap,
* we don't free the memory - we can't use free(), as
* we might not have been built with the same version
* of the C runtime library as WinPcap was, and, if we're
* not, free() isn't guaranteed to work on something
* allocated by WinPcap.
*/
if (p_pcap_free_datalinks != NULL)
p_pcap_free_datalinks(ddlt);
}
#endif
const char *
pcap_datalink_val_to_name(int dlt)
{
if (has_wpcap)
return p_pcap_datalink_val_to_name(dlt);
else
return NULL;
}
const char *
pcap_datalink_val_to_description(int dlt)
{
if (has_wpcap)
return p_pcap_datalink_val_to_description(dlt);
return NULL;
}
void pcap_breakloop(pcap_t *a)
{
p_pcap_breakloop(a);
}
/* setbuff is win32 specific! */
int pcap_setbuff(pcap_t *a, int b)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
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)
{
2021-06-18 18:21:42 +00:00
ws_assert(has_wpcap);
return p_pcap_next_ex(a, b, c);
}
#ifdef HAVE_PCAP_REMOTE
GList *
get_remote_interface_list(const char *hostname, const char *port,
int auth_type, const char *username,
const char *passwd, int *err, char **err_str)
{
if (!has_wpcap) {
/*
* We don't have Npcap or WinPcap, so we can't get a list of
* interfaces.
*/
*err = DONT_HAVE_PCAP;
if (err_str != NULL)
*err_str = cant_load_winpcap_err("you");
return NULL;
}
return get_interface_list_findalldevs_ex(hostname, port, auth_type,
username, passwd, err, err_str);
}
#endif
GList *
get_interface_list(int *err, char **err_str)
{
if (!has_wpcap) {
/*
* We don't have Npcap or WinPcap, so we can't get a list of
* interfaces.
*/
*err = DONT_HAVE_PCAP;
if (err_str != NULL)
*err_str = cant_load_winpcap_err("you");
return NULL;
}
return get_interface_list_findalldevs(err, err_str);
}
/*
* Get an error message string for a CANT_GET_INTERFACE_LIST error from
* "get_interface_list()".
*/
gchar *
cant_get_if_list_error_message(const char *err_str)
{
/*
* If the error message includes "Not enough storage is available
* to process this command" or "The operation completed successfully",
* suggest that they install a WinPcap version later than 3.0.
*/
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"
"This might be a problem with WinPcap 3.0. You should try updating to\n"
"Npcap. See https://nmap.org/npcap/ for more information.",
err_str);
}
return g_strdup_printf("Can't get list of interfaces: %s", err_str);
}
Move more capture device handling to the caputils library. Move the code to open capture devices and get properties of capture devices there, joining the code to get a list of capture devices. This lets us do a better job of handling pcap_create() in WinPcap, including handling both WinPcap with pcap_create() and WinPcap without pcap_create() at run time, just in case somebody tries using WinPcap 3.x with a Wireshark built with WinPcap 4.x. It also could make it easier to use libpcap/WinPcap directly in Wireshark and TShark, if we have versions of libpcap/WinPcap that run small helper utilities to do privileged functions, allowing programs using them never to need elevated privileges themselves. That might make it easier to fix some issues with running TShark when not saving to a file (we could avoid the file entirely) and with delays when stopping a capture in Wireshark (Wireshark could stop writing to the file as soon as you click the stop button, rather than letting dumpcap do so when the signal gets to it). It might also make it easier to handle future versions of libpcap/WinPcap that support using pcap_create()/pcap_activate() for remote captures, and other future extensions to libpcap/WinPcap. Rename some XXX_linktype routines to XXX_datalink to indicate that they work with DLT_ values rather than LINKTYPE_ values; future versions of libpcap might use LINKTYPE_ values in newer APIs. Check for pcap_create() on all platforms in CMake. Change-Id: Ia12e1692c96ec945c07a135d246958771a29c817 Reviewed-on: https://code.wireshark.org/review/13062 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Guy Harris <guy@alum.mit.edu>
2016-01-05 21:54:02 +00:00
if_capabilities_t *
get_if_capabilities_local(interface_options *interface_opts,
cap_device_open_status *status, char **status_str)
Move more capture device handling to the caputils library. Move the code to open capture devices and get properties of capture devices there, joining the code to get a list of capture devices. This lets us do a better job of handling pcap_create() in WinPcap, including handling both WinPcap with pcap_create() and WinPcap without pcap_create() at run time, just in case somebody tries using WinPcap 3.x with a Wireshark built with WinPcap 4.x. It also could make it easier to use libpcap/WinPcap directly in Wireshark and TShark, if we have versions of libpcap/WinPcap that run small helper utilities to do privileged functions, allowing programs using them never to need elevated privileges themselves. That might make it easier to fix some issues with running TShark when not saving to a file (we could avoid the file entirely) and with delays when stopping a capture in Wireshark (Wireshark could stop writing to the file as soon as you click the stop button, rather than letting dumpcap do so when the signal gets to it). It might also make it easier to handle future versions of libpcap/WinPcap that support using pcap_create()/pcap_activate() for remote captures, and other future extensions to libpcap/WinPcap. Rename some XXX_linktype routines to XXX_datalink to indicate that they work with DLT_ values rather than LINKTYPE_ values; future versions of libpcap might use LINKTYPE_ values in newer APIs. Check for pcap_create() on all platforms in CMake. Change-Id: Ia12e1692c96ec945c07a135d246958771a29c817 Reviewed-on: https://code.wireshark.org/review/13062 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Guy Harris <guy@alum.mit.edu>
2016-01-05 21:54:02 +00:00
{
/*
* We're not getting capaibilities for a remote device; use
* pcap_create() and pcap_activate() if we have them, so that
* we can set various options, otherwise use pcap_open_live().
*/
#ifdef HAVE_PCAP_CREATE
if (p_pcap_create != NULL)
return get_if_capabilities_pcap_create(interface_opts, status,
status_str);
Move more capture device handling to the caputils library. Move the code to open capture devices and get properties of capture devices there, joining the code to get a list of capture devices. This lets us do a better job of handling pcap_create() in WinPcap, including handling both WinPcap with pcap_create() and WinPcap without pcap_create() at run time, just in case somebody tries using WinPcap 3.x with a Wireshark built with WinPcap 4.x. It also could make it easier to use libpcap/WinPcap directly in Wireshark and TShark, if we have versions of libpcap/WinPcap that run small helper utilities to do privileged functions, allowing programs using them never to need elevated privileges themselves. That might make it easier to fix some issues with running TShark when not saving to a file (we could avoid the file entirely) and with delays when stopping a capture in Wireshark (Wireshark could stop writing to the file as soon as you click the stop button, rather than letting dumpcap do so when the signal gets to it). It might also make it easier to handle future versions of libpcap/WinPcap that support using pcap_create()/pcap_activate() for remote captures, and other future extensions to libpcap/WinPcap. Rename some XXX_linktype routines to XXX_datalink to indicate that they work with DLT_ values rather than LINKTYPE_ values; future versions of libpcap might use LINKTYPE_ values in newer APIs. Check for pcap_create() on all platforms in CMake. Change-Id: Ia12e1692c96ec945c07a135d246958771a29c817 Reviewed-on: https://code.wireshark.org/review/13062 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Guy Harris <guy@alum.mit.edu>
2016-01-05 21:54:02 +00:00
#endif
return get_if_capabilities_pcap_open_live(interface_opts, status,
status_str);
Move more capture device handling to the caputils library. Move the code to open capture devices and get properties of capture devices there, joining the code to get a list of capture devices. This lets us do a better job of handling pcap_create() in WinPcap, including handling both WinPcap with pcap_create() and WinPcap without pcap_create() at run time, just in case somebody tries using WinPcap 3.x with a Wireshark built with WinPcap 4.x. It also could make it easier to use libpcap/WinPcap directly in Wireshark and TShark, if we have versions of libpcap/WinPcap that run small helper utilities to do privileged functions, allowing programs using them never to need elevated privileges themselves. That might make it easier to fix some issues with running TShark when not saving to a file (we could avoid the file entirely) and with delays when stopping a capture in Wireshark (Wireshark could stop writing to the file as soon as you click the stop button, rather than letting dumpcap do so when the signal gets to it). It might also make it easier to handle future versions of libpcap/WinPcap that support using pcap_create()/pcap_activate() for remote captures, and other future extensions to libpcap/WinPcap. Rename some XXX_linktype routines to XXX_datalink to indicate that they work with DLT_ values rather than LINKTYPE_ values; future versions of libpcap might use LINKTYPE_ values in newer APIs. Check for pcap_create() on all platforms in CMake. Change-Id: Ia12e1692c96ec945c07a135d246958771a29c817 Reviewed-on: https://code.wireshark.org/review/13062 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Guy Harris <guy@alum.mit.edu>
2016-01-05 21:54:02 +00:00
}
pcap_t *
open_capture_device_local(capture_options *capture_opts,
interface_options *interface_opts, int timeout,
cap_device_open_status *open_status,
char (*open_status_str)[PCAP_ERRBUF_SIZE])
Move more capture device handling to the caputils library. Move the code to open capture devices and get properties of capture devices there, joining the code to get a list of capture devices. This lets us do a better job of handling pcap_create() in WinPcap, including handling both WinPcap with pcap_create() and WinPcap without pcap_create() at run time, just in case somebody tries using WinPcap 3.x with a Wireshark built with WinPcap 4.x. It also could make it easier to use libpcap/WinPcap directly in Wireshark and TShark, if we have versions of libpcap/WinPcap that run small helper utilities to do privileged functions, allowing programs using them never to need elevated privileges themselves. That might make it easier to fix some issues with running TShark when not saving to a file (we could avoid the file entirely) and with delays when stopping a capture in Wireshark (Wireshark could stop writing to the file as soon as you click the stop button, rather than letting dumpcap do so when the signal gets to it). It might also make it easier to handle future versions of libpcap/WinPcap that support using pcap_create()/pcap_activate() for remote captures, and other future extensions to libpcap/WinPcap. Rename some XXX_linktype routines to XXX_datalink to indicate that they work with DLT_ values rather than LINKTYPE_ values; future versions of libpcap might use LINKTYPE_ values in newer APIs. Check for pcap_create() on all platforms in CMake. Change-Id: Ia12e1692c96ec945c07a135d246958771a29c817 Reviewed-on: https://code.wireshark.org/review/13062 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Guy Harris <guy@alum.mit.edu>
2016-01-05 21:54:02 +00:00
{
/*
* We're not opening a remote device; use pcap_create() and
* pcap_activate() if we have them, so that we can set various
* options, otherwise use pcap_open_live().
*/
#ifdef HAVE_PCAP_CREATE
if (p_pcap_create != NULL)
return open_capture_device_pcap_create(capture_opts,
interface_opts, timeout, open_status, open_status_str);
Move more capture device handling to the caputils library. Move the code to open capture devices and get properties of capture devices there, joining the code to get a list of capture devices. This lets us do a better job of handling pcap_create() in WinPcap, including handling both WinPcap with pcap_create() and WinPcap without pcap_create() at run time, just in case somebody tries using WinPcap 3.x with a Wireshark built with WinPcap 4.x. It also could make it easier to use libpcap/WinPcap directly in Wireshark and TShark, if we have versions of libpcap/WinPcap that run small helper utilities to do privileged functions, allowing programs using them never to need elevated privileges themselves. That might make it easier to fix some issues with running TShark when not saving to a file (we could avoid the file entirely) and with delays when stopping a capture in Wireshark (Wireshark could stop writing to the file as soon as you click the stop button, rather than letting dumpcap do so when the signal gets to it). It might also make it easier to handle future versions of libpcap/WinPcap that support using pcap_create()/pcap_activate() for remote captures, and other future extensions to libpcap/WinPcap. Rename some XXX_linktype routines to XXX_datalink to indicate that they work with DLT_ values rather than LINKTYPE_ values; future versions of libpcap might use LINKTYPE_ values in newer APIs. Check for pcap_create() on all platforms in CMake. Change-Id: Ia12e1692c96ec945c07a135d246958771a29c817 Reviewed-on: https://code.wireshark.org/review/13062 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Guy Harris <guy@alum.mit.edu>
2016-01-05 21:54:02 +00:00
#endif
return open_capture_device_pcap_open_live(interface_opts, timeout,
open_status, open_status_str);
Move more capture device handling to the caputils library. Move the code to open capture devices and get properties of capture devices there, joining the code to get a list of capture devices. This lets us do a better job of handling pcap_create() in WinPcap, including handling both WinPcap with pcap_create() and WinPcap without pcap_create() at run time, just in case somebody tries using WinPcap 3.x with a Wireshark built with WinPcap 4.x. It also could make it easier to use libpcap/WinPcap directly in Wireshark and TShark, if we have versions of libpcap/WinPcap that run small helper utilities to do privileged functions, allowing programs using them never to need elevated privileges themselves. That might make it easier to fix some issues with running TShark when not saving to a file (we could avoid the file entirely) and with delays when stopping a capture in Wireshark (Wireshark could stop writing to the file as soon as you click the stop button, rather than letting dumpcap do so when the signal gets to it). It might also make it easier to handle future versions of libpcap/WinPcap that support using pcap_create()/pcap_activate() for remote captures, and other future extensions to libpcap/WinPcap. Rename some XXX_linktype routines to XXX_datalink to indicate that they work with DLT_ values rather than LINKTYPE_ values; future versions of libpcap might use LINKTYPE_ values in newer APIs. Check for pcap_create() on all platforms in CMake. Change-Id: Ia12e1692c96ec945c07a135d246958771a29c817 Reviewed-on: https://code.wireshark.org/review/13062 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Guy Harris <guy@alum.mit.edu>
2016-01-05 21:54:02 +00:00
}
/*
* Append the WinPcap or Npcap SDK version with which we were compiled to a GString.
*/
void
get_compiled_caplibs_version(GString *str)
{
g_string_append(str, "with libpcap");
}
/*
* Append the version of Npcap with which we we're running to a GString.
*/
void
get_runtime_caplibs_version(GString *str)
{
/*
* On Windows, we might have been compiled with WinPcap/Npcap but
* might not have it loaded; indicate whether we have it or
* 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());
} else
g_string_append(str, "without Npcap or WinPcap");
}
/*
* If npf.sys is running, return TRUE.
*/
gboolean
npf_sys_is_running(void)
{
SC_HANDLE h_scm, h_serv;
SERVICE_STATUS ss;
h_scm = OpenSCManager(NULL, NULL, 0);
if (!h_scm)
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;
}
}
if (QueryServiceStatus(h_serv, &ss)) {
if (ss.dwCurrentState & SERVICE_RUNNING) {
CloseServiceHandle(h_serv);
CloseServiceHandle(h_scm);
return TRUE;
}
}
CloseServiceHandle(h_serv);
CloseServiceHandle(h_scm);
return FALSE;
}
#else /* HAVE_LIBPCAP */
void
load_wpcap(void)
{
return;
}
/*
* Append an indication that we were not compiled with WinPcap
* to a GString.
*/
void
get_compiled_caplibs_version(GString *str)
{
g_string_append(str, "without Npcap or WinPcap");
}
/*
* Don't append anything, as we weren't even compiled to use WinPcap/Npcap.
*/
void
get_runtime_caplibs_version(GString *str _U_)
{
}
#endif /* HAVE_LIBPCAP */
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/