From 556ec0cf80ad96758f524a2ea1a40019d08272cc Mon Sep 17 00:00:00 2001 From: kanjitalk755 Date: Fri, 5 Feb 2021 22:13:46 +0900 Subject: [PATCH] added port forwarding for Windows --- BasiliskII/src/Unix/configure.ac | 4 - BasiliskII/src/Windows/ether_windows.cpp | 95 ++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 4 deletions(-) diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index 643ce699..e5fb37b0 100755 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -471,10 +471,6 @@ if [[ "x$WANT_GTK" = "xgtk" ]]; then AM_PATH_GTK(1.2.0, [ GUI_CFLAGS="$GTK_CFLAGS" GUI_LIBS="$GTK_LIBS" - dnl somehow, would redefine gettext() to nothing if - dnl ENABLE_NLS is not set, thusly conflicting with C++ which - dnl includes - AM_GNU_GETTEXT B2_PATH_GNOMEUI([ AC_DEFINE(HAVE_GNOMEUI, 1, [Define if libgnomeui is available.]) GUI_CFLAGS="$GUI_CFLAGS $GNOMEUI_CFLAGS" diff --git a/BasiliskII/src/Windows/ether_windows.cpp b/BasiliskII/src/Windows/ether_windows.cpp index aa40a8b8..1f9e245e 100755 --- a/BasiliskII/src/Windows/ether_windows.cpp +++ b/BasiliskII/src/Windows/ether_windows.cpp @@ -42,6 +42,7 @@ // somehow util_windows undefines min #define min(x,y) ((x) < (y) ? (x) : (y)) #include "libslirp.h" +#include "ctl.h" // Define to let the slirp library determine the right timeout for select() #define USE_SLIRP_TIMEOUT 1 @@ -200,6 +201,8 @@ static int16 ether_do_add_multicast(uint8 *addr); static int16 ether_do_del_multicast(uint8 *addr); static int16 ether_do_write(uint32 arg); static void ether_do_interrupt(void); +static void slirp_add_redirs(); +static int slirp_add_redir(const char *redir_str); /* @@ -263,6 +266,7 @@ bool ether_init(void) WarningAlert(GetString(STR_SLIRP_NO_DNS_FOUND_WARN)); return false; } + slirp_add_redirs(); } // Open ethernet device @@ -1640,6 +1644,97 @@ static void ether_do_interrupt(void) } } +// Helper function for port forwarding +static int get_str_sep(char *buf, int buf_size, const char **pp, int sep) +{ + const char *p, *p1; + int len; + p = *pp; + p1 = strchr(p, sep); + if (!p1) + return -1; + len = p1 - p; + p1++; + if (buf_size > 0) { + if (len > buf_size - 1) + len = buf_size - 1; + memcpy(buf, p, len); + buf[len] = '\0'; + } + *pp = p1; + return 0; +} + +// Set up port forwarding for slirp +static void slirp_add_redirs() +{ + int index = 0; + const char *str; + while ((str = PrefsFindString("redir", index++)) != NULL) { + slirp_add_redir(str); + } +} + +// Add a port forward/redirection for slirp +static int slirp_add_redir(const char *redir_str) +{ + // code adapted from qemu source + struct in_addr guest_addr = {0}; + int host_port, guest_port; + const char *p; + char buf[256]; + int is_udp; + char *end; + char str[256]; + + p = redir_str; + if (!p || get_str_sep(buf, sizeof(buf), &p, ':') < 0) { + goto fail_syntax; + } + if (!strcmp(buf, "tcp") || buf[0] == '\0') { + is_udp = 0; + } else if (!strcmp(buf, "udp")) { + is_udp = 1; + } else { + goto fail_syntax; + } + + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { + goto fail_syntax; + } + host_port = strtol(buf, &end, 0); + if (*end != '\0' || host_port < 1 || host_port > 65535) { + goto fail_syntax; + } + + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { + goto fail_syntax; + } + // 0.0.0.0 doesn't seem to work, so default to a client address + // if none is specified + if (buf[0] == '\0' ? + !inet_pton(AF_INET, CTL_LOCAL, &guest_addr) : + !inet_pton(AF_INET, buf, &guest_addr)) { + goto fail_syntax; + } + + guest_port = strtol(p, &end, 0); + if (*end != '\0' || guest_port < 1 || guest_port > 65535) { + goto fail_syntax; + } + + if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) { + sprintf(str, "could not set up host forwarding rule '%s'", redir_str); + WarningAlert(str); + return -1; + } + return 0; + + fail_syntax: + sprintf(str, "invalid host forwarding rule '%s'", redir_str); + WarningAlert(str); + return -1; +} #if DEBUG #pragma optimize("",on) #endif