1c0b746e5SOllivier Robert /* 2c0b746e5SOllivier Robert * pretty printing of status information 3c0b746e5SOllivier Robert */ 4c0b746e5SOllivier Robert #ifdef HAVE_CONFIG_H 5c0b746e5SOllivier Robert #include <config.h> 6c0b746e5SOllivier Robert #endif 7c0b746e5SOllivier Robert #include <stdio.h> 8c0b746e5SOllivier Robert #include "ntp_stdlib.h" 9c0b746e5SOllivier Robert #include "ntp_fp.h" 10c0b746e5SOllivier Robert #include "ntp.h" 11c0b746e5SOllivier Robert #include "lib_strbuf.h" 12c0b746e5SOllivier Robert #include "ntp_refclock.h" 13c0b746e5SOllivier Robert #include "ntp_control.h" 14c0b746e5SOllivier Robert #include "ntp_string.h" 152b15cb3dSCy Schubert #ifdef KERNEL_PLL 162b15cb3dSCy Schubert # include "ntp_syscall.h" 172b15cb3dSCy Schubert #endif 182b15cb3dSCy Schubert 19c0b746e5SOllivier Robert 20c0b746e5SOllivier Robert /* 21c0b746e5SOllivier Robert * Structure for turning various constants into a readable string. 22c0b746e5SOllivier Robert */ 23c0b746e5SOllivier Robert struct codestring { 24c0b746e5SOllivier Robert int code; 2509100258SXin LI const char * const string1; 2609100258SXin LI const char * const string0; 27c0b746e5SOllivier Robert }; 28c0b746e5SOllivier Robert 29c0b746e5SOllivier Robert /* 302b15cb3dSCy Schubert * Leap status (leap) 31c0b746e5SOllivier Robert */ 322b15cb3dSCy Schubert static const struct codestring leap_codes[] = { 3309100258SXin LI { LEAP_NOWARNING, "leap_none", 0 }, 3409100258SXin LI { LEAP_ADDSECOND, "leap_add_sec", 0 }, 3509100258SXin LI { LEAP_DELSECOND, "leap_del_sec", 0 }, 3609100258SXin LI { LEAP_NOTINSYNC, "leap_alarm", 0 }, 3709100258SXin LI { -1, "leap", 0 } 38c0b746e5SOllivier Robert }; 39c0b746e5SOllivier Robert 40c0b746e5SOllivier Robert /* 412b15cb3dSCy Schubert * Clock source status (sync) 42c0b746e5SOllivier Robert */ 432b15cb3dSCy Schubert static const struct codestring sync_codes[] = { 4409100258SXin LI { CTL_SST_TS_UNSPEC, "sync_unspec", 0 }, 4509100258SXin LI { CTL_SST_TS_ATOM, "sync_pps", 0 }, 4609100258SXin LI { CTL_SST_TS_LF, "sync_lf_radio", 0 }, 4709100258SXin LI { CTL_SST_TS_HF, "sync_hf_radio", 0 }, 4809100258SXin LI { CTL_SST_TS_UHF, "sync_uhf_radio", 0 }, 4909100258SXin LI { CTL_SST_TS_LOCAL, "sync_local", 0 }, 5009100258SXin LI { CTL_SST_TS_NTP, "sync_ntp", 0 }, 5109100258SXin LI { CTL_SST_TS_UDPTIME, "sync_other", 0 }, 5209100258SXin LI { CTL_SST_TS_WRSTWTCH, "sync_wristwatch", 0 }, 5309100258SXin LI { CTL_SST_TS_TELEPHONE, "sync_telephone", 0 }, 5409100258SXin LI { -1, "sync", 0 } 55c0b746e5SOllivier Robert }; 56c0b746e5SOllivier Robert 57c0b746e5SOllivier Robert /* 582b15cb3dSCy Schubert * Peer selection status (sel) 59c0b746e5SOllivier Robert */ 602b15cb3dSCy Schubert static const struct codestring select_codes[] = { 6109100258SXin LI { CTL_PST_SEL_REJECT, "sel_reject", 0 }, 6209100258SXin LI { CTL_PST_SEL_SANE, "sel_falsetick", 0 }, 6309100258SXin LI { CTL_PST_SEL_CORRECT, "sel_excess", 0 }, 6409100258SXin LI { CTL_PST_SEL_SELCAND, "sel_outlier", 0 }, 6509100258SXin LI { CTL_PST_SEL_SYNCCAND, "sel_candidate", 0 }, 6609100258SXin LI { CTL_PST_SEL_EXCESS, "sel_backup", 0 }, 6709100258SXin LI { CTL_PST_SEL_SYSPEER, "sel_sys.peer", 0 }, 6809100258SXin LI { CTL_PST_SEL_PPS, "sel_pps.peer", 0 }, 6909100258SXin LI { -1, "sel", 0 } 70c0b746e5SOllivier Robert }; 71c0b746e5SOllivier Robert 72c0b746e5SOllivier Robert /* 732b15cb3dSCy Schubert * Clock status (clk) 74c0b746e5SOllivier Robert */ 752b15cb3dSCy Schubert static const struct codestring clock_codes[] = { 7609100258SXin LI { CTL_CLK_OKAY, "clk_unspec", 0 }, 7709100258SXin LI { CTL_CLK_NOREPLY, "clk_no_reply", 0 }, 7809100258SXin LI { CTL_CLK_BADFORMAT, "clk_bad_format", 0 }, 7909100258SXin LI { CTL_CLK_FAULT, "clk_fault", 0 }, 8009100258SXin LI { CTL_CLK_PROPAGATION, "clk_bad_signal", 0 }, 8109100258SXin LI { CTL_CLK_BADDATE, "clk_bad_date", 0 }, 8209100258SXin LI { CTL_CLK_BADTIME, "clk_bad_time", 0 }, 8309100258SXin LI { -1, "clk", 0 } 84c0b746e5SOllivier Robert }; 85c0b746e5SOllivier Robert 86c0b746e5SOllivier Robert 872b15cb3dSCy Schubert #ifdef FLASH_CODES_UNUSED 88c0b746e5SOllivier Robert /* 892b15cb3dSCy Schubert * Flash bits -- see ntpq.c tstflags & tstflagnames 90c0b746e5SOllivier Robert */ 912b15cb3dSCy Schubert static const struct codestring flash_codes[] = { 9209100258SXin LI { TEST1, "pkt_dup", 0 }, 9309100258SXin LI { TEST2, "pkt_bogus", 0 }, 9409100258SXin LI { TEST3, "pkt_unsync", 0 }, 9509100258SXin LI { TEST4, "pkt_denied", 0 }, 9609100258SXin LI { TEST5, "pkt_auth", 0 }, 9709100258SXin LI { TEST6, "pkt_stratum", 0 }, 9809100258SXin LI { TEST7, "pkt_header", 0 }, 9909100258SXin LI { TEST8, "pkt_autokey", 0 }, 10009100258SXin LI { TEST9, "pkt_crypto", 0 }, 10109100258SXin LI { TEST10, "peer_stratum", 0 }, 10209100258SXin LI { TEST11, "peer_dist", 0 }, 10309100258SXin LI { TEST12, "peer_loop", 0 }, 10409100258SXin LI { TEST13, "peer_unreach", 0 }, 10509100258SXin LI { -1, "flash", 0 } 106c0b746e5SOllivier Robert }; 107c0b746e5SOllivier Robert #endif 1082b15cb3dSCy Schubert 1092b15cb3dSCy Schubert 1102b15cb3dSCy Schubert /* 1112b15cb3dSCy Schubert * System events (sys) 1122b15cb3dSCy Schubert */ 1132b15cb3dSCy Schubert static const struct codestring sys_codes[] = { 11409100258SXin LI { EVNT_UNSPEC, "unspecified", 0 }, 11509100258SXin LI { EVNT_NSET, "freq_not_set", 0 }, 11609100258SXin LI { EVNT_FSET, "freq_set", 0 }, 11709100258SXin LI { EVNT_SPIK, "spike_detect", 0 }, 11809100258SXin LI { EVNT_FREQ, "freq_mode", 0 }, 11909100258SXin LI { EVNT_SYNC, "clock_sync", 0 }, 12009100258SXin LI { EVNT_SYSRESTART, "restart", 0 }, 12109100258SXin LI { EVNT_SYSFAULT, "panic_stop", 0 }, 12209100258SXin LI { EVNT_NOPEER, "no_sys_peer", 0 }, 12309100258SXin LI { EVNT_ARMED, "leap_armed", 0 }, 12409100258SXin LI { EVNT_DISARMED, "leap_disarmed", 0 }, 12509100258SXin LI { EVNT_LEAP, "leap_event", 0 }, 12609100258SXin LI { EVNT_CLOCKRESET, "clock_step", 0 }, 12709100258SXin LI { EVNT_KERN, "kern", 0 }, 12809100258SXin LI { EVNT_TAI, "TAI", 0 }, 12909100258SXin LI { EVNT_LEAPVAL, "stale_leapsecond_values", 0 }, 13009100258SXin LI { -1, "", 0 } 131c0b746e5SOllivier Robert }; 132c0b746e5SOllivier Robert 1339c2daa00SOllivier Robert /* 1342b15cb3dSCy Schubert * Peer events (peer) 1359c2daa00SOllivier Robert */ 1362b15cb3dSCy Schubert static const struct codestring peer_codes[] = { 13709100258SXin LI { PEVNT_MOBIL & ~PEER_EVENT, "mobilize", 0 }, 13809100258SXin LI { PEVNT_DEMOBIL & ~PEER_EVENT, "demobilize", 0 }, 13909100258SXin LI { PEVNT_UNREACH & ~PEER_EVENT, "unreachable", 0 }, 14009100258SXin LI { PEVNT_REACH & ~PEER_EVENT, "reachable", 0 }, 14109100258SXin LI { PEVNT_RESTART & ~PEER_EVENT, "restart", 0 }, 14209100258SXin LI { PEVNT_REPLY & ~PEER_EVENT, "no_reply", 0 }, 14309100258SXin LI { PEVNT_RATE & ~PEER_EVENT, "rate_exceeded", 0 }, 14409100258SXin LI { PEVNT_DENY & ~PEER_EVENT, "access_denied", 0 }, 14509100258SXin LI { PEVNT_ARMED & ~PEER_EVENT, "leap_armed", 0 }, 14609100258SXin LI { PEVNT_NEWPEER & ~PEER_EVENT, "sys_peer", 0 }, 14709100258SXin LI { PEVNT_CLOCK & ~PEER_EVENT, "clock_event", 0 }, 14809100258SXin LI { PEVNT_AUTH & ~PEER_EVENT, "bad_auth", 0 }, 14909100258SXin LI { PEVNT_POPCORN & ~PEER_EVENT, "popcorn", 0 }, 15009100258SXin LI { PEVNT_XLEAVE & ~PEER_EVENT, "interleave_mode", 0 }, 15109100258SXin LI { PEVNT_XERR & ~PEER_EVENT, "interleave_error", 0 }, 15209100258SXin LI { -1, "", 0 } 1532b15cb3dSCy Schubert }; 1542b15cb3dSCy Schubert 1552b15cb3dSCy Schubert /* 1562b15cb3dSCy Schubert * Peer status bits 1572b15cb3dSCy Schubert */ 1582b15cb3dSCy Schubert static const struct codestring peer_st_bits[] = { 15909100258SXin LI { CTL_PST_CONFIG, "conf", 0 }, 16009100258SXin LI { CTL_PST_AUTHENABLE, "authenb", 0 }, 16109100258SXin LI { CTL_PST_AUTHENTIC, "auth", 0 }, 16209100258SXin LI { CTL_PST_REACH, "reach", 0 }, 16309100258SXin LI { CTL_PST_BCAST, "bcast", 0 }, 1642b15cb3dSCy Schubert /* not used with getcode(), no terminating entry needed */ 1652b15cb3dSCy Schubert }; 1662b15cb3dSCy Schubert 1672b15cb3dSCy Schubert /* 1682b15cb3dSCy Schubert * Restriction match bits 1692b15cb3dSCy Schubert */ 1702b15cb3dSCy Schubert static const struct codestring res_match_bits[] = { 17109100258SXin LI { RESM_NTPONLY, "ntpport", 0 }, 17209100258SXin LI { RESM_INTERFACE, "interface", 0 }, 17309100258SXin LI { RESM_SOURCE, "source", 0 }, 1742b15cb3dSCy Schubert /* not used with getcode(), no terminating entry needed */ 1752b15cb3dSCy Schubert }; 1762b15cb3dSCy Schubert 1772b15cb3dSCy Schubert /* 1782b15cb3dSCy Schubert * Restriction access bits 1792b15cb3dSCy Schubert */ 1802b15cb3dSCy Schubert static const struct codestring res_access_bits[] = { 18109100258SXin LI { RES_IGNORE, "ignore", 0 }, 18209100258SXin LI { RES_DONTSERVE, "noserve", "serve" }, 18309100258SXin LI { RES_DONTTRUST, "notrust", "trust" }, 184*2d4e511cSCy Schubert { RES_VERSION, "version", 0 }, 18509100258SXin LI { RES_NOPEER, "nopeer", "peer" }, 18609100258SXin LI { RES_NOEPEER, "noepeer", "epeer" }, 187*2d4e511cSCy Schubert { RES_LIMITED, "limited", 0 }, 188*2d4e511cSCy Schubert 189*2d4e511cSCy Schubert { RES_NOQUERY, "noquery", "query" }, 190*2d4e511cSCy Schubert { RES_NOMODIFY, "nomodify", 0 }, 19109100258SXin LI { RES_NOTRAP, "notrap", "trap" }, 19209100258SXin LI { RES_LPTRAP, "lptrap", 0 }, 193*2d4e511cSCy Schubert 19409100258SXin LI { RES_KOD, "kod", 0 }, 195*2d4e511cSCy Schubert { RES_MSSNTP, "mssntp", 0 }, 19609100258SXin LI { RES_FLAKE, "flake", 0 }, 197*2d4e511cSCy Schubert { RES_NOMRULIST, "nomrulist", 0 }, 198*2d4e511cSCy Schubert 199*2d4e511cSCy Schubert { RES_SRVRSPFUZ, "serverresponse fuzz", 0 }, 200*2d4e511cSCy Schubert 2012b15cb3dSCy Schubert /* not used with getcode(), no terminating entry needed */ 2022b15cb3dSCy Schubert }; 2032b15cb3dSCy Schubert 2042b15cb3dSCy Schubert #ifdef AUTOKEY 2052b15cb3dSCy Schubert /* 2062b15cb3dSCy Schubert * Crypto events (cryp) 2072b15cb3dSCy Schubert */ 2082b15cb3dSCy Schubert static const struct codestring crypto_codes[] = { 20909100258SXin LI { XEVNT_OK & ~CRPT_EVENT, "success", 0 }, 21009100258SXin LI { XEVNT_LEN & ~CRPT_EVENT, "bad_field_format_or_length", 0 }, 21109100258SXin LI { XEVNT_TSP & ~CRPT_EVENT, "bad_timestamp", 0 }, 21209100258SXin LI { XEVNT_FSP & ~CRPT_EVENT, "bad_filestamp", 0 }, 21309100258SXin LI { XEVNT_PUB & ~CRPT_EVENT, "bad_or_missing_public_key", 0 }, 21409100258SXin LI { XEVNT_MD & ~CRPT_EVENT, "unsupported_digest_type", 0 }, 21509100258SXin LI { XEVNT_KEY & ~CRPT_EVENT, "unsupported_identity_type", 0 }, 21609100258SXin LI { XEVNT_SGL & ~CRPT_EVENT, "bad_signature_length", 0 }, 21709100258SXin LI { XEVNT_SIG & ~CRPT_EVENT, "signature_not_verified", 0 }, 21809100258SXin LI { XEVNT_VFY & ~CRPT_EVENT, "certificate_not_verified", 0 }, 21909100258SXin LI { XEVNT_PER & ~CRPT_EVENT, "host_certificate_expired", 0 }, 22009100258SXin LI { XEVNT_CKY & ~CRPT_EVENT, "bad_or_missing_cookie", 0 }, 22109100258SXin LI { XEVNT_DAT & ~CRPT_EVENT, "bad_or_missing_leapseconds", 0 }, 22209100258SXin LI { XEVNT_CRT & ~CRPT_EVENT, "bad_or_missing_certificate", 0 }, 22309100258SXin LI { XEVNT_ID & ~CRPT_EVENT, "bad_or_missing_group key", 0 }, 22409100258SXin LI { XEVNT_ERR & ~CRPT_EVENT, "protocol_error", 0 }, 22509100258SXin LI { -1, "", 0 } 2269c2daa00SOllivier Robert }; 2272b15cb3dSCy Schubert #endif /* AUTOKEY */ 2282b15cb3dSCy Schubert 2292b15cb3dSCy Schubert #ifdef KERNEL_PLL 2302b15cb3dSCy Schubert /* 2312b15cb3dSCy Schubert * kernel discipline status bits 2322b15cb3dSCy Schubert */ 2332b15cb3dSCy Schubert static const struct codestring k_st_bits[] = { 2342b15cb3dSCy Schubert # ifdef STA_PLL 23509100258SXin LI { STA_PLL, "pll", 0 }, 2362b15cb3dSCy Schubert # endif 2372b15cb3dSCy Schubert # ifdef STA_PPSFREQ 23809100258SXin LI { STA_PPSFREQ, "ppsfreq", 0 }, 2392b15cb3dSCy Schubert # endif 2402b15cb3dSCy Schubert # ifdef STA_PPSTIME 24109100258SXin LI { STA_PPSTIME, "ppstime", 0 }, 2422b15cb3dSCy Schubert # endif 2432b15cb3dSCy Schubert # ifdef STA_FLL 24409100258SXin LI { STA_FLL, "fll", 0 }, 2452b15cb3dSCy Schubert # endif 2462b15cb3dSCy Schubert # ifdef STA_INS 24709100258SXin LI { STA_INS, "ins", 0 }, 2482b15cb3dSCy Schubert # endif 2492b15cb3dSCy Schubert # ifdef STA_DEL 25009100258SXin LI { STA_DEL, "del", 0 }, 2512b15cb3dSCy Schubert # endif 2522b15cb3dSCy Schubert # ifdef STA_UNSYNC 25309100258SXin LI { STA_UNSYNC, "unsync", 0 }, 2542b15cb3dSCy Schubert # endif 2552b15cb3dSCy Schubert # ifdef STA_FREQHOLD 25609100258SXin LI { STA_FREQHOLD, "freqhold", 0 }, 2572b15cb3dSCy Schubert # endif 2582b15cb3dSCy Schubert # ifdef STA_PPSSIGNAL 25909100258SXin LI { STA_PPSSIGNAL, "ppssignal", 0 }, 2602b15cb3dSCy Schubert # endif 2612b15cb3dSCy Schubert # ifdef STA_PPSJITTER 26209100258SXin LI { STA_PPSJITTER, "ppsjitter", 0 }, 2632b15cb3dSCy Schubert # endif 2642b15cb3dSCy Schubert # ifdef STA_PPSWANDER 26509100258SXin LI { STA_PPSWANDER, "ppswander", 0 }, 2662b15cb3dSCy Schubert # endif 2672b15cb3dSCy Schubert # ifdef STA_PPSERROR 26809100258SXin LI { STA_PPSERROR, "ppserror", 0 }, 2692b15cb3dSCy Schubert # endif 2702b15cb3dSCy Schubert # ifdef STA_CLOCKERR 27109100258SXin LI { STA_CLOCKERR, "clockerr", 0 }, 2722b15cb3dSCy Schubert # endif 2732b15cb3dSCy Schubert # ifdef STA_NANO 27409100258SXin LI { STA_NANO, "nano", 0 }, 2752b15cb3dSCy Schubert # endif 2762b15cb3dSCy Schubert # ifdef STA_MODE 27709100258SXin LI { STA_MODE, "mode=fll", 0 }, 2782b15cb3dSCy Schubert # endif 2792b15cb3dSCy Schubert # ifdef STA_CLK 28009100258SXin LI { STA_CLK, "src=B", 0 }, 2812b15cb3dSCy Schubert # endif 2822b15cb3dSCy Schubert /* not used with getcode(), no terminating entry needed */ 2832b15cb3dSCy Schubert }; 2842b15cb3dSCy Schubert #endif /* KERNEL_PLL */ 2859c2daa00SOllivier Robert 286c0b746e5SOllivier Robert /* Forwards */ 2872b15cb3dSCy Schubert static const char * getcode(int, const struct codestring *); 2882b15cb3dSCy Schubert static const char * getevents(int); 2892b15cb3dSCy Schubert static const char * peer_st_flags(u_char pst); 290c0b746e5SOllivier Robert 291c0b746e5SOllivier Robert /* 292c0b746e5SOllivier Robert * getcode - return string corresponding to code 293c0b746e5SOllivier Robert */ 294c0b746e5SOllivier Robert static const char * 295c0b746e5SOllivier Robert getcode( 296c0b746e5SOllivier Robert int code, 2972b15cb3dSCy Schubert const struct codestring * codetab 298c0b746e5SOllivier Robert ) 299c0b746e5SOllivier Robert { 3002b15cb3dSCy Schubert char * buf; 301c0b746e5SOllivier Robert 302c0b746e5SOllivier Robert while (codetab->code != -1) { 303c0b746e5SOllivier Robert if (codetab->code == code) 30409100258SXin LI return codetab->string1; 305c0b746e5SOllivier Robert codetab++; 306c0b746e5SOllivier Robert } 3072b15cb3dSCy Schubert 3082b15cb3dSCy Schubert LIB_GETBUF(buf); 30909100258SXin LI snprintf(buf, LIB_BUFLENGTH, "%s_%d", codetab->string1, code); 3102b15cb3dSCy Schubert 311c0b746e5SOllivier Robert return buf; 312c0b746e5SOllivier Robert } 313c0b746e5SOllivier Robert 314c0b746e5SOllivier Robert /* 315c0b746e5SOllivier Robert * getevents - return a descriptive string for the event count 316c0b746e5SOllivier Robert */ 317c0b746e5SOllivier Robert static const char * 318c0b746e5SOllivier Robert getevents( 319c0b746e5SOllivier Robert int cnt 320c0b746e5SOllivier Robert ) 321c0b746e5SOllivier Robert { 3222b15cb3dSCy Schubert char * buf; 323c0b746e5SOllivier Robert 324c0b746e5SOllivier Robert if (cnt == 0) 325c0b746e5SOllivier Robert return "no events"; 3262b15cb3dSCy Schubert 3272b15cb3dSCy Schubert LIB_GETBUF(buf); 3282b15cb3dSCy Schubert snprintf(buf, LIB_BUFLENGTH, "%d event%s", cnt, 3292b15cb3dSCy Schubert (1 == cnt) 3302b15cb3dSCy Schubert ? "" 3312b15cb3dSCy Schubert : "s"); 3322b15cb3dSCy Schubert 333c0b746e5SOllivier Robert return buf; 334c0b746e5SOllivier Robert } 335c0b746e5SOllivier Robert 3362b15cb3dSCy Schubert 3372b15cb3dSCy Schubert /* 3382b15cb3dSCy Schubert * decode_bitflags() 3392b15cb3dSCy Schubert * 3402b15cb3dSCy Schubert * returns a human-readable string with a keyword from tab for each bit 3412b15cb3dSCy Schubert * set in bits, separating multiple entries with text of sep2. 3422b15cb3dSCy Schubert */ 3432b15cb3dSCy Schubert static const char * 3442b15cb3dSCy Schubert decode_bitflags( 3452b15cb3dSCy Schubert int bits, 3462b15cb3dSCy Schubert const char * sep2, 3472b15cb3dSCy Schubert const struct codestring * tab, 3482b15cb3dSCy Schubert size_t tab_ct 3492b15cb3dSCy Schubert ) 3502b15cb3dSCy Schubert { 3512b15cb3dSCy Schubert const char * sep; 3522b15cb3dSCy Schubert char * buf; 3532b15cb3dSCy Schubert char * pch; 3542b15cb3dSCy Schubert char * lim; 3552b15cb3dSCy Schubert size_t b; 3562b15cb3dSCy Schubert int rc; 3572b15cb3dSCy Schubert int saved_errno; /* for use in DPRINTF with %m */ 3582b15cb3dSCy Schubert 3592b15cb3dSCy Schubert saved_errno = errno; 3602b15cb3dSCy Schubert LIB_GETBUF(buf); 3612b15cb3dSCy Schubert pch = buf; 3622b15cb3dSCy Schubert lim = buf + LIB_BUFLENGTH; 3632b15cb3dSCy Schubert sep = ""; 3642b15cb3dSCy Schubert 3652b15cb3dSCy Schubert for (b = 0; b < tab_ct; b++) { 36609100258SXin LI const char * flagstr; 36709100258SXin LI 3682b15cb3dSCy Schubert if (tab[b].code & bits) { 36909100258SXin LI flagstr = tab[b].string1; 37009100258SXin LI } else { 37109100258SXin LI flagstr = tab[b].string0; 37209100258SXin LI } 37309100258SXin LI 37409100258SXin LI if (flagstr) { 375f0574f5cSXin LI size_t avail = lim - pch; 376f0574f5cSXin LI rc = snprintf(pch, avail, "%s%s", sep, 37709100258SXin LI flagstr); 378f0574f5cSXin LI if ((size_t)rc >= avail) 3792b15cb3dSCy Schubert goto toosmall; 380f0574f5cSXin LI pch += rc; 3812b15cb3dSCy Schubert sep = sep2; 3822b15cb3dSCy Schubert } 3832b15cb3dSCy Schubert } 3842b15cb3dSCy Schubert 3852b15cb3dSCy Schubert return buf; 3862b15cb3dSCy Schubert 3872b15cb3dSCy Schubert toosmall: 3882b15cb3dSCy Schubert snprintf(buf, LIB_BUFLENGTH, 3892b15cb3dSCy Schubert "decode_bitflags(%s) can't decode 0x%x in %d bytes", 3902b15cb3dSCy Schubert (tab == peer_st_bits) 3912b15cb3dSCy Schubert ? "peer_st" 3922b15cb3dSCy Schubert : 3932b15cb3dSCy Schubert #ifdef KERNEL_PLL 3942b15cb3dSCy Schubert (tab == k_st_bits) 3952b15cb3dSCy Schubert ? "kern_st" 3962b15cb3dSCy Schubert : 3972b15cb3dSCy Schubert #endif 3982b15cb3dSCy Schubert "", 3992b15cb3dSCy Schubert bits, (int)LIB_BUFLENGTH); 4002b15cb3dSCy Schubert errno = saved_errno; 4012b15cb3dSCy Schubert 4022b15cb3dSCy Schubert return buf; 4032b15cb3dSCy Schubert } 4042b15cb3dSCy Schubert 4052b15cb3dSCy Schubert 4062b15cb3dSCy Schubert static const char * 4072b15cb3dSCy Schubert peer_st_flags( 4082b15cb3dSCy Schubert u_char pst 4092b15cb3dSCy Schubert ) 4102b15cb3dSCy Schubert { 4112b15cb3dSCy Schubert return decode_bitflags(pst, ", ", peer_st_bits, 4122b15cb3dSCy Schubert COUNTOF(peer_st_bits)); 4132b15cb3dSCy Schubert } 4142b15cb3dSCy Schubert 4152b15cb3dSCy Schubert 4162b15cb3dSCy Schubert const char * 4172b15cb3dSCy Schubert res_match_flags( 4182b15cb3dSCy Schubert u_short mf 4192b15cb3dSCy Schubert ) 4202b15cb3dSCy Schubert { 4212b15cb3dSCy Schubert return decode_bitflags(mf, " ", res_match_bits, 4222b15cb3dSCy Schubert COUNTOF(res_match_bits)); 4232b15cb3dSCy Schubert } 4242b15cb3dSCy Schubert 4252b15cb3dSCy Schubert 4262b15cb3dSCy Schubert const char * 4272b15cb3dSCy Schubert res_access_flags( 428*2d4e511cSCy Schubert u_int32 af 4292b15cb3dSCy Schubert ) 4302b15cb3dSCy Schubert { 4312b15cb3dSCy Schubert return decode_bitflags(af, " ", res_access_bits, 4322b15cb3dSCy Schubert COUNTOF(res_access_bits)); 4332b15cb3dSCy Schubert } 4342b15cb3dSCy Schubert 4352b15cb3dSCy Schubert 4362b15cb3dSCy Schubert #ifdef KERNEL_PLL 4372b15cb3dSCy Schubert const char * 4382b15cb3dSCy Schubert k_st_flags( 4392b15cb3dSCy Schubert u_int32 st 4402b15cb3dSCy Schubert ) 4412b15cb3dSCy Schubert { 4422b15cb3dSCy Schubert return decode_bitflags(st, " ", k_st_bits, COUNTOF(k_st_bits)); 4432b15cb3dSCy Schubert } 4442b15cb3dSCy Schubert #endif /* KERNEL_PLL */ 4452b15cb3dSCy Schubert 4462b15cb3dSCy Schubert 447c0b746e5SOllivier Robert /* 448c0b746e5SOllivier Robert * statustoa - return a descriptive string for a peer status 449c0b746e5SOllivier Robert */ 450c0b746e5SOllivier Robert char * 451c0b746e5SOllivier Robert statustoa( 452c0b746e5SOllivier Robert int type, 453c0b746e5SOllivier Robert int st 454c0b746e5SOllivier Robert ) 455c0b746e5SOllivier Robert { 456c0b746e5SOllivier Robert char * cb; 4572b15cb3dSCy Schubert char * cc; 458c0b746e5SOllivier Robert u_char pst; 459c0b746e5SOllivier Robert 460c0b746e5SOllivier Robert LIB_GETBUF(cb); 461c0b746e5SOllivier Robert 462c0b746e5SOllivier Robert switch (type) { 4632b15cb3dSCy Schubert 464c0b746e5SOllivier Robert case TYPE_SYS: 4652b15cb3dSCy Schubert snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s, %s", 4662b15cb3dSCy Schubert getcode(CTL_SYS_LI(st), leap_codes), 4672b15cb3dSCy Schubert getcode(CTL_SYS_SOURCE(st), sync_codes), 4682b15cb3dSCy Schubert getevents(CTL_SYS_NEVNT(st)), 4692b15cb3dSCy Schubert getcode(CTL_SYS_EVENT(st), sys_codes)); 470c0b746e5SOllivier Robert break; 471c0b746e5SOllivier Robert 472c0b746e5SOllivier Robert case TYPE_PEER: 473c0b746e5SOllivier Robert pst = (u_char)CTL_PEER_STATVAL(st); 4742b15cb3dSCy Schubert snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s", 4752b15cb3dSCy Schubert peer_st_flags(pst), 4762b15cb3dSCy Schubert getcode(pst & 0x7, select_codes), 4772b15cb3dSCy Schubert getevents(CTL_PEER_NEVNT(st))); 478c0b746e5SOllivier Robert if (CTL_PEER_EVENT(st) != EVNT_UNSPEC) { 4792b15cb3dSCy Schubert cc = cb + strlen(cb); 4802b15cb3dSCy Schubert snprintf(cc, LIB_BUFLENGTH - (cc - cb), ", %s", 4812b15cb3dSCy Schubert getcode(CTL_PEER_EVENT(st), 482c0b746e5SOllivier Robert peer_codes)); 483c0b746e5SOllivier Robert } 484c0b746e5SOllivier Robert break; 485c0b746e5SOllivier Robert 486c0b746e5SOllivier Robert case TYPE_CLOCK: 4872b15cb3dSCy Schubert snprintf(cb, LIB_BUFLENGTH, "%s, %s", 4882b15cb3dSCy Schubert getevents(CTL_SYS_NEVNT(st)), 4892b15cb3dSCy Schubert getcode((st) & 0xf, clock_codes)); 490c0b746e5SOllivier Robert break; 491c0b746e5SOllivier Robert } 4922b15cb3dSCy Schubert 493c0b746e5SOllivier Robert return cb; 494c0b746e5SOllivier Robert } 495c0b746e5SOllivier Robert 496c0b746e5SOllivier Robert const char * 497c0b746e5SOllivier Robert eventstr( 498c0b746e5SOllivier Robert int num 499c0b746e5SOllivier Robert ) 500c0b746e5SOllivier Robert { 5019c2daa00SOllivier Robert if (num & PEER_EVENT) 5029c2daa00SOllivier Robert return (getcode(num & ~PEER_EVENT, peer_codes)); 5032b15cb3dSCy Schubert #ifdef AUTOKEY 5049c2daa00SOllivier Robert else if (num & CRPT_EVENT) 5059c2daa00SOllivier Robert return (getcode(num & ~CRPT_EVENT, crypto_codes)); 5062b15cb3dSCy Schubert #endif /* AUTOKEY */ 5079c2daa00SOllivier Robert else 5089c2daa00SOllivier Robert return (getcode(num, sys_codes)); 509c0b746e5SOllivier Robert } 510c0b746e5SOllivier Robert 511c0b746e5SOllivier Robert const char * 512c0b746e5SOllivier Robert ceventstr( 513c0b746e5SOllivier Robert int num 514c0b746e5SOllivier Robert ) 515c0b746e5SOllivier Robert { 516c0b746e5SOllivier Robert return getcode(num, clock_codes); 517c0b746e5SOllivier Robert } 518