NDIS_PACKET_OOB_DATA structure

Note   NDIS 5. x has been deprecated and is superseded by NDIS 6. x. For new NDIS driver development, see Network Drivers Starting with Windows Vista. For information about porting NDIS 5. x drivers to NDIS 6. x, see Porting NDIS 5.x Drivers to NDIS 6.0.

The NDIS_PACKET_OOB_DATA structure specifies out-of-band information associated with a packet descriptor, used by drivers whose media supplies, requires, or accepts out-of-band information, such as information for an ATM NIC, and by drivers that support multipacket receives and/or sends.

Syntax

typedef struct _NDIS_PACKET_OOB_DATA {
  union {
    ULONGLONG TimeToSend;
    ULONGLONG TimeSent;
  };
  ULONGLONG   TimeReceived;
  UINT        HeaderSize;
  UINT        SizeMediaSpecificInfo;
  PVOID       MediaSpecificInformation;
  NDIS_STATUS Status;
} NDIS_PACKET_OOB_DATA, *PNDIS_PACKET_OOB_DATA;

Members

  • TimeToSend
    Specifies the time, in system time units, at which a given packet should be transmitted over the network.

    Protocols can set this timestamp before passing an array of packet descriptor pointers to NdisSendPackets or a packet descriptor pointer to NdisSend.

    The MiniportSendPackets or MiniportSend functions of underlying drivers can retrieve the value of this timestamp to determine when the given packet(s) should be transmitted over the network. Usually, only the lowest-level underlying driver retrieves this timestamp.

  • TimeSent
    Specifies the time, in system time units, at which a received packet was transmitted over the network from a remote node.

    NIC drivers and, possibly, intermediate drivers that export only a set of MiniportXxx functions set this timestamp before indicating receive packet(s).

    The ProtocolReceivePacket functions of drivers bound above such a miniport driver can retrieve the value of this timestamp to determine when any particular packet was transmitted from the remote node. If the ProtocolReceive function is given an indication and the underlying driver sets this timestamp, ProtocolReceive can call NdisGetReceivedPacket and NDIS_GET_ORIGINAL_PACKET to retrieve the packet that contains this timestamp.

  • TimeReceived
    Specifies the time, in system time units, at which a given packet from a remote node on the network was received on the NIC.

    NIC drivers and, possibly, intermediate drivers that export only a set of MiniportXxx functions set this timestamp before calling NdisMIndicateReceivePacket with a packet array, which can have one or more pointers to packet descriptors.

    The ProtocolReceivePacket functions of drivers bound above any such miniport driver can retrieve the value of this timestamp to determine when the given packet(s) were received. If the ProtocolReceive function is given an indication and the underlying driver sets this timestamp, ProtocolReceive can call NdisGetReceivedPacket and NDIS_GET_ORIGINAL_PACKET to retrieve the packet that contains this timestamp.

  • HeaderSize
    Specifies the size in bytes of the medium-specific header contained in the buffer mapped by the initial buffer descriptor chained to the packet descriptor.

    Lower-level drivers set this member for subsequent receive indication(s) according to the medium each driver's MiniportInitialize function elected to support.

    The ProtocolReceivePacket functions of drivers bound above such a miniport driver can retrieve the value of this member to determine how to process the medium-specific net packet.

  • SizeMediaSpecificInfo
    Specifies the size in bytes of the buffer at MediaSpecificInformation.

    A driver must set this member if it supplies out-of-band information with a packet to be sent or indicated.

  • MediaSpecificInformation
    Specifies the address of a driver-allocated buffer. This buffer contains any out-of-band data, such as information for an ATM NIC, that accompanies the net packet specified with the packet descriptor. The out-of-band data has been set up either by the allocating protocol for a send or by the allocating miniport driver for a receive indication.

    Either type of driver can retrieve the address of the out-of-band data buffer and its size to determine how to process or interpret the send or receive specified with the incoming packet descriptor. If the ProtocolReceive function is given an indication and the underlying driver supplies this information, ProtocolReceive can call NdisGetReceivedPacket and NDIS_GET_ORIGINAL_PACKET to retrieve the packet that contains the virtual range of this buffer.

  • Status
    Specifies the current status of the packet descriptor and the ownership of all driver-allocated resources specified with the packet descriptor.

    Only lower-level drivers and NDIS set this member.

    In the Receive Path

    A miniport driver can set this member before it calls NdisMIndicateReceivePacket to indicate how soon it needs to regain ownership of its allocated resources specified in the associated packet descriptor(s). A serialized can retrieve this value on return from NdisMIndicateReceivePacket to determine whether the resources specified with the packet descriptor for its indication can be prepared for reuse immediately. A deserialized or connection-oriented miniport, however, does not have to check this value on return from NdisMCoIndicateReceivePacket.

    In the Send Path

    A serialized miniport driver can set this member in its MiniportSendPackets function to complete an incoming send immediately, to notify NDIS that it will complete the request asynchronously, or to request that NDIS requeue some or all of the incoming packet array and resubmit those packet descriptor(s) to MiniportSendPackets later.

    A protocol cannot retrieve this value to determine the completion status of a send on return from its call to NdisSendPackets or NdisSend.

    A deserialized or connection-oriented miniport driver cannot complete a multipacket send synchronously or request (by setting the Status member) that NDIS requeue some or all of an incoming packet array. Instead, a deserialized or connection-oriented miniport driver must queue internally the entire incoming packet array if it cannot send the data immediately and must always complete a multipacket send asynchronously with NdisMSendComplete(or NdisMCoSendComplete) for each packet in the array.

