Merge branch 'master' into Extra-VAXen
Conflicts: makefile
This commit is contained in:
commit
71bc2e80c1
6 changed files with 308 additions and 119 deletions
|
@ -378,6 +378,7 @@ Dave
|
||||||
Change Log
|
Change Log
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
|
||||||
|
17-Nov-11 MP Added dynamic loading of libpcap on *nix platforms
|
||||||
30-Oct-11 MP Added support for vde (Virtual Distributed Ethernet) networking
|
30-Oct-11 MP Added support for vde (Virtual Distributed Ethernet) networking
|
||||||
29-Oct-11 MP Added support for integrated Tap networking interfaces on OSX
|
29-Oct-11 MP Added support for integrated Tap networking interfaces on OSX
|
||||||
17-Aug-11 RMS Fix from Sergey Oboguev relating to XU and XQ Auto Config and
|
17-Aug-11 RMS Fix from Sergey Oboguev relating to XU and XQ Auto Config and
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
This dirctory contains a set of Visual Studio 2008 build projects for the current simh code base. When used (with Visual Studio Express 2008 or Visual Studio Express 2010) it populates a directory tree under the BIN directory of the Simh distribution for temporary build files and produces resulting executables in the BIN/NT/Win32-Debug or BIN/NT/Win32-Release directories (depending on whether you target a Debug or Release build). It expects that a winpcap developer pack zip file is expanded in a directory parallel to the simh directory.
|
This dirctory contains a set of Visual Studio 2008 build projects for the
|
||||||
|
current simh code base. When used (with Visual Studio Express 2008 or
|
||||||
|
Visual Studio Express 2010) it populates a directory tree under the BIN
|
||||||
|
directory of the Simh distribution for temporary build files and produces
|
||||||
|
resulting executables in the BIN/NT/Win32-Debug or BIN/NT/Win32-Release
|
||||||
|
directories (depending on whether you target a Debug or Release build).
|
||||||
|
It expects that a winpcap developer pack zip file is expanded in a directory
|
||||||
|
parallel to the simh directory.
|
||||||
|
|
||||||
For Example, the directory structure should look like:
|
For Example, the directory structure should look like:
|
||||||
|
|
||||||
|
@ -13,8 +20,10 @@ For Example, the directory structure should look like:
|
||||||
The winpcap developer pack can be found at:
|
The winpcap developer pack can be found at:
|
||||||
http://www.winpcap.org/devel.htm
|
http://www.winpcap.org/devel.htm
|
||||||
|
|
||||||
|
The latest version of the WinPcap developer's pack is Version 4.1.2
|
||||||
|
|
||||||
Some features can be enabled if the pthreads API is available and contained also in a parallel place in the directory structure.
|
Some features can be enabled if the pthreads API is available and contained
|
||||||
|
also in a parallel place in the directory structure.
|
||||||
|
|
||||||
|
|
||||||
.../simh/pthreads/Pre-built.2/include/include/pthreads.h
|
.../simh/pthreads/Pre-built.2/include/include/pthreads.h
|
||||||
|
@ -24,10 +33,18 @@ To install pthreads API, create the directory:
|
||||||
|
|
||||||
.../simh/pthreads/
|
.../simh/pthreads/
|
||||||
|
|
||||||
download the file: ftp://sourceware.org/pub/pthreads-win32/pthreads-w32-2-8-0-release.exe
|
download the file:
|
||||||
|
ftp://sourceware.org/pub/pthreads-win32/pthreads-w32-2-8-0-release.exe
|
||||||
to that directory and execute it. Click on the Extract button.
|
to that directory and execute it. Click on the Extract button.
|
||||||
Once installed, When running a simulator with pthreads support enabled, you will need a copy of the DLL file (simh\pthreads\Pre-built.2\lib\pthreadVC2.dll) to exist in either the %windir%\System32 directory or your working directory while running a simh simulator. The default working directory for included project files is the "Visual Studio Projects" directory.
|
Once installed, When running a simulator with pthreads support enabled, you
|
||||||
|
will need a copy of the DLL file (simh\pthreads\Pre-built.2\lib\pthreadVC2.dll)
|
||||||
|
to exist in either the %windir%\System32 directory (or %windir%\SysWOW64 on
|
||||||
|
x64 Windows environments) or your working directory while running a simh
|
||||||
|
simulator. The default working directory for included project files is the
|
||||||
|
"Visual Studio Projects" directory.
|
||||||
|
|
||||||
|
|
||||||
Only network devices are capable of using pthreads to enhance their performance. Build the desire simulator with USE_READER_THREAD defined. The relevant simulators which have network support are VAX, VAX780, PDP11 and PDP10.
|
Only network devices are capable of using pthreads to enhance their
|
||||||
|
performance. Build the desire simulator with USE_READER_THREAD defined. The
|
||||||
|
relevant simulators which have network support are VAX, VAX780 and PDP11.
|
||||||
|
|
||||||
|
|
189
makefile
189
makefile
|
@ -7,93 +7,162 @@
|
||||||
# NetBSD
|
# NetBSD
|
||||||
# FreeBSD
|
# FreeBSD
|
||||||
# Windows (MinGW & cygwin)
|
# Windows (MinGW & cygwin)
|
||||||
#
|
# Linux x86 targeting Android (using agcc script)
|
||||||
|
#
|
||||||
|
# Android targeted builds should invoke GNU make with GCC=agcc on
|
||||||
|
# the command line.
|
||||||
|
#
|
||||||
|
# In general, the logic below will detect and build with the available
|
||||||
|
# features which the host build environment provides.
|
||||||
|
#
|
||||||
|
# Dynamic loading of libpcap is the default behavior if pcap.h is
|
||||||
|
# available at build time. Direct calls to libpcap can be enabled
|
||||||
|
# if GNU make is invoked with USE_NETWORK on the command line.
|
||||||
|
#
|
||||||
|
# Internal ROM support can be disabled if GNU make is invoked with
|
||||||
|
# DONT_USE_ROMS=1 on the command line.
|
||||||
#
|
#
|
||||||
# CC Command (and platform available options). (Poor man's autoconf)
|
# CC Command (and platform available options). (Poor man's autoconf)
|
||||||
#
|
#
|
||||||
ifeq ($(WIN32),)
|
ifeq ($(WIN32),) #*nix Environments (&& cygwin)
|
||||||
#*nix Environments (&& cygwin)
|
ifeq ($(GCC),)
|
||||||
GCC = gcc
|
GCC = gcc
|
||||||
|
endif
|
||||||
ifeq (SunOS,$(shell uname))
|
ifeq (SunOS,$(shell uname))
|
||||||
TEST = /bin/test
|
TEST = /bin/test
|
||||||
else
|
else
|
||||||
TEST = test
|
TEST = test
|
||||||
endif
|
endif
|
||||||
ifeq (Darwin,$(shell uname))
|
ifeq (agcc,$(findstring agcc,$(GCC))) # Android target build?
|
||||||
LIBEXT = dylib
|
OS_CCDEFS = -D_GNU_SOURCE -DSIM_ASYNCH_IO
|
||||||
else
|
OS_LDFLAGS = -lm
|
||||||
ifeq (Linux,$(shell uname))
|
else # Non-Android Builds
|
||||||
LIBEXT = so
|
INCPATH=/usr/include
|
||||||
|
LIBPATH=/usr/lib
|
||||||
|
OS_CCDEFS = -D_GNU_SOURCE
|
||||||
|
ifeq (Darwin,$(shell uname))
|
||||||
|
LIBEXT = dylib
|
||||||
else
|
else
|
||||||
ifeq (SunOS,$(shell uname))
|
ifeq (Linux,$(shell uname))
|
||||||
LIBEXT = so
|
LIBEXT = so
|
||||||
|
ifeq (usrlib64,$(shell if $(TEST) -d /usr/lib64; then echo usrlib64; fi))
|
||||||
|
LIBPATH += /usr/lib64
|
||||||
|
endif
|
||||||
|
ifeq (lib32,$(shell if $(TEST) -d /usr/lib32; then echo lib32; fi))
|
||||||
|
LIBPATH += /usr/lib32
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
LIBEXT = a
|
ifeq (SunOS,$(shell uname))
|
||||||
endif
|
LIBEXT = so
|
||||||
endif
|
OS_LDFLAGS += -lsocket -lnsl
|
||||||
endif
|
ifeq (incsfw,$(shell if $(TEST) -d /opt/sfw/include; then echo incsfw; fi))
|
||||||
OS_CCDEFS = -D_GNU_SOURCE
|
INCPATH += /opt/sfw/include
|
||||||
ifeq (libm,$(shell if $(TEST) -e /usr/lib/libm.$(LIBEXT) -o -e /usr/lib64/libm.$(LIBEXT); then echo libm; fi))
|
OS_CCDEFS += -I/opt/sfw/include
|
||||||
OS_LDFLAGS += -lm
|
endif
|
||||||
endif
|
ifeq (libsfw,$(shell if $(TEST) -d /opt/sfw/lib; then echo libsfw; fi))
|
||||||
ifeq (SunOS,$(shell uname))
|
LIBPATH += /opt/sfw/lib
|
||||||
OS_CCDEFS += -I/opt/sfw/include
|
OS_LDFLAGS += -L/opt/sfw/lib -R/opt/sfw/lib
|
||||||
OS_LDFLAGS += -lsocket -lnsl -L/opt/sfw/lib -R/opt/sfw/lib
|
endif
|
||||||
endif
|
|
||||||
ifeq (cygwin,$(findstring cygwin,$(OSTYPE)))
|
|
||||||
OS_CCDEFS += -O2
|
|
||||||
endif
|
|
||||||
ifeq (librt,$(shell if $(TEST) -e /usr/lib/librt.$(LIBEXT) -o -e /usr/lib64/librt.$(LIBEXT); then echo librt; fi))
|
|
||||||
OS_LDFLAGS += -lrt
|
|
||||||
endif
|
|
||||||
ifeq (libpthread,$(shell if $(TEST) -e /usr/lib/libpthread.$(LIBEXT) -o -e /usr/lib64/libpthread.$(LIBEXT); then echo libpthread; fi))
|
|
||||||
OS_CCDEFS += -DSIM_ASYNCH_IO -DUSE_READER_THREAD
|
|
||||||
OS_LDFLAGS += -lpthread
|
|
||||||
endif
|
|
||||||
ifeq (readline,$(shell if $(TEST) -e /usr/lib/libreadline.$(LIBEXT) -o -e /usr/lib64/libreadline.$(LIBEXT) -o -e /opt/sfw/lib/libreadline.a; then echo readline; fi))
|
|
||||||
ifeq (readline_h,$(shell if $(TEST) -e /usr/include/readline/readline.h -o -e /usr/include/readline.h -o -e /opt/sfw/include/readline/readline.h; then echo readline_h; fi))
|
|
||||||
# Use Locally installed and available readline support
|
|
||||||
ifeq (ncurses,$(shell if $(TEST) -e /usr/lib/libncurses.$(LIBEXT) -o -e /opt/sfw/lib/libncurses.a; then echo ncurses; fi))
|
|
||||||
OS_CCDEFS += -DHAVE_READLINE
|
|
||||||
OS_LDFLAGS += -lreadline -lncurses
|
|
||||||
else
|
|
||||||
ifeq (curses,$(shell if $(TEST) -e /usr/lib/libcurses.$(LIBEXT); then echo curses; fi))
|
|
||||||
OS_CCDEFS += -DHAVE_READLINE
|
|
||||||
OS_LDFLAGS += -lreadline -lcurses
|
|
||||||
else
|
else
|
||||||
ifeq (solaris_readline,$(shell if $(TEST) ! -e /opt/sfw/lib/libreadline.a; then echo solaris_readline; fi))
|
ifeq (usrpkglib,$(shell if $(TEST) -d /usr/pkg/lib; then echo usrpkglib; fi))
|
||||||
OS_CCDEFS += -DHAVE_READLINE
|
LIBPATH += /usr/pkg/lib
|
||||||
OS_LDFLAGS += -lreadline
|
OS_LDFLAGS += -L/usr/pkg/lib -R/usr/pkg/lib
|
||||||
|
endif
|
||||||
|
ifneq (,$(findstring NetBSD,$(shell uname))$(findstring FreeBSD,$(shell uname)))
|
||||||
|
LIBEXT = so
|
||||||
|
else
|
||||||
|
LIBEXT = a
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
ifeq (pcap,$(shell if $(TEST) -e /usr/include/pcap.h -o -e /opt/sfw/include/pcap.h; then echo pcap; fi))
|
ifeq (cygwin,$(findstring cygwin,$(OSTYPE)))
|
||||||
# Use Locally installed and available pcap support
|
OS_CCDEFS += -O2
|
||||||
NETWORK_CCDEFS = -DUSE_NETWORK
|
|
||||||
NETWORK_LDFLAGS = -lpcap
|
|
||||||
endif
|
endif
|
||||||
ifeq (vde,$(shell if $(TEST) -e /usr/include/libvdeplug.h -a \( -e /usr/lib/libvdeplug.$(LIBEXT) -o -e /usr/lib64/libvdeplug.$(LIBEXT) \); then echo vde; fi))
|
find_lib = $(strip $(firstword $(foreach dir,$(strip $(LIBPATH)),$(wildcard $(dir)/lib$(1).$(LIBEXT)))))
|
||||||
# Provide support for vde networking
|
find_include = $(strip $(firstword $(foreach dir,$(strip $(INCPATH)),$(wildcard $(dir)/$(1).h))))
|
||||||
NETWORK_CCDEFS += -DUSE_VDE_NETWORK
|
ifneq (,$(call find_lib,m))
|
||||||
NETWORK_LDFLAGS += -lvdeplug
|
OS_LDFLAGS += -lm
|
||||||
|
$(info using libm: $(call find_lib,m))
|
||||||
endif
|
endif
|
||||||
ifeq (tuntap,$(shell if $(TEST) -e /usr/include/linux/if_tun.h; then echo tuntap; fi))
|
ifneq (,$(call find_lib,rt))
|
||||||
|
OS_LDFLAGS += -lrt
|
||||||
|
$(info using librt: $(call find_lib,rt))
|
||||||
|
endif
|
||||||
|
ifneq (,$(call find_lib,pthread))
|
||||||
|
ifneq (,$(call find_include,pthread))
|
||||||
|
OS_CCDEFS += -DSIM_ASYNCH_IO -DUSE_READER_THREAD
|
||||||
|
OS_LDFLAGS += -lpthread
|
||||||
|
$(info using libpthread: $(call find_lib,pthread) $(call find_include,pthread))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
ifneq (,$(call find_include,dlfcn))
|
||||||
|
ifneq (,$(call find_lib,dl))
|
||||||
|
OS_CCDEFS += -DHAVE_DLOPEN=$(LIBEXT)
|
||||||
|
OS_LDFLAGS += -ldl
|
||||||
|
$(info using libdl: $(call find_lib,dl) $(call find_include,dlfcn))
|
||||||
|
else
|
||||||
|
ifeq (BSD,$(findstring BSD,$(shell uname)))
|
||||||
|
OS_CCDEFS += -DHAVE_DLOPEN=so
|
||||||
|
$(info using libdl: $(call find_include,dlfcn))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
ifneq (,$(call find_include,pcap))
|
||||||
|
ifneq (,$(call find_lib,pcap))
|
||||||
|
ifneq ($(USE_NETWORK),) # Network support specified on the GNU make command line
|
||||||
|
NETWORK_CCDEFS = -DUSE_NETWORK
|
||||||
|
NETWORK_LDFLAGS = -lpcap
|
||||||
|
$(info using libpcap: $(call find_lib,pcap) $(call find_include,pcap))
|
||||||
|
else # default build uses dynamic libpcap
|
||||||
|
NETWORK_CCDEFS = -DUSE_SHARED
|
||||||
|
$(info using libpcap: $(call find_include,pcap))
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
NETWORK_CCDEFS = -DUSE_SHARED
|
||||||
|
$(info using libpcap: $(call find_include,pcap))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
ifneq (,$(call find_lib,vdeplug))
|
||||||
|
ifneq (,$(call find_include,libvdeplug))
|
||||||
|
# Provide support for vde networking
|
||||||
|
NETWORK_CCDEFS += -DUSE_VDE_NETWORK
|
||||||
|
NETWORK_LDFLAGS += -lvdeplug
|
||||||
|
$(info using libvdeplug: $(call find_lib,vdeplug) $(call find_include,libvdeplug))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
ifneq (,$(call find_include,linux/if_tun))
|
||||||
# Provide support for Tap networking on Linux
|
# Provide support for Tap networking on Linux
|
||||||
NETWORK_CCDEFS += -DUSE_TAP_NETWORK
|
NETWORK_CCDEFS += -DUSE_TAP_NETWORK
|
||||||
endif
|
endif
|
||||||
ifeq (bsdtuntap,$(shell if $(TEST) -e /usr/include/net/if_tun.h -o -e /Library/Extensions/tap.kext; then echo bsdtuntap; fi))
|
ifeq (bsdtuntap,$(shell if $(TEST) -e /usr/include/net/if_tun.h -o -e /Library/Extensions/tap.kext; then echo bsdtuntap; fi))
|
||||||
# Provide support for Tap networking
|
# Provide support for Tap networking on BSD platforms (including OS X)
|
||||||
NETWORK_CCDEFS += -DUSE_TAP_NETWORK -DUSE_BSDTUNTAP
|
NETWORK_CCDEFS += -DUSE_TAP_NETWORK -DUSE_BSDTUNTAP
|
||||||
endif
|
endif
|
||||||
ifneq (binexists,$(shell if $(TEST) -e BIN; then echo binexists; fi))
|
ifneq (binexists,$(shell if $(TEST) -e BIN; then echo binexists; fi))
|
||||||
MKDIRBIN = if $(TEST) ! -e BIN; then mkdir BIN; fi
|
MKDIRBIN = if $(TEST) ! -e BIN; then mkdir BIN; fi
|
||||||
endif
|
endif
|
||||||
NETWORK_OPT = $(NETWORK_CCDEFS)
|
NETWORK_OPT = $(NETWORK_CCDEFS)
|
||||||
ifneq ($(USE_NETWORK),)
|
ifneq ($(USE_NETWORK),) # Network support specified on the GNU make command line
|
||||||
# Assume built from tcpdump.org sources with default install target
|
ifneq (USE_NETWORK,$(findstring USE_NETWORK,$(NETWORK_CCDEFS)))
|
||||||
NETWORK_OPT = -DUSE_NETWORK -isystem /usr/local/include /usr/local/lib/libpcap.a
|
# Look for package built from tcpdump.org sources with default install target
|
||||||
|
LIBPATH += /usr/local/lib
|
||||||
|
INCPATH += /usr/local/include
|
||||||
|
LIBEXTSAVE = $(LIBEXT)
|
||||||
|
LIBEXT = a
|
||||||
|
ifneq (,$(call find_lib,pcap))
|
||||||
|
ifneq (,$(call find_include,pcap))
|
||||||
|
NETWORK_OPT := -DUSE_NETWORK -isystem $(dir $(call find_include,pcap)) $(call find_lib,pcap)
|
||||||
|
$(info using libpcap: $(call find_lib,pcap) $(call find_include,pcap))
|
||||||
|
else
|
||||||
|
$(error using libpcap: $(call find_lib,pcap) missing pcap.h)
|
||||||
|
endif
|
||||||
|
LIBEXT = $(LIBEXTSAVE)
|
||||||
|
else
|
||||||
|
$(error missing libpcap)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
#Win32 Environments (via MinGW32)
|
#Win32 Environments (via MinGW32)
|
||||||
|
@ -403,7 +472,11 @@ endif
|
||||||
|
|
||||||
${BIN}BuildROMs${EXE} :
|
${BIN}BuildROMs${EXE} :
|
||||||
${MKDIRBIN}
|
${MKDIRBIN}
|
||||||
|
ifeq (agcc,$(findstring agcc,$(firstword $(CC))))
|
||||||
|
gcc $(wordlist 2,1000,${CC}) sim_BuildROMs.c -o $@
|
||||||
|
else
|
||||||
${CC} sim_BuildROMs.c -o $@
|
${CC} sim_BuildROMs.c -o $@
|
||||||
|
endif
|
||||||
ifeq ($(WIN32),)
|
ifeq ($(WIN32),)
|
||||||
$@
|
$@
|
||||||
${RM} $@
|
${RM} $@
|
||||||
|
|
48
scp.c
48
scp.c
|
@ -213,9 +213,8 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#if defined(HAVE_READLINE)
|
#if defined(HAVE_DLOPEN) /* Dynamic Readline support */
|
||||||
#include <readline/readline.h>
|
#include <dlfcn.h>
|
||||||
#include <readline/history.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define EX_D 0 /* deposit */
|
#define EX_D 0 /* deposit */
|
||||||
|
@ -3841,15 +3840,40 @@ return read_line_p (NULL, cptr, size, stream);
|
||||||
char *read_line_p (char *prompt, char *cptr, int32 size, FILE *stream)
|
char *read_line_p (char *prompt, char *cptr, int32 size, FILE *stream)
|
||||||
{
|
{
|
||||||
char *tptr;
|
char *tptr;
|
||||||
|
#if defined(HAVE_DLOPEN)
|
||||||
|
static int initialized = 0;
|
||||||
|
static char *(*p_readline)(const char *) = NULL;
|
||||||
|
static void (*p_add_history)(const char *) = NULL;
|
||||||
|
|
||||||
#if defined(HAVE_READLINE)
|
if (!initialized) {
|
||||||
|
initialized = 1;
|
||||||
|
void *handle;
|
||||||
|
|
||||||
|
#define __STR_QUOTE(tok) #tok
|
||||||
|
#define __STR(tok) __STR_QUOTE(tok)
|
||||||
|
handle = dlopen("libncurses." __STR(HAVE_DLOPEN), RTLD_NOW|RTLD_GLOBAL);
|
||||||
|
handle = dlopen("libcurses." __STR(HAVE_DLOPEN), RTLD_NOW|RTLD_GLOBAL);
|
||||||
|
handle = dlopen("libreadline." __STR(HAVE_DLOPEN), RTLD_NOW|RTLD_GLOBAL);
|
||||||
|
if (handle) {
|
||||||
|
p_readline = dlsym(handle, "readline");
|
||||||
|
p_add_history = dlsym(handle, "add_history");
|
||||||
|
}
|
||||||
|
}
|
||||||
if (prompt) { /* interactive? */
|
if (prompt) { /* interactive? */
|
||||||
char *tmpc = readline (prompt); /* get cmd line */
|
char *tmpc;
|
||||||
if (tmpc == NULL) /* bad result? */
|
|
||||||
cptr = NULL;
|
if (p_readline) {
|
||||||
|
char *tmpc = p_readline (prompt); /* get cmd line */
|
||||||
|
if (tmpc == NULL) /* bad result? */
|
||||||
|
cptr = NULL;
|
||||||
|
else {
|
||||||
|
strncpy (cptr, tmpc, size); /* copy result */
|
||||||
|
free (tmpc) ; /* free temp */
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
strncpy (cptr, tmpc, size); /* copy result */
|
printf ("%s", prompt); /* display prompt */
|
||||||
free (tmpc) ; /* free temp */
|
cptr = fgets (cptr, size, stream); /* get cmd line */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else cptr = fgets (cptr, size, stream); /* get cmd line */
|
else cptr = fgets (cptr, size, stream); /* get cmd line */
|
||||||
|
@ -3875,9 +3899,9 @@ while (isspace (*cptr)) /* trim leading spc */
|
||||||
if (*cptr == ';') /* ignore comment */
|
if (*cptr == ';') /* ignore comment */
|
||||||
*cptr = 0;
|
*cptr = 0;
|
||||||
|
|
||||||
#if defined (HAVE_READLINE)
|
#if defined (HAVE_DLOPEN)
|
||||||
if (prompt)
|
if (prompt && p_add_history && *cptr) /* Save non blank lines in history */
|
||||||
add_history (cptr);
|
p_add_history (cptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return cptr;
|
return cptr;
|
||||||
|
|
152
sim_ether.c
152
sim_ether.c
|
@ -50,7 +50,7 @@
|
||||||
|
|
||||||
Define one of the two macros below to enable networking:
|
Define one of the two macros below to enable networking:
|
||||||
USE_NETWORK - Create statically linked network code
|
USE_NETWORK - Create statically linked network code
|
||||||
USE_SHARED - Create dynamically linked network code (_WIN32 only)
|
USE_SHARED - Create dynamically linked network code
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -160,6 +160,7 @@
|
||||||
|
|
||||||
Modification history:
|
Modification history:
|
||||||
|
|
||||||
|
17-Nov-11 MP Added dynamic loading of libpcap on *nix platforms
|
||||||
30-Oct-11 MP Added support for vde (Virtual Distributed Ethernet) networking
|
30-Oct-11 MP Added support for vde (Virtual Distributed Ethernet) networking
|
||||||
29-Oct-11 MP Added support for integrated Tap networking interfaces on OSX
|
29-Oct-11 MP Added support for integrated Tap networking interfaces on OSX
|
||||||
12-Aug-11 MP Cleaned up payload length determination
|
12-Aug-11 MP Cleaned up payload length determination
|
||||||
|
@ -752,7 +753,7 @@ void ethq_insert(ETH_QUE* que, int32 type, ETH_PACK* pack, int32 status)
|
||||||
/* Non-implemented versions */
|
/* Non-implemented versions */
|
||||||
/*============================================================================*/
|
/*============================================================================*/
|
||||||
|
|
||||||
#if !defined (USE_NETWORK) && (!defined (_WIN32) || !defined (USE_SHARED))
|
#if !defined (USE_NETWORK) && !defined (USE_SHARED)
|
||||||
t_stat eth_open(ETH_DEV* dev, char* name, DEVICE* dptr, uint32 dbit)
|
t_stat eth_open(ETH_DEV* dev, char* name, DEVICE* dptr, uint32 dbit)
|
||||||
{return SCPE_NOFNC;}
|
{return SCPE_NOFNC;}
|
||||||
t_stat eth_close (ETH_DEV* dev)
|
t_stat eth_close (ETH_DEV* dev)
|
||||||
|
@ -816,18 +817,39 @@ void eth_show_dev (FILE* st, ETH_DEV* dev)
|
||||||
#include <winreg.h>
|
#include <winreg.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(USE_SHARED)
|
#if defined(USE_SHARED) && (defined(_WIN32) || defined(HAVE_DLOPEN))
|
||||||
/* Dynamic DLL loading technique and modified source comes from
|
/* Dynamic DLL loading technique and modified source comes from
|
||||||
Etherial/WireShark capture_pcap.c */
|
Etherial/WireShark capture_pcap.c */
|
||||||
|
|
||||||
|
#ifdef HAVE_DLOPEN
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Dynamic DLL load variables */
|
/* Dynamic DLL load variables */
|
||||||
static HINSTANCE hDll = 0; /* handle to DLL */
|
#ifdef _WIN32
|
||||||
static int dll_loaded = 0; /* 0=not loaded, 1=loaded, 2=DLL load failed, 3=Func load failed */
|
static HINSTANCE hLib = 0; /* handle to DLL */
|
||||||
static char* no_wpcap = "wpcap load failure";
|
#else
|
||||||
|
static void *hLib = 0; /* handle to Library */
|
||||||
|
#endif
|
||||||
|
static int lib_loaded = 0; /* 0=not loaded, 1=loaded, 2=library load failed, 3=Func load failed */
|
||||||
|
static char* lib_name =
|
||||||
|
#ifdef _WIN32
|
||||||
|
"wpcap.dll";
|
||||||
|
#else
|
||||||
|
#define __STR_QUOTE(tok) #tok
|
||||||
|
#define __STR(tok) __STR_QUOTE(tok)
|
||||||
|
"libpcap." __STR(HAVE_DLOPEN);
|
||||||
|
#endif
|
||||||
|
static char* no_pcap =
|
||||||
|
#ifdef _WIN32
|
||||||
|
"wpcap load failure";
|
||||||
|
#else
|
||||||
|
"libpcap load failure";
|
||||||
|
#endif
|
||||||
|
|
||||||
/* define pointers to pcap functions needed */
|
/* define pointers to pcap functions needed */
|
||||||
static void (*p_pcap_close) (pcap_t *);
|
static void (*p_pcap_close) (pcap_t *);
|
||||||
static int (*p_pcap_compile) (pcap_t *, struct bpf_program *, char *, int, bpf_u_int32);
|
static int (*p_pcap_compile) (pcap_t *, struct bpf_program *, const char *, int, bpf_u_int32);
|
||||||
static int (*p_pcap_datalink) (pcap_t *);
|
static int (*p_pcap_datalink) (pcap_t *);
|
||||||
static int (*p_pcap_dispatch) (pcap_t *, int, pcap_handler, u_char *);
|
static int (*p_pcap_dispatch) (pcap_t *, int, pcap_handler, u_char *);
|
||||||
static int (*p_pcap_findalldevs) (pcap_if_t **, char *);
|
static int (*p_pcap_findalldevs) (pcap_if_t **, char *);
|
||||||
|
@ -836,46 +858,64 @@ static void (*p_pcap_freecode) (struct bpf_program *);
|
||||||
static char* (*p_pcap_geterr) (pcap_t *);
|
static char* (*p_pcap_geterr) (pcap_t *);
|
||||||
static int (*p_pcap_lookupnet) (const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
|
static int (*p_pcap_lookupnet) (const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
|
||||||
static pcap_t* (*p_pcap_open_live) (const char *, int, int, int, char *);
|
static pcap_t* (*p_pcap_open_live) (const char *, int, int, int, char *);
|
||||||
|
#ifdef _WIN32
|
||||||
static int (*p_pcap_setmintocopy) (pcap_t* handle, int);
|
static int (*p_pcap_setmintocopy) (pcap_t* handle, int);
|
||||||
static HANDLE (*p_pcap_getevent) (pcap_t *);
|
static HANDLE (*p_pcap_getevent) (pcap_t *);
|
||||||
|
#else
|
||||||
|
static int (*p_pcap_get_selectable_fd) (pcap_t *);
|
||||||
|
static int (*p_pcap_fileno) (pcap_t *);
|
||||||
|
#endif
|
||||||
static int (*p_pcap_sendpacket) (pcap_t* handle, const u_char* msg, int len);
|
static int (*p_pcap_sendpacket) (pcap_t* handle, const u_char* msg, int len);
|
||||||
static int (*p_pcap_setfilter) (pcap_t *, struct bpf_program *);
|
static int (*p_pcap_setfilter) (pcap_t *, struct bpf_program *);
|
||||||
static char* (*p_pcap_lib_version) (void);
|
static char* (*p_pcap_lib_version) (void);
|
||||||
|
|
||||||
/* load function pointer from DLL */
|
/* load function pointer from DLL */
|
||||||
void load_function(char* function, void** func_ptr) {
|
void load_function(char* function, void** func_ptr) {
|
||||||
*func_ptr = GetProcAddress(hDll, function);
|
#ifdef _WIN32
|
||||||
if (*func_ptr == 0) {
|
*func_ptr = GetProcAddress(hLib, function);
|
||||||
char* msg = "Eth: Failed to find function '%s' in wpcap.dll\r\n";
|
#else
|
||||||
|
*func_ptr = dlsym(hLib, function);
|
||||||
|
#endif
|
||||||
|
if (*func_ptr == 0) {
|
||||||
|
char* msg = "Eth: Failed to find function '%s' in %s\r\n";
|
||||||
|
|
||||||
printf (msg, function);
|
printf (msg, function, lib_name);
|
||||||
if (sim_log) fprintf (sim_log, msg, function);
|
if (sim_log) fprintf (sim_log, msg, function, lib_name);
|
||||||
dll_loaded = 3;
|
lib_loaded = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* load wpcap.dll as required */
|
/* load wpcap.dll as required */
|
||||||
int load_wpcap(void) {
|
int load_pcap(void) {
|
||||||
switch(dll_loaded) {
|
switch(lib_loaded) {
|
||||||
case 0: /* not loaded */
|
case 0: /* not loaded */
|
||||||
/* attempt to load DLL */
|
/* attempt to load DLL */
|
||||||
hDll = LoadLibrary(TEXT("wpcap.dll"));
|
#ifdef _WIN32
|
||||||
if (hDll == 0) {
|
hLib = LoadLibraryA(lib_name);
|
||||||
|
#else
|
||||||
|
hLib = dlopen(lib_name, RTLD_NOW);
|
||||||
|
#endif
|
||||||
|
if (hLib == 0) {
|
||||||
/* failed to load DLL */
|
/* failed to load DLL */
|
||||||
char* msg = "Eth: Failed to load wpcap.dll\r\n";
|
char* msg = "Eth: Failed to load %s\r\n";
|
||||||
char* msg2 = "Eth: You must install WinPcap 4.x to use networking\r\n";
|
char* msg2 =
|
||||||
|
#ifdef _WIN32
|
||||||
|
"Eth: You must install WinPcap 4.x to use networking\r\n";
|
||||||
|
#else
|
||||||
|
"Eth: You must install libpcap to use networking\r\n";
|
||||||
|
#endif
|
||||||
|
|
||||||
printf (msg);
|
printf (msg, lib_name);
|
||||||
printf (msg2);
|
printf ("%s", msg2);
|
||||||
if (sim_log) {
|
if (sim_log) {
|
||||||
fprintf (sim_log, msg);
|
fprintf (sim_log, msg, lib_name);
|
||||||
fprintf (sim_log, msg2);
|
fprintf (sim_log, "%s", msg2);
|
||||||
}
|
}
|
||||||
dll_loaded = 2;
|
lib_loaded = 2;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
/* DLL loaded OK */
|
/* library loaded OK */
|
||||||
dll_loaded = 1;
|
lib_loaded = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* load required functions; sets dll_load=3 on error */
|
/* load required functions; sets dll_load=3 on error */
|
||||||
|
@ -889,13 +929,18 @@ int load_wpcap(void) {
|
||||||
load_function("pcap_geterr", (void**) &p_pcap_geterr);
|
load_function("pcap_geterr", (void**) &p_pcap_geterr);
|
||||||
load_function("pcap_lookupnet", (void**) &p_pcap_lookupnet);
|
load_function("pcap_lookupnet", (void**) &p_pcap_lookupnet);
|
||||||
load_function("pcap_open_live", (void**) &p_pcap_open_live);
|
load_function("pcap_open_live", (void**) &p_pcap_open_live);
|
||||||
|
#ifdef _WIN32
|
||||||
load_function("pcap_setmintocopy", (void**) &p_pcap_setmintocopy);
|
load_function("pcap_setmintocopy", (void**) &p_pcap_setmintocopy);
|
||||||
load_function("pcap_getevent", (void**) &p_pcap_getevent);
|
load_function("pcap_getevent", (void**) &p_pcap_getevent);
|
||||||
|
#else
|
||||||
|
load_function("pcap_get_selectable_fd", (void**) &p_pcap_get_selectable_fd);
|
||||||
|
load_function("pcap_fileno", (void**) &p_pcap_fileno);
|
||||||
|
#endif
|
||||||
load_function("pcap_sendpacket", (void**) &p_pcap_sendpacket);
|
load_function("pcap_sendpacket", (void**) &p_pcap_sendpacket);
|
||||||
load_function("pcap_setfilter", (void**) &p_pcap_setfilter);
|
load_function("pcap_setfilter", (void**) &p_pcap_setfilter);
|
||||||
load_function("pcap_lib_version", (void**) &p_pcap_lib_version);
|
load_function("pcap_lib_version", (void**) &p_pcap_lib_version);
|
||||||
|
|
||||||
if (dll_loaded == 1) {
|
if (lib_loaded == 1) {
|
||||||
/* log successful load */
|
/* log successful load */
|
||||||
char* version = p_pcap_lib_version();
|
char* version = p_pcap_lib_version();
|
||||||
printf("%s\n", version);
|
printf("%s\n", version);
|
||||||
|
@ -906,18 +951,18 @@ int load_wpcap(void) {
|
||||||
default: /* loaded or failed */
|
default: /* loaded or failed */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return (dll_loaded == 1) ? 1 : 0;
|
return (lib_loaded == 1) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* define functions with dynamic revectoring */
|
/* define functions with dynamic revectoring */
|
||||||
void pcap_close(pcap_t* a) {
|
void pcap_close(pcap_t* a) {
|
||||||
if (load_wpcap() != 0) {
|
if (load_pcap() != 0) {
|
||||||
p_pcap_close(a);
|
p_pcap_close(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcap_compile(pcap_t* a, struct bpf_program* b, char* c, int d, bpf_u_int32 e) {
|
int pcap_compile(pcap_t* a, struct bpf_program* b, const char* c, int d, bpf_u_int32 e) {
|
||||||
if (load_wpcap() != 0) {
|
if (load_pcap() != 0) {
|
||||||
return p_pcap_compile(a, b, c, d, e);
|
return p_pcap_compile(a, b, c, d, e);
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -925,7 +970,7 @@ int pcap_compile(pcap_t* a, struct bpf_program* b, char* c, int d, bpf_u_int32 e
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcap_datalink(pcap_t* a) {
|
int pcap_datalink(pcap_t* a) {
|
||||||
if (load_wpcap() != 0) {
|
if (load_pcap() != 0) {
|
||||||
return p_pcap_datalink(a);
|
return p_pcap_datalink(a);
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -933,7 +978,7 @@ int pcap_datalink(pcap_t* a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcap_dispatch(pcap_t* a, int b, pcap_handler c, u_char* d) {
|
int pcap_dispatch(pcap_t* a, int b, pcap_handler c, u_char* d) {
|
||||||
if (load_wpcap() != 0) {
|
if (load_pcap() != 0) {
|
||||||
return p_pcap_dispatch(a, b, c, d);
|
return p_pcap_dispatch(a, b, c, d);
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -941,29 +986,29 @@ int pcap_dispatch(pcap_t* a, int b, pcap_handler c, u_char* d) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcap_findalldevs(pcap_if_t** a, char* b) {
|
int pcap_findalldevs(pcap_if_t** a, char* b) {
|
||||||
if (load_wpcap() != 0) {
|
if (load_pcap() != 0) {
|
||||||
return p_pcap_findalldevs(a, b);
|
return p_pcap_findalldevs(a, b);
|
||||||
} else {
|
} else {
|
||||||
*a = 0;
|
*a = 0;
|
||||||
strcpy(b, no_wpcap);
|
strcpy(b, no_pcap);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcap_freealldevs(pcap_if_t* a) {
|
void pcap_freealldevs(pcap_if_t* a) {
|
||||||
if (load_wpcap() != 0) {
|
if (load_pcap() != 0) {
|
||||||
p_pcap_freealldevs(a);
|
p_pcap_freealldevs(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcap_freecode(struct bpf_program* a) {
|
void pcap_freecode(struct bpf_program* a) {
|
||||||
if (load_wpcap() != 0) {
|
if (load_pcap() != 0) {
|
||||||
p_pcap_freecode(a);
|
p_pcap_freecode(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char* pcap_geterr(pcap_t* a) {
|
char* pcap_geterr(pcap_t* a) {
|
||||||
if (load_wpcap() != 0) {
|
if (load_pcap() != 0) {
|
||||||
return p_pcap_geterr(a);
|
return p_pcap_geterr(a);
|
||||||
} else {
|
} else {
|
||||||
return (char*) 0;
|
return (char*) 0;
|
||||||
|
@ -971,7 +1016,7 @@ char* pcap_geterr(pcap_t* a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcap_lookupnet(const char* a, bpf_u_int32* b, bpf_u_int32* c, char* d) {
|
int pcap_lookupnet(const char* a, bpf_u_int32* b, bpf_u_int32* c, char* d) {
|
||||||
if (load_wpcap() != 0) {
|
if (load_pcap() != 0) {
|
||||||
return p_pcap_lookupnet(a, b, c, d);
|
return p_pcap_lookupnet(a, b, c, d);
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -979,15 +1024,16 @@ int pcap_lookupnet(const char* a, bpf_u_int32* b, bpf_u_int32* c, char* d) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_t* pcap_open_live(const char* a, int b, int c, int d, char* e) {
|
pcap_t* pcap_open_live(const char* a, int b, int c, int d, char* e) {
|
||||||
if (load_wpcap() != 0) {
|
if (load_pcap() != 0) {
|
||||||
return p_pcap_open_live(a, b, c, d, e);
|
return p_pcap_open_live(a, b, c, d, e);
|
||||||
} else {
|
} else {
|
||||||
return (pcap_t*) 0;
|
return (pcap_t*) 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
int pcap_setmintocopy(pcap_t* a, int b) {
|
int pcap_setmintocopy(pcap_t* a, int b) {
|
||||||
if (load_wpcap() != 0) {
|
if (load_pcap() != 0) {
|
||||||
return p_pcap_setmintocopy(a, b);
|
return p_pcap_setmintocopy(a, b);
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -995,15 +1041,33 @@ int pcap_setmintocopy(pcap_t* a, int b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE pcap_getevent(pcap_t* a) {
|
HANDLE pcap_getevent(pcap_t* a) {
|
||||||
if (load_wpcap() != 0) {
|
if (load_pcap() != 0) {
|
||||||
return p_pcap_getevent(a);
|
return p_pcap_getevent(a);
|
||||||
} else {
|
} else {
|
||||||
return (HANDLE) 0;
|
return (HANDLE) 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
int pcap_get_selectable_fd(pcap_t* a) {
|
||||||
|
if (load_pcap() != 0) {
|
||||||
|
return p_pcap_get_selectable_fd(a);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int pcap_fileno(pcap_t * a) {
|
||||||
|
if (load_pcap() != 0) {
|
||||||
|
return p_pcap_fileno(a);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int pcap_sendpacket(pcap_t* a, const u_char* b, int c) {
|
int pcap_sendpacket(pcap_t* a, const u_char* b, int c) {
|
||||||
if (load_wpcap() != 0) {
|
if (load_pcap() != 0) {
|
||||||
return p_pcap_sendpacket(a, b, c);
|
return p_pcap_sendpacket(a, b, c);
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1011,7 +1075,7 @@ int pcap_sendpacket(pcap_t* a, const u_char* b, int c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcap_setfilter(pcap_t* a, struct bpf_program* b) {
|
int pcap_setfilter(pcap_t* a, struct bpf_program* b) {
|
||||||
if (load_wpcap() != 0) {
|
if (load_pcap() != 0) {
|
||||||
return p_pcap_setfilter(a, b);
|
return p_pcap_setfilter(a, b);
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
10
sim_ether.h
10
sim_ether.h
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
Modification history:
|
Modification history:
|
||||||
|
|
||||||
|
17-Nov-11 MP Added dynamic loading of libpcap on *nix platforms
|
||||||
30-Oct-11 MP Added support for vde (Virtual Distributed Ethernet) networking
|
30-Oct-11 MP Added support for vde (Virtual Distributed Ethernet) networking
|
||||||
18-Apr-11 MP Fixed race condition with self loopback packets in
|
18-Apr-11 MP Fixed race condition with self loopback packets in
|
||||||
multithreaded environments
|
multithreaded environments
|
||||||
|
@ -98,6 +99,15 @@
|
||||||
#endif
|
#endif
|
||||||
#endif /* USE_READER_THREAD */
|
#endif /* USE_READER_THREAD */
|
||||||
|
|
||||||
|
/* give priority to USE_NETWORK over USE_SHARED */
|
||||||
|
#if defined(USE_NETWORK) && defined(USE_SHARED)
|
||||||
|
#undef USE_SHARED
|
||||||
|
#endif
|
||||||
|
/* USE_SHARED only works on Windows or if HAVE_DLOPEN */
|
||||||
|
#if defined(USE_SHARED) && !defined(_WIN32) && !defined(HAVE_DLOPEN)
|
||||||
|
#undef USE_SHARED
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
USE_BPF is defined to let this code leverage the libpcap/OS kernel provided
|
USE_BPF is defined to let this code leverage the libpcap/OS kernel provided
|
||||||
BPF packet filtering. This generally will enhance performance. It may not
|
BPF packet filtering. This generally will enhance performance. It may not
|
||||||
|
|
Loading…
Add table
Reference in a new issue