Coverage Report

Created: 2023-05-19 06:16

/src/ntp-dev/libntp/statestr.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * pretty printing of status information
3
 */
4
#ifdef HAVE_CONFIG_H
5
#include <config.h>
6
#endif
7
#include <stdio.h>
8
#include "ntp_stdlib.h"
9
#include "ntp_fp.h"
10
#include "ntp.h"
11
#include "lib_strbuf.h"
12
#include "ntp_refclock.h"
13
#include "ntp_control.h"
14
#include "ntp_string.h"
15
#ifdef KERNEL_PLL
16
# include "ntp_syscall.h"
17
#endif
18
19
20
/*
21
 * Structure for turning various constants into a readable string.
22
 */
23
struct codestring {
24
  int code;
25
  const char * const string1;
26
  const char * const string0;
27
};
28
29
/*
30
 * Leap status (leap)
31
 */
32
static const struct codestring leap_codes[] = {
33
  { LEAP_NOWARNING, "leap_none",  0 },
34
  { LEAP_ADDSECOND, "leap_add_sec", 0 },
35
  { LEAP_DELSECOND, "leap_del_sec", 0 },
36
  { LEAP_NOTINSYNC, "leap_alarm", 0 },
37
  { -1,     "leap",   0 }
38
};
39
40
/*
41
 * Clock source status (sync)
42
 */
43
static const struct codestring sync_codes[] = {
44
  { CTL_SST_TS_UNSPEC,  "sync_unspec",    0 },
45
  { CTL_SST_TS_ATOM,  "sync_pps",   0 },
46
  { CTL_SST_TS_LF,  "sync_lf_radio",  0 },
47
  { CTL_SST_TS_HF,  "sync_hf_radio",  0 },
48
  { CTL_SST_TS_UHF, "sync_uhf_radio", 0 },
49
  { CTL_SST_TS_LOCAL, "sync_local",   0 },
50
  { CTL_SST_TS_NTP, "sync_ntp",   0 },
51
  { CTL_SST_TS_UDPTIME, "sync_other",   0 },
52
  { CTL_SST_TS_WRSTWTCH,  "sync_wristwatch",  0 },
53
  { CTL_SST_TS_TELEPHONE, "sync_telephone", 0 },
54
  { -1,     "sync",     0 }
55
};
56
57
/*
58
 * Peer selection status (sel)
59
 */
60
static const struct codestring select_codes[] = {
61
  { CTL_PST_SEL_REJECT, "sel_reject",   0 },
62
  { CTL_PST_SEL_SANE, "sel_falsetick",  0 },
63
  { CTL_PST_SEL_CORRECT,  "sel_excess",   0 },
64
  { CTL_PST_SEL_SELCAND,  "sel_outlier",    0 },
65
  { CTL_PST_SEL_SYNCCAND, "sel_candidate",  0 },
66
  { CTL_PST_SEL_EXCESS, "sel_backup",   0 },
67
  { CTL_PST_SEL_SYSPEER,  "sel_sys.peer",   0 },
68
  { CTL_PST_SEL_PPS,  "sel_pps.peer",   0 },
69
  { -1,     "sel",      0 }
70
};
71
72
/*
73
 * Clock status (clk)
74
 */
75
static const struct codestring clock_codes[] = {
76
  { CTL_CLK_OKAY,   "clk_unspec",   0 },
77
  { CTL_CLK_NOREPLY,  "clk_no_reply",   0 },
78
  { CTL_CLK_BADFORMAT,  "clk_bad_format", 0 },
79
  { CTL_CLK_FAULT,  "clk_fault",    0 },
80
  { CTL_CLK_PROPAGATION,  "clk_bad_signal", 0 },
81
  { CTL_CLK_BADDATE,  "clk_bad_date",   0 },
82
  { CTL_CLK_BADTIME,  "clk_bad_time",   0 },
83
  { -1,     "clk",      0 }
84
};
85
86
87
#ifdef FLASH_CODES_UNUSED
88
/*
89
 * Flash bits -- see ntpq.c tstflags & tstflagnames
90
 */
