xref: /netbsd-src/external/bsd/ntp/dist/libntp/statestr.c (revision eabc0478de71e4e011a5b4e0392741e01d491794)
1*eabc0478Schristos /*	$NetBSD: statestr.c,v 1.9 2024/08/18 20:47:13 christos Exp $	*/
2abb0f93cSkardel 
3abb0f93cSkardel /*
4abb0f93cSkardel  * pretty printing of status information
5abb0f93cSkardel  */
6abb0f93cSkardel #ifdef HAVE_CONFIG_H
7abb0f93cSkardel #include <config.h>
8abb0f93cSkardel #endif
9abb0f93cSkardel #include <stdio.h>
10abb0f93cSkardel #include "ntp_stdlib.h"
11abb0f93cSkardel #include "ntp_fp.h"
12abb0f93cSkardel #include "ntp.h"
13abb0f93cSkardel #include "ntp_refclock.h"
14abb0f93cSkardel #include "ntp_control.h"
15abb0f93cSkardel #include "ntp_string.h"
168585484eSchristos #ifdef KERNEL_PLL
178585484eSchristos # include "ntp_syscall.h"
188585484eSchristos #endif
198585484eSchristos 
20abb0f93cSkardel 
21abb0f93cSkardel /*
22abb0f93cSkardel  * Structure for turning various constants into a readable string.
23abb0f93cSkardel  */
24abb0f93cSkardel struct codestring {
25abb0f93cSkardel 	int code;
264eea345dSchristos 	const char * const string1;
274eea345dSchristos 	const char * const string0;
28abb0f93cSkardel };
29abb0f93cSkardel 
30abb0f93cSkardel /*
31abb0f93cSkardel  * Leap status (leap)
32abb0f93cSkardel  */
338585484eSchristos static const struct codestring leap_codes[] = {
344eea345dSchristos 	{ LEAP_NOWARNING,	"leap_none",	0 },
354eea345dSchristos 	{ LEAP_ADDSECOND,	"leap_add_sec",	0 },
364eea345dSchristos 	{ LEAP_DELSECOND,	"leap_del_sec",	0 },
374eea345dSchristos 	{ LEAP_NOTINSYNC,	"leap_alarm",	0 },
384eea345dSchristos 	{ -1,			"leap",		0 }
39abb0f93cSkardel };
40abb0f93cSkardel 
41abb0f93cSkardel /*
42abb0f93cSkardel  * Clock source status (sync)
43abb0f93cSkardel  */
448585484eSchristos static const struct codestring sync_codes[] = {
454eea345dSchristos 	{ CTL_SST_TS_UNSPEC,	"sync_unspec",		0 },
464eea345dSchristos 	{ CTL_SST_TS_ATOM,	"sync_pps",		0 },
474eea345dSchristos 	{ CTL_SST_TS_LF,	"sync_lf_radio",	0 },
484eea345dSchristos 	{ CTL_SST_TS_HF,	"sync_hf_radio",	0 },
494eea345dSchristos 	{ CTL_SST_TS_UHF,	"sync_uhf_radio",	0 },
504eea345dSchristos 	{ CTL_SST_TS_LOCAL,	"sync_local",		0 },
514eea345dSchristos 	{ CTL_SST_TS_NTP,	"sync_ntp",		0 },
524eea345dSchristos 	{ CTL_SST_TS_UDPTIME,	"sync_other",		0 },
534eea345dSchristos 	{ CTL_SST_TS_WRSTWTCH,	"sync_wristwatch",	0 },
544eea345dSchristos 	{ CTL_SST_TS_TELEPHONE,	"sync_telephone",	0 },
554eea345dSchristos 	{ -1,			"sync",			0 }
56abb0f93cSkardel };
57abb0f93cSkardel 
58abb0f93cSkardel /*
59abb0f93cSkardel  * Peer selection status (sel)
60abb0f93cSkardel  */
618585484eSchristos static const struct codestring select_codes[] = {
624eea345dSchristos 	{ CTL_PST_SEL_REJECT,	"sel_reject",		0 },
634eea345dSchristos 	{ CTL_PST_SEL_SANE,	"sel_falsetick",	0 },
644eea345dSchristos 	{ CTL_PST_SEL_CORRECT,	"sel_excess",		0 },
654eea345dSchristos 	{ CTL_PST_SEL_SELCAND,	"sel_outlier",		0 },
664eea345dSchristos 	{ CTL_PST_SEL_SYNCCAND,	"sel_candidate",	0 },
674eea345dSchristos 	{ CTL_PST_SEL_EXCESS,	"sel_backup",		0 },
684eea345dSchristos 	{ CTL_PST_SEL_SYSPEER,	"sel_sys.peer",		0 },
694eea345dSchristos 	{ CTL_PST_SEL_PPS,	"sel_pps.peer",		0 },
704eea345dSchristos 	{ -1,			"sel",			0 }
71abb0f93cSkardel };
72abb0f93cSkardel 
73abb0f93cSkardel /*
74abb0f93cSkardel  * Clock status (clk)
75abb0f93cSkardel  */
768585484eSchristos static const struct codestring clock_codes[] = {
774eea345dSchristos 	{ CTL_CLK_OKAY,		"clk_unspec",		0 },
784eea345dSchristos 	{ CTL_CLK_NOREPLY,	"clk_no_reply",		0 },
794eea345dSchristos 	{ CTL_CLK_BADFORMAT,	"clk_bad_format",	0 },
804eea345dSchristos 	{ CTL_CLK_FAULT,	"clk_fault",		0 },
814eea345dSchristos 	{ CTL_CLK_PROPAGATION,	"clk_bad_signal",	0 },
824eea345dSchristos 	{ CTL_CLK_BADDATE,	"clk_bad_date",		0 },
834eea345dSchristos 	{ CTL_CLK_BADTIME,	"clk_bad_time",		0 },
844eea345dSchristos 	{ -1,			"clk",			0 }
85abb0f93cSkardel };
86abb0f93cSkardel 
87abb0f93cSkardel 
88abb0f93cSkardel #ifdef FLASH_CODES_UNUSED
89abb0f93cSkardel /*
90abb0f93cSkardel  * Flash bits -- see ntpq.c tstflags & tstflagnames
91abb0f93cSkardel  */
928585484eSchristos static const struct codestring flash_codes[] = {
934eea345dSchristos 	{ TEST1,		"pkt_dup",	0 },
944eea345dSchristos 	{ TEST2,		"pkt_bogus",	0 },
954eea345dSchristos 	{ TEST3,		"pkt_unsync",	0 },
964eea345dSchristos 	{ TEST4,		"pkt_denied",	0 },
974eea345dSchristos 	{ TEST5,		"pkt_auth",	0 },
984eea345dSchristos 	{ TEST6,		"pkt_stratum",	0 },
994eea345dSchristos 	{ TEST7,		"pkt_header",	0 },
1004eea345dSchristos 	{ TEST8,		"pkt_autokey",	0 },
1014eea345dSchristos 	{ TEST9,		"pkt_crypto",	0 },
1024eea345dSchristos 	{ TEST10,		"peer_stratum",	0 },
1034eea345dSchristos 	{ TEST11,		"peer_dist",	0 },
1044eea345dSchristos 	{ TEST12,		"peer_loop",	0 },
1054eea345dSchristos 	{ TEST13,		"peer_unreach",	0 },
1064eea345dSchristos 	{ -1,			"flash",	0 }
107abb0f93cSkardel };
108abb0f93cSkardel #endif
109abb0f93cSkardel 
110abb0f93cSkardel 
111abb0f93cSkardel /*
112abb0f93cSkardel  * System events (sys)
113abb0f93cSkardel  */
1148585484eSchristos static const struct codestring sys_codes[] = {
1154eea345dSchristos 	{ EVNT_UNSPEC,		"unspecified",			0 },
1164eea345dSchristos 	{ EVNT_NSET,		"freq_not_set",			0 },
1174eea345dSchristos 	{ EVNT_FSET,		"freq_set",			0 },
1184eea345dSchristos 	{ EVNT_SPIK,		"spike_detect",			0 },
1194eea345dSchristos 	{ EVNT_FREQ,		"freq_mode",			0 },
1204eea345dSchristos 	{ EVNT_SYNC,		"clock_sync",			0 },
1214eea345dSchristos 	{ EVNT_SYSRESTART,	"restart",			0 },
1224eea345dSchristos 	{ EVNT_SYSFAULT,	"panic_stop",			0 },
1234eea345dSchristos 	{ EVNT_NOPEER,		"no_sys_peer",			0 },
1244eea345dSchristos 	{ EVNT_ARMED,		"leap_armed",			0 },
1254eea345dSchristos 	{ EVNT_DISARMED,	"leap_disarmed",		0 },
1264eea345dSchristos 	{ EVNT_LEAP,		"leap_event",			0 },
1274eea345dSchristos 	{ EVNT_CLOCKRESET,	"clock_step",			0 },
1284eea345dSchristos 	{ EVNT_KERN,		"kern",				0 },
1294eea345dSchristos 	{ EVNT_TAI,		"TAI",				0 },
1304eea345dSchristos 	{ EVNT_LEAPVAL,		"stale_leapsecond_values",	0 },
1314eea345dSchristos 	{ -1,			"",				0 }
132abb0f93cSkardel };
133abb0f93cSkardel 
134abb0f93cSkardel /*
135abb0f93cSkardel  * Peer events (peer)
136abb0f93cSkardel  */
1378585484eSchristos static const struct codestring peer_codes[] = {
1384eea345dSchristos 	{ PEVNT_MOBIL & ~PEER_EVENT,	"mobilize",		0 },
1394eea345dSchristos 	{ PEVNT_DEMOBIL & ~PEER_EVENT,	"demobilize",		0 },
1404eea345dSchristos 	{ PEVNT_UNREACH & ~PEER_EVENT,	"unreachable",		0 },
1414eea345dSchristos 	{ PEVNT_REACH & ~PEER_EVENT,	"reachable",		0 },
1424eea345dSchristos 	{ PEVNT_RESTART & ~PEER_EVENT,	"restart",		0 },
1434eea345dSchristos 	{ PEVNT_REPLY & ~PEER_EVENT,	"no_reply",		0 },
1444eea345dSchristos 	{ PEVNT_RATE & ~PEER_EVENT,	"rate_exceeded",	0 },
1454eea345dSchristos 	{ PEVNT_DENY & ~PEER_EVENT,	"access_denied",	0 },
1464eea345dSchristos 	{ PEVNT_ARMED & ~PEER_EVENT,	"leap_armed",		0 },
1474eea345dSchristos 	{ PEVNT_NEWPEER & ~PEER_EVENT,	"sys_peer",		0 },
1484eea345dSchristos 	{ PEVNT_CLOCK & ~PEER_EVENT,	"clock_event",		0 },
1494eea345dSchristos 	{ PEVNT_AUTH & ~PEER_EVENT,	"bad_auth",		0 },
1504eea345dSchristos 	{ PEVNT_POPCORN & ~PEER_EVENT,	"popcorn",		0 },
1514eea345dSchristos 	{ PEVNT_XLEAVE & ~PEER_EVENT,	"interleave_mode",	0 },
1524eea345dSchristos 	{ PEVNT_XERR & ~PEER_EVENT,	"interleave_error",	0 },
1534eea345dSchristos 	{ -1,				"",			0 }
154abb0f93cSkardel };
155abb0f93cSkardel 
1568585484eSchristos /*
1578585484eSchristos  * Peer status bits
1588585484eSchristos  */
1598585484eSchristos static const struct codestring peer_st_bits[] = {
1604eea345dSchristos 	{ CTL_PST_CONFIG,		"conf",		0 },
1614eea345dSchristos 	{ CTL_PST_AUTHENABLE,		"authenb",	0 },
1624eea345dSchristos 	{ CTL_PST_AUTHENTIC,		"auth",		0 },
1634eea345dSchristos 	{ CTL_PST_REACH,		"reach",	0 },
1644eea345dSchristos 	{ CTL_PST_BCAST,		"bcast",	0 },
1658585484eSchristos 	/* not used with getcode(), no terminating entry needed */
1668585484eSchristos };
1678585484eSchristos 
1688585484eSchristos /*
1698585484eSchristos  * Restriction match bits
1708585484eSchristos  */
1718585484eSchristos static const struct codestring res_match_bits[] = {
1724eea345dSchristos 	{ RESM_NTPONLY,			"ntpport",	0 },
1734eea345dSchristos 	{ RESM_INTERFACE,		"interface",	0 },
1744eea345dSchristos 	{ RESM_SOURCE,			"source",	0 },
1758585484eSchristos 	/* not used with getcode(), no terminating entry needed */
1768585484eSchristos };
1778585484eSchristos 
1788585484eSchristos /*
1798585484eSchristos  * Restriction access bits
1808585484eSchristos  */
1818585484eSchristos static const struct codestring res_access_bits[] = {
1824eea345dSchristos 	{ RES_IGNORE,			"ignore",	0 },
1834eea345dSchristos 	{ RES_DONTSERVE,		"noserve",	"serve" },
1844eea345dSchristos 	{ RES_DONTTRUST,		"notrust",	"trust" },
185cdfa2a7eSchristos 	{ RES_VERSION,			"version",	0 },
1864eea345dSchristos 	{ RES_NOPEER,			"nopeer",	"peer" },
1874eea345dSchristos 	{ RES_NOEPEER,			"noepeer",	"epeer" },
188cdfa2a7eSchristos 	{ RES_LIMITED,			"limited",	0 },
189cdfa2a7eSchristos 
190cdfa2a7eSchristos 	{ RES_NOQUERY,			"noquery",	"query" },
191cdfa2a7eSchristos 	{ RES_NOMODIFY,			"nomodify",	0 },
1924eea345dSchristos 	{ RES_NOTRAP,			"notrap",	"trap" },
1934eea345dSchristos 	{ RES_LPTRAP,			"lptrap",	0 },
194cdfa2a7eSchristos 
1954eea345dSchristos 	{ RES_KOD,			"kod",		0 },
196cdfa2a7eSchristos 	{ RES_MSSNTP,			"mssntp",	0 },
1974eea345dSchristos 	{ RES_FLAKE,			"flake",	0 },
198cdfa2a7eSchristos 	{ RES_NOMRULIST,		"nomrulist",	0 },
199cdfa2a7eSchristos 
200cdfa2a7eSchristos 	{ RES_SRVRSPFUZ,		"serverresponse fuzz",	0 },
201cdfa2a7eSchristos 
2028585484eSchristos 	/* not used with getcode(), no terminating entry needed */
2038585484eSchristos };
2048585484eSchristos 
2058585484eSchristos #ifdef AUTOKEY
206abb0f93cSkardel /*
207abb0f93cSkardel  * Crypto events (cryp)
208abb0f93cSkardel  */
2098585484eSchristos static const struct codestring crypto_codes[] = {
2104eea345dSchristos 	{ XEVNT_OK & ~CRPT_EVENT,	"success",			0 },
2114eea345dSchristos 	{ XEVNT_LEN & ~CRPT_EVENT,	"bad_field_format_or_length",	0 },
2124eea345dSchristos 	{ XEVNT_TSP & ~CRPT_EVENT,	"bad_timestamp",		0 },
2134eea345dSchristos 	{ XEVNT_FSP & ~CRPT_EVENT,	"bad_filestamp",		0 },
2144eea345dSchristos 	{ XEVNT_PUB & ~CRPT_EVENT,	"bad_or_missing_public_key",	0 },
2154eea345dSchristos 	{ XEVNT_MD & ~CRPT_EVENT,	"unsupported_digest_type",	0 },
2164eea345dSchristos 	{ XEVNT_KEY & ~CRPT_EVENT,	"unsupported_identity_type",	0 },
2174eea345dSchristos 	{ XEVNT_SGL & ~CRPT_EVENT,	"bad_signature_length",		0 },
2184eea345dSchristos 	{ XEVNT_SIG & ~CRPT_EVENT,	"signature_not_verified",	0 },
2194eea345dSchristos 	{ XEVNT_VFY & ~CRPT_EVENT,	"certificate_not_verified",	0 },
2204eea345dSchristos 	{ XEVNT_PER & ~CRPT_EVENT,	"host_certificate_expired",	0 },
2214eea345dSchristos 	{ XEVNT_CKY & ~CRPT_EVENT,	"bad_or_missing_cookie",	0 },
2224eea345dSchristos 	{ XEVNT_DAT & ~CRPT_EVENT,	"bad_or_missing_leapseconds",	0 },
2234eea345dSchristos 	{ XEVNT_CRT & ~CRPT_EVENT,	"bad_or_missing_certificate",	0 },
2244eea345dSchristos 	{ XEVNT_ID & ~CRPT_EVENT,	"bad_or_missing_group key",	0 },
2254eea345dSchristos 	{ XEVNT_ERR & ~CRPT_EVENT,	"protocol_error",		0 },
2264eea345dSchristos 	{ -1,				"",				0 }
227abb0f93cSkardel };
2288585484eSchristos #endif	/* AUTOKEY */
2298585484eSchristos 
2308585484eSchristos #ifdef KERNEL_PLL
2318585484eSchristos /*
2328585484eSchristos  * kernel discipline status bits
2338585484eSchristos  */
2348585484eSchristos static const struct codestring k_st_bits[] = {
2358585484eSchristos # ifdef STA_PLL
2364eea345dSchristos 	{ STA_PLL,			"pll",		0 },
2378585484eSchristos # endif
2388585484eSchristos # ifdef STA_PPSFREQ
2394eea345dSchristos 	{ STA_PPSFREQ,			"ppsfreq",	0 },
2408585484eSchristos # endif
2418585484eSchristos # ifdef STA_PPSTIME
2424eea345dSchristos 	{ STA_PPSTIME,			"ppstime",	0 },
2438585484eSchristos # endif
2448585484eSchristos # ifdef STA_FLL
2454eea345dSchristos 	{ STA_FLL,			"fll",		0 },
2468585484eSchristos # endif
2478585484eSchristos # ifdef STA_INS
2484eea345dSchristos 	{ STA_INS,			"ins",		0 },
2498585484eSchristos # endif
2508585484eSchristos # ifdef STA_DEL
2514eea345dSchristos 	{ STA_DEL,			"del",		0 },
2528585484eSchristos # endif
2538585484eSchristos # ifdef STA_UNSYNC
2544eea345dSchristos 	{ STA_UNSYNC,			"unsync",	0 },
2558585484eSchristos # endif
2568585484eSchristos # ifdef STA_FREQHOLD
2574eea345dSchristos 	{ STA_FREQHOLD,			"freqhold",	0 },
2588585484eSchristos # endif
2598585484eSchristos # ifdef STA_PPSSIGNAL
2604eea345dSchristos 	{ STA_PPSSIGNAL,		"ppssignal",	0 },
2618585484eSchristos # endif
2628585484eSchristos # ifdef STA_PPSJITTER
2634eea345dSchristos 	{ STA_PPSJITTER,		"ppsjitter",	0 },
2648585484eSchristos # endif
2658585484eSchristos # ifdef STA_PPSWANDER
2664eea345dSchristos 	{ STA_PPSWANDER,		"ppswander",	0 },
2678585484eSchristos # endif
2688585484eSchristos # ifdef STA_PPSERROR
2694eea345dSchristos 	{ STA_PPSERROR,			"ppserror",	0 },
2708585484eSchristos # endif
2718585484eSchristos # ifdef STA_CLOCKERR
2724eea345dSchristos 	{ STA_CLOCKERR,			"clockerr",	0 },
2738585484eSchristos # endif
2748585484eSchristos # ifdef STA_NANO
2754eea345dSchristos 	{ STA_NANO,			"nano",		0 },
2768585484eSchristos # endif
2778585484eSchristos # ifdef STA_MODE
2784eea345dSchristos 	{ STA_MODE,			"mode=fll",	0 },
2798585484eSchristos # endif
2808585484eSchristos # ifdef STA_CLK
2814eea345dSchristos 	{ STA_CLK,			"src=B",	0 },
2828585484eSchristos # endif
2838585484eSchristos 	/* not used with getcode(), no terminating entry needed */
2848585484eSchristos };
2858585484eSchristos #endif	/* KERNEL_PLL */
286abb0f93cSkardel 
287abb0f93cSkardel /* Forwards */
2888585484eSchristos static const char *	getcode(int, const struct codestring *);
289abb0f93cSkardel static const char *	getevents(int);
2908585484eSchristos static const char *	peer_st_flags(u_char pst);
291abb0f93cSkardel 
292abb0f93cSkardel /*
293abb0f93cSkardel  * getcode - return string corresponding to code
294abb0f93cSkardel  */
295abb0f93cSkardel static const char *
296abb0f93cSkardel getcode(
297abb0f93cSkardel 	int				code,
2988585484eSchristos 	const struct codestring *	codetab
299abb0f93cSkardel 	)
300abb0f93cSkardel {
3018585484eSchristos 	char *	buf;
302abb0f93cSkardel 
303abb0f93cSkardel 	while (codetab->code != -1) {
304abb0f93cSkardel 		if (codetab->code == code)
3054eea345dSchristos 			return codetab->string1;
306abb0f93cSkardel 		codetab++;
307abb0f93cSkardel 	}
3088585484eSchristos 
3098585484eSchristos 	LIB_GETBUF(buf);
3104eea345dSchristos 	snprintf(buf, LIB_BUFLENGTH, "%s_%d", codetab->string1, code);
3118585484eSchristos 
312abb0f93cSkardel 	return buf;
313abb0f93cSkardel }
314abb0f93cSkardel 
315abb0f93cSkardel /*
316abb0f93cSkardel  * getevents - return a descriptive string for the event count
317abb0f93cSkardel  */
318abb0f93cSkardel static const char *
319abb0f93cSkardel getevents(
320abb0f93cSkardel 	int cnt
321abb0f93cSkardel 	)
322abb0f93cSkardel {
3238585484eSchristos 	char *	buf;
324abb0f93cSkardel 
325abb0f93cSkardel 	if (cnt == 0)
326abb0f93cSkardel 		return "no events";
3278585484eSchristos 
3288585484eSchristos 	LIB_GETBUF(buf);
3298585484eSchristos 	snprintf(buf, LIB_BUFLENGTH, "%d event%s", cnt,
3308585484eSchristos 		 (1 == cnt)
3318585484eSchristos 		     ? ""
3328585484eSchristos 		     : "s");
3338585484eSchristos 
334abb0f93cSkardel 	return buf;
335abb0f93cSkardel }
336abb0f93cSkardel 
3378585484eSchristos 
3388585484eSchristos /*
3398585484eSchristos  * decode_bitflags()
3408585484eSchristos  *
3418585484eSchristos  * returns a human-readable string with a keyword from tab for each bit
3428585484eSchristos  * set in bits, separating multiple entries with text of sep2.
3438585484eSchristos  */
3448585484eSchristos static const char *
3458585484eSchristos decode_bitflags(
3468585484eSchristos 	int				bits,
3478585484eSchristos 	const char *			sep2,
3488585484eSchristos 	const struct codestring *	tab,
3498585484eSchristos 	size_t				tab_ct
3508585484eSchristos 	)
3518585484eSchristos {
3528585484eSchristos 	const char *	sep;
3538585484eSchristos 	char *		buf;
3548585484eSchristos 	char *		pch;
3558585484eSchristos 	char *		lim;
3568585484eSchristos 	size_t		b;
3578585484eSchristos 	int		rc;
3588585484eSchristos 	int		saved_errno;	/* for use in DPRINTF with %m */
3598585484eSchristos 
3608585484eSchristos 	saved_errno = errno;
3618585484eSchristos 	LIB_GETBUF(buf);
3628585484eSchristos 	pch = buf;
3638585484eSchristos 	lim = buf + LIB_BUFLENGTH;
3648585484eSchristos 	sep = "";
3658585484eSchristos 
3668585484eSchristos 	for (b = 0; b < tab_ct; b++) {
3674eea345dSchristos 		const char * flagstr;
3684eea345dSchristos 
3698585484eSchristos 		if (tab[b].code & bits) {
3704eea345dSchristos 			flagstr = tab[b].string1;
3714eea345dSchristos 		} else {
3724eea345dSchristos 			flagstr = tab[b].string0;
3734eea345dSchristos 		}
3744eea345dSchristos 
3754eea345dSchristos 		if (flagstr) {
376ccc794f0Schristos 			size_t avail = lim - pch;
377ccc794f0Schristos 			rc = snprintf(pch, avail, "%s%s", sep,
3784eea345dSchristos 				      flagstr);
379ccc794f0Schristos 			if ((size_t)rc >= avail)
3808585484eSchristos 				goto toosmall;
381ccc794f0Schristos 			pch += rc;
3828585484eSchristos 			sep = sep2;
3838585484eSchristos 		}
3848585484eSchristos 	}
3858585484eSchristos 
3868585484eSchristos 	return buf;
3878585484eSchristos 
3888585484eSchristos     toosmall:
3898585484eSchristos 	snprintf(buf, LIB_BUFLENGTH,
3908585484eSchristos 		 "decode_bitflags(%s) can't decode 0x%x in %d bytes",
3918585484eSchristos 		 (tab == peer_st_bits)
3928585484eSchristos 		     ? "peer_st"
3938585484eSchristos 		     :
3948585484eSchristos #ifdef KERNEL_PLL
3958585484eSchristos 		       (tab == k_st_bits)
3968585484eSchristos 			   ? "kern_st"
3978585484eSchristos 			   :
3988585484eSchristos #endif
3998585484eSchristos 			     "",
4008585484eSchristos 		 bits, (int)LIB_BUFLENGTH);
4018585484eSchristos 	errno = saved_errno;
4028585484eSchristos 
4038585484eSchristos 	return buf;
4048585484eSchristos }
4058585484eSchristos 
4068585484eSchristos 
4078585484eSchristos static const char *
4088585484eSchristos peer_st_flags(
4098585484eSchristos 	u_char pst
4108585484eSchristos 	)
4118585484eSchristos {
4128585484eSchristos 	return decode_bitflags(pst, ", ", peer_st_bits,
4138585484eSchristos 			       COUNTOF(peer_st_bits));
4148585484eSchristos }
4158585484eSchristos 
4168585484eSchristos 
4178585484eSchristos const char *
4188585484eSchristos res_match_flags(
4198585484eSchristos 	u_short mf
4208585484eSchristos 	)
4218585484eSchristos {
4228585484eSchristos 	return decode_bitflags(mf, " ", res_match_bits,
4238585484eSchristos 			       COUNTOF(res_match_bits));
4248585484eSchristos }
4258585484eSchristos 
4268585484eSchristos 
4278585484eSchristos const char *
4288585484eSchristos res_access_flags(
429cdfa2a7eSchristos 	u_int32 af
4308585484eSchristos 	)
4318585484eSchristos {
4328585484eSchristos 	return decode_bitflags(af, " ", res_access_bits,
4338585484eSchristos 			       COUNTOF(res_access_bits));
4348585484eSchristos }
4358585484eSchristos 
4368585484eSchristos 
4378585484eSchristos #ifdef KERNEL_PLL
4388585484eSchristos const char *
4398585484eSchristos k_st_flags(
4408585484eSchristos 	u_int32 st
4418585484eSchristos 	)
4428585484eSchristos {
4438585484eSchristos 	return decode_bitflags(st, " ", k_st_bits, COUNTOF(k_st_bits));
4448585484eSchristos }
4458585484eSchristos #endif	/* KERNEL_PLL */
4468585484eSchristos 
4478585484eSchristos 
448abb0f93cSkardel /*
449abb0f93cSkardel  * statustoa - return a descriptive string for a peer status
450abb0f93cSkardel  */
451abb0f93cSkardel char *
452abb0f93cSkardel statustoa(
453abb0f93cSkardel 	int type,
454abb0f93cSkardel 	int st
455abb0f93cSkardel 	)
456abb0f93cSkardel {
457abb0f93cSkardel 	char *	cb;
4588585484eSchristos 	char *	cc;
459abb0f93cSkardel 	u_char	pst;
460abb0f93cSkardel 
461abb0f93cSkardel 	LIB_GETBUF(cb);
462abb0f93cSkardel 
463abb0f93cSkardel 	switch (type) {
4648585484eSchristos 
465abb0f93cSkardel 	case TYPE_SYS:
4668585484eSchristos 		snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s, %s",
4678585484eSchristos 			 getcode(CTL_SYS_LI(st), leap_codes),
4688585484eSchristos 			 getcode(CTL_SYS_SOURCE(st), sync_codes),
4698585484eSchristos 			 getevents(CTL_SYS_NEVNT(st)),
4708585484eSchristos 			 getcode(CTL_SYS_EVENT(st), sys_codes));
471abb0f93cSkardel 		break;
472abb0f93cSkardel 
473abb0f93cSkardel 	case TYPE_PEER:
474abb0f93cSkardel 		pst = (u_char)CTL_PEER_STATVAL(st);
4758585484eSchristos 		snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s",
4768585484eSchristos 			 peer_st_flags(pst),
4778585484eSchristos 			 getcode(pst & 0x7, select_codes),
4788585484eSchristos 			 getevents(CTL_PEER_NEVNT(st)));
479abb0f93cSkardel 		if (CTL_PEER_EVENT(st) != EVNT_UNSPEC) {
4808585484eSchristos 			cc = cb + strlen(cb);
4818585484eSchristos 			snprintf(cc, LIB_BUFLENGTH - (cc - cb), ", %s",
4828585484eSchristos 				 getcode(CTL_PEER_EVENT(st),
483abb0f93cSkardel 					 peer_codes));
484abb0f93cSkardel 		}
485abb0f93cSkardel 		break;
486abb0f93cSkardel 
487abb0f93cSkardel 	case TYPE_CLOCK:
4888585484eSchristos 		snprintf(cb, LIB_BUFLENGTH, "%s, %s",
4898585484eSchristos 			 getevents(CTL_SYS_NEVNT(st)),
4908585484eSchristos 			 getcode((st) & 0xf, clock_codes));
491abb0f93cSkardel 		break;
492abb0f93cSkardel 	}
4938585484eSchristos 
494abb0f93cSkardel 	return cb;
495abb0f93cSkardel }
496abb0f93cSkardel 
497abb0f93cSkardel const char *
498abb0f93cSkardel eventstr(
499abb0f93cSkardel 	int num
500abb0f93cSkardel 	)
501abb0f93cSkardel {
502abb0f93cSkardel 	if (num & PEER_EVENT)
503abb0f93cSkardel 		return (getcode(num & ~PEER_EVENT, peer_codes));
5048585484eSchristos #ifdef AUTOKEY
505abb0f93cSkardel 	else if (num & CRPT_EVENT)
506abb0f93cSkardel 		return (getcode(num & ~CRPT_EVENT, crypto_codes));
5078585484eSchristos #endif	/* AUTOKEY */
508abb0f93cSkardel 	else
509abb0f93cSkardel 		return (getcode(num, sys_codes));
510abb0f93cSkardel }
511abb0f93cSkardel 
512abb0f93cSkardel const char *
513abb0f93cSkardel ceventstr(
514abb0f93cSkardel 	int num
515abb0f93cSkardel 	)
516abb0f93cSkardel {
517abb0f93cSkardel 	return getcode(num, clock_codes);
518abb0f93cSkardel }
519