Using Timestamps

All timestamps set in the NDIS_PACKET_OOB_DATA blocks associated with packet descriptors are expressed in system time units as the number of 100-nanosecond intervals since 12:00 a.m., January 1, 1601.

NDIS drivers can call NdisGetCurrentSystemTimewhen they set these timestamps with the NDIS_SET_PACKET_TIME_XXX macros. Still higher-level drivers or system components can convert these timestamps into locale-specific values more meaningful to the end user.

Supplying Out-of-Band Information with Packets

Any out-of-band information specified in the SizeMediaSpecificInfoand MediaSpecificInformationmembers is medium-type-specific. For example, some types of media require protocols to specify a packet priority for each packet they send and require NIC drivers to specify a packet priority with each receive packet they indicate. Such a NIC driver must call NdisMIndicateReceivePacketor NdisMCoIndicateReceivePacketto fulfill the requirements of these types of media.

While NDIS provides support for a range of priority values from zero through seven, some media support only two levels of priority. For these types of media, NDIS drivers should map values zero through three to the medium-specific normal priority value (usually zero for such media types) and values four through seven to the medium-specific, high-priority value (usually one for such media types).

The structure of individual records within the buffer at MediaSpecificInformationis defined as follows:

typedef struct     MediaSpecificInformation {
  UINT  NextEntryOffset;
  NDIS_CLASS_ID  ClassId;
  UINT  Size;
  UCHAR  ClassInformation[1];
} MEDIA_SPECIFIC_INFORMATION;

