捕获实时流量时如何打开纳秒级精度?

How do I turn on nanosecond precision when capturing live traffic?

如何让 libpcap v1.6.2 在捕获实时数据包时将纳秒值存储在 struct pcap_pkthdr::ts.tv_usec(而不是微秒值)中?

(注意:这个问题和How to enable nanosecond resolution when capturing live packets in libpcap?很相似,但是那个问题很模糊,所以我决定问一个新问题。)

对于离线和 "dead" 捕获,可以使用以下函数告诉 libpcap 用纳秒值填充 struct pcap_pkthdrts.tv_usec 成员:

不幸的是,pcap_open_live() or pcap_create() 似乎没有 _with_tstamp_precision 个变体。

我相信捕获具有纳秒分辨率的实时数据包应该是可能的,因为 v1.5.0 的 changelog 说(强调我的):

Add support for getting nanosecond-resolution time stamps when capturing and reading capture files

我确实看到了 pcap_set_tstamp_type() function and the pcap-tstamp man page,上面写着:

  • PCAP_TSTAMP_HOSThost: Time stamp provided by the host on which the capture is being done. The precision of this time stamp is unspecified; it might or might not be synchronized with the host operating system's clock.
  • PCAP_TSTAMP_HOST_LOWPREChost_lowprec: Time stamp provided by the host on which the capture is being done. This is a low-precision time stamp, synchronized with the host operating system's clock.
  • PCAP_TSTAMP_HOST_HIPREChost_hiprec: Time stamp provided by the host on which the capture is being done. This is a high-precision time stamp; it might or might not be synchronized with the host operating system's clock. It might be more expensive to fetch than PCAP_TSTAMP_HOST_LOWPREC.
  • PCAP_TSTAMP_ADAPTERadapter: Time stamp provided by the network adapter on which the capture is being done. This is a high-precision time stamp, synchronized with the host operating system's clock.
  • PCAP_TSTAMP_ADAPTER_UNSYNCEDadapter_unsynced: Time stamp provided by the network adapter on which the capture is being done. This is a high-precision time stamp; it is not synchronized with the host operating system's clock.

这里的短语 "high-precision time stamp" 是否意味着纳秒值存储在 header 的 ts.tv_usec 字段中?如果是这样,PCAP_TSTAMP_HOST 表示 "unspecified",那么我如何在运行时确定 ts.tv_usec 字段是微秒还是纳秒?如果从不调用 pcap_set_tstamp_type(),其中哪一个是默认值?

pcap_create() 几乎没有为捕获设备设置参数,并且没有其他调用来设置这些参数;这是设计使然。引入 pcap_create()pcap_activate() 的目的是,为了支持新参数,这些调用都不必更改,并且随着新参数的引入,将引入新的 API .

您应该调用 pcap_create() 来创建一个尚未激活的句柄,使用适当的调用设置参数,然后尝试使用 pcap_activate() 激活句柄。

其中一个合适的调用是 pcap_set_tstamp_precision(),这是您在 pcap_create()pcap_activate() 之间使用的调用,用于指定您需要纳秒级精度的时间戳。默认为微秒精度时间戳,用于向后源和二进制兼容性。

请注意,如果您无法从正在捕获的设备上获取纳秒精度的时间戳,pcap_set_tstamp_precision() 将会失败,因此您必须检查它是成功还是失败,或者调用 pcap_get_tstamp_precision() 在激活 pcap_t 以查看您将获得的时间戳精度后。

而且,不,"high-precision" 与您获得的是微秒还是纳秒无关,它与标称的微秒或纳秒值是否真的提供微秒或纳秒粒度有关,或者您是否总是得到的值是 10 的幂的倍数,因为所使用的时钟不能精确到微秒或纳秒。