summaryrefslogtreecommitdiffstats
path: root/lib/libpcap/libpcap/msdos
diff options
context:
space:
mode:
authorCameron Katri <me@cameronkatri.com>2021-05-10 14:55:20 -0400
committerCameron Katri <me@cameronkatri.com>2021-05-10 14:55:20 -0400
commitd88d199f23088ac1c3d7696374b0a1c1c1c18358 (patch)
tree977307e478f76c5de5ca141268cf8ce0309a09eb /lib/libpcap/libpcap/msdos
parent5fd83771641d15c418f747bd343ba6738d3875f7 (diff)
downloadapple_cmds-d88d199f23088ac1c3d7696374b0a1c1c1c18358.tar.gz
apple_cmds-d88d199f23088ac1c3d7696374b0a1c1c1c18358.tar.zst
apple_cmds-d88d199f23088ac1c3d7696374b0a1c1c1c18358.zip
libpcap-98.40.1
Diffstat (limited to 'lib/libpcap/libpcap/msdos')
-rw-r--r--lib/libpcap/libpcap/msdos/bin2c.c43
-rw-r--r--lib/libpcap/libpcap/msdos/common.dj0
-rw-r--r--lib/libpcap/libpcap/msdos/makefile180
-rw-r--r--lib/libpcap/libpcap/msdos/makefile.dj127
-rw-r--r--lib/libpcap/libpcap/msdos/makefile.wc132
-rw-r--r--lib/libpcap/libpcap/msdos/ndis2.c0
-rw-r--r--lib/libpcap/libpcap/msdos/ndis2.h0
-rw-r--r--lib/libpcap/libpcap/msdos/ndis_0.asm0
-rw-r--r--lib/libpcap/libpcap/msdos/pkt_rx0.asm197
-rw-r--r--lib/libpcap/libpcap/msdos/pkt_rx1.s155
-rw-r--r--lib/libpcap/libpcap/msdos/pktdrvr.c1436
-rw-r--r--lib/libpcap/libpcap/msdos/pktdrvr.h153
-rw-r--r--lib/libpcap/libpcap/msdos/readme.dos166
13 files changed, 2589 insertions, 0 deletions
diff --git a/lib/libpcap/libpcap/msdos/bin2c.c b/lib/libpcap/libpcap/msdos/bin2c.c
new file mode 100644
index 0000000..26d9008
--- /dev/null
+++ b/lib/libpcap/libpcap/msdos/bin2c.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <time.h>
+
+static void Abort (const char *fmt,...)
+{
+ va_list args;
+ va_start (args, fmt);
+ vfprintf (stderr, fmt, args);
+ va_end (args);
+ exit (1);
+}
+
+int main (int argc, char **argv)
+{
+ FILE *inFile;
+ FILE *outFile = stdout;
+ time_t now = time (NULL);
+ int ch, i;
+
+ if (argc != 2)
+ Abort ("Usage: %s bin-file [> result]", argv[0]);
+
+ if ((inFile = fopen(argv[1],"rb")) == NULL)
+ Abort ("Cannot open %s\n", argv[1]);
+
+ fprintf (outFile,
+ "/* data statements for file %s at %.24s */\n"
+ "/* Generated by BIN2C, G. Vanem 1995 */\n",
+ argv[1], ctime(&now));
+
+ i = 0;
+ while ((ch = fgetc(inFile)) != EOF)
+ {
+ if (i++ % 12 == 0)
+ fputs ("\n ", outFile);
+ fprintf (outFile, "0x%02X,", ch);
+ }
+ fputc ('\n', outFile);
+ fclose (inFile);
+ return (0);
+}
diff --git a/lib/libpcap/libpcap/msdos/common.dj b/lib/libpcap/libpcap/msdos/common.dj
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/libpcap/libpcap/msdos/common.dj
diff --git a/lib/libpcap/libpcap/msdos/makefile b/lib/libpcap/libpcap/msdos/makefile
new file mode 100644
index 0000000..599a619
--- /dev/null
+++ b/lib/libpcap/libpcap/msdos/makefile
@@ -0,0 +1,180 @@
+#
+# Makefile for dos-libpcap. NB. This makefile requires a Borland
+# compatible make tool.
+#
+# Targets:
+# Borland C 4.0+ (DOS large model)
+# Metaware HighC 3.3+ (PharLap 386|DosX)
+#
+
+.AUTODEPEND
+.SWAP
+
+!if "$(WATT_ROOT)" == ""
+!error Environment variable "WATT_ROOT" not set.
+!endif
+
+WATT_INC = $(WATT_ROOT)\inc
+
+DEFS = -DMSDOS -DDEBUG -DNDIS_DEBUG -D_U_= -Dinline= \
+ -DHAVE_STRERROR -DHAVE_LIMITS_H
+
+ASM = tasm.exe -t -l -mx -m2 -DDEBUG
+
+SOURCE = grammar.c scanner.c bpf_filt.c bpf_imag.c bpf_dump.c \
+ etherent.c gencode.c nametoad.c pcap-dos.c optimize.c \
+ savefile.c pcap.c msdos\ndis2.c msdos\pktdrvr.c \
+ missing\snprintf.c
+
+BORLAND_OBJ = $(SOURCE:.c=.obj) msdos\pkt_rx0.obj msdos\ndis_0.obj
+
+HIGHC_OBJ = $(SOURCE:.c=.o32) msdos\pkt_rx0.o32
+
+all:
+ @echo Usage: make pcap_bc.lib or pcap_hc.lib
+
+
+pcap_bc.lib: bcc.arg $(BORLAND_OBJ) pcap_bc
+
+
+pcap_hc.lib: hc386.arg $(HIGHC_OBJ)
+ 386lib $< @&&|
+ -nowarn -nobackup -twocase -replace $(HIGHC_OBJ)
+|
+
+pcap_bc: $(BORLAND_OBJ)
+ @tlib pcap_bc.lib /C @&&|
+ -+$(**:.obj=-+)
+|
+
+.c.obj:
+ bcc.exe @bcc.arg -o$*.obj $*.c
+
+.c.o32:
+ hc386.exe @hc386.arg -o $*.o32 $*.c
+
+.asm.obj:
+ $(ASM) $*.asm, $*.obj
+
+.asm.o32:
+ $(ASM) -DDOSX=1 $*.asm, $*.o32
+
+scanner.c: scanner.l
+ flex -Ppcap_ -7 -oscanner.c scanner.l
+
+grammar.c tokdefs.h: grammar.y
+ bison --name-prefix=pcap_ --yacc --defines grammar.y
+ - @del grammar.c
+ - @del tokdefs.h
+ ren y_tab.c grammar.c
+ ren y_tab.h tokdefs.h
+
+bcc.arg: msdos\Makefile
+ @copy &&|
+ $(DEFS) -ml -c -v -3 -O2 -po -RT- -w-
+ -I$(WATT_INC) -I. -I.\msdos\pm_drvr -H=$(TEMP)\bcc.sym
+| $<
+
+hc386.arg: msdos\Makefile
+ @copy &&|
+ # -DUSE_32BIT_DRIVERS
+ $(DEFS) -DDOSX=1 -w3 -c -g -O5
+ -I$(WATT_INC) -I. -I.\msdos\pm_drvr
+ -Hsuffix=.o32
+ -Hnocopyr
+ -Hpragma=Offwarn(491,553,572)
+ -Hon=Recognize_library # make memcpy/strlen etc. inline
+ -Hoff=Behaved # turn off some optimiser warnings
+| $<
+
+clean:
+ @del *.obj
+ @del *.o32
+ @del *.lst
+ @del *.map
+ @del bcc.arg
+ @del hc386.arg
+ @del grammar.c
+ @del tokdefs.h
+ @del scanner.c
+ @echo Cleaned
+
+#
+# dependencies
+#
+pkt_rx0.obj: msdos\pkt_rx0.asm
+
+bpf_filt.obj: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.h
+
+bpf_imag.obj: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h
+
+bpf_dump.obj: bpf_dump.c pcap.h pcap-bpf.h
+
+etherent.obj: etherent.c pcap-int.h pcap.h pcap-bpf.h pcap-namedb.h
+
+optimize.obj: optimize.c pcap-int.h pcap.h pcap-bpf.h gencode.h
+
+savefile.obj: savefile.c pcap-int.h pcap.h pcap-bpf.h
+
+pcap.obj: pcap.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h
+
+grammar.obj: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
+ pf.h pcap-namedb.h
+
+scanner.obj: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
+ pcap-namedb.h tokdefs.h
+
+gencode.obj: gencode.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \
+ ethertype.h nlpid.h llc.h gencode.h atmuni31.h sunatmpos.h ppp.h sll.h \
+ arcnet.h pf.h pcap-namedb.h
+
+nametoad.obj: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
+ pcap-namedb.h ethertype.h
+
+pcap-dos.obj: pcap-dos.c pcap.h pcap-bpf.h pcap-dos.h pcap-int.h \
+ msdos\pktdrvr.h
+
+pktdrvr.obj: msdos\pktdrvr.c gnuc.h pcap-dos.h pcap-int.h \
+ pcap.h pcap-bpf.h msdos\pktdrvr.h msdos\pkt_stub.inc
+
+ndis2.obj: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \
+ msdos\ndis2.h
+
+pkt_rx0.o32: msdos\pkt_rx0.asm
+
+bpf_filt.o32: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.h
+
+bpf_imag.o32: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h
+
+bpf_dump.o32: bpf_dump.c pcap.h pcap-bpf.h
+
+etherent.o32: etherent.c pcap-int.h pcap.h pcap-bpf.h pcap-namedb.h
+
+optimize.o32: optimize.c pcap-int.h pcap.h pcap-bpf.h gencode.h
+
+savefile.o32: savefile.c pcap-int.h pcap.h pcap-bpf.h
+
+pcap.o32: pcap.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h
+
+grammar.o32: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
+ pf.h pcap-namedb.h
+
+scanner.o32: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
+ pcap-namedb.h tokdefs.h
+
+gencode.o32: gencode.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \
+ ethertype.h nlpid.h llc.h gencode.h atmuni31.h sunatmpos.h ppp.h sll.h \
+ arcnet.h pf.h pcap-namedb.h
+
+nametoad.o32: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h \
+ pcap-namedb.h ethertype.h
+
+pcap-dos.o32: pcap-dos.c pcap.h pcap-bpf.h pcap-dos.h pcap-int.h \
+ msdos\pktdrvr.h
+
+pktdrvr.o32: msdos\pktdrvr.c gnuc.h pcap-dos.h pcap-int.h \
+ pcap.h pcap-bpf.h msdos\pktdrvr.h msdos\pkt_stub.inc
+
+ndis2.o32: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \
+ msdos\ndis2.h
+
diff --git a/lib/libpcap/libpcap/msdos/makefile.dj b/lib/libpcap/libpcap/msdos/makefile.dj
new file mode 100644
index 0000000..190db00
--- /dev/null
+++ b/lib/libpcap/libpcap/msdos/makefile.dj
@@ -0,0 +1,127 @@
+#
+# GNU Makefile for DOS-libpcap. djgpp version.
+#
+# Use this makefile from the libpcap root directory.
+# E.g. like this:
+#
+# c:\net\pcap> make -f msdos/makefile.dj
+#
+# Note: you should do a "set LFN=y" before running this makefile.
+#
+
+VPATH = missing msdos bpf/net
+
+PREREQUISITES = scanner.c grammar.c tokdefs.h version.h msdos/pkt_stub.inc
+
+include ./msdos/common.dj
+
+DRIVER_DIR = ./msdos/pm_drvr
+
+CFLAGS += -DDEBUG -DNDIS_DEBUG -DHAVE_LIMITS_H -DHAVE_STRERROR -DHAVE_SNPRINTF -DHAVE_VSNPRINTF\
+ -D_U_='__attribute__((unused))'
+
+CFLAGS += -Dyylval=pcap_lval # -DBDEBUG -DNDEBUG
+
+SOURCES = grammar.c scanner.c bpf/net/bpf_filter.c bpf_image.c bpf_dump.c \
+ etherent.c gencode.c nametoaddr.c pcap-common.c pcap-dos.c optimize.c \
+ savefile.c pcap.c sf-pcap.c sf-pcapng.c \
+ msdos/pktdrvr.c msdos/ndis2.c # missing/snprintf.c
+
+OBJECTS = $(addprefix $(OBJ_DIR)/, $(notdir $(SOURCES:.c=.o)))
+TEMPBIN = tmp.bin
+
+ifeq ($(USE_32BIT_DRIVERS),1)
+ PM_OBJECTS = $(addprefix $(OBJ_DIR)/, \
+ printk.o pci.o pci-scan.o bios32.o dma.o irq.o intwrap.o \
+ lock.o kmalloc.o quirks.o timer.o net_init.o)
+ #
+ # Static link of drivers
+ #
+ ifeq ($(USE_32BIT_MODULES),0)
+ PM_OBJECTS += $(addprefix $(OBJ_DIR)/, \
+ accton.o 8390.o 3c503.o 3c509.o 3c59x.o 3c515.o \
+ 3c575_cb.o 3c90x.o ne.o wd.o cs89x0.o rtl8139.o)
+ endif
+endif
+
+TARGETS = msdos/bin2c.exe libpcap.a filtertest.exe findalldevstest.exe \
+ nonblocktest.exe opentest.exe
+
+all: $(TARGETS)
+ @echo 'Welcome to libpcap/djgpp with samples.'
+
+ifeq ($(USE_32BIT_DRIVERS),1)
+$(PM_OBJECTS):
+ $(MAKE) -f Makefile.dj -C $(DRIVER_DIR) $(notdir $@)
+endif
+
+libpcap.a: version.h $(OBJECTS) $(PM_OBJECTS)
+ rm -f $@
+ ar rs $@ $^
+
+filtertest.exe: tests/filtertest.c libpcap.a
+ $(CC) $(CFLAGS) -Din_addr_t=u_long -o $@ $^ $(WATT32_ROOT)/lib/libwatt.a
+ @echo
+
+findalldevstest.exe: tests/findalldevstest.c libpcap.a
+ $(CC) $(CFLAGS) -o $@ $^ $(WATT32_ROOT)/lib/libwatt.a
+ @echo
+
+nonblocktest.exe: tests/nonblocktest.c libpcap.a
+ $(CC) $(CFLAGS) -o $@ $^ $(WATT32_ROOT)/lib/libwatt.a
+ @echo
+
+opentest.exe: tests/opentest.c libpcap.a
+ $(CC) $(CFLAGS) -o $@ $^ $(WATT32_ROOT)/lib/libwatt.a
+ @echo
+
+msdos/pkt_stub.inc: msdos/bin2c.exe msdos/pkt_rx1.S
+ $(ASM) -o $(TEMPBIN) -lmsdos/pkt_rx1.lst msdos/pkt_rx1.S
+ ./msdos/bin2c $(TEMPBIN) > $@
+ rm -f $(TEMPBIN)
+
+grammar.c tokdefs.h: grammar.y
+ rm -f grammar.c tokdefs.h
+ $(YACC) --name-prefix=pcap_ --yacc --defines grammar.y
+ mv -f y.tab.c grammar.c
+ mv -f y.tab.h tokdefs.h
+
+version.h: ./VERSION
+ @echo '/* Generated from VERSION. Do not edit */' > $@
+ sed -e 's/.*/static char pcap_version_string[] = "libpcap (&)";/' ./VERSION >> $@
+
+scanner.c: scanner.l
+ $(LEX) -Ppcap_ -7 -t $^ > $@
+ @echo
+
+msdos/bin2c.exe: msdos/bin2c.c
+ $(CC) $*.c -o $*.exe
+
+clean:
+ rm -f $(OBJECTS) msdos/pkt_rx1.lst Makefile.bak .depend.dj $(PREREQUISITES)
+# $(MAKE) -f Makefile.dj -C $(DRIVER_DIR) clean
+
+vclean: clean
+ rm -f $(TARGETS)
+ -rmdir $(OBJ_DIR)
+
+#
+# Manually generated dependencies
+#
+msdos/pktdrvr.c: msdos/pkt_stub.inc
+scanner.c: scanner.l
+grammar.c tokdefs.h: grammar.y
+grammar.h: grammar.y
+scanner.l: pcap-int.h pcap-namedb.h gencode.h grammar.h
+grammar.y: pcap-int.h gencode.h pcap-namedb.h
+
+#
+# Generate dependencies.
+#
+REPLACE = sed -e 's/\(.*\)\.o: /\n$$(OBJ_DIR)\/\1.o: /'
+
+depend: $(PREREQUISITES)
+ $(CC) -MM $(CFLAGS) $(SOURCES) | $(REPLACE) > .depend.dj
+
+-include .depend.dj
+
diff --git a/lib/libpcap/libpcap/msdos/makefile.wc b/lib/libpcap/libpcap/msdos/makefile.wc
new file mode 100644
index 0000000..0246012
--- /dev/null
+++ b/lib/libpcap/libpcap/msdos/makefile.wc
@@ -0,0 +1,132 @@
+#
+# Watcom Makefile for dos-libpcap.
+#
+# Specify MODEL = `3r' or `3s'
+# Specify TARGET = `pharlap' or `dos4g'
+#
+# Use this makefile from the libpcap root directory.
+# E.g. like this:
+#
+# c:\net\pcap> wmake -f msdos\makefile.wc
+#
+
+MODEL = 3s
+TARGET = dos4g
+
+OBJDIR = msdos\$(TARGET).w$(MODEL)
+LIB = $(OBJDIR)\pcap.lib
+
+.EXTENSIONS: .l .y
+
+DEFS = -dDEBUG -dNDIS_DEBUG -d_U_= -dHAVE_LIMITS_H -dHAVE_STRERROR &
+ -dHAVE_SNPRINTF -dHAVE_VSNPRINTF
+
+CC = wcc386.exe
+ASM = wasm.exe -$(MODEL) $(DEFS) -dDOSX -dDOS4GW -zq -bt=dos -fr=nul -d3 -s
+
+OBJS = $(OBJDIR)\grammar.obj $(OBJDIR)\scanner.obj $(OBJDIR)\pcap.obj &
+ $(OBJDIR)\bpf_filter.obj $(OBJDIR)\bpf_imag.obj $(OBJDIR)\bpf_dump.obj &
+ $(OBJDIR)\etherent.obj $(OBJDIR)\gencode.obj $(OBJDIR)\nametoad.obj &
+ $(OBJDIR)\pcap-dos.obj $(OBJDIR)\pktdrvr.obj $(OBJDIR)\optimize.obj &
+ $(OBJDIR)\savefile.obj $(OBJDIR)\ndis2.obj
+
+CFLAGS = $(DEFS) $(YYDEFS) -I. -I$(%watt_root)\inc -I.\msdos\pm_drvr &
+ -$(MODEL) -mf -zff -zgf -zq -bt=dos -fr=nul -w6 -fpi &
+ -oilrtf -zm
+
+TEMPBIN = tmp.bin
+
+all: $(OBJDIR) $(OBJDIR)\pcap.lib
+
+$(OBJDIR):
+ - mkdir $(OBJDIR)
+
+$(OBJDIR)\pcap.lib: $(OBJS) wlib.arg
+ wlib -q -b -c $(OBJDIR)\pcap.lib @wlib.arg
+
+wlib.arg: msdos\makefile.wc
+ %create $^@
+ for %f in ($(OBJS)) do %append $^@ +- %f
+
+$(OBJDIR)\pktdrvr.obj: msdos\pkt_stub.inc msdos\pktdrvr.c &
+ pcap-dos.h pcap-int.h pcap.h msdos\pktdrvr.h
+ *$(CC) $(CFLAGS) msdos\pktdrvr.c -fo=$@
+
+$(OBJDIR)\bpf_filter.obj: bpf\net\bpf_filter.c
+ *$(CC) $(CFLAGS) bpf\net\bpf_filter.c -fo=$@
+
+$(OBJDIR)\ndis2.obj: msdos\ndis2.c
+ *$(CC) $(CFLAGS) msdos\ndis2.c -fo=$@
+
+.ERASE
+.c{$(OBJDIR)}.obj:
+ *$(CC) $(CFLAGS) $[@ -fo=$@
+
+grammar.c tokdefs.h: grammar.y
+ bison --name-prefix=pcap_ --yacc --defines $[@
+ - @del grammar.c
+ - @del tokdefs.h
+ ren y_tab.c grammar.c
+ ren y_tab.h tokdefs.h
+
+scanner.c: scanner.l
+ flex -Ppcap_ -7 -o$@ $[@
+
+msdos\pkt_stub.inc: bin2c.exe msdos\pkt_rx1.S
+ nasm -fbin -dDEBUG -o $(TEMPBIN) -lmsdos\pkt_rx1.lst msdos\pkt_rx1.S
+ bin2c.exe $(TEMPBIN) > $@
+ @del $(TEMPBIN)
+
+bin2c.exe: msdos\bin2c.c
+ wcl $[@
+
+clean realclean vclean: .SYMBOLIC
+ for %f in (dos4g.w3r dos4g.w3s pharlap.w3r pharlap.w3s) do &
+ @del %f\*.obj
+ @del grammar.c
+ @del tokdefs.h
+ @del scanner.c
+ @del bin2c.exe
+ @del bin2c.obj
+ @del msdos\pkt_stub.inc
+ @echo Cleaned
+
+#
+# dependencies
+#
+$(OBJDIR)\bpf_filter.obj: bpf\net\bpf_filter.c pcap-int.h pcap.h pcap-bpf.h
+
+$(OBJDIR)\bpf_imag.obj: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h
+
+$(OBJDIR)\bpf_dump.obj: bpf_dump.c pcap.h pcap-bpf.h
+
+$(OBJDIR)\etherent.obj: etherent.c pcap-int.h pcap.h pcap-bpf.h pcap-namedb.h
+
+$(OBJDIR)\optimize.obj: optimize.c pcap-int.h pcap.h pcap-bpf.h gencode.h
+
+$(OBJDIR)\savefile.obj: savefile.c pcap-int.h pcap.h pcap-bpf.h
+
+$(OBJDIR)\pcap.obj: pcap.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h
+
+$(OBJDIR)\grammar.obj: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h &
+ pcap-namedb.h
+
+$(OBJDIR)\scanner.obj: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h &
+ pcap-namedb.h tokdefs.h
+
+$(OBJDIR)\gencode.obj: gencode.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h &
+ ethertyp.h nlpid.h llc.h gencode.h atmuni31.h sunatmpo.h ppp.h sll.h &
+ arcnet.h pcap-namedb.h
+
+$(OBJDIR)\nametoad.obj: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h &
+ pcap-namedb.h ethertyp.h
+
+$(OBJDIR)\pcap-dos.obj: pcap-dos.c pcap.h pcap-bpf.h pcap-dos.h pcap-int.h &
+ msdos\pktdrvr.h
+
+$(OBJDIR)\pktdrvr.obj: msdos\pktdrvr.c pcap-dos.h pcap-int.h &
+ pcap.h pcap-bpf.h msdos\pktdrvr.h msdos\pkt_stub.inc
+
+$(OBJDIR)\ndis2.obj: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h &
+ msdos\ndis2.h
+
diff --git a/lib/libpcap/libpcap/msdos/ndis2.c b/lib/libpcap/libpcap/msdos/ndis2.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/libpcap/libpcap/msdos/ndis2.c
diff --git a/lib/libpcap/libpcap/msdos/ndis2.h b/lib/libpcap/libpcap/msdos/ndis2.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/libpcap/libpcap/msdos/ndis2.h
diff --git a/lib/libpcap/libpcap/msdos/ndis_0.asm b/lib/libpcap/libpcap/msdos/ndis_0.asm
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/libpcap/libpcap/msdos/ndis_0.asm
diff --git a/lib/libpcap/libpcap/msdos/pkt_rx0.asm b/lib/libpcap/libpcap/msdos/pkt_rx0.asm
new file mode 100644
index 0000000..d604fa1
--- /dev/null
+++ b/lib/libpcap/libpcap/msdos/pkt_rx0.asm
@@ -0,0 +1,197 @@
+PAGE 60,132
+NAME PKT_RX
+
+ifdef ??version ; using TASM
+ masm
+ jumps
+endif
+
+PUBLIC _pktDrop, _pktRxBuf, _pktTxBuf, _pktTemp
+PUBLIC _rxOutOfs, _rxInOfs, _PktReceiver, _pktRxEnd
+
+;
+; these sizes MUST be equal to the sizes in PKTDRVR.H
+;
+
+RX_BUF_SIZE = 1500 ; max message size on Ethernet
+TX_BUF_SIZE = 1500
+
+ifdef DOSX
+ .386
+ NUM_RX_BUF = 32 ; # of RX element buffers
+ _TEXT SEGMENT PUBLIC DWORD USE16 'CODE'
+ _TEXT ENDS
+ _DATA SEGMENT PUBLIC DWORD USE16 'CODE'
+ _DATA ENDS
+ D_SEG EQU <_TEXT SEGMENT>
+ D_END EQU <_TEXT ENDS>
+ ASSUME CS:_TEXT,DS:_TEXT
+else
+ .286
+ NUM_RX_BUF = 10
+ _TEXT SEGMENT PUBLIC DWORD 'CODE'
+ _TEXT ENDS
+ _DATA SEGMENT PUBLIC DWORD 'DATA'
+ _DATA ENDS
+ D_SEG EQU <_DATA SEGMENT>
+ D_END EQU <_DATA ENDS>
+ ASSUME CS:_TEXT,DS:_DATA
+endif
+
+;-------------------------------------------
+
+D_SEG
+
+RX_ELEMENT STRUC
+ firstCount dw 0 ; # of bytes on 1st call
+ secondCount dw 0 ; # of bytes on 2nd call
+ handle dw 0 ; handle for upcall
+ destinAdr db 6 dup (0) ; packet destination address
+ sourceAdr db 6 dup (0) ; packet source address
+ protocol dw 0 ; packet protocol number
+ rxBuffer db RX_BUF_SIZE dup (0) ; RX buffer
+ENDS
+ align 4
+_rxOutOfs dw offset _pktRxBuf ; ring buffer offsets
+_rxInOfs dw offset _pktRxBuf ; into _pktRxBuf
+_pktDrop dw 0,0 ; packet drop counter
+_pktTemp db 20 dup (0) ; temp work area
+_pktTxBuf db (TX_BUF_SIZE+14) dup (0) ; TX buffer
+_pktRxBuf RX_ELEMENT NUM_RX_BUF dup (<>) ; RX structures
+ LAST_OFS = offset $
+
+ screenSeg dw 0B800h
+ newInOffset dw 0
+
+ fanChars db '-\|/'
+ fanIndex dw 0
+
+D_END
+
+_TEXT SEGMENT
+
+
+SHOW_RX MACRO
+ push es
+ push bx
+ mov bx, screenSeg
+ mov es, bx ;; r-mode segment of colour screen
+ mov di, 158 ;; upper right corner - 1
+ mov bx, fanIndex
+ mov al, fanChars[bx] ;; get write char
+ mov ah, 15 ;; and white colour
+ stosw ;; write to screen at ES:EDI
+ inc fanIndex ;; update next index
+ and fanIndex, 3
+ pop bx
+ pop es
+ENDM
+
+;------------------------------------------------------------------------
+;
+; This macro return ES:DI to tail of Rx queue
+
+ENQUEUE MACRO
+ LOCAL @noWrap
+ mov ax, _rxInOfs ;; DI = current in-offset
+ add ax, SIZE RX_ELEMENT ;; point to next _pktRxBuf buffer
+ cmp ax, LAST_OFS ;; pointing past last ?
+ jb @noWrap ;; no - jump
+ lea ax, _pktRxBuf ;; yes, point to 1st buffer
+ align 4
+@noWrap: cmp ax, _rxOutOfs ;; in-ofs = out-ofs ?
+ je @dump ;; yes, queue is full
+ mov di, _rxInOfs ;; ES:DI -> buffer at queue input
+ mov newInOffset, ax ;; remember new input offset
+
+ ;; NOTE. rxInOfs is updated after the packet has been copied
+ ;; to ES:DI (= DS:SI on 2nd call) by the packet driver
+
+ENDM
+
+;------------------------------------------------------------------------
+;
+; This routine gets called by the packet driver twice:
+; 1st time (AX=0) it requests an address where to put the packet
+;
+; 2nd time (AX=1) the packet has been copied to this location (DS:SI)
+; BX has client handle (stored in RX_ELEMENT.handle).
+; CX has # of bytes in packet on both call. They should be equal.
+;
+; A test for equality is done by putting CX in _pktRxBuf [n].firstCount
+; and _pktRxBuf[n].secondCount, and CL on first call in
+; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive"
+; (PKTDRVR.C)
+;
+;---------------------------------------------------------------------
+
+_PktReceiver:
+ pushf
+ cli ; no distraction wanted !
+ push ds
+ push bx
+ifdef DOSX
+ mov bx, cs
+else
+ mov bx, SEG _DATA
+endif
+ mov ds, bx
+ mov es, bx ; ES = DS = CS or seg _DATA
+ pop bx ; restore handle
+
+ cmp ax, 0 ; first call? (AX=0)
+ jne @post ; AX=1: second call, do post process
+
+ifdef DEBUG
+ SHOW_RX ; show that a packet is received
+endif
+ cmp cx, RX_BUF_SIZE+14 ; size OK ?
+ ja @skip ; no, packet to large for us
+
+ ENQUEUE ; ES:DI -> _pktRxBuf[n]
+
+ mov [di].firstCount, cx ; remember the first count.
+ mov [di].handle, bx ; remember the handle.
+ add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr
+ pop ds
+ popf
+ retf ; far return to driver with ES:DI
+
+ align 4
+@dump: inc _pktDrop[0] ; discard the packet on 1st call
+ adc _pktDrop[2], 0 ; increment packets lost
+
+@skip: xor di, di ; return ES:DI = NIL pointer
+ xor ax, ax
+ mov es, ax
+ pop ds
+ popf
+ retf
+
+ align 4
+@post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr
+ jz @discard ; make sure we don't use NULL-pointer
+
+ sub si, 6 ; DS:SI -> _pktRxBuf[n].destinAdr
+ ;
+ ; push si
+ ; push [si].firstCount
+ ; call bpf_filter_match ; run the filter here some day?
+ ; add sp, 4
+ ; cmp ax, 0
+ ; je @discard
+
+ mov [si].secondCount, cx
+ mov ax, newInOffset
+ mov _rxInOfs, ax ; update _pktRxBuf input offset
+
+ align 4
+@discard:pop ds
+ popf
+ retf
+
+_pktRxEnd db 0 ; marker for end of r-mode code/data
+
+_TEXT ENDS
+
+END
diff --git a/lib/libpcap/libpcap/msdos/pkt_rx1.s b/lib/libpcap/libpcap/msdos/pkt_rx1.s
new file mode 100644
index 0000000..654e657
--- /dev/null
+++ b/lib/libpcap/libpcap/msdos/pkt_rx1.s
@@ -0,0 +1,155 @@
+;
+; This file requires NASM 0.97+ to assemble
+;
+; Currently used only for djgpp + DOS4GW targets
+;
+; these sizes MUST be equal to the sizes in PKTDRVR.H
+;
+%define ETH_MTU 1500 ; max data size on Ethernet
+%define ETH_MIN 60 ; min/max total frame size
+%define ETH_MAX (ETH_MTU+2*6+2) ; =1514
+%define NUM_RX_BUF 32 ; # of RX element buffers
+%define RX_SIZE (ETH_MAX+6) ; sizeof(RX_ELEMENT) = 1514+6
+%idefine offset
+
+struc RX_ELEMENT
+ .firstCount resw 1 ; # of bytes on 1st call
+ .secondCount resw 1 ; # of bytes on 2nd call
+ .handle resw 1 ; handle for upcall
+ ; .timeStamp resw 4 ; 64-bit RDTSC value
+ .destinAdr resb 6 ; packet destination address
+ .sourceAdr resb 6 ; packet source address
+ .protocol resw 1 ; packet protocol number
+ .rxBuffer resb ETH_MTU ; RX buffer
+endstruc
+
+;-------------------------------------------
+
+[org 0] ; assemble to .bin file
+
+_rxOutOfs dw offset _pktRxBuf ; ring buffer offsets
+_rxInOfs dw offset _pktRxBuf ; into _pktRxBuf
+_pktDrop dw 0,0 ; packet drop counter
+_pktTemp resb 20 ; temp work area
+_pktTxBuf resb (ETH_MAX) ; TX buffer
+_pktRxBuf resb (RX_SIZE*NUM_RX_BUF) ; RX structures
+ LAST_OFS equ $
+
+screenSeg dw 0B800h
+newInOffset dw 0
+
+fanChars db '-\|/'
+fanIndex dw 0
+
+%macro SHOW_RX 0
+ push es
+ push bx
+ mov bx, [screenSeg]
+ mov es, bx ;; r-mode segment of colour screen
+ mov di, 158 ;; upper right corner - 1
+ mov bx, [fanIndex]
+ mov al, [fanChars+bx] ;; get write char
+ mov ah, 15 ;; and white colour
+ cld ;; Needed?
+ stosw ;; write to screen at ES:EDI
+ inc word [fanIndex] ;; update next index
+ and word [fanIndex], 3
+ pop bx
+ pop es
+%endmacro
+
+;PutTimeStamp
+; rdtsc
+; mov [si].timeStamp, eax
+; mov [si+4].timeStamp, edx
+; ret
+
+
+;------------------------------------------------------------------------
+;
+; This routine gets called by the packet driver twice:
+; 1st time (AX=0) it requests an address where to put the packet
+;
+; 2nd time (AX=1) the packet has been copied to this location (DS:SI)
+; BX has client handle (stored in RX_ELEMENT.handle).
+; CX has # of bytes in packet on both call. They should be equal.
+; A test for equality is done by putting CX in _pktRxBuf [n].firstCount
+; and _pktRxBuf[n].secondCount, and CL on first call in
+; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive"
+; (PKTDRVR.C)
+;
+;---------------------------------------------------------------------
+
+_PktReceiver:
+ pushf
+ cli ; no distraction wanted !
+ push ds
+ push bx
+ mov bx, cs
+ mov ds, bx
+ mov es, bx ; ES = DS = CS or seg _DATA
+ pop bx ; restore handle
+
+ cmp ax, 0 ; first call? (AX=0)
+ jne @post ; AX=1: second call, do post process
+
+%ifdef DEBUG
+ SHOW_RX ; show that a packet is received
+%endif
+
+ cmp cx, ETH_MAX ; size OK ?
+ ja @skip ; no, too big
+
+ mov ax, [_rxInOfs]
+ add ax, RX_SIZE
+ cmp ax, LAST_OFS
+ jb @noWrap
+ mov ax, offset _pktRxBuf
+@noWrap:
+ cmp ax, [_rxOutOfs]
+ je @dump
+ mov di, [_rxInOfs] ; ES:DI -> _pktRxBuf[n]
+ mov [newInOffset], ax
+
+ mov [di], cx ; remember firstCount.
+ mov [di+4], bx ; remember handle.
+ add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr
+ pop ds
+ popf
+ retf ; far return to driver with ES:DI
+
+@dump: add word [_pktDrop+0], 1 ; discard the packet on 1st call
+ adc word [_pktDrop+2], 0 ; increment packets lost
+
+@skip: xor di, di ; return ES:DI = NIL pointer
+ xor ax, ax
+ mov es, ax
+ pop ds
+ popf
+ retf
+
+@post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr
+ jz @discard ; make sure we don't use NULL-pointer
+
+ ;
+ ; push si
+ ; call bpf_filter_match ; run the filter here some day
+ ; pop si
+ ; cmp ax, 0
+ ; je @discard
+
+ mov [si-6+2], cx ; store _pktRxBuf[n].secondCount
+ mov ax, [newInOffset]
+ mov [_rxInOfs], ax ; update _pktRxBuf input offset
+
+ ; call PutTimeStamp
+
+@discard:
+ pop ds
+ popf
+ retf
+
+_pktRxEnd db 0 ; marker for end of r-mode code/data
+
+END
+
diff --git a/lib/libpcap/libpcap/msdos/pktdrvr.c b/lib/libpcap/libpcap/msdos/pktdrvr.c
new file mode 100644
index 0000000..37fc8a4
--- /dev/null
+++ b/lib/libpcap/libpcap/msdos/pktdrvr.c
@@ -0,0 +1,1436 @@
+/*
+ * File.........: pktdrvr.c
+ *
+ * Responsible..: Gisle Vanem, giva@bgnett.no
+ *
+ * Created......: 26.Sept 1995
+ *
+ * Description..: Packet-driver interface for 16/32-bit C :
+ * Borland C/C++ 3.0+ small/large model
+ * Watcom C/C++ 11+, DOS4GW flat model
+ * Metaware HighC 3.1+ and PharLap 386|DosX
+ * GNU C/C++ 2.7+ and djgpp 2.x extender
+ *
+ * References...: PC/TCP Packet driver Specification. rev 1.09
+ * FTP Software Inc.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dos.h>
+
+#include "pcap-dos.h"
+#include "pcap-int.h"
+#include "msdos/pktdrvr.h"
+
+#if (DOSX)
+#define NUM_RX_BUF 32 /* # of buffers in Rx FIFO queue */
+#else
+#define NUM_RX_BUF 10
+#endif
+
+#define DIM(x) (sizeof((x)) / sizeof(x[0]))
+#define PUTS(s) do { \
+ if (!pktInfo.quiet) \
+ pktInfo.error ? \
+ printf ("%s: %s\n", s, pktInfo.error) : \
+ printf ("%s\n", pktInfo.error = s); \
+ } while (0)
+
+#if defined(__HIGHC__)
+ extern UINT _mwenv;
+
+#elif defined(__DJGPP__)
+ #include <stddef.h>
+ #include <dpmi.h>
+ #include <go32.h>
+ #include <pc.h>
+ #include <sys/farptr.h>
+
+#elif defined(__WATCOMC__)
+ #include <i86.h>
+ #include <stddef.h>
+ extern char _Extender;
+
+#else
+ extern void far PktReceiver (void);
+#endif
+
+
+#if (DOSX & (DJGPP|DOS4GW))
+ #include <sys/pack_on.h>
+
+ struct DPMI_regs {
+ DWORD r_di;
+ DWORD r_si;
+ DWORD r_bp;
+ DWORD reserved;
+ DWORD r_bx;
+ DWORD r_dx;
+ DWORD r_cx;
+ DWORD r_ax;
+ WORD r_flags;
+ WORD r_es, r_ds, r_fs, r_gs;
+ WORD r_ip, r_cs, r_sp, r_ss;
+ };
+
+ /* Data located in a real-mode segment. This becomes far at runtime
+ */
+ typedef struct { /* must match data/code in pkt_rx1.s */
+ WORD _rxOutOfs;
+ WORD _rxInOfs;
+ DWORD _pktDrop;
+ BYTE _pktTemp [20];
+ TX_ELEMENT _pktTxBuf[1];
+ RX_ELEMENT _pktRxBuf[NUM_RX_BUF];
+ WORD _dummy[2]; /* screenSeg,newInOffset */
+ BYTE _fanChars[4];
+ WORD _fanIndex;
+ BYTE _PktReceiver[15]; /* starts on a paragraph (16byte) */
+ } PktRealStub;
+ #include <sys/pack_off.h>
+
+ static BYTE real_stub_array [] = {
+ #include "pkt_stub.inc" /* generated opcode array */
+ };
+
+ #define rxOutOfs offsetof (PktRealStub,_rxOutOfs)
+ #define rxInOfs offsetof (PktRealStub,_rxInOfs)
+ #define PktReceiver offsetof (PktRealStub,_PktReceiver [para_skip])
+ #define pktDrop offsetof (PktRealStub,_pktDrop)
+ #define pktTemp offsetof (PktRealStub,_pktTemp)
+ #define pktTxBuf offsetof (PktRealStub,_pktTxBuf)
+ #define FIRST_RX_BUF offsetof (PktRealStub,_pktRxBuf [0])
+ #define LAST_RX_BUF offsetof (PktRealStub,_pktRxBuf [NUM_RX_BUF-1])
+
+#else
+ extern WORD rxOutOfs; /* offsets into pktRxBuf FIFO queue */
+ extern WORD rxInOfs;
+ extern DWORD pktDrop; /* # packets dropped in PktReceiver() */
+ extern BYTE pktRxEnd; /* marks the end of r-mode code/data */
+
+ extern RX_ELEMENT pktRxBuf [NUM_RX_BUF]; /* PktDrvr Rx buffers */
+ extern TX_ELEMENT pktTxBuf; /* PktDrvr Tx buffer */
+ extern char pktTemp[20]; /* PktDrvr temp area */
+
+ #define FIRST_RX_BUF (WORD) &pktRxBuf [0]
+ #define LAST_RX_BUF (WORD) &pktRxBuf [NUM_RX_BUF-1]
+#endif
+
+
+#ifdef __BORLANDC__ /* Use Borland's inline functions */
+ #define memcpy __memcpy__
+ #define memcmp __memcmp__
+ #define memset __memset__
+#endif
+
+
+#if (DOSX & PHARLAP)
+ extern void PktReceiver (void); /* in pkt_rx0.asm */
+ static int RealCopy (ULONG, ULONG, REALPTR*, FARPTR*, USHORT*);
+
+ #undef FP_SEG
+ #undef FP_OFF
+ #define FP_OFF(x) ((WORD)(x))
+ #define FP_SEG(x) ((WORD)(realBase >> 16))
+ #define DOS_ADDR(s,o) (((DWORD)(s) << 16) + (WORD)(o))
+ #define r_ax eax
+ #define r_bx ebx
+ #define r_dx edx
+ #define r_cx ecx
+ #define r_si esi
+ #define r_di edi
+ #define r_ds ds
+ #define r_es es
+ LOCAL FARPTR protBase;
+ LOCAL REALPTR realBase;
+ LOCAL WORD realSeg; /* DOS para-address of allocated area */
+ LOCAL SWI_REGS reg;
+
+ static WORD _far *rxOutOfsFp, *rxInOfsFp;
+
+#elif (DOSX & DJGPP)
+ static _go32_dpmi_seginfo rm_mem;
+ static __dpmi_regs reg;
+ static DWORD realBase;
+ static int para_skip = 0;
+
+ #define DOS_ADDR(s,o) (((WORD)(s) << 4) + (o))
+ #define r_ax x.ax
+ #define r_bx x.bx
+ #define r_dx x.dx
+ #define r_cx x.cx
+ #define r_si x.si
+ #define r_di x.di
+ #define r_ds x.ds
+ #define r_es x.es
+
+#elif (DOSX & DOS4GW)
+ LOCAL struct DPMI_regs reg;
+ LOCAL WORD rm_base_seg, rm_base_sel;
+ LOCAL DWORD realBase;
+ LOCAL int para_skip = 0;
+
+ LOCAL DWORD dpmi_get_real_vector (int intr);
+ LOCAL WORD dpmi_real_malloc (int size, WORD *selector);
+ LOCAL void dpmi_real_free (WORD selector);
+ #define DOS_ADDR(s,o) (((DWORD)(s) << 4) + (WORD)(o))
+
+#else /* real-mode Borland etc. */
+ static struct {
+ WORD r_ax, r_bx, r_cx, r_dx, r_bp;
+ WORD r_si, r_di, r_ds, r_es, r_flags;
+ } reg;
+#endif
+
+#ifdef __HIGHC__
+ #pragma Alias (pktDrop, "_pktDrop")
+ #pragma Alias (pktRxBuf, "_pktRxBuf")
+ #pragma Alias (pktTxBuf, "_pktTxBuf")
+ #pragma Alias (pktTemp, "_pktTemp")
+ #pragma Alias (rxOutOfs, "_rxOutOfs")
+ #pragma Alias (rxInOfs, "_rxInOfs")
+ #pragma Alias (pktRxEnd, "_pktRxEnd")
+ #pragma Alias (PktReceiver,"_PktReceiver")
+#endif
+
+
+PUBLIC PKT_STAT pktStat; /* statistics for packets */
+PUBLIC PKT_INFO pktInfo; /* packet-driver information */
+
+PUBLIC PKT_RX_MODE receiveMode = PDRX_DIRECT;
+PUBLIC ETHER myAddress = { 0, 0, 0, 0, 0, 0 };
+PUBLIC ETHER ethBroadcast = { 255,255,255,255,255,255 };
+
+LOCAL struct { /* internal statistics */
+ DWORD tooSmall; /* size < ETH_MIN */
+ DWORD tooLarge; /* size > ETH_MAX */
+ DWORD badSync; /* count_1 != count_2 */
+ DWORD wrongHandle; /* upcall to wrong handle */
+ } intStat;
+
+/***************************************************************************/
+
+PUBLIC const char *PktGetErrorStr (int errNum)
+{
+ static const char *errStr[] = {
+ "",
+ "Invalid handle number",
+ "No interfaces of specified class found",
+ "No interfaces of specified type found",
+ "No interfaces of specified number found",
+ "Bad packet type specified",
+ "Interface does not support multicast",
+ "Packet driver cannot terminate",
+ "Invalid receiver mode specified",
+ "Insufficient memory space",
+ "Type previously accessed, and not released",
+ "Command out of range, or not implemented",
+ "Cannot send packet (usually hardware error)",
+ "Cannot change hardware address ( > 1 handle open)",
+ "Hardware address has bad length or format",
+ "Cannot reset interface (more than 1 handle open)",
+ "Bad Check-sum",
+ "Bad size",
+ "Bad sync" ,
+ "Source hit"
+ };
+
+ if (errNum < 0 || errNum >= DIM(errStr))
+ return ("Unknown driver error.");
+ return (errStr [errNum]);
+}
+
+/**************************************************************************/
+
+PUBLIC const char *PktGetClassName (WORD class)
+{
+ switch (class)
+ {
+ case PD_ETHER:
+ return ("DIX-Ether");
+ case PD_PRONET10:
+ return ("ProNET-10");
+ case PD_IEEE8025:
+ return ("IEEE 802.5");
+ case PD_OMNINET:
+ return ("OmniNet");
+ case PD_APPLETALK:
+ return ("AppleTalk");
+ case PD_SLIP:
+ return ("SLIP");
+ case PD_STARTLAN:
+ return ("StartLAN");
+ case PD_ARCNET:
+ return ("ArcNet");
+ case PD_AX25:
+ return ("AX.25");
+ case PD_KISS:
+ return ("KISS");
+ case PD_IEEE8023_2:
+ return ("IEEE 802.3 w/802.2 hdr");
+ case PD_FDDI8022:
+ return ("FDDI w/802.2 hdr");
+ case PD_X25:
+ return ("X.25");
+ case PD_LANstar:
+ return ("LANstar");
+ case PD_PPP:
+ return ("PPP");
+ default:
+ return ("unknown");
+ }
+}
+
+/**************************************************************************/
+
+PUBLIC char const *PktRXmodeStr (PKT_RX_MODE mode)
+{
+ static const char *modeStr [] = {
+ "Receiver turned off",
+ "Receive only directly addressed packets",
+ "Receive direct & broadcast packets",
+ "Receive direct,broadcast and limited multicast packets",
+ "Receive direct,broadcast and all multicast packets",
+ "Receive all packets (promiscuouos mode)"
+ };
+
+ if (mode > DIM(modeStr))
+ return ("??");
+ return (modeStr [mode-1]);
+}
+
+/**************************************************************************/
+
+LOCAL __inline BOOL PktInterrupt (void)
+{
+ BOOL okay;
+
+#if (DOSX & PHARLAP)
+ _dx_real_int ((UINT)pktInfo.intr, &reg);
+ okay = ((reg.flags & 1) == 0); /* OK if carry clear */
+
+#elif (DOSX & DJGPP)
+ __dpmi_int ((int)pktInfo.intr, &reg);
+ okay = ((reg.x.flags & 1) == 0);
+
+#elif (DOSX & DOS4GW)
+ union REGS r;
+ struct SREGS s;
+
+ memset (&r, 0, sizeof(r));
+ segread (&s);
+ r.w.ax = 0x300;
+ r.x.ebx = pktInfo.intr;
+ r.w.cx = 0;
+ s.es = FP_SEG (&reg);
+ r.x.edi = FP_OFF (&reg);
+ reg.r_flags = 0;
+ reg.r_ss = reg.r_sp = 0; /* DPMI host provides stack */
+
+ int386x (0x31, &r, &r, &s);
+ okay = (!r.w.cflag);
+
+#else
+ reg.r_flags = 0;
+ intr (pktInfo.intr, (struct REGPACK*)&reg);
+ okay = ((reg.r_flags & 1) == 0);
+#endif
+
+ if (okay)
+ pktInfo.error = NULL;
+ else pktInfo.error = PktGetErrorStr (reg.r_dx >> 8);
+ return (okay);
+}
+
+/**************************************************************************/
+
+/*
+ * Search for packet driver at interrupt 60h through 80h. If ASCIIZ
+ * string "PKT DRVR" found at offset 3 in the interrupt handler, return
+ * interrupt number, else return zero in pktInfo.intr
+ */
+PUBLIC BOOL PktSearchDriver (void)
+{
+ BYTE intr = 0x20;
+ BOOL found = FALSE;
+
+ while (!found && intr < 0xFF)
+ {
+ static char str[12]; /* 3 + strlen("PKT DRVR") */
+ static char pktStr[9] = "PKT DRVR"; /* ASCIIZ string at ofs 3 */
+ DWORD rp; /* in interrupt routine */
+
+#if (DOSX & PHARLAP)
+ _dx_rmiv_get (intr, &rp);
+ ReadRealMem (&str, (REALPTR)rp, sizeof(str));
+
+#elif (DOSX & DJGPP)
+ __dpmi_raddr realAdr;
+ __dpmi_get_real_mode_interrupt_vector (intr, &realAdr);
+ rp = (realAdr.segment << 4) + realAdr.offset16;
+ dosmemget (rp, sizeof(str), &str);
+
+#elif (DOSX & DOS4GW)
+ rp = dpmi_get_real_vector (intr);
+ memcpy (&str, (void*)rp, sizeof(str));
+
+#else
+ _fmemcpy (&str, getvect(intr), sizeof(str));
+#endif
+
+ found = memcmp (&str[3],&pktStr,sizeof(pktStr)) == 0;
+ intr++;
+ }
+ pktInfo.intr = (found ? intr-1 : 0);
+ return (found);
+}
+
+
+/**************************************************************************/
+
+static BOOL PktSetAccess (void)
+{
+ reg.r_ax = 0x0200 + pktInfo.class;
+ reg.r_bx = 0xFFFF;
+ reg.r_dx = 0;
+ reg.r_cx = 0;
+
+#if (DOSX & PHARLAP)
+ reg.ds = 0;
+ reg.esi = 0;
+ reg.es = RP_SEG (realBase);
+ reg.edi = (WORD) &PktReceiver;
+
+#elif (DOSX & DJGPP)
+ reg.x.ds = 0;
+ reg.x.si = 0;
+ reg.x.es = rm_mem.rm_segment;
+ reg.x.di = PktReceiver;
+
+#elif (DOSX & DOS4GW)
+ reg.r_ds = 0;
+ reg.r_si = 0;
+ reg.r_es = rm_base_seg;
+ reg.r_di = PktReceiver;
+
+#else
+ reg.r_ds = 0;
+ reg.r_si = 0;
+ reg.r_es = FP_SEG (&PktReceiver);
+ reg.r_di = FP_OFF (&PktReceiver);
+#endif
+
+ if (!PktInterrupt())
+ return (FALSE);
+
+ pktInfo.handle = reg.r_ax;
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktReleaseHandle (WORD handle)
+{
+ reg.r_ax = 0x0300;
+ reg.r_bx = handle;
+ return PktInterrupt();
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktTransmit (const void *eth, int len)
+{
+ if (len > ETH_MTU)
+ return (FALSE);
+
+ reg.r_ax = 0x0400; /* Function 4, send pkt */
+ reg.r_cx = len; /* total size of frame */
+
+#if (DOSX & DJGPP)
+ dosmemput (eth, len, realBase+pktTxBuf);
+ reg.x.ds = rm_mem.rm_segment; /* DOS data segment and */
+ reg.x.si = pktTxBuf; /* DOS offset to buffer */
+
+#elif (DOSX & DOS4GW)
+ memcpy ((void*)(realBase+pktTxBuf), eth, len);
+ reg.r_ds = rm_base_seg;
+ reg.r_si = pktTxBuf;
+
+#elif (DOSX & PHARLAP)
+ memcpy (&pktTxBuf, eth, len);
+ reg.r_ds = FP_SEG (&pktTxBuf);
+ reg.r_si = FP_OFF (&pktTxBuf);
+
+#else
+ reg.r_ds = FP_SEG (eth);
+ reg.r_si = FP_OFF (eth);
+#endif
+
+ return PktInterrupt();
+}
+
+/**************************************************************************/
+
+#if (DOSX & (DJGPP|DOS4GW))
+LOCAL __inline BOOL CheckElement (RX_ELEMENT *rx)
+#else
+LOCAL __inline BOOL CheckElement (RX_ELEMENT _far *rx)
+#endif
+{
+ WORD count_1, count_2;
+
+ /*
+ * We got an upcall to the same RMCB with wrong handle.
+ * This can happen if we failed to release handle at program exit
+ */
+ if (rx->handle != pktInfo.handle)
+ {
+ pktInfo.error = "Wrong handle";
+ intStat.wrongHandle++;
+ PktReleaseHandle (rx->handle);
+ return (FALSE);
+ }
+ count_1 = rx->firstCount;
+ count_2 = rx->secondCount;
+
+ if (count_1 != count_2)
+ {
+ pktInfo.error = "Bad sync";
+ intStat.badSync++;
+ return (FALSE);
+ }
+ if (count_1 > ETH_MAX)
+ {
+ pktInfo.error = "Large esize";
+ intStat.tooLarge++;
+ return (FALSE);
+ }
+#if 0
+ if (count_1 < ETH_MIN)
+ {
+ pktInfo.error = "Small esize";
+ intStat.tooSmall++;
+ return (FALSE);
+ }
+#endif
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktTerminHandle (WORD handle)
+{
+ reg.r_ax = 0x0500;
+ reg.r_bx = handle;
+ return PktInterrupt();
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktResetInterface (WORD handle)
+{
+ reg.r_ax = 0x0700;
+ reg.r_bx = handle;
+ return PktInterrupt();
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktSetReceiverMode (PKT_RX_MODE mode)
+{
+ if (pktInfo.class == PD_SLIP || pktInfo.class == PD_PPP)
+ return (TRUE);
+
+ reg.r_ax = 0x1400;
+ reg.r_bx = pktInfo.handle;
+ reg.r_cx = (WORD)mode;
+
+ if (!PktInterrupt())
+ return (FALSE);
+
+ receiveMode = mode;
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktGetReceiverMode (PKT_RX_MODE *mode)
+{
+ reg.r_ax = 0x1500;
+ reg.r_bx = pktInfo.handle;
+
+ if (!PktInterrupt())
+ return (FALSE);
+
+ *mode = reg.r_ax;
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+static PKT_STAT initialStat; /* statistics at startup */
+static BOOL resetStat = FALSE; /* statistics reset ? */
+
+PUBLIC BOOL PktGetStatistics (WORD handle)
+{
+ reg.r_ax = 0x1800;
+ reg.r_bx = handle;
+
+ if (!PktInterrupt())
+ return (FALSE);
+
+#if (DOSX & PHARLAP)
+ ReadRealMem (&pktStat, DOS_ADDR(reg.ds,reg.esi), sizeof(pktStat));
+
+#elif (DOSX & DJGPP)
+ dosmemget (DOS_ADDR(reg.x.ds,reg.x.si), sizeof(pktStat), &pktStat);
+
+#elif (DOSX & DOS4GW)
+ memcpy (&pktStat, (void*)DOS_ADDR(reg.r_ds,reg.r_si), sizeof(pktStat));
+
+#else
+ _fmemcpy (&pktStat, MK_FP(reg.r_ds,reg.r_si), sizeof(pktStat));
+#endif
+
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktSessStatistics (WORD handle)
+{
+ if (!PktGetStatistics(pktInfo.handle))
+ return (FALSE);
+
+ if (resetStat)
+ {
+ pktStat.inPackets -= initialStat.inPackets;
+ pktStat.outPackets -= initialStat.outPackets;
+ pktStat.inBytes -= initialStat.inBytes;
+ pktStat.outBytes -= initialStat.outBytes;
+ pktStat.inErrors -= initialStat.inErrors;
+ pktStat.outErrors -= initialStat.outErrors;
+ pktStat.outErrors -= initialStat.outErrors;
+ pktStat.lost -= initialStat.lost;
+ }
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktResetStatistics (WORD handle)
+{
+ if (!PktGetStatistics(pktInfo.handle))
+ return (FALSE);
+
+ memcpy (&initialStat, &pktStat, sizeof(initialStat));
+ resetStat = TRUE;
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktGetAddress (ETHER *addr)
+{
+ reg.r_ax = 0x0600;
+ reg.r_bx = pktInfo.handle;
+ reg.r_cx = sizeof (*addr);
+
+#if (DOSX & DJGPP)
+ reg.x.es = rm_mem.rm_segment;
+ reg.x.di = pktTemp;
+#elif (DOSX & DOS4GW)
+ reg.r_es = rm_base_seg;
+ reg.r_di = pktTemp;
+#else
+ reg.r_es = FP_SEG (&pktTemp);
+ reg.r_di = FP_OFF (&pktTemp); /* ES:DI = address for result */
+#endif
+
+ if (!PktInterrupt())
+ return (FALSE);
+
+#if (DOSX & PHARLAP)
+ ReadRealMem (addr, realBase + (WORD)&pktTemp, sizeof(*addr));
+
+#elif (DOSX & DJGPP)
+ dosmemget (realBase+pktTemp, sizeof(*addr), addr);
+
+#elif (DOSX & DOS4GW)
+ memcpy (addr, (void*)(realBase+pktTemp), sizeof(*addr));
+
+#else
+ memcpy ((void*)addr, &pktTemp, sizeof(*addr));
+#endif
+
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktSetAddress (const ETHER *addr)
+{
+ /* copy addr to real-mode scrath area */
+
+#if (DOSX & PHARLAP)
+ WriteRealMem (realBase + (WORD)&pktTemp, (void*)addr, sizeof(*addr));
+
+#elif (DOSX & DJGPP)
+ dosmemput (addr, sizeof(*addr), realBase+pktTemp);
+
+#elif (DOSX & DOS4GW)
+ memcpy ((void*)(realBase+pktTemp), addr, sizeof(*addr));
+
+#else
+ memcpy (&pktTemp, (void*)addr, sizeof(*addr));
+#endif
+
+ reg.r_ax = 0x1900;
+ reg.r_cx = sizeof (*addr); /* address length */
+
+#if (DOSX & DJGPP)
+ reg.x.es = rm_mem.rm_segment; /* DOS offset to param */
+ reg.x.di = pktTemp; /* DOS segment to param */
+#elif (DOSX & DOS4GW)
+ reg.r_es = rm_base_seg;
+ reg.r_di = pktTemp;
+#else
+ reg.r_es = FP_SEG (&pktTemp);
+ reg.r_di = FP_OFF (&pktTemp);
+#endif
+
+ return PktInterrupt();
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktGetDriverInfo (void)
+{
+ pktInfo.majVer = 0;
+ pktInfo.minVer = 0;
+ memset (&pktInfo.name, 0, sizeof(pktInfo.name));
+ reg.r_ax = 0x01FF;
+ reg.r_bx = 0;
+
+ if (!PktInterrupt())
+ return (FALSE);
+
+ pktInfo.number = reg.r_cx & 0xFF;
+ pktInfo.class = reg.r_cx >> 8;
+#if 0
+ pktInfo.minVer = reg.r_bx % 10;
+ pktInfo.majVer = reg.r_bx / 10;
+#else
+ pktInfo.majVer = reg.r_bx; // !!
+#endif
+ pktInfo.funcs = reg.r_ax & 0xFF;
+ pktInfo.type = reg.r_dx & 0xFF;
+
+#if (DOSX & PHARLAP)
+ ReadRealMem (&pktInfo.name, DOS_ADDR(reg.ds,reg.esi), sizeof(pktInfo.name));
+
+#elif (DOSX & DJGPP)
+ dosmemget (DOS_ADDR(reg.x.ds,reg.x.si), sizeof(pktInfo.name), &pktInfo.name);
+
+#elif (DOSX & DOS4GW)
+ memcpy (&pktInfo.name, (void*)DOS_ADDR(reg.r_ds,reg.r_si), sizeof(pktInfo.name));
+
+#else
+ _fmemcpy (&pktInfo.name, MK_FP(reg.r_ds,reg.r_si), sizeof(pktInfo.name));
+#endif
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktGetDriverParam (void)
+{
+ reg.r_ax = 0x0A00;
+
+ if (!PktInterrupt())
+ return (FALSE);
+
+#if (DOSX & PHARLAP)
+ ReadRealMem (&pktInfo.majVer, DOS_ADDR(reg.es,reg.edi), PKT_PARAM_SIZE);
+
+#elif (DOSX & DJGPP)
+ dosmemget (DOS_ADDR(reg.x.es,reg.x.di), PKT_PARAM_SIZE, &pktInfo.majVer);
+
+#elif (DOSX & DOS4GW)
+ memcpy (&pktInfo.majVer, (void*)DOS_ADDR(reg.r_es,reg.r_di), PKT_PARAM_SIZE);
+
+#else
+ _fmemcpy (&pktInfo.majVer, MK_FP(reg.r_es,reg.r_di), PKT_PARAM_SIZE);
+#endif
+ return (TRUE);
+}
+
+/**************************************************************************/
+
+#if (DOSX & PHARLAP)
+ PUBLIC int PktReceive (BYTE *buf, int max)
+ {
+ WORD inOfs = *rxInOfsFp;
+ WORD outOfs = *rxOutOfsFp;
+
+ if (outOfs != inOfs)
+ {
+ RX_ELEMENT _far *head = (RX_ELEMENT _far*)(protBase+outOfs);
+ int size, len = max;
+
+ if (CheckElement(head))
+ {
+ size = min (head->firstCount, sizeof(RX_ELEMENT));
+ len = min (size, max);
+ _fmemcpy (buf, &head->destin, len);
+ }
+ else
+ size = -1;
+
+ outOfs += sizeof (RX_ELEMENT);
+ if (outOfs > LAST_RX_BUF)
+ outOfs = FIRST_RX_BUF;
+ *rxOutOfsFp = outOfs;
+ return (size);
+ }
+ return (0);
+ }
+
+ PUBLIC void PktQueueBusy (BOOL busy)
+ {
+ *rxOutOfsFp = busy ? (*rxInOfsFp + sizeof(RX_ELEMENT)) : *rxInOfsFp;
+ if (*rxOutOfsFp > LAST_RX_BUF)
+ *rxOutOfsFp = FIRST_RX_BUF;
+ *(DWORD _far*)(protBase + (WORD)&pktDrop) = 0;
+ }
+
+ PUBLIC WORD PktBuffersUsed (void)
+ {
+ WORD inOfs = *rxInOfsFp;
+ WORD outOfs = *rxOutOfsFp;
+
+ if (inOfs >= outOfs)
+ return (inOfs - outOfs) / sizeof(RX_ELEMENT);
+ return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));
+ }
+
+ PUBLIC DWORD PktRxDropped (void)
+ {
+ return (*(DWORD _far*)(protBase + (WORD)&pktDrop));
+ }
+
+#elif (DOSX & DJGPP)
+ PUBLIC int PktReceive (BYTE *buf, int max)
+ {
+ WORD ofs = _farpeekw (_dos_ds, realBase+rxOutOfs);
+
+ if (ofs != _farpeekw (_dos_ds, realBase+rxInOfs))
+ {
+ RX_ELEMENT head;
+ int size, len = max;
+
+ head.firstCount = _farpeekw (_dos_ds, realBase+ofs);
+ head.secondCount = _farpeekw (_dos_ds, realBase+ofs+2);
+ head.handle = _farpeekw (_dos_ds, realBase+ofs+4);
+
+ if (CheckElement(&head))
+ {
+ size = min (head.firstCount, sizeof(RX_ELEMENT));
+ len = min (size, max);
+ dosmemget (realBase+ofs+6, len, buf);
+ }
+ else
+ size = -1;
+
+ ofs += sizeof (RX_ELEMENT);
+ if (ofs > LAST_RX_BUF)
+ _farpokew (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF);
+ else _farpokew (_dos_ds, realBase+rxOutOfs, ofs);
+ return (size);
+ }
+ return (0);
+ }
+
+ PUBLIC void PktQueueBusy (BOOL busy)
+ {
+ WORD ofs;
+
+ disable();
+ ofs = _farpeekw (_dos_ds, realBase+rxInOfs);
+ if (busy)
+ ofs += sizeof (RX_ELEMENT);
+
+ if (ofs > LAST_RX_BUF)
+ _farpokew (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF);
+ else _farpokew (_dos_ds, realBase+rxOutOfs, ofs);
+ _farpokel (_dos_ds, realBase+pktDrop, 0UL);
+ enable();
+ }
+
+ PUBLIC WORD PktBuffersUsed (void)
+ {
+ WORD inOfs, outOfs;
+
+ disable();
+ inOfs = _farpeekw (_dos_ds, realBase+rxInOfs);
+ outOfs = _farpeekw (_dos_ds, realBase+rxOutOfs);
+ enable();
+ if (inOfs >= outOfs)
+ return (inOfs - outOfs) / sizeof(RX_ELEMENT);
+ return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));
+ }
+
+ PUBLIC DWORD PktRxDropped (void)
+ {
+ return _farpeekl (_dos_ds, realBase+pktDrop);
+ }
+
+#elif (DOSX & DOS4GW)
+ PUBLIC int PktReceive (BYTE *buf, int max)
+ {
+ WORD ofs = *(WORD*) (realBase+rxOutOfs);
+
+ if (ofs != *(WORD*) (realBase+rxInOfs))
+ {
+ RX_ELEMENT head;
+ int size, len = max;
+
+ head.firstCount = *(WORD*) (realBase+ofs);
+ head.secondCount = *(WORD*) (realBase+ofs+2);
+ head.handle = *(WORD*) (realBase+ofs+4);
+
+ if (CheckElement(&head))
+ {
+ size = min (head.firstCount, sizeof(RX_ELEMENT));
+ len = min (size, max);
+ memcpy (buf, (const void*)(realBase+ofs+6), len);
+ }
+ else
+ size = -1;
+
+ ofs += sizeof (RX_ELEMENT);
+ if (ofs > LAST_RX_BUF)
+ *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF;
+ else *(WORD*) (realBase+rxOutOfs) = ofs;
+ return (size);
+ }
+ return (0);
+ }
+
+ PUBLIC void PktQueueBusy (BOOL busy)
+ {
+ WORD ofs;
+
+ _disable();
+ ofs = *(WORD*) (realBase+rxInOfs);
+ if (busy)
+ ofs += sizeof (RX_ELEMENT);
+
+ if (ofs > LAST_RX_BUF)
+ *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF;
+ else *(WORD*) (realBase+rxOutOfs) = ofs;
+ *(DWORD*) (realBase+pktDrop) = 0UL;
+ _enable();
+ }
+
+ PUBLIC WORD PktBuffersUsed (void)
+ {
+ WORD inOfs, outOfs;
+
+ _disable();
+ inOfs = *(WORD*) (realBase+rxInOfs);
+ outOfs = *(WORD*) (realBase+rxOutOfs);
+ _enable();
+ if (inOfs >= outOfs)
+ return (inOfs - outOfs) / sizeof(RX_ELEMENT);
+ return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));
+ }
+
+ PUBLIC DWORD PktRxDropped (void)
+ {
+ return *(DWORD*) (realBase+pktDrop);
+ }
+
+#else /* real-mode small/large model */
+
+ PUBLIC int PktReceive (BYTE *buf, int max)
+ {
+ if (rxOutOfs != rxInOfs)
+ {
+ RX_ELEMENT far *head = (RX_ELEMENT far*) MK_FP (_DS,rxOutOfs);
+ int size, len = max;
+
+ if (CheckElement(head))
+ {
+ size = min (head->firstCount, sizeof(RX_ELEMENT));
+ len = min (size, max);
+ _fmemcpy (buf, &head->destin, len);
+ }
+ else
+ size = -1;
+
+ rxOutOfs += sizeof (RX_ELEMENT);
+ if (rxOutOfs > LAST_RX_BUF)
+ rxOutOfs = FIRST_RX_BUF;
+ return (size);
+ }
+ return (0);
+ }
+
+ PUBLIC void PktQueueBusy (BOOL busy)
+ {
+ rxOutOfs = busy ? (rxInOfs + sizeof(RX_ELEMENT)) : rxInOfs;
+ if (rxOutOfs > LAST_RX_BUF)
+ rxOutOfs = FIRST_RX_BUF;
+ pktDrop = 0L;
+ }
+
+ PUBLIC WORD PktBuffersUsed (void)
+ {
+ WORD inOfs = rxInOfs;
+ WORD outOfs = rxOutOfs;
+
+ if (inOfs >= outOfs)
+ return ((inOfs - outOfs) / sizeof(RX_ELEMENT));
+ return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));
+ }
+
+ PUBLIC DWORD PktRxDropped (void)
+ {
+ return (pktDrop);
+ }
+#endif
+
+/**************************************************************************/
+
+LOCAL __inline void PktFreeMem (void)
+{
+#if (DOSX & PHARLAP)
+ if (realSeg)
+ {
+ _dx_real_free (realSeg);
+ realSeg = 0;
+ }
+#elif (DOSX & DJGPP)
+ if (rm_mem.rm_segment)
+ {
+ unsigned ofs; /* clear the DOS-mem to prevent further upcalls */
+
+ for (ofs = 0; ofs < 16 * rm_mem.size / 4; ofs += 4)
+ _farpokel (_dos_ds, realBase + ofs, 0);
+ _go32_dpmi_free_dos_memory (&rm_mem);
+ rm_mem.rm_segment = 0;
+ }
+#elif (DOSX & DOS4GW)
+ if (rm_base_sel)
+ {
+ dpmi_real_free (rm_base_sel);
+ rm_base_sel = 0;
+ }
+#endif
+}
+
+/**************************************************************************/
+
+PUBLIC BOOL PktExitDriver (void)
+{
+ if (pktInfo.handle)
+ {
+ if (!PktSetReceiverMode(PDRX_BROADCAST))
+ PUTS ("Error restoring receiver mode.");
+
+ if (!PktReleaseHandle(pktInfo.handle))
+ PUTS ("Error releasing PKT-DRVR handle.");
+
+ PktFreeMem();
+ pktInfo.handle = 0;
+ }
+
+ if (pcap_pkt_debug >= 1)
+ printf ("Internal stats: too-small %lu, too-large %lu, bad-sync %lu, "
+ "wrong-handle %lu\n",
+ intStat.tooSmall, intStat.tooLarge,
+ intStat.badSync, intStat.wrongHandle);
+ return (TRUE);
+}
+
+#if (DOSX & (DJGPP|DOS4GW))
+static void dump_pkt_stub (void)
+{
+ int i;
+
+ fprintf (stderr, "PktReceiver %lu, pkt_stub[PktReceiver] =\n",
+ PktReceiver);
+ for (i = 0; i < 15; i++)
+ fprintf (stderr, "%02X, ", real_stub_array[i+PktReceiver]);
+ fputs ("\n", stderr);
+}
+#endif
+
+/*
+ * Front end initialization routine
+ */
+PUBLIC BOOL PktInitDriver (PKT_RX_MODE mode)
+{
+ PKT_RX_MODE rxMode;
+ BOOL writeInfo = (pcap_pkt_debug >= 3);
+
+ pktInfo.quiet = (pcap_pkt_debug < 3);
+
+#if (DOSX & PHARLAP) && defined(__HIGHC__)
+ if (_mwenv != 2)
+ {
+ fprintf (stderr, "Only Pharlap DOS extender supported.\n");
+ return (FALSE);
+ }
+#endif
+
+#if (DOSX & PHARLAP) && defined(__WATCOMC__)
+ if (_Extender != 1)
+ {
+ fprintf (stderr, "Only DOS4GW style extenders supported.\n");
+ return (FALSE);
+ }
+#endif
+
+ if (!PktSearchDriver())
+ {
+ PUTS ("Packet driver not found.");
+ PktFreeMem();
+ return (FALSE);
+ }
+
+ if (!PktGetDriverInfo())
+ {
+ PUTS ("Error getting pkt-drvr information.");
+ PktFreeMem();
+ return (FALSE);
+ }
+
+#if (DOSX & PHARLAP)
+ if (RealCopy((ULONG)&rxOutOfs, (ULONG)&pktRxEnd,
+ &realBase, &protBase, (USHORT*)&realSeg))
+ {
+ rxOutOfsFp = (WORD _far *) (protBase + (WORD) &rxOutOfs);
+ rxInOfsFp = (WORD _far *) (protBase + (WORD) &rxInOfs);
+ *rxOutOfsFp = FIRST_RX_BUF;
+ *rxInOfsFp = FIRST_RX_BUF;
+ }
+ else
+ {
+ PUTS ("Cannot allocate real-mode stub.");
+ return (FALSE);
+ }
+
+#elif (DOSX & (DJGPP|DOS4GW))
+ if (sizeof(real_stub_array) > 0xFFFF)
+ {
+ fprintf (stderr, "`real_stub_array[]' too big.\n");
+ return (FALSE);
+ }
+#if (DOSX & DJGPP)
+ rm_mem.size = (sizeof(real_stub_array) + 15) / 16;
+
+ if (_go32_dpmi_allocate_dos_memory(&rm_mem) || rm_mem.rm_offset != 0)
+ {
+ PUTS ("real-mode init failed.");
+ return (FALSE);
+ }
+ realBase = (rm_mem.rm_segment << 4);
+ dosmemput (&real_stub_array, sizeof(real_stub_array), realBase);
+ _farpokel (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF);
+ _farpokel (_dos_ds, realBase+rxInOfs, FIRST_RX_BUF);
+
+#elif (DOSX & DOS4GW)
+ rm_base_seg = dpmi_real_malloc (sizeof(real_stub_array), &rm_base_sel);
+ if (!rm_base_seg)
+ {
+ PUTS ("real-mode init failed.");
+ return (FALSE);
+ }
+ realBase = (rm_base_seg << 4);
+ memcpy ((void*)realBase, &real_stub_array, sizeof(real_stub_array));
+ *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF;
+ *(WORD*) (realBase+rxInOfs) = FIRST_RX_BUF;
+
+#endif
+ {
+ int pushf = PktReceiver;
+
+ while (real_stub_array[pushf++] != 0x9C && /* pushf */
+ real_stub_array[pushf] != 0xFA) /* cli */
+ {
+ if (++para_skip > 16)
+ {
+ fprintf (stderr, "Something wrong with `pkt_stub.inc'.\n");
+ para_skip = 0;
+ dump_pkt_stub();
+ return (FALSE);
+ }
+ }
+ if (*(WORD*)(real_stub_array + offsetof(PktRealStub,_dummy)) != 0xB800)
+ {
+ fprintf (stderr, "`real_stub_array[]' is misaligned.\n");
+ return (FALSE);
+ }
+ }
+
+ if (pcap_pkt_debug > 2)
+ dump_pkt_stub();
+
+#else
+ rxOutOfs = FIRST_RX_BUF;
+ rxInOfs = FIRST_RX_BUF;
+#endif
+
+ if (!PktSetAccess())
+ {
+ PUTS ("Error setting pkt-drvr access.");
+ PktFreeMem();
+ return (FALSE);
+ }
+
+ if (!PktGetAddress(&myAddress))
+ {
+ PUTS ("Error fetching adapter address.");
+ PktFreeMem();
+ return (FALSE);
+ }
+
+ if (!PktSetReceiverMode(mode))
+ {
+ PUTS ("Error setting receiver mode.");
+ PktFreeMem();
+ return (FALSE);
+ }
+
+ if (!PktGetReceiverMode(&rxMode))
+ {
+ PUTS ("Error getting receiver mode.");
+ PktFreeMem();
+ return (FALSE);
+ }
+
+ if (writeInfo)
+ printf ("Pkt-driver information:\n"
+ " Version : %d.%d\n"
+ " Name : %.15s\n"
+ " Class : %u (%s)\n"
+ " Type : %u\n"
+ " Number : %u\n"
+ " Funcs : %u\n"
+ " Intr : %Xh\n"
+ " Handle : %u\n"
+ " Extended : %s\n"
+ " Hi-perf : %s\n"
+ " RX mode : %s\n"
+ " Eth-addr : %02X:%02X:%02X:%02X:%02X:%02X\n",
+
+ pktInfo.majVer, pktInfo.minVer, pktInfo.name,
+ pktInfo.class, PktGetClassName(pktInfo.class),
+ pktInfo.type, pktInfo.number,
+ pktInfo.funcs, pktInfo.intr, pktInfo.handle,
+ pktInfo.funcs == 2 || pktInfo.funcs == 6 ? "Yes" : "No",
+ pktInfo.funcs == 5 || pktInfo.funcs == 6 ? "Yes" : "No",
+ PktRXmodeStr(rxMode),
+ myAddress[0], myAddress[1], myAddress[2],
+ myAddress[3], myAddress[4], myAddress[5]);
+
+#if defined(DEBUG) && (DOSX & PHARLAP)
+ if (writeInfo)
+ {
+ DWORD rAdr = realBase + (WORD)&PktReceiver;
+ unsigned sel, ofs;
+
+ printf ("\nReceiver at %04X:%04X\n", RP_SEG(rAdr), RP_OFF(rAdr));
+ printf ("Realbase = %04X:%04X\n", RP_SEG(realBase),RP_OFF(realBase));
+
+ sel = _FP_SEG (protBase);
+ ofs = _FP_OFF (protBase);
+ printf ("Protbase = %04X:%08X\n", sel,ofs);
+ printf ("RealSeg = %04X\n", realSeg);
+
+ sel = _FP_SEG (rxOutOfsFp);
+ ofs = _FP_OFF (rxOutOfsFp);
+ printf ("rxOutOfsFp = %04X:%08X\n", sel,ofs);
+
+ sel = _FP_SEG (rxInOfsFp);
+ ofs = _FP_OFF (rxInOfsFp);
+ printf ("rxInOfsFp = %04X:%08X\n", sel,ofs);
+
+ printf ("Ready: *rxOutOfsFp = %04X *rxInOfsFp = %04X\n",
+ *rxOutOfsFp, *rxInOfsFp);
+
+ PktQueueBusy (TRUE);
+ printf ("Busy: *rxOutOfsFp = %04X *rxInOfsFp = %04X\n",
+ *rxOutOfsFp, *rxInOfsFp);
+ }
+#endif
+
+ memset (&pktStat, 0, sizeof(pktStat)); /* clear statistics */
+ PktQueueBusy (TRUE);
+ return (TRUE);
+}
+
+
+/*
+ * DPMI functions only for Watcom + DOS4GW extenders
+ */
+#if (DOSX & DOS4GW)
+LOCAL DWORD dpmi_get_real_vector (int intr)
+{
+ union REGS r;
+
+ r.x.eax = 0x200;
+ r.x.ebx = (DWORD) intr;
+ int386 (0x31, &r, &r);
+ return ((r.w.cx << 4) + r.w.dx);
+}
+
+LOCAL WORD dpmi_real_malloc (int size, WORD *selector)
+{
+ union REGS r;
+
+ r.x.eax = 0x0100; /* DPMI allocate DOS memory */
+ r.x.ebx = (size + 15) / 16; /* Number of paragraphs requested */
+ int386 (0x31, &r, &r);
+ if (r.w.cflag & 1)
+ return (0);
+
+ *selector = r.w.dx;
+ return (r.w.ax); /* Return segment address */
+}
+
+LOCAL void dpmi_real_free (WORD selector)
+{
+ union REGS r;
+
+ r.x.eax = 0x101; /* DPMI free DOS memory */
+ r.x.ebx = selector; /* Selector to free */
+ int386 (0x31, &r, &r);
+}
+#endif
+
+
+#if defined(DOSX) && (DOSX & PHARLAP)
+/*
+ * Description:
+ * This routine allocates conventional memory for the specified block
+ * of code (which must be within the first 64K of the protected mode
+ * program segment) and copies the code to it.
+ *
+ * The caller should free up the conventional memory block when it
+ * is done with the conventional memory.
+ *
+ * NOTE THIS ROUTINE REQUIRES 386|DOS-EXTENDER 3.0 OR LATER.
+ *
+ * Calling arguments:
+ * start_offs start of real mode code in program segment
+ * end_offs 1 byte past end of real mode code in program segment
+ * real_basep returned; real mode ptr to use as a base for the
+ * real mode code (eg, to get the real mode FAR
+ * addr of a function foo(), take
+ * real_basep + (ULONG) foo).
+ * This pointer is constructed such that
+ * offsets within the real mode segment are
+ * the same as the link-time offsets in the
+ * protected mode program segment
+ * prot_basep returned; prot mode ptr to use as a base for getting
+ * to the conventional memory, also constructed
+ * so that adding the prot mode offset of a
+ * function or variable to the base gets you a
+ * ptr to the function or variable in the
+ * conventional memory block.
+ * rmem_adrp returned; real mode para addr of allocated
+ * conventional memory block, to be used to free
+ * up the conventional memory when done. DO NOT
+ * USE THIS TO CONSTRUCT A REAL MODE PTR, USE
+ * REAL_BASEP INSTEAD SO THAT OFFSETS WORK OUT
+ * CORRECTLY.
+ *
+ * Returned values:
+ * 0 if error
+ * 1 if success
+ */
+int RealCopy (ULONG start_offs,
+ ULONG end_offs,
+ REALPTR *real_basep,
+ FARPTR *prot_basep,
+ USHORT *rmem_adrp)
+{
+ ULONG rm_base; /* base real mode para addr for accessing */
+ /* allocated conventional memory */
+ UCHAR *source; /* source pointer for copy */
+ FARPTR destin; /* destination pointer for copy */
+ ULONG len; /* number of bytes to copy */
+ ULONG temp;
+ USHORT stemp;
+
+ /* First check for valid inputs
+ */
+ if (start_offs >= end_offs || end_offs > 0x10000)
+ return (FALSE);
+
+ /* Round start_offs down to a paragraph (16-byte) boundary so we can set up
+ * the real mode pointer easily. Round up end_offs to make sure we allocate
+ * enough paragraphs
+ */
+ start_offs &= ~15;
+ end_offs = (15 + (end_offs << 4)) >> 4;
+
+ /* Allocate the conventional memory for our real mode code. Remember to
+ * round byte count UP to 16-byte paragraph size. We alloc it
+ * above the DOS data buffer so both the DOS data buffer and the appl
+ * conventional mem block can still be resized.
+ *
+ * First just try to alloc it; if we can't get it, shrink the appl mem
+ * block down to the minimum, try to alloc the memory again, then grow the
+ * appl mem block back to the maximum. (Don't try to shrink the DOS data
+ * buffer to free conventional memory; it wouldn't be good for this routine
+ * to have the possible side effect of making file I/O run slower.)
+ */
+ len = ((end_offs - start_offs) + 15) >> 4;
+ if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE)
+ {
+ if (_dx_cmem_usage(0, 0, &temp, &temp) != _DOSE_NONE)
+ return (FALSE);
+
+ if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE)
+ *rmem_adrp = 0;
+
+ if (_dx_cmem_usage(0, 1, &temp, &temp) != _DOSE_NONE)
+ {
+ if (*rmem_adrp != 0)
+ _dx_real_free (*rmem_adrp);
+ return (FALSE);
+ }
+
+ if (*rmem_adrp == 0)
+ return (FALSE);
+ }
+
+ /* Construct real mode & protected mode pointers to access the allocated
+ * memory. Note we know start_offs is aligned on a paragraph (16-byte)
+ * boundary, because we rounded it down.
+ *
+ * We make the offsets come out rights by backing off the real mode selector
+ * by start_offs.
+ */
+ rm_base = ((ULONG) *rmem_adrp) - (start_offs >> 4);
+ RP_SET (*real_basep, 0, rm_base);
+ FP_SET (*prot_basep, rm_base << 4, SS_DOSMEM);
+
+ /* Copy the real mode code/data to the allocated memory
+ */
+ source = (UCHAR *) start_offs;
+ destin = *prot_basep;
+ FP_SET (destin, FP_OFF(*prot_basep) + start_offs, FP_SEL(*prot_basep));
+ len = end_offs - start_offs;
+ WriteFarMem (destin, source, len);
+
+ return (TRUE);
+}
+#endif /* DOSX && (DOSX & PHARLAP) */
diff --git a/lib/libpcap/libpcap/msdos/pktdrvr.h b/lib/libpcap/libpcap/msdos/pktdrvr.h
new file mode 100644
index 0000000..3e0cfe0
--- /dev/null
+++ b/lib/libpcap/libpcap/msdos/pktdrvr.h
@@ -0,0 +1,153 @@
+#ifndef __PKTDRVR_H
+#define __PKTDRVR_H
+
+#define PUBLIC
+#define LOCAL static
+
+#define RX_BUF_SIZE ETH_MTU /* buffer size variables. NB !! */
+#define TX_BUF_SIZE ETH_MTU /* must be same as in pkt_rx*.* */
+
+#ifdef __HIGHC__
+#pragma Off(Align_members)
+#else
+#pragma pack(1)
+#endif
+
+typedef enum { /* Packet-driver classes */
+ PD_ETHER = 1,
+ PD_PRONET10 = 2,
+ PD_IEEE8025 = 3,
+ PD_OMNINET = 4,
+ PD_APPLETALK = 5,
+ PD_SLIP = 6,
+ PD_STARTLAN = 7,
+ PD_ARCNET = 8,
+ PD_AX25 = 9,
+ PD_KISS = 10,
+ PD_IEEE8023_2 = 11,
+ PD_FDDI8022 = 12,
+ PD_X25 = 13,
+ PD_LANstar = 14,
+ PD_PPP = 18
+ } PKT_CLASS;
+
+typedef enum { /* Packet-driver receive modes */
+ PDRX_OFF = 1, /* turn off receiver */
+ PDRX_DIRECT, /* receive only to this interface */
+ PDRX_BROADCAST, /* DIRECT + broadcast packets */
+ PDRX_MULTICAST1, /* BROADCAST + limited multicast */
+ PDRX_MULTICAST2, /* BROADCAST + all multicast */
+ PDRX_ALL_PACKETS, /* receive all packets on network */
+ } PKT_RX_MODE;
+
+typedef struct {
+ char type[8];
+ char len;
+ } PKT_FRAME;
+
+
+typedef struct {
+ BYTE class; /* = 1 for DEC/Interl/Xerox Ethernet */
+ BYTE number; /* = 0 for single LAN adapter */
+ WORD type; /* = 13 for 3C523 */
+ BYTE funcs; /* Basic/Extended/HiPerf functions */
+ WORD intr; /* user interrupt vector number */
+ WORD handle; /* Handle associated with session */
+ BYTE name [15]; /* Name of adapter interface,ie.3C523*/
+ BOOL quiet; /* (don't) print errors to stdout */
+ const char *error; /* address of error string */
+ BYTE majVer; /* Major driver implementation ver. */
+ BYTE minVer; /* Minor driver implementation ver. */
+ BYTE dummyLen; /* length of following data */
+ WORD MAClength; /* HiPerformance data, N/A */
+ WORD MTU; /* HiPerformance data, N/A */
+ WORD multicast; /* HiPerformance data, N/A */
+ WORD rcvrBuffers; /* valid for */
+ WORD UMTbufs; /* High Performance drivers only */
+ WORD postEOIintr; /* Usage ?? */
+ } PKT_INFO;
+
+#define PKT_PARAM_SIZE 14 /* members majVer - postEOIintr */
+
+
+typedef struct {
+ DWORD inPackets; /* # of packets received */
+ DWORD outPackets; /* # of packets transmitted */
+ DWORD inBytes; /* # of bytes received */
+ DWORD outBytes; /* # of bytes transmitted */
+ DWORD inErrors; /* # of reception errors */
+ DWORD outErrors; /* # of transmission errors */
+ DWORD lost; /* # of packets lost (RX) */
+ } PKT_STAT;
+
+
+typedef struct {
+ ETHER destin;
+ ETHER source;
+ WORD proto;
+ BYTE data [TX_BUF_SIZE];
+ } TX_ELEMENT;
+
+typedef struct {
+ WORD firstCount; /* # of bytes on 1st */
+ WORD secondCount; /* and 2nd upcall */
+ WORD handle; /* instance that upcalled */
+ ETHER destin; /* E-net destination address */
+ ETHER source; /* E-net source address */
+ WORD proto; /* protocol number */
+ BYTE data [RX_BUF_SIZE];
+ } RX_ELEMENT;
+
+
+#ifdef __HIGHC__
+#pragma pop(Align_members)
+#else
+#pragma pack()
+#endif
+
+
+/*
+ * Prototypes for publics
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern PKT_STAT pktStat; /* statistics for packets */
+extern PKT_INFO pktInfo; /* packet-driver information */
+
+extern PKT_RX_MODE receiveMode;
+extern ETHER myAddress, ethBroadcast;
+
+extern BOOL PktInitDriver (PKT_RX_MODE mode);
+extern BOOL PktExitDriver (void);
+
+extern const char *PktGetErrorStr (int errNum);
+extern const char *PktGetClassName (WORD class);
+extern const char *PktRXmodeStr (PKT_RX_MODE mode);
+extern BOOL PktSearchDriver (void);
+extern int PktReceive (BYTE *buf, int max);
+extern BOOL PktTransmit (const void *eth, int len);
+extern DWORD PktRxDropped (void);
+extern BOOL PktReleaseHandle (WORD handle);
+extern BOOL PktTerminHandle (WORD handle);
+extern BOOL PktResetInterface (WORD handle);
+extern BOOL PktSetReceiverMode(PKT_RX_MODE mode);
+extern BOOL PktGetReceiverMode(PKT_RX_MODE *mode);
+extern BOOL PktGetStatistics (WORD handle);
+extern BOOL PktSessStatistics (WORD handle);
+extern BOOL PktResetStatistics(WORD handle);
+extern BOOL PktGetAddress (ETHER *addr);
+extern BOOL PktSetAddress (const ETHER *addr);
+extern BOOL PktGetDriverInfo (void);
+extern BOOL PktGetDriverParam (void);
+extern void PktQueueBusy (BOOL busy);
+extern WORD PktBuffersUsed (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PKTDRVR_H */
+
diff --git a/lib/libpcap/libpcap/msdos/readme.dos b/lib/libpcap/libpcap/msdos/readme.dos
new file mode 100644
index 0000000..b95483f
--- /dev/null
+++ b/lib/libpcap/libpcap/msdos/readme.dos
@@ -0,0 +1,166 @@
+libpcap for DOS
+---------------
+
+This file contains some notes on building and using libpcap for MS-DOS.
+Look in `README' and `pcap.man' for usage and details. These targets are
+supported:
+
+ - Borland C 4.0+ small or large model.
+ - Metaware HighC 3.1+ with PharLap DOS-extender
+ - GNU C 2.7+ with djgpp 2.01+ DOS extender
+ - Watcom C 11.x with DOS4GW extender
+
+Note: the files in the libpcap.zip contains short truncated filenames.
+ So for djgpp to work with these, disable the use of long file names by
+ setting "LFN=n" in the environment. On the other hand, if you get libpcap
+ from Github or the official libpcap.tar.gz, some filenames are beyond 8+3.
+ In this case set "LFN=y".
+
+Files specific to DOS are pcap-dos.[ch] and the assembly and C files in
+the MSDOS sub-directory. Remember to built the libpcap library from the top
+install directory. And not from the MSDOS sub-directory.
+
+Note for djgpp users:
+ If you got the libpcap from the official site www.tcpdump, then that
+ distribution does NOT contain any sources for building 32-bit drivers.
+ Instead get the full version at
+ http://www.watt-32.net/pcap/libpcap.zip
+
+ and set "USE_32BIT_DRIVERS = 1" in msdos\common.dj.
+
+
+
+Requirements
+------------
+
+DOS-libpcap currently only works reliably with a real-mode Ethernet packet-
+driver. This driver must be installed prior to using any program (e.g.
+tcpdump) compiled with libpcap. Work is underway to implement protected-
+mode drivers for 32-bit targets (djgpp only). The 3Com 3c509 driver is
+working almost perfectly. Due to lack of LAN-cards, I've not had the
+opportunity to test other drivers. These 32-bit drivers are modified
+Linux drivers.
+
+
+Required packages
+-----------------
+
+The following packages and tools must be present for all targets.
+
+1. Watt-32 tcp/ip library. This library is *not* used to send or
+ receive network data. It's mostly used to access the 'hosts'
+ file and other <netdb.h> features. Get 'watt32s*.zip' at:
+
+ http://www.watt-32.net
+
+2. Exception handler and disassember library (libexc.a) is needed if
+ "USE_EXCEPT = 1" in common.dj. Available at:
+
+ http://www.watt-32.net/misc/exc_dx07.zip
+
+3. Flex & Bison is used to generate parser for the filter handler
+ pcap_compile:
+ ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/flx254b.zip
+ ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/bsn241b.zip
+
+4. NASM assembler v 0.98 or later is required when building djgpp and
+ Watcom targets:
+ http://www.nasm.us/
+
+5. sed (Stream Editor) is required for doing `make depend'.
+ It's available at:
+ ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/sed422b.zip
+
+ A touch tool to update the time-stamp of a file. E.g.:
+ ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/grep29b.zip
+
+6. For djgpp rm.exe and cp.exe are required. These should already be
+ part of your djgpp installation. Also required (experimental at the
+ time) for djgpp is DLX 2.91 or later. This tool is for the generation
+ of dynamically loadable modules.
+
+
+Compiling libpcap
+-----------------
+
+Follow these steps in building libpcap:
+
+1. Make sure you've installed Watt-32 properly (see it's `INSTALL' file).
+ During that installation a environment variable `WATT_ROOT' is set.
+ This variable is used for building libpcap also (`WATT_INC' is
+ deducted from `WATT_ROOT'). djgpp users should also define environment
+ variables `C_INCLUDE_PATH' and `LIBRARY_PATH' to point to the include
+ directory and library directory respectively. E.g. put this in your
+ AUTOEXEC.BAT:
+ set C_INCLUDE_PATH=c:/net/watt/inc
+ set LIBRARY_PATH=c:/net/watt/lib
+
+2. Revise the msdos/common.dj file for your djgpp/gcc installation;
+ - change the value of `GCCLIB' to match location of libgcc.a.
+ - set `USE_32BIT_DRIVERS = 1' to build 32-bit driver objects.
+
+
+3. Build pcap by using appropriate makefile. For djgpp, use:
+ `make -f msdos/makefile.dj' (i.e. GNU `make')
+
+ For a Watcom target say:
+ `wmake -f msdos\makefile.wc'
+
+ For a Borland target say:
+ `maker -f msdos\Makefile pcap_bc.lib' (Borland's `maker.exe')
+
+ And for a HighC/Pharlap target say:
+ `maker -f msdos\Makefile pcap_hc.lib' (Borland's `maker.exe')
+
+ You might like to change some `CFLAGS' -- only `DEBUG' define currently
+ have any effect. It shows a rotating "fan" in upper right corner of
+ screen. Remove `DEBUG' if you don't like it. You could add
+ `-fomit-frame-pointer' to `CFLAGS' to speed up the generated code.
+ But note, this makes debugging and crash-traceback difficult. Only
+ add it if you're fully confident your application is 100% stable.
+
+ Note: Code in `USE_NDIS2' does not work at the moment.
+
+4. The resulting library is put in current directory. There's some
+ test-program for `libpcap': `filtertest.exe', `findalldevstest.exe',
+ `nonblocktest.exe' and `opentest.exe'.
+
+ But linking the library with `tcpdump' is the ultimate test. DOS/djgpp
+ should now hopefully be a supported target. Get the sources at:
+ https://www.tcpdump.org/
+ or
+ https://github.com/the-tcpdump-group/tcpdump/
+
+ (click on the 'Download ZIP' on the right side of that page.)
+
+
+Extensions to libpcap
+---------------------
+
+I've included some extra functions to DOS-libpcap:
+
+ `pcap_config_hook (const char *keyword, const char *value)' :
+
+ Allows an application to set values of internal libpcap variables.
+ `keyword' and an associated `value' should be present in the `debug_tab[]'
+ array in pcap-dos.c (currently only used to set debug-levels and parameters
+ for the 32-bit network drivers.) Thus an application using DOS-libpcap can
+ override the default value during it's configure process (see tcpdump's
+ msdos/config.c file for an extended example).
+
+ `pcap_set_wait (pcap_t *, void (*)(void), int)' :
+
+ Only effective when reading offline traffic from dump-files.
+ Function `pcap_offline_read()' will wait (and optionally yield)
+ before printing next packet. This will simulate the pace the packets
+ where actually recorded.
+
+
+
+Happy sniffing !
+
+
+Gisle Vanem <gvanem@yahoo.no>
+
+October 1999, 2004, 2006, 2013
+