The members of this structure contain the following information:

  • NextEntryOffset
    Specifies the byte offset to this member in the next record, if any. Zero indicates this is the last record in the buffer; the values of all remaining members in the last record are also zero. The value of this member must be quad-aligned.

  • ClassId
    Specifies the type of the record. Possible values are one of the following:

    • NdisClass802_3Priority
      This value is no longer used. Per-packet priority is a member of the array that is contained in a NDIS_PACKET_EXTENSION structure. Drivers should use the NDIS_PER_PACKET_INFO_FROM_PACKET macro to access packet priority from a packet descriptor. Alternatively, drivers can use the NDIS_PACKET_EXTENSION_FROM_PACKET macro to access packet priority from a packet descriptor.

    • NdisClassWirelessWanMbxMailbox
      The underlying NIC driver examines the ULONG-sized record at ClassInformation to determine whether the mailbox flag should be set for the associated packet. (1 = set mailbox flag, 0 = do not set mailbox flag)

    • NdisClassIrdaPacketInfo
      An underlying IrDA NIC driver examines the NDIS_IRDA_PACKET_INFO structure at ClassInformation to determine the number of extra Beginning of Frame (BOF) flags that it must add to a frame to be transmitted and the minimum time (in microseconds) that it must wait after receiving a transmission before its NIC can start transmitting.

      The NDIS_IRDA_PACKET_INFO structure is defined as follows:

      typedef struct _NDIS_IRDA_PACKET_INFO
      {
          UINT  ExtraBOFs
          UNIT  MinTurnAroundTime;
      } NDIS_IRDA_PACKET_INFO, *PNDIS_IRDA_PACKET_INFO;
      
    • NdisClassAtmAALInfo
      Before sending a packet to an underlying NDIS driver for an ATM NIC, a protocol driver sets the appropriate information in the ATM_AAL_OOB_INFO structure at ClassInformation.

      The ATM_AAL_OOB_INFO structure is defined as follows:

      typedef struct _ATM_AAL_OOB_INFO
      {
          ATM_AAL_TYPE AalType;
          union
          {
              struct _ATM_AAL5_INFO
              {
                  BOOLEAN  CellLossPriority;
                  UCHAR    UserToUserIndication;
                  UCHAR    CommonPartIndicator;
              } ATM_AAL5_INFO;
      
              struct _ATM_AAL0_INFO
              {
                  BOOLEAN  CellLossPriority;
                  UCHAR    PayLoadTypeIdentifier;
              } ATM_AAL0_INFO;
          };
      } ATM_AAL_OOB_INFO, *PATM_AAL_OOB_INFO;
      

      When sending an AAL5 packet, the protocol sets the members of the ATM_AAL5_INFO structure ( CellLossPriority, UserToUserIndication, and CommonPartIndicator) to the values to which the miniport driver should set the corresponding fields of the ATM packet header. When sending an AAL0 packet, the protocol sets the members of the ATM_AAL0_INFO structure ( CellLossPriority and CommonPartIndicator) to the values to which the miniport driver should set the corresponding fields of the ATM cell header.

      The underlying driver examines the ATM_AAL_OOB_INFO structure to obtain values for fields in the AAL5 packet header or the AAL0 cell header.

  • Size
    Specifies the number of bytes in the ClassInformation array, including any padding necessary to align the NextEntryOffset of the next record on a four-byte boundary.

  • ClassInformation
    Specifies the out-of-band information for this record.

The NDIS_CLASS_ID type is an NDIS-defined enumeration. Most common classifications for records will be specified as system-defined values. However, a range of values in this enumeration will be available for vendor-defined experimental classes.

Setting Status Before Making Receive Indications

Only lower-level NDIS drivers use the Statusmember of this structure for receive indications. Before such a driver calls NdisMIndicateReceivePacket, it sets the Statuswith NDIS_SET_PACKET_STATUSfor one or more packet descriptors in the array to be indicated to either of the following values:

  • NDIS_STATUS_SUCCESS
    Tells NDIS that the driver is relinquishing ownership of the packet about to be indicated with NdisMIndicateReceivePacket or NdisMCoIndicateReceivePacket until the packet descriptor is returned to its MiniportReturnPacket function.

    Protocols that receive the indication can use the packet descriptor, along with all buffers mapped by buffer descriptors chained to the packet descriptor and any out-of-band information supplied with the packet, to copy the indicated net packet data or, possibly, to forward the indicated data to interested clients.

  • NDIS_STATUS_RESOURCES
    Tells NDIS that the driver is retaining ownership of the packet about to be indicated with NdisMCoIndicateReceivePacket. This packet will be indicated to the ProtocolReceive or ProtocolCoReceivePacket functions of bound protocols.

    Setting this status forces bound protocols to return ownership of each such packet descriptor, of any medium-specific buffer in the out-of-band data block for each packet descriptor, and of the memory mapped by each packet descriptor's respective chained buffer descriptors to the indicating driver more quickly. The protocols must wait for a call to their ProtocolReceiveComplete functions to begin postprocessing the data they copied from indication(s) and forwarding the data to clients.

    An indicating driver can set this status if it is running low on packet pool or buffer pool. An indicating NIC driver can set this status if it is running low on NIC receive buffers due to high network traffic. A bus-master DMA NIC driver might call NdisMAllocateSharedMemoryAsync in these circumstances to get additional NIC receive buffer space.

A deserialized or connection-oriented miniport driver must save the Statusmember of the out-of-band data block in a local variable before indicating up the packet descriptor. As explained in more detail below, when NdisMIndicateReceivePacketreturns, a deserialized miniport driver must check the saved packet Statusto determine whether it can immediately reclaim the packet descriptor and the associated buffers.

Getting Status on Return from NdisMIndicateReceivePacket

After a serialized driver has set the Statusfor some number of packet descriptors and called NdisMIndicateReceivePacketwith the array of pointers to the packet descriptors, it must use the NDIS_GET_PACKET_STATUSmacro when NdisMIndicateReceivePacketreturns control to retrieve the Statusset by NDIS.

The returned Statusin the NDIS_PACKET_OOB_DATA block associated with each packet descriptor that the serialized driver indicated with NDIS_STATUS_SUCCESS determines what the indicating driver does next, as follows:

  • NDIS_STATUS_SUCCESS
    If this is set on return from a miniport's call to NdisMIndicateReceivePacket, the miniport driver regains ownership of the following:

    • The packet descriptor

    • The associated out-of-band data block associated with the packet descriptor and of any media-specific information buffer specified in this block

    • All buffers mapped by buffer descriptors chained to the packet descriptor

    NDIS guarantees that any packet descriptors for which the indicating driver set NDIS_STATUS_RESOURCES, as already described, will be returned from its call to NdisMIndicateReceivePacket with NDIS_STATUS_SUCCESS.

    The driver can prepare these descriptors, the out-of-band block, and media-specific information buffer, if any, for reuse in subsequent receive indications immediately.

  • NDIS_STATUS_PENDING
    If this is set on return from NdisMIndicateReceivePacket, protocols retain ownership of the packet descriptor, of its associated out-of-band data block and of any buffer specified in this block, and of all buffers mapped by buffer descriptors chained to the packet descriptor until the packet descriptor is returned to the indicating driver's MiniportReturnPacket function.

A deserialized or connection-oriented miniport driver must not examine the Statusof indicated packets on return of NdisMIndicateReceivePacket. Instead, a deserialized miniport driver must save a packet's Statusin a local variable before indicating up the packet descriptor. When NdisMIndicateReceivePacketreturns, the miniport driver should check the saved packet Status. If the miniport driver set the packet's Statusto NDIS_STATUS_RESOURCES before indicating up the packet descriptor, it should reclaim the packet descriptor immediately after NdisMIndicateReceivePacketreturns, preferably by calling its own MiniportReturnPacketfunction. In this case, NDIS does not call the miniport driver's MiniportReturnPacketfunction to return the packet descriptor. If the miniport driver set the packet's Statusto NDIS_STATUS_SUCCESS before indicating up the packet descriptor, the miniport driver must not reclaim the packet descriptor until NDIS subsequently returns the packet descriptor to the miniport driver's MiniportReturnPacketfunction.

Setting Status in MiniportSendPackets

Only underlying serialized NDIS drivers with MiniportSendPacketsfunctions can use the Statusmember of this structure for packet descriptors specifying sends. Such a driver's MiniportSendPacketsfunction sets the Statusmember in the out-of-band data blocks associated with the packet descriptors in the input array as follows:

  • If the driver will complete the send operation asynchronously, MiniportSendPackets sets NDIS_STATUS_PENDING in the Status member for the given packet descriptor.

  • If the driver cannot process all sends in a given packet array due to current resource constraints, MiniportSendPackets sets NDIS_STATUS_RESOURCES in the Status member for one packet descriptor.

    NDIS queues these packet descriptors internally in the same order for resubmission to MiniportSendPackets when the driver calls NdisMSendResourcesAvailable or NdisMSendComplete, whichever occurs first. NDIS reflects this miniport-set status value to protocols as NDIS_STATUS_PENDING.

  • If MiniportSendPackets will complete a given send request before it returns control, it must set the Status member for the given packet descriptor to a driver-determined status value so that NDIS can reflect this status back to the protocol that initiated the send.

