statestr.c revision 182007
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"
1554359Sroberto
1654359Sroberto/*
1754359Sroberto * Structure for turning various constants into a readable string.
1854359Sroberto */
1954359Srobertostruct codestring {
2054359Sroberto	int code;
2154359Sroberto	const char *string;
2254359Sroberto};
2354359Sroberto
2454359Sroberto/*
2554359Sroberto * Leap values
2654359Sroberto */
2754359Srobertostatic
2854359Srobertostruct codestring leap_codes[] = {
2954359Sroberto	{ LEAP_NOWARNING,	"leap_none" },
3054359Sroberto	{ LEAP_ADDSECOND,	"leap_add_sec" },
3154359Sroberto	{ LEAP_DELSECOND,	"leap_del_sec" },
3254359Sroberto	{ LEAP_NOTINSYNC,	"sync_alarm" },
3354359Sroberto	{ -1,	"leap" }
3454359Sroberto};
3554359Sroberto
3654359Sroberto/*
3754359Sroberto * Clock source
3854359Sroberto */
3954359Srobertostatic
4054359Srobertostruct codestring sync_codes[] = {
4154359Sroberto	{ CTL_SST_TS_UNSPEC,	"sync_unspec" },
4254359Sroberto	{ CTL_SST_TS_ATOM,	"sync_atomic" },
4354359Sroberto	{ CTL_SST_TS_LF,	"sync_lf_clock" },
4454359Sroberto	{ CTL_SST_TS_HF,	"sync_hf_clock" },
4554359Sroberto	{ CTL_SST_TS_UHF,	"sync_uhf_clock" },
4654359Sroberto	{ CTL_SST_TS_LOCAL,	"sync_local_proto" },
4754359Sroberto	{ CTL_SST_TS_NTP,	"sync_ntp" },
4854359Sroberto	{ CTL_SST_TS_UDPTIME,	"sync_udp/time" },
4954359Sroberto	{ CTL_SST_TS_WRSTWTCH,	"sync_wristwatch" },
5054359Sroberto	{ CTL_SST_TS_TELEPHONE,	"sync_telephone" },
5154359Sroberto	{ -1,			"sync" }
5254359Sroberto};
5354359Sroberto
5454359Sroberto
5554359Sroberto/*
5654359Sroberto * Peer selection
5754359Sroberto */
5854359Srobertostatic
5954359Srobertostruct codestring select_codes[] = {
6054359Sroberto	{ CTL_PST_SEL_REJECT,	"selreject" },
6154359Sroberto	{ CTL_PST_SEL_SANE,	"sel_falsetick" },
6254359Sroberto	{ CTL_PST_SEL_CORRECT,	"sel_excess" },
6354359Sroberto	{ CTL_PST_SEL_SELCAND,	"sel_outlyer" },
6454359Sroberto	{ CTL_PST_SEL_SYNCCAND,	"sel_candidat" },
6554359Sroberto	{ CTL_PST_SEL_DISTSYSPEER, "sel_selected" },
6654359Sroberto	{ CTL_PST_SEL_SYSPEER,	"sel_sys.peer" },
6754359Sroberto	{ CTL_PST_SEL_PPS,	"sel_pps.peer" },
6854359Sroberto	{ -1,			"sel" }
6954359Sroberto};
7054359Sroberto
7154359Sroberto
7254359Sroberto/*
7354359Sroberto * Clock status
7454359Sroberto */
7554359Srobertostatic
7654359Srobertostruct codestring clock_codes[] = {
7754359Sroberto	{ CTL_CLK_OKAY,		"clk_okay" },
7854359Sroberto	{ CTL_CLK_NOREPLY,	"clk_noreply" },
7954359Sroberto	{ CTL_CLK_BADFORMAT,	"clk_badformat" },
8054359Sroberto	{ CTL_CLK_FAULT,	"clk_fault" },
8154359Sroberto	{ CTL_CLK_PROPAGATION,	"clk_badsignal" },
8254359Sroberto	{ CTL_CLK_BADDATE,	"clk_baddate" },
8354359Sroberto	{ CTL_CLK_BADTIME,	"clk_badtime" },
8454359Sroberto	{ -1,			"clk" }
8554359Sroberto};
8654359Sroberto
8754359Sroberto
8854359Sroberto/*
8954359Sroberto * System Events
9054359Sroberto */
9154359Srobertostatic
9254359Srobertostruct codestring sys_codes[] = {
9354359Sroberto	{ EVNT_UNSPEC,		"event_unspec" },
9454359Sroberto	{ EVNT_SYSRESTART,	"event_restart" },
9554359Sroberto	{ EVNT_SYSFAULT,	"event_fault" },
9654359Sroberto	{ EVNT_SYNCCHG,		"event_sync_chg" },
9754359Sroberto	{ EVNT_PEERSTCHG,	"event_peer/strat_chg" },
9854359Sroberto	{ EVNT_CLOCKRESET,	"event_clock_reset" },
9954359Sroberto	{ EVNT_BADDATETIM,	"event_bad_date" },
10054359Sroberto	{ EVNT_CLOCKEXCPT,	"event_clock_excptn" },
10154359Sroberto	{ -1,			"event" }
10254359Sroberto};
10354359Sroberto
10454359Sroberto/*
105132451Sroberto * Peer events
10654359Sroberto */
10754359Srobertostatic
10854359Srobertostruct codestring peer_codes[] = {
10954359Sroberto	{ EVNT_UNSPEC,			"event_unspec" },
11054359Sroberto	{ EVNT_PEERIPERR & ~PEER_EVENT,	"event_ip_err" },
11154359Sroberto	{ EVNT_PEERAUTH & ~PEER_EVENT,	"event_authen" },
11254359Sroberto	{ EVNT_UNREACH & ~PEER_EVENT,	"event_unreach" },
11354359Sroberto	{ EVNT_REACH & ~PEER_EVENT,	"event_reach" },
11454359Sroberto	{ EVNT_PEERCLOCK & ~PEER_EVENT,	"event_peer_clock" },
11554359Sroberto#if 0
11654359Sroberto	{ EVNT_PEERSTRAT & ~PEER_EVENT,	"event_stratum_chg" },
11754359Sroberto#endif
11854359Sroberto	{ -1,				"event" }
11954359Sroberto};
12054359Sroberto
121132451Sroberto#ifdef OPENSSL
122132451Sroberto/*
123132451Sroberto * Crypto events
124132451Sroberto */
125132451Srobertostatic
126132451Srobertostruct codestring crypto_codes[] = {
127132451Sroberto	{ XEVNT_OK & ~CRPT_EVENT,	"success" },
128132451Sroberto	{ XEVNT_LEN & ~CRPT_EVENT,	"bad_field_format_or_length" },
129132451Sroberto	{ XEVNT_TSP & ~CRPT_EVENT,	"bad_timestamp" },
130132451Sroberto	{ XEVNT_FSP & ~CRPT_EVENT,	"bad_filestamp" },
131182007Sroberto	{ XEVNT_PUB & ~CRPT_EVENT,	"bad_or_missing_public_key" },
132132451Sroberto	{ XEVNT_MD & ~CRPT_EVENT,	"unsupported_digest_type" },
133132451Sroberto	{ XEVNT_KEY & ~CRPT_EVENT,	"unsupported_identity_type" },
134132451Sroberto	{ XEVNT_SGL & ~CRPT_EVENT,	"bad_signature_length" },
135132451Sroberto	{ XEVNT_SIG & ~CRPT_EVENT,	"signature_not_verified" },
136182007Sroberto	{ XEVNT_VFY & ~CRPT_EVENT,	"certificate_not_verified" },
137182007Sroberto	{ XEVNT_PER & ~CRPT_EVENT,	"host certificate_expired" },
138132451Sroberto	{ XEVNT_CKY & ~CRPT_EVENT,	"bad_or_missing_cookie" },
139132451Sroberto	{ XEVNT_DAT & ~CRPT_EVENT,	"bad_or_missing_leapsecond_table" },
140132451Sroberto	{ XEVNT_CRT & ~CRPT_EVENT,	"bad_or_missing_certificate" },
141182007Sroberto	{ XEVNT_ID & ~CRPT_EVENT,	"bad_or_missing_group_key" },
142182007Sroberto	{ XEVNT_ERR & ~CRPT_EVENT,	"protocol_error" },
143182007Sroberto	{ XEVNT_SRV & ~CRPT_EVENT,	"server certificate expired" },
144132451Sroberto	{ -1,				"crypto" }
145132451Sroberto};
146132451Sroberto#endif /* OPENSSL */
147132451Sroberto
14854359Sroberto/* Forwards */
14954359Srobertostatic const char *getcode P((int, struct codestring *));
15054359Srobertostatic const char *getevents P((int));
15154359Sroberto
15254359Sroberto/*
15354359Sroberto * getcode - return string corresponding to code
15454359Sroberto */
15554359Srobertostatic const char *
15654359Srobertogetcode(
15754359Sroberto	int code,
15854359Sroberto	struct codestring *codetab
15954359Sroberto	)
16054359Sroberto{
16154359Sroberto	static char buf[30];
16254359Sroberto
16354359Sroberto	while (codetab->code != -1) {
16454359Sroberto		if (codetab->code == code)
16554359Sroberto		    return codetab->string;
16654359Sroberto		codetab++;
16754359Sroberto	}
16854359Sroberto	(void) sprintf(buf, "%s_%d", codetab->string, code);
16954359Sroberto	return buf;
17054359Sroberto}
17154359Sroberto
17254359Sroberto/*
17354359Sroberto * getevents - return a descriptive string for the event count
17454359Sroberto */
17554359Srobertostatic const char *
17654359Srobertogetevents(
17754359Sroberto	int cnt
17854359Sroberto	)
17954359Sroberto{
18054359Sroberto	static char buf[20];
18154359Sroberto
18254359Sroberto	if (cnt == 0)
18354359Sroberto	    return "no events";
18454359Sroberto	(void) sprintf(buf, "%d event%s", cnt, (cnt==1) ? "" : "s");
18554359Sroberto	return buf;
18654359Sroberto}
18754359Sroberto
18854359Sroberto/*
18954359Sroberto * statustoa - return a descriptive string for a peer status
19054359Sroberto */
19154359Srobertochar *
19254359Srobertostatustoa(
19354359Sroberto	int type,
19454359Sroberto	int st
19554359Sroberto	)
19654359Sroberto{
19754359Sroberto	char *cb;
19854359Sroberto	u_char pst;
19954359Sroberto
20054359Sroberto	LIB_GETBUF(cb);
20154359Sroberto
20254359Sroberto	switch (type) {
20354359Sroberto	    case TYPE_SYS:
20454359Sroberto		(void)strcpy(cb, getcode(CTL_SYS_LI(st), leap_codes));
20554359Sroberto		(void)strcat(cb, ", ");
20654359Sroberto		(void)strcat(cb, getcode(CTL_SYS_SOURCE(st) & ~CTL_SST_TS_PPS, sync_codes));
20754359Sroberto		if (CTL_SYS_SOURCE(st) & CTL_SST_TS_PPS)
20854359Sroberto		    (void)strcat(cb, "/PPS");
20954359Sroberto		(void)strcat(cb, ", ");
21054359Sroberto		(void)strcat(cb, getevents(CTL_SYS_NEVNT(st)));
21154359Sroberto		(void)strcat(cb, ", ");
21254359Sroberto		(void)strcat(cb, getcode(CTL_SYS_EVENT(st), sys_codes));
21354359Sroberto		break;
21454359Sroberto
21554359Sroberto	    case TYPE_PEER:
21654359Sroberto		/*
21754359Sroberto		 * Handcraft the bits
21854359Sroberto		 */
21954359Sroberto		pst = (u_char) CTL_PEER_STATVAL(st);
22054359Sroberto		if (!(pst & CTL_PST_REACH)) {
22154359Sroberto			(void)strcpy(cb, "unreach");
22254359Sroberto		} else {
22354359Sroberto			(void)strcpy(cb, "reach");
22454359Sroberto
22554359Sroberto		}
22654359Sroberto		if (pst & CTL_PST_CONFIG)
22754359Sroberto		    (void)strcat(cb, ", conf");
22854359Sroberto		if (pst & CTL_PST_AUTHENABLE) {
22954359Sroberto			if (!(pst & CTL_PST_REACH) || (pst & CTL_PST_AUTHENTIC))
23054359Sroberto			    (void)strcat(cb, ", auth");
23154359Sroberto			else
23254359Sroberto			    (void)strcat(cb, ", unauth");
23354359Sroberto		}
23454359Sroberto
23554359Sroberto		/*
23654359Sroberto		 * Now the codes
23754359Sroberto		 */
23854359Sroberto		if ((pst & 0x7) != CTL_PST_SEL_REJECT) {
23954359Sroberto			(void)strcat(cb, ", ");
24054359Sroberto			(void)strcat(cb, getcode(pst & 0x7, select_codes));
24154359Sroberto		}
24254359Sroberto		(void)strcat(cb, ", ");
24354359Sroberto		(void)strcat(cb, getevents(CTL_PEER_NEVNT(st)));
24454359Sroberto		if (CTL_PEER_EVENT(st) != EVNT_UNSPEC) {
24554359Sroberto			(void)strcat(cb, ", ");
24654359Sroberto			(void)strcat(cb, getcode(CTL_PEER_EVENT(st),
24754359Sroberto						 peer_codes));
24854359Sroberto		}
24954359Sroberto		break;
25054359Sroberto
25154359Sroberto	    case TYPE_CLOCK:
25254359Sroberto		(void)strcpy(cb, getcode(((st)>>8) & 0xff, clock_codes));
25354359Sroberto		(void)strcat(cb, ", last_");
25454359Sroberto		(void)strcat(cb, getcode((st) & 0xff, clock_codes));
25554359Sroberto		break;
25654359Sroberto	}
25754359Sroberto	return cb;
25854359Sroberto}
25954359Sroberto
26054359Srobertoconst char *
26154359Srobertoeventstr(
26254359Sroberto	int num
26354359Sroberto	)
26454359Sroberto{
265132451Sroberto	if (num & PEER_EVENT)
266132451Sroberto		return (getcode(num & ~PEER_EVENT, peer_codes));
267132451Sroberto#ifdef OPENSSL
268132451Sroberto	else if (num & CRPT_EVENT)
269132451Sroberto		return (getcode(num & ~CRPT_EVENT, crypto_codes));
270132451Sroberto#endif /* OPENSSL */
271132451Sroberto	else
272132451Sroberto		return (getcode(num, sys_codes));
27354359Sroberto}
27454359Sroberto
27554359Srobertoconst char *
27654359Srobertoceventstr(
27754359Sroberto	int num
27854359Sroberto	)
27954359Sroberto{
28054359Sroberto	return getcode(num, clock_codes);
28154359Sroberto}
28254359Sroberto
28354359Srobertoconst char *
28454359Srobertosysstatstr(
28554359Sroberto	int status
28654359Sroberto	)
28754359Sroberto{
28854359Sroberto	return statustoa(TYPE_SYS, status);
28954359Sroberto}
29054359Sroberto
29154359Srobertoconst char *
29254359Srobertopeerstatstr(
29354359Sroberto	int status
29454359Sroberto	)
29554359Sroberto{
29654359Sroberto	return statustoa(TYPE_PEER, status);
29754359Sroberto}
29854359Sroberto
29954359Srobertoconst char *
30054359Srobertoclockstatstr(
30154359Sroberto	int status
30254359Sroberto	)
30354359Sroberto{
30454359Sroberto	return statustoa(TYPE_CLOCK, status);
30554359Sroberto}
306