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

Support timestamp method selection by capture handle rather than registry key #46

Closed
fyodor opened this issue Oct 7, 2019 · 5 comments

Comments

@fyodor
Copy link
Member

fyodor commented Oct 7, 2019

Operating systems have various timestamp methods available with differing tradeoffs between granularity, accuracy, precision, efficiency, etc.

Npcap has an undocumented legacy method (inherited from Winpcap) for choosing this on a system-wide basis using TimestampMode registry key. It can be set to "0", "2", or "3":

  • 0 is the default and uses KeQueryPerformanceCounter. This provides great precision (some microseconds) but is less reliable on SMP/HyperThreading machines since it doesn't return monotonic values across multiple CPUs.
  • 2 uses KeQuerySystemTime instead, which is more reliable on SMP/HyperThreading machines, with a precision of a scheduling quantum (10/15 milliseconds)
  • 3 uses the i386 RDTSC instruction. This is also less reliable on SMP/HyperThreading/SpeedStep machines and has a precision of some microseconds.

The registry location for this key depends on whether you are using Npcap native mode or Winpcap compatible:

  • HKLM\System\CurrentControlSet\Services\npcap\Parameters\TimestampMode if using Npcap native API mode (npcap driver)
  • HKLM\System\CurrentControlSet\Services\npf\Parameters\TimestampMode if using Winpcap compatible mode (npf driver)

It is probably best to just set both. Also note that even the Winpcap compatible location is a bit different than what Winpcap uses (which is HKLM\System\CurrentControlSet\Services\NPF\TimestampMode).

We have verified that this feature works with Npcap 0.9983, but we haven't officially documented it because setting the timestamp mode system-wide is not a great approach. It could cause issues if multiple applications are using Npcap and each wants a different mode.

The better method that we might actually want to officially support uses the per-capture handle timestamp option as described here. That describes the options available on several platforms, but we don't offer any non-default options through this API on Windows (Npcap). But we might, if we see demand for it. We created this issue both to document the current situation and also so folks can comment if the normal default mechanism doesn't work well for them. Please also note what you would prefer and why. The more well-supported requests we get, the more we can prioritize this issue. We don't waste time implementing a feature that nobody seems to want. And, at least for our Nmap Security Scanner, the default timestamp methods seem to be working well enough for us.

@fyodor fyodor changed the title Add capture handle timestamp type support Support timestamp method selection by capture handle rather than registry key Oct 9, 2019
@fyodor
Copy link
Member Author

fyodor commented Oct 9, 2019

Just as a data point, I was conversing with one Npcap user today who is now using mode "2" because they want the monotonic data.

@guyharris
Copy link
Contributor

See also issue nmap/nmap#1407 "Can Npcap use KeQuerySystemTimePrecise() if running on Windows 8 or later?"

@guyharris
Copy link
Contributor

And note that the set of timestamp types can be expanded if none apply to the modes Npcap can offer. The legacy WinPcap modes are all "host" modes, so they would be PCAP_TSTAMP_HOST_ modes.

dmiller-nmap referenced this issue Mar 16, 2020
Any of the supported timestamp modes can be set via
PacketSetTimestampMode(), which uses the new BIOCSTIMESTAMPMODE
IoControl code. The TimestampMode Registry setting is still observed as
the default for new capture handles. Changing the timestamp mode will
empty the kernel's capture buffer to avoid conflict between timestamps
in captured packets.
@guyharris
Copy link
Contributor

So the next step would be to have a packet.dll interface to get a list of all the supported TIMESTAMP_ modes for a given handle. (Currently, it's system-wide, rather than per-adapter, but if Microsoft ever offers a way to get adapters that have their own clocks to provide time stamps to NDIS filter drivers, it could become per-adapter, so let's make it per-handle.)

Then the next step would be to add support for pcap_list_tstamp_types() and pcap_set_tstamp_type() to pcap-npf.c.

Note, however, that, on Windows 8 and later, TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE is probably what almost all, if not all, users would want; it offers high-resolution time stamps synchronized with the system clock, with the only potential disadvantage being performance, if KeQuerySystemTimePrecise() is sufficiently slower than either KeQuerySystemTime() (for mode 2's low-resolution time stamps synchronized with the system clock) or KeQueryPerformanceCounter() (for mode 0's high-resolution time stamps not synchronized with the system clock).

Offering a choice for Windows 7 might be worthwhile, as you can't get both high resolution and synchronization with the system clock, so you'd have to choose which you want - assuming the now-supported-only-maybe-by-extra-long-term-support-with-Microsoft Windows 7 is worth adding that. (Note that Wireshark currently has no way to request different time stamp types from the GUI, so that would need to be added. tcpdump and dumpcap support specifying the time stamp type.)

@fyodor fyodor transferred this issue from nmap/nmap May 20, 2020
@dmiller-nmap
Copy link
Contributor

dmiller-nmap commented Jul 14, 2020

Since timestamp method selection is already available per capture handle, I'm closing this issue. The idea for getting a list of timestamp modes via ioctl is #174

Regarding "TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE is probably what almost all, if not all, users would want," I think Nmap in particular would rather have all clocks monotonically increasing, since it's less important for us what time the wall clock said when a packet arrived as it is how long it has been since we sent the probe that elicited the response. Unfortunately, on all systems we use gettimeofday() for measuring time intervals, so QST is probably better for now, but nmap/nmap#180 may get fixed eventually :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants