// ndis.h
typedef struct _PD_BUFFER {
struct _PD_BUFFER *NextPDBuffer;
struct _PD_BUFFER *NextPartialPDBuffer;
PVOID PDClientReserved;
PVOID PDClientContext;
PUCHAR DataBufferVirtualAddress;
DMA_LOGICAL_ADDRESS DataBufferDmaLogicalAddress;
ULONG DataBufferSize;
USHORT PDClientContextSize;
USHORT Attributes;
USHORT Flags;
USHORT DataStart;
ULONG DataLength;
union {
struct {
union {
ULONG64 RxFilterContext;
ULONG64 GftFlowEntryId;
};
ULONG RxHashValue;
union {
struct {
ULONG RxIPHeaderChecksumSucceeded : 1;
ULONG RxTCPChecksumSucceeded : 1;
ULONG RxUDPChecksumSucceeded : 1;
ULONG RxIPHeaderChecksumFailed : 1;
ULONG RxTCPChecksumFailed : 1;
ULONG RxUDPChecksumFailed : 1;
ULONG RxHashComputed : 1;
ULONG RxHashWithL4PortNumbers : 1;
ULONG RxGftDirectionIngress : 1;
ULONG RxGftExceptionPacket : 1;
ULONG RxGftCopyPacket : 1;
ULONG RxGftSamplePacket : 1;
ULONG RxReserved1 : 4;
ULONG RxCoalescedSegCount : 16;
ULONG RxRscTcpTimestampDelta;
};
ULONG RxOffloads[2];
};
union {
struct {
ULONG TxIsIPv4 : 1;
ULONG TxIsIPv6 : 1;
ULONG TxTransportHeaderOffset : 10;
ULONG TxMSS : 20;
ULONG TxComputeIPHeaderChecksum : 1;
ULONG TxComputeTCPChecksum : 1;
ULONG TxComputeUDPChecksum : 1;
ULONG TxIsEncapsulatedPacket : 1;
ULONG TxInnerPacketOffsetsValid : 1;
ULONG TxReserved1 : 11;
ULONG TxInnerFrameOffset : 8;
ULONG TxInnerIpHeaderRelativeOffset : 6;
ULONG TxInnerIsIPv6 : 1;
ULONG TxInnerTcpOptionsPresent : 1;
};
ULONG TxOffloads[2];
};
PD_BUFFER_VIRTUAL_SUBNET_INFO VirtualSubnetInfo;
PD_BUFFER_8021Q_INFO Ieee8021qInfo;
USHORT GftSourceVPortId;
ULONG Reserved;
UINT64 ProviderScratch;
} MetaDataV0;
};
} PD_BUFFER;
View the official Windows Driver Kit DDI referenceNo description available.
This structure represents a PacketDirect (PD) packet, or a portion of a PD packet in a queue.
NextPDBufferA pointer to the next PD_BUFFER structure in the queue.
NextPartialPDBufferA pointer to the next partial PD_BUFFER structure in the queue.
PDClientReservedReserved for system use. Do not use.
PDClientContextThe client and the provider are not allowed to modify this field. If a client has allocated the PD_BUFFER with a non-zero value for ClientContextSize, then the PDClientContext refers to a buffer size of ClientContextSize. Otherwise, this field is NULL.
DataBufferVirtualAddressThis field represents the address that hosts and software can use to access/modify the packet contents. The actual packet data is always at DataBufferVirtualAddress+DataStart. The provider and the platform never modify the value of this field after the PD_BUFFER initialization.
DataBufferDmaLogicalAddressThis field represents the logical memory location used for storing the packet data. The provider must use for DMA. The actual packet data is always at DataBufferDmaLogicalAddress+DataStart. The provider and the platform must never modify the value of this field after the PD_BUFFER initialization.
DataBufferSizeThis is the total size of the allocated data buffer. The provider and the platform must never modify the value of this field after the PD_BUFFER initialization. This data type is ULONG instead of USHORT because of large send offload.
PDClientContextSizeWhen this value is non-zero, it is the size of the buffer pointed to by PDClientContext. The value of this field must only be modified by the platform. The platform does not change the value of this field after the PD_BUFFER allocation.
AttributesThe attributes must never be modified by the provider. The table below lists attributes that this PD_BUFFER structure can have.
| Attribute | Description |
|---|---|
| PD_BUFFER_ATTR_BUILT_IN_DATA_BUFFER | A PD_BUFFER allocated with its own accompanying data buffer will have this attribute set. The PD_BUFFER attributes must never be modified by clients or providers. |
FlagsThe following table lists flags that this PD_BUFFER structure can have.
| Flag | Description |
|---|---|
| PD_BUFFER_FLAG_PARTIAL_PACKET_HEAD | Indicates that this buffer is the head of partial packets. |
DataStartThis field denotes where the packet starts relative to the original starting address of the allocated data buffer. The provider must never modify this field. The provider adds this value to the DataBufferDmaLogicalAddress value to derive the actual target DMA address for packet reception/transmission. For example, the target DMA address value in the hardware receive/transmit descriptor must be set to DataBufferDmaLogicalAddress+DataStart when a PD_BUFFER is posted to a receive/transmit queue.
DataLengthThe length of the packet or partial packet data.
MetaDataV0MetaDataV0.RxFilterContextThe provider sets this to the filter context value obtained from the matched filter that steered the packet to the receive queue. Filter context values are specified by the clients when configuring filters.
MetaDataV0.GftFlowEntryIdIf one of the RxGftExceptionPacket or RxGftCopyPacket or RxGftSamplePacket bits are set, the RxFilterContext value is overwritten with a GFT flow entry Id value.
MetaDataV0.RxHashValueThe hash value computed for the incoming packet that is steered to the receive queue using RSS.
MetaDataV0.RxIPHeaderChecksumSucceededA common RX offload field that indicates if the IP header checksum succeeded.
MetaDataV0.RxTCPChecksumSucceededA common RX offload field that indicates if the TCP checksum succeeded.
MetaDataV0.RxUDPChecksumSucceededA common RX offload field that indicates if the UDP checksum succeeded.
MetaDataV0.RxIPHeaderChecksumFailedA common RX offload field that indicates if the IP header checksum failed.
MetaDataV0.RxTCPChecksumFailedA common RX offload field that indicates if the TCP checksum failed.
MetaDataV0.RxUDPChecksumFailedA common RX offload field that indicates if the UDP checksum failed.
MetaDataV0.RxHashComputedA common RX offload field that indicates if the hash is computed.
MetaDataV0.RxHashWithL4PortNumbersA common RX offload field that indicates the hash is computed with L4 port numbers.
MetaDataV0.RxGftDirectionIngressMetaDataV0.RxGftExceptionPacketA common RX offload field that indicates this is a GFT exception packet.
MetaDataV0.RxGftCopyPacketA common RX offload field that indicates this is a GFT copy packet.
MetaDataV0.RxGftSamplePacketA common RX offload field that indicates this is a GFT sample packet.
MetaDataV0.RxReserved1Reserved.
MetaDataV0.RxCoalescedSegCountA common RX offload field that contains the amount of coalesced segments.
MetaDataV0.RxRscTcpTimestampDeltaA common RX offload field that contains RSC and TCP timestamp difference.
MetaDataV0.RxOffloadsRX offloads for this buffer.
MetaDataV0.TxIsIPv4A common TX offload field that indicates this packet is IPv4.
MetaDataV0.TxIsIPv6A common TX offload field that indicates this packet is IPv6.
MetaDataV0.TxTransportHeaderOffsetA common TX offload field that contains the packet's header offset.
MetaDataV0.TxMSSA common TX offload field that contains the maximum segment size of this packet.
MetaDataV0.TxComputeIPHeaderChecksumA common TX offload field that indicates the IP header checksum is computed.
MetaDataV0.TxComputeTCPChecksumA common TX offload field that indicates the TCP checksum is computed.
MetaDataV0.TxComputeUDPChecksumA common TX offload field that indicates the UDP checksum is computed.
MetaDataV0.TxIsEncapsulatedPacketA common TX offload field that indicates the packet is encapsulated.
MetaDataV0.TxInnerPacketOffsetsValidA common TX offload field that indicates the inner packet offsets are valid.
MetaDataV0.TxReserved1Reserved.
MetaDataV0.TxInnerFrameOffsetA common TX offload field that contains the inner frame offset.
MetaDataV0.TxInnerIpHeaderRelativeOffsetA common TX offload field that contains the inner IP header relative offset.
MetaDataV0.TxInnerIsIPv6A common TX offload field that indicates the inner packet is IPv6.
MetaDataV0.TxInnerTcpOptionsPresentA common TX offload field that indicates the inner TCP options are present.
MetaDataV0.TxOffloadsTX offloads for this buffer.
MetaDataV0.VirtualSubnetInfoThe virtual subnet information.
MetaDataV0.Ieee8021qInfoThe IEEE 802.1Q information.
MetaDataV0.GftSourceVPortIdThe GFT source virtual port ID.
MetaDataV0.ReservedReserved for system use.
MetaDataV0.ProviderScratchA scratch field that the PD provider can use for its own purposes while the PD_BUFFER is sitting in the provider queue (in other words, posted by the client but not yet drained back by the client). Once the PD_BUFFER is drained by the client, there is no guarantee that the contents of this field will be preserved.
If an L2 packet is represented by multiple PD_BUFFER structures, the first PD_BUFFER must have the PD_BUFFER_ATTR_BUILT_IN_DATA_BUFFER flag set and the NextPartialPDBuffer field must point to the partial PD_BUFFER structures that constitute the whole packet. Each of the partial PD_BUFFER structures must point to the next partial PD_BUFFER by using the NextPartialPDBuffer as opposed to the NextPDBuffer field. The NextPDBuffer field must be NULL in all partial PD_BUFFER structures except for the head buffer. All partial PD_BUFFER structures except for the head buffer must have the PD_BUFFER_ATTR_BUILT_IN_DATA_BUFFER flag cleared. The last partial PD_BUFFER must have it's NextPartialPDBuffer field set to NULL. The total length of the L2 packet is the sum of DataLength fields from each partial PD_BUFFER. The head PD_BUFFER must contain up to and including the IP transport (TCP, UDP, SCTP, etc) header. In the case of encapsulation or double-encapsulation, the inner-most IP transport header must be contained in the head PD_BUFFER.
When posting PD_BUFFER structures to receive queues, DataLength is ignored by the provider (For more information see the ReceiveDataLength description in the NDIS_PD_QUEUE_PARAMETERS structure). When draining completed PD_BUFFER structures from receive queues, the provider stores the length of the received packet in the DataLength field. The length does not include FCS or any stripped 801Q headers. When posting PD_BUFFER structures to transmit queues, DataLength denotes the length of the packet to be sent. When draining completed PD_BUFFER structures from transmit queues, the provider leaves the DataLength field unmodified.