In NDIS4/NDIS5 Protocol drivers, NDIS has two ways to indicate a packet to the protocol binding:
- As a NDIS_PACKET (the new old way) via ProtocolReceivePacket
- As a ‘legacy’ receive via ProtocolReceive
It turns out that in NDIS4 there were reasons for NDIS to indicate with ProtocolReceive when infact the underlying Miniport had indicated an NDIS_PACKET. Sending the packet to more than one binding, for example, or processing a loopback.
However, in NDIS4 support for Out Of Band (OOB) data was added so one could find out all sorts of interesting things about the received packet. However, if NDIS had decided to indicate a recieve with the ‘legacy’ ProtocolReceive packet, well, that protocol would be unable to access the OOB data because it did not have an NDIS_PACKET to extract it from.
So enter the ‘hack’ of NdisGetReceivePacket(). It allows a Protocol to get at the NDIS_PACKET when NDIS has decided to turn a perfectly good NDIS_PACKET style receive indication from a Miniport into a legacy ProtocolRecieve indication. Now mind you, you cannot actually do much with the packet returned - it is still ‘syncronous’ (to be treated as if indicated with NDIS_STATUS_RESOURCES) and you cannot assume ownership of the packet. You cannot modify it, cannot use the ProtocolReserved area, etc. However, about the only useful thing one might want to do is the access the OOB data from it (well, actually, one should call NdisGetOriginalPacket() on it and access the OOB data from the ‘original’ packet - yet anothe story).
The only sample I know of that shows dealing with the OOB data and accessing it in a legacy recieve is PASSTHRU. I don’t think NDISPROT does (I suppose this reveals me to be one lazy SOB since I could probably go read it - but you can too!)
Good Luck,
Dave Cattley
Date: Tue, 15 Mar 2011 17:13:07 -0400
From: xxxxx@yahoo.com
To: xxxxx@lists.osr.com
Subject: [ntdev] NDIS, NdisGetReceivedPacket and all, all, all
Hello all.
I read MSDN and WDK examples. There are some questions about NdisGetReceivedPacket and general scheme of receiving packets in NDIS.
First of all I don’t understand what idea stands behind this function? MSDN says about that:
…
If the underlying miniport driver supplies out-of-band information with the receives it indicates, ProtocolReceive can call NdisGetReceivedPacket or NDIS_GET_ORIGINAL_PACKET to retrieve the out-of-band information for each such packet. Because such an underlying miniport driver always indicates full-packet receives, ProtocolReceive will never call NdisTransferData for a packet indicated with NdisMIndicateReceivePacket.
…
After googling a bit I found out that the function may return NULL and probably NdisMIndicateReceivePacket must be called. But what is the general idea?
Another question is also very general. After receiving a packet NIC’s miniport driver calls either ProtocolReceive or ProtocolReceivePacket handlers (through NDIS of course). The latter is optional. As far as I understand the choice between these function is based on NIC’s and Protocol driver’s abilities. Pseudocode looks like this:
ProtocolReceive:
if (LookaheadDataSize <= PacketSize)
{
NdisCopyLookaheadBuffer(…)
}
else
{
NdisAllocateBuffer(…)
NdisAllocatePacket(…)
NdisChainBuffer(…)
NdisDataTransfer(…)
}
ProtocolReceivePacket:
if (NDIS_GET_PACKET_STATUS(NdisPacket) == NDIS_STATUS_RESOURCES)
{
NdisCopyFromPacketToPacket(…)
return 0;
}
else
{
return ReferenceCount;
}
When driver finishes work with the packet it must call NdisReturnPackets(…, ReferenceCount)
Are these algorithms correct?
–
Thanking In Advance,
Mikae.
NTDEV is sponsored by OSR
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