Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

813 lines
21 KiB

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
dltyp.h
Abstract:
This module includes all internal typedefs and constats
of data link driver.
Author:
Antti Saarenheimo (o-anttis) 17-MAY-1991
Revision History:
--*/
#include "refcnt.h"
//
// Design notes:
// All data structures are designed at first for
// multiple clients to make the interface very clean.
// This implements also a simple kernel level interface
// of data link layer to be used by somebody that needs it.
//
struct _LLC_NDIS_PACKET;
typedef struct _LLC_NDIS_PACKET LLC_NDIS_PACKET, *PLLC_NDIS_PACKET;
struct _LLC_SAP;
typedef struct _LLC_SAP LLC_SAP, *PLLC_SAP;
struct _DATA_LINK;
typedef struct _DATA_LINK DATA_LINK, *PDATA_LINK;
struct _ADAPTER_CONTEXT;
typedef struct _ADAPTER_CONTEXT ADAPTER_CONTEXT, *PADAPTER_CONTEXT;
//
// LLC_GENERIC_OBJECT - these fields are common in all LLC objects
//
struct _LLC_GENERIC_OBJECT {
//
// DEBUG version - we have a 16-byte identifier header for consistency
// checking and to help when looking at DLC using the kernel debugger
//
// DBG_OBJECT_ID;
//
// pointer to singly-linked list of same-type structures
//
PLLC_OBJECT pNext;
//
// ObjectType - SAP, DIRECT or LINK
//
UCHAR ObjectType;
//
// EthernetType - if we have opened the adapter binding in AUTO mode then
// for SAPs and Link Stations we need to determine whether to talk 802.3
// or DIX
//
UCHAR EthernetType;
//
// usReserved - just aligns to DWORD (not necessary)
//
USHORT usReserved;
PADAPTER_CONTEXT pAdapterContext;
PBINDING_CONTEXT pLlcBinding;
//
// hClientHandle - handle to LINK object in upper layer
//
PVOID hClientHandle;
PLLC_PACKET pCompletionPackets;
ULONG ReferenceCount;
};
typedef struct _LLC_GENERIC_OBJECT LLC_GENERIC_OBJECT, *PLLC_GENERIC_OBJECT;
//
// LLC_U_RESPONSE - LLC header for U-type response frame
//
typedef struct _LLC_U_RESPONSE {
UCHAR Dsap; // Destination Service Access Point.
UCHAR Ssap; // Source Service Access Point.
UCHAR Command; // command code.
UCHAR Info[1]; // respomse table
} LLC_U_RESPONSE, *PLLC_U_RESPONSE;
//
// QUEUE_PACKET - generic doubly-linked list header
//
typedef struct _QUEUE_PACKET {
struct _QUEUE_PACKET* pNext;
struct _QUEUE_PACKET* pPrev;
} QUEUE_PACKET, *PQUEUE_PACKET;
//
// LLC_QUEUE -
//
typedef struct _LLC_QUEUE {
LIST_ENTRY ListEntry;
LIST_ENTRY ListHead; // the list head
PVOID pObject; // owner handle (used if element is linked)
} LLC_QUEUE, *PLLC_QUEUE;
//
// This information is a part of the DLC.STATISTICS
// information for a link station. The whole
// strcuture can be reseted.
//
typedef struct _LINK_STATION_STATISTICS {
USHORT I_FramesTransmitted;
USHORT I_FramesReceived;
UCHAR I_FrameReceiveErrors;
UCHAR I_FrameTransmissionErrors;
USHORT T1_ExpirationCount; // not in data xfer mode
} LINK_STATION_STATISTICS, *PLINK_STATION_STATISTICS;
typedef struct _SAP_STATISTICS {
ULONG FramesTransmitted;
ULONG FramesReceived;
ULONG FramesDiscardedNoRcv;
ULONG DataLostCounter;
} SAP_STATISTICS, *PSAP_STATISTICS;
struct _LLC_SAP {
LLC_GENERIC_OBJECT Gen;
USHORT SourceSap; // THIS MUST OVERLAY ObjectAddress
USHORT OpenOptions;
SAP_STATISTICS Statistics;
//
// KEEP THIS SAME IN SAP STATION AND GENERIC OBJECT
//
DLC_LINK_PARAMETERS DefaultParameters;
NDIS_SPIN_LOCK FlowControlLock;
PDATA_LINK pActiveLinks; // all link stations of this sap
};
struct _TIMER_TICK;
typedef struct _TIMER_TICK TIMER_TICK, *PTIMER_TICK;
typedef struct _LLC_TIMER {
struct _LLC_TIMER* pNext;
struct _LLC_TIMER* pPrev;
PTIMER_TICK pTimerTick;
ULONG ExpirationTime;
PVOID hContext;
#if defined(LOCK_CHECK)
ULONG Disabled;
#endif
} LLC_TIMER, *PLLC_TIMER;
struct _TIMER_TICK {
struct _TIMER_TICK* pNext;
// struct _TIMER_TICK* pPrev;
PLLC_TIMER pFront;
UINT DeltaTime;
USHORT Input;
USHORT ReferenceCount;
};
//
// DATA_LINK - these 'objects' are from a two level data storage. The hash table
// provides a very fast access to links, when there are less than 100 links
// (about 99 % of the cases). The binary tree keeps the search times still quite
// small, when there are very many connections from/to the same server.
//
struct _DATA_LINK {
LLC_GENERIC_OBJECT Gen;
//
// Data link station state machine variables, *2 means the value
// to be used as 2 increments, because modulo 256 is much easier
// to handle than modulo 128. UCHAR wraps around automatically.
//
SHORT Is_Ct; // Max number of I retries (Update_Va & xxx_Chkpt)
USHORT Ia_Ct; // Number of LPDU acknowledgements since Ww was incr.
UCHAR State; // current state of the finite state machine
UCHAR Ir_Ct; // LPDUs possible to send before next acknowledgement
UCHAR Vs; // *2, Send state variable (Ns of next sent LPDU)
UCHAR VsMax; // *2, Max Send state variable (Ns of next sent LPDU)
UCHAR Vr; // *2, Receive state variable( Nr of next sent LPDU)
UCHAR Pf; // value of PollFinal bit in last command
UCHAR Va; // *2, Last valid Nr received (ack state variable)
UCHAR Vp; // *2, Poll state var. (Ns of last sent cmd with P-bit)
UCHAR Vb; // Busy state (Vl, Vb, Vlb)
UCHAR Vc; // Stacked command variable (only DISC is possible)
UCHAR Vi; // initialization state variable
//
// BEGIN OF DLC_LINK_PARAMETERS (same as llc_params struct)
// DON'T TOUCH !!!!
//
UCHAR TimerT1; // Timer T1 value
UCHAR TimerT2; // Timer T2 value
UCHAR TimerTi; // Timer Ti value
UCHAR MaxOut; // *2, maximum transmit window size (MaxOut)
UCHAR RW; // maximum receive window size (MaxIn)
UCHAR Nw; // number of LPDUs acknowledged, before Ww is incr.)
UCHAR N2; // Number of retires allowed (both Polls and I LPDSs)
UCHAR AccessPrty; // access priority
USHORT MaxIField; // maximum received info field (not used in LLC)
//
// End of DLC_LINK_PARAMETERS
//
UCHAR Ww; // *2, working window size
UCHAR N3; // number of I format LPDUs between acks (with Ir_Ct)
UCHAR P_Ct; // Poll retry count
UCHAR Nr; // last Nr of the received frame
//
// Variables needed to maintain dynamic response base time for timers.
//
USHORT LastTimeWhenCmdPollWasSent;
USHORT AverageResponseTime;
UCHAR cbLanHeaderLength;
UCHAR VrDuringLocalBusy;
UCHAR Flags;
UCHAR TW; // dynamic MaxOut value
USHORT FullWindowTransmits; // succeeded Polls of full window xmits
UCHAR T1_Timeouts; // T1 timeouts after I-c1
UCHAR RemoteOpen;
//
// The link status flags contains these status bits:
//
// DLC_WAITING_RESPONSE_TO_POLL
// DLC_FIRST_POLL
// DLC_ACTIVE_REMOTE_CONECT_REQUEST
// DLC_COMMAND_POLL_PENDING_IN_NDIS;
// DLC_SEND_DISABLED
// DLC_SEND_ACTIVE
// DLC_LOCAL_BUSY_BUFFER
// DLC_LOCAL_BUSY_USER
//
//
// the timer objects
//
LLC_TIMER T1;
LLC_TIMER T2;
LLC_TIMER Ti;
LLC_QUEUE SendQueue; // untransmitted queue for the I frames
LIST_ENTRY SentQueue; // the sent but not acknowledged I- frames
PDATA_LINK pNextNode; // for the hash table
LAN802_ADDRESS LinkAddr;// 64 bit lan address of the link
PLLC_SAP pSap; // link to the SAP object of this link
DLC_STATUS_TABLE DlcStatus;
//
// Resetable link station statistics counters
//
LINK_STATION_STATISTICS Statistics;
UCHAR LastCmdOrRespSent;
UCHAR LastCmdOrRespReceived;
UCHAR Dsap; // Destination SAP
UCHAR Ssap; // Source SAP
//
// some link statistics (don't reset this)
//
ULONG BufferCommitment;
//
// FramingType - type of framing (802.3/DIX/don't care) that we should use
// for this connection. Required because in AUTO mode, the actual framing
// type may be different than that in the BINDING_CONTEXT, and since the
// BINDING_CONTEXT is per-adapter, we cannot rely on it (this whole thing
// is messed up)
//
ULONG FramingType;
//
// Network frame header (includes the full address information)
//
UCHAR auchLanHeader[1];
//
// LAN HEADER OVERFLOWS HERE !!!!
//
};
typedef struct _LLC_STATION_OBJECT {
LLC_GENERIC_OBJECT Gen;
USHORT ObjectAddress;
USHORT OpenOptions;
SAP_STATISTICS Statistics;
} LLC_STATION_OBJECT, *PLLC_STATION_OBJECT;
union _LLC_OBJECT {
//
// KEEP THIS SAME AS DIRECT AND SAP STATIONS
//
LLC_GENERIC_OBJECT Gen;
DATA_LINK Link;
LLC_SAP Sap;
LLC_STATION_OBJECT Group;
LLC_STATION_OBJECT Dix;
LLC_STATION_OBJECT Dir;
};
//*****************************************************************
typedef struct _NDIS_MAC_PACKET {
NDIS_PACKET_PRIVATE private;
UCHAR auchMacReserved[16];
} NDIS_MAC_PACKET;
struct _LLC_NDIS_PACKET {
NDIS_PACKET_PRIVATE private; // we accesss this also directly
UCHAR auchMacReserved[16];
PMDL pMdl; // MDL for LAN and LLC headers
//
// request handle and command completion handler are saved to
// the packet until NDIS has completed the command
//
PLLC_PACKET pCompletionPacket;
#if LLC_DBG
ULONG ReferenceCount;
#endif
UCHAR auchLanHeader[LLC_MAX_LAN_HEADER + sizeof(LLC_U_HEADER) + sizeof(LLC_RESPONSE_INFO)];
};
typedef struct _LLC_TRANSFER_PACKET {
NDIS_PACKET_PRIVATE private;
UCHAR auchMacReserved[16];
PLLC_PACKET pPacket;
} LLC_TRANSFER_PACKET, *PLLC_TRANSFER_PACKET;
typedef struct _EVENT_PACKET {
struct _EVENT_PACKET* pNext;
struct _EVENT_PACKET* pPrev;
PBINDING_CONTEXT pBinding;
PVOID hClientHandle;
PVOID pEventInformation;
UINT Event;
UINT SecondaryInfo;
} EVENT_PACKET, *PEVENT_PACKET;
//
// The next structure is used only in the allocating packets to the pool
//
typedef union _UNITED_PACKETS {
QUEUE_PACKET queue;
EVENT_PACKET event;
LLC_PACKET XmitPacket;
UCHAR auchLanHeader[LLC_MAX_LAN_HEADER];
} UNITED_PACKETS, *PUNITED_PACKETS;
//
// NODE_ADDRESS - 6 byte MAC address expressed as bytes or ULONG & USHORT for
// minimal comparisons/moves on 32-bit architecture
//
typedef union {
UCHAR Bytes[6];
struct {
ULONG Top4;
USHORT Bottom2;
} Words;
} NODE_ADDRESS, *PNODE_ADDRESS;
//
// FRAMING_DISCOVERY_CACHE_ENTRY - the solution to the LLC_ETHERNET_TYPE_AUTO
// problem (where we can end up proliferating TEST/XIDs and SABME/UAs) is to
// keep a cache of destinations we have 'ping'ed with TEST/XID/SABME. We send
// both frame types - DIX and 802.3. We indicate the first received response
// and create a cache entry, recording the remote MAC address and the framing
// type. If another response frame arrives from the cached MAC address with
// the other framing type, it is discarded
//
typedef struct {
NODE_ADDRESS NodeAddress; // the remote MAC address
BOOLEAN InUse; // TRUE if in use (could use TimeStamp == 0)
UCHAR FramingType; // DIX or 802.3
LARGE_INTEGER TimeStamp; // used for LRU throw-out
} FRAMING_DISCOVERY_CACHE_ENTRY, *PFRAMING_DISCOVERY_CACHE_ENTRY;
#define FRAMING_TYPE_DIX 0x1d // arbitrary value
#define FRAMING_TYPE_802_3 0x83 // " "
//
// BINDING_CONTEXT - one of these created for each client (app/open driver
// handle instance) opening the adapter. We only perform an open adapter at
// NDIS level once, which creates the ADAPTER_CONTEXT for the NDIS open
// adapter instance. Subsequent open adapter requests from processes cause
// a BINDING_CONTEXT to be created and linked to the ADAPTER_CONTEXT
//
struct _BINDING_CONTEXT {
//
// DEBUG version - we have a 16-byte identifier header for consistency
// checking and to help when looking at DLC using the kernel debugger
//
// DBG_OBJECT_ID;
//
// pointer to singly-linked list of BINDING_CONTEXT structures for this
// ADAPTER_CONTEXT
//
struct _BINDING_CONTEXT* pNext;
//
// pointer to ADAPTER_CONTEXT structure for this BINDING_CONTEXT
//
PADAPTER_CONTEXT pAdapterContext;
//
// handle of/pointer to FILE_CONTEXT structure
//
PVOID hClientContext;
//
// pointers to command completion, receive and event indication functions
//
PFLLC_COMMAND_COMPLETE pfCommandComplete;
PFLLC_RECEIVE_INDICATION pfReceiveIndication;
PFLLC_EVENT_INDICATION pfEventIndication;
//
// Functional - functional address applied to this binding by the app
//
TR_BROADCAST_ADDRESS Functional;
//
// ulFunctionalZeroBits - mask of bits which should be off for functional
// address/multicast address
//
ULONG ulFunctionalZeroBits;
//
// 0.5 second timer used for DIR.TIMER functions
//
LLC_TIMER DlcTimer;
//
// NdisMedium - the actual medium that the adapter to which we are bound talks
//
UINT NdisMedium;
//
// AddressTranslation - how the bits in addresses should be represented at
// the top and bottom edges of LLC
//
USHORT AddressTranslation;
//
// BroadCastAddress - 6 byte broadcast address treated as USHORT and ULONG
// entities. Used for checking promiscuous packets
//
USHORT usBroadcastAddress;
ULONG ulBroadcastAddress;
//
// InternalAddressTranslation -
//
USHORT InternalAddressTranslation;
//
// EthernetType - value which determines the format of an Ethernet frame.
// Different for 802.3 vs. DIX vs. ...
//
USHORT EthernetType;
//
// SwapCopiedLanAddresses - TRUE if we bit-swap LAN addresses when copying
// up or down the layers
//
BOOLEAN SwapCopiedLanAddresses;
//
// The big substructures should be in the end
// to produce optimal code for x86
//
LLC_TRANSFER_PACKET TransferDataPacket;
//
// FramingDiscoveryCacheEntries - maximum number of elements that can be
// in DiscoveryFramingCache. Will be zero if the adapter is not ethernet and
// LLC_ETHERNET_TYPE_AUTO was not requested, else number determined from
// registry or default value. Number from registry may also be 0, indicating
// caching is not to be used (old semantics)
//
ULONG FramingDiscoveryCacheEntries;
//
// FramingDiscoveryCache - if this EthernetType == LLC_ETHERNET_TYPE_AUTO,
// we create a cache of destination MAC addresses and the DIX/802.3 framing
// type they use. This array is FramingDiscoveryCacheEntries long
//
FRAMING_DISCOVERY_CACHE_ENTRY FramingDiscoveryCache[];
};
//
// ADAPTER_CONTEXT - the device context of an NDIS driver. It includes links to
// all dynamic data structures of the data link driver.
//
// This version does not support the group SAPs
//
#define LINK_HASH_SIZE 128
struct _ADAPTER_CONTEXT {
//
// DEBUG version - we have a 16-byte identifier header for consistency
// checking and to help when looking at DLC using the kernel debugger
//
// DBG_OBJECT_ID;
//
// pointer to singly-linked list of ADAPTER_CONTEXT structures opened by
// all clients of this driver
//
struct _ADAPTER_CONTEXT* pNext;
#if !defined(DLC_UNILOCK)
NDIS_SPIN_LOCK SendSpinLock; // locked when accessing send queues
NDIS_SPIN_LOCK ObjectDataBase; // used also with sap/direct create
#endif
PLLC_STATION_OBJECT pDirectStation; // link list of direct stations
PBINDING_CONTEXT pBindings; // link list of all bindings
NDIS_HANDLE NdisBindingHandle;
PVOID hLinkPool; // pool for link station structs
PVOID hPacketPool; // pool for usr/small LLC packets
//
// circular link list is free NDIS packets for send (initially maybe 5)
//
PLLC_NDIS_PACKET pNdisPacketPool;
NDIS_HANDLE hNdisPacketPool;
//
// Some stuff for asynchronous receive indications
//
PVOID hReceiveCompletionRequest;
PLLC_PACKET pResetPackets;
//
// pHeadBuf - pointer to the MAC header buffer, containing:
//
// FDDI:
// 1 Byte Frame Control (FDDI)
// 6 Bytes Destination MAC Address (ALL)
// 6 Bytes Source MAC Address (ALL)
//
// Token Ring:
// 1 Byte Access Control (Token Ring)
// 1 Byte Frame Control (Token Ring)
// 6 Bytes Destination MAC Address (ALL)
// 6 Bytes Source MAC Address (ALL)
// 0-18 Bytes Source Routing
//
// Ethernet:
// 6 Bytes Destination MAC Address (ALL)
// 6 Bytes Source MAC Address (ALL)
// 2 Bytes Length or DIX Type
//
PUCHAR pHeadBuf;
//
// cbHeadBuf - number of bytes in pHeadBuf
//
UINT cbHeadBuf;
//
// pLookBuf - pointer to the MAC look-ahead buffer which contains the rest
// of the data for this frame or as much as the MAC could fit into the look
// ahead buffer (in which case NdisTransferData must be used to get the
// rest)
//
PUCHAR pLookBuf;
//
// cbLookBuf - number of bytes in pLookBuf
//
UINT cbLookBuf;
//
// cbPacketSize - actual size of the whole frame. Calculated from information
// in the header or supplied by the MAC, depending on the medium
//
UINT cbPacketSize;
//
// IsSnaDixFrame - true if the frame just received (on ethernet) is a DIX
// frame and the DIX identifier is 0x80D5 (big-endian)
//
UINT IsSnaDixFrame;
LAN802_ADDRESS Adapter;
ULONG MaxFrameSize;
ULONG LinkSpeed;
//
// We use UINTs, because (Move mem, ULONG) may not be an
// atomic operation (in theory)
//
UINT NdisMedium;
UINT XidTestResponses;
ULONG ObjectCount; // must be zero, when adapter closed
//
// ConfigInfo - holds the SwapAddressBits and UseDixOverEthernet flags and
// the timer tick values
//
ADAPTER_CONFIGURATION_INFO ConfigInfo;
//
// the original node addresses
//
ULONG ulBroadcastAddress;
USHORT usBroadcastAddress;
USHORT BackgroundProcessRequests;
UCHAR NodeAddress[6]; // Current network format
USHORT cbMaxFrameHeader;
UCHAR PermanentAddress[6];
USHORT OpenOptions;
USHORT AddressTranslationMode;
USHORT FrameType;
USHORT usRcvMask;
USHORT EthernetType;
USHORT RcvLanHeaderLength;
USHORT BindingCount;
USHORT usHighFunctionalBits;
//
// Keep UCHAR alignment
//
BOOLEAN boolTranferDataNotComplete;
BOOLEAN IsDirty;
BOOLEAN ResetInProgress;
UCHAR Unused1;
#ifndef NDIS40
// Not used.
UCHAR AdapterNumber;
#endif // NDIS40
UCHAR IsBroadcast;
BOOLEAN SendProcessIsActive;
BOOLEAN LlcPacketInSendQueue;
//
// We keep the big structures and tables in the end,
// that makes most x86 offsets 1 byte instead of 4.
// The compiler aligns the fields naturally, whenever
// it is necessary.
//
//
// the next elements will be linked to circular
// end process link list, if there are any frames to send
//
LIST_ENTRY NextSendTask; // pointer to active sends
LIST_ENTRY QueueEvents;
LIST_ENTRY QueueCommands;
LLC_QUEUE QueueI;
LLC_QUEUE QueueDirAndU;
LLC_QUEUE QueueExpidited;
UNICODE_STRING Name; // current adapter name
PTIMER_TICK pTimerTicks;
NDIS_STATUS AsyncOpenStatus; // used to wait async open
NDIS_STATUS AsyncCloseResetStatus; // used to wait async close
NDIS_STATUS OpenCompleteStatus; // used to wait the first open
NDIS_STATUS LinkRcvStatus; // link state machine ret status
NDIS_STATUS NdisRcvStatus; // NdisRcvIndication ret status
NDIS_STATUS OpenErrorStatus; // special adapter open status
//
// NDIS calls back when adapter open completes. Use a Kernel Event to
// synchronize LLC with NDIS
//
KEVENT Event;
//
// the following are reasonably large arrays (like 256 pointers to SAP
// objects...)
//
PLLC_SAP apSapBindings[256]; // the clients bound to the SAPs
PDATA_LINK aLinkHash[LINK_HASH_SIZE]; // hash table to links
PLLC_STATION_OBJECT aDixStations[MAX_DIX_TABLE];
LLC_TRANSFER_PACKET TransferDataPacket;
#if DBG
//
// memory usage counters for memory owned by this ADAPTER_CONTEXT
//
MEMORY_USAGE MemoryUsage;
MEMORY_USAGE StringUsage;
#endif
#ifdef NDIS40
#define BIND_STATE_UNBOUND 1
#define BIND_STATE_UNBINDING 2
#define BIND_STATE_BOUND 3
LONG BindState;
REF_CNT AdapterRefCnt;
KEVENT CloseAdapterEvent;
#endif // NDIS40
};
typedef PLLC_PACKET (*PF_GET_PACKET)(IN PADAPTER_CONTEXT pAdapterContext);