On Sep 8, 2015, at 7:45 PM, 食肉大灰兔V5 <[email protected]> wrote:

> On Wed, Sep 9, 2015 at 8:12 AM, Guy Harris <[email protected]> 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.

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 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?

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".

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.
_______________________________________________
Winpcap-users mailing list
[email protected]
https://www.winpcap.org/mailman/listinfo/winpcap-users

Reply via email to