diff options
Diffstat (limited to '')
-rw-r--r-- | private/ntos/ndis/ndis30/ffilter.h | 692 |
1 files changed, 692 insertions, 0 deletions
diff --git a/private/ntos/ndis/ndis30/ffilter.h b/private/ntos/ndis/ndis30/ffilter.h new file mode 100644 index 000000000..ae3ae8120 --- /dev/null +++ b/private/ntos/ndis/ndis30/ffilter.h @@ -0,0 +1,692 @@ +/*++ + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + ffilter.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: + + Sean Selitrennikoff (SeanSe) - converter efilter.* for FDDI support. + + +--*/ + +#ifndef _FDDI_FILTER_DEFS_ +#define _FDDI_FILTER_DEFS_ + +#define FDDI_LENGTH_OF_LONG_ADDRESS 6 +#define FDDI_LENGTH_OF_SHORT_ADDRESS 2 + + +// +// ZZZ This is a little-endian specific check. +// +#define FDDI_IS_MULTICAST(Address, AddressLength, Result) \ +{ \ + PUCHAR _A = Address; \ + *Result = (BOOLEAN)(_A[0] & ((UCHAR)0x01)); \ +} + +// +// Check whether the frame is SMT or not. +// +#define FDDI_IS_SMT(FcByte, Result) \ +{ \ + *Result = ((FcByte & ((UCHAR)0xf0)) == 0x40); \ +} + + +// +// Check whether an address is broadcast. +// +#define FDDI_IS_BROADCAST(Address, AddressLength, Result) \ +{ \ + PUCHAR _A = Address; \ + PUCHAR _E = _A + AddressLength;\ + *Result = TRUE;\ + for (; _A < _E ; _A++) {\ + if (*_A != 0xFF) {\ + *Result = FALSE;\ + break;\ + }\ + }\ +} + + +// +// 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 FDDI_COMPARE_NETWORK_ADDRESSES(A,B,_AddressLength,Result) \ +{ \ + PUCHAR _A = (PUCHAR)(A); \ + PUCHAR _B = (PUCHAR)(B); \ + if ( *(USHORT UNALIGNED *)_A > \ + *(USHORT UNALIGNED *)_B ) { \ + *Result = 1; \ + } else if ( *(USHORT UNALIGNED *)_A < \ + *(USHORT UNALIGNED *)_B ) { \ + *Result = (UINT)-1; \ + } else if (_AddressLength == 2) { \ + *Result = 0; \ + } else 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 { \ + *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 FDDI_COMPARE_NETWORK_ADDRESSES_EQ(A,B,_AddressLength,Result) \ +{ \ + PUCHAR _A = (PUCHAR)(A); \ + PUCHAR _B = (PUCHAR)(B); \ + if ( ( *(USHORT UNALIGNED *)_A == \ + *(USHORT UNALIGNED *)_B ) && \ + ( ( (_AddressLength) == 2 ) || \ + ( *(ULONG UNALIGNED *)&_A[2] == \ + *(ULONG UNALIGNED *)&_B[2] ) ) ) { \ + *Result = 0; \ + } else { \ + *Result = 1; \ + } \ +} + + +// +// This macro is used to copy from one network address to +// another. +// +#define FDDI_COPY_NETWORK_ADDRESS(D,S,AddressLength) \ +{ \ + PCHAR _D = (D); \ + PCHAR _S = (S); \ + UINT _C = (AddressLength);\ + for ( ; _C > 0 ; _D++, _S++, _C--) {\ + *_D = *_S;\ + }\ +} + + +// +//UINT +//FDDI_QUERY_FILTER_CLASSES( +// IN PFDDI_FILTER Filter +// ) +// +// This macro returns the currently enabled filter classes. +// +// NOTE: THIS MACRO ASSUMES THAT THE FILTER LOCK IS HELD. +// +#define FDDI_QUERY_FILTER_CLASSES(Filter) ((Filter)->CombinedPacketFilter) + + +// +//UINT +//FDDI_QUERY_PACKET_FILTER( +// IN PFDDI_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 FDDI_QUERY_PACKET_FILTER(Filter, NdisFilterHandle) \ + (((PFDDI_BINDING_INFO)(NdisFilterHandle))->PacketFilters) + + +// +//UINT +//FDDI_NUMBER_OF_GLOBAL_FILTER_LONG_ADDRESSES( +// IN PFDDI_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 FDDI_NUMBER_OF_GLOBAL_FILTER_LONG_ADDRESSES(Filter) ((Filter)->NumberOfLongAddresses) + + +// +//UINT +//FDDI_NUMBER_OF_GLOBAL_FILTER_SHORT_ADDRESSES( +// IN PFDDI_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 FDDI_NUMBER_OF_GLOBAL_FILTER_SHORT_ADDRESSES(Filter) ((Filter)->NumberOfShortAddresses) + + +// +// 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 +(*FDDI_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 +(*FDDI_ADDRESS_CHANGE)( + IN UINT OldLongAddressCount, + IN CHAR OldLongAddresses[][FDDI_LENGTH_OF_LONG_ADDRESS], + IN UINT NewLongAddressCount, + IN CHAR NewLongAddresses[][FDDI_LENGTH_OF_LONG_ADDRESS], + IN UINT OldShortAddressCount, + IN CHAR OldShortAddresses[][FDDI_LENGTH_OF_SHORT_ADDRESS], + IN UINT NewShortAddressCount, + IN CHAR NewShortAddresses[][FDDI_LENGTH_OF_SHORT_ADDRESS], + IN NDIS_HANDLE MacBindingHandle, + IN PNDIS_REQUEST NdisRequest, + IN BOOLEAN Set + ); + +// +// 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 +(*FDDI_DEFERRED_CLOSE)( + IN NDIS_HANDLE MacBindingHandle + ); + +typedef ULONG FDDI_MASK,*PFDDI_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 FDDI_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 _FDDI_BINDING_INFO { + NDIS_HANDLE MacBindingHandle; + NDIS_HANDLE NdisBindingContext; + UINT PacketFilters; + ULONG References; + struct _FDDI_BINDING_INFO *NextOpen; + struct _FDDI_BINDING_INFO *PrevOpen; + BOOLEAN ReceivedAPacket; + UCHAR FilterIndex; +} FDDI_BINDING_INFO,*PFDDI_BINDING_INFO; + +// +// An opaque type that contains a filter database. +// The MAC need not know how it is structured. +// +typedef struct _FDDI_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 (*MulticastLongAddresses)[FDDI_LENGTH_OF_LONG_ADDRESS]; + + // + // Pointer to an array of FDDI_MASKS that work in conjuction with + // the MulticastLongAddress array. In the masks, a bit being enabled + // indicates that the binding with the given FilterIndex is using + // the corresponding address. + // + FDDI_MASK *BindingsUsingLongAddress; + + // + // Pointer to an array of 2 character arrays holding the + // multicast addresses requested for filtering. + // + CHAR (*MulticastShortAddresses)[FDDI_LENGTH_OF_SHORT_ADDRESS]; + + // + // Pointer to an array of FDDI_MASKS that work in conjuction with + // the MulticastShortAddress array. In the masks, a bit being enabled + // indicates that the binding with the given FilterIndex is using + // the corresponding address. + // + FDDI_MASK *BindingsUsingShortAddress; + + // + // Combination of all the filters of all the open bindings. + // + UINT CombinedPacketFilter; + + // + // Pointer for traversing the open list. + // + PFDDI_BINDING_INFO OpenList; + + + // + // Action routines to be invoked on notable changes in the filter. + // + + FDDI_ADDRESS_CHANGE AddressChangeAction; + FDDI_FILTER_CHANGE FilterChangeAction; + FDDI_DEFERRED_CLOSE CloseAction; + + // + // The maximum number of long addresses used for filtering. + // + UINT MaximumMulticastLongAddresses; + + // + // The maximum number of short addresses used for filtering. + // + UINT MaximumMulticastShortAddresses; + + // + // The current number of addresses in the LongAddress filter. + // + UINT NumberOfLongAddresses; + + // + // The current number of addresses in the ShortAddress filter. + // + UINT NumberOfShortAddresses; + + // + // Bit mask of opens that are available. + // + ULONG FreeBindingMask; + + // + // Long Address of the adapter. + // + UCHAR AdapterLongAddress[FDDI_LENGTH_OF_LONG_ADDRESS]; + + // + // Short Address of the adapter. + // + UCHAR AdapterShortAddress[FDDI_LENGTH_OF_SHORT_ADDRESS]; + +} FDDI_FILTER,*PFDDI_FILTER; + +// +// Only for internal wrapper use. +// +VOID +FddiInitializePackage( + VOID + ); + +VOID +FddiReferencePackage( + VOID + ); + +VOID +FddiDereferencePackage( + VOID + ); + +// +// Exported routines +// + +EXPORT +BOOLEAN +FddiCreateFilter( + IN UINT MaximumMulticastLongAddresses, + IN UINT MaximumMulticastShortAddresses, + IN FDDI_ADDRESS_CHANGE AddressChangeAction, + IN FDDI_FILTER_CHANGE FilterChangeAction, + IN FDDI_DEFERRED_CLOSE CloseAction, + IN PUCHAR AdapterLongAddress, + IN PUCHAR AdapterShortAddress, + IN PNDIS_SPIN_LOCK Lock, + OUT PFDDI_FILTER *Filter + ); + +EXPORT +VOID +FddiDeleteFilter( + IN PFDDI_FILTER Filter + ); + +EXPORT +BOOLEAN +FddiNoteFilterOpenAdapter( + IN PFDDI_FILTER Filter, + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE NdisBindingContext, + OUT PNDIS_HANDLE NdisFilterHandle + ); + +EXPORT +NDIS_STATUS +FddiDeleteFilterOpenAdapter( + IN PFDDI_FILTER Filter, + IN NDIS_HANDLE NdisFilterHandle, + IN PNDIS_REQUEST NdisRequest + ); + +EXPORT +NDIS_STATUS +FddiChangeFilterLongAddresses( + IN PFDDI_FILTER Filter, + IN NDIS_HANDLE NdisFilterHandle, + IN PNDIS_REQUEST NdisRequest, + IN UINT AddressCount, + IN CHAR Addresses[][FDDI_LENGTH_OF_LONG_ADDRESS], + IN BOOLEAN Set + ); + +EXPORT +NDIS_STATUS +FddiChangeFilterShortAddresses( + IN PFDDI_FILTER Filter, + IN NDIS_HANDLE NdisFilterHandle, + IN PNDIS_REQUEST NdisRequest, + IN UINT AddressCount, + IN CHAR Addresses[][FDDI_LENGTH_OF_SHORT_ADDRESS], + IN BOOLEAN Set + ); + + +#define FddiShouldAddressLoopBackMacro(_Filter, _Address, _AddressLength, _pfLoopBack, _pfSelfDirected)\ +{ \ + /* \ + * Holds the result of address determinations. \ + */ \ + INT ResultOfAddressCheck; \ + \ + UINT CombinedFilters; \ + \ + CombinedFilters = FDDI_QUERY_FILTER_CLASSES(_Filter); \ + \ + *(_pfLoopBack) = FALSE; \ + *(_pfSelfDirected) = FALSE; \ + \ + do \ + { \ + if (CombinedFilters & NDIS_PACKET_TYPE_PROMISCUOUS) \ + { \ + *(_pfLoopBack) = TRUE; \ + break; \ + } \ + \ + /* \ + * First check if it *at least* has the multicast address bit. \ + */ \ + \ + FDDI_IS_MULTICAST( \ + _Address, \ + _AddressLength, \ + &ResultOfAddressCheck \ + ); \ + \ + if (ResultOfAddressCheck) \ + { \ + /* \ + * It is at least a multicast address. Check to see if \ + * it is a broadcast address. \ + */ \ + \ + FDDI_IS_BROADCAST( \ + _Address, \ + _AddressLength, \ + &ResultOfAddressCheck \ + ); \ + \ + if (ResultOfAddressCheck) \ + { \ + 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 \ + { \ + break; \ + } \ + } \ + } \ + else \ + { \ + /* \ + * Directed to ourself? \ + */ \ + if (AddressLength == FDDI_LENGTH_OF_LONG_ADDRESS) \ + { \ + FDDI_COMPARE_NETWORK_ADDRESSES_EQ((_Filter)->AdapterLongAddress, \ + _Address, \ + FDDI_LENGTH_OF_LONG_ADDRESS, \ + &ResultOfAddressCheck \ + ); \ + } \ + else \ + { \ + FDDI_COMPARE_NETWORK_ADDRESSES_EQ((_Filter)->AdapterShortAddress, \ + _Address, \ + FDDI_LENGTH_OF_SHORT_ADDRESS, \ + &ResultOfAddressCheck \ + ); \ + } \ + \ + if (ResultOfAddressCheck == 0) \ + { \ + *(_pfLoopBack) = TRUE; \ + *(_pfSelfDirected) = TRUE; \ + break; \ + } \ + } \ + } while (FALSE); \ +} + +EXPORT +BOOLEAN +FddiShouldAddressLoopBack( + IN PFDDI_FILTER Filter, + IN CHAR Address[], + IN UINT LengthOfAddress + ); + +EXPORT +NDIS_STATUS +FddiFilterAdjust( + IN PFDDI_FILTER Filter, + IN NDIS_HANDLE NdisFilterHandle, + IN PNDIS_REQUEST NdisRequest, + IN UINT FilterClasses, + IN BOOLEAN Set + ); + +EXPORT +UINT +FddiNumberOfOpenFilterLongAddresses( + IN PFDDI_FILTER Filter, + IN NDIS_HANDLE NdisFilterHandle + ); + +EXPORT +UINT +FddiNumberOfOpenFilterShortAddresses( + IN PFDDI_FILTER Filter, + IN NDIS_HANDLE NdisFilterHandle + ); + +EXPORT +VOID +FddiQueryGlobalFilterLongAddresses( + OUT PNDIS_STATUS Status, + IN PFDDI_FILTER Filter, + IN UINT SizeOfArray, + OUT PUINT NumberOfAddresses, + IN OUT CHAR AddressArray[][FDDI_LENGTH_OF_LONG_ADDRESS] + ); + +EXPORT +VOID +FddiQueryGlobalFilterShortAddresses( + OUT PNDIS_STATUS Status, + IN PFDDI_FILTER Filter, + IN UINT SizeOfArray, + OUT PUINT NumberOfAddresses, + IN OUT CHAR AddressArray[][FDDI_LENGTH_OF_SHORT_ADDRESS] + ); + +EXPORT +VOID +FddiQueryOpenFilterLongAddresses( + OUT PNDIS_STATUS Status, + IN PFDDI_FILTER Filter, + IN NDIS_HANDLE NdisFilterHandle, + IN UINT SizeOfArray, + OUT PUINT NumberOfAddresses, + IN OUT CHAR AddressArray[][FDDI_LENGTH_OF_LONG_ADDRESS] + ); + +EXPORT +VOID +FddiQueryOpenFilterShortAddresses( + OUT PNDIS_STATUS Status, + IN PFDDI_FILTER Filter, + IN NDIS_HANDLE NdisFilterHandle, + IN UINT SizeOfArray, + OUT PUINT NumberOfAddresses, + IN OUT CHAR AddressArray[][FDDI_LENGTH_OF_SHORT_ADDRESS] + ); + +EXPORT +VOID +FddiFilterIndicateReceive( + IN PFDDI_FILTER Filter, + IN NDIS_HANDLE MacReceiveContext, + IN PCHAR Address, + IN UINT AddressLength, + IN PVOID HeaderBuffer, + IN UINT HeaderBufferSize, + IN PVOID LookaheadBuffer, + IN UINT LookaheadBufferSize, + IN UINT PacketSize + ); + +EXPORT +VOID +FddiFilterDprIndicateReceive( + IN PFDDI_FILTER Filter, + IN NDIS_HANDLE MacReceiveContext, + IN PCHAR Address, + IN UINT AddressLength, + IN PVOID HeaderBuffer, + IN UINT HeaderBufferSize, + IN PVOID LookaheadBuffer, + IN UINT LookaheadBufferSize, + IN UINT PacketSize + ); + +EXPORT +VOID +FddiFilterIndicateReceiveComplete( + IN PFDDI_FILTER Filter + ); + +EXPORT +VOID +FddiFilterDprIndicateReceiveComplete( + IN PFDDI_FILTER Filter + ); + +#endif // _FDDI_FILTER_DEFS_ + |