#include "ntp_request.h"
#include "ntp_assert.h"
#include "timevalops.h"
+#include "timespecops.h"
#include "ntpd-opts.h"
/* Don't include ISC's version of IPv6 variables and structures */
nic_rule *nic_rule_list;
-#if defined(SO_TIMESTAMPNS) && defined(SCM_TIMESTAMPNS) && defined(CMSG_FIRSTHDR)
+#if defined(SO_BINTIME) && defined(SCM_BINTIME) && defined(CMSG_FIRSTHDR)
+# define HAVE_PACKET_TIMESTAMP
+# define HAVE_BINTIME
+# ifdef BINTIME_CTLMSGBUF_SIZE
+# define CMSG_BUFSIZE BINTIME_CTLMSGBUF_SIZE
+# else
+# define CMSG_BUFSIZE 1536 /* moderate default */
+# endif
+#elif defined(SO_TIMESTAMPNS) && defined(SCM_TIMESTAMPNS) && defined(CMSG_FIRSTHDR)
# define HAVE_PACKET_TIMESTAMP
# define HAVE_TIMESTAMPNS
# ifdef TIMESTAMPNS_CTLMSGBUF_SIZE
fd, stoa(addr)));
}
#endif
+#ifdef HAVE_BINTIME
+ {
+ if (setsockopt(fd, SOL_SOCKET, SO_BINTIME,
+ (char*)&on, sizeof(on)))
+ msyslog(LOG_DEBUG,
+ "setsockopt SO_BINTIME on fails on address %s: %m",
+ stoa(addr));
+ else
+ DPRINTF(4, ("setsockopt SO_BINTIME enabled on fd %d address %s\n",
+ fd, stoa(addr)));
+ }
+#endif
DPRINTF(4, ("bind(%d) AF_INET%s, addr %s%%%d#%d, flags 0x%x\n",
fd, IS_IPV6(addr) ? "6" : "", stoa(addr),
)
{
struct cmsghdr * cmsghdr;
+#ifdef HAVE_BINTIME
+ struct bintime * btp;
+#endif
+#ifdef HAVE_TIMESTAMPNS
+ struct timespec * tsp;
+#endif
+#ifdef HAVE_TIMESTAMP
struct timeval * tvp;
- long ticks;
+#endif
+ unsigned long ticks;
double fuzz;
l_fp lfpfuzz;
l_fp nts;
while (cmsghdr != NULL) {
switch (cmsghdr->cmsg_type)
{
+#ifdef HAVE_BINTIME
+ case SCM_BINTIME:
+#endif /* HAVE_BINTIME */
+#ifdef HAVE_TIMESTAMPNS
+ case SCM_TIMESTAMPNS:
+#endif /* HAVE_TIMESTAMPNS */
#ifdef HAVE_TIMESTAMP
case SCM_TIMESTAMP:
- tvp = (struct timeval *)CMSG_DATA(cmsghdr);
- if (sys_tick > measured_tick &&
- sys_tick > 1e-6) {
- ticks = (long)((tvp->tv_usec * 1e-6) /
- sys_tick);
- tvp->tv_usec = (long)(ticks * 1e6 *
- sys_tick);
+#endif /* HAVE_TIMESTAMP */
+#if defined(HAVE_BINTIME) || defined (HAVE_TIMESTAMPNS) || defined(HAVE_TIMESTAMP)
+ switch (cmsghdr->cmsg_type)
+ {
+#ifdef HAVE_BINTIME
+ case SCM_BINTIME:
+ btp = (struct bintime *)CMSG_DATA(cmsghdr);
+ /*
+ * bintime documentation is at http://phk.freebsd.dk/pubs/timecounter.pdf
+ */
+ nts.l_i = btp->sec + JAN_1970;
+ nts.l_uf = (u_int32)(btp->frac >> 32);
+ if (sys_tick > measured_tick &&
+ sys_tick > 1e-9) {
+ ticks = (unsigned long)(nts.l_uf / (unsigned long)(sys_tick * FRAC));
+ nts.l_uf = (unsigned long)(ticks * (unsigned long)(sys_tick * FRAC));
+ }
+ DPRINTF(4, ("fetch_timestamp: system bintime network time stamp: %ld.%09lu\n",
+ btp->sec, (unsigned long)((nts.l_uf / FRAC) * 1e9)));
+ break;
+#endif /* HAVE_BINTIME */
+#ifdef HAVE_TIMESTAMPNS
+ case SCM_TIMESTAMPNS:
+ tsp = (struct timespec *)CMSG_DATA(cmsghdr);
+ if (sys_tick > measured_tick &&
+ sys_tick > 1e-9) {
+ ticks = (unsigned long)((tsp->tv_nsec * 1e-9) /
+ sys_tick);
+ tsp->tv_nsec = (long)(ticks * 1e9 *
+ sys_tick);
+ }
+ DPRINTF(4, ("fetch_timestamp: system nsec network time stamp: %ld.%09ld\n",
+ tsp->tv_sec, tsp->tv_nsec));
+ nts = tspec_stamp_to_lfp(*tsp);
+ break;
+#endif /* HAVE_TIMESTAMPNS */
+#ifdef HAVE_TIMESTAMP
+ case SCM_TIMESTAMP:
+ tvp = (struct timeval *)CMSG_DATA(cmsghdr);
+ if (sys_tick > measured_tick &&
+ sys_tick > 1e-6) {
+ ticks = (unsigned long)((tvp->tv_usec * 1e-6) /
+ sys_tick);
+ tvp->tv_usec = (long)(ticks * 1e6 *
+ sys_tick);
+ }
+ DPRINTF(4, ("fetch_timestamp: system usec network time stamp: %ld.%06ld\n",
+ tvp->tv_sec, tvp->tv_usec));
+ nts = tval_stamp_to_lfp(*tvp);
+ break;
+#endif /* HAVE_TIMESTAMP */
}
- DPRINTF(4, ("fetch_timestamp: system usec network time stamp: %ld.%06ld\n",
- tvp->tv_sec, tvp->tv_usec));
- nts = tval_stamp_to_lfp(*tvp);
fuzz = ntp_random() * 2. / FRAC * sys_fuzz;
DTOLFP(fuzz, &lfpfuzz);
L_ADD(&nts, &lfpfuzz);
#endif /* DEBUG_TIMING */
ts = nts; /* network time stamp */
break;
-#endif /* HAVE_TIMESTAMP */
-
-#ifdef HAVE_TIMESTAMPNS
- case SCM_TIMESTAMPNS:
- {
- struct timespec *tsp;
- double dtemp;
- l_fp nts;
-
- tsp = (struct timespec *)CMSG_DATA(cmsghdr);
- DPRINTF(4, ("fetch_timestamp: system nsec network time stamp: %ld.%09ld\n",
- tsp->tv_sec, tsp->tv_nsec));
- nts.l_i = tsp->tv_sec + JAN_1970;
- dtemp = (tsp->tv_nsec
- + (ntp_random() * 2. / FRAC)) / 1e9;
- nts.l_uf = (u_int32)(dtemp * FRAC);
-#ifdef DEBUG_TIMING
- {
- l_fp dts;
-
- dts = ts;
- L_SUB(&dts, &nts);
- collect_timing(rb,
- "input processing delay",
- 1, &dts);
- DPRINTF(4, ("fetch_timestamp: timestamp delta: %s (incl. prec fuzz)\n",
- lfptoa(&dts, 9)));
- }
-#endif
- ts = nts; /* network time stamp */
- break;
- }
-#endif /* HAVE_TIMESTAMPNS */
+#endif /* HAVE_BINTIME || HAVE_TIMESTAMPNS || HAVE_TIMESTAMP */
default:
DPRINTF(4, ("fetch_timestamp: skipping control message 0x%x\n",