]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
refactored slirp to make it possible to use an alternative implementation
authorFrode Solheim <frode@fs-uae.net>
Sat, 5 Sep 2015 10:24:46 +0000 (12:24 +0200)
committerFrode Solheim <frode@fs-uae.net>
Sat, 5 Sep 2015 12:55:57 +0000 (05:55 -0700)
ethernet.cpp
include/ethernet.h
include/uae/slirp.h [new file with mode: 0644]
od-win32/sysconfig.h
od-win32/win32_uaenet.cpp
od-win32/winuae_msvc14/winuae_msvc.vcxproj
od-win32/winuae_msvc14/winuae_msvc.vcxproj.filters
slirp_uae.cpp [new file with mode: 0644]

index 5f2a7696976e070661953444db4cd4394be668e9..43c09989a33ffa637c12af3cfcdc42f91a266355 100644 (file)
@@ -1,15 +1,25 @@
+#include "sysconfig.h"
+#include "sysdeps.h"
 
-#include "slirp/slirp.h"
-#include "slirp/libslirp.h"
-
+#include "ethernet.h"
 #ifdef _WIN32
 #include "win32_uaenet.h"
-#else
-#include "ethernet.h"
 #endif
 #include "threaddep/thread.h"
 #include "options.h"
 #include "sana2.h"
+#include "uae/slirp.h"
+
+#ifndef HAVE_INET_ATON
+static int inet_aton(const char *cp, struct in_addr *ia)
+{
+       uint32_t addr = inet_addr(cp);
+       if (addr == 0xffffffff)
+               return 0;
+       ia->s_addr = addr;
+       return 1;
+}
+#endif
 
 struct ethernet_data
 {
@@ -44,12 +54,7 @@ static struct netdriverdata slirpd2 =
        1
 };
 
-int slirp_can_output(void)
-{
-       return 1;
-}
-
-void slirp_output (const uint8 *pkt, int pkt_len)
+void slirp_output (const uint8_t *pkt, int pkt_len)
 {
        if (!slirp_data)
                return;
@@ -77,7 +82,7 @@ void ethernet_trigger (struct netdriverdata *ndd, void *vsd)
                                uae_sem_post (&slirp_sem1);
                                if (v) {
                                        uae_sem_wait (&slirp_sem2);
-                                       slirp_input(pkt, len);
+                                       uae_slirp_input(pkt, len);
                                        uae_sem_post (&slirp_sem2);
                                }
                        }
@@ -105,21 +110,21 @@ int ethernet_open (struct netdriverdata *ndd, void *vsd, void *user, ethernet_go
                        slirp_data = ed;
                        uae_sem_init (&slirp_sem1, 0, 1);
                        uae_sem_init (&slirp_sem2, 0, 1);
-                       slirp_init ();
+                       uae_slirp_init();
                        for (int i = 0; i < MAX_SLIRP_REDIRS; i++) {
                                struct slirp_redir *sr = &currprefs.slirp_redirs[i];
                                if (sr->proto) {
                                        struct in_addr a;
                                        if (sr->srcport == 0) {
                                            inet_aton("10.0.2.15", &a);
-                                               slirp_redir (0, sr->dstport, a, sr->dstport);
+                                               uae_slirp_redir (0, sr->dstport, a, sr->dstport);
                                        } else {
 #ifdef HAVE_STRUCT_IN_ADDR_S_UN
                                                a.S_un.S_addr = sr->addr;
 #else
                                                a.s_addr = sr->addr;
 #endif
-                                               slirp_redir (sr->proto == 1 ? 0 : 1, sr->dstport, a, sr->srcport);
+                                               uae_slirp_redir (sr->proto == 1 ? 0 : 1, sr->dstport, a, sr->srcport);
                                        }
                                }
                        }
@@ -135,11 +140,11 @@ int ethernet_open (struct netdriverdata *ndd, void *vsd, void *user, ethernet_go
                                                        break;
                                        }
                                        if (j == MAX_SLIRP_REDIRS)
-                                               slirp_redir (0, port + SLIRP_PORT_OFFSET, a, port);
+                                               uae_slirp_redir (0, port + SLIRP_PORT_OFFSET, a, port);
                                }
                        }
                        netmode = ndd->type;
-                       slirp_start ();
+                       uae_slirp_start ();
                }
                return 1;
 #ifdef WITH_UAENET_PCAP
