1 /* $NetBSD: statestr.c,v 1.1.1.1 2009/12/13 16:55:05 kardel Exp $ */ 2 3 /* 4 * pretty printing of status information 5 */ 6 #ifdef HAVE_CONFIG_H 7 #include <config.h> 8 #endif 9 #include <stdio.h> 10 #include "ntp_stdlib.h" 11 #include "ntp_fp.h" 12 #include "ntp.h" 13 #include "lib_strbuf.h" 14 #include "ntp_refclock.h" 15 #include "ntp_control.h" 16 #include "ntp_string.h" 17 18 /* 19 * Structure for turning various constants into a readable string. 20 */ 21 struct codestring { 22 int code; 23 const char *string; 24 }; 25 26 /* 27 * Leap status (leap) 28 */ 29 static 30 struct codestring leap_codes[] = { 31 { LEAP_NOWARNING, "leap_none" }, 32 { LEAP_ADDSECOND, "leap_add_sec" }, 33 { LEAP_DELSECOND, "leap_del_sec" }, 34 { LEAP_NOTINSYNC, "leap_alarm" }, 35 { -1, "leap" } 36 }; 37 38 /* 39 * Clock source status (sync) 40 */ 41 static 42 struct codestring sync_codes[] = { 43 { CTL_SST_TS_UNSPEC, "sync_unspec" }, 44 { CTL_SST_TS_ATOM, "sync_pps" }, 45 { CTL_SST_TS_LF, "sync_lf_radio" }, 46 { CTL_SST_TS_HF, "sync_hf_radio" }, 47 { CTL_SST_TS_UHF, "sync_uhf_radio" }, 48 { CTL_SST_TS_LOCAL, "sync_local" }, 49 { CTL_SST_TS_NTP, "sync_ntp" }, 50 { CTL_SST_TS_UDPTIME, "sync_other" }, 51 { CTL_SST_TS_WRSTWTCH, "sync_wristwatch" }, 52 { CTL_SST_TS_TELEPHONE, "sync_telephone" }, 53 { -1, "sync" } 54 }; 55 56 /* 57 * Peer selection status (sel) 58 */ 59 static 60 struct codestring select_codes[] = { 61 { CTL_PST_SEL_REJECT, "sel_reject" }, 62 { CTL_PST_SEL_SANE, "sel_falsetick" }, 63 { CTL_PST_SEL_CORRECT, "sel_excess" }, 64 { CTL_PST_SEL_SELCAND, "sel_outlyer" }, 65 { CTL_PST_SEL_SYNCCAND, "sel_candidate" }, 66 { CTL_PST_SEL_EXCESS, "sel_backup" }, 67 { CTL_PST_SEL_SYSPEER, "sel_sys.peer" }, 68 { CTL_PST_SEL_PPS, "sel_pps.peer" }, 69 { -1, "sel" } 70 }; 71 72 /* 73 * Clock status (clk) 74 */ 75 static 76 struct codestring clock_codes[] = { 77 { CTL_CLK_OKAY, "clk_unspec" }, 78 { CTL_CLK_NOREPLY, "clk_no_reply" }, 79 { CTL_CLK_BADFORMAT, "clk_bad_format" }, 80 { CTL_CLK_FAULT, "clk_fault" }, 81 { CTL_CLK_PROPAGATION, "clk_bad_signal" }, 82 { CTL_CLK_BADDATE, "clk_bad_date" }, 83 { CTL_CLK_BADTIME, "clk_bad_time" }, 84 { -1, "clk" } 85 }; 86 87 88 #ifdef FLASH_CODES_UNUSED 89 /* 90 * Flash bits -- see ntpq.c tstflags & tstflagnames 91 */ 92 static 93 struct codestring flash_codes[] = { 94 { TEST1, "pkt_dup" }, 95 { TEST2, "pkt_bogus" }, 96 { TEST3, "pkt_unsync" }, 97 { TEST4, "pkt_denied" }, 98 { TEST5, "pkt_auth" }, 99 { TEST6, "pkt_stratum" }, 100 { TEST7, "pkt_header" }, 101 { TEST8, "pkt_autokey" }, 102 { TEST9, "pkt_crypto" }, 103 { TEST10, "peer_stratum" }, 104 { TEST11, "peer_dist" }, 105 { TEST12, "peer_loop" }, 106 { TEST13, "peer_unreach" }, 107 { -1, "flash" } 108 }; 109 #endif 110 111 112 /* 113 * System events (sys) 114 */ 115 static 116 struct codestring sys_codes[] = { 117 { EVNT_UNSPEC, "unspecified" }, 118 { EVNT_NSET, "freq_not_set" }, 119 { EVNT_FSET, "freq_set" }, 120 { EVNT_SPIK, "spike_detect" }, 121 { EVNT_FREQ, "freq_mode" }, 122 { EVNT_SYNC, "clock_sync" }, 123 { EVNT_SYSRESTART, "restart" }, 124 { EVNT_SYSFAULT, "panic_stop" }, 125 { EVNT_NOPEER, "no_sys_peer" }, 126 { EVNT_ARMED, "leap_armed" }, 127 { EVNT_DISARMED, "leap_disarmed" }, 128 { EVNT_LEAP, "leap_event" }, 129 { EVNT_CLOCKRESET, "clock_step" }, 130 { EVNT_KERN, "kern" }, 131 { EVNT_TAI, "TAI" }, 132 { EVNT_LEAPVAL, "stale_leapsecond_values" }, 133 { EVNT_CLKHOP, "clockhop" }, 134 { -1, "" } 135 }; 136 137 /* 138 * Peer events (peer) 139 */ 140 static 141 struct codestring peer_codes[] = { 142 { PEVNT_MOBIL & ~PEER_EVENT, "mobilize" }, 143 { PEVNT_DEMOBIL & ~PEER_EVENT, "demobilize" }, 144 { PEVNT_UNREACH & ~PEER_EVENT, "unreachable" }, 145 { PEVNT_REACH & ~PEER_EVENT, "reachable" }, 146 { PEVNT_RESTART & ~PEER_EVENT, "restart" }, 147 { PEVNT_REPLY & ~PEER_EVENT, "no_reply" }, 148 { PEVNT_RATE & ~PEER_EVENT, "rate_exceeded" }, 149 { PEVNT_DENY & ~PEER_EVENT, "access_denied" }, 150 { PEVNT_ARMED & ~PEER_EVENT, "leap_armed" }, 151 { PEVNT_NEWPEER & ~PEER_EVENT, "sys_peer" }, 152 { PEVNT_CLOCK & ~PEER_EVENT, "clock_event" }, 153 { PEVNT_AUTH & ~PEER_EVENT, "bad_auth" }, 154 { PEVNT_POPCORN & ~PEER_EVENT, "popcorn" }, 155 { PEVNT_XLEAVE & ~PEER_EVENT, "interleave_mode" }, 156 { PEVNT_XERR & ~PEER_EVENT, "interleave_error" }, 157 { PEVNT_TAI & ~PEER_EVENT, "TAI" }, 158 { -1, "" } 159 }; 160 161 #ifdef OPENSSL 162 /* 163 * Crypto events (cryp) 164 */ 165 static 166 struct codestring crypto_codes[] = { 167 { XEVNT_OK & ~CRPT_EVENT, "success" }, 168 { XEVNT_LEN & ~CRPT_EVENT, "bad_field_format_or_length" }, 169 { XEVNT_TSP & ~CRPT_EVENT, "bad_timestamp" }, 170 { XEVNT_FSP & ~CRPT_EVENT, "bad_filestamp" }, 171 { XEVNT_PUB & ~CRPT_EVENT, "bad_or_missing_public_key" }, 172 { XEVNT_MD & ~CRPT_EVENT, "unsupported_digest_type" }, 173 { XEVNT_KEY & ~CRPT_EVENT, "unsupported_identity_type" }, 174 { XEVNT_SGL & ~CRPT_EVENT, "bad_signature_length" }, 175 { XEVNT_SIG & ~CRPT_EVENT, "signature_not_verified" }, 176 { XEVNT_VFY & ~CRPT_EVENT, "certificate_not_verified" }, 177 { XEVNT_PER & ~CRPT_EVENT, "host_certificate_expired" }, 178 { XEVNT_CKY & ~CRPT_EVENT, "bad_or_missing_cookie" }, 179 { XEVNT_DAT & ~CRPT_EVENT, "bad_or_missing_leapseconds" }, 180 { XEVNT_CRT & ~CRPT_EVENT, "bad_or_missing_certificate" }, 181 { XEVNT_ID & ~CRPT_EVENT, "bad_or_missing_group key" }, 182 { XEVNT_ERR & ~CRPT_EVENT, "protocol_error" }, 183 { -1, "" } 184 }; 185 #endif /* OPENSSL */ 186 187 /* Forwards */ 188 static const char *getcode (int, struct codestring *); 189 static const char *getevents (int); 190 191 /* 192 * getcode - return string corresponding to code 193 */ 194 static const char * 195 getcode( 196 int code, 197 struct codestring *codetab 198 ) 199 { 200 static char buf[30]; 201 202 while (codetab->code != -1) { 203 if (codetab->code == code) 204 return codetab->string; 205 codetab++; 206 } 207 snprintf(buf, sizeof(buf), "%s_%d", codetab->string, code); 208 return buf; 209 } 210 211 /* 212 * getevents - return a descriptive string for the event count 213 */ 214 static const char * 215 getevents( 216 int cnt 217 ) 218 { 219 static char buf[20]; 220 221 if (cnt == 0) 222 return "no events"; 223 snprintf(buf, sizeof(buf), "%d event%s", cnt, (cnt==1) ? "" : 224 "s"); 225 return buf; 226 } 227 228 /* 229 * statustoa - return a descriptive string for a peer status 230 */ 231 char * 232 statustoa( 233 int type, 234 int st 235 ) 236 { 237 char *cb; 238 u_char pst; 239 240 LIB_GETBUF(cb); 241 242 switch (type) { 243 case TYPE_SYS: 244 strcpy(cb, getcode(CTL_SYS_LI(st), leap_codes)); 245 strcat(cb, ", "); 246 strcat(cb, getcode(CTL_SYS_SOURCE(st), sync_codes)); 247 strcat(cb, ", "); 248 strcat(cb, getevents(CTL_SYS_NEVNT(st))); 249 strcat(cb, ", "); 250 strcat(cb, getcode(CTL_SYS_EVENT(st), sys_codes)); 251 break; 252 253 case TYPE_PEER: 254 255 /* 256 * Handcraft the bits 257 */ 258 pst = (u_char) CTL_PEER_STATVAL(st); 259 if (pst & CTL_PST_CONFIG) 260 strcpy(cb, "conf"); 261 if (pst & CTL_PST_AUTHENABLE) { 262 if (pst & CTL_PST_CONFIG) 263 strcat(cb, ", authenb"); 264 else 265 strcat(cb, "authenb"); 266 } 267 if (pst & CTL_PST_AUTHENTIC) { 268 if (pst & (CTL_PST_CONFIG | CTL_PST_AUTHENABLE)) 269 strcat(cb, ", auth"); 270 else 271 strcat(cb, "auth"); 272 } 273 if (pst & CTL_PST_REACH) { 274 if (pst & (CTL_PST_CONFIG | CTL_PST_AUTHENABLE | 275 CTL_PST_AUTHENTIC)) 276 strcat(cb, ", reach"); 277 else 278 strcat(cb, "reach"); 279 } 280 if (pst & CTL_PST_BCAST) { 281 if (pst & (CTL_PST_CONFIG | CTL_PST_AUTHENABLE | 282 CTL_PST_AUTHENTIC | CTL_PST_REACH)) 283 strcat(cb, ", bcst"); 284 else 285 strcat(cb, "bcst"); 286 } 287 288 /* 289 * Now the codes 290 */ 291 strcat(cb, ", "); 292 strcat(cb, getcode(pst & 0x7, select_codes)); 293 strcat(cb, ", "); 294 strcat(cb, getevents(CTL_PEER_NEVNT(st))); 295 if (CTL_PEER_EVENT(st) != EVNT_UNSPEC) { 296 strcat(cb, ", "); 297 strcat(cb, getcode(CTL_PEER_EVENT(st), 298 peer_codes)); 299 } 300 break; 301 302 case TYPE_CLOCK: 303 strcat(cb, ", "); 304 strcat(cb, getevents(CTL_SYS_NEVNT(st))); 305 strcat(cb, ", "); 306 strcat(cb, getcode((st) & 0xf, clock_codes)); 307 break; 308 } 309 return cb; 310 } 311 312 const char * 313 eventstr( 314 int num 315 ) 316 { 317 if (num & PEER_EVENT) 318 return (getcode(num & ~PEER_EVENT, peer_codes)); 319 #ifdef OPENSSL 320 else if (num & CRPT_EVENT) 321 return (getcode(num & ~CRPT_EVENT, crypto_codes)); 322 #endif /* OPENSSL */ 323 else 324 return (getcode(num, sys_codes)); 325 } 326 327 const char * 328 ceventstr( 329 int num 330 ) 331 { 332 return getcode(num, clock_codes); 333 } 334