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