|
|
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
mac.h
Abstract:
This header file defines manifest constants and necessary macros for use by transports dealing with multiple MAC cards through the NDIS interface.
Author:
David Beaver (dbeaver) 02-Oct-1990
Revision History:
--*/
#ifndef _MAC_
#define _MAC_
//
// MAC-specific definitions, some of which get used below
//
#define MAX_MAC_HEADER_LENGTH 32
#define MAX_SOURCE_ROUTING 18
#define MAX_DEFAULT_SR 2
#define ETHERNET_ADDRESS_LENGTH 6
#define ETHERNET_PACKET_LENGTH 1514 // max size of an ethernet packet
#define ETHERNET_HEADER_LENGTH 14 // size of the ethernet MAC header
#define ETHERNET_DATA_LENGTH_OFFSET 12
#define ETHERNET_DESTINATION_OFFSET 0
#define ETHERNET_SOURCE_OFFSET 6
#define TR_ADDRESS_LENGTH 6
#define TR_ADDRESS_OFFSET 2
#define TR_SPECIFIC_OFFSET 0
#define TR_PACKET_LENGTH 1514 // max size of a TR packet
#define TR_HEADER_LENGTH 36 // size of the MAC header w/o source routing
#define TR_DATA_LENGTH_OFFSET 0
#define TR_DESTINATION_OFFSET 2
#define TR_SOURCE_OFFSET 8
#define TR_ROUTING_OFFSET 14 // starts at the 14th byte
#define TR_GR_BCAST_LENGTH 2
#define TR_GR_BROADCAST 0xC270 // what a general route b'cast looks like
#define TR_ROUTING_LENGTH_MASK 0x1F // low 5 bits in byte
#define TR_DIRECTION_MASK 0x80 // returns direction bit
#define TR_PREAMBLE_AC 0x10 // how would these be specified?
#define TR_PREAMBLE_FC 0x40
#define TR_HEADER_BYTE_0 0x10
#define TR_HEADER_BYTE_1 0x40
#define FDDI_ADDRESS_LENGTH 6
#define FDDI_HEADER_BYTE 0x57
//
// We need this to define information about the MAC. Note that
// it is a strange structure in that the first four elements
// are for use internally by the nbfmac routines, while the
// DeviceContext knows about and uses the last two.
//
typedef struct _NBF_NDIS_IDENTIFICATION { NDIS_MEDIUM MediumType; BOOLEAN SourceRouting; BOOLEAN MediumAsync; BOOLEAN QueryWithoutSourceRouting; BOOLEAN AllRoutesNameRecognized; ULONG DestinationOffset; ULONG SourceOffset; ULONG AddressLength; ULONG TransferDataOffset; ULONG MaxHeaderLength; BOOLEAN CopyLookahead; BOOLEAN ReceiveSerialized; BOOLEAN TransferSynchronous; BOOLEAN SingleReceive; } NBF_NDIS_IDENTIFICATION, *PNBF_NDIS_IDENTIFICATION;
VOID MacConstructHeader( IN PNBF_NDIS_IDENTIFICATION MacInfo, IN PUCHAR Buffer, IN PUCHAR DestinationAddress, IN PUCHAR SourceAddress, IN UINT PacketLength, IN PUCHAR SourceRouting, IN UINT SourceRoutingLength, OUT PUINT HeaderLength );
VOID MacReturnMaxDataSize( IN PNBF_NDIS_IDENTIFICATION MacInfo, IN PUCHAR SourceRouting, IN UINT SourceRoutingLength, IN UINT DeviceMaxFrameSize, IN BOOLEAN AssumeWorstCase, OUT PUINT MaxFrameSize );
VOID MacInitializeMacInfo( IN NDIS_MEDIUM MacType, IN BOOLEAN UseDix, OUT PNBF_NDIS_IDENTIFICATION MacInfo );
extern UCHAR SingleRouteSourceRouting[]; extern UCHAR GeneralRouteSourceRouting[]; extern ULONG DefaultSourceRoutingLength;
//++
//
// VOID
// MacReturnDestinationAddress(
// IN PNBF_NDIS_IDENTIFICATION MacInfo,
// IN PVOID Packet,
// OUT PVOID * DestinationAddress
// );
//
// Routine Description:
//
// Returns the a pointer to the destination address in the packet.
//
// Arguments:
//
// MacInfo - Describes the MAC we wish to decode.
//
// Packet - The packet data.
//
// DestinationAddress - Returns the start of the destination address.
//
// Return Value:
//
// None.
//
//--
#define MacReturnDestinationAddress(_MacInfo, _Packet, _DestinationAddress) \
*(_DestinationAddress) = ((PUCHAR)(_Packet)) + (_MacInfo)->DestinationOffset
//++
//
// VOID
// MacReturnSourceAddress(
// IN PNBF_NDIS_IDENTIFICATION MacInfo,
// IN PVOID Packet,
// OUT PHARDWARE_ADDRESS SourceAddressBuffer,
// OUT PHARDWARE_ADDRESS * SourceAddress,
// OUT BOOLEAN * Multicast OPTIONAL
// );
//
// Routine Description:
//
// Copies the source address in the packet into SourceAddress.
// NOTE THAT IT MAY COPY THE DATA, UNLIKE ReturnDestinationAddress
// AND ReturnSourceRouting. Optionally, indicates whether the
// destination address is a multicast address.
//
// Arguments:
//
// MacInfo - Describes the MAC we wish to decode.
//
// Packet - The packet data.
//
// SourceAddressBuffer - A buffer to hold the source address,
// if needed.
//
// SourceAddress - Returns a pointer to the source address.
//
// Multicast - Optional pointer to a BOOLEAN to receive indication
// of whether the destination was a multicast address.
//
// Return Value:
//
// None.
//
//--
//
// NOTE: The default case below handles Ethernet and FDDI.
//
#define MacReturnSourceAddress(_MacInfo, _Packet, _SourceAddressBuffer, \
_SourceAddress, _Multicast) \ { \ PUCHAR TmpPacket = (PUCHAR)(_Packet); \ PUCHAR SrcBuffer = (PUCHAR)(_SourceAddressBuffer); \ \ switch ((_MacInfo)->MediumType) { \ case NdisMedium802_5: \ if (ARGUMENT_PRESENT(_Multicast)) { \ *(PBOOLEAN)(_Multicast) = TmpPacket[2] & 0x80; \ } \ if (TmpPacket[8] & 0x80) { \ *(PULONG)SrcBuffer = *(ULONG UNALIGNED *)(&TmpPacket[8]) & ~0x80;\ SrcBuffer[4] = TmpPacket[12]; \ SrcBuffer[5] = TmpPacket[13]; \ *(_SourceAddress) = (PHARDWARE_ADDRESS)SrcBuffer; \ } else { \ *(_SourceAddress) = (PHARDWARE_ADDRESS)(TmpPacket + 8); \ } \ break; \ default: \ if (ARGUMENT_PRESENT(_Multicast)) { \ *(PBOOLEAN)(_Multicast) = TmpPacket[0] & 0x01; \ } \ *(_SourceAddress) = (PHARDWARE_ADDRESS)(TmpPacket + \ (_MacInfo)->SourceOffset); \ break; \ } \ }
//++
//
// VOID
// MacReturnSourceRouting(
// IN PNBF_NDIS_IDENTIFICATION MacInfo,
// IN PVOID Packet,
// OUT PVOID * SourceRouting
// OUT PUINT SourceRoutingLength
// );
//
// Routine Description:
//
// Returns the a pointer to the source routing info in the packet.
//
// Arguments:
//
// MacInfo - Describes the MAC we wish to decode.
//
// Packet - The packet data.
//
// SourceRouting - Returns the start of the source routing information,
// or NULL if none is present.
//
// SourceRoutingLength - Returns the length of the source routing
// information.
//
// Return Value:
//
// None.
//
//--
#define MacReturnSourceRouting(_MacInfo, _Packet, _SourceRouting, _SourceRoutingLength) \
{ \ PUCHAR TmpPacket = (PUCHAR)(_Packet); \ *(_SourceRoutingLength) = 0; \ if ((_MacInfo)->SourceRouting) { \ if (TmpPacket[8] & 0x80) { \ *(_SourceRouting) = TmpPacket + 14; \ *(_SourceRoutingLength) = TmpPacket[14] & 0x1f; \ } else { \ *(_SourceRouting) = NULL; \ } \ } else { \ *(_SourceRouting) = NULL; \ } \ }
//++
//
// VOID
// MacIsMulticast(
// IN PNBF_NDIS_IDENTIFICATION MacInfo,
// IN PVOID Packet,
// OUT PBOOLEAN Multicast
// );
//
// Routine Description:
//
// Returns TRUE if the packet is sent to the multicast address.
//
// Arguments:
//
// MacInfo - Describes the MAC we wish to decode.
//
// Packet - The packet data.
//
// Multicast - Returns the result.
//
// Return Value:
//
// None.
//
//--
#define MacIsMulticast(_MacInfo, _Packet, _Multicast) \
{ \ PUCHAR TmpPacket = (PUCHAR)(_Packet); \ \ switch ((_MacInfo)->MediumType) { \ case NdisMedium802_5: \ *(_Multicast) = ((TmpPacket[2] & 0x80) != 0); \ break; \ default: \ *(_Multicast) = ((TmpPacket[0] & 0x01) != 0); \ break; \ } \ }
//++
//
// VOID
// MacReturnPacketLength(
// IN PNBF_NDIS_IDENTIFICATION MacInfo,
// IN PVOID Header,
// IN UINT PacketLength,
// OUT PUINT DataLength
// );
//
// Routine Description:
//
// Returns the length of data in the packet given the header.
//
// Arguments:
//
// MacInfo - Describes the MAC we wish to decode.
//
// Header - The packet header.
//
// PacketLength - The length of the data (not including header).
//
// DataLength - Returns the length of the data. Unchanged if the
// packet is not recognized. Should be initialized by caller to 0.
//
// Return Value:
//
// None.
//
//--
#define MacReturnPacketLength(_MacInfo, _Header, _HeaderLength, _PacketLength, _DataLength, _LookaheadBuffer, _LookaheadBufferLength) \
{ \ PUCHAR TmpPacket = (PUCHAR)(_Header); \ UINT TmpLength; \ \ switch ((_MacInfo)->MediumType) { \ case NdisMedium802_3: \ if ((_HeaderLength) >= 14) { \ TmpLength = (TmpPacket[12] << 8) | TmpPacket[13]; \ if (TmpLength <= 0x600) { \ if (TmpLength <= (_PacketLength)) { \ *(_DataLength) = TmpLength; \ } \ } \ } \ break; \ case NdisMedium802_5: \ if (((_HeaderLength) >= 14) && \ (!(TmpPacket[8] & 0x80) || \ ((_HeaderLength) >= \ (UINT)(14 + (TmpPacket[14] & 0x1f))))) { \ *(_DataLength) = (_PacketLength); \ } \ break; \ case NdisMediumFddi: \ if ((_HeaderLength) >= 13) { \ *(_DataLength) = (_PacketLength); \ } \ break; \ case NdisMediumDix: \ if ((TmpPacket[12] == 0x80) && (TmpPacket[13] == 0xd5)) { \ if (*(_LookaheadBufferLength) >= 3) { \ TmpPacket = (PUCHAR)(*(_LookaheadBuffer)); \ TmpLength = (TmpPacket[0] << 8) | TmpPacket[1]; \ if (TmpLength <= (_PacketLength)-3) { \ *(_DataLength) = TmpLength; \ *(_LookaheadBuffer) = (PVOID)(TmpPacket + 3); \ *(_LookaheadBufferLength) -= 3; \ } \ } \ } \ break; \ } \ }
//++
//
// VOID
// MacReturnHeaderLength(
// IN PNBF_NDIS_IDENTIFICATION MacInfo,
// IN PVOID Packet,
// OUT PVOID HeaderLength,
// );
//
// Routine Description:
//
// Returns the length of the MAC header in a packet (this
// is used for loopback indications to separate header
// and data).
//
// Arguments:
//
// MacInfo - Describes the MAC we wish to decode.
//
// Header - The packet header.
//
// HeaderLength - Returns the length of the header.
//
// Return Value:
//
// None.
//
//--
#define MacReturnHeaderLength(_MacInfo, _Header, _HeaderLength) \
{ \ PUCHAR TmpPacket = (PUCHAR)(_Header); \ \ switch ((_MacInfo)->MediumType) { \ case NdisMedium802_3: \ case NdisMediumDix: \ *(_HeaderLength) = 14; \ break; \ case NdisMedium802_5: \ if (TmpPacket[8] & 0x80) { \ *(_HeaderLength) = (TmpPacket[14] & 0x1f) + 14; \ } else { \ *(_HeaderLength) = 14; \ } \ break; \ case NdisMediumFddi: \ *(_HeaderLength) = 13; \ break; \ } \ }
//++
//
// VOID
// MacReturnSingleRouteSR(
// IN PNBF_NDIS_IDENTIFICATION MacInfo,
// OUT PVOID * SingleRouteSR,
// OUT PUINT SingleRouteSRLength
// );
//
// Routine Description:
//
// Returns the a pointer to the standard single route broadcast
// source routing information for the media type. This is used
// for ADD_NAME_QUERY, DATAGRAM, NAME_IN_CONFLICT, NAME_QUERY,
// and STATUS_QUERY frames.
//
// Arguments:
//
// MacInfo - Describes the MAC we wish to decode.
//
// SingleRouteSR - Returns a pointer to the data.
//
// SingleRouteSRLength - The length of SingleRouteSR.
//
// Return Value:
//
// None.
//
//--
#define MacReturnSingleRouteSR(_MacInfo, _SingleRouteSR, _SingleRouteSRLength) \
{ \ switch ((_MacInfo)->MediumType) { \ case NdisMedium802_5: \ *(_SingleRouteSR) = SingleRouteSourceRouting; \ *(_SingleRouteSRLength) = DefaultSourceRoutingLength; \ break; \ default: \ *(_SingleRouteSR) = NULL; \ break; \ } \ }
//++
//
// VOID
// MacReturnGeneralRouteSR(
// IN PNBF_NDIS_IDENTIFICATION MacInfo,
// OUT PVOID * GeneralRouteSR,
// OUT PUINT GeneralRouteSRLength
// );
//
// Routine Description:
//
// Returns the a pointer to the standard general route broadcast
// source routing information for the media type. This is used
// for NAME_RECOGNIZED frames.
//
// Arguments:
//
// MacInfo - Describes the MAC we wish to decode.
//
// GeneralRouteSR - Returns a pointer to the data.
//
// GeneralRouteSRLength - The length of GeneralRouteSR.
//
// Return Value:
//
// None.
//
//--
#define MacReturnGeneralRouteSR(_MacInfo, _GeneralRouteSR, _GeneralRouteSRLength) \
{ \ switch ((_MacInfo)->MediumType) { \ case NdisMedium802_5: \ *(_GeneralRouteSR) = GeneralRouteSourceRouting; \ *(_GeneralRouteSRLength) = DefaultSourceRoutingLength; \ break; \ default: \ *(_GeneralRouteSR) = NULL; \ break; \ } \ }
#if 0
//++
//
// VOID
// MacCreateGeneralRouteReplySR(
// IN PNBF_NDIS_IDENTIFICATION MacInfo,
// IN PUCHAR ExistingSR,
// IN UINT ExistingSRLength,
// OUT PUCHAR * NewSR
// );
//
// Routine Description:
//
// This modifies an existing source routing entry to make
// it into a general-route source routing entry. The assumption
// is that is to reply to existing source routing, so the
// direction bit is also reversed. In addition, if it is
// determined that no source routing is needed in the reply,
// then NULL is returned.
//
// Note that the information is modified in-place, but a
// separate pointer is returned (to allow NULL to be returned).
//
// Arguments:
//
// MacInfo - Describes the MAC we wish to decode.
//
// ExistingSR - The existing source routing to be modified.
//
// Return Value:
//
// None.
//
//--
#define MacCreateGeneralRouteReplySR(_MacInfo, _ExistingSR, _ExistingSRLength, _NewSR) \
{ \ if (_ExistingSR) { \ PUCHAR TmpSR = (PUCHAR)(_ExistingSR); \ switch ((_MacInfo)->MediumType) { \ case NdisMedium802_5: \ TmpSR[0] = (TmpSR[0] & 0x1f) | 0x80; \ TmpSR[1] = (TmpSR[1] ^ 0x80); \ *(_NewSR) = (_ExistingSR); \ break; \ default: \ *(_NewSR) = (_ExistingSR); \ break; \ } \ } else { \ *(_NewSR) = NULL; \ } \ } #endif
//++
//
// VOID
// MacCreateNonBroadcastReplySR(
// IN PNBF_NDIS_IDENTIFICATION MacInfo,
// IN PUCHAR ExistingSR,
// IN UINT ExistingSRLength,
// OUT PUCHAR * NewSR
// );
//
// Routine Description:
//
// This modifies an existing source routing entry to make
// it into a non-broadcast source routing entry. The assumption
// is that is to reply to existing source routing, so the
// direction bit is also reversed. In addition, if it is
// determined that no source routing is needed in the reply,
// then NULL is returned.
//
// Note that the information is modified in-place, but a
// separate pointer is returned (to allow NULL to be returned).
//
// Arguments:
//
// MacInfo - Describes the MAC we wish to decode.
//
// ExistingSR - The existing source routing to be modified.
//
// Return Value:
//
// None.
//
//--
#define MacCreateNonBroadcastReplySR(_MacInfo, _ExistingSR, _ExistingSRLength, _NewSR) \
{ \ if (_ExistingSR) { \ PUCHAR TmpSR = (PUCHAR)(_ExistingSR); \ switch ((_MacInfo)->MediumType) { \ case NdisMedium802_5: \ if ((_ExistingSRLength) == 2) { \ *(_NewSR) = NULL; \ } else { \ TmpSR[0] = (TmpSR[0] & 0x1f); \ TmpSR[1] = (TmpSR[1] ^ 0x80); \ *(_NewSR) = (_ExistingSR); \ } \ break; \ default: \ *(_NewSR) = (_ExistingSR); \ break; \ } \ } else { \ *(_NewSR) = NULL; \ } \ }
//++
//
// VOID
// MacModifyHeader(
// IN PNBF_NDIS_IDENTIFICATION MacInfo,
// IN PUCHAR Header,
// IN UINT PacketLength
// );
//
// Routine Description:
//
// Modifies a pre-built packet header to include the
// packet length. Used for connection-oriented traffic
// where the header is pre-built.
//
// Arguments:
//
// MacInfo - Describes the MAC we wish to decode.
//
// Header - The header to modify.
//
// PacketLength - Packet length (not including the header).
// Currently this is the only field that cannot be pre-built.
//
// Return Value:
//
// None.
//
//--
#define MacModifyHeader(_MacInfo, _Header, _PacketLength) \
{ \ switch ((_MacInfo)->MediumType) { \ case NdisMedium802_3: \ (_Header)[12] = (UCHAR)((_PacketLength) >> 8); \ (_Header)[13] = (UCHAR)((_PacketLength) & 0xff); \ break; \ case NdisMediumDix: \ (_Header)[14] = (UCHAR)((_PacketLength) >> 8); \ (_Header)[15] = (UCHAR)((_PacketLength) & 0xff); \ break; \ } \ }
//++
//
// VOID
// MacReturnMagicAddress(
// IN PNBF_NDIS_IDENTIFICATION MacInfo,
// IN PVOID Address,
// OUT PULARGE_INTEGER Magic
// );
//
// Routine Description:
//
// MacReturnMagicAddress returns the link as a 64 bit number.
// We then find the link in the link trees by doing a large
// integer comparison.
//
// The number is constructed by assigning the last four bytes of
// the address as the low longword, and the first two bytes as
// the high one. For 802_5 we need to mask off the source routing
// bit in byte 0 of the address.
//
// Arguments:
//
// MacInfo - Describes the MAC we wish to decode.
//
// Address - The address we are encoding.
//
// Magic - Returns the magic number for this address.
//
// Return Value:
//
// None.
//
//--
#define MacReturnMagicAddress(_MacInfo, _Address, _Magic) \
{ \ PUCHAR TempAddr = (PUCHAR)(_Address); \ \ (_Magic)->LowPart = *((LONG UNALIGNED *)(TempAddr + 2)); \ if ((_MacInfo)->MediumType == NdisMedium802_5) { \ (_Magic)->HighPart = ((TempAddr[0] & 0x7f) << 8) + TempAddr[1]; \ } else { \ (_Magic)->HighPart = (TempAddr[0] << 8) + TempAddr[1]; \ } \ }
VOID MacSetNetBIOSMulticast ( IN NDIS_MEDIUM Type, IN PUCHAR Buffer );
// VOID
// NbfSetNdisPacketLength (
// IN NDIS_PACKET Packet,
// IN ULONG Length
// );
//
// NB: This is not a general purpose macro; it assumes that we are setting the
// length of an NDIS packet with only one NDIS_BUFFER chained. We do
// this to save time during the sending of short control packets.
//
#define NbfSetNdisPacketLength(_packet,_length) { \
PNDIS_BUFFER NdisBuffer; \ NdisQueryPacket((_packet), NULL, NULL, &NdisBuffer, NULL); \ NdisAdjustBufferLength(NdisBuffer, (_length)); \ NdisRecalculatePacketCounts(_packet); \ }
#endif // ifdef _MAC_
|