xref: /minix3/external/bsd/libpcap/dist/msdos/ndis2.c (revision d56f51ea7d8b9045e5c8e2028422523d3f9a5840)
1*d56f51eaSDavid van Moolenbroek /*
2*d56f51eaSDavid van Moolenbroek  * Copyright (c) 1993,1994
3*d56f51eaSDavid van Moolenbroek  *      Texas A&M University.  All rights reserved.
4*d56f51eaSDavid van Moolenbroek  *
5*d56f51eaSDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
6*d56f51eaSDavid van Moolenbroek  * modification, are permitted provided that the following conditions
7*d56f51eaSDavid van Moolenbroek  * are met:
8*d56f51eaSDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
9*d56f51eaSDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer.
10*d56f51eaSDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce the above copyright
11*d56f51eaSDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer in the
12*d56f51eaSDavid van Moolenbroek  *    documentation and/or other materials provided with the distribution.
13*d56f51eaSDavid van Moolenbroek  * 3. All advertising materials mentioning features or use of this software
14*d56f51eaSDavid van Moolenbroek  *    must display the following acknowledgement:
15*d56f51eaSDavid van Moolenbroek  *      This product includes software developed by Texas A&M University
16*d56f51eaSDavid van Moolenbroek  *      and its contributors.
17*d56f51eaSDavid van Moolenbroek  * 4. Neither the name of the University nor the names of its contributors
18*d56f51eaSDavid van Moolenbroek  *    may be used to endorse or promote products derived from this software
19*d56f51eaSDavid van Moolenbroek  *    without specific prior written permission.
20*d56f51eaSDavid van Moolenbroek  *
21*d56f51eaSDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
22*d56f51eaSDavid van Moolenbroek  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23*d56f51eaSDavid van Moolenbroek  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24*d56f51eaSDavid van Moolenbroek  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
25*d56f51eaSDavid van Moolenbroek  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*d56f51eaSDavid van Moolenbroek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27*d56f51eaSDavid van Moolenbroek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*d56f51eaSDavid van Moolenbroek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29*d56f51eaSDavid van Moolenbroek  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30*d56f51eaSDavid van Moolenbroek  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*d56f51eaSDavid van Moolenbroek  * SUCH DAMAGE.
32*d56f51eaSDavid van Moolenbroek  *
33*d56f51eaSDavid van Moolenbroek  * Developers:
34*d56f51eaSDavid van Moolenbroek  *             David K. Hess, Douglas Lee Schales, David R. Safford
35*d56f51eaSDavid van Moolenbroek  *
36*d56f51eaSDavid van Moolenbroek  * Heavily modified for Metaware HighC + GNU C 2.8+
37*d56f51eaSDavid van Moolenbroek  *             Gisle Vanem 1998
38*d56f51eaSDavid van Moolenbroek  */
39*d56f51eaSDavid van Moolenbroek 
40*d56f51eaSDavid van Moolenbroek #include <stdio.h>
41*d56f51eaSDavid van Moolenbroek #include <stdlib.h>
42*d56f51eaSDavid van Moolenbroek #include <dos.h>
43*d56f51eaSDavid van Moolenbroek #include <io.h>
44*d56f51eaSDavid van Moolenbroek #include <fcntl.h>
45*d56f51eaSDavid van Moolenbroek #include <malloc.h>
46*d56f51eaSDavid van Moolenbroek #include <string.h>
47*d56f51eaSDavid van Moolenbroek 
48*d56f51eaSDavid van Moolenbroek #include "pcap-dos.h"
49*d56f51eaSDavid van Moolenbroek #include "pcap-int.h"
50*d56f51eaSDavid van Moolenbroek #include "msdos/ndis2.h"
51*d56f51eaSDavid van Moolenbroek 
52*d56f51eaSDavid van Moolenbroek #if defined(USE_NDIS2)
53*d56f51eaSDavid van Moolenbroek 
54*d56f51eaSDavid van Moolenbroek /*
55*d56f51eaSDavid van Moolenbroek  *  Packet buffer handling
56*d56f51eaSDavid van Moolenbroek  */
57*d56f51eaSDavid van Moolenbroek extern int     FreePktBuf  (PktBuf *buf);
58*d56f51eaSDavid van Moolenbroek extern int     EnquePktBuf (PktBuf *buf);
59*d56f51eaSDavid van Moolenbroek extern PktBuf* AllocPktBuf (void);
60*d56f51eaSDavid van Moolenbroek 
61*d56f51eaSDavid van Moolenbroek /*
62*d56f51eaSDavid van Moolenbroek  *  Various defines
63*d56f51eaSDavid van Moolenbroek  */
64*d56f51eaSDavid van Moolenbroek #define MAX_NUM_DEBUG_STRINGS 90
65*d56f51eaSDavid van Moolenbroek #define DEBUG_STRING_LENGTH   80
66*d56f51eaSDavid van Moolenbroek #define STACK_POOL_SIZE       6
67*d56f51eaSDavid van Moolenbroek #define STACK_SIZE            256
68*d56f51eaSDavid van Moolenbroek 
69*d56f51eaSDavid van Moolenbroek #define MEDIA_FDDI            1
70*d56f51eaSDavid van Moolenbroek #define MEDIA_ETHERNET        2
71*d56f51eaSDavid van Moolenbroek #define MEDIA_TOKEN           3
72*d56f51eaSDavid van Moolenbroek 
73*d56f51eaSDavid van Moolenbroek static int     startDebug     = 0;
74*d56f51eaSDavid van Moolenbroek static int     stopDebug      = 0;
75*d56f51eaSDavid van Moolenbroek 
76*d56f51eaSDavid van Moolenbroek static DWORD   droppedPackets = 0L;
77*d56f51eaSDavid van Moolenbroek static WORD    frameSize      = 0;
78*d56f51eaSDavid van Moolenbroek static WORD    headerSize     = 0;
79*d56f51eaSDavid van Moolenbroek static int     mediaType      = 0;
80*d56f51eaSDavid van Moolenbroek static char   *lastErr        = NULL;
81*d56f51eaSDavid van Moolenbroek 
82*d56f51eaSDavid van Moolenbroek static BYTE    debugStrings [MAX_NUM_DEBUG_STRINGS][DEBUG_STRING_LENGTH];
83*d56f51eaSDavid van Moolenbroek static BYTE   *freeStacks   [STACK_POOL_SIZE];
84*d56f51eaSDavid van Moolenbroek static int     freeStackPtr = STACK_POOL_SIZE - 1;
85*d56f51eaSDavid van Moolenbroek 
86*d56f51eaSDavid van Moolenbroek static ProtMan protManEntry = NULL;
87*d56f51eaSDavid van Moolenbroek static WORD    protManDS    = 0;
88*d56f51eaSDavid van Moolenbroek static volatile int xmitPending;
89*d56f51eaSDavid van Moolenbroek 
90*d56f51eaSDavid van Moolenbroek static struct _PktBuf        *txBufPending;
91*d56f51eaSDavid van Moolenbroek static struct _CardHandle    *handle;
92*d56f51eaSDavid van Moolenbroek static struct _CommonChars    common;
93*d56f51eaSDavid van Moolenbroek static struct _ProtocolChars  protChars;
94*d56f51eaSDavid van Moolenbroek static struct _ProtDispatch   lowerTable;
95*d56f51eaSDavid van Moolenbroek 
96*d56f51eaSDavid van Moolenbroek static struct _FailingModules failingModules;
97*d56f51eaSDavid van Moolenbroek static struct _BindingsList   bindings;
98*d56f51eaSDavid van Moolenbroek 
99*d56f51eaSDavid van Moolenbroek static struct {
100*d56f51eaSDavid van Moolenbroek          WORD  err_num;
101*d56f51eaSDavid van Moolenbroek          char *err_text;
102*d56f51eaSDavid van Moolenbroek        } ndis_errlist[] = {
103*d56f51eaSDavid van Moolenbroek 
104*d56f51eaSDavid van Moolenbroek   { ERR_SUCCESS,
105*d56f51eaSDavid van Moolenbroek     "The function completed successfully.\n"  },
106*d56f51eaSDavid van Moolenbroek 
107*d56f51eaSDavid van Moolenbroek   { ERR_WAIT_FOR_RELEASE,
108*d56f51eaSDavid van Moolenbroek     "The ReceiveChain completed successfully but the protocol has\n"
109*d56f51eaSDavid van Moolenbroek     "retained control of the buffer.\n"  },
110*d56f51eaSDavid van Moolenbroek 
111*d56f51eaSDavid van Moolenbroek   { ERR_REQUEST_QUEUED,
112*d56f51eaSDavid van Moolenbroek     "The current request has been queued.\n"  },
113*d56f51eaSDavid van Moolenbroek 
114*d56f51eaSDavid van Moolenbroek   { ERR_FRAME_NOT_RECOGNIZED,
115*d56f51eaSDavid van Moolenbroek     "Frame not recognized.\n"  },
116*d56f51eaSDavid van Moolenbroek 
117*d56f51eaSDavid van Moolenbroek   { ERR_FRAME_REJECTED,
118*d56f51eaSDavid van Moolenbroek     "Frame was discarded.\n"  },
119*d56f51eaSDavid van Moolenbroek 
120*d56f51eaSDavid van Moolenbroek   { ERR_FORWARD_FRAME,
121*d56f51eaSDavid van Moolenbroek     "Protocol wishes to forward frame to another protocol.\n"  },
122*d56f51eaSDavid van Moolenbroek 
123*d56f51eaSDavid van Moolenbroek   { ERR_OUT_OF_RESOURCE,
124*d56f51eaSDavid van Moolenbroek     "Out of resource.\n"  },
125*d56f51eaSDavid van Moolenbroek 
126*d56f51eaSDavid van Moolenbroek   { ERR_INVALID_PARAMETER,
127*d56f51eaSDavid van Moolenbroek     "Invalid parameter.\n"  },
128*d56f51eaSDavid van Moolenbroek 
129*d56f51eaSDavid van Moolenbroek   { ERR_INVALID_FUNCTION,
130*d56f51eaSDavid van Moolenbroek     "Invalid function.\n"  },
131*d56f51eaSDavid van Moolenbroek 
132*d56f51eaSDavid van Moolenbroek   { ERR_NOT_SUPPORTED,
133*d56f51eaSDavid van Moolenbroek     "Not supported.\n"  },
134*d56f51eaSDavid van Moolenbroek 
135*d56f51eaSDavid van Moolenbroek   { ERR_HARDWARE_ERROR,
136*d56f51eaSDavid van Moolenbroek     "Hardware error.\n"  },
137*d56f51eaSDavid van Moolenbroek 
138*d56f51eaSDavid van Moolenbroek   { ERR_TRANSMIT_ERROR,
139*d56f51eaSDavid van Moolenbroek     "The packet was not transmitted due to an error.\n"  },
140*d56f51eaSDavid van Moolenbroek 
141*d56f51eaSDavid van Moolenbroek   { ERR_NO_SUCH_DESTINATION,
142*d56f51eaSDavid van Moolenbroek     "Token ring packet was not recognized when transmitted.\n"  },
143*d56f51eaSDavid van Moolenbroek 
144*d56f51eaSDavid van Moolenbroek   { ERR_BUFFER_TOO_SMALL,
145*d56f51eaSDavid van Moolenbroek     "Provided buffer was too small.\n"  },
146*d56f51eaSDavid van Moolenbroek 
147*d56f51eaSDavid van Moolenbroek   { ERR_ALREADY_STARTED,
148*d56f51eaSDavid van Moolenbroek     "Network drivers already started.\n"  },
149*d56f51eaSDavid van Moolenbroek 
150*d56f51eaSDavid van Moolenbroek   { ERR_INCOMPLETE_BINDING,
151*d56f51eaSDavid van Moolenbroek     "Protocol driver could not complete its bindings.\n"  },
152*d56f51eaSDavid van Moolenbroek 
153*d56f51eaSDavid van Moolenbroek   { ERR_DRIVER_NOT_INITIALIZED,
154*d56f51eaSDavid van Moolenbroek     "MAC did not initialize properly.\n"  },
155*d56f51eaSDavid van Moolenbroek 
156*d56f51eaSDavid van Moolenbroek   { ERR_HARDWARE_NOT_FOUND,
157*d56f51eaSDavid van Moolenbroek     "Hardware not found.\n"  },
158*d56f51eaSDavid van Moolenbroek 
159*d56f51eaSDavid van Moolenbroek   { ERR_HARDWARE_FAILURE,
160*d56f51eaSDavid van Moolenbroek     "Hardware failure.\n"  },
161*d56f51eaSDavid van Moolenbroek 
162*d56f51eaSDavid van Moolenbroek   { ERR_CONFIGURATION_FAILURE,
163*d56f51eaSDavid van Moolenbroek     "Configuration failure.\n"  },
164*d56f51eaSDavid van Moolenbroek 
165*d56f51eaSDavid van Moolenbroek   { ERR_INTERRUPT_CONFLICT,
166*d56f51eaSDavid van Moolenbroek     "Interrupt conflict.\n"  },
167*d56f51eaSDavid van Moolenbroek 
168*d56f51eaSDavid van Moolenbroek   { ERR_INCOMPATIBLE_MAC,
169*d56f51eaSDavid van Moolenbroek     "The MAC is not compatible with the protocol.\n"  },
170*d56f51eaSDavid van Moolenbroek 
171*d56f51eaSDavid van Moolenbroek   { ERR_INITIALIZATION_FAILED,
172*d56f51eaSDavid van Moolenbroek     "Initialization failed.\n"  },
173*d56f51eaSDavid van Moolenbroek 
174*d56f51eaSDavid van Moolenbroek   { ERR_NO_BINDING,
175*d56f51eaSDavid van Moolenbroek     "Binding did not occur.\n"  },
176*d56f51eaSDavid van Moolenbroek 
177*d56f51eaSDavid van Moolenbroek   { ERR_NETWORK_MAY_NOT_BE_CONNECTED,
178*d56f51eaSDavid van Moolenbroek     "The network may not be connected to the adapter.\n"  },
179*d56f51eaSDavid van Moolenbroek 
180*d56f51eaSDavid van Moolenbroek   { ERR_INCOMPATIBLE_OS_VERSION,
181*d56f51eaSDavid van Moolenbroek     "The version of the operating system is incompatible with the protocol.\n"  },
182*d56f51eaSDavid van Moolenbroek 
183*d56f51eaSDavid van Moolenbroek   { ERR_ALREADY_REGISTERED,
184*d56f51eaSDavid van Moolenbroek     "The protocol is already registered.\n"  },
185*d56f51eaSDavid van Moolenbroek 
186*d56f51eaSDavid van Moolenbroek   { ERR_PATH_NOT_FOUND,
187*d56f51eaSDavid van Moolenbroek     "PROTMAN.EXE could not be found.\n"  },
188*d56f51eaSDavid van Moolenbroek 
189*d56f51eaSDavid van Moolenbroek   { ERR_INSUFFICIENT_MEMORY,
190*d56f51eaSDavid van Moolenbroek     "Insufficient memory.\n"  },
191*d56f51eaSDavid van Moolenbroek 
192*d56f51eaSDavid van Moolenbroek   { ERR_INFO_NOT_FOUND,
193*d56f51eaSDavid van Moolenbroek     "Protocol Mananger info structure is lost or corrupted.\n"  },
194*d56f51eaSDavid van Moolenbroek 
195*d56f51eaSDavid van Moolenbroek   { ERR_GENERAL_FAILURE,
196*d56f51eaSDavid van Moolenbroek     "General failure.\n"  }
197*d56f51eaSDavid van Moolenbroek };
198*d56f51eaSDavid van Moolenbroek 
199*d56f51eaSDavid van Moolenbroek /*
200*d56f51eaSDavid van Moolenbroek  *  Some handy macros
201*d56f51eaSDavid van Moolenbroek  */
202*d56f51eaSDavid van Moolenbroek #define PERROR(str)    printf("%s (%d): %s\n", __FILE__,__LINE__,str)
203*d56f51eaSDavid van Moolenbroek #define DEBUG_RING()   (debugStrings[stopDebug+1 == MAX_NUM_DEBUG_STRINGS ? \
204*d56f51eaSDavid van Moolenbroek                         stopDebug = 0 : ++stopDebug])
205*d56f51eaSDavid van Moolenbroek 
206*d56f51eaSDavid van Moolenbroek /*
207*d56f51eaSDavid van Moolenbroek  * needs rewrite for DOSX
208*d56f51eaSDavid van Moolenbroek  */
209*d56f51eaSDavid van Moolenbroek #define MAC_DISPATCH(hnd)  ((struct _MacUpperDispatch*)(hnd)->common->upperDispatchTable)
210*d56f51eaSDavid van Moolenbroek #define MAC_STATUS(hnd)    ((struct _MacStatusTable*)  (hnd)->common->serviceStatus)
211*d56f51eaSDavid van Moolenbroek #define MAC_CHAR(hnd)      ((struct _MacChars*)        (hnd)->common->serviceChars)
212*d56f51eaSDavid van Moolenbroek 
213*d56f51eaSDavid van Moolenbroek #ifdef NDIS_DEBUG
214*d56f51eaSDavid van Moolenbroek   #define DEBUG0(str)      printf (str)
215*d56f51eaSDavid van Moolenbroek   #define DEBUG1(fmt,a)    printf (fmt,a)
216*d56f51eaSDavid van Moolenbroek   #define DEBUG2(fmt,a,b)  printf (fmt,a,b)
217*d56f51eaSDavid van Moolenbroek   #define TRACE0(str)      sprintf (DEBUG_RING(),str)
218*d56f51eaSDavid van Moolenbroek   #define TRACE1(fmt,a)    sprintf (DEBUG_RING(),fmt,a)
219*d56f51eaSDavid van Moolenbroek #else
220*d56f51eaSDavid van Moolenbroek   #define DEBUG0(str)      ((void)0)
221*d56f51eaSDavid van Moolenbroek   #define DEBUG1(fmt,a)    ((void)0)
222*d56f51eaSDavid van Moolenbroek   #define DEBUG2(fmt,a,b)  ((void)0)
223*d56f51eaSDavid van Moolenbroek   #define TRACE0(str)      ((void)0)
224*d56f51eaSDavid van Moolenbroek   #define TRACE1(fmt,a)    ((void)0)
225*d56f51eaSDavid van Moolenbroek #endif
226*d56f51eaSDavid van Moolenbroek 
227*d56f51eaSDavid van Moolenbroek /*
228*d56f51eaSDavid van Moolenbroek  * This routine is called from both threads
229*d56f51eaSDavid van Moolenbroek  */
NdisFreeStack(BYTE * aStack)230*d56f51eaSDavid van Moolenbroek void NdisFreeStack (BYTE *aStack)
231*d56f51eaSDavid van Moolenbroek {
232*d56f51eaSDavid van Moolenbroek   GUARD();
233*d56f51eaSDavid van Moolenbroek 
234*d56f51eaSDavid van Moolenbroek   if (freeStackPtr == STACK_POOL_SIZE - 1)
235*d56f51eaSDavid van Moolenbroek      PERROR ("tried to free too many stacks");
236*d56f51eaSDavid van Moolenbroek 
237*d56f51eaSDavid van Moolenbroek   freeStacks[++freeStackPtr] = aStack;
238*d56f51eaSDavid van Moolenbroek 
239*d56f51eaSDavid van Moolenbroek   if (freeStackPtr == 0)
240*d56f51eaSDavid van Moolenbroek      TRACE0 ("freeStackPtr went positive\n");
241*d56f51eaSDavid van Moolenbroek 
242*d56f51eaSDavid van Moolenbroek   UNGUARD();
243*d56f51eaSDavid van Moolenbroek }
244*d56f51eaSDavid van Moolenbroek 
245*d56f51eaSDavid van Moolenbroek /*
246*d56f51eaSDavid van Moolenbroek  * This routine is called from callbacks to allocate local data
247*d56f51eaSDavid van Moolenbroek  */
NdisAllocStack(void)248*d56f51eaSDavid van Moolenbroek BYTE *NdisAllocStack (void)
249*d56f51eaSDavid van Moolenbroek {
250*d56f51eaSDavid van Moolenbroek   BYTE *stack;
251*d56f51eaSDavid van Moolenbroek 
252*d56f51eaSDavid van Moolenbroek   GUARD();
253*d56f51eaSDavid van Moolenbroek 
254*d56f51eaSDavid van Moolenbroek   if (freeStackPtr < 0)
255*d56f51eaSDavid van Moolenbroek   {
256*d56f51eaSDavid van Moolenbroek     /* Ran out of stack buffers. Return NULL which will start
257*d56f51eaSDavid van Moolenbroek      * dropping packets
258*d56f51eaSDavid van Moolenbroek      */
259*d56f51eaSDavid van Moolenbroek     TRACE0 ("freeStackPtr went negative\n");
260*d56f51eaSDavid van Moolenbroek     stack = 0;
261*d56f51eaSDavid van Moolenbroek   }
262*d56f51eaSDavid van Moolenbroek   else
263*d56f51eaSDavid van Moolenbroek     stack = freeStacks[freeStackPtr--];
264*d56f51eaSDavid van Moolenbroek 
265*d56f51eaSDavid van Moolenbroek   UNGUARD();
266*d56f51eaSDavid van Moolenbroek   return (stack);
267*d56f51eaSDavid van Moolenbroek }
268*d56f51eaSDavid van Moolenbroek 
CALLBACK(NdisSystemRequest (DWORD param1,DWORD param2,WORD param3,WORD opcode,WORD targetDS))269*d56f51eaSDavid van Moolenbroek CALLBACK (NdisSystemRequest (DWORD param1, DWORD param2, WORD param3,
270*d56f51eaSDavid van Moolenbroek                              WORD opcode, WORD targetDS))
271*d56f51eaSDavid van Moolenbroek {
272*d56f51eaSDavid van Moolenbroek   static int            bindEntry = 0;
273*d56f51eaSDavid van Moolenbroek   struct _CommonChars  *macCommon;
274*d56f51eaSDavid van Moolenbroek   volatile WORD result;
275*d56f51eaSDavid van Moolenbroek 
276*d56f51eaSDavid van Moolenbroek   switch (opcode)
277*d56f51eaSDavid van Moolenbroek   {
278*d56f51eaSDavid van Moolenbroek     case REQ_INITIATE_BIND:
279*d56f51eaSDavid van Moolenbroek          macCommon = (struct _CommonChars*) param2;
280*d56f51eaSDavid van Moolenbroek          if (macCommon == NULL)
281*d56f51eaSDavid van Moolenbroek 	 {
282*d56f51eaSDavid van Moolenbroek            printf ("There is an NDIS misconfiguration.\n");
283*d56f51eaSDavid van Moolenbroek            result = ERR_GENERAL_FAILURE;
284*d56f51eaSDavid van Moolenbroek 	   break;
285*d56f51eaSDavid van Moolenbroek 	 }
286*d56f51eaSDavid van Moolenbroek          DEBUG2 ("module name %s\n"
287*d56f51eaSDavid van Moolenbroek                  "module type %s\n",
288*d56f51eaSDavid van Moolenbroek                  macCommon->moduleName,
289*d56f51eaSDavid van Moolenbroek                  ((MacChars*) macCommon->serviceChars)->macName);
290*d56f51eaSDavid van Moolenbroek 
291*d56f51eaSDavid van Moolenbroek          /* Binding to the MAC */
292*d56f51eaSDavid van Moolenbroek          result = macCommon->systemRequest ((DWORD)&common, (DWORD)&macCommon,
293*d56f51eaSDavid van Moolenbroek                                             0, REQ_BIND,
294*d56f51eaSDavid van Moolenbroek                                             macCommon->moduleDS);
295*d56f51eaSDavid van Moolenbroek 
296*d56f51eaSDavid van Moolenbroek          if (!strcmp(bindings.moduleName[bindEntry], handle->moduleName))
297*d56f51eaSDavid van Moolenbroek               handle->common = macCommon;
298*d56f51eaSDavid van Moolenbroek          else PERROR ("unknown module");
299*d56f51eaSDavid van Moolenbroek          ++bindEntry;
300*d56f51eaSDavid van Moolenbroek 	 break;
301*d56f51eaSDavid van Moolenbroek 
302*d56f51eaSDavid van Moolenbroek     case REQ_INITIATE_UNBIND:
303*d56f51eaSDavid van Moolenbroek          macCommon = (struct _CommonChars*) param2;
304*d56f51eaSDavid van Moolenbroek          result = macCommon->systemRequest ((DWORD)&common, 0,
305*d56f51eaSDavid van Moolenbroek                                             0, REQ_UNBIND,
306*d56f51eaSDavid van Moolenbroek                                             macCommon->moduleDS);
307*d56f51eaSDavid van Moolenbroek          break;
308*d56f51eaSDavid van Moolenbroek 
309*d56f51eaSDavid van Moolenbroek     default:
310*d56f51eaSDavid van Moolenbroek          result = ERR_GENERAL_FAILURE;
311*d56f51eaSDavid van Moolenbroek 	 break;
312*d56f51eaSDavid van Moolenbroek   }
313*d56f51eaSDavid van Moolenbroek   ARGSUSED (param1);
314*d56f51eaSDavid van Moolenbroek   ARGSUSED (param3);
315*d56f51eaSDavid van Moolenbroek   ARGSUSED (targetDS);
316*d56f51eaSDavid van Moolenbroek   return (result);
317*d56f51eaSDavid van Moolenbroek }
318*d56f51eaSDavid van Moolenbroek 
CALLBACK(NdisRequestConfirm (WORD protId,WORD macId,WORD reqHandle,WORD status,WORD request,WORD protDS))319*d56f51eaSDavid van Moolenbroek CALLBACK (NdisRequestConfirm (WORD protId, WORD macId,   WORD reqHandle,
320*d56f51eaSDavid van Moolenbroek                               WORD status, WORD request, WORD protDS))
321*d56f51eaSDavid van Moolenbroek {
322*d56f51eaSDavid van Moolenbroek   ARGSUSED (protId);    ARGSUSED (macId);
323*d56f51eaSDavid van Moolenbroek   ARGSUSED (reqHandle); ARGSUSED (status);
324*d56f51eaSDavid van Moolenbroek   ARGSUSED (request);   ARGSUSED (protDS);
325*d56f51eaSDavid van Moolenbroek   return (ERR_SUCCESS);
326*d56f51eaSDavid van Moolenbroek }
327*d56f51eaSDavid van Moolenbroek 
CALLBACK(NdisTransmitConfirm (WORD protId,WORD macId,WORD reqHandle,WORD status,WORD protDS))328*d56f51eaSDavid van Moolenbroek CALLBACK (NdisTransmitConfirm (WORD protId, WORD macId, WORD reqHandle,
329*d56f51eaSDavid van Moolenbroek                                WORD status, WORD protDS))
330*d56f51eaSDavid van Moolenbroek {
331*d56f51eaSDavid van Moolenbroek   xmitPending--;
332*d56f51eaSDavid van Moolenbroek   FreePktBuf (txBufPending);  /* Add passed ECB back to the free list */
333*d56f51eaSDavid van Moolenbroek 
334*d56f51eaSDavid van Moolenbroek   ARGSUSED (reqHandle);
335*d56f51eaSDavid van Moolenbroek   ARGSUSED (status);
336*d56f51eaSDavid van Moolenbroek   ARGSUSED (protDS);
337*d56f51eaSDavid van Moolenbroek   return (ERR_SUCCESS);
338*d56f51eaSDavid van Moolenbroek }
339*d56f51eaSDavid van Moolenbroek 
340*d56f51eaSDavid van Moolenbroek 
341*d56f51eaSDavid van Moolenbroek /*
342*d56f51eaSDavid van Moolenbroek  * The primary function for receiving packets
343*d56f51eaSDavid van Moolenbroek  */
CALLBACK(NdisReceiveLookahead (WORD macId,WORD frameSize,WORD bytesAvail,BYTE * buffer,BYTE * indicate,WORD protDS))344*d56f51eaSDavid van Moolenbroek CALLBACK (NdisReceiveLookahead (WORD  macId,      WORD  frameSize,
345*d56f51eaSDavid van Moolenbroek                                 WORD  bytesAvail, BYTE *buffer,
346*d56f51eaSDavid van Moolenbroek                                 BYTE *indicate,   WORD  protDS))
347*d56f51eaSDavid van Moolenbroek {
348*d56f51eaSDavid van Moolenbroek   int     result;
349*d56f51eaSDavid van Moolenbroek   PktBuf *pktBuf;
350*d56f51eaSDavid van Moolenbroek   WORD    bytesCopied;
351*d56f51eaSDavid van Moolenbroek   struct _TDBufDescr tDBufDescr;
352*d56f51eaSDavid van Moolenbroek 
353*d56f51eaSDavid van Moolenbroek #if 0
354*d56f51eaSDavid van Moolenbroek   TRACE1 ("lookahead length = %d, ", bytesAvail);
355*d56f51eaSDavid van Moolenbroek   TRACE1 ("ecb = %08lX, ",          *ecb);
356*d56f51eaSDavid van Moolenbroek   TRACE1 ("count = %08lX\n",         count);
357*d56f51eaSDavid van Moolenbroek   TRACE1 ("offset = %08lX, ",        offset);
358*d56f51eaSDavid van Moolenbroek   TRACE1 ("timesAllowed = %d, ",     timesAllowed);
359*d56f51eaSDavid van Moolenbroek   TRACE1 ("packet size = %d\n",      look->dataLookAheadLen);
360*d56f51eaSDavid van Moolenbroek #endif
361*d56f51eaSDavid van Moolenbroek 
362*d56f51eaSDavid van Moolenbroek   /* Allocate a buffer for the packet
363*d56f51eaSDavid van Moolenbroek    */
364*d56f51eaSDavid van Moolenbroek   if ((pktBuf = AllocPktBuf()) == NULL)
365*d56f51eaSDavid van Moolenbroek   {
366*d56f51eaSDavid van Moolenbroek     droppedPackets++;
367*d56f51eaSDavid van Moolenbroek     return (ERR_FRAME_REJECTED);
368*d56f51eaSDavid van Moolenbroek   }
369*d56f51eaSDavid van Moolenbroek 
370*d56f51eaSDavid van Moolenbroek   /*
371*d56f51eaSDavid van Moolenbroek    * Now kludge things. Note we will have to undo this later. This will
372*d56f51eaSDavid van Moolenbroek    * make the packet contiguous after the MLID has done the requested copy.
373*d56f51eaSDavid van Moolenbroek    */
374*d56f51eaSDavid van Moolenbroek 
375*d56f51eaSDavid van Moolenbroek   tDBufDescr.tDDataCount = 1;
376*d56f51eaSDavid van Moolenbroek   tDBufDescr.tDBufDescrRec[0].tDPtrType = NDIS_PTR_PHYSICAL;
377*d56f51eaSDavid van Moolenbroek   tDBufDescr.tDBufDescrRec[0].tDDataPtr = pktBuf->buffer;
378*d56f51eaSDavid van Moolenbroek   tDBufDescr.tDBufDescrRec[0].tDDataLen = pktBuf->length;
379*d56f51eaSDavid van Moolenbroek   tDBufDescr.tDBufDescrRec[0].dummy     = 0;
380*d56f51eaSDavid van Moolenbroek 
381*d56f51eaSDavid van Moolenbroek   result = MAC_DISPATCH(handle)->transferData (&bytesCopied, 0, &tDBufDescr,
382*d56f51eaSDavid van Moolenbroek                                                handle->common->moduleDS);
383*d56f51eaSDavid van Moolenbroek   pktBuf->packetLength = bytesCopied;
384*d56f51eaSDavid van Moolenbroek 
385*d56f51eaSDavid van Moolenbroek   if (result == ERR_SUCCESS)
386*d56f51eaSDavid van Moolenbroek        EnquePktBuf(pktBuf);
387*d56f51eaSDavid van Moolenbroek   else FreePktBuf (pktBuf);
388*d56f51eaSDavid van Moolenbroek 
389*d56f51eaSDavid van Moolenbroek   ARGSUSED (frameSize);
390*d56f51eaSDavid van Moolenbroek   ARGSUSED (bytesAvail);
391*d56f51eaSDavid van Moolenbroek   ARGSUSED (indicate);
392*d56f51eaSDavid van Moolenbroek   ARGSUSED (protDS);
393*d56f51eaSDavid van Moolenbroek 
394*d56f51eaSDavid van Moolenbroek   return (ERR_SUCCESS);
395*d56f51eaSDavid van Moolenbroek }
396*d56f51eaSDavid van Moolenbroek 
CALLBACK(NdisIndicationComplete (WORD macId,WORD protDS))397*d56f51eaSDavid van Moolenbroek CALLBACK (NdisIndicationComplete (WORD macId, WORD protDS))
398*d56f51eaSDavid van Moolenbroek {
399*d56f51eaSDavid van Moolenbroek   ARGSUSED (macId);
400*d56f51eaSDavid van Moolenbroek   ARGSUSED (protDS);
401*d56f51eaSDavid van Moolenbroek 
402*d56f51eaSDavid van Moolenbroek   /* We don't give a hoot about these. Just return
403*d56f51eaSDavid van Moolenbroek    */
404*d56f51eaSDavid van Moolenbroek   return (ERR_SUCCESS);
405*d56f51eaSDavid van Moolenbroek }
406*d56f51eaSDavid van Moolenbroek 
407*d56f51eaSDavid van Moolenbroek /*
408*d56f51eaSDavid van Moolenbroek  * This is the OTHER way we may receive packets
409*d56f51eaSDavid van Moolenbroek  */
CALLBACK(NdisReceiveChain (WORD macId,WORD frameSize,WORD reqHandle,struct _RxBufDescr * rxBufDescr,BYTE * indicate,WORD protDS))410*d56f51eaSDavid van Moolenbroek CALLBACK (NdisReceiveChain (WORD macId, WORD frameSize, WORD reqHandle,
411*d56f51eaSDavid van Moolenbroek                             struct _RxBufDescr *rxBufDescr,
412*d56f51eaSDavid van Moolenbroek                             BYTE *indicate, WORD protDS))
413*d56f51eaSDavid van Moolenbroek {
414*d56f51eaSDavid van Moolenbroek   struct _PktBuf *pktBuf;
415*d56f51eaSDavid van Moolenbroek   int     i;
416*d56f51eaSDavid van Moolenbroek 
417*d56f51eaSDavid van Moolenbroek   /*
418*d56f51eaSDavid van Moolenbroek    * For now we copy the entire packet over to a PktBuf structure. This may be
419*d56f51eaSDavid van Moolenbroek    * a performance hit but this routine probably isn't called very much, and
420*d56f51eaSDavid van Moolenbroek    * it is a lot of work to do it otherwise. Also if it is a filter protocol
421*d56f51eaSDavid van Moolenbroek    * packet we could end up sucking up MAC buffes.
422*d56f51eaSDavid van Moolenbroek    */
423*d56f51eaSDavid van Moolenbroek 
424*d56f51eaSDavid van Moolenbroek   if ((pktBuf = AllocPktBuf()) == NULL)
425*d56f51eaSDavid van Moolenbroek   {
426*d56f51eaSDavid van Moolenbroek     droppedPackets++;
427*d56f51eaSDavid van Moolenbroek     return (ERR_FRAME_REJECTED);
428*d56f51eaSDavid van Moolenbroek   }
429*d56f51eaSDavid van Moolenbroek   pktBuf->packetLength = 0;
430*d56f51eaSDavid van Moolenbroek 
431*d56f51eaSDavid van Moolenbroek   /* Copy the packet to the buffer
432*d56f51eaSDavid van Moolenbroek    */
433*d56f51eaSDavid van Moolenbroek   for (i = 0; i < rxBufDescr->rxDataCount; ++i)
434*d56f51eaSDavid van Moolenbroek   {
435*d56f51eaSDavid van Moolenbroek     struct _RxBufDescrRec *rxDescr = &rxBufDescr->rxBufDescrRec[i];
436*d56f51eaSDavid van Moolenbroek 
437*d56f51eaSDavid van Moolenbroek     memcpy (pktBuf->buffer + pktBuf->packetLength,
438*d56f51eaSDavid van Moolenbroek             rxDescr->rxDataPtr, rxDescr->rxDataLen);
439*d56f51eaSDavid van Moolenbroek     pktBuf->packetLength += rxDescr->rxDataLen;
440*d56f51eaSDavid van Moolenbroek   }
441*d56f51eaSDavid van Moolenbroek 
442*d56f51eaSDavid van Moolenbroek   EnquePktBuf (pktBuf);
443*d56f51eaSDavid van Moolenbroek 
444*d56f51eaSDavid van Moolenbroek   ARGSUSED (frameSize);
445*d56f51eaSDavid van Moolenbroek   ARGSUSED (reqHandle);
446*d56f51eaSDavid van Moolenbroek   ARGSUSED (indicate);
447*d56f51eaSDavid van Moolenbroek   ARGSUSED (protDS);
448*d56f51eaSDavid van Moolenbroek 
449*d56f51eaSDavid van Moolenbroek   /* This frees up the buffer for the MAC to use
450*d56f51eaSDavid van Moolenbroek    */
451*d56f51eaSDavid van Moolenbroek   return (ERR_SUCCESS);
452*d56f51eaSDavid van Moolenbroek }
453*d56f51eaSDavid van Moolenbroek 
CALLBACK(NdisStatusProc (WORD macId,WORD param1,BYTE * indicate,WORD opcode,WORD protDS))454*d56f51eaSDavid van Moolenbroek CALLBACK (NdisStatusProc (WORD macId,  WORD param1, BYTE *indicate,
455*d56f51eaSDavid van Moolenbroek                           WORD opcode, WORD protDS))
456*d56f51eaSDavid van Moolenbroek {
457*d56f51eaSDavid van Moolenbroek   switch (opcode)
458*d56f51eaSDavid van Moolenbroek   {
459*d56f51eaSDavid van Moolenbroek     case STATUS_RING_STATUS:
460*d56f51eaSDavid van Moolenbroek 	 break;
461*d56f51eaSDavid van Moolenbroek     case STATUS_ADAPTER_CHECK:
462*d56f51eaSDavid van Moolenbroek 	 break;
463*d56f51eaSDavid van Moolenbroek     case STATUS_START_RESET:
464*d56f51eaSDavid van Moolenbroek 	 break;
465*d56f51eaSDavid van Moolenbroek     case STATUS_INTERRUPT:
466*d56f51eaSDavid van Moolenbroek 	 break;
467*d56f51eaSDavid van Moolenbroek     case STATUS_END_RESET:
468*d56f51eaSDavid van Moolenbroek 	 break;
469*d56f51eaSDavid van Moolenbroek     default:
470*d56f51eaSDavid van Moolenbroek 	 break;
471*d56f51eaSDavid van Moolenbroek   }
472*d56f51eaSDavid van Moolenbroek   ARGSUSED (macId);
473*d56f51eaSDavid van Moolenbroek   ARGSUSED (param1);
474*d56f51eaSDavid van Moolenbroek   ARGSUSED (indicate);
475*d56f51eaSDavid van Moolenbroek   ARGSUSED (opcode);
476*d56f51eaSDavid van Moolenbroek   ARGSUSED (protDS);
477*d56f51eaSDavid van Moolenbroek 
478*d56f51eaSDavid van Moolenbroek   /* We don't need to do anything about this stuff yet
479*d56f51eaSDavid van Moolenbroek    */
480*d56f51eaSDavid van Moolenbroek   return (ERR_SUCCESS);
481*d56f51eaSDavid van Moolenbroek }
482*d56f51eaSDavid van Moolenbroek 
483*d56f51eaSDavid van Moolenbroek /*
484*d56f51eaSDavid van Moolenbroek  * Tell the NDIS driver to start the delivery of the packet
485*d56f51eaSDavid van Moolenbroek  */
NdisSendPacket(struct _PktBuf * pktBuf,int macId)486*d56f51eaSDavid van Moolenbroek int NdisSendPacket (struct _PktBuf *pktBuf, int macId)
487*d56f51eaSDavid van Moolenbroek {
488*d56f51eaSDavid van Moolenbroek   struct _TxBufDescr txBufDescr;
489*d56f51eaSDavid van Moolenbroek   int     result;
490*d56f51eaSDavid van Moolenbroek 
491*d56f51eaSDavid van Moolenbroek   xmitPending++;
492*d56f51eaSDavid van Moolenbroek   txBufPending = pktBuf;    /* we only have 1 pending Tx at a time */
493*d56f51eaSDavid van Moolenbroek 
494*d56f51eaSDavid van Moolenbroek   txBufDescr.txImmedLen  = 0;
495*d56f51eaSDavid van Moolenbroek   txBufDescr.txImmedPtr  = NULL;
496*d56f51eaSDavid van Moolenbroek   txBufDescr.txDataCount = 1;
497*d56f51eaSDavid van Moolenbroek   txBufDescr.txBufDescrRec[0].txPtrType = NDIS_PTR_PHYSICAL;
498*d56f51eaSDavid van Moolenbroek   txBufDescr.txBufDescrRec[0].dummy     = 0;
499*d56f51eaSDavid van Moolenbroek   txBufDescr.txBufDescrRec[0].txDataLen = pktBuf->packetLength;
500*d56f51eaSDavid van Moolenbroek   txBufDescr.txBufDescrRec[0].txDataPtr = pktBuf->buffer;
501*d56f51eaSDavid van Moolenbroek 
502*d56f51eaSDavid van Moolenbroek   result = MAC_DISPATCH(handle)->transmitChain (common.moduleId,
503*d56f51eaSDavid van Moolenbroek                                                 pktBuf->handle,
504*d56f51eaSDavid van Moolenbroek                                                 &txBufDescr,
505*d56f51eaSDavid van Moolenbroek                                                 handle->common->moduleDS);
506*d56f51eaSDavid van Moolenbroek   switch (result)
507*d56f51eaSDavid van Moolenbroek   {
508*d56f51eaSDavid van Moolenbroek     case ERR_OUT_OF_RESOURCE:
509*d56f51eaSDavid van Moolenbroek          /* Note that this should not happen but if it does there is not
510*d56f51eaSDavid van Moolenbroek           * much we can do about it
511*d56f51eaSDavid van Moolenbroek           */
512*d56f51eaSDavid van Moolenbroek          printf ("ERROR: transmit queue overflowed\n");
513*d56f51eaSDavid van Moolenbroek          return (0);
514*d56f51eaSDavid van Moolenbroek 
515*d56f51eaSDavid van Moolenbroek     case ERR_SUCCESS:
516*d56f51eaSDavid van Moolenbroek          /* Everything was hunky dory and synchronous. Free up the
517*d56f51eaSDavid van Moolenbroek           * packet buffer
518*d56f51eaSDavid van Moolenbroek           */
519*d56f51eaSDavid van Moolenbroek          xmitPending--;
520*d56f51eaSDavid van Moolenbroek          FreePktBuf (pktBuf);
521*d56f51eaSDavid van Moolenbroek          return (1);
522*d56f51eaSDavid van Moolenbroek 
523*d56f51eaSDavid van Moolenbroek     case ERR_REQUEST_QUEUED:
524*d56f51eaSDavid van Moolenbroek          /* Everything was hunky dory and asynchronous. Do nothing
525*d56f51eaSDavid van Moolenbroek           */
526*d56f51eaSDavid van Moolenbroek          return (1);
527*d56f51eaSDavid van Moolenbroek 
528*d56f51eaSDavid van Moolenbroek     default:
529*d56f51eaSDavid van Moolenbroek          printf ("Tx fail, code = %04X\n", result);
530*d56f51eaSDavid van Moolenbroek          return (0);
531*d56f51eaSDavid van Moolenbroek   }
532*d56f51eaSDavid van Moolenbroek }
533*d56f51eaSDavid van Moolenbroek 
534*d56f51eaSDavid van Moolenbroek 
535*d56f51eaSDavid van Moolenbroek 
536*d56f51eaSDavid van Moolenbroek static int ndis_nerr = sizeof(ndis_errlist) / sizeof(ndis_errlist[0]);
537*d56f51eaSDavid van Moolenbroek 
Ndis_strerror(WORD errorCode)538*d56f51eaSDavid van Moolenbroek static char *Ndis_strerror (WORD errorCode)
539*d56f51eaSDavid van Moolenbroek {
540*d56f51eaSDavid van Moolenbroek   static char buf[30];
541*d56f51eaSDavid van Moolenbroek   int    i;
542*d56f51eaSDavid van Moolenbroek 
543*d56f51eaSDavid van Moolenbroek   for (i = 0; i < ndis_nerr; i++)
544*d56f51eaSDavid van Moolenbroek       if (errorCode == ndis_errlist[i].err_num)
545*d56f51eaSDavid van Moolenbroek          return (ndis_errlist[i].err_text);
546*d56f51eaSDavid van Moolenbroek 
547*d56f51eaSDavid van Moolenbroek   sprintf (buf,"unknown error %d",errorCode);
548*d56f51eaSDavid van Moolenbroek   return (buf);
549*d56f51eaSDavid van Moolenbroek }
550*d56f51eaSDavid van Moolenbroek 
551*d56f51eaSDavid van Moolenbroek 
NdisLastError(void)552*d56f51eaSDavid van Moolenbroek char *NdisLastError (void)
553*d56f51eaSDavid van Moolenbroek {
554*d56f51eaSDavid van Moolenbroek   char *errStr = lastErr;
555*d56f51eaSDavid van Moolenbroek   lastErr = NULL;
556*d56f51eaSDavid van Moolenbroek   return (errStr);
557*d56f51eaSDavid van Moolenbroek }
558*d56f51eaSDavid van Moolenbroek 
NdisOpen(void)559*d56f51eaSDavid van Moolenbroek int NdisOpen (void)
560*d56f51eaSDavid van Moolenbroek {
561*d56f51eaSDavid van Moolenbroek   struct _ReqBlock reqBlock;
562*d56f51eaSDavid van Moolenbroek   int     result;
563*d56f51eaSDavid van Moolenbroek   int     ndisFd = open (NDIS_PATH, O_RDONLY);
564*d56f51eaSDavid van Moolenbroek 
565*d56f51eaSDavid van Moolenbroek   if (ndisFd < 0)
566*d56f51eaSDavid van Moolenbroek   {
567*d56f51eaSDavid van Moolenbroek     printf ("Could not open NDIS Protocol Manager device.\n");
568*d56f51eaSDavid van Moolenbroek     return (0);
569*d56f51eaSDavid van Moolenbroek   }
570*d56f51eaSDavid van Moolenbroek 
571*d56f51eaSDavid van Moolenbroek   memset (&reqBlock, 0, sizeof(ReqBlock));
572*d56f51eaSDavid van Moolenbroek 
573*d56f51eaSDavid van Moolenbroek   reqBlock.opcode = PM_GET_PROTOCOL_MANAGER_LINKAGE;
574*d56f51eaSDavid van Moolenbroek 
575*d56f51eaSDavid van Moolenbroek   result = NdisGetLinkage (ndisFd, (char*)&reqBlock, sizeof(ReqBlock));
576*d56f51eaSDavid van Moolenbroek   if (result != 0)
577*d56f51eaSDavid van Moolenbroek   {
578*d56f51eaSDavid van Moolenbroek     printf ("Could not get Protocol Manager linkage.\n");
579*d56f51eaSDavid van Moolenbroek     close (ndisFd);
580*d56f51eaSDavid van Moolenbroek     return (0);
581*d56f51eaSDavid van Moolenbroek   }
582*d56f51eaSDavid van Moolenbroek 
583*d56f51eaSDavid van Moolenbroek   close (ndisFd);
584*d56f51eaSDavid van Moolenbroek   protManEntry = (ProtMan) reqBlock.pointer1;
585*d56f51eaSDavid van Moolenbroek   protManDS    = reqBlock.word1;
586*d56f51eaSDavid van Moolenbroek 
587*d56f51eaSDavid van Moolenbroek   DEBUG2 ("Entry Point = %04X:%04X\n", FP_SEG(protManEntry),FP_OFF(protManEntry));
588*d56f51eaSDavid van Moolenbroek   DEBUG1 ("ProtMan DS  = %04X\n", protManDS);
589*d56f51eaSDavid van Moolenbroek   return (1);
590*d56f51eaSDavid van Moolenbroek }
591*d56f51eaSDavid van Moolenbroek 
592*d56f51eaSDavid van Moolenbroek 
NdisRegisterAndBind(int promis)593*d56f51eaSDavid van Moolenbroek int NdisRegisterAndBind (int promis)
594*d56f51eaSDavid van Moolenbroek {
595*d56f51eaSDavid van Moolenbroek   struct _ReqBlock reqBlock;
596*d56f51eaSDavid van Moolenbroek   WORD    result;
597*d56f51eaSDavid van Moolenbroek 
598*d56f51eaSDavid van Moolenbroek   memset (&common,0,sizeof(common));
599*d56f51eaSDavid van Moolenbroek 
600*d56f51eaSDavid van Moolenbroek   common.tableSize = sizeof (common);
601*d56f51eaSDavid van Moolenbroek 
602*d56f51eaSDavid van Moolenbroek   common.majorNdisVersion   = 2;
603*d56f51eaSDavid van Moolenbroek   common.minorNdisVersion   = 0;
604*d56f51eaSDavid van Moolenbroek   common.majorModuleVersion = 2;
605*d56f51eaSDavid van Moolenbroek   common.minorModuleVersion = 0;
606*d56f51eaSDavid van Moolenbroek 
607*d56f51eaSDavid van Moolenbroek   /* Indicates binding from below and dynamically loaded
608*d56f51eaSDavid van Moolenbroek    */
609*d56f51eaSDavid van Moolenbroek   common.moduleFlags = 0x00000006L;
610*d56f51eaSDavid van Moolenbroek 
611*d56f51eaSDavid van Moolenbroek   strcpy (common.moduleName, "PCAP");
612*d56f51eaSDavid van Moolenbroek 
613*d56f51eaSDavid van Moolenbroek   common.protocolLevelUpper = 0xFF;
614*d56f51eaSDavid van Moolenbroek   common.protocolLevelLower = 1;
615*d56f51eaSDavid van Moolenbroek   common.interfaceLower     = 1;
616*d56f51eaSDavid van Moolenbroek #ifdef __DJGPP__
617*d56f51eaSDavid van Moolenbroek   common.moduleDS           = _dos_ds; /* the callback data segment */
618*d56f51eaSDavid van Moolenbroek #else
619*d56f51eaSDavid van Moolenbroek   common.moduleDS           = _DS;
620*d56f51eaSDavid van Moolenbroek #endif
621*d56f51eaSDavid van Moolenbroek 
622*d56f51eaSDavid van Moolenbroek   common.systemRequest      = (SystemRequest) systemRequestGlue;
623*d56f51eaSDavid van Moolenbroek   common.serviceChars       = (BYTE*) &protChars;
624*d56f51eaSDavid van Moolenbroek   common.serviceStatus      = NULL;
625*d56f51eaSDavid van Moolenbroek   common.upperDispatchTable = NULL;
626*d56f51eaSDavid van Moolenbroek   common.lowerDispatchTable = (BYTE*) &lowerTable;
627*d56f51eaSDavid van Moolenbroek 
628*d56f51eaSDavid van Moolenbroek   protChars.length  = sizeof (protChars);
629*d56f51eaSDavid van Moolenbroek   protChars.name[0] = 0;
630*d56f51eaSDavid van Moolenbroek   protChars.type    = 0;
631*d56f51eaSDavid van Moolenbroek 
632*d56f51eaSDavid van Moolenbroek   lowerTable.backPointer        = &common;
633*d56f51eaSDavid van Moolenbroek   lowerTable.requestConfirm     = requestConfirmGlue;
634*d56f51eaSDavid van Moolenbroek   lowerTable.transmitConfirm    = transmitConfirmGlue;
635*d56f51eaSDavid van Moolenbroek   lowerTable.receiveLookahead   = receiveLookaheadGlue;
636*d56f51eaSDavid van Moolenbroek   lowerTable.indicationComplete = indicationCompleteGlue;
637*d56f51eaSDavid van Moolenbroek   lowerTable.receiveChain       = receiveChainGlue;
638*d56f51eaSDavid van Moolenbroek   lowerTable.status             = statusGlue;
639*d56f51eaSDavid van Moolenbroek   lowerTable.flags              = 3;
640*d56f51eaSDavid van Moolenbroek   if (promis)
641*d56f51eaSDavid van Moolenbroek      lowerTable.flags |= 4;   /* promiscous mode (receive everything) */
642*d56f51eaSDavid van Moolenbroek 
643*d56f51eaSDavid van Moolenbroek   bindings.numBindings = 1;
644*d56f51eaSDavid van Moolenbroek   strcpy (bindings.moduleName[0], handle->moduleName);
645*d56f51eaSDavid van Moolenbroek 
646*d56f51eaSDavid van Moolenbroek   /* Register ourselves with NDIS
647*d56f51eaSDavid van Moolenbroek    */
648*d56f51eaSDavid van Moolenbroek   reqBlock.opcode   = PM_REGISTER_MODULE;
649*d56f51eaSDavid van Moolenbroek   reqBlock.pointer1 = (BYTE FAR*) &common;
650*d56f51eaSDavid van Moolenbroek   reqBlock.pointer2 = (BYTE FAR*) &bindings;
651*d56f51eaSDavid van Moolenbroek 
652*d56f51eaSDavid van Moolenbroek   result = (*protManEntry) (&reqBlock, protManDS);
653*d56f51eaSDavid van Moolenbroek   if (result)
654*d56f51eaSDavid van Moolenbroek   {
655*d56f51eaSDavid van Moolenbroek     printf ("Protman registering failed: %s\n", Ndis_strerror(result));
656*d56f51eaSDavid van Moolenbroek     return (0);
657*d56f51eaSDavid van Moolenbroek   }
658*d56f51eaSDavid van Moolenbroek 
659*d56f51eaSDavid van Moolenbroek   /* Start the binding process
660*d56f51eaSDavid van Moolenbroek    */
661*d56f51eaSDavid van Moolenbroek   reqBlock.opcode   = PM_BIND_AND_START;
662*d56f51eaSDavid van Moolenbroek   reqBlock.pointer1 = (BYTE FAR*) &failingModules;
663*d56f51eaSDavid van Moolenbroek 
664*d56f51eaSDavid van Moolenbroek   result = (*protManEntry) (&reqBlock, protManDS);
665*d56f51eaSDavid van Moolenbroek   if (result)
666*d56f51eaSDavid van Moolenbroek   {
667*d56f51eaSDavid van Moolenbroek     printf ("Start binding failed: %s\n", Ndis_strerror(result));
668*d56f51eaSDavid van Moolenbroek     return (0);
669*d56f51eaSDavid van Moolenbroek   }
670*d56f51eaSDavid van Moolenbroek   return (1);
671*d56f51eaSDavid van Moolenbroek }
672*d56f51eaSDavid van Moolenbroek 
CheckMacFeatures(CardHandle * card)673*d56f51eaSDavid van Moolenbroek static int CheckMacFeatures (CardHandle *card)
674*d56f51eaSDavid van Moolenbroek {
675*d56f51eaSDavid van Moolenbroek   DWORD      serviceFlags;
676*d56f51eaSDavid van Moolenbroek   BYTE _far *mediaString;
677*d56f51eaSDavid van Moolenbroek   BYTE _far *mac_addr;
678*d56f51eaSDavid van Moolenbroek 
679*d56f51eaSDavid van Moolenbroek   DEBUG2 ("checking card features\n"
680*d56f51eaSDavid van Moolenbroek           "common table address = %08lX, macId = %d\n",
681*d56f51eaSDavid van Moolenbroek           card->common, card->common->moduleId);
682*d56f51eaSDavid van Moolenbroek 
683*d56f51eaSDavid van Moolenbroek   serviceFlags = MAC_CHAR (handle)->serviceFlags;
684*d56f51eaSDavid van Moolenbroek 
685*d56f51eaSDavid van Moolenbroek   if ((serviceFlags & SF_PROMISCUOUS) == 0)
686*d56f51eaSDavid van Moolenbroek   {
687*d56f51eaSDavid van Moolenbroek     printf ("The MAC %s does not support promiscuous mode.\n",
688*d56f51eaSDavid van Moolenbroek             card->moduleName);
689*d56f51eaSDavid van Moolenbroek     return (0);
690*d56f51eaSDavid van Moolenbroek   }
691*d56f51eaSDavid van Moolenbroek 
692*d56f51eaSDavid van Moolenbroek   mediaString = MAC_CHAR (handle)->macName;
693*d56f51eaSDavid van Moolenbroek 
694*d56f51eaSDavid van Moolenbroek   DEBUG1 ("media type = %s\n",mediaString);
695*d56f51eaSDavid van Moolenbroek 
696*d56f51eaSDavid van Moolenbroek   /* Get the media type. And set the header size
697*d56f51eaSDavid van Moolenbroek    */
698*d56f51eaSDavid van Moolenbroek   if (!strncmp(mediaString,"802.3",5) ||
699*d56f51eaSDavid van Moolenbroek       !strncmp(mediaString,"DIX",3)   ||
700*d56f51eaSDavid van Moolenbroek       !strncmp(mediaString,"DIX+802.3",9))
701*d56f51eaSDavid van Moolenbroek        headerSize = sizeof (EthernetIIHeader);
702*d56f51eaSDavid van Moolenbroek 
703*d56f51eaSDavid van Moolenbroek   else if (!strncmp(mediaString,"FDDI",4))
704*d56f51eaSDavid van Moolenbroek        headerSize = sizeof (FddiHeader) +
705*d56f51eaSDavid van Moolenbroek                     sizeof (Ieee802Dot2SnapHeader);
706*d56f51eaSDavid van Moolenbroek   else
707*d56f51eaSDavid van Moolenbroek   {
708*d56f51eaSDavid van Moolenbroek     printf ("Unsupported MAC type: `%s'\n", mediaString);
709*d56f51eaSDavid van Moolenbroek     return (0);
710*d56f51eaSDavid van Moolenbroek   }
711*d56f51eaSDavid van Moolenbroek 
712*d56f51eaSDavid van Moolenbroek   frameSize = MAC_CHAR (handle)->maxFrameSize;
713*d56f51eaSDavid van Moolenbroek   mac_addr  = MAC_CHAR (handle)->currentAddress;
714*d56f51eaSDavid van Moolenbroek 
715*d56f51eaSDavid van Moolenbroek   printf ("Hardware address: %02X:%02X:%02X:%02X:%02X:%02X\n",
716*d56f51eaSDavid van Moolenbroek           mac_addr[0], mac_addr[1], mac_addr[2],
717*d56f51eaSDavid van Moolenbroek           mac_addr[3], mac_addr[4], mac_addr[5]);
718*d56f51eaSDavid van Moolenbroek   return (1);
719*d56f51eaSDavid van Moolenbroek }
720*d56f51eaSDavid van Moolenbroek 
NdisStartMac(CardHandle * card)721*d56f51eaSDavid van Moolenbroek static int NdisStartMac (CardHandle *card)
722*d56f51eaSDavid van Moolenbroek {
723*d56f51eaSDavid van Moolenbroek   WORD result;
724*d56f51eaSDavid van Moolenbroek 
725*d56f51eaSDavid van Moolenbroek   /* Set the lookahead length
726*d56f51eaSDavid van Moolenbroek    */
727*d56f51eaSDavid van Moolenbroek   result = MAC_DISPATCH(handle)->request (common.moduleId, 0,
728*d56f51eaSDavid van Moolenbroek                                           headerSize, 0,
729*d56f51eaSDavid van Moolenbroek                                           REQ_SET_LOOKAHEAD,
730*d56f51eaSDavid van Moolenbroek                                           card->common->moduleDS);
731*d56f51eaSDavid van Moolenbroek 
732*d56f51eaSDavid van Moolenbroek   /* We assume that if we got INVALID PARAMETER then either this
733*d56f51eaSDavid van Moolenbroek    * is not supported or will work anyway. NE2000 does this.
734*d56f51eaSDavid van Moolenbroek    */
735*d56f51eaSDavid van Moolenbroek   if (result != ERR_SUCCESS && result != ERR_INVALID_PARAMETER)
736*d56f51eaSDavid van Moolenbroek   {
737*d56f51eaSDavid van Moolenbroek     DEBUG1 ("Set lookahead failed: %s\n", Ndis_strerror(result));
738*d56f51eaSDavid van Moolenbroek     return (0);
739*d56f51eaSDavid van Moolenbroek   }
740*d56f51eaSDavid van Moolenbroek 
741*d56f51eaSDavid van Moolenbroek   /* Set the packet filter. Note that for some medias and drivers we
742*d56f51eaSDavid van Moolenbroek    * must specify all three flags or the card(s) will not operate correctly.
743*d56f51eaSDavid van Moolenbroek    */
744*d56f51eaSDavid van Moolenbroek   result = MAC_DISPATCH(handle)->request (common.moduleId, 0,
745*d56f51eaSDavid van Moolenbroek                       /* all packets */   FILTER_PROMISCUOUS |
746*d56f51eaSDavid van Moolenbroek                       /* packets to us */ FILTER_DIRECTED    |
747*d56f51eaSDavid van Moolenbroek                       /* broadcasts */    FILTER_BROADCAST,
748*d56f51eaSDavid van Moolenbroek                                           0, REQ_SET_PACKET_FILTER,
749*d56f51eaSDavid van Moolenbroek                                           card->common->moduleDS);
750*d56f51eaSDavid van Moolenbroek   if (result != ERR_SUCCESS)
751*d56f51eaSDavid van Moolenbroek   {
752*d56f51eaSDavid van Moolenbroek     DEBUG1 ("Set packet filter failed: %s\n", Ndis_strerror(result));
753*d56f51eaSDavid van Moolenbroek     return (0);
754*d56f51eaSDavid van Moolenbroek   }
755*d56f51eaSDavid van Moolenbroek 
756*d56f51eaSDavid van Moolenbroek   /* If OPEN/CLOSE supported then open the adapter
757*d56f51eaSDavid van Moolenbroek    */
758*d56f51eaSDavid van Moolenbroek   if (MAC_CHAR(handle)->serviceFlags & SF_OPEN_CLOSE)
759*d56f51eaSDavid van Moolenbroek   {
760*d56f51eaSDavid van Moolenbroek     result = MAC_DISPATCH(handle)->request (common.moduleId, 0, 0, NULL,
761*d56f51eaSDavid van Moolenbroek                                             REQ_OPEN_ADAPTER,
762*d56f51eaSDavid van Moolenbroek                                             card->common->moduleDS);
763*d56f51eaSDavid van Moolenbroek     if (result != ERR_SUCCESS)
764*d56f51eaSDavid van Moolenbroek     {
765*d56f51eaSDavid van Moolenbroek       DEBUG1 ("Opening the MAC failed: %s\n", Ndis_strerror(result));
766*d56f51eaSDavid van Moolenbroek       return (0);
767*d56f51eaSDavid van Moolenbroek     }
768*d56f51eaSDavid van Moolenbroek   }
769*d56f51eaSDavid van Moolenbroek   return (1);
770*d56f51eaSDavid van Moolenbroek }
771*d56f51eaSDavid van Moolenbroek 
NdisShutdown(void)772*d56f51eaSDavid van Moolenbroek void NdisShutdown (void)
773*d56f51eaSDavid van Moolenbroek {
774*d56f51eaSDavid van Moolenbroek   struct _ReqBlock reqBlock;
775*d56f51eaSDavid van Moolenbroek   int     result, i;
776*d56f51eaSDavid van Moolenbroek 
777*d56f51eaSDavid van Moolenbroek   if (!handle)
778*d56f51eaSDavid van Moolenbroek      return;
779*d56f51eaSDavid van Moolenbroek 
780*d56f51eaSDavid van Moolenbroek   /* If the adapters support open and are open then close them
781*d56f51eaSDavid van Moolenbroek    */
782*d56f51eaSDavid van Moolenbroek   if ((MAC_CHAR(handle)->serviceFlags & SF_OPEN_CLOSE) &&
783*d56f51eaSDavid van Moolenbroek       (MAC_STATUS(handle)->macStatus & MAC_OPEN))
784*d56f51eaSDavid van Moolenbroek   {
785*d56f51eaSDavid van Moolenbroek     result = MAC_DISPATCH(handle)->request (common.moduleId, 0, 0, 0,
786*d56f51eaSDavid van Moolenbroek                                             REQ_CLOSE_ADAPTER,
787*d56f51eaSDavid van Moolenbroek                                             handle->common->moduleDS);
788*d56f51eaSDavid van Moolenbroek     if (result != ERR_SUCCESS)
789*d56f51eaSDavid van Moolenbroek     {
790*d56f51eaSDavid van Moolenbroek       printf ("Closing the MAC failed: %s\n", Ndis_strerror(result));
791*d56f51eaSDavid van Moolenbroek       return;
792*d56f51eaSDavid van Moolenbroek     }
793*d56f51eaSDavid van Moolenbroek   }
794*d56f51eaSDavid van Moolenbroek 
795*d56f51eaSDavid van Moolenbroek   /* Tell the Protocol Manager to unbind and stop
796*d56f51eaSDavid van Moolenbroek    */
797*d56f51eaSDavid van Moolenbroek   reqBlock.opcode   = PM_UNBIND_AND_STOP;
798*d56f51eaSDavid van Moolenbroek   reqBlock.pointer1 = (BYTE FAR*) &failingModules;
799*d56f51eaSDavid van Moolenbroek   reqBlock.pointer2 = NULL;
800*d56f51eaSDavid van Moolenbroek 
801*d56f51eaSDavid van Moolenbroek   result = (*protManEntry) (&reqBlock, protManDS);
802*d56f51eaSDavid van Moolenbroek   if (result)
803*d56f51eaSDavid van Moolenbroek      printf ("Unbind failed: %s\n",  Ndis_strerror(result));
804*d56f51eaSDavid van Moolenbroek 
805*d56f51eaSDavid van Moolenbroek   for (i = 0; i < STACK_POOL_SIZE; ++i)
806*d56f51eaSDavid van Moolenbroek      free (freeStacks[i] - STACK_SIZE);
807*d56f51eaSDavid van Moolenbroek 
808*d56f51eaSDavid van Moolenbroek   handle = NULL;
809*d56f51eaSDavid van Moolenbroek }
810*d56f51eaSDavid van Moolenbroek 
NdisInit(int promis)811*d56f51eaSDavid van Moolenbroek int NdisInit (int promis)
812*d56f51eaSDavid van Moolenbroek {
813*d56f51eaSDavid van Moolenbroek   int i, result;
814*d56f51eaSDavid van Moolenbroek 
815*d56f51eaSDavid van Moolenbroek   /* Allocate the real mode stacks used for NDIS callbacks
816*d56f51eaSDavid van Moolenbroek    */
817*d56f51eaSDavid van Moolenbroek   for (i = 0; i < STACK_POOL_SIZE; ++i)
818*d56f51eaSDavid van Moolenbroek   {
819*d56f51eaSDavid van Moolenbroek     freeStacks[i] = malloc (STACK_SIZE);
820*d56f51eaSDavid van Moolenbroek     if (!freeStacks[i])
821*d56f51eaSDavid van Moolenbroek        return (0);
822*d56f51eaSDavid van Moolenbroek     freeStacks[i] += STACK_SIZE;
823*d56f51eaSDavid van Moolenbroek   }
824*d56f51eaSDavid van Moolenbroek 
825*d56f51eaSDavid van Moolenbroek   if (!NdisOpen())
826*d56f51eaSDavid van Moolenbroek      return (0);
827*d56f51eaSDavid van Moolenbroek 
828*d56f51eaSDavid van Moolenbroek   if (!NdisRegisterAndBind(promis))
829*d56f51eaSDavid van Moolenbroek      return (0);
830*d56f51eaSDavid van Moolenbroek 
831*d56f51eaSDavid van Moolenbroek   DEBUG1 ("My module id: %d\n", common.moduleId);
832*d56f51eaSDavid van Moolenbroek   DEBUG1 ("Handle id;    %d\n", handle->common->moduleId);
833*d56f51eaSDavid van Moolenbroek   DEBUG1 ("MAC card:     %-16s - ", handle->moduleName);
834*d56f51eaSDavid van Moolenbroek 
835*d56f51eaSDavid van Moolenbroek   atexit (NdisShutdown);
836*d56f51eaSDavid van Moolenbroek 
837*d56f51eaSDavid van Moolenbroek   if (!CheckMacFeatures(&handle))
838*d56f51eaSDavid van Moolenbroek      return (0);
839*d56f51eaSDavid van Moolenbroek 
840*d56f51eaSDavid van Moolenbroek   switch (mediaType)
841*d56f51eaSDavid van Moolenbroek   {
842*d56f51eaSDavid van Moolenbroek     case MEDIA_FDDI:
843*d56f51eaSDavid van Moolenbroek          DEBUG0 ("Media type: FDDI");
844*d56f51eaSDavid van Moolenbroek 	 break;
845*d56f51eaSDavid van Moolenbroek     case MEDIA_ETHERNET:
846*d56f51eaSDavid van Moolenbroek          DEBUG0 ("Media type: ETHERNET");
847*d56f51eaSDavid van Moolenbroek 	 break;
848*d56f51eaSDavid van Moolenbroek     default:
849*d56f51eaSDavid van Moolenbroek          DEBUG0 ("Unsupported media.\n");
850*d56f51eaSDavid van Moolenbroek          return (0);
851*d56f51eaSDavid van Moolenbroek   }
852*d56f51eaSDavid van Moolenbroek 
853*d56f51eaSDavid van Moolenbroek   DEBUG1 (" - Frame size: %d\n", frameSize);
854*d56f51eaSDavid van Moolenbroek 
855*d56f51eaSDavid van Moolenbroek   if (!NdisStartMac(&handle))
856*d56f51eaSDavid van Moolenbroek      return (0);
857*d56f51eaSDavid van Moolenbroek   return (1);
858*d56f51eaSDavid van Moolenbroek }
859*d56f51eaSDavid van Moolenbroek #endif  /* USE_NDIS2 */
860*d56f51eaSDavid van Moolenbroek 
861