xref: /netbsd/external/bsd/ntp/dist/libntp/statestr.c (revision 6550d01e)
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