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