Rewrite of the network driver plugin code.
- Removed "pseudo device plugin" containing common code and specific drivers. - Moved network module base classes and module handling to the Bochs core. Now loading network driver plugins in netmod.cc. - Moved shared networking code used by the 'vnet' driver and 'bxhub' from netmod.cc/.h to new files netutil.cc/.h. - Created separate plugins for each network driver implementation. - Modified Bochs plugin system to support new plugin type PLUGTYPE_NETWORK.
This commit is contained in:
parent
d73284442f
commit
758f4de4d4
@ -46,6 +46,8 @@ Detailed change log :
|
|||||||
- Networking
|
- Networking
|
||||||
- Added ethernet module 'socket', designed to interconnect Bochs instances
|
- Added ethernet module 'socket', designed to interconnect Bochs instances
|
||||||
with external program 'bxhub' (simulating a multi-port ethernet hub).
|
with external program 'bxhub' (simulating a multi-port ethernet hub).
|
||||||
|
- Now creating separate plugins for each network driver implementation
|
||||||
|
(slirp, win32, etc.).
|
||||||
- Sound
|
- Sound
|
||||||
- Added PCM output data resampling in a separate thread. The resampler
|
- Added PCM output data resampling in a separate thread. The resampler
|
||||||
requires either libsamplerate or the SoX resampler library installed.
|
requires either libsamplerate or the SoX resampler library installed.
|
||||||
|
@ -253,8 +253,8 @@ bximage@EXE@: misc/bximage.o misc/hdimage.o misc/vmware3.o misc/vmware4.o misc/v
|
|||||||
niclist@EXE@: misc/niclist.o
|
niclist@EXE@: misc/niclist.o
|
||||||
@LINK_CONSOLE@ misc/niclist.o
|
@LINK_CONSOLE@ misc/niclist.o
|
||||||
|
|
||||||
bxhub@EXE@: misc/bxhub.o misc/netmod.o
|
bxhub@EXE@: misc/bxhub.o misc/netutil.o
|
||||||
@LINK_CONSOLE@ misc/bxhub.o misc/netmod.o @BXHUB_LINK_OPTS@
|
@LINK_CONSOLE@ misc/bxhub.o misc/netutil.o @BXHUB_LINK_OPTS@
|
||||||
|
|
||||||
# compile with console CXXFLAGS, not gui CXXFLAGS
|
# compile with console CXXFLAGS, not gui CXXFLAGS
|
||||||
misc/bximage.o: $(srcdir)/misc/bximage.cc $(srcdir)/misc/bswap.h \
|
misc/bximage.o: $(srcdir)/misc/bximage.cc $(srcdir)/misc/bswap.h \
|
||||||
@ -285,9 +285,9 @@ misc/bxhub.o: $(srcdir)/misc/bxhub.cc $(srcdir)/iodev/network/netmod.h \
|
|||||||
$(srcdir)/misc/bxcompat.h
|
$(srcdir)/misc/bxcompat.h
|
||||||
$(CC) @DASH@c $(BX_INCDIRS) $(CXXFLAGS_CONSOLE) $(srcdir)/misc/bxhub.cc @OFP@$@
|
$(CC) @DASH@c $(BX_INCDIRS) $(CXXFLAGS_CONSOLE) $(srcdir)/misc/bxhub.cc @OFP@$@
|
||||||
|
|
||||||
misc/netmod.o: $(srcdir)/iodev/network/netmod.cc $(srcdir)/iodev/network/netmod.h \
|
misc/netutil.o: $(srcdir)/iodev/network/netmod.cc $(srcdir)/iodev/network/netutil.h \
|
||||||
$(srcdir)/misc/bxcompat.h
|
$(srcdir)/iodev/network/netmod.h $(srcdir)/misc/bxcompat.h
|
||||||
$(CXX) @DASH@c $(BX_INCDIRS) @BXHUB_FLAG@ $(CXXFLAGS_CONSOLE) $(srcdir)/iodev/network/netmod.cc @OFP@$@
|
$(CXX) @DASH@c $(BX_INCDIRS) @BXHUB_FLAG@ $(CXXFLAGS_CONSOLE) $(srcdir)/iodev/network/netutil.cc @OFP@$@
|
||||||
|
|
||||||
# compile with console CFLAGS, not gui CXXFLAGS
|
# compile with console CFLAGS, not gui CXXFLAGS
|
||||||
misc/niclist.o: $(srcdir)/misc/niclist.c
|
misc/niclist.o: $(srcdir)/misc/niclist.c
|
||||||
|
8
bochs/configure
vendored
8
bochs/configure
vendored
@ -1,5 +1,5 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# From configure.in Id: configure.in 13079 2017-02-20 18:21:19Z vruppert .
|
# From configure.in Id: configure.in 13087 2017-02-27 22:26:43Z vruppert .
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.69.
|
# Generated by GNU Autoconf 2.69.
|
||||||
#
|
#
|
||||||
@ -23627,7 +23627,7 @@ fi
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
if test $can_compile_slirp = 1; then
|
if test $can_compile_slirp = 1; then
|
||||||
NETLOW_OBJS="$NETLOW_OBJS eth_slirp.o \$(SLIRP_OBJS)"
|
NETLOW_OBJS="$NETLOW_OBJS eth_slirp.o"
|
||||||
ethernet_modules="$ethernet_modules slirp"
|
ethernet_modules="$ethernet_modules slirp"
|
||||||
$as_echo "#define BX_NETMOD_SLIRP 1" >>confdefs.h
|
$as_echo "#define BX_NETMOD_SLIRP 1" >>confdefs.h
|
||||||
|
|
||||||
@ -23744,10 +23744,8 @@ fi
|
|||||||
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
if test "$bx_plugins" = 0; then
|
NETWORK_LIB_VAR='iodev/network/libnetwork.a'
|
||||||
NETWORK_LIB_VAR='iodev/network/libnetwork.a'
|
|
||||||
|
|
||||||
fi
|
|
||||||
$as_echo "#define BX_NETWORKING 1" >>confdefs.h
|
$as_echo "#define BX_NETWORKING 1" >>confdefs.h
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ethernet modules" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ethernet modules" >&5
|
||||||
|
@ -1702,7 +1702,7 @@ if test "$networking" = yes; then
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
if test $can_compile_slirp = 1; then
|
if test $can_compile_slirp = 1; then
|
||||||
NETLOW_OBJS="$NETLOW_OBJS eth_slirp.o \$(SLIRP_OBJS)"
|
NETLOW_OBJS="$NETLOW_OBJS eth_slirp.o"
|
||||||
ethernet_modules="$ethernet_modules slirp"
|
ethernet_modules="$ethernet_modules slirp"
|
||||||
AC_DEFINE(BX_NETMOD_SLIRP, 1)
|
AC_DEFINE(BX_NETMOD_SLIRP, 1)
|
||||||
NETLOW_OBJS="$NETLOW_OBJS eth_socket.o"
|
NETLOW_OBJS="$NETLOW_OBJS eth_socket.o"
|
||||||
@ -1779,10 +1779,8 @@ if test "$networking" = yes; then
|
|||||||
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
if test "$bx_plugins" = 0; then
|
NETWORK_LIB_VAR='iodev/network/libnetwork.a'
|
||||||
NETWORK_LIB_VAR='iodev/network/libnetwork.a'
|
AC_SUBST(NETWORK_LIB_VAR)
|
||||||
AC_SUBST(NETWORK_LIB_VAR)
|
|
||||||
fi
|
|
||||||
AC_DEFINE(BX_NETWORKING, 1)
|
AC_DEFINE(BX_NETWORKING, 1)
|
||||||
AC_MSG_CHECKING(for ethernet modules)
|
AC_MSG_CHECKING(for ethernet modules)
|
||||||
AC_MSG_RESULT($ethernet_modules)
|
AC_MSG_RESULT($ethernet_modules)
|
||||||
|
@ -33,6 +33,7 @@ enum plugintype_t {
|
|||||||
PLUGTYPE_STANDARD,
|
PLUGTYPE_STANDARD,
|
||||||
PLUGTYPE_OPTIONAL,
|
PLUGTYPE_OPTIONAL,
|
||||||
PLUGTYPE_SOUND,
|
PLUGTYPE_SOUND,
|
||||||
|
PLUGTYPE_NETWORK,
|
||||||
PLUGTYPE_USER
|
PLUGTYPE_USER
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "iodev/virt_timer.h"
|
#include "iodev/virt_timer.h"
|
||||||
#include "iodev/slowdown_timer.h"
|
#include "iodev/slowdown_timer.h"
|
||||||
#include "iodev/sound/soundmod.h"
|
#include "iodev/sound/soundmod.h"
|
||||||
|
#include "iodev/network/netmod.h"
|
||||||
|
|
||||||
#define LOG_THIS bx_devices.
|
#define LOG_THIS bx_devices.
|
||||||
|
|
||||||
@ -92,9 +93,6 @@ void bx_devices_c::init_stubs()
|
|||||||
#if BX_SUPPORT_PCIUSB
|
#if BX_SUPPORT_PCIUSB
|
||||||
pluginUsbDevCtl = &stubUsbDevCtl;
|
pluginUsbDevCtl = &stubUsbDevCtl;
|
||||||
#endif
|
#endif
|
||||||
#if BX_NETWORKING
|
|
||||||
pluginNetModCtl = &stubNetModCtl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bx_devices_c::init(BX_MEM_C *newmem)
|
void bx_devices_c::init(BX_MEM_C *newmem)
|
||||||
@ -161,7 +159,7 @@ void bx_devices_c::init(BX_MEM_C *newmem)
|
|||||||
#if BX_NETWORKING
|
#if BX_NETWORKING
|
||||||
network_enabled = is_network_enabled();
|
network_enabled = is_network_enabled();
|
||||||
if (network_enabled)
|
if (network_enabled)
|
||||||
PLUG_load_plugin(netmod, PLUGTYPE_CORE);
|
bx_netmod_ctl.init();
|
||||||
#endif
|
#endif
|
||||||
#if BX_SUPPORT_SOUNDLOW
|
#if BX_SUPPORT_SOUNDLOW
|
||||||
sound_enabled = is_sound_enabled();
|
sound_enabled = is_sound_enabled();
|
||||||
@ -390,7 +388,7 @@ void bx_devices_c::exit()
|
|||||||
PLUG_unload_plugin(hdimage);
|
PLUG_unload_plugin(hdimage);
|
||||||
#if BX_NETWORKING
|
#if BX_NETWORKING
|
||||||
if (network_enabled)
|
if (network_enabled)
|
||||||
PLUG_unload_plugin(netmod);
|
bx_netmod_ctl.exit();
|
||||||
#endif
|
#endif
|
||||||
#if BX_SUPPORT_SOUNDLOW
|
#if BX_SUPPORT_SOUNDLOW
|
||||||
if (sound_enabled)
|
if (sound_enabled)
|
||||||
|
@ -343,15 +343,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if BX_NETWORKING
|
|
||||||
class BOCHSAPI bx_netmod_ctl_stub_c : public bx_devmodel_c {
|
|
||||||
public:
|
|
||||||
virtual void* init_module(bx_list_c *base, void* rxh, void* rxstat, bx_devmodel_c *dev) {
|
|
||||||
STUBFUNC(netmod_ctl, init_module); return NULL;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class BOCHSAPI bx_devices_c : public logfunctions {
|
class BOCHSAPI bx_devices_c : public logfunctions {
|
||||||
public:
|
public:
|
||||||
bx_devices_c();
|
bx_devices_c();
|
||||||
@ -447,9 +438,6 @@ public:
|
|||||||
#if BX_SUPPORT_PCIUSB
|
#if BX_SUPPORT_PCIUSB
|
||||||
bx_usb_devctl_stub_c *pluginUsbDevCtl;
|
bx_usb_devctl_stub_c *pluginUsbDevCtl;
|
||||||
#endif
|
#endif
|
||||||
#if BX_NETWORKING
|
|
||||||
bx_netmod_ctl_stub_c *pluginNetModCtl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// stub classes that the pointers (above) can point to until a plugin is
|
// stub classes that the pointers (above) can point to until a plugin is
|
||||||
// loaded
|
// loaded
|
||||||
@ -479,9 +467,6 @@ public:
|
|||||||
#if BX_SUPPORT_PCIUSB
|
#if BX_SUPPORT_PCIUSB
|
||||||
bx_usb_devctl_stub_c stubUsbDevCtl;
|
bx_usb_devctl_stub_c stubUsbDevCtl;
|
||||||
#endif
|
#endif
|
||||||
#if BX_NETWORKING
|
|
||||||
bx_netmod_ctl_stub_c stubNetModCtl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Some info to pass to devices which can handled bulk IO. This allows
|
// Some info to pass to devices which can handled bulk IO. This allows
|
||||||
// the interface to remain the same for IO devices which can't handle
|
// the interface to remain the same for IO devices which can't handle
|
||||||
|
@ -79,12 +79,15 @@ SLIRP_OBJS = \
|
|||||||
BX_INCDIRS = -I.. -I../.. -I$(srcdir)/.. -I$(srcdir)/../.. -I../../@INSTRUMENT_DIR@ -I$(srcdir)/../../@INSTRUMENT_DIR@
|
BX_INCDIRS = -I.. -I../.. -I$(srcdir)/.. -I$(srcdir)/../.. -I../../@INSTRUMENT_DIR@ -I$(srcdir)/../../@INSTRUMENT_DIR@
|
||||||
LOCAL_CXXFLAGS = $(MCH_CFLAGS)
|
LOCAL_CXXFLAGS = $(MCH_CFLAGS)
|
||||||
|
|
||||||
|
OBJS_THAT_CANNOT_BE_PLUGINS = netmod.o
|
||||||
|
|
||||||
OBJS_THAT_CAN_BE_PLUGINS = \
|
OBJS_THAT_CAN_BE_PLUGINS = \
|
||||||
@NETDEV_OBJS@ \
|
@NETDEV_OBJS@ \
|
||||||
netmod.o
|
$(NETLOW_OBJS)
|
||||||
|
|
||||||
OBJS_THAT_SUPPORT_OTHER_PLUGINS = \
|
OBJS_THAT_SUPPORT_OTHER_PLUGINS = \
|
||||||
$(NETLOW_OBJS)
|
netutil.o \
|
||||||
|
$(SLIRP_OBJS)
|
||||||
|
|
||||||
NONPLUGIN_OBJS = @IODEV_EXT_NON_PLUGIN_OBJS@
|
NONPLUGIN_OBJS = @IODEV_EXT_NON_PLUGIN_OBJS@
|
||||||
PLUGIN_OBJS = @IODEV_EXT_PLUGIN_OBJS@
|
PLUGIN_OBJS = @IODEV_EXT_PLUGIN_OBJS@
|
||||||
@ -96,7 +99,8 @@ plugins: @PLUGIN_TARGET_2@
|
|||||||
|
|
||||||
plugins_gcc: $(PLUGIN_OBJS:@PLUGIN_LIBNAME_TRANSFORMATION@)
|
plugins_gcc: $(PLUGIN_OBJS:@PLUGIN_LIBNAME_TRANSFORMATION@)
|
||||||
|
|
||||||
plugins_msvc: bx_netmod.dll $(NETDEV_DLL_TARGETS)
|
plugins_msvc: $(NETDEV_DLL_TARGETS) bx_eth_null.dll bx_eth_slirp.dll \
|
||||||
|
bx_eth_socket.dll bx_eth_vnet.dll bx_eth_win32.dll
|
||||||
|
|
||||||
libnetwork.a: $(NONPLUGIN_OBJS)
|
libnetwork.a: $(NONPLUGIN_OBJS)
|
||||||
@RMCOMMAND@ libnetwork.a
|
@RMCOMMAND@ libnetwork.a
|
||||||
@ -115,16 +119,31 @@ libbx_%.la: %.lo
|
|||||||
$(LIBTOOL) --mode=link --tag CXX $(CXX) -module $< -o $@ -rpath $(PLUGIN_PATH)
|
$(LIBTOOL) --mode=link --tag CXX $(CXX) -module $< -o $@ -rpath $(PLUGIN_PATH)
|
||||||
|
|
||||||
# special link rules for plugins that require more than one object file
|
# special link rules for plugins that require more than one object file
|
||||||
libbx_netmod.la: netmod.lo $(NETLOW_OBJS:.o=.lo)
|
libbx_eth_slirp.la: eth_slirp.lo $(SLIRP_OBJS:.o=.lo)
|
||||||
$(LIBTOOL) --mode=link --tag CXX $(CXX) -module netmod.lo $(NETLOW_OBJS:.o=.lo) -o libbx_netmod.la -rpath $(PLUGIN_PATH)
|
$(LIBTOOL) --mode=link --tag CXX $(CXX) -module eth_slirp.lo $(SLIRP_OBJS:.o=.lo) -o libbx_eth_slirp.la -rpath $(PLUGIN_PATH)
|
||||||
|
|
||||||
|
libbx_eth_vnet.la: eth_vnet.lo netutil.lo
|
||||||
|
$(LIBTOOL) --mode=link --tag CXX $(CXX) -module eth_vnet.lo netutil.lo -o libbx_eth_vnet.la -rpath $(PLUGIN_PATH)
|
||||||
|
|
||||||
#### building DLLs for win32 (Cygwin and MinGW/MSYS)
|
#### building DLLs for win32 (Cygwin and MinGW/MSYS)
|
||||||
bx_%.dll: %.o
|
bx_%.dll: %.o
|
||||||
$(CXX) $(CXXFLAGS) -shared -o $@ $< $(WIN32_DLL_IMPORT_LIBRARY)
|
$(CXX) $(CXXFLAGS) -shared -o $@ $< $(WIN32_DLL_IMPORT_LIBRARY)
|
||||||
|
|
||||||
# special link rules for plugins with Cygwin, MinGW/MSYS and MSVC nmake
|
# special link rules for plugins with Cygwin, MinGW/MSYS and MSVC nmake
|
||||||
bx_netmod.dll: netmod.o $(NETLOW_OBJS)
|
bx_eth_null.dll: eth_null.o
|
||||||
@LINK_DLL@ netmod.o $(NETLOW_OBJS) $(WIN32_DLL_IMPORT_LIBRARY) $(NETMOD_LINK_OPTS@LINK_VAR@)
|
@LINK_DLL@ eth_null.o $(WIN32_DLL_IMPORT_LIBRARY)
|
||||||
|
|
||||||
|
bx_eth_slirp.dll: eth_slirp.o $(SLIRP_OBJS)
|
||||||
|
@LINK_DLL@ eth_slirp.o $(SLIRP_OBJS) $(WIN32_DLL_IMPORT_LIBRARY) $(NETMOD_LINK_OPTS@LINK_VAR@)
|
||||||
|
|
||||||
|
bx_eth_socket.dll: eth_socket.o
|
||||||
|
@LINK_DLL@ eth_socket.o $(WIN32_DLL_IMPORT_LIBRARY) $(NETMOD_LINK_OPTS@LINK_VAR@)
|
||||||
|
|
||||||
|
bx_eth_vnet.dll: eth_vnet.o netutil.o
|
||||||
|
@LINK_DLL@ eth_vnet.o netutil.o $(WIN32_DLL_IMPORT_LIBRARY) $(NETMOD_LINK_OPTS@LINK_VAR@)
|
||||||
|
|
||||||
|
bx_eth_win32.dll: eth_win32.o
|
||||||
|
@LINK_DLL@ eth_win32.o $(WIN32_DLL_IMPORT_LIBRARY) $(NETMOD_LINK_OPTS@LINK_VAR@)
|
||||||
|
|
||||||
bx_e1000.dll: e1000.o
|
bx_e1000.dll: e1000.o
|
||||||
@LINK_DLL@ e1000.o $(WIN32_DLL_IMPORT_LIBRARY)
|
@LINK_DLL@ e1000.o $(WIN32_DLL_IMPORT_LIBRARY)
|
||||||
@ -218,7 +237,7 @@ eth_vnet.o: eth_vnet.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
|
|||||||
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \
|
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \
|
||||||
../../memory/memory-bochs.h ../../pc_system.h ../../gui/gui.h \
|
../../memory/memory-bochs.h ../../pc_system.h ../../gui/gui.h \
|
||||||
../../instrument/stubs/instrument.h ../../plugin.h ../../extplugin.h \
|
../../instrument/stubs/instrument.h ../../plugin.h ../../extplugin.h \
|
||||||
../../param_names.h netmod.h
|
../../param_names.h netmod.h netutil.h
|
||||||
eth_win32.o: eth_win32.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
|
eth_win32.o: eth_win32.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
|
||||||
../../osdep.h ../../bx_debug/debug.h ../../config.h ../../osdep.h \
|
../../osdep.h ../../bx_debug/debug.h ../../config.h ../../osdep.h \
|
||||||
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \
|
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \
|
||||||
@ -237,6 +256,12 @@ netmod.o: netmod.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h ../../osde
|
|||||||
../../memory/memory-bochs.h ../../pc_system.h ../../gui/gui.h \
|
../../memory/memory-bochs.h ../../pc_system.h ../../gui/gui.h \
|
||||||
../../instrument/stubs/instrument.h ../../plugin.h ../../extplugin.h \
|
../../instrument/stubs/instrument.h ../../plugin.h ../../extplugin.h \
|
||||||
../../param_names.h netmod.h
|
../../param_names.h netmod.h
|
||||||
|
netutil.o: netutil.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
|
||||||
|
../../osdep.h ../../bx_debug/debug.h ../../config.h ../../osdep.h \
|
||||||
|
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \
|
||||||
|
../../memory/memory-bochs.h ../../pc_system.h ../../gui/gui.h \
|
||||||
|
../../instrument/stubs/instrument.h ../../plugin.h ../../extplugin.h \
|
||||||
|
../../param_names.h netmod.h netutil.h
|
||||||
pcipnic.o: pcipnic.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
|
pcipnic.o: pcipnic.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
|
||||||
../../osdep.h ../../bx_debug/debug.h ../../config.h ../../osdep.h \
|
../../osdep.h ../../bx_debug/debug.h ../../config.h ../../osdep.h \
|
||||||
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \
|
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \
|
||||||
@ -428,7 +453,7 @@ eth_vnet.lo: eth_vnet.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
|
|||||||
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \
|
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \
|
||||||
../../memory/memory-bochs.h ../../pc_system.h ../../gui/gui.h \
|
../../memory/memory-bochs.h ../../pc_system.h ../../gui/gui.h \
|
||||||
../../instrument/stubs/instrument.h ../../plugin.h ../../extplugin.h \
|
../../instrument/stubs/instrument.h ../../plugin.h ../../extplugin.h \
|
||||||
../../param_names.h netmod.h
|
../../param_names.h netmod.h netutil.h
|
||||||
eth_win32.lo: eth_win32.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
|
eth_win32.lo: eth_win32.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
|
||||||
../../osdep.h ../../bx_debug/debug.h ../../config.h ../../osdep.h \
|
../../osdep.h ../../bx_debug/debug.h ../../config.h ../../osdep.h \
|
||||||
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \
|
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \
|
||||||
@ -447,6 +472,12 @@ netmod.lo: netmod.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h ../../osd
|
|||||||
../../memory/memory-bochs.h ../../pc_system.h ../../gui/gui.h \
|
../../memory/memory-bochs.h ../../pc_system.h ../../gui/gui.h \
|
||||||
../../instrument/stubs/instrument.h ../../plugin.h ../../extplugin.h \
|
../../instrument/stubs/instrument.h ../../plugin.h ../../extplugin.h \
|
||||||
../../param_names.h netmod.h
|
../../param_names.h netmod.h
|
||||||
|
netutil.lo: netutil.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
|
||||||
|
../../osdep.h ../../bx_debug/debug.h ../../config.h ../../osdep.h \
|
||||||
|
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \
|
||||||
|
../../memory/memory-bochs.h ../../pc_system.h ../../gui/gui.h \
|
||||||
|
../../instrument/stubs/instrument.h ../../plugin.h ../../extplugin.h \
|
||||||
|
../../param_names.h netmod.h netutil.h
|
||||||
pcipnic.lo: pcipnic.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
|
pcipnic.lo: pcipnic.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
|
||||||
../../osdep.h ../../bx_debug/debug.h ../../config.h ../../osdep.h \
|
../../osdep.h ../../bx_debug/debug.h ../../config.h ../../osdep.h \
|
||||||
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \
|
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \
|
||||||
|
@ -53,6 +53,21 @@
|
|||||||
|
|
||||||
#if BX_NETWORKING && BX_NETMOD_FBSD
|
#if BX_NETWORKING && BX_NETMOD_FBSD
|
||||||
|
|
||||||
|
// network driver plugin entry points
|
||||||
|
|
||||||
|
int CDECL libfbsd_net_plugin_init(plugin_t *plugin, plugintype_t type)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
return 0; // Success
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDECL libfbsd_net_plugin_fini(void)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
}
|
||||||
|
|
||||||
|
// network driver implementation
|
||||||
|
|
||||||
#define LOG_THIS netdev->
|
#define LOG_THIS netdev->
|
||||||
|
|
||||||
#define BX_ETH_FBSD_LOGGING 0
|
#define BX_ETH_FBSD_LOGGING 0
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// $Id$
|
// $Id$
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Copyright (C) 2001-2011 The Bochs Project
|
// Copyright (C) 2001-2017 The Bochs Project
|
||||||
//
|
//
|
||||||
// This library is free software; you can redistribute it and/or
|
// This library is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
@ -45,6 +45,21 @@
|
|||||||
|
|
||||||
#if BX_NETWORKING && BX_NETMOD_LINUX
|
#if BX_NETWORKING && BX_NETMOD_LINUX
|
||||||
|
|
||||||
|
// network driver plugin entry points
|
||||||
|
|
||||||
|
int CDECL liblinux_net_plugin_init(plugin_t *plugin, plugintype_t type)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
return 0; // Success
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDECL liblinux_net_plugin_fini(void)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
}
|
||||||
|
|
||||||
|
// network driver implementation
|
||||||
|
|
||||||
#define LOG_THIS netdev->
|
#define LOG_THIS netdev->
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -36,6 +36,21 @@
|
|||||||
|
|
||||||
#if BX_NETWORKING
|
#if BX_NETWORKING
|
||||||
|
|
||||||
|
// network driver plugin entry points
|
||||||
|
|
||||||
|
int CDECL libnull_net_plugin_init(plugin_t *plugin, plugintype_t type)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
return 0; // Success
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDECL libnull_net_plugin_fini(void)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
}
|
||||||
|
|
||||||
|
// network driver implementation
|
||||||
|
|
||||||
#define LOG_THIS netdev->
|
#define LOG_THIS netdev->
|
||||||
|
|
||||||
#define BX_ETH_NULL_LOGGING 1
|
#define BX_ETH_NULL_LOGGING 1
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// $Id$
|
// $Id$
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Copyright (C) 2014-2016 The Bochs Project
|
// Copyright (C) 2014-2017 The Bochs Project
|
||||||
//
|
//
|
||||||
// This library is free software; you can redistribute it and/or
|
// This library is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
@ -31,12 +31,28 @@
|
|||||||
#include "slirp/slirp.h"
|
#include "slirp/slirp.h"
|
||||||
#include "slirp/libslirp.h"
|
#include "slirp/libslirp.h"
|
||||||
|
|
||||||
|
static unsigned int bx_slirp_instances;
|
||||||
|
|
||||||
|
// network driver plugin entry points
|
||||||
|
|
||||||
|
int CDECL libslirp_net_plugin_init(plugin_t *plugin, plugintype_t type)
|
||||||
|
{
|
||||||
|
bx_slirp_instances = 0;
|
||||||
|
return 0; // Success
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDECL libslirp_net_plugin_fini(void)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
}
|
||||||
|
|
||||||
|
// network driver implementation
|
||||||
|
|
||||||
#define LOG_THIS netdev->
|
#define LOG_THIS netdev->
|
||||||
|
|
||||||
#define MAX_HOSTFWD 5
|
#define MAX_HOSTFWD 5
|
||||||
|
|
||||||
static int rx_timer_index = BX_NULL_TIMER_HANDLE;
|
static int rx_timer_index = BX_NULL_TIMER_HANDLE;
|
||||||
static unsigned int bx_slirp_instances = 0;
|
|
||||||
fd_set rfds, wfds, xfds;
|
fd_set rfds, wfds, xfds;
|
||||||
int nfds;
|
int nfds;
|
||||||
|
|
||||||
@ -382,7 +398,7 @@ void slirp_output(void *this_ptr, const Bit8u *pkt, int pkt_len)
|
|||||||
void bx_slirp_pktmover_c::receive(void *pkt, unsigned pkt_len)
|
void bx_slirp_pktmover_c::receive(void *pkt, unsigned pkt_len)
|
||||||
{
|
{
|
||||||
if (this->rxstat(this->netdev) & BX_NETDEV_RXREADY) {
|
if (this->rxstat(this->netdev) & BX_NETDEV_RXREADY) {
|
||||||
if (pkt_len < 60) pkt_len = 60;
|
if (pkt_len < MIN_RX_PACKET_LEN) pkt_len = MIN_RX_PACKET_LEN;
|
||||||
this->rxh(this->netdev, pkt, pkt_len);
|
this->rxh(this->netdev, pkt, pkt_len);
|
||||||
} else {
|
} else {
|
||||||
BX_ERROR(("device not ready to receive data"));
|
BX_ERROR(("device not ready to receive data"));
|
||||||
|
@ -57,6 +57,21 @@
|
|||||||
|
|
||||||
#if BX_NETWORKING && BX_NETMOD_SOCKET
|
#if BX_NETWORKING && BX_NETMOD_SOCKET
|
||||||
|
|
||||||
|
// network driver plugin entry points
|
||||||
|
|
||||||
|
int CDECL libsocket_net_plugin_init(plugin_t *plugin, plugintype_t type)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
return 0; // Success
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDECL libsocket_net_plugin_fini(void)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
}
|
||||||
|
|
||||||
|
// network driver implementation
|
||||||
|
|
||||||
#define LOG_THIS netdev->
|
#define LOG_THIS netdev->
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -88,6 +88,21 @@
|
|||||||
|
|
||||||
#if BX_NETWORKING && BX_NETMOD_TAP
|
#if BX_NETWORKING && BX_NETMOD_TAP
|
||||||
|
|
||||||
|
// network driver plugin entry points
|
||||||
|
|
||||||
|
int CDECL libtap_net_plugin_init(plugin_t *plugin, plugintype_t type)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
return 0; // Success
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDECL libtap_net_plugin_fini(void)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
}
|
||||||
|
|
||||||
|
// network driver implementation
|
||||||
|
|
||||||
#define LOG_THIS netdev->
|
#define LOG_THIS netdev->
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -406,9 +421,9 @@ void bx_tap_pktmover_c::rx_timer()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
BX_DEBUG(("eth_tap: got packet: %d bytes, dst=%x:%x:%x:%x:%x:%x, src=%x:%x:%x:%x:%x:%x\n", nbytes, rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3], rxbuf[4], rxbuf[5], rxbuf[6], rxbuf[7], rxbuf[8], rxbuf[9], rxbuf[10], rxbuf[11]));
|
BX_DEBUG(("eth_tap: got packet: %d bytes, dst=%x:%x:%x:%x:%x:%x, src=%x:%x:%x:%x:%x:%x\n", nbytes, rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3], rxbuf[4], rxbuf[5], rxbuf[6], rxbuf[7], rxbuf[8], rxbuf[9], rxbuf[10], rxbuf[11]));
|
||||||
if (nbytes < 60) {
|
if (nbytes < MIN_RX_PACKET_LEN) {
|
||||||
BX_INFO(("packet too short (%d), padding to 60", nbytes));
|
BX_INFO(("packet too short (%d), padding to %d", nbytes, MIN_RX_PACKET_LEN));
|
||||||
nbytes = 60;
|
nbytes = MIN_RX_PACKET_LEN;
|
||||||
}
|
}
|
||||||
if (this->rxstat(this->netdev) & BX_NETDEV_RXREADY) {
|
if (this->rxstat(this->netdev) & BX_NETDEV_RXREADY) {
|
||||||
this->rxh(this->netdev, rxbuf, nbytes);
|
this->rxh(this->netdev, rxbuf, nbytes);
|
||||||
|
@ -32,6 +32,21 @@
|
|||||||
|
|
||||||
#if BX_NETWORKING && BX_NETMOD_TUNTAP
|
#if BX_NETWORKING && BX_NETMOD_TUNTAP
|
||||||
|
|
||||||
|
// network driver plugin entry points
|
||||||
|
|
||||||
|
int CDECL libtuntap_net_plugin_init(plugin_t *plugin, plugintype_t type)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
return 0; // Success
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDECL libtuntap_net_plugin_fini(void)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
}
|
||||||
|
|
||||||
|
// network driver implementation
|
||||||
|
|
||||||
#define LOG_THIS netdev->
|
#define LOG_THIS netdev->
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -331,9 +346,9 @@ void bx_tuntap_pktmover_c::rx_timer()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
BX_DEBUG(("eth_tuntap: got packet: %d bytes, dst=%02x:%02x:%02x:%02x:%02x:%02x, src=%02x:%02x:%02x:%02x:%02x:%02x", nbytes, rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3], rxbuf[4], rxbuf[5], rxbuf[6], rxbuf[7], rxbuf[8], rxbuf[9], rxbuf[10], rxbuf[11]));
|
BX_DEBUG(("eth_tuntap: got packet: %d bytes, dst=%02x:%02x:%02x:%02x:%02x:%02x, src=%02x:%02x:%02x:%02x:%02x:%02x", nbytes, rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3], rxbuf[4], rxbuf[5], rxbuf[6], rxbuf[7], rxbuf[8], rxbuf[9], rxbuf[10], rxbuf[11]));
|
||||||
if (nbytes < 60) {
|
if (nbytes < MIN_RX_PACKET_LEN) {
|
||||||
BX_INFO(("packet too short (%d), padding to 60", nbytes));
|
BX_INFO(("packet too short (%d), padding to %d", nbytes, MIN_RX_PACKET_LEN));
|
||||||
nbytes = 60;
|
nbytes = MIN_RX_PACKET_LEN;
|
||||||
}
|
}
|
||||||
if (this->rxstat(this->netdev) & BX_NETDEV_RXREADY) {
|
if (this->rxstat(this->netdev) & BX_NETDEV_RXREADY) {
|
||||||
this->rxh(this->netdev, rxbuf, nbytes);
|
this->rxh(this->netdev, rxbuf, nbytes);
|
||||||
|
@ -34,6 +34,21 @@
|
|||||||
|
|
||||||
#if BX_NETWORKING && BX_NETMOD_VDE
|
#if BX_NETWORKING && BX_NETMOD_VDE
|
||||||
|
|
||||||
|
// network driver plugin entry points
|
||||||
|
|
||||||
|
int CDECL libvde_net_plugin_init(plugin_t *plugin, plugintype_t type)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
return 0; // Success
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDECL libvde_net_plugin_fini(void)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
}
|
||||||
|
|
||||||
|
// network driver implementation
|
||||||
|
|
||||||
#define LOG_THIS netdev->
|
#define LOG_THIS netdev->
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -250,9 +265,9 @@ void bx_vde_pktmover_c::rx_timer()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
BX_DEBUG(("eth_vde: got packet: %d bytes, dst=%x:%x:%x:%x:%x:%x, src=%x:%x:%x:%x:%x:%x\n", nbytes, rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3], rxbuf[4], rxbuf[5], rxbuf[6], rxbuf[7], rxbuf[8], rxbuf[9], rxbuf[10], rxbuf[11]));
|
BX_DEBUG(("eth_vde: got packet: %d bytes, dst=%x:%x:%x:%x:%x:%x, src=%x:%x:%x:%x:%x:%x\n", nbytes, rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3], rxbuf[4], rxbuf[5], rxbuf[6], rxbuf[7], rxbuf[8], rxbuf[9], rxbuf[10], rxbuf[11]));
|
||||||
if (nbytes < 60) {
|
if (nbytes < MIN_RX_PACKET_LEN) {
|
||||||
BX_INFO(("packet too short (%d), padding to 60", nbytes));
|
BX_INFO(("packet too short (%d), padding to %d", nbytes, MIN_RX_PACKET_LEN));
|
||||||
nbytes = 60;
|
nbytes = MIN_RX_PACKET_LEN;
|
||||||
}
|
}
|
||||||
if (this->rxstat(this->netdev) & BX_NETDEV_RXREADY) {
|
if (this->rxstat(this->netdev) & BX_NETDEV_RXREADY) {
|
||||||
this->rxh(this->netdev, rxbuf, nbytes);
|
this->rxh(this->netdev, rxbuf, nbytes);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// $Id$
|
// $Id$
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Copyright (C) 2005-2017 The Bochs Project
|
// Copyright (C) 2004-2017 The Bochs Project
|
||||||
//
|
//
|
||||||
// This library is free software; you can redistribute it and/or
|
// This library is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
@ -35,9 +35,27 @@
|
|||||||
|
|
||||||
#include "iodev.h"
|
#include "iodev.h"
|
||||||
#include "netmod.h"
|
#include "netmod.h"
|
||||||
|
#include "netutil.h"
|
||||||
|
|
||||||
#if BX_NETWORKING
|
#if BX_NETWORKING
|
||||||
|
|
||||||
|
static unsigned int bx_vnet_instances;
|
||||||
|
|
||||||
|
// network driver plugin entry points
|
||||||
|
|
||||||
|
int CDECL libvnet_net_plugin_init(plugin_t *plugin, plugintype_t type)
|
||||||
|
{
|
||||||
|
bx_vnet_instances = 0;
|
||||||
|
return 0; // Success
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDECL libvnet_net_plugin_fini(void)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
}
|
||||||
|
|
||||||
|
// network driver implementation
|
||||||
|
|
||||||
#define LOG_THIS netdev->
|
#define LOG_THIS netdev->
|
||||||
|
|
||||||
#define BX_ETH_VNET_LOGGING 1
|
#define BX_ETH_VNET_LOGGING 1
|
||||||
@ -53,8 +71,6 @@
|
|||||||
#include <pcap.h>
|
#include <pcap.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static unsigned int bx_vnet_instances = 0;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// handler to send/receive packets
|
// handler to send/receive packets
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
@ -347,7 +363,7 @@ void bx_vnet_pktmover_c::rx_timer(void)
|
|||||||
|
|
||||||
void bx_vnet_pktmover_c::host_to_guest(Bit8u *buf, unsigned io_len, unsigned l3type)
|
void bx_vnet_pktmover_c::host_to_guest(Bit8u *buf, unsigned io_len, unsigned l3type)
|
||||||
{
|
{
|
||||||
Bit8u localbuf[60];
|
Bit8u localbuf[MIN_RX_PACKET_LEN];
|
||||||
|
|
||||||
if (io_len < 14) {
|
if (io_len < 14) {
|
||||||
BX_PANIC(("host_to_guest: io_len < 14!"));
|
BX_PANIC(("host_to_guest: io_len < 14!"));
|
||||||
|
@ -42,6 +42,21 @@
|
|||||||
|
|
||||||
#if BX_NETWORKING && BX_NETMOD_WIN32
|
#if BX_NETWORKING && BX_NETMOD_WIN32
|
||||||
|
|
||||||
|
// network driver plugin entry points
|
||||||
|
|
||||||
|
int CDECL libwin32_net_plugin_init(plugin_t *plugin, plugintype_t type)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
return 0; // Success
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDECL libwin32_net_plugin_fini(void)
|
||||||
|
{
|
||||||
|
// Nothing here yet
|
||||||
|
}
|
||||||
|
|
||||||
|
// network driver implementation
|
||||||
|
|
||||||
#ifndef __CYGWIN__
|
#ifndef __CYGWIN__
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
@ -391,7 +406,7 @@ void bx_win32_pktmover_c::rx_timer(void)
|
|||||||
if(memcmp(pPacket, cMacAddr, 6) == 0 || memcmp(pPacket, broadcast_macaddr, 6) == 0)
|
if(memcmp(pPacket, cMacAddr, 6) == 0 || memcmp(pPacket, broadcast_macaddr, 6) == 0)
|
||||||
{
|
{
|
||||||
pktlen = hdr->bh_caplen;
|
pktlen = hdr->bh_caplen;
|
||||||
if (pktlen < 60) pktlen = 60;
|
if (pktlen < MIN_RX_PACKET_LEN) pktlen = MIN_RX_PACKET_LEN;
|
||||||
#if BX_ETH_WIN32_LOGGING
|
#if BX_ETH_WIN32_LOGGING
|
||||||
write_pktlog_txt(pktlog_txt, pPacket, pktlen, 1);
|
write_pktlog_txt(pktlog_txt, pPacket, pktlen, 1);
|
||||||
#endif
|
#endif
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -29,12 +29,16 @@
|
|||||||
|
|
||||||
#ifndef BXHUB
|
#ifndef BXHUB
|
||||||
// Pseudo device that loads the lowlevel networking module
|
// Pseudo device that loads the lowlevel networking module
|
||||||
class bx_netmod_ctl_c : public bx_netmod_ctl_stub_c {
|
class BOCHSAPI bx_netmod_ctl_c : public logfunctions {
|
||||||
public:
|
public:
|
||||||
bx_netmod_ctl_c();
|
bx_netmod_ctl_c();
|
||||||
virtual ~bx_netmod_ctl_c() {}
|
virtual ~bx_netmod_ctl_c() {}
|
||||||
|
void init(void);
|
||||||
|
void exit(void);
|
||||||
virtual void* init_module(bx_list_c *base, void* rxh, void* rxstat, bx_devmodel_c *dev);
|
virtual void* init_module(bx_list_c *base, void* rxh, void* rxstat, bx_devmodel_c *dev);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BOCHSAPI extern bx_netmod_ctl_c bx_netmod_ctl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define BX_PACKET_BUFSIZE 2048 // Enough for an ether frame
|
#define BX_PACKET_BUFSIZE 2048 // Enough for an ether frame
|
||||||
@ -49,120 +53,14 @@ public:
|
|||||||
// this should not be smaller than an arp reply with an ethernet header
|
// this should not be smaller than an arp reply with an ethernet header
|
||||||
#define MIN_RX_PACKET_LEN 60
|
#define MIN_RX_PACKET_LEN 60
|
||||||
|
|
||||||
#define ETHERNET_MAC_ADDR_LEN 6
|
|
||||||
#define ETHERNET_TYPE_IPV4 0x0800
|
|
||||||
#define ETHERNET_TYPE_ARP 0x0806
|
|
||||||
|
|
||||||
#define ARP_OPCODE_REQUEST 1
|
|
||||||
#define ARP_OPCODE_REPLY 2
|
|
||||||
#define ARP_OPCODE_REV_REQUEST 3
|
|
||||||
#define ARP_OPCODE_REV_REPLY 4
|
|
||||||
|
|
||||||
#define ICMP_ECHO_PACKET_MAX 128
|
|
||||||
|
|
||||||
#define TFTP_BUFFER_SIZE 1024
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
#elif defined(__MWERKS__) && defined(macintosh)
|
|
||||||
#pragma options align=packed
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct ethernet_header {
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER>=1300)
|
|
||||||
__declspec(align(1))
|
|
||||||
#endif
|
|
||||||
Bit8u dst_mac_addr[ETHERNET_MAC_ADDR_LEN];
|
|
||||||
Bit8u src_mac_addr[ETHERNET_MAC_ADDR_LEN];
|
|
||||||
Bit16u type;
|
|
||||||
}
|
|
||||||
#if !defined(_MSC_VER)
|
|
||||||
GCC_ATTRIBUTE((packed))
|
|
||||||
#endif
|
|
||||||
ethernet_header_t;
|
|
||||||
|
|
||||||
typedef struct arp_header {
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER>=1300)
|
|
||||||
__declspec(align(1))
|
|
||||||
#endif
|
|
||||||
Bit16u hw_addr_space;
|
|
||||||
Bit16u proto_addr_space;
|
|
||||||
Bit8u hw_addr_len;
|
|
||||||
Bit8u proto_addr_len;
|
|
||||||
Bit16u opcode;
|
|
||||||
/* HW address of sender */
|
|
||||||
/* Protocol address of sender */
|
|
||||||
/* HW address of target*/
|
|
||||||
/* Protocol address of target */
|
|
||||||
}
|
|
||||||
#if !defined(_MSC_VER)
|
|
||||||
GCC_ATTRIBUTE((packed))
|
|
||||||
#endif
|
|
||||||
arp_header_t;
|
|
||||||
|
|
||||||
typedef struct ip_header {
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER>=1300)
|
|
||||||
__declspec(align(1))
|
|
||||||
#endif
|
|
||||||
#ifdef BX_LITTLE_ENDIAN
|
|
||||||
Bit8u header_len : 4;
|
|
||||||
Bit8u version : 4;
|
|
||||||
#else
|
|
||||||
Bit8u version : 4;
|
|
||||||
Bit8u header_len : 4;
|
|
||||||
#endif
|
|
||||||
Bit8u tos;
|
|
||||||
Bit16u total_len;
|
|
||||||
Bit16u id;
|
|
||||||
Bit16u frag_offs;
|
|
||||||
Bit8u ttl;
|
|
||||||
Bit8u protocol;
|
|
||||||
Bit16u checksum;
|
|
||||||
Bit32u src_addr;
|
|
||||||
Bit32u dst_addr;
|
|
||||||
}
|
|
||||||
#if !defined(_MSC_VER)
|
|
||||||
GCC_ATTRIBUTE((packed))
|
|
||||||
#endif
|
|
||||||
ip_header_t;
|
|
||||||
|
|
||||||
typedef struct udp_header {
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER>=1300)
|
|
||||||
__declspec(align(1))
|
|
||||||
#endif
|
|
||||||
Bit16u src_port;
|
|
||||||
Bit16u dst_port;
|
|
||||||
Bit16u length;
|
|
||||||
Bit16u checksum;
|
|
||||||
}
|
|
||||||
#if !defined(_MSC_VER)
|
|
||||||
GCC_ATTRIBUTE((packed))
|
|
||||||
#endif
|
|
||||||
udp_header_t;
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#pragma pack(pop)
|
|
||||||
#elif defined(__MWERKS__) && defined(macintosh)
|
|
||||||
#pragma options align=reset
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef void (*eth_rx_handler_t)(void *arg, const void *buf, unsigned len);
|
typedef void (*eth_rx_handler_t)(void *arg, const void *buf, unsigned len);
|
||||||
typedef Bit32u (*eth_rx_status_t)(void *arg);
|
typedef Bit32u (*eth_rx_status_t)(void *arg);
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Bit8u host_macaddr[6];
|
|
||||||
Bit8u guest_macaddr[6];
|
|
||||||
Bit8u host_ipv4addr[4];
|
|
||||||
Bit8u default_guest_ipv4addr[4];
|
|
||||||
Bit8u guest_ipv4addr[4];
|
|
||||||
Bit8u dns_ipv4addr[4];
|
|
||||||
} dhcp_cfg_t;
|
|
||||||
|
|
||||||
static const Bit8u broadcast_macaddr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
|
static const Bit8u broadcast_macaddr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
|
||||||
|
|
||||||
#ifndef BXHUB
|
#ifndef BXHUB
|
||||||
int execute_script(bx_devmodel_c *netdev, const char *name, char* arg1);
|
int execute_script(bx_devmodel_c *netdev, const char *name, char* arg1);
|
||||||
void write_pktlog_txt(FILE *pktlog_txt, const Bit8u *buf, unsigned len, bx_bool host_to_guest);
|
void BOCHSAPI_MSVCONLY write_pktlog_txt(FILE *pktlog_txt, const Bit8u *buf, unsigned len, bx_bool host_to_guest);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BX_CPP_INLINE Bit16u get_net2(const Bit8u *buf)
|
BX_CPP_INLINE Bit16u get_net2(const Bit8u *buf)
|
||||||
@ -193,21 +91,6 @@ BX_CPP_INLINE void put_net4(Bit8u *buf,Bit32u data)
|
|||||||
*(buf+3) = (Bit8u)(data & 0xff);
|
*(buf+3) = (Bit8u)(data & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
// vnet code shared with bxhub
|
|
||||||
#ifdef BXHUB
|
|
||||||
#define bx_devmodel_c void
|
|
||||||
#endif
|
|
||||||
Bit16u ip_checksum(const Bit8u *buf, unsigned buf_len);
|
|
||||||
void vnet_prepare_reply(Bit8u *replybuf, unsigned l3type, dhcp_cfg_t *dhcpc);
|
|
||||||
bx_bool vnet_process_arp_request(const Bit8u *buf, Bit8u *reply, dhcp_cfg_t *dhcp);
|
|
||||||
bx_bool vnet_process_icmp_echo(const Bit8u *l3pkt, unsigned l3header_len,
|
|
||||||
const Bit8u *l4pkt, unsigned l4pkt_len,
|
|
||||||
Bit8u *reply);
|
|
||||||
int vnet_process_dhcp(bx_devmodel_c *netdev, const Bit8u *data, unsigned data_len,
|
|
||||||
Bit8u *reply, dhcp_cfg_t *dhcp);
|
|
||||||
int vnet_process_tftp(bx_devmodel_c *netdev, const Bit8u *data, unsigned data_len,
|
|
||||||
Bit16u req_tid, Bit8u *reply, const char *tftp_rootdir);
|
|
||||||
|
|
||||||
#ifndef BXHUB
|
#ifndef BXHUB
|
||||||
//
|
//
|
||||||
// The eth_pktmover class is used by ethernet chip emulations
|
// The eth_pktmover class is used by ethernet chip emulations
|
||||||
@ -233,8 +116,10 @@ protected:
|
|||||||
// their name. Chip emulations use the static 'create' method
|
// their name. Chip emulations use the static 'create' method
|
||||||
// to locate and instantiate a pktmover class.
|
// to locate and instantiate a pktmover class.
|
||||||
//
|
//
|
||||||
class eth_locator_c {
|
class BOCHSAPI_MSVCONLY eth_locator_c {
|
||||||
public:
|
public:
|
||||||
|
static bx_bool module_present(const char *type);
|
||||||
|
static void cleanup();
|
||||||
static eth_pktmover_c *create(const char *type, const char *netif,
|
static eth_pktmover_c *create(const char *type, const char *netif,
|
||||||
const char *macaddr,
|
const char *macaddr,
|
||||||
eth_rx_handler_t rxh,
|
eth_rx_handler_t rxh,
|
||||||
@ -243,7 +128,7 @@ public:
|
|||||||
const char *script);
|
const char *script);
|
||||||
protected:
|
protected:
|
||||||
eth_locator_c(const char *type);
|
eth_locator_c(const char *type);
|
||||||
virtual ~eth_locator_c() {}
|
virtual ~eth_locator_c();
|
||||||
virtual eth_pktmover_c *allocate(const char *netif,
|
virtual eth_pktmover_c *allocate(const char *netif,
|
||||||
const char *macaddr,
|
const char *macaddr,
|
||||||
eth_rx_handler_t rxh,
|
eth_rx_handler_t rxh,
|
||||||
|
856
bochs/iodev/network/netutil.cc
Normal file
856
bochs/iodev/network/netutil.cc
Normal file
@ -0,0 +1,856 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
// $Id$
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2004-2017 The Bochs Project
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
//
|
||||||
|
|
||||||
|
// netutil.cc - shared code for eth_vnet.cc and bxhub.cc
|
||||||
|
|
||||||
|
#define BX_PLUGGABLE
|
||||||
|
|
||||||
|
#ifdef BXHUB
|
||||||
|
#include "config.h"
|
||||||
|
#else
|
||||||
|
#include "iodev.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BX_NETWORKING
|
||||||
|
|
||||||
|
#include "netmod.h"
|
||||||
|
#include "netutil.h"
|
||||||
|
|
||||||
|
#ifdef BXHUB
|
||||||
|
#include "misc/bxcompat.h"
|
||||||
|
#else
|
||||||
|
#define LOG_THIS netdev->
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Bit16u ip_checksum(const Bit8u *buf, unsigned buf_len)
|
||||||
|
{
|
||||||
|
Bit32u sum = 0;
|
||||||
|
unsigned n;
|
||||||
|
|
||||||
|
for (n = 0; n < buf_len; n++) {
|
||||||
|
if (n & 1) {
|
||||||
|
sum += (Bit32u)(*buf++);
|
||||||
|
} else {
|
||||||
|
sum += (Bit32u)(*buf++) << 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (sum > 0xffff) {
|
||||||
|
sum = (sum >> 16) + (sum & 0xffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Bit16u)sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DHCP server
|
||||||
|
|
||||||
|
#define BOOTREQUEST 1
|
||||||
|
#define BOOTREPLY 2
|
||||||
|
|
||||||
|
#define BOOTPOPT_PADDING 0
|
||||||
|
#define BOOTPOPT_END 255
|
||||||
|
#define BOOTPOPT_SUBNETMASK 1
|
||||||
|
#define BOOTPOPT_TIMEOFFSET 2
|
||||||
|
#define BOOTPOPT_ROUTER_OPTION 3
|
||||||
|
#define BOOTPOPT_DOMAIN_NAMESERVER 6
|
||||||
|
#define BOOTPOPT_HOST_NAME 12
|
||||||
|
#define BOOTPOPT_DOMAIN_NAME 15
|
||||||
|
#define BOOTPOPT_MAX_DATAGRAM_SIZE 22
|
||||||
|
#define BOOTPOPT_DEFAULT_IP_TTL 23
|
||||||
|
#define BOOTPOPT_BROADCAST_ADDRESS 28
|
||||||
|
#define BOOTPOPT_ARPCACHE_TIMEOUT 35
|
||||||
|
#define BOOTPOPT_DEFAULT_TCP_TTL 37
|
||||||
|
#define BOOTPOPT_NTP_SERVER 42
|
||||||
|
#define BOOTPOPT_NETBIOS_NAMESERVER 44
|
||||||
|
#define BOOTPOPT_X_FONTSERVER 48
|
||||||
|
#define BOOTPOPT_REQUESTED_IP_ADDRESS 50
|
||||||
|
#define BOOTPOPT_IP_ADDRESS_LEASE_TIME 51
|
||||||
|
#define BOOTPOPT_OPTION_OVRLOAD 52
|
||||||
|
#define BOOTPOPT_DHCP_MESSAGETYPE 53
|
||||||
|
#define BOOTPOPT_SERVER_IDENTIFIER 54
|
||||||
|
#define BOOTPOPT_PARAMETER_REQUEST_LIST 55
|
||||||
|
#define BOOTPOPT_MAX_DHCP_MESSAGE_SIZE 57
|
||||||
|
#define BOOTPOPT_RENEWAL_TIME 58
|
||||||
|
#define BOOTPOPT_REBINDING_TIME 59
|
||||||
|
#define BOOTPOPT_CLASS_IDENTIFIER 60
|
||||||
|
#define BOOTPOPT_CLIENT_IDENTIFIER 61
|
||||||
|
|
||||||
|
#define DHCPDISCOVER 1
|
||||||
|
#define DHCPOFFER 2
|
||||||
|
#define DHCPREQUEST 3
|
||||||
|
#define DHCPDECLINE 4
|
||||||
|
#define DHCPACK 5
|
||||||
|
#define DHCPNAK 6
|
||||||
|
#define DHCPRELEASE 7
|
||||||
|
#define DHCPINFORM 8
|
||||||
|
|
||||||
|
#define DEFAULT_LEASE_TIME 28800
|
||||||
|
|
||||||
|
// TFTP server support by EaseWay <easeway@123.com>
|
||||||
|
|
||||||
|
#define TFTP_RRQ 1
|
||||||
|
#define TFTP_WRQ 2
|
||||||
|
#define TFTP_DATA 3
|
||||||
|
#define TFTP_ACK 4
|
||||||
|
#define TFTP_ERROR 5
|
||||||
|
#define TFTP_OPTACK 6
|
||||||
|
|
||||||
|
#define TFTP_OPTION_OCTET 0x1
|
||||||
|
#define TFTP_OPTION_BLKSIZE 0x2
|
||||||
|
#define TFTP_OPTION_TSIZE 0x4
|
||||||
|
#define TFTP_OPTION_TIMEOUT 0x8
|
||||||
|
|
||||||
|
#define TFTP_DEFAULT_BLKSIZE 512
|
||||||
|
#define TFTP_DEFAULT_TIMEOUT 5
|
||||||
|
|
||||||
|
static const Bit8u subnetmask_ipv4addr[4] = {0xff,0xff,0xff,0x00};
|
||||||
|
static const Bit8u broadcast_ipv4addr1[4] = {0xff,0xff,0xff,0xff};
|
||||||
|
|
||||||
|
void vnet_prepare_reply(Bit8u *replybuf, unsigned l3type, dhcp_cfg_t *dhcpc)
|
||||||
|
{
|
||||||
|
ethernet_header_t *ethhdr = (ethernet_header_t *)replybuf;
|
||||||
|
|
||||||
|
memcpy(ethhdr->dst_mac_addr, dhcpc->guest_macaddr, ETHERNET_MAC_ADDR_LEN);
|
||||||
|
memcpy(ethhdr->src_mac_addr, dhcpc->host_macaddr, ETHERNET_MAC_ADDR_LEN);
|
||||||
|
put_net2((Bit8u*)ðhdr->type, l3type);
|
||||||
|
}
|
||||||
|
|
||||||
|
bx_bool vnet_process_arp_request(const Bit8u *buf, Bit8u *reply, dhcp_cfg_t *dhcp)
|
||||||
|
{
|
||||||
|
arp_header_t *arprhdr = (arp_header_t *)(reply + sizeof(ethernet_header_t));
|
||||||
|
|
||||||
|
if (!memcmp(&buf[22], dhcp->guest_macaddr, 6)) {
|
||||||
|
memcpy(dhcp->guest_ipv4addr, &buf[28], 4);
|
||||||
|
if (!memcmp(&buf[38], dhcp->host_ipv4addr, 4)) {
|
||||||
|
memset(reply, 0, MIN_RX_PACKET_LEN);
|
||||||
|
memcpy(arprhdr, &buf[14], 6);
|
||||||
|
put_net2((Bit8u*)&arprhdr->opcode, ARP_OPCODE_REPLY);
|
||||||
|
memcpy((Bit8u *)arprhdr+8, dhcp->host_macaddr, ETHERNET_MAC_ADDR_LEN);
|
||||||
|
memcpy((Bit8u *)arprhdr+14, dhcp->host_ipv4addr, 4);
|
||||||
|
memcpy((Bit8u *)arprhdr+18, dhcp->guest_macaddr, ETHERNET_MAC_ADDR_LEN);
|
||||||
|
memcpy((Bit8u *)arprhdr+24, dhcp->guest_ipv4addr, 4);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bx_bool vnet_process_icmp_echo(const Bit8u *l3pkt, unsigned l3header_len,
|
||||||
|
const Bit8u *l4pkt, unsigned l4pkt_len,
|
||||||
|
Bit8u *reply)
|
||||||
|
{
|
||||||
|
if ((14U+l3header_len+l4pkt_len) > ICMP_ECHO_PACKET_MAX) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memcpy(&reply[14], l3pkt, l3header_len);
|
||||||
|
memcpy(&reply[14+l3header_len], l4pkt, l4pkt_len);
|
||||||
|
reply[14+l3header_len+0] = 0x00; // echo reply
|
||||||
|
put_net2(&reply[14+l3header_len+2],0);
|
||||||
|
put_net2(&reply[14+l3header_len+2],
|
||||||
|
ip_checksum(&reply[14+l3header_len],l4pkt_len) ^ (Bit16u)0xffff);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vnet_process_dhcp(bx_devmodel_c *netdev, const Bit8u *data, unsigned data_len, Bit8u *reply, dhcp_cfg_t *dhcp)
|
||||||
|
{
|
||||||
|
const Bit8u *opts;
|
||||||
|
unsigned opts_len;
|
||||||
|
unsigned extcode;
|
||||||
|
unsigned extlen;
|
||||||
|
const Bit8u *extdata;
|
||||||
|
unsigned dhcpmsgtype = 0;
|
||||||
|
bx_bool found_serverid = false;
|
||||||
|
bx_bool found_leasetime = false;
|
||||||
|
bx_bool found_guest_ipaddr = false;
|
||||||
|
bx_bool found_host_name = false;
|
||||||
|
Bit32u leasetime = BX_MAX_BIT32U;
|
||||||
|
const Bit8u *dhcpreqparams = NULL;
|
||||||
|
unsigned dhcpreqparams_len = 0;
|
||||||
|
Bit8u dhcpreqparam_default[8];
|
||||||
|
bx_bool dhcpreqparam_default_validflag = false;
|
||||||
|
unsigned dhcpreqparams_default_len = 0;
|
||||||
|
Bit8u *replyopts;
|
||||||
|
Bit8u replybuf[576];
|
||||||
|
char *hostname = NULL;
|
||||||
|
unsigned hostname_len = 0;
|
||||||
|
|
||||||
|
if (data_len < (236U+4U)) return 0;
|
||||||
|
if (data[0] != BOOTREQUEST) return 0;
|
||||||
|
if (data[1] != 1 || data[2] != 6) return 0;
|
||||||
|
if (memcmp(&data[28U], dhcp->guest_macaddr, 6)) return 0;
|
||||||
|
if (data[236] != 0x63 || data[237] != 0x82 ||
|
||||||
|
data[238] != 0x53 || data[239] != 0x63) return 0;
|
||||||
|
|
||||||
|
opts = &data[240];
|
||||||
|
opts_len = data_len - 240U;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (opts_len < 1) {
|
||||||
|
BX_ERROR(("dhcp: invalid request"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
extcode = *opts++;
|
||||||
|
opts_len--;
|
||||||
|
|
||||||
|
if (extcode == BOOTPOPT_PADDING) continue;
|
||||||
|
if (extcode == BOOTPOPT_END) break;
|
||||||
|
if (opts_len < 1) {
|
||||||
|
BX_ERROR(("dhcp: invalid request"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
extlen = *opts++;
|
||||||
|
opts_len--;
|
||||||
|
if (opts_len < extlen) {
|
||||||
|
BX_ERROR(("dhcp: invalid request"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
extdata = opts;
|
||||||
|
opts += extlen;
|
||||||
|
opts_len -= extlen;
|
||||||
|
|
||||||
|
switch (extcode)
|
||||||
|
{
|
||||||
|
case BOOTPOPT_DHCP_MESSAGETYPE:
|
||||||
|
if (extlen != 1)
|
||||||
|
break;
|
||||||
|
dhcpmsgtype = *extdata;
|
||||||
|
break;
|
||||||
|
case BOOTPOPT_PARAMETER_REQUEST_LIST:
|
||||||
|
if (extlen < 1)
|
||||||
|
break;
|
||||||
|
dhcpreqparams = extdata;
|
||||||
|
dhcpreqparams_len = extlen;
|
||||||
|
break;
|
||||||
|
case BOOTPOPT_SERVER_IDENTIFIER:
|
||||||
|
if (extlen != 4)
|
||||||
|
break;
|
||||||
|
if (memcmp(extdata, dhcp->host_ipv4addr, 4)) {
|
||||||
|
BX_INFO(("dhcp: request to another server"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
found_serverid = true;
|
||||||
|
break;
|
||||||
|
case BOOTPOPT_IP_ADDRESS_LEASE_TIME:
|
||||||
|
if (extlen != 4)
|
||||||
|
break;
|
||||||
|
leasetime = get_net4(&extdata[0]);
|
||||||
|
found_leasetime = true;
|
||||||
|
break;
|
||||||
|
case BOOTPOPT_REQUESTED_IP_ADDRESS:
|
||||||
|
if (extlen != 4)
|
||||||
|
break;
|
||||||
|
if (!memcmp(extdata, dhcp->default_guest_ipv4addr,4)) {
|
||||||
|
found_guest_ipaddr = true;
|
||||||
|
memcpy(dhcp->guest_ipv4addr, dhcp->default_guest_ipv4addr, 4);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BOOTPOPT_HOST_NAME:
|
||||||
|
if (extlen < 1)
|
||||||
|
break;
|
||||||
|
hostname = (char*)malloc(extlen);
|
||||||
|
memcpy(hostname, extdata, extlen);
|
||||||
|
hostname_len = extlen;
|
||||||
|
found_host_name = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BX_ERROR(("extcode %d not supported yet", extcode));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&dhcpreqparam_default,0,sizeof(dhcpreqparam_default));
|
||||||
|
memset(&replybuf[0],0,sizeof(replybuf));
|
||||||
|
replybuf[0] = BOOTREPLY;
|
||||||
|
replybuf[1] = 1;
|
||||||
|
replybuf[2] = 6;
|
||||||
|
memcpy(&replybuf[4],&data[4],4);
|
||||||
|
memcpy(&replybuf[16], dhcp->default_guest_ipv4addr, 4);
|
||||||
|
memcpy(&replybuf[20], dhcp->host_ipv4addr, 4);
|
||||||
|
memcpy(&replybuf[28],&data[28],6);
|
||||||
|
memcpy(&replybuf[44],"vnet",4);
|
||||||
|
memcpy(&replybuf[108],"pxelinux.0",10);
|
||||||
|
replybuf[236] = 0x63;
|
||||||
|
replybuf[237] = 0x82;
|
||||||
|
replybuf[238] = 0x53;
|
||||||
|
replybuf[239] = 0x63;
|
||||||
|
replyopts = &replybuf[240];
|
||||||
|
opts_len = sizeof(replybuf)/sizeof(replybuf[0])-240;
|
||||||
|
switch (dhcpmsgtype) {
|
||||||
|
case DHCPDISCOVER:
|
||||||
|
BX_DEBUG(("dhcp server: DHCPDISCOVER"));
|
||||||
|
// reset guest address; answer must be broadcasted to unconfigured IP
|
||||||
|
memcpy(dhcp->guest_ipv4addr, broadcast_ipv4addr1, 4);
|
||||||
|
*replyopts ++ = BOOTPOPT_DHCP_MESSAGETYPE;
|
||||||
|
*replyopts ++ = 1;
|
||||||
|
*replyopts ++ = DHCPOFFER;
|
||||||
|
opts_len -= 3;
|
||||||
|
dhcpreqparam_default[0] = BOOTPOPT_IP_ADDRESS_LEASE_TIME;
|
||||||
|
dhcpreqparam_default[1] = BOOTPOPT_SERVER_IDENTIFIER;
|
||||||
|
if (found_host_name) {
|
||||||
|
dhcpreqparam_default[2] = BOOTPOPT_HOST_NAME;
|
||||||
|
}
|
||||||
|
dhcpreqparam_default_validflag = true;
|
||||||
|
break;
|
||||||
|
case DHCPREQUEST:
|
||||||
|
BX_DEBUG(("dhcp server: DHCPREQUEST"));
|
||||||
|
// check ciaddr.
|
||||||
|
if (found_serverid || found_guest_ipaddr || (!memcmp(&data[12], dhcp->default_guest_ipv4addr, 4))) {
|
||||||
|
*replyopts ++ = BOOTPOPT_DHCP_MESSAGETYPE;
|
||||||
|
*replyopts ++ = 1;
|
||||||
|
*replyopts ++ = DHCPACK;
|
||||||
|
opts_len -= 3;
|
||||||
|
dhcpreqparam_default[0] = BOOTPOPT_IP_ADDRESS_LEASE_TIME;
|
||||||
|
if (!found_serverid) {
|
||||||
|
dhcpreqparam_default[1] = BOOTPOPT_SERVER_IDENTIFIER;
|
||||||
|
}
|
||||||
|
dhcpreqparam_default_validflag = true;
|
||||||
|
} else {
|
||||||
|
*replyopts ++ = BOOTPOPT_DHCP_MESSAGETYPE;
|
||||||
|
*replyopts ++ = 1;
|
||||||
|
*replyopts ++ = DHCPNAK;
|
||||||
|
opts_len -= 3;
|
||||||
|
if (found_leasetime) {
|
||||||
|
dhcpreqparam_default[dhcpreqparams_default_len++] = BOOTPOPT_IP_ADDRESS_LEASE_TIME;
|
||||||
|
dhcpreqparam_default_validflag = true;
|
||||||
|
}
|
||||||
|
if (!found_serverid) {
|
||||||
|
dhcpreqparam_default[dhcpreqparams_default_len++] = BOOTPOPT_SERVER_IDENTIFIER;
|
||||||
|
dhcpreqparam_default_validflag = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BX_ERROR(("dhcp server: unsupported message type %u",dhcpmsgtype));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
while (dhcpreqparams_len-- > 0) {
|
||||||
|
switch (*dhcpreqparams++) {
|
||||||
|
case BOOTPOPT_SUBNETMASK:
|
||||||
|
BX_DEBUG(("provide BOOTPOPT_SUBNETMASK"));
|
||||||
|
if (opts_len < 6) {
|
||||||
|
BX_ERROR(("option buffer is insufficient"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
opts_len -= 6;
|
||||||
|
*replyopts ++ = BOOTPOPT_SUBNETMASK;
|
||||||
|
*replyopts ++ = 4;
|
||||||
|
memcpy(replyopts,subnetmask_ipv4addr,4);
|
||||||
|
replyopts += 4;
|
||||||
|
break;
|
||||||
|
case BOOTPOPT_ROUTER_OPTION:
|
||||||
|
BX_DEBUG(("provide BOOTPOPT_ROUTER_OPTION"));
|
||||||
|
if (opts_len < 6) {
|
||||||
|
BX_ERROR(("option buffer is insufficient"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
opts_len -= 6;
|
||||||
|
*replyopts ++ = BOOTPOPT_ROUTER_OPTION;
|
||||||
|
*replyopts ++ = 4;
|
||||||
|
memcpy(replyopts, dhcp->host_ipv4addr, 4);
|
||||||
|
replyopts += 4;
|
||||||
|
break;
|
||||||
|
case BOOTPOPT_DOMAIN_NAMESERVER:
|
||||||
|
if (dhcp->dns_ipv4addr[0] != 0) {
|
||||||
|
BX_DEBUG(("provide BOOTPOPT_DOMAIN_NAMESERVER"));
|
||||||
|
if (opts_len < 6) {
|
||||||
|
BX_ERROR(("option buffer is insufficient"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
opts_len -= 6;
|
||||||
|
*replyopts ++ = BOOTPOPT_DOMAIN_NAMESERVER;
|
||||||
|
*replyopts ++ = 4;
|
||||||
|
memcpy(replyopts, dhcp->dns_ipv4addr, 4);
|
||||||
|
replyopts += 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BOOTPOPT_BROADCAST_ADDRESS:
|
||||||
|
BX_DEBUG(("provide BOOTPOPT_BROADCAST_ADDRESS"));
|
||||||
|
if (opts_len < 6) {
|
||||||
|
BX_ERROR(("option buffer is insufficient"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
opts_len -= 6;
|
||||||
|
*replyopts ++ = BOOTPOPT_BROADCAST_ADDRESS;
|
||||||
|
*replyopts ++ = 4;
|
||||||
|
memcpy(replyopts, dhcp->host_ipv4addr, 3);
|
||||||
|
replyopts += 3;
|
||||||
|
*replyopts ++ = 0xff;
|
||||||
|
break;
|
||||||
|
case BOOTPOPT_IP_ADDRESS_LEASE_TIME:
|
||||||
|
BX_DEBUG(("provide BOOTPOPT_IP_ADDRESS_LEASE_TIME"));
|
||||||
|
if (opts_len < 6) {
|
||||||
|
BX_ERROR(("option buffer is insufficient"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
opts_len -= 6;
|
||||||
|
*replyopts ++ = BOOTPOPT_IP_ADDRESS_LEASE_TIME;
|
||||||
|
*replyopts ++ = 4;
|
||||||
|
if (leasetime < DEFAULT_LEASE_TIME) {
|
||||||
|
put_net4(replyopts, leasetime);
|
||||||
|
} else {
|
||||||
|
put_net4(replyopts, DEFAULT_LEASE_TIME);
|
||||||
|
}
|
||||||
|
replyopts += 4;
|
||||||
|
break;
|
||||||
|
case BOOTPOPT_SERVER_IDENTIFIER:
|
||||||
|
BX_DEBUG(("provide BOOTPOPT_SERVER_IDENTIFIER"));
|
||||||
|
if (opts_len < 6) {
|
||||||
|
BX_ERROR(("option buffer is insufficient"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
opts_len -= 6;
|
||||||
|
*replyopts ++ = BOOTPOPT_SERVER_IDENTIFIER;
|
||||||
|
*replyopts ++ = 4;
|
||||||
|
memcpy(replyopts, dhcp->host_ipv4addr,4);
|
||||||
|
replyopts += 4;
|
||||||
|
break;
|
||||||
|
case BOOTPOPT_RENEWAL_TIME:
|
||||||
|
BX_DEBUG(("provide BOOTPOPT_RENEWAL_TIME"));
|
||||||
|
if (opts_len < 6) {
|
||||||
|
BX_ERROR(("option buffer is insufficient"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
opts_len -= 6;
|
||||||
|
*replyopts ++ = BOOTPOPT_RENEWAL_TIME;
|
||||||
|
*replyopts ++ = 4;
|
||||||
|
put_net4(replyopts, 600);
|
||||||
|
replyopts += 4;
|
||||||
|
break;
|
||||||
|
case BOOTPOPT_REBINDING_TIME:
|
||||||
|
BX_DEBUG(("provide BOOTPOPT_REBINDING_TIME"));
|
||||||
|
if (opts_len < 6) {
|
||||||
|
BX_ERROR(("option buffer is insufficient"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
opts_len -= 6;
|
||||||
|
*replyopts ++ = BOOTPOPT_REBINDING_TIME;
|
||||||
|
*replyopts ++ = 4;
|
||||||
|
put_net4(replyopts, 1800);
|
||||||
|
replyopts += 4;
|
||||||
|
break;
|
||||||
|
case BOOTPOPT_HOST_NAME:
|
||||||
|
if (hostname != NULL) {
|
||||||
|
BX_DEBUG(("provide BOOTPOPT_HOST_NAME"));
|
||||||
|
if (opts_len < (hostname_len + 2)) {
|
||||||
|
free(hostname);
|
||||||
|
BX_ERROR(("option buffer is insufficient"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
opts_len -= (hostname_len + 2);
|
||||||
|
*replyopts ++ = BOOTPOPT_HOST_NAME;
|
||||||
|
*replyopts ++ = hostname_len;
|
||||||
|
memcpy(replyopts, hostname, hostname_len);
|
||||||
|
replyopts += hostname_len;
|
||||||
|
free(hostname);
|
||||||
|
hostname = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if (*(dhcpreqparams-1) != 0) {
|
||||||
|
BX_ERROR(("dhcp server: requested parameter %u not supported yet",*(dhcpreqparams-1)));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dhcpreqparam_default_validflag) break;
|
||||||
|
dhcpreqparams = &dhcpreqparam_default[0];
|
||||||
|
dhcpreqparams_len = sizeof(dhcpreqparam_default);
|
||||||
|
dhcpreqparam_default_validflag = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts_len < 1) {
|
||||||
|
BX_ERROR(("option buffer is insufficient"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
opts_len -= 2;
|
||||||
|
*replyopts ++ = BOOTPOPT_END;
|
||||||
|
|
||||||
|
opts_len = replyopts - &replybuf[0];
|
||||||
|
if (opts_len < (236U+64U)) {
|
||||||
|
opts_len = (236U+64U); // BOOTP
|
||||||
|
}
|
||||||
|
if (opts_len < (548U)) {
|
||||||
|
opts_len = 548U; // DHCP
|
||||||
|
}
|
||||||
|
memcpy(reply, replybuf, opts_len);
|
||||||
|
return opts_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TFTP support
|
||||||
|
|
||||||
|
typedef struct tftp_session {
|
||||||
|
char filename[BX_PATHNAME_LEN];
|
||||||
|
Bit16u tid;
|
||||||
|
bx_bool write;
|
||||||
|
unsigned options;
|
||||||
|
size_t tsize_val;
|
||||||
|
unsigned blksize_val;
|
||||||
|
unsigned timeout_val;
|
||||||
|
unsigned timestamp;
|
||||||
|
struct tftp_session *next;
|
||||||
|
} tftp_session_t;
|
||||||
|
|
||||||
|
tftp_session_t *tftp_sessions = NULL;
|
||||||
|
|
||||||
|
tftp_session_t *tftp_new_session(Bit16u req_tid, bx_bool mode, const char *tpath, const char *tname)
|
||||||
|
{
|
||||||
|
tftp_session_t *s = new tftp_session_t;
|
||||||
|
s->tid = req_tid;
|
||||||
|
s->write = mode;
|
||||||
|
s->options = 0;
|
||||||
|
s->blksize_val = TFTP_DEFAULT_BLKSIZE;
|
||||||
|
s->timeout_val = TFTP_DEFAULT_TIMEOUT;
|
||||||
|
s->next = tftp_sessions;
|
||||||
|
tftp_sessions = s;
|
||||||
|
if ((strlen(tname) > 0) && ((strlen(tpath) + strlen(tname)) < BX_PATHNAME_LEN)) {
|
||||||
|
sprintf(s->filename, "%s/%s", tpath, tname);
|
||||||
|
} else {
|
||||||
|
s->filename[0] = 0;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
tftp_session_t *tftp_find_session(Bit16u tid)
|
||||||
|
{
|
||||||
|
tftp_session_t *s = tftp_sessions;
|
||||||
|
while (s != NULL) {
|
||||||
|
if (s->tid != tid)
|
||||||
|
s = s->next;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tftp_remove_session(tftp_session_t *s)
|
||||||
|
{
|
||||||
|
tftp_session_t *last;
|
||||||
|
|
||||||
|
if (tftp_sessions == s) {
|
||||||
|
tftp_sessions = s->next;
|
||||||
|
} else {
|
||||||
|
last = tftp_sessions;
|
||||||
|
while (last != NULL) {
|
||||||
|
if (last->next != s)
|
||||||
|
last = last->next;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (last) {
|
||||||
|
last->next = s->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tftp_update_timestamp(tftp_session_t *s)
|
||||||
|
{
|
||||||
|
#ifndef BXHUB
|
||||||
|
s->timestamp = (unsigned)(bx_pc_system.time_usec() / 1000000);
|
||||||
|
#else
|
||||||
|
s->timestamp = (unsigned)time(NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void tftp_timeout_check()
|
||||||
|
{
|
||||||
|
#ifndef BXHUB
|
||||||
|
unsigned curtime = (unsigned)(bx_pc_system.time_usec() / 1000000);
|
||||||
|
#else
|
||||||
|
unsigned curtime = (unsigned)time(NULL);
|
||||||
|
#endif
|
||||||
|
tftp_session_t *next, *s = tftp_sessions;
|
||||||
|
|
||||||
|
while (s != NULL) {
|
||||||
|
if ((curtime - s->timestamp) > s->timeout_val) {
|
||||||
|
next = s->next;
|
||||||
|
tftp_remove_session(s);
|
||||||
|
s = next;
|
||||||
|
} else {
|
||||||
|
s = s->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int tftp_send_error(Bit8u *buffer, unsigned code, const char *msg, tftp_session_t *s)
|
||||||
|
{
|
||||||
|
put_net2(buffer, TFTP_ERROR);
|
||||||
|
put_net2(buffer + 2, code);
|
||||||
|
strcpy((char*)buffer + 4, msg);
|
||||||
|
if (s != NULL) {
|
||||||
|
tftp_remove_session(s);
|
||||||
|
}
|
||||||
|
return (strlen(msg) + 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
int tftp_send_data(Bit8u *buffer, unsigned block_nr, tftp_session_t *s)
|
||||||
|
{
|
||||||
|
char msg[BX_PATHNAME_LEN];
|
||||||
|
int rd;
|
||||||
|
|
||||||
|
FILE *fp = fopen(s->filename, "rb");
|
||||||
|
if (!fp) {
|
||||||
|
sprintf(msg, "File not found: %s", s->filename);
|
||||||
|
return tftp_send_error(buffer, 1, msg, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fseek(fp, (block_nr - 1) * s->blksize_val, SEEK_SET) < 0) {
|
||||||
|
fclose(fp);
|
||||||
|
return tftp_send_error(buffer, 3, "Block not seekable", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
rd = fread(buffer + 4, 1, s->blksize_val, fp);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
if (rd < 0) {
|
||||||
|
return tftp_send_error(buffer, 3, "Block not readable", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
put_net2(buffer, TFTP_DATA);
|
||||||
|
put_net2(buffer + 2, block_nr);
|
||||||
|
if (rd < (int)s->blksize_val) {
|
||||||
|
tftp_remove_session(s);
|
||||||
|
} else {
|
||||||
|
tftp_update_timestamp(s);
|
||||||
|
}
|
||||||
|
return (rd + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
int tftp_send_ack(Bit8u *buffer, unsigned block_nr)
|
||||||
|
{
|
||||||
|
put_net2(buffer, TFTP_ACK);
|
||||||
|
put_net2(buffer + 2, block_nr);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tftp_send_optack(Bit8u *buffer, tftp_session_t *s)
|
||||||
|
{
|
||||||
|
Bit8u *p = buffer;
|
||||||
|
put_net2(p, TFTP_OPTACK);
|
||||||
|
p += 2;
|
||||||
|
if (s->options & TFTP_OPTION_TSIZE) {
|
||||||
|
*p++='t'; *p++='s'; *p++='i'; *p++='z'; *p++='e'; *p++='\0';
|
||||||
|
sprintf((char *)p, "%lu", (unsigned long)s->tsize_val);
|
||||||
|
p += strlen((const char *)p) + 1;
|
||||||
|
}
|
||||||
|
if (s->options & TFTP_OPTION_BLKSIZE) {
|
||||||
|
*p++='b'; *p++='l'; *p++='k'; *p++='s'; *p++='i'; *p++='z'; *p++='e'; *p++='\0';
|
||||||
|
sprintf((char *)p, "%u", s->blksize_val);
|
||||||
|
p += strlen((const char *)p) + 1;
|
||||||
|
}
|
||||||
|
if (s->options & TFTP_OPTION_TIMEOUT) {
|
||||||
|
*p++='t'; *p++='i'; *p++='m'; *p++='e'; *p++='o'; *p++='u'; *p++='t'; *p++='\0';
|
||||||
|
sprintf((char *)p, "%u", s->timeout_val);
|
||||||
|
p += strlen((const char *)p) + 1;
|
||||||
|
}
|
||||||
|
tftp_update_timestamp(s);
|
||||||
|
return (p - buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tftp_parse_options(bx_devmodel_c *netdev, const char *mode, const Bit8u *data,
|
||||||
|
unsigned data_len, tftp_session_t *s)
|
||||||
|
{
|
||||||
|
while (mode < (const char*)data + data_len) {
|
||||||
|
if (memcmp(mode, "octet\0", 6) == 0) {
|
||||||
|
s->options |= TFTP_OPTION_OCTET;
|
||||||
|
mode += 6;
|
||||||
|
} else if (memcmp(mode, "tsize\0", 6) == 0) {
|
||||||
|
s->options |= TFTP_OPTION_TSIZE; // size needed
|
||||||
|
mode += 6;
|
||||||
|
if (s->write) {
|
||||||
|
s->tsize_val = atoi(mode);
|
||||||
|
}
|
||||||
|
mode += strlen(mode)+1;
|
||||||
|
} else if (memcmp(mode, "blksize\0", 8) == 0) {
|
||||||
|
s->options |= TFTP_OPTION_BLKSIZE;
|
||||||
|
mode += 8;
|
||||||
|
s->blksize_val = atoi(mode);
|
||||||
|
if (s->blksize_val > TFTP_BUFFER_SIZE) {
|
||||||
|
BX_ERROR(("tftp req: blksize value %d not supported - using %d instead",
|
||||||
|
s->blksize_val, TFTP_BUFFER_SIZE));
|
||||||
|
s->blksize_val = TFTP_BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
mode += strlen(mode)+1;
|
||||||
|
} else if (memcmp(mode, "timeout\0", 8) == 0) {
|
||||||
|
s->options |= TFTP_OPTION_TIMEOUT;
|
||||||
|
mode += 8;
|
||||||
|
s->timeout_val = atoi(mode);
|
||||||
|
if ((s->timeout_val < 1) || (s->timeout_val > 255)) {
|
||||||
|
BX_ERROR(("tftp req: timeout value %d not supported - using %d instead",
|
||||||
|
s->timeout_val, TFTP_DEFAULT_TIMEOUT));
|
||||||
|
s->timeout_val = TFTP_DEFAULT_TIMEOUT;
|
||||||
|
}
|
||||||
|
mode += strlen(mode)+1;
|
||||||
|
} else {
|
||||||
|
BX_ERROR(("tftp req: unknown option %s", mode));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int vnet_process_tftp(bx_devmodel_c *netdev, const Bit8u *data, unsigned data_len, Bit16u req_tid, Bit8u *reply, const char *tftp_rootdir)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
unsigned block_nr;
|
||||||
|
unsigned tftp_len;
|
||||||
|
tftp_session_t *s;
|
||||||
|
|
||||||
|
tftp_timeout_check();
|
||||||
|
s = tftp_find_session(req_tid);
|
||||||
|
switch (get_net2(data)) {
|
||||||
|
case TFTP_RRQ:
|
||||||
|
{
|
||||||
|
if (s != NULL) {
|
||||||
|
tftp_remove_session(s);
|
||||||
|
}
|
||||||
|
strncpy((char*)reply, (const char*)data + 2, data_len - 2);
|
||||||
|
reply[data_len - 4] = 0;
|
||||||
|
|
||||||
|
s = tftp_new_session(req_tid, 0, tftp_rootdir, (const char*)reply);
|
||||||
|
if (strlen(s->filename) == 0) {
|
||||||
|
return tftp_send_error(reply, 1, "Illegal file name", s);
|
||||||
|
}
|
||||||
|
// options
|
||||||
|
if (strlen((char*)reply) < data_len - 2) {
|
||||||
|
const char *mode = (const char*)data + 2 + strlen((char*)reply) + 1;
|
||||||
|
tftp_parse_options(netdev, mode, data, data_len, s);
|
||||||
|
}
|
||||||
|
if (!(s->options & TFTP_OPTION_OCTET)) {
|
||||||
|
return tftp_send_error(reply, 4, "Unsupported transfer mode", NULL);
|
||||||
|
}
|
||||||
|
if (s->options & TFTP_OPTION_TSIZE) {
|
||||||
|
struct stat stbuf;
|
||||||
|
if (stat(s->filename, &stbuf) < 0) {
|
||||||
|
s->options &= ~TFTP_OPTION_TSIZE;
|
||||||
|
} else {
|
||||||
|
s->tsize_val = (size_t)stbuf.st_size;
|
||||||
|
BX_DEBUG(("tftp filesize: %lu", (unsigned long)s->tsize_val));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((s->options & ~TFTP_OPTION_OCTET) > 0) {
|
||||||
|
return tftp_send_optack(reply, s);
|
||||||
|
} else {
|
||||||
|
return tftp_send_data(reply, 1, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TFTP_WRQ:
|
||||||
|
{
|
||||||
|
if (s != NULL) {
|
||||||
|
tftp_remove_session(s);
|
||||||
|
}
|
||||||
|
strncpy((char*)reply, (const char*)data + 2, data_len - 2);
|
||||||
|
reply[data_len - 4] = 0;
|
||||||
|
|
||||||
|
s = tftp_new_session(req_tid, 1, tftp_rootdir, (const char*)reply);
|
||||||
|
if (strlen(s->filename) == 0) {
|
||||||
|
return tftp_send_error(reply, 1, "Illegal file name", s);
|
||||||
|
}
|
||||||
|
// options
|
||||||
|
if (strlen((char*)reply) < data_len - 2) {
|
||||||
|
const char *mode = (const char*)data + 2 + strlen((char*)reply) + 1;
|
||||||
|
tftp_parse_options(netdev, mode, data, data_len, s);
|
||||||
|
}
|
||||||
|
if (!(s->options & TFTP_OPTION_OCTET)) {
|
||||||
|
return tftp_send_error(reply, 4, "Unsupported transfer mode", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
fp = fopen(s->filename, "rb");
|
||||||
|
if (fp) {
|
||||||
|
fclose(fp);
|
||||||
|
return tftp_send_error(reply, 6, "File exists", s);
|
||||||
|
}
|
||||||
|
fp = fopen(s->filename, "wb");
|
||||||
|
if (!fp) {
|
||||||
|
return tftp_send_error(reply, 2, "Access violation", s);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
if ((s->options & ~TFTP_OPTION_OCTET) > 0) {
|
||||||
|
return tftp_send_optack(reply, s);
|
||||||
|
} else {
|
||||||
|
tftp_update_timestamp(s);
|
||||||
|
return tftp_send_ack(reply, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TFTP_DATA:
|
||||||
|
if (s != NULL) {
|
||||||
|
if (s->write == 1) {
|
||||||
|
block_nr = get_net2(data + 2);
|
||||||
|
strncpy((char*)reply, (const char*)data + 4, data_len - 4);
|
||||||
|
tftp_len = data_len - 4;
|
||||||
|
reply[tftp_len] = 0;
|
||||||
|
if (tftp_len <= s->blksize_val) {
|
||||||
|
fp = fopen(s->filename, "ab");
|
||||||
|
if (!fp) {
|
||||||
|
return tftp_send_error(reply, 2, "Access violation", s);
|
||||||
|
}
|
||||||
|
if (fseek(fp, (block_nr - 1) * TFTP_BUFFER_SIZE, SEEK_SET) < 0) {
|
||||||
|
fclose(fp);
|
||||||
|
return tftp_send_error(reply, 3, "Block not seekable", s);
|
||||||
|
}
|
||||||
|
fwrite(reply, 1, tftp_len, fp);
|
||||||
|
fclose(fp);
|
||||||
|
if (tftp_len < s->blksize_val) {
|
||||||
|
tftp_remove_session(s);
|
||||||
|
} else {
|
||||||
|
tftp_update_timestamp(s);
|
||||||
|
}
|
||||||
|
return tftp_send_ack(reply, block_nr);
|
||||||
|
} else {
|
||||||
|
return tftp_send_error(reply, 4, "Illegal request", s);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return tftp_send_error(reply, 4, "Illegal request", s);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return tftp_send_error(reply, 5, "Unknown transfer ID", s);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TFTP_ACK:
|
||||||
|
if (s != NULL) {
|
||||||
|
if (s->write == 0) {
|
||||||
|
return tftp_send_data(reply, get_net2(data + 2) + 1, s);
|
||||||
|
} else {
|
||||||
|
return tftp_send_error(reply, 4, "Illegal request", s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TFTP_ERROR:
|
||||||
|
if (s != NULL) {
|
||||||
|
tftp_remove_session(s);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
BX_ERROR(("TFTP unknown opt %d", get_net2(data)));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* if BX_NETWORKING */
|
149
bochs/iodev/network/netutil.h
Normal file
149
bochs/iodev/network/netutil.h
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
// $Id$
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2004-2017 The Bochs Project
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
//
|
||||||
|
|
||||||
|
// netutil.h - shared code for eth_vnet.cc and bxhub.cc
|
||||||
|
|
||||||
|
#ifndef BX_NETUTIL_H
|
||||||
|
#define BX_NETUTIL_H
|
||||||
|
|
||||||
|
#define ETHERNET_MAC_ADDR_LEN 6
|
||||||
|
#define ETHERNET_TYPE_IPV4 0x0800
|
||||||
|
#define ETHERNET_TYPE_ARP 0x0806
|
||||||
|
|
||||||
|
#define ARP_OPCODE_REQUEST 1
|
||||||
|
#define ARP_OPCODE_REPLY 2
|
||||||
|
#define ARP_OPCODE_REV_REQUEST 3
|
||||||
|
#define ARP_OPCODE_REV_REPLY 4
|
||||||
|
|
||||||
|
#define ICMP_ECHO_PACKET_MAX 128
|
||||||
|
|
||||||
|
#define TFTP_BUFFER_SIZE 1024
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
#elif defined(__MWERKS__) && defined(macintosh)
|
||||||
|
#pragma options align=packed
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct ethernet_header {
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER>=1300)
|
||||||
|
__declspec(align(1))
|
||||||
|
#endif
|
||||||
|
Bit8u dst_mac_addr[ETHERNET_MAC_ADDR_LEN];
|
||||||
|
Bit8u src_mac_addr[ETHERNET_MAC_ADDR_LEN];
|
||||||
|
Bit16u type;
|
||||||
|
}
|
||||||
|
#if !defined(_MSC_VER)
|
||||||
|
GCC_ATTRIBUTE((packed))
|
||||||
|
#endif
|
||||||
|
ethernet_header_t;
|
||||||
|
|
||||||
|
typedef struct arp_header {
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER>=1300)
|
||||||
|
__declspec(align(1))
|
||||||
|
#endif
|
||||||
|
Bit16u hw_addr_space;
|
||||||
|
Bit16u proto_addr_space;
|
||||||
|
Bit8u hw_addr_len;
|
||||||
|
Bit8u proto_addr_len;
|
||||||
|
Bit16u opcode;
|
||||||
|
/* HW address of sender */
|
||||||
|
/* Protocol address of sender */
|
||||||
|
/* HW address of target*/
|
||||||
|
/* Protocol address of target */
|
||||||
|
}
|
||||||
|
#if !defined(_MSC_VER)
|
||||||
|
GCC_ATTRIBUTE((packed))
|
||||||
|
#endif
|
||||||
|
arp_header_t;
|
||||||
|
|
||||||
|
typedef struct ip_header {
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER>=1300)
|
||||||
|
__declspec(align(1))
|
||||||
|
#endif
|
||||||
|
#ifdef BX_LITTLE_ENDIAN
|
||||||
|
Bit8u header_len : 4;
|
||||||
|
Bit8u version : 4;
|
||||||
|
#else
|
||||||
|
Bit8u version : 4;
|
||||||
|
Bit8u header_len : 4;
|
||||||
|
#endif
|
||||||
|
Bit8u tos;
|
||||||
|
Bit16u total_len;
|
||||||
|
Bit16u id;
|
||||||
|
Bit16u frag_offs;
|
||||||
|
Bit8u ttl;
|
||||||
|
Bit8u protocol;
|
||||||
|
Bit16u checksum;
|
||||||
|
Bit32u src_addr;
|
||||||
|
Bit32u dst_addr;
|
||||||
|
}
|
||||||
|
#if !defined(_MSC_VER)
|
||||||
|
GCC_ATTRIBUTE((packed))
|
||||||
|
#endif
|
||||||
|
ip_header_t;
|
||||||
|
|
||||||
|
typedef struct udp_header {
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER>=1300)
|
||||||
|
__declspec(align(1))
|
||||||
|
#endif
|
||||||
|
Bit16u src_port;
|
||||||
|
Bit16u dst_port;
|
||||||
|
Bit16u length;
|
||||||
|
Bit16u checksum;
|
||||||
|
}
|
||||||
|
#if !defined(_MSC_VER)
|
||||||
|
GCC_ATTRIBUTE((packed))
|
||||||
|
#endif
|
||||||
|
udp_header_t;
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma pack(pop)
|
||||||
|
#elif defined(__MWERKS__) && defined(macintosh)
|
||||||
|
#pragma options align=reset
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// DHCP configuration structure
|
||||||
|
typedef struct {
|
||||||
|
Bit8u host_macaddr[6];
|
||||||
|
Bit8u guest_macaddr[6];
|
||||||
|
Bit8u host_ipv4addr[4];
|
||||||
|
Bit8u default_guest_ipv4addr[4];
|
||||||
|
Bit8u guest_ipv4addr[4];
|
||||||
|
Bit8u dns_ipv4addr[4];
|
||||||
|
} dhcp_cfg_t;
|
||||||
|
|
||||||
|
// vnet functions shared with bxhub
|
||||||
|
#ifdef BXHUB
|
||||||
|
#define bx_devmodel_c void
|
||||||
|
#endif
|
||||||
|
Bit16u ip_checksum(const Bit8u *buf, unsigned buf_len);
|
||||||
|
void vnet_prepare_reply(Bit8u *replybuf, unsigned l3type, dhcp_cfg_t *dhcpc);
|
||||||
|
bx_bool vnet_process_arp_request(const Bit8u *buf, Bit8u *reply, dhcp_cfg_t *dhcp);
|
||||||
|
bx_bool vnet_process_icmp_echo(const Bit8u *l3pkt, unsigned l3header_len,
|
||||||
|
const Bit8u *l4pkt, unsigned l4pkt_len,
|
||||||
|
Bit8u *reply);
|
||||||
|
int vnet_process_dhcp(bx_devmodel_c *netdev, const Bit8u *data, unsigned data_len,
|
||||||
|
Bit8u *reply, dhcp_cfg_t *dhcp);
|
||||||
|
int vnet_process_tftp(bx_devmodel_c *netdev, const Bit8u *data, unsigned data_len,
|
||||||
|
Bit16u req_tid, Bit8u *reply, const char *tftp_rootdir);
|
||||||
|
|
||||||
|
#endif
|
@ -57,6 +57,7 @@ typedef int SOCKET;
|
|||||||
#include "misc/bxcompat.h"
|
#include "misc/bxcompat.h"
|
||||||
#include "osdep.h"
|
#include "osdep.h"
|
||||||
#include "iodev/network/netmod.h"
|
#include "iodev/network/netmod.h"
|
||||||
|
#include "iodev/network/netutil.h"
|
||||||
|
|
||||||
#define BXHUB_MAX_CLIENTS 6
|
#define BXHUB_MAX_CLIENTS 6
|
||||||
|
|
||||||
|
@ -42,14 +42,18 @@
|
|||||||
#define GUI_PLUGIN_FINI_FMT_STRING "lib%s_gui_plugin_fini"
|
#define GUI_PLUGIN_FINI_FMT_STRING "lib%s_gui_plugin_fini"
|
||||||
#define SOUND_PLUGIN_INIT_FMT_STRING "lib%s_sound_plugin_init"
|
#define SOUND_PLUGIN_INIT_FMT_STRING "lib%s_sound_plugin_init"
|
||||||
#define SOUND_PLUGIN_FINI_FMT_STRING "lib%s_sound_plugin_fini"
|
#define SOUND_PLUGIN_FINI_FMT_STRING "lib%s_sound_plugin_fini"
|
||||||
|
#define NET_PLUGIN_INIT_FMT_STRING "lib%s_net_plugin_init"
|
||||||
|
#define NET_PLUGIN_FINI_FMT_STRING "lib%s_net_plugin_fini"
|
||||||
#define PLUGIN_PATH ""
|
#define PLUGIN_PATH ""
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#define PLUGIN_FILENAME_FORMAT "libbx_%s.so"
|
#define PLUGIN_FILENAME_FORMAT "libbx_%s.so"
|
||||||
#define SOUND_PLUGIN_FILENAME_FORMAT "libbx_sound%s.so"
|
#define SOUND_PLUGIN_FILENAME_FORMAT "libbx_sound%s.so"
|
||||||
|
#define NET_PLUGIN_FILENAME_FORMAT "libbx_eth_%s.so"
|
||||||
#else
|
#else
|
||||||
#define PLUGIN_FILENAME_FORMAT "bx_%s.dll"
|
#define PLUGIN_FILENAME_FORMAT "bx_%s.dll"
|
||||||
#define SOUND_PLUGIN_FILENAME_FORMAT "bx_sound%s.dll"
|
#define SOUND_PLUGIN_FILENAME_FORMAT "bx_sound%s.dll"
|
||||||
|
#define NET_PLUGIN_FILENAME_FORMAT "bx_eth_%s.dll"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
logfunctions *pluginlog;
|
logfunctions *pluginlog;
|
||||||
@ -334,10 +338,12 @@ void plugin_load(char *name, plugintype_t type)
|
|||||||
plugin->initialized = 0;
|
plugin->initialized = 0;
|
||||||
|
|
||||||
char plugin_filename[BX_PATHNAME_LEN], tmpname[BX_PATHNAME_LEN];
|
char plugin_filename[BX_PATHNAME_LEN], tmpname[BX_PATHNAME_LEN];
|
||||||
if (type != PLUGTYPE_SOUND) {
|
if (type == PLUGTYPE_SOUND) {
|
||||||
sprintf(tmpname, PLUGIN_FILENAME_FORMAT, name);
|
|
||||||
} else {
|
|
||||||
sprintf(tmpname, SOUND_PLUGIN_FILENAME_FORMAT, name);
|
sprintf(tmpname, SOUND_PLUGIN_FILENAME_FORMAT, name);
|
||||||
|
} else if (type == PLUGTYPE_NETWORK) {
|
||||||
|
sprintf(tmpname, NET_PLUGIN_FILENAME_FORMAT, name);
|
||||||
|
} else {
|
||||||
|
sprintf(tmpname, PLUGIN_FILENAME_FORMAT, name);
|
||||||
}
|
}
|
||||||
sprintf(plugin_filename, "%s%s", PLUGIN_PATH, tmpname);
|
sprintf(plugin_filename, "%s%s", PLUGIN_PATH, tmpname);
|
||||||
|
|
||||||
@ -383,6 +389,8 @@ void plugin_load(char *name, plugintype_t type)
|
|||||||
sprintf(tmpname, GUI_PLUGIN_INIT_FMT_STRING, name);
|
sprintf(tmpname, GUI_PLUGIN_INIT_FMT_STRING, name);
|
||||||
} else if (type == PLUGTYPE_SOUND) {
|
} else if (type == PLUGTYPE_SOUND) {
|
||||||
sprintf(tmpname, SOUND_PLUGIN_INIT_FMT_STRING, name);
|
sprintf(tmpname, SOUND_PLUGIN_INIT_FMT_STRING, name);
|
||||||
|
} else if (type == PLUGTYPE_NETWORK) {
|
||||||
|
sprintf(tmpname, NET_PLUGIN_INIT_FMT_STRING, name);
|
||||||
} else if (type != PLUGTYPE_USER) {
|
} else if (type != PLUGTYPE_USER) {
|
||||||
sprintf(tmpname, PLUGIN_INIT_FMT_STRING, name);
|
sprintf(tmpname, PLUGIN_INIT_FMT_STRING, name);
|
||||||
} else {
|
} else {
|
||||||
@ -406,6 +414,8 @@ void plugin_load(char *name, plugintype_t type)
|
|||||||
sprintf(tmpname, GUI_PLUGIN_FINI_FMT_STRING, name);
|
sprintf(tmpname, GUI_PLUGIN_FINI_FMT_STRING, name);
|
||||||
} else if (type == PLUGTYPE_SOUND) {
|
} else if (type == PLUGTYPE_SOUND) {
|
||||||
sprintf(tmpname, SOUND_PLUGIN_FINI_FMT_STRING, name);
|
sprintf(tmpname, SOUND_PLUGIN_FINI_FMT_STRING, name);
|
||||||
|
} else if (type == PLUGTYPE_NETWORK) {
|
||||||
|
sprintf(tmpname, NET_PLUGIN_FINI_FMT_STRING, name);
|
||||||
} else if (type != PLUGTYPE_USER) {
|
} else if (type != PLUGTYPE_USER) {
|
||||||
sprintf(tmpname, PLUGIN_FINI_FMT_STRING, name);
|
sprintf(tmpname, PLUGIN_FINI_FMT_STRING, name);
|
||||||
} else {
|
} else {
|
||||||
@ -799,6 +809,7 @@ typedef struct {
|
|||||||
#define BUILTIN_GUI_PLUGIN_ENTRY(mod) {#mod, PLUGTYPE_GUI, lib##mod##_gui_plugin_init, lib##mod##_gui_plugin_fini, 0}
|
#define BUILTIN_GUI_PLUGIN_ENTRY(mod) {#mod, PLUGTYPE_GUI, lib##mod##_gui_plugin_init, lib##mod##_gui_plugin_fini, 0}
|
||||||
#define BUILTIN_OPT_PLUGIN_ENTRY(mod) {#mod, PLUGTYPE_OPTIONAL, lib##mod##_LTX_plugin_init, lib##mod##_LTX_plugin_fini, 0}
|
#define BUILTIN_OPT_PLUGIN_ENTRY(mod) {#mod, PLUGTYPE_OPTIONAL, lib##mod##_LTX_plugin_init, lib##mod##_LTX_plugin_fini, 0}
|
||||||
#define BUILTIN_SND_PLUGIN_ENTRY(mod) {#mod, PLUGTYPE_SOUND, lib##mod##_sound_plugin_init, lib##mod##_sound_plugin_fini, 0}
|
#define BUILTIN_SND_PLUGIN_ENTRY(mod) {#mod, PLUGTYPE_SOUND, lib##mod##_sound_plugin_init, lib##mod##_sound_plugin_fini, 0}
|
||||||
|
#define BUILTIN_NET_PLUGIN_ENTRY(mod) {#mod, PLUGTYPE_NETWORK, lib##mod##_net_plugin_init, lib##mod##_net_plugin_fini, 0}
|
||||||
|
|
||||||
static builtin_plugin_t builtin_plugins[] = {
|
static builtin_plugin_t builtin_plugins[] = {
|
||||||
#if BX_WITH_AMIGAOS
|
#if BX_WITH_AMIGAOS
|
||||||
@ -905,6 +916,34 @@ static builtin_plugin_t builtin_plugins[] = {
|
|||||||
BUILTIN_SND_PLUGIN_ENTRY(win),
|
BUILTIN_SND_PLUGIN_ENTRY(win),
|
||||||
#endif
|
#endif
|
||||||
BUILTIN_SND_PLUGIN_ENTRY(file),
|
BUILTIN_SND_PLUGIN_ENTRY(file),
|
||||||
|
#endif
|
||||||
|
#if BX_NETWORKING
|
||||||
|
#if BX_NETMOD_FBSD
|
||||||
|
BUILTIN_NET_PLUGIN_ENTRY(fbsd),
|
||||||
|
#endif
|
||||||
|
#if BX_NETMOD_LINUX
|
||||||
|
BUILTIN_NET_PLUGIN_ENTRY(linux),
|
||||||
|
#endif
|
||||||
|
BUILTIN_NET_PLUGIN_ENTRY(null),
|
||||||
|
#if BX_NETMOD_SLIRP
|
||||||
|
BUILTIN_NET_PLUGIN_ENTRY(slirp),
|
||||||
|
#endif
|
||||||
|
#if BX_NETMOD_SOCKET
|
||||||
|
BUILTIN_NET_PLUGIN_ENTRY(socket),
|
||||||
|
#endif
|
||||||
|
#if BX_NETMOD_TAP
|
||||||
|
BUILTIN_NET_PLUGIN_ENTRY(tap),
|
||||||
|
#endif
|
||||||
|
#if BX_NETMOD_TUNTAP
|
||||||
|
BUILTIN_NET_PLUGIN_ENTRY(tuntap),
|
||||||
|
#endif
|
||||||
|
#if BX_NETMOD_VDE
|
||||||
|
BUILTIN_NET_PLUGIN_ENTRY(vde),
|
||||||
|
#endif
|
||||||
|
BUILTIN_NET_PLUGIN_ENTRY(vnet),
|
||||||
|
#if BX_NETMOD_WIN32
|
||||||
|
BUILTIN_NET_PLUGIN_ENTRY(win32),
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
{"NULL", PLUGTYPE_GUI, NULL, NULL, 0}
|
{"NULL", PLUGTYPE_GUI, NULL, NULL, 0}
|
||||||
};
|
};
|
||||||
@ -965,6 +1004,25 @@ int bx_unload_snd_plugin(const char *name)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if BX_NETWORKING
|
||||||
|
int bx_unload_net_plugin(const char *name)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while (strcmp(builtin_plugins[i].name, "NULL")) {
|
||||||
|
if ((!strcmp(name, builtin_plugins[i].name)) &&
|
||||||
|
(builtin_plugins[i].type == PLUGTYPE_NETWORK)) {
|
||||||
|
if (builtin_plugins[i].status == 1) {
|
||||||
|
builtin_plugins[i].plugin_fini();
|
||||||
|
builtin_plugins[i].status = 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
};
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,6 @@ extern "C" {
|
|||||||
#define BX_PLUGIN_PCI_IDE "pci_ide"
|
#define BX_PLUGIN_PCI_IDE "pci_ide"
|
||||||
#define BX_PLUGIN_SB16 "sb16"
|
#define BX_PLUGIN_SB16 "sb16"
|
||||||
#define BX_PLUGIN_ES1370 "es1370"
|
#define BX_PLUGIN_ES1370 "es1370"
|
||||||
#define BX_PLUGIN_NETMOD "netmod"
|
|
||||||
#define BX_PLUGIN_NE2K "ne2k"
|
#define BX_PLUGIN_NE2K "ne2k"
|
||||||
#define BX_PLUGIN_EXTFPUIRQ "extfpuirq"
|
#define BX_PLUGIN_EXTFPUIRQ "extfpuirq"
|
||||||
#define BX_PLUGIN_PCIDEV "pcidev"
|
#define BX_PLUGIN_PCIDEV "pcidev"
|
||||||
@ -88,10 +87,12 @@ extern "C" {
|
|||||||
#define PLUG_load_gui_plugin(name) bx_load_plugin(name,PLUGTYPE_GUI)
|
#define PLUG_load_gui_plugin(name) bx_load_plugin(name,PLUGTYPE_GUI)
|
||||||
#define PLUG_load_opt_plugin(name) bx_load_plugin(name,PLUGTYPE_OPTIONAL)
|
#define PLUG_load_opt_plugin(name) bx_load_plugin(name,PLUGTYPE_OPTIONAL)
|
||||||
#define PLUG_load_snd_plugin(name) bx_load_plugin(name,PLUGTYPE_SOUND)
|
#define PLUG_load_snd_plugin(name) bx_load_plugin(name,PLUGTYPE_SOUND)
|
||||||
|
#define PLUG_load_net_plugin(name) bx_load_plugin(name,PLUGTYPE_NETWORK)
|
||||||
#define PLUG_load_user_plugin(name) {bx_load_plugin(name,PLUGTYPE_USER);}
|
#define PLUG_load_user_plugin(name) {bx_load_plugin(name,PLUGTYPE_USER);}
|
||||||
#define PLUG_unload_plugin(name) {bx_unload_plugin(#name,1);}
|
#define PLUG_unload_plugin(name) {bx_unload_plugin(#name,1);}
|
||||||
#define PLUG_unload_opt_plugin(name) bx_unload_plugin(name,1)
|
#define PLUG_unload_opt_plugin(name) bx_unload_plugin(name,1)
|
||||||
#define PLUG_unload_snd_plugin(name) bx_unload_plugin(name,1)
|
#define PLUG_unload_snd_plugin(name) bx_unload_plugin(name,1)
|
||||||
|
#define PLUG_unload_net_plugin(name) bx_unload_plugin(name,1)
|
||||||
#define PLUG_unload_user_plugin(name) {bx_unload_plugin(name,1);}
|
#define PLUG_unload_user_plugin(name) {bx_unload_plugin(name,1);}
|
||||||
|
|
||||||
#define DEV_register_ioread_handler(b,c,d,e,f) pluginRegisterIOReadHandler(b,c,d,e,f)
|
#define DEV_register_ioread_handler(b,c,d,e,f) pluginRegisterIOReadHandler(b,c,d,e,f)
|
||||||
@ -116,9 +117,11 @@ extern "C" {
|
|||||||
#define PLUG_load_gui_plugin(name) bx_load_plugin2(name,PLUGTYPE_GUI)
|
#define PLUG_load_gui_plugin(name) bx_load_plugin2(name,PLUGTYPE_GUI)
|
||||||
#define PLUG_load_opt_plugin(name) bx_load_plugin2(name,PLUGTYPE_OPTIONAL)
|
#define PLUG_load_opt_plugin(name) bx_load_plugin2(name,PLUGTYPE_OPTIONAL)
|
||||||
#define PLUG_load_snd_plugin(name) bx_load_plugin2(name,PLUGTYPE_SOUND)
|
#define PLUG_load_snd_plugin(name) bx_load_plugin2(name,PLUGTYPE_SOUND)
|
||||||
|
#define PLUG_load_net_plugin(name) bx_load_plugin2(name,PLUGTYPE_NETWORK)
|
||||||
#define PLUG_unload_plugin(name) {lib##name##_LTX_plugin_fini();}
|
#define PLUG_unload_plugin(name) {lib##name##_LTX_plugin_fini();}
|
||||||
#define PLUG_unload_opt_plugin(name) bx_unload_opt_plugin(name,1);
|
#define PLUG_unload_opt_plugin(name) bx_unload_opt_plugin(name,1);
|
||||||
#define PLUG_unload_snd_plugin(name) bx_unload_snd_plugin(name);
|
#define PLUG_unload_snd_plugin(name) bx_unload_snd_plugin(name);
|
||||||
|
#define PLUG_unload_net_plugin(name) bx_unload_net_plugin(name);
|
||||||
|
|
||||||
#define DEV_register_ioread_handler(b,c,d,e,f) bx_devices.register_io_read_handler(b,c,d,e,f)
|
#define DEV_register_ioread_handler(b,c,d,e,f) bx_devices.register_io_read_handler(b,c,d,e,f)
|
||||||
#define DEV_register_iowrite_handler(b,c,d,e,f) bx_devices.register_io_write_handler(b,c,d,e,f)
|
#define DEV_register_iowrite_handler(b,c,d,e,f) bx_devices.register_io_write_handler(b,c,d,e,f)
|
||||||
@ -269,7 +272,7 @@ extern "C" {
|
|||||||
|
|
||||||
///////// Networking module macro
|
///////// Networking module macro
|
||||||
#define DEV_net_init_module(a,b,c,d) \
|
#define DEV_net_init_module(a,b,c,d) \
|
||||||
((eth_pktmover_c*)bx_devices.pluginNetModCtl->init_module(a,(void*)b,(void*)c,d))
|
((eth_pktmover_c*)bx_netmod_ctl.init_module(a,(void*)b,(void*)c,d))
|
||||||
|
|
||||||
///////// Gameport macro
|
///////// Gameport macro
|
||||||
#define DEV_gameport_set_enabled(a) bx_devices.pluginGameport->set_enabled(a)
|
#define DEV_gameport_set_enabled(a) bx_devices.pluginGameport->set_enabled(a)
|
||||||
@ -379,6 +382,9 @@ int plugin_init(plugin_t *plugin, plugintype_t type);
|
|||||||
#define DECLARE_PLUGIN_INIT_FINI_FOR_SOUND_MODULE(mod) \
|
#define DECLARE_PLUGIN_INIT_FINI_FOR_SOUND_MODULE(mod) \
|
||||||
extern "C" __declspec(dllexport) int __cdecl lib##mod##_sound_plugin_init(plugin_t *plugin, plugintype_t type); \
|
extern "C" __declspec(dllexport) int __cdecl lib##mod##_sound_plugin_init(plugin_t *plugin, plugintype_t type); \
|
||||||
extern "C" __declspec(dllexport) void __cdecl lib##mod##_sound_plugin_fini(void);
|
extern "C" __declspec(dllexport) void __cdecl lib##mod##_sound_plugin_fini(void);
|
||||||
|
#define DECLARE_PLUGIN_INIT_FINI_FOR_NET_MODULE(mod) \
|
||||||
|
extern "C" __declspec(dllexport) int __cdecl lib##mod##_net_plugin_init(plugin_t *plugin, plugintype_t type); \
|
||||||
|
extern "C" __declspec(dllexport) void __cdecl lib##mod##_net_plugin_fini(void);
|
||||||
#else
|
#else
|
||||||
#define DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(mod) \
|
#define DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(mod) \
|
||||||
int CDECL lib##mod##_LTX_plugin_init(plugin_t *plugin, plugintype_t type); \
|
int CDECL lib##mod##_LTX_plugin_init(plugin_t *plugin, plugintype_t type); \
|
||||||
@ -389,6 +395,9 @@ int plugin_init(plugin_t *plugin, plugintype_t type);
|
|||||||
#define DECLARE_PLUGIN_INIT_FINI_FOR_SOUND_MODULE(mod) \
|
#define DECLARE_PLUGIN_INIT_FINI_FOR_SOUND_MODULE(mod) \
|
||||||
int CDECL lib##mod##_sound_plugin_init(plugin_t *plugin, plugintype_t type); \
|
int CDECL lib##mod##_sound_plugin_init(plugin_t *plugin, plugintype_t type); \
|
||||||
void CDECL lib##mod##_sound_plugin_fini(void);
|
void CDECL lib##mod##_sound_plugin_fini(void);
|
||||||
|
#define DECLARE_PLUGIN_INIT_FINI_FOR_NET_MODULE(mod) \
|
||||||
|
int CDECL lib##mod##_net_plugin_init(plugin_t *plugin, plugintype_t type); \
|
||||||
|
void CDECL lib##mod##_net_plugin_fini(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// device plugins
|
// device plugins
|
||||||
@ -451,6 +460,17 @@ DECLARE_PLUGIN_INIT_FINI_FOR_SOUND_MODULE(oss)
|
|||||||
DECLARE_PLUGIN_INIT_FINI_FOR_SOUND_MODULE(osx)
|
DECLARE_PLUGIN_INIT_FINI_FOR_SOUND_MODULE(osx)
|
||||||
DECLARE_PLUGIN_INIT_FINI_FOR_SOUND_MODULE(sdl)
|
DECLARE_PLUGIN_INIT_FINI_FOR_SOUND_MODULE(sdl)
|
||||||
DECLARE_PLUGIN_INIT_FINI_FOR_SOUND_MODULE(win)
|
DECLARE_PLUGIN_INIT_FINI_FOR_SOUND_MODULE(win)
|
||||||
|
// network driver plugins
|
||||||
|
DECLARE_PLUGIN_INIT_FINI_FOR_NET_MODULE(fbsd)
|
||||||
|
DECLARE_PLUGIN_INIT_FINI_FOR_NET_MODULE(linux)
|
||||||
|
DECLARE_PLUGIN_INIT_FINI_FOR_NET_MODULE(null)
|
||||||
|
DECLARE_PLUGIN_INIT_FINI_FOR_NET_MODULE(slirp)
|
||||||
|
DECLARE_PLUGIN_INIT_FINI_FOR_NET_MODULE(socket)
|
||||||
|
DECLARE_PLUGIN_INIT_FINI_FOR_NET_MODULE(tap)
|
||||||
|
DECLARE_PLUGIN_INIT_FINI_FOR_NET_MODULE(tuntap)
|
||||||
|
DECLARE_PLUGIN_INIT_FINI_FOR_NET_MODULE(vde)
|
||||||
|
DECLARE_PLUGIN_INIT_FINI_FOR_NET_MODULE(vnet)
|
||||||
|
DECLARE_PLUGIN_INIT_FINI_FOR_NET_MODULE(win32)
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
Loading…
Reference in New Issue
Block a user