summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/netdev/pcap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/netdev/pcap.cpp')
-rw-r--r--src/osd/modules/netdev/pcap.cpp181
1 files changed, 72 insertions, 109 deletions
diff --git a/src/osd/modules/netdev/pcap.cpp b/src/osd/modules/netdev/pcap.cpp
index 541ed422d8a..1cd7ae3bfa8 100644
--- a/src/osd/modules/netdev/pcap.cpp
+++ b/src/osd/modules/netdev/pcap.cpp
@@ -1,61 +1,47 @@
// license:BSD-3-Clause
// copyright-holders:Carl
-#if defined(OSD_NET_USE_PCAP)
-#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
-#ifdef UNICODE
-#define LIB_NAME L"wpcap.dll"
-#define LoadDynamicLibrary LoadLibraryW
-#else
-#define LIB_NAME "wpcap.dll"
-#define LoadDynamicLibrary LoadLibraryA
-#endif
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif
-
-#include <pcap.h>
+#if defined(OSD_NET_USE_PCAP)
#include "emu.h"
#include "osdnet.h"
#include "netdev_module.h"
#include "modules/osdmodule.h"
+#include "modules/lib/osdlib.h"
#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef interface
+#define LIB_NAME "wpcap.dll"
-#define LIB_ERROR_STR "Unable to load winpcap: %lx\n"
-typedef DWORD except_type;
-
-#else
-
-#include <dlfcn.h>
-#ifdef SDLMAME_MACOSX
+#elif defined(SDLMAME_MACOSX)
#include <pthread.h>
#include <libkern/OSAtomic.h>
-#endif
-
-#ifdef SDLMAME_MACOSX
#define LIB_NAME "libpcap.dylib"
+
#else
#define LIB_NAME "libpcap.so"
#endif
-#define LIB_ERROR_STR "Unable to load pcap: %s\n"
-typedef void *HMODULE;
-typedef const char *except_type;
-#define FreeLibrary(x) dlclose(x)
-#define GetLastError() dlerror()
-#define GetProcAddress(x, y) dlsym(x, y)
-#define LoadDynamicLibrary(x) dlopen(x, RTLD_LAZY)
+#include <pcap.h>
-#endif
+// Typedefs for dynamically loaded functions
+typedef int (*pcap_findalldevs_fn)(pcap_if_t **, char *);
+typedef pcap_t *(*pcap_open_live_fn)(const char *, int, int, int, char *);
+typedef int (*pcap_next_ex_fn)(pcap_t *, struct pcap_pkthdr **, const u_char **);
+typedef int (*pcap_compile_fn)(pcap_t *, struct bpf_program *, const char *, int, bpf_u_int32);
+typedef void (*pcap_close_fn)(pcap_t *);
+typedef int (*pcap_setfilter_fn)(pcap_t *, struct bpf_program *);
+typedef int (*pcap_sendpacket_fn)(pcap_t *, const u_char *, int);
+typedef int (*pcap_set_datalink_fn)(pcap_t *, int);
+typedef int (*pcap_dispatch_fn)(pcap_t *, int, pcap_handler, u_char *);
class pcap_module : public osd_module, public netdev_module
{
public:
-
pcap_module()
- : osd_module(OSD_NETDEV_PROVIDER, "pcap"), netdev_module(), handle(nullptr)
+ : osd_module(OSD_NETDEV_PROVIDER, "pcap"), netdev_module()
{
}
virtual ~pcap_module() { }
@@ -63,32 +49,46 @@ public:
virtual int init(const osd_options &options) override;
virtual void exit() override;
- virtual bool probe() override;
+ virtual bool probe() override
+ {
+ pcap_dll = osd::dynamic_module::open({ LIB_NAME });
+
+ pcap_findalldevs_dl = pcap_dll->bind<pcap_findalldevs_fn>("pcap_findalldevs");
+ pcap_open_live_dl = pcap_dll->bind<pcap_open_live_fn>("pcap_open_live");
+ pcap_next_ex_dl = pcap_dll->bind<pcap_next_ex_fn>("pcap_next_ex");
+ pcap_compile_dl = pcap_dll->bind<pcap_compile_fn>("pcap_compile");
+ pcap_close_dl = pcap_dll->bind<pcap_close_fn>("pcap_close");
+ pcap_setfilter_dl = pcap_dll->bind<pcap_setfilter_fn>("pcap_setfilter");
+ pcap_sendpacket_dl = pcap_dll->bind<pcap_sendpacket_fn>("pcap_sendpacket");
+ pcap_set_datalink_dl = pcap_dll->bind<pcap_set_datalink_fn>("pcap_set_datalink");
+ pcap_dispatch_dl = pcap_dll->bind<pcap_dispatch_fn>("pcap_dispatch");
+
+ if (!pcap_findalldevs_dl || !pcap_open_live_dl || !pcap_next_ex_dl ||
+ !pcap_compile_dl || !pcap_close_dl || !pcap_setfilter_dl ||
+ !pcap_sendpacket_dl || !pcap_set_datalink_dl || !pcap_dispatch_dl)
+ {
+ osd_printf_error("Unable to load the PCAP library\n");
+ return false;
+ }
+
+ return true;
+ }
- HMODULE handle;
+ osd::dynamic_module::ptr pcap_dll;
+
+ pcap_findalldevs_fn pcap_findalldevs_dl;
+ pcap_open_live_fn pcap_open_live_dl;
+ pcap_next_ex_fn pcap_next_ex_dl;
+ pcap_compile_fn pcap_compile_dl;
+ pcap_close_fn pcap_close_dl;
+ pcap_setfilter_fn pcap_setfilter_dl;
+ pcap_sendpacket_fn pcap_sendpacket_dl;
+ pcap_set_datalink_fn pcap_set_datalink_dl;
+ pcap_dispatch_fn pcap_dispatch_dl;
};
-static int (*pcap_compile_dl)(pcap_t *, struct bpf_program *, char *, int, bpf_u_int32) = nullptr;
-static int (*pcap_findalldevs_dl)(pcap_if_t **, char *) = nullptr;
-static pcap_t *(*pcap_open_live_dl)(const char *name, int, int, int, char *) = nullptr;
-static int (*pcap_next_ex_dl)(pcap_t *, struct pcap_pkthdr **, const u_char **) = nullptr;
-static void (*pcap_close_dl)(pcap_t *) = nullptr;
-static int (*pcap_setfilter_dl)(pcap_t *, struct bpf_program *) = nullptr;
-static int (*pcap_sendpacket_dl)(pcap_t *, u_char *, int) = nullptr;
-static int (*pcap_set_datalink_dl)(pcap_t *, int) = nullptr;
-static int (*pcap_dispatch_dl)(pcap_t *, int, pcap_handler callback, u_char *) = nullptr;
-
-
-#if 0
-#define pcap_compile_dl pcap_compile
-#define pcap_findalldevs_dl pcap_findalldevs
-#define pcap_open_live_dl pcap_open_live
-#define pcap_next_ex_dl pcap_next_ex
-#define pcap_close_dl pcap_close
-#define pcap_setfilter_dl pcap_setfilter
-#define pcap_sendpacket_dl pcap_sendpacket
-#define pcap_set_datalink_dl pcap_set_datalink
-#endif
+// FIXME: bridge between pcap_module and netdev_pcap
+static pcap_module *module = nullptr;
#ifdef SDLMAME_MACOSX
struct netdev_pcap_context {
@@ -140,7 +140,7 @@ static void *netdev_pcap_blocker(void *arg) {
struct netdev_pcap_context *ctx = (struct netdev_pcap_context*)arg;
while(ctx && ctx->p) {
- pcap_dispatch_dl(ctx->p, 1, netdev_pcap_handler, (u_char*)ctx);
+ (*module->pcap_dispatch_dl)(ctx->p, 1, netdev_pcap_handler, (u_char*)ctx);
}
return 0;
@@ -152,19 +152,19 @@ netdev_pcap::netdev_pcap(const char *name, class device_network_interface *ifdev
{
char errbuf[PCAP_ERRBUF_SIZE];
#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
- m_p = pcap_open_live_dl(name, 65535, 1, -1, errbuf);
+ m_p = (*module->pcap_open_live_dl)(name, 65535, 1, -1, errbuf);
#else
- m_p = pcap_open_live_dl(name, 65535, 1, 1, errbuf);
+ m_p = (*module->pcap_open_live_dl)(name, 65535, 1, 1, errbuf);
#endif
if(!m_p)
{
osd_printf_error("Unable to open %s: %s\n", name, errbuf);
return;
}
- if(pcap_set_datalink_dl(m_p, DLT_EN10MB) == -1)
+ if ((*module->pcap_set_datalink_dl)(m_p, DLT_EN10MB) == -1)
{
osd_printf_error("Unable to set %s to ethernet", name);
- pcap_close_dl(m_p);
+ (*module->pcap_close_dl)(m_p);
m_p = nullptr;
return;
}
@@ -188,10 +188,10 @@ void netdev_pcap::set_mac(const char *mac)
#else
sprintf(filter, "ether dst %.2X:%.2X:%.2X:%.2X:%.2X:%.2X or ether multicast or ether broadcast", (unsigned char)mac[0], (unsigned char)mac[1], (unsigned char)mac[2],(unsigned char)mac[3], (unsigned char)mac[4], (unsigned char)mac[5]);
#endif
- if(pcap_compile_dl(m_p, &fp, filter, 1, 0) == -1) {
+ if ((*module->pcap_compile_dl)(m_p, &fp, filter, 1, 0) == -1) {
osd_printf_error("Error with pcap_compile\n");
}
- if(pcap_setfilter_dl(m_p, &fp) == -1) {
+ if ((*module->pcap_setfilter_dl)(m_p, &fp) == -1) {
osd_printf_error("Error with pcap_setfilter\n");
}
}
@@ -203,7 +203,7 @@ int netdev_pcap::send(UINT8 *buf, int len)
printf("send invoked, but no pcap context\n");
return 0;
}
- ret = pcap_sendpacket_dl(m_p, buf, len);
+ ret = (*module->pcap_sendpacket_dl)(m_p, buf, len);
printf("sent packet length %d, returned %d\n", len, ret);
return ret ? len : 0;
//return (!pcap_sendpacket_dl(m_p, buf, len))?len:0;
@@ -228,7 +228,7 @@ int netdev_pcap::recv_dev(UINT8 **buf)
#else
struct pcap_pkthdr *header;
if(!m_p) return 0;
- return (pcap_next_ex_dl(m_p, &header, (const u_char **)buf) == 1)?header->len:0;
+ return ((*module->pcap_next_ex_dl)(m_p, &header, (const u_char **)buf) == 1)?header->len:0;
#endif
}
@@ -239,7 +239,7 @@ netdev_pcap::~netdev_pcap()
pthread_cancel(m_thread);
pthread_join(m_thread, nullptr);
#endif
- if(m_p) pcap_close_dl(m_p);
+ if(m_p) (*module->pcap_close_dl)(m_p);
m_p = nullptr;
}
@@ -249,52 +249,16 @@ static CREATE_NETDEV(create_pcap)
return dynamic_cast<osd_netdev *>(dev);
}
-bool pcap_module::probe()
-{
- if (handle == nullptr)
- {
- handle = LoadDynamicLibrary(LIB_NAME);
- return (handle != nullptr);
- }
- return true;
-}
-
-
int pcap_module::init(const osd_options &options)
{
pcap_if_t *devs;
char errbuf[PCAP_ERRBUF_SIZE];
- try
- {
- if(!(pcap_findalldevs_dl = (int (*)(pcap_if_t **, char *))GetProcAddress(handle, "pcap_findalldevs")))
- throw GetLastError();
- if(!(pcap_open_live_dl = (pcap_t* (*)(const char *, int, int, int, char *))GetProcAddress(handle, "pcap_open_live")))
- throw GetLastError();
- if(!(pcap_next_ex_dl = (int (*)(pcap_t *, struct pcap_pkthdr **, const u_char **))GetProcAddress(handle, "pcap_next_ex")))
- throw GetLastError();
- if(!(pcap_compile_dl = (int (*)(pcap_t *, struct bpf_program *, char *, int, bpf_u_int32))GetProcAddress(handle, "pcap_compile")))
- throw GetLastError();
- if(!(pcap_close_dl = (void (*)(pcap_t *))GetProcAddress(handle, "pcap_close")))
- throw GetLastError();
- if(!(pcap_setfilter_dl = (int (*)(pcap_t *, struct bpf_program *))GetProcAddress(handle, "pcap_setfilter")))
- throw GetLastError();
- if(!(pcap_sendpacket_dl = (int (*)(pcap_t *, u_char *, int))GetProcAddress(handle, "pcap_sendpacket")))
- throw GetLastError();
- if(!(pcap_set_datalink_dl = (int (*)(pcap_t *, int))GetProcAddress(handle, "pcap_set_datalink")))
- throw GetLastError();
- if(!(pcap_dispatch_dl = (int (*)(pcap_t *, int, pcap_handler callback, u_char *))GetProcAddress(handle, "pcap_dispatch")))
- throw GetLastError();
- }
- catch (except_type e)
- {
- FreeLibrary(handle);
- osd_printf_error(LIB_ERROR_STR, e);
- return 1;
- }
- if(pcap_findalldevs_dl(&devs, errbuf) == -1)
+ // FIXME: bridge between pcap_module and netdev_pcap
+ module = this;
+
+ if ((*pcap_findalldevs_dl)(&devs, errbuf) == -1)
{
- FreeLibrary(handle);
osd_printf_error("Unable to get network devices: %s\n", errbuf);
return 1;
}
@@ -314,9 +278,8 @@ int pcap_module::init(const osd_options &options)
void pcap_module::exit()
{
clear_netdev();
- //FreeLibrary(handle);
- //handle = nullptr;
}
+
#else
#include "modules/osdmodule.h"
#include "netdev_module.h"