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