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 */ 19 struct codestring { 20 int code; 21 const char *string; 22 }; 23 24 /* 25 * Leap values 26 */ 27 static 28 struct 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 */ 39 static 40 struct 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 */ 58 static 59 struct 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 */ 75 static 76 struct 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 */ 91 static 92 struct 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 */ 107 static 108 struct 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 */ 125 static 126 struct 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 */ 149 static const char *getcode P((int, struct codestring *)); 150 static const char *getevents P((int)); 151 152 /* 153 * getcode - return string corresponding to code 154 */ 155 static const char * 156 getcode( 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 */ 175 static const char * 176 getevents( 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 */ 191 char * 192 statustoa( 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 260 const char * 261 eventstr( 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 275 const char * 276 ceventstr( 277 int num 278 ) 279 { 280 return getcode(num, clock_codes); 281 } 282 283 const char * 284 sysstatstr( 285 int status 286 ) 287 { 288 return statustoa(TYPE_SYS, status); 289 } 290 291 const char * 292 peerstatstr( 293 int status 294 ) 295 { 296 return statustoa(TYPE_PEER, status); 297 } 298 299 const char * 300 clockstatstr( 301 int status 302 ) 303 { 304 return statustoa(TYPE_CLOCK, status); 305 } 306