You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Npcap: packet capture interrupted when enumerating devices or opening another packet capture #401
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[/+]on May 1, 2018
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.
Activity
[-]Npcap: packet capture interrupted when enumerating devices under 100Mbps load[/-][+]Npcap: packet capture interrupted when enumerating devices or opening another packet capture[/+]dmiller-nmap commentedon May 1, 2018
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_PACKETsockets.In libpcap (which is included in Npcap as wpcap.dll), promiscuous mode is a boolean flag within the
pcap_thandle, set or cleared withpcap_set_promisc. Libpcap checks this flag when activating the pcap handle, and sets thePACKET_ADD_MEMBERSHIPsocket option with thePACKET_MR_PROMISCflag 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_LOCALfor 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
PacketSetHwFilterwith anything other thanNDIS_PACKET_TYPE_PROMISCUOUSorNDIS_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.Track packet filter separately for each open instance. See nmap/nmap#…
dmiller-nmap commentedon Jun 13, 2018
This issue is fixed in Npcap 0.99-r6.