91
static const struct codestring flash_codes[] = {
92
  { TEST1,    "pkt_dup",  0 },
93
  { TEST2,    "pkt_bogus",  0 },
94
  { TEST3,    "pkt_unsync", 0 },
95
  { TEST4,    "pkt_denied", 0 },
96
  { TEST5,    "pkt_auth", 0 },
97
  { TEST6,    "pkt_stratum",  0 },
98
  { TEST7,    "pkt_header", 0 },
99
  { TEST8,    "pkt_autokey",  0 },
100
  { TEST9,    "pkt_crypto", 0 },
101
  { TEST10,   "peer_stratum", 0 },
102
  { TEST11,   "peer_dist",  0 },
103
  { TEST12,   "peer_loop",  0 },
104
  { TEST13,   "peer_unreach", 0 },
105
  { -1,     "flash",  0 }
106
};
107
#endif
108
109
110
/*
111
 * System events (sys)
112
 */
113
static const struct codestring sys_codes[] = {
114
  { EVNT_UNSPEC,    "unspecified",      0 },
115
  { EVNT_NSET,    "freq_not_set",     0 },
116
  { EVNT_FSET,    "freq_set",     0 },
117
  { EVNT_SPIK,    "spike_detect",     0 },
118
  { EVNT_FREQ,    "freq_mode",      0 },
119
  { EVNT_SYNC,    "clock_sync",     0 },
120
  { EVNT_SYSRESTART,  "restart",      0 },
121
  { EVNT_SYSFAULT,  "panic_stop",     0 },
122
  { EVNT_NOPEER,    "no_sys_peer",      0 },
123
  { EVNT_ARMED,   "leap_armed",     0 },
124
  { EVNT_DISARMED,  "leap_disarmed",    0 },
125
  { EVNT_LEAP,    "leap_event",     0 },
126
  { EVNT_CLOCKRESET,  "clock_step",     0 },
127
  { EVNT_KERN,    "kern",       0 },
128
  { EVNT_TAI,   "TAI",        0 },
129
  { EVNT_LEAPVAL,   "stale_leapsecond_values",  0 },
130
  { -1,     "",       0 }
131
};
132
133
/*
134
 * Peer events (peer)
135
 */
136
static const struct codestring peer_codes[] = {
137
  { PEVNT_MOBIL & ~PEER_EVENT,  "mobilize",   0 },
138
  { PEVNT_DEMOBIL & ~PEER_EVENT,  "demobilize",   0 },
139
  { PEVNT_UNREACH & ~PEER_EVENT,  "unreachable",    0 },
140
  { PEVNT_REACH & ~PEER_EVENT,  "reachable",    0 },
141
  { PEVNT_RESTART & ~PEER_EVENT,  "restart",    0 },
142
  { PEVNT_REPLY & ~PEER_EVENT,  "no_reply",   0 },
143
  { PEVNT_RATE & ~PEER_EVENT, "rate_exceeded",  0 },
144
  { PEVNT_DENY & ~PEER_EVENT, "access_denied",  0 },
145
  { PEVNT_ARMED & ~PEER_EVENT,  "leap_armed",   0 },
146
  { PEVNT_NEWPEER & ~PEER_EVENT,  "sys_peer",   0 },
147
  { PEVNT_CLOCK & ~PEER_EVENT,  "clock_event",    0 },
148
  { PEVNT_AUTH & ~PEER_EVENT, "bad_auth",   0 },
149
  { PEVNT_POPCORN & ~PEER_EVENT,  "popcorn",    0 },
150
  { PEVNT_XLEAVE & ~PEER_EVENT, "interleave_mode",  0 },
151
  { PEVNT_XERR & ~PEER_EVENT, "interleave_error", 0 },
152
  { -1,       "",     0 }
153
};
154
155
/*
156
 * Peer status bits
157
 */
158
static const struct codestring peer_st_bits[] = {
159
  { CTL_PST_CONFIG,   "conf",   0 },
160
  { CTL_PST_AUTHENABLE,   "authenb",  0 },
161
  { CTL_PST_AUTHENTIC,    "auth",   0 },
162
  { CTL_PST_REACH,    "reach",  0 },
163
  { CTL_PST_BCAST,    "bcast",  0 },
164
  /* not used with getcode(), no terminating entry needed */
165
};
166
167
/*
168
 * Restriction match bits
169
 */
