[Git][NTPsec/ntpsec][master] 4 commits: Supress warnings on FreeBSD with --disable-droproot
Hal Murray (@hal.murray)
gitlab at mg.gitlab.com
Sun Jan 23 03:26:57 UTC 2022
Hal Murray pushed to branch master at NTPsec / ntpsec
Commits:
69d5c379 by Hal Murray at 2022-01-21T03:32:30-08:00
Supress warnings on FreeBSD with --disable-droproot
- - - - -
75a4072f by Hal Murray at 2022-01-21T03:32:30-08:00
Fix tests/option-tester.sh to work without pkg-config
- - - - -
f21e7aa4 by Hal Murray at 2022-01-22T02:24:51-08:00
Fix for #723, Loop in derive_nonce
- - - - -
003a1148 by Hal Murray at 2022-01-22T02:30:04-08:00
Fix #724, NMEA driver doesn't handle GPS WNRO with 2 digit years
- - - - -
7 changed files:
- ntpd/ntp_control.c
- ntpd/ntp_sandbox.c
- − ntpd/ntp_wrapdate.c
- ntpd/refclock_nmea.c
- ntpd/wscript
- tests/option-tester.sh
- wscript
Changes:
=====================================
ntpd/ntp_control.c
=====================================
@@ -2848,7 +2848,7 @@ static uint32_t derive_nonce(
)
{
static uint8_t salt[16];
- static unsigned long last_salt_update = 0;
+ static unsigned long next_salt_update = 0;
union d_tag {
uint8_t digest[EVP_MAX_MD_SIZE];
uint32_t extract;
@@ -2856,9 +2856,11 @@ static uint32_t derive_nonce(
EVP_MD_CTX *ctx;
unsigned int len;
- while (!last_salt_update || current_time - last_salt_update >= SECSPERHR) {
+ if (current_time >= next_salt_update) {
ntp_RAND_bytes(&salt[0], sizeof(salt));
- last_salt_update = current_time;
+ next_salt_update = current_time+SECSPERHR;
+ if (0) msyslog(LOG_INFO, "derive_nonce: update salt, %lld", \
+ (long long)next_salt_update);
}
ctx = EVP_MD_CTX_create();
=====================================
ntpd/ntp_sandbox.c
=====================================
@@ -35,7 +35,7 @@ static priv_set_t *lowprivs = NULL;
static priv_set_t *highprivs = NULL;
#endif /* HAVE_SOLARIS_PRIVS */
-#ifdef HAVE_PRIV_NTP_ADJTIME
+#if defined(HAVE_PRIV_NTP_ADJTIME) && defined(ENABLE_DROPROOT)
#include <sys/types.h>
#include <sys/sysctl.h>
static void CheckFreeBSDdroproot(uid_t uid);
@@ -492,7 +492,7 @@ int scmp_sc[] = {
return nonroot;
}
-#ifdef HAVE_PRIV_NTP_ADJTIME
+#if defined(HAVE_PRIV_NTP_ADJTIME) && defined(ENABLE_DROPROOT)
void CheckFreeBSDdroproot(uid_t uid) {
/* This checks that mac_ntpd.ko is loaded.
* It defaults to 123 and enabled, aka what we want.
=====================================
ntpd/ntp_wrapdate.c deleted
=====================================
@@ -1,320 +0,0 @@
-/*
- * Calendar-oriented stuff -- perhaps a bit hard to grok.
- *
- * Used for interpreting GPS sentences and resolving wrap issues
- * around 2-digit years. Formerly part of refclock_nmea.c,
- * dissected out so it can be used by other drivers.
- */
-
-#include "config.h"
-#include "ntp_types.h"
-
-#include "ntp.h"
-#include "ntpd.h"
-#include "ntp_io.h"
-#include "ntp_stdlib.h"
-#include "ntp_calendar.h"
-#include "ntp_wrapdate.h"
-#include "timespecops.h"
-
-static int32_t g_gpsMinBase;
-static int32_t g_gpsMinYear;
-
-/*
- * The GPS week time scale starts on Sunday, 1980-01-06. We need the
- * rata die number of this day.
- */
-#ifndef DAY_GPS_STARTS
-#define DAY_GPS_STARTS 722820
-#endif
-
-/*
- * -------------------------------------------------------------------
- * nmea_init - initialise data
- *
- * calculates a few runtime constants that cannot be made compile time
- * constants.
- * -------------------------------------------------------------------
- */
-void
-wrapdate_init(void)
-{
- struct calendar date;
-
- /* - calculate min. base value for GPS epoch & century unfolding
- * This assumes that the build system was roughly in sync with
- * the world, and that really synchronising to a time before the
- * program was created would be unsafe or insane. If the build
- * date cannot be established, at least use the start of GPS
- * (1980-01-06) as minimum, because GPS can surely NOT
- * synchronise beyond it's own big bang. We add a little safety
- * margin for the fuzziness of the build date, which is in an
- * undefined time zone. */
- if (ntpcal_get_build_date(&date))
- g_gpsMinBase = ntpcal_date_to_rd(&date) - 2;
- else
- g_gpsMinBase = 0;
-
- if (g_gpsMinBase < DAY_GPS_STARTS)
- g_gpsMinBase = DAY_GPS_STARTS;
-
- ntpcal_rd_to_date(&date, g_gpsMinBase);
- g_gpsMinYear = date.year;
- g_gpsMinBase -= DAY_NTP_STARTS;
-}
-
-/*
- * -------------------------------------------------------------------
- *
- * Unfold a time-of-day (seconds since midnight) around the current
- * system time in a manner that guarantees an absolute difference of
- * less than 12hrs.
- *
- * This function is used for NMEA sentences that contain no date
- * information. This requires the system clock to be in +/-12hrs
- * around the true time, or the clock will synchronize the system 1day
- * off if not augmented with a time sources that also provide the
- * necessary date information.
- *
- * The function updates the calendar structure it also uses as
- * input to fetch the time from.
- *
- * returns true on success, false on failure
- * -------------------------------------------------------------------
- */
-bool
-unfold_day(
- struct calendar * jd,
- uint32_t rec_ui
- )
-{
- time64_t rec_qw;
- ntpcal_split rec_ds;
-
- /*
- * basically this is the periodic extension of the receive
- * time - 12hrs to the time-of-day with a period of 1 day.
- * But we would have to execute this in 64bit arithmetic, and we
- * cannot assume we can do this; therefore this is done
- * in split representation.
- */
- rec_qw = ntpcal_ntp_to_ntp(rec_ui - SECSPERDAY/2, time(NULL));
- rec_ds = ntpcal_daysplit(rec_qw);
- rec_ds.lo = ntpcal_periodic_extend(rec_ds.lo,
- ntpcal_date_to_daysec(jd),
- SECSPERDAY);
- rec_ds.hi += ntpcal_daysec_to_date(jd, rec_ds.lo);
- /* -1 return means calculation overflowed */
- return (ntpcal_rd_to_date(jd, rec_ds.hi + DAY_NTP_STARTS) >= 0);
-}
-
-/*
- * -------------------------------------------------------------------
- * A 2-digit year is expanded into full year spec around the year found
- * in 'jd->year'. This should be in +79/-19 years around the system time,
- * or the result will be off by 100 years. The asymmetric behaviour was
- * chosen to enable initial sync for systems that do not have a
- * battery-backup clock and start with a date that is typically years in
- * the past.
- *
- * Since the GPS epoch starts at 1980-01-06, the resulting year will be
- * not be before 1980 in any case.
- *
- * returns true on success, false on failure
- * -------------------------------------------------------------------
- */
-bool
-unfold_century(
- struct calendar * jd,
- uint32_t rec_ui
- )
-{
- struct calendar rec;
- int32_t baseyear;
-
- ntpcal_ntp_to_date(&rec, rec_ui, time(NULL));
- baseyear = rec.year - 20;
- if (baseyear < g_gpsMinYear)
- baseyear = g_gpsMinYear;
- jd->year = (unsigned short)ntpcal_periodic_extend(baseyear, jd->year,
- 100);
-
- return ((baseyear <= jd->year) && (baseyear + 100 > jd->year));
-}
-
-/*
- * -------------------------------------------------------------------
- * A 2-digit year is expanded into a full year spec by correlation with
- * a GPS week number and the current leap second count.
- *
- * The GPS week time scale counts weeks since Sunday, 1980-01-06, modulo
- * 1024 and seconds since start of the week. The GPS time scale is based
- * on international atomic time (TAI), so the leap second difference to
- * UTC is also needed for a proper conversion.
- *
- * A brute-force analysis (that is, test for every date) shows that a
- * wrong assignment of the century can not happen between the years 1900
- * to 2399 when comparing the week signatures for different
- * centuries. (I *think* that will not happen for 400*1024 years, but I
- * have no valid proof. -*-perlinger at ntp.org-*-)
- *
- * This function is bound to work between years 1980 and 2399
- * (inclusive), which should suffice for now ;-)
- *
- * Note: This function needs a full date&time spec on input due to the
- * necessary leap second corrections!
- *
- * returns true on success, false on failure
- * -------------------------------------------------------------------
- */
-bool
-gpsfix_century(
- struct calendar * jd,
- const gps_weektm * wd,
- unsigned short * century
- )
-{
- int32_t days;
- int32_t doff;
- unsigned short week;
- unsigned short year;
- int loop;
-
- /* Get day offset. Assumes that the input time is in range and
- * that the leap seconds do not shift more than +/-1 day.
- */
- doff = ntpcal_date_to_daysec(jd) + wd->wt_leap;
- doff = (doff >= SECSPERDAY) - (doff < 0);
-
- /*
- * Loop over centuries to get a match, starting with the last
- * successful one. (Or with the 19th century if the cached value
- * is out of range...)
- */
- year = jd->year % 100;
- for (loop = 5; loop > 0; loop--,(*century)++) {
- if (*century < 19 || *century >= 24) {
- *century = 19;
- }
- /* Get days and week in GPS epoch */
- jd->year = year + *century * 100;
- days = ntpcal_date_to_rd(jd) - DAY_GPS_STARTS + doff;
- week = (days / 7) % 1024;
- if (days >= 0 && wd->wt_week == week)
- return true; /* matched... */
- }
-
- jd->year = year;
- return false; /* match failed... */
-}
-
-/*
- * -------------------------------------------------------------------
- * And now the final exercise: Considering the fact that many (most?)
- * GPS receivers cannot handle a GPS epoch wrap well, we try to
- * compensate for that problem by unwrapping a GPS epoch around the
- * receive stamp. Another exercise in periodic unfolding, of course,
- * but with enough points to take care of.
- *
- * Note: The integral part of 'tofs' is intended to handle small(!)
- * systematic offsets, as -1 for handling $GPZDG, which gives the
- * following second. (sigh...) The absolute value shall be less than a
- * day (86400 seconds).
- * -------------------------------------------------------------------
- */
-l_fp
-eval_gps_time(
- const char * clockname, /* for logging */
- const struct calendar * gpst, /* GPS time stamp */
- const struct timespec * tofs, /* GPS frac second & offset */
- const bool trusted, /* do we fully trust dates from this GPS? */
- short *epoch_warp, /* for logging */
- const l_fp * xrecv /* receive time stamp */
- )
-{
-
- l_fp retv;
-
- /* components of calculation */
- int32_t rcv_sec, rcv_day; /* receive ToD and day */
- int32_t gps_sec, gps_day; /* GPS ToD and day in NTP epoch */
- int32_t adj_day, weeks; /* adjusted GPS day and week shift */
-
- /* some temporaries to shuffle data */
- time64_t vi64;
- ntpcal_split rs64;
-
- /* evaluate time stamp from receiver. */
- gps_sec = ntpcal_date_to_daysec(gpst);
- gps_day = ntpcal_date_to_rd(gpst) - DAY_NTP_STARTS;
-
- /* merge in fractional offset */
- retv = tspec_intv_to_lfp(*tofs);
- gps_sec += lfpsint(retv);
-
- /* If we fully trust the GPS receiver, just combine days and
- * seconds and be done. */
- if (trusted) {
- setlfpuint(retv, time64lo(ntpcal_dayjoin(gps_day, gps_sec)));
- return retv;
- }
-
- /* So we do not trust the GPS receiver to deliver a correct date
- * due to the GPS epoch changes. We map the date from the
- * receiver into the +/-512 week interval around the receive
- * time in that case. This would be a tad easier with 64bit
- * calculations, but again, we restrict the code to 32bit ops
- * when possible. */
-
- /* - make sure the GPS fractional day is normalised
- * Applying the offset value might have put us slightly over the
- * edge of the allowed range for seconds-of-day. Doing a full
- * division with floor correction is overkill here; a simple
- * addition or subtraction step is sufficient. Using WHILE loops
- * gives the right result even if the offset exceeds one day,
- * which is NOT what it's intended for! */
- while (gps_sec >= SECSPERDAY) {
- gps_sec -= SECSPERDAY;
- gps_day += 1;
- }
- while (gps_sec < 0) {
- gps_sec += SECSPERDAY;
- gps_day -= 1;
- }
-
- /* - get unfold base: day of full recv time - 512 weeks */
- vi64 = ntpcal_ntp_to_ntp(lfpuint(*xrecv), time(NULL));
- rs64 = ntpcal_daysplit(vi64);
- rcv_sec = rs64.lo;
- rcv_day = rs64.hi - 512 * 7;
-
- /* - take the fractional days into account
- * If the fractional day of the GPS time is smaller than the
- * fractional day of the receive time, we shift the base day for
- * the unfold by 1. */
- if ( gps_sec < rcv_sec
- || (gps_sec == rcv_sec && lfpfrac(retv) < lfpfrac(*xrecv)))
- rcv_day += 1;
-
- /* - don't warp ahead of GPS invention! */
- if (rcv_day < g_gpsMinBase)
- rcv_day = g_gpsMinBase;
-
- /* - let the magic happen: */
- adj_day = ntpcal_periodic_extend(rcv_day, gps_day, 1024*7);
-
- /* - check if we should log a GPS epoch warp */
- weeks = (adj_day - gps_day) / 7;
- if (weeks != *epoch_warp) {
- *epoch_warp = (short)weeks;
- LOGIF(CLOCKINFO, (LOG_INFO,
- "%s Changed GPS epoch warp to %d weeks",
- clockname, weeks));
- }
-
- /* - build result and be done */
- setlfpuint(retv, time64lo(ntpcal_dayjoin(adj_day, gps_sec)));
- return retv;
-}
-
-// end
=====================================
ntpd/refclock_nmea.c
=====================================
@@ -30,8 +30,6 @@
#include "ntp_io.h"
#include "ntp_refclock.h"
#include "ntp_stdlib.h"
-#include "ntp_calendar.h"
-#include "ntp_wrapdate.h"
#include "timespecops.h"
#ifdef HAVE_PPSAPI
@@ -220,9 +218,8 @@ typedef struct {
bool ppsapi_gate; /* system is on PPS */
#endif /* HAVE_PPSAPI */
bool gps_time; /* use GPS time, not UTC */
- unsigned short century_cache; /* cached current century */
l_fp last_reftime; /* last processed reference stamp */
- short epoch_warp; /* last epoch warp, for logging */
+ int wnro; /* last epoch warp, for logging */
/* tally stats, reset each poll cycle */
struct
{
@@ -248,18 +245,10 @@ typedef struct {
int cidx; /* current field index */
} nmea_data;
-/*
- * The GPS week time scale starts on Sunday, 1980-01-06. We need the
- * rata die number of this day.
- */
-#ifndef DAY_GPS_STARTS
-#define DAY_GPS_STARTS 722820
-#endif
/*
* Function prototypes
*/
-static void nmea_init (void);
static bool nmea_start (int, struct peer *);
static void nmea_shutdown (struct refclockproc *);
static void nmea_receive (struct recvbuf *);
@@ -279,12 +268,12 @@ static char * field_parse (nmea_data * data, int fn);
static void field_wipe (nmea_data * data, ...);
static uint8_t parse_qual (nmea_data * data, int idx,
char tag, int inv);
-static bool parse_time (struct calendar * jd, long * nsec,
- nmea_data *, int idx);
-static bool parse_date (struct calendar *jd, nmea_data*,
- int idx, enum date_fmt fmt);
-static bool parse_weekdata (gps_weektm *, nmea_data *,
- int weekidx, int timeidx, int leapidx);
+static bool parse_time (struct timespec *dt, nmea_data *, int idx);
+static bool parse_date (struct timespec *dt, nmea_data*,
+ int idx, enum date_fmt fmt);
+static bool kludge_day (struct timespec *dt);
+static bool fix_WNRO (struct timespec *dt, int *wnro, \
+ const struct peer *peer);
static void save_ltc (struct refclockproc * const, const char * const,
size_t);
@@ -308,24 +297,10 @@ struct refclock refclock_nmea = {
nmea_shutdown, /* shut down driver */
nmea_poll, /* transmit poll message */
NMEA_CONTROL, /* fudge control */
- nmea_init, /* initialize driver */
+ NULL, /* initialize driver */
nmea_timer /* called once per second */
};
-/*
- * -------------------------------------------------------------------
- * nmea_init - initialise data
- *
- * calculates a few runtime constants that cannot be made compile time
- * constants.
- * -------------------------------------------------------------------
- */
-static void
-nmea_init(void)
-{
- wrapdate_init();
-}
-
/*
* -------------------------------------------------------------------
* nmea_start - open the GPS devices and initialize data for processing
@@ -849,9 +824,7 @@ nmea_receive(
double rd_fudge;
/* working stuff */
- struct calendar date; /* to keep & convert the time stamp */
- struct timespec tofs; /* offset to full-second reftime */
- gps_weektm gpsw; /* week time storage */
+ struct timespec date; /* to keep & convert the time stamp */
/* results of sentence/date/time parsing */
uint8_t sentence; /* sentence tag */
int checkres;
@@ -860,9 +833,7 @@ nmea_receive(
bool rc_time;
/* make sure data has defined pristine state */
- ZERO(tofs);
ZERO(date);
- ZERO(gpsw);
sentence = 0;
rc_date = false;
rc_time = false;
@@ -983,28 +954,27 @@ nmea_receive(
case NMEA_GPRMC:
/* Check quality byte, fetch data & time */
- rc_time = parse_time(&date, &tofs.tv_nsec, &rdata, 1);
+ rc_time = parse_time(&date, &rdata, 1);
pp->leap = parse_qual(&rdata, 2, 'A', 0);
- rc_date = parse_date(&date, &rdata, 9, DATE_1_DDMMYY)
- && unfold_century(&date, lfpuint(rd_timestamp));
+ rc_date = parse_date(&date, &rdata, 9, DATE_1_DDMMYY);
if (CLK_FLAG4 & pp->sloppyclockflag)
field_wipe(&rdata, 3, 4, 5, 6, -1);
break;
case NMEA_GPGGA:
/* Check quality byte, fetch time only */
- rc_time = parse_time(&date, &tofs.tv_nsec, &rdata, 1);
+ rc_time = parse_time(&date, &rdata, 1);
pp->leap = parse_qual(&rdata, 6, '0', 1);
- rc_date = unfold_day(&date, lfpuint(rd_timestamp));
+ rc_date = kludge_day(&date);
if (CLK_FLAG4 & pp->sloppyclockflag)
field_wipe(&rdata, 2, 4, -1);
break;
case NMEA_GPGLL:
/* Check quality byte, fetch time only */
- rc_time = parse_time(&date, &tofs.tv_nsec, &rdata, 5);
+ rc_time = parse_time(&date, &rdata, 5);
pp->leap = parse_qual(&rdata, 6, 'A', 0);
- rc_date = unfold_day(&date, lfpuint(rd_timestamp));
+ rc_date = kludge_day(&date);
if (CLK_FLAG4 & pp->sloppyclockflag)
field_wipe(&rdata, 1, 3, -1);
break;
@@ -1012,29 +982,25 @@ nmea_receive(
case NMEA_GPZDA:
/* No quality. Assume best, fetch time & full date */
pp->leap = LEAP_NOWARNING;
- rc_time = parse_time(&date, &tofs.tv_nsec, &rdata, 1);
+ rc_time = parse_time(&date, &rdata, 1);
rc_date = parse_date(&date, &rdata, 2, DATE_3_DDMMYYYY);
break;
case NMEA_GPZDG:
/* Check quality byte, fetch time & full date */
- rc_time = parse_time(&date, &tofs.tv_nsec, &rdata, 1);
+ rc_time = parse_time(&date, &rdata, 1);
rc_date = parse_date(&date, &rdata, 2, DATE_3_DDMMYYYY);
pp->leap = parse_qual(&rdata, 4, '0', 1);
- tofs.tv_sec = -1; /* GPZDG is following second */
+/* May be wrong sign: HGM, 2022-Jan-17 */
+ date.tv_sec = -1; /* GPZDG is following second */
break;
case NMEA_PGRMF:
- /* get date, time, qualifier and GPS weektime. We need
- * date and time-of-day for the century fix, so we read
- * them first.
+ /* Ignore week stuff. Use date and time fields.
*/
- rc_date = parse_weekdata(&gpsw, &rdata, 1, 2, 5)
- && parse_date(&date, &rdata, 3, DATE_1_DDMMYY);
- rc_time = parse_time(&date, &tofs.tv_nsec, &rdata, 4);
+ rc_time = parse_time(&date, &rdata, 4);
+ rc_date = parse_date(&date, &rdata, 3, DATE_1_DDMMYY);
pp->leap = parse_qual(&rdata, 11, '0', 1);
- rc_date = rc_date
- && gpsfix_century(&date, &gpsw, &up->century_cache);
if (CLK_FLAG4 & pp->sloppyclockflag)
field_wipe(&rdata, 6, 8, -1);
break;
@@ -1068,10 +1034,9 @@ nmea_receive(
return;
}
- DPRINT(1, ("%s effective timecode: %04u-%02u-%02u %02d:%02d:%02d\n",
- refclock_name(peer),
- date.year, date.month, date.monthday,
- date.hour, date.minute, date.second));
+ /* FIXME: should use ctime_r */
+ DPRINT(1, ("%s effective timecode: %s",
+ refclock_name(peer), ctime(&date.tv_sec)));
/* Check if we must enter GPS time mode; log so if we do */
if (!up->gps_time && (sentence == NMEA_GPZDG)) {
@@ -1081,14 +1046,16 @@ nmea_receive(
up->gps_time = true;
}
+ /* Check/fix WNRO */
+ fix_WNRO(&date, &up->wnro, peer);
+ rd_reftime = tspec_stamp_to_lfp(date);
+
/*
* Get the reference time stamp from the calendar buffer.
* Process the new sample in the median filter and determine the
* timecode timestamp, but only if the PPS is not in control.
* Discard sentence if reference time did not change.
*/
- rd_reftime = eval_gps_time(refclock_name(peer), &date, &tofs,
- (peer->cfg.mode & NMEA_DATETRUST_MASK), &up->epoch_warp, &rd_timestamp);
if (up->last_reftime == rd_reftime) {
/* Do not touch pp->a_lastcode on purpose! */
up->tally.filtered++;
@@ -1552,13 +1519,14 @@ parse_qual(
* -------------------------------------------------------------------
* Parse a time stamp in HHMMSS[.sss] format with error checking.
*
+ * Add result to arg
+ *
* returns true on success, false on failure
* -------------------------------------------------------------------
*/
static bool
parse_time(
- struct calendar * jd, /* result calendar pointer */
- long * ns, /* storage for nsec fraction */
+ struct timespec * dt, /* result date+time */
nmea_data * rd,
int idx
)
@@ -1590,14 +1558,10 @@ parse_time(
return false;
}
- jd->hour = (uint8_t)h;
- jd->minute = (uint8_t)m;
- jd->second = (uint8_t)s;
+ dt->tv_sec += h*3600 + m*60 + s;
/* if we have a fraction, scale it up to nanoseconds. */
if (rc == 4) {
- *ns = (long)(f * weight[p2 - p1 - 1]);
- } else {
- *ns = 0;
+ dt->tv_nsec += (f * weight[p2 - p1 - 1]);
}
return true;
@@ -1610,12 +1574,14 @@ parse_time(
* spec spanning three fields. This function does some extensive error
* checking to make sure the date string was consistent.
*
+ * Add result to arg
+ *
* returns true on success, false on failure
* -------------------------------------------------------------------
*/
static bool
parse_date(
- struct calendar * jd, /* result pointer */
+ struct timespec * dt, /* result pointer */
nmea_data * rd,
int idx,
enum date_fmt fmt
@@ -1627,6 +1593,7 @@ parse_date(
unsigned int d;
int p;
char * dp;
+ struct tm tm;
dp = field_parse(rd, idx);
switch (fmt) {
@@ -1638,6 +1605,19 @@ parse_date(
dp));
return false;
}
+ if (y > 80) {
+ /* We know the time is now > 2000 but
+ * GPS might be off by n*1024 weeks.
+ * WNRO: Week Number Roll Over, ~20 years
+ * Don't break that correction.
+ *
+ * GPS time started in 1980
+ * anything < 80 is from the next century.
+ */
+ y += 1900;
+ } else {
+ y += 2000;
+ }
break;
case DATE_3_DDMMYYYY:
@@ -1661,46 +1641,77 @@ parse_date(
return false;
}
- /* store results */
- jd->monthday = (uint8_t)d;
- jd->month = (uint8_t)m;
- jd->year = (unsigned short)y;
+ /* timegm is non-Posix. */
+ ZERO(tm);
+ tm.tm_year = y-1900;
+ tm.tm_mon = m-1;
+ tm.tm_mday = d;
+ dt->tv_sec += timegm(&tm); /* No error checking */
return true;
}
-/*
- * -------------------------------------------------------------------
- * Parse GPS week time info from an NMEA sentence. This info contains
- * the GPS week number, the GPS time-of-week and the leap seconds GPS
- * to UTC.
+/* Use system time for missing date field.
+ * Time from GPS is in dt. We add a day offset.
+ * This assumes the system time is within 12 hours.
+ * Note the 2 interesting cases:
+ * If GPS time is late in the day and we are early in the day
+ * we are actually early in the following day.
+ * If GPS time is early in the day and we are late in the day
+ * we are actually late in the previous day.
+ *
+ * This code hasn't been tested yet.
*
- * returns true on success, false on failure
- * -------------------------------------------------------------------
*/
-static bool
-parse_weekdata(
- gps_weektm * wd,
- nmea_data * rd,
- int weekidx,
- int timeidx,
- int leapidx
- )
-{
- unsigned long secs;
- int fcnt;
-
- /* parse fields and count success */
- fcnt = sscanf(field_parse(rd, weekidx), "%hu", &wd->wt_week);
- fcnt += sscanf(field_parse(rd, timeidx), "%lu", &secs);
- fcnt += sscanf(field_parse(rd, leapidx), "%hd", &wd->wt_leap);
- if (fcnt != 3 || wd->wt_week >= 1024 || secs >= 7*SECSPERDAY) {
- DPRINT(1, ("nmea: parse_weekdata: invalid weektime spec\n"));
- return false;
- }
- wd->wt_time = (uint32_t)secs;
-
- return true;
+static bool kludge_day (struct timespec *dt) {
+ struct timespec now;
+
+/* FIXME: check if clock is valid. */
+
+ clock_gettime(CLOCK_REALTIME, &now);
+ int nowday = now.tv_sec / 86400;
+ int nowsec = now.tv_sec % 86400;
+ int gpssec = (int)dt->tv_sec;
+ if ((gpssec-nowsec) > 12*3600) nowday -= 1;
+ if ((nowsec-gpssec) > 12*3600) nowday += 1;
+ dt->tv_sec += nowday*86400;
+ return true;
}
+/* FIXME move this to a better place */
+/* Get this from date +%s */
+#define GPS_PIVOT 1642417438
+
+/* Early GPS has a 10 bit week number field.
+ * That's a bit less than 20 years.
+ * GPS started in 1980. We have now wrapped twice: Aug 1999 and Apr 2019.
+ * https://en.wikipedia.org/wiki/GPS_week_number_rollover
+ *
+ * Some firmware fixes the date to be at least the firmware build date.
+ * That gives valid time for 20 years from the build date.
+ * It also means that old GPS units can break at any time,
+ * not just on 1024 week boundaries.
+ *
+ * This code wraps based on our build date.
+ * But using a build date would break repeatable builds.
+ * So we use a pivot date that gets updated at release time.
+ * So our code should work for 1024 weeks from the release date.
+ *
+ * Modern GPS satellites have added 3 more bits.
+ * Old firmware doesn't know about them.
+ */
+
+static bool fix_WNRO (struct timespec *dt, int *wnro, const struct peer *peer) {
+ int i;
+ for (i=0; dt->tv_sec < GPS_PIVOT; i++) {
+ dt->tv_sec += 1024*7*86400;
+ }
+ if (*wnro != i) {
+ *wnro = i;
+ msyslog(LOG_INFO, "REFCLOCK: %s date advanced by %d weeks, WNRO", \
+ refclock_name(peer), *wnro*1024);
+ }
+ return true;
+};
+
// end
=====================================
ntpd/wscript
=====================================
@@ -81,7 +81,6 @@ def build(ctx):
if ctx.env.REFCLOCK_ENABLE:
refclock_source = ["ntp_refclock.c",
- "ntp_wrapdate.c",
"refclock_conf.c"
]
=====================================
tests/option-tester.sh
=====================================
@@ -16,8 +16,13 @@ then
fi
PURGE=""
-SECCOMP="$(pkg-config libseccomp --variable=includedir)"
-SECCOMP="$SECCOMP/seccomp.h"
+if which pkg-config
+then
+ SECCOMP="$(pkg-config libseccomp --variable=includedir)"
+ SECCOMP="$SECCOMP/seccomp.h"
+else
+ SECCOMP=""
+fi
LINUX=""
if [ `uname -s` = "Linux" -a -n "$SECCOMP" -a -f "$SECCOMPH" ]
then
@@ -38,7 +43,7 @@ then
DISABLE_NTS="--disable-nts"
fi
else
- if ! $PYTHON ../wafhelpers/tlscheck.py
+ if ! $PYTHON ./wafhelpers/tlscheck.py
then
DISABLE_NTS="--disable-nts"
fi
=====================================
wscript
=====================================
@@ -641,6 +641,7 @@ int main(int argc, char **argv) {
('res_init', ["netinet/in.h", "arpa/nameser.h", "resolv.h"]),
('strlcpy', ["string.h"]),
('strlcat', ["string.h"]),
+ ('timegm', ["time.h"]),
# Hack. It's not a function, but this works.
('PRIV_NTP_ADJTIME', ["sys/priv.h"]) # FreeBSD
)
@@ -755,6 +756,12 @@ int main(int argc, char **argv) {
if ctx.options.refclocks:
from wafhelpers.refclock import refclock_config
refclock_config(ctx)
+ # timegm needed by refclock_nmea, it's not in POSIX
+ # It's in Linux, FreeBSD, and NetBSD
+ if not ctx.get_define("HAVE_TIMEGM") and ctx.get_define("CLOCK_NMEA"):
+ ctx.fatal("Refclock NMEA needs timegm")
+ # We should provide an implementation.
+ # Like we do for BSD string functions.
# NetBSD (used to) need to recreate sockets on changed routing.
# Perhaps it still does. If so, this should be set. The autoconf
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/ab11c6446b724f3dd71138c688ccc7e14bb21662...003a1148ede6a4ac5deaf2507ecfd3b40b07731a
--
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/ab11c6446b724f3dd71138c688ccc7e14bb21662...003a1148ede6a4ac5deaf2507ecfd3b40b07731a
You're receiving this email because of your account on gitlab.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20220123/57925145/attachment-0001.htm>
More information about the vc
mailing list