From: Francois-Xavier Le Bail Date: Tue, 22 Sep 2015 04:28:07 +0000 (+0200) Subject: Introduce end-of-line normalization X-Git-Tag: libpcap-1.8.0-bp~192 X-Git-Url: https://git.tcpdump.org/libpcap/commitdiff_plain/e1f993b39b60bf01f69d9a8ab05d9a674a899d8a?ds=sidebyside Introduce end-of-line normalization Moreover: Delete trailing spaces/tabs in normalized files --- diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..dfe07704 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/msdos/bin2c.c b/msdos/bin2c.c index d82056e1..a6a3c887 100644 --- a/msdos/bin2c.c +++ b/msdos/bin2c.c @@ -1,43 +1,43 @@ -#include -#include -#include -#include - -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); -} +#include +#include +#include +#include + +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); +} diff --git a/msdos/makefile b/msdos/makefile index cdb4e7cd..234a2763 100644 --- a/msdos/makefile +++ b/msdos/makefile @@ -1,184 +1,184 @@ -# -# 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 - +# +# 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 + diff --git a/msdos/makefile.wc b/msdos/makefile.wc index e0d5672d..8cb6c67c 100644 --- a/msdos/makefile.wc +++ b/msdos/makefile.wc @@ -1,131 +1,131 @@ -# -# 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 - +# +# 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 + diff --git a/msdos/ndis2.c b/msdos/ndis2.c index 0a5ea2a7..526b2219 100644 --- a/msdos/ndis2.c +++ b/msdos/ndis2.c @@ -1,860 +1,860 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include - -#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 */ - +/* + * 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 +#include +#include +#include +#include +#include +#include + +#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 */ + diff --git a/msdos/ndis2.h b/msdos/ndis2.h index dc72f4c6..f278b5dc 100644 --- a/msdos/ndis2.h +++ b/msdos/ndis2.h @@ -1,559 +1,559 @@ -/* - * 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 +/* + * 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 diff --git a/msdos/ndis_0.asm b/msdos/ndis_0.asm index 2990985f..ea65e0f8 100644 --- a/msdos/ndis_0.asm +++ b/msdos/ndis_0.asm @@ -1,188 +1,188 @@ -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 ; DOSX is tiny-model - D_SEG EQU <_TEXT SEGMENT> - D_END EQU <_TEXT ENDS> - ASSUME CS:_TEXT,DS:_TEXT - - PUSHREGS equ - POPREGS equ - - 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 ; 16bit is small/large model - D_SEG EQU <_DATA SEGMENT> - D_END EQU <_DATA ENDS> - ASSUME CS:_TEXT,DS:_DATA - - PUSHREGS equ - POPREGS equ - - 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 +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 ; DOSX is tiny-model + D_SEG EQU <_TEXT SEGMENT> + D_END EQU <_TEXT ENDS> + ASSUME CS:_TEXT,DS:_TEXT + + PUSHREGS equ + POPREGS equ + + 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 ; 16bit is small/large model + D_SEG EQU <_DATA SEGMENT> + D_END EQU <_DATA ENDS> + ASSUME CS:_TEXT,DS:_DATA + + PUSHREGS equ + POPREGS equ + + 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 diff --git a/msdos/pkt_rx0.asm b/msdos/pkt_rx0.asm index 94f3d098..d604fa14 100644 --- a/msdos/pkt_rx0.asm +++ b/msdos/pkt_rx0.asm @@ -1,197 +1,197 @@ -PAGE 60,132 -NAME PKT_RX - -ifdef ??version ; using TASM - masm - jumps -endif - -PUBLIC _pktDrop, _pktRxBuf, _pktTxBuf, _pktTemp -PUBLIC _rxOutOfs, _rxInOfs, _PktReceiver, _pktRxEnd - -; -; these sizes MUST be equal to the sizes in PKTDRVR.H -; - -RX_BUF_SIZE = 1500 ; max message size on Ethernet -TX_BUF_SIZE = 1500 - -ifdef DOSX - .386 - NUM_RX_BUF = 32 ; # of RX element buffers - _TEXT SEGMENT PUBLIC DWORD USE16 'CODE' - _TEXT ENDS - _DATA SEGMENT PUBLIC DWORD USE16 'CODE' - _DATA ENDS - D_SEG EQU <_TEXT SEGMENT> - D_END EQU <_TEXT ENDS> - ASSUME CS:_TEXT,DS:_TEXT -else - .286 - NUM_RX_BUF = 10 - _TEXT SEGMENT PUBLIC DWORD 'CODE' - _TEXT ENDS - _DATA SEGMENT PUBLIC DWORD 'DATA' - _DATA ENDS - D_SEG EQU <_DATA SEGMENT> - D_END EQU <_DATA ENDS> - ASSUME CS:_TEXT,DS:_DATA -endif - -;------------------------------------------- - -D_SEG - -RX_ELEMENT STRUC - firstCount dw 0 ; # of bytes on 1st call - secondCount dw 0 ; # of bytes on 2nd call - handle dw 0 ; handle for upcall - destinAdr db 6 dup (0) ; packet destination address - sourceAdr db 6 dup (0) ; packet source address - protocol dw 0 ; packet protocol number - rxBuffer db RX_BUF_SIZE dup (0) ; RX buffer -ENDS - align 4 -_rxOutOfs dw offset _pktRxBuf ; ring buffer offsets -_rxInOfs dw offset _pktRxBuf ; into _pktRxBuf -_pktDrop dw 0,0 ; packet drop counter -_pktTemp db 20 dup (0) ; temp work area -_pktTxBuf db (TX_BUF_SIZE+14) dup (0) ; TX buffer -_pktRxBuf RX_ELEMENT NUM_RX_BUF dup (<>) ; RX structures - LAST_OFS = offset $ - - screenSeg dw 0B800h - newInOffset dw 0 - - fanChars db '-\|/' - fanIndex dw 0 - -D_END - -_TEXT SEGMENT - - -SHOW_RX MACRO - push es - push bx - mov bx, screenSeg - mov es, bx ;; r-mode segment of colour screen - mov di, 158 ;; upper right corner - 1 - mov bx, fanIndex - mov al, fanChars[bx] ;; get write char - mov ah, 15 ;; and white colour - stosw ;; write to screen at ES:EDI - inc fanIndex ;; update next index - and fanIndex, 3 - pop bx - pop es -ENDM - -;------------------------------------------------------------------------ -; -; This macro return ES:DI to tail of Rx queue - -ENQUEUE MACRO - LOCAL @noWrap - mov ax, _rxInOfs ;; DI = current in-offset - add ax, SIZE RX_ELEMENT ;; point to next _pktRxBuf buffer - cmp ax, LAST_OFS ;; pointing past last ? - jb @noWrap ;; no - jump - lea ax, _pktRxBuf ;; yes, point to 1st buffer - align 4 -@noWrap: cmp ax, _rxOutOfs ;; in-ofs = out-ofs ? - je @dump ;; yes, queue is full - mov di, _rxInOfs ;; ES:DI -> buffer at queue input - mov newInOffset, ax ;; remember new input offset - - ;; NOTE. rxInOfs is updated after the packet has been copied - ;; to ES:DI (= DS:SI on 2nd call) by the packet driver - -ENDM - -;------------------------------------------------------------------------ -; -; This routine gets called by the packet driver twice: -; 1st time (AX=0) it requests an address where to put the packet -; -; 2nd time (AX=1) the packet has been copied to this location (DS:SI) -; BX has client handle (stored in RX_ELEMENT.handle). -; CX has # of bytes in packet on both call. They should be equal. -; -; A test for equality is done by putting CX in _pktRxBuf [n].firstCount -; and _pktRxBuf[n].secondCount, and CL on first call in -; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive" -; (PKTDRVR.C) -; -;--------------------------------------------------------------------- - -_PktReceiver: - pushf - cli ; no distraction wanted ! - push ds - push bx -ifdef DOSX - mov bx, cs -else - mov bx, SEG _DATA -endif - mov ds, bx - mov es, bx ; ES = DS = CS or seg _DATA - pop bx ; restore handle - - cmp ax, 0 ; first call? (AX=0) - jne @post ; AX=1: second call, do post process - -ifdef DEBUG - SHOW_RX ; show that a packet is received -endif - cmp cx, RX_BUF_SIZE+14 ; size OK ? - ja @skip ; no, packet to large for us - - ENQUEUE ; ES:DI -> _pktRxBuf[n] - - mov [di].firstCount, cx ; remember the first count. - mov [di].handle, bx ; remember the handle. - add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr - pop ds - popf - retf ; far return to driver with ES:DI - - align 4 -@dump: inc _pktDrop[0] ; discard the packet on 1st call - adc _pktDrop[2], 0 ; increment packets lost - -@skip: xor di, di ; return ES:DI = NIL pointer - xor ax, ax - mov es, ax - pop ds - popf - retf - - align 4 -@post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr - jz @discard ; make sure we don't use NULL-pointer - - sub si, 6 ; DS:SI -> _pktRxBuf[n].destinAdr - ; - ; push si - ; push [si].firstCount - ; call bpf_filter_match ; run the filter here some day? - ; add sp, 4 - ; cmp ax, 0 - ; je @discard - - mov [si].secondCount, cx - mov ax, newInOffset - mov _rxInOfs, ax ; update _pktRxBuf input offset - - align 4 -@discard:pop ds - popf - retf - -_pktRxEnd db 0 ; marker for end of r-mode code/data - -_TEXT ENDS - -END +PAGE 60,132 +NAME PKT_RX + +ifdef ??version ; using TASM + masm + jumps +endif + +PUBLIC _pktDrop, _pktRxBuf, _pktTxBuf, _pktTemp +PUBLIC _rxOutOfs, _rxInOfs, _PktReceiver, _pktRxEnd + +; +; these sizes MUST be equal to the sizes in PKTDRVR.H +; + +RX_BUF_SIZE = 1500 ; max message size on Ethernet +TX_BUF_SIZE = 1500 + +ifdef DOSX + .386 + NUM_RX_BUF = 32 ; # of RX element buffers + _TEXT SEGMENT PUBLIC DWORD USE16 'CODE' + _TEXT ENDS + _DATA SEGMENT PUBLIC DWORD USE16 'CODE' + _DATA ENDS + D_SEG EQU <_TEXT SEGMENT> + D_END EQU <_TEXT ENDS> + ASSUME CS:_TEXT,DS:_TEXT +else + .286 + NUM_RX_BUF = 10 + _TEXT SEGMENT PUBLIC DWORD 'CODE' + _TEXT ENDS + _DATA SEGMENT PUBLIC DWORD 'DATA' + _DATA ENDS + D_SEG EQU <_DATA SEGMENT> + D_END EQU <_DATA ENDS> + ASSUME CS:_TEXT,DS:_DATA +endif + +;------------------------------------------- + +D_SEG + +RX_ELEMENT STRUC + firstCount dw 0 ; # of bytes on 1st call + secondCount dw 0 ; # of bytes on 2nd call + handle dw 0 ; handle for upcall + destinAdr db 6 dup (0) ; packet destination address + sourceAdr db 6 dup (0) ; packet source address + protocol dw 0 ; packet protocol number + rxBuffer db RX_BUF_SIZE dup (0) ; RX buffer +ENDS + align 4 +_rxOutOfs dw offset _pktRxBuf ; ring buffer offsets +_rxInOfs dw offset _pktRxBuf ; into _pktRxBuf +_pktDrop dw 0,0 ; packet drop counter +_pktTemp db 20 dup (0) ; temp work area +_pktTxBuf db (TX_BUF_SIZE+14) dup (0) ; TX buffer +_pktRxBuf RX_ELEMENT NUM_RX_BUF dup (<>) ; RX structures + LAST_OFS = offset $ + + screenSeg dw 0B800h + newInOffset dw 0 + + fanChars db '-\|/' + fanIndex dw 0 + +D_END + +_TEXT SEGMENT + + +SHOW_RX MACRO + push es + push bx + mov bx, screenSeg + mov es, bx ;; r-mode segment of colour screen + mov di, 158 ;; upper right corner - 1 + mov bx, fanIndex + mov al, fanChars[bx] ;; get write char + mov ah, 15 ;; and white colour + stosw ;; write to screen at ES:EDI + inc fanIndex ;; update next index + and fanIndex, 3 + pop bx + pop es +ENDM + +;------------------------------------------------------------------------ +; +; This macro return ES:DI to tail of Rx queue + +ENQUEUE MACRO + LOCAL @noWrap + mov ax, _rxInOfs ;; DI = current in-offset + add ax, SIZE RX_ELEMENT ;; point to next _pktRxBuf buffer + cmp ax, LAST_OFS ;; pointing past last ? + jb @noWrap ;; no - jump + lea ax, _pktRxBuf ;; yes, point to 1st buffer + align 4 +@noWrap: cmp ax, _rxOutOfs ;; in-ofs = out-ofs ? + je @dump ;; yes, queue is full + mov di, _rxInOfs ;; ES:DI -> buffer at queue input + mov newInOffset, ax ;; remember new input offset + + ;; NOTE. rxInOfs is updated after the packet has been copied + ;; to ES:DI (= DS:SI on 2nd call) by the packet driver + +ENDM + +;------------------------------------------------------------------------ +; +; This routine gets called by the packet driver twice: +; 1st time (AX=0) it requests an address where to put the packet +; +; 2nd time (AX=1) the packet has been copied to this location (DS:SI) +; BX has client handle (stored in RX_ELEMENT.handle). +; CX has # of bytes in packet on both call. They should be equal. +; +; A test for equality is done by putting CX in _pktRxBuf [n].firstCount +; and _pktRxBuf[n].secondCount, and CL on first call in +; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive" +; (PKTDRVR.C) +; +;--------------------------------------------------------------------- + +_PktReceiver: + pushf + cli ; no distraction wanted ! + push ds + push bx +ifdef DOSX + mov bx, cs +else + mov bx, SEG _DATA +endif + mov ds, bx + mov es, bx ; ES = DS = CS or seg _DATA + pop bx ; restore handle + + cmp ax, 0 ; first call? (AX=0) + jne @post ; AX=1: second call, do post process + +ifdef DEBUG + SHOW_RX ; show that a packet is received +endif + cmp cx, RX_BUF_SIZE+14 ; size OK ? + ja @skip ; no, packet to large for us + + ENQUEUE ; ES:DI -> _pktRxBuf[n] + + mov [di].firstCount, cx ; remember the first count. + mov [di].handle, bx ; remember the handle. + add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr + pop ds + popf + retf ; far return to driver with ES:DI + + align 4 +@dump: inc _pktDrop[0] ; discard the packet on 1st call + adc _pktDrop[2], 0 ; increment packets lost + +@skip: xor di, di ; return ES:DI = NIL pointer + xor ax, ax + mov es, ax + pop ds + popf + retf + + align 4 +@post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr + jz @discard ; make sure we don't use NULL-pointer + + sub si, 6 ; DS:SI -> _pktRxBuf[n].destinAdr + ; + ; push si + ; push [si].firstCount + ; call bpf_filter_match ; run the filter here some day? + ; add sp, 4 + ; cmp ax, 0 + ; je @discard + + mov [si].secondCount, cx + mov ax, newInOffset + mov _rxInOfs, ax ; update _pktRxBuf input offset + + align 4 +@discard:pop ds + popf + retf + +_pktRxEnd db 0 ; marker for end of r-mode code/data + +_TEXT ENDS + +END diff --git a/msdos/pkt_rx1.s b/msdos/pkt_rx1.s index b294a369..98eafafc 100644 --- a/msdos/pkt_rx1.s +++ b/msdos/pkt_rx1.s @@ -1,155 +1,155 @@ -; -; This file requires NASM 0.97+ to assemble -; -; Currently used only for djgpp + DOS4GW targets -; -; these sizes MUST be equal to the sizes in PKTDRVR.H -; -%define ETH_MTU 1500 ; max data size on Ethernet -%define ETH_MIN 60 ; min/max total frame size -%define ETH_MAX (ETH_MTU+2*6+2) -%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 - +; +; 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 + diff --git a/msdos/pktdrvr.c b/msdos/pktdrvr.c index cd22ee64..37fc8a41 100644 --- a/msdos/pktdrvr.c +++ b/msdos/pktdrvr.c @@ -1,1436 +1,1436 @@ -/* - * File.........: pktdrvr.c - * - * Responsible..: Gisle Vanem, giva@bgnett.no - * - * Created......: 26.Sept 1995 - * - * Description..: Packet-driver interface for 16/32-bit C : - * Borland C/C++ 3.0+ small/large model - * Watcom C/C++ 11+, DOS4GW flat model - * Metaware HighC 3.1+ and PharLap 386|DosX - * GNU C/C++ 2.7+ and djgpp 2.x extender - * - * References...: PC/TCP Packet driver Specification. rev 1.09 - * FTP Software Inc. - * - */ - -#include -#include -#include -#include - -#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 - #include - #include - #include - #include - -#elif defined(__WATCOMC__) - #include - #include - extern char _Extender; - -#else - extern void far PktReceiver (void); -#endif - - -#if (DOSX & (DJGPP|DOS4GW)) - #include - - 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 - - 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) */ +/* + * File.........: pktdrvr.c + * + * Responsible..: Gisle Vanem, giva@bgnett.no + * + * Created......: 26.Sept 1995 + * + * Description..: Packet-driver interface for 16/32-bit C : + * Borland C/C++ 3.0+ small/large model + * Watcom C/C++ 11+, DOS4GW flat model + * Metaware HighC 3.1+ and PharLap 386|DosX + * GNU C/C++ 2.7+ and djgpp 2.x extender + * + * References...: PC/TCP Packet driver Specification. rev 1.09 + * FTP Software Inc. + * + */ + +#include +#include +#include +#include + +#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 + #include + #include + #include + #include + +#elif defined(__WATCOMC__) + #include + #include + extern char _Extender; + +#else + extern void far PktReceiver (void); +#endif + + +#if (DOSX & (DJGPP|DOS4GW)) + #include + + 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 + + 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) */ diff --git a/msdos/pktdrvr.h b/msdos/pktdrvr.h index 08898ae8..3e0cfe01 100644 --- a/msdos/pktdrvr.h +++ b/msdos/pktdrvr.h @@ -1,153 +1,153 @@ -#ifndef __PKTDRVR_H -#define __PKTDRVR_H - -#define PUBLIC -#define LOCAL static - -#define RX_BUF_SIZE ETH_MTU /* buffer size variables. NB !! */ -#define TX_BUF_SIZE ETH_MTU /* must be same as in pkt_rx*.* */ - -#ifdef __HIGHC__ -#pragma Off(Align_members) -#else -#pragma pack(1) -#endif - -typedef enum { /* Packet-driver classes */ - PD_ETHER = 1, - PD_PRONET10 = 2, - PD_IEEE8025 = 3, - PD_OMNINET = 4, - PD_APPLETALK = 5, - PD_SLIP = 6, - PD_STARTLAN = 7, - PD_ARCNET = 8, - PD_AX25 = 9, - PD_KISS = 10, - PD_IEEE8023_2 = 11, - PD_FDDI8022 = 12, - PD_X25 = 13, - PD_LANstar = 14, - PD_PPP = 18 - } PKT_CLASS; - -typedef enum { /* Packet-driver receive modes */ - PDRX_OFF = 1, /* turn off receiver */ - PDRX_DIRECT, /* receive only to this interface */ - PDRX_BROADCAST, /* DIRECT + broadcast packets */ - PDRX_MULTICAST1, /* BROADCAST + limited multicast */ - PDRX_MULTICAST2, /* BROADCAST + all multicast */ - PDRX_ALL_PACKETS, /* receive all packets on network */ - } PKT_RX_MODE; - -typedef struct { - char type[8]; - char len; - } PKT_FRAME; - - -typedef struct { - BYTE class; /* = 1 for DEC/Interl/Xerox Ethernet */ - BYTE number; /* = 0 for single LAN adapter */ - WORD type; /* = 13 for 3C523 */ - BYTE funcs; /* Basic/Extended/HiPerf functions */ - WORD intr; /* user interrupt vector number */ - WORD handle; /* Handle associated with session */ - BYTE name [15]; /* Name of adapter interface,ie.3C523*/ - BOOL quiet; /* (don't) print errors to stdout */ - const char *error; /* address of error string */ - BYTE majVer; /* Major driver implementation ver. */ - BYTE minVer; /* Minor driver implementation ver. */ - BYTE dummyLen; /* length of following data */ - WORD MAClength; /* HiPerformance data, N/A */ - WORD MTU; /* HiPerformance data, N/A */ - WORD multicast; /* HiPerformance data, N/A */ - WORD rcvrBuffers; /* valid for */ - WORD UMTbufs; /* High Performance drivers only */ - WORD postEOIintr; /* Usage ?? */ - } PKT_INFO; - -#define PKT_PARAM_SIZE 14 /* members majVer - postEOIintr */ - - -typedef struct { - DWORD inPackets; /* # of packets received */ - DWORD outPackets; /* # of packets transmitted */ - DWORD inBytes; /* # of bytes received */ - DWORD outBytes; /* # of bytes transmitted */ - DWORD inErrors; /* # of reception errors */ - DWORD outErrors; /* # of transmission errors */ - DWORD lost; /* # of packets lost (RX) */ - } PKT_STAT; - - -typedef struct { - ETHER destin; - ETHER source; - WORD proto; - BYTE data [TX_BUF_SIZE]; - } TX_ELEMENT; - -typedef struct { - WORD firstCount; /* # of bytes on 1st */ - WORD secondCount; /* and 2nd upcall */ - WORD handle; /* instance that upcalled */ - ETHER destin; /* E-net destination address */ - ETHER source; /* E-net source address */ - WORD proto; /* protocol number */ - BYTE data [RX_BUF_SIZE]; - } RX_ELEMENT; - - -#ifdef __HIGHC__ -#pragma pop(Align_members) -#else -#pragma pack() -#endif - - -/* - * Prototypes for publics - */ - -#ifdef __cplusplus -extern "C" { -#endif - -extern PKT_STAT pktStat; /* statistics for packets */ -extern PKT_INFO pktInfo; /* packet-driver information */ - -extern PKT_RX_MODE receiveMode; -extern ETHER myAddress, ethBroadcast; - -extern BOOL PktInitDriver (PKT_RX_MODE mode); -extern BOOL PktExitDriver (void); - -extern const char *PktGetErrorStr (int errNum); -extern const char *PktGetClassName (WORD class); -extern const char *PktRXmodeStr (PKT_RX_MODE mode); -extern BOOL PktSearchDriver (void); -extern int PktReceive (BYTE *buf, int max); -extern BOOL PktTransmit (const void *eth, int len); -extern DWORD PktRxDropped (void); -extern BOOL PktReleaseHandle (WORD handle); -extern BOOL PktTerminHandle (WORD handle); -extern BOOL PktResetInterface (WORD handle); -extern BOOL PktSetReceiverMode(PKT_RX_MODE mode); -extern BOOL PktGetReceiverMode(PKT_RX_MODE *mode); -extern BOOL PktGetStatistics (WORD handle); -extern BOOL PktSessStatistics (WORD handle); -extern BOOL PktResetStatistics(WORD handle); -extern BOOL PktGetAddress (ETHER *addr); -extern BOOL PktSetAddress (const ETHER *addr); -extern BOOL PktGetDriverInfo (void); -extern BOOL PktGetDriverParam (void); -extern void PktQueueBusy (BOOL busy); -extern WORD PktBuffersUsed (void); - -#ifdef __cplusplus -} -#endif - -#endif /* __PKTDRVR_H */ - +#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 */ +