170
static const struct codestring res_match_bits[] = {
171
  { RESM_NTPONLY,     "ntpport",  0 },
172
  { RESM_INTERFACE,   "interface",  0 },
173
  { RESM_SOURCE,      "source", 0 },
174
  /* not used with getcode(), no terminating entry needed */
175
};
176
177
/*
178
 * Restriction access bits
179
 */
180
static const struct codestring res_access_bits[] = {
181
  { RES_IGNORE,     "ignore", 0 },
182
  { RES_DONTSERVE,    "noserve",  "serve" },
183
  { RES_DONTTRUST,    "notrust",  "trust" },
184
  { RES_NOQUERY,      "noquery",  "query" },
185
  { RES_NOMODIFY,     "nomodify", 0 },
186
  { RES_NOPEER,     "nopeer", "peer" },
187
  { RES_NOEPEER,      "noepeer",  "epeer" },
188
  { RES_NOTRAP,     "notrap", "trap" },
189
  { RES_LPTRAP,     "lptrap", 0 },
190
  { RES_LIMITED,      "limited",  0 },
191
  { RES_VERSION,      "version",  0 },
192
  { RES_KOD,      "kod",    0 },
193
  { RES_FLAKE,      "flake",  0 },
194
  /* not used with getcode(), no terminating entry needed */
195
};
196
197
#ifdef AUTOKEY
198
/*
199
 * Crypto events (cryp)
200
 */
201
static const struct codestring crypto_codes[] = {
202
  { XEVNT_OK & ~CRPT_EVENT, "success",      0 },
203
  { XEVNT_LEN & ~CRPT_EVENT,  "bad_field_format_or_length", 0 },
204
  { XEVNT_TSP & ~CRPT_EVENT,  "bad_timestamp",    0 },
205
  { XEVNT_FSP & ~CRPT_EVENT,  "bad_filestamp",    0 },
206
  { XEVNT_PUB & ~CRPT_EVENT,  "bad_or_missing_public_key",  0 },
207
  { XEVNT_MD & ~CRPT_EVENT, "unsupported_digest_type",  0 },
208
  { XEVNT_KEY & ~CRPT_EVENT,  "unsupported_identity_type",  0 },
209
  { XEVNT_SGL & ~CRPT_EVENT,  "bad_signature_length",   0 },
210
  { XEVNT_SIG & ~CRPT_EVENT,  "signature_not_verified", 0 },
211
  { XEVNT_VFY & ~CRPT_EVENT,  "certificate_not_verified", 0 },
212
  { XEVNT_PER & ~CRPT_EVENT,  "host_certificate_expired", 0 },
213
  { XEVNT_CKY & ~CRPT_EVENT,  "bad_or_missing_cookie",  0 },
214
  { XEVNT_DAT & ~CRPT_EVENT,  "bad_or_missing_leapseconds", 0 },
215
  { XEVNT_CRT & ~CRPT_EVENT,  "bad_or_missing_certificate", 0 },  
216
  { XEVNT_ID & ~CRPT_EVENT, "bad_or_missing_group key", 0 },
217
  { XEVNT_ERR & ~CRPT_EVENT,  "protocol_error",   0 },
218
  { -1,       "",       0 }
219
};
220
#endif  /* AUTOKEY */
221
222
#ifdef KERNEL_PLL
223
/*
224
 * kernel discipline status bits
225
 */