@@ -164,8 +169,8 @@ void ethernet_close (struct netdriverdata *ndd, void *vsd)
                case UAENET_SLIRP_INBOUND:
                if (slirp_data) {
                        slirp_data = NULL;
-                       slirp_end ();
-                       slirp_cleanup ();
+                       uae_slirp_end ();
+                       uae_slirp_cleanup ();
                        uae_sem_destroy (&slirp_sem1);
                        uae_sem_destroy (&slirp_sem2);
                }
index 77465ef7fdb9fd6a64aebab627ede69cb15bc443..c1585d0227e372e964ba8057be61ca496f492283 100644 (file)
@@ -1,5 +1,7 @@
-#ifndef _UAE_ETHERNET_H_
-#define _UAE_ETHERNET_H_
+#ifndef UAE_ETHERNET_H
+#define UAE_ETHERNET_H
+
+#include "uae/types.h"
 
 #define UAENET_NONE 0
 #define UAENET_SLIRP 1
@@ -28,11 +30,6 @@ extern int ethernet_getdatalenght (struct netdriverdata *ndd);
 extern int ethernet_getbytespending (void*);
 extern int ethernet_open (struct netdriverdata *ndd, void*, void*, ethernet_gotfunc*, ethernet_getfunc*, int);
 extern void ethernet_close (struct netdriverdata *ndd, void*);
-extern void ethernet_gotdata (struct s2devstruct *dev, const uae_u8 *data, int len);
-extern int ethernet_getdata (struct s2devstruct *dev, uae_u8 *d, int *len);
 extern void ethernet_trigger (struct netdriverdata *ndd, void*);
 
-extern bool slirp_start (void);
-extern void slirp_end (void);
-
-#endif // _UAE_ETHERNET_H_
+#endif /* UAE_ETHERNET_H */
diff --git a/include/uae/slirp.h b/include/uae/slirp.h
new file mode 100644 (file)
index 0000000..bf04038
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef UAE_SLIRP_H
+#define UAE_SLIRP_H
+
+#include "uae/types.h"
+
+#ifdef _WIN32
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+
+int uae_slirp_init(void);
+void uae_slirp_cleanup(void);
+int uae_slirp_redir(int is_udp, int host_port, struct in_addr guest_addr,
+                                       int guest_port);
+bool uae_slirp_start (void);
+void uae_slirp_end (void);
+void uae_slirp_input(const uint8_t *pkt, int pkt_len);
+
+void slirp_output(const uint8_t *pkt, int pkt_len);
+
+#endif /* UAE_SLIRP_H */
index 8e66204b7ffdaefcb72cb57515fc11ef28f80e0b..fd8adea81a35166abc3ba115ef882e1dd4a46218 100644 (file)
@@ -92,6 +92,7 @@
 #define WITH_LUA /* lua scripting */
 #define WITH_UAENATIVE
 #define WITH_SLIRP
+#define WITH_BUILTIN_SLIRP
 #define WITH_TABLETLIBRARY
 #define WITH_UAENET_PCAP
 #define WITH_PPC
index 2f528a545120b0ef48b44812278c6334b49166e7..e976265693eb6e86f1c558291f41903999d6331d 100644 (file)
@@ -6,7 +6,11 @@
 * Copyright 2007 Toni Wilen
 */
 
-#include "slirp/slirp.h"
+#include "sysconfig.h"
+
+#ifdef WITH_SLIRP
+#include "../slirp/slirp.h"
+#endif
 
 #include <stdio.h>
 
@@ -432,66 +436,3 @@ void uaenet_close_driver (struct netdriverdata *tc)
                tc[i].active = 0;
        }
 }
