xref: /minix3/external/bsd/libpcap/dist/msdos/pktdrvr.c (revision d56f51ea7d8b9045e5c8e2028422523d3f9a5840)
1*d56f51eaSDavid van Moolenbroek /*
2*d56f51eaSDavid van Moolenbroek  *  File.........: pktdrvr.c
3*d56f51eaSDavid van Moolenbroek  *
4*d56f51eaSDavid van Moolenbroek  *  Responsible..: Gisle Vanem,  giva@bgnett.no
5*d56f51eaSDavid van Moolenbroek  *
6*d56f51eaSDavid van Moolenbroek  *  Created......: 26.Sept 1995
7*d56f51eaSDavid van Moolenbroek  *
8*d56f51eaSDavid van Moolenbroek  *  Description..: Packet-driver interface for 16/32-bit C :
9*d56f51eaSDavid van Moolenbroek  *                 Borland C/C++ 3.0+ small/large model
10*d56f51eaSDavid van Moolenbroek  *                 Watcom C/C++ 11+, DOS4GW flat model
11*d56f51eaSDavid van Moolenbroek  *                 Metaware HighC 3.1+ and PharLap 386|DosX
12*d56f51eaSDavid van Moolenbroek  *                 GNU C/C++ 2.7+ and djgpp 2.x extender
13*d56f51eaSDavid van Moolenbroek  *
14*d56f51eaSDavid van Moolenbroek  *  References...: PC/TCP Packet driver Specification. rev 1.09
15*d56f51eaSDavid van Moolenbroek  *                 FTP Software Inc.
16*d56f51eaSDavid van Moolenbroek  *
17*d56f51eaSDavid van Moolenbroek  */
18*d56f51eaSDavid van Moolenbroek 
19*d56f51eaSDavid van Moolenbroek #include <stdio.h>
20*d56f51eaSDavid van Moolenbroek #include <stdlib.h>
21*d56f51eaSDavid van Moolenbroek #include <string.h>
22*d56f51eaSDavid van Moolenbroek #include <dos.h>
23*d56f51eaSDavid van Moolenbroek 
24*d56f51eaSDavid van Moolenbroek #include "pcap-dos.h"
25*d56f51eaSDavid van Moolenbroek #include "pcap-int.h"
26*d56f51eaSDavid van Moolenbroek #include "msdos/pktdrvr.h"
27*d56f51eaSDavid van Moolenbroek 
28*d56f51eaSDavid van Moolenbroek #if (DOSX)
29*d56f51eaSDavid van Moolenbroek #define NUM_RX_BUF  32      /* # of buffers in Rx FIFO queue */
30*d56f51eaSDavid van Moolenbroek #else
31*d56f51eaSDavid van Moolenbroek #define NUM_RX_BUF  10
32*d56f51eaSDavid van Moolenbroek #endif
33*d56f51eaSDavid van Moolenbroek 
34*d56f51eaSDavid van Moolenbroek #define DIM(x)   (sizeof((x)) / sizeof(x[0]))
35*d56f51eaSDavid van Moolenbroek #define PUTS(s)  do {                                           \
36*d56f51eaSDavid van Moolenbroek                    if (!pktInfo.quiet)                          \
37*d56f51eaSDavid van Moolenbroek                       pktInfo.error ?                           \
38*d56f51eaSDavid van Moolenbroek                         printf ("%s: %s\n", s, pktInfo.error) : \
39*d56f51eaSDavid van Moolenbroek                         printf ("%s\n", pktInfo.error = s);     \
40*d56f51eaSDavid van Moolenbroek                  } while (0)
41*d56f51eaSDavid van Moolenbroek 
42*d56f51eaSDavid van Moolenbroek #if defined(__HIGHC__)
43*d56f51eaSDavid van Moolenbroek   extern UINT _mwenv;
44*d56f51eaSDavid van Moolenbroek 
45*d56f51eaSDavid van Moolenbroek #elif defined(__DJGPP__)
46*d56f51eaSDavid van Moolenbroek   #include <stddef.h>
47*d56f51eaSDavid van Moolenbroek   #include <dpmi.h>
48*d56f51eaSDavid van Moolenbroek   #include <go32.h>
49*d56f51eaSDavid van Moolenbroek   #include <pc.h>
50*d56f51eaSDavid van Moolenbroek   #include <sys/farptr.h>
51*d56f51eaSDavid van Moolenbroek 
52*d56f51eaSDavid van Moolenbroek #elif defined(__WATCOMC__)
53*d56f51eaSDavid van Moolenbroek   #include <i86.h>
54*d56f51eaSDavid van Moolenbroek   #include <stddef.h>
55*d56f51eaSDavid van Moolenbroek   extern char _Extender;
56*d56f51eaSDavid van Moolenbroek 
57*d56f51eaSDavid van Moolenbroek #else
58*d56f51eaSDavid van Moolenbroek   extern void far PktReceiver (void);
59*d56f51eaSDavid van Moolenbroek #endif
60*d56f51eaSDavid van Moolenbroek 
61*d56f51eaSDavid van Moolenbroek 
62*d56f51eaSDavid van Moolenbroek #if (DOSX & (DJGPP|DOS4GW))
63*d56f51eaSDavid van Moolenbroek   #include <sys/pack_on.h>
64*d56f51eaSDavid van Moolenbroek 
65*d56f51eaSDavid van Moolenbroek   struct DPMI_regs {
66*d56f51eaSDavid van Moolenbroek          DWORD  r_di;
67*d56f51eaSDavid van Moolenbroek          DWORD  r_si;
68*d56f51eaSDavid van Moolenbroek          DWORD  r_bp;
69*d56f51eaSDavid van Moolenbroek          DWORD  reserved;
70*d56f51eaSDavid van Moolenbroek          DWORD  r_bx;
71*d56f51eaSDavid van Moolenbroek          DWORD  r_dx;
72*d56f51eaSDavid van Moolenbroek          DWORD  r_cx;
73*d56f51eaSDavid van Moolenbroek          DWORD  r_ax;
74*d56f51eaSDavid van Moolenbroek          WORD   r_flags;
75*d56f51eaSDavid van Moolenbroek          WORD   r_es, r_ds, r_fs, r_gs;
76*d56f51eaSDavid van Moolenbroek          WORD   r_ip, r_cs, r_sp, r_ss;
77*d56f51eaSDavid van Moolenbroek        };
78*d56f51eaSDavid van Moolenbroek 
79*d56f51eaSDavid van Moolenbroek   /* Data located in a real-mode segment. This becomes far at runtime
80*d56f51eaSDavid van Moolenbroek    */
81*d56f51eaSDavid van Moolenbroek   typedef struct  {          /* must match data/code in pkt_rx1.s */
82*d56f51eaSDavid van Moolenbroek           WORD       _rxOutOfs;
83*d56f51eaSDavid van Moolenbroek           WORD       _rxInOfs;
84*d56f51eaSDavid van Moolenbroek           DWORD      _pktDrop;
85*d56f51eaSDavid van Moolenbroek           BYTE       _pktTemp [20];
86*d56f51eaSDavid van Moolenbroek           TX_ELEMENT _pktTxBuf[1];
87*d56f51eaSDavid van Moolenbroek           RX_ELEMENT _pktRxBuf[NUM_RX_BUF];
88*d56f51eaSDavid van Moolenbroek           WORD       _dummy[2];        /* screenSeg,newInOffset */
89*d56f51eaSDavid van Moolenbroek           BYTE       _fanChars[4];
90*d56f51eaSDavid van Moolenbroek           WORD       _fanIndex;
91*d56f51eaSDavid van Moolenbroek           BYTE       _PktReceiver[15]; /* starts on a paragraph (16byte) */
92*d56f51eaSDavid van Moolenbroek         } PktRealStub;
93*d56f51eaSDavid van Moolenbroek   #include <sys/pack_off.h>
94*d56f51eaSDavid van Moolenbroek 
95*d56f51eaSDavid van Moolenbroek   static BYTE real_stub_array [] = {
96*d56f51eaSDavid van Moolenbroek          #include "pkt_stub.inc"       /* generated opcode array */
97*d56f51eaSDavid van Moolenbroek        };
98*d56f51eaSDavid van Moolenbroek 
99*d56f51eaSDavid van Moolenbroek   #define rxOutOfs      offsetof (PktRealStub,_rxOutOfs)
100*d56f51eaSDavid van Moolenbroek   #define rxInOfs       offsetof (PktRealStub,_rxInOfs)
101*d56f51eaSDavid van Moolenbroek   #define PktReceiver   offsetof (PktRealStub,_PktReceiver [para_skip])
102*d56f51eaSDavid van Moolenbroek   #define pktDrop       offsetof (PktRealStub,_pktDrop)
103*d56f51eaSDavid van Moolenbroek   #define pktTemp       offsetof (PktRealStub,_pktTemp)
104*d56f51eaSDavid van Moolenbroek   #define pktTxBuf      offsetof (PktRealStub,_pktTxBuf)
105*d56f51eaSDavid van Moolenbroek   #define FIRST_RX_BUF  offsetof (PktRealStub,_pktRxBuf [0])
106*d56f51eaSDavid van Moolenbroek   #define LAST_RX_BUF   offsetof (PktRealStub,_pktRxBuf [NUM_RX_BUF-1])
107*d56f51eaSDavid van Moolenbroek 
108*d56f51eaSDavid van Moolenbroek #else
109*d56f51eaSDavid van Moolenbroek   extern WORD       rxOutOfs;    /* offsets into pktRxBuf FIFO queue   */
110*d56f51eaSDavid van Moolenbroek   extern WORD       rxInOfs;
111*d56f51eaSDavid van Moolenbroek   extern DWORD      pktDrop;     /* # packets dropped in PktReceiver() */
112*d56f51eaSDavid van Moolenbroek   extern BYTE       pktRxEnd;    /* marks the end of r-mode code/data  */
113*d56f51eaSDavid van Moolenbroek 
114*d56f51eaSDavid van Moolenbroek   extern RX_ELEMENT pktRxBuf [NUM_RX_BUF];       /* PktDrvr Rx buffers */
115*d56f51eaSDavid van Moolenbroek   extern TX_ELEMENT pktTxBuf;                    /* PktDrvr Tx buffer  */
116*d56f51eaSDavid van Moolenbroek   extern char       pktTemp[20];                 /* PktDrvr temp area  */
117*d56f51eaSDavid van Moolenbroek 
118*d56f51eaSDavid van Moolenbroek   #define FIRST_RX_BUF (WORD) &pktRxBuf [0]
119*d56f51eaSDavid van Moolenbroek   #define LAST_RX_BUF  (WORD) &pktRxBuf [NUM_RX_BUF-1]
120*d56f51eaSDavid van Moolenbroek #endif
121*d56f51eaSDavid van Moolenbroek 
122*d56f51eaSDavid van Moolenbroek 
123*d56f51eaSDavid van Moolenbroek #ifdef __BORLANDC__           /* Use Borland's inline functions */
124*d56f51eaSDavid van Moolenbroek   #define memcpy  __memcpy__
125*d56f51eaSDavid van Moolenbroek   #define memcmp  __memcmp__
126*d56f51eaSDavid van Moolenbroek   #define memset  __memset__
127*d56f51eaSDavid van Moolenbroek #endif
128*d56f51eaSDavid van Moolenbroek 
129*d56f51eaSDavid van Moolenbroek 
130*d56f51eaSDavid van Moolenbroek #if (DOSX & PHARLAP)
131*d56f51eaSDavid van Moolenbroek   extern void PktReceiver (void);     /* in pkt_rx0.asm */
132*d56f51eaSDavid van Moolenbroek   static int  RealCopy    (ULONG, ULONG, REALPTR*, FARPTR*, USHORT*);
133*d56f51eaSDavid van Moolenbroek 
134*d56f51eaSDavid van Moolenbroek   #undef  FP_SEG
135*d56f51eaSDavid van Moolenbroek   #undef  FP_OFF
136*d56f51eaSDavid van Moolenbroek   #define FP_OFF(x)     ((WORD)(x))
137*d56f51eaSDavid van Moolenbroek   #define FP_SEG(x)     ((WORD)(realBase >> 16))
138*d56f51eaSDavid van Moolenbroek   #define DOS_ADDR(s,o) (((DWORD)(s) << 16) + (WORD)(o))
139*d56f51eaSDavid van Moolenbroek   #define r_ax          eax
140*d56f51eaSDavid van Moolenbroek   #define r_bx          ebx
141*d56f51eaSDavid van Moolenbroek   #define r_dx          edx
142*d56f51eaSDavid van Moolenbroek   #define r_cx          ecx
143*d56f51eaSDavid van Moolenbroek   #define r_si          esi
144*d56f51eaSDavid van Moolenbroek   #define r_di          edi
145*d56f51eaSDavid van Moolenbroek   #define r_ds          ds
146*d56f51eaSDavid van Moolenbroek   #define r_es          es
147*d56f51eaSDavid van Moolenbroek   LOCAL FARPTR          protBase;
148*d56f51eaSDavid van Moolenbroek   LOCAL REALPTR         realBase;
149*d56f51eaSDavid van Moolenbroek   LOCAL WORD            realSeg;   /* DOS para-address of allocated area */
150*d56f51eaSDavid van Moolenbroek   LOCAL SWI_REGS        reg;
151*d56f51eaSDavid van Moolenbroek 
152*d56f51eaSDavid van Moolenbroek   static WORD _far *rxOutOfsFp, *rxInOfsFp;
153*d56f51eaSDavid van Moolenbroek 
154*d56f51eaSDavid van Moolenbroek #elif (DOSX & DJGPP)
155*d56f51eaSDavid van Moolenbroek   static _go32_dpmi_seginfo rm_mem;
156*d56f51eaSDavid van Moolenbroek   static __dpmi_regs        reg;
157*d56f51eaSDavid van Moolenbroek   static DWORD              realBase;
158*d56f51eaSDavid van Moolenbroek   static int                para_skip = 0;
159*d56f51eaSDavid van Moolenbroek 
160*d56f51eaSDavid van Moolenbroek   #define DOS_ADDR(s,o)     (((WORD)(s) << 4) + (o))
161*d56f51eaSDavid van Moolenbroek   #define r_ax              x.ax
162*d56f51eaSDavid van Moolenbroek   #define r_bx              x.bx
163*d56f51eaSDavid van Moolenbroek   #define r_dx              x.dx
164*d56f51eaSDavid van Moolenbroek   #define r_cx              x.cx
165*d56f51eaSDavid van Moolenbroek   #define r_si              x.si
166*d56f51eaSDavid van Moolenbroek   #define r_di              x.di
167*d56f51eaSDavid van Moolenbroek   #define r_ds              x.ds
168*d56f51eaSDavid van Moolenbroek   #define r_es              x.es
169*d56f51eaSDavid van Moolenbroek 
170*d56f51eaSDavid van Moolenbroek #elif (DOSX & DOS4GW)
171*d56f51eaSDavid van Moolenbroek   LOCAL struct DPMI_regs    reg;
172*d56f51eaSDavid van Moolenbroek   LOCAL WORD                rm_base_seg, rm_base_sel;
173*d56f51eaSDavid van Moolenbroek   LOCAL DWORD               realBase;
174*d56f51eaSDavid van Moolenbroek   LOCAL int                 para_skip = 0;
175*d56f51eaSDavid van Moolenbroek 
176*d56f51eaSDavid van Moolenbroek   LOCAL DWORD dpmi_get_real_vector (int intr);
177*d56f51eaSDavid van Moolenbroek   LOCAL WORD  dpmi_real_malloc     (int size, WORD *selector);
178*d56f51eaSDavid van Moolenbroek   LOCAL void  dpmi_real_free       (WORD selector);
179*d56f51eaSDavid van Moolenbroek   #define DOS_ADDR(s,o) (((DWORD)(s) << 4) + (WORD)(o))
180*d56f51eaSDavid van Moolenbroek 
181*d56f51eaSDavid van Moolenbroek #else              /* real-mode Borland etc. */
182*d56f51eaSDavid van Moolenbroek   static struct  {
183*d56f51eaSDavid van Moolenbroek          WORD r_ax, r_bx, r_cx, r_dx, r_bp;
184*d56f51eaSDavid van Moolenbroek          WORD r_si, r_di, r_ds, r_es, r_flags;
185*d56f51eaSDavid van Moolenbroek        } reg;
186*d56f51eaSDavid van Moolenbroek #endif
187*d56f51eaSDavid van Moolenbroek 
188*d56f51eaSDavid van Moolenbroek #ifdef __HIGHC__
189*d56f51eaSDavid van Moolenbroek   #pragma Alias (pktDrop,    "_pktDrop")
190*d56f51eaSDavid van Moolenbroek   #pragma Alias (pktRxBuf,   "_pktRxBuf")
191*d56f51eaSDavid van Moolenbroek   #pragma Alias (pktTxBuf,   "_pktTxBuf")
192*d56f51eaSDavid van Moolenbroek   #pragma Alias (pktTemp,    "_pktTemp")
193*d56f51eaSDavid van Moolenbroek   #pragma Alias (rxOutOfs,   "_rxOutOfs")
194*d56f51eaSDavid van Moolenbroek   #pragma Alias (rxInOfs,    "_rxInOfs")
195*d56f51eaSDavid van Moolenbroek   #pragma Alias (pktRxEnd,   "_pktRxEnd")
196*d56f51eaSDavid van Moolenbroek   #pragma Alias (PktReceiver,"_PktReceiver")
197*d56f51eaSDavid van Moolenbroek #endif
198*d56f51eaSDavid van Moolenbroek 
199*d56f51eaSDavid van Moolenbroek 
200*d56f51eaSDavid van Moolenbroek PUBLIC PKT_STAT    pktStat;    /* statistics for packets    */
201*d56f51eaSDavid van Moolenbroek PUBLIC PKT_INFO    pktInfo;    /* packet-driver information */
202*d56f51eaSDavid van Moolenbroek 
203*d56f51eaSDavid van Moolenbroek PUBLIC PKT_RX_MODE receiveMode  = PDRX_DIRECT;
204*d56f51eaSDavid van Moolenbroek PUBLIC ETHER       myAddress    = {   0,  0,  0,  0,  0,  0 };
205*d56f51eaSDavid van Moolenbroek PUBLIC ETHER       ethBroadcast = { 255,255,255,255,255,255 };
206*d56f51eaSDavid van Moolenbroek 
207*d56f51eaSDavid van Moolenbroek LOCAL  struct {             /* internal statistics */
208*d56f51eaSDavid van Moolenbroek        DWORD  tooSmall;     /* size < ETH_MIN */
209*d56f51eaSDavid van Moolenbroek        DWORD  tooLarge;     /* size > ETH_MAX */
210*d56f51eaSDavid van Moolenbroek        DWORD  badSync;      /* count_1 != count_2 */
211*d56f51eaSDavid van Moolenbroek        DWORD  wrongHandle;  /* upcall to wrong handle */
212*d56f51eaSDavid van Moolenbroek      } intStat;
213*d56f51eaSDavid van Moolenbroek 
214*d56f51eaSDavid van Moolenbroek /***************************************************************************/
215*d56f51eaSDavid van Moolenbroek 
PktGetErrorStr(int errNum)216*d56f51eaSDavid van Moolenbroek PUBLIC const char *PktGetErrorStr (int errNum)
217*d56f51eaSDavid van Moolenbroek {
218*d56f51eaSDavid van Moolenbroek   static const char *errStr[] = {
219*d56f51eaSDavid van Moolenbroek                     "",
220*d56f51eaSDavid van Moolenbroek                     "Invalid handle number",
221*d56f51eaSDavid van Moolenbroek                     "No interfaces of specified class found",
222*d56f51eaSDavid van Moolenbroek                     "No interfaces of specified type found",
223*d56f51eaSDavid van Moolenbroek                     "No interfaces of specified number found",
224*d56f51eaSDavid van Moolenbroek                     "Bad packet type specified",
225*d56f51eaSDavid van Moolenbroek                     "Interface does not support multicast",
226*d56f51eaSDavid van Moolenbroek                     "Packet driver cannot terminate",
227*d56f51eaSDavid van Moolenbroek                     "Invalid receiver mode specified",
228*d56f51eaSDavid van Moolenbroek                     "Insufficient memory space",
229*d56f51eaSDavid van Moolenbroek                     "Type previously accessed, and not released",
230*d56f51eaSDavid van Moolenbroek                     "Command out of range, or not implemented",
231*d56f51eaSDavid van Moolenbroek                     "Cannot send packet (usually hardware error)",
232*d56f51eaSDavid van Moolenbroek                     "Cannot change hardware address ( > 1 handle open)",
233*d56f51eaSDavid van Moolenbroek                     "Hardware address has bad length or format",
234*d56f51eaSDavid van Moolenbroek                     "Cannot reset interface (more than 1 handle open)",
235*d56f51eaSDavid van Moolenbroek                     "Bad Check-sum",
236*d56f51eaSDavid van Moolenbroek                     "Bad size",
237*d56f51eaSDavid van Moolenbroek                     "Bad sync" ,
238*d56f51eaSDavid van Moolenbroek                     "Source hit"
239*d56f51eaSDavid van Moolenbroek                   };
240*d56f51eaSDavid van Moolenbroek 
241*d56f51eaSDavid van Moolenbroek   if (errNum < 0 || errNum >= DIM(errStr))
242*d56f51eaSDavid van Moolenbroek      return ("Unknown driver error.");
243*d56f51eaSDavid van Moolenbroek   return (errStr [errNum]);
244*d56f51eaSDavid van Moolenbroek }
245*d56f51eaSDavid van Moolenbroek 
246*d56f51eaSDavid van Moolenbroek /**************************************************************************/
247*d56f51eaSDavid van Moolenbroek 
PktGetClassName(WORD class)248*d56f51eaSDavid van Moolenbroek PUBLIC const char *PktGetClassName (WORD class)
249*d56f51eaSDavid van Moolenbroek {
250*d56f51eaSDavid van Moolenbroek   switch (class)
251*d56f51eaSDavid van Moolenbroek   {
252*d56f51eaSDavid van Moolenbroek     case PD_ETHER:
253*d56f51eaSDavid van Moolenbroek          return ("DIX-Ether");
254*d56f51eaSDavid van Moolenbroek     case PD_PRONET10:
255*d56f51eaSDavid van Moolenbroek          return ("ProNET-10");
256*d56f51eaSDavid van Moolenbroek     case PD_IEEE8025:
257*d56f51eaSDavid van Moolenbroek          return ("IEEE 802.5");
258*d56f51eaSDavid van Moolenbroek     case PD_OMNINET:
259*d56f51eaSDavid van Moolenbroek          return ("OmniNet");
260*d56f51eaSDavid van Moolenbroek     case PD_APPLETALK:
261*d56f51eaSDavid van Moolenbroek          return ("AppleTalk");
262*d56f51eaSDavid van Moolenbroek     case PD_SLIP:
263*d56f51eaSDavid van Moolenbroek          return ("SLIP");
264*d56f51eaSDavid van Moolenbroek     case PD_STARTLAN:
265*d56f51eaSDavid van Moolenbroek          return ("StartLAN");
266*d56f51eaSDavid van Moolenbroek     case PD_ARCNET:
267*d56f51eaSDavid van Moolenbroek          return ("ArcNet");
268*d56f51eaSDavid van Moolenbroek     case PD_AX25:
269*d56f51eaSDavid van Moolenbroek          return ("AX.25");
270*d56f51eaSDavid van Moolenbroek     case PD_KISS:
271*d56f51eaSDavid van Moolenbroek          return ("KISS");
272*d56f51eaSDavid van Moolenbroek     case PD_IEEE8023_2:
273*d56f51eaSDavid van Moolenbroek          return ("IEEE 802.3 w/802.2 hdr");
274*d56f51eaSDavid van Moolenbroek     case PD_FDDI8022:
275*d56f51eaSDavid van Moolenbroek          return ("FDDI w/802.2 hdr");
276*d56f51eaSDavid van Moolenbroek     case PD_X25:
277*d56f51eaSDavid van Moolenbroek          return ("X.25");
278*d56f51eaSDavid van Moolenbroek     case PD_LANstar:
279*d56f51eaSDavid van Moolenbroek          return ("LANstar");
280*d56f51eaSDavid van Moolenbroek     case PD_PPP:
281*d56f51eaSDavid van Moolenbroek          return ("PPP");
282*d56f51eaSDavid van Moolenbroek     default:
283*d56f51eaSDavid van Moolenbroek          return ("unknown");
284*d56f51eaSDavid van Moolenbroek   }
285*d56f51eaSDavid van Moolenbroek }
286*d56f51eaSDavid van Moolenbroek 
287*d56f51eaSDavid van Moolenbroek /**************************************************************************/
288*d56f51eaSDavid van Moolenbroek 
PktRXmodeStr(PKT_RX_MODE mode)289*d56f51eaSDavid van Moolenbroek PUBLIC char const *PktRXmodeStr (PKT_RX_MODE mode)
290*d56f51eaSDavid van Moolenbroek {
291*d56f51eaSDavid van Moolenbroek   static const char *modeStr [] = {
292*d56f51eaSDavid van Moolenbroek                     "Receiver turned off",
293*d56f51eaSDavid van Moolenbroek                     "Receive only directly addressed packets",
294*d56f51eaSDavid van Moolenbroek                     "Receive direct & broadcast packets",
295*d56f51eaSDavid van Moolenbroek                     "Receive direct,broadcast and limited multicast packets",
296*d56f51eaSDavid van Moolenbroek                     "Receive direct,broadcast and all multicast packets",
297*d56f51eaSDavid van Moolenbroek                     "Receive all packets (promiscuouos mode)"
298*d56f51eaSDavid van Moolenbroek                   };
299*d56f51eaSDavid van Moolenbroek 
300*d56f51eaSDavid van Moolenbroek   if (mode > DIM(modeStr))
301*d56f51eaSDavid van Moolenbroek      return ("??");
302*d56f51eaSDavid van Moolenbroek   return (modeStr [mode-1]);
303*d56f51eaSDavid van Moolenbroek }
304*d56f51eaSDavid van Moolenbroek 
305*d56f51eaSDavid van Moolenbroek /**************************************************************************/
306*d56f51eaSDavid van Moolenbroek 
PktInterrupt(void)307*d56f51eaSDavid van Moolenbroek LOCAL __inline BOOL PktInterrupt (void)
308*d56f51eaSDavid van Moolenbroek {
309*d56f51eaSDavid van Moolenbroek   BOOL okay;
310*d56f51eaSDavid van Moolenbroek 
311*d56f51eaSDavid van Moolenbroek #if (DOSX & PHARLAP)
312*d56f51eaSDavid van Moolenbroek   _dx_real_int ((UINT)pktInfo.intr, &reg);
313*d56f51eaSDavid van Moolenbroek   okay = ((reg.flags & 1) == 0);  /* OK if carry clear */
314*d56f51eaSDavid van Moolenbroek 
315*d56f51eaSDavid van Moolenbroek #elif (DOSX & DJGPP)
316*d56f51eaSDavid van Moolenbroek   __dpmi_int ((int)pktInfo.intr, &reg);
317*d56f51eaSDavid van Moolenbroek   okay = ((reg.x.flags & 1) == 0);
318*d56f51eaSDavid van Moolenbroek 
319*d56f51eaSDavid van Moolenbroek #elif (DOSX & DOS4GW)
320*d56f51eaSDavid van Moolenbroek   union  REGS  r;
321*d56f51eaSDavid van Moolenbroek   struct SREGS s;
322*d56f51eaSDavid van Moolenbroek 
323*d56f51eaSDavid van Moolenbroek   memset (&r, 0, sizeof(r));
324*d56f51eaSDavid van Moolenbroek   segread (&s);
325*d56f51eaSDavid van Moolenbroek   r.w.ax  = 0x300;
326*d56f51eaSDavid van Moolenbroek   r.x.ebx = pktInfo.intr;
327*d56f51eaSDavid van Moolenbroek   r.w.cx  = 0;
328*d56f51eaSDavid van Moolenbroek   s.es    = FP_SEG (&reg);
329*d56f51eaSDavid van Moolenbroek   r.x.edi = FP_OFF (&reg);
330*d56f51eaSDavid van Moolenbroek   reg.r_flags = 0;
331*d56f51eaSDavid van Moolenbroek   reg.r_ss = reg.r_sp = 0;     /* DPMI host provides stack */
332*d56f51eaSDavid van Moolenbroek 
333*d56f51eaSDavid van Moolenbroek   int386x (0x31, &r, &r, &s);
334*d56f51eaSDavid van Moolenbroek   okay = (!r.w.cflag);
335*d56f51eaSDavid van Moolenbroek 
336*d56f51eaSDavid van Moolenbroek #else
337*d56f51eaSDavid van Moolenbroek   reg.r_flags = 0;
338*d56f51eaSDavid van Moolenbroek   intr (pktInfo.intr, (struct REGPACK*)&reg);
339*d56f51eaSDavid van Moolenbroek   okay = ((reg.r_flags & 1) == 0);
340*d56f51eaSDavid van Moolenbroek #endif
341*d56f51eaSDavid van Moolenbroek 
342*d56f51eaSDavid van Moolenbroek   if (okay)
343*d56f51eaSDavid van Moolenbroek        pktInfo.error = NULL;
344*d56f51eaSDavid van Moolenbroek   else pktInfo.error = PktGetErrorStr (reg.r_dx >> 8);
345*d56f51eaSDavid van Moolenbroek   return (okay);
346*d56f51eaSDavid van Moolenbroek }
347*d56f51eaSDavid van Moolenbroek 
348*d56f51eaSDavid van Moolenbroek /**************************************************************************/
349*d56f51eaSDavid van Moolenbroek 
350*d56f51eaSDavid van Moolenbroek /*
351*d56f51eaSDavid van Moolenbroek  * Search for packet driver at interrupt 60h through 80h. If ASCIIZ
352*d56f51eaSDavid van Moolenbroek  * string "PKT DRVR" found at offset 3 in the interrupt handler, return
353*d56f51eaSDavid van Moolenbroek  * interrupt number, else return zero in pktInfo.intr
354*d56f51eaSDavid van Moolenbroek  */
PktSearchDriver(void)355*d56f51eaSDavid van Moolenbroek PUBLIC BOOL PktSearchDriver (void)
356*d56f51eaSDavid van Moolenbroek {
357*d56f51eaSDavid van Moolenbroek   BYTE intr  = 0x20;
358*d56f51eaSDavid van Moolenbroek   BOOL found = FALSE;
359*d56f51eaSDavid van Moolenbroek 
360*d56f51eaSDavid van Moolenbroek   while (!found && intr < 0xFF)
361*d56f51eaSDavid van Moolenbroek   {
362*d56f51eaSDavid van Moolenbroek     static char str[12];                 /* 3 + strlen("PKT DRVR") */
363*d56f51eaSDavid van Moolenbroek     static char pktStr[9] = "PKT DRVR";  /* ASCIIZ string at ofs 3 */
364*d56f51eaSDavid van Moolenbroek     DWORD  rp;                           /* in interrupt  routine  */
365*d56f51eaSDavid van Moolenbroek 
366*d56f51eaSDavid van Moolenbroek #if (DOSX & PHARLAP)
367*d56f51eaSDavid van Moolenbroek     _dx_rmiv_get (intr, &rp);
368*d56f51eaSDavid van Moolenbroek     ReadRealMem (&str, (REALPTR)rp, sizeof(str));
369*d56f51eaSDavid van Moolenbroek 
370*d56f51eaSDavid van Moolenbroek #elif (DOSX & DJGPP)
371*d56f51eaSDavid van Moolenbroek     __dpmi_raddr realAdr;
372*d56f51eaSDavid van Moolenbroek     __dpmi_get_real_mode_interrupt_vector (intr, &realAdr);
373*d56f51eaSDavid van Moolenbroek     rp = (realAdr.segment << 4) + realAdr.offset16;
374*d56f51eaSDavid van Moolenbroek     dosmemget (rp, sizeof(str), &str);
375*d56f51eaSDavid van Moolenbroek 
376*d56f51eaSDavid van Moolenbroek #elif (DOSX & DOS4GW)
377*d56f51eaSDavid van Moolenbroek     rp = dpmi_get_real_vector (intr);
378*d56f51eaSDavid van Moolenbroek     memcpy (&str, (void*)rp, sizeof(str));
379*d56f51eaSDavid van Moolenbroek 
380*d56f51eaSDavid van Moolenbroek #else
381*d56f51eaSDavid van Moolenbroek     _fmemcpy (&str, getvect(intr), sizeof(str));
382*d56f51eaSDavid van Moolenbroek #endif
383*d56f51eaSDavid van Moolenbroek 
384*d56f51eaSDavid van Moolenbroek     found = memcmp (&str[3],&pktStr,sizeof(pktStr)) == 0;
385*d56f51eaSDavid van Moolenbroek     intr++;
386*d56f51eaSDavid van Moolenbroek   }
387*d56f51eaSDavid van Moolenbroek   pktInfo.intr = (found ? intr-1 : 0);
388*d56f51eaSDavid van Moolenbroek   return (found);
389*d56f51eaSDavid van Moolenbroek }
390*d56f51eaSDavid van Moolenbroek 
391*d56f51eaSDavid van Moolenbroek 
392*d56f51eaSDavid van Moolenbroek /**************************************************************************/
393*d56f51eaSDavid van Moolenbroek 
PktSetAccess(void)394*d56f51eaSDavid van Moolenbroek static BOOL PktSetAccess (void)
395*d56f51eaSDavid van Moolenbroek {
396*d56f51eaSDavid van Moolenbroek   reg.r_ax = 0x0200 + pktInfo.class;
397*d56f51eaSDavid van Moolenbroek   reg.r_bx = 0xFFFF;
398*d56f51eaSDavid van Moolenbroek   reg.r_dx = 0;
399*d56f51eaSDavid van Moolenbroek   reg.r_cx = 0;
400*d56f51eaSDavid van Moolenbroek 
401*d56f51eaSDavid van Moolenbroek #if (DOSX & PHARLAP)
402*d56f51eaSDavid van Moolenbroek   reg.ds  = 0;
403*d56f51eaSDavid van Moolenbroek   reg.esi = 0;
404*d56f51eaSDavid van Moolenbroek   reg.es  = RP_SEG (realBase);
405*d56f51eaSDavid van Moolenbroek   reg.edi = (WORD) &PktReceiver;
406*d56f51eaSDavid van Moolenbroek 
407*d56f51eaSDavid van Moolenbroek #elif (DOSX & DJGPP)
408*d56f51eaSDavid van Moolenbroek   reg.x.ds = 0;
409*d56f51eaSDavid van Moolenbroek   reg.x.si = 0;
410*d56f51eaSDavid van Moolenbroek   reg.x.es = rm_mem.rm_segment;
411*d56f51eaSDavid van Moolenbroek   reg.x.di = PktReceiver;
412*d56f51eaSDavid van Moolenbroek 
413*d56f51eaSDavid van Moolenbroek #elif (DOSX & DOS4GW)
414*d56f51eaSDavid van Moolenbroek   reg.r_ds = 0;
415*d56f51eaSDavid van Moolenbroek   reg.r_si = 0;
416*d56f51eaSDavid van Moolenbroek   reg.r_es = rm_base_seg;
417*d56f51eaSDavid van Moolenbroek   reg.r_di = PktReceiver;
418*d56f51eaSDavid van Moolenbroek 
419*d56f51eaSDavid van Moolenbroek #else
420*d56f51eaSDavid van Moolenbroek   reg.r_ds = 0;
421*d56f51eaSDavid van Moolenbroek   reg.r_si = 0;
422*d56f51eaSDavid van Moolenbroek   reg.r_es = FP_SEG (&PktReceiver);
423*d56f51eaSDavid van Moolenbroek   reg.r_di = FP_OFF (&PktReceiver);
424*d56f51eaSDavid van Moolenbroek #endif
425*d56f51eaSDavid van Moolenbroek 
426*d56f51eaSDavid van Moolenbroek   if (!PktInterrupt())
427*d56f51eaSDavid van Moolenbroek      return (FALSE);
428*d56f51eaSDavid van Moolenbroek 
429*d56f51eaSDavid van Moolenbroek   pktInfo.handle = reg.r_ax;
430*d56f51eaSDavid van Moolenbroek   return (TRUE);
431*d56f51eaSDavid van Moolenbroek }
432*d56f51eaSDavid van Moolenbroek 
433*d56f51eaSDavid van Moolenbroek /**************************************************************************/
434*d56f51eaSDavid van Moolenbroek 
PktReleaseHandle(WORD handle)435*d56f51eaSDavid van Moolenbroek PUBLIC BOOL PktReleaseHandle (WORD handle)
436*d56f51eaSDavid van Moolenbroek {
437*d56f51eaSDavid van Moolenbroek   reg.r_ax = 0x0300;
438*d56f51eaSDavid van Moolenbroek   reg.r_bx = handle;
439*d56f51eaSDavid van Moolenbroek   return PktInterrupt();
440*d56f51eaSDavid van Moolenbroek }
441*d56f51eaSDavid van Moolenbroek 
442*d56f51eaSDavid van Moolenbroek /**************************************************************************/
443*d56f51eaSDavid van Moolenbroek 
PktTransmit(const void * eth,int len)444*d56f51eaSDavid van Moolenbroek PUBLIC BOOL PktTransmit (const void *eth, int len)
445*d56f51eaSDavid van Moolenbroek {
446*d56f51eaSDavid van Moolenbroek   if (len > ETH_MTU)
447*d56f51eaSDavid van Moolenbroek      return (FALSE);
448*d56f51eaSDavid van Moolenbroek 
449*d56f51eaSDavid van Moolenbroek   reg.r_ax = 0x0400;             /* Function 4, send pkt */
450*d56f51eaSDavid van Moolenbroek   reg.r_cx = len;                /* total size of frame  */
451*d56f51eaSDavid van Moolenbroek 
452*d56f51eaSDavid van Moolenbroek #if (DOSX & DJGPP)
453*d56f51eaSDavid van Moolenbroek   dosmemput (eth, len, realBase+pktTxBuf);
454*d56f51eaSDavid van Moolenbroek   reg.x.ds = rm_mem.rm_segment;  /* DOS data segment and */
455*d56f51eaSDavid van Moolenbroek   reg.x.si = pktTxBuf;           /* DOS offset to buffer */
456*d56f51eaSDavid van Moolenbroek 
457*d56f51eaSDavid van Moolenbroek #elif (DOSX & DOS4GW)
458*d56f51eaSDavid van Moolenbroek   memcpy ((void*)(realBase+pktTxBuf), eth, len);
459*d56f51eaSDavid van Moolenbroek   reg.r_ds = rm_base_seg;
460*d56f51eaSDavid van Moolenbroek   reg.r_si = pktTxBuf;
461*d56f51eaSDavid van Moolenbroek 
462*d56f51eaSDavid van Moolenbroek #elif (DOSX & PHARLAP)
463*d56f51eaSDavid van Moolenbroek   memcpy (&pktTxBuf, eth, len);
464*d56f51eaSDavid van Moolenbroek   reg.r_ds = FP_SEG (&pktTxBuf);
465*d56f51eaSDavid van Moolenbroek   reg.r_si = FP_OFF (&pktTxBuf);
466*d56f51eaSDavid van Moolenbroek 
467*d56f51eaSDavid van Moolenbroek #else
468*d56f51eaSDavid van Moolenbroek   reg.r_ds = FP_SEG (eth);
469*d56f51eaSDavid van Moolenbroek   reg.r_si = FP_OFF (eth);
470*d56f51eaSDavid van Moolenbroek #endif
471*d56f51eaSDavid van Moolenbroek 
472*d56f51eaSDavid van Moolenbroek   return PktInterrupt();
473*d56f51eaSDavid van Moolenbroek }
474*d56f51eaSDavid van Moolenbroek 
475*d56f51eaSDavid van Moolenbroek /**************************************************************************/
476*d56f51eaSDavid van Moolenbroek 
477*d56f51eaSDavid van Moolenbroek #if (DOSX & (DJGPP|DOS4GW))
CheckElement(RX_ELEMENT * rx)478*d56f51eaSDavid van Moolenbroek LOCAL __inline BOOL CheckElement (RX_ELEMENT *rx)
479*d56f51eaSDavid van Moolenbroek #else
480*d56f51eaSDavid van Moolenbroek LOCAL __inline BOOL CheckElement (RX_ELEMENT _far *rx)
481*d56f51eaSDavid van Moolenbroek #endif
482*d56f51eaSDavid van Moolenbroek {
483*d56f51eaSDavid van Moolenbroek   WORD count_1, count_2;
484*d56f51eaSDavid van Moolenbroek 
485*d56f51eaSDavid van Moolenbroek   /*
486*d56f51eaSDavid van Moolenbroek    * We got an upcall to the same RMCB with wrong handle.
487*d56f51eaSDavid van Moolenbroek    * This can happen if we failed to release handle at program exit
488*d56f51eaSDavid van Moolenbroek    */
489*d56f51eaSDavid van Moolenbroek   if (rx->handle != pktInfo.handle)
490*d56f51eaSDavid van Moolenbroek   {
491*d56f51eaSDavid van Moolenbroek     pktInfo.error = "Wrong handle";
492*d56f51eaSDavid van Moolenbroek     intStat.wrongHandle++;
493*d56f51eaSDavid van Moolenbroek     PktReleaseHandle (rx->handle);
494*d56f51eaSDavid van Moolenbroek     return (FALSE);
495*d56f51eaSDavid van Moolenbroek   }
496*d56f51eaSDavid van Moolenbroek   count_1 = rx->firstCount;
497*d56f51eaSDavid van Moolenbroek   count_2 = rx->secondCount;
498*d56f51eaSDavid van Moolenbroek 
499*d56f51eaSDavid van Moolenbroek   if (count_1 != count_2)
500*d56f51eaSDavid van Moolenbroek   {
501*d56f51eaSDavid van Moolenbroek     pktInfo.error = "Bad sync";
502*d56f51eaSDavid van Moolenbroek     intStat.badSync++;
503*d56f51eaSDavid van Moolenbroek     return (FALSE);
504*d56f51eaSDavid van Moolenbroek   }
505*d56f51eaSDavid van Moolenbroek   if (count_1 > ETH_MAX)
506*d56f51eaSDavid van Moolenbroek   {
507*d56f51eaSDavid van Moolenbroek     pktInfo.error = "Large esize";
508*d56f51eaSDavid van Moolenbroek     intStat.tooLarge++;
509*d56f51eaSDavid van Moolenbroek     return (FALSE);
510*d56f51eaSDavid van Moolenbroek   }
511*d56f51eaSDavid van Moolenbroek #if 0
512*d56f51eaSDavid van Moolenbroek   if (count_1 < ETH_MIN)
513*d56f51eaSDavid van Moolenbroek   {
514*d56f51eaSDavid van Moolenbroek     pktInfo.error = "Small esize";
515*d56f51eaSDavid van Moolenbroek     intStat.tooSmall++;
516*d56f51eaSDavid van Moolenbroek     return (FALSE);
517*d56f51eaSDavid van Moolenbroek   }
518*d56f51eaSDavid van Moolenbroek #endif
519*d56f51eaSDavid van Moolenbroek   return (TRUE);
520*d56f51eaSDavid van Moolenbroek }
521*d56f51eaSDavid van Moolenbroek 
522*d56f51eaSDavid van Moolenbroek /**************************************************************************/
523*d56f51eaSDavid van Moolenbroek 
PktTerminHandle(WORD handle)524*d56f51eaSDavid van Moolenbroek PUBLIC BOOL PktTerminHandle (WORD handle)
525*d56f51eaSDavid van Moolenbroek {
526*d56f51eaSDavid van Moolenbroek   reg.r_ax = 0x0500;
527*d56f51eaSDavid van Moolenbroek   reg.r_bx = handle;
528*d56f51eaSDavid van Moolenbroek   return PktInterrupt();
529*d56f51eaSDavid van Moolenbroek }
530*d56f51eaSDavid van Moolenbroek 
531*d56f51eaSDavid van Moolenbroek /**************************************************************************/
532*d56f51eaSDavid van Moolenbroek 
PktResetInterface(WORD handle)533*d56f51eaSDavid van Moolenbroek PUBLIC BOOL PktResetInterface (WORD handle)
534*d56f51eaSDavid van Moolenbroek {
535*d56f51eaSDavid van Moolenbroek   reg.r_ax = 0x0700;
536*d56f51eaSDavid van Moolenbroek   reg.r_bx = handle;
537*d56f51eaSDavid van Moolenbroek   return PktInterrupt();
538*d56f51eaSDavid van Moolenbroek }
539*d56f51eaSDavid van Moolenbroek 
540*d56f51eaSDavid van Moolenbroek /**************************************************************************/
541*d56f51eaSDavid van Moolenbroek 
PktSetReceiverMode(PKT_RX_MODE mode)542*d56f51eaSDavid van Moolenbroek PUBLIC BOOL PktSetReceiverMode (PKT_RX_MODE mode)
543*d56f51eaSDavid van Moolenbroek {
544*d56f51eaSDavid van Moolenbroek   if (pktInfo.class == PD_SLIP || pktInfo.class == PD_PPP)
545*d56f51eaSDavid van Moolenbroek      return (TRUE);
546*d56f51eaSDavid van Moolenbroek 
547*d56f51eaSDavid van Moolenbroek   reg.r_ax = 0x1400;
548*d56f51eaSDavid van Moolenbroek   reg.r_bx = pktInfo.handle;
549*d56f51eaSDavid van Moolenbroek   reg.r_cx = (WORD)mode;
550*d56f51eaSDavid van Moolenbroek 
551*d56f51eaSDavid van Moolenbroek   if (!PktInterrupt())
552*d56f51eaSDavid van Moolenbroek      return (FALSE);
553*d56f51eaSDavid van Moolenbroek 
554*d56f51eaSDavid van Moolenbroek   receiveMode = mode;
555*d56f51eaSDavid van Moolenbroek   return (TRUE);
556*d56f51eaSDavid van Moolenbroek }
557*d56f51eaSDavid van Moolenbroek 
558*d56f51eaSDavid van Moolenbroek /**************************************************************************/
559*d56f51eaSDavid van Moolenbroek 
PktGetReceiverMode(PKT_RX_MODE * mode)560*d56f51eaSDavid van Moolenbroek PUBLIC BOOL PktGetReceiverMode (PKT_RX_MODE *mode)
561*d56f51eaSDavid van Moolenbroek {
562*d56f51eaSDavid van Moolenbroek   reg.r_ax = 0x1500;
563*d56f51eaSDavid van Moolenbroek   reg.r_bx = pktInfo.handle;
564*d56f51eaSDavid van Moolenbroek 
565*d56f51eaSDavid van Moolenbroek   if (!PktInterrupt())
566*d56f51eaSDavid van Moolenbroek      return (FALSE);
567*d56f51eaSDavid van Moolenbroek 
568*d56f51eaSDavid van Moolenbroek   *mode = reg.r_ax;
569*d56f51eaSDavid van Moolenbroek   return (TRUE);
570*d56f51eaSDavid van Moolenbroek }
571*d56f51eaSDavid van Moolenbroek 
572*d56f51eaSDavid van Moolenbroek /**************************************************************************/
573*d56f51eaSDavid van Moolenbroek 
574*d56f51eaSDavid van Moolenbroek static PKT_STAT initialStat;         /* statistics at startup */
575*d56f51eaSDavid van Moolenbroek static BOOL     resetStat = FALSE;   /* statistics reset ? */
576*d56f51eaSDavid van Moolenbroek 
PktGetStatistics(WORD handle)577*d56f51eaSDavid van Moolenbroek PUBLIC BOOL PktGetStatistics (WORD handle)
578*d56f51eaSDavid van Moolenbroek {
579*d56f51eaSDavid van Moolenbroek   reg.r_ax = 0x1800;
580*d56f51eaSDavid van Moolenbroek   reg.r_bx = handle;
581*d56f51eaSDavid van Moolenbroek 
582*d56f51eaSDavid van Moolenbroek   if (!PktInterrupt())
583*d56f51eaSDavid van Moolenbroek      return (FALSE);
584*d56f51eaSDavid van Moolenbroek 
585*d56f51eaSDavid van Moolenbroek #if (DOSX & PHARLAP)
586*d56f51eaSDavid van Moolenbroek   ReadRealMem (&pktStat, DOS_ADDR(reg.ds,reg.esi), sizeof(pktStat));
587*d56f51eaSDavid van Moolenbroek 
588*d56f51eaSDavid van Moolenbroek #elif (DOSX & DJGPP)
589*d56f51eaSDavid van Moolenbroek   dosmemget (DOS_ADDR(reg.x.ds,reg.x.si), sizeof(pktStat), &pktStat);
590*d56f51eaSDavid van Moolenbroek 
591*d56f51eaSDavid van Moolenbroek #elif (DOSX & DOS4GW)
592*d56f51eaSDavid van Moolenbroek   memcpy (&pktStat, (void*)DOS_ADDR(reg.r_ds,reg.r_si), sizeof(pktStat));
593*d56f51eaSDavid van Moolenbroek 
594*d56f51eaSDavid van Moolenbroek #else
595*d56f51eaSDavid van Moolenbroek   _fmemcpy (&pktStat, MK_FP(reg.r_ds,reg.r_si), sizeof(pktStat));
596*d56f51eaSDavid van Moolenbroek #endif
597*d56f51eaSDavid van Moolenbroek 
598*d56f51eaSDavid van Moolenbroek   return (TRUE);
599*d56f51eaSDavid van Moolenbroek }
600*d56f51eaSDavid van Moolenbroek 
601*d56f51eaSDavid van Moolenbroek /**************************************************************************/
602*d56f51eaSDavid van Moolenbroek 
PktSessStatistics(WORD handle)603*d56f51eaSDavid van Moolenbroek PUBLIC BOOL PktSessStatistics (WORD handle)
604*d56f51eaSDavid van Moolenbroek {
605*d56f51eaSDavid van Moolenbroek   if (!PktGetStatistics(pktInfo.handle))
606*d56f51eaSDavid van Moolenbroek      return (FALSE);
607*d56f51eaSDavid van Moolenbroek 
608*d56f51eaSDavid van Moolenbroek   if (resetStat)
609*d56f51eaSDavid van Moolenbroek   {
610*d56f51eaSDavid van Moolenbroek     pktStat.inPackets  -= initialStat.inPackets;
611*d56f51eaSDavid van Moolenbroek     pktStat.outPackets -= initialStat.outPackets;
612*d56f51eaSDavid van Moolenbroek     pktStat.inBytes    -= initialStat.inBytes;
613*d56f51eaSDavid van Moolenbroek     pktStat.outBytes   -= initialStat.outBytes;
614*d56f51eaSDavid van Moolenbroek     pktStat.inErrors   -= initialStat.inErrors;
615*d56f51eaSDavid van Moolenbroek     pktStat.outErrors  -= initialStat.outErrors;
616*d56f51eaSDavid van Moolenbroek     pktStat.outErrors  -= initialStat.outErrors;
617*d56f51eaSDavid van Moolenbroek     pktStat.lost       -= initialStat.lost;
618*d56f51eaSDavid van Moolenbroek   }
619*d56f51eaSDavid van Moolenbroek   return (TRUE);
620*d56f51eaSDavid van Moolenbroek }
621*d56f51eaSDavid van Moolenbroek 
622*d56f51eaSDavid van Moolenbroek /**************************************************************************/
623*d56f51eaSDavid van Moolenbroek 
PktResetStatistics(WORD handle)624*d56f51eaSDavid van Moolenbroek PUBLIC BOOL PktResetStatistics (WORD handle)
625*d56f51eaSDavid van Moolenbroek {
626*d56f51eaSDavid van Moolenbroek   if (!PktGetStatistics(pktInfo.handle))
627*d56f51eaSDavid van Moolenbroek      return (FALSE);
628*d56f51eaSDavid van Moolenbroek 
629*d56f51eaSDavid van Moolenbroek   memcpy (&initialStat, &pktStat, sizeof(initialStat));
630*d56f51eaSDavid van Moolenbroek   resetStat = TRUE;
631*d56f51eaSDavid van Moolenbroek   return (TRUE);
632*d56f51eaSDavid van Moolenbroek }
633*d56f51eaSDavid van Moolenbroek 
634*d56f51eaSDavid van Moolenbroek /**************************************************************************/
635*d56f51eaSDavid van Moolenbroek 
PktGetAddress(ETHER * addr)636*d56f51eaSDavid van Moolenbroek PUBLIC BOOL PktGetAddress (ETHER *addr)
637*d56f51eaSDavid van Moolenbroek {
638*d56f51eaSDavid van Moolenbroek   reg.r_ax = 0x0600;
639*d56f51eaSDavid van Moolenbroek   reg.r_bx = pktInfo.handle;
640*d56f51eaSDavid van Moolenbroek   reg.r_cx = sizeof (*addr);
641*d56f51eaSDavid van Moolenbroek 
642*d56f51eaSDavid van Moolenbroek #if (DOSX & DJGPP)
643*d56f51eaSDavid van Moolenbroek   reg.x.es = rm_mem.rm_segment;
644*d56f51eaSDavid van Moolenbroek   reg.x.di = pktTemp;
645*d56f51eaSDavid van Moolenbroek #elif (DOSX & DOS4GW)
646*d56f51eaSDavid van Moolenbroek   reg.r_es = rm_base_seg;
647*d56f51eaSDavid van Moolenbroek   reg.r_di = pktTemp;
648*d56f51eaSDavid van Moolenbroek #else
649*d56f51eaSDavid van Moolenbroek   reg.r_es = FP_SEG (&pktTemp);
650*d56f51eaSDavid van Moolenbroek   reg.r_di = FP_OFF (&pktTemp);  /* ES:DI = address for result */
651*d56f51eaSDavid van Moolenbroek #endif
652*d56f51eaSDavid van Moolenbroek 
653*d56f51eaSDavid van Moolenbroek   if (!PktInterrupt())
654*d56f51eaSDavid van Moolenbroek      return (FALSE);
655*d56f51eaSDavid van Moolenbroek 
656*d56f51eaSDavid van Moolenbroek #if (DOSX & PHARLAP)
657*d56f51eaSDavid van Moolenbroek   ReadRealMem (addr, realBase + (WORD)&pktTemp, sizeof(*addr));
658*d56f51eaSDavid van Moolenbroek 
659*d56f51eaSDavid van Moolenbroek #elif (DOSX & DJGPP)
660*d56f51eaSDavid van Moolenbroek   dosmemget (realBase+pktTemp, sizeof(*addr), addr);
661*d56f51eaSDavid van Moolenbroek 
662*d56f51eaSDavid van Moolenbroek #elif (DOSX & DOS4GW)
663*d56f51eaSDavid van Moolenbroek   memcpy (addr, (void*)(realBase+pktTemp), sizeof(*addr));
664*d56f51eaSDavid van Moolenbroek 
665*d56f51eaSDavid van Moolenbroek #else
666*d56f51eaSDavid van Moolenbroek   memcpy ((void*)addr, &pktTemp, sizeof(*addr));
667*d56f51eaSDavid van Moolenbroek #endif
668*d56f51eaSDavid van Moolenbroek 
669*d56f51eaSDavid van Moolenbroek   return (TRUE);
670*d56f51eaSDavid van Moolenbroek }
671*d56f51eaSDavid van Moolenbroek 
672*d56f51eaSDavid van Moolenbroek /**************************************************************************/
673*d56f51eaSDavid van Moolenbroek 
PktSetAddress(const ETHER * addr)674*d56f51eaSDavid van Moolenbroek PUBLIC BOOL PktSetAddress (const ETHER *addr)
675*d56f51eaSDavid van Moolenbroek {
676*d56f51eaSDavid van Moolenbroek   /* copy addr to real-mode scrath area */
677*d56f51eaSDavid van Moolenbroek 
678*d56f51eaSDavid van Moolenbroek #if (DOSX & PHARLAP)
679*d56f51eaSDavid van Moolenbroek   WriteRealMem (realBase + (WORD)&pktTemp, (void*)addr, sizeof(*addr));
680*d56f51eaSDavid van Moolenbroek 
681*d56f51eaSDavid van Moolenbroek #elif (DOSX & DJGPP)
682*d56f51eaSDavid van Moolenbroek   dosmemput (addr, sizeof(*addr), realBase+pktTemp);
683*d56f51eaSDavid van Moolenbroek 
684*d56f51eaSDavid van Moolenbroek #elif (DOSX & DOS4GW)
685*d56f51eaSDavid van Moolenbroek   memcpy ((void*)(realBase+pktTemp), addr, sizeof(*addr));
686*d56f51eaSDavid van Moolenbroek 
687*d56f51eaSDavid van Moolenbroek #else
688*d56f51eaSDavid van Moolenbroek   memcpy (&pktTemp, (void*)addr, sizeof(*addr));
689*d56f51eaSDavid van Moolenbroek #endif
690*d56f51eaSDavid van Moolenbroek 
691*d56f51eaSDavid van Moolenbroek   reg.r_ax = 0x1900;
692*d56f51eaSDavid van Moolenbroek   reg.r_cx = sizeof (*addr);      /* address length       */
693*d56f51eaSDavid van Moolenbroek 
694*d56f51eaSDavid van Moolenbroek #if (DOSX & DJGPP)
695*d56f51eaSDavid van Moolenbroek   reg.x.es = rm_mem.rm_segment;   /* DOS offset to param  */
696*d56f51eaSDavid van Moolenbroek   reg.x.di = pktTemp;             /* DOS segment to param */
697*d56f51eaSDavid van Moolenbroek #elif (DOSX & DOS4GW)
698*d56f51eaSDavid van Moolenbroek   reg.r_es = rm_base_seg;
699*d56f51eaSDavid van Moolenbroek   reg.r_di = pktTemp;
700*d56f51eaSDavid van Moolenbroek #else
701*d56f51eaSDavid van Moolenbroek   reg.r_es = FP_SEG (&pktTemp);
702*d56f51eaSDavid van Moolenbroek   reg.r_di = FP_OFF (&pktTemp);
703*d56f51eaSDavid van Moolenbroek #endif
704*d56f51eaSDavid van Moolenbroek 
705*d56f51eaSDavid van Moolenbroek   return PktInterrupt();
706*d56f51eaSDavid van Moolenbroek }
707*d56f51eaSDavid van Moolenbroek 
708*d56f51eaSDavid van Moolenbroek /**************************************************************************/
709*d56f51eaSDavid van Moolenbroek 
PktGetDriverInfo(void)710*d56f51eaSDavid van Moolenbroek PUBLIC BOOL PktGetDriverInfo (void)
711*d56f51eaSDavid van Moolenbroek {
712*d56f51eaSDavid van Moolenbroek   pktInfo.majVer = 0;
713*d56f51eaSDavid van Moolenbroek   pktInfo.minVer = 0;
714*d56f51eaSDavid van Moolenbroek   memset (&pktInfo.name, 0, sizeof(pktInfo.name));
715*d56f51eaSDavid van Moolenbroek   reg.r_ax = 0x01FF;
716*d56f51eaSDavid van Moolenbroek   reg.r_bx = 0;
717*d56f51eaSDavid van Moolenbroek 
718*d56f51eaSDavid van Moolenbroek   if (!PktInterrupt())
719*d56f51eaSDavid van Moolenbroek      return (FALSE);
720*d56f51eaSDavid van Moolenbroek 
721*d56f51eaSDavid van Moolenbroek   pktInfo.number = reg.r_cx & 0xFF;
722*d56f51eaSDavid van Moolenbroek   pktInfo.class  = reg.r_cx >> 8;
723*d56f51eaSDavid van Moolenbroek #if 0
724*d56f51eaSDavid van Moolenbroek   pktInfo.minVer = reg.r_bx % 10;
725*d56f51eaSDavid van Moolenbroek   pktInfo.majVer = reg.r_bx / 10;
726*d56f51eaSDavid van Moolenbroek #else
727*d56f51eaSDavid van Moolenbroek   pktInfo.majVer = reg.r_bx;  // !!
728*d56f51eaSDavid van Moolenbroek #endif
729*d56f51eaSDavid van Moolenbroek   pktInfo.funcs  = reg.r_ax & 0xFF;
730*d56f51eaSDavid van Moolenbroek   pktInfo.type   = reg.r_dx & 0xFF;
731*d56f51eaSDavid van Moolenbroek 
732*d56f51eaSDavid van Moolenbroek #if (DOSX & PHARLAP)
733*d56f51eaSDavid van Moolenbroek   ReadRealMem (&pktInfo.name, DOS_ADDR(reg.ds,reg.esi), sizeof(pktInfo.name));
734*d56f51eaSDavid van Moolenbroek 
735*d56f51eaSDavid van Moolenbroek #elif (DOSX & DJGPP)
736*d56f51eaSDavid van Moolenbroek   dosmemget (DOS_ADDR(reg.x.ds,reg.x.si), sizeof(pktInfo.name), &pktInfo.name);
737*d56f51eaSDavid van Moolenbroek 
738*d56f51eaSDavid van Moolenbroek #elif (DOSX & DOS4GW)
739*d56f51eaSDavid van Moolenbroek   memcpy (&pktInfo.name, (void*)DOS_ADDR(reg.r_ds,reg.r_si), sizeof(pktInfo.name));
740*d56f51eaSDavid van Moolenbroek 
741*d56f51eaSDavid van Moolenbroek #else
742*d56f51eaSDavid van Moolenbroek   _fmemcpy (&pktInfo.name, MK_FP(reg.r_ds,reg.r_si), sizeof(pktInfo.name));
743*d56f51eaSDavid van Moolenbroek #endif
744*d56f51eaSDavid van Moolenbroek   return (TRUE);
745*d56f51eaSDavid van Moolenbroek }
746*d56f51eaSDavid van Moolenbroek 
747*d56f51eaSDavid van Moolenbroek /**************************************************************************/
748*d56f51eaSDavid van Moolenbroek 
PktGetDriverParam(void)749*d56f51eaSDavid van Moolenbroek PUBLIC BOOL PktGetDriverParam (void)
750*d56f51eaSDavid van Moolenbroek {
751*d56f51eaSDavid van Moolenbroek   reg.r_ax = 0x0A00;
752*d56f51eaSDavid van Moolenbroek 
753*d56f51eaSDavid van Moolenbroek   if (!PktInterrupt())
754*d56f51eaSDavid van Moolenbroek      return (FALSE);
755*d56f51eaSDavid van Moolenbroek 
756*d56f51eaSDavid van Moolenbroek #if (DOSX & PHARLAP)
757*d56f51eaSDavid van Moolenbroek   ReadRealMem (&pktInfo.majVer, DOS_ADDR(reg.es,reg.edi), PKT_PARAM_SIZE);
758*d56f51eaSDavid van Moolenbroek 
759*d56f51eaSDavid van Moolenbroek #elif (DOSX & DJGPP)
760*d56f51eaSDavid van Moolenbroek   dosmemget (DOS_ADDR(reg.x.es,reg.x.di), PKT_PARAM_SIZE, &pktInfo.majVer);
761*d56f51eaSDavid van Moolenbroek 
762*d56f51eaSDavid van Moolenbroek #elif (DOSX & DOS4GW)
763*d56f51eaSDavid van Moolenbroek   memcpy (&pktInfo.majVer, (void*)DOS_ADDR(reg.r_es,reg.r_di), PKT_PARAM_SIZE);
764*d56f51eaSDavid van Moolenbroek 
765*d56f51eaSDavid van Moolenbroek #else
766*d56f51eaSDavid van Moolenbroek   _fmemcpy (&pktInfo.majVer, MK_FP(reg.r_es,reg.r_di), PKT_PARAM_SIZE);
767*d56f51eaSDavid van Moolenbroek #endif
768*d56f51eaSDavid van Moolenbroek   return (TRUE);
769*d56f51eaSDavid van Moolenbroek }
770*d56f51eaSDavid van Moolenbroek 
771*d56f51eaSDavid van Moolenbroek /**************************************************************************/
772*d56f51eaSDavid van Moolenbroek 
773*d56f51eaSDavid van Moolenbroek #if (DOSX & PHARLAP)
PktReceive(BYTE * buf,int max)774*d56f51eaSDavid van Moolenbroek   PUBLIC int PktReceive (BYTE *buf, int max)
775*d56f51eaSDavid van Moolenbroek   {
776*d56f51eaSDavid van Moolenbroek     WORD inOfs  = *rxInOfsFp;
777*d56f51eaSDavid van Moolenbroek     WORD outOfs = *rxOutOfsFp;
778*d56f51eaSDavid van Moolenbroek 
779*d56f51eaSDavid van Moolenbroek     if (outOfs != inOfs)
780*d56f51eaSDavid van Moolenbroek     {
781*d56f51eaSDavid van Moolenbroek       RX_ELEMENT _far *head = (RX_ELEMENT _far*)(protBase+outOfs);
782*d56f51eaSDavid van Moolenbroek       int size, len = max;
783*d56f51eaSDavid van Moolenbroek 
784*d56f51eaSDavid van Moolenbroek       if (CheckElement(head))
785*d56f51eaSDavid van Moolenbroek       {
786*d56f51eaSDavid van Moolenbroek         size = min (head->firstCount, sizeof(RX_ELEMENT));
787*d56f51eaSDavid van Moolenbroek         len  = min (size, max);
788*d56f51eaSDavid van Moolenbroek         _fmemcpy (buf, &head->destin, len);
789*d56f51eaSDavid van Moolenbroek       }
790*d56f51eaSDavid van Moolenbroek       else
791*d56f51eaSDavid van Moolenbroek         size = -1;
792*d56f51eaSDavid van Moolenbroek 
793*d56f51eaSDavid van Moolenbroek       outOfs += sizeof (RX_ELEMENT);
794*d56f51eaSDavid van Moolenbroek       if (outOfs > LAST_RX_BUF)
795*d56f51eaSDavid van Moolenbroek           outOfs = FIRST_RX_BUF;
796*d56f51eaSDavid van Moolenbroek       *rxOutOfsFp = outOfs;
797*d56f51eaSDavid van Moolenbroek       return (size);
798*d56f51eaSDavid van Moolenbroek     }
799*d56f51eaSDavid van Moolenbroek     return (0);
800*d56f51eaSDavid van Moolenbroek   }
801*d56f51eaSDavid van Moolenbroek 
PktQueueBusy(BOOL busy)802*d56f51eaSDavid van Moolenbroek   PUBLIC void PktQueueBusy (BOOL busy)
803*d56f51eaSDavid van Moolenbroek   {
804*d56f51eaSDavid van Moolenbroek     *rxOutOfsFp = busy ? (*rxInOfsFp + sizeof(RX_ELEMENT)) : *rxInOfsFp;
805*d56f51eaSDavid van Moolenbroek     if (*rxOutOfsFp > LAST_RX_BUF)
806*d56f51eaSDavid van Moolenbroek         *rxOutOfsFp = FIRST_RX_BUF;
807*d56f51eaSDavid van Moolenbroek     *(DWORD _far*)(protBase + (WORD)&pktDrop) = 0;
808*d56f51eaSDavid van Moolenbroek   }
809*d56f51eaSDavid van Moolenbroek 
PktBuffersUsed(void)810*d56f51eaSDavid van Moolenbroek   PUBLIC WORD PktBuffersUsed (void)
811*d56f51eaSDavid van Moolenbroek   {
812*d56f51eaSDavid van Moolenbroek     WORD inOfs  = *rxInOfsFp;
813*d56f51eaSDavid van Moolenbroek     WORD outOfs = *rxOutOfsFp;
814*d56f51eaSDavid van Moolenbroek 
815*d56f51eaSDavid van Moolenbroek     if (inOfs >= outOfs)
816*d56f51eaSDavid van Moolenbroek        return (inOfs - outOfs) / sizeof(RX_ELEMENT);
817*d56f51eaSDavid van Moolenbroek     return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));
818*d56f51eaSDavid van Moolenbroek   }
819*d56f51eaSDavid van Moolenbroek 
PktRxDropped(void)820*d56f51eaSDavid van Moolenbroek   PUBLIC DWORD PktRxDropped (void)
821*d56f51eaSDavid van Moolenbroek   {
822*d56f51eaSDavid van Moolenbroek     return (*(DWORD _far*)(protBase + (WORD)&pktDrop));
823*d56f51eaSDavid van Moolenbroek   }
824*d56f51eaSDavid van Moolenbroek 
825*d56f51eaSDavid van Moolenbroek #elif (DOSX & DJGPP)
PktReceive(BYTE * buf,int max)826*d56f51eaSDavid van Moolenbroek   PUBLIC int PktReceive (BYTE *buf, int max)
827*d56f51eaSDavid van Moolenbroek   {
828*d56f51eaSDavid van Moolenbroek     WORD ofs = _farpeekw (_dos_ds, realBase+rxOutOfs);
829*d56f51eaSDavid van Moolenbroek 
830*d56f51eaSDavid van Moolenbroek     if (ofs != _farpeekw (_dos_ds, realBase+rxInOfs))
831*d56f51eaSDavid van Moolenbroek     {
832*d56f51eaSDavid van Moolenbroek       RX_ELEMENT head;
833*d56f51eaSDavid van Moolenbroek       int  size, len = max;
834*d56f51eaSDavid van Moolenbroek 
835*d56f51eaSDavid van Moolenbroek       head.firstCount  = _farpeekw (_dos_ds, realBase+ofs);
836*d56f51eaSDavid van Moolenbroek       head.secondCount = _farpeekw (_dos_ds, realBase+ofs+2);
837*d56f51eaSDavid van Moolenbroek       head.handle      = _farpeekw (_dos_ds, realBase+ofs+4);
838*d56f51eaSDavid van Moolenbroek 
839*d56f51eaSDavid van Moolenbroek       if (CheckElement(&head))
840*d56f51eaSDavid van Moolenbroek       {
841*d56f51eaSDavid van Moolenbroek         size = min (head.firstCount, sizeof(RX_ELEMENT));
842*d56f51eaSDavid van Moolenbroek         len  = min (size, max);
843*d56f51eaSDavid van Moolenbroek         dosmemget (realBase+ofs+6, len, buf);
844*d56f51eaSDavid van Moolenbroek       }
845*d56f51eaSDavid van Moolenbroek       else
846*d56f51eaSDavid van Moolenbroek         size = -1;
847*d56f51eaSDavid van Moolenbroek 
848*d56f51eaSDavid van Moolenbroek       ofs += sizeof (RX_ELEMENT);
849*d56f51eaSDavid van Moolenbroek       if (ofs > LAST_RX_BUF)
850*d56f51eaSDavid van Moolenbroek            _farpokew (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF);
851*d56f51eaSDavid van Moolenbroek       else _farpokew (_dos_ds, realBase+rxOutOfs, ofs);
852*d56f51eaSDavid van Moolenbroek       return (size);
853*d56f51eaSDavid van Moolenbroek     }
854*d56f51eaSDavid van Moolenbroek     return (0);
855*d56f51eaSDavid van Moolenbroek   }
856*d56f51eaSDavid van Moolenbroek 
PktQueueBusy(BOOL busy)857*d56f51eaSDavid van Moolenbroek   PUBLIC void PktQueueBusy (BOOL busy)
858*d56f51eaSDavid van Moolenbroek   {
859*d56f51eaSDavid van Moolenbroek     WORD ofs;
860*d56f51eaSDavid van Moolenbroek 
861*d56f51eaSDavid van Moolenbroek     disable();
862*d56f51eaSDavid van Moolenbroek     ofs = _farpeekw (_dos_ds, realBase+rxInOfs);
863*d56f51eaSDavid van Moolenbroek     if (busy)
864*d56f51eaSDavid van Moolenbroek        ofs += sizeof (RX_ELEMENT);
865*d56f51eaSDavid van Moolenbroek 
866*d56f51eaSDavid van Moolenbroek     if (ofs > LAST_RX_BUF)
867*d56f51eaSDavid van Moolenbroek          _farpokew (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF);
868*d56f51eaSDavid van Moolenbroek     else _farpokew (_dos_ds, realBase+rxOutOfs, ofs);
869*d56f51eaSDavid van Moolenbroek     _farpokel (_dos_ds, realBase+pktDrop, 0UL);
870*d56f51eaSDavid van Moolenbroek     enable();
871*d56f51eaSDavid van Moolenbroek   }
872*d56f51eaSDavid van Moolenbroek 
PktBuffersUsed(void)873*d56f51eaSDavid van Moolenbroek   PUBLIC WORD PktBuffersUsed (void)
874*d56f51eaSDavid van Moolenbroek   {
875*d56f51eaSDavid van Moolenbroek     WORD inOfs, outOfs;
876*d56f51eaSDavid van Moolenbroek 
877*d56f51eaSDavid van Moolenbroek     disable();
878*d56f51eaSDavid van Moolenbroek     inOfs  = _farpeekw (_dos_ds, realBase+rxInOfs);
879*d56f51eaSDavid van Moolenbroek     outOfs = _farpeekw (_dos_ds, realBase+rxOutOfs);
880*d56f51eaSDavid van Moolenbroek     enable();
881*d56f51eaSDavid van Moolenbroek     if (inOfs >= outOfs)
882*d56f51eaSDavid van Moolenbroek        return (inOfs - outOfs) / sizeof(RX_ELEMENT);
883*d56f51eaSDavid van Moolenbroek     return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));
884*d56f51eaSDavid van Moolenbroek   }
885*d56f51eaSDavid van Moolenbroek 
PktRxDropped(void)886*d56f51eaSDavid van Moolenbroek   PUBLIC DWORD PktRxDropped (void)
887*d56f51eaSDavid van Moolenbroek   {
888*d56f51eaSDavid van Moolenbroek     return _farpeekl (_dos_ds, realBase+pktDrop);
889*d56f51eaSDavid van Moolenbroek   }
890*d56f51eaSDavid van Moolenbroek 
891*d56f51eaSDavid van Moolenbroek #elif (DOSX & DOS4GW)
PktReceive(BYTE * buf,int max)892*d56f51eaSDavid van Moolenbroek   PUBLIC int PktReceive (BYTE *buf, int max)
893*d56f51eaSDavid van Moolenbroek   {
894*d56f51eaSDavid van Moolenbroek     WORD ofs = *(WORD*) (realBase+rxOutOfs);
895*d56f51eaSDavid van Moolenbroek 
896*d56f51eaSDavid van Moolenbroek     if (ofs != *(WORD*) (realBase+rxInOfs))
897*d56f51eaSDavid van Moolenbroek     {
898*d56f51eaSDavid van Moolenbroek       RX_ELEMENT head;
899*d56f51eaSDavid van Moolenbroek       int  size, len = max;
900*d56f51eaSDavid van Moolenbroek 
901*d56f51eaSDavid van Moolenbroek       head.firstCount  = *(WORD*) (realBase+ofs);
902*d56f51eaSDavid van Moolenbroek       head.secondCount = *(WORD*) (realBase+ofs+2);
903*d56f51eaSDavid van Moolenbroek       head.handle      = *(WORD*) (realBase+ofs+4);
904*d56f51eaSDavid van Moolenbroek 
905*d56f51eaSDavid van Moolenbroek       if (CheckElement(&head))
906*d56f51eaSDavid van Moolenbroek       {
907*d56f51eaSDavid van Moolenbroek         size = min (head.firstCount, sizeof(RX_ELEMENT));
908*d56f51eaSDavid van Moolenbroek         len  = min (size, max);
909*d56f51eaSDavid van Moolenbroek         memcpy (buf, (const void*)(realBase+ofs+6), len);
910*d56f51eaSDavid van Moolenbroek       }
911*d56f51eaSDavid van Moolenbroek       else
912*d56f51eaSDavid van Moolenbroek         size = -1;
913*d56f51eaSDavid van Moolenbroek 
914*d56f51eaSDavid van Moolenbroek       ofs += sizeof (RX_ELEMENT);
915*d56f51eaSDavid van Moolenbroek       if (ofs > LAST_RX_BUF)
916*d56f51eaSDavid van Moolenbroek            *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF;
917*d56f51eaSDavid van Moolenbroek       else *(WORD*) (realBase+rxOutOfs) = ofs;
918*d56f51eaSDavid van Moolenbroek       return (size);
919*d56f51eaSDavid van Moolenbroek     }
920*d56f51eaSDavid van Moolenbroek     return (0);
921*d56f51eaSDavid van Moolenbroek   }
922*d56f51eaSDavid van Moolenbroek 
PktQueueBusy(BOOL busy)923*d56f51eaSDavid van Moolenbroek   PUBLIC void PktQueueBusy (BOOL busy)
924*d56f51eaSDavid van Moolenbroek   {
925*d56f51eaSDavid van Moolenbroek     WORD ofs;
926*d56f51eaSDavid van Moolenbroek 
927*d56f51eaSDavid van Moolenbroek     _disable();
928*d56f51eaSDavid van Moolenbroek     ofs = *(WORD*) (realBase+rxInOfs);
929*d56f51eaSDavid van Moolenbroek     if (busy)
930*d56f51eaSDavid van Moolenbroek        ofs += sizeof (RX_ELEMENT);
931*d56f51eaSDavid van Moolenbroek 
932*d56f51eaSDavid van Moolenbroek     if (ofs > LAST_RX_BUF)
933*d56f51eaSDavid van Moolenbroek          *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF;
934*d56f51eaSDavid van Moolenbroek     else *(WORD*) (realBase+rxOutOfs) = ofs;
935*d56f51eaSDavid van Moolenbroek     *(DWORD*) (realBase+pktDrop) = 0UL;
936*d56f51eaSDavid van Moolenbroek     _enable();
937*d56f51eaSDavid van Moolenbroek   }
938*d56f51eaSDavid van Moolenbroek 
PktBuffersUsed(void)939*d56f51eaSDavid van Moolenbroek   PUBLIC WORD PktBuffersUsed (void)
940*d56f51eaSDavid van Moolenbroek   {
941*d56f51eaSDavid van Moolenbroek     WORD inOfs, outOfs;
942*d56f51eaSDavid van Moolenbroek 
943*d56f51eaSDavid van Moolenbroek     _disable();
944*d56f51eaSDavid van Moolenbroek     inOfs  = *(WORD*) (realBase+rxInOfs);
945*d56f51eaSDavid van Moolenbroek     outOfs = *(WORD*) (realBase+rxOutOfs);
946*d56f51eaSDavid van Moolenbroek     _enable();
947*d56f51eaSDavid van Moolenbroek     if (inOfs >= outOfs)
948*d56f51eaSDavid van Moolenbroek        return (inOfs - outOfs) / sizeof(RX_ELEMENT);
949*d56f51eaSDavid van Moolenbroek     return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));
950*d56f51eaSDavid van Moolenbroek   }
951*d56f51eaSDavid van Moolenbroek 
PktRxDropped(void)952*d56f51eaSDavid van Moolenbroek   PUBLIC DWORD PktRxDropped (void)
953*d56f51eaSDavid van Moolenbroek   {
954*d56f51eaSDavid van Moolenbroek     return *(DWORD*) (realBase+pktDrop);
955*d56f51eaSDavid van Moolenbroek   }
956*d56f51eaSDavid van Moolenbroek 
957*d56f51eaSDavid van Moolenbroek #else     /* real-mode small/large model */
958*d56f51eaSDavid van Moolenbroek 
PktReceive(BYTE * buf,int max)959*d56f51eaSDavid van Moolenbroek   PUBLIC int PktReceive (BYTE *buf, int max)
960*d56f51eaSDavid van Moolenbroek   {
961*d56f51eaSDavid van Moolenbroek     if (rxOutOfs != rxInOfs)
962*d56f51eaSDavid van Moolenbroek     {
963*d56f51eaSDavid van Moolenbroek       RX_ELEMENT far *head = (RX_ELEMENT far*) MK_FP (_DS,rxOutOfs);
964*d56f51eaSDavid van Moolenbroek       int  size, len = max;
965*d56f51eaSDavid van Moolenbroek 
966*d56f51eaSDavid van Moolenbroek       if (CheckElement(head))
967*d56f51eaSDavid van Moolenbroek       {
968*d56f51eaSDavid van Moolenbroek         size = min (head->firstCount, sizeof(RX_ELEMENT));
969*d56f51eaSDavid van Moolenbroek         len  = min (size, max);
970*d56f51eaSDavid van Moolenbroek         _fmemcpy (buf, &head->destin, len);
971*d56f51eaSDavid van Moolenbroek       }
972*d56f51eaSDavid van Moolenbroek       else
973*d56f51eaSDavid van Moolenbroek         size = -1;
974*d56f51eaSDavid van Moolenbroek 
975*d56f51eaSDavid van Moolenbroek       rxOutOfs += sizeof (RX_ELEMENT);
976*d56f51eaSDavid van Moolenbroek       if (rxOutOfs > LAST_RX_BUF)
977*d56f51eaSDavid van Moolenbroek           rxOutOfs = FIRST_RX_BUF;
978*d56f51eaSDavid van Moolenbroek       return (size);
979*d56f51eaSDavid van Moolenbroek     }
980*d56f51eaSDavid van Moolenbroek     return (0);
981*d56f51eaSDavid van Moolenbroek   }
982*d56f51eaSDavid van Moolenbroek 
PktQueueBusy(BOOL busy)983*d56f51eaSDavid van Moolenbroek   PUBLIC void PktQueueBusy (BOOL busy)
984*d56f51eaSDavid van Moolenbroek   {
985*d56f51eaSDavid van Moolenbroek     rxOutOfs = busy ? (rxInOfs + sizeof(RX_ELEMENT)) : rxInOfs;
986*d56f51eaSDavid van Moolenbroek     if (rxOutOfs > LAST_RX_BUF)
987*d56f51eaSDavid van Moolenbroek         rxOutOfs = FIRST_RX_BUF;
988*d56f51eaSDavid van Moolenbroek     pktDrop = 0L;
989*d56f51eaSDavid van Moolenbroek   }
990*d56f51eaSDavid van Moolenbroek 
PktBuffersUsed(void)991*d56f51eaSDavid van Moolenbroek   PUBLIC WORD PktBuffersUsed (void)
992*d56f51eaSDavid van Moolenbroek   {
993*d56f51eaSDavid van Moolenbroek     WORD inOfs  = rxInOfs;
994*d56f51eaSDavid van Moolenbroek     WORD outOfs = rxOutOfs;
995*d56f51eaSDavid van Moolenbroek 
996*d56f51eaSDavid van Moolenbroek     if (inOfs >= outOfs)
997*d56f51eaSDavid van Moolenbroek        return ((inOfs - outOfs) / sizeof(RX_ELEMENT));
998*d56f51eaSDavid van Moolenbroek     return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));
999*d56f51eaSDavid van Moolenbroek   }
1000*d56f51eaSDavid van Moolenbroek 
PktRxDropped(void)1001*d56f51eaSDavid van Moolenbroek   PUBLIC DWORD PktRxDropped (void)
1002*d56f51eaSDavid van Moolenbroek   {
1003*d56f51eaSDavid van Moolenbroek     return (pktDrop);
1004*d56f51eaSDavid van Moolenbroek   }
1005*d56f51eaSDavid van Moolenbroek #endif
1006*d56f51eaSDavid van Moolenbroek 
1007*d56f51eaSDavid van Moolenbroek /**************************************************************************/
1008*d56f51eaSDavid van Moolenbroek 
PktFreeMem(void)1009*d56f51eaSDavid van Moolenbroek LOCAL __inline void PktFreeMem (void)
1010*d56f51eaSDavid van Moolenbroek {
1011*d56f51eaSDavid van Moolenbroek #if (DOSX & PHARLAP)
1012*d56f51eaSDavid van Moolenbroek   if (realSeg)
1013*d56f51eaSDavid van Moolenbroek   {
1014*d56f51eaSDavid van Moolenbroek     _dx_real_free (realSeg);
1015*d56f51eaSDavid van Moolenbroek     realSeg = 0;
1016*d56f51eaSDavid van Moolenbroek   }
1017*d56f51eaSDavid van Moolenbroek #elif (DOSX & DJGPP)
1018*d56f51eaSDavid van Moolenbroek   if (rm_mem.rm_segment)
1019*d56f51eaSDavid van Moolenbroek   {
1020*d56f51eaSDavid van Moolenbroek     unsigned ofs;  /* clear the DOS-mem to prevent further upcalls */
1021*d56f51eaSDavid van Moolenbroek 
1022*d56f51eaSDavid van Moolenbroek     for (ofs = 0; ofs < 16 * rm_mem.size / 4; ofs += 4)
1023*d56f51eaSDavid van Moolenbroek        _farpokel (_dos_ds, realBase + ofs, 0);
1024*d56f51eaSDavid van Moolenbroek     _go32_dpmi_free_dos_memory (&rm_mem);
1025*d56f51eaSDavid van Moolenbroek     rm_mem.rm_segment = 0;
1026*d56f51eaSDavid van Moolenbroek   }
1027*d56f51eaSDavid van Moolenbroek #elif (DOSX & DOS4GW)
1028*d56f51eaSDavid van Moolenbroek   if (rm_base_sel)
1029*d56f51eaSDavid van Moolenbroek   {
1030*d56f51eaSDavid van Moolenbroek     dpmi_real_free (rm_base_sel);
1031*d56f51eaSDavid van Moolenbroek     rm_base_sel = 0;
1032*d56f51eaSDavid van Moolenbroek   }
1033*d56f51eaSDavid van Moolenbroek #endif
1034*d56f51eaSDavid van Moolenbroek }
1035*d56f51eaSDavid van Moolenbroek 
1036*d56f51eaSDavid van Moolenbroek /**************************************************************************/
1037*d56f51eaSDavid van Moolenbroek 
PktExitDriver(void)1038*d56f51eaSDavid van Moolenbroek PUBLIC BOOL PktExitDriver (void)
1039*d56f51eaSDavid van Moolenbroek {
1040*d56f51eaSDavid van Moolenbroek   if (pktInfo.handle)
1041*d56f51eaSDavid van Moolenbroek   {
1042*d56f51eaSDavid van Moolenbroek     if (!PktSetReceiverMode(PDRX_BROADCAST))
1043*d56f51eaSDavid van Moolenbroek        PUTS ("Error restoring receiver mode.");
1044*d56f51eaSDavid van Moolenbroek 
1045*d56f51eaSDavid van Moolenbroek     if (!PktReleaseHandle(pktInfo.handle))
1046*d56f51eaSDavid van Moolenbroek        PUTS ("Error releasing PKT-DRVR handle.");
1047*d56f51eaSDavid van Moolenbroek 
1048*d56f51eaSDavid van Moolenbroek     PktFreeMem();
1049*d56f51eaSDavid van Moolenbroek     pktInfo.handle = 0;
1050*d56f51eaSDavid van Moolenbroek   }
1051*d56f51eaSDavid van Moolenbroek 
1052*d56f51eaSDavid van Moolenbroek   if (pcap_pkt_debug >= 1)
1053*d56f51eaSDavid van Moolenbroek      printf ("Internal stats: too-small %lu, too-large %lu, bad-sync %lu, "
1054*d56f51eaSDavid van Moolenbroek              "wrong-handle %lu\n",
1055*d56f51eaSDavid van Moolenbroek              intStat.tooSmall, intStat.tooLarge,
1056*d56f51eaSDavid van Moolenbroek              intStat.badSync, intStat.wrongHandle);
1057*d56f51eaSDavid van Moolenbroek   return (TRUE);
1058*d56f51eaSDavid van Moolenbroek }
1059*d56f51eaSDavid van Moolenbroek 
1060*d56f51eaSDavid van Moolenbroek #if (DOSX & (DJGPP|DOS4GW))
dump_pkt_stub(void)1061*d56f51eaSDavid van Moolenbroek static void dump_pkt_stub (void)
1062*d56f51eaSDavid van Moolenbroek {
1063*d56f51eaSDavid van Moolenbroek   int i;
1064*d56f51eaSDavid van Moolenbroek 
1065*d56f51eaSDavid van Moolenbroek   fprintf (stderr, "PktReceiver %lu, pkt_stub[PktReceiver] =\n",
1066*d56f51eaSDavid van Moolenbroek            PktReceiver);
1067*d56f51eaSDavid van Moolenbroek   for (i = 0; i < 15; i++)
1068*d56f51eaSDavid van Moolenbroek       fprintf (stderr, "%02X, ", real_stub_array[i+PktReceiver]);
1069*d56f51eaSDavid van Moolenbroek   fputs ("\n", stderr);
1070*d56f51eaSDavid van Moolenbroek }
1071*d56f51eaSDavid van Moolenbroek #endif
1072*d56f51eaSDavid van Moolenbroek 
1073*d56f51eaSDavid van Moolenbroek /*
1074*d56f51eaSDavid van Moolenbroek  * Front end initialization routine
1075*d56f51eaSDavid van Moolenbroek  */
PktInitDriver(PKT_RX_MODE mode)1076*d56f51eaSDavid van Moolenbroek PUBLIC BOOL PktInitDriver (PKT_RX_MODE mode)
1077*d56f51eaSDavid van Moolenbroek {
1078*d56f51eaSDavid van Moolenbroek   PKT_RX_MODE rxMode;
1079*d56f51eaSDavid van Moolenbroek   BOOL   writeInfo = (pcap_pkt_debug >= 3);
1080*d56f51eaSDavid van Moolenbroek 
1081*d56f51eaSDavid van Moolenbroek   pktInfo.quiet = (pcap_pkt_debug < 3);
1082*d56f51eaSDavid van Moolenbroek 
1083*d56f51eaSDavid van Moolenbroek #if (DOSX & PHARLAP) && defined(__HIGHC__)
1084*d56f51eaSDavid van Moolenbroek   if (_mwenv != 2)
1085*d56f51eaSDavid van Moolenbroek   {
1086*d56f51eaSDavid van Moolenbroek     fprintf (stderr, "Only Pharlap DOS extender supported.\n");
1087*d56f51eaSDavid van Moolenbroek     return (FALSE);
1088*d56f51eaSDavid van Moolenbroek   }
1089*d56f51eaSDavid van Moolenbroek #endif
1090*d56f51eaSDavid van Moolenbroek 
1091*d56f51eaSDavid van Moolenbroek #if (DOSX & PHARLAP) && defined(__WATCOMC__)
1092*d56f51eaSDavid van Moolenbroek   if (_Extender != 1)
1093*d56f51eaSDavid van Moolenbroek   {
1094*d56f51eaSDavid van Moolenbroek     fprintf (stderr, "Only DOS4GW style extenders supported.\n");
1095*d56f51eaSDavid van Moolenbroek     return (FALSE);
1096*d56f51eaSDavid van Moolenbroek   }
1097*d56f51eaSDavid van Moolenbroek #endif
1098*d56f51eaSDavid van Moolenbroek 
1099*d56f51eaSDavid van Moolenbroek   if (!PktSearchDriver())
1100*d56f51eaSDavid van Moolenbroek   {
1101*d56f51eaSDavid van Moolenbroek     PUTS ("Packet driver not found.");
1102*d56f51eaSDavid van Moolenbroek     PktFreeMem();
1103*d56f51eaSDavid van Moolenbroek     return (FALSE);
1104*d56f51eaSDavid van Moolenbroek   }
1105*d56f51eaSDavid van Moolenbroek 
1106*d56f51eaSDavid van Moolenbroek   if (!PktGetDriverInfo())
1107*d56f51eaSDavid van Moolenbroek   {
1108*d56f51eaSDavid van Moolenbroek     PUTS ("Error getting pkt-drvr information.");
1109*d56f51eaSDavid van Moolenbroek     PktFreeMem();
1110*d56f51eaSDavid van Moolenbroek     return (FALSE);
1111*d56f51eaSDavid van Moolenbroek   }
1112*d56f51eaSDavid van Moolenbroek 
1113*d56f51eaSDavid van Moolenbroek #if (DOSX & PHARLAP)
1114*d56f51eaSDavid van Moolenbroek   if (RealCopy((ULONG)&rxOutOfs, (ULONG)&pktRxEnd,
1115*d56f51eaSDavid van Moolenbroek                &realBase, &protBase, (USHORT*)&realSeg))
1116*d56f51eaSDavid van Moolenbroek   {
1117*d56f51eaSDavid van Moolenbroek     rxOutOfsFp  = (WORD _far *) (protBase + (WORD) &rxOutOfs);
1118*d56f51eaSDavid van Moolenbroek     rxInOfsFp   = (WORD _far *) (protBase + (WORD) &rxInOfs);
1119*d56f51eaSDavid van Moolenbroek     *rxOutOfsFp = FIRST_RX_BUF;
1120*d56f51eaSDavid van Moolenbroek     *rxInOfsFp  = FIRST_RX_BUF;
1121*d56f51eaSDavid van Moolenbroek   }
1122*d56f51eaSDavid van Moolenbroek   else
1123*d56f51eaSDavid van Moolenbroek   {
1124*d56f51eaSDavid van Moolenbroek     PUTS ("Cannot allocate real-mode stub.");
1125*d56f51eaSDavid van Moolenbroek     return (FALSE);
1126*d56f51eaSDavid van Moolenbroek   }
1127*d56f51eaSDavid van Moolenbroek 
1128*d56f51eaSDavid van Moolenbroek #elif (DOSX & (DJGPP|DOS4GW))
1129*d56f51eaSDavid van Moolenbroek   if (sizeof(real_stub_array) > 0xFFFF)
1130*d56f51eaSDavid van Moolenbroek   {
1131*d56f51eaSDavid van Moolenbroek     fprintf (stderr, "`real_stub_array[]' too big.\n");
1132*d56f51eaSDavid van Moolenbroek     return (FALSE);
1133*d56f51eaSDavid van Moolenbroek   }
1134*d56f51eaSDavid van Moolenbroek #if (DOSX & DJGPP)
1135*d56f51eaSDavid van Moolenbroek   rm_mem.size = (sizeof(real_stub_array) + 15) / 16;
1136*d56f51eaSDavid van Moolenbroek 
1137*d56f51eaSDavid van Moolenbroek   if (_go32_dpmi_allocate_dos_memory(&rm_mem) || rm_mem.rm_offset != 0)
1138*d56f51eaSDavid van Moolenbroek   {
1139*d56f51eaSDavid van Moolenbroek     PUTS ("real-mode init failed.");
1140*d56f51eaSDavid van Moolenbroek     return (FALSE);
1141*d56f51eaSDavid van Moolenbroek   }
1142*d56f51eaSDavid van Moolenbroek   realBase = (rm_mem.rm_segment << 4);
1143*d56f51eaSDavid van Moolenbroek   dosmemput (&real_stub_array, sizeof(real_stub_array), realBase);
1144*d56f51eaSDavid van Moolenbroek   _farpokel (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF);
1145*d56f51eaSDavid van Moolenbroek   _farpokel (_dos_ds, realBase+rxInOfs,  FIRST_RX_BUF);
1146*d56f51eaSDavid van Moolenbroek 
1147*d56f51eaSDavid van Moolenbroek #elif (DOSX & DOS4GW)
1148*d56f51eaSDavid van Moolenbroek   rm_base_seg = dpmi_real_malloc (sizeof(real_stub_array), &rm_base_sel);
1149*d56f51eaSDavid van Moolenbroek   if (!rm_base_seg)
1150*d56f51eaSDavid van Moolenbroek   {
1151*d56f51eaSDavid van Moolenbroek     PUTS ("real-mode init failed.");
1152*d56f51eaSDavid van Moolenbroek     return (FALSE);
1153*d56f51eaSDavid van Moolenbroek   }
1154*d56f51eaSDavid van Moolenbroek   realBase = (rm_base_seg << 4);
1155*d56f51eaSDavid van Moolenbroek   memcpy ((void*)realBase, &real_stub_array, sizeof(real_stub_array));
1156*d56f51eaSDavid van Moolenbroek   *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF;
1157*d56f51eaSDavid van Moolenbroek   *(WORD*) (realBase+rxInOfs)  = FIRST_RX_BUF;
1158*d56f51eaSDavid van Moolenbroek 
1159*d56f51eaSDavid van Moolenbroek #endif
1160*d56f51eaSDavid van Moolenbroek   {
1161*d56f51eaSDavid van Moolenbroek     int pushf = PktReceiver;
1162*d56f51eaSDavid van Moolenbroek 
1163*d56f51eaSDavid van Moolenbroek     while (real_stub_array[pushf++] != 0x9C &&    /* pushf */
1164*d56f51eaSDavid van Moolenbroek            real_stub_array[pushf]   != 0xFA)      /* cli   */
1165*d56f51eaSDavid van Moolenbroek     {
1166*d56f51eaSDavid van Moolenbroek       if (++para_skip > 16)
1167*d56f51eaSDavid van Moolenbroek       {
1168*d56f51eaSDavid van Moolenbroek         fprintf (stderr, "Something wrong with `pkt_stub.inc'.\n");
1169*d56f51eaSDavid van Moolenbroek         para_skip = 0;
1170*d56f51eaSDavid van Moolenbroek         dump_pkt_stub();
1171*d56f51eaSDavid van Moolenbroek         return (FALSE);
1172*d56f51eaSDavid van Moolenbroek       }
1173*d56f51eaSDavid van Moolenbroek     }
1174*d56f51eaSDavid van Moolenbroek     if (*(WORD*)(real_stub_array + offsetof(PktRealStub,_dummy)) != 0xB800)
1175*d56f51eaSDavid van Moolenbroek     {
1176*d56f51eaSDavid van Moolenbroek       fprintf (stderr, "`real_stub_array[]' is misaligned.\n");
1177*d56f51eaSDavid van Moolenbroek       return (FALSE);
1178*d56f51eaSDavid van Moolenbroek     }
1179*d56f51eaSDavid van Moolenbroek   }
1180*d56f51eaSDavid van Moolenbroek 
1181*d56f51eaSDavid van Moolenbroek   if (pcap_pkt_debug > 2)
1182*d56f51eaSDavid van Moolenbroek       dump_pkt_stub();
1183*d56f51eaSDavid van Moolenbroek 
1184*d56f51eaSDavid van Moolenbroek #else
1185*d56f51eaSDavid van Moolenbroek   rxOutOfs = FIRST_RX_BUF;
1186*d56f51eaSDavid van Moolenbroek   rxInOfs  = FIRST_RX_BUF;
1187*d56f51eaSDavid van Moolenbroek #endif
1188*d56f51eaSDavid van Moolenbroek 
1189*d56f51eaSDavid van Moolenbroek   if (!PktSetAccess())
1190*d56f51eaSDavid van Moolenbroek   {
1191*d56f51eaSDavid van Moolenbroek     PUTS ("Error setting pkt-drvr access.");
1192*d56f51eaSDavid van Moolenbroek     PktFreeMem();
1193*d56f51eaSDavid van Moolenbroek     return (FALSE);
1194*d56f51eaSDavid van Moolenbroek   }
1195*d56f51eaSDavid van Moolenbroek 
1196*d56f51eaSDavid van Moolenbroek   if (!PktGetAddress(&myAddress))
1197*d56f51eaSDavid van Moolenbroek   {
1198*d56f51eaSDavid van Moolenbroek     PUTS ("Error fetching adapter address.");
1199*d56f51eaSDavid van Moolenbroek     PktFreeMem();
1200*d56f51eaSDavid van Moolenbroek     return (FALSE);
1201*d56f51eaSDavid van Moolenbroek   }
1202*d56f51eaSDavid van Moolenbroek 
1203*d56f51eaSDavid van Moolenbroek   if (!PktSetReceiverMode(mode))
1204*d56f51eaSDavid van Moolenbroek   {
1205*d56f51eaSDavid van Moolenbroek     PUTS ("Error setting receiver mode.");
1206*d56f51eaSDavid van Moolenbroek     PktFreeMem();
1207*d56f51eaSDavid van Moolenbroek     return (FALSE);
1208*d56f51eaSDavid van Moolenbroek   }
1209*d56f51eaSDavid van Moolenbroek 
1210*d56f51eaSDavid van Moolenbroek   if (!PktGetReceiverMode(&rxMode))
1211*d56f51eaSDavid van Moolenbroek   {
1212*d56f51eaSDavid van Moolenbroek     PUTS ("Error getting receiver mode.");
1213*d56f51eaSDavid van Moolenbroek     PktFreeMem();
1214*d56f51eaSDavid van Moolenbroek     return (FALSE);
1215*d56f51eaSDavid van Moolenbroek   }
1216*d56f51eaSDavid van Moolenbroek 
1217*d56f51eaSDavid van Moolenbroek   if (writeInfo)
1218*d56f51eaSDavid van Moolenbroek      printf ("Pkt-driver information:\n"
1219*d56f51eaSDavid van Moolenbroek              "  Version  : %d.%d\n"
1220*d56f51eaSDavid van Moolenbroek              "  Name     : %.15s\n"
1221*d56f51eaSDavid van Moolenbroek              "  Class    : %u (%s)\n"
1222*d56f51eaSDavid van Moolenbroek              "  Type     : %u\n"
1223*d56f51eaSDavid van Moolenbroek              "  Number   : %u\n"
1224*d56f51eaSDavid van Moolenbroek              "  Funcs    : %u\n"
1225*d56f51eaSDavid van Moolenbroek              "  Intr     : %Xh\n"
1226*d56f51eaSDavid van Moolenbroek              "  Handle   : %u\n"
1227*d56f51eaSDavid van Moolenbroek              "  Extended : %s\n"
1228*d56f51eaSDavid van Moolenbroek              "  Hi-perf  : %s\n"
1229*d56f51eaSDavid van Moolenbroek              "  RX mode  : %s\n"
1230*d56f51eaSDavid van Moolenbroek              "  Eth-addr : %02X:%02X:%02X:%02X:%02X:%02X\n",
1231*d56f51eaSDavid van Moolenbroek 
1232*d56f51eaSDavid van Moolenbroek              pktInfo.majVer, pktInfo.minVer, pktInfo.name,
1233*d56f51eaSDavid van Moolenbroek              pktInfo.class,  PktGetClassName(pktInfo.class),
1234*d56f51eaSDavid van Moolenbroek              pktInfo.type,   pktInfo.number,
1235*d56f51eaSDavid van Moolenbroek              pktInfo.funcs,  pktInfo.intr,   pktInfo.handle,
1236*d56f51eaSDavid van Moolenbroek              pktInfo.funcs == 2 || pktInfo.funcs == 6 ? "Yes" : "No",
1237*d56f51eaSDavid van Moolenbroek              pktInfo.funcs == 5 || pktInfo.funcs == 6 ? "Yes" : "No",
1238*d56f51eaSDavid van Moolenbroek              PktRXmodeStr(rxMode),
1239*d56f51eaSDavid van Moolenbroek              myAddress[0], myAddress[1], myAddress[2],
1240*d56f51eaSDavid van Moolenbroek              myAddress[3], myAddress[4], myAddress[5]);
1241*d56f51eaSDavid van Moolenbroek 
1242*d56f51eaSDavid van Moolenbroek #if defined(DEBUG) && (DOSX & PHARLAP)
1243*d56f51eaSDavid van Moolenbroek   if (writeInfo)
1244*d56f51eaSDavid van Moolenbroek   {
1245*d56f51eaSDavid van Moolenbroek     DWORD    rAdr = realBase + (WORD)&PktReceiver;
1246*d56f51eaSDavid van Moolenbroek     unsigned sel, ofs;
1247*d56f51eaSDavid van Moolenbroek 
1248*d56f51eaSDavid van Moolenbroek     printf ("\nReceiver at   %04X:%04X\n", RP_SEG(rAdr),    RP_OFF(rAdr));
1249*d56f51eaSDavid van Moolenbroek     printf ("Realbase    = %04X:%04X\n",   RP_SEG(realBase),RP_OFF(realBase));
1250*d56f51eaSDavid van Moolenbroek 
1251*d56f51eaSDavid van Moolenbroek     sel = _FP_SEG (protBase);
1252*d56f51eaSDavid van Moolenbroek     ofs = _FP_OFF (protBase);
1253*d56f51eaSDavid van Moolenbroek     printf ("Protbase    = %04X:%08X\n", sel,ofs);
1254*d56f51eaSDavid van Moolenbroek     printf ("RealSeg     = %04X\n", realSeg);
1255*d56f51eaSDavid van Moolenbroek 
1256*d56f51eaSDavid van Moolenbroek     sel = _FP_SEG (rxOutOfsFp);
1257*d56f51eaSDavid van Moolenbroek     ofs = _FP_OFF (rxOutOfsFp);
1258*d56f51eaSDavid van Moolenbroek     printf ("rxOutOfsFp  = %04X:%08X\n", sel,ofs);
1259*d56f51eaSDavid van Moolenbroek 
1260*d56f51eaSDavid van Moolenbroek     sel = _FP_SEG (rxInOfsFp);
1261*d56f51eaSDavid van Moolenbroek     ofs = _FP_OFF (rxInOfsFp);
1262*d56f51eaSDavid van Moolenbroek     printf ("rxInOfsFp   = %04X:%08X\n", sel,ofs);
1263*d56f51eaSDavid van Moolenbroek 
1264*d56f51eaSDavid van Moolenbroek     printf ("Ready: *rxOutOfsFp = %04X *rxInOfsFp = %04X\n",
1265*d56f51eaSDavid van Moolenbroek             *rxOutOfsFp, *rxInOfsFp);
1266*d56f51eaSDavid van Moolenbroek 
1267*d56f51eaSDavid van Moolenbroek     PktQueueBusy (TRUE);
1268*d56f51eaSDavid van Moolenbroek     printf ("Busy:  *rxOutOfsFp = %04X *rxInOfsFp = %04X\n",
1269*d56f51eaSDavid van Moolenbroek             *rxOutOfsFp, *rxInOfsFp);
1270*d56f51eaSDavid van Moolenbroek   }
1271*d56f51eaSDavid van Moolenbroek #endif
1272*d56f51eaSDavid van Moolenbroek 
1273*d56f51eaSDavid van Moolenbroek   memset (&pktStat, 0, sizeof(pktStat));  /* clear statistics */
1274*d56f51eaSDavid van Moolenbroek   PktQueueBusy (TRUE);
1275*d56f51eaSDavid van Moolenbroek   return (TRUE);
1276*d56f51eaSDavid van Moolenbroek }
1277*d56f51eaSDavid van Moolenbroek 
1278*d56f51eaSDavid van Moolenbroek 
1279*d56f51eaSDavid van Moolenbroek /*
1280*d56f51eaSDavid van Moolenbroek  * DPMI functions only for Watcom + DOS4GW extenders
1281*d56f51eaSDavid van Moolenbroek  */
1282*d56f51eaSDavid van Moolenbroek #if (DOSX & DOS4GW)
dpmi_get_real_vector(int intr)1283*d56f51eaSDavid van Moolenbroek LOCAL DWORD dpmi_get_real_vector (int intr)
1284*d56f51eaSDavid van Moolenbroek {
1285*d56f51eaSDavid van Moolenbroek   union REGS r;
1286*d56f51eaSDavid van Moolenbroek 
1287*d56f51eaSDavid van Moolenbroek   r.x.eax = 0x200;
1288*d56f51eaSDavid van Moolenbroek   r.x.ebx = (DWORD) intr;
1289*d56f51eaSDavid van Moolenbroek   int386 (0x31, &r, &r);
1290*d56f51eaSDavid van Moolenbroek   return ((r.w.cx << 4) + r.w.dx);
1291*d56f51eaSDavid van Moolenbroek }
1292*d56f51eaSDavid van Moolenbroek 
dpmi_real_malloc(int size,WORD * selector)1293*d56f51eaSDavid van Moolenbroek LOCAL WORD dpmi_real_malloc (int size, WORD *selector)
1294*d56f51eaSDavid van Moolenbroek {
1295*d56f51eaSDavid van Moolenbroek   union REGS r;
1296*d56f51eaSDavid van Moolenbroek 
1297*d56f51eaSDavid van Moolenbroek   r.x.eax = 0x0100;             /* DPMI allocate DOS memory */
1298*d56f51eaSDavid van Moolenbroek   r.x.ebx = (size + 15) / 16;   /* Number of paragraphs requested */
1299*d56f51eaSDavid van Moolenbroek   int386 (0x31, &r, &r);
1300*d56f51eaSDavid van Moolenbroek   if (r.w.cflag & 1)
1301*d56f51eaSDavid van Moolenbroek      return (0);
1302*d56f51eaSDavid van Moolenbroek 
1303*d56f51eaSDavid van Moolenbroek   *selector = r.w.dx;
1304*d56f51eaSDavid van Moolenbroek   return (r.w.ax);              /* Return segment address */
1305*d56f51eaSDavid van Moolenbroek }
1306*d56f51eaSDavid van Moolenbroek 
dpmi_real_free(WORD selector)1307*d56f51eaSDavid van Moolenbroek LOCAL void dpmi_real_free (WORD selector)
1308*d56f51eaSDavid van Moolenbroek {
1309*d56f51eaSDavid van Moolenbroek   union REGS r;
1310*d56f51eaSDavid van Moolenbroek 
1311*d56f51eaSDavid van Moolenbroek   r.x.eax = 0x101;              /* DPMI free DOS memory */
1312*d56f51eaSDavid van Moolenbroek   r.x.ebx = selector;           /* Selector to free */
1313*d56f51eaSDavid van Moolenbroek   int386 (0x31, &r, &r);
1314*d56f51eaSDavid van Moolenbroek }
1315*d56f51eaSDavid van Moolenbroek #endif
1316*d56f51eaSDavid van Moolenbroek 
1317*d56f51eaSDavid van Moolenbroek 
1318*d56f51eaSDavid van Moolenbroek #if defined(DOSX) && (DOSX & PHARLAP)
1319*d56f51eaSDavid van Moolenbroek /*
1320*d56f51eaSDavid van Moolenbroek  * Description:
1321*d56f51eaSDavid van Moolenbroek  *     This routine allocates conventional memory for the specified block
1322*d56f51eaSDavid van Moolenbroek  *     of code (which must be within the first 64K of the protected mode
1323*d56f51eaSDavid van Moolenbroek  *     program segment) and copies the code to it.
1324*d56f51eaSDavid van Moolenbroek  *
1325*d56f51eaSDavid van Moolenbroek  *     The caller should free up the conventional memory block when it
1326*d56f51eaSDavid van Moolenbroek  *     is done with the conventional memory.
1327*d56f51eaSDavid van Moolenbroek  *
1328*d56f51eaSDavid van Moolenbroek  *     NOTE THIS ROUTINE REQUIRES 386|DOS-EXTENDER 3.0 OR LATER.
1329*d56f51eaSDavid van Moolenbroek  *
1330*d56f51eaSDavid van Moolenbroek  * Calling arguments:
1331*d56f51eaSDavid van Moolenbroek  *     start_offs      start of real mode code in program segment
1332*d56f51eaSDavid van Moolenbroek  *     end_offs        1 byte past end of real mode code in program segment
1333*d56f51eaSDavid van Moolenbroek  *     real_basep      returned;  real mode ptr to use as a base for the
1334*d56f51eaSDavid van Moolenbroek  *                        real mode code (eg, to get the real mode FAR
1335*d56f51eaSDavid van Moolenbroek  *                        addr of a function foo(), take
1336*d56f51eaSDavid van Moolenbroek  *                        real_basep + (ULONG) foo).
1337*d56f51eaSDavid van Moolenbroek  *                        This pointer is constructed such that
1338*d56f51eaSDavid van Moolenbroek  *                        offsets within the real mode segment are
1339*d56f51eaSDavid van Moolenbroek  *                        the same as the link-time offsets in the
1340*d56f51eaSDavid van Moolenbroek  *                        protected mode program segment
1341*d56f51eaSDavid van Moolenbroek  *     prot_basep      returned;  prot mode ptr to use as a base for getting
1342*d56f51eaSDavid van Moolenbroek  *                        to the conventional memory, also constructed
1343*d56f51eaSDavid van Moolenbroek  *                        so that adding the prot mode offset of a
1344*d56f51eaSDavid van Moolenbroek  *                        function or variable to the base gets you a
1345*d56f51eaSDavid van Moolenbroek  *                        ptr to the function or variable in the
1346*d56f51eaSDavid van Moolenbroek  *                        conventional memory block.
1347*d56f51eaSDavid van Moolenbroek  *     rmem_adrp       returned;  real mode para addr of allocated
1348*d56f51eaSDavid van Moolenbroek  *                        conventional memory block, to be used to free
1349*d56f51eaSDavid van Moolenbroek  *                        up the conventional memory when done.  DO NOT
1350*d56f51eaSDavid van Moolenbroek  *                        USE THIS TO CONSTRUCT A REAL MODE PTR, USE
1351*d56f51eaSDavid van Moolenbroek  *                        REAL_BASEP INSTEAD SO THAT OFFSETS WORK OUT
1352*d56f51eaSDavid van Moolenbroek  *                        CORRECTLY.
1353*d56f51eaSDavid van Moolenbroek  *
1354*d56f51eaSDavid van Moolenbroek  * Returned values:
1355*d56f51eaSDavid van Moolenbroek  *     0      if error
1356*d56f51eaSDavid van Moolenbroek  *     1      if success
1357*d56f51eaSDavid van Moolenbroek  */
RealCopy(ULONG start_offs,ULONG end_offs,REALPTR * real_basep,FARPTR * prot_basep,USHORT * rmem_adrp)1358*d56f51eaSDavid van Moolenbroek int RealCopy (ULONG    start_offs,
1359*d56f51eaSDavid van Moolenbroek               ULONG    end_offs,
1360*d56f51eaSDavid van Moolenbroek               REALPTR *real_basep,
1361*d56f51eaSDavid van Moolenbroek               FARPTR  *prot_basep,
1362*d56f51eaSDavid van Moolenbroek               USHORT  *rmem_adrp)
1363*d56f51eaSDavid van Moolenbroek {
1364*d56f51eaSDavid van Moolenbroek   ULONG   rm_base;    /* base real mode para addr for accessing */
1365*d56f51eaSDavid van Moolenbroek                       /* allocated conventional memory          */
1366*d56f51eaSDavid van Moolenbroek   UCHAR  *source;     /* source pointer for copy                */
1367*d56f51eaSDavid van Moolenbroek   FARPTR  destin;     /* destination pointer for copy           */
1368*d56f51eaSDavid van Moolenbroek   ULONG   len;        /* number of bytes to copy                */
1369*d56f51eaSDavid van Moolenbroek   ULONG   temp;
1370*d56f51eaSDavid van Moolenbroek   USHORT  stemp;
1371*d56f51eaSDavid van Moolenbroek 
1372*d56f51eaSDavid van Moolenbroek   /* First check for valid inputs
1373*d56f51eaSDavid van Moolenbroek    */
1374*d56f51eaSDavid van Moolenbroek   if (start_offs >= end_offs || end_offs > 0x10000)
1375*d56f51eaSDavid van Moolenbroek      return (FALSE);
1376*d56f51eaSDavid van Moolenbroek 
1377*d56f51eaSDavid van Moolenbroek   /* Round start_offs down to a paragraph (16-byte) boundary so we can set up
1378*d56f51eaSDavid van Moolenbroek    * the real mode pointer easily. Round up end_offs to make sure we allocate
1379*d56f51eaSDavid van Moolenbroek    * enough paragraphs
1380*d56f51eaSDavid van Moolenbroek    */
1381*d56f51eaSDavid van Moolenbroek   start_offs &= ~15;
1382*d56f51eaSDavid van Moolenbroek   end_offs = (15 + (end_offs << 4)) >> 4;
1383*d56f51eaSDavid van Moolenbroek 
1384*d56f51eaSDavid van Moolenbroek   /* Allocate the conventional memory for our real mode code.  Remember to
1385*d56f51eaSDavid van Moolenbroek    * round byte count UP to 16-byte paragraph size.  We alloc it
1386*d56f51eaSDavid van Moolenbroek    * above the DOS data buffer so both the DOS data buffer and the appl
1387*d56f51eaSDavid van Moolenbroek    * conventional mem block can still be resized.
1388*d56f51eaSDavid van Moolenbroek    *
1389*d56f51eaSDavid van Moolenbroek    * First just try to alloc it;  if we can't get it, shrink the appl mem
1390*d56f51eaSDavid van Moolenbroek    * block down to the minimum, try to alloc the memory again, then grow the
1391*d56f51eaSDavid van Moolenbroek    * appl mem block back to the maximum.  (Don't try to shrink the DOS data
1392*d56f51eaSDavid van Moolenbroek    * buffer to free conventional memory;  it wouldn't be good for this routine
1393*d56f51eaSDavid van Moolenbroek    * to have the possible side effect of making file I/O run slower.)
1394*d56f51eaSDavid van Moolenbroek    */
1395*d56f51eaSDavid van Moolenbroek   len = ((end_offs - start_offs) + 15) >> 4;
1396*d56f51eaSDavid van Moolenbroek   if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE)
1397*d56f51eaSDavid van Moolenbroek   {
1398*d56f51eaSDavid van Moolenbroek     if (_dx_cmem_usage(0, 0, &temp, &temp) != _DOSE_NONE)
1399*d56f51eaSDavid van Moolenbroek        return (FALSE);
1400*d56f51eaSDavid van Moolenbroek 
1401*d56f51eaSDavid van Moolenbroek     if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE)
1402*d56f51eaSDavid van Moolenbroek        *rmem_adrp = 0;
1403*d56f51eaSDavid van Moolenbroek 
1404*d56f51eaSDavid van Moolenbroek     if (_dx_cmem_usage(0, 1, &temp, &temp) != _DOSE_NONE)
1405*d56f51eaSDavid van Moolenbroek     {
1406*d56f51eaSDavid van Moolenbroek       if (*rmem_adrp != 0)
1407*d56f51eaSDavid van Moolenbroek          _dx_real_free (*rmem_adrp);
1408*d56f51eaSDavid van Moolenbroek       return (FALSE);
1409*d56f51eaSDavid van Moolenbroek     }
1410*d56f51eaSDavid van Moolenbroek 
1411*d56f51eaSDavid van Moolenbroek     if (*rmem_adrp == 0)
1412*d56f51eaSDavid van Moolenbroek        return (FALSE);
1413*d56f51eaSDavid van Moolenbroek   }
1414*d56f51eaSDavid van Moolenbroek 
1415*d56f51eaSDavid van Moolenbroek   /* Construct real mode & protected mode pointers to access the allocated
1416*d56f51eaSDavid van Moolenbroek    * memory.  Note we know start_offs is aligned on a paragraph (16-byte)
1417*d56f51eaSDavid van Moolenbroek    * boundary, because we rounded it down.
1418*d56f51eaSDavid van Moolenbroek    *
1419*d56f51eaSDavid van Moolenbroek    * We make the offsets come out rights by backing off the real mode selector
1420*d56f51eaSDavid van Moolenbroek    * by start_offs.
1421*d56f51eaSDavid van Moolenbroek    */
1422*d56f51eaSDavid van Moolenbroek   rm_base = ((ULONG) *rmem_adrp) - (start_offs >> 4);
1423*d56f51eaSDavid van Moolenbroek   RP_SET (*real_basep, 0, rm_base);
1424*d56f51eaSDavid van Moolenbroek   FP_SET (*prot_basep, rm_base << 4, SS_DOSMEM);
1425*d56f51eaSDavid van Moolenbroek 
1426*d56f51eaSDavid van Moolenbroek   /* Copy the real mode code/data to the allocated memory
1427*d56f51eaSDavid van Moolenbroek    */
1428*d56f51eaSDavid van Moolenbroek   source = (UCHAR *) start_offs;
1429*d56f51eaSDavid van Moolenbroek   destin = *prot_basep;
1430*d56f51eaSDavid van Moolenbroek   FP_SET (destin, FP_OFF(*prot_basep) + start_offs, FP_SEL(*prot_basep));
1431*d56f51eaSDavid van Moolenbroek   len = end_offs - start_offs;
1432*d56f51eaSDavid van Moolenbroek   WriteFarMem (destin, source, len);
1433*d56f51eaSDavid van Moolenbroek 
1434*d56f51eaSDavid van Moolenbroek   return (TRUE);
1435*d56f51eaSDavid van Moolenbroek }
1436*d56f51eaSDavid van Moolenbroek #endif /* DOSX && (DOSX & PHARLAP) */
1437