Yes, I really did read this post. Really. It is early, I have not had
enough coffee. (Even at 3pm I have not had enough coffee).
You are not sharing packets with TCPIP. I got that. I just had a synaptic
disconnect due to low cafeen levels. My appologies.
However, do you have NETMON or Ethereal bound to your adapter to watch what
is going on (or both!)? Make sure your protocol is ‘first’ in the binding
order or, as others suggest, start with being ‘only’ in the binding order!
Also (I have not confirmed this, it is a hunch) it is quite possible that
TCPIP or NDISUIO or any other protocol might queue packets indcated to its
ProtocolReceivePacket() without first checking the MAC header to see if the
packet is even interesting. In that case, it truly will be bad luck for the
remaining protocols.
-dave
-----Original Message-----
From: David R. Cattley [mailto:xxxxx@msn.com]
Sent: Friday, November 02, 2007 9:32 AM
To: ‘Windows System Software Devs Interest List’
Subject: RE: [ntdev] ProtocolDriver Receive Callbacks (ProtocolReceive vs
ProtocolReceivePacket)
NDIS will call a ProtocolReceive() handler when the original packet is
indicated to NdisMIndicatePacket() with the packet status set to
NDIS_STATUS_RESOURCES.
NDIS will also call a ProtocolRecieve() handler when, during he completion
processing of send, the packet matches the loopback or local filter
criteria. In this case the system cannot provide the packet because the
packet is already owned by a ‘protocol’.
However, it is my understanding that NDIS will endeavor to indicate the
NDIS_PACKET via ProtocolReceivePacket() to every bound protocol that has
such a handler. The return value from those handlers is a reference count
that NDIS internally maintains. Only when that reference count reaches
(effectively) zero due to calls to NdisReturnPackets() will (the) NDIS
(wrapper) return the packet to the indicating Miniport via
MiniportReturnPacket().
But consider what happens if a Protocol return a non-zero reference count.
At that point, the protocol has taken ‘ownership’ of the packet and thus has
the exlusive right to use the ProtocolReserved field of the packet. It
is therefore impossible to ‘give’ this packet to another Protocol. Thus the
behavior that NDIS will only indicate a receive to ProtocolReceivePacket()
as long as the packet is not already accepted by a previous protocol in the
binding list.
Since most packets are of interest to only one protocol, this is not
typically a problem. Some rather curious side-effects can occur, however,
with performance and such if the binding order of protocols that are both
interested in a subset of LAN traffic get shifted around.
In my experience most common reason for a protocol to get a
ProtocolReceive() when the developer was expecting a ProtocolReceivePacket()
is the NDIS_STATUS_RESOURCES indication. In this case, however, it sounds
like both your protocol and another in the system are likely interested in
the same packets. Since your protocol is (conincidently) after the other
protocol in the Miniport Open List, well, you lose.
In the bad old days of thinking that IM drivers were the greatest thing
since running water and flushing toilets, the way to get an asyncronously
ownable read-only reference to a received packet was to have an IM driver
(instead of a protocol) that was just ‘passing through’ the packet. Since
the IM driver can ‘add to’ the reference count (in a sense) by holding both
a ‘passthru’ reference and an ‘internal’ reference, the buffer copy can be
avoided. The impact, however, of an IM driver tends to overwhelm the
savings, however, and so I suggest you stick with the Pure Protocol approach
and just deal with the necessary fact that if you share a packet with TCPIP,
chances are one of you will have to buffer the packet.
Good Luck,
-dave
David R. Cattley
Consulting Engineer
Systems Software Development
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Friday, November 02, 2007 5:03 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] ProtocolDriver Receive Callbacks (ProtocolReceive vs
ProtocolReceivePacket)
Thomas
Thank you. DDK on NdisMIndicateReceivePacket
“…When a miniport driver calls NdisMIndicateReceivePacket, NDIS passes
each pointer at ReceivePackets separately, in the miniport driver-determined
order, to the ProtocolReceivePacket function(s) of bound protocol(s) that
export this function. To other bound protocols, NDIS passes each packet
pointer to the ProtocolReceive function(s)…”
Above verbatim is unclear and seem to suggest both ways. Anyways
- what is the miniport driver-determined order?
- How is it decided who gets called back at ProtocolReceivePacket and who
gets called at ProtocolReceive?
Hope MS folks can throw some light on this for me.
Not sure if this helps, but my protocol driver receives pkts of a unique
protocol type which no other protocol drver in teh system will be interested
in and my protocol driver is bound only to my miniport (i.e not to all
installed NICs).
Our miniport driver and IM driver both use NdisMIndicateReceivePacket to
indicate full packets to their upper edge.
Right now I am using NdistransferData->ProtocolTransferDatacomplete
(basically the NdisProt sample).
Also DDK says
“…When NDIS calls the ProtocolReceive function of a driver that exports a
ProtocolReceivePacket function, ProtocolReceive can call
NdisGetReceivedPacket and NDIS_GET_ORIGINAL_PACKET to retrieve the
out-of-band information associated with an incoming packet that was
indicated as part of a packet array…”
I will try NdisGetReceivedPacket / NDIS_GET_ORIGINAL_PACKET in the context
of ProtocolReceive itself and hopefully have the whole pkt there itself
instead of calling NdisTransferData and waiting to be called back at
ProtocolTransferDatacomplete(). The later is making me to have unnecessary
code requiring me to maintain rx pkt/buffer pools in my protocol driver too
(in addition to those already maintained by natively by the miniport).
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