summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/testmac
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/ndis/testmac
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/ndis/testmac')
-rw-r--r--private/ntos/ndis/testmac/makefile6
-rw-r--r--private/ntos/ndis/testmac/sources41
-rw-r--r--private/ntos/ndis/testmac/testmac.c1236
-rw-r--r--private/ntos/ndis/testmac/testmac.h349
4 files changed, 1632 insertions, 0 deletions
diff --git a/private/ntos/ndis/testmac/makefile b/private/ntos/ndis/testmac/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/ntos/ndis/testmac/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/ntos/ndis/testmac/sources b/private/ntos/ndis/testmac/sources
new file mode 100644
index 000000000..e54919b71
--- /dev/null
+++ b/private/ntos/ndis/testmac/sources
@@ -0,0 +1,41 @@
+!IF 0
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+
+Author:
+
+ Steve Wood (stevewo) 12-Apr-1990
+
+NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl
+
+!ENDIF
+
+MAJORCOMP=ntos
+MINORCOMP=ndis
+
+TARGETNAME=testmac
+TARGETPATH=\nt\public\sdk\lib
+TARGETTYPE=DRIVER
+
+TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\ndis.lib
+
+INCLUDES=..\..\inc
+
+SOURCES=testmac.c
+
+RELATIVE_DEPTH=..\..
+
+MSC_WARNING_LEVEL=/W3 /WX
+
diff --git a/private/ntos/ndis/testmac/testmac.c b/private/ntos/ndis/testmac/testmac.c
new file mode 100644
index 000000000..ad689ca82
--- /dev/null
+++ b/private/ntos/ndis/testmac/testmac.c
@@ -0,0 +1,1236 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ testmac.c
+
+Abstract:
+
+ simple MAC to test the NDIS wrapper.
+ Mostly taken from the Elnkii code spec.
+
+Author:
+
+ Adam Barr (adamba) 14-Jul-1990
+
+Environment:
+
+ Kernel mode, FSD
+
+Revision History:
+
+
+--*/
+
+#include <ntos.h>
+
+#include <ndis.h>
+
+#include "testmac.h"
+
+
+/*++
+
+Routine Description:
+
+ This is the initialization routine for the driver. It is invoked once
+ when the driver is loaded into the system. Its job is to initialize all
+ the structures which will be used by the FSD.
+
+Arguments:
+
+ DriverObject - Pointer to driver object created by the system.
+
+Return Value:
+
+ None.
+
+--*/
+
+
+
+static
+NTSTATUS
+TestMacDispatch(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ )
+
+/*++
+
+Routine Description:
+
+ This routine is the main dispatch routine for the FSD. This routine
+ accepts an I/O Request Packet (IRP) and either performs the request
+ itself, or it passes it to the FSP for processing.
+
+Arguments:
+
+ DeviceObject - Pointer to the device object for this driver.
+
+ Irp - Pointer to the request packet representing the I/O request.
+
+Return Value:
+
+ The function value is the status of the operation.
+
+
+--*/
+
+{
+ KIRQL oldIrql;
+
+ DeviceObject;
+
+ KeRaiseIrql( DISPATCH_LEVEL, &oldIrql );
+ IoCompleteRequest( Irp, 0 );
+ KeLowerIrql( oldIrql );
+
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+
+
+
+MAC_BLOCK GlobalMacBlock;
+UCHAR * AdapterNames[] = {
+ "\\Device\\TestMac0",
+ "\\Device\\TestMac1",
+ "\\Device\\TestMac2"
+ };
+
+
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject
+ )
+{
+ PMAC_BLOCK NewMacP = &GlobalMacBlock;
+ NDIS_STATUS Status;
+ CLONG i;
+ STRING AdapterName;
+
+ // Initialize the driver object with this driver's entry points.
+ for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
+ DriverObject->MajorFunction[i] = TestMacDispatch;
+ }
+
+ // Initialize the wrapper
+ NdisInitializeWrapper( (PVOID)DriverObject, NULL, NULL);
+
+ NewMacP->Debug = FALSE;
+
+ // set up driver object, etc.
+ NewMacP->DriverObject = DriverObject;
+ KeInitializePowerStatus(&NewMacP->PowerStatus);
+ NewMacP->PowerBoolean = FALSE;
+ KeInsertQueuePowerStatus(&NewMacP->PowerStatus, &NewMacP->PowerBoolean);
+ NdisAllocateSpinLock(&NewMacP->SpinLock);
+
+ NewMacP->NumAdapters = 0;
+ NewMacP->AdapterQueue = (PADAPTER_BLOCK)NULL;
+
+ // get ready to call NdisRegisterMac
+ NewMacP->MacCharacteristics.MajorNdisVersion = 3;
+ NewMacP->MacCharacteristics.MinorNdisVersion = 0;
+ NewMacP->MacCharacteristics.Reserved = 0;
+ NewMacP->MacCharacteristics.OpenAdapterHandler = TestMacOpenAdapter;
+ NewMacP->MacCharacteristics.CloseAdapterHandler = TestMacCloseAdapter;
+ NewMacP->MacCharacteristics.SetPacketFilterHandler = TestMacSetPacketFilter;
+ NewMacP->MacCharacteristics.AddMulticastAddressHandler =
+ TestMacAddMulticastAddress;
+ NewMacP->MacCharacteristics.DeleteMulticastAddressHandler =
+ TestMacDeleteMulticastAddress;
+ NewMacP->MacCharacteristics.SendHandler = TestMacSend;
+ NewMacP->MacCharacteristics.TransferDataHandler = TestMacTransferData;
+ NewMacP->MacCharacteristics.QueryInformationHandler =
+ TestMacQueryInformation;
+ NewMacP->MacCharacteristics.SetInformationHandler = TestMacSetInformation;
+ NewMacP->MacCharacteristics.ResetHandler = TestMacReset;
+ NewMacP->MacCharacteristics.TestHandler = TestMacTest;
+ NewMacP->MacCharacteristics.NameLength = sizeof("TESTMAC");
+ RtlMoveMemory(NewMacP->MacCharacteristics.Name, "TESTMAC", 8);
+
+ NdisRegisterMac(&Status,
+ &NewMacP->NdisMacHandle,
+ &NewMacP->MacCharacteristics,
+ sizeof(NewMacP->MacCharacteristics)+8);
+
+ if (Status != NDIS_STATUS_SUCCESS) {
+ // NdisRegisterMac failed
+ if (NewMacP->Debug)
+ DbgPrint(" [ RegisterMac FAILURE %d ] ", Status);
+ KeRemoveQueuePowerStatus(&NewMacP->PowerStatus);
+ NdisFreeSpinLock(&NewMacP->SpinLock);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ for (i=0; i<3; i++) {
+ RtlInitString(&AdapterName, AdapterNames[i]);
+ if (TestMacRegisterAdapter(&AdapterName, i) != NDIS_STATUS_SUCCESS)
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+
+//
+// MacRegisterAdapter
+//
+// NT will call this function when a new adapter should be opened
+//
+// - allocates space for adapter block and open blocks
+// - initializes the open block
+// - calls NdisRegisterAdapter
+//
+
+static
+NDIS_STATUS
+TestMacRegisterAdapter(
+ IN PSTRING AdapterName,
+ IN UINT AdapterNumber
+ )
+{
+ PADAPTER_BLOCK NewAdaptP;
+ NDIS_STATUS Status;
+ UINT i;
+
+ // OK to allocate memory now
+ NewAdaptP = (PADAPTER_BLOCK)AllocPhys(sizeof(ADAPTER_BLOCK));
+ if (NewAdaptP == (PADAPTER_BLOCK)NULL)
+ return NDIS_STATUS_FAILURE;
+
+ NewAdaptP->AdapterName = AdapterName;
+ NewAdaptP->AdapterNumber = AdapterNumber;
+
+ NewAdaptP->MaxOpens = 4;
+ NewAdaptP->MulticastListMax = 8;
+ NewAdaptP->MulticastDontModify = FALSE;
+
+ // need to get this memory now
+ NewAdaptP->OpenBlocks =
+ (POPEN_BLOCK)AllocPhys(sizeof(OPEN_BLOCK) * NewAdaptP->MaxOpens);
+ if (NewAdaptP->OpenBlocks == (POPEN_BLOCK)NULL)
+ {
+ FreePhys((PVOID)NewAdaptP);
+ return NDIS_STATUS_FAILURE;
+ }
+
+ ++(NewAdaptP->MulticastListMax); // to allow for broadcast address
+ // need to get this memory now
+ NewAdaptP->MulticastList = (PMULTICAST_ENTRY)
+ AllocPhys(sizeof(MULTICAST_ENTRY) * (NewAdaptP->MulticastListMax));
+ if (NewAdaptP->MulticastList == (PMULTICAST_ENTRY)NULL) {
+ FreePhys((PVOID)NewAdaptP->OpenBlocks);
+ FreePhys((PVOID)NewAdaptP);
+ return NDIS_STATUS_FAILURE;
+ }
+ NdisAllocateSpinLock(&NewAdaptP->MulticastSpinLock);
+
+ // set up the broadcast address as first multicast list entry
+ NewAdaptP->MulticastListSize = 1;
+ RtlMoveMemory(NewAdaptP->MulticastList->Address,
+ BroadcastAddress, ADDRESS_LEN);
+ NewAdaptP->MulticastList->ProtocolMask = ~(MASK)0; // not really needed
+
+ NewAdaptP->LoopbackQueue = (PNDIS_PACKET)NULL;
+ NdisAllocateSpinLock(&NewAdaptP->LoopbackSpinLock);
+
+ NewAdaptP->NumOpens = 0;
+ NewAdaptP->OpenQueue = (POPEN_BLOCK)NULL;
+
+ // set up free list of open blocks
+ NewAdaptP->FreeOpenQueue = NewAdaptP->OpenBlocks;
+ for (i = 0; i < NewAdaptP->MaxOpens-1; i++)
+ NewAdaptP->OpenBlocks[i].NextOpen = &(NewAdaptP->OpenBlocks[i+1]);
+ NewAdaptP->OpenBlocks[i].NextOpen = (POPEN_BLOCK)NULL;
+
+ NewAdaptP->MacBlock = &GlobalMacBlock;
+
+ NdisAcquireSpinLock(&GlobalMacBlock.SpinLock);
+ NewAdaptP->NextAdapter = GlobalMacBlock.AdapterQueue;
+ GlobalMacBlock.AdapterQueue = NewAdaptP;
+ NdisReleaseSpinLock(&GlobalMacBlock.SpinLock);
+
+ NewAdaptP->Debug = GlobalMacBlock.Debug;
+
+ Status = NdisRegisterAdapter(&NewAdaptP->NdisAdapterHandle,
+ GlobalMacBlock.NdisMacHandle,
+ (NDIS_HANDLE)NewAdaptP,
+ AdapterName);
+
+ if (Status != NDIS_STATUS_SUCCESS) {
+ if (NewAdaptP->Debug)
+ DbgPrint(" [ NdisRegisterAdapter FAILURE %d ] ", Status);
+ //*\\ take us out of GlobalMacBlock.AdapterQueue;
+ FreePhys((PVOID)NewAdaptP->OpenBlocks);
+ FreePhys((PVOID)NewAdaptP);
+ return NDIS_STATUS_FAILURE;
+ }
+
+ KeInitializeDpc(&NewAdaptP->IndicateDpc,
+ TestMacIndicateDpc, (PVOID)NewAdaptP);
+ NewAdaptP->DpcQueued = FALSE;
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+
+//
+// MacOpenAdapter
+//
+// NDIS function
+//
+
+static
+NDIS_STATUS
+TestMacOpenAdapter(
+ OUT NDIS_HANDLE * MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle,
+ IN NDIS_HANDLE NdisBindingContext,
+ IN NDIS_HANDLE MacAdapterContext,
+ IN PSTRING AddressingInformation OPTIONAL
+ )
+{
+#define AdaptP ((PADAPTER_BLOCK)MacAdapterContext)
+ POPEN_BLOCK NewOpenP;
+
+ RequestHandle;
+
+ // take care of linking us in to the appropriate lists
+ NdisAcquireSpinLock(&AdaptP->MacBlock->SpinLock);
+ if (AdaptP->NumOpens == AdaptP->MaxOpens) {
+ NdisReleaseSpinLock(&AdaptP->MacBlock->SpinLock);
+ return NDIS_STATUS_FAILURE;
+ }
+ // rearrange free list
+ NewOpenP = AdaptP->FreeOpenQueue;
+ AdaptP->FreeOpenQueue = NewOpenP->NextOpen;
+
+ // and link us on to active list
+ NewOpenP->NextOpen = AdaptP->OpenQueue;
+ AdaptP->OpenQueue = NewOpenP;
+
+ ++(AdaptP->NumOpens);
+ NdisReleaseSpinLock(&AdaptP->MacBlock->SpinLock);
+
+ // set up the open block
+ NewOpenP->AdapterBlock = AdaptP;
+ NewOpenP->MacBlock = AdaptP->MacBlock;
+ NewOpenP->NdisBindingContext = NdisBindingContext;
+ NewOpenP->AddressingInformation = AddressingInformation;
+ // set nth bit of Multicast bit (where n is our index in AdaptP->OpenBlocks)
+ NewOpenP->MulticastBit = 1;
+ NewOpenP->MulticastBit <<= AdaptP->OpenBlocks - NewOpenP;
+
+ NewOpenP->Debug = AdaptP->Debug;
+
+ if (NewOpenP->Debug)
+ DbgPrint("--> TestMacOpenAdapter %d\n", AdaptP->AdapterNumber);
+
+ //*\\ initialize OpenData to zero
+
+ *MacBindingHandle = (NDIS_HANDLE)NewOpenP;
+ return NDIS_STATUS_SUCCESS;
+#undef AdaptP
+}
+
+
+
+//
+// MacCloseAdapter
+//
+// NDIS function
+//
+
+static
+NDIS_STATUS
+TestMacCloseAdapter(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle
+ )
+{
+#define OpenP ((POPEN_BLOCK)MacBindingHandle)
+ PADAPTER_BLOCK AdaptP = OpenP->AdapterBlock;
+ POPEN_BLOCK TmpOpenP;
+
+ RequestHandle;
+
+ if (OpenP->Debug)
+ DbgPrint("--> TestMacCloseAdapter %d\n", AdaptP->AdapterNumber);
+
+ // first zap us off the multicast address list
+ TestMacKillMulticastAddresses(AdaptP, OpenP->MulticastBit);
+
+ // now remove us from the list of opens for this adapter
+ NdisAcquireSpinLock(&AdaptP->MacBlock->SpinLock);
+
+ // take us off active list
+ if (OpenP == AdaptP->OpenQueue)
+ AdaptP->OpenQueue = OpenP->NextOpen;
+ else {
+ TmpOpenP = AdaptP->OpenQueue;
+ while (TmpOpenP->NextOpen != OpenP)
+ TmpOpenP = TmpOpenP->NextOpen;
+ TmpOpenP->NextOpen = OpenP->NextOpen;
+ }
+
+ // put us on free list
+ OpenP->NextOpen = AdaptP->FreeOpenQueue;
+ AdaptP->FreeOpenQueue = OpenP;
+
+ --(AdaptP->NumOpens);
+ NdisReleaseSpinLock(&AdaptP->MacBlock->SpinLock);
+
+ return NDIS_STATUS_SUCCESS;
+#undef OpenP
+}
+
+
+
+
+//
+// MacSetPacketFilter
+//
+// NDIS function
+//
+// - set appropriate bits in the adapter filters
+// - modify the card Receive Configuration Register if needed
+//
+
+static
+NDIS_STATUS
+TestMacSetPacketFilter(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle,
+ IN UINT PacketFilter
+ )
+{
+#define OpenP ((POPEN_BLOCK)MacBindingHandle)
+ PADAPTER_BLOCK AdaptP = OpenP->AdapterBlock;
+ MASK BitOn = OpenP->MulticastBit;
+ MASK BitOff = ~(OpenP->MulticastBit);
+
+ RequestHandle;
+
+ if (OpenP->Debug)
+ DbgPrint("--> TestMacSetPacketFilter %d\n", AdaptP->AdapterNumber);
+
+ // acquire AdaptP->MulticastSpinLock
+ TestMacGetMulticastAccess(AdaptP);
+
+ if (PacketFilter & NDIS_PACKET_TYPE_DIRECTED)
+ AdaptP->DirectedFilter |= BitOn;
+ else
+ AdaptP->DirectedFilter &= BitOff;
+
+ if (PacketFilter & NDIS_PACKET_TYPE_MULTICAST)
+ AdaptP->MulticastFilter |= BitOn;
+ else
+ AdaptP->MulticastFilter &= BitOff;
+
+ if (PacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST)
+ AdaptP->AllMulticastFilter |= BitOn;
+ else
+ AdaptP->AllMulticastFilter &= BitOff;
+
+ if (PacketFilter & NDIS_PACKET_TYPE_BROADCAST)
+ AdaptP->BroadcastFilter |= BitOn;
+ else
+ AdaptP->BroadcastFilter &= BitOff;
+
+ if (PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
+ AdaptP->PromiscuousFilter |= BitOn;
+ else
+ AdaptP->PromiscuousFilter &= BitOff;
+
+ NdisReleaseSpinLock(&AdaptP->MulticastSpinLock);
+
+ return NDIS_STATUS_SUCCESS;
+#undef OpenP
+}
+
+
+
+//
+// MacAddMulticastAddress
+//
+// NDIS function
+//
+// - add the address to the list if needed
+// - modify the card multicast registers if needed
+//
+
+static
+NDIS_STATUS
+TestMacAddMulticastAddress(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle,
+ IN PSTRING MulticastAddress
+ )
+{
+#define OpenP ((POPEN_BLOCK)MacBindingHandle)
+ PADAPTER_BLOCK AdaptP = OpenP->AdapterBlock;
+ PMULTICAST_ENTRY MCSlot;
+
+ RequestHandle;
+
+ if (OpenP->Debug)
+ DbgPrint("--> TestMacAddMulticastAddress %d\n", AdaptP->AdapterNumber);
+
+ // acquire AdaptP->MulticastSpinLock
+ TestMacGetMulticastAccess(AdaptP);
+
+ // see if this address exists in our list
+ MCSlot = TestMacFindMulticastAddress(AdaptP->MulticastList,
+ AdaptP->MulticastListSize, MulticastAddress->Buffer);
+ if (MCSlot == (PMULTICAST_ENTRY)NULL) {
+ // see if our list is full
+ if (AdaptP->MulticastListSize == AdaptP->MulticastListMax) {
+ NdisReleaseSpinLock(&AdaptP->MulticastSpinLock);
+ return NDIS_MULTICAST_LIST_FULL;
+ }
+ // add us at the end
+ MCSlot = &(AdaptP->MulticastList[AdaptP->MulticastListSize]);
+ ++(AdaptP->MulticastListSize);
+ RtlMoveMemory(MCSlot->Address, MulticastAddress->Buffer, ADDRESS_LEN);
+ MCSlot->ProtocolMask = OpenP->MulticastBit; // so far, only us
+ } else {
+ if (MCSlot->ProtocolMask & OpenP->MulticastBit) {
+ NdisReleaseSpinLock(&AdaptP->MulticastSpinLock);
+ return NDIS_MULTICAST_EXISTS;
+ }
+ MCSlot->ProtocolMask |= OpenP->MulticastBit;
+ }
+
+ NdisReleaseSpinLock(&AdaptP->MulticastSpinLock);
+
+ return NDIS_STATUS_SUCCESS;
+#undef OpenP
+}
+
+
+//
+// GetMulticastAccess
+//
+// - acquire AdaptP->MulticastSpinLock in a lazy fashion
+//
+
+static
+VOID
+TestMacGetMulticastAccess(
+ IN PADAPTER_BLOCK AdaptP
+ )
+{
+ for (;;) {
+ NdisAcquireSpinLock(&AdaptP->MulticastSpinLock);
+ if (AdaptP->MulticastDontModify) {
+ NdisReleaseSpinLock(&AdaptP->MulticastSpinLock);
+ // wait a little bit..
+ } else
+ return;
+ }
+}
+
+
+// just hack this in
+static
+UINT
+ExCompareMemory(
+ PUCHAR s,
+ PUCHAR t,
+ UINT l
+ )
+{
+ UINT i;
+
+ for (i=0; i<l; i++) {
+ if (s[i] != t[i])
+ return -1;
+ }
+ return 0;
+}
+
+
+//
+// FindMulticastAddress
+//
+// finds a multicast address in a list
+//
+// - call this with a spin lock held
+//
+
+static
+PMULTICAST_ENTRY
+TestMacFindMulticastAddress(
+ IN PMULTICAST_ENTRY List,
+ IN UINT Size,
+ IN PUCHAR MulticastAddress
+ )
+{
+ PMULTICAST_ENTRY End = &List[Size];
+
+ for ( ; List<End; ++List) {
+ // thanks to HenrySa for this idea...
+ if (MulticastAddress[4] != List->Address[4])
+ continue;
+ if (ExCompareMemory(MulticastAddress, List->Address, ADDRESS_LEN) == 0)
+ return List;
+ }
+ return (PMULTICAST_ENTRY)NULL;
+}
+
+
+//
+// KillMulticastAddresses
+//
+// removes all multicast entries with MulticastBit on
+//
+// - called when an open is closed
+// - if this is the last reference to an entry, remove it
+//
+
+static
+VOID
+TestMacKillMulticastAddresses(
+ IN PADAPTER_BLOCK AdaptP,
+ IN MASK MulticastBit
+ )
+{
+ PMULTICAST_ENTRY List = AdaptP->MulticastList;
+ PMULTICAST_ENTRY End = &List[AdaptP->MulticastListSize];
+ PMULTICAST_ENTRY Dest;
+
+ // acquire AdaptP->MulticastSpinLock
+ TestMacGetMulticastAccess(AdaptP);
+
+ Dest = List;
+ while (List < End) {
+ List->ProtocolMask &= ~MulticastBit;
+ if (List->ProtocolMask != 0) {
+ if (Dest < List)
+ RtlMoveMemory(Dest, List, sizeof(MULTICAST_ENTRY));
+ ++Dest;
+ }
+ ++List;
+ }
+ AdaptP->MulticastListSize = Dest - AdaptP->MulticastList;
+
+ NdisReleaseSpinLock(&AdaptP->MulticastSpinLock);
+}
+
+
+
+//
+// MacDeleteMulticastAddress
+//
+// NDIS function
+//
+
+static
+NDIS_STATUS
+TestMacDeleteMulticastAddress(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle,
+ IN PSTRING MulticastAddress
+ )
+{
+#define OpenP ((POPEN_BLOCK)MacBindingHandle)
+ PADAPTER_BLOCK AdaptP = OpenP->AdapterBlock;
+ PMULTICAST_ENTRY MCSlot;
+
+ RequestHandle;
+
+ if (OpenP->Debug)
+ DbgPrint("--> TestMacDeleteMulticastAddress %d\n", AdaptP->AdapterNumber);
+
+ // acquire AdaptP->MulticastSpinLock
+ TestMacGetMulticastAccess(AdaptP);
+
+ MCSlot = TestMacFindMulticastAddress(AdaptP->MulticastList,
+ AdaptP->MulticastListSize, MulticastAddress->Buffer);
+ if (MCSlot == (PMULTICAST_ENTRY)NULL) {
+ NdisReleaseSpinLock(&AdaptP->MulticastSpinLock);
+ return NDIS_MULTICAST_NOT_FOUND;
+ } else {
+ if (!(MCSlot->ProtocolMask & OpenP->MulticastBit)) {
+ NdisReleaseSpinLock(&AdaptP->MulticastSpinLock);
+ return NDIS_MULTICAST_NOT_FOUND;
+ } else {
+ MCSlot->ProtocolMask &= ~(OpenP->MulticastBit);
+ if (MCSlot->ProtocolMask == 0) { // nobody using it
+ // remove this entry from the list
+ --(AdaptP->MulticastListSize);
+ if (MCSlot != &AdaptP->MulticastList[AdaptP->MulticastListSize])
+ RtlMoveMemory(MCSlot,
+ &AdaptP->MulticastList[AdaptP->MulticastListSize],
+ sizeof(MULTICAST_ENTRY));
+ }
+ }
+ }
+ NdisReleaseSpinLock(&AdaptP->MulticastSpinLock);
+
+ return NDIS_STATUS_SUCCESS;
+#undef OpenP
+}
+
+
+
+//
+// MacSend
+//
+// NDIS function
+//
+
+static
+NDIS_STATUS
+TestMacSend(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle,
+ IN PNDIS_PACKET Packet
+ )
+{
+#define OpenP ((POPEN_BLOCK)MacBindingHandle)
+ PADAPTER_BLOCK AdaptP = ((POPEN_BLOCK)MacBindingHandle)->AdapterBlock;
+ PMAC_RESERVED Reserved = RESERVED(Packet);
+
+ if (OpenP->Debug)
+ DbgPrint("--> TestMacSend %d\n", AdaptP->AdapterNumber);
+
+ if (OpenP->Debug) {
+ UCHAR Buf[80];
+ UINT Len;
+ Len = TestMacCopyOver(Buf, Packet, 0, 80);
+ DbgPrint("Message <%.*s>\n", Len, Buf);
+ }
+
+ Reserved->RequestHandle = RequestHandle;
+ Reserved->OpenBlock = (POPEN_BLOCK)MacBindingHandle;
+ Reserved->NextPacket = (PNDIS_PACKET)NULL;
+ TestMacSetLoopbackFlag(Packet);
+
+ if (Reserved->Loopback) {
+ Reserved->Status = 1;
+ NdisAcquireSpinLock(&AdaptP->LoopbackSpinLock);
+ TestMacLoopbackPacket(AdaptP, Packet);
+ NdisReleaseSpinLock(&AdaptP->LoopbackSpinLock);
+ }
+
+ return NDIS_STATUS_PENDING; // will complete when looped back
+#undef OpenP
+}
+
+
+//
+// SetLoopbackFlag
+//
+// sets the loopback flag in the reserved section of a packet
+// if it has a multicast destination address
+//
+
+static
+VOID
+TestMacSetLoopbackFlag(
+ IN OUT PNDIS_PACKET Packet
+ )
+{
+ UINT Dummy;
+ PNDIS_BUFFER FirstBuf;
+ PVOID BufVA;
+ PMAC_RESERVED Reserved = RESERVED(Packet);
+
+#if 0
+ NdisQueryPacket(Packet, NULL, &Dummy, &FirstBuf, NULL);
+ NdisQueryBuffer(FirstBuf, NULL, &BufVA, &Dummy);
+ Reserved->Loopback = (BOOLEAN)((((PUCHAR)BufVA)[0] & 1) != 0);
+#else
+ Dummy; FirstBuf; BufVA;
+ Reserved->Loopback = TRUE;
+#endif
+}
+
+
+//
+// LoopbackPacket
+//
+// put a packet on the loopback queue
+//
+// - call this with LoopbackSpinLock held
+//
+//
+
+static
+VOID
+TestMacLoopbackPacket(
+ IN PADAPTER_BLOCK AdaptP,
+ IN OUT PNDIS_PACKET Packet
+ )
+{
+ PMAC_RESERVED Reserved = RESERVED(Packet);
+
+ if (AdaptP->LoopbackQueue == (PNDIS_PACKET)NULL) {
+ AdaptP->LoopbackQueue = Packet;
+ AdaptP->LoopbackQTail = Packet;
+ } else {
+ PMAC_RESERVED Res2 = RESERVED(AdaptP->LoopbackQTail);
+ Res2->NextPacket = Packet;
+ AdaptP->LoopbackQTail = Packet;
+ }
+ Reserved->NextPacket = (PNDIS_PACKET)NULL;
+
+ if (!AdaptP->DpcQueued) {
+ AdaptP->DpcQueued = TRUE;
+ KeInsertQueueDpc(&AdaptP->IndicateDpc, NULL, NULL);
+ }
+}
+
+
+
+//
+// IndicateLoopbackPacket
+//
+// indicates a loopback packet to the protocols
+//
+// - the protocol must want to receive multicast/broadcast packets
+// - the address must be on his multicast list
+//
+
+static
+VOID
+TestMacIndicateLoopbackPacket(
+ IN PADAPTER_BLOCK AdaptP,
+ IN PNDIS_PACKET Packet
+ )
+{
+ PMULTICAST_ENTRY MCSlot;
+ POPEN_BLOCK CurOpen;
+ MASK EffectiveMask;
+ UINT IndicateLen;
+ UINT PacketLen;
+ NDIS_STATUS Status;
+
+ // copy destination address of packet into AdaptP->Lookahead
+ if (TestMacCopyOver(AdaptP->Lookahead, Packet, 0, ADDRESS_LEN) < ADDRESS_LEN) {
+ return;
+ // error, runt packet
+ }
+
+ NdisAcquireSpinLock(&AdaptP->MulticastSpinLock);
+ AdaptP->MulticastDontModify = TRUE;
+ NdisReleaseSpinLock(&AdaptP->MulticastSpinLock);
+
+ if (AdaptP->Lookahead[0] & 1) {
+ // if bit x in EffectiveMask is on, the protocol x wants this packet
+ MCSlot = TestMacFindMulticastAddress(AdaptP->MulticastList,
+ AdaptP->MulticastListSize, AdaptP->Lookahead);
+ if (MCSlot == (PMULTICAST_ENTRY)NULL)
+ EffectiveMask = AdaptP->MulticastFilter | AdaptP->PromiscuousFilter;
+ else if (MCSlot == &AdaptP->MulticastList[0]) // broadcast
+ EffectiveMask = AdaptP->BroadcastFilter | AdaptP->PromiscuousFilter;
+ else
+ EffectiveMask = MCSlot->ProtocolMask &
+ (AdaptP->MulticastFilter | AdaptP->AllMulticastFilter |
+ AdaptP->PromiscuousFilter);
+ } else {
+ EffectiveMask = AdaptP->DirectedFilter | AdaptP->PromiscuousFilter;
+ }
+
+ // as long as somebody wants it, indicate it
+ if (EffectiveMask != 0) {
+ PacketLen = TestMacPacketSize(Packet);
+ IndicateLen = (PacketLen > 256) ? 256 : PacketLen;
+ // copy the lookahead data into a contiguous buffer
+ TestMacCopyOver(AdaptP->Lookahead+ADDRESS_LEN,
+ Packet, ADDRESS_LEN, IndicateLen-ADDRESS_LEN);
+ CurOpen = AdaptP->OpenQueue;
+ while (CurOpen) {
+ if (CurOpen->MulticastBit & EffectiveMask) {
+ NdisIndicateReceive(&Status,
+ CurOpen->NdisBindingContext,
+ (NDIS_HANDLE)AdaptP,
+ AdaptP->Lookahead,
+ IndicateLen,
+ PacketLen);
+ }
+ CurOpen = CurOpen->NextOpen;
+ }
+ }
+
+ NdisAcquireSpinLock(&AdaptP->MulticastSpinLock);
+ AdaptP->MulticastDontModify = FALSE;
+ NdisReleaseSpinLock(&AdaptP->MulticastSpinLock);
+}
+
+
+//
+// PacketSize
+//
+// returns the number of bytes of data in a packet
+//
+
+static
+UINT
+TestMacPacketSize(
+ IN PNDIS_PACKET Packet
+ )
+{
+ PNDIS_BUFFER CurBuffer;
+ UINT Dummy;
+ UINT BufLen;
+ UINT TotLen;
+
+ TotLen = 0;
+ NdisQueryPacket(Packet, NULL, &Dummy, &CurBuffer, NULL);
+ while (CurBuffer != (PNDIS_BUFFER)NULL) {
+ NdisQueryBuffer(CurBuffer, NULL, NULL, &BufLen);
+ TotLen += BufLen;
+ NdisGetNextBuffer(CurBuffer, &CurBuffer);
+ }
+ return TotLen;
+}
+
+
+//
+// CopyOver
+//
+// copy bytes from a packet into a buffer
+//
+// - returns the actual number of bytes copied
+//
+
+static
+UINT
+TestMacCopyOver(
+ OUT PUCHAR Buf, // destination
+ IN PNDIS_PACKET Packet, // source packet
+ IN UINT Offset, // offset in packet
+ IN UINT Length // number of bytes to copy
+ )
+{
+ PNDIS_BUFFER CurBuffer;
+ UINT Dummy;
+ UINT BytesCopied;
+ PUCHAR BufVA;
+ UINT BufLen;
+ UINT ToCopy;
+ UINT CurOffset;
+
+ BytesCopied = 0;
+ // first move to Offset bytes into the packet
+ CurOffset = 0;
+ NdisQueryPacket(Packet, NULL, &Dummy, &CurBuffer, NULL);
+ while (CurBuffer != (PNDIS_BUFFER)NULL) {
+ NdisQueryBuffer(CurBuffer, NULL, (PVOID *) &BufVA, &BufLen);
+ if (CurOffset + BufLen > Offset)
+ break;
+ CurOffset += BufLen;
+ NdisGetNextBuffer(CurBuffer, &CurBuffer);
+ }
+ // see if we went off the end of the packet
+ if (CurBuffer == (PNDIS_BUFFER)NULL)
+ return 0;
+ // now copy over Length bytes
+ BufVA += (Offset - CurOffset);
+ BufLen -= (Offset - CurOffset);
+ for (;;) {
+ ToCopy = (BytesCopied+BufLen > Length) ? Length - BytesCopied : BufLen;
+ RtlMoveMemory(Buf+BytesCopied, BufVA, ToCopy);
+ BytesCopied += ToCopy;
+ if (BytesCopied == Length)
+ return BytesCopied;
+ NdisGetNextBuffer(CurBuffer, &CurBuffer);
+ if (CurBuffer == (PNDIS_BUFFER)NULL)
+ break;
+ NdisQueryBuffer(CurBuffer, NULL, (PVOID *) &BufVA, &BufLen);
+ }
+ return BytesCopied;
+}
+
+
+
+//
+// NdisTransferData
+//
+// NDIS function
+//
+// - AdaptP->LoopbackPacket will be FALSE if this is for a normal
+// indication, otherwise it will point to a loopback packet
+//
+
+static
+NDIS_STATUS
+TestMacTransferData(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle,
+ IN NDIS_HANDLE MacReceiveContext,
+ IN UINT ByteOffset,
+ IN UINT BytesToTransfer,
+ OUT PNDIS_PACKET Packet,
+ OUT PUINT BytesTransferred
+ )
+{
+#define OpenP ((POPEN_BLOCK)MacBindingHandle)
+#define AdaptP ((PADAPTER_BLOCK)MacReceiveContext)
+
+ RequestHandle; ByteOffset; BytesToTransfer; Packet; BytesTransferred;
+
+ if (OpenP->Debug)
+ DbgPrint("--> TestMacTransferData %d\n", AdaptP->AdapterNumber);
+
+ if (AdaptP->LoopbackPacket != (PNDIS_PACKET)NULL) {
+ PNDIS_BUFFER CurBuffer;
+ UINT Dummy;
+ PUCHAR BufVA;
+ UINT BufLen, Copied;
+ UINT CurOff;
+
+ // have to copy data from AdaptP->LoopbackPacket into Packet
+ NdisQueryPacket(Packet, NULL, &Dummy, &CurBuffer, NULL);
+ CurOff = ByteOffset;
+ while (CurBuffer != (PNDIS_BUFFER)NULL) {
+ NdisQueryBuffer(CurBuffer, NULL, (PVOID *) &BufVA, &BufLen);
+ Copied = TestMacCopyOver(BufVA, AdaptP->LoopbackPacket,
+ CurOff, BufLen);
+ CurOff += Copied;
+ if (Copied < BufLen)
+ break;
+ NdisGetNextBuffer(CurBuffer, &CurBuffer);
+ }
+ *BytesTransferred = CurOff - ByteOffset;
+ }
+
+ return NDIS_STATUS_SUCCESS;
+#undef AdaptP
+#undef OpenP
+}
+
+
+
+//
+// MacQueryInformation
+//
+// NDIS function
+//
+
+static
+NDIS_STATUS
+TestMacQueryInformation(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle,
+ IN NDIS_INFORMATION_CLASS InformationClass,
+ OUT PVOID Buffer,
+ IN UINT BufferLength
+ )
+{
+#define OpenP ((POPEN_BLOCK)MacBindingHandle)
+ PADAPTER_BLOCK AdaptP = OpenP->AdapterBlock;
+ UINT i;
+ static UCHAR StationAddress[] = { 0x00, 0x00, 0x00, 0x01, 0x02, 0x03 };
+
+ RequestHandle; InformationClass; Buffer; BufferLength;
+
+ if (OpenP->Debug)
+ DbgPrint("--> TestMacQueryInformation %d\n", AdaptP->AdapterNumber);
+
+
+ switch (InformationClass) {
+
+ case NdisInfoStationAddress:
+ RtlMoveMemory(Buffer, StationAddress, 6);
+ break;
+
+ }
+
+#if 0
+ if ((UINT)InformationClass == 1) {
+ // show multicast list
+ PMULTICAST_ENTRY MCSlot, End;
+ POPEN_BLOCK CurOpen;
+ PUCHAR Tcp;
+
+ NdisAcquireSpinLock(&AdaptP->MulticastSpinLock);
+ AdaptP->MulticastDontModify = TRUE;
+ NdisReleaseSpinLock(&AdaptP->MulticastSpinLock);
+
+ MCSlot = AdaptP->MulticastList;
+ End = &AdaptP->MulticastList[AdaptP->MulticastListSize];
+ while (MCSlot < End) {
+ Tcp = MCSlot->Address;
+ for (i=0; i<6; i++) {
+ if (Tcp[i] >= ' ' && Tcp[i] <= 'z')
+ DbgPrint(" %c ", Tcp[i]);
+ else
+ DbgPrint("%2x ", Tcp[i]);
+ }
+ CurOpen = AdaptP->OpenQueue;
+ while (CurOpen != (POPEN_BLOCK)NULL) {
+ if (CurOpen->MulticastBit & MCSlot->ProtocolMask)
+ DbgPrint(CurOpen == OpenP ? " X" : " x");
+ else
+ DbgPrint(" ");
+ CurOpen = CurOpen->NextOpen;
+ }
+ DbgPrint("\n");
+ ++MCSlot;
+ }
+
+ NdisAcquireSpinLock(&AdaptP->MulticastSpinLock);
+ AdaptP->MulticastDontModify = FALSE;
+ NdisReleaseSpinLock(&AdaptP->MulticastSpinLock);
+ }
+#else
+ i;
+#endif
+
+ return NDIS_STATUS_SUCCESS;
+#undef OpenP
+}
+
+
+
+//
+// MacSetInformation
+//
+// NDIS function
+//
+
+static
+NDIS_STATUS
+TestMacSetInformation(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle,
+ IN NDIS_INFORMATION_CLASS InformationClass,
+ IN PVOID Buffer,
+ IN UINT BufferLength
+ )
+{
+#define OpenP ((POPEN_BLOCK)MacBindingHandle)
+ PADAPTER_BLOCK AdaptP = OpenP->AdapterBlock;
+
+ RequestHandle; InformationClass; Buffer; BufferLength;
+
+ if (OpenP->Debug)
+ DbgPrint("--> TestMacSetInformation %d\n", AdaptP->AdapterNumber);
+
+ // this will involve the OpenData and AdapterData structures
+
+ return NDIS_STATUS_SUCCESS;
+#undef OpenP
+}
+
+
+
+//
+// MacReset
+//
+// NDIS function
+//
+
+static
+NDIS_STATUS
+TestMacReset(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle
+ )
+{
+#define OpenP ((POPEN_BLOCK)MacBindingHandle)
+ PADAPTER_BLOCK AdaptP = OpenP->AdapterBlock;
+ POPEN_BLOCK TmpOpenP;
+
+ RequestHandle;
+
+ if (OpenP->Debug)
+ DbgPrint("--> TestMacReset %d\n", AdaptP->AdapterNumber);
+
+ TmpOpenP = AdaptP->OpenQueue;
+ while (TmpOpenP != (POPEN_BLOCK)NULL) {
+ NdisIndicateStatus(TmpOpenP->NdisBindingContext, NDIS_STATUS_RESET, 0);
+ TmpOpenP = TmpOpenP->NextOpen;
+ }
+
+ return NDIS_STATUS_SUCCESS;
+#undef OpenP
+}
+
+
+
+//
+// MacTest
+//
+// NDIS function
+//
+
+static
+NDIS_STATUS
+TestMacTest(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle
+ )
+{
+#define OpenP ((POPEN_BLOCK)MacBindingHandle)
+ PADAPTER_BLOCK AdaptP = OpenP->AdapterBlock;
+
+ RequestHandle;
+
+ if (OpenP->Debug)
+ DbgPrint("--> TestMacTest %d\n", AdaptP->AdapterNumber);
+
+ return NDIS_STATUS_SUCCESS;
+#undef OpenP
+}
+
+
+static
+VOID
+TestMacIndicateDpc(
+ IN PKDPC Dpc,
+ IN PVOID DeferredContext,
+ IN PVOID SystemArgument1,
+ IN PVOID SystemArgument2
+ )
+{
+#define AdaptP ((PADAPTER_BLOCK)DeferredContext)
+ PNDIS_PACKET LPacket;
+ PMAC_RESERVED Reserved;
+ POPEN_BLOCK CurOpen;
+
+ UNREFERENCED_PARAMETER(Dpc);
+ UNREFERENCED_PARAMETER(SystemArgument1);
+ UNREFERENCED_PARAMETER(SystemArgument2);
+
+ // loopback any waiting packets
+ NdisAcquireSpinLock(&AdaptP->LoopbackSpinLock);
+ while (AdaptP->LoopbackQueue) {
+ // take the first packet off the queue
+ LPacket = AdaptP->LoopbackQueue;
+ Reserved = RESERVED(LPacket);
+ AdaptP->LoopbackQueue = RESERVED(AdaptP->LoopbackQueue)->NextPacket;
+ NdisReleaseSpinLock(&AdaptP->LoopbackSpinLock);
+ AdaptP->LoopbackPacket = LPacket;
+ // actually indicate it
+ TestMacIndicateLoopbackPacket(AdaptP, AdaptP->LoopbackPacket);
+ NdisAcquireSpinLock(&AdaptP->LoopbackSpinLock);
+ // complete the packet if needed
+ if (Reserved->RequestHandle != 0) {
+ NdisCompleteSend(
+ Reserved->OpenBlock->NdisBindingContext,
+ Reserved->RequestHandle,
+ NDIS_STATUS_SUCCESS);
+ }
+ }
+ AdaptP->DpcQueued = FALSE;
+ NdisReleaseSpinLock(&AdaptP->LoopbackSpinLock);
+
+ // indicate ReceiveComplete
+ CurOpen = AdaptP->OpenQueue;
+ while (CurOpen) {
+ NdisIndicateReceiveComplete(CurOpen->NdisBindingContext);
+ CurOpen = CurOpen->NextOpen;
+ }
+
+#undef AdaptP
+}
diff --git a/private/ntos/ndis/testmac/testmac.h b/private/ntos/ndis/testmac/testmac.h
new file mode 100644
index 000000000..750bb213e
--- /dev/null
+++ b/private/ntos/ndis/testmac/testmac.h
@@ -0,0 +1,349 @@
+
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ testmac.h
+
+Abstract:
+
+ Definitions for test MAC.
+ Motsly taken from the Elnkii code spec.
+
+Author:
+
+ Adam Barr (adamba) 16-Jul-1990
+
+Revision History:
+
+--*/
+
+#define AllocPhys(s) ExAllocatePool(NonPagedPool, s)
+#define FreePhys(s) ExFreePool(s)
+
+#define ADDRESS_LEN 6
+
+typedef ULONG MASK;
+
+UCHAR BroadcastAddress[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+
+// only have one of these structures
+
+typedef struct _MAC_BLOCK {
+ // NDIS information
+ NDIS_HANDLE NdisMacHandle; // returned from NdisRegisterMac
+ NDIS_MAC_CHARACTERISTICS MacCharacteristics;
+ UCHAR MacName[8];
+ // adapters registered for us
+ UINT NumAdapters;
+ struct _ADAPTER_BLOCK * AdapterQueue;
+ // should we be verbose
+ BOOLEAN Debug;
+ // NT specific
+ PDRIVER_OBJECT DriverObject;
+ KPOWER_STATUS PowerStatus;
+ BOOLEAN PowerBoolean;
+ NDIS_SPIN_LOCK SpinLock; // guards NumAdapter and AdapterQueue
+} MAC_BLOCK, * PMAC_BLOCK;
+
+
+// the multicast address list consists of these
+typedef struct _MULTICAST_ENTRY {
+ UCHAR Address[ADDRESS_LEN];
+ MASK ProtocolMask; // determines which opens it applies to
+} MULTICAST_ENTRY, * PMULTICAST_ENTRY;
+
+// one of these per adapter registered
+
+typedef struct _ADAPTER_BLOCK {
+ // NDIS information
+ NDIS_HANDLE NdisAdapterHandle; // returned from NdisRegisterAdapter
+ PSTRING AdapterName;
+ // used to mark us
+ UINT AdapterNumber;
+ // links with our MAC
+ PMAC_BLOCK MacBlock;
+ struct _ADAPTER_BLOCK * NextAdapter; // used by MacBlock->OpenQueue
+ // opens for this adapter
+ UINT MaxOpens; // maximum number
+ struct _OPEN_BLOCK * OpenBlocks; // storage for MaxOpens OPEN_BLOCKs
+ UINT NumOpens;
+ struct _OPEN_BLOCK * OpenQueue;
+ struct _OPEN_BLOCK * FreeOpenQueue;
+ // should we be verbose
+ BOOLEAN Debug;
+ // PROTOCOL.INI information
+ UINT MulticastListMax;
+ // these are for the current packet
+ UCHAR PacketHeader[4];
+ UCHAR Lookahead[256];
+ UINT PacketLen;
+ // receive information
+ UINT MulticastListSize; // current size
+ PMULTICAST_ENTRY MulticastList;
+ NDIS_SPIN_LOCK MulticastSpinLock; // guards all data in this section
+ BOOLEAN MulticastDontModify; // an extended spinlock
+ MASK MulticastFilter; // these filters work as explained
+ MASK DirectedFilter; // in the design note
+ MASK BroadcastFilter;
+ MASK PromiscuousFilter;
+ MASK AllMulticastFilter;
+ // loopback information
+ PNDIS_PACKET LoopbackQueue;
+ PNDIS_PACKET LoopbackQTail;
+ NDIS_SPIN_LOCK LoopbackSpinLock;
+ PNDIS_PACKET LoopbackPacket;
+ // NT specific
+ PKINTERRUPT Interrupt;
+ KDPC IndicateDpc;
+ BOOLEAN DpcQueued;
+} ADAPTER_BLOCK, * PADAPTER_BLOCK;
+
+// general macros
+#define MSB(value) ((UCHAR)((value) << 8))
+#define LSB(value) ((UCHAR)((value) && 0xff))
+
+// one of these per open on the adapter
+
+typedef struct _OPEN_BLOCK {
+ // NDIS information
+ NDIS_HANDLE NdisBindingContext; // passed to MacOpenAdapter
+ PSTRING AddressingInformation; // not used currently
+ // links to our adapter
+ PADAPTER_BLOCK AdapterBlock;
+ struct _OPEN_BLOCK * NextOpen;
+ // links to our MAC
+ PMAC_BLOCK MacBlock; // faster than using AdapterBlock->MacBlock
+ // should we be verbose
+ BOOLEAN Debug;
+ // used for multicast addresses
+ MASK MulticastBit;
+} OPEN_BLOCK, * POPEN_BLOCK;
+
+
+
+// the reserved section of a packet
+
+typedef struct _MAC_RESERVED { // can't be more than 16 bytes
+ PNDIS_PACKET NextPacket; // used to in the transmit queue (4 bytes)
+ NDIS_HANDLE RequestHandle; // for async send completion (4 bytes)
+ POPEN_BLOCK OpenBlock; // so we know who to complete to (4 bytes)
+ USHORT Status; // completion status (2 bytes)
+ BOOLEAN Loopback; // is this a loopback packet (1 byte)
+ BOOLEAN ReadyToComplete; // is one out of xmit or loopback done (1 byte)
+} MAC_RESERVED, * PMAC_RESERVED;
+
+// macro to retrieve the MAC_RESERVED structure from a packet
+#define RESERVED(Packet) ((PMAC_RESERVED)((Packet)->MacReserved))
+
+extern MAC_BLOCK GlobalMacBlock;
+
+
+//
+// function prototypes
+//
+
+
+NTSTATUS
+TestMacInitialize(
+ IN PDRIVER_OBJECT DriverObject
+ );
+
+
+static
+NTSTATUS
+TestMacDispatch(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ );
+
+
+static
+NDIS_STATUS
+TestMacRegisterAdapter(
+ IN PSTRING AdapterName,
+ IN UINT AdapterNumber
+ );
+
+
+static
+NDIS_STATUS
+TestMacOpenAdapter(
+ OUT NDIS_HANDLE * MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle,
+ IN NDIS_HANDLE NdisBindingContext,
+ IN NDIS_HANDLE MacAdapterContext,
+ IN PSTRING AddressingInformation OPTIONAL
+ );
+
+
+static
+NDIS_STATUS
+TestMacCloseAdapter(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle
+ );
+
+
+static
+NDIS_STATUS
+TestMacSetPacketFilter(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle,
+ IN UINT PacketFilter
+ );
+
+
+static
+NDIS_STATUS
+TestMacAddMulticastAddress(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle,
+ IN PSTRING MulticastAddress
+ );
+
+
+static
+VOID
+TestMacGetMulticastAccess(
+ IN PADAPTER_BLOCK AdaptP
+ );
+
+
+static
+PMULTICAST_ENTRY
+TestMacFindMulticastAddress(
+ IN PMULTICAST_ENTRY List,
+ IN UINT Size,
+ IN PUCHAR MulticastAddress
+ );
+
+
+static
+VOID
+TestMacKillMulticastAddresses(
+ IN PADAPTER_BLOCK AdaptP,
+ IN MASK MulticastBit
+ );
+
+
+static
+NDIS_STATUS
+TestMacDeleteMulticastAddress(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle,
+ IN PSTRING MulticastAddress
+ );
+
+
+static
+NDIS_STATUS
+TestMacSend(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle,
+ IN PNDIS_PACKET Packet
+ );
+
+
+static
+VOID
+TestMacSetLoopbackFlag(
+ IN OUT PNDIS_PACKET Packet
+ );
+
+
+static
+VOID
+TestMacLoopbackPacket(
+ IN PADAPTER_BLOCK AdaptP,
+ IN OUT PNDIS_PACKET Packet
+ );
+
+
+static
+VOID
+TestMacIndicateLoopbackPacket(
+ IN PADAPTER_BLOCK AdaptP,
+ IN PNDIS_PACKET Packet
+ );
+
+
+static
+UINT
+TestMacPacketSize(
+ IN PNDIS_PACKET Packet
+ );
+
+
+static
+UINT
+TestMacCopyOver(
+ OUT PUCHAR Buf,
+ IN PNDIS_PACKET Packet,
+ IN UINT Offset,
+ IN UINT Length
+ );
+
+
+static
+NDIS_STATUS
+TestMacTransferData(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle,
+ IN NDIS_HANDLE MacReceiveContext,
+ IN UINT ByteOffset,
+ IN UINT BytesToTransfer,
+ OUT PNDIS_PACKET Packet,
+ OUT PUINT BytesTransferred
+ );
+
+
+static
+NDIS_STATUS
+TestMacQueryInformation(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle,
+ IN NDIS_INFORMATION_CLASS InformationClass,
+ OUT PVOID Buffer,
+ IN UINT BufferLength
+ );
+
+
+static
+NDIS_STATUS
+TestMacSetInformation(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle,
+ IN NDIS_INFORMATION_CLASS InformationClass,
+ IN PVOID Buffer,
+ IN UINT BufferLength
+ );
+
+
+static
+NDIS_STATUS
+TestMacReset(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle
+ );
+
+
+static
+NDIS_STATUS
+TestMacTest(
+ IN NDIS_HANDLE MacBindingHandle,
+ IN NDIS_HANDLE RequestHandle
+ );
+
+
+static
+VOID
+TestMacIndicateDpc(
+ IN PKDPC Dpc,
+ IN PVOID DeferredContext,
+ IN PVOID SystemArgument1,
+ IN PVOID SystemArgument2
+ );