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 "ntp_refclock.h" 12c0b746e5SOllivier Robert #include "ntp_control.h" 13c0b746e5SOllivier Robert #include "ntp_string.h" 142b15cb3dSCy Schubert #ifdef KERNEL_PLL 152b15cb3dSCy Schubert # include "ntp_syscall.h" 162b15cb3dSCy Schubert #endif 172b15cb3dSCy Schubert 18c0b746e5SOllivier Robert 19c0b746e5SOllivier Robert /* 20c0b746e5SOllivier Robert * Structure for turning various constants into a readable string. 21c0b746e5SOllivier Robert */ 22c0b746e5SOllivier Robert struct codestring { 23c0b746e5SOllivier Robert int code; 2409100258SXin LI const char * const string1; 2509100258SXin LI const char * const string0; 26c0b746e5SOllivier Robert }; 27c0b746e5SOllivier Robert 28c0b746e5SOllivier Robert /* 292b15cb3dSCy Schubert * Leap status (leap) 30c0b746e5SOllivier Robert */ 312b15cb3dSCy Schubert static const struct codestring leap_codes[] = { 3209100258SXin LI { LEAP_NOWARNING, "leap_none", 0 }, 3309100258SXin LI { LEAP_ADDSECOND, "leap_add_sec", 0 }, 3409100258SXin LI { LEAP_DELSECOND, "leap_del_sec", 0 }, 3509100258SXin LI { LEAP_NOTINSYNC, "leap_alarm", 0 }, 3609100258SXin LI { -1, "leap", 0 } 37c0b746e5SOllivier Robert }; 38c0b746e5SOllivier Robert 39c0b746e5SOllivier Robert /* 402b15cb3dSCy Schubert * Clock source status (sync) 41c0b746e5SOllivier Robert */ 422b15cb3dSCy Schubert static const struct codestring sync_codes[] = { 4309100258SXin LI { CTL_SST_TS_UNSPEC, "sync_unspec", 0 }, 4409100258SXin LI { CTL_SST_TS_ATOM, "sync_pps", 0 }, 4509100258SXin LI { CTL_SST_TS_LF, "sync_lf_radio", 0 }, 4609100258SXin LI { CTL_SST_TS_HF, "sync_hf_radio", 0 }, 4709100258SXin LI { CTL_SST_TS_UHF, "sync_uhf_radio", 0 }, 4809100258SXin LI { CTL_SST_TS_LOCAL, "sync_local", 0 }, 4909100258SXin LI { CTL_SST_TS_NTP, "sync_ntp", 0 }, 5009100258SXin LI { CTL_SST_TS_UDPTIME, "sync_other", 0 }, 5109100258SXin LI { CTL_SST_TS_WRSTWTCH, "sync_wristwatch", 0 }, 5209100258SXin LI { CTL_SST_TS_TELEPHONE, "sync_telephone", 0 }, 5309100258SXin LI { -1, "sync", 0 } 54c0b746e5SOllivier Robert }; 55c0b746e5SOllivier Robert 56c0b746e5SOllivier Robert /* 572b15cb3dSCy Schubert * Peer selection status (sel) 58c0b746e5SOllivier Robert */ 592b15cb3dSCy Schubert static const struct codestring select_codes[] = { 6009100258SXin LI { CTL_PST_SEL_REJECT, "sel_reject", 0 }, 6109100258SXin LI { CTL_PST_SEL_SANE, "sel_falsetick", 0 }, 6209100258SXin LI { CTL_PST_SEL_CORRECT, "sel_excess", 0 }, 6309100258SXin LI { CTL_PST_SEL_SELCAND, "sel_outlier", 0 }, 6409100258SXin LI { CTL_PST_SEL_SYNCCAND, "sel_candidate", 0 }, 6509100258SXin LI { CTL_PST_SEL_EXCESS, "sel_backup", 0 }, 6609100258SXin LI { CTL_PST_SEL_SYSPEER, "sel_sys.peer", 0 }, 6709100258SXin LI { CTL_PST_SEL_PPS, "sel_pps.peer", 0 }, 6809100258SXin LI { -1, "sel", 0 } 69c0b746e5SOllivier Robert }; 70c0b746e5SOllivier Robert 71c0b746e5SOllivier Robert /* 722b15cb3dSCy Schubert * Clock status (clk) 73c0b746e5SOllivier Robert */ 742b15cb3dSCy Schubert static const struct codestring clock_codes[] = { 7509100258SXin LI { CTL_CLK_OKAY, "clk_unspec", 0 }, 7609100258SXin LI { CTL_CLK_NOREPLY, "clk_no_reply", 0 }, 7709100258SXin LI { CTL_CLK_BADFORMAT, "clk_bad_format", 0 }, 7809100258SXin LI { CTL_CLK_FAULT, "clk_fault", 0 }, 7909100258SXin LI { CTL_CLK_PROPAGATION, "clk_bad_signal", 0 }, 8009100258SXin LI { CTL_CLK_BADDATE, "clk_bad_date", 0 }, 8109100258SXin LI { CTL_CLK_BADTIME, "clk_bad_time", 0 }, 8209100258SXin LI { -1, "clk", 0 } 83c0b746e5SOllivier Robert }; 84c0b746e5SOllivier Robert 85c0b746e5SOllivier Robert 862b15cb3dSCy Schubert #ifdef FLASH_CODES_UNUSED 87c0b746e5SOllivier Robert /* 882b15cb3dSCy Schubert * Flash bits -- see ntpq.c tstflags & tstflagnames 89c0b746e5SOllivier Robert */ 902b15cb3dSCy Schubert static const struct codestring flash_codes[] = { 9109100258SXin LI { TEST1, "pkt_dup", 0 }, 9209100258SXin LI { TEST2, "pkt_bogus", 0 }, 9309100258SXin LI { TEST3, "pkt_unsync", 0 }, 9409100258SXin LI { TEST4, "pkt_denied", 0 }, 9509100258SXin LI { TEST5, "pkt_auth", 0 }, 9609100258SXin LI { TEST6, "pkt_stratum", 0 }, 9709100258SXin LI { TEST7, "pkt_header", 0 }, 9809100258SXin LI { TEST8, "pkt_autokey", 0 }, 9909100258SXin LI { TEST9, "pkt_crypto", 0 }, 10009100258SXin LI { TEST10, "peer_stratum", 0 }, 10109100258SXin LI { TEST11, "peer_dist", 0 }, 10209100258SXin LI { TEST12, "peer_loop", 0 }, 10309100258SXin LI { TEST13, "peer_unreach", 0 }, 10409100258SXin LI { -1, "flash", 0 } 105c0b746e5SOllivier Robert }; 106c0b746e5SOllivier Robert #endif 1072b15cb3dSCy Schubert 1082b15cb3dSCy Schubert 1092b15cb3dSCy Schubert /* 1102b15cb3dSCy Schubert * System events (sys) 1112b15cb3dSCy Schubert */ 1122b15cb3dSCy Schubert static const struct codestring sys_codes[] = { 11309100258SXin LI { EVNT_UNSPEC, "unspecified", 0 }, 11409100258SXin LI { EVNT_NSET, "freq_not_set", 0 }, 11509100258SXin LI { EVNT_FSET, "freq_set", 0 }, 11609100258SXin LI { EVNT_SPIK, "spike_detect", 0 }, 11709100258SXin LI { EVNT_FREQ, "freq_mode", 0 }, 11809100258SXin LI { EVNT_SYNC, "clock_sync", 0 }, 11909100258SXin LI { EVNT_SYSRESTART, "restart", 0 }, 12009100258SXin LI { EVNT_SYSFAULT, "panic_stop", 0 }, 12109100258SXin LI { EVNT_NOPEER, "no_sys_peer", 0 }, 12209100258SXin LI { EVNT_ARMED, "leap_armed", 0 }, 12309100258SXin LI { EVNT_DISARMED, "leap_disarmed", 0 }, 12409100258SXin LI { EVNT_LEAP, "leap_event", 0 }, 12509100258SXin LI { EVNT_CLOCKRESET, "clock_step", 0 }, 12609100258SXin LI { EVNT_KERN, "kern", 0 }, 12709100258SXin LI { EVNT_TAI, "TAI", 0 }, 12809100258SXin LI { EVNT_LEAPVAL, "stale_leapsecond_values", 0 }, 12909100258SXin LI { -1, "", 0 } 130c0b746e5SOllivier Robert }; 131c0b746e5SOllivier Robert 1329c2daa00SOllivier Robert /* 1332b15cb3dSCy Schubert * Peer events (peer) 1349c2daa00SOllivier Robert */ 1352b15cb3dSCy Schubert static const struct codestring peer_codes[] = { 13609100258SXin LI { PEVNT_MOBIL & ~PEER_EVENT, "mobilize", 0 }, 13709100258SXin LI { PEVNT_DEMOBIL & ~PEER_EVENT, "demobilize", 0 }, 13809100258SXin LI { PEVNT_UNREACH & ~PEER_EVENT, "unreachable", 0 }, 13909100258SXin LI { PEVNT_REACH & ~PEER_EVENT, "reachable", 0 }, 14009100258SXin LI { PEVNT_RESTART & ~PEER_EVENT, "restart", 0 }, 14109100258SXin LI { PEVNT_REPLY & ~PEER_EVENT, "no_reply", 0 }, 14209100258SXin LI { PEVNT_RATE & ~PEER_EVENT, "rate_exceeded", 0 }, 14309100258SXin LI { PEVNT_DENY & ~PEER_EVENT, "access_denied", 0 }, 14409100258SXin LI { PEVNT_ARMED & ~PEER_EVENT, "leap_armed", 0 }, 14509100258SXin LI { PEVNT_NEWPEER & ~PEER_EVENT, "sys_peer", 0 }, 14609100258SXin LI { PEVNT_CLOCK & ~PEER_EVENT, "clock_event", 0 }, 14709100258SXin LI { PEVNT_AUTH & ~PEER_EVENT, "bad_auth", 0 }, 14809100258SXin LI { PEVNT_POPCORN & ~PEER_EVENT, "popcorn", 0 }, 14909100258SXin LI { PEVNT_XLEAVE & ~PEER_EVENT, "interleave_mode", 0 }, 15009100258SXin LI { PEVNT_XERR & ~PEER_EVENT, "interleave_error", 0 }, 15109100258SXin LI { -1, "", 0 } 1522b15cb3dSCy Schubert }; 1532b15cb3dSCy Schubert 1542b15cb3dSCy Schubert /* 1552b15cb3dSCy Schubert * Peer status bits 1562b15cb3dSCy Schubert */ 1572b15cb3dSCy Schubert static const struct codestring peer_st_bits[] = { 15809100258SXin LI { CTL_PST_CONFIG, "conf", 0 }, 15909100258SXin LI { CTL_PST_AUTHENABLE, "authenb", 0 }, 16009100258SXin LI { CTL_PST_AUTHENTIC, "auth", 0 }, 16109100258SXin LI { CTL_PST_REACH, "reach", 0 }, 16209100258SXin LI { CTL_PST_BCAST, "bcast", 0 }, 1632b15cb3dSCy Schubert /* not used with getcode(), no terminating entry needed */ 1642b15cb3dSCy Schubert }; 1652b15cb3dSCy Schubert 1662b15cb3dSCy Schubert /* 1672b15cb3dSCy Schubert * Restriction match bits 1682b15cb3dSCy Schubert */ 1692b15cb3dSCy Schubert static const struct codestring res_match_bits[] = { 17009100258SXin LI { RESM_NTPONLY, "ntpport", 0 }, 17109100258SXin LI { RESM_INTERFACE, "interface", 0 }, 17209100258SXin LI { RESM_SOURCE, "source", 0 }, 1732b15cb3dSCy Schubert /* not used with getcode(), no terminating entry needed */ 1742b15cb3dSCy Schubert }; 1752b15cb3dSCy Schubert 1762b15cb3dSCy Schubert /* 1772b15cb3dSCy Schubert * Restriction access bits 1782b15cb3dSCy Schubert */ 1792b15cb3dSCy Schubert static const struct codestring res_access_bits[] = { 18009100258SXin LI { RES_IGNORE, "ignore", 0 }, 18109100258SXin LI { RES_DONTSERVE, "noserve", "serve" }, 18209100258SXin LI { RES_DONTTRUST, "notrust", "trust" }, 183*2d4e511cSCy Schubert { RES_VERSION, "version", 0 }, 18409100258SXin LI { RES_NOPEER, "nopeer", "peer" }, 18509100258SXin LI { RES_NOEPEER, "noepeer", "epeer" }, 186*2d4e511cSCy Schubert { RES_LIMITED, "limited", 0 }, 187*2d4e511cSCy Schubert 188*2d4e511cSCy Schubert { RES_NOQUERY, "noquery", "query" }, 189*2d4e511cSCy Schubert { RES_NOMODIFY, "nomodify", 0 }, 19009100258SXin LI { RES_NOTRAP, "notrap", "trap" }, 19109100258SXin LI { RES_LPTRAP, "lptrap", 0 }, 192*2d4e511cSCy Schubert 19309100258SXin LI { RES_KOD, "kod", 0 }, 194*2d4e511cSCy Schubert { RES_MSSNTP, "mssntp", 0 }, 19509100258SXin LI { RES_FLAKE, "flake", 0 }, 196*2d4e511cSCy Schubert { RES_NOMRULIST, "nomrulist", 0 }, 197*2d4e511cSCy Schubert 198*2d4e511cSCy Schubert { RES_SRVRSPFUZ, "serverresponse fuzz", 0 }, 199*2d4e511cSCy Schubert 2002b15cb3dSCy Schubert /* not used with getcode(), no terminating entry needed */ 2012b15cb3dSCy Schubert }; 2022b15cb3dSCy Schubert 2032b15cb3dSCy Schubert #ifdef AUTOKEY 2042b15cb3dSCy Schubert /* 2052b15cb3dSCy Schubert * Crypto events (cryp) 2062b15cb3dSCy Schubert */ 2072b15cb3dSCy Schubert static const struct codestring crypto_codes[] = { 20809100258SXin LI { XEVNT_OK & ~CRPT_EVENT, "success", 0 }, 20909100258SXin LI { XEVNT_LEN & ~CRPT_EVENT, "bad_field_format_or_length", 0 }, 21009100258SXin LI { XEVNT_TSP & ~CRPT_EVENT, "bad_timestamp", 0 }, 21109100258SXin LI { XEVNT_FSP & ~CRPT_EVENT, "bad_filestamp", 0 }, 21209100258SXin LI { XEVNT_PUB & ~CRPT_EVENT, "bad_or_missing_public_key", 0 }, 21309100258SXin LI { XEVNT_MD & ~CRPT_EVENT, "unsupported_digest_type", 0 }, 21409100258SXin LI { XEVNT_KEY & ~CRPT_EVENT, "unsupported_identity_type", 0 }, 21509100258SXin LI { XEVNT_SGL & ~CRPT_EVENT, "bad_signature_length", 0 }, 21609100258SXin LI { XEVNT_SIG & ~CRPT_EVENT, "signature_not_verified", 0 }, 21709100258SXin LI { XEVNT_VFY & ~CRPT_EVENT, "certificate_not_verified", 0 }, 21809100258SXin LI { XEVNT_PER & ~CRPT_EVENT, "host_certificate_expired", 0 }, 21909100258SXin LI { XEVNT_CKY & ~CRPT_EVENT, "bad_or_missing_cookie", 0 }, 22009100258SXin LI { XEVNT_DAT & ~CRPT_EVENT, "bad_or_missing_leapseconds", 0 }, 22109100258SXin LI { XEVNT_CRT & ~CRPT_EVENT, "bad_or_missing_certificate", 0 }, 22209100258SXin LI { XEVNT_ID & ~CRPT_EVENT, "bad_or_missing_group key", 0 }, 22309100258SXin LI { XEVNT_ERR & ~CRPT_EVENT, "protocol_error", 0 }, 22409100258SXin LI { -1, "", 0 } 2259c2daa00SOllivier Robert }; 2262b15cb3dSCy Schubert #endif /* AUTOKEY */ 2272b15cb3dSCy Schubert 2282b15cb3dSCy Schubert #ifdef KERNEL_PLL 2292b15cb3dSCy Schubert /* 2302b15cb3dSCy Schubert * kernel discipline status bits 2312b15cb3dSCy Schubert */ 2322b15cb3dSCy Schubert static const struct codestring k_st_bits[] = { 2332b15cb3dSCy Schubert # ifdef STA_PLL 23409100258SXin LI { STA_PLL, "pll", 0 }, 2352b15cb3dSCy Schubert # endif 2362b15cb3dSCy Schubert # ifdef STA_PPSFREQ 23709100258SXin LI { STA_PPSFREQ, "ppsfreq", 0 }, 2382b15cb3dSCy Schubert # endif 2392b15cb3dSCy Schubert # ifdef STA_PPSTIME 24009100258SXin LI { STA_PPSTIME, "ppstime", 0 }, 2412b15cb3dSCy Schubert # endif 2422b15cb3dSCy Schubert # ifdef STA_FLL 24309100258SXin LI { STA_FLL, "fll", 0 }, 2442b15cb3dSCy Schubert # endif 2452b15cb3dSCy Schubert # ifdef STA_INS 24609100258SXin LI { STA_INS, "ins", 0 }, 2472b15cb3dSCy Schubert # endif 2482b15cb3dSCy Schubert # ifdef STA_DEL 24909100258SXin LI { STA_DEL, "del", 0 }, 2502b15cb3dSCy Schubert # endif 2512b15cb3dSCy Schubert # ifdef STA_UNSYNC 25209100258SXin LI { STA_UNSYNC, "unsync", 0 }, 2532b15cb3dSCy Schubert # endif 2542b15cb3dSCy Schubert # ifdef STA_FREQHOLD 25509100258SXin LI { STA_FREQHOLD, "freqhold", 0 }, 2562b15cb3dSCy Schubert # endif 2572b15cb3dSCy Schubert # ifdef STA_PPSSIGNAL 25809100258SXin LI { STA_PPSSIGNAL, "ppssignal", 0 }, 2592b15cb3dSCy Schubert # endif 2602b15cb3dSCy Schubert # ifdef STA_PPSJITTER 26109100258SXin LI { STA_PPSJITTER, "ppsjitter", 0 }, 2622b15cb3dSCy Schubert # endif 2632b15cb3dSCy Schubert # ifdef STA_PPSWANDER 26409100258SXin LI { STA_PPSWANDER, "ppswander", 0 }, 2652b15cb3dSCy Schubert # endif 2662b15cb3dSCy Schubert # ifdef STA_PPSERROR 26709100258SXin LI { STA_PPSERROR, "ppserror", 0 }, 2682b15cb3dSCy Schubert # endif 2692b15cb3dSCy Schubert # ifdef STA_CLOCKERR 27009100258SXin LI { STA_CLOCKERR, "clockerr", 0 }, 2712b15cb3dSCy Schubert # endif 2722b15cb3dSCy Schubert # ifdef STA_NANO 27309100258SXin LI { STA_NANO, "nano", 0 }, 2742b15cb3dSCy Schubert # endif 2752b15cb3dSCy Schubert # ifdef STA_MODE 27609100258SXin LI { STA_MODE, "mode=fll", 0 }, 2772b15cb3dSCy Schubert # endif 2782b15cb3dSCy Schubert # ifdef STA_CLK 27909100258SXin LI { STA_CLK, "src=B", 0 }, 2802b15cb3dSCy Schubert # endif 2812b15cb3dSCy Schubert /* not used with getcode(), no terminating entry needed */ 2822b15cb3dSCy Schubert }; 2832b15cb3dSCy Schubert #endif /* KERNEL_PLL */ 2849c2daa00SOllivier Robert 285c0b746e5SOllivier Robert /* Forwards */ 2862b15cb3dSCy Schubert static const char * getcode(int, const struct codestring *); 2872b15cb3dSCy Schubert static const char * getevents(int); 2882b15cb3dSCy Schubert static const char * peer_st_flags(u_char pst); 289c0b746e5SOllivier Robert 290c0b746e5SOllivier Robert /* 291c0b746e5SOllivier Robert * getcode - return string corresponding to code 292c0b746e5SOllivier Robert */ 293c0b746e5SOllivier Robert static const char * 294c0b746e5SOllivier Robert getcode( 295c0b746e5SOllivier Robert int code, 2962b15cb3dSCy Schubert const struct codestring * codetab 297c0b746e5SOllivier Robert ) 298c0b746e5SOllivier Robert { 2992b15cb3dSCy Schubert char * buf; 300c0b746e5SOllivier Robert 301c0b746e5SOllivier Robert while (codetab->code != -1) { 302c0b746e5SOllivier Robert if (codetab->code == code) 30309100258SXin LI return codetab->string1; 304c0b746e5SOllivier Robert codetab++; 305c0b746e5SOllivier Robert } 3062b15cb3dSCy Schubert 3072b15cb3dSCy Schubert LIB_GETBUF(buf); 30809100258SXin LI snprintf(buf, LIB_BUFLENGTH, "%s_%d", codetab->string1, code); 3092b15cb3dSCy Schubert 310c0b746e5SOllivier Robert return buf; 311c0b746e5SOllivier Robert } 312c0b746e5SOllivier Robert 313c0b746e5SOllivier Robert /* 314c0b746e5SOllivier Robert * getevents - return a descriptive string for the event count 315c0b746e5SOllivier Robert */ 316c0b746e5SOllivier Robert static const char * 317c0b746e5SOllivier Robert getevents( 318c0b746e5SOllivier Robert int cnt 319c0b746e5SOllivier Robert ) 320c0b746e5SOllivier Robert { 3212b15cb3dSCy Schubert char * buf; 322c0b746e5SOllivier Robert 323c0b746e5SOllivier Robert if (cnt == 0) 324c0b746e5SOllivier Robert return "no events"; 3252b15cb3dSCy Schubert 3262b15cb3dSCy Schubert LIB_GETBUF(buf); 3272b15cb3dSCy Schubert snprintf(buf, LIB_BUFLENGTH, "%d event%s", cnt, 3282b15cb3dSCy Schubert (1 == cnt) 3292b15cb3dSCy Schubert ? "" 3302b15cb3dSCy Schubert : "s"); 3312b15cb3dSCy Schubert 332c0b746e5SOllivier Robert return buf; 333c0b746e5SOllivier Robert } 334c0b746e5SOllivier Robert 3352b15cb3dSCy Schubert 3362b15cb3dSCy Schubert /* 3372b15cb3dSCy Schubert * decode_bitflags() 3382b15cb3dSCy Schubert * 3392b15cb3dSCy Schubert * returns a human-readable string with a keyword from tab for each bit 3402b15cb3dSCy Schubert * set in bits, separating multiple entries with text of sep2. 3412b15cb3dSCy Schubert */ 3422b15cb3dSCy Schubert static const char * 3432b15cb3dSCy Schubert decode_bitflags( 3442b15cb3dSCy Schubert int bits, 3452b15cb3dSCy Schubert const char * sep2, 3462b15cb3dSCy Schubert const struct codestring * tab, 3472b15cb3dSCy Schubert size_t tab_ct 3482b15cb3dSCy Schubert ) 3492b15cb3dSCy Schubert { 3502b15cb3dSCy Schubert const char * sep; 3512b15cb3dSCy Schubert char * buf; 3522b15cb3dSCy Schubert char * pch; 3532b15cb3dSCy Schubert char * lim; 3542b15cb3dSCy Schubert size_t b; 3552b15cb3dSCy Schubert int rc; 3562b15cb3dSCy Schubert int saved_errno; /* for use in DPRINTF with %m */ 3572b15cb3dSCy Schubert 3582b15cb3dSCy Schubert saved_errno = errno; 3592b15cb3dSCy Schubert LIB_GETBUF(buf); 3602b15cb3dSCy Schubert pch = buf; 3612b15cb3dSCy Schubert lim = buf + LIB_BUFLENGTH; 3622b15cb3dSCy Schubert sep = ""; 3632b15cb3dSCy Schubert 3642b15cb3dSCy Schubert for (b = 0; b < tab_ct; b++) { 36509100258SXin LI const char * flagstr; 36609100258SXin LI 3672b15cb3dSCy Schubert if (tab[b].code & bits) { 36809100258SXin LI flagstr = tab[b].string1; 36909100258SXin LI } else { 37009100258SXin LI flagstr = tab[b].string0; 37109100258SXin LI } 37209100258SXin LI 37309100258SXin LI if (flagstr) { 374f0574f5cSXin LI size_t avail = lim - pch; 375f0574f5cSXin LI rc = snprintf(pch, avail, "%s%s", sep, 37609100258SXin LI flagstr); 377f0574f5cSXin LI if ((size_t)rc >= avail) 3782b15cb3dSCy Schubert goto toosmall; 379f0574f5cSXin LI pch += rc; 3802b15cb3dSCy Schubert sep = sep2; 3812b15cb3dSCy Schubert } 3822b15cb3dSCy Schubert } 3832b15cb3dSCy Schubert 3842b15cb3dSCy Schubert return buf; 3852b15cb3dSCy Schubert 3862b15cb3dSCy Schubert toosmall: 3872b15cb3dSCy Schubert snprintf(buf, LIB_BUFLENGTH, 3882b15cb3dSCy Schubert "decode_bitflags(%s) can't decode 0x%x in %d bytes", 3892b15cb3dSCy Schubert (tab == peer_st_bits) 3902b15cb3dSCy Schubert ? "peer_st" 3912b15cb3dSCy Schubert : 3922b15cb3dSCy Schubert #ifdef KERNEL_PLL 3932b15cb3dSCy Schubert (tab == k_st_bits) 3942b15cb3dSCy Schubert ? "kern_st" 3952b15cb3dSCy Schubert : 3962b15cb3dSCy Schubert #endif 3972b15cb3dSCy Schubert "", 3982b15cb3dSCy Schubert bits, (int)LIB_BUFLENGTH); 3992b15cb3dSCy Schubert errno = saved_errno; 4002b15cb3dSCy Schubert 4012b15cb3dSCy Schubert return buf; 4022b15cb3dSCy Schubert } 4032b15cb3dSCy Schubert 4042b15cb3dSCy Schubert 4052b15cb3dSCy Schubert static const char * 4062b15cb3dSCy Schubert peer_st_flags( 4072b15cb3dSCy Schubert u_char pst 4082b15cb3dSCy Schubert ) 4092b15cb3dSCy Schubert { 4102b15cb3dSCy Schubert return decode_bitflags(pst, ", ", peer_st_bits, 4112b15cb3dSCy Schubert COUNTOF(peer_st_bits)); 4122b15cb3dSCy Schubert } 4132b15cb3dSCy Schubert 4142b15cb3dSCy Schubert 4152b15cb3dSCy Schubert const char * 4162b15cb3dSCy Schubert res_match_flags( 4172b15cb3dSCy Schubert u_short mf 4182b15cb3dSCy Schubert ) 4192b15cb3dSCy Schubert { 4202b15cb3dSCy Schubert return decode_bitflags(mf, " ", res_match_bits, 4212b15cb3dSCy Schubert COUNTOF(res_match_bits)); 4222b15cb3dSCy Schubert } 4232b15cb3dSCy Schubert 4242b15cb3dSCy Schubert 4252b15cb3dSCy Schubert const char * 4262b15cb3dSCy Schubert res_access_flags( 427*2d4e511cSCy Schubert u_int32 af 4282b15cb3dSCy Schubert ) 4292b15cb3dSCy Schubert { 4302b15cb3dSCy Schubert return decode_bitflags(af, " ", res_access_bits, 4312b15cb3dSCy Schubert COUNTOF(res_access_bits)); 4322b15cb3dSCy Schubert } 4332b15cb3dSCy Schubert 4342b15cb3dSCy Schubert 4352b15cb3dSCy Schubert #ifdef KERNEL_PLL 4362b15cb3dSCy Schubert const char * 4372b15cb3dSCy Schubert k_st_flags( 4382b15cb3dSCy Schubert u_int32 st 4392b15cb3dSCy Schubert ) 4402b15cb3dSCy Schubert { 4412b15cb3dSCy Schubert return decode_bitflags(st, " ", k_st_bits, COUNTOF(k_st_bits)); 4422b15cb3dSCy Schubert } 4432b15cb3dSCy Schubert #endif /* KERNEL_PLL */ 4442b15cb3dSCy Schubert 4452b15cb3dSCy Schubert 446c0b746e5SOllivier Robert /* 447c0b746e5SOllivier Robert * statustoa - return a descriptive string for a peer status 448c0b746e5SOllivier Robert */ 449c0b746e5SOllivier Robert char * 450c0b746e5SOllivier Robert statustoa( 451c0b746e5SOllivier Robert int type, 452c0b746e5SOllivier Robert int st 453c0b746e5SOllivier Robert ) 454c0b746e5SOllivier Robert { 455c0b746e5SOllivier Robert char * cb; 4562b15cb3dSCy Schubert char * cc; 457c0b746e5SOllivier Robert u_char pst; 458c0b746e5SOllivier Robert 459c0b746e5SOllivier Robert LIB_GETBUF(cb); 460c0b746e5SOllivier Robert 461c0b746e5SOllivier Robert switch (type) { 4622b15cb3dSCy Schubert 463c0b746e5SOllivier Robert case TYPE_SYS: 4642b15cb3dSCy Schubert snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s, %s", 4652b15cb3dSCy Schubert getcode(CTL_SYS_LI(st), leap_codes), 4662b15cb3dSCy Schubert getcode(CTL_SYS_SOURCE(st), sync_codes), 4672b15cb3dSCy Schubert getevents(CTL_SYS_NEVNT(st)), 4682b15cb3dSCy Schubert getcode(CTL_SYS_EVENT(st), sys_codes)); 469c0b746e5SOllivier Robert break; 470c0b746e5SOllivier Robert 471c0b746e5SOllivier Robert case TYPE_PEER: 472c0b746e5SOllivier Robert pst = (u_char)CTL_PEER_STATVAL(st); 4732b15cb3dSCy Schubert snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s", 4742b15cb3dSCy Schubert peer_st_flags(pst), 4752b15cb3dSCy Schubert getcode(pst & 0x7, select_codes), 4762b15cb3dSCy Schubert getevents(CTL_PEER_NEVNT(st))); 477c0b746e5SOllivier Robert if (CTL_PEER_EVENT(st) != EVNT_UNSPEC) { 4782b15cb3dSCy Schubert cc = cb + strlen(cb); 4792b15cb3dSCy Schubert snprintf(cc, LIB_BUFLENGTH - (cc - cb), ", %s", 4802b15cb3dSCy Schubert getcode(CTL_PEER_EVENT(st), 481c0b746e5SOllivier Robert peer_codes)); 482c0b746e5SOllivier Robert } 483c0b746e5SOllivier Robert break; 484c0b746e5SOllivier Robert 485c0b746e5SOllivier Robert case TYPE_CLOCK: 4862b15cb3dSCy Schubert snprintf(cb, LIB_BUFLENGTH, "%s, %s", 4872b15cb3dSCy Schubert getevents(CTL_SYS_NEVNT(st)), 4882b15cb3dSCy Schubert getcode((st) & 0xf, clock_codes)); 489c0b746e5SOllivier Robert break; 490c0b746e5SOllivier Robert } 4912b15cb3dSCy Schubert 492c0b746e5SOllivier Robert return cb; 493c0b746e5SOllivier Robert } 494c0b746e5SOllivier Robert 495c0b746e5SOllivier Robert const char * 496c0b746e5SOllivier Robert eventstr( 497c0b746e5SOllivier Robert int num 498c0b746e5SOllivier Robert ) 499c0b746e5SOllivier Robert { 5009c2daa00SOllivier Robert if (num & PEER_EVENT) 5019c2daa00SOllivier Robert return (getcode(num & ~PEER_EVENT, peer_codes)); 5022b15cb3dSCy Schubert #ifdef AUTOKEY 5039c2daa00SOllivier Robert else if (num & CRPT_EVENT) 5049c2daa00SOllivier Robert return (getcode(num & ~CRPT_EVENT, crypto_codes)); 5052b15cb3dSCy Schubert #endif /* AUTOKEY */ 5069c2daa00SOllivier Robert else 5079c2daa00SOllivier Robert return (getcode(num, sys_codes)); 508c0b746e5SOllivier Robert } 509c0b746e5SOllivier Robert 510c0b746e5SOllivier Robert const char * 511c0b746e5SOllivier Robert ceventstr( 512c0b746e5SOllivier Robert int num 513c0b746e5SOllivier Robert ) 514c0b746e5SOllivier Robert { 515c0b746e5SOllivier Robert return getcode(num, clock_codes); 516c0b746e5SOllivier Robert } 517