--- attic/backwards.c.orig 2022-12-22 22:08:52.000000000 -0800 +++ attic/backwards.c 2023-12-30 22:12:39.000000000 -0800 @@ -7,6 +7,8 @@ #include #include +#include "ntp_machine.h" /* For clock_gettime fallback */ + #define UNUSED_ARG(arg) ((void)(arg)) static void ts_print(struct timespec *ts0, struct timespec *ts1); --- attic/clocks.c.orig 2023-12-28 20:53:56.000000000 -0800 +++ attic/clocks.c 2023-12-30 22:12:39.000000000 -0800 @@ -9,6 +9,8 @@ #include +#include "ntp_machine.h" /* For clock_gettime fallback */ + struct table { const int type; const char* name; --- attic/cmac-timing.c.orig 2023-12-28 20:53:53.000000000 -0800 +++ attic/cmac-timing.c 2023-12-30 22:12:39.000000000 -0800 @@ -36,6 +36,8 @@ #include #endif +#include "ntp_machine.h" /* For clock_gettime fallback */ + #define UNUSED_ARG(arg) ((void)(arg)) --- attic/digest-timing.c.orig 2023-12-28 20:53:56.000000000 -0800 +++ attic/digest-timing.c 2023-12-30 22:12:39.000000000 -0800 @@ -32,6 +32,8 @@ #include #include +#include "ntp_machine.h" /* For clock_gettime fallback */ + #define UNUSED_ARG(arg) ((void)(arg)) #ifndef EVP_MD_CTX_new --- attic/random.c.orig 2023-12-28 20:53:56.000000000 -0800 +++ attic/random.c 2023-12-30 22:12:39.000000000 -0800 @@ -10,6 +10,8 @@ #include /* for OPENSSL_VERSION_NUMBER */ #include +#include "ntp_machine.h" /* For clock_gettime fallback */ + #define BATCHSIZE 1000000 #define BILLION 1000000000 #define HISTSIZE 2500 --- include/ntp_machine.h.orig 2022-12-22 22:08:52.000000000 -0800 +++ include/ntp_machine.h 2023-12-30 22:12:39.000000000 -0800 @@ -13,14 +13,145 @@ #ifndef CLOCK_REALTIME /* - * Pacify platforms that don't have a real clock_gettime(2), - * notably Mac OS X. + * Handle platforms that don't have a real clock_gettime(2), + * notably some versions of Mac OS X. */ -#define CLOCK_REALTIME 0 -#define CLOCK_MONOTONIC 1 + +#include + typedef int clockid_t; -int clock_gettime(clockid_t clock_id, struct timespec *tp); -#endif + +#define CLOCK_REALTIME 0 + +#ifdef __APPLE__ + +#define CLOCK_MONOTONIC 1 +#define CLOCK_MONOTONIC_RAW 2 + +#include +#include +#include + +#endif /* __APPLE__ */ + +static inline int clock_gettime(clockid_t clk_id, struct timespec *tp) +{ + switch (clk_id) { + + case CLOCK_REALTIME: + { + /* + * On OSX, it's tempting to use clock_get_time() for its apparent + * nanosecond resolution, but it really only has microsecond + * resolution, and is substantially slower than gettimeofday(). + */ + struct timeval tv; + + if (gettimeofday(&tv, NULL)) + return -1; + tp->tv_sec = tv.tv_sec; + tp->tv_nsec = tv.tv_usec * 1000; + return 0; + } + +#ifdef __APPLE__ + case CLOCK_MONOTONIC: + { + mach_timespec_t mts; + static clock_serv_t sclock = 0; + + /* + * Obtain clock port on first call, then reuse it. + * Rely on exit cleanup to free it. + */ + if (!sclock) { + mach_port_t mach_host = mach_host_self(); + host_get_clock_service(mach_host, + SYSTEM_CLOCK, &sclock); + mach_port_deallocate(mach_task_self(), mach_host); + } + clock_get_time(sclock, &mts); + tp->tv_sec = mts.tv_sec; + tp->tv_nsec = mts.tv_nsec; + return 0; + } + + case CLOCK_MONOTONIC_RAW: + { + static mach_timebase_info_data_t sTimebaseInfo = {0, 0}; + unsigned long long nanos; + + /* Obtain scale factors on first call, then reuse them. */ + if ( sTimebaseInfo.denom == 0 ) { + (void) mach_timebase_info(&sTimebaseInfo); + } + nanos = mach_absolute_time() + * sTimebaseInfo.numer / sTimebaseInfo.denom; + tp->tv_sec = nanos / 1000000000U; + tp->tv_nsec = nanos - tp->tv_sec * 1000000000U; + return 0; + } +#endif /* __APPLE__ */ + + default: + errno = EINVAL; + return -1; + } +} + +static inline int clock_getres(clockid_t clk_id, struct timespec *res) +{ + switch (clk_id) { + + case CLOCK_REALTIME: + res->tv_sec = 0; + res->tv_nsec = 1000; + return 0; + +#ifdef __APPLE__ + case CLOCK_MONOTONIC: + case CLOCK_MONOTONIC_RAW: + res->tv_sec = 0; + res->tv_nsec = 1; + return 0; +#endif /* __APPLE__ */ + + default: + errno = EINVAL; + return -1; + } +} + +/* + * Prototype for settimeofday() may suppressed by feature-test flags. + * Provide it here just in case, and get an error if it mismatches. + * Similarly, "struct timezone" definition may be suppressed, but the + * incomplete definition provided here is adequate given that the + * timezone argument is unused. + */ +struct timezone; +int settimeofday(const struct timeval *, const struct timezone *); + +static inline int clock_settime(clockid_t clk_id, const struct timespec *tp) +{ + switch (clk_id) { + + case CLOCK_REALTIME: + { + struct timeval tv; + + tv.tv_sec = tp->tv_sec; + tv.tv_usec = (tp->tv_nsec + 500) / 1000; + return settimeofday(&tv, NULL); + } + + default: + errno = EINVAL; + return -1; + } +} + +#endif /* !CLOCK_REALTIME */ int ntp_set_tod (struct timespec *tvs); --- include/ntp_stdlib.h.orig 2023-12-28 20:53:56.000000000 -0800 +++ include/ntp_stdlib.h 2023-12-30 22:12:39.000000000 -0800 @@ -103,7 +103,9 @@ extern const char * eventstr (int); extern const char * ceventstr (int); extern const char * res_match_flags(unsigned short); extern const char * res_access_flags(unsigned short); +#ifdef HAVE_KERNEL_PLL extern const char * k_st_flags (uint32_t); +#endif extern char * statustoa (int, int); extern const char * socktoa (const sockaddr_u *); extern const char * socktoa_r (const sockaddr_u *sock, char *buf, size_t buflen); --- include/ntp_syscall.h.orig 2022-12-22 22:08:52.000000000 -0800 +++ include/ntp_syscall.h 2023-12-30 22:12:39.000000000 -0800 @@ -9,9 +9,11 @@ #ifndef GUARD_NTP_SYSCALL_H #define GUARD_NTP_SYSCALL_H +#ifdef HAVE_SYS_TIMEX_H # include /* prerequisite on NetBSD */ # include extern int ntp_adjtime_ns(struct timex *); +#endif /* * The units of the maxerror and esterror fields vary by platform. If --- libntp/clockwork.c.orig 2023-12-28 20:53:56.000000000 -0800 +++ libntp/clockwork.c 2023-12-30 22:12:39.000000000 -0800 @@ -5,8 +5,10 @@ #include "config.h" #include -#include /* prerequisite on NetBSD */ -#include +#ifdef HAVE_SYS_TIMEX_H +# include /* prerequisite on NetBSD */ +# include +#endif #include "ntp.h" #include "ntp_machine.h" --- libntp/statestr.c.orig 2022-12-22 22:08:52.000000000 -0800 +++ libntp/statestr.c 2023-12-30 22:12:39.000000000 -0800 @@ -12,7 +12,9 @@ #include "lib_strbuf.h" #include "ntp_refclock.h" #include "ntp_control.h" +#ifdef HAVE_KERNEL_PLL # include "ntp_syscall.h" +#endif /* @@ -186,23 +188,50 @@ static const struct codestring res_acces /* not used with getcode(), no terminating entry needed */ }; +#ifdef HAVE_KERNEL_PLL /* * kernel discipline status bits */ static const struct codestring k_st_bits[] = { +# ifdef STA_PLL { STA_PLL, "pll" }, +# endif +# ifdef STA_PPSFREQ { STA_PPSFREQ, "ppsfreq" }, +# endif +# ifdef STA_PPSTIME { STA_PPSTIME, "ppstime" }, +# endif +# ifdef STA_FLL { STA_FLL, "fll" }, +# endif +# ifdef STA_INS { STA_INS, "ins" }, +# endif +# ifdef STA_DEL { STA_DEL, "del" }, +# endif +# ifdef STA_UNSYNC { STA_UNSYNC, "unsync" }, +# endif +# ifdef STA_FREQHOLD { STA_FREQHOLD, "freqhold" }, +# endif +# ifdef STA_PPSSIGNAL { STA_PPSSIGNAL, "ppssignal" }, +# endif +# ifdef STA_PPSJITTER { STA_PPSJITTER, "ppsjitter" }, +# endif +# ifdef STA_PPSWANDER { STA_PPSWANDER, "ppswander" }, +# endif +# ifdef STA_PPSERROR { STA_PPSERROR, "ppserror" }, +# endif +# ifdef STA_CLOCKERR { STA_CLOCKERR, "clockerr" }, +# endif # ifdef STA_NANO { STA_NANO, "nano" }, # endif @@ -214,6 +243,7 @@ static const struct codestring k_st_bits # endif /* not used with getcode(), no terminating entry needed */ }; +#endif /* HAVE_KERNEL_PLL */ /* Forwards */ static const char * getcode(int, const struct codestring *); @@ -318,10 +348,12 @@ decode_bitflags( "decode_bitflags(%s) can't decode 0x%x in %d bytes", (tab == peer_st_bits) ? "peer_st" - : + : +#ifdef HAVE_KERNEL_PLL (tab == k_st_bits) ? "kern_st" : +#endif "", (unsigned)bits, (int)LIB_BUFLENGTH); errno = saved_errno; @@ -360,6 +392,7 @@ res_access_flags( } +#ifdef HAVE_KERNEL_PLL const char * k_st_flags( uint32_t st @@ -367,6 +400,8 @@ k_st_flags( { return decode_bitflags((int)st, " ", k_st_bits, COUNTOF(k_st_bits)); } +#endif /* HAVE_KERNEL_PLL */ + /* * statustoa - return a descriptive string for a peer status --- ntpd/ntp_control.c.orig 2023-12-28 20:53:56.000000000 -0800 +++ ntpd/ntp_control.c 2023-12-30 22:12:39.000000000 -0800 @@ -35,7 +35,9 @@ struct utsname utsnamebuf; /* Variables that need updating each time. */ static leap_signature_t lsig; +#ifdef HAVE_KERNEL_PLL static struct timex ntx; +#endif /* HAVE_KERNEL_PLL */ /* * Statistic counters to keep track of requests and responses. @@ -364,6 +366,7 @@ static const struct var sys_var[] = { Var_uli("authcmacdecrypts", RO, authcmacdecrypt), Var_uli("authcmacfails", RO, authcmacfail), +#ifdef HAVE_KERNEL_PLL /* kerninfo: Kernel timekeeping info */ Var_kli("koffset", RO|N_CLOCK|KNUToMS, ntx.offset), Var_kli("kfreq", RO|N_CLOCK|K_16, ntx.freq), @@ -381,6 +384,7 @@ static const struct var sys_var[] = { Var_li("kppscaliberrs", RO|N_CLOCK, ntx.errcnt), Var_li("kppsjitexc", RO|N_CLOCK, ntx.jitcnt), Var_li("kppsstbexc", RO|N_CLOCK, ntx.stbcnt), +#endif /* HAVE_KERNEL_PLL */ /* refclock stuff in ntp_io */ @@ -1395,7 +1399,9 @@ ctl_putarray( */ static void ctl_putsys(const struct var * v) { +#ifdef HAVE_KERNEL_PLL static unsigned long ntp_adjtime_time; +#endif /* HAVE_KERNEL_PLL */ static unsigned long ntp_leap_time; /* older compilers don't allow declarations on each case without {} */ @@ -1407,6 +1413,7 @@ ctl_putsys(const struct var * v) { * This should get pushed up a layer: flag, once per request * This could get data from 2 samples if the clock ticks while we are working.. */ +#ifdef HAVE_KERNEL_PLL /* The Kernel clock variables need up-to-date output of ntp_adjtime() */ if (v->flags&N_CLOCK && current_time != ntp_adjtime_time) { ZERO(ntx); @@ -1415,6 +1422,7 @@ ctl_putsys(const struct var * v) { "MODE6: ntp_adjtime() for mode 6 query failed: %s", strerror(errno)); ntp_adjtime_time = current_time; } +#endif /* HAVE_KERNEL_PLL */ /* The leap second variables need up-to-date info */ if (v->flags&N_LEAP && current_time != ntp_leap_time) { --- ntpd/ntp_loopfilter.c.orig 2023-12-28 20:53:56.000000000 -0800 +++ ntpd/ntp_loopfilter.c 2023-12-30 22:12:39.000000000 -0800 @@ -23,8 +23,10 @@ #define NTP_MAXFREQ 500e-6 +#ifdef HAVE_KERNEL_PLL # define FREQTOD(x) ((x) / 65536e6) /* NTP to double */ # define DTOFREQ(x) ((int32_t)((x) * 65536e6)) /* double to NTP */ +#endif /* HAVE_KERNEL_PLL */ /* * This is an implementation of the clock discipline algorithm described @@ -125,6 +127,7 @@ static void rstclock (int, double); /* t static double direct_freq(double); /* direct set frequency */ static void set_freq(double); /* set frequency */ +#ifdef HAVE_KERNEL_PLL #ifndef PATH_MAX # define PATH_MAX MAX_PATH #endif @@ -138,6 +141,7 @@ static unsigned int loop_tai; /* last TA #endif /* STA_NANO */ static void start_kern_loop(void); static void stop_kern_loop(void); +#endif /* HAVE_KERNEL_PLL */ /* * Clock state machine control flags @@ -154,7 +158,9 @@ struct clock_control_flags clock_ctl = { int freq_cnt; /* initial frequency clamp */ static int freq_set; /* initial set frequency switch */ +#ifdef HAVE_KERNEL_PLL static bool ext_enable; /* external clock enabled */ +#endif /* HAVE_KERNEL_PLL */ /* * Clock state machine variables @@ -172,10 +178,13 @@ static int sys_hufflen; /* huff-n'-puff static int sys_huffptr; /* huff-n'-puff filter pointer */ static double sys_mindly; /* huff-n'-puff filter min delay */ +#if defined(HAVE_KERNEL_PLL) /* Emacs cc-mode goes nuts if we split the next line... */ #define MOD_BITS (MOD_OFFSET | MOD_MAXERROR | MOD_ESTERROR | \ MOD_STATUS | MOD_TIMECONST) +#endif /* HAVE_KERNEL_PLL */ +#ifdef HAVE_KERNEL_PLL static void sync_status(const char *what, int ostatus, int nstatus) { /* only used in non-lockclock case */ @@ -199,6 +208,7 @@ static char *file_name(void) { } return this_file; } +#endif /* HAVE_KERNEL_PLL */ /* * init_loopfilter - initialize loop filter data @@ -213,6 +223,7 @@ init_loopfilter(void) { freq_cnt = (int)clock_minstep; } +#ifdef HAVE_KERNEL_PLL /* * ntp_adjtime_error_handler - process errors from ntp_adjtime */ @@ -411,6 +422,7 @@ or, from ntp_adjtime(): } return; } +#endif /* HAVE_KERNEL_PLL */ /* * local_clock - the NTP logical clock loop filter. @@ -444,7 +456,9 @@ local_clock( int rval; /* return code */ int osys_poll; /* old system poll */ +#ifdef HAVE_KERNEL_PLL int ntp_adj_ret; /* returned by ntp_adjtime */ +#endif /* HAVE_KERNEL_PLL */ double mu; /* interval since last update */ double clock_frequency; /* clock frequency */ double dtemp, etemp; /* double temps */ @@ -701,6 +715,7 @@ local_clock( } } +#ifdef HAVE_KERNEL_PLL /* * This code segment works when clock adjustments are made using * precision time kernel support and the ntp_adjtime() system @@ -810,6 +825,7 @@ local_clock( } #endif /* STA_NANO */ } +#endif /* HAVE_KERNEL_PLL */ /* * Clamp the frequency within the tolerance range and calculate @@ -921,8 +937,10 @@ adj_host_clock( } else if (freq_cnt > 0) { offset_adj = clock_offset / (CLOCK_PLL * ULOGTOD(1)); freq_cnt--; +#ifdef HAVE_KERNEL_PLL } else if (clock_ctl.pll_control && clock_ctl.kern_enable) { offset_adj = 0.; +#endif /* HAVE_KERNEL_PLL */ } else { offset_adj = clock_offset / (CLOCK_PLL * ULOGTOD(clkstate.sys_poll)); } @@ -933,9 +951,11 @@ adj_host_clock( * set_freq(). Otherwise it is a component of the adj_systime() * offset. */ +#ifdef HAVE_KERNEL_PLL if (clock_ctl.pll_control && clock_ctl.kern_enable) freq_adj = 0.; else +#endif /* HAVE_KERNEL_PLL */ freq_adj = loop_data.drift_comp; /* Bound absolute value of total adjustment to NTP_MAXFREQ. */ @@ -1024,6 +1044,7 @@ set_freq( loop_data.drift_comp = freq; loop_desc = "ntpd"; +#ifdef HAVE_KERNEL_PLL if (clock_ctl.pll_control) { int ntp_adj_ret; ZERO(ntv); @@ -1036,10 +1057,12 @@ set_freq( ntp_adjtime_error_handler(__func__, &ntv, ntp_adj_ret, errno, false, false, __LINE__ - 1); } } +#endif /* HAVE_KERNEL_PLL */ mprintf_event(EVNT_FSET, NULL, "%s %.6f PPM", loop_desc, loop_data.drift_comp * US_PER_S); } +#ifdef HAVE_KERNEL_PLL static void start_kern_loop(void) { @@ -1075,8 +1098,10 @@ start_kern_loop(void) "kernel time sync enabled"); } } +#endif /* HAVE_KERNEL_PLL */ +#ifdef HAVE_KERNEL_PLL static void stop_kern_loop(void) { @@ -1084,6 +1109,7 @@ stop_kern_loop(void) report_event(EVNT_KERN, NULL, "kernel time sync disabled"); } +#endif /* HAVE_KERNEL_PLL */ /* @@ -1096,11 +1122,15 @@ select_loop( { if (clock_ctl.kern_enable == use_kern_loop) return; +#ifdef HAVE_KERNEL_PLL if (clock_ctl.pll_control && !use_kern_loop) stop_kern_loop(); +#endif /* HAVE_KERNEL_PLL */ clock_ctl.kern_enable = use_kern_loop; +#ifdef HAVE_KERNEL_PLL if (clock_ctl.pll_control && use_kern_loop) start_kern_loop(); +#endif /* HAVE_KERNEL_PLL */ /* * If this loop selection change occurs after initial startup, * call set_freq() to switch the frequency compensation to or @@ -1156,10 +1186,12 @@ loop_config( * variables. Otherwise, continue leaving no harm behind. */ case LOOP_DRIFTINIT: +#ifdef HAVE_KERNEL_PLL if (loop_data.lockclock || clock_ctl.mode_ntpdate) break; start_kern_loop(); +#endif /* HAVE_KERNEL_PLL */ /* * Initialize frequency if given; otherwise, begin frequency @@ -1178,11 +1210,14 @@ loop_config( rstclock(EVNT_FSET, 0); else rstclock(EVNT_NSET, 0); +#ifdef HAVE_KERNEL_PLL loop_started = true; +#endif /* HAVE_KERNEL_PLL */ break; case LOOP_KERN_CLEAR: #if 0 /* XXX: needs more review, and how can we get here? */ +# ifdef HAVE_KERNEL_PLL if (!loop_data.lockclock && (clock_ctl.pll_control && clock_ctl.kern_enable)) { memset((char *)&ntv, 0, sizeof(ntv)); ntv.modes = MOD_STATUS; @@ -1192,6 +1227,7 @@ loop_config( pll_status, ntv.status); } +# endif /* HAVE_KERNEL_PLL */ #endif break; @@ -1272,4 +1308,3 @@ loop_config( "CONFIG: loop_config: unsupported option %d", item); } } - --- ntpd/ntp_packetstamp.c.orig 2022-12-22 22:08:52.000000000 -0800 +++ ntpd/ntp_packetstamp.c 2023-12-30 22:12:39.000000000 -0800 @@ -6,6 +6,7 @@ */ #include "config.h" +#include #ifdef HAVE_SYS_IOCTL_H # include #endif @@ -33,6 +34,44 @@ * */ +/* + * OSX prior to 10.6 defines CMSG_DATA incorrectly in 64-bit builds, due to + * bad alignment assumptions. + * + * In those OS versions we substitute a version of the definition from >=10.6. + */ + +#if defined(__APPLE__) \ + && (!defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) \ + || __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1060) + +#define __DARWIN_ALIGNBYTES32 (sizeof(__uint32_t) - 1) +#define __DARWIN_ALIGN32(p) \ + ((size_t)((char *)(size_t)(p) \ + + __DARWIN_ALIGNBYTES32) &~ __DARWIN_ALIGNBYTES32) + +/* given pointer to struct cmsghdr, return pointer to data */ +#undef CMSG_DATA +#define CMSG_DATA(cmsg) ((unsigned char *)(cmsg) + \ + __DARWIN_ALIGN32(sizeof(struct cmsghdr))) + +#endif /* OSX < 10.6 */ + +/* + * Packet timestamps use the kernel's notion of time_t, which may not match + * the userspace version. We need to accomodate both 32- and 64-bit + * versions. + */ + +struct timeval_32 { + uint32_t tv_sec; /* Unsigned to get past 2038 */ + int32_t tv_usec; +}; + +struct timeval_64 { + int64_t tv_sec; + int32_t tv_usec; +}; void enable_packetstamps( @@ -104,10 +143,11 @@ fetch_packetstamp( ) { struct cmsghdr * cmsghdr; + int datalen; #if defined(SO_TIMESTAMPNS) || defined(SO_TS_CLOCK) struct timespec * tsp; #elif defined(SO_TIMESTAMP) - struct timeval * tvp; + struct timeval tv; #endif #ifdef ENABLE_FUZZ unsigned long ticks; @@ -124,6 +164,7 @@ fetch_packetstamp( exit(2); /* return ts; ** Kludge to use time from select. */ } + datalen = cmsghdr->cmsg_len - sizeof(*cmsghdr); #if defined(SO_TIMESTAMPNS) /* Linux and ?? */ if (SCM_TIMESTAMPNS != cmsghdr->cmsg_type) { @@ -160,16 +201,42 @@ fetch_packetstamp( (long)tsp->tv_sec, tsp->tv_nsec)); nts = tspec_stamp_to_lfp(*tsp); #elif defined(SO_TIMESTAMP) - tvp = (struct timeval *)CMSG_DATA(cmsghdr); + switch (datalen) { + + case sizeof(struct timeval_32): + { + struct timeval_32 *tvp = (struct timeval_32 *) + CMSG_DATA(cmsghdr); + tv.tv_sec = tvp->tv_sec; tv.tv_usec = tvp->tv_usec; + } + break; + + case sizeof(struct timeval_64): + { + struct timeval_64 *tvp = (struct timeval_64 *) + CMSG_DATA(cmsghdr); + tv.tv_sec = tvp->tv_sec; tv.tv_usec = tvp->tv_usec; + } + break; + + default: + DPRINT(4, + ("fetch_timestamp: bad timestamp length %d", + datalen)); + msyslog(LOG_ERR, + "ERR: fetch_timestamp: bad timestamp length %d", + datalen); + exit(2); + } #ifdef ENABLE_FUZZ if (sys_tick > measured_tick && sys_tick > S_PER_NS) { - ticks = (unsigned long) ((tvp->tv_usec * S_PER_NS) / sys_tick); - tvp->tv_usec = (long)(ticks * US_PER_S * sys_tick); + ticks = (unsigned long) ((tv.tv_usec * S_PER_NS) / sys_tick); + tv.tv_usec = (long)(ticks * US_PER_S * sys_tick); } #endif DPRINT(4, ("fetch_timestamp: system usec network time stamp: %jd.%06ld\n", - (intmax_t)tvp->tv_sec, (long)tvp->tv_usec)); - nts = tspec_stamp_to_lfp(tval_to_tspec(*tvp)); + (intmax_t)tv.tv_sec, (long)tv.tv_usec)); + nts = tspec_stamp_to_lfp(tval_to_tspec(tv)); #else # error "Can't get packet timestamp" #endif --- ntpd/ntp_timer.c.orig 2023-12-28 20:53:56.000000000 -0800 +++ ntpd/ntp_timer.c 2023-12-30 22:12:39.000000000 -0800 @@ -13,7 +13,9 @@ #include #include +#ifdef HAVE_KERNEL_PLL #include "ntp_syscall.h" +#endif /* HAVE_KERNEL_PLL */ #ifdef HAVE_TIMER_CREATE /* TC_ERR represents the timer_create() error return value. */ @@ -373,7 +375,11 @@ check_leapsec( leap_result_t lsdata; uint32_t lsprox; +#ifdef HAVE_KERNEL_PLL leapsec_electric((clock_ctl.pll_control && clock_ctl.kern_enable) ? electric_on : electric_off); +#else + leapsec_electric(electric_off); +#endif #ifdef ENABLE_LEAP_SMEAR leap_smear.enabled = (leap_smear_intv != 0); #endif --- ntpd/refclock_local.c.orig 2022-12-22 22:08:52.000000000 -0800 +++ ntpd/refclock_local.c 2023-12-30 22:12:39.000000000 -0800 @@ -158,6 +158,7 @@ local_poll( * If another process is disciplining the system clock, we set * the leap bits and quality indicators from the kernel. */ +#ifdef HAVE_KERNEL_PLL if (loop_data.lockclock) { struct timex ntv; memset(&ntv, 0, sizeof ntv); @@ -188,6 +189,13 @@ local_poll( pp->disp = DISPERSION; pp->jitter = 0; } + pp->disp = 0; + pp->jitter = 0; +#else /* !HAVE_KERNEL_PLL */ + pp->leap = LEAP_NOWARNING; + pp->disp = DISPERSION; + pp->jitter = 0; +#endif /* !HAVE_KERNEL_PLL */ pp->lastref = pp->lastrec; refclock_receive(peer); } --- ntpfrob/precision.c.orig 2023-12-28 20:53:56.000000000 -0800 +++ ntpfrob/precision.c 2023-12-30 22:12:39.000000000 -0800 @@ -11,6 +11,7 @@ #include "ntp_types.h" #include "ntp_calendar.h" #include "ntpfrob.h" +#include "ntp_machine.h" #define DEFAULT_SYS_PRECISION -99 --- tests/libntp/statestr.c.orig 2022-12-22 22:08:52.000000000 -0800 +++ tests/libntp/statestr.c 2023-12-30 22:12:39.000000000 -0800 @@ -4,7 +4,9 @@ #include "unity.h" #include "unity_fixture.h" +#ifdef HAVE_SYS_TIMEX_H #include +#endif TEST_GROUP(statestr); @@ -29,7 +31,9 @@ TEST(statestr, ResAccessFlags) { // k_st_flags() TEST(statestr, KSTFlags) { +#ifdef STA_PPSFREQ TEST_ASSERT_EQUAL_STRING("ppsfreq", k_st_flags(STA_PPSFREQ)); +#endif } // statustoa --- wafhelpers/bin_test.py.orig 2022-12-22 22:08:52.000000000 -0800 +++ wafhelpers/bin_test.py 2023-12-30 22:12:39.000000000 -0800 @@ -103,6 +103,12 @@ def cmd_bin_test(ctx): if ctx.env['PYTHON_CURSES']: cmd_map_python.update(cmd_map_python_curses) + # Kludge to remove ntptime if it didn't get built + if not ctx.env.HEADER_SYS_TIMEX_H: + for cmd in list(cmd_map.keys()): + if 'ntptime' in cmd[0]: + del cmd_map[cmd] + for cmd in sorted(cmd_map): if not run(cmd, cmd_map[cmd] % version): fails += 1 --- wafhelpers/options.py.orig 2023-12-28 20:53:56.000000000 -0800 +++ wafhelpers/options.py 2023-12-30 22:12:39.000000000 -0800 @@ -23,6 +23,8 @@ def options_cmd(ctx, config): help="Droproot earlier (breaks SHM and NetBSD).") grp.add_option('--enable-seccomp', action='store_true', default=False, help="Enable seccomp (restricts syscalls).") + grp.add_option('--disable-kernel-pll', action='store_true', + default=False, help="Disable kernel PLL.") grp.add_option('--disable-mdns-registration', action='store_true', default=False, help="Disable MDNS registration.") grp.add_option( --- wscript.orig 2023-12-28 20:53:56.000000000 -0800 +++ wscript 2023-12-30 22:12:39.000000000 -0800 @@ -587,7 +587,7 @@ int main(int argc, char **argv) { structures = ( ("struct if_laddrconf", ["sys/types.h", "net/if6.h"], False), ("struct if_laddrreq", ["sys/types.h", "net/if6.h"], False), - ("struct timex", ["sys/time.h", "sys/timex.h"], True), + ("struct timex", ["sys/time.h", "sys/timex.h"], False), ("struct ntptimeval", ["sys/time.h", "sys/timex.h"], False), ) for (s, h, r) in structures: @@ -812,6 +812,21 @@ int main(int argc, char **argv) { ctx.define("ENABLE_FUZZ", 1, comment="Enable fuzzing low bits of time") + # Does the kernel implement a phase-locked loop for timing? + # All modern Unixes (in particular Linux and *BSD) have this. + # + # The README for the (now deleted) kernel directory says this: + # "If the precision-time kernel (KERNEL_PLL define) is + # configured, the installation process requires the header + # file /usr/include/sys/timex.h for the particular + # architecture to be in place." + # + if ((ctx.get_define("HAVE_SYS_TIMEX_H") and + not ctx.options.disable_kernel_pll)): + ctx.define("HAVE_KERNEL_PLL", 1, + comment="Whether phase-locked loop for timing " + "exists and is enabled") + # SO_REUSEADDR socket option is needed to open a socket on an # interface when the port number is already in use on another # interface. Linux needs this, NetBSD does not, status on