1 /* 2 * Copyright (c) 1993,1994 3 * Texas A&M University. All rights reserved. 4 * 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. 20 * 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. 32 * 33 * Developers: 34 * David K. Hess, Douglas Lee Schales, David R. Safford 35 * 36 * Heavily modified for Metaware HighC + GNU C 2.8+ 37 * Gisle Vanem 1998 38 */ 39 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> 47 48 #include "pcap-dos.h" 49 #include "pcap-int.h" 50 #include "msdos/ndis2.h" 51 52 #if defined(USE_NDIS2) 53 54 /* 55 * Packet buffer handling 56 */ 57 extern int FreePktBuf (PktBuf *buf); 58 extern int EnquePktBuf (PktBuf *buf); 59 extern PktBuf* AllocPktBuf (void); 60 61 /* 62 * Various defines 63 */ 64 #define MAX_NUM_DEBUG_STRINGS 90 65 #define DEBUG_STRING_LENGTH 80 66 #define STACK_POOL_SIZE 6 67 #define STACK_SIZE 256 68 69 #define MEDIA_FDDI 1 70 #define MEDIA_ETHERNET 2 71 #define MEDIA_TOKEN 3 72 73 static int startDebug = 0; 74 static int stopDebug = 0; 75 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; 81 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; 85 86 static ProtMan protManEntry = NULL; 87 static WORD protManDS = 0; 88 static volatile int xmitPending; 89 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; 95 96 static struct _FailingModules failingModules; 97 static struct _BindingsList bindings; 98 99 static struct { 100 WORD err_num; 101 char *err_text; 102 } ndis_errlist[] = { 103 104 { ERR_SUCCESS, 105 "The function completed successfully.\n" }, 106 107 { ERR_WAIT_FOR_RELEASE, 108 "The ReceiveChain completed successfully but the protocol has\n" 109 "retained control of the buffer.\n" }, 110 111 { ERR_REQUEST_QUEUED, 112 "The current request has been queued.\n" }, 113 114 { ERR_FRAME_NOT_RECOGNIZED, 115 "Frame not recognized.\n" }, 116 117 { ERR_FRAME_REJECTED, 118 "Frame was discarded.\n" }, 119 120 { ERR_FORWARD_FRAME, 121 "Protocol wishes to forward frame to another protocol.\n" }, 122 123 { ERR_OUT_OF_RESOURCE, 124 "Out of resource.\n" }, 125 126 { ERR_INVALID_PARAMETER, 127 "Invalid parameter.\n" }, 128 129 { ERR_INVALID_FUNCTION, 130 "Invalid function.\n" }, 131 132 { ERR_NOT_SUPPORTED, 133 "Not supported.\n" }, 134 135 { ERR_HARDWARE_ERROR, 136 "Hardware error.\n" }, 137 138 { ERR_TRANSMIT_ERROR, 139 "The packet was not transmitted due to an error.\n" }, 140 141 { ERR_NO_SUCH_DESTINATION, 142 "Token ring packet was not recognized when transmitted.\n" }, 143 144 { ERR_BUFFER_TOO_SMALL, 145 "Provided buffer was too small.\n" }, 146 147 { ERR_ALREADY_STARTED, 148 "Network drivers already started.\n" }, 149 150 { ERR_INCOMPLETE_BINDING, 151 "Protocol driver could not complete its bindings.\n" }, 152 153 { ERR_DRIVER_NOT_INITIALIZED, 154 "MAC did not initialize properly.\n" }, 155 156 { ERR_HARDWARE_NOT_FOUND, 157 "Hardware not found.\n" }, 158 159 { ERR_HARDWARE_FAILURE, 160 "Hardware failure.\n" }, 161 162 { ERR_CONFIGURATION_FAILURE, 163 "Configuration failure.\n" }, 164 165 { ERR_INTERRUPT_CONFLICT, 166 "Interrupt conflict.\n" }, 167 168 { ERR_INCOMPATIBLE_MAC, 169 "The MAC is not compatible with the protocol.\n" }, 170 171 { ERR_INITIALIZATION_FAILED, 172 "Initialization failed.\n" }, 173 174 { ERR_NO_BINDING, 175 "Binding did not occur.\n" }, 176 177 { ERR_NETWORK_MAY_NOT_BE_CONNECTED, 178 "The network may not be connected to the adapter.\n" }, 179 180 { ERR_INCOMPATIBLE_OS_VERSION, 181 "The version of the operating system is incompatible with the protocol.\n" }, 182 183 { ERR_ALREADY_REGISTERED, 184 "The protocol is already registered.\n" }, 185 186 { ERR_PATH_NOT_FOUND, 187 "PROTMAN.EXE could not be found.\n" }, 188 189 { ERR_INSUFFICIENT_MEMORY, 190 "Insufficient memory.\n" }, 191 192 { ERR_INFO_NOT_FOUND, 193 "Protocol Mananger info structure is lost or corrupted.\n" }, 194 195 { ERR_GENERAL_FAILURE, 196 "General failure.\n" } 197 }; 198 199 /* 200 * Some handy macros 201 */ 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]) 205 206 /* 207 * needs rewrite for DOSX 208 */ 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) 212 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 226 227 /* 228 * This routine is called from both threads 229 */ 230 void NdisFreeStack (BYTE *aStack) 231 { 232 GUARD(); 233 234 if (freeStackPtr == STACK_POOL_SIZE - 1) 235 PERROR ("tried to free too many stacks"); 236 237 freeStacks[++freeStackPtr] = aStack; 238 239 if (freeStackPtr == 0) 240 TRACE0 ("freeStackPtr went positive\n"); 241 242 UNGUARD(); 243 } 244 245 /* 246 * This routine is called from callbacks to allocate local data 247 */ 248 BYTE *NdisAllocStack (void) 249 { 250 BYTE *stack; 251 252 GUARD(); 253 254 if (freeStackPtr < 0) 255 { 256 /* Ran out of stack buffers. Return NULL which will start 257 * dropping packets 258 */ 259 TRACE0 ("freeStackPtr went negative\n"); 260 stack = 0; 261 } 262 else 263 stack = freeStacks[freeStackPtr--]; 264 265 UNGUARD(); 266 return (stack); 267 } 268 269 CALLBACK (NdisSystemRequest (DWORD param1, DWORD param2, WORD param3, 270 WORD opcode, WORD targetDS)) 271 { 272 static int bindEntry = 0; 273 struct _CommonChars *macCommon; 274 volatile WORD result; 275 276 switch (opcode) 277 { 278 case REQ_INITIATE_BIND: 279 macCommon = (struct _CommonChars*) param2; 280 if (macCommon == NULL) 281 { 282 printf ("There is an NDIS misconfiguration.\n"); 283 result = ERR_GENERAL_FAILURE; 284 break; 285 } 286 DEBUG2 ("module name %s\n" 287 "module type %s\n", 288 macCommon->moduleName, 289 ((MacChars*) macCommon->serviceChars)->macName); 290 291 /* Binding to the MAC */ 292 result = macCommon->systemRequest ((DWORD)&common, (DWORD)&macCommon, 293 0, REQ_BIND, 294 macCommon->moduleDS); 295 296 if (!strcmp(bindings.moduleName[bindEntry], handle->moduleName)) 297 handle->common = macCommon; 298 else PERROR ("unknown module"); 299 ++bindEntry; 300 break; 301 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; 308 309 default: 310 result = ERR_GENERAL_FAILURE; 311 break; 312 } 313 ARGSUSED (param1); 314 ARGSUSED (param3); 315 ARGSUSED (targetDS); 316 return (result); 317 } 318 319 CALLBACK (NdisRequestConfirm (WORD protId, WORD macId, WORD reqHandle, 320 WORD status, WORD request, WORD protDS)) 321 { 322 ARGSUSED (protId); ARGSUSED (macId); 323 ARGSUSED (reqHandle); ARGSUSED (status); 324 ARGSUSED (request); ARGSUSED (protDS); 325 return (ERR_SUCCESS); 326 } 327 328 CALLBACK (NdisTransmitConfirm (WORD protId, WORD macId, WORD reqHandle, 329 WORD status, WORD protDS)) 330 { 331 xmitPending--; 332 FreePktBuf (txBufPending); /* Add passed ECB back to the free list */ 333 334 ARGSUSED (reqHandle); 335 ARGSUSED (status); 336 ARGSUSED (protDS); 337 return (ERR_SUCCESS); 338 } 339 340 341 /* 342 * The primary function for receiving packets 343 */ 344 CALLBACK (NdisReceiveLookahead (WORD macId, WORD frameSize, 345 WORD bytesAvail, BYTE *buffer, 346 BYTE *indicate, WORD protDS)) 347 { 348 int result; 349 PktBuf *pktBuf; 350 WORD bytesCopied; 351 struct _TDBufDescr tDBufDescr; 352 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 361 362 /* Allocate a buffer for the packet 363 */ 364 if ((pktBuf = AllocPktBuf()) == NULL) 365 { 366 droppedPackets++; 367 return (ERR_FRAME_REJECTED); 368 } 369 370 /* 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. 373 */ 374 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; 380 381 result = MAC_DISPATCH(handle)->transferData (&bytesCopied, 0, &tDBufDescr, 382 handle->common->moduleDS); 383 pktBuf->packetLength = bytesCopied; 384 385 if (result == ERR_SUCCESS) 386 EnquePktBuf(pktBuf); 387 else FreePktBuf (pktBuf); 388 389 ARGSUSED (frameSize); 390 ARGSUSED (bytesAvail); 391 ARGSUSED (indicate); 392 ARGSUSED (protDS); 393 394 return (ERR_SUCCESS); 395 } 396 397 CALLBACK (NdisIndicationComplete (WORD macId, WORD protDS)) 398 { 399 ARGSUSED (macId); 400 ARGSUSED (protDS); 401 402 /* We don't give a hoot about these. Just return 403 */ 404 return (ERR_SUCCESS); 405 } 406 407 /* 408 * This is the OTHER way we may receive packets 409 */ 410 CALLBACK (NdisReceiveChain (WORD macId, WORD frameSize, WORD reqHandle, 411 struct _RxBufDescr *rxBufDescr, 412 BYTE *indicate, WORD protDS)) 413 { 414 struct _PktBuf *pktBuf; 415 int i; 416 417 /* 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. 422 */ 423 424 if ((pktBuf = AllocPktBuf()) == NULL) 425 { 426 droppedPackets++; 427 return (ERR_FRAME_REJECTED); 428 } 429 pktBuf->packetLength = 0; 430 431 /* Copy the packet to the buffer 432 */ 433 for (i = 0; i < rxBufDescr->rxDataCount; ++i) 434 { 435 struct _RxBufDescrRec *rxDescr = &rxBufDescr->rxBufDescrRec[i]; 436 437 memcpy (pktBuf->buffer + pktBuf->packetLength, 438 rxDescr->rxDataPtr, rxDescr->rxDataLen); 439 pktBuf->packetLength += rxDescr->rxDataLen; 440 } 441 442 EnquePktBuf (pktBuf); 443 444 ARGSUSED (frameSize); 445 ARGSUSED (reqHandle); 446 ARGSUSED (indicate); 447 ARGSUSED (protDS); 448 449 /* This frees up the buffer for the MAC to use 450 */ 451 return (ERR_SUCCESS); 452 } 453 454 CALLBACK (NdisStatusProc (WORD macId, WORD param1, BYTE *indicate, 455 WORD opcode, WORD protDS)) 456 { 457 switch (opcode) 458 { 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; 471 } 472 ARGSUSED (macId); 473 ARGSUSED (param1); 474 ARGSUSED (indicate); 475 ARGSUSED (opcode); 476 ARGSUSED (protDS); 477 478 /* We don't need to do anything about this stuff yet 479 */ 480 return (ERR_SUCCESS); 481 } 482 483 /* 484 * Tell the NDIS driver to start the delivery of the packet 485 */ 486 int NdisSendPacket (struct _PktBuf *pktBuf, int macId) 487 { 488 struct _TxBufDescr txBufDescr; 489 int result; 490 491 xmitPending++; 492 txBufPending = pktBuf; /* we only have 1 pending Tx at a time */ 493 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; 501 502 result = MAC_DISPATCH(handle)->transmitChain (common.moduleId, 503 pktBuf->handle, 504 &txBufDescr, 505 handle->common->moduleDS); 506 switch (result) 507 { 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 511 */ 512 printf ("ERROR: transmit queue overflowed\n"); 513 return (0); 514 515 case ERR_SUCCESS: 516 /* Everything was hunky dory and synchronous. Free up the 517 * packet buffer 518 */ 519 xmitPending--; 520 FreePktBuf (pktBuf); 521 return (1); 522 523 case ERR_REQUEST_QUEUED: 524 /* Everything was hunky dory and asynchronous. Do nothing 525 */ 526 return (1); 527 528 default: 529 printf ("Tx fail, code = %04X\n", result); 530 return (0); 531 } 532 } 533 534 535 536 static int ndis_nerr = sizeof(ndis_errlist) / sizeof(ndis_errlist[0]); 537 538 static char *Ndis_strerror (WORD errorCode) 539 { 540 static char buf[30]; 541 int i; 542 543 for (i = 0; i < ndis_nerr; i++) 544 if (errorCode == ndis_errlist[i].err_num) 545 return (ndis_errlist[i].err_text); 546 547 sprintf (buf,"unknown error %d",errorCode); 548 return (buf); 549 } 550 551 552 char *NdisLastError (void) 553 { 554 char *errStr = lastErr; 555 lastErr = NULL; 556 return (errStr); 557 } 558 559 int NdisOpen (void) 560 { 561 struct _ReqBlock reqBlock; 562 int result; 563 int ndisFd = open (NDIS_PATH, O_RDONLY); 564 565 if (ndisFd < 0) 566 { 567 printf ("Could not open NDIS Protocol Manager device.\n"); 568 return (0); 569 } 570 571 memset (&reqBlock, 0, sizeof(ReqBlock)); 572 573 reqBlock.opcode = PM_GET_PROTOCOL_MANAGER_LINKAGE; 574 575 result = NdisGetLinkage (ndisFd, (char*)&reqBlock, sizeof(ReqBlock)); 576 if (result != 0) 577 { 578 printf ("Could not get Protocol Manager linkage.\n"); 579 close (ndisFd); 580 return (0); 581 } 582 583 close (ndisFd); 584 protManEntry = (ProtMan) reqBlock.pointer1; 585 protManDS = reqBlock.word1; 586 587 DEBUG2 ("Entry Point = %04X:%04X\n", FP_SEG(protManEntry),FP_OFF(protManEntry)); 588 DEBUG1 ("ProtMan DS = %04X\n", protManDS); 589 return (1); 590 } 591 592 593 int NdisRegisterAndBind (int promis) 594 { 595 struct _ReqBlock reqBlock; 596 WORD result; 597 598 memset (&common,0,sizeof(common)); 599 600 common.tableSize = sizeof (common); 601 602 common.majorNdisVersion = 2; 603 common.minorNdisVersion = 0; 604 common.majorModuleVersion = 2; 605 common.minorModuleVersion = 0; 606 607 /* Indicates binding from below and dynamically loaded 608 */ 609 common.moduleFlags = 0x00000006L; 610 611 strcpy (common.moduleName, "PCAP"); 612 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 621 622 common.systemRequest = (SystemRequest) systemRequestGlue; 623 common.serviceChars = (BYTE*) &protChars; 624 common.serviceStatus = NULL; 625 common.upperDispatchTable = NULL; 626 common.lowerDispatchTable = (BYTE*) &lowerTable; 627 628 protChars.length = sizeof (protChars); 629 protChars.name[0] = 0; 630 protChars.type = 0; 631 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) */ 642 643 bindings.numBindings = 1; 644 strcpy (bindings.moduleName[0], handle->moduleName); 645 646 /* Register ourselves with NDIS 647 */ 648 reqBlock.opcode = PM_REGISTER_MODULE; 649 reqBlock.pointer1 = (BYTE FAR*) &common; 650 reqBlock.pointer2 = (BYTE FAR*) &bindings; 651 652 result = (*protManEntry) (&reqBlock, protManDS); 653 if (result) 654 { 655 printf ("Protman registering failed: %s\n", Ndis_strerror(result)); 656 return (0); 657 } 658 659 /* Start the binding process 660 */ 661 reqBlock.opcode = PM_BIND_AND_START; 662 reqBlock.pointer1 = (BYTE FAR*) &failingModules; 663 664 result = (*protManEntry) (&reqBlock, protManDS); 665 if (result) 666 { 667 printf ("Start binding failed: %s\n", Ndis_strerror(result)); 668 return (0); 669 } 670 return (1); 671 } 672 673 static int CheckMacFeatures (CardHandle *card) 674 { 675 DWORD serviceFlags; 676 BYTE _far *mediaString; 677 BYTE _far *mac_addr; 678 679 DEBUG2 ("checking card features\n" 680 "common table address = %08lX, macId = %d\n", 681 card->common, card->common->moduleId); 682 683 serviceFlags = MAC_CHAR (handle)->serviceFlags; 684 685 if ((serviceFlags & SF_PROMISCUOUS) == 0) 686 { 687 printf ("The MAC %s does not support promiscuous mode.\n", 688 card->moduleName); 689 return (0); 690 } 691 692 mediaString = MAC_CHAR (handle)->macName; 693 694 DEBUG1 ("media type = %s\n",mediaString); 695 696 /* Get the media type. And set the header size 697 */ 698 if (!strncmp(mediaString,"802.3",5) || 699 !strncmp(mediaString,"DIX",3) || 700 !strncmp(mediaString,"DIX+802.3",9)) 701 headerSize = sizeof (EthernetIIHeader); 702 703 else if (!strncmp(mediaString,"FDDI",4)) 704 headerSize = sizeof (FddiHeader) + 705 sizeof (Ieee802Dot2SnapHeader); 706 else 707 { 708 printf ("Unsupported MAC type: `%s'\n", mediaString); 709 return (0); 710 } 711 712 frameSize = MAC_CHAR (handle)->maxFrameSize; 713 mac_addr = MAC_CHAR (handle)->currentAddress; 714 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); 719 } 720 721 static int NdisStartMac (CardHandle *card) 722 { 723 WORD result; 724 725 /* Set the lookahead length 726 */ 727 result = MAC_DISPATCH(handle)->request (common.moduleId, 0, 728 headerSize, 0, 729 REQ_SET_LOOKAHEAD, 730 card->common->moduleDS); 731 732 /* We assume that if we got INVALID PARAMETER then either this 733 * is not supported or will work anyway. NE2000 does this. 734 */ 735 if (result != ERR_SUCCESS && result != ERR_INVALID_PARAMETER) 736 { 737 DEBUG1 ("Set lookahead failed: %s\n", Ndis_strerror(result)); 738 return (0); 739 } 740 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. 743 */ 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) 751 { 752 DEBUG1 ("Set packet filter failed: %s\n", Ndis_strerror(result)); 753 return (0); 754 } 755 756 /* If OPEN/CLOSE supported then open the adapter 757 */ 758 if (MAC_CHAR(handle)->serviceFlags & SF_OPEN_CLOSE) 759 { 760 result = MAC_DISPATCH(handle)->request (common.moduleId, 0, 0, NULL, 761 REQ_OPEN_ADAPTER, 762 card->common->moduleDS); 763 if (result != ERR_SUCCESS) 764 { 765 DEBUG1 ("Opening the MAC failed: %s\n", Ndis_strerror(result)); 766 return (0); 767 } 768 } 769 return (1); 770 } 771 772 void NdisShutdown (void) 773 { 774 struct _ReqBlock reqBlock; 775 int result, i; 776 777 if (!handle) 778 return; 779 780 /* If the adapters support open and are open then close them 781 */ 782 if ((MAC_CHAR(handle)->serviceFlags & SF_OPEN_CLOSE) && 783 (MAC_STATUS(handle)->macStatus & MAC_OPEN)) 784 { 785 result = MAC_DISPATCH(handle)->request (common.moduleId, 0, 0, 0, 786 REQ_CLOSE_ADAPTER, 787 handle->common->moduleDS); 788 if (result != ERR_SUCCESS) 789 { 790 printf ("Closing the MAC failed: %s\n", Ndis_strerror(result)); 791 return; 792 } 793 } 794 795 /* Tell the Protocol Manager to unbind and stop 796 */ 797 reqBlock.opcode = PM_UNBIND_AND_STOP; 798 reqBlock.pointer1 = (BYTE FAR*) &failingModules; 799 reqBlock.pointer2 = NULL; 800 801 result = (*protManEntry) (&reqBlock, protManDS); 802 if (result) 803 printf ("Unbind failed: %s\n", Ndis_strerror(result)); 804 805 for (i = 0; i < STACK_POOL_SIZE; ++i) 806 free (freeStacks[i] - STACK_SIZE); 807 808 handle = NULL; 809 } 810 811 int NdisInit (int promis) 812 { 813 int i, result; 814 815 /* Allocate the real mode stacks used for NDIS callbacks 816 */ 817 for (i = 0; i < STACK_POOL_SIZE; ++i) 818 { 819 freeStacks[i] = malloc (STACK_SIZE); 820 if (!freeStacks[i]) 821 return (0); 822 freeStacks[i] += STACK_SIZE; 823 } 824 825 if (!NdisOpen()) 826 return (0); 827 828 if (!NdisRegisterAndBind(promis)) 829 return (0); 830 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); 834 835 atexit (NdisShutdown); 836 837 if (!CheckMacFeatures(&handle)) 838 return (0); 839 840 switch (mediaType) 841 { 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); 851 } 852 853 DEBUG1 (" - Frame size: %d\n", frameSize); 854 855 if (!NdisStartMac(&handle)) 856 return (0); 857 return (1); 858 } 859 #endif /* USE_NDIS2 */ 860 861