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, ®);
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, ®);
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 (®);
329*d56f51eaSDavid van Moolenbroek r.x.edi = FP_OFF (®);
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*)®);
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