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_procedure_or_data" }, 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, "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 identification" }, 142 { -1, "crypto" } 143 }; 144 #endif /* OPENSSL */ 145 146 /* Forwards */ 147 static const char *getcode P((int, struct codestring *)); 148 static const char *getevents P((int)); 149 150 /* 151 * getcode - return string corresponding to code 152 */ 153 static const char * 154 getcode( 155 int code, 156 struct codestring *codetab 157 ) 158 { 159 static char buf[30]; 160 161 while (codetab->code != -1) { 162 if (codetab->code == code) 163 return codetab->string; 164 codetab++; 165 } 166 (void) sprintf(buf, "%s_%d", codetab->string, code); 167 return buf; 168 } 169 170 /* 171 * getevents - return a descriptive string for the event count 172 */ 173 static const char * 174 getevents( 175 int cnt 176 ) 177 { 178 static char buf[20]; 179 180 if (cnt == 0) 181 return "no events"; 182 (void) sprintf(buf, "%d event%s", cnt, (cnt==1) ? "" : "s"); 183 return buf; 184 } 185 186 /* 187 * statustoa - return a descriptive string for a peer status 188 */ 189 char * 190 statustoa( 191 int type, 192 int st 193 ) 194 { 195 char *cb; 196 u_char pst; 197 198 LIB_GETBUF(cb); 199 200 switch (type) { 201 case TYPE_SYS: 202 (void)strcpy(cb, getcode(CTL_SYS_LI(st), leap_codes)); 203 (void)strcat(cb, ", "); 204 (void)strcat(cb, getcode(CTL_SYS_SOURCE(st) & ~CTL_SST_TS_PPS, sync_codes)); 205 if (CTL_SYS_SOURCE(st) & CTL_SST_TS_PPS) 206 (void)strcat(cb, "/PPS"); 207 (void)strcat(cb, ", "); 208 (void)strcat(cb, getevents(CTL_SYS_NEVNT(st))); 209 (void)strcat(cb, ", "); 210 (void)strcat(cb, getcode(CTL_SYS_EVENT(st), sys_codes)); 211 break; 212 213 case TYPE_PEER: 214 /* 215 * Handcraft the bits 216 */ 217 pst = (u_char) CTL_PEER_STATVAL(st); 218 if (!(pst & CTL_PST_REACH)) { 219 (void)strcpy(cb, "unreach"); 220 } else { 221 (void)strcpy(cb, "reach"); 222 223 } 224 if (pst & CTL_PST_CONFIG) 225 (void)strcat(cb, ", conf"); 226 if (pst & CTL_PST_AUTHENABLE) { 227 if (!(pst & CTL_PST_REACH) || (pst & CTL_PST_AUTHENTIC)) 228 (void)strcat(cb, ", auth"); 229 else 230 (void)strcat(cb, ", unauth"); 231 } 232 233 /* 234 * Now the codes 235 */ 236 if ((pst & 0x7) != CTL_PST_SEL_REJECT) { 237 (void)strcat(cb, ", "); 238 (void)strcat(cb, getcode(pst & 0x7, select_codes)); 239 } 240 (void)strcat(cb, ", "); 241 (void)strcat(cb, getevents(CTL_PEER_NEVNT(st))); 242 if (CTL_PEER_EVENT(st) != EVNT_UNSPEC) { 243 (void)strcat(cb, ", "); 244 (void)strcat(cb, getcode(CTL_PEER_EVENT(st), 245 peer_codes)); 246 } 247 break; 248 249 case TYPE_CLOCK: 250 (void)strcpy(cb, getcode(((st)>>8) & 0xff, clock_codes)); 251 (void)strcat(cb, ", last_"); 252 (void)strcat(cb, getcode((st) & 0xff, clock_codes)); 253 break; 254 } 255 return cb; 256 } 257 258 const char * 259 eventstr( 260 int num 261 ) 262 { 263 if (num & PEER_EVENT) 264 return (getcode(num & ~PEER_EVENT, peer_codes)); 265 #ifdef OPENSSL 266 else if (num & CRPT_EVENT) 267 return (getcode(num & ~CRPT_EVENT, crypto_codes)); 268 #endif /* OPENSSL */ 269 else 270 return (getcode(num, sys_codes)); 271 } 272 273 const char * 274 ceventstr( 275 int num 276 ) 277 { 278 return getcode(num, clock_codes); 279 } 280 281 const char * 282 sysstatstr( 283 int status 284 ) 285 { 286 return statustoa(TYPE_SYS, status); 287 } 288 289 const char * 290 peerstatstr( 291 int status 292 ) 293 { 294 return statustoa(TYPE_PEER, status); 295 } 296 297 const char * 298 clockstatstr( 299 int status 300 ) 301 { 302 return statustoa(TYPE_CLOCK, status); 303 } 304