226
static const struct codestring k_st_bits[] = {
227
# ifdef STA_PLL
228
  { STA_PLL,      "pll",    0 },
229
# endif
230
# ifdef STA_PPSFREQ
231
  { STA_PPSFREQ,      "ppsfreq",  0 },
232
# endif
233
# ifdef STA_PPSTIME
234
  { STA_PPSTIME,      "ppstime",  0 },
235
# endif
236
# ifdef STA_FLL
237
  { STA_FLL,      "fll",    0 },
238
# endif
239
# ifdef STA_INS
240
  { STA_INS,      "ins",    0 },
241
# endif
242
# ifdef STA_DEL
243
  { STA_DEL,      "del",    0 },
244
# endif
245
# ifdef STA_UNSYNC
246
  { STA_UNSYNC,     "unsync", 0 },
247
# endif
248
# ifdef STA_FREQHOLD
249
  { STA_FREQHOLD,     "freqhold", 0 },
250
# endif
251
# ifdef STA_PPSSIGNAL
252
  { STA_PPSSIGNAL,    "ppssignal",  0 },
253
# endif
254
# ifdef STA_PPSJITTER
255
  { STA_PPSJITTER,    "ppsjitter",  0 },
256
# endif
257
# ifdef STA_PPSWANDER
258
  { STA_PPSWANDER,    "ppswander",  0 },
259
# endif
260
# ifdef STA_PPSERROR
261
  { STA_PPSERROR,     "ppserror", 0 },
262
# endif
263
# ifdef STA_CLOCKERR
264
  { STA_CLOCKERR,     "clockerr", 0 },
265
# endif
266
# ifdef STA_NANO
267
  { STA_NANO,     "nano",   0 },
268
# endif
269
# ifdef STA_MODE
270
  { STA_MODE,     "mode=fll", 0 },
271
# endif
272
# ifdef STA_CLK
273
  { STA_CLK,      "src=B",  0 },
274
# endif
275
  /* not used with getcode(), no terminating entry needed */
276
};
277
#endif  /* KERNEL_PLL */
278
279
/* Forwards */
280
static const char * getcode(int, const struct codestring *);
281
static const char * getevents(int);
282
static const char * peer_st_flags(u_char pst);
283
284
/*
285
 * getcode - return string corresponding to code
286
 */
287
static const char *
288
getcode(
289
  int       code,
290
  const struct codestring * codetab
291
  )
292
15
{
293
15
  char *  buf;
294
295
180
  while (codetab->code != -1) {
296
180
    if (codetab->code == code)
297
15
      return codetab->string1;
298
165
    codetab++;
299
165
  }
300
301
0
  LIB_GETBUF(buf);
302
0
  snprintf(buf, LIB_BUFLENGTH, "%s_%d", codetab->string1, code);
303
304
0
  return buf;
305
15
}
306
307
/*
308
 * getevents - return a descriptive string for the event count
309
 */
310
static const char *
311
getevents(
312
  int cnt
313
  )
314
0
{
315
0
  char *  buf;
316
317
0
  if (cnt == 0)
318
0
    return "no events";
319
320
0
  LIB_GETBUF(buf);
321
0
  snprintf(buf, LIB_BUFLENGTH, "%d event%s", cnt,
322
0
     (1 == cnt)
323
0
         ? ""
324
0
         : "s");
325
326
0
  return buf;
327
0
}
328
329
330
/*
331
 * decode_bitflags()
332
 *
333
 * returns a human-readable string with a keyword from tab for each bit
334
 * set in bits, separating multiple entries with text of sep2.
335
 */
336
static const char *
337
decode_bitflags(
338
  int       bits,
339
  const char *      sep2,
340
  const struct codestring * tab,
341
  size_t        tab_ct
342
  )
343
0
{
344
0
  const char *  sep;
345
0
  char *    buf;
346
0
  char *    pch;
347
0
  char *    lim;
348
0
  size_t    b;
349
0
  int   rc;
350
0
  int   saved_errno;  /* for use in DPRINTF with %m */
351
352
0
  saved_errno = errno;
353
0
  LIB_GETBUF(buf);
354
0
  pch = buf;
355
0
  lim = buf + LIB_BUFLENGTH;
356
0
  sep = "";
357
358
0
  for (b = 0; b < tab_ct; b++) {
359
0
    const char * flagstr;
360
361
0
    if (tab[b].code & bits) {
362
0
      flagstr = tab[b].string1;
363
0
    } else {
364
0
      flagstr = tab[b].string0;
365
0
    }
366
367
0
    if (flagstr) {
368
0
      size_t avail = lim - pch;
369
0
      rc = snprintf(pch, avail, "%s%s", sep,
370
0
              flagstr);
371
0
      if ((size_t)rc >= avail)
372
0
        goto toosmall;
373
0
      pch += rc;
374
0
      sep = sep2;
375
0
    }
376
0
  }
377
378
0
  return buf;
379
380
0
    toosmall:
381
0
  snprintf(buf, LIB_BUFLENGTH,
382
0
     "decode_bitflags(%s) can't decode 0x%x in %d bytes",
383
0
     (tab == peer_st_bits)
384
0
         ? "peer_st"
385
0
         : 
386
0
#ifdef KERNEL_PLL
387
0
           (tab == k_st_bits)
388
0
         ? "kern_st"
389
0
         :
390
0
#endif
391
0
           "",
392
0
     bits, (int)LIB_BUFLENGTH);
393
0
  errno = saved_errno;
394
395
0
  return buf;
396
0
}
397
398
399
static const char *
400
peer_st_flags(
401
  u_char pst
402
  )
403
0
{
404
0
  return decode_bitflags(pst, ", ", peer_st_bits,
405
0
             COUNTOF(peer_st_bits));
406
0
}
407
408
409
const char *
410
res_match_flags(
411
  u_short mf
412
  )
413
0
{
414
0
  return decode_bitflags(mf, " ", res_match_bits,
415
0
             COUNTOF(res_match_bits));
416
0
}
417
418
419
const char *
420
res_access_flags(
421
  u_short af
422
  )
423
0
{
424
0
  return decode_bitflags(af, " ", res_access_bits,
425
0
             COUNTOF(res_access_bits));
426
0
}
427
428
429
#ifdef KERNEL_PLL
430
const char *
431
k_st_flags(
432
  u_int32 st
433
  )
434
0
{
435
0
  return decode_bitflags(st, " ", k_st_bits, COUNTOF(k_st_bits));
436
0
}
437
#endif  /* KERNEL_PLL */
438
439
440
/*
441
 * statustoa - return a descriptive string for a peer status
442
 */
443
char *
444
statustoa(
445
  int type,
446
  int st
447
  )
448
0
{
449
0
  char *  cb;
450
0
  char *  cc;
451
0
  u_char  pst;
452
453
0
  LIB_GETBUF(cb);
454
455
0
  switch (type) {
456
457
0
  case TYPE_SYS:
458
0
    snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s, %s",
459
0
       getcode(CTL_SYS_LI(st), leap_codes),
460
0
       getcode(CTL_SYS_SOURCE(st), sync_codes),
461
0
       getevents(CTL_SYS_NEVNT(st)),
462
0
       getcode(CTL_SYS_EVENT(st), sys_codes));
463
0
    break;
464
  
465
0
  case TYPE_PEER:
466
0
    pst = (u_char)CTL_PEER_STATVAL(st);
467
0
    snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s",
468
0
       peer_st_flags(pst),
469
0
       getcode(pst & 0x7, select_codes),
470
0
       getevents(CTL_PEER_NEVNT(st)));
471
0
    if (CTL_PEER_EVENT(st) != EVNT_UNSPEC) {
472
0
      cc = cb + strlen(cb);
473
0
      snprintf(cc, LIB_BUFLENGTH - (cc - cb), ", %s",
474
0
         getcode(CTL_PEER_EVENT(st),
475
0
           peer_codes));
476
0
    }
477
0
    break;
478
  
479
0
  case TYPE_CLOCK:
480
0
    snprintf(cb, LIB_BUFLENGTH, "%s, %s",
481
0
       getevents(CTL_SYS_NEVNT(st)),
482
0
       getcode((st) & 0xf, clock_codes));
483
0
    break;
484
0
  }
485
486
0
  return cb;
487
0
}
488
489
const char *
490
eventstr(
491
  int num
492
  )
493
15
{
494
15
  if (num & PEER_EVENT)
495
15
    return (getcode(num & ~PEER_EVENT, peer_codes));
496
#ifdef AUTOKEY
497
  else if (num & CRPT_EVENT)
498
    return (getcode(num & ~CRPT_EVENT, crypto_codes));
499
#endif  /* AUTOKEY */
500
0
  else
501
0
    return (getcode(num, sys_codes));
502
15
}
503
504
const char *
505
ceventstr(
506
  int num
507
  )
508
0
{
509
0
  return getcode(num, clock_codes);
510
0
}