diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index 962199ad..6e6ab0c7 100644 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -323,6 +323,8 @@ else SDL_SUPPORT="none" fi +LIBS="$CFLAGS -lvdeplug" + dnl We need X11, if not using SDL or Mac GUI. if [[ "x$WANT_SDL_VIDEO" = "xno" -a "x$WANT_MACOSX_GUI" = "xno" ]]; then AC_PATH_XTRA diff --git a/BasiliskII/src/Unix/ether_unix.cpp b/BasiliskII/src/Unix/ether_unix.cpp index a9ca33ce..aff82e4e 100644 --- a/BasiliskII/src/Unix/ether_unix.cpp +++ b/BasiliskII/src/Unix/ether_unix.cpp @@ -20,6 +20,9 @@ #include "sysdeps.h" +extern "C" { +#include +} /* * NOTES concerning MacOS X issues: * - poll() does not exist in 10.2.8, but is available in 10.4.4 @@ -93,7 +96,8 @@ enum { NET_IF_SHEEPNET, NET_IF_ETHERTAP, NET_IF_TUNTAP, - NET_IF_SLIRP + NET_IF_SLIRP, + NET_IF_VDE }; // Constants @@ -115,6 +119,7 @@ static pthread_t slirp_thread; // Slirp reception thread static bool slirp_thread_active = false; // Flag: Slirp reception threadinstalled static int slirp_output_fd = -1; // fd of slirp output pipe static int slirp_input_fds[2] = { -1, -1 }; // fds of slirp input pipe +static VDECONN *vde_conn; #ifdef SHEEPSHAVER static bool net_open = false; // Flag: initialization succeeded, network device open static uint8 ether_addr[6]; // Our Ethernet address @@ -240,18 +245,30 @@ bool ether_init(void) // Determine Ethernet device type net_if_type = -1; - if (strncmp(name, "tap", 3) == 0) + if (strncmp(name, "tap", 3) == 0) { net_if_type = NET_IF_ETHERTAP; + printf("selected Ethernet device type tap\n"); + } #if ENABLE_TUNTAP - else if (strcmp(name, "tun") == 0) + else if (strcmp(name, "tun") == 0) { net_if_type = NET_IF_TUNTAP; + printf("selected Ethernet device type tun\n"); + } #endif #ifdef HAVE_SLIRP - else if (strcmp(name, "slirp") == 0) + else if (strcmp(name, "slirp") == 0) { net_if_type = NET_IF_SLIRP; + printf("selected Ethernet device type slirp\n"); + } #endif - else + else if (strcmp(name, "vde") == 0) { + net_if_type = NET_IF_VDE; + printf("selected Ethernet device type VDE\n"); + } + else { net_if_type = NET_IF_SHEEPNET; + printf("selected Ethernet device type sheep_net\n"); + } // Don't raise SIGPIPE, let errno be set to EPIPE struct sigaction sigpipe_sa; @@ -301,7 +318,33 @@ bool ether_init(void) strcpy(dev_name, "/dev/sheep_net"); break; } - if (net_if_type != NET_IF_SLIRP) { + + //vde switch information + int port = 0; + char *init_group = NULL; + mode_t mode = 0700; + + struct vde_open_args args = { + .port = port, + .group = init_group, + .mode = mode, + }; + + if (net_if_type == NET_IF_VDE) { + /* calling vde open to open the vde connection to the vde switch */ + vde_conn = vde_open(vde_sock, (char *)"macemu", &args); + + if (!vde_conn) { + D(bug("VDE open failed\n")); + return -1; + } else { + /* for select/poll when this fd receive data, there are + * packets to recv(call vde_recv) */ + fd = vde_datafd(vde_conn); + } + } + + if (net_if_type != NET_IF_SLIRP && net_if_type != NET_IF_VDE) { fd = open(dev_name, O_RDWR); if (fd < 0) { sprintf(str, GetString(STR_NO_SHEEP_NET_DRIVER_WARN), dev_name, strerror(errno)); @@ -388,6 +431,13 @@ bool ether_init(void) ether_addr[4] = 0x34; ether_addr[5] = 0x56; #endif + } else if (net_if_type == NET_IF_VDE) { + ether_addr[0] = 0x52; + ether_addr[1] = 0x54; + ether_addr[2] = 0x00; + ether_addr[3] = 0x12; + ether_addr[4] = 0x34; + ether_addr[5] = 0x56; } else ioctl(fd, SIOCGIFADDR, ether_addr); D(bug("Ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); @@ -453,6 +503,9 @@ void ether_exit(void) if (slirp_output_fd > 0) close(slirp_output_fd); + // Close vde_connection + if (net_if_type == NET_IF_VDE) + vde_close(vde_conn); #if STATISTICS // Show statistics printf("%ld messages put on write queue\n", num_wput); @@ -751,7 +804,24 @@ static int16 ether_do_write(uint32 arg) return noErr; } else #endif - if (write(fd, packet, len) < 0) { + if (net_if_type == NET_IF_VDE) { + if (fd == -1) { // which means vde service is not running + D(bug("WARNING: Couldn't transmit VDE packet\n")); + return excessCollsns; + } + + if (vde_conn == NULL) { + D(bug("WARNING: vde_conn is NULL\n")); + return -1; + } + + do { + len = vde_send(vde_conn, packet, sizeof(packet), 0); + } while (len < 0); + + return noErr; + } + else if (write(fd, packet, len) < 0) { D(bug("WARNING: Couldn't transmit packet\n")); return excessCollsns; } else @@ -925,13 +995,17 @@ void ether_do_interrupt(void) } else #endif { - - // Read packet from sheep_net device + if (net_if_type == NET_IF_VDE) { + length = vde_recv(vde_conn, Mac2HostAddr(packet), 1514, 0); + } else { + // Read packet from sheep_net device #if defined(__linux__) - length = read(fd, Mac2HostAddr(packet), net_if_type == NET_IF_ETHERTAP ? 1516 : 1514); + length = read(fd, Mac2HostAddr(packet), net_if_type == NET_IF_ETHERTAP ? 1516 : 1514); #else - length = read(fd, Mac2HostAddr(packet), 1514); + length = read(fd, Mac2HostAddr(packet), 1514); #endif + } + if (length < 14) break; diff --git a/BasiliskII/src/Unix/main_unix.cpp b/BasiliskII/src/Unix/main_unix.cpp index c4f975a3..0a888ccd 100644 --- a/BasiliskII/src/Unix/main_unix.cpp +++ b/BasiliskII/src/Unix/main_unix.cpp @@ -207,6 +207,8 @@ static void sigill_handler(int sig, int code, struct sigcontext *scp); extern "C" void EmulOpTrampoline(void); #endif +// vde switch variable +char* vde_sock; /* * Ersatz functions @@ -374,7 +376,8 @@ static void usage(const char *prg_name) " --display STRING\n X display to use\n" " --break ADDRESS\n set ROM breakpoint in hexadecimal\n" " --loadbreak FILE\n load breakpoint from FILE\n" - " --rominfo\n dump ROM information\n", prg_name + " --rominfo\n dump ROM information\n" + " --switch SWITCH_PATH\n vde_switch address\n", prg_name ); LoadPrefs(NULL); // read the prefs file so PrefsPrintUsage() will print the correct default values PrefsPrintUsage(); @@ -436,6 +439,14 @@ int main(int argc, char **argv) } else if (strcmp(argv[i], "--rominfo") == 0) { argv[i] = NULL; PrintROMInfo = true; + } else if (strcmp(argv[i], "--switch") == 0) { + argv[i] = NULL; + if (argv[++i] == NULL) { + printf("switch address not defined\n"); + usage(argv[0]); + } + vde_sock = argv[i]; + argv[i] = NULL; } } diff --git a/BasiliskII/src/include/main.h b/BasiliskII/src/include/main.h index 1ba7b6ac..cfe9730f 100644 --- a/BasiliskII/src/include/main.h +++ b/BasiliskII/src/include/main.h @@ -74,6 +74,9 @@ extern uint32 InterruptFlags; // Currently pending interrupts extern void SetInterruptFlag(uint32 flag); // Set/clear interrupt flags extern void ClearInterruptFlag(uint32 flag); +// vde switch variable +extern char* vde_sock; + // Array length #if __cplusplus >= 201103L || (_MSC_VER >= 1900 && defined __cplusplus) template