mirror of
https://github.com/LIV2/WinUAE.git
synced 2025-12-06 00:12:52 +00:00
230 lines
4.3 KiB
C++
230 lines
4.3 KiB
C++
|
|
#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;
|
|
int 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 == SOCKET_ERROR) {
|
|
write_log(_T("SLIRP socket ERR=%d\n"), WSAGetLastError());
|
|
}
|
|
}
|
|
if (ret >= 0) {
|
|
uae_sem_wait (&slirp_sem2);
|
|
slirp_select_poll(&rfds, &wfds, &xfds);
|
|
uae_sem_post (&slirp_sem2);
|
|
}
|
|
}
|
|
slirp_thread_active = -1;
|
|
}
|
|
|
|
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 */
|