diff --git a/0readme_ethernet.txt b/0readme_ethernet.txt index eb1c66f0..225f5be0 100644 --- a/0readme_ethernet.txt +++ b/0readme_ethernet.txt @@ -378,6 +378,7 @@ Dave 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 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 diff --git a/Visual Studio Projects/0ReadMe_Projects.txt b/Visual Studio Projects/0ReadMe_Projects.txt index fa304799..19baa7c6 100644 --- a/Visual Studio Projects/0ReadMe_Projects.txt +++ b/Visual Studio Projects/0ReadMe_Projects.txt @@ -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: @@ -13,8 +20,10 @@ For Example, the directory structure should look like: The winpcap developer pack can be found at: 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 @@ -24,10 +33,18 @@ To install pthreads API, create the directory: .../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. -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. diff --git a/makefile b/makefile index b5b7c0ac..e9083995 100644 --- a/makefile +++ b/makefile @@ -7,93 +7,162 @@ # NetBSD # FreeBSD # 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) # -ifeq ($(WIN32),) - #*nix Environments (&& cygwin) - GCC = gcc +ifeq ($(WIN32),) #*nix Environments (&& cygwin) + ifeq ($(GCC),) + GCC = gcc + endif ifeq (SunOS,$(shell uname)) TEST = /bin/test else TEST = test endif - ifeq (Darwin,$(shell uname)) - LIBEXT = dylib - else - ifeq (Linux,$(shell uname)) - LIBEXT = so + ifeq (agcc,$(findstring agcc,$(GCC))) # Android target build? + OS_CCDEFS = -D_GNU_SOURCE -DSIM_ASYNCH_IO + OS_LDFLAGS = -lm + else # Non-Android Builds + INCPATH=/usr/include + LIBPATH=/usr/lib + OS_CCDEFS = -D_GNU_SOURCE + ifeq (Darwin,$(shell uname)) + LIBEXT = dylib else - ifeq (SunOS,$(shell uname)) + ifeq (Linux,$(shell uname)) 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 - LIBEXT = a - endif - endif - endif - OS_CCDEFS = -D_GNU_SOURCE - ifeq (libm,$(shell if $(TEST) -e /usr/lib/libm.$(LIBEXT) -o -e /usr/lib64/libm.$(LIBEXT); then echo libm; fi)) - OS_LDFLAGS += -lm - endif - ifeq (SunOS,$(shell uname)) - OS_CCDEFS += -I/opt/sfw/include - OS_LDFLAGS += -lsocket -lnsl -L/opt/sfw/lib -R/opt/sfw/lib - 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 + ifeq (SunOS,$(shell uname)) + LIBEXT = so + OS_LDFLAGS += -lsocket -lnsl + ifeq (incsfw,$(shell if $(TEST) -d /opt/sfw/include; then echo incsfw; fi)) + INCPATH += /opt/sfw/include + OS_CCDEFS += -I/opt/sfw/include + endif + ifeq (libsfw,$(shell if $(TEST) -d /opt/sfw/lib; then echo libsfw; fi)) + LIBPATH += /opt/sfw/lib + OS_LDFLAGS += -L/opt/sfw/lib -R/opt/sfw/lib + endif else - ifeq (solaris_readline,$(shell if $(TEST) ! -e /opt/sfw/lib/libreadline.a; then echo solaris_readline; fi)) - OS_CCDEFS += -DHAVE_READLINE - OS_LDFLAGS += -lreadline + ifeq (usrpkglib,$(shell if $(TEST) -d /usr/pkg/lib; then echo usrpkglib; fi)) + LIBPATH += /usr/pkg/lib + 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 - ifeq (pcap,$(shell if $(TEST) -e /usr/include/pcap.h -o -e /opt/sfw/include/pcap.h; then echo pcap; fi)) - # Use Locally installed and available pcap support - NETWORK_CCDEFS = -DUSE_NETWORK - NETWORK_LDFLAGS = -lpcap + ifeq (cygwin,$(findstring cygwin,$(OSTYPE))) + OS_CCDEFS += -O2 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)) - # Provide support for vde networking - NETWORK_CCDEFS += -DUSE_VDE_NETWORK - NETWORK_LDFLAGS += -lvdeplug + find_lib = $(strip $(firstword $(foreach dir,$(strip $(LIBPATH)),$(wildcard $(dir)/lib$(1).$(LIBEXT))))) + find_include = $(strip $(firstword $(foreach dir,$(strip $(INCPATH)),$(wildcard $(dir)/$(1).h)))) + ifneq (,$(call find_lib,m)) + OS_LDFLAGS += -lm + $(info using libm: $(call find_lib,m)) 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 NETWORK_CCDEFS += -DUSE_TAP_NETWORK endif 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 endif ifneq (binexists,$(shell if $(TEST) -e BIN; then echo binexists; fi)) MKDIRBIN = if $(TEST) ! -e BIN; then mkdir BIN; fi endif NETWORK_OPT = $(NETWORK_CCDEFS) - ifneq ($(USE_NETWORK),) - # Assume built from tcpdump.org sources with default install target - NETWORK_OPT = -DUSE_NETWORK -isystem /usr/local/include /usr/local/lib/libpcap.a + ifneq ($(USE_NETWORK),) # Network support specified on the GNU make command line + ifneq (USE_NETWORK,$(findstring USE_NETWORK,$(NETWORK_CCDEFS))) + # 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 else #Win32 Environments (via MinGW32) @@ -403,7 +472,11 @@ endif ${BIN}BuildROMs${EXE} : ${MKDIRBIN} +ifeq (agcc,$(findstring agcc,$(firstword $(CC)))) + gcc $(wordlist 2,1000,${CC}) sim_BuildROMs.c -o $@ +else ${CC} sim_BuildROMs.c -o $@ +endif ifeq ($(WIN32),) $@ ${RM} $@ diff --git a/scp.c b/scp.c index 9473b947..b70905be 100644 --- a/scp.c +++ b/scp.c @@ -213,9 +213,8 @@ #include #include -#if defined(HAVE_READLINE) -#include -#include +#if defined(HAVE_DLOPEN) /* Dynamic Readline support */ +#include #endif #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 *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? */ - char *tmpc = readline (prompt); /* get cmd line */ - if (tmpc == NULL) /* bad result? */ - cptr = NULL; + char *tmpc; + + 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 { - strncpy (cptr, tmpc, size); /* copy result */ - free (tmpc) ; /* free temp */ + printf ("%s", prompt); /* display prompt */ + 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 */ *cptr = 0; -#if defined (HAVE_READLINE) -if (prompt) - add_history (cptr); +#if defined (HAVE_DLOPEN) +if (prompt && p_add_history && *cptr) /* Save non blank lines in history */ + p_add_history (cptr); #endif return cptr; diff --git a/sim_ether.c b/sim_ether.c index 3ca7eefa..e428360c 100644 --- a/sim_ether.c +++ b/sim_ether.c @@ -50,7 +50,7 @@ Define one of the two macros below to enable networking: 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: + 17-Nov-11 MP Added dynamic loading of libpcap on *nix platforms 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 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 */ /*============================================================================*/ -#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) {return SCPE_NOFNC;} t_stat eth_close (ETH_DEV* dev) @@ -816,18 +817,39 @@ void eth_show_dev (FILE* st, ETH_DEV* dev) #include #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 Etherial/WireShark capture_pcap.c */ +#ifdef HAVE_DLOPEN +#include +#endif + /* Dynamic DLL load variables */ -static HINSTANCE hDll = 0; /* handle to DLL */ -static int dll_loaded = 0; /* 0=not loaded, 1=loaded, 2=DLL load failed, 3=Func load failed */ -static char* no_wpcap = "wpcap load failure"; +#ifdef _WIN32 +static HINSTANCE hLib = 0; /* handle to DLL */ +#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 */ 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_dispatch) (pcap_t *, int, pcap_handler, u_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 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 *); +#ifdef _WIN32 static int (*p_pcap_setmintocopy) (pcap_t* handle, int); 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_setfilter) (pcap_t *, struct bpf_program *); static char* (*p_pcap_lib_version) (void); /* load function pointer from DLL */ void load_function(char* function, void** func_ptr) { - *func_ptr = GetProcAddress(hDll, function); - if (*func_ptr == 0) { - char* msg = "Eth: Failed to find function '%s' in wpcap.dll\r\n"; +#ifdef _WIN32 + *func_ptr = GetProcAddress(hLib, function); +#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); - if (sim_log) fprintf (sim_log, msg, function); - dll_loaded = 3; + printf (msg, function, lib_name); + if (sim_log) fprintf (sim_log, msg, function, lib_name); + lib_loaded = 3; } } /* load wpcap.dll as required */ -int load_wpcap(void) { - switch(dll_loaded) { +int load_pcap(void) { + switch(lib_loaded) { case 0: /* not loaded */ /* attempt to load DLL */ - hDll = LoadLibrary(TEXT("wpcap.dll")); - if (hDll == 0) { +#ifdef _WIN32 + hLib = LoadLibraryA(lib_name); +#else + hLib = dlopen(lib_name, RTLD_NOW); +#endif + if (hLib == 0) { /* failed to load DLL */ - char* msg = "Eth: Failed to load wpcap.dll\r\n"; - char* msg2 = "Eth: You must install WinPcap 4.x to use networking\r\n"; + char* msg = "Eth: Failed to load %s\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 (msg2); + printf (msg, lib_name); + printf ("%s", msg2); if (sim_log) { - fprintf (sim_log, msg); - fprintf (sim_log, msg2); + fprintf (sim_log, msg, lib_name); + fprintf (sim_log, "%s", msg2); } - dll_loaded = 2; + lib_loaded = 2; break; } else { - /* DLL loaded OK */ - dll_loaded = 1; + /* library loaded OK */ + lib_loaded = 1; } /* 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_lookupnet", (void**) &p_pcap_lookupnet); load_function("pcap_open_live", (void**) &p_pcap_open_live); +#ifdef _WIN32 load_function("pcap_setmintocopy", (void**) &p_pcap_setmintocopy); 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_setfilter", (void**) &p_pcap_setfilter); load_function("pcap_lib_version", (void**) &p_pcap_lib_version); - if (dll_loaded == 1) { + if (lib_loaded == 1) { /* log successful load */ char* version = p_pcap_lib_version(); printf("%s\n", version); @@ -906,18 +951,18 @@ int load_wpcap(void) { default: /* loaded or failed */ break; } - return (dll_loaded == 1) ? 1 : 0; + return (lib_loaded == 1) ? 1 : 0; } /* define functions with dynamic revectoring */ void pcap_close(pcap_t* a) { - if (load_wpcap() != 0) { + if (load_pcap() != 0) { p_pcap_close(a); } } -int pcap_compile(pcap_t* a, struct bpf_program* b, char* c, int d, bpf_u_int32 e) { - if (load_wpcap() != 0) { +int pcap_compile(pcap_t* a, struct bpf_program* b, const char* c, int d, bpf_u_int32 e) { + if (load_pcap() != 0) { return p_pcap_compile(a, b, c, d, e); } else { 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) { - if (load_wpcap() != 0) { + if (load_pcap() != 0) { return p_pcap_datalink(a); } else { 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) { - if (load_wpcap() != 0) { + if (load_pcap() != 0) { return p_pcap_dispatch(a, b, c, d); } else { 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) { - if (load_wpcap() != 0) { + if (load_pcap() != 0) { return p_pcap_findalldevs(a, b); } else { *a = 0; - strcpy(b, no_wpcap); + strcpy(b, no_pcap); return -1; } } void pcap_freealldevs(pcap_if_t* a) { - if (load_wpcap() != 0) { + if (load_pcap() != 0) { p_pcap_freealldevs(a); } } void pcap_freecode(struct bpf_program* a) { - if (load_wpcap() != 0) { + if (load_pcap() != 0) { p_pcap_freecode(a); } } char* pcap_geterr(pcap_t* a) { - if (load_wpcap() != 0) { + if (load_pcap() != 0) { return p_pcap_geterr(a); } else { 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) { - if (load_wpcap() != 0) { + if (load_pcap() != 0) { return p_pcap_lookupnet(a, b, c, d); } else { 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) { - if (load_wpcap() != 0) { + if (load_pcap() != 0) { return p_pcap_open_live(a, b, c, d, e); } else { return (pcap_t*) 0; } } +#ifdef _WIN32 int pcap_setmintocopy(pcap_t* a, int b) { - if (load_wpcap() != 0) { + if (load_pcap() != 0) { return p_pcap_setmintocopy(a, b); } else { return 0; @@ -995,15 +1041,33 @@ int pcap_setmintocopy(pcap_t* a, int b) { } HANDLE pcap_getevent(pcap_t* a) { - if (load_wpcap() != 0) { + if (load_pcap() != 0) { return p_pcap_getevent(a); } else { 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) { - if (load_wpcap() != 0) { + if (load_pcap() != 0) { return p_pcap_sendpacket(a, b, c); } else { 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) { - if (load_wpcap() != 0) { + if (load_pcap() != 0) { return p_pcap_setfilter(a, b); } else { return 0; diff --git a/sim_ether.h b/sim_ether.h index 1478c40c..2314e835 100644 --- a/sim_ether.h +++ b/sim_ether.h @@ -28,6 +28,7 @@ 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 18-Apr-11 MP Fixed race condition with self loopback packets in multithreaded environments @@ -98,6 +99,15 @@ #endif #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 BPF packet filtering. This generally will enhance performance. It may not