-
-
-static volatile int slirp_thread_active;
-static HANDLE slirp_thread;
-static uae_thread_id slirp_tid;
-extern uae_sem_t slirp_sem2;
-
-static void *slirp_receive_func(void *arg)
-{
-       slirp_thread_active = 1;
-       while (slirp_thread_active) {
-               // Wait for packets to arrive
-               fd_set rfds, wfds, xfds;
-               SOCKET nfds;
-               int ret, timeout;
-
-               // ... in the output queue
-               nfds = -1;
-               FD_ZERO(&rfds);
-               FD_ZERO(&wfds);
-               FD_ZERO(&xfds);
-               uae_sem_wait (&slirp_sem2);
-               timeout = slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
-               uae_sem_post (&slirp_sem2);
-               if (nfds < 0) {
-                       /* Windows does not honour the timeout if there is not
-                          descriptor to wait for */
-                       sleep_millis (timeout / 1000);
-                       ret = 0;
-               }
-               else {
-                       struct timeval tv;
-                       tv.tv_sec = 0;
-                       tv.tv_usec = timeout;
-                       ret = select(0, &rfds, &wfds, &xfds, &tv);
-               }
-               if (ret >= 0) {
-                       uae_sem_wait (&slirp_sem2);
-                       slirp_select_poll(&rfds, &wfds, &xfds);
-                       uae_sem_post (&slirp_sem2);
-               }
-       }
-       slirp_thread_active = -1;
-       return 0;
-}
-
-bool slirp_start (void)
-{
-       slirp_end ();
-       uae_start_thread_fast (slirp_receive_func, NULL, &slirp_tid);
-       return true;
-}
-void slirp_end (void)
-{
-       if (slirp_thread_active > 0) {
-               slirp_thread_active = 0;
-               while (slirp_thread_active == 0) {
-                       sleep_millis (10);
-               }
-               uae_end_thread (&slirp_tid);
-       }
-       slirp_thread_active = 0;
-}
index 5a5b09fc5e8546f4d39a17520115492d2649c467..062320d0ec950e9892124e8e9f22ac10689bca33 100644 (file)
     <ClCompile Include="..\..\slirp\tcp_timer.cpp" />
     <ClCompile Include="..\..\slirp\tftp.cpp" />
     <ClCompile Include="..\..\slirp\udp.cpp" />
+    <ClCompile Include="..\..\slirp_uae.cpp" />
     <ClCompile Include="..\..\sndboard.cpp" />
     <ClCompile Include="..\..\specialmonitors.cpp" />
     <ClCompile Include="..\..\statusline.cpp" />
index b8d17d91407548f86864b752eed95d451894f652..ae07b2357869cf35224fd13d20a5a9497c85e618 100644 (file)
     <ClCompile Include="..\..\fake86_cpu.cpp">
       <Filter>x86</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\slirp_uae.cpp">
