From fd0be74ab47456c9c7f3932885d78cc26df3ad52 Mon Sep 17 00:00:00 2001 From: "R. Belmont" Date: Mon, 31 Oct 2011 01:30:24 +0000 Subject: [PATCH] SDL: Add TAP/TUN networking capability and shell script for configuration [Carl] --- .gitattributes | 5 +++ makefile | 6 ++- src/osd/sdl/netdev.c | 7 +++ src/osd/sdl/netdev.h | 6 +++ src/osd/sdl/netdev_tap.c | 97 ++++++++++++++++++++++++++++++++++++++++ src/osd/sdl/netdev_tap.h | 6 +++ src/osd/sdl/sdl.mak | 15 +++++++ src/osd/sdl/sdlmain.c | 7 ++- src/osd/sdl/taputil.sh | 42 +++++++++++++++++ 9 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 src/osd/sdl/netdev.c create mode 100644 src/osd/sdl/netdev.h create mode 100644 src/osd/sdl/netdev_tap.c create mode 100644 src/osd/sdl/netdev_tap.h create mode 100644 src/osd/sdl/taputil.sh diff --git a/.gitattributes b/.gitattributes index fe78be61998..bcd9ac8eaae 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4908,6 +4908,10 @@ src/osd/sdl/man/ldverify.1 svneol=native#text/plain src/osd/sdl/man/mame.1 svneol=native#text/plain src/osd/sdl/man/romcmp.1 svneol=native#text/plain src/osd/sdl/man/testkeys.1 svneol=native#text/plain +src/osd/sdl/netdev.c svneol=native#text/plain +src/osd/sdl/netdev.h svneol=native#text/plain +src/osd/sdl/netdev_tap.c svneol=native#text/plain +src/osd/sdl/netdev_tap.h svneol=native#text/plain src/osd/sdl/osd_opengl.h svneol=native#text/plain src/osd/sdl/osdsdl.h svneol=native#text/plain src/osd/sdl/osinline.h svneol=native#text/plain @@ -4962,6 +4966,7 @@ src/osd/sdl/shader/glsl_plain_rgb32_lut.fsh.c svneol=native#text/plain src/osd/sdl/sound.c svneol=native#text/plain src/osd/sdl/strconv.c svneol=native#text/plain src/osd/sdl/strconv.h svneol=native#text/plain +src/osd/sdl/taputil.sh svneol=native#text/plain src/osd/sdl/testkeys.c svneol=native#text/plain src/osd/sdl/texcopy.c svneol=native#text/plain src/osd/sdl/texsrc.h svneol=native#text/plain diff --git a/makefile b/makefile index d8e415f1e89..b8f45afa3ae 100644 --- a/makefile +++ b/makefile @@ -75,7 +75,7 @@ else UNAME = $(shell uname -a) ifeq ($(firstword $(filter Linux,$(UNAME))),Linux) -TARGETOS = unix +TARGETOS = linux endif ifeq ($(firstword $(filter Solaris,$(UNAME))),Solaris) TARGETOS = solaris @@ -405,6 +405,10 @@ ifdef PROFILER DEFS += -DMAME_PROFILER endif +# define USE_NETWORK if we are a making network enabled build +ifdef USE_NETWORK +DEFS += -DUSE_NETWORK +endif #------------------------------------------------- diff --git a/src/osd/sdl/netdev.c b/src/osd/sdl/netdev.c new file mode 100644 index 00000000000..ff54bb02011 --- /dev/null +++ b/src/osd/sdl/netdev.c @@ -0,0 +1,7 @@ +#include "emu.h" +#include "netdev_tap.h" + +void sdlnetdev_init(running_machine &machine) +{ + init_tap(); +} diff --git a/src/osd/sdl/netdev.h b/src/osd/sdl/netdev.h new file mode 100644 index 00000000000..993d6f1bb44 --- /dev/null +++ b/src/osd/sdl/netdev.h @@ -0,0 +1,6 @@ +#ifndef __NETDEV_H +#define __NETDEV_H + +void sdlnetdev_init(running_machine &machine); + +#endif diff --git a/src/osd/sdl/netdev_tap.c b/src/osd/sdl/netdev_tap.c new file mode 100644 index 00000000000..3cc9a53458f --- /dev/null +++ b/src/osd/sdl/netdev_tap.c @@ -0,0 +1,97 @@ +#include +#include +#include +#include +#include + +#include "emu.h" +#include "osdnet.h" + +#ifdef __linux__ +#define IFF_TAP 0x0002 +#define IFF_NO_PI 0x1000 +#define TUNSETIFF _IOW('T', 202, int) +#endif + +class netdev_tap : public netdev +{ +public: + netdev_tap(const char *name, class device_network_interface *ifdev, int rate); + ~netdev_tap(); + + int send(UINT8 *buf, int len); + void set_mac(const char *mac); +protected: + int recv_dev(UINT8 **buf); +private: + int m_fd; + char m_ifname[10]; + char m_mac[6]; + UINT8 m_buf[2048]; +}; + +netdev_tap::netdev_tap(const char *name, class device_network_interface *ifdev, int rate) + : netdev(ifdev, rate) +{ +#ifdef __linux__ + struct ifreq ifr; + + m_fd = -1; + if((m_fd = open("/dev/net/tun", O_RDWR)) == -1) { + logerror("tap: open failed %d\n", errno); + return; + } + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + sprintf(ifr.ifr_name, "tap-mess-%d-0", getuid()); + if(ioctl(m_fd, TUNSETIFF, (void *)&ifr) == -1) { + logerror("tap: ioctl failed %d\n", errno); + close(m_fd); + m_fd = -1; + return; + } + strncpy(m_ifname, ifr.ifr_name, 10); + fcntl(m_fd, F_SETFL, O_NONBLOCK); + +#else + m_fd = -1; +#endif +} + +netdev_tap::~netdev_tap() +{ + close(m_fd); +} + +void netdev_tap::set_mac(const char *mac) +{ + memcpy(m_mac, mac, 6); +} + +int netdev_tap::send(UINT8 *buf, int len) +{ + if(m_fd == -1) return 0; + len = write(m_fd, buf, len); + return (len == -1)?0:len; +} + +int netdev_tap::recv_dev(UINT8 **buf) +{ + int len; + if(m_fd == -1) return 0; + len = read(m_fd, m_buf, sizeof(m_buf)); + *buf = m_buf; + return (len == -1)?0:len; +} + +static CREATE_NETDEV(create_tap) +{ + class netdev_tap *dev = new netdev_tap(ifname, ifdev, rate); + return dynamic_cast(dev); +} + +void init_tap() +{ + add_netdev("tap", create_tap); +} diff --git a/src/osd/sdl/netdev_tap.h b/src/osd/sdl/netdev_tap.h new file mode 100644 index 00000000000..aab8742f209 --- /dev/null +++ b/src/osd/sdl/netdev_tap.h @@ -0,0 +1,6 @@ +#ifndef __NETDEV_H +#define __NETDEV_H + +void init_tap(); + +#endif diff --git a/src/osd/sdl/sdl.mak b/src/osd/sdl/sdl.mak index 0cf9af2a8b9..6659f66ec9b 100644 --- a/src/osd/sdl/sdl.mak +++ b/src/osd/sdl/sdl.mak @@ -134,6 +134,7 @@ endif ifeq ($(TARGETOS),linux) BASE_TARGETOS = unix SYNC_IMPLEMENTATION = tc +SDL_NETWORK = on endif ifeq ($(TARGETOS),freebsd) @@ -496,6 +497,20 @@ LIBS += -L/usr/X11/lib -L/usr/X11R6/lib -L/usr/openwin/lib INCPATH += -I/usr/X11/include -I/usr/X11R6/include -I/usr/openwin/include endif # NO_X11 +#------------------------------------------------- +# Network (TAP/TUN) +#------------------------------------------------- + +ifdef USE_NETWORK +ifeq ($(SDL_NETWORK),on) +OSDOBJS += \ + $(SDLOBJ)/netdev.o \ + $(SDLOBJ)/netdev_tap.o + +DEFS += -DSDLMAME_NETWORK +endif +endif + #------------------------------------------------- # Dependencies #------------------------------------------------- diff --git a/src/osd/sdl/sdlmain.c b/src/osd/sdl/sdlmain.c index 97075e47b07..7d5b708c222 100644 --- a/src/osd/sdl/sdlmain.c +++ b/src/osd/sdl/sdlmain.c @@ -44,6 +44,7 @@ #include "output.h" #include "osdsdl.h" #include "sdlos.h" +#include "netdev.h" // we override SDL's normal startup on Win32 // please see sdlprefix.h as well @@ -646,11 +647,13 @@ void sdl_osd_interface::init(running_machine &machine) } sdlinput_init(machine); - sdlaudio_init(machine); - sdloutput_init(machine); +#ifdef SDLMAME_NETWORK + sdlnetdev_init(machine); +#endif + if (options.oslog()) machine.add_logerror_callback(output_oslog); diff --git a/src/osd/sdl/taputil.sh b/src/osd/sdl/taputil.sh new file mode 100644 index 00000000000..afc6cbd6665 --- /dev/null +++ b/src/osd/sdl/taputil.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +NAME=$2 +UID=`id -u $NAME` +HOSTIP=$4 +EMUIP=$3 +TAP="tap-mess-$UID-0" + +if [ `id -u` != "0" ] +then +echo "must be run as root" +exit +fi + +if [ "$1" = "-d" ] +then +echo 0 > /proc/sys/net/ipv4/ip_forward +echo 0 > /proc/sys/net/ipv4/conf/all/proxy_arp +chmod 660 /dev/net/tun +ip tuntap del dev $TAP mode tap +exit +fi + +if [ "$#" != "5" ] +then +echo "usage: mess-tap [-c] [-d] USER EMUADDR HOSTADDR MASK\n" +echo "-c\t\tcreate interface" +echo "-d\t\tdelete interface" +echo "USER\t\tuser to own interface, required to delete" +echo "EMUADDR\temulated machine ip address" +echo "HOSTADDR\thost ip address" +exit +fi + +echo 1 > /proc/sys/net/ipv4/ip_forward +echo 1 > /proc/sys/net/ipv4/conf/all/proxy_arp +chmod 666 /dev/net/tun + +ip tuntap add dev $TAP mode tap user $NAME pi +ip link set $TAP up arp on +ip addr replace dev $TAP $HOSTIP/32 +ip route replace $EMUIP via $HOSTIP dev $TAP