/*
* [wi]npcap dynamic loader
*
* Copyright (C) 2021 Matt Borgerson
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include "qemu/osdep.h"
#include
#include
const char *lib_not_loaded_err = "winpcap library is not loaded";
static pcap_t *pcap_open_live_stub(const char *device, int snaplen, int promisc, int to_ms, char *errbuf)
{
strncpy(errbuf, lib_not_loaded_err, PCAP_ERRBUF_SIZE);
return NULL;
}
static int pcap_findalldevs_stub(pcap_if_t **alldevsp, char *errbuf)
{
strncpy(errbuf, lib_not_loaded_err, PCAP_ERRBUF_SIZE);
return -1;
}
void (*fptr_pcap_close)(pcap_t *);
int (*fptr_pcap_next_ex)(pcap_t *, struct pcap_pkthdr **, const u_char **);
char *(*fptr_pcap_geterr)(pcap_t *);
pcap_t *(*fptr_pcap_open_live)(const char *, int, int, int, char *) = pcap_open_live_stub;
int (*fptr_pcap_set_datalink)(pcap_t *, int);
int (*fptr_pcap_setmintocopy)(pcap_t *p, int size);
HANDLE (*fptr_pcap_getevent)(pcap_t *p);
int (*fptr_pcap_sendpacket)(pcap_t *, const u_char *, int);
int (*fptr_pcap_findalldevs)(pcap_if_t **, char *) = pcap_findalldevs_stub;
void (*fptr_pcap_freealldevs)(pcap_if_t *);
void pcap_close(pcap_t *p)
{ fptr_pcap_close(p); }
int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, const u_char **pkt_data)
{ return fptr_pcap_next_ex(p, pkt_header, pkt_data); }
char *pcap_geterr(pcap_t *p)
{ return fptr_pcap_geterr(p); }
pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *errbuf)
{ return fptr_pcap_open_live(device, snaplen, promisc, to_ms, errbuf); }
int pcap_set_datalink(pcap_t *p, int dlt)
{ return fptr_pcap_set_datalink(p, dlt); }
int pcap_setmintocopy(pcap_t *p, int size)
{ return fptr_pcap_setmintocopy(p, size); }
HANDLE pcap_getevent(pcap_t *p)
{ return fptr_pcap_getevent(p); }
int pcap_sendpacket(pcap_t *p, const u_char *buf, int size)
{ return fptr_pcap_sendpacket(p, buf, size); }
int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{ return fptr_pcap_findalldevs(alldevsp, errbuf); }
void pcap_freealldevs(pcap_if_t *alldevs)
{ fptr_pcap_freealldevs(alldevs); }
int pcap_load_library(void)
{
static int is_loaded = 0;
if (is_loaded) {
return 0;
}
HANDLE hwpcap = LoadLibrary("wpcap.dll");
if (hwpcap == NULL) {
return 1;
}
#define LOAD_FN(fname) do {\
void *p = (void*)GetProcAddress(hwpcap, stringify(fname)); \
if (p == NULL) { \
return 1; \
} else { \
fptr_ ## fname = p; \
} \
} while(0)
LOAD_FN(pcap_close);
LOAD_FN(pcap_next_ex);
LOAD_FN(pcap_geterr);
LOAD_FN(pcap_open_live);
LOAD_FN(pcap_set_datalink);
LOAD_FN(pcap_setmintocopy);
LOAD_FN(pcap_getevent);
LOAD_FN(pcap_sendpacket);
LOAD_FN(pcap_findalldevs);
LOAD_FN(pcap_freealldevs);
is_loaded = 1;
return 0;
}