+      <Filter>slirp</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\resources\35floppy.ico">
diff --git a/slirp_uae.cpp b/slirp_uae.cpp
new file mode 100644 (file)
index 0000000..7097c92
--- /dev/null
@@ -0,0 +1,226 @@
+#include "sysconfig.h"
+#ifdef _WIN32
+#include "Winsock2.h"
+#endif
+#include "sysdeps.h"
+
+#ifdef WITH_SLIRP
+
+#include "options.h"
+#include "uae/slirp.h"
+#include "uae.h"
+
+#ifdef WITH_BUILTIN_SLIRP
+#include "slirp/slirp.h"
+#include "slirp/libslirp.h"
+#include "threaddep/thread.h"
+#endif
+
+#ifdef WITH_QEMU_SLIRP
+#include "uae/dlopen.h"
+#include "uae/ppc.h"
+#include "uae/qemu.h"
+#endif
+
+/* Implementation enumeration must correspond to slirp_implementations in
+ * cfgfile.cpp. */
+enum Implementation {
+       AUTO_IMPLEMENTATION = 0,
+       NO_IMPLEMENTATION,
+       BUILTIN_IMPLEMENTATION,
+       QEMU_IMPLEMENTATION,
+};
+
+static Implementation impl;
+
+static Implementation check_conf(Implementation check)
+{
+       int conf = AUTO_IMPLEMENTATION;
+       if (conf == AUTO_IMPLEMENTATION || conf == check) {
+               return check;
+       }
+       return AUTO_IMPLEMENTATION;
+}
+
+int uae_slirp_init(void)
+{
+#if defined(WITH_QEMU_SLIRP)
+       if (impl == AUTO_IMPLEMENTATION) {
+               impl = check_conf(QEMU_IMPLEMENTATION);
+       }
+#endif
+#if defined(WITH_BUILTIN_SLIRP)
+       if (impl == AUTO_IMPLEMENTATION) {
+               impl = check_conf(BUILTIN_IMPLEMENTATION);
+       }
+#endif
+       if (impl == AUTO_IMPLEMENTATION) {
+               impl = NO_IMPLEMENTATION;
+       }
+
+#ifdef WITH_QEMU_SLIRP
+       if (impl == QEMU_IMPLEMENTATION) {
+               return uae_qemu_uae_init() == NULL;
+       }
+#endif
+#ifdef WITH_BUILTIN_SLIRP
+       if (impl == BUILTIN_IMPLEMENTATION) {
+               return slirp_init();
+       }
+#endif
+       return -1;
+}
+
+void uae_slirp_cleanup(void)
+{
+#ifdef WITH_QEMU_SLIRP
+       if (impl == QEMU_IMPLEMENTATION) {
+               UAE_LOG_STUB("");
+               return;
+       }
+#endif
+#ifdef WITH_BUILTIN_SLIRP
+       if (impl == BUILTIN_IMPLEMENTATION) {
+               slirp_cleanup();
+               return;
+       }
+#endif
+}
+
+void uae_slirp_input(const uint8_t *pkt, int pkt_len)
+{
+#ifdef WITH_QEMU_SLIRP
+       if (impl == QEMU_IMPLEMENTATION) {
+               if (qemu_uae_slirp_input) {
+                       qemu_uae_slirp_input(pkt, pkt_len);
+               }
+               return;
+       }
+#endif
+#ifdef WITH_BUILTIN_SLIRP
+       if (impl == BUILTIN_IMPLEMENTATION) {
+               slirp_input(pkt, pkt_len);
+               return;
+       }
+#endif
+}
+
+void uae_slirp_output(const uint8_t *pkt, int pkt_len)
+{
+#if 0
+       write_log(_T("uae_slirp_output pkt_len %d\n"), pkt_len);
+#endif
+       slirp_output(pkt, pkt_len);
+}
+
+int uae_slirp_redir(int is_udp, int host_port, struct in_addr guest_addr,
+                   int guest_port)
+{
+#ifdef WITH_QEMU_SLIRP
+       if (impl == QEMU_IMPLEMENTATION) {
+               UAE_LOG_STUB("");
+               return 0;
+       }
+#endif
+#ifdef WITH_BUILTIN_SLIRP
+       if (impl == BUILTIN_IMPLEMENTATION) {
+               return slirp_redir(is_udp, host_port, guest_addr, guest_port);
+       }
+#endif
+       return 0;
+}
+
+#ifdef WITH_BUILTIN_SLIRP
+
+static volatile int slirp_thread_active;
+static uae_thread_id slirp_tid;
+extern uae_sem_t slirp_sem2;
+
+static void *slirp_receive_func(void *arg)
+{
+       slirp_thread_active = 1;
+       while (slirp_thread_active) {
+               // Wait for packets to arrive
+               fd_set rfds, wfds, xfds;
+               SOCKET nfds;
+               int ret, timeout;
+
+               // ... in the output queue
+               nfds = -1;
+               FD_ZERO(&rfds);
+               FD_ZERO(&wfds);
+               FD_ZERO(&xfds);
+               uae_sem_wait (&slirp_sem2);
+               timeout = slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
+               uae_sem_post (&slirp_sem2);
+               if (nfds < 0) {
+                       /* Windows does not honour the timeout if there is not
+                          descriptor to wait for */
+                       sleep_millis (timeout / 1000);
+                       ret = 0;
+               } else {
+                       struct timeval tv;
+                       tv.tv_sec = 0;
+                       tv.tv_usec = timeout;
+                       ret = select(0, &rfds, &wfds, &xfds, &tv);
+               }
+               if (ret >= 0) {
+                       uae_sem_wait (&slirp_sem2);
+                       slirp_select_poll(&rfds, &wfds, &xfds);
+                       uae_sem_post (&slirp_sem2);
+               }
+       }
+       slirp_thread_active = -1;
+       return 0;
+}
+
+int slirp_can_output(void)
+{
+       return 1;
+}
+
+#endif
+
+bool uae_slirp_start (void)
+{
+#ifdef WITH_QEMU_SLIRP
+       if (impl == QEMU_IMPLEMENTATION) {
+               UAE_LOG_STUB("");
+               return true;
+       }
+#endif
+#ifdef WITH_BUILTIN_SLIRP
+       if (impl == BUILTIN_IMPLEMENTATION) {
+               uae_slirp_end ();
+               uae_start_thread(_T("slirp-receive"), slirp_receive_func, NULL,
+                                                &slirp_tid);
+               return true;
+       }
+#endif
+       return false;
+}
+
+void uae_slirp_end (void)
+{
+#ifdef WITH_QEMU_SLIRP
+       if (impl == QEMU_IMPLEMENTATION) {
+               UAE_LOG_STUB("");
+               return;
+       }
+#endif
+#ifdef WITH_BUILTIN_SLIRP
+       if (impl == BUILTIN_IMPLEMENTATION) {
+               if (slirp_thread_active > 0) {
+                       slirp_thread_active = 0;
+                       while (slirp_thread_active == 0) {
+                               sleep_millis (10);
+                       }
+                       uae_end_thread (&slirp_tid);
+               }
+               slirp_thread_active = 0;
+               return;
+       }
+#endif
+}
+
+#endif /* WITH_SLIRP */