Merge branch 'master' into Extra-VAXen

Conflicts:
	makefile
This commit is contained in:
Mark Pizzolato 2011-11-17 17:14:27 -08:00
commit 71bc2e80c1
6 changed files with 308 additions and 119 deletions

View file

@ -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

View file

@ -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
View file

@ -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
View file

@ -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;

View file

@ -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;

View file

@ -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