From: Erik Auerswald Date: Thu, 16 Jan 2025 11:12:51 +0000 (+0100) Subject: complete SO_TIMESTAMPNS to SO_TIMESTAMP fallback X-Git-Url: https://git.gsnw.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=511aa3720639402777632a237845252b6fcf5b36;p=fping.git complete SO_TIMESTAMPNS to SO_TIMESTAMP fallback Commit e8660637ccc3bf2aae163fa7c26216843ae98180 added a fallback from setting the socket option SO_TIMESTAMPNS to setting the socket option SO_TIMESTAMP if the nanosecond timestamp option could not be set. But it did not add code to also look for the control message related to SO_TIMESTAMP. Thus microsecond timestamps were requested, but not read. This commit adds the missing code to read microsecond timestamp control messages. The problem was reported in GitHub issue #374 by @payload. --- diff --git a/CHANGELOG.md b/CHANGELOG.md index 880e7e5..6f92dba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +Next +==== + +## Bugfixes and other changes + +- Fix fallback to SO\_TIMESTAMP if SO\_TIMESTAMPNS is not available (#375, thanks + @auerswal) + fping 5.3 (2025-01-02) ====================== diff --git a/src/fping.c b/src/fping.c index 5e059d0..01cfc17 100644 --- a/src/fping.c +++ b/src/fping.c @@ -1284,6 +1284,14 @@ static inline int64_t timespec_ns(struct timespec *a) return ((int64_t)a->tv_sec * 1000000000) + a->tv_nsec; } +#if HAVE_SO_TIMESTAMPNS +/* convert a struct timeval to nanoseconds */ +static inline int64_t timeval_ns(struct timeval *a) +{ + return ((int64_t)a->tv_sec * 1000000000) + ((int64_t)a->tv_usec * 1000); +} +#endif /* HAVE_SO_TIMESTAMPNS */ + void add_cidr(char *addr) { char *addr_end; @@ -2105,6 +2113,7 @@ int receive_packet(int64_t wait_time, /* ancilliary data */ { struct timespec reply_timestamp_ts; + struct timeval reply_timestamp_tv; for (cmsg = CMSG_FIRSTHDR(&recv_msghdr); cmsg != NULL; cmsg = CMSG_NXTHDR(&recv_msghdr, cmsg)) { @@ -2112,6 +2121,10 @@ int receive_packet(int64_t wait_time, memcpy(&reply_timestamp_ts, CMSG_DATA(cmsg), sizeof(reply_timestamp_ts)); *reply_timestamp = timespec_ns(&reply_timestamp_ts); } + if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMP) { + memcpy(&reply_timestamp_tv, CMSG_DATA(cmsg), sizeof(reply_timestamp_tv)); + *reply_timestamp = timeval_ns(&reply_timestamp_tv); + } } } #endif