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