Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

NDIS Protocol driver not getting ProtocolReceiveNetBufferLists function called

Shane_CorbinShane_Corbin Member Posts: 247

The underlying driver calls NdisMIndicateReceiveNetBufferLists to indicate receive data to NDIS. I'm expecting NDIS to call my protocol driver's ProtocolReceiveNetBufferLists function when data is received. This does happen if I open the interface in Wireshark and start a capture. As soon as I stop the capture my ProtocolReceiveNetBufferLists is no longer called.

Any ideas?

Comments

  • Jeffrey_Tippet_[MSFT]Jeffrey_Tippet_[MSFT] Member - All Emails Posts: 539

    It's likely that the protocol hasn't sent down OID_GEN_CURRENT_PACKET_FILTER with the flags for the packet types that you want.

    Protocols express their interest in a particular type of packet by sending the OID. By default, protocols get nothing.

    Note that this is a performance optimization only, not a correctness thing. So NDIS does not guarantee minimal packet filtering: NDIS permits itself to give you more packets than you asked for.

    Corollary: if your protocol driver has opinions about the EtherType or destination MAC address, you need to double-check them yourself. Don't rely on NDIS to do it.

    One curious consequence of the way that NDIS implements its performance optimizations combined with the way that Wireshark's NPF driver infests itself into the stack is that all other protocols start getting all other traffic as soon as Wireshark starts. (This should make you nervous: a diagnostic tool shouldn't visibly change the behavior of the system, lest you risk Heisenbugs.)

    Anyway, send the OID and the receive path should start flowing. And consider routinely testing both with and without wireshark installed, since it obviously has some interactions with other drivers.

  • Shane_CorbinShane_Corbin Member Posts: 247

    Very good info to know. I went back and tried the sample protocol driver from GitHub and am observing the same behavior.

    I think it's doing what you're recommending as part of the IOCTL_NDISPROT_OPEN_DEVICE call chain:

    NdisOidRequest
    ndisprotDoRequest
    ndisprotValidateOpenAndDoRequest <-- sets the packet filter to NDIS_PACKET_TYPE_DIRECTED|MULTICAST|BROADCAST
    ndisprotOpenDevice
    NdisProtEvtIoDeviceControl
    

    Any other thoughts?

  • Jeffrey_Tippet_[MSFT]Jeffrey_Tippet_[MSFT] Member - All Emails Posts: 539

    Another thing that could go wrong: If you're on Ethernet media type, your protocol will provide a list of the EtherTypes that it wants. If you provide an empty list, then NDIS assumes you want all EtherTypes. Otherwise, if you put some value in there, NDIS will generally try to limit traffic to just the EtherType you asked for.

    Double-check that the packet filter got set with !ndiskd.mopen. After the OID succeeds, you should see the Receive path has a Packet filter that allows whatever flags you asked for (presumably at least DIRECTED packets).

    Example:

    kd> !ndiskd.mopen ffff8a0288a50bf0
    
    RECEIVE PATH
    
        Packet filter      DIRECTED, MULTICAST, BROADCAST
        Frame Type(s)      0x0800, 0x0806
        Multicast address list 01-00-5e-00-00-01
                           01-00-5e-7f-ff-fa
                           01-00-5e-00-00-fb
                           01-00-5e-00-00-fc
    

    In that example, a protocol has asked for EtherTypes 0x0800 and 0806. It has asked to receive packets to the unicast address (aka DIRECTED), to the broadcast address, and to 4 different multicast addresses. NDIS will deliver inbound packets that match both the destination address and the ethertype. Any other packets might get delivered accidentally, but no effort is made.

  • Shane_CorbinShane_Corbin Member Posts: 247

    Here's what I got after the OID succeeds. Prior to sending the OID the packet filter is [No flags set], so that makes me think at least packet filter request is working.

    kd> !ndiskd.mopen ffff8d05666e8c00
    
    RECEIVE PATH
        Packet filter      DIRECTED, MULTICAST, BROADCAST
        Frame Type(s)      0x888e, 0x8100
        Multicast address list [This protocol has not added any multicast addresses]
    

    You mentioned the protocol asking for specific EtherTypes. How is that done? I'm trying to match 0xF788 ethType.
    Still not sure why NDIS is only delivering NBLs when Wireshark is open.

  • Jeffrey_Tippet_[MSFT]Jeffrey_Tippet_[MSFT] Member - All Emails Posts: 539

    The parameter to NdisOpenAdapterEx takes NDIS_OPEN_PARAMETERS::FrameTypeArray. Evidently you have EtherTypes 0x888e and 0x8100 in it now. If you want 0xf788, make sure that's in the list.

    Still not sure why NDIS is only delivering NBLs when Wireshark is open.

    All this is a performance optimization. Wireshark defeats the performance optimization, so NDIS floods packets to all protocols, regardless of what filters they had set up.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
Developing Minifilters 29 July 2019 OSR Seminar Space
Writing WDF Drivers 23 Sept 2019 OSR Seminar Space
Kernel Debugging 21 Oct 2019 OSR Seminar Space
Internals & Software Drivers 18 Nov 2019 Dulles, VA