NdisGetDataBuffer

Hi!

I’m seeing cases on WIndows 7 where NdisGetDataBuffer returns NULL
unexpectedly. I provide a storage buffer (DnsFrame) that should be large
enough to get the data I want (in this case, a DNS payload). I have also
advanced the ND (referenced by pNetBuffer) to be past the L3/L4 header.
Also, when I hit the assert for a NULL return, I’ve verified that the number
of bytes requested is much smaller than the size of the storage buffer.

Here’s my code:

numDnsBytes = NET_BUFFER_DATA_LENGTH(pNetBuffer);

//
// We should expect that we are getting a pointer within the net buffer
and
// that NDIS will not need to copy fragmented data into the DnsFrame
buffer
//
pDnsHdr = NdisGetDataBuffer(
pNetBuffer,
numDnsBytes,
DnsFrame, // uint8 array of 1500 bytes
2,
0
);
DBG_ASSERT(pDnsHdr != NULL);

Are there other reasons that NdisGetDataBuffer() would return NULL other
than those documented in the WDK? BTW, this code is executed for processing
of rx packets, which (for the most part) should be contained in on one mdl.

Thanks!

Why alignment of 2?

Thomas F. Divine
http://www.pcausa.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of SoquelDude
Sent: Monday, April 1, 2013 1:32 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] NdisGetDataBuffer

Hi!

I’m seeing cases on WIndows 7 where NdisGetDataBuffer returns NULL
unexpectedly. I provide a storage buffer (DnsFrame) that should be large
enough to get the data I want (in this case, a DNS payload). I have also
advanced the ND (referenced by pNetBuffer) to be past the L3/L4 header.
Also, when I hit the assert for a NULL return, I’ve verified that the number
of bytes requested is much smaller than the size of the storage buffer.

Here’s my code:

numDnsBytes = NET_BUFFER_DATA_LENGTH(pNetBuffer);

//
// We should expect that we are getting a pointer within the net buffer
and
// that NDIS will not need to copy fragmented data into the DnsFrame
buffer
//
pDnsHdr = NdisGetDataBuffer(
pNetBuffer,
numDnsBytes,
DnsFrame, // uint8 array of 1500 bytes
2,
0
);
DBG_ASSERT(pDnsHdr != NULL);

Are there other reasons that NdisGetDataBuffer() would return NULL other
than those documented in the WDK? BTW, this code is executed for processing
of rx packets, which (for the most part) should be contained in on one mdl.

Thanks!


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

I wanted to align on a uint16 boundary for the DNS header. However, I see
the same problem with alignment of 1.

“Thomas F. Divine” wrote in message news:xxxxx@ntdev…

Why alignment of 2?

Thomas F. Divine
http://www.pcausa.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of SoquelDude
Sent: Monday, April 1, 2013 1:32 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] NdisGetDataBuffer

Hi!

I’m seeing cases on WIndows 7 where NdisGetDataBuffer returns NULL
unexpectedly. I provide a storage buffer (DnsFrame) that should be large
enough to get the data I want (in this case, a DNS payload). I have also
advanced the ND (referenced by pNetBuffer) to be past the L3/L4 header.
Also, when I hit the assert for a NULL return, I’ve verified that the number
of bytes requested is much smaller than the size of the storage buffer.

Here’s my code:

numDnsBytes = NET_BUFFER_DATA_LENGTH(pNetBuffer);

//
// We should expect that we are getting a pointer within the net buffer
and
// that NDIS will not need to copy fragmented data into the DnsFrame
buffer
//
pDnsHdr = NdisGetDataBuffer(
pNetBuffer,
numDnsBytes,
DnsFrame, // uint8 array of 1500 bytes
2,
0
);
DBG_ASSERT(pDnsHdr != NULL);

Are there other reasons that NdisGetDataBuffer() would return NULL other
than those documented in the WDK? BTW, this code is executed for processing
of rx packets, which (for the most part) should be contained in on one mdl.

Thanks!


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

NdisGetDataBuffer returns NULL for exactly these reasons:

  1. Invalid parameter (BytesNeeded == 0, or NB->DataLength < BytesNeeded)
  2. Malformed NET_BUFFER (NB->CurrentMdl is NULL, or the MDL chain is not in sync with the NB’s DataLength)
  3. NB’s buffer can’t be mapped into VA
  4. Storage parameter is NULL, and the NB’s buffer doesn’t meet the alignment & contiguousness requirements

Interestingly, a “unit8 array of 1500 bytes” is not really guaranteed to have the alignment you want. But NdisGetDataBuffer doesn’t actually check that *your* storage meets the alignment requirements, since it assumes you know what you’re doing.

You’ll probably have to take a look at the failing NET_BUFFER and its MDL chain, and make sure that it looks valid.