diff options
Diffstat (limited to 'contrib/libpcap/msdos/pktdrvr.c')
-rw-r--r-- | contrib/libpcap/msdos/pktdrvr.c | 1436 |
1 files changed, 0 insertions, 1436 deletions
diff --git a/contrib/libpcap/msdos/pktdrvr.c b/contrib/libpcap/msdos/pktdrvr.c deleted file mode 100644 index 360c893..0000000 --- a/contrib/libpcap/msdos/pktdrvr.c +++ /dev/null @@ -1,1436 +0,0 @@ -/* - * File.........: pktdrvr.c - * - * Responsible..: Gisle Vanem, giva@bgnett.no - * - * Created......: 26.Sept 1995 - * - * Description..: Packet-driver interface for 16/32-bit C : - * Borland C/C++ 3.0+ small/large model - * Watcom C/C++ 11+, DOS4GW flat model - * Metaware HighC 3.1+ and PharLap 386|DosX - * GNU C/C++ 2.7+ and djgpp 2.x extender - * - * References...: PC/TCP Packet driver Specification. rev 1.09 - * FTP Software Inc. - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <dos.h> - -#include "pcap-dos.h" -#include "pcap-int.h" -#include "msdos/pktdrvr.h" - -#if (DOSX) -#define NUM_RX_BUF 32 /* # of buffers in Rx FIFO queue */ -#else -#define NUM_RX_BUF 10 -#endif - -#define DIM(x) (sizeof((x)) / sizeof(x[0])) -#define PUTS(s) do { \ - if (!pktInfo.quiet) \ - pktInfo.error ? \ - printf ("%s: %s\n", s, pktInfo.error) : \ - printf ("%s\n", pktInfo.error = s); \ - } while (0) - -#if defined(__HIGHC__) - extern UINT _mwenv; - -#elif defined(__DJGPP__) - #include <stddef.h> - #include <dpmi.h> - #include <go32.h> - #include <pc.h> - #include <sys/farptr.h> - -#elif defined(__WATCOMC__) - #include <i86.h> - #include <stddef.h> - extern char _Extender; - -#else - extern void far PktReceiver (void); -#endif - - -#if (DOSX & (DJGPP|DOS4GW)) - #include <sys/pack_on.h> - - struct DPMI_regs { - DWORD r_di; - DWORD r_si; - DWORD r_bp; - DWORD reserved; - DWORD r_bx; - DWORD r_dx; - DWORD r_cx; - DWORD r_ax; - WORD r_flags; - WORD r_es, r_ds, r_fs, r_gs; - WORD r_ip, r_cs, r_sp, r_ss; - }; - - /* Data located in a real-mode segment. This becomes far at runtime - */ - typedef struct { /* must match data/code in pkt_rx1.s */ - WORD _rxOutOfs; - WORD _rxInOfs; - DWORD _pktDrop; - BYTE _pktTemp [20]; - TX_ELEMENT _pktTxBuf[1]; - RX_ELEMENT _pktRxBuf[NUM_RX_BUF]; - WORD _dummy[2]; /* screenSeg,newInOffset */ - BYTE _fanChars[4]; - WORD _fanIndex; - BYTE _PktReceiver[15]; /* starts on a paragraph (16byte) */ - } PktRealStub; - #include <sys/pack_off.h> - - static BYTE real_stub_array [] = { - #include "pkt_stub.inc" /* generated opcode array */ - }; - - #define rxOutOfs offsetof (PktRealStub,_rxOutOfs) - #define rxInOfs offsetof (PktRealStub,_rxInOfs) - #define PktReceiver offsetof (PktRealStub,_PktReceiver [para_skip]) - #define pktDrop offsetof (PktRealStub,_pktDrop) - #define pktTemp offsetof (PktRealStub,_pktTemp) - #define pktTxBuf offsetof (PktRealStub,_pktTxBuf) - #define FIRST_RX_BUF offsetof (PktRealStub,_pktRxBuf [0]) - #define LAST_RX_BUF offsetof (PktRealStub,_pktRxBuf [NUM_RX_BUF-1]) - -#else - extern WORD rxOutOfs; /* offsets into pktRxBuf FIFO queue */ - extern WORD rxInOfs; - extern DWORD pktDrop; /* # packets dropped in PktReceiver() */ - extern BYTE pktRxEnd; /* marks the end of r-mode code/data */ - - extern RX_ELEMENT pktRxBuf [NUM_RX_BUF]; /* PktDrvr Rx buffers */ - extern TX_ELEMENT pktTxBuf; /* PktDrvr Tx buffer */ - extern char pktTemp[20]; /* PktDrvr temp area */ - - #define FIRST_RX_BUF (WORD) &pktRxBuf [0] - #define LAST_RX_BUF (WORD) &pktRxBuf [NUM_RX_BUF-1] -#endif - - -#ifdef __BORLANDC__ /* Use Borland's inline functions */ - #define memcpy __memcpy__ - #define memcmp __memcmp__ - #define memset __memset__ -#endif - - -#if (DOSX & PHARLAP) - extern void PktReceiver (void); /* in pkt_rx0.asm */ - static int RealCopy (ULONG, ULONG, REALPTR*, FARPTR*, USHORT*); - - #undef FP_SEG - #undef FP_OFF - #define FP_OFF(x) ((WORD)(x)) - #define FP_SEG(x) ((WORD)(realBase >> 16)) - #define DOS_ADDR(s,o) (((DWORD)(s) << 16) + (WORD)(o)) - #define r_ax eax - #define r_bx ebx - #define r_dx edx - #define r_cx ecx - #define r_si esi - #define r_di edi - #define r_ds ds - #define r_es es - LOCAL FARPTR protBase; - LOCAL REALPTR realBase; - LOCAL WORD realSeg; /* DOS para-address of allocated area */ - LOCAL SWI_REGS reg; - - static WORD _far *rxOutOfsFp, *rxInOfsFp; - -#elif (DOSX & DJGPP) - static _go32_dpmi_seginfo rm_mem; - static __dpmi_regs reg; - static DWORD realBase; - static int para_skip = 0; - - #define DOS_ADDR(s,o) (((WORD)(s) << 4) + (o)) - #define r_ax x.ax - #define r_bx x.bx - #define r_dx x.dx - #define r_cx x.cx - #define r_si x.si - #define r_di x.di - #define r_ds x.ds - #define r_es x.es - -#elif (DOSX & DOS4GW) - LOCAL struct DPMI_regs reg; - LOCAL WORD rm_base_seg, rm_base_sel; - LOCAL DWORD realBase; - LOCAL int para_skip = 0; - - LOCAL DWORD dpmi_get_real_vector (int intr); - LOCAL WORD dpmi_real_malloc (int size, WORD *selector); - LOCAL void dpmi_real_free (WORD selector); - #define DOS_ADDR(s,o) (((DWORD)(s) << 4) + (WORD)(o)) - -#else /* real-mode Borland etc. */ - static struct { - WORD r_ax, r_bx, r_cx, r_dx, r_bp; - WORD r_si, r_di, r_ds, r_es, r_flags; - } reg; -#endif - -#ifdef __HIGHC__ - #pragma Alias (pktDrop, "_pktDrop") - #pragma Alias (pktRxBuf, "_pktRxBuf") - #pragma Alias (pktTxBuf, "_pktTxBuf") - #pragma Alias (pktTemp, "_pktTemp") - #pragma Alias (rxOutOfs, "_rxOutOfs") - #pragma Alias (rxInOfs, "_rxInOfs") - #pragma Alias (pktRxEnd, "_pktRxEnd") - #pragma Alias (PktReceiver,"_PktReceiver") -#endif - - -PUBLIC PKT_STAT pktStat; /* statistics for packets */ -PUBLIC PKT_INFO pktInfo; /* packet-driver information */ - -PUBLIC PKT_RX_MODE receiveMode = PDRX_DIRECT; -PUBLIC ETHER myAddress = { 0, 0, 0, 0, 0, 0 }; -PUBLIC ETHER ethBroadcast = { 255,255,255,255,255,255 }; - -LOCAL struct { /* internal statistics */ - DWORD tooSmall; /* size < ETH_MIN */ - DWORD tooLarge; /* size > ETH_MAX */ - DWORD badSync; /* count_1 != count_2 */ - DWORD wrongHandle; /* upcall to wrong handle */ - } intStat; - -/***************************************************************************/ - -PUBLIC const char *PktGetErrorStr (int errNum) -{ - static const char *errStr[] = { - "", - "Invalid handle number", - "No interfaces of specified class found", - "No interfaces of specified type found", - "No interfaces of specified number found", - "Bad packet type specified", - "Interface does not support multicast", - "Packet driver cannot terminate", - "Invalid receiver mode specified", - "Insufficient memory space", - "Type previously accessed, and not released", - "Command out of range, or not implemented", - "Cannot send packet (usually hardware error)", - "Cannot change hardware address ( > 1 handle open)", - "Hardware address has bad length or format", - "Cannot reset interface (more than 1 handle open)", - "Bad Check-sum", - "Bad size", - "Bad sync" , - "Source hit" - }; - - if (errNum < 0 || errNum >= DIM(errStr)) - return ("Unknown driver error."); - return (errStr [errNum]); -} - -/**************************************************************************/ - -PUBLIC const char *PktGetClassName (WORD class) -{ - switch (class) - { - case PD_ETHER: - return ("DIX-Ether"); - case PD_PRONET10: - return ("ProNET-10"); - case PD_IEEE8025: - return ("IEEE 802.5"); - case PD_OMNINET: - return ("OmniNet"); - case PD_APPLETALK: - return ("AppleTalk"); - case PD_SLIP: - return ("SLIP"); - case PD_STARTLAN: - return ("StartLAN"); - case PD_ARCNET: - return ("ArcNet"); - case PD_AX25: - return ("AX.25"); - case PD_KISS: - return ("KISS"); - case PD_IEEE8023_2: - return ("IEEE 802.3 w/802.2 hdr"); - case PD_FDDI8022: - return ("FDDI w/802.2 hdr"); - case PD_X25: - return ("X.25"); - case PD_LANstar: - return ("LANstar"); - case PD_PPP: - return ("PPP"); - default: - return ("unknown"); - } -} - -/**************************************************************************/ - -PUBLIC char const *PktRXmodeStr (PKT_RX_MODE mode) -{ - static const char *modeStr [] = { - "Receiver turned off", - "Receive only directly addressed packets", - "Receive direct & broadcast packets", - "Receive direct,broadcast and limited multicast packets", - "Receive direct,broadcast and all multicast packets", - "Receive all packets (promiscuouos mode)" - }; - - if (mode > DIM(modeStr)) - return ("??"); - return (modeStr [mode-1]); -} - -/**************************************************************************/ - -LOCAL __inline BOOL PktInterrupt (void) -{ - BOOL okay; - -#if (DOSX & PHARLAP) - _dx_real_int ((UINT)pktInfo.intr, ®); - 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) */ |