From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/ntos/ndis/ndis30/efilter.h | 605 +++++++++++++++++++++++++++++++++++++ 1 file changed, 605 insertions(+) create mode 100644 private/ntos/ndis/ndis30/efilter.h (limited to 'private/ntos/ndis/ndis30/efilter.h') diff --git a/private/ntos/ndis/ndis30/efilter.h b/private/ntos/ndis/ndis30/efilter.h new file mode 100644 index 000000000..c33749973 --- /dev/null +++ b/private/ntos/ndis/ndis30/efilter.h @@ -0,0 +1,605 @@ +/*++ + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + efilter.h + +Abstract: + + Header file for the address filtering library for NDIS MAC's. + +Author: + + Anthony V. Ercolano (tonye) creation-date 3-Aug-1990 + +Environment: + + Runs in the context of a single MAC driver. + +Notes: + + None. + +Revision History: + + Adam Barr (adamba) 28-May-1991 + + - renamed MacXXX to EthXXX, changed filter.h to efilter.h + + +--*/ + +#ifndef _ETH_FILTER_DEFS_ +#define _ETH_FILTER_DEFS_ + +#define ETH_LENGTH_OF_ADDRESS 6 + + +// +// ZZZ This is a little-endian specific check. +// +#define ETH_IS_MULTICAST(Address) \ + (((PUCHAR)(Address))[0] & ((UCHAR)0x01)) + + +// +// Check whether an address is broadcast. +// +#define ETH_IS_BROADCAST(Address) \ + ((*((ULONG UNALIGNED *) \ + (&(((PUCHAR) \ + Address \ + )[2] \ + ) \ + ) \ + ) == \ + ((ULONG)0xffffffff) \ + ) && \ + (((PUCHAR)Address)[0] == ((UCHAR)0xff)) && \ + (((PUCHAR)Address)[1] == ((UCHAR)0xff))) + + +// +// This macro will compare network addresses. +// +// A - Is a network address. +// +// B - Is a network address. +// +// Result - The result of comparing two network address. +// +// Result < 0 Implies the B address is greater. +// Result > 0 Implies the A element is greater. +// Result = 0 Implies equality. +// +// Note that this is an arbitrary ordering. There is not +// defined relation on network addresses. This is ad-hoc! +// +// +#define ETH_COMPARE_NETWORK_ADDRESSES(A,B,Result) \ +{ \ + PUCHAR _A = (PUCHAR)(A); \ + PUCHAR _B = (PUCHAR)(B); \ + if ( *(ULONG UNALIGNED *)&_A[2] > \ + *(ULONG UNALIGNED *)&_B[2] ) { \ + *Result = 1; \ + } else if ( *(ULONG UNALIGNED *)&_A[2] < \ + *(ULONG UNALIGNED *)&_B[2] ) { \ + *Result = (UINT)-1; \ + } else if ( *(USHORT UNALIGNED *)_A > \ + *(USHORT UNALIGNED *)_B ) { \ + *Result = 1; \ + } else if ( *(USHORT UNALIGNED *)_A < \ + *(USHORT UNALIGNED *)_B ) { \ + *Result = (UINT)-1; \ + } else { \ + *Result = 0; \ + } \ +} + +// +// This macro will compare network addresses. +// +// A - Is a network address. +// +// B - Is a network address. +// +// Result - The result of comparing two network address. +// +// Result != 0 Implies inequality. +// Result == 0 Implies equality. +// +// +#define ETH_COMPARE_NETWORK_ADDRESSES_EQ(A,B,Result) \ +{ \ + PUCHAR _A = (PUCHAR)(A); \ + PUCHAR _B = (PUCHAR)(B); \ + if ( ( *(ULONG UNALIGNED *)&_A[2] == \ + *(ULONG UNALIGNED *)&_B[2] ) && \ + ( *(USHORT UNALIGNED *)_A == \ + *(USHORT UNALIGNED *)_B ) ) { \ + *Result = 0; \ + } else { \ + *Result = 1; \ + } \ +} + + +// +// This macro is used to copy from one network address to +// another. +// +#define ETH_COPY_NETWORK_ADDRESS(D,S) \ +{ \ + PCHAR _D = (D); \ + PCHAR _S = (S); \ + *((ULONG UNALIGNED *)_D) = *((ULONG UNALIGNED *)_S); \ + _D[4] = _S[4]; \ + _D[5] = _S[5]; \ +} + + +// +//UINT +//ETH_QUERY_FILTER_CLASSES( +// IN PETH_FILTER Filter +// ) +// +// This macro returns the currently enabled filter classes. +// +// NOTE: THIS MACRO ASSUMES THAT THE FILTER LOCK IS HELD. +// +#define ETH_QUERY_FILTER_CLASSES(Filter) ((Filter)->CombinedPacketFilter) + + +// +//UINT +//ETH_QUERY_PACKET_FILTER( +// IN PETH_FILTER Filter, +// IN NDIS_HANDLE NdisFilterHandle +// ) +// +// This macro returns the currently enabled filter classes for a specific +// open instance. +// +// NOTE: THIS MACRO ASSUMES THAT THE FILTER LOCK IS HELD. +// +#define ETH_QUERY_PACKET_FILTER(Filter, NdisFilterHandle) \ + (((PETH_BINDING_INFO)(NdisFilterHandle))->PacketFilters) + + +// +//UINT +//ETH_NUMBER_OF_GLOBAL_FILTER_ADDRESSES( +// IN PETH_FILTER Filter +// ) +// +// This macro returns the number of multicast addresses in the +// multicast address list. +// +// NOTE: THIS MACRO ASSUMES THAT THE FILTER LOCK IS HELD. +// +#define ETH_NUMBER_OF_GLOBAL_FILTER_ADDRESSES(Filter) ((Filter)->NumberOfAddresses) + + +// +// An action routine type. The routines are called +// when a filter type is set for the first time or +// no more bindings require a particular type of filter. +// +// NOTE: THIS ROUTINE SHOULD ASSUME THAT THE LOCK IS ACQUIRED. +// +typedef +NDIS_STATUS +(*ETH_FILTER_CHANGE)( + IN UINT OldFilterClasses, + IN UINT NewFilterClasses, + IN NDIS_HANDLE MacBindingHandle, + IN PNDIS_REQUEST NdisRequest, + IN BOOLEAN Set + ); + +// +// This action routine is called when a new multicast address +// list is given to the filter. The action routine is given +// arrays containing the old and new multicast addresses. +// +// NOTE: THIS ROUTINE SHOULD ASSUME THAT THE LOCK IS ACQUIRED. +// +typedef +NDIS_STATUS +(*ETH_ADDRESS_CHANGE)( + IN UINT OldAddressCount, + IN CHAR OldAddresses[][ETH_LENGTH_OF_ADDRESS], + IN UINT NewAddressCount, + IN CHAR NewAddresses[][ETH_LENGTH_OF_ADDRESS], + IN NDIS_HANDLE MacBindingHandle, + IN PNDIS_REQUEST NdisRequest, + IN BOOLEAN Set + ); + +#if 0 +// This action routine is called when a unique multicast address +// is added to the filter. The action routine is passed an array +// filled with all of the addresses that are being filtered, as +// well as the index into this array of the unique address just +// added. It is also passed an array of contexts, associated +// with each address; it can store a context for the new address +// in AddressContexts[NewAddress]. The contexts are passed +// back to the delete action routine. +// +// NOTE: THIS ROUTINE SHOULD ASSUME THAT THE LOCK IS ACQUIRED. +// +typedef +NDIS_STATUS +(*ETH_ADDRESS_ADD)( + IN UINT CurrentAddressCount, + IN CHAR CurrentAddresses[][ETH_LENGTH_OF_ADDRESS], + IN UINT NewAddress, + IN OUT NDIS_HANDLE AddressContexts[], + IN NDIS_HANDLE MacBindingHandle, + IN PNDIS_REQUEST NdisRequest + ); + +// +// This action routine is called when a unique multicast address +// is no longer requested for filtering by any binding. The +// action routine is passed an array filled with the all of the +// addresses that are *still* being used for multicast filtering. +// It is also passed the array of contexts for those addresses. +// The routine is also passed the address of the address being deleted, +// and the context of the address being deleted (as set during +// the add action routine). +// +// NOTE: THIS ROUTINE SHOULD ASSUME THAT THE LOCK IS ACQUIRED. +// +typedef +NDIS_STATUS +(*ETH_ADDRESS_DELETE)( + IN UINT CurrentAddressCount, + IN CHAR CurrentAddresses[][ETH_LENGTH_OF_ADDRESS], + IN CHAR OldAddress[ETH_LENGTH_OF_ADDRESS], + IN NDIS_HANDLE AddressContexts[], + IN NDIS_HANDLE OldAddressContext, + IN NDIS_HANDLE MacBindingHandle, + IN PNDIS_REQUEST NdisRequest + ); +#endif + +// +// This action routine is called when the mac requests a close for +// a particular binding *WHILE THE BINDING IS BEING INDICATED TO +// THE PROTOCOL*. The filtering package can't get rid of the open +// right away. So this routine will be called as soon as the +// NdisIndicateReceive returns. +// +// NOTE: THIS ROUTINE SHOULD ASSUME THAT THE LOCK IS ACQUIRED. +// +typedef +VOID +(*ETH_DEFERRED_CLOSE)( + IN NDIS_HANDLE MacBindingHandle + ); + +typedef ULONG ETH_MASK,*PETH_MASK; + +// +// Maximum number of opens the filter package will support. This is +// the max so that bit masks can be used instead of a spaghetti of +// pointers. +// +#define ETH_FILTER_MAX_OPENS (sizeof(ULONG) * 8) + +// +// The binding info is threaded on two lists. When +// the binding is free it is on a single freelist. +// +// When the binding is being used it is on a doubly linked +// index list. +// +typedef struct _ETH_BINDING_INFO { + NDIS_HANDLE MacBindingHandle; + NDIS_HANDLE NdisBindingContext; + UINT PacketFilters; + ULONG References; + struct _ETH_BINDING_INFO *NextOpen; + struct _ETH_BINDING_INFO *PrevOpen; + BOOLEAN ReceivedAPacket; + UCHAR FilterIndex; +} ETH_BINDING_INFO,*PETH_BINDING_INFO; + +// +// An opaque type that contains a filter database. +// The MAC need not know how it is structured. +// +typedef struct _ETH_FILTER { + + // + // Spin lock used to protect the filter from multiple accesses. + // + PNDIS_SPIN_LOCK Lock; + + // + // Pointer to an array of 6 character arrays holding the + // multicast addresses requested for filtering. + // + CHAR (*MulticastAddresses)[ETH_LENGTH_OF_ADDRESS]; + + // + // Pointer to an array of ETH_MASKS that work in conjuction with + // the MulticastAddress array. In the masks, a bit being enabled + // indicates that the binding with the given FilterIndex is using + // the corresponding address. + // + ETH_MASK *BindingsUsingAddress; + + // + // Combination of all the filters of all the open bindings. + // + UINT CombinedPacketFilter; + + // + // Pointer for traversing the open list. + // + PETH_BINDING_INFO OpenList; + + + // + // Action routines to be invoked on notable changes in the filter. + // + + ETH_ADDRESS_CHANGE AddressChangeAction; + ETH_FILTER_CHANGE FilterChangeAction; + ETH_DEFERRED_CLOSE CloseAction; + + // + // The maximum number of addresses used for filtering. + // + UINT MaximumMulticastAddresses; + + // + // The current number of addresses in the address filter. + // + UINT NumberOfAddresses; + + // + // Bit mask of opens that are available. + // + ULONG FreeBindingMask; + + // + // Address of the adapter. + // + UCHAR AdapterAddress[ETH_LENGTH_OF_ADDRESS]; + +} ETH_FILTER,*PETH_FILTER; + + +// +// Only for internal wrapper use. +// +VOID +EthInitializePackage( + VOID + ); + +VOID +EthReferencePackage( + VOID + ); + +VOID +EthDereferencePackage( + VOID + ); + +// +// Exported functions +// +EXPORT +BOOLEAN +EthCreateFilter( + IN UINT MaximumMulticastAddresses, + IN ETH_ADDRESS_CHANGE AddressChangeAction, + IN ETH_FILTER_CHANGE FilterChangeAction, + IN ETH_DEFERRED_CLOSE CloseAction, + IN PUCHAR AdapterAddress, + IN PNDIS_SPIN_LOCK Lock, + OUT PETH_FILTER *Filter + ); + +EXPORT +VOID +EthDeleteFilter( + IN PETH_FILTER Filter + ); + +EXPORT +BOOLEAN +EthNoteFilterOpenAdapter( + IN PETH_FILTER Filter, + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE NdisBindingContext, + OUT PNDIS_HANDLE NdisFilterHandle + ); + +EXPORT +NDIS_STATUS +EthDeleteFilterOpenAdapter( + IN PETH_FILTER Filter, + IN NDIS_HANDLE NdisFilterHandle, + IN PNDIS_REQUEST NdisRequest + ); + +EXPORT +NDIS_STATUS +EthChangeFilterAddresses( + IN PETH_FILTER Filter, + IN NDIS_HANDLE NdisFilterHandle, + IN PNDIS_REQUEST NdisRequest, + IN UINT AddressCount, + IN CHAR Addresses[][ETH_LENGTH_OF_ADDRESS], + IN BOOLEAN Set + ); + + +#define EthShouldAddressLoopBackMacro(_Filter, _Address, _pfLoopback, _pfSelfDirected) \ +{ \ + UINT CombinedFilters; \ + \ + CombinedFilters = ETH_QUERY_FILTER_CLASSES(_Filter); \ + \ + *(_pfLoopback) = FALSE; \ + *(_pfSelfDirected) = FALSE; \ + \ + do \ + { \ + /* \ + * First check if the filter is promiscuous. \ + */ \ + \ + if (CombinedFilters & NDIS_PACKET_TYPE_PROMISCUOUS) \ + { \ + *(_pfLoopback) = TRUE; \ + break; \ + } \ + \ + /* \ + * Check if it *at least* has the multicast address bit. \ + */ \ + \ + if (ETH_IS_MULTICAST(_Address)) \ + { \ + /* \ + * It is at least a multicast address. Check to see if \ + * it is a broadcast address. \ + */ \ + \ + if (ETH_IS_BROADCAST(_Address)) \ + { \ + if (CombinedFilters & NDIS_PACKET_TYPE_BROADCAST) \ + { \ + *(_pfLoopback) = TRUE; \ + break; \ + } \ + else \ + { \ + break; \ + } \ + } \ + else \ + { \ + if ((CombinedFilters & NDIS_PACKET_TYPE_ALL_MULTICAST) || \ + (CombinedFilters & NDIS_PACKET_TYPE_MULTICAST)) \ + { \ + *(_pfLoopback) = TRUE; \ + break; \ + } \ + } \ + } \ + else \ + { \ + /* \ + * Directed to ourself?? \ + */ \ + \ + if ((*(ULONG UNALIGNED *)&(_Address)[2] == \ + *(ULONG UNALIGNED *)&(_Filter)->AdapterAddress[2]) && \ + (*(USHORT UNALIGNED *)&(_Address)[0] == \ + *(USHORT UNALIGNED *)&(_Filter)->AdapterAddress[0])) \ + { \ + *(_pfLoopback) = TRUE; \ + *(_pfSelfDirected) = TRUE; \ + } \ + } \ + } while (FALSE); \ +} + +EXPORT +BOOLEAN +EthShouldAddressLoopBack( + IN PETH_FILTER Filter, + IN CHAR Address[ETH_LENGTH_OF_ADDRESS] + ); + +EXPORT +NDIS_STATUS +EthFilterAdjust( + IN PETH_FILTER Filter, + IN NDIS_HANDLE NdisFilterHandle, + IN PNDIS_REQUEST NdisRequest, + IN UINT FilterClasses, + IN BOOLEAN Set + ); + +EXPORT +UINT +EthNumberOfOpenFilterAddresses( + IN PETH_FILTER Filter, + IN NDIS_HANDLE NdisFilterHandle + ); + +EXPORT +VOID +EthQueryGlobalFilterAddresses( + OUT PNDIS_STATUS Status, + IN PETH_FILTER Filter, + IN UINT SizeOfArray, + OUT PUINT NumberOfAddresses, + IN OUT CHAR AddressArray[][ETH_LENGTH_OF_ADDRESS] + ); + +EXPORT +VOID +EthQueryOpenFilterAddresses( + OUT PNDIS_STATUS Status, + IN PETH_FILTER Filter, + IN NDIS_HANDLE NdisFilterHandle, + IN UINT SizeOfArray, + OUT PUINT NumberOfAddresses, + IN OUT CHAR AddressArray[][ETH_LENGTH_OF_ADDRESS] + ); + + +EXPORT +VOID +EthFilterIndicateReceive( + IN PETH_FILTER Filter, + IN NDIS_HANDLE MacReceiveContext, + IN PCHAR Address, + IN PVOID HeaderBuffer, + IN UINT HeaderBufferSize, + IN PVOID LookaheadBuffer, + IN UINT LookaheadBufferSize, + IN UINT PacketSize + ); + +EXPORT +VOID +EthFilterDprIndicateReceive( + IN PETH_FILTER Filter, + IN NDIS_HANDLE MacReceiveContext, + IN PCHAR Address, + IN PVOID HeaderBuffer, + IN UINT HeaderBufferSize, + IN PVOID LookaheadBuffer, + IN UINT LookaheadBufferSize, + IN UINT PacketSize + ); + +EXPORT +VOID +EthFilterIndicateReceiveComplete( + IN PETH_FILTER Filter + ); + +EXPORT +VOID +EthFilterDprIndicateReceiveComplete( + IN PETH_FILTER Filter + ); + +#endif // _ETH_FILTER_DEFS_ + -- cgit v1.2.3