Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Npcap: packet capture interrupted when enumerating devices or opening another packet capture #401

Closed
dmiller-nmap opened this issue Oct 13, 2017 · 2 comments

Comments

@dmiller-nmap
Copy link
Contributor

User reports packet capture interruption under the following conditions:

  1. Network adapter is under constant bus load of 100 Mbps.
  2. Wireshark 2.4.0 with Npcap 0.94 is capturing packets.
  3. A second Wireshark instance is started, showing capture interfaces.
  4. The first Wireshark stops receiving packets.
  5. When the second Wireshark starts a packet capture, the first Wireshark resumes packet capture.

We have been unable to reproduce under 300 Mbps load on Windows 10.

@dmiller-nmap dmiller-nmap changed the title Npcap: packet capture interrupted when enumerating devices under 100Mbps load Npcap: packet capture interrupted when enumerating devices or opening another packet capture May 1, 2018
@dmiller-nmap
Copy link
Contributor Author

Another report has shed more light on this issue. The network load is not a factor. The source of the problem is a discrepancy between how Windows and *nix define and implement "promiscuous mode." For the purposes of discussion, I'll be referring to the Linux implementation of libpcap which uses PF_PACKET sockets.

In libpcap (which is included in Npcap as wpcap.dll), promiscuous mode is a boolean flag within the pcap_t handle, set or cleared with pcap_set_promisc. Libpcap checks this flag when activating the pcap handle, and sets the PACKET_ADD_MEMBERSHIP socket option with the PACKET_MR_PROMISC flag set. The Linux kernel then puts the interface into promiscuous mode. The Linux kernel itself keeps track of how many PF_PACKET sockets have this flag set, and when they all are closed, it puts the interface back in normal mode. I surmise that a running non-promiscuous packet capture on Linux would suddenly begin receiving "misaddressed" packets if a second packet capture is started in promiscuous mode, though I have not tested.

On Windows, promiscuous mode is set by each driver (of which Npcap is one). It is one of several "packet filter" flags that can be set. If all flags are cleared, no packets are delivered. This means that we have to choose one of the other flags to be the "default" packet filter, and we (both in libpcap and in Npcap's Packet.dll) use NDIS_PACKET_TYPE_ALL_LOCAL for this. This leads to the core problem:

Because the Npcap driver is responsible for setting promiscuous mode or "normal mode," starting a second packet capture in "normal mode" can turn off the promiscuous mode for all other running captures. We need to keep track of the mode of all running captures and use the most permissive set.

The solution appears to be that we keep track of the packet filters (modes) set by all running captures and use bitwise operations to add or remove them from the final filter that we send downstream. I have not found any software that calls PacketSetHwFilter with anything other than NDIS_PACKET_TYPE_PROMISCUOUS or NDIS_PACKET_TYPE_ALL_LOCAL, but this solution ought to be able to handle it anyway. We already keep track of filters set by drivers higher on the stack so that we do not clear those filters when we set the mode ourselves, so this would be something of an extension of that.

The odd part here is that a running capture would be affected when enumerating interfaces, as this shouldn't set the underlying packet filter. In the case of Wireshark, the capture interface list shows a sparkline graph of traffic for each interface; this may be a result of opening a packet capture, which would make sense as a cause for this problem. But if I understand correctly, the original reporter claims that this happens when simply calling pcap_findalldevs_ex. Regardless, keeping track of the union of all requested packet filters ought to solve the problem.

@dmiller-nmap
Copy link
Contributor Author

This issue is fixed in Npcap 0.99-r6.

@fyodor fyodor transferred this issue from nmap/nmap May 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant