1c0b746e5SOllivier Robert /* 2c0b746e5SOllivier Robert * pretty printing of status information 3c0b746e5SOllivier Robert */ 4c0b746e5SOllivier Robert #ifdef HAVE_CONFIG_H 5c0b746e5SOllivier Robert #include <config.h> 6c0b746e5SOllivier Robert #endif 7c0b746e5SOllivier Robert #include <stdio.h> 8c0b746e5SOllivier Robert #include "ntp_stdlib.h" 9c0b746e5SOllivier Robert #include "ntp_fp.h" 10c0b746e5SOllivier Robert #include "ntp.h" 11c0b746e5SOllivier Robert #include "lib_strbuf.h" 12c0b746e5SOllivier Robert #include "ntp_refclock.h" 13c0b746e5SOllivier Robert #include "ntp_control.h" 14c0b746e5SOllivier Robert #include "ntp_string.h" 15c0b746e5SOllivier Robert 16c0b746e5SOllivier Robert /* 17c0b746e5SOllivier Robert * Structure for turning various constants into a readable string. 18c0b746e5SOllivier Robert */ 19c0b746e5SOllivier Robert struct codestring { 20c0b746e5SOllivier Robert int code; 21c0b746e5SOllivier Robert const char *string; 22c0b746e5SOllivier Robert }; 23c0b746e5SOllivier Robert 24c0b746e5SOllivier Robert /* 25c0b746e5SOllivier Robert * Leap values 26c0b746e5SOllivier Robert */ 27c0b746e5SOllivier Robert static 28c0b746e5SOllivier Robert struct codestring leap_codes[] = { 29c0b746e5SOllivier Robert { LEAP_NOWARNING, "leap_none" }, 30c0b746e5SOllivier Robert { LEAP_ADDSECOND, "leap_add_sec" }, 31c0b746e5SOllivier Robert { LEAP_DELSECOND, "leap_del_sec" }, 32c0b746e5SOllivier Robert { LEAP_NOTINSYNC, "sync_alarm" }, 33c0b746e5SOllivier Robert { -1, "leap" } 34c0b746e5SOllivier Robert }; 35c0b746e5SOllivier Robert 36c0b746e5SOllivier Robert /* 37c0b746e5SOllivier Robert * Clock source 38c0b746e5SOllivier Robert */ 39c0b746e5SOllivier Robert static 40c0b746e5SOllivier Robert struct codestring sync_codes[] = { 41c0b746e5SOllivier Robert { CTL_SST_TS_UNSPEC, "sync_unspec" }, 42c0b746e5SOllivier Robert { CTL_SST_TS_ATOM, "sync_atomic" }, 43c0b746e5SOllivier Robert { CTL_SST_TS_LF, "sync_lf_clock" }, 44c0b746e5SOllivier Robert { CTL_SST_TS_HF, "sync_hf_clock" }, 45c0b746e5SOllivier Robert { CTL_SST_TS_UHF, "sync_uhf_clock" }, 46c0b746e5SOllivier Robert { CTL_SST_TS_LOCAL, "sync_local_proto" }, 47c0b746e5SOllivier Robert { CTL_SST_TS_NTP, "sync_ntp" }, 48c0b746e5SOllivier Robert { CTL_SST_TS_UDPTIME, "sync_udp/time" }, 49c0b746e5SOllivier Robert { CTL_SST_TS_WRSTWTCH, "sync_wristwatch" }, 50c0b746e5SOllivier Robert { CTL_SST_TS_TELEPHONE, "sync_telephone" }, 51c0b746e5SOllivier Robert { -1, "sync" } 52c0b746e5SOllivier Robert }; 53c0b746e5SOllivier Robert 54c0b746e5SOllivier Robert 55c0b746e5SOllivier Robert /* 56c0b746e5SOllivier Robert * Peer selection 57c0b746e5SOllivier Robert */ 58c0b746e5SOllivier Robert static 59c0b746e5SOllivier Robert struct codestring select_codes[] = { 60c0b746e5SOllivier Robert { CTL_PST_SEL_REJECT, "selreject" }, 61c0b746e5SOllivier Robert { CTL_PST_SEL_SANE, "sel_falsetick" }, 62c0b746e5SOllivier Robert { CTL_PST_SEL_CORRECT, "sel_excess" }, 63c0b746e5SOllivier Robert { CTL_PST_SEL_SELCAND, "sel_outlyer" }, 64c0b746e5SOllivier Robert { CTL_PST_SEL_SYNCCAND, "sel_candidat" }, 65c0b746e5SOllivier Robert { CTL_PST_SEL_DISTSYSPEER, "sel_selected" }, 66c0b746e5SOllivier Robert { CTL_PST_SEL_SYSPEER, "sel_sys.peer" }, 67c0b746e5SOllivier Robert { CTL_PST_SEL_PPS, "sel_pps.peer" }, 68c0b746e5SOllivier Robert { -1, "sel" } 69c0b746e5SOllivier Robert }; 70c0b746e5SOllivier Robert 71c0b746e5SOllivier Robert 72c0b746e5SOllivier Robert /* 73c0b746e5SOllivier Robert * Clock status 74c0b746e5SOllivier Robert */ 75c0b746e5SOllivier Robert static 76c0b746e5SOllivier Robert struct codestring clock_codes[] = { 77c0b746e5SOllivier Robert { CTL_CLK_OKAY, "clk_okay" }, 78c0b746e5SOllivier Robert { CTL_CLK_NOREPLY, "clk_noreply" }, 79c0b746e5SOllivier Robert { CTL_CLK_BADFORMAT, "clk_badformat" }, 80c0b746e5SOllivier Robert { CTL_CLK_FAULT, "clk_fault" }, 81c0b746e5SOllivier Robert { CTL_CLK_PROPAGATION, "clk_badsignal" }, 82c0b746e5SOllivier Robert { CTL_CLK_BADDATE, "clk_baddate" }, 83c0b746e5SOllivier Robert { CTL_CLK_BADTIME, "clk_badtime" }, 84c0b746e5SOllivier Robert { -1, "clk" } 85c0b746e5SOllivier Robert }; 86c0b746e5SOllivier Robert 87c0b746e5SOllivier Robert 88c0b746e5SOllivier Robert /* 89c0b746e5SOllivier Robert * System Events 90c0b746e5SOllivier Robert */ 91c0b746e5SOllivier Robert static 92c0b746e5SOllivier Robert struct codestring sys_codes[] = { 93c0b746e5SOllivier Robert { EVNT_UNSPEC, "event_unspec" }, 94c0b746e5SOllivier Robert { EVNT_SYSRESTART, "event_restart" }, 95c0b746e5SOllivier Robert { EVNT_SYSFAULT, "event_fault" }, 96c0b746e5SOllivier Robert { EVNT_SYNCCHG, "event_sync_chg" }, 97c0b746e5SOllivier Robert { EVNT_PEERSTCHG, "event_peer/strat_chg" }, 98c0b746e5SOllivier Robert { EVNT_CLOCKRESET, "event_clock_reset" }, 99c0b746e5SOllivier Robert { EVNT_BADDATETIM, "event_bad_date" }, 100c0b746e5SOllivier Robert { EVNT_CLOCKEXCPT, "event_clock_excptn" }, 101c0b746e5SOllivier Robert { -1, "event" } 102c0b746e5SOllivier Robert }; 103c0b746e5SOllivier Robert 104c0b746e5SOllivier Robert /* 1059c2daa00SOllivier Robert * Peer events 106c0b746e5SOllivier Robert */ 107c0b746e5SOllivier Robert static 108c0b746e5SOllivier Robert struct codestring peer_codes[] = { 109c0b746e5SOllivier Robert { EVNT_UNSPEC, "event_unspec" }, 110c0b746e5SOllivier Robert { EVNT_PEERIPERR & ~PEER_EVENT, "event_ip_err" }, 111c0b746e5SOllivier Robert { EVNT_PEERAUTH & ~PEER_EVENT, "event_authen" }, 112c0b746e5SOllivier Robert { EVNT_UNREACH & ~PEER_EVENT, "event_unreach" }, 113c0b746e5SOllivier Robert { EVNT_REACH & ~PEER_EVENT, "event_reach" }, 114c0b746e5SOllivier Robert { EVNT_PEERCLOCK & ~PEER_EVENT, "event_peer_clock" }, 115c0b746e5SOllivier Robert #if 0 116c0b746e5SOllivier Robert { EVNT_PEERSTRAT & ~PEER_EVENT, "event_stratum_chg" }, 117c0b746e5SOllivier Robert #endif 118c0b746e5SOllivier Robert { -1, "event" } 119c0b746e5SOllivier Robert }; 120c0b746e5SOllivier Robert 1219c2daa00SOllivier Robert #ifdef OPENSSL 1229c2daa00SOllivier Robert /* 1239c2daa00SOllivier Robert * Crypto events 1249c2daa00SOllivier Robert */ 1259c2daa00SOllivier Robert static 1269c2daa00SOllivier Robert struct codestring crypto_codes[] = { 1279c2daa00SOllivier Robert { XEVNT_OK & ~CRPT_EVENT, "success" }, 1289c2daa00SOllivier Robert { XEVNT_LEN & ~CRPT_EVENT, "bad_field_format_or_length" }, 1299c2daa00SOllivier Robert { XEVNT_TSP & ~CRPT_EVENT, "bad_timestamp" }, 1309c2daa00SOllivier Robert { XEVNT_FSP & ~CRPT_EVENT, "bad_filestamp" }, 1319c2daa00SOllivier Robert { XEVNT_PUB & ~CRPT_EVENT, "bad_procedure_or_data" }, 1329c2daa00SOllivier Robert { XEVNT_MD & ~CRPT_EVENT, "unsupported_digest_type" }, 1339c2daa00SOllivier Robert { XEVNT_KEY & ~CRPT_EVENT, "unsupported_identity_type" }, 1349c2daa00SOllivier Robert { XEVNT_SGL & ~CRPT_EVENT, "bad_signature_length" }, 1359c2daa00SOllivier Robert { XEVNT_SIG & ~CRPT_EVENT, "signature_not_verified" }, 1369c2daa00SOllivier Robert { XEVNT_VFY & ~CRPT_EVENT, "certificate not verified" }, 1379c2daa00SOllivier Robert { XEVNT_PER & ~CRPT_EVENT, "certificate_expired" }, 1389c2daa00SOllivier Robert { XEVNT_CKY & ~CRPT_EVENT, "bad_or_missing_cookie" }, 1399c2daa00SOllivier Robert { XEVNT_DAT & ~CRPT_EVENT, "bad_or_missing_leapsecond_table" }, 1409c2daa00SOllivier Robert { XEVNT_CRT & ~CRPT_EVENT, "bad_or_missing_certificate" }, 1419c2daa00SOllivier Robert { XEVNT_ID & ~CRPT_EVENT, "bad or missing identification" }, 1429c2daa00SOllivier Robert { -1, "crypto" } 1439c2daa00SOllivier Robert }; 1449c2daa00SOllivier Robert #endif /* OPENSSL */ 1459c2daa00SOllivier Robert 146c0b746e5SOllivier Robert /* Forwards */ 147c0b746e5SOllivier Robert static const char *getcode P((int, struct codestring *)); 148c0b746e5SOllivier Robert static const char *getevents P((int)); 149c0b746e5SOllivier Robert 150c0b746e5SOllivier Robert /* 151c0b746e5SOllivier Robert * getcode - return string corresponding to code 152c0b746e5SOllivier Robert */ 153c0b746e5SOllivier Robert static const char * 154c0b746e5SOllivier Robert getcode( 155c0b746e5SOllivier Robert int code, 156c0b746e5SOllivier Robert struct codestring *codetab 157c0b746e5SOllivier Robert ) 158c0b746e5SOllivier Robert { 159c0b746e5SOllivier Robert static char buf[30]; 160c0b746e5SOllivier Robert 161c0b746e5SOllivier Robert while (codetab->code != -1) { 162c0b746e5SOllivier Robert if (codetab->code == code) 163c0b746e5SOllivier Robert return codetab->string; 164c0b746e5SOllivier Robert codetab++; 165c0b746e5SOllivier Robert } 166c0b746e5SOllivier Robert (void) sprintf(buf, "%s_%d", codetab->string, code); 167c0b746e5SOllivier Robert return buf; 168c0b746e5SOllivier Robert } 169c0b746e5SOllivier Robert 170c0b746e5SOllivier Robert /* 171c0b746e5SOllivier Robert * getevents - return a descriptive string for the event count 172c0b746e5SOllivier Robert */ 173c0b746e5SOllivier Robert static const char * 174c0b746e5SOllivier Robert getevents( 175c0b746e5SOllivier Robert int cnt 176c0b746e5SOllivier Robert ) 177c0b746e5SOllivier Robert { 178c0b746e5SOllivier Robert static char buf[20]; 179c0b746e5SOllivier Robert 180c0b746e5SOllivier Robert if (cnt == 0) 181c0b746e5SOllivier Robert return "no events"; 182c0b746e5SOllivier Robert (void) sprintf(buf, "%d event%s", cnt, (cnt==1) ? "" : "s"); 183c0b746e5SOllivier Robert return buf; 184c0b746e5SOllivier Robert } 185c0b746e5SOllivier Robert 186c0b746e5SOllivier Robert /* 187c0b746e5SOllivier Robert * statustoa - return a descriptive string for a peer status 188c0b746e5SOllivier Robert */ 189c0b746e5SOllivier Robert char * 190c0b746e5SOllivier Robert statustoa( 191c0b746e5SOllivier Robert int type, 192c0b746e5SOllivier Robert int st 193c0b746e5SOllivier Robert ) 194c0b746e5SOllivier Robert { 195c0b746e5SOllivier Robert char *cb; 196c0b746e5SOllivier Robert u_char pst; 197c0b746e5SOllivier Robert 198c0b746e5SOllivier Robert LIB_GETBUF(cb); 199c0b746e5SOllivier Robert 200c0b746e5SOllivier Robert switch (type) { 201c0b746e5SOllivier Robert case TYPE_SYS: 202c0b746e5SOllivier Robert (void)strcpy(cb, getcode(CTL_SYS_LI(st), leap_codes)); 203c0b746e5SOllivier Robert (void)strcat(cb, ", "); 204c0b746e5SOllivier Robert (void)strcat(cb, getcode(CTL_SYS_SOURCE(st) & ~CTL_SST_TS_PPS, sync_codes)); 205c0b746e5SOllivier Robert if (CTL_SYS_SOURCE(st) & CTL_SST_TS_PPS) 206c0b746e5SOllivier Robert (void)strcat(cb, "/PPS"); 207c0b746e5SOllivier Robert (void)strcat(cb, ", "); 208c0b746e5SOllivier Robert (void)strcat(cb, getevents(CTL_SYS_NEVNT(st))); 209c0b746e5SOllivier Robert (void)strcat(cb, ", "); 210c0b746e5SOllivier Robert (void)strcat(cb, getcode(CTL_SYS_EVENT(st), sys_codes)); 211c0b746e5SOllivier Robert break; 212c0b746e5SOllivier Robert 213c0b746e5SOllivier Robert case TYPE_PEER: 214c0b746e5SOllivier Robert /* 215c0b746e5SOllivier Robert * Handcraft the bits 216c0b746e5SOllivier Robert */ 217c0b746e5SOllivier Robert pst = (u_char) CTL_PEER_STATVAL(st); 218c0b746e5SOllivier Robert if (!(pst & CTL_PST_REACH)) { 219c0b746e5SOllivier Robert (void)strcpy(cb, "unreach"); 220c0b746e5SOllivier Robert } else { 221c0b746e5SOllivier Robert (void)strcpy(cb, "reach"); 222c0b746e5SOllivier Robert 223c0b746e5SOllivier Robert } 224c0b746e5SOllivier Robert if (pst & CTL_PST_CONFIG) 225c0b746e5SOllivier Robert (void)strcat(cb, ", conf"); 226c0b746e5SOllivier Robert if (pst & CTL_PST_AUTHENABLE) { 227c0b746e5SOllivier Robert if (!(pst & CTL_PST_REACH) || (pst & CTL_PST_AUTHENTIC)) 228c0b746e5SOllivier Robert (void)strcat(cb, ", auth"); 229c0b746e5SOllivier Robert else 230c0b746e5SOllivier Robert (void)strcat(cb, ", unauth"); 231c0b746e5SOllivier Robert } 232c0b746e5SOllivier Robert 233c0b746e5SOllivier Robert /* 234c0b746e5SOllivier Robert * Now the codes 235c0b746e5SOllivier Robert */ 236c0b746e5SOllivier Robert if ((pst & 0x7) != CTL_PST_SEL_REJECT) { 237c0b746e5SOllivier Robert (void)strcat(cb, ", "); 238c0b746e5SOllivier Robert (void)strcat(cb, getcode(pst & 0x7, select_codes)); 239c0b746e5SOllivier Robert } 240c0b746e5SOllivier Robert (void)strcat(cb, ", "); 241c0b746e5SOllivier Robert (void)strcat(cb, getevents(CTL_PEER_NEVNT(st))); 242c0b746e5SOllivier Robert if (CTL_PEER_EVENT(st) != EVNT_UNSPEC) { 243c0b746e5SOllivier Robert (void)strcat(cb, ", "); 244c0b746e5SOllivier Robert (void)strcat(cb, getcode(CTL_PEER_EVENT(st), 245c0b746e5SOllivier Robert peer_codes)); 246c0b746e5SOllivier Robert } 247c0b746e5SOllivier Robert break; 248c0b746e5SOllivier Robert 249c0b746e5SOllivier Robert case TYPE_CLOCK: 250c0b746e5SOllivier Robert (void)strcpy(cb, getcode(((st)>>8) & 0xff, clock_codes)); 251c0b746e5SOllivier Robert (void)strcat(cb, ", last_"); 252c0b746e5SOllivier Robert (void)strcat(cb, getcode((st) & 0xff, clock_codes)); 253c0b746e5SOllivier Robert break; 254c0b746e5SOllivier Robert } 255c0b746e5SOllivier Robert return cb; 256c0b746e5SOllivier Robert } 257c0b746e5SOllivier Robert 258c0b746e5SOllivier Robert const char * 259c0b746e5SOllivier Robert eventstr( 260c0b746e5SOllivier Robert int num 261c0b746e5SOllivier Robert ) 262c0b746e5SOllivier Robert { 2639c2daa00SOllivier Robert if (num & PEER_EVENT) 2649c2daa00SOllivier Robert return (getcode(num & ~PEER_EVENT, peer_codes)); 2659c2daa00SOllivier Robert #ifdef OPENSSL 2669c2daa00SOllivier Robert else if (num & CRPT_EVENT) 2679c2daa00SOllivier Robert return (getcode(num & ~CRPT_EVENT, crypto_codes)); 2689c2daa00SOllivier Robert #endif /* OPENSSL */ 2699c2daa00SOllivier Robert else 2709c2daa00SOllivier Robert return (getcode(num, sys_codes)); 271c0b746e5SOllivier Robert } 272c0b746e5SOllivier Robert 273c0b746e5SOllivier Robert const char * 274c0b746e5SOllivier Robert ceventstr( 275c0b746e5SOllivier Robert int num 276c0b746e5SOllivier Robert ) 277c0b746e5SOllivier Robert { 278c0b746e5SOllivier Robert return getcode(num, clock_codes); 279c0b746e5SOllivier Robert } 280c0b746e5SOllivier Robert 281c0b746e5SOllivier Robert const char * 282c0b746e5SOllivier Robert sysstatstr( 283c0b746e5SOllivier Robert int status 284c0b746e5SOllivier Robert ) 285c0b746e5SOllivier Robert { 286c0b746e5SOllivier Robert return statustoa(TYPE_SYS, status); 287c0b746e5SOllivier Robert } 288c0b746e5SOllivier Robert 289c0b746e5SOllivier Robert const char * 290c0b746e5SOllivier Robert peerstatstr( 291c0b746e5SOllivier Robert int status 292c0b746e5SOllivier Robert ) 293c0b746e5SOllivier Robert { 294c0b746e5SOllivier Robert return statustoa(TYPE_PEER, status); 295c0b746e5SOllivier Robert } 296c0b746e5SOllivier Robert 297c0b746e5SOllivier Robert const char * 298c0b746e5SOllivier Robert clockstatstr( 299c0b746e5SOllivier Robert int status 300c0b746e5SOllivier Robert ) 301c0b746e5SOllivier Robert { 302c0b746e5SOllivier Robert return statustoa(TYPE_CLOCK, status); 303c0b746e5SOllivier Robert } 304