154359Sroberto/*
254359Sroberto * pretty printing of status information
354359Sroberto */
454359Sroberto#ifdef HAVE_CONFIG_H
554359Sroberto#include <config.h>
654359Sroberto#endif
754359Sroberto#include <stdio.h>
854359Sroberto#include "ntp_stdlib.h"
954359Sroberto#include "ntp_fp.h"
1054359Sroberto#include "ntp.h"
1154359Sroberto#include "lib_strbuf.h"
1254359Sroberto#include "ntp_refclock.h"
1354359Sroberto#include "ntp_control.h"
1454359Sroberto#include "ntp_string.h"
15285612Sdelphij#ifdef KERNEL_PLL
16285612Sdelphij# include "ntp_syscall.h"
17285612Sdelphij#endif
1854359Sroberto
19285612Sdelphij
2054359Sroberto/*
2154359Sroberto * Structure for turning various constants into a readable string.
2254359Sroberto */
2354359Srobertostruct codestring {
2454359Sroberto	int code;
25330141Sdelphij	const char * const string1;
26330141Sdelphij	const char * const string0;
2754359Sroberto};
2854359Sroberto
2954359Sroberto/*
30285612Sdelphij * Leap status (leap)
3154359Sroberto */
32285612Sdelphijstatic const struct codestring leap_codes[] = {
33330141Sdelphij	{ LEAP_NOWARNING,	"leap_none",	0 },
34330141Sdelphij	{ LEAP_ADDSECOND,	"leap_add_sec",	0 },
35330141Sdelphij	{ LEAP_DELSECOND,	"leap_del_sec",	0 },
36330141Sdelphij	{ LEAP_NOTINSYNC,	"leap_alarm",	0 },
37330141Sdelphij	{ -1,			"leap",		0 }
3854359Sroberto};
3954359Sroberto
4054359Sroberto/*
41285612Sdelphij * Clock source status (sync)
4254359Sroberto */
43285612Sdelphijstatic const struct codestring sync_codes[] = {
44330141Sdelphij	{ CTL_SST_TS_UNSPEC,	"sync_unspec",		0 },
45330141Sdelphij	{ CTL_SST_TS_ATOM,	"sync_pps",		0 },
46330141Sdelphij	{ CTL_SST_TS_LF,	"sync_lf_radio",	0 },
47330141Sdelphij	{ CTL_SST_TS_HF,	"sync_hf_radio",	0 },
48330141Sdelphij	{ CTL_SST_TS_UHF,	"sync_uhf_radio",	0 },
49330141Sdelphij	{ CTL_SST_TS_LOCAL,	"sync_local",		0 },
50330141Sdelphij	{ CTL_SST_TS_NTP,	"sync_ntp",		0 },
51330141Sdelphij	{ CTL_SST_TS_UDPTIME,	"sync_other",		0 },
52330141Sdelphij	{ CTL_SST_TS_WRSTWTCH,	"sync_wristwatch",	0 },
53330141Sdelphij	{ CTL_SST_TS_TELEPHONE,	"sync_telephone",	0 },
54330141Sdelphij	{ -1,			"sync",			0 }
5554359Sroberto};
5654359Sroberto
5754359Sroberto/*
58285612Sdelphij * Peer selection status (sel)
5954359Sroberto */
60285612Sdelphijstatic const struct codestring select_codes[] = {
61330141Sdelphij	{ CTL_PST_SEL_REJECT,	"sel_reject",		0 },
62330141Sdelphij	{ CTL_PST_SEL_SANE,	"sel_falsetick",	0 },
63330141Sdelphij	{ CTL_PST_SEL_CORRECT,	"sel_excess",		0 },
64330141Sdelphij	{ CTL_PST_SEL_SELCAND,	"sel_outlier",		0 },
65330141Sdelphij	{ CTL_PST_SEL_SYNCCAND,	"sel_candidate",	0 },
66330141Sdelphij	{ CTL_PST_SEL_EXCESS,	"sel_backup",		0 },
67330141Sdelphij	{ CTL_PST_SEL_SYSPEER,	"sel_sys.peer",		0 },
68330141Sdelphij	{ CTL_PST_SEL_PPS,	"sel_pps.peer",		0 },
69330141Sdelphij	{ -1,			"sel",			0 }
7054359Sroberto};
7154359Sroberto
7254359Sroberto/*
73285612Sdelphij * Clock status (clk)
7454359Sroberto */
75285612Sdelphijstatic const struct codestring clock_codes[] = {
76330141Sdelphij	{ CTL_CLK_OKAY,		"clk_unspec",		0 },
77330141Sdelphij	{ CTL_CLK_NOREPLY,	"clk_no_reply",		0 },
78330141Sdelphij	{ CTL_CLK_BADFORMAT,	"clk_bad_format",	0 },
79330141Sdelphij	{ CTL_CLK_FAULT,	"clk_fault",		0 },
80330141Sdelphij	{ CTL_CLK_PROPAGATION,	"clk_bad_signal",	0 },
81330141Sdelphij	{ CTL_CLK_BADDATE,	"clk_bad_date",		0 },
82330141Sdelphij	{ CTL_CLK_BADTIME,	"clk_bad_time",		0 },
83330141Sdelphij	{ -1,			"clk",			0 }
8454359Sroberto};
8554359Sroberto
8654359Sroberto
87285612Sdelphij#ifdef FLASH_CODES_UNUSED
8854359Sroberto/*
89285612Sdelphij * Flash bits -- see ntpq.c tstflags & tstflagnames
9054359Sroberto */
91285612Sdelphijstatic const struct codestring flash_codes[] = {
92330141Sdelphij	{ TEST1,		"pkt_dup",	0 },
93330141Sdelphij	{ TEST2,		"pkt_bogus",	0 },
94330141Sdelphij	{ TEST3,		"pkt_unsync",	0 },
95330141Sdelphij	{ TEST4,		"pkt_denied",	0 },
96330141Sdelphij	{ TEST5,		"pkt_auth",	0 },
97330141Sdelphij	{ TEST6,		"pkt_stratum",	0 },
98330141Sdelphij	{ TEST7,		"pkt_header",	0 },
99330141Sdelphij	{ TEST8,		"pkt_autokey",	0 },
100330141Sdelphij	{ TEST9,		"pkt_crypto",	0 },
101330141Sdelphij	{ TEST10,		"peer_stratum",	0 },
102330141Sdelphij	{ TEST11,		"peer_dist",	0 },
103330141Sdelphij	{ TEST12,		"peer_loop",	0 },
104330141Sdelphij	{ TEST13,		"peer_unreach",	0 },
105330141Sdelphij	{ -1,			"flash",	0 }
10654359Sroberto};
107285612Sdelphij#endif
10854359Sroberto
109285612Sdelphij
11054359Sroberto/*
111285612Sdelphij * System events (sys)
11254359Sroberto */
113285612Sdelphijstatic const struct codestring sys_codes[] = {
114330141Sdelphij	{ EVNT_UNSPEC,		"unspecified",			0 },
115330141Sdelphij	{ EVNT_NSET,		"freq_not_set",			0 },
116330141Sdelphij	{ EVNT_FSET,		"freq_set",			0 },
117330141Sdelphij	{ EVNT_SPIK,		"spike_detect",			0 },
118330141Sdelphij	{ EVNT_FREQ,		"freq_mode",			0 },
119330141Sdelphij	{ EVNT_SYNC,		"clock_sync",			0 },
120330141Sdelphij	{ EVNT_SYSRESTART,	"restart",			0 },
121330141Sdelphij	{ EVNT_SYSFAULT,	"panic_stop",			0 },
122330141Sdelphij	{ EVNT_NOPEER,		"no_sys_peer",			0 },
123330141Sdelphij	{ EVNT_ARMED,		"leap_armed",			0 },
124330141Sdelphij	{ EVNT_DISARMED,	"leap_disarmed",		0 },
125330141Sdelphij	{ EVNT_LEAP,		"leap_event",			0 },
126330141Sdelphij	{ EVNT_CLOCKRESET,	"clock_step",			0 },
127330141Sdelphij	{ EVNT_KERN,		"kern",				0 },
128330141Sdelphij	{ EVNT_TAI,		"TAI",				0 },
129330141Sdelphij	{ EVNT_LEAPVAL,		"stale_leapsecond_values",	0 },
130330141Sdelphij	{ -1,			"",				0 }
13154359Sroberto};
13254359Sroberto
133132451Sroberto/*
134285612Sdelphij * Peer events (peer)
135132451Sroberto */
136285612Sdelphijstatic const struct codestring peer_codes[] = {
137330141Sdelphij	{ PEVNT_MOBIL & ~PEER_EVENT,	"mobilize",		0 },
138330141Sdelphij	{ PEVNT_DEMOBIL & ~PEER_EVENT,	"demobilize",		0 },
139330141Sdelphij	{ PEVNT_UNREACH & ~PEER_EVENT,	"unreachable",		0 },
140330141Sdelphij	{ PEVNT_REACH & ~PEER_EVENT,	"reachable",		0 },
141330141Sdelphij	{ PEVNT_RESTART & ~PEER_EVENT,	"restart",		0 },
142330141Sdelphij	{ PEVNT_REPLY & ~PEER_EVENT,	"no_reply",		0 },
143330141Sdelphij	{ PEVNT_RATE & ~PEER_EVENT,	"rate_exceeded",	0 },
144330141Sdelphij	{ PEVNT_DENY & ~PEER_EVENT,	"access_denied",	0 },
145330141Sdelphij	{ PEVNT_ARMED & ~PEER_EVENT,	"leap_armed",		0 },
146330141Sdelphij	{ PEVNT_NEWPEER & ~PEER_EVENT,	"sys_peer",		0 },
147330141Sdelphij	{ PEVNT_CLOCK & ~PEER_EVENT,	"clock_event",		0 },
148330141Sdelphij	{ PEVNT_AUTH & ~PEER_EVENT,	"bad_auth",		0 },
149330141Sdelphij	{ PEVNT_POPCORN & ~PEER_EVENT,	"popcorn",		0 },
150330141Sdelphij	{ PEVNT_XLEAVE & ~PEER_EVENT,	"interleave_mode",	0 },
151330141Sdelphij	{ PEVNT_XERR & ~PEER_EVENT,	"interleave_error",	0 },
152330141Sdelphij	{ -1,				"",			0 }
153285612Sdelphij};
154285612Sdelphij
155285612Sdelphij/*
156285612Sdelphij * Peer status bits
157285612Sdelphij */
158285612Sdelphijstatic const struct codestring peer_st_bits[] = {
159330141Sdelphij	{ CTL_PST_CONFIG,		"conf",		0 },
160330141Sdelphij	{ CTL_PST_AUTHENABLE,		"authenb",	0 },
161330141Sdelphij	{ CTL_PST_AUTHENTIC,		"auth",		0 },
162330141Sdelphij	{ CTL_PST_REACH,		"reach",	0 },
163330141Sdelphij	{ CTL_PST_BCAST,		"bcast",	0 },
164285612Sdelphij	/* not used with getcode(), no terminating entry needed */
165285612Sdelphij};
166285612Sdelphij
167285612Sdelphij/*
168285612Sdelphij * Restriction match bits
169285612Sdelphij */
170285612Sdelphijstatic const struct codestring res_match_bits[] = {
171330141Sdelphij	{ RESM_NTPONLY,			"ntpport",	0 },
172330141Sdelphij	{ RESM_INTERFACE,		"interface",	0 },
173330141Sdelphij	{ RESM_SOURCE,			"source",	0 },
174285612Sdelphij	/* not used with getcode(), no terminating entry needed */
175285612Sdelphij};
176285612Sdelphij
177285612Sdelphij/*
178285612Sdelphij * Restriction access bits
179285612Sdelphij */
180285612Sdelphijstatic const struct codestring res_access_bits[] = {
181330141Sdelphij	{ RES_IGNORE,			"ignore",	0 },
182330141Sdelphij	{ RES_DONTSERVE,		"noserve",	"serve" },
183330141Sdelphij	{ RES_DONTTRUST,		"notrust",	"trust" },
184330141Sdelphij	{ RES_NOQUERY,			"noquery",	"query" },
185330141Sdelphij	{ RES_NOMODIFY,			"nomodify",	0 },
186330141Sdelphij	{ RES_NOPEER,			"nopeer",	"peer" },
187330141Sdelphij	{ RES_NOEPEER,			"noepeer",	"epeer" },
188330141Sdelphij	{ RES_NOTRAP,			"notrap",	"trap" },
189330141Sdelphij	{ RES_LPTRAP,			"lptrap",	0 },
190330141Sdelphij	{ RES_LIMITED,			"limited",	0 },
191330141Sdelphij	{ RES_VERSION,			"version",	0 },
192330141Sdelphij	{ RES_KOD,			"kod",		0 },
193330141Sdelphij	{ RES_FLAKE,			"flake",	0 },
194285612Sdelphij	/* not used with getcode(), no terminating entry needed */
195285612Sdelphij};
196285612Sdelphij
197285612Sdelphij#ifdef AUTOKEY
198285612Sdelphij/*
199285612Sdelphij * Crypto events (cryp)
200285612Sdelphij */
201285612Sdelphijstatic const struct codestring crypto_codes[] = {
202330141Sdelphij	{ XEVNT_OK & ~CRPT_EVENT,	"success",			0 },
203330141Sdelphij	{ XEVNT_LEN & ~CRPT_EVENT,	"bad_field_format_or_length",	0 },
204330141Sdelphij	{ XEVNT_TSP & ~CRPT_EVENT,	"bad_timestamp",		0 },
205330141Sdelphij	{ XEVNT_FSP & ~CRPT_EVENT,	"bad_filestamp",		0 },
206330141Sdelphij	{ XEVNT_PUB & ~CRPT_EVENT,	"bad_or_missing_public_key",	0 },
207330141Sdelphij	{ XEVNT_MD & ~CRPT_EVENT,	"unsupported_digest_type",	0 },
208330141Sdelphij	{ XEVNT_KEY & ~CRPT_EVENT,	"unsupported_identity_type",	0 },
209330141Sdelphij	{ XEVNT_SGL & ~CRPT_EVENT,	"bad_signature_length",		0 },
210330141Sdelphij	{ XEVNT_SIG & ~CRPT_EVENT,	"signature_not_verified",	0 },
211330141Sdelphij	{ XEVNT_VFY & ~CRPT_EVENT,	"certificate_not_verified",	0 },
212330141Sdelphij	{ XEVNT_PER & ~CRPT_EVENT,	"host_certificate_expired",	0 },
213330141Sdelphij	{ XEVNT_CKY & ~CRPT_EVENT,	"bad_or_missing_cookie",	0 },
214330141Sdelphij	{ XEVNT_DAT & ~CRPT_EVENT,	"bad_or_missing_leapseconds",	0 },
215330141Sdelphij	{ XEVNT_CRT & ~CRPT_EVENT,	"bad_or_missing_certificate",	0 },
216330141Sdelphij	{ XEVNT_ID & ~CRPT_EVENT,	"bad_or_missing_group key",	0 },
217330141Sdelphij	{ XEVNT_ERR & ~CRPT_EVENT,	"protocol_error",		0 },
218330141Sdelphij	{ -1,				"",				0 }
219132451Sroberto};
220285612Sdelphij#endif	/* AUTOKEY */
221132451Sroberto
222285612Sdelphij#ifdef KERNEL_PLL
223285612Sdelphij/*
224285612Sdelphij * kernel discipline status bits
225285612Sdelphij */
226285612Sdelphijstatic const struct codestring k_st_bits[] = {
227285612Sdelphij# ifdef STA_PLL
228330141Sdelphij	{ STA_PLL,			"pll",		0 },
229285612Sdelphij# endif
230285612Sdelphij# ifdef STA_PPSFREQ
231330141Sdelphij	{ STA_PPSFREQ,			"ppsfreq",	0 },
232285612Sdelphij# endif
233285612Sdelphij# ifdef STA_PPSTIME
234330141Sdelphij	{ STA_PPSTIME,			"ppstime",	0 },
235285612Sdelphij# endif
236285612Sdelphij# ifdef STA_FLL
237330141Sdelphij	{ STA_FLL,			"fll",		0 },
238285612Sdelphij# endif
239285612Sdelphij# ifdef STA_INS
240330141Sdelphij	{ STA_INS,			"ins",		0 },
241285612Sdelphij# endif
242285612Sdelphij# ifdef STA_DEL
243330141Sdelphij	{ STA_DEL,			"del",		0 },
244285612Sdelphij# endif
245285612Sdelphij# ifdef STA_UNSYNC
246330141Sdelphij	{ STA_UNSYNC,			"unsync",	0 },
247285612Sdelphij# endif
248285612Sdelphij# ifdef STA_FREQHOLD
249330141Sdelphij	{ STA_FREQHOLD,			"freqhold",	0 },
250285612Sdelphij# endif
251285612Sdelphij# ifdef STA_PPSSIGNAL
252330141Sdelphij	{ STA_PPSSIGNAL,		"ppssignal",	0 },
253285612Sdelphij# endif
254285612Sdelphij# ifdef STA_PPSJITTER
255330141Sdelphij	{ STA_PPSJITTER,		"ppsjitter",	0 },
256285612Sdelphij# endif
257285612Sdelphij# ifdef STA_PPSWANDER
258330141Sdelphij	{ STA_PPSWANDER,		"ppswander",	0 },
259285612Sdelphij# endif
260285612Sdelphij# ifdef STA_PPSERROR
261330141Sdelphij	{ STA_PPSERROR,			"ppserror",	0 },
262285612Sdelphij# endif
263285612Sdelphij# ifdef STA_CLOCKERR
264330141Sdelphij	{ STA_CLOCKERR,			"clockerr",	0 },
265285612Sdelphij# endif
266285612Sdelphij# ifdef STA_NANO
267330141Sdelphij	{ STA_NANO,			"nano",		0 },
268285612Sdelphij# endif
269285612Sdelphij# ifdef STA_MODE
270330141Sdelphij	{ STA_MODE,			"mode=fll",	0 },
271285612Sdelphij# endif
272285612Sdelphij# ifdef STA_CLK
273330141Sdelphij	{ STA_CLK,			"src=B",	0 },
274285612Sdelphij# endif
275285612Sdelphij	/* not used with getcode(), no terminating entry needed */
276285612Sdelphij};
277285612Sdelphij#endif	/* KERNEL_PLL */
278285612Sdelphij
27954359Sroberto/* Forwards */
280285612Sdelphijstatic const char *	getcode(int, const struct codestring *);
281285612Sdelphijstatic const char *	getevents(int);
282285612Sdelphijstatic const char *	peer_st_flags(u_char pst);
28354359Sroberto
28454359Sroberto/*
28554359Sroberto * getcode - return string corresponding to code
28654359Sroberto */
28754359Srobertostatic const char *
28854359Srobertogetcode(
289285612Sdelphij	int				code,
290285612Sdelphij	const struct codestring *	codetab
29154359Sroberto	)
29254359Sroberto{
293285612Sdelphij	char *	buf;
29454359Sroberto
29554359Sroberto	while (codetab->code != -1) {
29654359Sroberto		if (codetab->code == code)
297330141Sdelphij			return codetab->string1;
29854359Sroberto		codetab++;
29954359Sroberto	}
300285612Sdelphij
301285612Sdelphij	LIB_GETBUF(buf);
302330141Sdelphij	snprintf(buf, LIB_BUFLENGTH, "%s_%d", codetab->string1, code);
303285612Sdelphij
30454359Sroberto	return buf;
30554359Sroberto}
30654359Sroberto
30754359Sroberto/*
30854359Sroberto * getevents - return a descriptive string for the event count
30954359Sroberto */
31054359Srobertostatic const char *
31154359Srobertogetevents(
31254359Sroberto	int cnt
31354359Sroberto	)
31454359Sroberto{
315285612Sdelphij	char *	buf;
31654359Sroberto
31754359Sroberto	if (cnt == 0)
318285612Sdelphij		return "no events";
319285612Sdelphij
320285612Sdelphij	LIB_GETBUF(buf);
321285612Sdelphij	snprintf(buf, LIB_BUFLENGTH, "%d event%s", cnt,
322285612Sdelphij		 (1 == cnt)
323285612Sdelphij		     ? ""
324285612Sdelphij		     : "s");
325285612Sdelphij
32654359Sroberto	return buf;
32754359Sroberto}
32854359Sroberto
329285612Sdelphij
33054359Sroberto/*
331285612Sdelphij * decode_bitflags()
332285612Sdelphij *
333285612Sdelphij * returns a human-readable string with a keyword from tab for each bit
334285612Sdelphij * set in bits, separating multiple entries with text of sep2.
335285612Sdelphij */
336285612Sdelphijstatic const char *
337285612Sdelphijdecode_bitflags(
338285612Sdelphij	int				bits,
339285612Sdelphij	const char *			sep2,
340285612Sdelphij	const struct codestring *	tab,
341285612Sdelphij	size_t				tab_ct
342285612Sdelphij	)
343285612Sdelphij{
344285612Sdelphij	const char *	sep;
345285612Sdelphij	char *		buf;
346285612Sdelphij	char *		pch;
347285612Sdelphij	char *		lim;
348285612Sdelphij	size_t		b;
349285612Sdelphij	int		rc;
350285612Sdelphij	int		saved_errno;	/* for use in DPRINTF with %m */
351285612Sdelphij
352285612Sdelphij	saved_errno = errno;
353285612Sdelphij	LIB_GETBUF(buf);
354285612Sdelphij	pch = buf;
355285612Sdelphij	lim = buf + LIB_BUFLENGTH;
356285612Sdelphij	sep = "";
357285612Sdelphij
358285612Sdelphij	for (b = 0; b < tab_ct; b++) {
359330141Sdelphij		const char * flagstr;
360330141Sdelphij
361285612Sdelphij		if (tab[b].code & bits) {
362330141Sdelphij			flagstr = tab[b].string1;
363330141Sdelphij		} else {
364330141Sdelphij			flagstr = tab[b].string0;
365330141Sdelphij		}
366330141Sdelphij
367330141Sdelphij		if (flagstr) {
368316069Sdelphij			size_t avail = lim - pch;
369316069Sdelphij			rc = snprintf(pch, avail, "%s%s", sep,
370330141Sdelphij				      flagstr);
371316069Sdelphij			if ((size_t)rc >= avail)
372285612Sdelphij				goto toosmall;
373316069Sdelphij			pch += rc;
374285612Sdelphij			sep = sep2;
375285612Sdelphij		}
376285612Sdelphij	}
377285612Sdelphij
378285612Sdelphij	return buf;
379285612Sdelphij
380285612Sdelphij    toosmall:
381285612Sdelphij	snprintf(buf, LIB_BUFLENGTH,
382285612Sdelphij		 "decode_bitflags(%s) can't decode 0x%x in %d bytes",
383285612Sdelphij		 (tab == peer_st_bits)
384285612Sdelphij		     ? "peer_st"
385285612Sdelphij		     :
386285612Sdelphij#ifdef KERNEL_PLL
387285612Sdelphij		       (tab == k_st_bits)
388285612Sdelphij			   ? "kern_st"
389285612Sdelphij			   :
390285612Sdelphij#endif
391285612Sdelphij			     "",
392285612Sdelphij		 bits, (int)LIB_BUFLENGTH);
393285612Sdelphij	errno = saved_errno;
394285612Sdelphij
395285612Sdelphij	return buf;
396285612Sdelphij}
397285612Sdelphij
398285612Sdelphij
399285612Sdelphijstatic const char *
400285612Sdelphijpeer_st_flags(
401285612Sdelphij	u_char pst
402285612Sdelphij	)
403285612Sdelphij{
404285612Sdelphij	return decode_bitflags(pst, ", ", peer_st_bits,
405285612Sdelphij			       COUNTOF(peer_st_bits));
406285612Sdelphij}
407285612Sdelphij
408285612Sdelphij
409285612Sdelphijconst char *
410285612Sdelphijres_match_flags(
411285612Sdelphij	u_short mf
412285612Sdelphij	)
413285612Sdelphij{
414285612Sdelphij	return decode_bitflags(mf, " ", res_match_bits,
415285612Sdelphij			       COUNTOF(res_match_bits));
416285612Sdelphij}
417285612Sdelphij
418285612Sdelphij
419285612Sdelphijconst char *
420285612Sdelphijres_access_flags(
421285612Sdelphij	u_short af
422285612Sdelphij	)
423285612Sdelphij{
424285612Sdelphij	return decode_bitflags(af, " ", res_access_bits,
425285612Sdelphij			       COUNTOF(res_access_bits));
426285612Sdelphij}
427285612Sdelphij
428285612Sdelphij
429285612Sdelphij#ifdef KERNEL_PLL
430285612Sdelphijconst char *
431285612Sdelphijk_st_flags(
432285612Sdelphij	u_int32 st
433285612Sdelphij	)
434285612Sdelphij{
435285612Sdelphij	return decode_bitflags(st, " ", k_st_bits, COUNTOF(k_st_bits));
436285612Sdelphij}
437285612Sdelphij#endif	/* KERNEL_PLL */
438285612Sdelphij
439285612Sdelphij
440285612Sdelphij/*
44154359Sroberto * statustoa - return a descriptive string for a peer status
44254359Sroberto */
44354359Srobertochar *
44454359Srobertostatustoa(
44554359Sroberto	int type,
44654359Sroberto	int st
44754359Sroberto	)
44854359Sroberto{
449285612Sdelphij	char *	cb;
450285612Sdelphij	char *	cc;
451285612Sdelphij	u_char	pst;
45254359Sroberto
45354359Sroberto	LIB_GETBUF(cb);
45454359Sroberto
45554359Sroberto	switch (type) {
456285612Sdelphij
457285612Sdelphij	case TYPE_SYS:
458285612Sdelphij		snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s, %s",
459285612Sdelphij			 getcode(CTL_SYS_LI(st), leap_codes),
460285612Sdelphij			 getcode(CTL_SYS_SOURCE(st), sync_codes),
461285612Sdelphij			 getevents(CTL_SYS_NEVNT(st)),
462285612Sdelphij			 getcode(CTL_SYS_EVENT(st), sys_codes));
46354359Sroberto		break;
46454359Sroberto
465285612Sdelphij	case TYPE_PEER:
466285612Sdelphij		pst = (u_char)CTL_PEER_STATVAL(st);
467285612Sdelphij		snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s",
468285612Sdelphij			 peer_st_flags(pst),
469285612Sdelphij			 getcode(pst & 0x7, select_codes),
470285612Sdelphij			 getevents(CTL_PEER_NEVNT(st)));
47154359Sroberto		if (CTL_PEER_EVENT(st) != EVNT_UNSPEC) {
472285612Sdelphij			cc = cb + strlen(cb);
473285612Sdelphij			snprintf(cc, LIB_BUFLENGTH - (cc - cb), ", %s",
474285612Sdelphij				 getcode(CTL_PEER_EVENT(st),
475285612Sdelphij					 peer_codes));
47654359Sroberto		}
47754359Sroberto		break;
47854359Sroberto
479285612Sdelphij	case TYPE_CLOCK:
480285612Sdelphij		snprintf(cb, LIB_BUFLENGTH, "%s, %s",
481285612Sdelphij			 getevents(CTL_SYS_NEVNT(st)),
482285612Sdelphij			 getcode((st) & 0xf, clock_codes));
48354359Sroberto		break;
48454359Sroberto	}
485285612Sdelphij
48654359Sroberto	return cb;
48754359Sroberto}
48854359Sroberto
48954359Srobertoconst char *
49054359Srobertoeventstr(
49154359Sroberto	int num
49254359Sroberto	)
49354359Sroberto{
494132451Sroberto	if (num & PEER_EVENT)
495132451Sroberto		return (getcode(num & ~PEER_EVENT, peer_codes));
496285612Sdelphij#ifdef AUTOKEY
497132451Sroberto	else if (num & CRPT_EVENT)
498132451Sroberto		return (getcode(num & ~CRPT_EVENT, crypto_codes));
499285612Sdelphij#endif	/* AUTOKEY */
500132451Sroberto	else
501132451Sroberto		return (getcode(num, sys_codes));
50254359Sroberto}
50354359Sroberto
50454359Srobertoconst char *
50554359Srobertoceventstr(
50654359Sroberto	int num
50754359Sroberto	)
50854359Sroberto{
50954359Sroberto	return getcode(num, clock_codes);
51054359Sroberto}
511