mirror of
https://github.com/holub/mame
synced 2025-04-24 01:11:11 +03:00
Converted pcap and taptun network code into modules. (nw)
This commit is contained in:
parent
723823ce11
commit
ae4dddb9c1
@ -1,7 +1,7 @@
|
||||
#ifndef __DINETWORK_H__
|
||||
#define __DINETWORK_H__
|
||||
|
||||
class netdev;
|
||||
class osd_netdev;
|
||||
|
||||
class device_network_interface : public device_interface
|
||||
{
|
||||
@ -24,7 +24,7 @@ protected:
|
||||
bool m_promisc;
|
||||
char m_mac[6];
|
||||
float m_bandwidth;
|
||||
auto_pointer<class netdev> m_dev;
|
||||
auto_pointer<class osd_netdev> m_dev;
|
||||
int m_intf;
|
||||
};
|
||||
|
||||
|
@ -159,7 +159,7 @@ void ui_menu_network_devices::populate()
|
||||
{
|
||||
int curr = network->get_interface();
|
||||
const char *title = NULL;
|
||||
const netdev_entry_t *entry = netdev_first();
|
||||
const osd_netdev::entry_t *entry = netdev_first();
|
||||
while(entry) {
|
||||
if(entry->id==curr) {
|
||||
title = entry->description;
|
||||
|
@ -1048,7 +1048,7 @@ void video_manager::recompute_speed(const attotime &emutime)
|
||||
if (filerr == FILERR_NONE)
|
||||
save_snapshot(machine().first_screen(), file);
|
||||
}
|
||||
|
||||
//printf("Scheduled exit at %f\n", emutime.as_double());
|
||||
// schedule our demise
|
||||
machine().schedule_exit();
|
||||
}
|
||||
|
@ -128,6 +128,10 @@ void osd_common_t::register_options()
|
||||
REGISTER_MODULE(m_mod_man, DEBUG_INTERNAL);
|
||||
REGISTER_MODULE(m_mod_man, DEBUG_NONE);
|
||||
|
||||
REGISTER_MODULE(m_mod_man, NETDEV_TAPTUN);
|
||||
REGISTER_MODULE(m_mod_man, NETDEV_PCAP);
|
||||
|
||||
|
||||
// after initialization we know which modules are supported
|
||||
|
||||
const char *names[20];
|
||||
@ -399,9 +403,15 @@ bool osd_common_t::execute_command(const char *command)
|
||||
{
|
||||
if (strcmp(command, OSDCOMMAND_LIST_NETWORK_ADAPTERS) == 0)
|
||||
{
|
||||
network_init();
|
||||
osd_list_network_adapters();
|
||||
network_exit();
|
||||
osd_module *om = select_module_options(options(), OSD_NETDEV_PROVIDER);
|
||||
|
||||
if (om->probe())
|
||||
{
|
||||
om->init();
|
||||
osd_list_network_adapters();
|
||||
om->exit();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (strcmp(command, OSDCOMMAND_LIST_MIDI_DEVICES) == 0)
|
||||
@ -431,9 +441,6 @@ void osd_common_t::init_subsystems()
|
||||
machine().add_notifier(MACHINE_NOTIFY_RESUME, machine_notify_delegate(FUNC(osd_common_t::input_resume), this));
|
||||
|
||||
output_init();
|
||||
#ifdef USE_NETWORK
|
||||
network_init();
|
||||
#endif
|
||||
midi_init();
|
||||
|
||||
m_font_module = select_module_options<font_module *>(options(), OSD_FONT_PROVIDER);
|
||||
@ -444,6 +451,8 @@ void osd_common_t::init_subsystems()
|
||||
|
||||
m_debugger = select_module_options<debug_module *>(options(), OSD_DEBUG_PROVIDER);
|
||||
|
||||
select_module_options<netdev_module *>(options(), OSD_NETDEV_PROVIDER);
|
||||
|
||||
m_mod_man.init();
|
||||
|
||||
}
|
||||
@ -485,19 +494,11 @@ bool osd_common_t::output_init()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool osd_common_t::network_init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void osd_common_t::exit_subsystems()
|
||||
{
|
||||
video_exit();
|
||||
input_exit();
|
||||
output_exit();
|
||||
#ifdef USE_NETWORK
|
||||
network_exit();
|
||||
#endif
|
||||
midi_exit();
|
||||
}
|
||||
|
||||
@ -517,10 +518,6 @@ void osd_common_t::output_exit()
|
||||
{
|
||||
}
|
||||
|
||||
void osd_common_t::network_exit()
|
||||
{
|
||||
}
|
||||
|
||||
void osd_common_t::osd_exit()
|
||||
{
|
||||
m_mod_man.exit();
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "modules/font/font_module.h"
|
||||
#include "modules/sound/sound_module.h"
|
||||
#include "modules/debugger/debug_module.h"
|
||||
#include "modules/netdev/netdev_module.h"
|
||||
#include "cliopts.h"
|
||||
|
||||
//============================================================
|
||||
@ -164,7 +165,6 @@ public:
|
||||
|
||||
virtual void input_resume();
|
||||
virtual bool output_init();
|
||||
virtual bool network_init();
|
||||
virtual bool midi_init();
|
||||
|
||||
virtual void exit_subsystems();
|
||||
@ -172,7 +172,6 @@ public:
|
||||
virtual void window_exit();
|
||||
virtual void input_exit();
|
||||
virtual void output_exit();
|
||||
virtual void network_exit();
|
||||
virtual void midi_exit();
|
||||
|
||||
virtual void osd_exit();
|
||||
|
303
src/osd/modules/netdev/pcap.c
Normal file
303
src/osd/modules/netdev/pcap.c
Normal file
@ -0,0 +1,303 @@
|
||||
#ifdef SDLMAME_NET_PCAP
|
||||
|
||||
#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <pcap.h>
|
||||
|
||||
#include "emu.h"
|
||||
#include "osdnet.h"
|
||||
#include "netdev_module.h"
|
||||
#include "modules/osdmodule.h"
|
||||
|
||||
#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
|
||||
|
||||
#define LIB_NAME L"wpcap.dll"
|
||||
#define LIB_ERROR_STR "Unable to load winpcap: %lx\n"
|
||||
typedef DWORD except_type;
|
||||
|
||||
#else
|
||||
|
||||
#include <dlfcn.h>
|
||||
#ifdef 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 LoadLibrary(x) dlopen(x, RTLD_LAZY)
|
||||
|
||||
#endif
|
||||
|
||||
class pcap_module : public osd_module, public netdev_module
|
||||
{
|
||||
public:
|
||||
|
||||
pcap_module()
|
||||
: osd_module(OSD_NETDEV_PROVIDER, "pcap"), netdev_module(), handle(NULL)
|
||||
{
|
||||
}
|
||||
virtual ~pcap_module() { }
|
||||
|
||||
virtual int init();
|
||||
virtual void exit();
|
||||
|
||||
virtual bool probe();
|
||||
|
||||
HMODULE handle;
|
||||
};
|
||||
|
||||
static int (*pcap_compile_dl)(pcap_t *, struct bpf_program *, char *, int, bpf_u_int32) = NULL;
|
||||
static int (*pcap_findalldevs_dl)(pcap_if_t **, char *) = NULL;
|
||||
static pcap_t *(*pcap_open_live_dl)(const char *name, int, int, int, char *) = NULL;
|
||||
static int (*pcap_next_ex_dl)(pcap_t *, struct pcap_pkthdr **, const u_char **) = NULL;
|
||||
static void (*pcap_close_dl)(pcap_t *) = NULL;
|
||||
static int (*pcap_setfilter_dl)(pcap_t *, struct bpf_program *) = NULL;
|
||||
static int (*pcap_sendpacket_dl)(pcap_t *, u_char *, int) = NULL;
|
||||
static int (*pcap_set_datalink_dl)(pcap_t *, int) = NULL;
|
||||
static int (*pcap_dispatch_dl)(pcap_t *, int, pcap_handler callback, u_char *) = NULL;
|
||||
|
||||
|
||||
#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
|
||||
|
||||
#ifdef SDLMAME_MACOSX
|
||||
struct netdev_pcap_context {
|
||||
UINT8 *pkt;
|
||||
int len;
|
||||
pcap_t *p;
|
||||
|
||||
UINT8 packets[32][1600];
|
||||
int packetlens[32];
|
||||
int head;
|
||||
int tail;
|
||||
};
|
||||
#endif
|
||||
|
||||
class netdev_pcap : public osd_netdev
|
||||
{
|
||||
public:
|
||||
netdev_pcap(const char *name, class device_network_interface *ifdev, int rate);
|
||||
~netdev_pcap();
|
||||
|
||||
int send(UINT8 *buf, int len);
|
||||
void set_mac(const char *mac);
|
||||
protected:
|
||||
int recv_dev(UINT8 **buf);
|
||||
private:
|
||||
pcap_t *m_p;
|
||||
#ifdef SDLMAME_MACOSX
|
||||
struct netdev_pcap_context m_ctx;
|
||||
pthread_t m_thread;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef SDLMAME_MACOSX
|
||||
static void netdev_pcap_handler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes) {
|
||||
struct netdev_pcap_context *ctx = (struct netdev_pcap_context*)user;
|
||||
|
||||
if(OSAtomicCompareAndSwapInt((ctx->head+1) & 0x1F, ctx->tail, &ctx->tail)) {
|
||||
printf("buffer full, dropping packet\n");
|
||||
return;
|
||||
}
|
||||
memcpy(ctx->packets[ctx->head], bytes, h->len);
|
||||
ctx->packetlens[ctx->head] = h->len;
|
||||
OSAtomicCompareAndSwapInt(ctx->head, (ctx->head+1) & 0x1F, &ctx->head);
|
||||
}
|
||||
|
||||
static void *netdev_pcap_blocker(void *arg) {
|
||||
struct netdev_pcap_context *ctx = (struct netdev_pcap_context*)arg;
|
||||
|
||||
while(1) {
|
||||
pcap_dispatch_dl(ctx->p, 1, netdev_pcap_handler, (u_char*)ctx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
netdev_pcap::netdev_pcap(const char *name, class device_network_interface *ifdev, int rate)
|
||||
: osd_netdev(ifdev, rate)
|
||||
{
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
|
||||
m_p = pcap_open_live_dl(name, 65535, 1, -1, errbuf);
|
||||
#else
|
||||
m_p = pcap_open_live_dl(name, 65535, 1, 1, errbuf);
|
||||
#endif
|
||||
if(!m_p)
|
||||
{
|
||||
logerror("Unable to open %s: %s\n", name, errbuf);
|
||||
return;
|
||||
}
|
||||
if(pcap_set_datalink_dl(m_p, DLT_EN10MB) == -1)
|
||||
{
|
||||
logerror("Unable to set %s to ethernet", name);
|
||||
pcap_close_dl(m_p);
|
||||
m_p = NULL;
|
||||
return;
|
||||
}
|
||||
set_mac(get_mac());
|
||||
|
||||
#ifdef SDLMAME_MACOSX
|
||||
m_ctx.head = 0;
|
||||
m_ctx.tail = 0;
|
||||
m_ctx.p = m_p;
|
||||
pthread_create(&m_thread, NULL, netdev_pcap_blocker, &m_ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
void netdev_pcap::set_mac(const char *mac)
|
||||
{
|
||||
char filter[256];
|
||||
struct bpf_program fp;
|
||||
if(!m_p) return;
|
||||
#ifdef SDLMAME_MACOSX
|
||||
sprintf(filter, "not ether src %.2X:%.2X:%.2X:%.2X:%.2X:%.2X and (ether dst %.2X:%.2X:%.2X:%.2X:%.2X:%.2X or ether multicast or ether broadcast or ether dst 09:00:07:ff:ff:ff)", (unsigned char)mac[0], (unsigned char)mac[1], (unsigned char)mac[2],(unsigned char)mac[3], (unsigned char)mac[4], (unsigned char)mac[5], (unsigned char)mac[0], (unsigned char)mac[1], (unsigned char)mac[2],(unsigned char)mac[3], (unsigned char)mac[4], (unsigned char)mac[5]);
|
||||
#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) {
|
||||
logerror("Error with pcap_compile\n");
|
||||
}
|
||||
if(pcap_setfilter_dl(m_p, &fp) == -1) {
|
||||
logerror("Error with pcap_setfilter\n");
|
||||
}
|
||||
}
|
||||
|
||||
int netdev_pcap::send(UINT8 *buf, int len)
|
||||
{
|
||||
if(!m_p) return 0;
|
||||
return (!pcap_sendpacket_dl(m_p, buf, len))?len:0;
|
||||
}
|
||||
|
||||
int netdev_pcap::recv_dev(UINT8 **buf)
|
||||
{
|
||||
#ifdef SDLMAME_MACOSX
|
||||
UINT8 pktbuf[2048];
|
||||
int ret;
|
||||
|
||||
// Empty
|
||||
if(OSAtomicCompareAndSwapInt(m_ctx.head, m_ctx.tail, &m_ctx.tail)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(pktbuf, m_ctx.packets[m_ctx.tail], m_ctx.packetlens[m_ctx.tail]);
|
||||
ret = m_ctx.packetlens[m_ctx.tail];
|
||||
OSAtomicCompareAndSwapInt(m_ctx.tail, (m_ctx.tail+1) & 0x1F, &m_ctx.tail);
|
||||
*buf = pktbuf;
|
||||
return ret;
|
||||
#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;
|
||||
#endif
|
||||
}
|
||||
|
||||
netdev_pcap::~netdev_pcap()
|
||||
{
|
||||
if(m_p) pcap_close_dl(m_p);
|
||||
}
|
||||
|
||||
static CREATE_NETDEV(create_pcap)
|
||||
{
|
||||
class netdev_pcap *dev = global_alloc(netdev_pcap(ifname, ifdev, rate));
|
||||
return dynamic_cast<osd_netdev *>(dev);
|
||||
}
|
||||
|
||||
bool pcap_module::probe()
|
||||
{
|
||||
if (handle == NULL)
|
||||
{
|
||||
handle = LoadLibrary(LIB_NAME);
|
||||
return (handle != NULL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int pcap_module::init()
|
||||
{
|
||||
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);
|
||||
logerror(LIB_ERROR_STR, e);
|
||||
return 1;
|
||||
}
|
||||
if(pcap_findalldevs_dl(&devs, errbuf) == -1)
|
||||
{
|
||||
FreeLibrary(handle);
|
||||
logerror("Unable to get network devices: %s\n", errbuf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while(devs)
|
||||
{
|
||||
add_netdev(devs->name, devs->description, create_pcap);
|
||||
devs = devs->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pcap_module::exit()
|
||||
{
|
||||
clear_netdev();
|
||||
FreeLibrary(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
#else
|
||||
#include "modules/osdmodule.h"
|
||||
#include "netdev_module.h"
|
||||
|
||||
MODULE_NOT_SUPPORTED(pcap_module, OSD_NETDEV_PROVIDER, "pcap")
|
||||
#endif
|
||||
|
||||
|
||||
MODULE_DEFINITION(NETDEV_PCAP, pcap_module)
|
||||
|
@ -1,3 +1,5 @@
|
||||
#if defined(SDLMAME_NET_TAPTUN)
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
@ -6,6 +8,8 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "osdnet.h"
|
||||
#include "modules/osdmodule.h"
|
||||
#include "netdev_module.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#define IFF_TAP 0x0002
|
||||
@ -13,7 +17,25 @@
|
||||
#define TUNSETIFF _IOW('T', 202, int)
|
||||
#endif
|
||||
|
||||
class netdev_tap : public netdev
|
||||
class taptun_module : public osd_module, public netdev_module
|
||||
{
|
||||
public:
|
||||
|
||||
taptun_module()
|
||||
: osd_module(OSD_NETDEV_PROVIDER, "taptun"), netdev_module()
|
||||
{
|
||||
}
|
||||
virtual ~taptun_module() { }
|
||||
|
||||
virtual int init();
|
||||
virtual void exit();
|
||||
|
||||
virtual bool probe() { return true; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
class netdev_tap : public osd_netdev
|
||||
{
|
||||
public:
|
||||
netdev_tap(const char *name, class device_network_interface *ifdev, int rate);
|
||||
@ -31,7 +53,7 @@ private:
|
||||
};
|
||||
|
||||
netdev_tap::netdev_tap(const char *name, class device_network_interface *ifdev, int rate)
|
||||
: netdev(ifdev, rate)
|
||||
: osd_netdev(ifdev, rate)
|
||||
{
|
||||
#ifdef __linux__
|
||||
struct ifreq ifr;
|
||||
@ -93,15 +115,27 @@ int netdev_tap::recv_dev(UINT8 **buf)
|
||||
static CREATE_NETDEV(create_tap)
|
||||
{
|
||||
class netdev_tap *dev = global_alloc(netdev_tap(ifname, ifdev, rate));
|
||||
return dynamic_cast<netdev *>(dev);
|
||||
return dynamic_cast<osd_netdev *>(dev);
|
||||
}
|
||||
|
||||
void init_tap()
|
||||
int taptun_module::init()
|
||||
{
|
||||
add_netdev("tap", "TAP/TUN Device", create_tap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void deinit_tap()
|
||||
void taptun_module::exit()
|
||||
{
|
||||
clear_netdev();
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
#include "modules/osdmodule.h"
|
||||
#include "netdev_module.h"
|
||||
|
||||
MODULE_NOT_SUPPORTED(taptun_module, OSD_NETDEV_PROVIDER, "taptun")
|
||||
#endif
|
||||
|
||||
|
||||
MODULE_DEFINITION(NETDEV_TAPTUN, taptun_module)
|
@ -34,7 +34,7 @@ public:
|
||||
const char * name() const { return m_name; }
|
||||
const char * type() const { return m_type; }
|
||||
|
||||
virtual bool probe() const { return true; }
|
||||
virtual bool probe() { return true; }
|
||||
|
||||
virtual int init() { return 0; }
|
||||
virtual void exit() { }
|
||||
@ -100,7 +100,7 @@ private:
|
||||
public: \
|
||||
_mod () \
|
||||
: osd_module(_type, _name) {} \
|
||||
bool probe() const { return false; } \
|
||||
bool probe() { return false; } \
|
||||
};
|
||||
|
||||
#endif /* __OSDMODULE_H__ */
|
||||
|
@ -1,11 +1,11 @@
|
||||
#include "emu.h"
|
||||
#include "osdnet.h"
|
||||
|
||||
static class simple_list<netdev_entry_t> netdev_list;
|
||||
static class simple_list<osd_netdev::entry_t> netdev_list;
|
||||
|
||||
void add_netdev(const char *name, const char *description, create_netdev func)
|
||||
{
|
||||
netdev_entry_t *entry = global_alloc_clear(netdev_entry_t);
|
||||
osd_netdev::entry_t *entry = global_alloc_clear(osd_netdev::entry_t);
|
||||
entry->id = netdev_list.count();
|
||||
strncpy(entry->name, name, 255);
|
||||
entry->name[255] = '\0';
|
||||
@ -20,13 +20,13 @@ void clear_netdev()
|
||||
netdev_list.reset();
|
||||
}
|
||||
|
||||
const netdev_entry_t *netdev_first() {
|
||||
const osd_netdev::entry_t *netdev_first() {
|
||||
return netdev_list.first();
|
||||
}
|
||||
|
||||
class netdev *open_netdev(int id, class device_network_interface *ifdev, int rate)
|
||||
class osd_netdev *open_netdev(int id, class device_network_interface *ifdev, int rate)
|
||||
{
|
||||
netdev_entry_t *entry = netdev_list.first();
|
||||
osd_netdev::entry_t *entry = netdev_list.first();
|
||||
while(entry) {
|
||||
if(entry->id==id)
|
||||
return entry->func(entry->name, ifdev, rate);
|
||||
@ -36,22 +36,22 @@ class netdev *open_netdev(int id, class device_network_interface *ifdev, int rat
|
||||
return NULL;
|
||||
}
|
||||
|
||||
netdev::netdev(class device_network_interface *ifdev, int rate)
|
||||
osd_netdev::osd_netdev(class device_network_interface *ifdev, int rate)
|
||||
{
|
||||
m_dev = ifdev;
|
||||
ifdev->device().machine().scheduler().timer_pulse(attotime::from_hz(rate), timer_expired_delegate(FUNC(netdev::recv), this));
|
||||
ifdev->device().machine().scheduler().timer_pulse(attotime::from_hz(rate), timer_expired_delegate(FUNC(osd_netdev::recv), this));
|
||||
}
|
||||
|
||||
netdev::~netdev()
|
||||
osd_netdev::~osd_netdev()
|
||||
{
|
||||
}
|
||||
|
||||
int netdev::send(UINT8 *buf, int len)
|
||||
int osd_netdev::send(UINT8 *buf, int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void netdev::recv(void *ptr, int param)
|
||||
void osd_netdev::recv(void *ptr, int param)
|
||||
{
|
||||
UINT8 *buf;
|
||||
int len;
|
||||
@ -74,27 +74,27 @@ void netdev::recv(void *ptr, int param)
|
||||
}
|
||||
}
|
||||
|
||||
int netdev::recv_dev(UINT8 **buf)
|
||||
int osd_netdev::recv_dev(UINT8 **buf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void netdev::set_mac(const char *mac)
|
||||
void osd_netdev::set_mac(const char *mac)
|
||||
{
|
||||
}
|
||||
|
||||
void netdev::set_promisc(bool promisc)
|
||||
void osd_netdev::set_promisc(bool promisc)
|
||||
{
|
||||
}
|
||||
|
||||
bool netdev::get_promisc()
|
||||
bool osd_netdev::get_promisc()
|
||||
{
|
||||
if(m_dev)
|
||||
return m_dev->get_promisc();
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *netdev::get_mac()
|
||||
const char *osd_netdev::get_mac()
|
||||
{
|
||||
if(m_dev)
|
||||
return m_dev->get_mac();
|
||||
@ -118,7 +118,7 @@ void osd_list_network_adapters(void)
|
||||
}
|
||||
|
||||
printf("Available network adapters:\n");
|
||||
const netdev_entry_t *entry = netdev_first();
|
||||
const osd_netdev::entry_t *entry = netdev_first();
|
||||
while(entry) {
|
||||
printf(" %s\n", entry->description);
|
||||
entry = entry->m_next;
|
||||
|
@ -3,25 +3,24 @@
|
||||
#ifndef __OSDNET_H__
|
||||
#define __OSDNET_H__
|
||||
|
||||
class netdev;
|
||||
class osd_netdev;
|
||||
|
||||
#define CREATE_NETDEV(name) class netdev *name(const char *ifname, class device_network_interface *ifdev, int rate)
|
||||
typedef class netdev *(*create_netdev)(const char *ifname, class device_network_interface *ifdev, int rate);
|
||||
#define CREATE_NETDEV(name) class osd_netdev *name(const char *ifname, class device_network_interface *ifdev, int rate)
|
||||
typedef class osd_netdev *(*create_netdev)(const char *ifname, class device_network_interface *ifdev, int rate);
|
||||
|
||||
struct netdev_entry_t
|
||||
{
|
||||
int id;
|
||||
char name[256];
|
||||
char description[256];
|
||||
create_netdev func;
|
||||
netdev_entry_t *m_next;
|
||||
};
|
||||
|
||||
class netdev
|
||||
class osd_netdev
|
||||
{
|
||||
public:
|
||||
netdev(class device_network_interface *ifdev, int rate);
|
||||
virtual ~netdev();
|
||||
struct entry_t
|
||||
{
|
||||
int id;
|
||||
char name[256];
|
||||
char description[256];
|
||||
create_netdev func;
|
||||
entry_t *m_next;
|
||||
};
|
||||
osd_netdev(class device_network_interface *ifdev, int rate);
|
||||
virtual ~osd_netdev();
|
||||
|
||||
virtual int send(UINT8 *buf, int len);
|
||||
virtual void set_mac(const char *mac);
|
||||
@ -39,9 +38,9 @@ private:
|
||||
class device_network_interface *m_dev;
|
||||
};
|
||||
|
||||
class netdev *open_netdev(int id, class device_network_interface *ifdev, int rate);
|
||||
class osd_netdev *open_netdev(int id, class device_network_interface *ifdev, int rate);
|
||||
void add_netdev(const char *name, const char *description, create_netdev func);
|
||||
void clear_netdev();
|
||||
const netdev_entry_t *netdev_first();
|
||||
const osd_netdev::entry_t *netdev_first();
|
||||
int netdev_count();
|
||||
#endif
|
||||
|
@ -1,25 +0,0 @@
|
||||
#include "emu.h"
|
||||
#include "netdev_tap.h"
|
||||
#include "netdev_pcap.h"
|
||||
#include "osdsdl.h"
|
||||
|
||||
bool sdl_osd_interface::network_init()
|
||||
{
|
||||
#ifdef SDLMAME_NET_TAPTUN
|
||||
init_tap();
|
||||
#endif
|
||||
#ifdef SDLMAME_NET_PCAP
|
||||
init_pcap();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void sdl_osd_interface::network_exit()
|
||||
{
|
||||
#ifdef SDLMAME_NET_TAPTUN
|
||||
deinit_tap();
|
||||
#endif
|
||||
#ifdef SDLMAME_NET_PCAP
|
||||
deinit_pcap();
|
||||
#endif
|
||||
}
|
@ -1,148 +0,0 @@
|
||||
#ifdef SDLMAME_WIN32
|
||||
#include "../windows/netdev_pcap.c"
|
||||
#else
|
||||
|
||||
#include <pcap.h>
|
||||
|
||||
static int (*pcap_compile_dl)(pcap_t *, struct bpf_program *, char *, int, bpf_u_int32) = NULL;
|
||||
static int (*pcap_findalldevs_dl)(pcap_if_t **, char *) = NULL;
|
||||
static pcap_t *(*pcap_open_live_dl)(const char *name, int, int, int, char *) = NULL;
|
||||
static int (*pcap_next_ex_dl)(pcap_t *, struct pcap_pkthdr **, const u_char **) = NULL;
|
||||
static void (*pcap_close_dl)(pcap_t *) = NULL;
|
||||
static int (*pcap_setfilter_dl)(pcap_t *, struct bpf_program *) = NULL;
|
||||
static int (*pcap_sendpacket_dl)(pcap_t *, u_char *, int) = NULL;
|
||||
static int (*pcap_set_datalink_dl)(pcap_t *, int) = NULL;
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "emu.h"
|
||||
#include "osdnet.h"
|
||||
|
||||
static void *handle = NULL;
|
||||
|
||||
class netdev_pcap : public netdev
|
||||
{
|
||||
public:
|
||||
netdev_pcap(const char *name, class device_network_interface *ifdev, int rate);
|
||||
~netdev_pcap();
|
||||
|
||||
int send(UINT8 *buf, int len);
|
||||
void set_mac(const char *mac);
|
||||
protected:
|
||||
int recv_dev(UINT8 **buf);
|
||||
private:
|
||||
pcap_t *m_p;
|
||||
};
|
||||
|
||||
netdev_pcap::netdev_pcap(const char *name, class device_network_interface *ifdev, int rate)
|
||||
: netdev(ifdev, rate)
|
||||
{
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
m_p = pcap_open_live_dl(name, 65535, 1, 1, errbuf);
|
||||
if(!m_p)
|
||||
{
|
||||
osd_printf_verbose("Unable to open %s: %s\n", name, errbuf);
|
||||
return;
|
||||
}
|
||||
if(pcap_set_datalink_dl(m_p, DLT_EN10MB) == -1)
|
||||
{
|
||||
osd_printf_verbose("Unable to set %s to ethernet\n", name);
|
||||
pcap_close_dl(m_p);
|
||||
m_p = NULL;
|
||||
return;
|
||||
}
|
||||
set_mac(get_mac());
|
||||
}
|
||||
|
||||
void netdev_pcap::set_mac(const char *mac)
|
||||
{
|
||||
char filter[256];
|
||||
struct bpf_program fp;
|
||||
if(!m_p) return;
|
||||
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]);
|
||||
if(pcap_compile_dl(m_p, &fp, filter, 1, 0) == -1) {
|
||||
osd_printf_verbose("Error with pcap_compile\n");
|
||||
}
|
||||
if(pcap_setfilter_dl(m_p, &fp) == -1) {
|
||||
osd_printf_verbose("Error with pcap_setfilter\n");
|
||||
}
|
||||
}
|
||||
|
||||
int netdev_pcap::send(UINT8 *buf, int len)
|
||||
{
|
||||
if(!m_p) return 0;
|
||||
return (!pcap_sendpacket_dl(m_p, buf, len))?len:0;
|
||||
}
|
||||
|
||||
int netdev_pcap::recv_dev(UINT8 **buf)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
netdev_pcap::~netdev_pcap()
|
||||
{
|
||||
if(m_p) pcap_close_dl(m_p);
|
||||
}
|
||||
|
||||
static CREATE_NETDEV(create_pcap)
|
||||
{
|
||||
class netdev_pcap *dev = global_alloc(netdev_pcap(ifname, ifdev, rate));
|
||||
return dynamic_cast<netdev *>(dev);
|
||||
}
|
||||
|
||||
void init_pcap()
|
||||
{
|
||||
pcap_if_t *devs;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
handle = NULL;
|
||||
|
||||
try
|
||||
{
|
||||
if(!(handle = dlopen("libpcap.so", RTLD_LAZY))) throw dlerror();
|
||||
if(!(pcap_findalldevs_dl = (int (*)(pcap_if_t **, char *))dlsym(handle, "pcap_findalldevs")))
|
||||
throw dlerror();
|
||||
if(!(pcap_open_live_dl = (pcap_t* (*)(const char *, int, int, int, char *))dlsym(handle, "pcap_open_live")))
|
||||
throw dlerror();
|
||||
if(!(pcap_next_ex_dl = (int (*)(pcap_t *, struct pcap_pkthdr **, const u_char **))dlsym(handle, "pcap_next_ex")))
|
||||
throw dlerror();
|
||||
if(!(pcap_compile_dl = (int (*)(pcap_t *, struct bpf_program *, char *, int, bpf_u_int32))dlsym(handle, "pcap_compile")))
|
||||
throw dlerror();
|
||||
if(!(pcap_close_dl = (void (*)(pcap_t *))dlsym(handle, "pcap_close")))
|
||||
throw dlerror();
|
||||
if(!(pcap_setfilter_dl = (int (*)(pcap_t *, struct bpf_program *))dlsym(handle, "pcap_setfilter")))
|
||||
throw dlerror();
|
||||
if(!(pcap_sendpacket_dl = (int (*)(pcap_t *, u_char *, int))dlsym(handle, "pcap_sendpacket")))
|
||||
throw dlerror();
|
||||
if(!(pcap_set_datalink_dl = (int (*)(pcap_t *, int))dlsym(handle, "pcap_set_datalink")))
|
||||
throw dlerror();
|
||||
}
|
||||
catch (const char *e)
|
||||
{
|
||||
dlclose(handle);
|
||||
osd_printf_verbose("Unable to load winpcap: %s\n", e);
|
||||
return;
|
||||
}
|
||||
if(pcap_findalldevs_dl(&devs, errbuf) == -1)
|
||||
{
|
||||
dlclose(handle);
|
||||
osd_printf_verbose("Unable to get network devices: %s\n", errbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
while(devs)
|
||||
{
|
||||
add_netdev(devs->name, devs->description, create_pcap);
|
||||
devs = devs->next;
|
||||
}
|
||||
}
|
||||
|
||||
void deinit_pcap()
|
||||
{
|
||||
clear_netdev();
|
||||
dlclose(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
|
||||
#endif // SDLMAME_WIN32
|
@ -1,7 +0,0 @@
|
||||
#ifndef __NETDEV_PCAP_H__
|
||||
#define __NETDEV_PCAP_H__
|
||||
|
||||
void init_pcap();
|
||||
void deinit_pcap();
|
||||
|
||||
#endif
|
@ -1,175 +0,0 @@
|
||||
#ifdef SDLMAME_WIN32
|
||||
#include "../windows/netdev_pcap.c"
|
||||
#else
|
||||
|
||||
#include <pcap.h>
|
||||
#include "emu.h"
|
||||
#include "osdnet.h"
|
||||
#include <pthread.h>
|
||||
#include <libkern/OSAtomic.h>
|
||||
|
||||
#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
|
||||
|
||||
struct netdev_pcap_context {
|
||||
UINT8 *pkt;
|
||||
int len;
|
||||
pcap_t *p;
|
||||
|
||||
UINT8 packets[32][1600];
|
||||
int packetlens[32];
|
||||
int head;
|
||||
int tail;
|
||||
};
|
||||
|
||||
class netdev_pcap : public netdev
|
||||
{
|
||||
public:
|
||||
netdev_pcap(const char *name, class device_network_interface *ifdev, int rate);
|
||||
~netdev_pcap();
|
||||
|
||||
int send(UINT8 *buf, int len);
|
||||
void set_mac(const char *mac);
|
||||
protected:
|
||||
int recv_dev(UINT8 **buf);
|
||||
private:
|
||||
pcap_t *m_p;
|
||||
struct netdev_pcap_context m_ctx;
|
||||
pthread_t m_thread;
|
||||
};
|
||||
|
||||
static void netdev_pcap_handler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes) {
|
||||
struct netdev_pcap_context *ctx = (struct netdev_pcap_context*)user;
|
||||
|
||||
if(OSAtomicCompareAndSwapInt((ctx->head+1) & 0x1F, ctx->tail, &ctx->tail)) {
|
||||
printf("buffer full, dropping packet\n");
|
||||
return;
|
||||
}
|
||||
memcpy(ctx->packets[ctx->head], bytes, h->len);
|
||||
ctx->packetlens[ctx->head] = h->len;
|
||||
OSAtomicCompareAndSwapInt(ctx->head, (ctx->head+1) & 0x1F, &ctx->head);
|
||||
}
|
||||
|
||||
static void *netdev_pcap_blocker(void *arg) {
|
||||
struct netdev_pcap_context *ctx = (struct netdev_pcap_context*)arg;
|
||||
|
||||
while(1) {
|
||||
pcap_dispatch(ctx->p, 1, netdev_pcap_handler, (u_char*)ctx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
netdev_pcap::netdev_pcap(const char *name, class device_network_interface *ifdev, int rate)
|
||||
: netdev(ifdev, rate)
|
||||
{
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
m_p = pcap_open_live_dl(name, 65535, 1, 1, errbuf);
|
||||
if(!m_p)
|
||||
{
|
||||
osd_printf_verbose("Unable to open %s: %s\n", name, errbuf);
|
||||
return;
|
||||
}
|
||||
if(pcap_set_datalink_dl(m_p, DLT_EN10MB) == -1)
|
||||
{
|
||||
osd_printf_verbose("Unable to set %s to ethernet\n", name);
|
||||
pcap_close_dl(m_p);
|
||||
m_p = NULL;
|
||||
return;
|
||||
}
|
||||
set_mac(get_mac());
|
||||
|
||||
m_ctx.head = 0;
|
||||
m_ctx.tail = 0;
|
||||
m_ctx.p = m_p;
|
||||
pthread_create(&m_thread, NULL, netdev_pcap_blocker, &m_ctx);
|
||||
}
|
||||
|
||||
void netdev_pcap::set_mac(const char *mac)
|
||||
{
|
||||
char filter[256];
|
||||
struct bpf_program fp;
|
||||
if(!m_p) return;
|
||||
sprintf(filter, "not ether src %.2X:%.2X:%.2X:%.2X:%.2X:%.2X and (ether dst %.2X:%.2X:%.2X:%.2X:%.2X:%.2X or ether multicast or ether broadcast or ether dst 09:00:07:ff:ff:ff)", (unsigned char)mac[0], (unsigned char)mac[1], (unsigned char)mac[2],(unsigned char)mac[3], (unsigned char)mac[4], (unsigned char)mac[5], (unsigned char)mac[0], (unsigned char)mac[1], (unsigned char)mac[2],(unsigned char)mac[3], (unsigned char)mac[4], (unsigned char)mac[5]);
|
||||
if(pcap_compile_dl(m_p, &fp, filter, 1, 0) == -1) {
|
||||
osd_printf_verbose("Error with pcap_compile\n");
|
||||
}
|
||||
if(pcap_setfilter_dl(m_p, &fp) == -1) {
|
||||
osd_printf_verbose("Error with pcap_setfilter\n");
|
||||
}
|
||||
}
|
||||
|
||||
int netdev_pcap::send(UINT8 *buf, int len)
|
||||
{
|
||||
if(!m_p) return 0;
|
||||
return (!pcap_sendpacket_dl(m_p, buf, len))?len:0;
|
||||
}
|
||||
|
||||
int netdev_pcap::recv_dev(UINT8 **buf)
|
||||
{
|
||||
UINT8 pktbuf[2048];
|
||||
int ret;
|
||||
|
||||
// Empty
|
||||
if(OSAtomicCompareAndSwapInt(m_ctx.head, m_ctx.tail, &m_ctx.tail)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(pktbuf, m_ctx.packets[m_ctx.tail], m_ctx.packetlens[m_ctx.tail]);
|
||||
ret = m_ctx.packetlens[m_ctx.tail];
|
||||
OSAtomicCompareAndSwapInt(m_ctx.tail, (m_ctx.tail+1) & 0x1F, &m_ctx.tail);
|
||||
*buf = pktbuf;
|
||||
return ret;
|
||||
}
|
||||
|
||||
netdev_pcap::~netdev_pcap()
|
||||
{
|
||||
if(m_p) pcap_close_dl(m_p);
|
||||
}
|
||||
|
||||
static CREATE_NETDEV(create_pcap)
|
||||
{
|
||||
class netdev_pcap *dev = global_alloc(netdev_pcap(ifname, ifdev, rate));
|
||||
return dynamic_cast<netdev *>(dev);
|
||||
}
|
||||
|
||||
void init_pcap()
|
||||
{
|
||||
pcap_if_t *devs;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
if(pcap_findalldevs_dl(&devs, errbuf) == -1)
|
||||
{
|
||||
osd_printf_verbose("Unable to get network devices: %s\n", errbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
#if 1
|
||||
while(devs)
|
||||
{
|
||||
add_netdev(devs->name, devs->description, create_pcap);
|
||||
devs = devs->next;
|
||||
}
|
||||
#else
|
||||
if (devs)
|
||||
{
|
||||
while(devs->next)
|
||||
{
|
||||
add_netdev(devs->name, devs->description ? devs->description : devs->name, create_pcap);
|
||||
devs = devs->next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void deinit_pcap()
|
||||
{
|
||||
clear_netdev();
|
||||
}
|
||||
|
||||
#endif // SDLMAME_WIN32
|
@ -1,6 +0,0 @@
|
||||
#ifndef __NETDEV_TAP_H__
|
||||
#define __NETDEV_TAP_H__
|
||||
|
||||
void init_tap();
|
||||
void deinit_tap();
|
||||
#endif
|
@ -195,18 +195,12 @@ public:
|
||||
virtual void input_pause();
|
||||
virtual void input_resume();
|
||||
virtual bool output_init();
|
||||
#ifdef USE_NETWORK
|
||||
virtual bool network_init();
|
||||
#endif
|
||||
//virtual bool midi_init();
|
||||
|
||||
virtual void video_exit();
|
||||
virtual void window_exit();
|
||||
virtual void input_exit();
|
||||
virtual void output_exit();
|
||||
#ifdef USE_NETWORK
|
||||
virtual void network_exit();
|
||||
#endif
|
||||
//virtual void midi_exit();
|
||||
|
||||
sdl_options &options() { return m_options; }
|
||||
|
@ -403,6 +403,7 @@ OBJDIRS += $(SDLOBJ) \
|
||||
$(OSDOBJ)/modules/lib \
|
||||
$(OSDOBJ)/modules/midi \
|
||||
$(OSDOBJ)/modules/font \
|
||||
$(OSDOBJ)/modules/netdev \
|
||||
|
||||
#-------------------------------------------------
|
||||
# OSD core library
|
||||
@ -445,6 +446,8 @@ OSDOBJS = \
|
||||
$(OSDOBJ)/modules/font/font_windows.o \
|
||||
$(OSDOBJ)/modules/font/font_osx.o \
|
||||
$(OSDOBJ)/modules/font/font_none.o \
|
||||
$(OSDOBJ)/modules/netdev/taptun.o \
|
||||
$(OSDOBJ)/modules/netdev/pcap.o \
|
||||
|
||||
ifdef NO_USE_MIDI
|
||||
OSDOBJS += $(OSDOBJ)/modules/midi/none.o
|
||||
@ -452,10 +455,6 @@ else
|
||||
OSDOBJS += $(OSDOBJ)/modules/midi/portmidi.o
|
||||
endif
|
||||
|
||||
ifeq ($(BASE_TARGETOS),win32)
|
||||
OSDOBJS += $(OSDOBJ)/modules/sound/direct_sound.o
|
||||
endif
|
||||
|
||||
# Add SDL2.0 support
|
||||
|
||||
ifeq ($(SDL_LIBVER),sdl2)
|
||||
@ -465,12 +464,6 @@ endif
|
||||
# add an ARCH define
|
||||
DEFS += -DSDLMAME_ARCH="$(ARCHOPTS)" -DSYNC_IMPLEMENTATION=$(SYNC_IMPLEMENTATION)
|
||||
|
||||
# Add JavaScript sound module for Emscripten compiles
|
||||
|
||||
ifeq ($(TARGETOS),emscripten)
|
||||
OSDOBJS += $(OSDOBJ)/modules/sound/js_sound.o
|
||||
endif
|
||||
|
||||
#-------------------------------------------------
|
||||
# Generic defines and additions
|
||||
#-------------------------------------------------
|
||||
@ -828,29 +821,21 @@ endif # USE_XINPUT
|
||||
# Network (TAP/TUN)
|
||||
#-------------------------------------------------
|
||||
|
||||
OSDOBJS += $(SDLOBJ)/netdev.o
|
||||
|
||||
ifndef DONT_USE_NETWORK
|
||||
|
||||
ifeq ($(SDL_NETWORK),taptun)
|
||||
OSDOBJS += $(SDLOBJ)/netdev_tap.o
|
||||
|
||||
DEFS += -DSDLMAME_NETWORK -DSDLMAME_NET_TAPTUN
|
||||
DEFS += -DSDLMAME_NET_TAPTUN
|
||||
endif
|
||||
|
||||
ifeq ($(SDL_NETWORK),pcap)
|
||||
|
||||
ifeq ($(TARGETOS),macosx)
|
||||
OSDOBJS += $(SDLOBJ)/netdev_pcap_osx.o
|
||||
else
|
||||
OSDOBJS += $(SDLOBJ)/netdev_pcap.o
|
||||
endif
|
||||
DEFS += -DSDLMAME_NET_PCAP
|
||||
|
||||
DEFS += -DSDLMAME_NETWORK -DSDLMAME_NET_PCAP
|
||||
|
||||
ifneq ($(TARGETOS),win32)
|
||||
LIBS += -lpcap
|
||||
endif
|
||||
# dynamically linked ...
|
||||
#ifneq ($(TARGETOS),win32)
|
||||
#LIBS += -lpcap
|
||||
#endif
|
||||
|
||||
endif # ifeq ($(SDL_NETWORK),pcap)
|
||||
|
||||
|
@ -1,14 +0,0 @@
|
||||
#include "emu.h"
|
||||
#include "winmain.h"
|
||||
#include "netdev_pcap.h"
|
||||
|
||||
bool windows_osd_interface::network_init()
|
||||
{
|
||||
init_pcap();
|
||||
return true;
|
||||
}
|
||||
|
||||
void windows_osd_interface::network_exit()
|
||||
{
|
||||
deinit_pcap();
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <pcap.h>
|
||||
|
||||
static int (*pcap_compile_dl)(pcap_t *, struct bpf_program *, char *, int, bpf_u_int32) = NULL;
|
||||
static int (*pcap_findalldevs_dl)(pcap_if_t **, char *) = NULL;
|
||||
static pcap_t *(*pcap_open_live_dl)(const char *name, int, int, int, char *) = NULL;
|
||||
static int (*pcap_next_ex_dl)(pcap_t *, struct pcap_pkthdr **, const u_char **) = NULL;
|
||||
static void (*pcap_close_dl)(pcap_t *) = NULL;
|
||||
static int (*pcap_setfilter_dl)(pcap_t *, struct bpf_program *) = NULL;
|
||||
static int (*pcap_sendpacket_dl)(pcap_t *, u_char *, int) = NULL;
|
||||
static int (*pcap_set_datalink_dl)(pcap_t *, int) = NULL;
|
||||
static HMODULE handle = NULL;
|
||||
|
||||
#include "emu.h"
|
||||
#include "osdnet.h"
|
||||
|
||||
class netdev_pcap : public netdev
|
||||
{
|
||||
public:
|
||||
netdev_pcap(const char *name, class device_network_interface *ifdev, int rate);
|
||||
~netdev_pcap();
|
||||
|
||||
int send(UINT8 *buf, int len);
|
||||
void set_mac(const char *mac);
|
||||
protected:
|
||||
int recv_dev(UINT8 **buf);
|
||||
private:
|
||||
pcap_t *m_p;
|
||||
};
|
||||
|
||||
netdev_pcap::netdev_pcap(const char *name, class device_network_interface *ifdev, int rate)
|
||||
: netdev(ifdev, rate)
|
||||
{
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
m_p = pcap_open_live_dl(name, 65535, 1, -1, errbuf);
|
||||
if(!m_p)
|
||||
{
|
||||
logerror("Unable to open %s: %s\n", name, errbuf);
|
||||
return;
|
||||
}
|
||||
if(pcap_set_datalink_dl(m_p, DLT_EN10MB) == -1)
|
||||
{
|
||||
logerror("Unable to set %s to ethernet", name);
|
||||
pcap_close_dl(m_p);
|
||||
m_p = NULL;
|
||||
return;
|
||||
}
|
||||
set_mac(get_mac());
|
||||
}
|
||||
|
||||
void netdev_pcap::set_mac(const char *mac)
|
||||
{
|
||||
char filter[256];
|
||||
struct bpf_program fp;
|
||||
if(!m_p) return;
|
||||
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]);
|
||||
pcap_compile_dl(m_p, &fp, filter, 1, 0);
|
||||
pcap_setfilter_dl(m_p, &fp);
|
||||
}
|
||||
|
||||
int netdev_pcap::send(UINT8 *buf, int len)
|
||||
{
|
||||
if(!m_p) return 0;
|
||||
return (!pcap_sendpacket_dl(m_p, buf, len))?len:0;
|
||||
}
|
||||
|
||||
int netdev_pcap::recv_dev(UINT8 **buf)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
netdev_pcap::~netdev_pcap()
|
||||
{
|
||||
if(m_p && handle) pcap_close_dl(m_p);
|
||||
}
|
||||
|
||||
static CREATE_NETDEV(create_pcap)
|
||||
{
|
||||
class netdev_pcap *dev = global_alloc(netdev_pcap(ifname, ifdev, rate));
|
||||
return dynamic_cast<netdev *>(dev);
|
||||
}
|
||||
|
||||
void init_pcap()
|
||||
{
|
||||
pcap_if_t *devs;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
handle = NULL;
|
||||
|
||||
try
|
||||
{
|
||||
if(!(handle = LoadLibrary(L"wpcap.dll"))) throw GetLastError();
|
||||
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();
|
||||
}
|
||||
catch (DWORD e)
|
||||
{
|
||||
FreeLibrary(handle);
|
||||
osd_printf_verbose("Unable to load winpcap: %lx\n", e);
|
||||
return;
|
||||
}
|
||||
if(pcap_findalldevs_dl(&devs, errbuf) == -1)
|
||||
{
|
||||
FreeLibrary(handle);
|
||||
osd_printf_verbose("Unable to get network devices: %s\n", errbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
while(devs)
|
||||
{
|
||||
add_netdev(devs->name, devs->description, create_pcap);
|
||||
devs = devs->next;
|
||||
}
|
||||
}
|
||||
|
||||
void deinit_pcap()
|
||||
{
|
||||
clear_netdev();
|
||||
FreeLibrary(handle);
|
||||
handle = NULL;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
#ifndef __NETDEV_PCAP_H__
|
||||
#define __NETDEV_PCAP_H__
|
||||
|
||||
void init_pcap();
|
||||
void deinit_pcap();
|
||||
|
||||
#endif
|
@ -92,6 +92,7 @@ OBJDIRS += $(WINOBJ) \
|
||||
$(OSDOBJ)/modules/lib \
|
||||
$(OSDOBJ)/modules/midi \
|
||||
$(OSDOBJ)/modules/font \
|
||||
$(OSDOBJ)/modules/netdev \
|
||||
|
||||
ifdef USE_QTDEBUG
|
||||
OBJDIRS += $(OSDOBJ)/modules/debugger/qt
|
||||
@ -387,6 +388,8 @@ OSDOBJS = \
|
||||
$(OSDOBJ)/modules/font/font_windows.o \
|
||||
$(OSDOBJ)/modules/font/font_osx.o \
|
||||
$(OSDOBJ)/modules/font/font_none.o \
|
||||
$(OSDOBJ)/modules/netdev/pcap.o \
|
||||
$(OSDOBJ)/modules/netdev/taptun.o \
|
||||
|
||||
ifdef USE_SDL
|
||||
OSDOBJS += \
|
||||
@ -394,9 +397,7 @@ OSDOBJS += \
|
||||
endif
|
||||
|
||||
ifndef DONT_USE_NETWORK
|
||||
OSDOBJS += \
|
||||
$(WINOBJ)/netdev.o \
|
||||
$(WINOBJ)/netdev_pcap.o
|
||||
DEFS += -DSDLMAME_NET_PCAP
|
||||
endif
|
||||
|
||||
CCOMFLAGS += -DDIRECT3D_VERSION=0x0900
|
||||
|
@ -260,17 +260,11 @@ public:
|
||||
virtual void input_pause();
|
||||
virtual void input_resume();
|
||||
virtual bool output_init();
|
||||
#ifdef USE_NETWORK
|
||||
virtual bool network_init();
|
||||
#endif
|
||||
|
||||
virtual void video_exit();
|
||||
virtual void window_exit();
|
||||
virtual void input_exit();
|
||||
virtual void output_exit();
|
||||
#ifdef USE_NETWORK
|
||||
virtual void network_exit();
|
||||
#endif
|
||||
|
||||
private:
|
||||
void osd_exit();
|
||||
|
Loading…
Reference in New Issue
Block a user