[Winpcap-users] Is an NDIS 5 PacketReceive routine guaranteed to be handed the *full* packet on a system using NDIS 5?

食肉大灰兔V5 hsluoyz at gmail.com
Wed Sep 9 12:25:58 UTC 2015


Hi Guy,

On Wed, Sep 9, 2015 at 6:25 PM, Guy Harris <guy at alum.mit.edu> wrote:

>
> On Sep 8, 2015, at 7:45 PM, 食肉大灰兔V5 <hsluoyz at gmail.com> wrote:
>
> > On Wed, Sep 9, 2015 at 8:12 AM, Guy Harris <guy at alum.mit.edu> wrote:
> >
> >> In NPF_tap(), the BPF filter routine is called only with data from the
> header buffer (HeaderBuffer) if the difference between LookaheadBuffer and
> HeaderBuffer is equal to HeaderBufferSize (this appears to assume that the
> packet will be contained in a single buffer in this case, and that the
> header buffer contains the entire packet), and, otherwise, called with data
> from the header buffer and the lookahead buffer.
> >
> > In fact, I didn't quite understand this part when I am doing the porting
> job to NDIS 6. AFAIK, like for an Ethernet packet, HeaderBuffer is the
> Ethernet header data, and LookaheadBuffer is the data beginning from IP
> header. If PacketSize is less than or equal to the given
> LookaheadBufferSize, the lookahead buffer contains the entire packet (see
> https://msdn.microsoft.com/en-us/library/windows/hardware/ff563246(v=vs.85).aspx
> ).
>
> That's the NDIS 5 version of the documentation for the PacketReceive
> function.  It would be an ugly incompatibility if NDIS 6's NDIS 5 shims
> didn't preserve that behavior, but it's possible that it does.
>

OK. I thought LookaheadBuffer will always start from the end of
HeaderBuffer before this post. I looked twice at the MSDN and found
Microsoft never promised this assumption in NDIS 5, so it's reasonable for
WinPcap to split this into 2 conditions. Although for NDIS 6, **usually**
MAC, IP and TCP headers are carried in the same buffer (I confirmed this in
Npcap, also see the figure in: http://codemachine.com/article_ndis6nbls.html),
but Microsoft never guarantees it.


>
> Apparently OpenVPN has both NDIS 5 and NDIS 6 drivers:
>
>         https://community.openvpn.net/openvpn/wiki/CodeRepositories
>
> I'm guessing that the NDIS 6 driver is being used on his Windows 10
> system; perhaps it does something that the NDIS 6 -> NDIS 5 shim doesn't
> handle correctly.
>

I have a glance at the repo, and I think the NDIS 6 version OpenVPN driver
is a NDIS 6 miniport. A miniport is really far away with a protocol (NDIS 5
or 6) (see:
http://stackoverflow.com/questions/18257048/ndis-filter-driver-filterreceivenetbufferlists-handler-isnt-called?noredirect=1#comment27011779_18257048).
So it's weird that OpenVPN could affect the WinPcap driver. A miniport
should be transparent to a protocol.


>
> > I don't know why there is a compare between LookaheadBuffer -
> HeaderBuffer with HeaderBufferSize. HeaderBuffer can't contain the entire
> packet (as there won't be a packet with only Ethernet header and have no
> content).
>
> I think what it's doing is clearer if it's written as
>
>         if((PUCHAR)LookaheadBuffer !=
> ((PUCHAR)HeaderBuffer)+HeaderBufferSize)
>
> which tests whether the lookahead buffer begins immediately after the end
> of the header buffer, i.e. that there's really only one buffer; the comment
> before it indicates that:
>
>         //
>         //Check if the lookahead buffer follows the mac header.
>         //If the data follow the header (i.e. there is only a buffer) a
> normal bpf_filter() is
>         //executed on the packet.
>         //Otherwise if there are 2 separate buffers (this could be the
> case of LAN emulation or
>         //things like this) bpf_filter_with_2_buffers() is executed.
>         //
>
> > I think the caller of ProtocolReceive routine only guarantees that the
> HeaderBuffer and LookaheadBuffer together cover till the TCP header.
>
> Meaning that they will cover the TCP header, or that they only guarantee
> that the stuff *before* the TCP header is provided?
>

Sorry for my english, which I mean NDIS will guarantee the TCP header is
contained in LookaheadBuffer (see:
http://www.verycomputer.com/5_8593f09f8b078987_1.htm)


>
> If it's the latter, then:
>
> > So it's enough to make a decision for a BPF filter.
>
> ...that's not enough for a BPF filter such as "tcp port 80" that tests
> fields in the TCP header.
>
> If it's the former, even that's not enough for BPF filters that explicitly
> test past the end of the TCP header, which *is* possible, and even
> supported by the libpcap filter language by using the general expression
> mechanism.  But that wouldn't cause a problem with "tcp port 80".
>

You are right, if an application layer filter (like HTTP or FTP) is set, I
don't think the current WinPcap implementation will function well, as I
didn't see any Microsoft document said they will promise the length of
LookaheadBuffer up to application layer. So
WinPcap's PacketTransferDataComplete should also do some kind of BPF filter
work if NPF_Tap's filter fails with inadequate buffer length.


>
> I suspect that the NDIS 6 -> NDIS 5 shim in Windows 10 might not be
> handling packets provided by the OpenVPN driver - perhaps that driver is
> providing packets in a form that the shim can't properly map to something
> to hand to an NDIS 5 protocol driver like the WinPcap driver; Npcap is an
> NDIS 6 driver, so the shim isn't in the way.
>

Possible.


Cheers,
Yang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winpcap.org/pipermail/winpcap-users/attachments/20150909/5b1977d6/attachment.html>


More information about the Winpcap-users mailing list