Previous 199869 Revisions Next

r34747 Friday 30th January, 2015 at 20:10:32 UTC by Couriersud
Converted pcap and taptun network code into modules. (nw)
[3rdparty/sqlite3]sqlite3.h
[src/emu]dinetwork.h video.c
[src/emu/cpu]drcbex64.h drcbex86.h uml.h
[src/emu/cpu/amis2000]amis2000.c amis2000.h amis2000op.inc
[src/emu/ui]inputmap.c mainmenu.c miscmenu.c
[src/lib/util]bitmap.c
[src/osd]osdnet.c osdnet.h
[src/osd/modules]osdmodule.h
[src/osd/modules/lib]osdobj_common.c osdobj_common.h
[src/osd/modules/netdev]pcap.c* taptun.c*
[src/osd/sdl]netdev.c netdev_pcap.c netdev_pcap.h netdev_pcap_osx.c netdev_tap.c netdev_tap.h osdsdl.h sdl.mak
[src/osd/windows]netdev.c netdev_pcap.c netdev_pcap.h windows.mak winmain.h winprefix.h

trunk/3rdparty/sqlite3/sqlite3.h
r243258r243259
256256typedef sqlite_int64 sqlite3_int64;
257257typedef sqlite_uint64 sqlite3_uint64;
258258
259/* pointer-sized values */
260#ifdef PTR64
261typedef sqlite3_uint64                      FPTR;
262#else
263typedef unsigned int                        FPTR;
264#endif
265
266259/*
267260** If compiling for a processor that lacks floating point support,
268261** substitute integer for floating-point.
r243258r243259
43894382*/
43904383typedef void (*sqlite3_destructor_type)(void*);
43914384#define SQLITE_STATIC      ((sqlite3_destructor_type)0)
4392#define SQLITE_TRANSIENT   ((sqlite3_destructor_type)(FPTR)-1)
4385#define SQLITE_TRANSIENT   ((sqlite3_destructor_type)-1)
43934386
43944387/*
43954388** CAPI3REF: Setting The Result Of An SQL Function
trunk/src/emu/cpu/amis2000/amis2000.c
r243258r243259
134134   // zerofill
135135   memset(m_callstack, 0, sizeof(m_callstack));
136136   m_pc = 0;
137   m_ppr = 0;
138   m_pbr = 0;
139   m_pp_index = 0;
140137   m_skip = false;
141138   m_op = 0;
142139   m_f = 0;
r243258r243259
151148   // register for savestates
152149   save_item(NAME(m_callstack));
153150   save_item(NAME(m_pc));
154   save_item(NAME(m_ppr));
155   save_item(NAME(m_pbr));
156   save_item(NAME(m_pp_index));
157151   save_item(NAME(m_skip));
158152   save_item(NAME(m_op));
159153   save_item(NAME(m_f));
r243258r243259
188182void amis2000_device::device_reset()
189183{
190184   m_pc = 0;
191   m_skip = false;
192   m_op = 0;
193185}
194186
195187
r243258r243259
205197   while (m_icount > 0)
206198   {
207199      m_icount--;
208     
209      // increase PP prefix count
210      if ((m_op & 0xf0) == 0x60)
211      {
212         if (m_pp_index < 2)
213            m_pp_index++;
214      }
215      else
216         m_pp_index = 0;
217200
218201      debugger_instruction_hook(this, m_pc);
219202      m_op = m_program->read_byte(m_pc);
trunk/src/emu/cpu/amis2000/amis2000.h
r243258r243259
7272   
7373   UINT8 m_bu_bits;
7474   UINT16 m_bu_mask;
75   UINT8 m_callstack_bits;     // number of program counter bits held in callstack
75   UINT8 m_callstack_bits;
7676   UINT16 m_callstack_mask;
7777   UINT8 m_callstack_depth;    // callstack levels: 3 on 2000/2150, 5 on 2200/2400
7878   UINT16 m_callstack[5];      // max 5
7979
80   UINT16 m_pc;                // 13-bit program counter
81   UINT8 m_ppr;                // prepared page register (PP 1)
82   UINT8 m_pbr;                // prepared bank register (PP 2)
83   UINT8 m_pp_index;           // number of handled PP prefixes
84   bool m_skip;                // skip next opcode, including PP prefixes
80   UINT16 m_pc;
81   bool m_skip;
8582   UINT8 m_op;
8683   UINT8 m_f;                  // generic flags: 2 on 2000/2150, 6 on 2200/2400
8784   UINT8 m_carry;              // carry flag
r243258r243259
10299   
103100   UINT8 ram_r();
104101   void ram_w(UINT8 data);
105   void pop_callstack();
106   void push_callstack();
107102   void op_illegal();
108103   
109104   void op_lai();
trunk/src/emu/cpu/amis2000/amis2000op.inc
r243258r243259
1414   m_data->write_byte(address, data & 0xf);
1515}
1616
17void amis2000_device::pop_callstack()
18{
19   m_pc = (m_pc & ~m_callstack_mask) | (m_callstack[0] & m_callstack_mask);
20   for (int i = 0; i < m_callstack_depth-1; i++)
21   {
22      m_callstack[i] = m_callstack[i+1];
23      m_callstack[i+1] = 0;
24   }
25}
26
27void amis2000_device::push_callstack()
28{
29   for (int i = m_callstack_depth-1; i >= 1; i--)
30   {
31      m_callstack[i] = m_callstack[i-1];
32   }
33   m_callstack[0] = m_pc & m_callstack_mask;
34}
35
3617void amis2000_device::op_illegal()
3718{
3819   logerror("%s unknown opcode $%02X at $%04X\n", tag(), m_op, m_pc);
r243258r243259
226207void amis2000_device::op_pp()
227208{
228209   // PP _X: prepare page/bank with _X
229   UINT8 param = ~m_op & 0x0f;
230   if (m_pp_index == 0)
231      m_ppr = param;
232   else
233      m_pbr = param & 7;
210   op_illegal();
234211}
235212
236213void amis2000_device::op_jmp()
237214{
238215   // JMP X: jump to X(+PP)
239   UINT16 mask = 0x3f;
240   UINT16 param = m_op & mask;
241   if (m_pp_index > 0)
242   {
243      param |= m_ppr << 6;
244      mask |= 0x3c0;
245   }
246   if (m_pp_index > 1)
247   {
248      param |= m_pbr << 10;
249      mask |= 0x1c00;
250   }
251   m_pc = (m_pc & ~mask) | param;
216   op_illegal();
252217}
253218
254219void amis2000_device::op_jms()
255220{
256221   // JMS X: call to X(+PP)
257   m_icount--;
258   push_callstack();
259   if (m_pp_index == 0)
260   {
261      // subroutines default location is page 15
262      m_ppr = 0xf;
263      m_pp_index++;
264   }
265   op_jmp();
222   op_illegal();
266223}
267224
268225void amis2000_device::op_rt()
269226{
270227   // RT: return from subroutine
271   pop_callstack();
228   op_illegal();
272229}
273230
274231void amis2000_device::op_rts()
275232{
276233   // RTS: return from subroutine and skip next
277   op_rt();
278   m_skip = true;
234   op_illegal();
279235}
280236
281237void amis2000_device::op_nop()
trunk/src/emu/cpu/drcbex64.h
r243258r243259
7373      static inline be_parameter make_ireg(int regnum) { assert(regnum >= 0 && regnum < x64emit::REG_MAX); return be_parameter(PTYPE_INT_REGISTER, regnum); }
7474      static inline be_parameter make_freg(int regnum) { assert(regnum >= 0 && regnum < x64emit::REG_MAX); return be_parameter(PTYPE_FLOAT_REGISTER, regnum); }
7575      static inline be_parameter make_vreg(int regnum) { assert(regnum >= 0 && regnum < x64emit::REG_MAX); return be_parameter(PTYPE_VECTOR_REGISTER, regnum); }
76      static inline be_parameter make_memory(void *base) { return be_parameter(PTYPE_MEMORY, static_cast<be_parameter_value>(reinterpret_cast<FPTR>(base))); }
77      static inline be_parameter make_memory(const void *base) { return be_parameter(PTYPE_MEMORY, static_cast<be_parameter_value>(reinterpret_cast<FPTR>(const_cast<void *>(base)))); }
76      static inline be_parameter make_memory(void *base) { return be_parameter(PTYPE_MEMORY, reinterpret_cast<be_parameter_value>(base)); }
77      static inline be_parameter make_memory(const void *base) { return be_parameter(PTYPE_MEMORY, reinterpret_cast<be_parameter_value>(const_cast<void *>(base))); }
7878
7979      // operators
8080      bool operator==(const be_parameter &rhs) const { return (m_type == rhs.m_type && m_value == rhs.m_value); }
trunk/src/emu/cpu/drcbex86.h
r243258r243259
7373      static inline be_parameter make_ireg(int regnum) { assert(regnum >= 0 && regnum < x86emit::REG_MAX); return be_parameter(PTYPE_INT_REGISTER, regnum); }
7474      static inline be_parameter make_freg(int regnum) { assert(regnum >= 0 && regnum < x86emit::REG_MAX); return be_parameter(PTYPE_FLOAT_REGISTER, regnum); }
7575      static inline be_parameter make_vreg(int regnum) { assert(regnum >= 0 && regnum < x86emit::REG_MAX); return be_parameter(PTYPE_VECTOR_REGISTER, regnum); }
76      static inline be_parameter make_memory(void *base) { return be_parameter(PTYPE_MEMORY, static_cast<be_parameter_value>(reinterpret_cast<FPTR>(base))); }
77      static inline be_parameter make_memory(const void *base) { return be_parameter(PTYPE_MEMORY, static_cast<be_parameter_value>(reinterpret_cast<FPTR>(const_cast<void *>(base)))); }
76      static inline be_parameter make_memory(void *base) { return be_parameter(PTYPE_MEMORY, reinterpret_cast<be_parameter_value>(base)); }
77      static inline be_parameter make_memory(const void *base) { return be_parameter(PTYPE_MEMORY, reinterpret_cast<be_parameter_value>(const_cast<void *>(base))); }
7878
7979      // operators
8080      bool operator==(const be_parameter &rhs) const { return (m_type == rhs.m_type && m_value == rhs.m_value); }
trunk/src/emu/cpu/uml.h
r243258r243259
305305      parameter(UINT64 val) : m_type(PTYPE_IMMEDIATE), m_value(val) { }
306306      parameter(operand_size size, memory_scale scale) : m_type(PTYPE_SIZE_SCALE), m_value((scale << 4) | size) { assert(size >= SIZE_BYTE && size <= SIZE_DQWORD); assert(scale >= SCALE_x1 && scale <= SCALE_x8); }
307307      parameter(operand_size size, memory_space space) : m_type(PTYPE_SIZE_SPACE), m_value((space << 4) | size) { assert(size >= SIZE_BYTE && size <= SIZE_DQWORD); assert(space >= SPACE_PROGRAM && space <= SPACE_IO); }
308      parameter(code_handle &handle) : m_type(PTYPE_CODE_HANDLE), m_value(static_cast<parameter_value>(reinterpret_cast<FPTR>(&handle))) { }
308      parameter(code_handle &handle) : m_type(PTYPE_CODE_HANDLE), m_value(reinterpret_cast<parameter_value>(&handle)) { }
309309      parameter(code_label &label) : m_type(PTYPE_CODE_LABEL), m_value(label) { }
310310
311311      // creators for types that don't safely default
r243258r243259
313313      static inline parameter make_freg(int regnum) { assert(regnum >= REG_F0 && regnum < REG_F_END); return parameter(PTYPE_FLOAT_REGISTER, regnum); }
314314      static inline parameter make_vreg(int regnum) { assert(regnum >= REG_V0 && regnum < REG_V_END); return parameter(PTYPE_VECTOR_REGISTER, regnum); }
315315      static inline parameter make_mapvar(int mvnum) { assert(mvnum >= MAPVAR_M0 && mvnum < MAPVAR_END); return parameter(PTYPE_MAPVAR, mvnum); }
316      static inline parameter make_memory(void *base) { return parameter(PTYPE_MEMORY, static_cast<parameter_value>(reinterpret_cast<FPTR>(base))); }
317      static inline parameter make_memory(const void *base) { return parameter(PTYPE_MEMORY, static_cast<parameter_value>(reinterpret_cast<FPTR>(const_cast<void *>(base)))); }
316      static inline parameter make_memory(void *base) { return parameter(PTYPE_MEMORY, reinterpret_cast<parameter_value>(base)); }
317      static inline parameter make_memory(const void *base) { return parameter(PTYPE_MEMORY, reinterpret_cast<parameter_value>(const_cast<void *>(base))); }
318318      static inline parameter make_size(operand_size size) { assert(size >= SIZE_BYTE && size <= SIZE_DQWORD); return parameter(PTYPE_SIZE, size); }
319      static inline parameter make_string(const char *string) { return parameter(PTYPE_STRING, static_cast<parameter_value>(reinterpret_cast<FPTR>(const_cast<char *>(string)))); }
320      static inline parameter make_cfunc(c_function func) { return parameter(PTYPE_C_FUNCTION, static_cast<parameter_value>(reinterpret_cast<FPTR>(func))); }
319      static inline parameter make_string(const char *string) { return parameter(PTYPE_STRING, reinterpret_cast<parameter_value>(const_cast<char *>(string))); }
320      static inline parameter make_cfunc(c_function func) { return parameter(PTYPE_C_FUNCTION, reinterpret_cast<parameter_value>(func)); }
321321      static inline parameter make_rounding(float_rounding_mode mode) { assert(mode >= ROUND_TRUNC && mode <= ROUND_DEFAULT); return parameter(PTYPE_ROUNDING, mode); }
322322
323323      // operators
trunk/src/emu/dinetwork.h
r243258r243259
11#ifndef __DINETWORK_H__
22#define __DINETWORK_H__
33
4class netdev;
4class osd_netdev;
55
66class device_network_interface : public device_interface
77{
r243258r243259
2424   bool m_promisc;
2525   char m_mac[6];
2626   float m_bandwidth;
27   auto_pointer<class netdev> m_dev;
27   auto_pointer<class osd_netdev> m_dev;
2828   int m_intf;
2929};
3030
trunk/src/emu/ui/inputmap.c
r243258r243259
7373   /* process the menu */
7474   const ui_menu_event *menu_event = process(0);
7575   if (menu_event != NULL && menu_event->iptkey == IPT_UI_SELECT)
76      ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_input_general(machine(), container, int((long long)((FPTR)menu_event->itemref)-1))));
76      ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_input_general(machine(), container, int((long long)(menu_event->itemref)-1))));
7777}
7878
7979
trunk/src/emu/ui/mainmenu.c
r243258r243259
151151   /* process the menu */
152152   const ui_menu_event *menu_event = process(0);
153153   if (menu_event != NULL && menu_event->iptkey == IPT_UI_SELECT) {
154      switch((long long)((FPTR) menu_event->itemref)) {
154      switch((long long)(menu_event->itemref)) {
155155      case INPUT_GROUPS:
156156         ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_input_groups(machine(), container)));
157157         break;
trunk/src/emu/ui/miscmenu.c
r243258r243259
159159   {
160160      int curr = network->get_interface();
161161      const char *title = NULL;
162      const netdev_entry_t *entry = netdev_first();
162      const osd_netdev::entry_t *entry = netdev_first();
163163      while(entry) {
164164         if(entry->id==curr) {
165165            title = entry->description;
trunk/src/emu/video.c
r243258r243259
10481048         if (filerr == FILERR_NONE)
10491049            save_snapshot(machine().first_screen(), file);
10501050      }
1051
1051        //printf("Scheduled exit at %f\n", emutime.as_double());
10521052      // schedule our demise
10531053      machine().schedule_exit();
10541054   }
trunk/src/lib/util/bitmap.c
r243258r243259
4949inline void bitmap_t::compute_base(int xslop, int yslop)
5050{
5151   m_base = m_alloc + (m_rowpixels * yslop + xslop) * (m_bpp / 8);
52   UINT64 aligned_base = ((static_cast<UINT64>(reinterpret_cast<FPTR>(m_base)) + (BITMAP_OVERALL_ALIGN - 1)) / BITMAP_OVERALL_ALIGN) * BITMAP_OVERALL_ALIGN;
52   UINT64 aligned_base = ((reinterpret_cast<UINT64>(m_base) + (BITMAP_OVERALL_ALIGN - 1)) / BITMAP_OVERALL_ALIGN) * BITMAP_OVERALL_ALIGN;
5353   m_base = reinterpret_cast<void *>(aligned_base);
5454}
5555
trunk/src/osd/modules/lib/osdobj_common.c
r243258r243259
128128   REGISTER_MODULE(m_mod_man, DEBUG_INTERNAL);
129129   REGISTER_MODULE(m_mod_man, DEBUG_NONE);
130130
131   REGISTER_MODULE(m_mod_man, NETDEV_TAPTUN);
132   REGISTER_MODULE(m_mod_man, NETDEV_PCAP);
133
134
131135   // after initialization we know which modules are supported
132136
133137   const char *names[20];
r243258r243259
399403{
400404   if (strcmp(command, OSDCOMMAND_LIST_NETWORK_ADAPTERS) == 0)
401405   {
402      network_init();
403      osd_list_network_adapters();
404      network_exit();
406      osd_module *om = select_module_options(options(), OSD_NETDEV_PROVIDER);
407
408      if (om->probe())
409      {
410         om->init();
411         osd_list_network_adapters();
412         om->exit();
413      }
414
405415      return true;
406416   }
407417   else if (strcmp(command, OSDCOMMAND_LIST_MIDI_DEVICES) == 0)
r243258r243259
431441   machine().add_notifier(MACHINE_NOTIFY_RESUME, machine_notify_delegate(FUNC(osd_common_t::input_resume), this));
432442
433443   output_init();
434#ifdef USE_NETWORK
435   network_init();
436#endif
437444   midi_init();
438445
439446   m_font_module = select_module_options<font_module *>(options(), OSD_FONT_PROVIDER);
r243258r243259
444451
445452   m_debugger = select_module_options<debug_module *>(options(), OSD_DEBUG_PROVIDER);
446453
454   select_module_options<netdev_module *>(options(), OSD_NETDEV_PROVIDER);
455
447456   m_mod_man.init();
448457
449458}
r243258r243259
485494   return true;
486495}
487496
488bool osd_common_t::network_init()
489{
490   return true;
491}
492
493497void osd_common_t::exit_subsystems()
494498{
495499   video_exit();
496500   input_exit();
497501   output_exit();
498   #ifdef USE_NETWORK
499   network_exit();
500   #endif
501502   midi_exit();
502503}
503504
r243258r243259
517518{
518519}
519520
520void osd_common_t::network_exit()
521{
522}
523
524521void osd_common_t::osd_exit()
525522{
526523   m_mod_man.exit();
trunk/src/osd/modules/lib/osdobj_common.h
r243258r243259
1818#include "modules/font/font_module.h"
1919#include "modules/sound/sound_module.h"
2020#include "modules/debugger/debug_module.h"
21#include "modules/netdev/netdev_module.h"
2122#include "cliopts.h"
2223
2324//============================================================
r243258r243259
164165
165166   virtual void input_resume();
166167   virtual bool output_init();
167   virtual bool network_init();
168168   virtual bool midi_init();
169169
170170   virtual void exit_subsystems();
r243258r243259
172172   virtual void window_exit();
173173   virtual void input_exit();
174174   virtual void output_exit();
175   virtual void network_exit();
176175   virtual void midi_exit();
177176
178177   virtual void osd_exit();
trunk/src/osd/modules/netdev/pcap.c
r0r243259
1#ifdef SDLMAME_NET_PCAP
2
3#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
4
5#define WIN32_LEAN_AND_MEAN
6#include <windows.h>
7#endif
8
9#include <pcap.h>
10
11#include "emu.h"
12#include "osdnet.h"
13#include "netdev_module.h"
14#include "modules/osdmodule.h"
15
16#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
17
18#define LIB_NAME      L"wpcap.dll"
19#define LIB_ERROR_STR    "Unable to load winpcap: %lx\n"
20typedef DWORD except_type;
21
22#else
23
24#include <dlfcn.h>
25#ifdef SDLMAME_MACOSX
26#include <pthread.h>
27#include <libkern/OSAtomic.h>
28#endif
29
30#ifdef SDLMAME_MACOSX
31#define LIB_NAME   "libpcap.dylib"
32#else
33#define LIB_NAME   "libpcap.so"
34#endif
35#define LIB_ERROR_STR    "Unable to load pcap: %s\n"
36
37typedef void *HMODULE;
38typedef const char *except_type;
39#define FreeLibrary(x) dlclose(x)
40#define GetLastError() dlerror()
41#define GetProcAddress(x, y) dlsym(x, y)
42#define LoadLibrary(x) dlopen(x, RTLD_LAZY)
43
44#endif
45
46class pcap_module : public osd_module, public netdev_module
47{
48public:
49
50   pcap_module()
51   : osd_module(OSD_NETDEV_PROVIDER, "pcap"), netdev_module(), handle(NULL)
52   {
53   }
54   virtual ~pcap_module() { }
55
56   virtual int init();
57   virtual void exit();
58
59   virtual bool probe();
60
61   HMODULE handle;
62};
63
64static int (*pcap_compile_dl)(pcap_t *, struct bpf_program *, char *, int, bpf_u_int32) = NULL;
65static int (*pcap_findalldevs_dl)(pcap_if_t **, char *) = NULL;
66static pcap_t *(*pcap_open_live_dl)(const char *name, int, int, int, char *) = NULL;
67static int (*pcap_next_ex_dl)(pcap_t *, struct pcap_pkthdr **, const u_char **) = NULL;
68static void (*pcap_close_dl)(pcap_t *) = NULL;
69static int (*pcap_setfilter_dl)(pcap_t *, struct bpf_program *) = NULL;
70static int (*pcap_sendpacket_dl)(pcap_t *, u_char *, int) = NULL;
71static int (*pcap_set_datalink_dl)(pcap_t *, int) = NULL;
72static int (*pcap_dispatch_dl)(pcap_t *, int, pcap_handler callback, u_char *) = NULL;
73
74
75#if 0
76#define pcap_compile_dl pcap_compile
77#define pcap_findalldevs_dl pcap_findalldevs
78#define pcap_open_live_dl pcap_open_live
79#define pcap_next_ex_dl pcap_next_ex
80#define pcap_close_dl pcap_close
81#define pcap_setfilter_dl pcap_setfilter
82#define pcap_sendpacket_dl pcap_sendpacket
83#define pcap_set_datalink_dl pcap_set_datalink
84#endif
85
86#ifdef SDLMAME_MACOSX
87struct netdev_pcap_context {
88   UINT8 *pkt;
89   int len;
90   pcap_t *p;
91
92   UINT8 packets[32][1600];
93   int packetlens[32];
94   int head;
95   int tail;
96};
97#endif
98
99class netdev_pcap : public osd_netdev
100{
101public:
102   netdev_pcap(const char *name, class device_network_interface *ifdev, int rate);
103   ~netdev_pcap();
104
105   int send(UINT8 *buf, int len);
106   void set_mac(const char *mac);
107protected:
108   int recv_dev(UINT8 **buf);
109private:
110   pcap_t *m_p;
111#ifdef SDLMAME_MACOSX
112   struct netdev_pcap_context m_ctx;
113   pthread_t m_thread;
114#endif
115};
116
117#ifdef SDLMAME_MACOSX
118static void netdev_pcap_handler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes) {
119   struct netdev_pcap_context *ctx = (struct netdev_pcap_context*)user;
120
121   if(OSAtomicCompareAndSwapInt((ctx->head+1) & 0x1F, ctx->tail, &ctx->tail)) {
122      printf("buffer full, dropping packet\n");
123      return;
124   }
125   memcpy(ctx->packets[ctx->head], bytes, h->len);
126   ctx->packetlens[ctx->head] = h->len;
127   OSAtomicCompareAndSwapInt(ctx->head, (ctx->head+1) & 0x1F, &ctx->head);
128}
129
130static void *netdev_pcap_blocker(void *arg) {
131   struct netdev_pcap_context *ctx = (struct netdev_pcap_context*)arg;
132
133   while(1) {
134      pcap_dispatch_dl(ctx->p, 1, netdev_pcap_handler, (u_char*)ctx);
135   }
136
137   return 0;
138}
139#endif
140
141netdev_pcap::netdev_pcap(const char *name, class device_network_interface *ifdev, int rate)
142   : osd_netdev(ifdev, rate)
143{
144   char errbuf[PCAP_ERRBUF_SIZE];
145#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
146   m_p = pcap_open_live_dl(name, 65535, 1, -1, errbuf);
147#else
148   m_p = pcap_open_live_dl(name, 65535, 1, 1, errbuf);
149#endif
150   if(!m_p)
151   {
152      logerror("Unable to open %s: %s\n", name, errbuf);
153      return;
154   }
155   if(pcap_set_datalink_dl(m_p, DLT_EN10MB) == -1)
156   {
157      logerror("Unable to set %s to ethernet", name);
158      pcap_close_dl(m_p);
159      m_p = NULL;
160      return;
161   }
162   set_mac(get_mac());
163
164#ifdef SDLMAME_MACOSX
165   m_ctx.head = 0;
166   m_ctx.tail = 0;
167   m_ctx.p = m_p;
168   pthread_create(&m_thread, NULL, netdev_pcap_blocker, &m_ctx);
169#endif
170}
171
172void netdev_pcap::set_mac(const char *mac)
173{
174   char filter[256];
175   struct bpf_program fp;
176   if(!m_p) return;
177#ifdef SDLMAME_MACOSX
178   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]);
179#else
180   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]);
181#endif   
182   if(pcap_compile_dl(m_p, &fp, filter, 1, 0) == -1) {
183      logerror("Error with pcap_compile\n");
184   }
185   if(pcap_setfilter_dl(m_p, &fp) == -1) {
186      logerror("Error with pcap_setfilter\n");
187   }
188}
189
190int netdev_pcap::send(UINT8 *buf, int len)
191{
192   if(!m_p) return 0;
193   return (!pcap_sendpacket_dl(m_p, buf, len))?len:0;
194}
195
196int netdev_pcap::recv_dev(UINT8 **buf)
197{
198#ifdef SDLMAME_MACOSX
199   UINT8 pktbuf[2048];
200   int ret;
201
202   // Empty
203   if(OSAtomicCompareAndSwapInt(m_ctx.head, m_ctx.tail, &m_ctx.tail)) {
204      return 0;
205   }
206
207   memcpy(pktbuf, m_ctx.packets[m_ctx.tail], m_ctx.packetlens[m_ctx.tail]);
208   ret = m_ctx.packetlens[m_ctx.tail];
209   OSAtomicCompareAndSwapInt(m_ctx.tail, (m_ctx.tail+1) & 0x1F, &m_ctx.tail);
210   *buf = pktbuf;
211   return ret;
212#else
213   struct pcap_pkthdr *header;
214   if(!m_p) return 0;
215   return (pcap_next_ex_dl(m_p, &header, (const u_char **)buf) == 1)?header->len:0;
216#endif
217}
218
219netdev_pcap::~netdev_pcap()
220{
221   if(m_p) pcap_close_dl(m_p);
222}
223
224static CREATE_NETDEV(create_pcap)
225{
226   class netdev_pcap *dev = global_alloc(netdev_pcap(ifname, ifdev, rate));
227   return dynamic_cast<osd_netdev *>(dev);
228}
229
230bool pcap_module::probe()
231{
232   if (handle == NULL)
233   {
234      handle = LoadLibrary(LIB_NAME);
235      return (handle != NULL);
236   }
237   return true;
238}
239
240
241int pcap_module::init()
242{
243   pcap_if_t *devs;
244   char errbuf[PCAP_ERRBUF_SIZE];
245
246   try
247   {
248      if(!(pcap_findalldevs_dl = (int (*)(pcap_if_t **, char *))GetProcAddress(handle, "pcap_findalldevs")))
249         throw GetLastError();
250      if(!(pcap_open_live_dl = (pcap_t* (*)(const char *, int, int, int, char *))GetProcAddress(handle, "pcap_open_live")))
251         throw GetLastError();
252      if(!(pcap_next_ex_dl = (int (*)(pcap_t *, struct pcap_pkthdr **, const u_char **))GetProcAddress(handle, "pcap_next_ex")))
253         throw GetLastError();
254      if(!(pcap_compile_dl = (int (*)(pcap_t *, struct bpf_program *, char *, int, bpf_u_int32))GetProcAddress(handle, "pcap_compile")))
255         throw GetLastError();
256      if(!(pcap_close_dl = (void (*)(pcap_t *))GetProcAddress(handle, "pcap_close")))
257         throw GetLastError();
258      if(!(pcap_setfilter_dl = (int (*)(pcap_t *, struct bpf_program *))GetProcAddress(handle, "pcap_setfilter")))
259         throw GetLastError();
260      if(!(pcap_sendpacket_dl = (int (*)(pcap_t *, u_char *, int))GetProcAddress(handle, "pcap_sendpacket")))
261         throw GetLastError();
262      if(!(pcap_set_datalink_dl = (int (*)(pcap_t *, int))GetProcAddress(handle, "pcap_set_datalink")))
263         throw GetLastError();
264      if(!(pcap_dispatch_dl = (int (*)(pcap_t *, int, pcap_handler callback, u_char *))GetProcAddress(handle, "pcap_dispatch")))
265         throw GetLastError();
266   }
267   catch (except_type e)
268   {
269      FreeLibrary(handle);
270      logerror(LIB_ERROR_STR, e);
271      return 1;
272   }
273   if(pcap_findalldevs_dl(&devs, errbuf) == -1)
274   {
275      FreeLibrary(handle);
276      logerror("Unable to get network devices: %s\n", errbuf);
277      return 1;
278   }
279
280   while(devs)
281   {
282      add_netdev(devs->name, devs->description, create_pcap);
283      devs = devs->next;
284   }
285   return 0;
286}
287
288void pcap_module::exit()
289{
290   clear_netdev();
291   FreeLibrary(handle);
292   handle = NULL;
293}
294#else
295   #include "modules/osdmodule.h"
296   #include "netdev_module.h"
297
298   MODULE_NOT_SUPPORTED(pcap_module, OSD_NETDEV_PROVIDER, "pcap")
299#endif
300
301
302MODULE_DEFINITION(NETDEV_PCAP, pcap_module)
303
trunk/src/osd/modules/netdev/taptun.c
r0r243259
1#if defined(SDLMAME_NET_TAPTUN)
2
3#include <unistd.h>
4#include <fcntl.h>
5#include <sys/ioctl.h>
6#include <net/if.h>
7#include <errno.h>
8
9#include "emu.h"
10#include "osdnet.h"
11#include "modules/osdmodule.h"
12#include "netdev_module.h"
13
14#ifdef __linux__
15#define IFF_TAP     0x0002
16#define IFF_NO_PI   0x1000
17#define TUNSETIFF     _IOW('T', 202, int)
18#endif
19
20class taptun_module : public osd_module, public netdev_module
21{
22public:
23
24   taptun_module()
25   : osd_module(OSD_NETDEV_PROVIDER, "taptun"), netdev_module()
26   {
27   }
28   virtual ~taptun_module() { }
29
30   virtual int init();
31   virtual void exit();
32
33   virtual bool probe() { return true; }
34};
35
36
37
38class netdev_tap : public osd_netdev
39{
40public:
41   netdev_tap(const char *name, class device_network_interface *ifdev, int rate);
42   ~netdev_tap();
43
44   int send(UINT8 *buf, int len);
45   void set_mac(const char *mac);
46protected:
47   int recv_dev(UINT8 **buf);
48private:
49   int m_fd;
50   char m_ifname[10];
51   char m_mac[6];
52   UINT8 m_buf[2048];
53};
54
55netdev_tap::netdev_tap(const char *name, class device_network_interface *ifdev, int rate)
56   : osd_netdev(ifdev, rate)
57{
58#ifdef __linux__
59   struct ifreq ifr;
60
61   m_fd = -1;
62   if((m_fd = open("/dev/net/tun", O_RDWR)) == -1) {
63      osd_printf_verbose("tap: open failed %d\n", errno);
64      return;
65   }
66
67   memset(&ifr, 0, sizeof(ifr));
68   ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
69   sprintf(ifr.ifr_name, "tap-mess-%d-0", getuid());
70   if(ioctl(m_fd, TUNSETIFF, (void *)&ifr) == -1) {
71      osd_printf_verbose("tap: ioctl failed %d\n", errno);
72      close(m_fd);
73      m_fd = -1;
74      return;
75   }
76   osd_printf_verbose("netdev_tap: network up!\n");
77   strncpy(m_ifname, ifr.ifr_name, 10);
78   fcntl(m_fd, F_SETFL, O_NONBLOCK);
79
80#else
81   m_fd = -1;
82#endif
83}
84
85netdev_tap::~netdev_tap()
86{
87   close(m_fd);
88}
89
90void netdev_tap::set_mac(const char *mac)
91{
92   memcpy(m_mac, mac, 6);
93}
94
95int netdev_tap::send(UINT8 *buf, int len)
96{
97   if(m_fd == -1) return 0;
98   len = write(m_fd, buf, len);
99   return (len == -1)?0:len;
100}
101
102int netdev_tap::recv_dev(UINT8 **buf)
103{
104   int len;
105   if(m_fd == -1) return 0;
106   // exit if we didn't receive anything, got an error, got a broadcast or multicast packet,
107   // are in promiscuous mode or got a packet with our mac.
108   do {
109      len = read(m_fd, m_buf, sizeof(m_buf));
110   } while((len > 0) && memcmp(get_mac(), m_buf, 6) && !get_promisc() && !(m_buf[0] & 1));
111   *buf = m_buf;
112   return (len == -1)?0:len;
113}
114
115static CREATE_NETDEV(create_tap)
116{
117   class netdev_tap *dev = global_alloc(netdev_tap(ifname, ifdev, rate));
118   return dynamic_cast<osd_netdev *>(dev);
119}
120
121int taptun_module::init()
122{
123   add_netdev("tap", "TAP/TUN Device", create_tap);
124   return 0;
125}
126
127void taptun_module::exit()
128{
129   clear_netdev();
130}
131
132
133#else
134   #include "modules/osdmodule.h"
135   #include "netdev_module.h"
136
137   MODULE_NOT_SUPPORTED(taptun_module, OSD_NETDEV_PROVIDER, "taptun")
138#endif
139
140
141MODULE_DEFINITION(NETDEV_TAPTUN, taptun_module)
trunk/src/osd/modules/osdmodule.h
r243258r243259
3434   const char * name() const { return m_name; }
3535   const char * type() const { return m_type; }
3636
37   virtual bool probe() const { return true; }
37   virtual bool probe() { return true; }
3838
3939   virtual int init() { return 0; }
4040   virtual void exit() { }
r243258r243259
100100   public: \
101101      _mod () \
102102      : osd_module(_type, _name) {} \
103      bool probe() const { return false; } \
103      bool probe() { return false; } \
104104   };
105105
106106#endif  /* __OSDMODULE_H__ */
trunk/src/osd/osdnet.c
r243258r243259
11#include "emu.h"
22#include "osdnet.h"
33
4static class simple_list<netdev_entry_t> netdev_list;
4static class simple_list<osd_netdev::entry_t> netdev_list;
55
66void add_netdev(const char *name, const char *description, create_netdev func)
77{
8   netdev_entry_t *entry = global_alloc_clear(netdev_entry_t);
8   osd_netdev::entry_t *entry = global_alloc_clear(osd_netdev::entry_t);
99   entry->id = netdev_list.count();
1010   strncpy(entry->name, name, 255);
1111   entry->name[255] = '\0';
r243258r243259
2020   netdev_list.reset();
2121}
2222
23const netdev_entry_t *netdev_first() {
23const osd_netdev::entry_t *netdev_first() {
2424   return netdev_list.first();
2525}
2626
27class netdev *open_netdev(int id, class device_network_interface *ifdev, int rate)
27class osd_netdev *open_netdev(int id, class device_network_interface *ifdev, int rate)
2828{
29   netdev_entry_t *entry = netdev_list.first();
29   osd_netdev::entry_t *entry = netdev_list.first();
3030   while(entry) {
3131      if(entry->id==id)
3232         return entry->func(entry->name, ifdev, rate);
r243258r243259
3636   return NULL;
3737}
3838
39netdev::netdev(class device_network_interface *ifdev, int rate)
39osd_netdev::osd_netdev(class device_network_interface *ifdev, int rate)
4040{
4141   m_dev = ifdev;
42   ifdev->device().machine().scheduler().timer_pulse(attotime::from_hz(rate), timer_expired_delegate(FUNC(netdev::recv), this));
42   ifdev->device().machine().scheduler().timer_pulse(attotime::from_hz(rate), timer_expired_delegate(FUNC(osd_netdev::recv), this));
4343}
4444
45netdev::~netdev()
45osd_netdev::~osd_netdev()
4646{
4747}
4848
49int netdev::send(UINT8 *buf, int len)
49int osd_netdev::send(UINT8 *buf, int len)
5050{
5151   return 0;
5252}
5353
54void netdev::recv(void *ptr, int param)
54void osd_netdev::recv(void *ptr, int param)
5555{
5656   UINT8 *buf;
5757   int len;
r243258r243259
7474   }
7575}
7676
77int netdev::recv_dev(UINT8 **buf)
77int osd_netdev::recv_dev(UINT8 **buf)
7878{
7979   return 0;
8080}
8181
82void netdev::set_mac(const char *mac)
82void osd_netdev::set_mac(const char *mac)
8383{
8484}
8585
86void netdev::set_promisc(bool promisc)
86void osd_netdev::set_promisc(bool promisc)
8787{
8888}
8989
90bool netdev::get_promisc()
90bool osd_netdev::get_promisc()
9191{
9292   if(m_dev)
9393      return m_dev->get_promisc();
9494   return false;
9595}
9696
97const char *netdev::get_mac()
97const char *osd_netdev::get_mac()
9898{
9999   if(m_dev)
100100      return m_dev->get_mac();
r243258r243259
118118   }
119119
120120   printf("Available network adapters:\n");
121   const netdev_entry_t *entry = netdev_first();
121   const osd_netdev::entry_t *entry = netdev_first();
122122   while(entry) {
123123      printf("    %s\n", entry->description);
124124      entry = entry->m_next;
trunk/src/osd/osdnet.h
r243258r243259
33#ifndef __OSDNET_H__
44#define __OSDNET_H__
55
6class netdev;
6class osd_netdev;
77
8#define CREATE_NETDEV(name) class netdev *name(const char *ifname, class device_network_interface *ifdev, int rate)
9typedef class netdev *(*create_netdev)(const char *ifname, class device_network_interface *ifdev, int rate);
8#define CREATE_NETDEV(name) class osd_netdev *name(const char *ifname, class device_network_interface *ifdev, int rate)
9typedef class osd_netdev *(*create_netdev)(const char *ifname, class device_network_interface *ifdev, int rate);
1010
11struct netdev_entry_t
11class osd_netdev
1212{
13   int id;
14   char name[256];
15   char description[256];
16   create_netdev func;
17   netdev_entry_t *m_next;
18};
19
20class netdev
21{
2213public:
23   netdev(class device_network_interface *ifdev, int rate);
24   virtual ~netdev();
14   struct entry_t
15   {
16      int id;
17      char name[256];
18      char description[256];
19      create_netdev func;
20      entry_t *m_next;
21   };
22   osd_netdev(class device_network_interface *ifdev, int rate);
23   virtual ~osd_netdev();
2524
2625   virtual int send(UINT8 *buf, int len);
2726   virtual void set_mac(const char *mac);
r243258r243259
3938   class device_network_interface *m_dev;
4039};
4140
42class netdev *open_netdev(int id, class device_network_interface *ifdev, int rate);
41class osd_netdev *open_netdev(int id, class device_network_interface *ifdev, int rate);
4342void add_netdev(const char *name, const char *description, create_netdev func);
4443void clear_netdev();
45const netdev_entry_t *netdev_first();
44const osd_netdev::entry_t *netdev_first();
4645int netdev_count();
4746#endif
trunk/src/osd/sdl/netdev.c
r243258r243259
1#include "emu.h"
2#include "netdev_tap.h"
3#include "netdev_pcap.h"
4#include "osdsdl.h"
5
6bool sdl_osd_interface::network_init()
7{
8   #ifdef SDLMAME_NET_TAPTUN
9   init_tap();
10   #endif
11   #ifdef SDLMAME_NET_PCAP
12   init_pcap();
13   #endif
14   return true;
15}
16
17void sdl_osd_interface::network_exit()
18{
19   #ifdef SDLMAME_NET_TAPTUN
20   deinit_tap();
21   #endif
22   #ifdef SDLMAME_NET_PCAP
23   deinit_pcap();
24   #endif
25}
trunk/src/osd/sdl/netdev_pcap.c
r243258r243259
1#ifdef SDLMAME_WIN32
2#include "../windows/netdev_pcap.c"
3#else
4
5#include <pcap.h>
6
7static int (*pcap_compile_dl)(pcap_t *, struct bpf_program *, char *, int, bpf_u_int32) = NULL;
8static int (*pcap_findalldevs_dl)(pcap_if_t **, char *) = NULL;
9static pcap_t *(*pcap_open_live_dl)(const char *name, int, int, int, char *) = NULL;
10static int (*pcap_next_ex_dl)(pcap_t *, struct pcap_pkthdr **, const u_char **) = NULL;
11static void (*pcap_close_dl)(pcap_t *) = NULL;
12static int (*pcap_setfilter_dl)(pcap_t *, struct bpf_program *) = NULL;
13static int (*pcap_sendpacket_dl)(pcap_t *, u_char *, int) = NULL;
14static int (*pcap_set_datalink_dl)(pcap_t *, int) = NULL;
15
16#include <dlfcn.h>
17
18#include "emu.h"
19#include "osdnet.h"
20
21static void *handle = NULL;
22
23class netdev_pcap : public netdev
24{
25public:
26   netdev_pcap(const char *name, class device_network_interface *ifdev, int rate);
27   ~netdev_pcap();
28
29   int send(UINT8 *buf, int len);
30   void set_mac(const char *mac);
31protected:
32   int recv_dev(UINT8 **buf);
33private:
34   pcap_t *m_p;
35};
36
37netdev_pcap::netdev_pcap(const char *name, class device_network_interface *ifdev, int rate)
38   : netdev(ifdev, rate)
39{
40   char errbuf[PCAP_ERRBUF_SIZE];
41   m_p = pcap_open_live_dl(name, 65535, 1, 1, errbuf);
42   if(!m_p)
43   {
44      osd_printf_verbose("Unable to open %s: %s\n", name, errbuf);
45      return;
46   }
47   if(pcap_set_datalink_dl(m_p, DLT_EN10MB) == -1)
48   {
49      osd_printf_verbose("Unable to set %s to ethernet\n", name);
50      pcap_close_dl(m_p);
51      m_p = NULL;
52      return;
53   }
54   set_mac(get_mac());
55}
56
57void netdev_pcap::set_mac(const char *mac)
58{
59   char filter[256];
60   struct bpf_program fp;
61   if(!m_p) return;
62   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]);
63   if(pcap_compile_dl(m_p, &fp, filter, 1, 0) == -1) {
64      osd_printf_verbose("Error with pcap_compile\n");
65   }
66   if(pcap_setfilter_dl(m_p, &fp) == -1) {
67      osd_printf_verbose("Error with pcap_setfilter\n");
68   }
69}
70
71int netdev_pcap::send(UINT8 *buf, int len)
72{
73   if(!m_p) return 0;
74   return (!pcap_sendpacket_dl(m_p, buf, len))?len:0;
75}
76
77int netdev_pcap::recv_dev(UINT8 **buf)
78{
79   struct pcap_pkthdr *header;
80   if(!m_p) return 0;
81   return (pcap_next_ex_dl(m_p, &header, (const u_char **)buf) == 1)?header->len:0;
82}
83
84netdev_pcap::~netdev_pcap()
85{
86   if(m_p) pcap_close_dl(m_p);
87}
88
89static CREATE_NETDEV(create_pcap)
90{
91   class netdev_pcap *dev = global_alloc(netdev_pcap(ifname, ifdev, rate));
92   return dynamic_cast<netdev *>(dev);
93}
94
95void init_pcap()
96{
97   pcap_if_t *devs;
98   char errbuf[PCAP_ERRBUF_SIZE];
99   handle = NULL;
100
101   try
102   {
103      if(!(handle = dlopen("libpcap.so", RTLD_LAZY))) throw dlerror();
104      if(!(pcap_findalldevs_dl = (int (*)(pcap_if_t **, char *))dlsym(handle, "pcap_findalldevs")))
105         throw dlerror();
106      if(!(pcap_open_live_dl = (pcap_t* (*)(const char *, int, int, int, char *))dlsym(handle, "pcap_open_live")))
107         throw dlerror();
108      if(!(pcap_next_ex_dl = (int (*)(pcap_t *, struct pcap_pkthdr **, const u_char **))dlsym(handle, "pcap_next_ex")))
109         throw dlerror();
110      if(!(pcap_compile_dl = (int (*)(pcap_t *, struct bpf_program *, char *, int, bpf_u_int32))dlsym(handle, "pcap_compile")))
111         throw dlerror();
112      if(!(pcap_close_dl = (void (*)(pcap_t *))dlsym(handle, "pcap_close")))
113         throw dlerror();
114      if(!(pcap_setfilter_dl = (int (*)(pcap_t *, struct bpf_program *))dlsym(handle, "pcap_setfilter")))
115         throw dlerror();
116      if(!(pcap_sendpacket_dl = (int (*)(pcap_t *, u_char *, int))dlsym(handle, "pcap_sendpacket")))
117         throw dlerror();
118      if(!(pcap_set_datalink_dl = (int (*)(pcap_t *, int))dlsym(handle, "pcap_set_datalink")))
119         throw dlerror();
120   }
121   catch (const char *e)
122   {
123      dlclose(handle);
124      osd_printf_verbose("Unable to load winpcap: %s\n", e);
125      return;
126   }
127   if(pcap_findalldevs_dl(&devs, errbuf) == -1)
128   {
129      dlclose(handle);
130      osd_printf_verbose("Unable to get network devices: %s\n", errbuf);
131      return;
132   }
133
134   while(devs)
135   {
136      add_netdev(devs->name, devs->description, create_pcap);
137      devs = devs->next;
138   }
139}
140
141void deinit_pcap()
142{
143   clear_netdev();
144   dlclose(handle);
145   handle = NULL;
146}
147
148#endif  // SDLMAME_WIN32
trunk/src/osd/sdl/netdev_pcap.h
r243258r243259
1#ifndef __NETDEV_PCAP_H__
2#define __NETDEV_PCAP_H__
3
4void init_pcap();
5void deinit_pcap();
6
7#endif
trunk/src/osd/sdl/netdev_pcap_osx.c
r243258r243259
1#ifdef SDLMAME_WIN32
2#include "../windows/netdev_pcap.c"
3#else
4
5#include <pcap.h>
6#include "emu.h"
7#include "osdnet.h"
8#include <pthread.h>
9#include <libkern/OSAtomic.h>
10
11#define pcap_compile_dl pcap_compile
12#define pcap_findalldevs_dl pcap_findalldevs
13#define pcap_open_live_dl pcap_open_live
14#define pcap_next_ex_dl pcap_next_ex
15#define pcap_close_dl pcap_close
16#define pcap_setfilter_dl pcap_setfilter
17#define pcap_sendpacket_dl pcap_sendpacket
18#define pcap_set_datalink_dl pcap_set_datalink
19
20struct netdev_pcap_context {
21   UINT8 *pkt;
22   int len;
23   pcap_t *p;
24
25   UINT8 packets[32][1600];
26   int packetlens[32];
27   int head;
28   int tail;
29};
30
31class netdev_pcap : public netdev
32{
33public:
34   netdev_pcap(const char *name, class device_network_interface *ifdev, int rate);
35   ~netdev_pcap();
36
37   int send(UINT8 *buf, int len);
38   void set_mac(const char *mac);
39protected:
40   int recv_dev(UINT8 **buf);
41private:
42   pcap_t *m_p;
43   struct netdev_pcap_context m_ctx;
44   pthread_t m_thread;
45};
46
47static void netdev_pcap_handler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes) {
48   struct netdev_pcap_context *ctx = (struct netdev_pcap_context*)user;
49
50   if(OSAtomicCompareAndSwapInt((ctx->head+1) & 0x1F, ctx->tail, &ctx->tail)) {
51      printf("buffer full, dropping packet\n");
52      return;
53   }
54   memcpy(ctx->packets[ctx->head], bytes, h->len);
55   ctx->packetlens[ctx->head] = h->len;
56   OSAtomicCompareAndSwapInt(ctx->head, (ctx->head+1) & 0x1F, &ctx->head);
57}
58
59static void *netdev_pcap_blocker(void *arg) {
60   struct netdev_pcap_context *ctx = (struct netdev_pcap_context*)arg;
61
62   while(1) {
63      pcap_dispatch(ctx->p, 1, netdev_pcap_handler, (u_char*)ctx);
64   }
65
66   return 0;
67}
68
69netdev_pcap::netdev_pcap(const char *name, class device_network_interface *ifdev, int rate)
70   : netdev(ifdev, rate)
71{
72   char errbuf[PCAP_ERRBUF_SIZE];
73   m_p = pcap_open_live_dl(name, 65535, 1, 1, errbuf);
74   if(!m_p)
75   {
76      osd_printf_verbose("Unable to open %s: %s\n", name, errbuf);
77      return;
78   }
79   if(pcap_set_datalink_dl(m_p, DLT_EN10MB) == -1)
80   {
81      osd_printf_verbose("Unable to set %s to ethernet\n", name);
82      pcap_close_dl(m_p);
83      m_p = NULL;
84      return;
85   }
86   set_mac(get_mac());
87
88   m_ctx.head = 0;
89   m_ctx.tail = 0;
90   m_ctx.p = m_p;
91   pthread_create(&m_thread, NULL, netdev_pcap_blocker, &m_ctx);
92}
93
94void netdev_pcap::set_mac(const char *mac)
95{
96   char filter[256];
97   struct bpf_program fp;
98   if(!m_p) return;
99   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]);
100   if(pcap_compile_dl(m_p, &fp, filter, 1, 0) == -1) {
101      osd_printf_verbose("Error with pcap_compile\n");
102   }
103   if(pcap_setfilter_dl(m_p, &fp) == -1) {
104      osd_printf_verbose("Error with pcap_setfilter\n");
105   }
106}
107
108int netdev_pcap::send(UINT8 *buf, int len)
109{
110   if(!m_p) return 0;
111   return (!pcap_sendpacket_dl(m_p, buf, len))?len:0;
112}
113
114int netdev_pcap::recv_dev(UINT8 **buf)
115{
116   UINT8 pktbuf[2048];
117   int ret;
118
119   // Empty
120   if(OSAtomicCompareAndSwapInt(m_ctx.head, m_ctx.tail, &m_ctx.tail)) {
121      return 0;
122   }
123
124   memcpy(pktbuf, m_ctx.packets[m_ctx.tail], m_ctx.packetlens[m_ctx.tail]);
125   ret = m_ctx.packetlens[m_ctx.tail];
126   OSAtomicCompareAndSwapInt(m_ctx.tail, (m_ctx.tail+1) & 0x1F, &m_ctx.tail);
127   *buf = pktbuf;
128   return ret;
129}
130
131netdev_pcap::~netdev_pcap()
132{
133   if(m_p) pcap_close_dl(m_p);
134}
135
136static CREATE_NETDEV(create_pcap)
137{
138   class netdev_pcap *dev = global_alloc(netdev_pcap(ifname, ifdev, rate));
139   return dynamic_cast<netdev *>(dev);
140}
141
142void init_pcap()
143{
144   pcap_if_t *devs;
145   char errbuf[PCAP_ERRBUF_SIZE];
146   if(pcap_findalldevs_dl(&devs, errbuf) == -1)
147   {
148      osd_printf_verbose("Unable to get network devices: %s\n", errbuf);
149      return;
150   }
151
152#if 1
153   while(devs)
154   {
155      add_netdev(devs->name, devs->description, create_pcap);
156      devs = devs->next;
157   }
158#else
159   if (devs)
160   {
161      while(devs->next)
162      {
163         add_netdev(devs->name, devs->description ? devs->description : devs->name, create_pcap);
164         devs = devs->next;
165      }
166   }
167#endif
168}
169
170void deinit_pcap()
171{
172   clear_netdev();
173}
174
175#endif  // SDLMAME_WIN32
trunk/src/osd/sdl/netdev_tap.c
r243258r243259
1#include <unistd.h>
2#include <fcntl.h>
3#include <sys/ioctl.h>
4#include <net/if.h>
5#include <errno.h>
6
7#include "emu.h"
8#include "osdnet.h"
9
10#ifdef __linux__
11#define IFF_TAP     0x0002
12#define IFF_NO_PI   0x1000
13#define TUNSETIFF     _IOW('T', 202, int)
14#endif
15
16class netdev_tap : public netdev
17{
18public:
19   netdev_tap(const char *name, class device_network_interface *ifdev, int rate);
20   ~netdev_tap();
21
22   int send(UINT8 *buf, int len);
23   void set_mac(const char *mac);
24protected:
25   int recv_dev(UINT8 **buf);
26private:
27   int m_fd;
28   char m_ifname[10];
29   char m_mac[6];
30   UINT8 m_buf[2048];
31};
32
33netdev_tap::netdev_tap(const char *name, class device_network_interface *ifdev, int rate)
34   : netdev(ifdev, rate)
35{
36#ifdef __linux__
37   struct ifreq ifr;
38
39   m_fd = -1;
40   if((m_fd = open("/dev/net/tun", O_RDWR)) == -1) {
41      osd_printf_verbose("tap: open failed %d\n", errno);
42      return;
43   }
44
45   memset(&ifr, 0, sizeof(ifr));
46   ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
47   sprintf(ifr.ifr_name, "tap-mess-%d-0", getuid());
48   if(ioctl(m_fd, TUNSETIFF, (void *)&ifr) == -1) {
49      osd_printf_verbose("tap: ioctl failed %d\n", errno);
50      close(m_fd);
51      m_fd = -1;
52      return;
53   }
54   osd_printf_verbose("netdev_tap: network up!\n");
55   strncpy(m_ifname, ifr.ifr_name, 10);
56   fcntl(m_fd, F_SETFL, O_NONBLOCK);
57
58#else
59   m_fd = -1;
60#endif
61}
62
63netdev_tap::~netdev_tap()
64{
65   close(m_fd);
66}
67
68void netdev_tap::set_mac(const char *mac)
69{
70   memcpy(m_mac, mac, 6);
71}
72
73int netdev_tap::send(UINT8 *buf, int len)
74{
75   if(m_fd == -1) return 0;
76   len = write(m_fd, buf, len);
77   return (len == -1)?0:len;
78}
79
80int netdev_tap::recv_dev(UINT8 **buf)
81{
82   int len;
83   if(m_fd == -1) return 0;
84   // exit if we didn't receive anything, got an error, got a broadcast or multicast packet,
85   // are in promiscuous mode or got a packet with our mac.
86   do {
87      len = read(m_fd, m_buf, sizeof(m_buf));
88   } while((len > 0) && memcmp(get_mac(), m_buf, 6) && !get_promisc() && !(m_buf[0] & 1));
89   *buf = m_buf;
90   return (len == -1)?0:len;
91}
92
93static CREATE_NETDEV(create_tap)
94{
95   class netdev_tap *dev = global_alloc(netdev_tap(ifname, ifdev, rate));
96   return dynamic_cast<netdev *>(dev);
97}
98
99void init_tap()
100{
101   add_netdev("tap", "TAP/TUN Device", create_tap);
102}
103
104void deinit_tap()
105{
106   clear_netdev();
107}
trunk/src/osd/sdl/netdev_tap.h
r243258r243259
1#ifndef __NETDEV_TAP_H__
2#define __NETDEV_TAP_H__
3
4void init_tap();
5void deinit_tap();
6#endif
trunk/src/osd/sdl/osdsdl.h
r243258r243259
195195   virtual void input_pause();
196196   virtual void input_resume();
197197   virtual bool output_init();
198   #ifdef USE_NETWORK
199   virtual bool network_init();
200   #endif
201198   //virtual bool midi_init();
202199
203200   virtual void video_exit();
204201   virtual void window_exit();
205202   virtual void input_exit();
206203   virtual void output_exit();
207   #ifdef USE_NETWORK
208   virtual void network_exit();
209   #endif
210204   //virtual void midi_exit();
211205
212206   sdl_options &options() { return m_options; }
trunk/src/osd/sdl/sdl.mak
r243258r243259
403403   $(OSDOBJ)/modules/lib \
404404   $(OSDOBJ)/modules/midi \
405405   $(OSDOBJ)/modules/font \
406   $(OSDOBJ)/modules/netdev \
406407
407408#-------------------------------------------------
408409# OSD core library
r243258r243259
445446   $(OSDOBJ)/modules/font/font_windows.o \
446447   $(OSDOBJ)/modules/font/font_osx.o \
447448   $(OSDOBJ)/modules/font/font_none.o \
449   $(OSDOBJ)/modules/netdev/taptun.o \
450   $(OSDOBJ)/modules/netdev/pcap.o \
448451
449452ifdef NO_USE_MIDI
450453   OSDOBJS += $(OSDOBJ)/modules/midi/none.o
r243258r243259
452455   OSDOBJS += $(OSDOBJ)/modules/midi/portmidi.o
453456endif
454457
455ifeq ($(BASE_TARGETOS),win32)
456   OSDOBJS += $(OSDOBJ)/modules/sound/direct_sound.o
457endif
458
459458# Add SDL2.0 support
460459
461460ifeq ($(SDL_LIBVER),sdl2)
r243258r243259
465464# add an ARCH define
466465DEFS += -DSDLMAME_ARCH="$(ARCHOPTS)" -DSYNC_IMPLEMENTATION=$(SYNC_IMPLEMENTATION)
467466
468# Add JavaScript sound module for Emscripten compiles
469
470ifeq ($(TARGETOS),emscripten)
471OSDOBJS += $(OSDOBJ)/modules/sound/js_sound.o
472endif
473
474467#-------------------------------------------------
475468# Generic defines and additions
476469#-------------------------------------------------
r243258r243259
828821# Network (TAP/TUN)
829822#-------------------------------------------------
830823
831OSDOBJS += $(SDLOBJ)/netdev.o
832
833824ifndef DONT_USE_NETWORK
834825
835826ifeq ($(SDL_NETWORK),taptun)
836OSDOBJS += $(SDLOBJ)/netdev_tap.o
837827
838DEFS += -DSDLMAME_NETWORK -DSDLMAME_NET_TAPTUN
828DEFS += -DSDLMAME_NET_TAPTUN
839829endif
840830
841831ifeq ($(SDL_NETWORK),pcap)
842832
843ifeq ($(TARGETOS),macosx)
844OSDOBJS += $(SDLOBJ)/netdev_pcap_osx.o
845else
846OSDOBJS += $(SDLOBJ)/netdev_pcap.o
847endif
833DEFS += -DSDLMAME_NET_PCAP
848834
849DEFS += -DSDLMAME_NETWORK -DSDLMAME_NET_PCAP
835# dynamically linked ...
836#ifneq ($(TARGETOS),win32)
837#LIBS += -lpcap
838#endif
850839
851ifneq ($(TARGETOS),win32)
852LIBS += -lpcap
853endif
854
855840endif # ifeq ($(SDL_NETWORK),pcap)
856841
857842endif # ifndef DONT_USE_NETWORK
trunk/src/osd/windows/netdev.c
r243258r243259
1#include "emu.h"
2#include "winmain.h"
3#include "netdev_pcap.h"
4
5bool windows_osd_interface::network_init()
6{
7   init_pcap();
8   return true;
9}
10
11void windows_osd_interface::network_exit()
12{
13   deinit_pcap();
14}
trunk/src/osd/windows/netdev_pcap.c
r243258r243259
1#define WIN32_LEAN_AND_MEAN
2#include <windows.h>
3#include <pcap.h>
4
5static int (*pcap_compile_dl)(pcap_t *, struct bpf_program *, char *, int, bpf_u_int32) = NULL;
6static int (*pcap_findalldevs_dl)(pcap_if_t **, char *) = NULL;
7static pcap_t *(*pcap_open_live_dl)(const char *name, int, int, int, char *) = NULL;
8static int (*pcap_next_ex_dl)(pcap_t *, struct pcap_pkthdr **, const u_char **) = NULL;
9static void (*pcap_close_dl)(pcap_t *) = NULL;
10static int (*pcap_setfilter_dl)(pcap_t *, struct bpf_program *) = NULL;
11static int (*pcap_sendpacket_dl)(pcap_t *, u_char *, int) = NULL;
12static int (*pcap_set_datalink_dl)(pcap_t *, int) = NULL;
13static HMODULE handle = NULL;
14
15#include "emu.h"
16#include "osdnet.h"
17
18class netdev_pcap : public netdev
19{
20public:
21   netdev_pcap(const char *name, class device_network_interface *ifdev, int rate);
22   ~netdev_pcap();
23
24   int send(UINT8 *buf, int len);
25   void set_mac(const char *mac);
26protected:
27   int recv_dev(UINT8 **buf);
28private:
29   pcap_t *m_p;
30};
31
32netdev_pcap::netdev_pcap(const char *name, class device_network_interface *ifdev, int rate)
33   : netdev(ifdev, rate)
34{
35   char errbuf[PCAP_ERRBUF_SIZE];
36   m_p = pcap_open_live_dl(name, 65535, 1, -1, errbuf);
37   if(!m_p)
38   {
39      logerror("Unable to open %s: %s\n", name, errbuf);
40      return;
41   }
42   if(pcap_set_datalink_dl(m_p, DLT_EN10MB) == -1)
43   {
44      logerror("Unable to set %s to ethernet", name);
45      pcap_close_dl(m_p);
46      m_p = NULL;
47      return;
48   }
49   set_mac(get_mac());
50}
51
52void netdev_pcap::set_mac(const char *mac)
53{
54   char filter[256];
55   struct bpf_program fp;
56   if(!m_p) return;
57   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]);
58   pcap_compile_dl(m_p, &fp, filter, 1, 0);
59   pcap_setfilter_dl(m_p, &fp);
60}
61
62int netdev_pcap::send(UINT8 *buf, int len)
63{
64   if(!m_p) return 0;
65   return (!pcap_sendpacket_dl(m_p, buf, len))?len:0;
66}
67
68int netdev_pcap::recv_dev(UINT8 **buf)
69{
70   struct pcap_pkthdr *header;
71   if(!m_p) return 0;
72   return (pcap_next_ex_dl(m_p, &header, (const u_char **)buf) == 1)?header->len:0;
73}
74
75netdev_pcap::~netdev_pcap()
76{
77   if(m_p && handle) pcap_close_dl(m_p);
78}
79
80static CREATE_NETDEV(create_pcap)
81{
82   class netdev_pcap *dev = global_alloc(netdev_pcap(ifname, ifdev, rate));
83   return dynamic_cast<netdev *>(dev);
84}
85
86void init_pcap()
87{
88   pcap_if_t *devs;
89   char errbuf[PCAP_ERRBUF_SIZE];
90   handle = NULL;
91
92   try
93   {
94      if(!(handle = LoadLibrary(L"wpcap.dll"))) throw GetLastError();
95      if(!(pcap_findalldevs_dl = (int (*)(pcap_if_t **, char *))GetProcAddress(handle, "pcap_findalldevs")))
96         throw GetLastError();
97      if(!(pcap_open_live_dl = (pcap_t* (*)(const char *, int, int, int, char *))GetProcAddress(handle, "pcap_open_live")))
98         throw GetLastError();
99      if(!(pcap_next_ex_dl = (int (*)(pcap_t *, struct pcap_pkthdr **, const u_char **))GetProcAddress(handle, "pcap_next_ex")))
100         throw GetLastError();
101      if(!(pcap_compile_dl = (int (*)(pcap_t *, struct bpf_program *, char *, int, bpf_u_int32))GetProcAddress(handle, "pcap_compile")))
102         throw GetLastError();
103      if(!(pcap_close_dl = (void (*)(pcap_t *))GetProcAddress(handle, "pcap_close")))
104         throw GetLastError();
105      if(!(pcap_setfilter_dl = (int (*)(pcap_t *, struct bpf_program *))GetProcAddress(handle, "pcap_setfilter")))
106         throw GetLastError();
107      if(!(pcap_sendpacket_dl = (int (*)(pcap_t *, u_char *, int))GetProcAddress(handle, "pcap_sendpacket")))
108         throw GetLastError();
109      if(!(pcap_set_datalink_dl = (int (*)(pcap_t *, int))GetProcAddress(handle, "pcap_set_datalink")))
110         throw GetLastError();
111   }
112   catch (DWORD e)
113   {
114      FreeLibrary(handle);
115      osd_printf_verbose("Unable to load winpcap: %lx\n", e);
116      return;
117   }
118   if(pcap_findalldevs_dl(&devs, errbuf) == -1)
119   {
120      FreeLibrary(handle);
121      osd_printf_verbose("Unable to get network devices: %s\n", errbuf);
122      return;
123   }
124
125   while(devs)
126   {
127      add_netdev(devs->name, devs->description, create_pcap);
128      devs = devs->next;
129   }
130}
131
132void deinit_pcap()
133{
134   clear_netdev();
135   FreeLibrary(handle);
136   handle = NULL;
137}
trunk/src/osd/windows/netdev_pcap.h
r243258r243259
1#ifndef __NETDEV_PCAP_H__
2#define __NETDEV_PCAP_H__
3
4void init_pcap();
5void deinit_pcap();
6
7#endif
trunk/src/osd/windows/windows.mak
r243258r243259
9292   $(OSDOBJ)/modules/lib \
9393   $(OSDOBJ)/modules/midi \
9494   $(OSDOBJ)/modules/font \
95   $(OSDOBJ)/modules/netdev \
9596
9697ifdef USE_QTDEBUG
9798OBJDIRS += $(OSDOBJ)/modules/debugger/qt
r243258r243259
387388   $(OSDOBJ)/modules/font/font_windows.o \
388389   $(OSDOBJ)/modules/font/font_osx.o \
389390   $(OSDOBJ)/modules/font/font_none.o \
391   $(OSDOBJ)/modules/netdev/pcap.o \
392   $(OSDOBJ)/modules/netdev/taptun.o \
390393
391394ifdef USE_SDL
392395OSDOBJS += \
r243258r243259
394397endif
395398
396399ifndef DONT_USE_NETWORK
397OSDOBJS += \
398   $(WINOBJ)/netdev.o \
399   $(WINOBJ)/netdev_pcap.o
400DEFS +=   -DSDLMAME_NET_PCAP
400401endif
401402
402403CCOMFLAGS += -DDIRECT3D_VERSION=0x0900
trunk/src/osd/windows/winmain.h
r243258r243259
260260   virtual void input_pause();
261261   virtual void input_resume();
262262   virtual bool output_init();
263   #ifdef USE_NETWORK
264   virtual bool network_init();
265   #endif
266263
267264   virtual void video_exit();
268265   virtual void window_exit();
269266   virtual void input_exit();
270267   virtual void output_exit();
271   #ifdef USE_NETWORK
272   virtual void network_exit();
273   #endif
274268
275269private:
276270   void osd_exit();
trunk/src/osd/windows/winprefix.h
r243258r243259
3131#pragma warning (disable: 5025 5026 5027)
3232#define _CRT_STDIO_LEGACY_WIDE_SPECIFIERS
3333#endif
34#define strtoll _strtoi64
3534#endif
3635
3736#ifdef __GNUC__


Previous 199869 Revisions Next


© 1997-2024 The MAME Team