mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-09-16 13:55:59 +00:00
Recognize Intel Compilers. Add user mode network stack with slirp from qemu.
Simply use "ether slirp" in the prefs file, no kernel module required. I could perform up to 450 KB/sec on my DSL line.
This commit is contained in:
parent
5fffe6e2cd
commit
20fcf38e30
@ -19,7 +19,7 @@ CC = @CC@
|
|||||||
CXX = @CXX@
|
CXX = @CXX@
|
||||||
CFLAGS = @CFLAGS@
|
CFLAGS = @CFLAGS@
|
||||||
CXXFLAGS = @CXXFLAGS@
|
CXXFLAGS = @CXXFLAGS@
|
||||||
CPPFLAGS = @CPPFLAGS@ -I../include -I. @CPUINCLUDES@
|
CPPFLAGS = @CPPFLAGS@ -I../include -I. @CPUINCLUDES@ -I../slirp
|
||||||
DEFS = @DEFS@ @DEFINES@ -D_REENTRANT -DDATADIR=\"$(datadir)/$(APP)\"
|
DEFS = @DEFS@ @DEFINES@ -D_REENTRANT -DDATADIR=\"$(datadir)/$(APP)\"
|
||||||
LDFLAGS = @LDFLAGS@
|
LDFLAGS = @LDFLAGS@
|
||||||
LIBS = @LIBS@
|
LIBS = @LIBS@
|
||||||
@ -31,6 +31,16 @@ INSTALL = @INSTALL@
|
|||||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@ -s
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@ -s
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
|
||||||
|
SLIRP_CFLAGS = @SLIRP_CFLAGS@
|
||||||
|
SLIRP_SRCS = \
|
||||||
|
../slirp/bootp.c ../slirp/ip_output.c ../slirp/tcp_input.c \
|
||||||
|
../slirp/cksum.c ../slirp/mbuf.c ../slirp/tcp_output.c \
|
||||||
|
../slirp/debug.c ../slirp/misc.c ../slirp/tcp_subr.c \
|
||||||
|
../slirp/if.c ../slirp/sbuf.c ../slirp/tcp_timer.c \
|
||||||
|
../slirp/ip_icmp.c ../slirp/slirp.c ../slirp/tftp.c \
|
||||||
|
../slirp/ip_input.c ../slirp/socket.c ../slirp/udp.c
|
||||||
|
SLIRP_OBJS = $(SLIRP_SRCS:../slirp/%.c=obj/%.o)
|
||||||
|
|
||||||
## Files
|
## Files
|
||||||
SRCS = ../main.cpp main_unix.cpp ../prefs.cpp ../prefs_items.cpp prefs_unix.cpp \
|
SRCS = ../main.cpp main_unix.cpp ../prefs.cpp ../prefs_items.cpp prefs_unix.cpp \
|
||||||
sys_unix.cpp ../rom_patches.cpp ../slot_rom.cpp ../rsrc_patches.cpp \
|
sys_unix.cpp ../rom_patches.cpp ../slot_rom.cpp ../rsrc_patches.cpp \
|
||||||
@ -39,7 +49,7 @@ SRCS = ../main.cpp main_unix.cpp ../prefs.cpp ../prefs_items.cpp prefs_unix.cpp
|
|||||||
../sony.cpp ../disk.cpp ../cdrom.cpp ../scsi.cpp ../video.cpp video_blit.cpp \
|
../sony.cpp ../disk.cpp ../cdrom.cpp ../scsi.cpp ../video.cpp video_blit.cpp \
|
||||||
vm_alloc.cpp sigsegv.cpp ../audio.cpp ../extfs.cpp extfs_unix.cpp \
|
vm_alloc.cpp sigsegv.cpp ../audio.cpp ../extfs.cpp extfs_unix.cpp \
|
||||||
../user_strings.cpp user_strings_unix.cpp sshpty.c strlcpy.c \
|
../user_strings.cpp user_strings_unix.cpp sshpty.c strlcpy.c \
|
||||||
$(SYSSRCS) $(CPUSRCS)
|
$(SYSSRCS) $(CPUSRCS) $(SLIRP_SRCS)
|
||||||
APP = BasiliskII
|
APP = BasiliskII
|
||||||
|
|
||||||
## Rules
|
## Rules
|
||||||
@ -104,6 +114,8 @@ distclean: clean
|
|||||||
depend dep:
|
depend dep:
|
||||||
makedepend $(CPPFLAGS) -Y. $(SRCS) 2>/dev/null
|
makedepend $(CPPFLAGS) -Y. $(SRCS) 2>/dev/null
|
||||||
|
|
||||||
|
$(OBJ_DIR)/%.o : ../slirp/%.c
|
||||||
|
$(CC) $(CPPFLAGS) $(DEFS) $(SLIRP_CFLAGS) -c $< -o $@
|
||||||
$(OBJ_DIR)/%.o : %.c
|
$(OBJ_DIR)/%.o : %.c
|
||||||
$(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c $< -o $@
|
$(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c $< -o $@
|
||||||
$(OBJ_DIR)/%.o : %.cpp
|
$(OBJ_DIR)/%.o : %.cpp
|
||||||
|
@ -275,7 +275,8 @@ dnl Checks for header files.
|
|||||||
AC_HEADER_STDC
|
AC_HEADER_STDC
|
||||||
AC_CHECK_HEADERS(unistd.h fcntl.h sys/types.h sys/time.h sys/mman.h mach/mach.h)
|
AC_CHECK_HEADERS(unistd.h fcntl.h sys/types.h sys/time.h sys/mman.h mach/mach.h)
|
||||||
AC_CHECK_HEADERS(readline.h history.h readline/readline.h readline/history.h)
|
AC_CHECK_HEADERS(readline.h history.h readline/readline.h readline/history.h)
|
||||||
AC_CHECK_HEADERS(sys/socket.h)
|
AC_CHECK_HEADERS(sys/socket.h sys/ioctl.h sys/filio.h sys/bitypes.h sys/wait.h sys/select.h)
|
||||||
|
AC_CHECK_HEADERS(arpa/inet.h)
|
||||||
AC_CHECK_HEADERS(linux/if.h linux/if_tun.h net/if.h net/if_tun.h, [], [], [
|
AC_CHECK_HEADERS(linux/if.h linux/if_tun.h net/if.h net/if_tun.h, [], [], [
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@ -321,11 +322,12 @@ if [[ "x$ac_cv_type_socklen_t" != "xyes" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
dnl Checks for library functions.
|
dnl Checks for library functions.
|
||||||
AC_CHECK_FUNCS(strdup cfmakeraw)
|
AC_CHECK_FUNCS(strdup strerror cfmakeraw)
|
||||||
AC_CHECK_FUNCS(clock_gettime timer_create)
|
AC_CHECK_FUNCS(clock_gettime timer_create)
|
||||||
AC_CHECK_FUNCS(sigaction signal)
|
AC_CHECK_FUNCS(sigaction signal)
|
||||||
AC_CHECK_FUNCS(mmap mprotect munmap)
|
AC_CHECK_FUNCS(mmap mprotect munmap)
|
||||||
AC_CHECK_FUNCS(vm_allocate vm_deallocate vm_protect)
|
AC_CHECK_FUNCS(vm_allocate vm_deallocate vm_protect)
|
||||||
|
AC_CHECK_FUNCS(inet_aton)
|
||||||
|
|
||||||
dnl Darwin seems to define mach_task_self() instead of task_self().
|
dnl Darwin seems to define mach_task_self() instead of task_self().
|
||||||
AC_CHECK_FUNCS(mach_task_self task_self)
|
AC_CHECK_FUNCS(mach_task_self task_self)
|
||||||
@ -1063,6 +1065,14 @@ AC_EGREP_CPP(xyes,
|
|||||||
#endif
|
#endif
|
||||||
], [AC_MSG_RESULT(yes); HAVE_GCC30=yes], AC_MSG_RESULT(no))
|
], [AC_MSG_RESULT(yes); HAVE_GCC30=yes], AC_MSG_RESULT(no))
|
||||||
|
|
||||||
|
dnl Check for ICC.
|
||||||
|
AC_MSG_CHECKING(for ICC)
|
||||||
|
HAVE_ICC=no
|
||||||
|
if $CXX -V -v 2>&1 | grep -q "Intel(R) C++ Compiler"; then
|
||||||
|
HAVE_ICC=yes
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT($HAVE_ICC)
|
||||||
|
|
||||||
dnl Set "-fomit-frame-pointer" on i386 GCC 2.7 or higher.
|
dnl Set "-fomit-frame-pointer" on i386 GCC 2.7 or higher.
|
||||||
dnl Also set "-fno-exceptions" for C++ because exception handling requires
|
dnl Also set "-fno-exceptions" for C++ because exception handling requires
|
||||||
dnl the frame pointer.
|
dnl the frame pointer.
|
||||||
@ -1076,7 +1086,7 @@ dnl As of 2001/08/02, this affects the following compilers:
|
|||||||
dnl Official: probably gcc-3.1 (mainline CVS)
|
dnl Official: probably gcc-3.1 (mainline CVS)
|
||||||
dnl Mandrake: gcc-2.96 >= 0.59mdk, gcc-3.0.1 >= 0.1mdk
|
dnl Mandrake: gcc-2.96 >= 0.59mdk, gcc-3.0.1 >= 0.1mdk
|
||||||
dnl Red Hat : gcc-2.96 >= 89, gcc-3.0 >= 1
|
dnl Red Hat : gcc-2.96 >= 89, gcc-3.0 >= 1
|
||||||
if [[ "x$HAVE_GCC27" = "xyes" ]]; then
|
if [[ "x$HAVE_GCC27" = "xyes" -a "x$HAVE_ICC" = "xno" ]]; then
|
||||||
SAVED_CXXFLAGS="$CXXFLAGS"
|
SAVED_CXXFLAGS="$CXXFLAGS"
|
||||||
CXXFLAGS="$CXXFLAGS -fno-merge-constants"
|
CXXFLAGS="$CXXFLAGS -fno-merge-constants"
|
||||||
AC_CACHE_CHECK([whether GCC supports constants merging], ac_cv_gcc_constants_merging, [
|
AC_CACHE_CHECK([whether GCC supports constants merging], ac_cv_gcc_constants_merging, [
|
||||||
@ -1092,7 +1102,7 @@ fi
|
|||||||
|
|
||||||
dnl Store motion was introduced in 3.3-hammer branch and any gcc >= 3.4
|
dnl Store motion was introduced in 3.3-hammer branch and any gcc >= 3.4
|
||||||
dnl However, there are some corner cases exposed on x86-64
|
dnl However, there are some corner cases exposed on x86-64
|
||||||
if [[ "x$HAVE_GCC27" = "xyes" ]]; then
|
if [[ "x$HAVE_GCC27" = "xyes" -a "x$HAVE_ICC" = "xno" ]]; then
|
||||||
SAVED_CXXFLAGS="$CXXFLAGS"
|
SAVED_CXXFLAGS="$CXXFLAGS"
|
||||||
CXXFLAGS="$CXXFLAGS -fno-gcse-sm"
|
CXXFLAGS="$CXXFLAGS -fno-gcse-sm"
|
||||||
AC_CACHE_CHECK([whether GCC supports store motion], ac_cv_gcc_store_motion, [
|
AC_CACHE_CHECK([whether GCC supports store motion], ac_cv_gcc_store_motion, [
|
||||||
@ -1106,6 +1116,19 @@ if [[ "x$HAVE_GCC27" = "xyes" ]]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl Add -fno-strict-aliasing for slirp sources
|
||||||
|
if [[ "x$HAVE_GCC30" = "xyes" ]]; then
|
||||||
|
SAVED_CXXFLAGS="$CXXFLAGS"
|
||||||
|
CFLAGS="$CFLAGS -fno-strict-aliasing"
|
||||||
|
AC_CACHE_CHECK([whether the compiler supports -fno-strict-aliasing],
|
||||||
|
ac_cv_gcc_no_strict_aliasing, [
|
||||||
|
AC_TRY_COMPILE([],[],
|
||||||
|
[ac_cv_gcc_no_strict_aliasing=yes; AC_SUBST(SLIRP_CFLAGS, "$CFLAGS")],
|
||||||
|
[ac_cv_gcc_no_strict_aliasing=no])
|
||||||
|
])
|
||||||
|
CFLAGS="$SAVED_CFLAGS"
|
||||||
|
fi
|
||||||
|
|
||||||
dnl Select appropriate CPU source and REGPARAM define.
|
dnl Select appropriate CPU source and REGPARAM define.
|
||||||
ASM_OPTIMIZATIONS=none
|
ASM_OPTIMIZATIONS=none
|
||||||
CPUSRCS="cpuemu1.cpp cpuemu2.cpp cpuemu3.cpp cpuemu4.cpp cpuemu5.cpp cpuemu6.cpp cpuemu7.cpp cpuemu8.cpp"
|
CPUSRCS="cpuemu1.cpp cpuemu2.cpp cpuemu3.cpp cpuemu4.cpp cpuemu5.cpp cpuemu6.cpp cpuemu7.cpp cpuemu8.cpp"
|
||||||
|
@ -45,6 +45,11 @@
|
|||||||
#include <net/if_tun.h>
|
#include <net/if_tun.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// XXX: slirp is currently not 64-bit clean
|
||||||
|
#if SIZEOF_VOID_P == 4
|
||||||
|
#define HAVE_SLIRP 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "cpu_emulation.h"
|
#include "cpu_emulation.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "macos_util.h"
|
#include "macos_util.h"
|
||||||
@ -52,6 +57,7 @@
|
|||||||
#include "user_strings.h"
|
#include "user_strings.h"
|
||||||
#include "ether.h"
|
#include "ether.h"
|
||||||
#include "ether_defs.h"
|
#include "ether_defs.h"
|
||||||
|
#include "libslirp.h"
|
||||||
|
|
||||||
#ifndef NO_STD_NAMESPACE
|
#ifndef NO_STD_NAMESPACE
|
||||||
using std::map;
|
using std::map;
|
||||||
@ -68,6 +74,7 @@ enum {
|
|||||||
NET_IF_SHEEPNET,
|
NET_IF_SHEEPNET,
|
||||||
NET_IF_ETHERTAP,
|
NET_IF_ETHERTAP,
|
||||||
NET_IF_TUNTAP,
|
NET_IF_TUNTAP,
|
||||||
|
NET_IF_SLIRP
|
||||||
};
|
};
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
@ -83,12 +90,16 @@ static bool udp_tunnel; // Flag: UDP tunnelling active, fd is the socket de
|
|||||||
static int net_if_type = -1; // Ethernet device type
|
static int net_if_type = -1; // Ethernet device type
|
||||||
static char *net_if_name = NULL; // TUN/TAP device name
|
static char *net_if_name = NULL; // TUN/TAP device name
|
||||||
static const char *net_if_script = NULL; // Network config script
|
static const char *net_if_script = NULL; // Network config script
|
||||||
|
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
|
||||||
|
|
||||||
// Attached network protocols, maps protocol type to MacOS handler address
|
// Attached network protocols, maps protocol type to MacOS handler address
|
||||||
static map<uint16, uint32> net_protocols;
|
static map<uint16, uint32> net_protocols;
|
||||||
|
|
||||||
// Prototypes
|
// Prototypes
|
||||||
static void *receive_func(void *arg);
|
static void *receive_func(void *arg);
|
||||||
|
static void *slirp_receive_func(void *arg);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -109,6 +120,16 @@ static bool start_thread(void)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_SLIRP
|
||||||
|
if (net_if_type == NET_IF_SLIRP) {
|
||||||
|
slirp_thread_active = (pthread_create(&slirp_thread, NULL, slirp_receive_func, NULL) == 0);
|
||||||
|
if (!slirp_thread_active) {
|
||||||
|
printf("WARNING: Cannot start slirp reception thread\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,6 +140,14 @@ static bool start_thread(void)
|
|||||||
|
|
||||||
static void stop_thread(void)
|
static void stop_thread(void)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_SLIRP
|
||||||
|
if (slirp_thread_active) {
|
||||||
|
pthread_cancel(slirp_thread);
|
||||||
|
pthread_join(slirp_thread, NULL);
|
||||||
|
slirp_thread_active = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (thread_active) {
|
if (thread_active) {
|
||||||
pthread_cancel(ether_thread);
|
pthread_cancel(ether_thread);
|
||||||
pthread_join(ether_thread, NULL);
|
pthread_join(ether_thread, NULL);
|
||||||
@ -178,10 +207,28 @@ bool ether_init(void)
|
|||||||
#if ENABLE_TUNTAP
|
#if ENABLE_TUNTAP
|
||||||
else if (strcmp(name, "tun") == 0)
|
else if (strcmp(name, "tun") == 0)
|
||||||
net_if_type = NET_IF_TUNTAP;
|
net_if_type = NET_IF_TUNTAP;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SLIRP
|
||||||
|
else if (strcmp(name, "slirp") == 0)
|
||||||
|
net_if_type = NET_IF_SLIRP;
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
net_if_type = NET_IF_SHEEPNET;
|
net_if_type = NET_IF_SHEEPNET;
|
||||||
|
|
||||||
|
#ifdef HAVE_SLIRP
|
||||||
|
// Initialize slirp library
|
||||||
|
if (net_if_type == NET_IF_SLIRP) {
|
||||||
|
slirp_init();
|
||||||
|
|
||||||
|
// Open slirp output pipe
|
||||||
|
int fds[2];
|
||||||
|
if (pipe(fds) < 0)
|
||||||
|
return false;
|
||||||
|
fd = fds[0];
|
||||||
|
slirp_output_fd = fds[1];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Open sheep_net or ethertap or TUN/TAP device
|
// Open sheep_net or ethertap or TUN/TAP device
|
||||||
char dev_name[16];
|
char dev_name[16];
|
||||||
switch (net_if_type) {
|
switch (net_if_type) {
|
||||||
@ -195,11 +242,13 @@ bool ether_init(void)
|
|||||||
strcpy(dev_name, "/dev/sheep_net");
|
strcpy(dev_name, "/dev/sheep_net");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fd = open(dev_name, O_RDWR);
|
if (net_if_type != NET_IF_SLIRP) {
|
||||||
if (fd < 0) {
|
fd = open(dev_name, O_RDWR);
|
||||||
sprintf(str, GetString(STR_NO_SHEEP_NET_DRIVER_WARN), dev_name, strerror(errno));
|
if (fd < 0) {
|
||||||
WarningAlert(str);
|
sprintf(str, GetString(STR_NO_SHEEP_NET_DRIVER_WARN), dev_name, strerror(errno));
|
||||||
goto open_error;
|
WarningAlert(str);
|
||||||
|
goto open_error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_TUNTAP
|
#if ENABLE_TUNTAP
|
||||||
@ -257,6 +306,15 @@ bool ether_init(void)
|
|||||||
ether_addr[3] = p >> 16;
|
ether_addr[3] = p >> 16;
|
||||||
ether_addr[4] = p >> 8;
|
ether_addr[4] = p >> 8;
|
||||||
ether_addr[5] = p;
|
ether_addr[5] = p;
|
||||||
|
#ifdef HAVE_SLIRP
|
||||||
|
} else if (net_if_type == NET_IF_SLIRP) {
|
||||||
|
ether_addr[0] = 0x52;
|
||||||
|
ether_addr[1] = 0x54;
|
||||||
|
ether_addr[2] = 0x00;
|
||||||
|
ether_addr[3] = 0x12;
|
||||||
|
ether_addr[4] = 0x34;
|
||||||
|
ether_addr[5] = 0x56;
|
||||||
|
#endif
|
||||||
} else
|
} else
|
||||||
ioctl(fd, SIOCGIFADDR, ether_addr);
|
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]));
|
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]));
|
||||||
@ -275,6 +333,10 @@ open_error:
|
|||||||
close(fd);
|
close(fd);
|
||||||
fd = -1;
|
fd = -1;
|
||||||
}
|
}
|
||||||
|
if (slirp_output_fd >= 0) {
|
||||||
|
close(slirp_output_fd);
|
||||||
|
slirp_output_fd = -1;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,6 +366,10 @@ void ether_exit(void)
|
|||||||
// Close sheep_net device
|
// Close sheep_net device
|
||||||
if (fd > 0)
|
if (fd > 0)
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
// Close slirp output buffer
|
||||||
|
if (slirp_output_fd > 0)
|
||||||
|
close(slirp_output_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -323,14 +389,19 @@ void ether_reset(void)
|
|||||||
|
|
||||||
int16 ether_add_multicast(uint32 pb)
|
int16 ether_add_multicast(uint32 pb)
|
||||||
{
|
{
|
||||||
if (net_if_type != NET_IF_TUNTAP && ioctl(fd, SIOCADDMULTI, Mac2HostAddr(pb + eMultiAddr)) < 0) {
|
switch (net_if_type) {
|
||||||
D(bug("WARNING: Couldn't enable multicast address\n"));
|
case NET_IF_ETHERTAP:
|
||||||
if (net_if_type == NET_IF_ETHERTAP)
|
case NET_IF_SHEEPNET:
|
||||||
return noErr;
|
if (ioctl(fd, SIOCADDMULTI, Mac2HostAddr(pb + eMultiAddr)) < 0) {
|
||||||
else
|
D(bug("WARNING: Couldn't enable multicast address\n"));
|
||||||
return eMultiErr;
|
if (net_if_type == NET_IF_ETHERTAP)
|
||||||
} else
|
return noErr;
|
||||||
|
else
|
||||||
|
return eMultiErr;
|
||||||
|
}
|
||||||
|
default:
|
||||||
return noErr;
|
return noErr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -340,11 +411,16 @@ int16 ether_add_multicast(uint32 pb)
|
|||||||
|
|
||||||
int16 ether_del_multicast(uint32 pb)
|
int16 ether_del_multicast(uint32 pb)
|
||||||
{
|
{
|
||||||
if (net_if_type != NET_IF_TUNTAP && ioctl(fd, SIOCDELMULTI, Mac2HostAddr(pb + eMultiAddr)) < 0) {
|
switch (net_if_type) {
|
||||||
D(bug("WARNING: Couldn't disable multicast address\n"));
|
case NET_IF_ETHERTAP:
|
||||||
return eMultiErr;
|
case NET_IF_SHEEPNET:
|
||||||
} else
|
if (ioctl(fd, SIOCDELMULTI, Mac2HostAddr(pb + eMultiAddr)) < 0) {
|
||||||
|
D(bug("WARNING: Couldn't disable multicast address\n"));
|
||||||
|
return eMultiErr;
|
||||||
|
}
|
||||||
|
default:
|
||||||
return noErr;
|
return noErr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -400,6 +476,12 @@ int16 ether_write(uint32 wds)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Transmit packet
|
// Transmit packet
|
||||||
|
#ifdef HAVE_SLIRP
|
||||||
|
if (net_if_type == NET_IF_SLIRP) {
|
||||||
|
slirp_input(packet, len);
|
||||||
|
return noErr;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
if (write(fd, packet, len) < 0) {
|
if (write(fd, packet, len) < 0) {
|
||||||
D(bug("WARNING: Couldn't transmit packet\n"));
|
D(bug("WARNING: Couldn't transmit packet\n"));
|
||||||
return excessCollsns;
|
return excessCollsns;
|
||||||
@ -431,6 +513,53 @@ void ether_stop_udp_thread(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SLIRP output buffer glue
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_SLIRP
|
||||||
|
int slirp_can_output(void)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void slirp_output(const uint8 *packet, int len)
|
||||||
|
{
|
||||||
|
write(slirp_output_fd, packet, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *slirp_receive_func(void *arg)
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
// Wait for packets to arrive
|
||||||
|
fd_set rfds, wfds, xfds;
|
||||||
|
int nfds;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
nfds = -1;
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_ZERO(&wfds);
|
||||||
|
FD_ZERO(&xfds);
|
||||||
|
slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 16667;
|
||||||
|
if (select(nfds + 1, &rfds, &wfds, &xfds, &tv) >= 0)
|
||||||
|
slirp_select_poll(&rfds, &wfds, &xfds);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int slirp_can_output(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void slirp_output(const uint8 *packet, int len)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Packet reception thread
|
* Packet reception thread
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user