blob: 0a5ea2a7b89e5a0fc9172d81e0d6a86325651ac6 [file] [log] [blame]
/*
* Copyright (c) 1993,1994
* Texas A&M University. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Texas A&M University
* and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Developers:
* David K. Hess, Douglas Lee Schales, David R. Safford
*
* Heavily modified for Metaware HighC + GNU C 2.8+
* Gisle Vanem 1998
*/
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <io.h>
#include <fcntl.h>
#include <malloc.h>
#include <string.h>
#include "pcap-dos.h"
#include "pcap-int.h"
#include "msdos/ndis2.h"
#if defined(USE_NDIS2)
/*
* Packet buffer handling
*/
extern int FreePktBuf (PktBuf *buf);
extern int EnquePktBuf (PktBuf *buf);
extern PktBuf* AllocPktBuf (void);
/*
* Various defines
*/
#define MAX_NUM_DEBUG_STRINGS 90
#define DEBUG_STRING_LENGTH 80
#define STACK_POOL_SIZE 6
#define STACK_SIZE 256
#define MEDIA_FDDI 1
#define MEDIA_ETHERNET 2
#define MEDIA_TOKEN 3
static int startDebug = 0;
static int stopDebug = 0;
static DWORD droppedPackets = 0L;
static WORD frameSize = 0;
static WORD headerSize = 0;
static int mediaType = 0;
static char *lastErr = NULL;
static BYTE debugStrings [MAX_NUM_DEBUG_STRINGS][DEBUG_STRING_LENGTH];
static BYTE *freeStacks [STACK_POOL_SIZE];
static int freeStackPtr = STACK_POOL_SIZE - 1;
static ProtMan protManEntry = NULL;
static WORD protManDS = 0;
static volatile int xmitPending;
static struct _PktBuf *txBufPending;
static struct _CardHandle *handle;
static struct _CommonChars common;
static struct _ProtocolChars protChars;
static struct _ProtDispatch lowerTable;
static struct _FailingModules failingModules;
static struct _BindingsList bindings;
static struct {
WORD err_num;
char *err_text;
} ndis_errlist[] = {
{ ERR_SUCCESS,
"The function completed successfully.\n" },
{ ERR_WAIT_FOR_RELEASE,
"The ReceiveChain completed successfully but the protocol has\n"
"retained control of the buffer.\n" },
{ ERR_REQUEST_QUEUED,
"The current request has been queued.\n" },
{ ERR_FRAME_NOT_RECOGNIZED,
"Frame not recognized.\n" },
{ ERR_FRAME_REJECTED,
"Frame was discarded.\n" },
{ ERR_FORWARD_FRAME,
"Protocol wishes to forward frame to another protocol.\n" },
{ ERR_OUT_OF_RESOURCE,
"Out of resource.\n" },
{ ERR_INVALID_PARAMETER,
"Invalid parameter.\n" },
{ ERR_INVALID_FUNCTION,
"Invalid function.\n" },
{ ERR_NOT_SUPPORTED,
"Not supported.\n" },
{ ERR_HARDWARE_ERROR,
"Hardware error.\n" },
{ ERR_TRANSMIT_ERROR,
"The packet was not transmitted due to an error.\n" },
{ ERR_NO_SUCH_DESTINATION,
"Token ring packet was not recognized when transmitted.\n" },
{ ERR_BUFFER_TOO_SMALL,
"Provided buffer was too small.\n" },
{ ERR_ALREADY_STARTED,
"Network drivers already started.\n" },
{ ERR_INCOMPLETE_BINDING,
"Protocol driver could not complete its bindings.\n" },
{ ERR_DRIVER_NOT_INITIALIZED,
"MAC did not initialize properly.\n" },
{ ERR_HARDWARE_NOT_FOUND,
"Hardware not found.\n" },
{ ERR_HARDWARE_FAILURE,
"Hardware failure.\n" },
{ ERR_CONFIGURATION_FAILURE,
"Configuration failure.\n" },
{ ERR_INTERRUPT_CONFLICT,
"Interrupt conflict.\n" },
{ ERR_INCOMPATIBLE_MAC,
"The MAC is not compatible with the protocol.\n" },
{ ERR_INITIALIZATION_FAILED,
"Initialization failed.\n" },
{ ERR_NO_BINDING,
"Binding did not occur.\n" },
{ ERR_NETWORK_MAY_NOT_BE_CONNECTED,
"The network may not be connected to the adapter.\n" },
{ ERR_INCOMPATIBLE_OS_VERSION,
"The version of the operating system is incompatible with the protocol.\n" },
{ ERR_ALREADY_REGISTERED,
"The protocol is already registered.\n" },
{ ERR_PATH_NOT_FOUND,
"PROTMAN.EXE could not be found.\n" },
{ ERR_INSUFFICIENT_MEMORY,
"Insufficient memory.\n" },
{ ERR_INFO_NOT_FOUND,
"Protocol Mananger info structure is lost or corrupted.\n" },
{ ERR_GENERAL_FAILURE,
"General failure.\n" }
};
/*
* Some handy macros
*/
#define PERROR(str) printf("%s (%d): %s\n", __FILE__,__LINE__,str)
#define DEBUG_RING() (debugStrings[stopDebug+1 == MAX_NUM_DEBUG_STRINGS ? \
stopDebug = 0 : ++stopDebug])
/*
* needs rewrite for DOSX
*/
#define MAC_DISPATCH(hnd) ((struct _MacUpperDispatch*)(hnd)->common->upperDispatchTable)
#define MAC_STATUS(hnd) ((struct _MacStatusTable*) (hnd)->common->serviceStatus)
#define MAC_CHAR(hnd) ((struct _MacChars*) (hnd)->common->serviceChars)
#ifdef NDIS_DEBUG
#define DEBUG0(str) printf (str)
#define DEBUG1(fmt,a) printf (fmt,a)
#define DEBUG2(fmt,a,b) printf (fmt,a,b)
#define TRACE0(str) sprintf (DEBUG_RING(),str)
#define TRACE1(fmt,a) sprintf (DEBUG_RING(),fmt,a)
#else
#define DEBUG0(str) ((void)0)
#define DEBUG1(fmt,a) ((void)0)
#define DEBUG2(fmt,a,b) ((void)0)
#define TRACE0(str) ((void)0)
#define TRACE1(fmt,a) ((void)0)
#endif
/*
* This routine is called from both threads
*/
void NdisFreeStack (BYTE *aStack)
{
GUARD();
if (freeStackPtr == STACK_POOL_SIZE - 1)
PERROR ("tried to free too many stacks");
freeStacks[++freeStackPtr] = aStack;
if (freeStackPtr == 0)
TRACE0 ("freeStackPtr went positive\n");
UNGUARD();
}
/*
* This routine is called from callbacks to allocate local data
*/
BYTE *NdisAllocStack (void)
{
BYTE *stack;
GUARD();
if (freeStackPtr < 0)
{
/* Ran out of stack buffers. Return NULL which will start
* dropping packets
*/
TRACE0 ("freeStackPtr went negative\n");
stack = 0;
}
else
stack = freeStacks[freeStackPtr--];
UNGUARD();
return (stack);
}
CALLBACK (NdisSystemRequest (DWORD param1, DWORD param2, WORD param3,
WORD opcode, WORD targetDS))
{
static int bindEntry = 0;
struct _CommonChars *macCommon;
volatile WORD result;
switch (opcode)
{
case REQ_INITIATE_BIND:
macCommon = (struct _CommonChars*) param2;
if (macCommon == NULL)
{
printf ("There is an NDIS misconfiguration.\n");
result = ERR_GENERAL_FAILURE;
break;
}
DEBUG2 ("module name %s\n"
"module type %s\n",
macCommon->moduleName,
((MacChars*) macCommon->serviceChars)->macName);
/* Binding to the MAC */
result = macCommon->systemRequest ((DWORD)&common, (DWORD)&macCommon,
0, REQ_BIND,
macCommon->moduleDS);
if (!strcmp(bindings.moduleName[bindEntry], handle->moduleName))
handle->common = macCommon;
else PERROR ("unknown module");
++bindEntry;
break;
case REQ_INITIATE_UNBIND:
macCommon = (struct _CommonChars*) param2;
result = macCommon->systemRequest ((DWORD)&common, 0,
0, REQ_UNBIND,
macCommon->moduleDS);
break;
default:
result = ERR_GENERAL_FAILURE;
break;
}
ARGSUSED (param1);
ARGSUSED (param3);
ARGSUSED (targetDS);
return (result);
}
CALLBACK (NdisRequestConfirm (WORD protId, WORD macId, WORD reqHandle,
WORD status, WORD request, WORD protDS))
{
ARGSUSED (protId); ARGSUSED (macId);
ARGSUSED (reqHandle); ARGSUSED (status);
ARGSUSED (request); ARGSUSED (protDS);
return (ERR_SUCCESS);
}
CALLBACK (NdisTransmitConfirm (WORD protId, WORD macId, WORD reqHandle,
WORD status, WORD protDS))
{
xmitPending--;
FreePktBuf (txBufPending); /* Add passed ECB back to the free list */
ARGSUSED (reqHandle);
ARGSUSED (status);
ARGSUSED (protDS);
return (ERR_SUCCESS);
}
/*
* The primary function for receiving packets
*/
CALLBACK (NdisReceiveLookahead (WORD macId, WORD frameSize,
WORD bytesAvail, BYTE *buffer,
BYTE *indicate, WORD protDS))
{
int result;
PktBuf *pktBuf;
WORD bytesCopied;
struct _TDBufDescr tDBufDescr;
#if 0
TRACE1 ("lookahead length = %d, ", bytesAvail);
TRACE1 ("ecb = %08lX, ", *ecb);
TRACE1 ("count = %08lX\n", count);
TRACE1 ("offset = %08lX, ", offset);
TRACE1 ("timesAllowed = %d, ", timesAllowed);
TRACE1 ("packet size = %d\n", look->dataLookAheadLen);
#endif
/* Allocate a buffer for the packet
*/
if ((pktBuf = AllocPktBuf()) == NULL)
{
droppedPackets++;
return (ERR_FRAME_REJECTED);
}
/*
* Now kludge things. Note we will have to undo this later. This will
* make the packet contiguous after the MLID has done the requested copy.
*/
tDBufDescr.tDDataCount = 1;
tDBufDescr.tDBufDescrRec[0].tDPtrType = NDIS_PTR_PHYSICAL;
tDBufDescr.tDBufDescrRec[0].tDDataPtr = pktBuf->buffer;
tDBufDescr.tDBufDescrRec[0].tDDataLen = pktBuf->length;
tDBufDescr.tDBufDescrRec[0].dummy = 0;
result = MAC_DISPATCH(handle)->transferData (&bytesCopied, 0, &tDBufDescr,
handle->common->moduleDS);
pktBuf->packetLength = bytesCopied;
if (result == ERR_SUCCESS)
EnquePktBuf(pktBuf);
else FreePktBuf (pktBuf);
ARGSUSED (frameSize);
ARGSUSED (bytesAvail);
ARGSUSED (indicate);
ARGSUSED (protDS);
return (ERR_SUCCESS);
}
CALLBACK (NdisIndicationComplete (WORD macId, WORD protDS))
{
ARGSUSED (macId);
ARGSUSED (protDS);
/* We don't give a hoot about these. Just return
*/
return (ERR_SUCCESS);
}
/*
* This is the OTHER way we may receive packets
*/
CALLBACK (NdisReceiveChain (WORD macId, WORD frameSize, WORD reqHandle,
struct _RxBufDescr *rxBufDescr,
BYTE *indicate, WORD protDS))
{
struct _PktBuf *pktBuf;
int i;
/*
* For now we copy the entire packet over to a PktBuf structure. This may be
* a performance hit but this routine probably isn't called very much, and
* it is a lot of work to do it otherwise. Also if it is a filter protocol
* packet we could end up sucking up MAC buffes.
*/
if ((pktBuf = AllocPktBuf()) == NULL)
{
droppedPackets++;
return (ERR_FRAME_REJECTED);
}
pktBuf->packetLength = 0;
/* Copy the packet to the buffer
*/
for (i = 0; i < rxBufDescr->rxDataCount; ++i)
{
struct _RxBufDescrRec *rxDescr = &rxBufDescr->rxBufDescrRec[i];
memcpy (pktBuf->buffer + pktBuf->packetLength,
rxDescr->rxDataPtr, rxDescr->rxDataLen);
pktBuf->packetLength += rxDescr->rxDataLen;
}
EnquePktBuf (pktBuf);
ARGSUSED (frameSize);
ARGSUSED (reqHandle);
ARGSUSED (indicate);
ARGSUSED (protDS);
/* This frees up the buffer for the MAC to use
*/
return (ERR_SUCCESS);
}
CALLBACK (NdisStatusProc (WORD macId, WORD param1, BYTE *indicate,
WORD opcode, WORD protDS))
{
switch (opcode)
{
case STATUS_RING_STATUS:
break;
case STATUS_ADAPTER_CHECK:
break;
case STATUS_START_RESET:
break;
case STATUS_INTERRUPT:
break;
case STATUS_END_RESET:
break;
default:
break;
}
ARGSUSED (macId);
ARGSUSED (param1);
ARGSUSED (indicate);
ARGSUSED (opcode);
ARGSUSED (protDS);
/* We don't need to do anything about this stuff yet
*/
return (ERR_SUCCESS);
}
/*
* Tell the NDIS driver to start the delivery of the packet
*/
int NdisSendPacket (struct _PktBuf *pktBuf, int macId)
{
struct _TxBufDescr txBufDescr;
int result;
xmitPending++;
txBufPending = pktBuf; /* we only have 1 pending Tx at a time */
txBufDescr.txImmedLen = 0;
txBufDescr.txImmedPtr = NULL;
txBufDescr.txDataCount = 1;
txBufDescr.txBufDescrRec[0].txPtrType = NDIS_PTR_PHYSICAL;
txBufDescr.txBufDescrRec[0].dummy = 0;
txBufDescr.txBufDescrRec[0].txDataLen = pktBuf->packetLength;
txBufDescr.txBufDescrRec[0].txDataPtr = pktBuf->buffer;
result = MAC_DISPATCH(handle)->transmitChain (common.moduleId,
pktBuf->handle,
&txBufDescr,
handle->common->moduleDS);
switch (result)
{
case ERR_OUT_OF_RESOURCE:
/* Note that this should not happen but if it does there is not
* much we can do about it
*/
printf ("ERROR: transmit queue overflowed\n");
return (0);
case ERR_SUCCESS:
/* Everything was hunky dory and synchronous. Free up the
* packet buffer
*/
xmitPending--;
FreePktBuf (pktBuf);
return (1);
case ERR_REQUEST_QUEUED:
/* Everything was hunky dory and asynchronous. Do nothing
*/
return (1);
default:
printf ("Tx fail, code = %04X\n", result);
return (0);
}
}
static int ndis_nerr = sizeof(ndis_errlist) / sizeof(ndis_errlist[0]);
static char *Ndis_strerror (WORD errorCode)
{
static char buf[30];
int i;
for (i = 0; i < ndis_nerr; i++)
if (errorCode == ndis_errlist[i].err_num)
return (ndis_errlist[i].err_text);
sprintf (buf,"unknown error %d",errorCode);
return (buf);
}
char *NdisLastError (void)
{
char *errStr = lastErr;
lastErr = NULL;
return (errStr);
}
int NdisOpen (void)
{
struct _ReqBlock reqBlock;
int result;
int ndisFd = open (NDIS_PATH, O_RDONLY);
if (ndisFd < 0)
{
printf ("Could not open NDIS Protocol Manager device.\n");
return (0);
}
memset (&reqBlock, 0, sizeof(ReqBlock));
reqBlock.opcode = PM_GET_PROTOCOL_MANAGER_LINKAGE;
result = NdisGetLinkage (ndisFd, (char*)&reqBlock, sizeof(ReqBlock));
if (result != 0)
{
printf ("Could not get Protocol Manager linkage.\n");
close (ndisFd);
return (0);
}
close (ndisFd);
protManEntry = (ProtMan) reqBlock.pointer1;
protManDS = reqBlock.word1;
DEBUG2 ("Entry Point = %04X:%04X\n", FP_SEG(protManEntry),FP_OFF(protManEntry));
DEBUG1 ("ProtMan DS = %04X\n", protManDS);
return (1);
}
int NdisRegisterAndBind (int promis)
{
struct _ReqBlock reqBlock;
WORD result;
memset (&common,0,sizeof(common));
common.tableSize = sizeof (common);
common.majorNdisVersion = 2;
common.minorNdisVersion = 0;
common.majorModuleVersion = 2;
common.minorModuleVersion = 0;
/* Indicates binding from below and dynamically loaded
*/
common.moduleFlags = 0x00000006L;
strcpy (common.moduleName, "PCAP");
common.protocolLevelUpper = 0xFF;
common.protocolLevelLower = 1;
common.interfaceLower = 1;
#ifdef __DJGPP__
common.moduleDS = _dos_ds; /* the callback data segment */
#else
common.moduleDS = _DS;
#endif
common.systemRequest = (SystemRequest) systemRequestGlue;
common.serviceChars = (BYTE*) &protChars;
common.serviceStatus = NULL;
common.upperDispatchTable = NULL;
common.lowerDispatchTable = (BYTE*) &lowerTable;
protChars.length = sizeof (protChars);
protChars.name[0] = 0;
protChars.type = 0;
lowerTable.backPointer = &common;
lowerTable.requestConfirm = requestConfirmGlue;
lowerTable.transmitConfirm = transmitConfirmGlue;
lowerTable.receiveLookahead = receiveLookaheadGlue;
lowerTable.indicationComplete = indicationCompleteGlue;
lowerTable.receiveChain = receiveChainGlue;
lowerTable.status = statusGlue;
lowerTable.flags = 3;
if (promis)
lowerTable.flags |= 4; /* promiscous mode (receive everything) */
bindings.numBindings = 1;
strcpy (bindings.moduleName[0], handle->moduleName);
/* Register ourselves with NDIS
*/
reqBlock.opcode = PM_REGISTER_MODULE;
reqBlock.pointer1 = (BYTE FAR*) &common;
reqBlock.pointer2 = (BYTE FAR*) &bindings;
result = (*protManEntry) (&reqBlock, protManDS);
if (result)
{
printf ("Protman registering failed: %s\n", Ndis_strerror(result));
return (0);
}
/* Start the binding process
*/
reqBlock.opcode = PM_BIND_AND_START;
reqBlock.pointer1 = (BYTE FAR*) &failingModules;
result = (*protManEntry) (&reqBlock, protManDS);
if (result)
{
printf ("Start binding failed: %s\n", Ndis_strerror(result));
return (0);
}
return (1);
}
static int CheckMacFeatures (CardHandle *card)
{
DWORD serviceFlags;
BYTE _far *mediaString;
BYTE _far *mac_addr;
DEBUG2 ("checking card features\n"
"common table address = %08lX, macId = %d\n",
card->common, card->common->moduleId);
serviceFlags = MAC_CHAR (handle)->serviceFlags;
if ((serviceFlags & SF_PROMISCUOUS) == 0)
{
printf ("The MAC %s does not support promiscuous mode.\n",
card->moduleName);
return (0);
}
mediaString = MAC_CHAR (handle)->macName;
DEBUG1 ("media type = %s\n",mediaString);
/* Get the media type. And set the header size
*/
if (!strncmp(mediaString,"802.3",5) ||
!strncmp(mediaString,"DIX",3) ||
!strncmp(mediaString,"DIX+802.3",9))
headerSize = sizeof (EthernetIIHeader);
else if (!strncmp(mediaString,"FDDI",4))
headerSize = sizeof (FddiHeader) +
sizeof (Ieee802Dot2SnapHeader);
else
{
printf ("Unsupported MAC type: `%s'\n", mediaString);
return (0);
}
frameSize = MAC_CHAR (handle)->maxFrameSize;
mac_addr = MAC_CHAR (handle)->currentAddress;
printf ("Hardware address: %02X:%02X:%02X:%02X:%02X:%02X\n",
mac_addr[0], mac_addr[1], mac_addr[2],
mac_addr[3], mac_addr[4], mac_addr[5]);
return (1);
}
static int NdisStartMac (CardHandle *card)
{
WORD result;
/* Set the lookahead length
*/
result = MAC_DISPATCH(handle)->request (common.moduleId, 0,
headerSize, 0,
REQ_SET_LOOKAHEAD,
card->common->moduleDS);
/* We assume that if we got INVALID PARAMETER then either this
* is not supported or will work anyway. NE2000 does this.
*/
if (result != ERR_SUCCESS && result != ERR_INVALID_PARAMETER)
{
DEBUG1 ("Set lookahead failed: %s\n", Ndis_strerror(result));
return (0);
}
/* Set the packet filter. Note that for some medias and drivers we
* must specify all three flags or the card(s) will not operate correctly.
*/
result = MAC_DISPATCH(handle)->request (common.moduleId, 0,
/* all packets */ FILTER_PROMISCUOUS |
/* packets to us */ FILTER_DIRECTED |
/* broadcasts */ FILTER_BROADCAST,
0, REQ_SET_PACKET_FILTER,
card->common->moduleDS);
if (result != ERR_SUCCESS)
{
DEBUG1 ("Set packet filter failed: %s\n", Ndis_strerror(result));
return (0);
}
/* If OPEN/CLOSE supported then open the adapter
*/
if (MAC_CHAR(handle)->serviceFlags & SF_OPEN_CLOSE)
{
result = MAC_DISPATCH(handle)->request (common.moduleId, 0, 0, NULL,
REQ_OPEN_ADAPTER,
card->common->moduleDS);
if (result != ERR_SUCCESS)
{
DEBUG1 ("Opening the MAC failed: %s\n", Ndis_strerror(result));
return (0);
}
}
return (1);
}
void NdisShutdown (void)
{
struct _ReqBlock reqBlock;
int result, i;
if (!handle)
return;
/* If the adapters support open and are open then close them
*/
if ((MAC_CHAR(handle)->serviceFlags & SF_OPEN_CLOSE) &&
(MAC_STATUS(handle)->macStatus & MAC_OPEN))
{
result = MAC_DISPATCH(handle)->request (common.moduleId, 0, 0, 0,
REQ_CLOSE_ADAPTER,
handle->common->moduleDS);
if (result != ERR_SUCCESS)
{
printf ("Closing the MAC failed: %s\n", Ndis_strerror(result));
return;
}
}
/* Tell the Protocol Manager to unbind and stop
*/
reqBlock.opcode = PM_UNBIND_AND_STOP;
reqBlock.pointer1 = (BYTE FAR*) &failingModules;
reqBlock.pointer2 = NULL;
result = (*protManEntry) (&reqBlock, protManDS);
if (result)
printf ("Unbind failed: %s\n", Ndis_strerror(result));
for (i = 0; i < STACK_POOL_SIZE; ++i)
free (freeStacks[i] - STACK_SIZE);
handle = NULL;
}
int NdisInit (int promis)
{
int i, result;
/* Allocate the real mode stacks used for NDIS callbacks
*/
for (i = 0; i < STACK_POOL_SIZE; ++i)
{
freeStacks[i] = malloc (STACK_SIZE);
if (!freeStacks[i])
return (0);
freeStacks[i] += STACK_SIZE;
}
if (!NdisOpen())
return (0);
if (!NdisRegisterAndBind(promis))
return (0);
DEBUG1 ("My module id: %d\n", common.moduleId);
DEBUG1 ("Handle id; %d\n", handle->common->moduleId);
DEBUG1 ("MAC card: %-16s - ", handle->moduleName);
atexit (NdisShutdown);
if (!CheckMacFeatures(&handle))
return (0);
switch (mediaType)
{
case MEDIA_FDDI:
DEBUG0 ("Media type: FDDI");
break;
case MEDIA_ETHERNET:
DEBUG0 ("Media type: ETHERNET");
break;
default:
DEBUG0 ("Unsupported media.\n");
return (0);
}
DEBUG1 (" - Frame size: %d\n", frameSize);
if (!NdisStartMac(&handle))
return (0);
return (1);
}
#endif /* USE_NDIS2 */