--- /dev/null
+# Auto detect text files and perform LF normalization
+* text=auto
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <stdarg.h>\r
-#include <time.h>\r
-\r
-static void Abort (char *fmt,...)\r
-{\r
- va_list args;\r
- va_start (args, fmt);\r
- vfprintf (stderr, fmt, args);\r
- va_end (args);\r
- exit (1);\r
-}\r
-\r
-int main (int argc, char **argv)\r
-{\r
- FILE *inFile;\r
- FILE *outFile = stdout;\r
- time_t now = time (NULL);\r
- int ch, i;\r
-\r
- if (argc != 2)\r
- Abort ("Usage: %s bin-file [> result]", argv[0]);\r
-\r
- if ((inFile = fopen(argv[1],"rb")) == NULL)\r
- Abort ("Cannot open %s\n", argv[1]);\r
-\r
- fprintf (outFile,\r
- "/* data statements for file %s at %.24s */\n"\r
- "/* Generated by BIN2C, G.Vanem 1995 */\n",\r
- argv[1], ctime(&now));\r
-\r
- i = 0;\r
- while ((ch = fgetc(inFile)) != EOF)\r
- {\r
- if (i++ % 12 == 0)\r
- fputs ("\n ", outFile);\r
- fprintf (outFile, "0x%02X,", ch);\r
- }\r
- fputc ('\n', outFile);\r
- fclose (inFile);\r
- return (0);\r
-}\r
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <time.h>
+
+static void Abort (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);
+}
-#\r
-# Makefile for dos-libpcap. NB. This makefile requires a Borland\r
-# compatible make tool.\r
-#\r
-# Targets:\r
-# Borland C 4.0+ (DOS large model)\r
-# Metaware HighC 3.3+ (PharLap 386|DosX)\r
-#\r
-\r
-.AUTODEPEND\r
-.SWAP\r
-\r
-!if "$(WATT_ROOT)" == ""\r
-!error Environment variable "WATT_ROOT" not set.\r
-!endif\r
-\r
-WATT_INC = $(WATT_ROOT)\inc\r
-\r
-DEFS = -DMSDOS -DDEBUG -DNDIS_DEBUG -D_U_= -Dinline= \\r
- -DHAVE_STRERROR -DHAVE_LIMITS_H\r
-\r
-ASM = tasm.exe -t -l -mx -m2 -DDEBUG\r
-\r
-SOURCE = grammar.c scanner.c bpf_filt.c bpf_imag.c bpf_dump.c \\r
- etherent.c gencode.c nametoad.c pcap-dos.c optimize.c \\r
- savefile.c pcap.c inet.c msdos\ndis2.c msdos\pktdrvr.c \\r
- missing\snprintf.c\r
-\r
-BORLAND_OBJ = $(SOURCE:.c=.obj) msdos\pkt_rx0.obj msdos\ndis_0.obj\r
-\r
-HIGHC_OBJ = $(SOURCE:.c=.o32) msdos\pkt_rx0.o32\r
-\r
-all:\r
- @echo Usage: make pcap_bc.lib or pcap_hc.lib\r
-\r
-\r
-pcap_bc.lib: bcc.arg $(BORLAND_OBJ) pcap_bc\r
-\r
-\r
-pcap_hc.lib: hc386.arg $(HIGHC_OBJ)\r
- 386lib $< @&&|\r
- -nowarn -nobackup -twocase -replace $(HIGHC_OBJ)\r
-|\r
-\r
-pcap_bc: $(BORLAND_OBJ)\r
- @tlib pcap_bc.lib /C @&&|\r
- -+$(**:.obj=-+)\r
-|\r
-\r
-.c.obj:\r
- bcc.exe @bcc.arg -o$*.obj $*.c\r
-\r
-.c.o32:\r
- hc386.exe @hc386.arg -o $*.o32 $*.c\r
-\r
-.asm.obj:\r
- $(ASM) $*.asm, $*.obj\r
-\r
-.asm.o32:\r
- $(ASM) -DDOSX=1 $*.asm, $*.o32\r
-\r
-scanner.c: scanner.l\r
- flex -Ppcap_ -7 -oscanner.c scanner.l\r
-\r
-grammar.c tokdefs.h: grammar.y\r
- bison --name-prefix=pcap_ --yacc --defines grammar.y\r
- - @del grammar.c\r
- - @del tokdefs.h\r
- ren y_tab.c grammar.c\r
- ren y_tab.h tokdefs.h\r
-\r
-bcc.arg: msdos\Makefile\r
- @copy &&|\r
- $(DEFS) -ml -c -v -3 -O2 -po -RT- -w-\r
- -I$(WATT_INC) -I. -I.\msdos\pm_drvr -H=$(TEMP)\bcc.sym\r
-| $<\r
-\r
-hc386.arg: msdos\Makefile\r
- @copy &&|\r
- # -DUSE_32BIT_DRIVERS\r
- $(DEFS) -DDOSX=1 -w3 -c -g -O5\r
- -I$(WATT_INC) -I. -I.\msdos\pm_drvr\r
- -Hsuffix=.o32\r
- -Hnocopyr\r
- -Hpragma=Offwarn(491,553,572)\r
- -Hon=Recognize_library # make memcpy/strlen etc. inline\r
- -Hoff=Behaved # turn off some optimiser warnings\r
-| $<\r
-\r
-clean:\r
- @del *.obj\r
- @del *.o32\r
- @del *.lst\r
- @del *.map\r
- @del bcc.arg\r
- @del hc386.arg\r
- @del grammar.c\r
- @del tokdefs.h\r
- @del scanner.c\r
- @echo Cleaned\r
-\r
-#\r
-# dependencies\r
-# \r
-pkt_rx0.obj: msdos\pkt_rx0.asm\r
-\r
-bpf_filt.obj: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.h\r
-\r
-bpf_imag.obj: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h\r
-\r
-bpf_dump.obj: bpf_dump.c pcap.h pcap-bpf.h\r
-\r
-etherent.obj: etherent.c pcap-int.h pcap.h pcap-bpf.h pcap-namedb.h\r
-\r
-optimize.obj: optimize.c pcap-int.h pcap.h pcap-bpf.h gencode.h\r
-\r
-savefile.obj: savefile.c pcap-int.h pcap.h pcap-bpf.h\r
-\r
-pcap.obj: pcap.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h\r
-\r
-inet.obj: inet.c pcap-int.h pcap.h pcap-bpf.h\r
-\r
-grammar.obj: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h \\r
- pf.h pcap-namedb.h\r
-\r
-scanner.obj: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h \\r
- pcap-namedb.h tokdefs.h\r
-\r
-gencode.obj: gencode.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \\r
- ethertype.h nlpid.h llc.h gencode.h atmuni31.h sunatmpos.h ppp.h sll.h \\r
- arcnet.h pf.h pcap-namedb.h\r
-\r
-nametoad.obj: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h \\r
- pcap-namedb.h ethertype.h\r
-\r
-pcap-dos.obj: pcap-dos.c pcap.h pcap-bpf.h pcap-dos.h pcap-int.h \\r
- msdos\pktdrvr.h\r
-\r
-pktdrvr.obj: msdos\pktdrvr.c gnuc.h pcap-dos.h pcap-int.h \\r
- pcap.h pcap-bpf.h msdos\pktdrvr.h msdos\pkt_stub.inc\r
-\r
-ndis2.obj: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \\r
- msdos\ndis2.h\r
-\r
-pkt_rx0.o32: msdos\pkt_rx0.asm\r
-\r
-bpf_filt.o32: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.h\r
-\r
-bpf_imag.o32: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h\r
-\r
-bpf_dump.o32: bpf_dump.c pcap.h pcap-bpf.h\r
-\r
-etherent.o32: etherent.c pcap-int.h pcap.h pcap-bpf.h pcap-namedb.h\r
-\r
-optimize.o32: optimize.c pcap-int.h pcap.h pcap-bpf.h gencode.h\r
-\r
-savefile.o32: savefile.c pcap-int.h pcap.h pcap-bpf.h\r
-\r
-pcap.o32: pcap.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h\r
-\r
-inet.o32: inet.c pcap-int.h pcap.h pcap-bpf.h\r
-\r
-grammar.o32: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h \\r
- pf.h pcap-namedb.h\r
-\r
-scanner.o32: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h \\r
- pcap-namedb.h tokdefs.h\r
-\r
-gencode.o32: gencode.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \\r
- ethertype.h nlpid.h llc.h gencode.h atmuni31.h sunatmpos.h ppp.h sll.h \\r
- arcnet.h pf.h pcap-namedb.h\r
-\r
-nametoad.o32: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h \\r
- pcap-namedb.h ethertype.h\r
-\r
-pcap-dos.o32: pcap-dos.c pcap.h pcap-bpf.h pcap-dos.h pcap-int.h \\r
- msdos\pktdrvr.h\r
-\r
-pktdrvr.o32: msdos\pktdrvr.c gnuc.h pcap-dos.h pcap-int.h \\r
- pcap.h pcap-bpf.h msdos\pktdrvr.h msdos\pkt_stub.inc\r
-\r
-ndis2.o32: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h \\r
- msdos\ndis2.h\r
-\r
+#
+# 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 inet.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
+
+inet.obj: inet.c 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
+
+inet.o32: inet.c 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
+
-#\r
-# Watcom Makefile for dos-libpcap.\r
-#\r
-# Specify MODEL = `3r' or `3s'\r
-# Specify TARGET = `pharlap' or `dos4g'\r
-#\r
-# Use this makefile from the libpcap root directory.\r
-# E.g. like this:\r
-#\r
-# c:\net\pcap> wmake -f msdos\makefile.wc\r
-#\r
-\r
-MODEL = 3s\r
-TARGET = dos4g\r
-\r
-OBJDIR = msdos\$(TARGET).w$(MODEL)\r
-LIB = $(OBJDIR)\pcap.lib\r
-\r
-.EXTENSIONS: .l .y\r
-\r
-DEFS = -dDEBUG -dNDIS_DEBUG -d_U_= -dHAVE_LIMITS_H -dHAVE_STRERROR &\r
- -dHAVE_SNPRINTF -dHAVE_VSNPRINTF\r
-\r
-CC = wcc386.exe\r
-ASM = wasm.exe -$(MODEL) $(DEFS) -dDOSX -dDOS4GW -zq -bt=dos -fr=nul -d3 -s\r
-\r
-OBJS = $(OBJDIR)\grammar.obj $(OBJDIR)\scanner.obj $(OBJDIR)\pcap.obj &\r
- $(OBJDIR)\bpf_filt.obj $(OBJDIR)\bpf_imag.obj $(OBJDIR)\bpf_dump.obj &\r
- $(OBJDIR)\etherent.obj $(OBJDIR)\gencode.obj $(OBJDIR)\nametoad.obj &\r
- $(OBJDIR)\pcap-dos.obj $(OBJDIR)\pktdrvr.obj $(OBJDIR)\optimize.obj &\r
- $(OBJDIR)\savefile.obj $(OBJDIR)\inet.obj $(OBJDIR)\ndis2.obj\r
-\r
-CFLAGS = $(DEFS) $(YYDEFS) -I. -I$(%watt_root)\inc -I.\msdos\pm_drvr &\r
- -$(MODEL) -mf -zff -zgf -zq -bt=dos -fr=nul -w6 -fpi &\r
- -oilrtf -zm\r
-\r
-TEMPBIN = tmp.bin\r
-\r
-all: $(OBJDIR) $(OBJDIR)\pcap.lib\r
-\r
-$(OBJDIR):\r
- - mkdir $(OBJDIR)\r
-\r
-$(OBJDIR)\pcap.lib: $(OBJS) wlib.arg\r
- wlib -q -b -c $(OBJDIR)\pcap.lib @wlib.arg\r
-\r
-wlib.arg: msdos\makefile.wc\r
- %create $^@\r
- for %f in ($(OBJS)) do %append $^@ +- %f\r
-\r
-$(OBJDIR)\pktdrvr.obj: msdos\pkt_stub.inc msdos\pktdrvr.c gnuc.h &\r
- pcap-dos.h pcap-int.h pcap.h msdos\pktdrvr.h\r
- *$(CC) $(CFLAGS) msdos\pktdrvr.c -fo=$@\r
-\r
-$(OBJDIR)\ndis2.obj: msdos\ndis2.c\r
- *$(CC) $(CFLAGS) msdos\ndis2.c -fo=$@\r
-\r
-.ERASE\r
-.c{$(OBJDIR)}.obj:\r
- *$(CC) $(CFLAGS) $[@ -fo=$@\r
-\r
-grammar.c tokdefs.h: grammar.y \r
- bison --name-prefix=pcap_ --yacc --defines $[@\r
- - @del grammar.c\r
- - @del tokdefs.h\r
- ren y_tab.c grammar.c\r
- ren y_tab.h tokdefs.h\r
-\r
-scanner.c: scanner.l\r
- flex -Ppcap_ -7 -o$@ $[@\r
-\r
-msdos\pkt_stub.inc: bin2c.exe msdos\pkt_rx1.S\r
- nasm -fbin -dDEBUG -o $(TEMPBIN) -lmsdos\pkt_rx1.lst msdos\pkt_rx1.S\r
- bin2c.exe $(TEMPBIN) > $@\r
- @del $(TEMPBIN)\r
-\r
-bin2c.exe: msdos\bin2c.c\r
- wcl $[@\r
-\r
-clean realclean vclean: .SYMBOLIC\r
- for %f in (dos4g.w3r dos4g.w3s pharlap.w3r pharlap.w3s) do &\r
- @del %f\*.obj\r
- @del grammar.c\r
- @del tokdefs.h\r
- @del scanner.c\r
- @del bin2c.exe\r
- @del bin2c.obj\r
- @del msdos\pkt_stub.inc\r
- @echo Cleaned\r
-\r
-#\r
-# dependencies\r
-# \r
-$(OBJDIR)\bpf_filt.obj: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.h\r
-\r
-$(OBJDIR)\bpf_imag.obj: bpf_imag.c pcap-int.h pcap.h pcap-bpf.h\r
-\r
-$(OBJDIR)\bpf_dump.obj: bpf_dump.c pcap.h pcap-bpf.h\r
-\r
-$(OBJDIR)\etherent.obj: etherent.c pcap-int.h pcap.h pcap-bpf.h pcap-nam.h\r
-\r
-$(OBJDIR)\optimize.obj: optimize.c pcap-int.h pcap.h pcap-bpf.h gencode.h\r
-\r
-$(OBJDIR)\savefile.obj: savefile.c pcap-int.h pcap.h pcap-bpf.h\r
-\r
-$(OBJDIR)\pcap.obj: pcap.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h\r
-\r
-$(OBJDIR)\inet.obj: inet.c pcap-int.h pcap.h pcap-bpf.h\r
-\r
-$(OBJDIR)\grammar.obj: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h &\r
- pf.h pcap-nam.h\r
-\r
-$(OBJDIR)\scanner.obj: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h &\r
- pcap-nam.h tokdefs.h\r
-\r
-$(OBJDIR)\gencode.obj: gencode.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h &\r
- ethertyp.h nlpid.h llc.h gencode.h atmuni31.h sunatmpo.h ppp.h sll.h &\r
- arcnet.h pf.h pcap-nam.h\r
-\r
-$(OBJDIR)\nametoad.obj: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h &\r
- pcap-nam.h ethertyp.h\r
-\r
-$(OBJDIR)\pcap-dos.obj: pcap-dos.c pcap.h pcap-bpf.h pcap-dos.h pcap-int.h &\r
- msdos\pktdrvr.h\r
-\r
-$(OBJDIR)\pktdrvr.obj: msdos\pktdrvr.c gnuc.h pcap-dos.h pcap-int.h &\r
- pcap.h pcap-bpf.h msdos\pktdrvr.h msdos\pkt_stub.inc\r
-\r
-$(OBJDIR)\ndis2.obj: msdos\ndis2.c pcap-dos.h pcap-int.h pcap.h pcap-bpf.h &\r
- msdos\ndis2.h\r
-\r
+#
+# 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_filt.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)\inet.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 gnuc.h &
+ pcap-dos.h pcap-int.h pcap.h msdos\pktdrvr.h
+ *$(CC) $(CFLAGS) msdos\pktdrvr.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_filt.obj: bpf_filt.c pcap-int.h pcap.h pcap-bpf.h gnuc.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-nam.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)\inet.obj: inet.c pcap-int.h pcap.h pcap-bpf.h
+
+$(OBJDIR)\grammar.obj: grammar.c pcap-int.h pcap.h pcap-bpf.h gencode.h &
+ pf.h pcap-nam.h
+
+$(OBJDIR)\scanner.obj: scanner.c pcap-int.h pcap.h pcap-bpf.h gencode.h &
+ pcap-nam.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 pf.h pcap-nam.h
+
+$(OBJDIR)\nametoad.obj: nametoad.c pcap-int.h pcap.h pcap-bpf.h gencode.h &
+ pcap-nam.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 gnuc.h 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
+
-/* \r
- * Copyright (c) 1993,1994\r
- * Texas A&M University. All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- * 1. Redistributions of source code must retain the above copyright\r
- * notice, this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the\r
- * documentation and/or other materials provided with the distribution.\r
- * 3. All advertising materials mentioning features or use of this software\r
- * must display the following acknowledgement:\r
- * This product includes software developed by Texas A&M University\r
- * and its contributors.\r
- * 4. Neither the name of the University nor the names of its contributors\r
- * may be used to endorse or promote products derived from this software\r
- * without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND\r
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE\r
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
- * SUCH DAMAGE.\r
- *\r
- * Developers:\r
- * David K. Hess, Douglas Lee Schales, David R. Safford\r
- *\r
- * Heavily modified for Metaware HighC + GNU C 2.8+\r
- * Gisle Vanem 1998\r
- */\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <dos.h>\r
-#include <io.h>\r
-#include <fcntl.h>\r
-#include <malloc.h>\r
-#include <string.h>\r
-\r
-#include "pcap-dos.h"\r
-#include "pcap-int.h"\r
-#include "msdos/ndis2.h"\r
-\r
-#if defined(USE_NDIS2)\r
-\r
-/*\r
- * Packet buffer handling\r
- */\r
-extern int FreePktBuf (PktBuf *buf);\r
-extern int EnquePktBuf (PktBuf *buf);\r
-extern PktBuf* AllocPktBuf (void);\r
-\r
-/*\r
- * Various defines\r
- */\r
-#define MAX_NUM_DEBUG_STRINGS 90\r
-#define DEBUG_STRING_LENGTH 80\r
-#define STACK_POOL_SIZE 6\r
-#define STACK_SIZE 256\r
-\r
-#define MEDIA_FDDI 1\r
-#define MEDIA_ETHERNET 2\r
-#define MEDIA_TOKEN 3\r
-\r
-static int startDebug = 0;\r
-static int stopDebug = 0;\r
-\r
-static DWORD droppedPackets = 0L;\r
-static WORD frameSize = 0;\r
-static WORD headerSize = 0;\r
-static int mediaType = 0;\r
-static char *lastErr = NULL;\r
-\r
-static BYTE debugStrings [MAX_NUM_DEBUG_STRINGS][DEBUG_STRING_LENGTH];\r
-static BYTE *freeStacks [STACK_POOL_SIZE];\r
-static int freeStackPtr = STACK_POOL_SIZE - 1;\r
-\r
-static ProtMan protManEntry = NULL;\r
-static WORD protManDS = 0;\r
-static volatile int xmitPending;\r
-\r
-static struct _PktBuf *txBufPending;\r
-static struct _CardHandle *handle;\r
-static struct _CommonChars common;\r
-static struct _ProtocolChars protChars;\r
-static struct _ProtDispatch lowerTable;\r
-\r
-static struct _FailingModules failingModules;\r
-static struct _BindingsList bindings;\r
-\r
-static struct {\r
- WORD err_num;\r
- char *err_text;\r
- } ndis_errlist[] = {\r
-\r
- { ERR_SUCCESS,\r
- "The function completed successfully.\n" },\r
-\r
- { ERR_WAIT_FOR_RELEASE,\r
- "The ReceiveChain completed successfully but the protocol has\n"\r
- "retained control of the buffer.\n" },\r
-\r
- { ERR_REQUEST_QUEUED,\r
- "The current request has been queued.\n" },\r
-\r
- { ERR_FRAME_NOT_RECOGNIZED,\r
- "Frame not recognized.\n" },\r
-\r
- { ERR_FRAME_REJECTED,\r
- "Frame was discarded.\n" },\r
-\r
- { ERR_FORWARD_FRAME,\r
- "Protocol wishes to forward frame to another protocol.\n" },\r
-\r
- { ERR_OUT_OF_RESOURCE,\r
- "Out of resource.\n" },\r
-\r
- { ERR_INVALID_PARAMETER,\r
- "Invalid parameter.\n" },\r
-\r
- { ERR_INVALID_FUNCTION,\r
- "Invalid function.\n" },\r
-\r
- { ERR_NOT_SUPPORTED,\r
- "Not supported.\n" },\r
-\r
- { ERR_HARDWARE_ERROR,\r
- "Hardware error.\n" },\r
-\r
- { ERR_TRANSMIT_ERROR,\r
- "The packet was not transmitted due to an error.\n" },\r
-\r
- { ERR_NO_SUCH_DESTINATION,\r
- "Token ring packet was not recognized when transmitted.\n" },\r
-\r
- { ERR_BUFFER_TOO_SMALL,\r
- "Provided buffer was too small.\n" },\r
-\r
- { ERR_ALREADY_STARTED,\r
- "Network drivers already started.\n" },\r
-\r
- { ERR_INCOMPLETE_BINDING,\r
- "Protocol driver could not complete its bindings.\n" },\r
-\r
- { ERR_DRIVER_NOT_INITIALIZED,\r
- "MAC did not initialize properly.\n" },\r
-\r
- { ERR_HARDWARE_NOT_FOUND,\r
- "Hardware not found.\n" },\r
-\r
- { ERR_HARDWARE_FAILURE,\r
- "Hardware failure.\n" },\r
-\r
- { ERR_CONFIGURATION_FAILURE,\r
- "Configuration failure.\n" },\r
-\r
- { ERR_INTERRUPT_CONFLICT,\r
- "Interrupt conflict.\n" },\r
-\r
- { ERR_INCOMPATIBLE_MAC,\r
- "The MAC is not compatible with the protocol.\n" },\r
-\r
- { ERR_INITIALIZATION_FAILED,\r
- "Initialization failed.\n" },\r
-\r
- { ERR_NO_BINDING,\r
- "Binding did not occur.\n" },\r
-\r
- { ERR_NETWORK_MAY_NOT_BE_CONNECTED,\r
- "The network may not be connected to the adapter.\n" },\r
-\r
- { ERR_INCOMPATIBLE_OS_VERSION,\r
- "The version of the operating system is incompatible with the protocol.\n" },\r
-\r
- { ERR_ALREADY_REGISTERED,\r
- "The protocol is already registered.\n" },\r
-\r
- { ERR_PATH_NOT_FOUND,\r
- "PROTMAN.EXE could not be found.\n" },\r
-\r
- { ERR_INSUFFICIENT_MEMORY,\r
- "Insufficient memory.\n" },\r
-\r
- { ERR_INFO_NOT_FOUND,\r
- "Protocol Mananger info structure is lost or corrupted.\n" },\r
-\r
- { ERR_GENERAL_FAILURE,\r
- "General failure.\n" }\r
-};\r
-\r
-/*\r
- * Some handy macros\r
- */ \r
-#define PERROR(str) printf("%s (%d): %s\n", __FILE__,__LINE__,str)\r
-#define DEBUG_RING() (debugStrings[stopDebug+1 == MAX_NUM_DEBUG_STRINGS ? \\r
- stopDebug = 0 : ++stopDebug])\r
-\r
-/*\r
- * needs rewrite for DOSX\r
- */\r
-#define MAC_DISPATCH(hnd) ((struct _MacUpperDispatch*)(hnd)->common->upperDispatchTable)\r
-#define MAC_STATUS(hnd) ((struct _MacStatusTable*) (hnd)->common->serviceStatus)\r
-#define MAC_CHAR(hnd) ((struct _MacChars*) (hnd)->common->serviceChars)\r
-\r
-#ifdef NDIS_DEBUG\r
- #define DEBUG0(str) printf (str)\r
- #define DEBUG1(fmt,a) printf (fmt,a)\r
- #define DEBUG2(fmt,a,b) printf (fmt,a,b)\r
- #define TRACE0(str) sprintf (DEBUG_RING(),str)\r
- #define TRACE1(fmt,a) sprintf (DEBUG_RING(),fmt,a)\r
-#else\r
- #define DEBUG0(str) ((void)0)\r
- #define DEBUG1(fmt,a) ((void)0)\r
- #define DEBUG2(fmt,a,b) ((void)0)\r
- #define TRACE0(str) ((void)0)\r
- #define TRACE1(fmt,a) ((void)0)\r
-#endif\r
-\r
-/*\r
- * This routine is called from both threads\r
- */\r
-void NdisFreeStack (BYTE *aStack)\r
-{\r
- GUARD();\r
-\r
- if (freeStackPtr == STACK_POOL_SIZE - 1)\r
- PERROR ("tried to free too many stacks");\r
-\r
- freeStacks[++freeStackPtr] = aStack;\r
-\r
- if (freeStackPtr == 0)\r
- TRACE0 ("freeStackPtr went positive\n");\r
-\r
- UNGUARD();\r
-}\r
-\r
-/*\r
- * This routine is called from callbacks to allocate local data\r
- */\r
-BYTE *NdisAllocStack (void)\r
-{\r
- BYTE *stack;\r
-\r
- GUARD();\r
-\r
- if (freeStackPtr < 0)\r
- {\r
- /* Ran out of stack buffers. Return NULL which will start\r
- * dropping packets\r
- */\r
- TRACE0 ("freeStackPtr went negative\n");\r
- stack = 0;\r
- }\r
- else\r
- stack = freeStacks[freeStackPtr--];\r
-\r
- UNGUARD();\r
- return (stack);\r
-}\r
-\r
-CALLBACK (NdisSystemRequest (DWORD param1, DWORD param2, WORD param3,\r
- WORD opcode, WORD targetDS))\r
-{\r
- static int bindEntry = 0;\r
- struct _CommonChars *macCommon;\r
- volatile WORD result;\r
-\r
- switch (opcode)\r
- {\r
- case REQ_INITIATE_BIND:\r
- macCommon = (struct _CommonChars*) param2;\r
- if (macCommon == NULL)\r
- {\r
- printf ("There is an NDIS misconfiguration.\n");\r
- result = ERR_GENERAL_FAILURE;\r
- break;\r
- }\r
- DEBUG2 ("module name %s\n"\r
- "module type %s\n",\r
- macCommon->moduleName,\r
- ((MacChars*) macCommon->serviceChars)->macName);\r
-\r
- /* Binding to the MAC */\r
- result = macCommon->systemRequest ((DWORD)&common, (DWORD)&macCommon,\r
- 0, REQ_BIND,\r
- macCommon->moduleDS);\r
-\r
- if (!strcmp(bindings.moduleName[bindEntry], handle->moduleName))\r
- handle->common = macCommon;\r
- else PERROR ("unknown module");\r
- ++bindEntry;\r
- break;\r
-\r
- case REQ_INITIATE_UNBIND:\r
- macCommon = (struct _CommonChars*) param2;\r
- result = macCommon->systemRequest ((DWORD)&common, 0,\r
- 0, REQ_UNBIND,\r
- macCommon->moduleDS);\r
- break;\r
-\r
- default:\r
- result = ERR_GENERAL_FAILURE;\r
- break;\r
- }\r
- ARGSUSED (param1);\r
- ARGSUSED (param3);\r
- ARGSUSED (targetDS);\r
- return (result);\r
-}\r
-\r
-CALLBACK (NdisRequestConfirm (WORD protId, WORD macId, WORD reqHandle,\r
- WORD status, WORD request, WORD protDS))\r
-{\r
- ARGSUSED (protId); ARGSUSED (macId);\r
- ARGSUSED (reqHandle); ARGSUSED (status);\r
- ARGSUSED (request); ARGSUSED (protDS);\r
- return (ERR_SUCCESS);\r
-}\r
-\r
-CALLBACK (NdisTransmitConfirm (WORD protId, WORD macId, WORD reqHandle,\r
- WORD status, WORD protDS))\r
-{\r
- xmitPending--;\r
- FreePktBuf (txBufPending); /* Add passed ECB back to the free list */\r
-\r
- ARGSUSED (reqHandle);\r
- ARGSUSED (status);\r
- ARGSUSED (protDS);\r
- return (ERR_SUCCESS);\r
-}\r
-\r
-\r
-/*\r
- * The primary function for receiving packets\r
- */\r
-CALLBACK (NdisReceiveLookahead (WORD macId, WORD frameSize,\r
- WORD bytesAvail, BYTE *buffer,\r
- BYTE *indicate, WORD protDS))\r
-{\r
- int result;\r
- PktBuf *pktBuf;\r
- WORD bytesCopied;\r
- struct _TDBufDescr tDBufDescr;\r
-\r
-#if 0\r
- TRACE1 ("lookahead length = %d, ", bytesAvail);\r
- TRACE1 ("ecb = %08lX, ", *ecb);\r
- TRACE1 ("count = %08lX\n", count);\r
- TRACE1 ("offset = %08lX, ", offset);\r
- TRACE1 ("timesAllowed = %d, ", timesAllowed);\r
- TRACE1 ("packet size = %d\n", look->dataLookAheadLen);\r
-#endif\r
-\r
- /* Allocate a buffer for the packet\r
- */\r
- if ((pktBuf = AllocPktBuf()) == NULL)\r
- {\r
- droppedPackets++;\r
- return (ERR_FRAME_REJECTED);\r
- }\r
-\r
- /*\r
- * Now kludge things. Note we will have to undo this later. This will\r
- * make the packet contiguous after the MLID has done the requested copy.\r
- */\r
-\r
- tDBufDescr.tDDataCount = 1;\r
- tDBufDescr.tDBufDescrRec[0].tDPtrType = NDIS_PTR_PHYSICAL;\r
- tDBufDescr.tDBufDescrRec[0].tDDataPtr = pktBuf->buffer;\r
- tDBufDescr.tDBufDescrRec[0].tDDataLen = pktBuf->length;\r
- tDBufDescr.tDBufDescrRec[0].dummy = 0;\r
-\r
- result = MAC_DISPATCH(handle)->transferData (&bytesCopied, 0, &tDBufDescr,\r
- handle->common->moduleDS);\r
- pktBuf->packetLength = bytesCopied;\r
-\r
- if (result == ERR_SUCCESS)\r
- EnquePktBuf(pktBuf);\r
- else FreePktBuf (pktBuf);\r
-\r
- ARGSUSED (frameSize);\r
- ARGSUSED (bytesAvail);\r
- ARGSUSED (indicate);\r
- ARGSUSED (protDS);\r
-\r
- return (ERR_SUCCESS);\r
-}\r
-\r
-CALLBACK (NdisIndicationComplete (WORD macId, WORD protDS))\r
-{\r
- ARGSUSED (macId);\r
- ARGSUSED (protDS);\r
-\r
- /* We don't give a hoot about these. Just return\r
- */\r
- return (ERR_SUCCESS);\r
-}\r
-\r
-/*\r
- * This is the OTHER way we may receive packets\r
- */\r
-CALLBACK (NdisReceiveChain (WORD macId, WORD frameSize, WORD reqHandle,\r
- struct _RxBufDescr *rxBufDescr,\r
- BYTE *indicate, WORD protDS))\r
-{\r
- struct _PktBuf *pktBuf;\r
- int i;\r
-\r
- /*\r
- * For now we copy the entire packet over to a PktBuf structure. This may be\r
- * a performance hit but this routine probably isn't called very much, and\r
- * it is a lot of work to do it otherwise. Also if it is a filter protocol\r
- * packet we could end up sucking up MAC buffes.\r
- */\r
-\r
- if ((pktBuf = AllocPktBuf()) == NULL)\r
- {\r
- droppedPackets++;\r
- return (ERR_FRAME_REJECTED);\r
- }\r
- pktBuf->packetLength = 0;\r
-\r
- /* Copy the packet to the buffer\r
- */\r
- for (i = 0; i < rxBufDescr->rxDataCount; ++i)\r
- {\r
- struct _RxBufDescrRec *rxDescr = &rxBufDescr->rxBufDescrRec[i];\r
-\r
- memcpy (pktBuf->buffer + pktBuf->packetLength,\r
- rxDescr->rxDataPtr, rxDescr->rxDataLen);\r
- pktBuf->packetLength += rxDescr->rxDataLen;\r
- }\r
-\r
- EnquePktBuf (pktBuf);\r
-\r
- ARGSUSED (frameSize);\r
- ARGSUSED (reqHandle);\r
- ARGSUSED (indicate);\r
- ARGSUSED (protDS); \r
-\r
- /* This frees up the buffer for the MAC to use\r
- */\r
- return (ERR_SUCCESS);\r
-}\r
-\r
-CALLBACK (NdisStatusProc (WORD macId, WORD param1, BYTE *indicate,\r
- WORD opcode, WORD protDS))\r
-{\r
- switch (opcode)\r
- {\r
- case STATUS_RING_STATUS:\r
- break;\r
- case STATUS_ADAPTER_CHECK:\r
- break;\r
- case STATUS_START_RESET:\r
- break;\r
- case STATUS_INTERRUPT:\r
- break;\r
- case STATUS_END_RESET:\r
- break;\r
- default:\r
- break;\r
- }\r
- ARGSUSED (macId);\r
- ARGSUSED (param1);\r
- ARGSUSED (indicate);\r
- ARGSUSED (opcode);\r
- ARGSUSED (protDS);\r
-\r
- /* We don't need to do anything about this stuff yet\r
- */\r
- return (ERR_SUCCESS);\r
-}\r
-\r
-/*\r
- * Tell the NDIS driver to start the delivery of the packet\r
- */\r
-int NdisSendPacket (struct _PktBuf *pktBuf, int macId)\r
-{ \r
- struct _TxBufDescr txBufDescr;\r
- int result;\r
-\r
- xmitPending++;\r
- txBufPending = pktBuf; /* we only have 1 pending Tx at a time */\r
-\r
- txBufDescr.txImmedLen = 0;\r
- txBufDescr.txImmedPtr = NULL;\r
- txBufDescr.txDataCount = 1;\r
- txBufDescr.txBufDescrRec[0].txPtrType = NDIS_PTR_PHYSICAL;\r
- txBufDescr.txBufDescrRec[0].dummy = 0;\r
- txBufDescr.txBufDescrRec[0].txDataLen = pktBuf->packetLength;\r
- txBufDescr.txBufDescrRec[0].txDataPtr = pktBuf->buffer;\r
-\r
- result = MAC_DISPATCH(handle)->transmitChain (common.moduleId,\r
- pktBuf->handle,\r
- &txBufDescr,\r
- handle->common->moduleDS);\r
- switch (result)\r
- {\r
- case ERR_OUT_OF_RESOURCE:\r
- /* Note that this should not happen but if it does there is not\r
- * much we can do about it\r
- */\r
- printf ("ERROR: transmit queue overflowed\n");\r
- return (0);\r
-\r
- case ERR_SUCCESS:\r
- /* Everything was hunky dory and synchronous. Free up the \r
- * packet buffer\r
- */\r
- xmitPending--;\r
- FreePktBuf (pktBuf);\r
- return (1);\r
-\r
- case ERR_REQUEST_QUEUED:\r
- /* Everything was hunky dory and asynchronous. Do nothing\r
- */\r
- return (1);\r
-\r
- default:\r
- printf ("Tx fail, code = %04X\n", result);\r
- return (0);\r
- }\r
-}\r
-\r
-\r
-\r
-static int ndis_nerr = sizeof(ndis_errlist) / sizeof(ndis_errlist[0]);\r
-\r
-static char *Ndis_strerror (WORD errorCode)\r
-{\r
- static char buf[30];\r
- int i;\r
-\r
- for (i = 0; i < ndis_nerr; i++)\r
- if (errorCode == ndis_errlist[i].err_num)\r
- return (ndis_errlist[i].err_text);\r
-\r
- sprintf (buf,"unknown error %d",errorCode);\r
- return (buf);\r
-}\r
-\r
-\r
-char *NdisLastError (void)\r
-{\r
- char *errStr = lastErr;\r
- lastErr = NULL;\r
- return (errStr);\r
-}\r
-\r
-int NdisOpen (void)\r
-{\r
- struct _ReqBlock reqBlock;\r
- int result;\r
- int ndisFd = open (NDIS_PATH, O_RDONLY);\r
-\r
- if (ndisFd < 0)\r
- {\r
- printf ("Could not open NDIS Protocol Manager device.\n");\r
- return (0);\r
- }\r
-\r
- memset (&reqBlock, 0, sizeof(ReqBlock));\r
-\r
- reqBlock.opcode = PM_GET_PROTOCOL_MANAGER_LINKAGE;\r
-\r
- result = NdisGetLinkage (ndisFd, (char*)&reqBlock, sizeof(ReqBlock));\r
- if (result != 0)\r
- {\r
- printf ("Could not get Protocol Manager linkage.\n");\r
- close (ndisFd);\r
- return (0);\r
- }\r
-\r
- close (ndisFd);\r
- protManEntry = (ProtMan) reqBlock.pointer1;\r
- protManDS = reqBlock.word1;\r
-\r
- DEBUG2 ("Entry Point = %04X:%04X\n", FP_SEG(protManEntry),FP_OFF(protManEntry));\r
- DEBUG1 ("ProtMan DS = %04X\n", protManDS);\r
- return (1);\r
-}\r
-\r
-\r
-int NdisRegisterAndBind (int promis)\r
-{\r
- struct _ReqBlock reqBlock;\r
- WORD result;\r
-\r
- memset (&common,0,sizeof(common));\r
-\r
- common.tableSize = sizeof (common);\r
-\r
- common.majorNdisVersion = 2;\r
- common.minorNdisVersion = 0;\r
- common.majorModuleVersion = 2;\r
- common.minorModuleVersion = 0;\r
-\r
- /* Indicates binding from below and dynamically loaded\r
- */\r
- common.moduleFlags = 0x00000006L;\r
-\r
- strcpy (common.moduleName, "PCAP");\r
-\r
- common.protocolLevelUpper = 0xFF;\r
- common.protocolLevelLower = 1;\r
- common.interfaceLower = 1;\r
-#ifdef __DJGPP__\r
- common.moduleDS = _dos_ds; /* the callback data segment */\r
-#else\r
- common.moduleDS = _DS;\r
-#endif\r
-\r
- common.systemRequest = (SystemRequest) systemRequestGlue;\r
- common.serviceChars = (BYTE*) &protChars;\r
- common.serviceStatus = NULL;\r
- common.upperDispatchTable = NULL;\r
- common.lowerDispatchTable = (BYTE*) &lowerTable;\r
-\r
- protChars.length = sizeof (protChars);\r
- protChars.name[0] = 0;\r
- protChars.type = 0;\r
-\r
- lowerTable.backPointer = &common;\r
- lowerTable.requestConfirm = requestConfirmGlue;\r
- lowerTable.transmitConfirm = transmitConfirmGlue;\r
- lowerTable.receiveLookahead = receiveLookaheadGlue;\r
- lowerTable.indicationComplete = indicationCompleteGlue;\r
- lowerTable.receiveChain = receiveChainGlue;\r
- lowerTable.status = statusGlue;\r
- lowerTable.flags = 3;\r
- if (promis)\r
- lowerTable.flags |= 4; /* promiscous mode (receive everything) */\r
-\r
- bindings.numBindings = 1;\r
- strcpy (bindings.moduleName[0], handle->moduleName);\r
-\r
- /* Register ourselves with NDIS\r
- */\r
- reqBlock.opcode = PM_REGISTER_MODULE;\r
- reqBlock.pointer1 = (BYTE FAR*) &common;\r
- reqBlock.pointer2 = (BYTE FAR*) &bindings;\r
-\r
- result = (*protManEntry) (&reqBlock, protManDS);\r
- if (result)\r
- {\r
- printf ("Protman registering failed: %s\n", Ndis_strerror(result));\r
- return (0);\r
- }\r
-\r
- /* Start the binding process\r
- */\r
- reqBlock.opcode = PM_BIND_AND_START;\r
- reqBlock.pointer1 = (BYTE FAR*) &failingModules;\r
-\r
- result = (*protManEntry) (&reqBlock, protManDS);\r
- if (result)\r
- {\r
- printf ("Start binding failed: %s\n", Ndis_strerror(result));\r
- return (0);\r
- }\r
- return (1);\r
-}\r
-\r
-static int CheckMacFeatures (CardHandle *card)\r
-{\r
- DWORD serviceFlags;\r
- BYTE _far *mediaString;\r
- BYTE _far *mac_addr;\r
-\r
- DEBUG2 ("checking card features\n"\r
- "common table address = %08lX, macId = %d\n",\r
- card->common, card->common->moduleId);\r
-\r
- serviceFlags = MAC_CHAR (handle)->serviceFlags;\r
-\r
- if ((serviceFlags & SF_PROMISCUOUS) == 0)\r
- {\r
- printf ("The MAC %s does not support promiscuous mode.\n",\r
- card->moduleName);\r
- return (0);\r
- }\r
-\r
- mediaString = MAC_CHAR (handle)->macName;\r
-\r
- DEBUG1 ("media type = %s\n",mediaString);\r
-\r
- /* Get the media type. And set the header size\r
- */\r
- if (!strncmp(mediaString,"802.3",5) ||\r
- !strncmp(mediaString,"DIX",3) ||\r
- !strncmp(mediaString,"DIX+802.3",9))\r
- headerSize = sizeof (EthernetIIHeader);\r
-\r
- else if (!strncmp(mediaString,"FDDI",4))\r
- headerSize = sizeof (FddiHeader) +\r
- sizeof (Ieee802Dot2SnapHeader);\r
- else\r
- {\r
- printf ("Unsupported MAC type: `%s'\n", mediaString);\r
- return (0);\r
- }\r
-\r
- frameSize = MAC_CHAR (handle)->maxFrameSize;\r
- mac_addr = MAC_CHAR (handle)->currentAddress;\r
-\r
- printf ("Hardware address: %02X:%02X:%02X:%02X:%02X:%02X\n",\r
- mac_addr[0], mac_addr[1], mac_addr[2],\r
- mac_addr[3], mac_addr[4], mac_addr[5]);\r
- return (1);\r
-}\r
-\r
-static int NdisStartMac (CardHandle *card)\r
-{\r
- WORD result;\r
-\r
- /* Set the lookahead length\r
- */\r
- result = MAC_DISPATCH(handle)->request (common.moduleId, 0,\r
- headerSize, 0,\r
- REQ_SET_LOOKAHEAD,\r
- card->common->moduleDS);\r
-\r
- /* We assume that if we got INVALID PARAMETER then either this\r
- * is not supported or will work anyway. NE2000 does this.\r
- */\r
- if (result != ERR_SUCCESS && result != ERR_INVALID_PARAMETER)\r
- {\r
- DEBUG1 ("Set lookahead failed: %s\n", Ndis_strerror(result));\r
- return (0);\r
- }\r
-\r
- /* Set the packet filter. Note that for some medias and drivers we\r
- * must specify all three flags or the card(s) will not operate correctly.\r
- */\r
- result = MAC_DISPATCH(handle)->request (common.moduleId, 0,\r
- /* all packets */ FILTER_PROMISCUOUS |\r
- /* packets to us */ FILTER_DIRECTED |\r
- /* broadcasts */ FILTER_BROADCAST,\r
- 0, REQ_SET_PACKET_FILTER,\r
- card->common->moduleDS);\r
- if (result != ERR_SUCCESS)\r
- {\r
- DEBUG1 ("Set packet filter failed: %s\n", Ndis_strerror(result));\r
- return (0);\r
- }\r
-\r
- /* If OPEN/CLOSE supported then open the adapter\r
- */\r
- if (MAC_CHAR(handle)->serviceFlags & SF_OPEN_CLOSE)\r
- {\r
- result = MAC_DISPATCH(handle)->request (common.moduleId, 0, 0, NULL,\r
- REQ_OPEN_ADAPTER,\r
- card->common->moduleDS);\r
- if (result != ERR_SUCCESS)\r
- {\r
- DEBUG1 ("Opening the MAC failed: %s\n", Ndis_strerror(result));\r
- return (0);\r
- }\r
- }\r
- return (1);\r
-}\r
-\r
-void NdisShutdown (void)\r
-{\r
- struct _ReqBlock reqBlock;\r
- int result, i;\r
-\r
- if (!handle)\r
- return;\r
-\r
- /* If the adapters support open and are open then close them\r
- */\r
- if ((MAC_CHAR(handle)->serviceFlags & SF_OPEN_CLOSE) &&\r
- (MAC_STATUS(handle)->macStatus & MAC_OPEN))\r
- {\r
- result = MAC_DISPATCH(handle)->request (common.moduleId, 0, 0, 0,\r
- REQ_CLOSE_ADAPTER,\r
- handle->common->moduleDS);\r
- if (result != ERR_SUCCESS)\r
- {\r
- printf ("Closing the MAC failed: %s\n", Ndis_strerror(result));\r
- return;\r
- }\r
- }\r
-\r
- /* Tell the Protocol Manager to unbind and stop\r
- */\r
- reqBlock.opcode = PM_UNBIND_AND_STOP;\r
- reqBlock.pointer1 = (BYTE FAR*) &failingModules;\r
- reqBlock.pointer2 = NULL;\r
-\r
- result = (*protManEntry) (&reqBlock, protManDS);\r
- if (result)\r
- printf ("Unbind failed: %s\n", Ndis_strerror(result));\r
-\r
- for (i = 0; i < STACK_POOL_SIZE; ++i)\r
- free (freeStacks[i] - STACK_SIZE);\r
-\r
- handle = NULL;\r
-}\r
-\r
-int NdisInit (int promis)\r
-{\r
- int i, result;\r
-\r
- /* Allocate the real mode stacks used for NDIS callbacks\r
- */\r
- for (i = 0; i < STACK_POOL_SIZE; ++i)\r
- {\r
- freeStacks[i] = malloc (STACK_SIZE);\r
- if (!freeStacks[i])\r
- return (0);\r
- freeStacks[i] += STACK_SIZE;\r
- }\r
-\r
- if (!NdisOpen())\r
- return (0);\r
-\r
- if (!NdisRegisterAndBind(promis))\r
- return (0);\r
-\r
- DEBUG1 ("My module id: %d\n", common.moduleId);\r
- DEBUG1 ("Handle id; %d\n", handle->common->moduleId);\r
- DEBUG1 ("MAC card: %-16s - ", handle->moduleName);\r
-\r
- atexit (NdisShutdown);\r
-\r
- if (!CheckMacFeatures(&handle))\r
- return (0);\r
-\r
- switch (mediaType)\r
- {\r
- case MEDIA_FDDI:\r
- DEBUG0 ("Media type: FDDI");\r
- break;\r
- case MEDIA_ETHERNET:\r
- DEBUG0 ("Media type: ETHERNET");\r
- break;\r
- default:\r
- DEBUG0 ("Unsupported media.\n");\r
- return (0);\r
- }\r
-\r
- DEBUG1 (" - Frame size: %d\n", frameSize);\r
-\r
- if (!NdisStartMac(&handle))\r
- return (0);\r
- return (1);\r
-}\r
-#endif /* USE_NDIS2 */\r
-\r
+/*
+ * Copyright (c) 1993,1994
+ * Texas A&M University. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Texas A&M University
+ * and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Developers:
+ * David K. Hess, Douglas Lee Schales, David R. Safford
+ *
+ * Heavily modified for Metaware HighC + GNU C 2.8+
+ * Gisle Vanem 1998
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dos.h>
+#include <io.h>
+#include <fcntl.h>
+#include <malloc.h>
+#include <string.h>
+
+#include "pcap-dos.h"
+#include "pcap-int.h"
+#include "msdos/ndis2.h"
+
+#if defined(USE_NDIS2)
+
+/*
+ * Packet buffer handling
+ */
+extern int FreePktBuf (PktBuf *buf);
+extern int EnquePktBuf (PktBuf *buf);
+extern PktBuf* AllocPktBuf (void);
+
+/*
+ * Various defines
+ */
+#define MAX_NUM_DEBUG_STRINGS 90
+#define DEBUG_STRING_LENGTH 80
+#define STACK_POOL_SIZE 6
+#define STACK_SIZE 256
+
+#define MEDIA_FDDI 1
+#define MEDIA_ETHERNET 2
+#define MEDIA_TOKEN 3
+
+static int startDebug = 0;
+static int stopDebug = 0;
+
+static DWORD droppedPackets = 0L;
+static WORD frameSize = 0;
+static WORD headerSize = 0;
+static int mediaType = 0;
+static char *lastErr = NULL;
+
+static BYTE debugStrings [MAX_NUM_DEBUG_STRINGS][DEBUG_STRING_LENGTH];
+static BYTE *freeStacks [STACK_POOL_SIZE];
+static int freeStackPtr = STACK_POOL_SIZE - 1;
+
+static ProtMan protManEntry = NULL;
+static WORD protManDS = 0;
+static volatile int xmitPending;
+
+static struct _PktBuf *txBufPending;
+static struct _CardHandle *handle;
+static struct _CommonChars common;
+static struct _ProtocolChars protChars;
+static struct _ProtDispatch lowerTable;
+
+static struct _FailingModules failingModules;
+static struct _BindingsList bindings;
+
+static struct {
+ WORD err_num;
+ char *err_text;
+ } ndis_errlist[] = {
+
+ { ERR_SUCCESS,
+ "The function completed successfully.\n" },
+
+ { ERR_WAIT_FOR_RELEASE,
+ "The ReceiveChain completed successfully but the protocol has\n"
+ "retained control of the buffer.\n" },
+
+ { ERR_REQUEST_QUEUED,
+ "The current request has been queued.\n" },
+
+ { ERR_FRAME_NOT_RECOGNIZED,
+ "Frame not recognized.\n" },
+
+ { ERR_FRAME_REJECTED,
+ "Frame was discarded.\n" },
+
+ { ERR_FORWARD_FRAME,
+ "Protocol wishes to forward frame to another protocol.\n" },
+
+ { ERR_OUT_OF_RESOURCE,
+ "Out of resource.\n" },
+
+ { ERR_INVALID_PARAMETER,
+ "Invalid parameter.\n" },
+
+ { ERR_INVALID_FUNCTION,
+ "Invalid function.\n" },
+
+ { ERR_NOT_SUPPORTED,
+ "Not supported.\n" },
+
+ { ERR_HARDWARE_ERROR,
+ "Hardware error.\n" },
+
+ { ERR_TRANSMIT_ERROR,
+ "The packet was not transmitted due to an error.\n" },
+
+ { ERR_NO_SUCH_DESTINATION,
+ "Token ring packet was not recognized when transmitted.\n" },
+
+ { ERR_BUFFER_TOO_SMALL,
+ "Provided buffer was too small.\n" },
+
+ { ERR_ALREADY_STARTED,
+ "Network drivers already started.\n" },
+
+ { ERR_INCOMPLETE_BINDING,
+ "Protocol driver could not complete its bindings.\n" },
+
+ { ERR_DRIVER_NOT_INITIALIZED,
+ "MAC did not initialize properly.\n" },
+
+ { ERR_HARDWARE_NOT_FOUND,
+ "Hardware not found.\n" },
+
+ { ERR_HARDWARE_FAILURE,
+ "Hardware failure.\n" },
+
+ { ERR_CONFIGURATION_FAILURE,
+ "Configuration failure.\n" },
+
+ { ERR_INTERRUPT_CONFLICT,
+ "Interrupt conflict.\n" },
+
+ { ERR_INCOMPATIBLE_MAC,
+ "The MAC is not compatible with the protocol.\n" },
+
+ { ERR_INITIALIZATION_FAILED,
+ "Initialization failed.\n" },
+
+ { ERR_NO_BINDING,
+ "Binding did not occur.\n" },
+
+ { ERR_NETWORK_MAY_NOT_BE_CONNECTED,
+ "The network may not be connected to the adapter.\n" },
+
+ { ERR_INCOMPATIBLE_OS_VERSION,
+ "The version of the operating system is incompatible with the protocol.\n" },
+
+ { ERR_ALREADY_REGISTERED,
+ "The protocol is already registered.\n" },
+
+ { ERR_PATH_NOT_FOUND,
+ "PROTMAN.EXE could not be found.\n" },
+
+ { ERR_INSUFFICIENT_MEMORY,
+ "Insufficient memory.\n" },
+
+ { ERR_INFO_NOT_FOUND,
+ "Protocol Mananger info structure is lost or corrupted.\n" },
+
+ { ERR_GENERAL_FAILURE,
+ "General failure.\n" }
+};
+
+/*
+ * Some handy macros
+ */
+#define PERROR(str) printf("%s (%d): %s\n", __FILE__,__LINE__,str)
+#define DEBUG_RING() (debugStrings[stopDebug+1 == MAX_NUM_DEBUG_STRINGS ? \
+ stopDebug = 0 : ++stopDebug])
+
+/*
+ * needs rewrite for DOSX
+ */
+#define MAC_DISPATCH(hnd) ((struct _MacUpperDispatch*)(hnd)->common->upperDispatchTable)
+#define MAC_STATUS(hnd) ((struct _MacStatusTable*) (hnd)->common->serviceStatus)
+#define MAC_CHAR(hnd) ((struct _MacChars*) (hnd)->common->serviceChars)
+
+#ifdef NDIS_DEBUG
+ #define DEBUG0(str) printf (str)
+ #define DEBUG1(fmt,a) printf (fmt,a)
+ #define DEBUG2(fmt,a,b) printf (fmt,a,b)
+ #define TRACE0(str) sprintf (DEBUG_RING(),str)
+ #define TRACE1(fmt,a) sprintf (DEBUG_RING(),fmt,a)
+#else
+ #define DEBUG0(str) ((void)0)
+ #define DEBUG1(fmt,a) ((void)0)
+ #define DEBUG2(fmt,a,b) ((void)0)
+ #define TRACE0(str) ((void)0)
+ #define TRACE1(fmt,a) ((void)0)
+#endif
+
+/*
+ * This routine is called from both threads
+ */
+void NdisFreeStack (BYTE *aStack)
+{
+ GUARD();
+
+ if (freeStackPtr == STACK_POOL_SIZE - 1)
+ PERROR ("tried to free too many stacks");
+
+ freeStacks[++freeStackPtr] = aStack;
+
+ if (freeStackPtr == 0)
+ TRACE0 ("freeStackPtr went positive\n");
+
+ UNGUARD();
+}
+
+/*
+ * This routine is called from callbacks to allocate local data
+ */
+BYTE *NdisAllocStack (void)
+{
+ BYTE *stack;
+
+ GUARD();
+
+ if (freeStackPtr < 0)
+ {
+ /* Ran out of stack buffers. Return NULL which will start
+ * dropping packets
+ */
+ TRACE0 ("freeStackPtr went negative\n");
+ stack = 0;
+ }
+ else
+ stack = freeStacks[freeStackPtr--];
+
+ UNGUARD();
+ return (stack);
+}
+
+CALLBACK (NdisSystemRequest (DWORD param1, DWORD param2, WORD param3,
+ WORD opcode, WORD targetDS))
+{
+ static int bindEntry = 0;
+ struct _CommonChars *macCommon;
+ volatile WORD result;
+
+ switch (opcode)
+ {
+ case REQ_INITIATE_BIND:
+ macCommon = (struct _CommonChars*) param2;
+ if (macCommon == NULL)
+ {
+ printf ("There is an NDIS misconfiguration.\n");
+ result = ERR_GENERAL_FAILURE;
+ break;
+ }
+ DEBUG2 ("module name %s\n"
+ "module type %s\n",
+ macCommon->moduleName,
+ ((MacChars*) macCommon->serviceChars)->macName);
+
+ /* Binding to the MAC */
+ result = macCommon->systemRequest ((DWORD)&common, (DWORD)&macCommon,
+ 0, REQ_BIND,
+ macCommon->moduleDS);
+
+ if (!strcmp(bindings.moduleName[bindEntry], handle->moduleName))
+ handle->common = macCommon;
+ else PERROR ("unknown module");
+ ++bindEntry;
+ break;
+
+ case REQ_INITIATE_UNBIND:
+ macCommon = (struct _CommonChars*) param2;
+ result = macCommon->systemRequest ((DWORD)&common, 0,
+ 0, REQ_UNBIND,
+ macCommon->moduleDS);
+ break;
+
+ default:
+ result = ERR_GENERAL_FAILURE;
+ break;
+ }
+ ARGSUSED (param1);
+ ARGSUSED (param3);
+ ARGSUSED (targetDS);
+ return (result);
+}
+
+CALLBACK (NdisRequestConfirm (WORD protId, WORD macId, WORD reqHandle,
+ WORD status, WORD request, WORD protDS))
+{
+ ARGSUSED (protId); ARGSUSED (macId);
+ ARGSUSED (reqHandle); ARGSUSED (status);
+ ARGSUSED (request); ARGSUSED (protDS);
+ return (ERR_SUCCESS);
+}
+
+CALLBACK (NdisTransmitConfirm (WORD protId, WORD macId, WORD reqHandle,
+ WORD status, WORD protDS))
+{
+ xmitPending--;
+ FreePktBuf (txBufPending); /* Add passed ECB back to the free list */
+
+ ARGSUSED (reqHandle);
+ ARGSUSED (status);
+ ARGSUSED (protDS);
+ return (ERR_SUCCESS);
+}
+
+
+/*
+ * The primary function for receiving packets
+ */
+CALLBACK (NdisReceiveLookahead (WORD macId, WORD frameSize,
+ WORD bytesAvail, BYTE *buffer,
+ BYTE *indicate, WORD protDS))
+{
+ int result;
+ PktBuf *pktBuf;
+ WORD bytesCopied;
+ struct _TDBufDescr tDBufDescr;
+
+#if 0
+ TRACE1 ("lookahead length = %d, ", bytesAvail);
+ TRACE1 ("ecb = %08lX, ", *ecb);
+ TRACE1 ("count = %08lX\n", count);
+ TRACE1 ("offset = %08lX, ", offset);
+ TRACE1 ("timesAllowed = %d, ", timesAllowed);
+ TRACE1 ("packet size = %d\n", look->dataLookAheadLen);
+#endif
+
+ /* Allocate a buffer for the packet
+ */
+ if ((pktBuf = AllocPktBuf()) == NULL)
+ {
+ droppedPackets++;
+ return (ERR_FRAME_REJECTED);
+ }
+
+ /*
+ * Now kludge things. Note we will have to undo this later. This will
+ * make the packet contiguous after the MLID has done the requested copy.
+ */
+
+ tDBufDescr.tDDataCount = 1;
+ tDBufDescr.tDBufDescrRec[0].tDPtrType = NDIS_PTR_PHYSICAL;
+ tDBufDescr.tDBufDescrRec[0].tDDataPtr = pktBuf->buffer;
+ tDBufDescr.tDBufDescrRec[0].tDDataLen = pktBuf->length;
+ tDBufDescr.tDBufDescrRec[0].dummy = 0;
+
+ result = MAC_DISPATCH(handle)->transferData (&bytesCopied, 0, &tDBufDescr,
+ handle->common->moduleDS);
+ pktBuf->packetLength = bytesCopied;
+
+ if (result == ERR_SUCCESS)
+ EnquePktBuf(pktBuf);
+ else FreePktBuf (pktBuf);
+
+ ARGSUSED (frameSize);
+ ARGSUSED (bytesAvail);
+ ARGSUSED (indicate);
+ ARGSUSED (protDS);
+
+ return (ERR_SUCCESS);
+}
+
+CALLBACK (NdisIndicationComplete (WORD macId, WORD protDS))
+{
+ ARGSUSED (macId);
+ ARGSUSED (protDS);
+
+ /* We don't give a hoot about these. Just return
+ */
+ return (ERR_SUCCESS);
+}
+
+/*
+ * This is the OTHER way we may receive packets
+ */
+CALLBACK (NdisReceiveChain (WORD macId, WORD frameSize, WORD reqHandle,
+ struct _RxBufDescr *rxBufDescr,
+ BYTE *indicate, WORD protDS))
+{
+ struct _PktBuf *pktBuf;
+ int i;
+
+ /*
+ * For now we copy the entire packet over to a PktBuf structure. This may be
+ * a performance hit but this routine probably isn't called very much, and
+ * it is a lot of work to do it otherwise. Also if it is a filter protocol
+ * packet we could end up sucking up MAC buffes.
+ */
+
+ if ((pktBuf = AllocPktBuf()) == NULL)
+ {
+ droppedPackets++;
+ return (ERR_FRAME_REJECTED);
+ }
+ pktBuf->packetLength = 0;
+
+ /* Copy the packet to the buffer
+ */
+ for (i = 0; i < rxBufDescr->rxDataCount; ++i)
+ {
+ struct _RxBufDescrRec *rxDescr = &rxBufDescr->rxBufDescrRec[i];
+
+ memcpy (pktBuf->buffer + pktBuf->packetLength,
+ rxDescr->rxDataPtr, rxDescr->rxDataLen);
+ pktBuf->packetLength += rxDescr->rxDataLen;
+ }
+
+ EnquePktBuf (pktBuf);
+
+ ARGSUSED (frameSize);
+ ARGSUSED (reqHandle);
+ ARGSUSED (indicate);
+ ARGSUSED (protDS);
+
+ /* This frees up the buffer for the MAC to use
+ */
+ return (ERR_SUCCESS);
+}
+
+CALLBACK (NdisStatusProc (WORD macId, WORD param1, BYTE *indicate,
+ WORD opcode, WORD protDS))
+{
+ switch (opcode)
+ {
+ case STATUS_RING_STATUS:
+ break;
+ case STATUS_ADAPTER_CHECK:
+ break;
+ case STATUS_START_RESET:
+ break;
+ case STATUS_INTERRUPT:
+ break;
+ case STATUS_END_RESET:
+ break;
+ default:
+ break;
+ }
+ ARGSUSED (macId);
+ ARGSUSED (param1);
+ ARGSUSED (indicate);
+ ARGSUSED (opcode);
+ ARGSUSED (protDS);
+
+ /* We don't need to do anything about this stuff yet
+ */
+ return (ERR_SUCCESS);
+}
+
+/*
+ * Tell the NDIS driver to start the delivery of the packet
+ */
+int NdisSendPacket (struct _PktBuf *pktBuf, int macId)
+{
+ struct _TxBufDescr txBufDescr;
+ int result;
+
+ xmitPending++;
+ txBufPending = pktBuf; /* we only have 1 pending Tx at a time */
+
+ txBufDescr.txImmedLen = 0;
+ txBufDescr.txImmedPtr = NULL;
+ txBufDescr.txDataCount = 1;
+ txBufDescr.txBufDescrRec[0].txPtrType = NDIS_PTR_PHYSICAL;
+ txBufDescr.txBufDescrRec[0].dummy = 0;
+ txBufDescr.txBufDescrRec[0].txDataLen = pktBuf->packetLength;
+ txBufDescr.txBufDescrRec[0].txDataPtr = pktBuf->buffer;
+
+ result = MAC_DISPATCH(handle)->transmitChain (common.moduleId,
+ pktBuf->handle,
+ &txBufDescr,
+ handle->common->moduleDS);
+ switch (result)
+ {
+ case ERR_OUT_OF_RESOURCE:
+ /* Note that this should not happen but if it does there is not
+ * much we can do about it
+ */
+ printf ("ERROR: transmit queue overflowed\n");
+ return (0);
+
+ case ERR_SUCCESS:
+ /* Everything was hunky dory and synchronous. Free up the
+ * packet buffer
+ */
+ xmitPending--;
+ FreePktBuf (pktBuf);
+ return (1);
+
+ case ERR_REQUEST_QUEUED:
+ /* Everything was hunky dory and asynchronous. Do nothing
+ */
+ return (1);
+
+ default:
+ printf ("Tx fail, code = %04X\n", result);
+ return (0);
+ }
+}
+
+
+
+static int ndis_nerr = sizeof(ndis_errlist) / sizeof(ndis_errlist[0]);
+
+static char *Ndis_strerror (WORD errorCode)
+{
+ static char buf[30];
+ int i;
+
+ for (i = 0; i < ndis_nerr; i++)
+ if (errorCode == ndis_errlist[i].err_num)
+ return (ndis_errlist[i].err_text);
+
+ sprintf (buf,"unknown error %d",errorCode);
+ return (buf);
+}
+
+
+char *NdisLastError (void)
+{
+ char *errStr = lastErr;
+ lastErr = NULL;
+ return (errStr);
+}
+
+int NdisOpen (void)
+{
+ struct _ReqBlock reqBlock;
+ int result;
+ int ndisFd = open (NDIS_PATH, O_RDONLY);
+
+ if (ndisFd < 0)
+ {
+ printf ("Could not open NDIS Protocol Manager device.\n");
+ return (0);
+ }
+
+ memset (&reqBlock, 0, sizeof(ReqBlock));
+
+ reqBlock.opcode = PM_GET_PROTOCOL_MANAGER_LINKAGE;
+
+ result = NdisGetLinkage (ndisFd, (char*)&reqBlock, sizeof(ReqBlock));
+ if (result != 0)
+ {
+ printf ("Could not get Protocol Manager linkage.\n");
+ close (ndisFd);
+ return (0);
+ }
+
+ close (ndisFd);
+ protManEntry = (ProtMan) reqBlock.pointer1;
+ protManDS = reqBlock.word1;
+
+ DEBUG2 ("Entry Point = %04X:%04X\n", FP_SEG(protManEntry),FP_OFF(protManEntry));
+ DEBUG1 ("ProtMan DS = %04X\n", protManDS);
+ return (1);
+}
+
+
+int NdisRegisterAndBind (int promis)
+{
+ struct _ReqBlock reqBlock;
+ WORD result;
+
+ memset (&common,0,sizeof(common));
+
+ common.tableSize = sizeof (common);
+
+ common.majorNdisVersion = 2;
+ common.minorNdisVersion = 0;
+ common.majorModuleVersion = 2;
+ common.minorModuleVersion = 0;
+
+ /* Indicates binding from below and dynamically loaded
+ */
+ common.moduleFlags = 0x00000006L;
+
+ strcpy (common.moduleName, "PCAP");
+
+ common.protocolLevelUpper = 0xFF;
+ common.protocolLevelLower = 1;
+ common.interfaceLower = 1;
+#ifdef __DJGPP__
+ common.moduleDS = _dos_ds; /* the callback data segment */
+#else
+ common.moduleDS = _DS;
+#endif
+
+ common.systemRequest = (SystemRequest) systemRequestGlue;
+ common.serviceChars = (BYTE*) &protChars;
+ common.serviceStatus = NULL;
+ common.upperDispatchTable = NULL;
+ common.lowerDispatchTable = (BYTE*) &lowerTable;
+
+ protChars.length = sizeof (protChars);
+ protChars.name[0] = 0;
+ protChars.type = 0;
+
+ lowerTable.backPointer = &common;
+ lowerTable.requestConfirm = requestConfirmGlue;
+ lowerTable.transmitConfirm = transmitConfirmGlue;
+ lowerTable.receiveLookahead = receiveLookaheadGlue;
+ lowerTable.indicationComplete = indicationCompleteGlue;
+ lowerTable.receiveChain = receiveChainGlue;
+ lowerTable.status = statusGlue;
+ lowerTable.flags = 3;
+ if (promis)
+ lowerTable.flags |= 4; /* promiscous mode (receive everything) */
+
+ bindings.numBindings = 1;
+ strcpy (bindings.moduleName[0], handle->moduleName);
+
+ /* Register ourselves with NDIS
+ */
+ reqBlock.opcode = PM_REGISTER_MODULE;
+ reqBlock.pointer1 = (BYTE FAR*) &common;
+ reqBlock.pointer2 = (BYTE FAR*) &bindings;
+
+ result = (*protManEntry) (&reqBlock, protManDS);
+ if (result)
+ {
+ printf ("Protman registering failed: %s\n", Ndis_strerror(result));
+ return (0);
+ }
+
+ /* Start the binding process
+ */
+ reqBlock.opcode = PM_BIND_AND_START;
+ reqBlock.pointer1 = (BYTE FAR*) &failingModules;
+
+ result = (*protManEntry) (&reqBlock, protManDS);
+ if (result)
+ {
+ printf ("Start binding failed: %s\n", Ndis_strerror(result));
+ return (0);
+ }
+ return (1);
+}
+
+static int CheckMacFeatures (CardHandle *card)
+{
+ DWORD serviceFlags;
+ BYTE _far *mediaString;
+ BYTE _far *mac_addr;
+
+ DEBUG2 ("checking card features\n"
+ "common table address = %08lX, macId = %d\n",
+ card->common, card->common->moduleId);
+
+ serviceFlags = MAC_CHAR (handle)->serviceFlags;
+
+ if ((serviceFlags & SF_PROMISCUOUS) == 0)
+ {
+ printf ("The MAC %s does not support promiscuous mode.\n",
+ card->moduleName);
+ return (0);
+ }
+
+ mediaString = MAC_CHAR (handle)->macName;
+
+ DEBUG1 ("media type = %s\n",mediaString);
+
+ /* Get the media type. And set the header size
+ */
+ if (!strncmp(mediaString,"802.3",5) ||
+ !strncmp(mediaString,"DIX",3) ||
+ !strncmp(mediaString,"DIX+802.3",9))
+ headerSize = sizeof (EthernetIIHeader);
+
+ else if (!strncmp(mediaString,"FDDI",4))
+ headerSize = sizeof (FddiHeader) +
+ sizeof (Ieee802Dot2SnapHeader);
+ else
+ {
+ printf ("Unsupported MAC type: `%s'\n", mediaString);
+ return (0);
+ }
+
+ frameSize = MAC_CHAR (handle)->maxFrameSize;
+ mac_addr = MAC_CHAR (handle)->currentAddress;
+
+ printf ("Hardware address: %02X:%02X:%02X:%02X:%02X:%02X\n",
+ mac_addr[0], mac_addr[1], mac_addr[2],
+ mac_addr[3], mac_addr[4], mac_addr[5]);
+ return (1);
+}
+
+static int NdisStartMac (CardHandle *card)
+{
+ WORD result;
+
+ /* Set the lookahead length
+ */
+ result = MAC_DISPATCH(handle)->request (common.moduleId, 0,
+ headerSize, 0,
+ REQ_SET_LOOKAHEAD,
+ card->common->moduleDS);
+
+ /* We assume that if we got INVALID PARAMETER then either this
+ * is not supported or will work anyway. NE2000 does this.
+ */
+ if (result != ERR_SUCCESS && result != ERR_INVALID_PARAMETER)
+ {
+ DEBUG1 ("Set lookahead failed: %s\n", Ndis_strerror(result));
+ return (0);
+ }
+
+ /* Set the packet filter. Note that for some medias and drivers we
+ * must specify all three flags or the card(s) will not operate correctly.
+ */
+ result = MAC_DISPATCH(handle)->request (common.moduleId, 0,
+ /* all packets */ FILTER_PROMISCUOUS |
+ /* packets to us */ FILTER_DIRECTED |
+ /* broadcasts */ FILTER_BROADCAST,
+ 0, REQ_SET_PACKET_FILTER,
+ card->common->moduleDS);
+ if (result != ERR_SUCCESS)
+ {
+ DEBUG1 ("Set packet filter failed: %s\n", Ndis_strerror(result));
+ return (0);
+ }
+
+ /* If OPEN/CLOSE supported then open the adapter
+ */
+ if (MAC_CHAR(handle)->serviceFlags & SF_OPEN_CLOSE)
+ {
+ result = MAC_DISPATCH(handle)->request (common.moduleId, 0, 0, NULL,
+ REQ_OPEN_ADAPTER,
+ card->common->moduleDS);
+ if (result != ERR_SUCCESS)
+ {
+ DEBUG1 ("Opening the MAC failed: %s\n", Ndis_strerror(result));
+ return (0);
+ }
+ }
+ return (1);
+}
+
+void NdisShutdown (void)
+{
+ struct _ReqBlock reqBlock;
+ int result, i;
+
+ if (!handle)
+ return;
+
+ /* If the adapters support open and are open then close them
+ */
+ if ((MAC_CHAR(handle)->serviceFlags & SF_OPEN_CLOSE) &&
+ (MAC_STATUS(handle)->macStatus & MAC_OPEN))
+ {
+ result = MAC_DISPATCH(handle)->request (common.moduleId, 0, 0, 0,
+ REQ_CLOSE_ADAPTER,
+ handle->common->moduleDS);
+ if (result != ERR_SUCCESS)
+ {
+ printf ("Closing the MAC failed: %s\n", Ndis_strerror(result));
+ return;
+ }
+ }
+
+ /* Tell the Protocol Manager to unbind and stop
+ */
+ reqBlock.opcode = PM_UNBIND_AND_STOP;
+ reqBlock.pointer1 = (BYTE FAR*) &failingModules;
+ reqBlock.pointer2 = NULL;
+
+ result = (*protManEntry) (&reqBlock, protManDS);
+ if (result)
+ printf ("Unbind failed: %s\n", Ndis_strerror(result));
+
+ for (i = 0; i < STACK_POOL_SIZE; ++i)
+ free (freeStacks[i] - STACK_SIZE);
+
+ handle = NULL;
+}
+
+int NdisInit (int promis)
+{
+ int i, result;
+
+ /* Allocate the real mode stacks used for NDIS callbacks
+ */
+ for (i = 0; i < STACK_POOL_SIZE; ++i)
+ {
+ freeStacks[i] = malloc (STACK_SIZE);
+ if (!freeStacks[i])
+ return (0);
+ freeStacks[i] += STACK_SIZE;
+ }
+
+ if (!NdisOpen())
+ return (0);
+
+ if (!NdisRegisterAndBind(promis))
+ return (0);
+
+ DEBUG1 ("My module id: %d\n", common.moduleId);
+ DEBUG1 ("Handle id; %d\n", handle->common->moduleId);
+ DEBUG1 ("MAC card: %-16s - ", handle->moduleName);
+
+ atexit (NdisShutdown);
+
+ if (!CheckMacFeatures(&handle))
+ return (0);
+
+ switch (mediaType)
+ {
+ case MEDIA_FDDI:
+ DEBUG0 ("Media type: FDDI");
+ break;
+ case MEDIA_ETHERNET:
+ DEBUG0 ("Media type: ETHERNET");
+ break;
+ default:
+ DEBUG0 ("Unsupported media.\n");
+ return (0);
+ }
+
+ DEBUG1 (" - Frame size: %d\n", frameSize);
+
+ if (!NdisStartMac(&handle))
+ return (0);
+ return (1);
+}
+#endif /* USE_NDIS2 */
+
-/* \r
- * Copyright (c) 1993,1994\r
- * Texas A&M University. All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- * 1. Redistributions of source code must retain the above copyright\r
- * notice, this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the\r
- * documentation and/or other materials provided with the distribution.\r
- * 3. All advertising materials mentioning features or use of this software\r
- * must display the following acknowledgement:\r
- * This product includes software developed by Texas A&M University\r
- * and its contributors.\r
- * 4. Neither the name of the University nor the names of its contributors\r
- * may be used to endorse or promote products derived from this software\r
- * without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND\r
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE\r
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
- * SUCH DAMAGE.\r
- *\r
- * Developers:\r
- * David K. Hess, Douglas Lee Schales, David R. Safford\r
- *\r
- * Heavily modified for Metaware HighC + GNU C 2.8+\r
- * Gisle Vanem 1998\r
- */\r
-\r
-#ifndef __PCAP_NDIS_H\r
-#define __PCAP_NDIS_H\r
-\r
-#if defined (__HIGHC__)\r
- #define pascal _CC(_CALLEE_POPS_STACK & ~_REVERSE_PARMS) /* calling convention */\r
- #define CALLBACK(foo) pascal WORD foo\r
- #define PAS_PTR(x,arg) typedef FAR WORD pascal (*x) arg\r
- #define GUARD() _inline (0x9C,0xFA) /* pushfd, cli */\r
- #define UNGUARD() _inline (0x9D) /* popfd */\r
- #define FAR _far\r
-\r
-#elif defined(__GNUC__)\r
- #define CALLBACK(foo) WORD foo __attribute__((stdcall))\r
- #define PAS_PTR(x,arg) typedef WORD (*x) arg __attribute__((stdcall))\r
- #define GUARD() __asm__ __volatile__ ("pushfd; cli")\r
- #define UNGUARD() __asm__ __volatile__ ("popfd")\r
- #define FAR\r
-\r
-#elif defined (__TURBOC__)\r
- #define CALLBACK(foo) WORD pascal foo\r
- #define PAS_PTR(x,arg) typedef WORD pascal (_far *x) arg\r
- #define GUARD() _asm { pushf; cli }\r
- #define UNGUARD() _asm { popf }\r
- #define FAR _far\r
-\r
-#elif defined (__WATCOMC__)\r
- #define CALLBACK(foo) WORD pascal foo\r
- #define PAS_PTR(x,arg) typedef WORD pascal (_far *x) arg\r
- #define GUARD() _disable()\r
- #define UNGUARD() _enable()\r
- #define FAR _far\r
-\r
-#else\r
- #error Unsupported compiler\r
-#endif\r
-\r
-\r
-/*\r
- * Forwards\r
- */\r
-struct _ReqBlock;\r
-struct _TxBufDescr;\r
-struct _TDBufDescr;\r
-\r
-/*\r
- * Protocol Manager API\r
- */\r
-PAS_PTR (ProtMan, (struct _ReqBlock FAR*, WORD));\r
-\r
-/*\r
- * System request\r
- */\r
-PAS_PTR (SystemRequest, (DWORD, DWORD, WORD, WORD, WORD));\r
-\r
-/*\r
- * MAC API\r
- */\r
-PAS_PTR (TransmitChain, (WORD, WORD, struct _TxBufDescr FAR*, WORD));\r
-PAS_PTR (TransferData, (WORD*,WORD, struct _TDBufDescr FAR*, WORD));\r
-PAS_PTR (Request, (WORD, WORD, WORD, DWORD, WORD, WORD));\r
-PAS_PTR (ReceiveRelease,(WORD, WORD));\r
-PAS_PTR (IndicationOn, (WORD));\r
-PAS_PTR (IndicationOff, (WORD));\r
-\r
-\r
-typedef enum {\r
- HARDWARE_NOT_INSTALLED = 0,\r
- HARDWARE_FAILED_DIAG = 1,\r
- HARDWARE_FAILED_CONFIG = 2,\r
- HARDWARE_HARD_FAULT = 3,\r
- HARDWARE_SOFT_FAULT = 4,\r
- HARDWARE_OK = 7,\r
- HARDWARE_MASK = 0x0007,\r
- MAC_BOUND = 0x0008,\r
- MAC_OPEN = 0x0010,\r
- DIAG_IN_PROGRESS = 0x0020\r
- } NdisMacStatus;\r
-\r
-typedef enum {\r
- STATUS_RING_STATUS = 1,\r
- STATUS_ADAPTER_CHECK = 2,\r
- STATUS_START_RESET = 3,\r
- STATUS_INTERRUPT = 4,\r
- STATUS_END_RESET = 5\r
- } NdisStatus;\r
-\r
-typedef enum {\r
- FILTER_DIRECTED = 1,\r
- FILTER_BROADCAST = 2,\r
- FILTER_PROMISCUOUS = 4,\r
- FILTER_SOURCE_ROUTE = 8\r
- } NdisPacketFilter;\r
-\r
-typedef enum {\r
- REQ_INITIATE_DIAGNOSTICS = 1,\r
- REQ_READ_ERROR_LOG = 2,\r
- REQ_SET_STATION_ADDRESS = 3,\r
- REQ_OPEN_ADAPTER = 4,\r
- REQ_CLOSE_ADAPTER = 5,\r
- REQ_RESET_MAC = 6,\r
- REQ_SET_PACKET_FILTER = 7,\r
- REQ_ADD_MULTICAST_ADDRESS = 8,\r
- REQ_DELETE_MULTICAST_ADDRESS = 9,\r
- REQ_UPDATE_STATISTICS = 10,\r
- REQ_CLEAR_STATISTICS = 11,\r
- REQ_INTERRUPT_REQUEST = 12,\r
- REQ_SET_FUNCTIONAL_ADDRESS = 13,\r
- REQ_SET_LOOKAHEAD = 14\r
- } NdisGeneralRequest;\r
-\r
-typedef enum {\r
- SF_BROADCAST = 0x00000001L,\r
- SF_MULTICAST = 0x00000002L,\r
- SF_FUNCTIONAL = 0x00000004L,\r
- SF_PROMISCUOUS = 0x00000008L,\r
- SF_SOFT_ADDRESS = 0x00000010L,\r
- SF_STATS_CURRENT = 0x00000020L,\r
- SF_INITIATE_DIAGS = 0x00000040L,\r
- SF_LOOPBACK = 0x00000080L,\r
- SF_RECEIVE_CHAIN = 0x00000100L,\r
- SF_SOURCE_ROUTING = 0x00000200L,\r
- SF_RESET_MAC = 0x00000400L,\r
- SF_OPEN_CLOSE = 0x00000800L,\r
- SF_INTERRUPT_REQUEST = 0x00001000L,\r
- SF_SOURCE_ROUTING_BRIDGE = 0x00002000L,\r
- SF_VIRTUAL_ADDRESSES = 0x00004000L\r
- } NdisMacServiceFlags;\r
-\r
-typedef enum {\r
- REQ_INITIATE_BIND = 1,\r
- REQ_BIND = 2,\r
- REQ_INITIATE_PREBIND = 3,\r
- REQ_INITIATE_UNBIND = 4,\r
- REQ_UNBIND = 5\r
- } NdisSysRequest;\r
-\r
-typedef enum {\r
- PM_GET_PROTOCOL_MANAGER_INFO = 1,\r
- PM_REGISTER_MODULE = 2,\r
- PM_BIND_AND_START = 3,\r
- PM_GET_PROTOCOL_MANAGER_LINKAGE = 4,\r
- PM_GET_PROTOCOL_INI_PATH = 5,\r
- PM_REGISTER_PROTOCOL_MANAGER_INFO = 6,\r
- PM_INIT_AND_REGISTER = 7,\r
- PM_UNBIND_AND_STOP = 8,\r
- PM_BIND_STATUS = 9,\r
- PM_REGISTER_STATUS = 10\r
- } NdisProtManager;\r
-\r
-\r
-typedef enum {\r
- ERR_SUCCESS = 0x00,\r
- ERR_WAIT_FOR_RELEASE = 0x01,\r
- ERR_REQUEST_QUEUED = 0x02,\r
- ERR_FRAME_NOT_RECOGNIZED = 0x03,\r
- ERR_FRAME_REJECTED = 0x04,\r
- ERR_FORWARD_FRAME = 0x05,\r
- ERR_OUT_OF_RESOURCE = 0x06,\r
- ERR_INVALID_PARAMETER = 0x07,\r
- ERR_INVALID_FUNCTION = 0x08,\r
- ERR_NOT_SUPPORTED = 0x09,\r
- ERR_HARDWARE_ERROR = 0x0A,\r
- ERR_TRANSMIT_ERROR = 0x0B,\r
- ERR_NO_SUCH_DESTINATION = 0x0C,\r
- ERR_BUFFER_TOO_SMALL = 0x0D,\r
- ERR_ALREADY_STARTED = 0x20,\r
- ERR_INCOMPLETE_BINDING = 0x21,\r
- ERR_DRIVER_NOT_INITIALIZED = 0x22,\r
- ERR_HARDWARE_NOT_FOUND = 0x23,\r
- ERR_HARDWARE_FAILURE = 0x24,\r
- ERR_CONFIGURATION_FAILURE = 0x25,\r
- ERR_INTERRUPT_CONFLICT = 0x26,\r
- ERR_INCOMPATIBLE_MAC = 0x27,\r
- ERR_INITIALIZATION_FAILED = 0x28,\r
- ERR_NO_BINDING = 0x29,\r
- ERR_NETWORK_MAY_NOT_BE_CONNECTED = 0x2A,\r
- ERR_INCOMPATIBLE_OS_VERSION = 0x2B,\r
- ERR_ALREADY_REGISTERED = 0x2C,\r
- ERR_PATH_NOT_FOUND = 0x2D,\r
- ERR_INSUFFICIENT_MEMORY = 0x2E,\r
- ERR_INFO_NOT_FOUND = 0x2F,\r
- ERR_GENERAL_FAILURE = 0xFF\r
- } NdisError;\r
-\r
-#define NDIS_PARAM_INTEGER 0\r
-#define NDIS_PARAM_STRING 1\r
-\r
-#define NDIS_TX_BUF_LENGTH 8\r
-#define NDIS_TD_BUF_LENGTH 1\r
-#define NDIS_RX_BUF_LENGTH 8\r
-\r
-#define NDIS_PTR_PHYSICAL 0\r
-#define NDIS_PTR_VIRTUAL 2\r
-\r
-#define NDIS_PATH "PROTMAN$"\r
-\r
-\r
-typedef struct _CommonChars {\r
- WORD tableSize;\r
- BYTE majorNdisVersion; /* 2 - Latest version */\r
- BYTE minorNdisVersion; /* 0 */\r
- WORD reserved1;\r
- BYTE majorModuleVersion;\r
- BYTE minorModuleVersion;\r
- DWORD moduleFlags;\r
- /* 0 - Binding at upper boundary supported\r
- * 1 - Binding at lower boundary supported\r
- * 2 - Dynamically bound.\r
- * 3-31 - Reserved, must be zero.\r
- */\r
- BYTE moduleName[16];\r
- BYTE protocolLevelUpper;\r
- /* 1 - MAC\r
- * 2 - Data Link\r
- * 3 - Network\r
- * 4 - Transport\r
- * 5 - Session\r
- * -1 - Not specified\r
- */\r
- BYTE interfaceUpper;\r
- BYTE protocolLevelLower;\r
- /* 0 - Physical\r
- * 1 - MAC\r
- * 2 - Data Link\r
- * 3 - Network\r
- * 4 - Transport\r
- * 5 - Session\r
- * -1 - Not specified\r
- */\r
- BYTE interfaceLower;\r
- WORD moduleId;\r
- WORD moduleDS;\r
- SystemRequest systemRequest;\r
- BYTE *serviceChars;\r
- BYTE *serviceStatus;\r
- BYTE *upperDispatchTable;\r
- BYTE *lowerDispatchTable;\r
- BYTE *reserved2; /* Must be NULL */\r
- BYTE *reserved3; /* Must be NULL */\r
- } CommonChars;\r
-\r
-\r
-typedef struct _MulticastList {\r
- WORD maxMulticastAddresses;\r
- WORD numberMulticastAddresses;\r
- BYTE multicastAddress[16][16];\r
- } MulticastList;\r
-\r
-\r
-typedef struct _MacChars {\r
- WORD tableSize;\r
- BYTE macName[16];\r
- WORD addressLength;\r
- BYTE permanentAddress[16];\r
- BYTE currentAddress[16];\r
- DWORD currentFunctionalAddress;\r
- MulticastList *multicastList;\r
- DWORD linkSpeed;\r
- DWORD serviceFlags;\r
- WORD maxFrameSize;\r
- DWORD txBufferSize;\r
- WORD txBufferAllocSize;\r
- DWORD rxBufferSize;\r
- WORD rxBufferAllocSize;\r
- BYTE ieeeVendor[3];\r
- BYTE vendorAdapter;\r
- BYTE *vendorAdapterDescription;\r
- WORD interruptLevel;\r
- WORD txQueueDepth;\r
- WORD maxDataBlocks;\r
- } MacChars;\r
-\r
-\r
-typedef struct _ProtocolChars {\r
- WORD length;\r
- BYTE name[16];\r
- WORD type;\r
- } ProtocolChars;\r
-\r
-\r
-typedef struct _MacUpperDispatch {\r
- CommonChars *backPointer;\r
- Request request;\r
- TransmitChain transmitChain;\r
- TransferData transferData;\r
- ReceiveRelease receiveRelease;\r
- IndicationOn indicationOn;\r
- IndicationOff indicationOff;\r
- } MacUpperDispatch;\r
-\r
-\r
-typedef struct _MacStatusTable {\r
- WORD tableSize;\r
- DWORD lastDiag;\r
- DWORD macStatus;\r
- WORD packetFilter;\r
- BYTE *mediaSpecificStats;\r
- DWORD lastClear;\r
- DWORD totalFramesRx;\r
- DWORD totalFramesCrc;\r
- DWORD totalBytesRx;\r
- DWORD totalDiscardBufSpaceRx;\r
- DWORD totalMulticastRx;\r
- DWORD totalBroadcastRx;\r
- DWORD obsolete1[5];\r
- DWORD totalDiscardHwErrorRx;\r
- DWORD totalFramesTx;\r
- DWORD totalBytesTx;\r
- DWORD totalMulticastTx;\r
- DWORD totalBroadcastTx;\r
- DWORD obsolete2[2];\r
- DWORD totalDiscardTimeoutTx;\r
- DWORD totalDiscardHwErrorTx;\r
- } MacStatusTable;\r
-\r
-\r
-typedef struct _ProtDispatch {\r
- CommonChars *backPointer;\r
- DWORD flags;\r
- /* 0 - handles non-LLC frames\r
- * 1 - handles specific-LSAP LLC frames\r
- * 2 - handles specific-LSAP LLC frames\r
- * 3-31 - reserved must be 0\r
- */\r
- void (*requestConfirm) (void);\r
- void (*transmitConfirm) (void);\r
- void (*receiveLookahead) (void);\r
- void (*indicationComplete) (void);\r
- void (*receiveChain) (void);\r
- void (*status) (void);\r
- } ProtDispatch;\r
-\r
-\r
-typedef struct _ReqBlock {\r
- WORD opcode;\r
- WORD status;\r
- BYTE FAR *pointer1;\r
- BYTE FAR *pointer2;\r
- WORD word1;\r
- } ReqBlock;\r
-\r
-\r
-typedef struct _TxBufDescrRec {\r
- BYTE txPtrType;\r
- BYTE dummy;\r
- WORD txDataLen;\r
- BYTE *txDataPtr;\r
- } TxBufDescrRec;\r
-\r
-\r
-typedef struct _TxBufDescr {\r
- WORD txImmedLen;\r
- BYTE *txImmedPtr;\r
- WORD txDataCount;\r
- TxBufDescrRec txBufDescrRec[NDIS_TX_BUF_LENGTH];\r
- } TxBufDescr;\r
-\r
-\r
-typedef struct _TDBufDescrRec {\r
- BYTE tDPtrType;\r
- BYTE dummy;\r
- WORD tDDataLen;\r
- BYTE *tDDataPtr;\r
- } TDBufDescrRec;\r
-\r
-\r
-typedef struct _TDBufDescr {\r
- WORD tDDataCount;\r
- TDBufDescrRec tDBufDescrRec[NDIS_TD_BUF_LENGTH];\r
- } TDBufDescr;\r
-\r
-\r
-typedef struct _RxBufDescrRec {\r
- WORD rxDataLen;\r
- BYTE *rxDataPtr;\r
- } RxBufDescrRec;\r
-\r
-\r
-typedef struct _RxBufDescr {\r
- WORD rxDataCount;\r
- RxBufDescrRec rxBufDescrRec[NDIS_RX_BUF_LENGTH];\r
- } RxBufDescr;\r
-\r
-\r
-typedef struct _PktBuf {\r
- struct _PktBuf *nextLink;\r
- struct _PktBuf *prevLink;\r
- int handle;\r
- int length;\r
- int packetLength;\r
- DWORD sequence;\r
- BYTE *buffer;\r
- } PktBuf;\r
-\r
-\r
-typedef struct _CardHandle {\r
- BYTE moduleName[16];\r
- CommonChars *common;\r
- } CardHandle;\r
-\r
-\r
-typedef struct _BindingsList {\r
- WORD numBindings;\r
- BYTE moduleName[2][16];\r
- } BindingsList;\r
-\r
-\r
-typedef struct _FailingModules {\r
- BYTE upperModuleName[16];\r
- BYTE lowerModuleName[16];\r
- } FailingModules;\r
-\r
-\r
-typedef union _HardwareAddress {\r
- BYTE bytes[6];\r
- WORD words[3];\r
- struct {\r
- BYTE bytes[6];\r
- } addr;\r
- } HardwareAddress;\r
-\r
-\r
-typedef struct _FddiHeader {\r
- BYTE frameControl;\r
- HardwareAddress etherDestHost;\r
- HardwareAddress etherSrcHost;\r
- } FddiHeader;\r
-\r
-\r
-typedef struct _EthernetIIHeader {\r
- HardwareAddress etherDestHost;\r
- HardwareAddress etherSrcHost;\r
- WORD etherType;\r
- } EthernetIIHeader;\r
-\r
-\r
-typedef struct _Ieee802Dot5Header {\r
- HardwareAddress etherDestHost;\r
- HardwareAddress etherSrcHost;\r
- BYTE routeInfo[30];\r
- } Ieee802Dot5Header;\r
-\r
-\r
-typedef struct _Ieee802Dot2SnapHeader {\r
- BYTE dsap; /* 0xAA */\r
- BYTE ssap; /* 0xAA */\r
- BYTE control; /* 3 */\r
- BYTE protocolId[5];\r
- } Ieee802Dot2SnapHeader;\r
-\r
-\r
-/*\r
- * Prototypes\r
- */\r
-extern char *NdisLastError (void);\r
-extern int NdisOpen (void);\r
-extern int NdisInit (int promis);\r
-extern int NdisRegisterAndBind (int promis);\r
-extern void NdisShutdown (void);\r
-extern void NdisCheckMacFeatures (struct _CardHandle *card);\r
-extern int NdisSendPacket (struct _PktBuf *pktBuf, int macId);\r
-\r
-/*\r
- * Assembly "glue" functions\r
- */\r
-extern int systemRequestGlue();\r
-extern int requestConfirmGlue();\r
-extern int transmitConfirmGlue();\r
-extern int receiveLookaheadGlue();\r
-extern int indicationCompleteGlue();\r
-extern int receiveChainGlue();\r
-extern int statusGlue();\r
-\r
-/*\r
- * IOCTL function\r
- */\r
-#ifdef __SMALL__\r
-extern int _far NdisGetLinkage (int handle, char *data, int size);\r
-#else\r
-extern int NdisGetLinkage (int handle, char *data, int size);\r
-#endif\r
-\r
-/*\r
- * NDIS callback handlers\r
- */\r
-CALLBACK (NdisSystemRequest (DWORD,DWORD, WORD, WORD, WORD));\r
-CALLBACK (NdisRequestConfirm ( WORD, WORD, WORD, WORD, WORD,WORD));\r
-CALLBACK (NdisTransmitConfirm ( WORD, WORD, WORD, WORD, WORD));\r
-CALLBACK (NdisReceiveLookahead ( WORD, WORD, WORD, BYTE*, BYTE*, WORD));\r
-CALLBACK (NdisReceiveChain ( WORD, WORD, WORD, struct _RxBufDescr*, BYTE*, WORD));\r
-CALLBACK (NdisStatusProc ( WORD, WORD, BYTE*, WORD,WORD));\r
-CALLBACK (NdisIndicationComplete( WORD, WORD));\r
-\r
-BYTE *NdisAllocStack (void);\r
-void NdisFreeStack (BYTE*);\r
-\r
-#ifdef __HIGHC__\r
- #define RENAME_ASM_SYM(x) pragma Alias(x,"@" #x "") /* prepend `@' */\r
- #define RENAME_C_SYM(x) pragma Alias(x,"_" #x "") /* prepend `_' */\r
-\r
- RENAME_ASM_SYM (systemRequestGlue);\r
- RENAME_ASM_SYM (requestConfirmGlue);\r
- RENAME_ASM_SYM (transmitConfirmGlue);\r
- RENAME_ASM_SYM (receiveLookaheadGlue);\r
- RENAME_ASM_SYM (indicationCompleteGlue);\r
- RENAME_ASM_SYM (receiveChainGlue);\r
- RENAME_ASM_SYM (statusGlue);\r
- RENAME_ASM_SYM (NdisGetLinkage);\r
- RENAME_C_SYM (NdisSystemRequest);\r
- RENAME_C_SYM (NdisRequestConfirm);\r
- RENAME_C_SYM (NdisTransmitConfirm);\r
- RENAME_C_SYM (NdisReceiveLookahead);\r
- RENAME_C_SYM (NdisIndicationComplete);\r
- RENAME_C_SYM (NdisReceiveChain);\r
- RENAME_C_SYM (NdisStatusProc);\r
- RENAME_C_SYM (NdisAllocStack);\r
- RENAME_C_SYM (NdisFreeStack);\r
-#endif\r
-\r
-#endif\r
+/*
+ * Copyright (c) 1993,1994
+ * Texas A&M University. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Texas A&M University
+ * and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Developers:
+ * David K. Hess, Douglas Lee Schales, David R. Safford
+ *
+ * Heavily modified for Metaware HighC + GNU C 2.8+
+ * Gisle Vanem 1998
+ */
+
+#ifndef __PCAP_NDIS_H
+#define __PCAP_NDIS_H
+
+#if defined (__HIGHC__)
+ #define pascal _CC(_CALLEE_POPS_STACK & ~_REVERSE_PARMS) /* calling convention */
+ #define CALLBACK(foo) pascal WORD foo
+ #define PAS_PTR(x,arg) typedef FAR WORD pascal (*x) arg
+ #define GUARD() _inline (0x9C,0xFA) /* pushfd, cli */
+ #define UNGUARD() _inline (0x9D) /* popfd */
+ #define FAR _far
+
+#elif defined(__GNUC__)
+ #define CALLBACK(foo) WORD foo __attribute__((stdcall))
+ #define PAS_PTR(x,arg) typedef WORD (*x) arg __attribute__((stdcall))
+ #define GUARD() __asm__ __volatile__ ("pushfd; cli")
+ #define UNGUARD() __asm__ __volatile__ ("popfd")
+ #define FAR
+
+#elif defined (__TURBOC__)
+ #define CALLBACK(foo) WORD pascal foo
+ #define PAS_PTR(x,arg) typedef WORD pascal (_far *x) arg
+ #define GUARD() _asm { pushf; cli }
+ #define UNGUARD() _asm { popf }
+ #define FAR _far
+
+#elif defined (__WATCOMC__)
+ #define CALLBACK(foo) WORD pascal foo
+ #define PAS_PTR(x,arg) typedef WORD pascal (_far *x) arg
+ #define GUARD() _disable()
+ #define UNGUARD() _enable()
+ #define FAR _far
+
+#else
+ #error Unsupported compiler
+#endif
+
+
+/*
+ * Forwards
+ */
+struct _ReqBlock;
+struct _TxBufDescr;
+struct _TDBufDescr;
+
+/*
+ * Protocol Manager API
+ */
+PAS_PTR (ProtMan, (struct _ReqBlock FAR*, WORD));
+
+/*
+ * System request
+ */
+PAS_PTR (SystemRequest, (DWORD, DWORD, WORD, WORD, WORD));
+
+/*
+ * MAC API
+ */
+PAS_PTR (TransmitChain, (WORD, WORD, struct _TxBufDescr FAR*, WORD));
+PAS_PTR (TransferData, (WORD*,WORD, struct _TDBufDescr FAR*, WORD));
+PAS_PTR (Request, (WORD, WORD, WORD, DWORD, WORD, WORD));
+PAS_PTR (ReceiveRelease,(WORD, WORD));
+PAS_PTR (IndicationOn, (WORD));
+PAS_PTR (IndicationOff, (WORD));
+
+
+typedef enum {
+ HARDWARE_NOT_INSTALLED = 0,
+ HARDWARE_FAILED_DIAG = 1,
+ HARDWARE_FAILED_CONFIG = 2,
+ HARDWARE_HARD_FAULT = 3,
+ HARDWARE_SOFT_FAULT = 4,
+ HARDWARE_OK = 7,
+ HARDWARE_MASK = 0x0007,
+ MAC_BOUND = 0x0008,
+ MAC_OPEN = 0x0010,
+ DIAG_IN_PROGRESS = 0x0020
+ } NdisMacStatus;
+
+typedef enum {
+ STATUS_RING_STATUS = 1,
+ STATUS_ADAPTER_CHECK = 2,
+ STATUS_START_RESET = 3,
+ STATUS_INTERRUPT = 4,
+ STATUS_END_RESET = 5
+ } NdisStatus;
+
+typedef enum {
+ FILTER_DIRECTED = 1,
+ FILTER_BROADCAST = 2,
+ FILTER_PROMISCUOUS = 4,
+ FILTER_SOURCE_ROUTE = 8
+ } NdisPacketFilter;
+
+typedef enum {
+ REQ_INITIATE_DIAGNOSTICS = 1,
+ REQ_READ_ERROR_LOG = 2,
+ REQ_SET_STATION_ADDRESS = 3,
+ REQ_OPEN_ADAPTER = 4,
+ REQ_CLOSE_ADAPTER = 5,
+ REQ_RESET_MAC = 6,
+ REQ_SET_PACKET_FILTER = 7,
+ REQ_ADD_MULTICAST_ADDRESS = 8,
+ REQ_DELETE_MULTICAST_ADDRESS = 9,
+ REQ_UPDATE_STATISTICS = 10,
+ REQ_CLEAR_STATISTICS = 11,
+ REQ_INTERRUPT_REQUEST = 12,
+ REQ_SET_FUNCTIONAL_ADDRESS = 13,
+ REQ_SET_LOOKAHEAD = 14
+ } NdisGeneralRequest;
+
+typedef enum {
+ SF_BROADCAST = 0x00000001L,
+ SF_MULTICAST = 0x00000002L,
+ SF_FUNCTIONAL = 0x00000004L,
+ SF_PROMISCUOUS = 0x00000008L,
+ SF_SOFT_ADDRESS = 0x00000010L,
+ SF_STATS_CURRENT = 0x00000020L,
+ SF_INITIATE_DIAGS = 0x00000040L,
+ SF_LOOPBACK = 0x00000080L,
+ SF_RECEIVE_CHAIN = 0x00000100L,
+ SF_SOURCE_ROUTING = 0x00000200L,
+ SF_RESET_MAC = 0x00000400L,
+ SF_OPEN_CLOSE = 0x00000800L,
+ SF_INTERRUPT_REQUEST = 0x00001000L,
+ SF_SOURCE_ROUTING_BRIDGE = 0x00002000L,
+ SF_VIRTUAL_ADDRESSES = 0x00004000L
+ } NdisMacServiceFlags;
+
+typedef enum {
+ REQ_INITIATE_BIND = 1,
+ REQ_BIND = 2,
+ REQ_INITIATE_PREBIND = 3,
+ REQ_INITIATE_UNBIND = 4,
+ REQ_UNBIND = 5
+ } NdisSysRequest;
+
+typedef enum {
+ PM_GET_PROTOCOL_MANAGER_INFO = 1,
+ PM_REGISTER_MODULE = 2,
+ PM_BIND_AND_START = 3,
+ PM_GET_PROTOCOL_MANAGER_LINKAGE = 4,
+ PM_GET_PROTOCOL_INI_PATH = 5,
+ PM_REGISTER_PROTOCOL_MANAGER_INFO = 6,
+ PM_INIT_AND_REGISTER = 7,
+ PM_UNBIND_AND_STOP = 8,
+ PM_BIND_STATUS = 9,
+ PM_REGISTER_STATUS = 10
+ } NdisProtManager;
+
+
+typedef enum {
+ ERR_SUCCESS = 0x00,
+ ERR_WAIT_FOR_RELEASE = 0x01,
+ ERR_REQUEST_QUEUED = 0x02,
+ ERR_FRAME_NOT_RECOGNIZED = 0x03,
+ ERR_FRAME_REJECTED = 0x04,
+ ERR_FORWARD_FRAME = 0x05,
+ ERR_OUT_OF_RESOURCE = 0x06,
+ ERR_INVALID_PARAMETER = 0x07,
+ ERR_INVALID_FUNCTION = 0x08,
+ ERR_NOT_SUPPORTED = 0x09,
+ ERR_HARDWARE_ERROR = 0x0A,
+ ERR_TRANSMIT_ERROR = 0x0B,
+ ERR_NO_SUCH_DESTINATION = 0x0C,
+ ERR_BUFFER_TOO_SMALL = 0x0D,
+ ERR_ALREADY_STARTED = 0x20,
+ ERR_INCOMPLETE_BINDING = 0x21,
+ ERR_DRIVER_NOT_INITIALIZED = 0x22,
+ ERR_HARDWARE_NOT_FOUND = 0x23,
+ ERR_HARDWARE_FAILURE = 0x24,
+ ERR_CONFIGURATION_FAILURE = 0x25,
+ ERR_INTERRUPT_CONFLICT = 0x26,
+ ERR_INCOMPATIBLE_MAC = 0x27,
+ ERR_INITIALIZATION_FAILED = 0x28,
+ ERR_NO_BINDING = 0x29,
+ ERR_NETWORK_MAY_NOT_BE_CONNECTED = 0x2A,
+ ERR_INCOMPATIBLE_OS_VERSION = 0x2B,
+ ERR_ALREADY_REGISTERED = 0x2C,
+ ERR_PATH_NOT_FOUND = 0x2D,
+ ERR_INSUFFICIENT_MEMORY = 0x2E,
+ ERR_INFO_NOT_FOUND = 0x2F,
+ ERR_GENERAL_FAILURE = 0xFF
+ } NdisError;
+
+#define NDIS_PARAM_INTEGER 0
+#define NDIS_PARAM_STRING 1
+
+#define NDIS_TX_BUF_LENGTH 8
+#define NDIS_TD_BUF_LENGTH 1
+#define NDIS_RX_BUF_LENGTH 8
+
+#define NDIS_PTR_PHYSICAL 0
+#define NDIS_PTR_VIRTUAL 2
+
+#define NDIS_PATH "PROTMAN$"
+
+
+typedef struct _CommonChars {
+ WORD tableSize;
+ BYTE majorNdisVersion; /* 2 - Latest version */
+ BYTE minorNdisVersion; /* 0 */
+ WORD reserved1;
+ BYTE majorModuleVersion;
+ BYTE minorModuleVersion;
+ DWORD moduleFlags;
+ /* 0 - Binding at upper boundary supported
+ * 1 - Binding at lower boundary supported
+ * 2 - Dynamically bound.
+ * 3-31 - Reserved, must be zero.
+ */
+ BYTE moduleName[16];
+ BYTE protocolLevelUpper;
+ /* 1 - MAC
+ * 2 - Data Link
+ * 3 - Network
+ * 4 - Transport
+ * 5 - Session
+ * -1 - Not specified
+ */
+ BYTE interfaceUpper;
+ BYTE protocolLevelLower;
+ /* 0 - Physical
+ * 1 - MAC
+ * 2 - Data Link
+ * 3 - Network
+ * 4 - Transport
+ * 5 - Session
+ * -1 - Not specified
+ */
+ BYTE interfaceLower;
+ WORD moduleId;
+ WORD moduleDS;
+ SystemRequest systemRequest;
+ BYTE *serviceChars;
+ BYTE *serviceStatus;
+ BYTE *upperDispatchTable;
+ BYTE *lowerDispatchTable;
+ BYTE *reserved2; /* Must be NULL */
+ BYTE *reserved3; /* Must be NULL */
+ } CommonChars;
+
+
+typedef struct _MulticastList {
+ WORD maxMulticastAddresses;
+ WORD numberMulticastAddresses;
+ BYTE multicastAddress[16][16];
+ } MulticastList;
+
+
+typedef struct _MacChars {
+ WORD tableSize;
+ BYTE macName[16];
+ WORD addressLength;
+ BYTE permanentAddress[16];
+ BYTE currentAddress[16];
+ DWORD currentFunctionalAddress;
+ MulticastList *multicastList;
+ DWORD linkSpeed;
+ DWORD serviceFlags;
+ WORD maxFrameSize;
+ DWORD txBufferSize;
+ WORD txBufferAllocSize;
+ DWORD rxBufferSize;
+ WORD rxBufferAllocSize;
+ BYTE ieeeVendor[3];
+ BYTE vendorAdapter;
+ BYTE *vendorAdapterDescription;
+ WORD interruptLevel;
+ WORD txQueueDepth;
+ WORD maxDataBlocks;
+ } MacChars;
+
+
+typedef struct _ProtocolChars {
+ WORD length;
+ BYTE name[16];
+ WORD type;
+ } ProtocolChars;
+
+
+typedef struct _MacUpperDispatch {
+ CommonChars *backPointer;
+ Request request;
+ TransmitChain transmitChain;
+ TransferData transferData;
+ ReceiveRelease receiveRelease;
+ IndicationOn indicationOn;
+ IndicationOff indicationOff;
+ } MacUpperDispatch;
+
+
+typedef struct _MacStatusTable {
+ WORD tableSize;
+ DWORD lastDiag;
+ DWORD macStatus;
+ WORD packetFilter;
+ BYTE *mediaSpecificStats;
+ DWORD lastClear;
+ DWORD totalFramesRx;
+ DWORD totalFramesCrc;
+ DWORD totalBytesRx;
+ DWORD totalDiscardBufSpaceRx;
+ DWORD totalMulticastRx;
+ DWORD totalBroadcastRx;
+ DWORD obsolete1[5];
+ DWORD totalDiscardHwErrorRx;
+ DWORD totalFramesTx;
+ DWORD totalBytesTx;
+ DWORD totalMulticastTx;
+ DWORD totalBroadcastTx;
+ DWORD obsolete2[2];
+ DWORD totalDiscardTimeoutTx;
+ DWORD totalDiscardHwErrorTx;
+ } MacStatusTable;
+
+
+typedef struct _ProtDispatch {
+ CommonChars *backPointer;
+ DWORD flags;
+ /* 0 - handles non-LLC frames
+ * 1 - handles specific-LSAP LLC frames
+ * 2 - handles specific-LSAP LLC frames
+ * 3-31 - reserved must be 0
+ */
+ void (*requestConfirm) (void);
+ void (*transmitConfirm) (void);
+ void (*receiveLookahead) (void);
+ void (*indicationComplete) (void);
+ void (*receiveChain) (void);
+ void (*status) (void);
+ } ProtDispatch;
+
+
+typedef struct _ReqBlock {
+ WORD opcode;
+ WORD status;
+ BYTE FAR *pointer1;
+ BYTE FAR *pointer2;
+ WORD word1;
+ } ReqBlock;
+
+
+typedef struct _TxBufDescrRec {
+ BYTE txPtrType;
+ BYTE dummy;
+ WORD txDataLen;
+ BYTE *txDataPtr;
+ } TxBufDescrRec;
+
+
+typedef struct _TxBufDescr {
+ WORD txImmedLen;
+ BYTE *txImmedPtr;
+ WORD txDataCount;
+ TxBufDescrRec txBufDescrRec[NDIS_TX_BUF_LENGTH];
+ } TxBufDescr;
+
+
+typedef struct _TDBufDescrRec {
+ BYTE tDPtrType;
+ BYTE dummy;
+ WORD tDDataLen;
+ BYTE *tDDataPtr;
+ } TDBufDescrRec;
+
+
+typedef struct _TDBufDescr {
+ WORD tDDataCount;
+ TDBufDescrRec tDBufDescrRec[NDIS_TD_BUF_LENGTH];
+ } TDBufDescr;
+
+
+typedef struct _RxBufDescrRec {
+ WORD rxDataLen;
+ BYTE *rxDataPtr;
+ } RxBufDescrRec;
+
+
+typedef struct _RxBufDescr {
+ WORD rxDataCount;
+ RxBufDescrRec rxBufDescrRec[NDIS_RX_BUF_LENGTH];
+ } RxBufDescr;
+
+
+typedef struct _PktBuf {
+ struct _PktBuf *nextLink;
+ struct _PktBuf *prevLink;
+ int handle;
+ int length;
+ int packetLength;
+ DWORD sequence;
+ BYTE *buffer;
+ } PktBuf;
+
+
+typedef struct _CardHandle {
+ BYTE moduleName[16];
+ CommonChars *common;
+ } CardHandle;
+
+
+typedef struct _BindingsList {
+ WORD numBindings;
+ BYTE moduleName[2][16];
+ } BindingsList;
+
+
+typedef struct _FailingModules {
+ BYTE upperModuleName[16];
+ BYTE lowerModuleName[16];
+ } FailingModules;
+
+
+typedef union _HardwareAddress {
+ BYTE bytes[6];
+ WORD words[3];
+ struct {
+ BYTE bytes[6];
+ } addr;
+ } HardwareAddress;
+
+
+typedef struct _FddiHeader {
+ BYTE frameControl;
+ HardwareAddress etherDestHost;
+ HardwareAddress etherSrcHost;
+ } FddiHeader;
+
+
+typedef struct _EthernetIIHeader {
+ HardwareAddress etherDestHost;
+ HardwareAddress etherSrcHost;
+ WORD etherType;
+ } EthernetIIHeader;
+
+
+typedef struct _Ieee802Dot5Header {
+ HardwareAddress etherDestHost;
+ HardwareAddress etherSrcHost;
+ BYTE routeInfo[30];
+ } Ieee802Dot5Header;
+
+
+typedef struct _Ieee802Dot2SnapHeader {
+ BYTE dsap; /* 0xAA */
+ BYTE ssap; /* 0xAA */
+ BYTE control; /* 3 */
+ BYTE protocolId[5];
+ } Ieee802Dot2SnapHeader;
+
+
+/*
+ * Prototypes
+ */
+extern char *NdisLastError (void);
+extern int NdisOpen (void);
+extern int NdisInit (int promis);
+extern int NdisRegisterAndBind (int promis);
+extern void NdisShutdown (void);
+extern void NdisCheckMacFeatures (struct _CardHandle *card);
+extern int NdisSendPacket (struct _PktBuf *pktBuf, int macId);
+
+/*
+ * Assembly "glue" functions
+ */
+extern int systemRequestGlue();
+extern int requestConfirmGlue();
+extern int transmitConfirmGlue();
+extern int receiveLookaheadGlue();
+extern int indicationCompleteGlue();
+extern int receiveChainGlue();
+extern int statusGlue();
+
+/*
+ * IOCTL function
+ */
+#ifdef __SMALL__
+extern int _far NdisGetLinkage (int handle, char *data, int size);
+#else
+extern int NdisGetLinkage (int handle, char *data, int size);
+#endif
+
+/*
+ * NDIS callback handlers
+ */
+CALLBACK (NdisSystemRequest (DWORD,DWORD, WORD, WORD, WORD));
+CALLBACK (NdisRequestConfirm ( WORD, WORD, WORD, WORD, WORD,WORD));
+CALLBACK (NdisTransmitConfirm ( WORD, WORD, WORD, WORD, WORD));
+CALLBACK (NdisReceiveLookahead ( WORD, WORD, WORD, BYTE*, BYTE*, WORD));
+CALLBACK (NdisReceiveChain ( WORD, WORD, WORD, struct _RxBufDescr*, BYTE*, WORD));
+CALLBACK (NdisStatusProc ( WORD, WORD, BYTE*, WORD,WORD));
+CALLBACK (NdisIndicationComplete( WORD, WORD));
+
+BYTE *NdisAllocStack (void);
+void NdisFreeStack (BYTE*);
+
+#ifdef __HIGHC__
+ #define RENAME_ASM_SYM(x) pragma Alias(x,"@" #x "") /* prepend `@' */
+ #define RENAME_C_SYM(x) pragma Alias(x,"_" #x "") /* prepend `_' */
+
+ RENAME_ASM_SYM (systemRequestGlue);
+ RENAME_ASM_SYM (requestConfirmGlue);
+ RENAME_ASM_SYM (transmitConfirmGlue);
+ RENAME_ASM_SYM (receiveLookaheadGlue);
+ RENAME_ASM_SYM (indicationCompleteGlue);
+ RENAME_ASM_SYM (receiveChainGlue);
+ RENAME_ASM_SYM (statusGlue);
+ RENAME_ASM_SYM (NdisGetLinkage);
+ RENAME_C_SYM (NdisSystemRequest);
+ RENAME_C_SYM (NdisRequestConfirm);
+ RENAME_C_SYM (NdisTransmitConfirm);
+ RENAME_C_SYM (NdisReceiveLookahead);
+ RENAME_C_SYM (NdisIndicationComplete);
+ RENAME_C_SYM (NdisReceiveChain);
+ RENAME_C_SYM (NdisStatusProc);
+ RENAME_C_SYM (NdisAllocStack);
+ RENAME_C_SYM (NdisFreeStack);
+#endif
+
+#endif
-PAGE 60,132\r
-NAME NDIS_0\r
-\r
-ifdef DOSX\r
- .386\r
- _TEXT SEGMENT PUBLIC DWORD USE16 'CODE'\r
- _TEXT ENDS\r
- _DATA SEGMENT PUBLIC DWORD USE16 'CODE'\r
- _DATA ENDS\r
- _TEXT32 SEGMENT PUBLIC BYTE USE32 'CODE'\r
- _TEXT32 ENDS\r
- CB_DSEG EQU <CS> ; DOSX is tiny-model\r
- D_SEG EQU <_TEXT SEGMENT>\r
- D_END EQU <_TEXT ENDS>\r
- ASSUME CS:_TEXT,DS:_TEXT\r
-\r
- PUSHREGS equ <pushad>\r
- POPREGS equ <popad>\r
-\r
- PUBPROC macro name\r
- align 4\r
- public @&name\r
- @&name label near\r
- endm\r
-else\r
- .286\r
- _TEXT SEGMENT PUBLIC DWORD 'CODE'\r
- _TEXT ENDS\r
- _DATA SEGMENT PUBLIC DWORD 'DATA'\r
- _DATA ENDS\r
- CB_DSEG EQU <SEG _DATA> ; 16bit is small/large model\r
- D_SEG EQU <_DATA SEGMENT>\r
- D_END EQU <_DATA ENDS>\r
- ASSUME CS:_TEXT,DS:_DATA\r
-\r
- PUSHREGS equ <pusha>\r
- POPREGS equ <popa>\r
-\r
- PUBPROC macro name\r
- public _&name\r
- _&name label far\r
- endm\r
-endif\r
-\r
-;-------------------------------------------\r
-\r
-D_SEG\r
-\r
-D_END\r
-\r
-\r
-_TEXT SEGMENT\r
-\r
-EXTRN _NdisSystemRequest : near\r
-EXTRN _NdisRequestConfirm : near\r
-EXTRN _NdisTransmitConfirm : near\r
-EXTRN _NdisReceiveLookahead : near\r
-EXTRN _NdisIndicationComplete : near\r
-EXTRN _NdisReceiveChain : near\r
-EXTRN _NdisStatusProc : near\r
-EXTRN _NdisAllocStack : near\r
-EXTRN _NdisFreeStack : near\r
-\r
-;\r
-; *ALL* interrupt threads come through this macro.\r
-;\r
-CALLBACK macro callbackProc, argsSize\r
-\r
- pushf\r
- PUSHREGS ;; Save the registers\r
-\r
- push es\r
- push ds\r
- mov ax,CB_DSEG ;; Load DS\r
- mov ds,ax\r
- call _NdisAllocStack ;; Get and install a stack.\r
-\r
- mov bx,ss ;; Save off the old stack in other regs\r
- mov cx,sp\r
- mov ss,dx ;; Install the new one\r
- mov sp,ax\r
- push bx ;; Save the old one on to the new stack\r
- push cx\r
- sub sp,&argsSize ;; Allocate space for arguments on the stack\r
-\r
- mov ax,ss ;; Set up the destination for the move\r
- mov es,ax\r
- mov di,sp\r
- mov ds,bx ;; Set up the source for the move.\r
- mov si,cx\r
- add si,4+6+32\r
-\r
- mov cx,&argsSize ;; Move the arguments to the stack.\r
- shr cx,1\r
- cld\r
- rep movsw\r
-\r
- mov ax,CB_DSEG ;; Set my data segment again.\r
- mov ds,ax\r
-\r
- call &callbackProc ;; Call the real callback.\r
- pop di ;; Pop off the old stack\r
- pop si\r
- mov bx,ss ;; Save off the current allocated stack.\r
- mov cx,sp\r
- mov ss,si ;; Restore the old stack\r
- mov sp,di\r
- push ax ;; Save the return code\r
- push bx ;; Free the stack. Push the pointer to it\r
- push cx\r
- call _NdisFreeStack\r
- add sp,4\r
- pop ax ;; Get the return code back\r
- add di,32 ;; Get a pointer to ax on the stack\r
- mov word ptr ss:[di],ax\r
- pop ds\r
- pop es\r
-\r
- POPREGS\r
- popf\r
-endm\r
-\r
-;\r
-; Define all of the callbacks for the NDIS procs.\r
-;\r
-\r
-PUBPROC systemRequestGlue\r
-CALLBACK _NdisSystemRequest,14\r
-RETF\r
-\r
-PUBPROC requestConfirmGlue\r
-CALLBACK _NdisRequestConfirm,12\r
-RETF\r
-\r
-PUBPROC transmitConfirmGlue\r
-CALLBACK _NdisTransmitConfirm,10\r
-RETF\r
-\r
-PUBPROC receiveLookaheadGlue\r
-CALLBACK _NdisReceiveLookahead,16\r
-RETF\r
-\r
-PUBPROC indicationCompleteGlue\r
-CALLBACK _NdisIndicationComplete,4\r
-RETF\r
-\r
-PUBPROC receiveChainGlue\r
-CALLBACK _NdisReceiveChain,16\r
-RETF\r
-\r
-PUBPROC statusGlue\r
-CALLBACK _NdisStatusProc,12\r
-RETF\r
-\r
-;\r
-; int FAR NdisGetLinkage (int handle, char *data, int size);\r
-;\r
-\r
-ifdef DOSX\r
- PUBPROC NdisGetLinkage\r
- push ebx\r
- mov ebx, [esp+8] ; device handle\r
- mov eax, 4402h ; IOCTRL read function\r
- mov edx, [esp+12] ; DS:EDX -> result data\r
- mov ecx, [esp+16] ; ECX = length\r
- int 21h\r
- pop ebx\r
- jc @fail\r
- xor eax, eax\r
- @fail: ret\r
-\r
-else\r
- PUBPROC NdisGetLinkage\r
- enter 0, 0\r
- mov bx, [bp+6]\r
- mov ax, 4402h\r
- mov dx, [bp+8]\r
- mov cx, [bp+12]\r
- int 21h\r
- jc @fail\r
- xor ax, ax\r
- @fail: leave\r
- retf\r
-endif\r
-\r
-ENDS\r
-\r
-END\r
+PAGE 60,132
+NAME NDIS_0
+
+ifdef DOSX
+ .386
+ _TEXT SEGMENT PUBLIC DWORD USE16 'CODE'
+ _TEXT ENDS
+ _DATA SEGMENT PUBLIC DWORD USE16 'CODE'
+ _DATA ENDS
+ _TEXT32 SEGMENT PUBLIC BYTE USE32 'CODE'
+ _TEXT32 ENDS
+ CB_DSEG EQU <CS> ; DOSX is tiny-model
+ D_SEG EQU <_TEXT SEGMENT>
+ D_END EQU <_TEXT ENDS>
+ ASSUME CS:_TEXT,DS:_TEXT
+
+ PUSHREGS equ <pushad>
+ POPREGS equ <popad>
+
+ PUBPROC macro name
+ align 4
+ public @&name
+ @&name label near
+ endm
+else
+ .286
+ _TEXT SEGMENT PUBLIC DWORD 'CODE'
+ _TEXT ENDS
+ _DATA SEGMENT PUBLIC DWORD 'DATA'
+ _DATA ENDS
+ CB_DSEG EQU <SEG _DATA> ; 16bit is small/large model
+ D_SEG EQU <_DATA SEGMENT>
+ D_END EQU <_DATA ENDS>
+ ASSUME CS:_TEXT,DS:_DATA
+
+ PUSHREGS equ <pusha>
+ POPREGS equ <popa>
+
+ PUBPROC macro name
+ public _&name
+ _&name label far
+ endm
+endif
+
+;-------------------------------------------
+
+D_SEG
+
+D_END
+
+
+_TEXT SEGMENT
+
+EXTRN _NdisSystemRequest : near
+EXTRN _NdisRequestConfirm : near
+EXTRN _NdisTransmitConfirm : near
+EXTRN _NdisReceiveLookahead : near
+EXTRN _NdisIndicationComplete : near
+EXTRN _NdisReceiveChain : near
+EXTRN _NdisStatusProc : near
+EXTRN _NdisAllocStack : near
+EXTRN _NdisFreeStack : near
+
+;
+; *ALL* interrupt threads come through this macro.
+;
+CALLBACK macro callbackProc, argsSize
+
+ pushf
+ PUSHREGS ;; Save the registers
+
+ push es
+ push ds
+ mov ax,CB_DSEG ;; Load DS
+ mov ds,ax
+ call _NdisAllocStack ;; Get and install a stack.
+
+ mov bx,ss ;; Save off the old stack in other regs
+ mov cx,sp
+ mov ss,dx ;; Install the new one
+ mov sp,ax
+ push bx ;; Save the old one on to the new stack
+ push cx
+ sub sp,&argsSize ;; Allocate space for arguments on the stack
+
+ mov ax,ss ;; Set up the destination for the move
+ mov es,ax
+ mov di,sp
+ mov ds,bx ;; Set up the source for the move.
+ mov si,cx
+ add si,4+6+32
+
+ mov cx,&argsSize ;; Move the arguments to the stack.
+ shr cx,1
+ cld
+ rep movsw
+
+ mov ax,CB_DSEG ;; Set my data segment again.
+ mov ds,ax
+
+ call &callbackProc ;; Call the real callback.
+ pop di ;; Pop off the old stack
+ pop si
+ mov bx,ss ;; Save off the current allocated stack.
+ mov cx,sp
+ mov ss,si ;; Restore the old stack
+ mov sp,di
+ push ax ;; Save the return code
+ push bx ;; Free the stack. Push the pointer to it
+ push cx
+ call _NdisFreeStack
+ add sp,4
+ pop ax ;; Get the return code back
+ add di,32 ;; Get a pointer to ax on the stack
+ mov word ptr ss:[di],ax
+ pop ds
+ pop es
+
+ POPREGS
+ popf
+endm
+
+;
+; Define all of the callbacks for the NDIS procs.
+;
+
+PUBPROC systemRequestGlue
+CALLBACK _NdisSystemRequest,14
+RETF
+
+PUBPROC requestConfirmGlue
+CALLBACK _NdisRequestConfirm,12
+RETF
+
+PUBPROC transmitConfirmGlue
+CALLBACK _NdisTransmitConfirm,10
+RETF
+
+PUBPROC receiveLookaheadGlue
+CALLBACK _NdisReceiveLookahead,16
+RETF
+
+PUBPROC indicationCompleteGlue
+CALLBACK _NdisIndicationComplete,4
+RETF
+
+PUBPROC receiveChainGlue
+CALLBACK _NdisReceiveChain,16
+RETF
+
+PUBPROC statusGlue
+CALLBACK _NdisStatusProc,12
+RETF
+
+;
+; int FAR NdisGetLinkage (int handle, char *data, int size);
+;
+
+ifdef DOSX
+ PUBPROC NdisGetLinkage
+ push ebx
+ mov ebx, [esp+8] ; device handle
+ mov eax, 4402h ; IOCTRL read function
+ mov edx, [esp+12] ; DS:EDX -> result data
+ mov ecx, [esp+16] ; ECX = length
+ int 21h
+ pop ebx
+ jc @fail
+ xor eax, eax
+ @fail: ret
+
+else
+ PUBPROC NdisGetLinkage
+ enter 0, 0
+ mov bx, [bp+6]
+ mov ax, 4402h
+ mov dx, [bp+8]
+ mov cx, [bp+12]
+ int 21h
+ jc @fail
+ xor ax, ax
+ @fail: leave
+ retf
+endif
+
+ENDS
+
+END
-PAGE 60,132\r
-NAME PKT_RX\r
-\r
-ifdef ??version ; using TASM\r
- masm\r
- jumps\r
-endif\r
-\r
-PUBLIC _pktDrop, _pktRxBuf, _pktTxBuf, _pktTemp\r
-PUBLIC _rxOutOfs, _rxInOfs, _PktReceiver, _pktRxEnd\r
-\r
-;\r
-; these sizes MUST be equal to the sizes in PKTDRVR.H\r
-;\r
-\r
-RX_BUF_SIZE = 1500 ; max message size on Ethernet\r
-TX_BUF_SIZE = 1500\r
-\r
-ifdef DOSX\r
- .386\r
- NUM_RX_BUF = 32 ; # of RX element buffers\r
- _TEXT SEGMENT PUBLIC DWORD USE16 'CODE'\r
- _TEXT ENDS\r
- _DATA SEGMENT PUBLIC DWORD USE16 'CODE'\r
- _DATA ENDS\r
- D_SEG EQU <_TEXT SEGMENT>\r
- D_END EQU <_TEXT ENDS>\r
- ASSUME CS:_TEXT,DS:_TEXT\r
-else\r
- .286\r
- NUM_RX_BUF = 10\r
- _TEXT SEGMENT PUBLIC DWORD 'CODE'\r
- _TEXT ENDS\r
- _DATA SEGMENT PUBLIC DWORD 'DATA'\r
- _DATA ENDS\r
- D_SEG EQU <_DATA SEGMENT>\r
- D_END EQU <_DATA ENDS>\r
- ASSUME CS:_TEXT,DS:_DATA\r
-endif\r
-\r
-;-------------------------------------------\r
-\r
-D_SEG\r
-\r
-RX_ELEMENT STRUC\r
- firstCount dw 0 ; # of bytes on 1st call\r
- secondCount dw 0 ; # of bytes on 2nd call\r
- handle dw 0 ; handle for upcall\r
- destinAdr db 6 dup (0) ; packet destination address\r
- sourceAdr db 6 dup (0) ; packet source address\r
- protocol dw 0 ; packet protocol number\r
- rxBuffer db RX_BUF_SIZE dup (0) ; RX buffer\r
-ENDS\r
- align 4\r
-_rxOutOfs dw offset _pktRxBuf ; ring buffer offsets\r
-_rxInOfs dw offset _pktRxBuf ; into _pktRxBuf\r
-_pktDrop dw 0,0 ; packet drop counter\r
-_pktTemp db 20 dup (0) ; temp work area\r
-_pktTxBuf db (TX_BUF_SIZE+14) dup (0) ; TX buffer\r
-_pktRxBuf RX_ELEMENT NUM_RX_BUF dup (<>) ; RX structures\r
- LAST_OFS = offset $\r
-\r
- screenSeg dw 0B800h\r
- newInOffset dw 0\r
-\r
- fanChars db '-\|/'\r
- fanIndex dw 0\r
-\r
-D_END\r
-\r
-_TEXT SEGMENT\r
-\r
-\r
-SHOW_RX MACRO\r
- push es\r
- push bx\r
- mov bx, screenSeg\r
- mov es, bx ;; r-mode segment of colour screen\r
- mov di, 158 ;; upper right corner - 1\r
- mov bx, fanIndex\r
- mov al, fanChars[bx] ;; get write char\r
- mov ah, 15 ;; and white colour\r
- stosw ;; write to screen at ES:EDI\r
- inc fanIndex ;; update next index\r
- and fanIndex, 3\r
- pop bx\r
- pop es\r
-ENDM\r
-\r
-;------------------------------------------------------------------------\r
-;\r
-; This macro return ES:DI to tail of Rx queue\r
-\r
-ENQUEUE MACRO\r
- LOCAL @noWrap\r
- mov ax, _rxInOfs ;; DI = current in-offset\r
- add ax, SIZE RX_ELEMENT ;; point to next _pktRxBuf buffer\r
- cmp ax, LAST_OFS ;; pointing past last ?\r
- jb @noWrap ;; no - jump\r
- lea ax, _pktRxBuf ;; yes, point to 1st buffer\r
- align 4\r
-@noWrap: cmp ax, _rxOutOfs ;; in-ofs = out-ofs ?\r
- je @dump ;; yes, queue is full\r
- mov di, _rxInOfs ;; ES:DI -> buffer at queue input\r
- mov newInOffset, ax ;; remember new input offset\r
-\r
- ;; NOTE. rxInOfs is updated after the packet has been copied\r
- ;; to ES:DI (= DS:SI on 2nd call) by the packet driver\r
-\r
-ENDM\r
-\r
-;------------------------------------------------------------------------\r
-;\r
-; This routine gets called by the packet driver twice:\r
-; 1st time (AX=0) it requests an address where to put the packet\r
-;\r
-; 2nd time (AX=1) the packet has been copied to this location (DS:SI)\r
-; BX has client handle (stored in RX_ELEMENT.handle).\r
-; CX has # of bytes in packet on both call. They should be equal.\r
-;\r
-; A test for equality is done by putting CX in _pktRxBuf [n].firstCount\r
-; and _pktRxBuf[n].secondCount, and CL on first call in\r
-; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive"\r
-; (PKTDRVR.C)\r
-;\r
-;---------------------------------------------------------------------\r
-\r
-_PktReceiver:\r
- pushf\r
- cli ; no distraction wanted !\r
- push ds\r
- push bx\r
-ifdef DOSX\r
- mov bx, cs\r
-else\r
- mov bx, SEG _DATA\r
-endif\r
- mov ds, bx\r
- mov es, bx ; ES = DS = CS or seg _DATA\r
- pop bx ; restore handle\r
-\r
- cmp ax, 0 ; first call? (AX=0)\r
- jne @post ; AX=1: second call, do post process\r
-\r
-ifdef DEBUG\r
- SHOW_RX ; show that a packet is received\r
-endif\r
- cmp cx, RX_BUF_SIZE+14 ; size OK ?\r
- ja @skip ; no, packet to large for us\r
-\r
- ENQUEUE ; ES:DI -> _pktRxBuf[n]\r
-\r
- mov [di].firstCount, cx ; remember the first count.\r
- mov [di].handle, bx ; remember the handle.\r
- add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr\r
- pop ds\r
- popf\r
- retf ; far return to driver with ES:DI\r
-\r
- align 4\r
-@dump: inc _pktDrop[0] ; discard the packet on 1st call\r
- adc _pktDrop[2], 0 ; increment packets lost\r
-\r
-@skip: xor di, di ; return ES:DI = NIL pointer\r
- xor ax, ax\r
- mov es, ax\r
- pop ds\r
- popf\r
- retf\r
-\r
- align 4\r
-@post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr\r
- jz @discard ; make sure we don't use NULL-pointer\r
-\r
- sub si, 6 ; DS:SI -> _pktRxBuf[n].destinAdr\r
- ;\r
- ; push si\r
- ; push [si].firstCount\r
- ; call bpf_filter_match ; run the filter here some day?\r
- ; add sp, 4\r
- ; cmp ax, 0\r
- ; je @discard\r
-\r
- mov [si].secondCount, cx\r
- mov ax, newInOffset\r
- mov _rxInOfs, ax ; update _pktRxBuf input offset\r
-\r
- align 4\r
-@discard:pop ds\r
- popf\r
- retf\r
-\r
-_pktRxEnd db 0 ; marker for end of r-mode code/data\r
-\r
-_TEXT ENDS\r
-\r
-END\r
+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
-;\r
-; This file requires NASM 0.97+ to assemble\r
-;\r
-; Currently used only for djgpp + DOS4GW targets\r
-;\r
-; these sizes MUST be equal to the sizes in PKTDRVR.H\r
-;\r
-%define ETH_MTU 1500 ; max data size on Ethernet\r
-%define ETH_MIN 60 ; min/max total frame size\r
-%define ETH_MAX (ETH_MTU+2*6+2)\r
-%define NUM_RX_BUF 32 ; # of RX element buffers\r
-%define RX_SIZE (ETH_MAX+6) ; sizeof(RX_ELEMENT) = 1514+6\r
-%idefine offset\r
-\r
-struc RX_ELEMENT\r
- .firstCount resw 1 ; # of bytes on 1st call\r
- .secondCount resw 1 ; # of bytes on 2nd call\r
- .handle resw 1 ; handle for upcall\r
- ; .timeStamp resw 4 ; 64-bit RDTSC value\r
- .destinAdr resb 6 ; packet destination address\r
- .sourceAdr resb 6 ; packet source address\r
- .protocol resw 1 ; packet protocol number\r
- .rxBuffer resb ETH_MTU ; RX buffer\r
-endstruc\r
-\r
-;-------------------------------------------\r
-\r
-[org 0] ; assemble to .bin file\r
-\r
-_rxOutOfs dw offset _pktRxBuf ; ring buffer offsets\r
-_rxInOfs dw offset _pktRxBuf ; into _pktRxBuf\r
-_pktDrop dw 0,0 ; packet drop counter\r
-_pktTemp resb 20 ; temp work area\r
-_pktTxBuf resb (ETH_MAX) ; TX buffer\r
-_pktRxBuf resb (RX_SIZE*NUM_RX_BUF) ; RX structures\r
- LAST_OFS equ $\r
-\r
-screenSeg dw 0B800h\r
-newInOffset dw 0\r
-\r
-fanChars db '-\|/'\r
-fanIndex dw 0\r
-\r
-%macro SHOW_RX 0\r
- push es\r
- push bx\r
- mov bx, [screenSeg]\r
- mov es, bx ;; r-mode segment of colour screen\r
- mov di, 158 ;; upper right corner - 1\r
- mov bx, [fanIndex]\r
- mov al, [fanChars+bx] ;; get write char\r
- mov ah, 15 ;; and white colour\r
- cld ;; Needed?\r
- stosw ;; write to screen at ES:EDI\r
- inc word [fanIndex] ;; update next index\r
- and word [fanIndex], 3\r
- pop bx\r
- pop es\r
-%endmacro\r
-\r
-;PutTimeStamp\r
-; rdtsc\r
-; mov [si].timeStamp, eax\r
-; mov [si+4].timeStamp, edx\r
-; ret\r
-\r
-\r
-;------------------------------------------------------------------------\r
-;\r
-; This routine gets called by the packet driver twice:\r
-; 1st time (AX=0) it requests an address where to put the packet\r
-;\r
-; 2nd time (AX=1) the packet has been copied to this location (DS:SI)\r
-; BX has client handle (stored in RX_ELEMENT.handle).\r
-; CX has # of bytes in packet on both call. They should be equal.\r
-; A test for equality is done by putting CX in _pktRxBuf [n].firstCount\r
-; and _pktRxBuf[n].secondCount, and CL on first call in\r
-; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive"\r
-; (PKTDRVR.C)\r
-;\r
-;---------------------------------------------------------------------\r
-\r
-_PktReceiver:\r
- pushf\r
- cli ; no distraction wanted !\r
- push ds\r
- push bx\r
- mov bx, cs\r
- mov ds, bx\r
- mov es, bx ; ES = DS = CS or seg _DATA\r
- pop bx ; restore handle\r
-\r
- cmp ax, 0 ; first call? (AX=0)\r
- jne @post ; AX=1: second call, do post process\r
-\r
-%ifdef DEBUG\r
- SHOW_RX ; show that a packet is received\r
-%endif\r
-\r
- cmp cx, ETH_MAX ; size OK ?\r
- ja @skip ; no, too big\r
-\r
- mov ax, [_rxInOfs]\r
- add ax, RX_SIZE\r
- cmp ax, LAST_OFS\r
- jb @noWrap\r
- mov ax, offset _pktRxBuf\r
-@noWrap:\r
- cmp ax, [_rxOutOfs]\r
- je @dump\r
- mov di, [_rxInOfs] ; ES:DI -> _pktRxBuf[n]\r
- mov [newInOffset], ax\r
-\r
- mov [di], cx ; remember firstCount.\r
- mov [di+4], bx ; remember handle.\r
- add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr\r
- pop ds\r
- popf\r
- retf ; far return to driver with ES:DI\r
-\r
-@dump: add word [_pktDrop+0], 1 ; discard the packet on 1st call\r
- adc word [_pktDrop+2], 0 ; increment packets lost\r
-\r
-@skip: xor di, di ; return ES:DI = NIL pointer\r
- xor ax, ax\r
- mov es, ax\r
- pop ds\r
- popf\r
- retf\r
-\r
-@post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr\r
- jz @discard ; make sure we don't use NULL-pointer\r
-\r
- ;\r
- ; push si\r
- ; call bpf_filter_match ; run the filter here some day\r
- ; pop si\r
- ; cmp ax, 0\r
- ; je @discard\r
-\r
- mov [si-6+2], cx ; store _pktRxBuf[n].secondCount\r
- mov ax, [newInOffset]\r
- mov [_rxInOfs], ax ; update _pktRxBuf input offset\r
-\r
- ; call PutTimeStamp\r
-\r
-@discard:\r
- pop ds\r
- popf\r
- retf\r
-\r
-_pktRxEnd db 0 ; marker for end of r-mode code/data\r
-\r
-END\r
-\r
+;
+; 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)
+%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
+
-/*\r
- * File.........: pktdrvr.c\r
- *\r
- *\r
- * Created......: 26.Sept 1995\r
- *\r
- * Description..: Packet-driver interface for 16/32-bit C :\r
- * Borland C/C++ 3.0+ small/large model\r
- * Watcom C/C++ 11+, DOS4GW flat model\r
- * Metaware HighC 3.1+ and PharLap 386|DosX\r
- * GNU C/C++ 2.7+ and djgpp 2.x extender\r
- *\r
- * References...: PC/TCP Packet driver Specification. rev 1.09\r
- * FTP Software Inc.\r
- *\r
- */\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <dos.h>\r
-\r
-#include "pcap-dos.h"\r
-#include "pcap-int.h"\r
-#include "msdos/pktdrvr.h"\r
-\r
-#if (DOSX)\r
-#define NUM_RX_BUF 32 /* # of buffers in Rx FIFO queue */\r
-#else\r
-#define NUM_RX_BUF 10\r
-#endif\r
-\r
-#define DIM(x) (sizeof((x)) / sizeof(x[0]))\r
-#define PUTS(s) do { \\r
- if (!pktInfo.quiet) \\r
- pktInfo.error ? \\r
- printf ("%s: %s\n", s, pktInfo.error) : \\r
- printf ("%s\n", pktInfo.error = s); \\r
- } while (0)\r
-\r
-#if defined(__HIGHC__)\r
- extern UINT _mwenv;\r
-\r
-#elif defined(__DJGPP__)\r
- #include <stddef.h>\r
- #include <dpmi.h>\r
- #include <go32.h>\r
- #include <pc.h>\r
- #include <sys/farptr.h>\r
-\r
-#elif defined(__WATCOMC__)\r
- #include <i86.h>\r
- #include <stddef.h>\r
- extern char _Extender;\r
-\r
-#else\r
- extern void far PktReceiver (void);\r
-#endif\r
-\r
-\r
-#if (DOSX & (DJGPP|DOS4GW))\r
- #include <sys/pack_on.h>\r
-\r
- struct DPMI_regs {\r
- DWORD r_di;\r
- DWORD r_si;\r
- DWORD r_bp;\r
- DWORD reserved;\r
- DWORD r_bx;\r
- DWORD r_dx;\r
- DWORD r_cx;\r
- DWORD r_ax;\r
- WORD r_flags;\r
- WORD r_es, r_ds, r_fs, r_gs;\r
- WORD r_ip, r_cs, r_sp, r_ss;\r
- };\r
-\r
- /* Data located in a real-mode segment. This becomes far at runtime\r
- */\r
- typedef struct { /* must match data/code in pkt_rx1.s */\r
- WORD _rxOutOfs;\r
- WORD _rxInOfs;\r
- DWORD _pktDrop;\r
- BYTE _pktTemp [20];\r
- TX_ELEMENT _pktTxBuf[1];\r
- RX_ELEMENT _pktRxBuf[NUM_RX_BUF];\r
- WORD _dummy[2]; /* screenSeg,newInOffset */\r
- BYTE _fanChars[4];\r
- WORD _fanIndex;\r
- BYTE _PktReceiver[15]; /* starts on a paragraph (16byte) */\r
- } PktRealStub;\r
- #include <sys/pack_off.h>\r
-\r
- static BYTE real_stub_array [] = {\r
- #include "pkt_stub.inc" /* generated opcode array */\r
- };\r
-\r
- #define rxOutOfs offsetof (PktRealStub,_rxOutOfs)\r
- #define rxInOfs offsetof (PktRealStub,_rxInOfs)\r
- #define PktReceiver offsetof (PktRealStub,_PktReceiver [para_skip])\r
- #define pktDrop offsetof (PktRealStub,_pktDrop)\r
- #define pktTemp offsetof (PktRealStub,_pktTemp)\r
- #define pktTxBuf offsetof (PktRealStub,_pktTxBuf)\r
- #define FIRST_RX_BUF offsetof (PktRealStub,_pktRxBuf [0])\r
- #define LAST_RX_BUF offsetof (PktRealStub,_pktRxBuf [NUM_RX_BUF-1])\r
-\r
-#else\r
- extern WORD rxOutOfs; /* offsets into pktRxBuf FIFO queue */\r
- extern WORD rxInOfs;\r
- extern DWORD pktDrop; /* # packets dropped in PktReceiver() */\r
- extern BYTE pktRxEnd; /* marks the end of r-mode code/data */\r
-\r
- extern RX_ELEMENT pktRxBuf [NUM_RX_BUF]; /* PktDrvr Rx buffers */\r
- extern TX_ELEMENT pktTxBuf; /* PktDrvr Tx buffer */\r
- extern char pktTemp[20]; /* PktDrvr temp area */\r
-\r
- #define FIRST_RX_BUF (WORD) &pktRxBuf [0]\r
- #define LAST_RX_BUF (WORD) &pktRxBuf [NUM_RX_BUF-1]\r
-#endif\r
-\r
-\r
-#ifdef __BORLANDC__ /* Use Borland's inline functions */\r
- #define memcpy __memcpy__\r
- #define memcmp __memcmp__\r
- #define memset __memset__\r
-#endif\r
-\r
-\r
-#if (DOSX & PHARLAP)\r
- extern void PktReceiver (void); /* in pkt_rx0.asm */\r
- static int RealCopy (ULONG, ULONG, REALPTR*, FARPTR*, USHORT*);\r
-\r
- #undef FP_SEG\r
- #undef FP_OFF\r
- #define FP_OFF(x) ((WORD)(x))\r
- #define FP_SEG(x) ((WORD)(realBase >> 16))\r
- #define DOS_ADDR(s,o) (((DWORD)(s) << 16) + (WORD)(o))\r
- #define r_ax eax\r
- #define r_bx ebx\r
- #define r_dx edx\r
- #define r_cx ecx\r
- #define r_si esi\r
- #define r_di edi\r
- #define r_ds ds\r
- #define r_es es\r
- LOCAL FARPTR protBase;\r
- LOCAL REALPTR realBase;\r
- LOCAL WORD realSeg; /* DOS para-address of allocated area */\r
- LOCAL SWI_REGS reg;\r
-\r
- static WORD _far *rxOutOfsFp, *rxInOfsFp;\r
-\r
-#elif (DOSX & DJGPP)\r
- static _go32_dpmi_seginfo rm_mem;\r
- static __dpmi_regs reg;\r
- static DWORD realBase;\r
- static int para_skip = 0;\r
-\r
- #define DOS_ADDR(s,o) (((WORD)(s) << 4) + (o))\r
- #define r_ax x.ax\r
- #define r_bx x.bx\r
- #define r_dx x.dx\r
- #define r_cx x.cx\r
- #define r_si x.si\r
- #define r_di x.di\r
- #define r_ds x.ds\r
- #define r_es x.es\r
-\r
-#elif (DOSX & DOS4GW)\r
- LOCAL struct DPMI_regs reg;\r
- LOCAL WORD rm_base_seg, rm_base_sel;\r
- LOCAL DWORD realBase;\r
- LOCAL int para_skip = 0;\r
-\r
- LOCAL DWORD dpmi_get_real_vector (int intr);\r
- LOCAL WORD dpmi_real_malloc (int size, WORD *selector);\r
- LOCAL void dpmi_real_free (WORD selector);\r
- #define DOS_ADDR(s,o) (((DWORD)(s) << 4) + (WORD)(o))\r
-\r
-#else /* real-mode Borland etc. */\r
- static struct {\r
- WORD r_ax, r_bx, r_cx, r_dx, r_bp;\r
- WORD r_si, r_di, r_ds, r_es, r_flags;\r
- } reg;\r
-#endif\r
-\r
-#ifdef __HIGHC__\r
- #pragma Alias (pktDrop, "_pktDrop")\r
- #pragma Alias (pktRxBuf, "_pktRxBuf")\r
- #pragma Alias (pktTxBuf, "_pktTxBuf")\r
- #pragma Alias (pktTemp, "_pktTemp")\r
- #pragma Alias (rxOutOfs, "_rxOutOfs")\r
- #pragma Alias (rxInOfs, "_rxInOfs")\r
- #pragma Alias (pktRxEnd, "_pktRxEnd")\r
- #pragma Alias (PktReceiver,"_PktReceiver")\r
-#endif\r
-\r
-\r
-PUBLIC PKT_STAT pktStat; /* statistics for packets */\r
-PUBLIC PKT_INFO pktInfo; /* packet-driver information */\r
-\r
-PUBLIC PKT_RX_MODE receiveMode = PDRX_DIRECT;\r
-PUBLIC ETHER myAddress = { 0, 0, 0, 0, 0, 0 };\r
-PUBLIC ETHER ethBroadcast = { 255,255,255,255,255,255 };\r
-\r
-LOCAL struct { /* internal statistics */\r
- DWORD tooSmall; /* size < ETH_MIN */\r
- DWORD tooLarge; /* size > ETH_MAX */\r
- DWORD badSync; /* count_1 != count_2 */\r
- DWORD wrongHandle; /* upcall to wrong handle */\r
- } intStat; \r
-\r
-/***************************************************************************/\r
-\r
-PUBLIC const char *PktGetErrorStr (int errNum)\r
-{\r
- static const char *errStr[] = {\r
- "",\r
- "Invalid handle number",\r
- "No interfaces of specified class found",\r
- "No interfaces of specified type found",\r
- "No interfaces of specified number found",\r
- "Bad packet type specified",\r
- "Interface does not support multicast",\r
- "Packet driver cannot terminate",\r
- "Invalid receiver mode specified",\r
- "Insufficient memory space",\r
- "Type previously accessed, and not released",\r
- "Command out of range, or not implemented",\r
- "Cannot send packet (usually hardware error)",\r
- "Cannot change hardware address ( > 1 handle open)",\r
- "Hardware address has bad length or format",\r
- "Cannot reset interface (more than 1 handle open)",\r
- "Bad Check-sum",\r
- "Bad size",\r
- "Bad sync" ,\r
- "Source hit"\r
- };\r
-\r
- if (errNum < 0 || errNum >= DIM(errStr))\r
- return ("Unknown driver error.");\r
- return (errStr [errNum]);\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-PUBLIC const char *PktGetClassName (WORD class)\r
-{\r
- switch (class)\r
- { \r
- case PD_ETHER:\r
- return ("DIX-Ether");\r
- case PD_PRONET10:\r
- return ("ProNET-10");\r
- case PD_IEEE8025:\r
- return ("IEEE 802.5");\r
- case PD_OMNINET:\r
- return ("OmniNet");\r
- case PD_APPLETALK:\r
- return ("AppleTalk");\r
- case PD_SLIP:\r
- return ("SLIP");\r
- case PD_STARTLAN:\r
- return ("StartLAN");\r
- case PD_ARCNET:\r
- return ("ArcNet");\r
- case PD_AX25:\r
- return ("AX.25");\r
- case PD_KISS:\r
- return ("KISS");\r
- case PD_IEEE8023_2:\r
- return ("IEEE 802.3 w/802.2 hdr");\r
- case PD_FDDI8022:\r
- return ("FDDI w/802.2 hdr");\r
- case PD_X25:\r
- return ("X.25");\r
- case PD_LANstar:\r
- return ("LANstar");\r
- case PD_PPP:\r
- return ("PPP");\r
- default:\r
- return ("unknown");\r
- }\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-PUBLIC char const *PktRXmodeStr (PKT_RX_MODE mode)\r
-{\r
- static const char *modeStr [] = {\r
- "Receiver turned off",\r
- "Receive only directly addressed packets",\r
- "Receive direct & broadcast packets",\r
- "Receive direct,broadcast and limited multicast packets",\r
- "Receive direct,broadcast and all multicast packets",\r
- "Receive all packets (promiscuouos mode)"\r
- };\r
-\r
- if (mode > DIM(modeStr))\r
- return ("??");\r
- return (modeStr [mode-1]);\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-LOCAL __inline BOOL PktInterrupt (void)\r
-{\r
- BOOL okay;\r
-\r
-#if (DOSX & PHARLAP)\r
- _dx_real_int ((UINT)pktInfo.intr, ®);\r
- okay = ((reg.flags & 1) == 0); /* OK if carry clear */\r
-\r
-#elif (DOSX & DJGPP)\r
- __dpmi_int ((int)pktInfo.intr, ®);\r
- okay = ((reg.x.flags & 1) == 0);\r
-\r
-#elif (DOSX & DOS4GW)\r
- union REGS r;\r
- struct SREGS s;\r
-\r
- memset (&r, 0, sizeof(r));\r
- segread (&s);\r
- r.w.ax = 0x300;\r
- r.x.ebx = pktInfo.intr;\r
- r.w.cx = 0;\r
- s.es = FP_SEG (®);\r
- r.x.edi = FP_OFF (®);\r
- reg.r_flags = 0;\r
- reg.r_ss = reg.r_sp = 0; /* DPMI host provides stack */\r
-\r
- int386x (0x31, &r, &r, &s);\r
- okay = (!r.w.cflag);\r
-\r
-#else\r
- reg.r_flags = 0;\r
- intr (pktInfo.intr, (struct REGPACK*)®);\r
- okay = ((reg.r_flags & 1) == 0);\r
-#endif\r
-\r
- if (okay)\r
- pktInfo.error = NULL;\r
- else pktInfo.error = PktGetErrorStr (reg.r_dx >> 8);\r
- return (okay);\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-/*\r
- * Search for packet driver at interrupt 60h through 80h. If ASCIIZ\r
- * string "PKT DRVR" found at offset 3 in the interrupt handler, return\r
- * interrupt number, else return zero in pktInfo.intr\r
- */\r
-PUBLIC BOOL PktSearchDriver (void)\r
-{\r
- BYTE intr = 0x20;\r
- BOOL found = FALSE;\r
-\r
- while (!found && intr < 0xFF)\r
- {\r
- static char str[12]; /* 3 + strlen("PKT DRVR") */\r
- static char pktStr[9] = "PKT DRVR"; /* ASCIIZ string at ofs 3 */\r
- DWORD rp; /* in interrupt routine */\r
-\r
-#if (DOSX & PHARLAP)\r
- _dx_rmiv_get (intr, &rp);\r
- ReadRealMem (&str, (REALPTR)rp, sizeof(str));\r
-\r
-#elif (DOSX & DJGPP)\r
- __dpmi_raddr realAdr;\r
- __dpmi_get_real_mode_interrupt_vector (intr, &realAdr);\r
- rp = (realAdr.segment << 4) + realAdr.offset16;\r
- dosmemget (rp, sizeof(str), &str);\r
-\r
-#elif (DOSX & DOS4GW)\r
- rp = dpmi_get_real_vector (intr);\r
- memcpy (&str, (void*)rp, sizeof(str));\r
-\r
-#else\r
- _fmemcpy (&str, getvect(intr), sizeof(str));\r
-#endif\r
-\r
- found = memcmp (&str[3],&pktStr,sizeof(pktStr)) == 0;\r
- intr++;\r
- }\r
- pktInfo.intr = (found ? intr-1 : 0);\r
- return (found);\r
-}\r
-\r
-\r
-/**************************************************************************/\r
-\r
-static BOOL PktSetAccess (void)\r
-{\r
- reg.r_ax = 0x0200 + pktInfo.class;\r
- reg.r_bx = 0xFFFF;\r
- reg.r_dx = 0;\r
- reg.r_cx = 0;\r
-\r
-#if (DOSX & PHARLAP)\r
- reg.ds = 0;\r
- reg.esi = 0;\r
- reg.es = RP_SEG (realBase);\r
- reg.edi = (WORD) &PktReceiver;\r
-\r
-#elif (DOSX & DJGPP)\r
- reg.x.ds = 0;\r
- reg.x.si = 0;\r
- reg.x.es = rm_mem.rm_segment;\r
- reg.x.di = PktReceiver;\r
-\r
-#elif (DOSX & DOS4GW)\r
- reg.r_ds = 0;\r
- reg.r_si = 0;\r
- reg.r_es = rm_base_seg;\r
- reg.r_di = PktReceiver;\r
-\r
-#else\r
- reg.r_ds = 0;\r
- reg.r_si = 0;\r
- reg.r_es = FP_SEG (&PktReceiver);\r
- reg.r_di = FP_OFF (&PktReceiver);\r
-#endif\r
-\r
- if (!PktInterrupt())\r
- return (FALSE);\r
-\r
- pktInfo.handle = reg.r_ax;\r
- return (TRUE);\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-PUBLIC BOOL PktReleaseHandle (WORD handle)\r
-{\r
- reg.r_ax = 0x0300;\r
- reg.r_bx = handle;\r
- return PktInterrupt();\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-PUBLIC BOOL PktTransmit (const void *eth, int len)\r
-{\r
- if (len > ETH_MTU)\r
- return (FALSE);\r
-\r
- reg.r_ax = 0x0400; /* Function 4, send pkt */\r
- reg.r_cx = len; /* total size of frame */\r
-\r
-#if (DOSX & DJGPP)\r
- dosmemput (eth, len, realBase+pktTxBuf);\r
- reg.x.ds = rm_mem.rm_segment; /* DOS data segment and */\r
- reg.x.si = pktTxBuf; /* DOS offset to buffer */\r
-\r
-#elif (DOSX & DOS4GW)\r
- memcpy ((void*)(realBase+pktTxBuf), eth, len);\r
- reg.r_ds = rm_base_seg;\r
- reg.r_si = pktTxBuf;\r
-\r
-#elif (DOSX & PHARLAP)\r
- memcpy (&pktTxBuf, eth, len);\r
- reg.r_ds = FP_SEG (&pktTxBuf);\r
- reg.r_si = FP_OFF (&pktTxBuf);\r
-\r
-#else\r
- reg.r_ds = FP_SEG (eth);\r
- reg.r_si = FP_OFF (eth);\r
-#endif\r
-\r
- return PktInterrupt();\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-#if (DOSX & (DJGPP|DOS4GW))\r
-LOCAL __inline BOOL CheckElement (RX_ELEMENT *rx)\r
-#else\r
-LOCAL __inline BOOL CheckElement (RX_ELEMENT _far *rx)\r
-#endif\r
-{\r
- WORD count_1, count_2;\r
-\r
- /*\r
- * We got an upcall to the same RMCB with wrong handle.\r
- * This can happen if we failed to release handle at program exit\r
- */\r
- if (rx->handle != pktInfo.handle)\r
- {\r
- pktInfo.error = "Wrong handle";\r
- intStat.wrongHandle++;\r
- PktReleaseHandle (rx->handle);\r
- return (FALSE);\r
- }\r
- count_1 = rx->firstCount;\r
- count_2 = rx->secondCount;\r
-\r
- if (count_1 != count_2)\r
- {\r
- pktInfo.error = "Bad sync";\r
- intStat.badSync++;\r
- return (FALSE);\r
- }\r
- if (count_1 > ETH_MAX)\r
- {\r
- pktInfo.error = "Large esize";\r
- intStat.tooLarge++;\r
- return (FALSE);\r
- }\r
-#if 0\r
- if (count_1 < ETH_MIN)\r
- {\r
- pktInfo.error = "Small esize";\r
- intStat.tooSmall++;\r
- return (FALSE);\r
- }\r
-#endif\r
- return (TRUE);\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-PUBLIC BOOL PktTerminHandle (WORD handle)\r
-{\r
- reg.r_ax = 0x0500;\r
- reg.r_bx = handle;\r
- return PktInterrupt();\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-PUBLIC BOOL PktResetInterface (WORD handle)\r
-{\r
- reg.r_ax = 0x0700;\r
- reg.r_bx = handle;\r
- return PktInterrupt();\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-PUBLIC BOOL PktSetReceiverMode (PKT_RX_MODE mode)\r
-{\r
- if (pktInfo.class == PD_SLIP || pktInfo.class == PD_PPP)\r
- return (TRUE);\r
-\r
- reg.r_ax = 0x1400;\r
- reg.r_bx = pktInfo.handle;\r
- reg.r_cx = (WORD)mode;\r
-\r
- if (!PktInterrupt())\r
- return (FALSE);\r
-\r
- receiveMode = mode;\r
- return (TRUE);\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-PUBLIC BOOL PktGetReceiverMode (PKT_RX_MODE *mode)\r
-{\r
- reg.r_ax = 0x1500;\r
- reg.r_bx = pktInfo.handle;\r
-\r
- if (!PktInterrupt())\r
- return (FALSE);\r
-\r
- *mode = reg.r_ax;\r
- return (TRUE);\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-static PKT_STAT initialStat; /* statistics at startup */\r
-static BOOL resetStat = FALSE; /* statistics reset ? */\r
-\r
-PUBLIC BOOL PktGetStatistics (WORD handle)\r
-{\r
- reg.r_ax = 0x1800;\r
- reg.r_bx = handle;\r
-\r
- if (!PktInterrupt())\r
- return (FALSE);\r
-\r
-#if (DOSX & PHARLAP)\r
- ReadRealMem (&pktStat, DOS_ADDR(reg.ds,reg.esi), sizeof(pktStat));\r
-\r
-#elif (DOSX & DJGPP)\r
- dosmemget (DOS_ADDR(reg.x.ds,reg.x.si), sizeof(pktStat), &pktStat);\r
-\r
-#elif (DOSX & DOS4GW)\r
- memcpy (&pktStat, (void*)DOS_ADDR(reg.r_ds,reg.r_si), sizeof(pktStat));\r
-\r
-#else\r
- _fmemcpy (&pktStat, MK_FP(reg.r_ds,reg.r_si), sizeof(pktStat));\r
-#endif\r
-\r
- return (TRUE);\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-PUBLIC BOOL PktSessStatistics (WORD handle)\r
-{\r
- if (!PktGetStatistics(pktInfo.handle))\r
- return (FALSE);\r
-\r
- if (resetStat)\r
- {\r
- pktStat.inPackets -= initialStat.inPackets;\r
- pktStat.outPackets -= initialStat.outPackets;\r
- pktStat.inBytes -= initialStat.inBytes;\r
- pktStat.outBytes -= initialStat.outBytes;\r
- pktStat.inErrors -= initialStat.inErrors;\r
- pktStat.outErrors -= initialStat.outErrors;\r
- pktStat.outErrors -= initialStat.outErrors;\r
- pktStat.lost -= initialStat.lost;\r
- }\r
- return (TRUE);\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-PUBLIC BOOL PktResetStatistics (WORD handle)\r
-{\r
- if (!PktGetStatistics(pktInfo.handle))\r
- return (FALSE);\r
-\r
- memcpy (&initialStat, &pktStat, sizeof(initialStat));\r
- resetStat = TRUE;\r
- return (TRUE);\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-PUBLIC BOOL PktGetAddress (ETHER *addr)\r
-{\r
- reg.r_ax = 0x0600;\r
- reg.r_bx = pktInfo.handle;\r
- reg.r_cx = sizeof (*addr);\r
-\r
-#if (DOSX & DJGPP)\r
- reg.x.es = rm_mem.rm_segment;\r
- reg.x.di = pktTemp;\r
-#elif (DOSX & DOS4GW)\r
- reg.r_es = rm_base_seg;\r
- reg.r_di = pktTemp;\r
-#else\r
- reg.r_es = FP_SEG (&pktTemp);\r
- reg.r_di = FP_OFF (&pktTemp); /* ES:DI = address for result */\r
-#endif\r
-\r
- if (!PktInterrupt())\r
- return (FALSE);\r
-\r
-#if (DOSX & PHARLAP)\r
- ReadRealMem (addr, realBase + (WORD)&pktTemp, sizeof(*addr));\r
-\r
-#elif (DOSX & DJGPP)\r
- dosmemget (realBase+pktTemp, sizeof(*addr), addr);\r
-\r
-#elif (DOSX & DOS4GW)\r
- memcpy (addr, (void*)(realBase+pktTemp), sizeof(*addr));\r
-\r
-#else\r
- memcpy ((void*)addr, &pktTemp, sizeof(*addr));\r
-#endif\r
-\r
- return (TRUE);\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-PUBLIC BOOL PktSetAddress (const ETHER *addr)\r
-{\r
- /* copy addr to real-mode scrath area */\r
-\r
-#if (DOSX & PHARLAP)\r
- WriteRealMem (realBase + (WORD)&pktTemp, (void*)addr, sizeof(*addr));\r
-\r
-#elif (DOSX & DJGPP)\r
- dosmemput (addr, sizeof(*addr), realBase+pktTemp);\r
-\r
-#elif (DOSX & DOS4GW)\r
- memcpy ((void*)(realBase+pktTemp), addr, sizeof(*addr));\r
-\r
-#else\r
- memcpy (&pktTemp, (void*)addr, sizeof(*addr));\r
-#endif\r
-\r
- reg.r_ax = 0x1900;\r
- reg.r_cx = sizeof (*addr); /* address length */\r
-\r
-#if (DOSX & DJGPP)\r
- reg.x.es = rm_mem.rm_segment; /* DOS offset to param */\r
- reg.x.di = pktTemp; /* DOS segment to param */\r
-#elif (DOSX & DOS4GW)\r
- reg.r_es = rm_base_seg;\r
- reg.r_di = pktTemp;\r
-#else\r
- reg.r_es = FP_SEG (&pktTemp);\r
- reg.r_di = FP_OFF (&pktTemp);\r
-#endif\r
-\r
- return PktInterrupt();\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-PUBLIC BOOL PktGetDriverInfo (void)\r
-{\r
- pktInfo.majVer = 0;\r
- pktInfo.minVer = 0;\r
- memset (&pktInfo.name, 0, sizeof(pktInfo.name));\r
- reg.r_ax = 0x01FF;\r
- reg.r_bx = 0;\r
-\r
- if (!PktInterrupt())\r
- return (FALSE);\r
-\r
- pktInfo.number = reg.r_cx & 0xFF;\r
- pktInfo.class = reg.r_cx >> 8;\r
-#if 0\r
- pktInfo.minVer = reg.r_bx % 10;\r
- pktInfo.majVer = reg.r_bx / 10;\r
-#else\r
- pktInfo.majVer = reg.r_bx; // !!\r
-#endif\r
- pktInfo.funcs = reg.r_ax & 0xFF;\r
- pktInfo.type = reg.r_dx & 0xFF;\r
-\r
-#if (DOSX & PHARLAP)\r
- ReadRealMem (&pktInfo.name, DOS_ADDR(reg.ds,reg.esi), sizeof(pktInfo.name));\r
-\r
-#elif (DOSX & DJGPP)\r
- dosmemget (DOS_ADDR(reg.x.ds,reg.x.si), sizeof(pktInfo.name), &pktInfo.name);\r
-\r
-#elif (DOSX & DOS4GW)\r
- memcpy (&pktInfo.name, (void*)DOS_ADDR(reg.r_ds,reg.r_si), sizeof(pktInfo.name));\r
-\r
-#else\r
- _fmemcpy (&pktInfo.name, MK_FP(reg.r_ds,reg.r_si), sizeof(pktInfo.name));\r
-#endif\r
- return (TRUE);\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-PUBLIC BOOL PktGetDriverParam (void)\r
-{\r
- reg.r_ax = 0x0A00;\r
-\r
- if (!PktInterrupt())\r
- return (FALSE);\r
-\r
-#if (DOSX & PHARLAP)\r
- ReadRealMem (&pktInfo.majVer, DOS_ADDR(reg.es,reg.edi), PKT_PARAM_SIZE);\r
-\r
-#elif (DOSX & DJGPP)\r
- dosmemget (DOS_ADDR(reg.x.es,reg.x.di), PKT_PARAM_SIZE, &pktInfo.majVer);\r
-\r
-#elif (DOSX & DOS4GW)\r
- memcpy (&pktInfo.majVer, (void*)DOS_ADDR(reg.r_es,reg.r_di), PKT_PARAM_SIZE);\r
-\r
-#else\r
- _fmemcpy (&pktInfo.majVer, MK_FP(reg.r_es,reg.r_di), PKT_PARAM_SIZE);\r
-#endif\r
- return (TRUE);\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-#if (DOSX & PHARLAP)\r
- PUBLIC int PktReceive (BYTE *buf, int max)\r
- {\r
- WORD inOfs = *rxInOfsFp;\r
- WORD outOfs = *rxOutOfsFp;\r
-\r
- if (outOfs != inOfs)\r
- {\r
- RX_ELEMENT _far *head = (RX_ELEMENT _far*)(protBase+outOfs);\r
- int size, len = max;\r
-\r
- if (CheckElement(head))\r
- {\r
- size = min (head->firstCount, sizeof(RX_ELEMENT));\r
- len = min (size, max);\r
- _fmemcpy (buf, &head->destin, len);\r
- }\r
- else\r
- size = -1;\r
-\r
- outOfs += sizeof (RX_ELEMENT);\r
- if (outOfs > LAST_RX_BUF)\r
- outOfs = FIRST_RX_BUF;\r
- *rxOutOfsFp = outOfs;\r
- return (size);\r
- }\r
- return (0);\r
- }\r
-\r
- PUBLIC void PktQueueBusy (BOOL busy)\r
- {\r
- *rxOutOfsFp = busy ? (*rxInOfsFp + sizeof(RX_ELEMENT)) : *rxInOfsFp;\r
- if (*rxOutOfsFp > LAST_RX_BUF)\r
- *rxOutOfsFp = FIRST_RX_BUF;\r
- *(DWORD _far*)(protBase + (WORD)&pktDrop) = 0;\r
- }\r
-\r
- PUBLIC WORD PktBuffersUsed (void)\r
- {\r
- WORD inOfs = *rxInOfsFp;\r
- WORD outOfs = *rxOutOfsFp;\r
-\r
- if (inOfs >= outOfs)\r
- return (inOfs - outOfs) / sizeof(RX_ELEMENT);\r
- return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));\r
- }\r
-\r
- PUBLIC DWORD PktRxDropped (void)\r
- {\r
- return (*(DWORD _far*)(protBase + (WORD)&pktDrop));\r
- }\r
-\r
-#elif (DOSX & DJGPP)\r
- PUBLIC int PktReceive (BYTE *buf, int max)\r
- {\r
- WORD ofs = _farpeekw (_dos_ds, realBase+rxOutOfs);\r
-\r
- if (ofs != _farpeekw (_dos_ds, realBase+rxInOfs))\r
- {\r
- RX_ELEMENT head;\r
- int size, len = max;\r
-\r
- head.firstCount = _farpeekw (_dos_ds, realBase+ofs);\r
- head.secondCount = _farpeekw (_dos_ds, realBase+ofs+2);\r
- head.handle = _farpeekw (_dos_ds, realBase+ofs+4);\r
-\r
- if (CheckElement(&head))\r
- {\r
- size = min (head.firstCount, sizeof(RX_ELEMENT));\r
- len = min (size, max);\r
- dosmemget (realBase+ofs+6, len, buf);\r
- }\r
- else\r
- size = -1;\r
-\r
- ofs += sizeof (RX_ELEMENT);\r
- if (ofs > LAST_RX_BUF)\r
- _farpokew (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF);\r
- else _farpokew (_dos_ds, realBase+rxOutOfs, ofs);\r
- return (size);\r
- }\r
- return (0);\r
- }\r
-\r
- PUBLIC void PktQueueBusy (BOOL busy)\r
- {\r
- WORD ofs;\r
-\r
- disable();\r
- ofs = _farpeekw (_dos_ds, realBase+rxInOfs);\r
- if (busy)\r
- ofs += sizeof (RX_ELEMENT);\r
-\r
- if (ofs > LAST_RX_BUF)\r
- _farpokew (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF);\r
- else _farpokew (_dos_ds, realBase+rxOutOfs, ofs);\r
- _farpokel (_dos_ds, realBase+pktDrop, 0UL);\r
- enable();\r
- }\r
-\r
- PUBLIC WORD PktBuffersUsed (void)\r
- {\r
- WORD inOfs, outOfs;\r
-\r
- disable();\r
- inOfs = _farpeekw (_dos_ds, realBase+rxInOfs);\r
- outOfs = _farpeekw (_dos_ds, realBase+rxOutOfs);\r
- enable();\r
- if (inOfs >= outOfs)\r
- return (inOfs - outOfs) / sizeof(RX_ELEMENT);\r
- return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));\r
- }\r
-\r
- PUBLIC DWORD PktRxDropped (void)\r
- {\r
- return _farpeekl (_dos_ds, realBase+pktDrop);\r
- }\r
-\r
-#elif (DOSX & DOS4GW)\r
- PUBLIC int PktReceive (BYTE *buf, int max)\r
- {\r
- WORD ofs = *(WORD*) (realBase+rxOutOfs);\r
-\r
- if (ofs != *(WORD*) (realBase+rxInOfs))\r
- {\r
- RX_ELEMENT head;\r
- int size, len = max;\r
-\r
- head.firstCount = *(WORD*) (realBase+ofs);\r
- head.secondCount = *(WORD*) (realBase+ofs+2);\r
- head.handle = *(WORD*) (realBase+ofs+4);\r
-\r
- if (CheckElement(&head))\r
- {\r
- size = min (head.firstCount, sizeof(RX_ELEMENT));\r
- len = min (size, max);\r
- memcpy (buf, (const void*)(realBase+ofs+6), len);\r
- }\r
- else\r
- size = -1;\r
-\r
- ofs += sizeof (RX_ELEMENT);\r
- if (ofs > LAST_RX_BUF)\r
- *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF;\r
- else *(WORD*) (realBase+rxOutOfs) = ofs;\r
- return (size);\r
- }\r
- return (0);\r
- }\r
-\r
- PUBLIC void PktQueueBusy (BOOL busy)\r
- {\r
- WORD ofs;\r
-\r
- _disable();\r
- ofs = *(WORD*) (realBase+rxInOfs);\r
- if (busy)\r
- ofs += sizeof (RX_ELEMENT);\r
-\r
- if (ofs > LAST_RX_BUF)\r
- *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF;\r
- else *(WORD*) (realBase+rxOutOfs) = ofs;\r
- *(DWORD*) (realBase+pktDrop) = 0UL;\r
- _enable();\r
- }\r
-\r
- PUBLIC WORD PktBuffersUsed (void)\r
- {\r
- WORD inOfs, outOfs;\r
-\r
- _disable();\r
- inOfs = *(WORD*) (realBase+rxInOfs);\r
- outOfs = *(WORD*) (realBase+rxOutOfs);\r
- _enable();\r
- if (inOfs >= outOfs)\r
- return (inOfs - outOfs) / sizeof(RX_ELEMENT);\r
- return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));\r
- }\r
-\r
- PUBLIC DWORD PktRxDropped (void)\r
- {\r
- return *(DWORD*) (realBase+pktDrop);\r
- }\r
-\r
-#else /* real-mode small/large model */\r
-\r
- PUBLIC int PktReceive (BYTE *buf, int max)\r
- {\r
- if (rxOutOfs != rxInOfs)\r
- {\r
- RX_ELEMENT far *head = (RX_ELEMENT far*) MK_FP (_DS,rxOutOfs);\r
- int size, len = max;\r
-\r
- if (CheckElement(head))\r
- {\r
- size = min (head->firstCount, sizeof(RX_ELEMENT));\r
- len = min (size, max);\r
- _fmemcpy (buf, &head->destin, len);\r
- }\r
- else\r
- size = -1;\r
-\r
- rxOutOfs += sizeof (RX_ELEMENT);\r
- if (rxOutOfs > LAST_RX_BUF)\r
- rxOutOfs = FIRST_RX_BUF;\r
- return (size);\r
- }\r
- return (0);\r
- }\r
-\r
- PUBLIC void PktQueueBusy (BOOL busy)\r
- {\r
- rxOutOfs = busy ? (rxInOfs + sizeof(RX_ELEMENT)) : rxInOfs;\r
- if (rxOutOfs > LAST_RX_BUF)\r
- rxOutOfs = FIRST_RX_BUF;\r
- pktDrop = 0L;\r
- }\r
-\r
- PUBLIC WORD PktBuffersUsed (void)\r
- {\r
- WORD inOfs = rxInOfs;\r
- WORD outOfs = rxOutOfs;\r
-\r
- if (inOfs >= outOfs)\r
- return ((inOfs - outOfs) / sizeof(RX_ELEMENT));\r
- return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));\r
- }\r
-\r
- PUBLIC DWORD PktRxDropped (void)\r
- {\r
- return (pktDrop);\r
- }\r
-#endif\r
-\r
-/**************************************************************************/\r
-\r
-LOCAL __inline void PktFreeMem (void)\r
-{\r
-#if (DOSX & PHARLAP)\r
- if (realSeg)\r
- {\r
- _dx_real_free (realSeg);\r
- realSeg = 0;\r
- }\r
-#elif (DOSX & DJGPP)\r
- if (rm_mem.rm_segment)\r
- {\r
- unsigned ofs; /* clear the DOS-mem to prevent further upcalls */\r
-\r
- for (ofs = 0; ofs < 16 * rm_mem.size / 4; ofs += 4)\r
- _farpokel (_dos_ds, realBase + ofs, 0);\r
- _go32_dpmi_free_dos_memory (&rm_mem);\r
- rm_mem.rm_segment = 0;\r
- }\r
-#elif (DOSX & DOS4GW)\r
- if (rm_base_sel)\r
- {\r
- dpmi_real_free (rm_base_sel);\r
- rm_base_sel = 0;\r
- }\r
-#endif\r
-}\r
-\r
-/**************************************************************************/\r
-\r
-PUBLIC BOOL PktExitDriver (void)\r
-{ \r
- if (pktInfo.handle)\r
- {\r
- if (!PktSetReceiverMode(PDRX_BROADCAST))\r
- PUTS ("Error restoring receiver mode.");\r
-\r
- if (!PktReleaseHandle(pktInfo.handle))\r
- PUTS ("Error releasing PKT-DRVR handle.");\r
-\r
- PktFreeMem();\r
- pktInfo.handle = 0;\r
- }\r
-\r
- if (pcap_pkt_debug >= 1)\r
- printf ("Internal stats: too-small %lu, too-large %lu, bad-sync %lu, "\r
- "wrong-handle %lu\n",\r
- intStat.tooSmall, intStat.tooLarge,\r
- intStat.badSync, intStat.wrongHandle);\r
- return (TRUE);\r
-}\r
-\r
-#if (DOSX & (DJGPP|DOS4GW))\r
-static void dump_pkt_stub (void)\r
-{\r
- int i;\r
-\r
- fprintf (stderr, "PktReceiver %lu, pkt_stub[PktReceiver] =\n",\r
- PktReceiver);\r
- for (i = 0; i < 15; i++)\r
- fprintf (stderr, "%02X, ", real_stub_array[i+PktReceiver]);\r
- fputs ("\n", stderr);\r
-}\r
-#endif\r
-\r
-/*\r
- * Front end initialization routine\r
- */\r
-PUBLIC BOOL PktInitDriver (PKT_RX_MODE mode)\r
-{\r
- PKT_RX_MODE rxMode;\r
- BOOL writeInfo = (pcap_pkt_debug >= 3);\r
-\r
- pktInfo.quiet = (pcap_pkt_debug < 3);\r
-\r
-#if (DOSX & PHARLAP) && defined(__HIGHC__)\r
- if (_mwenv != 2)\r
- {\r
- fprintf (stderr, "Only Pharlap DOS extender supported.\n");\r
- return (FALSE);\r
- }\r
-#endif\r
-\r
-#if (DOSX & PHARLAP) && defined(__WATCOMC__)\r
- if (_Extender != 1)\r
- {\r
- fprintf (stderr, "Only DOS4GW style extenders supported.\n");\r
- return (FALSE);\r
- }\r
-#endif\r
-\r
- if (!PktSearchDriver())\r
- {\r
- PUTS ("Packet driver not found.");\r
- PktFreeMem();\r
- return (FALSE);\r
- }\r
-\r
- if (!PktGetDriverInfo())\r
- {\r
- PUTS ("Error getting pkt-drvr information.");\r
- PktFreeMem();\r
- return (FALSE);\r
- }\r
-\r
-#if (DOSX & PHARLAP)\r
- if (RealCopy((ULONG)&rxOutOfs, (ULONG)&pktRxEnd,\r
- &realBase, &protBase, (USHORT*)&realSeg))\r
- {\r
- rxOutOfsFp = (WORD _far *) (protBase + (WORD) &rxOutOfs);\r
- rxInOfsFp = (WORD _far *) (protBase + (WORD) &rxInOfs);\r
- *rxOutOfsFp = FIRST_RX_BUF;\r
- *rxInOfsFp = FIRST_RX_BUF;\r
- }\r
- else\r
- {\r
- PUTS ("Cannot allocate real-mode stub.");\r
- return (FALSE);\r
- }\r
-\r
-#elif (DOSX & (DJGPP|DOS4GW))\r
- if (sizeof(real_stub_array) > 0xFFFF)\r
- {\r
- fprintf (stderr, "`real_stub_array[]' too big.\n");\r
- return (FALSE);\r
- }\r
-#if (DOSX & DJGPP)\r
- rm_mem.size = (sizeof(real_stub_array) + 15) / 16;\r
-\r
- if (_go32_dpmi_allocate_dos_memory(&rm_mem) || rm_mem.rm_offset != 0)\r
- {\r
- PUTS ("real-mode init failed.");\r
- return (FALSE);\r
- }\r
- realBase = (rm_mem.rm_segment << 4);\r
- dosmemput (&real_stub_array, sizeof(real_stub_array), realBase);\r
- _farpokel (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF);\r
- _farpokel (_dos_ds, realBase+rxInOfs, FIRST_RX_BUF);\r
-\r
-#elif (DOSX & DOS4GW)\r
- rm_base_seg = dpmi_real_malloc (sizeof(real_stub_array), &rm_base_sel);\r
- if (!rm_base_seg)\r
- {\r
- PUTS ("real-mode init failed.");\r
- return (FALSE);\r
- }\r
- realBase = (rm_base_seg << 4);\r
- memcpy ((void*)realBase, &real_stub_array, sizeof(real_stub_array));\r
- *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF;\r
- *(WORD*) (realBase+rxInOfs) = FIRST_RX_BUF;\r
-\r
-#endif\r
- {\r
- int pushf = PktReceiver;\r
-\r
- while (real_stub_array[pushf++] != 0x9C && /* pushf */\r
- real_stub_array[pushf] != 0xFA) /* cli */\r
- {\r
- if (++para_skip > 16)\r
- {\r
- fprintf (stderr, "Something wrong with `pkt_stub.inc'.\n");\r
- para_skip = 0;\r
- dump_pkt_stub();\r
- return (FALSE);\r
- }\r
- }\r
- if (*(WORD*)(real_stub_array + offsetof(PktRealStub,_dummy)) != 0xB800)\r
- {\r
- fprintf (stderr, "`real_stub_array[]' is misaligned.\n");\r
- return (FALSE);\r
- }\r
- }\r
-\r
- if (pcap_pkt_debug > 2)\r
- dump_pkt_stub();\r
-\r
-#else\r
- rxOutOfs = FIRST_RX_BUF;\r
- rxInOfs = FIRST_RX_BUF;\r
-#endif\r
-\r
- if (!PktSetAccess())\r
- {\r
- PUTS ("Error setting pkt-drvr access.");\r
- PktFreeMem();\r
- return (FALSE);\r
- }\r
-\r
- if (!PktGetAddress(&myAddress))\r
- {\r
- PUTS ("Error fetching adapter address.");\r
- PktFreeMem();\r
- return (FALSE);\r
- }\r
-\r
- if (!PktSetReceiverMode(mode))\r
- {\r
- PUTS ("Error setting receiver mode.");\r
- PktFreeMem();\r
- return (FALSE);\r
- }\r
-\r
- if (!PktGetReceiverMode(&rxMode))\r
- {\r
- PUTS ("Error getting receiver mode.");\r
- PktFreeMem();\r
- return (FALSE);\r
- }\r
-\r
- if (writeInfo)\r
- printf ("Pkt-driver information:\n"\r
- " Version : %d.%d\n"\r
- " Name : %.15s\n"\r
- " Class : %u (%s)\n"\r
- " Type : %u\n"\r
- " Number : %u\n"\r
- " Funcs : %u\n"\r
- " Intr : %Xh\n"\r
- " Handle : %u\n"\r
- " Extended : %s\n"\r
- " Hi-perf : %s\n"\r
- " RX mode : %s\n"\r
- " Eth-addr : %02X:%02X:%02X:%02X:%02X:%02X\n",\r
-\r
- pktInfo.majVer, pktInfo.minVer, pktInfo.name,\r
- pktInfo.class, PktGetClassName(pktInfo.class),\r
- pktInfo.type, pktInfo.number,\r
- pktInfo.funcs, pktInfo.intr, pktInfo.handle,\r
- pktInfo.funcs == 2 || pktInfo.funcs == 6 ? "Yes" : "No",\r
- pktInfo.funcs == 5 || pktInfo.funcs == 6 ? "Yes" : "No",\r
- PktRXmodeStr(rxMode),\r
- myAddress[0], myAddress[1], myAddress[2],\r
- myAddress[3], myAddress[4], myAddress[5]);\r
-\r
-#if defined(DEBUG) && (DOSX & PHARLAP)\r
- if (writeInfo)\r
- {\r
- DWORD rAdr = realBase + (WORD)&PktReceiver;\r
- unsigned sel, ofs;\r
-\r
- printf ("\nReceiver at %04X:%04X\n", RP_SEG(rAdr), RP_OFF(rAdr));\r
- printf ("Realbase = %04X:%04X\n", RP_SEG(realBase),RP_OFF(realBase));\r
-\r
- sel = _FP_SEG (protBase);\r
- ofs = _FP_OFF (protBase);\r
- printf ("Protbase = %04X:%08X\n", sel,ofs);\r
- printf ("RealSeg = %04X\n", realSeg);\r
-\r
- sel = _FP_SEG (rxOutOfsFp);\r
- ofs = _FP_OFF (rxOutOfsFp);\r
- printf ("rxOutOfsFp = %04X:%08X\n", sel,ofs);\r
-\r
- sel = _FP_SEG (rxInOfsFp);\r
- ofs = _FP_OFF (rxInOfsFp);\r
- printf ("rxInOfsFp = %04X:%08X\n", sel,ofs);\r
-\r
- printf ("Ready: *rxOutOfsFp = %04X *rxInOfsFp = %04X\n",\r
- *rxOutOfsFp, *rxInOfsFp);\r
-\r
- PktQueueBusy (TRUE);\r
- printf ("Busy: *rxOutOfsFp = %04X *rxInOfsFp = %04X\n",\r
- *rxOutOfsFp, *rxInOfsFp);\r
- }\r
-#endif\r
-\r
- memset (&pktStat, 0, sizeof(pktStat)); /* clear statistics */\r
- PktQueueBusy (TRUE);\r
- return (TRUE);\r
-}\r
-\r
-\r
-/*\r
- * DPMI functions only for Watcom + DOS4GW extenders\r
- */\r
-#if (DOSX & DOS4GW)\r
-LOCAL DWORD dpmi_get_real_vector (int intr)\r
-{\r
- union REGS r;\r
-\r
- r.x.eax = 0x200;\r
- r.x.ebx = (DWORD) intr;\r
- int386 (0x31, &r, &r);\r
- return ((r.w.cx << 4) + r.w.dx);\r
-}\r
-\r
-LOCAL WORD dpmi_real_malloc (int size, WORD *selector)\r
-{\r
- union REGS r;\r
-\r
- r.x.eax = 0x0100; /* DPMI allocate DOS memory */\r
- r.x.ebx = (size + 15) / 16; /* Number of paragraphs requested */\r
- int386 (0x31, &r, &r);\r
- if (r.w.cflag & 1)\r
- return (0);\r
-\r
- *selector = r.w.dx;\r
- return (r.w.ax); /* Return segment address */\r
-}\r
-\r
-LOCAL void dpmi_real_free (WORD selector)\r
-{\r
- union REGS r;\r
-\r
- r.x.eax = 0x101; /* DPMI free DOS memory */\r
- r.x.ebx = selector; /* Selector to free */\r
- int386 (0x31, &r, &r);\r
-}\r
-#endif\r
-\r
-\r
-#if defined(DOSX) && (DOSX & PHARLAP)\r
-/*\r
- * Description:\r
- * This routine allocates conventional memory for the specified block\r
- * of code (which must be within the first 64K of the protected mode\r
- * program segment) and copies the code to it.\r
- *\r
- * The caller should free up the conventional memory block when it\r
- * is done with the conventional memory.\r
- *\r
- * NOTE THIS ROUTINE REQUIRES 386|DOS-EXTENDER 3.0 OR LATER.\r
- *\r
- * Calling arguments:\r
- * start_offs start of real mode code in program segment\r
- * end_offs 1 byte past end of real mode code in program segment\r
- * real_basep returned; real mode ptr to use as a base for the\r
- * real mode code (eg, to get the real mode FAR\r
- * addr of a function foo(), take\r
- * real_basep + (ULONG) foo).\r
- * This pointer is constructed such that\r
- * offsets within the real mode segment are\r
- * the same as the link-time offsets in the\r
- * protected mode program segment\r
- * prot_basep returned; prot mode ptr to use as a base for getting\r
- * to the conventional memory, also constructed\r
- * so that adding the prot mode offset of a\r
- * function or variable to the base gets you a\r
- * ptr to the function or variable in the\r
- * conventional memory block.\r
- * rmem_adrp returned; real mode para addr of allocated\r
- * conventional memory block, to be used to free\r
- * up the conventional memory when done. DO NOT\r
- * USE THIS TO CONSTRUCT A REAL MODE PTR, USE\r
- * REAL_BASEP INSTEAD SO THAT OFFSETS WORK OUT\r
- * CORRECTLY.\r
- *\r
- * Returned values:\r
- * 0 if error\r
- * 1 if success\r
- */\r
-int RealCopy (ULONG start_offs,\r
- ULONG end_offs,\r
- REALPTR *real_basep,\r
- FARPTR *prot_basep,\r
- USHORT *rmem_adrp)\r
-{\r
- ULONG rm_base; /* base real mode para addr for accessing */\r
- /* allocated conventional memory */\r
- UCHAR *source; /* source pointer for copy */\r
- FARPTR destin; /* destination pointer for copy */\r
- ULONG len; /* number of bytes to copy */\r
- ULONG temp;\r
- USHORT stemp;\r
-\r
- /* First check for valid inputs\r
- */\r
- if (start_offs >= end_offs || end_offs > 0x10000)\r
- return (FALSE);\r
-\r
- /* Round start_offs down to a paragraph (16-byte) boundary so we can set up\r
- * the real mode pointer easily. Round up end_offs to make sure we allocate\r
- * enough paragraphs\r
- */\r
- start_offs &= ~15;\r
- end_offs = (15 + (end_offs << 4)) >> 4;\r
-\r
- /* Allocate the conventional memory for our real mode code. Remember to\r
- * round byte count UP to 16-byte paragraph size. We alloc it\r
- * above the DOS data buffer so both the DOS data buffer and the appl\r
- * conventional mem block can still be resized.\r
- *\r
- * First just try to alloc it; if we can't get it, shrink the appl mem\r
- * block down to the minimum, try to alloc the memory again, then grow the\r
- * appl mem block back to the maximum. (Don't try to shrink the DOS data\r
- * buffer to free conventional memory; it wouldn't be good for this routine\r
- * to have the possible side effect of making file I/O run slower.)\r
- */\r
- len = ((end_offs - start_offs) + 15) >> 4;\r
- if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE)\r
- {\r
- if (_dx_cmem_usage(0, 0, &temp, &temp) != _DOSE_NONE)\r
- return (FALSE);\r
-\r
- if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE)\r
- *rmem_adrp = 0;\r
-\r
- if (_dx_cmem_usage(0, 1, &temp, &temp) != _DOSE_NONE)\r
- {\r
- if (*rmem_adrp != 0)\r
- _dx_real_free (*rmem_adrp);\r
- return (FALSE);\r
- }\r
-\r
- if (*rmem_adrp == 0)\r
- return (FALSE);\r
- }\r
-\r
- /* Construct real mode & protected mode pointers to access the allocated\r
- * memory. Note we know start_offs is aligned on a paragraph (16-byte)\r
- * boundary, because we rounded it down.\r
- *\r
- * We make the offsets come out rights by backing off the real mode selector\r
- * by start_offs.\r
- */\r
- rm_base = ((ULONG) *rmem_adrp) - (start_offs >> 4);\r
- RP_SET (*real_basep, 0, rm_base);\r
- FP_SET (*prot_basep, rm_base << 4, SS_DOSMEM);\r
-\r
- /* Copy the real mode code/data to the allocated memory\r
- */\r
- source = (UCHAR *) start_offs;\r
- destin = *prot_basep;\r
- FP_SET (destin, FP_OFF(*prot_basep) + start_offs, FP_SEL(*prot_basep));\r
- len = end_offs - start_offs;\r
- WriteFarMem (destin, source, len);\r
-\r
- return (TRUE);\r
-}\r
-#endif /* DOSX && (DOSX & PHARLAP) */\r
+/*
+ * File.........: pktdrvr.c
+ *
+ *
+ * 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, ®);
+ okay = ((reg.flags & 1) == 0); /* OK if carry clear */
+
+#elif (DOSX & DJGPP)
+ __dpmi_int ((int)pktInfo.intr, ®);
+ 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 (®);
+ r.x.edi = FP_OFF (®);
+ 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*)®);
+ 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) */
-#ifndef __PKTDRVR_H\r
-#define __PKTDRVR_H\r
-\r
-#define PUBLIC\r
-#define LOCAL static\r
-\r
-#define RX_BUF_SIZE ETH_MTU /* buffer size variables. NB !! */\r
-#define TX_BUF_SIZE ETH_MTU /* must be same as in pkt_rx*.* */\r
-\r
-#ifdef __HIGHC__\r
-#pragma Off(Align_members)\r
-#else\r
-#pragma pack(1)\r
-#endif\r
-\r
-typedef enum { /* Packet-driver classes */\r
- PD_ETHER = 1,\r
- PD_PRONET10 = 2,\r
- PD_IEEE8025 = 3,\r
- PD_OMNINET = 4,\r
- PD_APPLETALK = 5,\r
- PD_SLIP = 6,\r
- PD_STARTLAN = 7,\r
- PD_ARCNET = 8,\r
- PD_AX25 = 9,\r
- PD_KISS = 10,\r
- PD_IEEE8023_2 = 11,\r
- PD_FDDI8022 = 12,\r
- PD_X25 = 13,\r
- PD_LANstar = 14,\r
- PD_PPP = 18\r
- } PKT_CLASS;\r
-\r
-typedef enum { /* Packet-driver receive modes */\r
- PDRX_OFF = 1, /* turn off receiver */\r
- PDRX_DIRECT, /* receive only to this interface */\r
- PDRX_BROADCAST, /* DIRECT + broadcast packets */\r
- PDRX_MULTICAST1, /* BROADCAST + limited multicast */\r
- PDRX_MULTICAST2, /* BROADCAST + all multicast */\r
- PDRX_ALL_PACKETS, /* receive all packets on network */\r
- } PKT_RX_MODE;\r
-\r
-typedef struct {\r
- char type[8];\r
- char len;\r
- } PKT_FRAME;\r
-\r
-\r
-typedef struct {\r
- BYTE class; /* = 1 for DEC/Interl/Xerox Ethernet */\r
- BYTE number; /* = 0 for single LAN adapter */\r
- WORD type; /* = 13 for 3C523 */\r
- BYTE funcs; /* Basic/Extended/HiPerf functions */\r
- WORD intr; /* user interrupt vector number */\r
- WORD handle; /* Handle associated with session */\r
- BYTE name [15]; /* Name of adapter interface,ie.3C523*/\r
- BOOL quiet; /* (don't) print errors to stdout */\r
- const char *error; /* address of error string */\r
- BYTE majVer; /* Major driver implementation ver. */\r
- BYTE minVer; /* Minor driver implementation ver. */\r
- BYTE dummyLen; /* length of following data */\r
- WORD MAClength; /* HiPerformance data, N/A */\r
- WORD MTU; /* HiPerformance data, N/A */\r
- WORD multicast; /* HiPerformance data, N/A */\r
- WORD rcvrBuffers; /* valid for */\r
- WORD UMTbufs; /* High Performance drivers only */\r
- WORD postEOIintr; /* Usage ?? */\r
- } PKT_INFO;\r
-\r
-#define PKT_PARAM_SIZE 14 /* members majVer - postEOIintr */\r
-\r
-\r
-typedef struct {\r
- DWORD inPackets; /* # of packets received */\r
- DWORD outPackets; /* # of packets transmitted */\r
- DWORD inBytes; /* # of bytes received */\r
- DWORD outBytes; /* # of bytes transmitted */\r
- DWORD inErrors; /* # of reception errors */\r
- DWORD outErrors; /* # of transmission errors */\r
- DWORD lost; /* # of packets lost (RX) */\r
- } PKT_STAT;\r
- \r
-\r
-typedef struct {\r
- ETHER destin;\r
- ETHER source;\r
- WORD proto;\r
- BYTE data [TX_BUF_SIZE];\r
- } TX_ELEMENT;\r
-\r
-typedef struct {\r
- WORD firstCount; /* # of bytes on 1st */\r
- WORD secondCount; /* and 2nd upcall */\r
- WORD handle; /* instance that upcalled */\r
- ETHER destin; /* E-net destination address */\r
- ETHER source; /* E-net source address */\r
- WORD proto; /* protocol number */\r
- BYTE data [RX_BUF_SIZE];\r
- } RX_ELEMENT;\r
-\r
-\r
-#ifdef __HIGHC__\r
-#pragma pop(Align_members)\r
-#else\r
-#pragma pack()\r
-#endif\r
-\r
-\r
-/*\r
- * Prototypes for publics\r
- */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-extern PKT_STAT pktStat; /* statistics for packets */\r
-extern PKT_INFO pktInfo; /* packet-driver information */\r
-\r
-extern PKT_RX_MODE receiveMode;\r
-extern ETHER myAddress, ethBroadcast;\r
-\r
-extern BOOL PktInitDriver (PKT_RX_MODE mode);\r
-extern BOOL PktExitDriver (void);\r
-\r
-extern const char *PktGetErrorStr (int errNum);\r
-extern const char *PktGetClassName (WORD class);\r
-extern const char *PktRXmodeStr (PKT_RX_MODE mode);\r
-extern BOOL PktSearchDriver (void);\r
-extern int PktReceive (BYTE *buf, int max);\r
-extern BOOL PktTransmit (const void *eth, int len);\r
-extern DWORD PktRxDropped (void);\r
-extern BOOL PktReleaseHandle (WORD handle);\r
-extern BOOL PktTerminHandle (WORD handle);\r
-extern BOOL PktResetInterface (WORD handle);\r
-extern BOOL PktSetReceiverMode(PKT_RX_MODE mode);\r
-extern BOOL PktGetReceiverMode(PKT_RX_MODE *mode);\r
-extern BOOL PktGetStatistics (WORD handle);\r
-extern BOOL PktSessStatistics (WORD handle);\r
-extern BOOL PktResetStatistics(WORD handle);\r
-extern BOOL PktGetAddress (ETHER *addr);\r
-extern BOOL PktSetAddress (const ETHER *addr);\r
-extern BOOL PktGetDriverInfo (void);\r
-extern BOOL PktGetDriverParam (void);\r
-extern void PktQueueBusy (BOOL busy);\r
-extern WORD PktBuffersUsed (void);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif /* __PKTDRVR_H */\r
-\r
+#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 */
+