ソフトウェアのタイムスタンプに使用されるsocket属性は、SO_TIMESTAMPNSです。このソケット属性は、システムクロックから時刻を返します。ハードウェアで生成されるのではなく、ソフトウェアで割り込みが処理されるシステム時間のスナップショットです。私たちは使用して、ソケットのペイロードの一部ではない補助的なデータ(CMSG)を介してこのタイムスタンプにアクセスすることができます。
int level, type;
struct cmsghdr *cm;
struct timespec *ts = NULL;
for (cm = CMSG_FIRSTHDR(&msg); cm != NULL; cm = CMSG_NXTHDR(&msg, cm))
{
level = cm->cmsg_level;
type = cm->cmsg_type;
if (SOL_SOCKET == level && SO_TIMESTAMPNS == type) {
ts = (struct timespec *) CMSG_DATA(cm);
printf("SW TIMESTAMP %ld.%09ld\n", (long)ts[0].tv_sec, (long)ts[0].tv_nsec);
}
}
SO_TIMESTAMPINGソケットオプションは、多くの異なるフラグを提供しています、そのうちのいくつかはある、
SOF_TIMESTAMPING_TX_HARDWARE // Transmit timestamp generated in hardware by NIC clock
SOF_TIMESTAMPING_RX_HARDWARE // Receive timestamp generated in hardware by NIC clock
SOF_TIMESTAMPING_TX_SOFTWARE // Transmit timestamp generated in kernel driver by NIC clock
SOF_TIMESTAMPING_RX_SOFTWARE // Receive timestamp generated in kernel driver by NIC clock
このソケットオプションは、すべてのネットワークインターフェイスカード(NIC)でサポートされていません。現在、多くのイーサネットNICがSO_TIMESTAMPINGをサポートしています。
ethtool -T ethX // where X corresponds to your particular interface
これは、すべてのソケットがethXをがタイムスタンプのためにサポートしている属性が返されます:特定のインタフェースドライバがSO_TIMESTAMPING、使用をサポートしているかどうか見つけるために。
のコードを使用し、特定のNICによって提供されるハードウェアタイムスタンプ機能を使用するには、次のサポート、他のカーネルならば
int flags;
flags = SOF_TIMESTAMPING_TX_HARDWARE
| SOF_TIMESTAMPING_RX_HARDWARE
| SOF_TIMESTAMPING_TX_SOFTWARE
| SOF_TIMESTAMPING_RX_SOFTWARE
| SOF_TIMESTAMPING_RAW_HARDWARE;
if (setsockopt(sd, SOL_SOCKET, SO_TIMESTAMPING, &flags, sizeof(flags)) < 0)
printf("ERROR: setsockopt SO_TIMESTAMPING\n");
int level, type;
struct cmsghdr *cm;
struct timespec *ts = NULL;
for (cm = CMSG_FIRSTHDR(&msg); cm != NULL; cm = CMSG_NXTHDR(&msg, cm))
{
if (SOL_SOCKET == level && SO_TIMESTAMPING == type) {
ts = (struct timespec *) CMSG_DATA(cm);
printf("HW TIMESTAMP %ld.%09ld\n", (long)ts[2].tv_sec, (long)ts[2].tv_nsec);
}
}
ハードウェアを。通常、このようなハードウェアはPTPのようなものを使用してカードを同期させますので、クロックに関連してタイムスタンプを受け取るようにしてください(単調であることは確かではありません - 他の誰かがコメントできるかもしれません...) – Nim
@Nimサポートされていればハードウェアを返しますか? SO_TIMESTAMPNS?ハードウェアタイムスタンプを有効にする必要がありますか? – Maverik
通常、この機能をサポートするハードウェアはソケットオプション( 'SO_TIMESTAMPNS'または' SO_TIMESTAMP')を見て、パケットをスタンプします。たとえば、適切な太陽フレアカードがある場合、オプションを設定すると、カードにタイムスタンプが設定されます。それ以外の場合は、カーネルによって管理されます。率直に言って、タイムスタンプを実際に得るためには、コントロールヘッダーを読まなければならないのは本当に好きではありません。恐ろしいインターフェイスです。 – Nim