Otherwise, such a driver supplies the completion status for each packet when it calls NdisMSendCompletewith the packet descriptor. Drivers that have MiniportSendinstead of MiniportSendPacketsfunctions return the status for each incoming send packet, so such a driver never sets the Statusmember of the out-of-band data block for a packet descriptor specifying a send.

Protocols cannot determine the completion status for a protocol-allocated packet descriptor from the Statusmember of the associated OOB block on return from NdisSendPacketsor NdisSend. This value can change dynamically as NDIS submits, requeues, and resubmits send packet(s) to underlying drivers' MiniportSendPacketsand/or MiniportSendfunctions.

A protocol cannot use any NDIS_GET_PACKET_XXX macro nor the NDIS_OOB_DATA_FROM_PACKET macro to access the OOB data block for such a protocol-allocated packet descriptor until its ProtocolSendCompletefunction is called with the packet descriptor.

Remarks

Every packet descriptor allocated with NdisAllocatePacket has an associated NDIS_PACKET_OOB_DATA block. Only drivers that support multipacket sends and/or receives and drivers that supply out-of-band information, such as packet priority, with each network packet to be transferred use the OOB block. Nevertheless, every NDIS driver that allocates packet descriptors for transfers between bound drivers must allocate those packet descriptors with NdisAllocatePacket from the packet pool that each such NDIS driver usually allocates when it initializes.

In general, drivers of high-capacity bus-master DMA NICs are most likely to support multipacket receives and sends because such a NIC driver makes the greatest performance gains by supporting multipacket transfers. Any protocol that binds itself to (or above) such an underlying NIC driver also should support multipacket sends and receives for maximum performance.

If such a protocol also binds itself above another NIC driver without multipacket transfer support, NDIS handles multipacket sends and single-packet receives in a manner transparent to both drivers by always calling the protocol's ProtocolReceive function and by calling that NIC driver's MiniportSend function with a single packet per call. Similarly, if a protocol that does not support multipacket transfers binds itself above a NIC driver that does, NDIS handles multipacket receive indications and single packet sends in a manner transparent to both drivers, although the MiniportSendPackets function of the underlying NIC driver is given only a single send request per call to NdisSend from such a protocol.

Requirements

Header

Ndis.h (include Ndis.h)

See also

MiniportAllocateComplete

MiniportHandleInterrupt

MiniportReturnPacket

MiniportSend

MiniportSendPackets

MiniportTimer

NdisAllocateBuffer

NdisAllocateBufferPool

NdisAllocatePacket

NdisAllocatePacketPool

NdisGetCurrentSystemTime

NDIS_GET_ORIGINAL_PACKET

NDIS_GET_PACKET_HEADER_SIZE

NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO

NDIS_GET_PACKET_STATUS

NDIS_GET_PACKET_TIME_RECEIVED

NDIS_GET_PACKET_TIME_SENT

NDIS_GET_PACKET_TIME_TO_SEND

NdisGetReceivedPacket

NdisMCoIndicateReceivePacket

NdisMIndicateReceivePacket

NdisMSendComplete

NdisMSendResourcesAvailable

NDIS_OOB_DATA_FROM_PACKET

NDIS_PACKET

NdisSend

NdisSendPackets

NDIS_SET_PACKET_HEADER_SIZE

NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO

NDIS_SET_PACKET_STATUS

NDIS_SET_PACKET_TIME_RECEIVED

NDIS_SET_PACKET_TIME_SENT

NDIS_SET_PACKET_TIME_TO_SEND

ProtocolReceive

ProtocolCoReceivePacket

ProtocolReceivePacket

ProtocolSendComplete

 

 

Send comments about this topic to Microsoft