1c0b746e5SOllivier Robert /* 22b15cb3dSCy Schubert * ntpdc_ops.c - subroutines which are called to perform operations by 32b15cb3dSCy Schubert * ntpdc 4c0b746e5SOllivier Robert */ 5c0b746e5SOllivier Robert 6c0b746e5SOllivier Robert #ifdef HAVE_CONFIG_H 7c0b746e5SOllivier Robert # include <config.h> 8c0b746e5SOllivier Robert #endif 9c0b746e5SOllivier Robert 10c0b746e5SOllivier Robert #include <stdio.h> 119c2daa00SOllivier Robert #include <stddef.h> 12224ba2bdSOllivier Robert 13224ba2bdSOllivier Robert #include "ntpdc.h" 142b15cb3dSCy Schubert #include "ntp_net.h" 15224ba2bdSOllivier Robert #include "ntp_control.h" 16224ba2bdSOllivier Robert #include "ntp_refclock.h" 17224ba2bdSOllivier Robert #include "ntp_stdlib.h" 18224ba2bdSOllivier Robert 19c0b746e5SOllivier Robert #include <ctype.h> 20c0b746e5SOllivier Robert #ifdef HAVE_SYS_TIMEX_H 21c0b746e5SOllivier Robert # include <sys/timex.h> 22c0b746e5SOllivier Robert #endif 23c0b746e5SOllivier Robert #if !defined(__bsdi__) && !defined(apollo) 242b15cb3dSCy Schubert #ifdef HAVE_NETINET_IN_H 25c0b746e5SOllivier Robert #include <netinet/in.h> 26c0b746e5SOllivier Robert #endif 272b15cb3dSCy Schubert #endif 28c0b746e5SOllivier Robert 29c0b746e5SOllivier Robert #include <arpa/inet.h> 30c0b746e5SOllivier Robert 31c0b746e5SOllivier Robert /* 322b15cb3dSCy Schubert * utility functions 332b15cb3dSCy Schubert */ 343311ff84SXin LI static int checkitems (size_t, FILE *); 353311ff84SXin LI static int checkitemsize (size_t, size_t); 363311ff84SXin LI static int check1item (size_t, FILE *); 372b15cb3dSCy Schubert 382b15cb3dSCy Schubert /* 39c0b746e5SOllivier Robert * Declarations for command handlers in here 40c0b746e5SOllivier Robert */ 412b15cb3dSCy Schubert static void peerlist (struct parse *, FILE *); 422b15cb3dSCy Schubert static void peers (struct parse *, FILE *); 432b15cb3dSCy Schubert static void doconfig (struct parse *pcmd, FILE *fp, int mode, int refc); 442b15cb3dSCy Schubert static void dmpeers (struct parse *, FILE *); 452b15cb3dSCy Schubert static void dopeers (struct parse *, FILE *, int); 462b15cb3dSCy Schubert static void printpeer (struct info_peer *, FILE *); 472b15cb3dSCy Schubert static void showpeer (struct parse *, FILE *); 482b15cb3dSCy Schubert static void peerstats (struct parse *, FILE *); 492b15cb3dSCy Schubert static void loopinfo (struct parse *, FILE *); 502b15cb3dSCy Schubert static void sysinfo (struct parse *, FILE *); 512b15cb3dSCy Schubert static void sysstats (struct parse *, FILE *); 522b15cb3dSCy Schubert static void iostats (struct parse *, FILE *); 532b15cb3dSCy Schubert static void memstats (struct parse *, FILE *); 542b15cb3dSCy Schubert static void timerstats (struct parse *, FILE *); 552b15cb3dSCy Schubert static void addpeer (struct parse *, FILE *); 562b15cb3dSCy Schubert static void addserver (struct parse *, FILE *); 572b15cb3dSCy Schubert static void addrefclock (struct parse *, FILE *); 582b15cb3dSCy Schubert static void broadcast (struct parse *, FILE *); 592b15cb3dSCy Schubert static void doconfig (struct parse *, FILE *, int, int); 602b15cb3dSCy Schubert static void unconfig (struct parse *, FILE *); 612b15cb3dSCy Schubert static void set (struct parse *, FILE *); 622b15cb3dSCy Schubert static void sys_clear (struct parse *, FILE *); 632b15cb3dSCy Schubert static void doset (struct parse *, FILE *, int); 642b15cb3dSCy Schubert static void reslist (struct parse *, FILE *); 652b15cb3dSCy Schubert static void new_restrict (struct parse *, FILE *); 662b15cb3dSCy Schubert static void unrestrict (struct parse *, FILE *); 672b15cb3dSCy Schubert static void delrestrict (struct parse *, FILE *); 682b15cb3dSCy Schubert static void do_restrict (struct parse *, FILE *, int); 692b15cb3dSCy Schubert static void monlist (struct parse *, FILE *); 702b15cb3dSCy Schubert static void reset (struct parse *, FILE *); 712b15cb3dSCy Schubert static void preset (struct parse *, FILE *); 722b15cb3dSCy Schubert static void readkeys (struct parse *, FILE *); 732b15cb3dSCy Schubert static void trustkey (struct parse *, FILE *); 742b15cb3dSCy Schubert static void untrustkey (struct parse *, FILE *); 752b15cb3dSCy Schubert static void do_trustkey (struct parse *, FILE *, int); 762b15cb3dSCy Schubert static void authinfo (struct parse *, FILE *); 772b15cb3dSCy Schubert static void traps (struct parse *, FILE *); 782b15cb3dSCy Schubert static void addtrap (struct parse *, FILE *); 792b15cb3dSCy Schubert static void clrtrap (struct parse *, FILE *); 802b15cb3dSCy Schubert static void do_addclr_trap (struct parse *, FILE *, int); 812b15cb3dSCy Schubert static void requestkey (struct parse *, FILE *); 822b15cb3dSCy Schubert static void controlkey (struct parse *, FILE *); 832b15cb3dSCy Schubert static void do_changekey (struct parse *, FILE *, int); 842b15cb3dSCy Schubert static void ctlstats (struct parse *, FILE *); 852b15cb3dSCy Schubert static void clockstat (struct parse *, FILE *); 862b15cb3dSCy Schubert static void fudge (struct parse *, FILE *); 872b15cb3dSCy Schubert static void clkbug (struct parse *, FILE *); 882b15cb3dSCy Schubert static void kerninfo (struct parse *, FILE *); 892b15cb3dSCy Schubert static void get_if_stats (struct parse *, FILE *); 902b15cb3dSCy Schubert static void do_if_reload (struct parse *, FILE *); 91c0b746e5SOllivier Robert 92c0b746e5SOllivier Robert /* 93c0b746e5SOllivier Robert * Commands we understand. Ntpdc imports this. 94c0b746e5SOllivier Robert */ 95c0b746e5SOllivier Robert struct xcmd opcmds[] = { 969c2daa00SOllivier Robert { "listpeers", peerlist, { OPT|IP_VERSION, NO, NO, NO }, 979c2daa00SOllivier Robert { "-4|-6", "", "", "" }, 989c2daa00SOllivier Robert "display list of peers the server knows about [IP Version]" }, 999c2daa00SOllivier Robert { "peers", peers, { OPT|IP_VERSION, NO, NO, NO }, 1009c2daa00SOllivier Robert { "-4|-6", "", "", "" }, 1019c2daa00SOllivier Robert "display peer summary information [IP Version]" }, 1029c2daa00SOllivier Robert { "dmpeers", dmpeers, { OPT|IP_VERSION, NO, NO, NO }, 1039c2daa00SOllivier Robert { "-4|-6", "", "", "" }, 1049c2daa00SOllivier Robert "display peer summary info the way Dave Mills likes it (IP Version)" }, 105ea906c41SOllivier Robert { "showpeer", showpeer, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD}, 106c0b746e5SOllivier Robert { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 107c0b746e5SOllivier Robert "display detailed information for one or more peers" }, 108ea906c41SOllivier Robert { "pstats", peerstats, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD }, 109c0b746e5SOllivier Robert { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 110c0b746e5SOllivier Robert "display statistical information for one or more peers" }, 111c0b746e5SOllivier Robert { "loopinfo", loopinfo, { OPT|NTP_STR, NO, NO, NO }, 112c0b746e5SOllivier Robert { "oneline|multiline", "", "", "" }, 113c0b746e5SOllivier Robert "display loop filter information" }, 114c0b746e5SOllivier Robert { "sysinfo", sysinfo, { NO, NO, NO, NO }, 115c0b746e5SOllivier Robert { "", "", "", "" }, 116c0b746e5SOllivier Robert "display local server information" }, 117c0b746e5SOllivier Robert { "sysstats", sysstats, { NO, NO, NO, NO }, 118c0b746e5SOllivier Robert { "", "", "", "" }, 119c0b746e5SOllivier Robert "display local server statistics" }, 120c0b746e5SOllivier Robert { "memstats", memstats, { NO, NO, NO, NO }, 121c0b746e5SOllivier Robert { "", "", "", "" }, 122c0b746e5SOllivier Robert "display peer memory usage statistics" }, 123c0b746e5SOllivier Robert { "iostats", iostats, { NO, NO, NO, NO }, 124c0b746e5SOllivier Robert { "", "", "", "" }, 125c0b746e5SOllivier Robert "display I/O subsystem statistics" }, 126c0b746e5SOllivier Robert { "timerstats", timerstats, { NO, NO, NO, NO }, 127c0b746e5SOllivier Robert { "", "", "", "" }, 128c0b746e5SOllivier Robert "display event timer subsystem statistics" }, 129ea906c41SOllivier Robert { "addpeer", addpeer, { NTP_ADD, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 130ea906c41SOllivier Robert { "addr", "keyid", "version", "minpoll#|prefer|burst|iburst|'minpoll N'|'maxpoll N'|'keyid N'|'version N' ..." }, 131c0b746e5SOllivier Robert "configure a new peer association" }, 132ea906c41SOllivier Robert { "addserver", addserver, { NTP_ADD, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 133ea906c41SOllivier Robert { "addr", "keyid", "version", "minpoll#|prefer|burst|iburst|'minpoll N'|'maxpoll N'|'keyid N'|'version N' ..." }, 134c0b746e5SOllivier Robert "configure a new server" }, 135ea906c41SOllivier Robert { "addrefclock",addrefclock, { NTP_ADD, OPT|NTP_UINT, OPT|NTP_STR, OPT|NTP_STR }, 136c0b746e5SOllivier Robert { "addr", "mode", "minpoll|prefer", "minpoll|prefer" }, 137c0b746e5SOllivier Robert "configure a new server" }, 138ea906c41SOllivier Robert { "broadcast", broadcast, { NTP_ADD, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 139c0b746e5SOllivier Robert { "addr", "keyid", "version", "minpoll" }, 140c0b746e5SOllivier Robert "configure broadcasting time service" }, 141ea906c41SOllivier Robert { "unconfig", unconfig, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD }, 142c0b746e5SOllivier Robert { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 143c0b746e5SOllivier Robert "unconfigure existing peer assocations" }, 144c0b746e5SOllivier Robert { "enable", set, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 145c0b746e5SOllivier Robert { "auth|bclient|monitor|pll|kernel|stats", "...", "...", "..." }, 146c0b746e5SOllivier Robert "set a system flag (auth, bclient, monitor, pll, kernel, stats)" }, 147c0b746e5SOllivier Robert { "disable", sys_clear, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 148c0b746e5SOllivier Robert { "auth|bclient|monitor|pll|kernel|stats", "...", "...", "..." }, 149c0b746e5SOllivier Robert "clear a system flag (auth, bclient, monitor, pll, kernel, stats)" }, 1509c2daa00SOllivier Robert { "reslist", reslist, {OPT|IP_VERSION, NO, NO, NO }, 1519c2daa00SOllivier Robert { "-4|-6", "", "", "" }, 152c0b746e5SOllivier Robert "display the server's restrict list" }, 153ea906c41SOllivier Robert { "restrict", new_restrict, { NTP_ADD, NTP_ADD, NTP_STR, OPT|NTP_STR }, 154c0b746e5SOllivier Robert { "address", "mask", 155224ba2bdSOllivier Robert "ntpport|ignore|noserve|notrust|noquery|nomodify|nopeer|version|kod", 156c0b746e5SOllivier Robert "..." }, 157c0b746e5SOllivier Robert "create restrict entry/add flags to entry" }, 158ea906c41SOllivier Robert { "unrestrict", unrestrict, { NTP_ADD, NTP_ADD, NTP_STR, OPT|NTP_STR }, 159c0b746e5SOllivier Robert { "address", "mask", 160224ba2bdSOllivier Robert "ntpport|ignore|noserve|notrust|noquery|nomodify|nopeer|version|kod", 161c0b746e5SOllivier Robert "..." }, 162c0b746e5SOllivier Robert "remove flags from a restrict entry" }, 163ea906c41SOllivier Robert { "delrestrict", delrestrict, { NTP_ADD, NTP_ADD, OPT|NTP_STR, NO }, 164c0b746e5SOllivier Robert { "address", "mask", "ntpport", "" }, 165c0b746e5SOllivier Robert "delete a restrict entry" }, 166ea906c41SOllivier Robert { "monlist", monlist, { OPT|NTP_INT, NO, NO, NO }, 167c0b746e5SOllivier Robert { "version", "", "", "" }, 168c0b746e5SOllivier Robert "display data the server's monitor routines have collected" }, 169c0b746e5SOllivier Robert { "reset", reset, { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, 1702b15cb3dSCy Schubert { "io|sys|mem|timer|auth|ctl|allpeers", "...", "...", "..." }, 171c0b746e5SOllivier Robert "reset various subsystem statistics counters" }, 172ea906c41SOllivier Robert { "preset", preset, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD }, 173c0b746e5SOllivier Robert { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" }, 174c0b746e5SOllivier Robert "reset stat counters associated with particular peer(s)" }, 175c0b746e5SOllivier Robert { "readkeys", readkeys, { NO, NO, NO, NO }, 176c0b746e5SOllivier Robert { "", "", "", "" }, 177c0b746e5SOllivier Robert "request a reread of the keys file and re-init of system keys" }, 178ea906c41SOllivier Robert { "trustedkey", trustkey, { NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT }, 179c0b746e5SOllivier Robert { "keyid", "keyid", "keyid", "keyid" }, 180c0b746e5SOllivier Robert "add one or more key ID's to the trusted list" }, 181ea906c41SOllivier Robert { "untrustedkey", untrustkey, { NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT }, 182c0b746e5SOllivier Robert { "keyid", "keyid", "keyid", "keyid" }, 183c0b746e5SOllivier Robert "remove one or more key ID's from the trusted list" }, 184c0b746e5SOllivier Robert { "authinfo", authinfo, { NO, NO, NO, NO }, 185c0b746e5SOllivier Robert { "", "", "", "" }, 186c0b746e5SOllivier Robert "display the state of the authentication code" }, 187c0b746e5SOllivier Robert { "traps", traps, { NO, NO, NO, NO }, 188c0b746e5SOllivier Robert { "", "", "", "" }, 189c0b746e5SOllivier Robert "display the traps set in the server" }, 190ea906c41SOllivier Robert { "addtrap", addtrap, { NTP_ADD, OPT|NTP_UINT, OPT|NTP_ADD, NO }, 191c0b746e5SOllivier Robert { "address", "port", "interface", "" }, 192c0b746e5SOllivier Robert "configure a trap in the server" }, 193ea906c41SOllivier Robert { "clrtrap", clrtrap, { NTP_ADD, OPT|NTP_UINT, OPT|NTP_ADD, NO }, 194c0b746e5SOllivier Robert { "address", "port", "interface", "" }, 195c0b746e5SOllivier Robert "remove a trap (configured or otherwise) from the server" }, 196ea906c41SOllivier Robert { "requestkey", requestkey, { NTP_UINT, NO, NO, NO }, 197c0b746e5SOllivier Robert { "keyid", "", "", "" }, 198c0b746e5SOllivier Robert "change the keyid the server uses to authenticate requests" }, 199ea906c41SOllivier Robert { "controlkey", controlkey, { NTP_UINT, NO, NO, NO }, 200c0b746e5SOllivier Robert { "keyid", "", "", "" }, 201c0b746e5SOllivier Robert "change the keyid the server uses to authenticate control messages" }, 202c0b746e5SOllivier Robert { "ctlstats", ctlstats, { NO, NO, NO, NO }, 203c0b746e5SOllivier Robert { "", "", "", "" }, 204c0b746e5SOllivier Robert "display packet count statistics from the control module" }, 205ea906c41SOllivier Robert { "clockstat", clockstat, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD }, 206c0b746e5SOllivier Robert { "address", "address", "address", "address" }, 207c0b746e5SOllivier Robert "display clock status information" }, 208ea906c41SOllivier Robert { "fudge", fudge, { NTP_ADD, NTP_STR, NTP_STR, NO }, 209c0b746e5SOllivier Robert { "address", "time1|time2|val1|val2|flags", "value", "" }, 210c0b746e5SOllivier Robert "set/change one of a clock's fudge factors" }, 211ea906c41SOllivier Robert { "clkbug", clkbug, { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD }, 212c0b746e5SOllivier Robert { "address", "address", "address", "address" }, 213c0b746e5SOllivier Robert "display clock debugging information" }, 214c0b746e5SOllivier Robert { "kerninfo", kerninfo, { NO, NO, NO, NO }, 215c0b746e5SOllivier Robert { "", "", "", "" }, 216c0b746e5SOllivier Robert "display the kernel pll/pps variables" }, 217ea906c41SOllivier Robert { "ifstats", get_if_stats, { NO, NO, NO, NO }, 218ea906c41SOllivier Robert { "", "", "", "" }, 219ea906c41SOllivier Robert "list interface statistics" }, 220ea906c41SOllivier Robert { "ifreload", do_if_reload, { NO, NO, NO, NO }, 221ea906c41SOllivier Robert { "", "", "", "" }, 222ea906c41SOllivier Robert "reload interface configuration" }, 223c0b746e5SOllivier Robert { 0, 0, { NO, NO, NO, NO }, 224c0b746e5SOllivier Robert { "", "", "", "" }, "" } 225c0b746e5SOllivier Robert }; 226c0b746e5SOllivier Robert 227c0b746e5SOllivier Robert /* 228c0b746e5SOllivier Robert * For quick string comparisons 229c0b746e5SOllivier Robert */ 230c0b746e5SOllivier Robert #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) 231c0b746e5SOllivier Robert 2322b15cb3dSCy Schubert /* 2332b15cb3dSCy Schubert * SET_SS_LEN_IF_PRESENT - used by SET_ADDR, SET_ADDRS macros 2342b15cb3dSCy Schubert */ 2352b15cb3dSCy Schubert 2362b15cb3dSCy Schubert #ifdef ISC_PLATFORM_HAVESALEN 2372b15cb3dSCy Schubert #define SET_SS_LEN_IF_PRESENT(psau) \ 2382b15cb3dSCy Schubert do { \ 2392b15cb3dSCy Schubert (psau)->sa.sa_len = SOCKLEN(psau); \ 2402b15cb3dSCy Schubert } while (0) 2412b15cb3dSCy Schubert #else 2422b15cb3dSCy Schubert #define SET_SS_LEN_IF_PRESENT(psau) do { } while (0) 2432b15cb3dSCy Schubert #endif 2442b15cb3dSCy Schubert 2452b15cb3dSCy Schubert /* 2462b15cb3dSCy Schubert * SET_ADDR - setup address for v4/v6 as needed 2472b15cb3dSCy Schubert */ 2482b15cb3dSCy Schubert #define SET_ADDR(address, v6flag, v4addr, v6addr) \ 2492b15cb3dSCy Schubert do { \ 2502b15cb3dSCy Schubert ZERO(address); \ 2512b15cb3dSCy Schubert if (v6flag) { \ 2522b15cb3dSCy Schubert AF(&(address)) = AF_INET6; \ 2532b15cb3dSCy Schubert SOCK_ADDR6(&(address)) = (v6addr); \ 2542b15cb3dSCy Schubert } else { \ 2552b15cb3dSCy Schubert AF(&(address)) = AF_INET; \ 2562b15cb3dSCy Schubert NSRCADR(&(address)) = (v4addr); \ 2572b15cb3dSCy Schubert } \ 2582b15cb3dSCy Schubert SET_SS_LEN_IF_PRESENT(&(address)); \ 2592b15cb3dSCy Schubert } while (0) 2602b15cb3dSCy Schubert 2612b15cb3dSCy Schubert 2622b15cb3dSCy Schubert /* 2632b15cb3dSCy Schubert * SET_ADDRS - setup source and destination addresses for 2642b15cb3dSCy Schubert * v4/v6 as needed 2652b15cb3dSCy Schubert */ 2662b15cb3dSCy Schubert #define SET_ADDRS(a1, a2, info, a1prefix, a2prefix) \ 2672b15cb3dSCy Schubert do { \ 2682b15cb3dSCy Schubert ZERO(a1); \ 2692b15cb3dSCy Schubert ZERO(a2); \ 2702b15cb3dSCy Schubert if ((info)->v6_flag) { \ 2712b15cb3dSCy Schubert AF(&(a1)) = AF_INET6; \ 2722b15cb3dSCy Schubert AF(&(a2)) = AF_INET6; \ 2732b15cb3dSCy Schubert SOCK_ADDR6(&(a1)) = (info)->a1prefix##6; \ 2742b15cb3dSCy Schubert SOCK_ADDR6(&(a2)) = (info)->a2prefix##6; \ 2752b15cb3dSCy Schubert } else { \ 2762b15cb3dSCy Schubert AF(&(a1)) = AF_INET; \ 2772b15cb3dSCy Schubert AF(&(a2)) = AF_INET; \ 2782b15cb3dSCy Schubert NSRCADR(&(a1)) = (info)->a1prefix; \ 2792b15cb3dSCy Schubert NSRCADR(&(a2)) = (info)->a2prefix; \ 2802b15cb3dSCy Schubert } \ 2812b15cb3dSCy Schubert SET_SS_LEN_IF_PRESENT(&(a1)); \ 2822b15cb3dSCy Schubert SET_SS_LEN_IF_PRESENT(&(a2)); \ 2832b15cb3dSCy Schubert } while (0) 2842b15cb3dSCy Schubert 285c0b746e5SOllivier Robert 286c0b746e5SOllivier Robert /* 287c0b746e5SOllivier Robert * checkitems - utility to print a message if no items were returned 288c0b746e5SOllivier Robert */ 289c0b746e5SOllivier Robert static int 290c0b746e5SOllivier Robert checkitems( 2913311ff84SXin LI size_t items, 292c0b746e5SOllivier Robert FILE *fp 293c0b746e5SOllivier Robert ) 294c0b746e5SOllivier Robert { 295c0b746e5SOllivier Robert if (items == 0) { 296c0b746e5SOllivier Robert (void) fprintf(fp, "No data returned in response to query\n"); 297c0b746e5SOllivier Robert return 0; 298c0b746e5SOllivier Robert } 299c0b746e5SOllivier Robert return 1; 300c0b746e5SOllivier Robert } 301c0b746e5SOllivier Robert 302c0b746e5SOllivier Robert 303c0b746e5SOllivier Robert /* 304c0b746e5SOllivier Robert * checkitemsize - utility to print a message if the item size is wrong 305c0b746e5SOllivier Robert */ 306c0b746e5SOllivier Robert static int 307c0b746e5SOllivier Robert checkitemsize( 3083311ff84SXin LI size_t itemsize, 3093311ff84SXin LI size_t expected 310c0b746e5SOllivier Robert ) 311c0b746e5SOllivier Robert { 312c0b746e5SOllivier Robert if (itemsize != expected) { 313c0b746e5SOllivier Robert (void) fprintf(stderr, 3143311ff84SXin LI "***Incorrect item size returned by remote host (%lu should be %lu)\n", 3153311ff84SXin LI (u_long)itemsize, (u_long)expected); 316c0b746e5SOllivier Robert return 0; 317c0b746e5SOllivier Robert } 318c0b746e5SOllivier Robert return 1; 319c0b746e5SOllivier Robert } 320c0b746e5SOllivier Robert 321c0b746e5SOllivier Robert 322c0b746e5SOllivier Robert /* 323c0b746e5SOllivier Robert * check1item - check to make sure we have exactly one item 324c0b746e5SOllivier Robert */ 325c0b746e5SOllivier Robert static int 326c0b746e5SOllivier Robert check1item( 3273311ff84SXin LI size_t items, 328c0b746e5SOllivier Robert FILE *fp 329c0b746e5SOllivier Robert ) 330c0b746e5SOllivier Robert { 331c0b746e5SOllivier Robert if (items == 0) { 332c0b746e5SOllivier Robert (void) fprintf(fp, "No data returned in response to query\n"); 333c0b746e5SOllivier Robert return 0; 334c0b746e5SOllivier Robert } 335c0b746e5SOllivier Robert if (items > 1) { 3363311ff84SXin LI (void) fprintf(fp, "Expected one item in response, got %lu\n", 3373311ff84SXin LI (u_long)items); 338c0b746e5SOllivier Robert return 0; 339c0b746e5SOllivier Robert } 340c0b746e5SOllivier Robert return 1; 341c0b746e5SOllivier Robert } 342c0b746e5SOllivier Robert 343c0b746e5SOllivier Robert 344c0b746e5SOllivier Robert /* 345c0b746e5SOllivier Robert * peerlist - get a short list of peers 346c0b746e5SOllivier Robert */ 347c0b746e5SOllivier Robert /*ARGSUSED*/ 348c0b746e5SOllivier Robert static void 349c0b746e5SOllivier Robert peerlist( 350c0b746e5SOllivier Robert struct parse *pcmd, 351c0b746e5SOllivier Robert FILE *fp 352c0b746e5SOllivier Robert ) 353c0b746e5SOllivier Robert { 354c0b746e5SOllivier Robert struct info_peer_list *plist; 3552b15cb3dSCy Schubert sockaddr_u paddr; 3563311ff84SXin LI size_t items; 3573311ff84SXin LI size_t itemsize; 358c0b746e5SOllivier Robert int res; 359c0b746e5SOllivier Robert 3609c2daa00SOllivier Robert again: 3619c2daa00SOllivier Robert res = doquery(impl_ver, REQ_PEER_LIST, 0, 0, 0, (char *)NULL, &items, 3629c2daa00SOllivier Robert &itemsize, (void *)&plist, 0, 3639c2daa00SOllivier Robert sizeof(struct info_peer_list)); 3649c2daa00SOllivier Robert 3659c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 3669c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 3679c2daa00SOllivier Robert goto again; 3689c2daa00SOllivier Robert } 369c0b746e5SOllivier Robert 370ea906c41SOllivier Robert if (res != 0) 371c0b746e5SOllivier Robert return; 372c0b746e5SOllivier Robert 373c0b746e5SOllivier Robert if (!checkitems(items, fp)) 374c0b746e5SOllivier Robert return; 375c0b746e5SOllivier Robert 3769c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_peer_list)) && 3779c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_peer_list))) 378c0b746e5SOllivier Robert return; 379c0b746e5SOllivier Robert 380c0b746e5SOllivier Robert while (items > 0) { 3812b15cb3dSCy Schubert SET_ADDR(paddr, plist->v6_flag, plist->addr, plist->addr6); 3829c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 3839c2daa00SOllivier Robert ((pcmd->argval->ival == 6) && (plist->v6_flag != 0)) || 3849c2daa00SOllivier Robert ((pcmd->argval->ival == 4) && (plist->v6_flag == 0))) 3859c2daa00SOllivier Robert (void) fprintf(fp, "%-9s %s\n", 3869c2daa00SOllivier Robert modetoa(plist->hmode), 3879c2daa00SOllivier Robert nntohost(&paddr)); 388c0b746e5SOllivier Robert plist++; 389c0b746e5SOllivier Robert items--; 390c0b746e5SOllivier Robert } 391c0b746e5SOllivier Robert } 392c0b746e5SOllivier Robert 393c0b746e5SOllivier Robert 394c0b746e5SOllivier Robert /* 395c0b746e5SOllivier Robert * peers - show peer summary 396c0b746e5SOllivier Robert */ 397c0b746e5SOllivier Robert static void 398c0b746e5SOllivier Robert peers( 399c0b746e5SOllivier Robert struct parse *pcmd, 400c0b746e5SOllivier Robert FILE *fp 401c0b746e5SOllivier Robert ) 402c0b746e5SOllivier Robert { 403c0b746e5SOllivier Robert dopeers(pcmd, fp, 0); 404c0b746e5SOllivier Robert } 405c0b746e5SOllivier Robert 406c0b746e5SOllivier Robert /* 407c0b746e5SOllivier Robert * dmpeers - show peer summary, Dave Mills style 408c0b746e5SOllivier Robert */ 409c0b746e5SOllivier Robert static void 410c0b746e5SOllivier Robert dmpeers( 411c0b746e5SOllivier Robert struct parse *pcmd, 412c0b746e5SOllivier Robert FILE *fp 413c0b746e5SOllivier Robert ) 414c0b746e5SOllivier Robert { 415c0b746e5SOllivier Robert dopeers(pcmd, fp, 1); 416c0b746e5SOllivier Robert } 417c0b746e5SOllivier Robert 418c0b746e5SOllivier Robert 419c0b746e5SOllivier Robert /* 420c0b746e5SOllivier Robert * peers - show peer summary 421c0b746e5SOllivier Robert */ 422c0b746e5SOllivier Robert /*ARGSUSED*/ 423c0b746e5SOllivier Robert static void 424c0b746e5SOllivier Robert dopeers( 425c0b746e5SOllivier Robert struct parse *pcmd, 426c0b746e5SOllivier Robert FILE *fp, 427c0b746e5SOllivier Robert int dmstyle 428c0b746e5SOllivier Robert ) 429c0b746e5SOllivier Robert { 430c0b746e5SOllivier Robert struct info_peer_summary *plist; 4312b15cb3dSCy Schubert sockaddr_u dstadr; 4322b15cb3dSCy Schubert sockaddr_u srcadr; 4333311ff84SXin LI size_t items; 4343311ff84SXin LI size_t itemsize; 435c0b746e5SOllivier Robert int ntp_poll; 436c0b746e5SOllivier Robert int res; 437c0b746e5SOllivier Robert int c; 438c0b746e5SOllivier Robert l_fp tempts; 439c0b746e5SOllivier Robert 4409c2daa00SOllivier Robert again: 4419c2daa00SOllivier Robert res = doquery(impl_ver, REQ_PEER_LIST_SUM, 0, 0, 0, (char *)NULL, 4429c2daa00SOllivier Robert &items, &itemsize, (void *)&plist, 0, 4439c2daa00SOllivier Robert sizeof(struct info_peer_summary)); 4449c2daa00SOllivier Robert 4459c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 4469c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 4479c2daa00SOllivier Robert goto again; 4489c2daa00SOllivier Robert } 449c0b746e5SOllivier Robert 450ea906c41SOllivier Robert if (res != 0) 451c0b746e5SOllivier Robert return; 452c0b746e5SOllivier Robert 453c0b746e5SOllivier Robert if (!checkitems(items, fp)) 454c0b746e5SOllivier Robert return; 455c0b746e5SOllivier Robert 4569c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_peer_summary)) && 4579c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_peer_summary))) 458c0b746e5SOllivier Robert return; 459c0b746e5SOllivier Robert 460c0b746e5SOllivier Robert (void) fprintf(fp, 461c0b746e5SOllivier Robert " remote local st poll reach delay offset disp\n"); 462c0b746e5SOllivier Robert (void) fprintf(fp, 463c0b746e5SOllivier Robert "=======================================================================\n"); 464c0b746e5SOllivier Robert while (items > 0) { 465c0b746e5SOllivier Robert if (!dmstyle) { 466c0b746e5SOllivier Robert if (plist->flags & INFO_FLAG_SYSPEER) 467c0b746e5SOllivier Robert c = '*'; 468c0b746e5SOllivier Robert else if (plist->hmode == MODE_ACTIVE) 469c0b746e5SOllivier Robert c = '+'; 470c0b746e5SOllivier Robert else if (plist->hmode == MODE_PASSIVE) 471c0b746e5SOllivier Robert c = '-'; 472c0b746e5SOllivier Robert else if (plist->hmode == MODE_CLIENT) 473c0b746e5SOllivier Robert c = '='; 474c0b746e5SOllivier Robert else if (plist->hmode == MODE_BROADCAST) 475c0b746e5SOllivier Robert c = '^'; 476c0b746e5SOllivier Robert else if (plist->hmode == MODE_BCLIENT) 477c0b746e5SOllivier Robert c = '~'; 478c0b746e5SOllivier Robert else 479c0b746e5SOllivier Robert c = ' '; 480c0b746e5SOllivier Robert } else { 481c0b746e5SOllivier Robert if (plist->flags & INFO_FLAG_SYSPEER) 482c0b746e5SOllivier Robert c = '*'; 483c0b746e5SOllivier Robert else if (plist->flags & INFO_FLAG_SHORTLIST) 484c0b746e5SOllivier Robert c = '+'; 485c0b746e5SOllivier Robert else if (plist->flags & INFO_FLAG_SEL_CANDIDATE) 486c0b746e5SOllivier Robert c = '.'; 487c0b746e5SOllivier Robert else 488c0b746e5SOllivier Robert c = ' '; 489c0b746e5SOllivier Robert } 490c0b746e5SOllivier Robert NTOHL_FP(&(plist->offset), &tempts); 491c0b746e5SOllivier Robert ntp_poll = 1<<max(min3(plist->ppoll, plist->hpoll, NTP_MAXPOLL), 492c0b746e5SOllivier Robert NTP_MINPOLL); 4932b15cb3dSCy Schubert SET_ADDRS(dstadr, srcadr, plist, dstadr, srcadr); 4949c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 4959c2daa00SOllivier Robert ((pcmd->argval->ival == 6) && (plist->v6_flag != 0)) || 4969c2daa00SOllivier Robert ((pcmd->argval->ival == 4) && (plist->v6_flag == 0))) 497c0b746e5SOllivier Robert (void) fprintf(fp, 4982b15cb3dSCy Schubert "%c%-15.15s %-15.15s %2u %4d %3o %7.7s %9.9s %7.7s\n", 4999c2daa00SOllivier Robert c, nntohost(&srcadr), stoa(&dstadr), 500c0b746e5SOllivier Robert plist->stratum, ntp_poll, plist->reach, 501c0b746e5SOllivier Robert fptoa(NTOHS_FP(plist->delay), 5), 502c0b746e5SOllivier Robert lfptoa(&tempts, 6), 503c0b746e5SOllivier Robert ufptoa(NTOHS_FP(plist->dispersion), 5)); 504c0b746e5SOllivier Robert plist++; 505c0b746e5SOllivier Robert items--; 506c0b746e5SOllivier Robert } 507c0b746e5SOllivier Robert } 508c0b746e5SOllivier Robert 509c0b746e5SOllivier Robert /* Convert a refid & stratum (in host order) to a string */ 510c0b746e5SOllivier Robert static char * 511c0b746e5SOllivier Robert refid_string( 512c0b746e5SOllivier Robert u_int32 refid, 513c0b746e5SOllivier Robert int stratum 514c0b746e5SOllivier Robert ) 515c0b746e5SOllivier Robert { 516c0b746e5SOllivier Robert if (stratum <= 1) { 517c0b746e5SOllivier Robert static char junk[5]; 518c0b746e5SOllivier Robert junk[4] = 0; 5192b15cb3dSCy Schubert memcpy(junk, &refid, 4); 520c0b746e5SOllivier Robert return junk; 521c0b746e5SOllivier Robert } 522c0b746e5SOllivier Robert 523c0b746e5SOllivier Robert return numtoa(refid); 524c0b746e5SOllivier Robert } 525c0b746e5SOllivier Robert 526ea906c41SOllivier Robert static void 527ea906c41SOllivier Robert print_pflag( 528ea906c41SOllivier Robert FILE * fp, 529ea906c41SOllivier Robert u_int32 flags 530ea906c41SOllivier Robert ) 531ea906c41SOllivier Robert { 5322b15cb3dSCy Schubert static const char none[] = ""; 5332b15cb3dSCy Schubert static const char comma[] = ","; 5342b15cb3dSCy Schubert const char *dlim; 535ea906c41SOllivier Robert 5362b15cb3dSCy Schubert if (0 == flags) { 5372b15cb3dSCy Schubert fprintf(fp, " none\n"); 5382b15cb3dSCy Schubert return; 5392b15cb3dSCy Schubert } 5402b15cb3dSCy Schubert dlim = none; 541ea906c41SOllivier Robert if (flags & INFO_FLAG_SYSPEER) { 5422b15cb3dSCy Schubert fprintf(fp, " system_peer"); 5432b15cb3dSCy Schubert dlim = comma; 544ea906c41SOllivier Robert } 545ea906c41SOllivier Robert if (flags & INFO_FLAG_CONFIG) { 5462b15cb3dSCy Schubert fprintf(fp, "%s config", dlim); 5472b15cb3dSCy Schubert dlim = comma; 548ea906c41SOllivier Robert } 549ea906c41SOllivier Robert if (flags & INFO_FLAG_REFCLOCK) { 5502b15cb3dSCy Schubert fprintf(fp, "%s refclock", dlim); 5512b15cb3dSCy Schubert dlim = comma; 552ea906c41SOllivier Robert } 553ea906c41SOllivier Robert if (flags & INFO_FLAG_AUTHENABLE) { 5542b15cb3dSCy Schubert fprintf(fp, "%s auth", dlim); 5552b15cb3dSCy Schubert dlim = comma; 556ea906c41SOllivier Robert } 557ea906c41SOllivier Robert if (flags & INFO_FLAG_PREFER) { 5582b15cb3dSCy Schubert fprintf(fp, "%s prefer", dlim); 5592b15cb3dSCy Schubert dlim = comma; 560ea906c41SOllivier Robert } 561ea906c41SOllivier Robert if (flags & INFO_FLAG_IBURST) { 5622b15cb3dSCy Schubert fprintf(fp, "%s iburst", dlim); 5632b15cb3dSCy Schubert dlim = comma; 564ea906c41SOllivier Robert } 565ea906c41SOllivier Robert if (flags & INFO_FLAG_BURST) { 5662b15cb3dSCy Schubert fprintf(fp, "%s burst", dlim); 5672b15cb3dSCy Schubert dlim = comma; 568ea906c41SOllivier Robert } 5692b15cb3dSCy Schubert if (flags & INFO_FLAG_SEL_CANDIDATE) { 5702b15cb3dSCy Schubert fprintf(fp, "%s candidate", dlim); 5712b15cb3dSCy Schubert dlim = comma; 572ea906c41SOllivier Robert } 5732b15cb3dSCy Schubert if (flags & INFO_FLAG_SHORTLIST) { 5742b15cb3dSCy Schubert fprintf(fp, "%s shortlist", dlim); 5752b15cb3dSCy Schubert dlim = comma; 5762b15cb3dSCy Schubert } 5772b15cb3dSCy Schubert fprintf(fp, "\n"); 578ea906c41SOllivier Robert } 579c0b746e5SOllivier Robert /* 580c0b746e5SOllivier Robert * printpeer - print detail information for a peer 581c0b746e5SOllivier Robert */ 582c0b746e5SOllivier Robert static void 583c0b746e5SOllivier Robert printpeer( 584c0b746e5SOllivier Robert register struct info_peer *pp, 585c0b746e5SOllivier Robert FILE *fp 586c0b746e5SOllivier Robert ) 587c0b746e5SOllivier Robert { 588c0b746e5SOllivier Robert register int i; 589c0b746e5SOllivier Robert l_fp tempts; 5902b15cb3dSCy Schubert sockaddr_u srcadr, dstadr; 591c0b746e5SOllivier Robert 5922b15cb3dSCy Schubert SET_ADDRS(dstadr, srcadr, pp, dstadr, srcadr); 5932b15cb3dSCy Schubert 594c0b746e5SOllivier Robert (void) fprintf(fp, "remote %s, local %s\n", 5959c2daa00SOllivier Robert stoa(&srcadr), stoa(&dstadr)); 596c0b746e5SOllivier Robert (void) fprintf(fp, "hmode %s, pmode %s, stratum %d, precision %d\n", 597c0b746e5SOllivier Robert modetoa(pp->hmode), modetoa(pp->pmode), 598c0b746e5SOllivier Robert pp->stratum, pp->precision); 599c0b746e5SOllivier Robert 600c0b746e5SOllivier Robert (void) fprintf(fp, 601c0b746e5SOllivier Robert "leap %c%c, refid [%s], rootdistance %s, rootdispersion %s\n", 602c0b746e5SOllivier Robert pp->leap & 0x2 ? '1' : '0', 603c0b746e5SOllivier Robert pp->leap & 0x1 ? '1' : '0', 604c0b746e5SOllivier Robert refid_string(pp->refid, pp->stratum), fptoa(NTOHS_FP(pp->rootdelay), 5), 605c0b746e5SOllivier Robert ufptoa(NTOHS_FP(pp->rootdispersion), 5)); 606c0b746e5SOllivier Robert 607c0b746e5SOllivier Robert (void) fprintf(fp, 608c0b746e5SOllivier Robert "ppoll %d, hpoll %d, keyid %lu, version %d, association %u\n", 609c0b746e5SOllivier Robert pp->ppoll, pp->hpoll, (u_long)pp->keyid, pp->version, ntohs(pp->associd)); 610c0b746e5SOllivier Robert 611c0b746e5SOllivier Robert (void) fprintf(fp, 612224ba2bdSOllivier Robert "reach %03o, unreach %d, flash 0x%04x, ", 613224ba2bdSOllivier Robert pp->reach, pp->unreach, pp->flash2); 614c0b746e5SOllivier Robert 615c0b746e5SOllivier Robert (void) fprintf(fp, "boffset %s, ttl/mode %d\n", 616c0b746e5SOllivier Robert fptoa(NTOHS_FP(pp->estbdelay), 5), pp->ttl); 617c0b746e5SOllivier Robert 618c0b746e5SOllivier Robert (void) fprintf(fp, "timer %lds, flags", (long)ntohl(pp->timer)); 619ea906c41SOllivier Robert print_pflag(fp, pp->flags); 620c0b746e5SOllivier Robert 621c0b746e5SOllivier Robert NTOHL_FP(&pp->reftime, &tempts); 622c0b746e5SOllivier Robert (void) fprintf(fp, "reference time: %s\n", 623c0b746e5SOllivier Robert prettydate(&tempts)); 624c0b746e5SOllivier Robert NTOHL_FP(&pp->org, &tempts); 625c0b746e5SOllivier Robert (void) fprintf(fp, "originate timestamp: %s\n", 626c0b746e5SOllivier Robert prettydate(&tempts)); 627c0b746e5SOllivier Robert NTOHL_FP(&pp->rec, &tempts); 628c0b746e5SOllivier Robert (void) fprintf(fp, "receive timestamp: %s\n", 629c0b746e5SOllivier Robert prettydate(&tempts)); 630c0b746e5SOllivier Robert NTOHL_FP(&pp->xmt, &tempts); 631c0b746e5SOllivier Robert (void) fprintf(fp, "transmit timestamp: %s\n", 632c0b746e5SOllivier Robert prettydate(&tempts)); 633c0b746e5SOllivier Robert 634c0b746e5SOllivier Robert (void) fprintf(fp, "filter delay: "); 635c0b746e5SOllivier Robert for (i = 0; i < NTP_SHIFT; i++) { 636c0b746e5SOllivier Robert (void) fprintf(fp, " %-8.8s", 637c0b746e5SOllivier Robert fptoa(NTOHS_FP(pp->filtdelay[i]), 5)); 638c0b746e5SOllivier Robert if (i == (NTP_SHIFT>>1)-1) 639c0b746e5SOllivier Robert (void) fprintf(fp, "\n "); 640c0b746e5SOllivier Robert } 641c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 642c0b746e5SOllivier Robert 643c0b746e5SOllivier Robert (void) fprintf(fp, "filter offset:"); 644c0b746e5SOllivier Robert for (i = 0; i < NTP_SHIFT; i++) { 645c0b746e5SOllivier Robert NTOHL_FP(&pp->filtoffset[i], &tempts); 646c0b746e5SOllivier Robert (void) fprintf(fp, " %-8.8s", lfptoa(&tempts, 6)); 647c0b746e5SOllivier Robert if (i == (NTP_SHIFT>>1)-1) 648c0b746e5SOllivier Robert (void) fprintf(fp, "\n "); 649c0b746e5SOllivier Robert } 650c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 651c0b746e5SOllivier Robert 652c0b746e5SOllivier Robert (void) fprintf(fp, "filter order: "); 653c0b746e5SOllivier Robert for (i = 0; i < NTP_SHIFT; i++) { 654c0b746e5SOllivier Robert (void) fprintf(fp, " %-8d", pp->order[i]); 655c0b746e5SOllivier Robert if (i == (NTP_SHIFT>>1)-1) 656c0b746e5SOllivier Robert (void) fprintf(fp, "\n "); 657c0b746e5SOllivier Robert } 658c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 659c0b746e5SOllivier Robert 660c0b746e5SOllivier Robert 661c0b746e5SOllivier Robert NTOHL_FP(&pp->offset, &tempts); 662c0b746e5SOllivier Robert (void) fprintf(fp, 663c0b746e5SOllivier Robert "offset %s, delay %s, error bound %s, filter error %s\n", 664c0b746e5SOllivier Robert lfptoa(&tempts, 6), fptoa(NTOHS_FP(pp->delay), 5), 665c0b746e5SOllivier Robert ufptoa(NTOHS_FP(pp->dispersion), 5), 666c0b746e5SOllivier Robert ufptoa(NTOHS_FP(pp->selectdisp), 5)); 667c0b746e5SOllivier Robert } 668c0b746e5SOllivier Robert 669c0b746e5SOllivier Robert 670c0b746e5SOllivier Robert /* 671c0b746e5SOllivier Robert * showpeer - show detailed information for a peer 672c0b746e5SOllivier Robert */ 673c0b746e5SOllivier Robert static void 674c0b746e5SOllivier Robert showpeer( 675c0b746e5SOllivier Robert struct parse *pcmd, 676c0b746e5SOllivier Robert FILE *fp 677c0b746e5SOllivier Robert ) 678c0b746e5SOllivier Robert { 679c0b746e5SOllivier Robert struct info_peer *pp; 680c0b746e5SOllivier Robert /* 4 is the maximum number of peers which will fit in a packet */ 6819c2daa00SOllivier Robert struct info_peer_list *pl, plist[min(MAXARGS, 4)]; 6823311ff84SXin LI size_t qitemlim; 6833311ff84SXin LI size_t qitems; 6843311ff84SXin LI size_t items; 6853311ff84SXin LI size_t itemsize; 686c0b746e5SOllivier Robert int res; 6879c2daa00SOllivier Robert int sendsize; 688c0b746e5SOllivier Robert 6899c2daa00SOllivier Robert again: 6909c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 6919c2daa00SOllivier Robert sendsize = sizeof(struct info_peer_list); 6929c2daa00SOllivier Robert else 6939c2daa00SOllivier Robert sendsize = v4sizeof(struct info_peer_list); 6949c2daa00SOllivier Robert 6952b15cb3dSCy Schubert qitemlim = min(pcmd->nargs, COUNTOF(plist)); 6962b15cb3dSCy Schubert for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) { 6972b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[qitems].netnum)) { 6982b15cb3dSCy Schubert pl->addr = NSRCADR(&pcmd->argval[qitems].netnum); 6999c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 7009c2daa00SOllivier Robert pl->v6_flag = 0; 7019c2daa00SOllivier Robert } else { 7029c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 7039c2daa00SOllivier Robert fprintf(stderr, 7049c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 7059c2daa00SOllivier Robert return; 7069c2daa00SOllivier Robert } 7072b15cb3dSCy Schubert pl->addr6 = SOCK_ADDR6(&pcmd->argval[qitems].netnum); 7089c2daa00SOllivier Robert pl->v6_flag = 1; 7099c2daa00SOllivier Robert } 7109c2daa00SOllivier Robert pl->port = (u_short)s_port; 7119c2daa00SOllivier Robert pl->hmode = pl->flags = 0; 7122b15cb3dSCy Schubert pl = (void *)((char *)pl + sendsize); 713c0b746e5SOllivier Robert } 714c0b746e5SOllivier Robert 7159c2daa00SOllivier Robert res = doquery(impl_ver, REQ_PEER_INFO, 0, qitems, 7169c2daa00SOllivier Robert sendsize, (char *)plist, &items, 7179c2daa00SOllivier Robert &itemsize, (void *)&pp, 0, sizeof(struct info_peer)); 7189c2daa00SOllivier Robert 7199c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 7209c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 7219c2daa00SOllivier Robert goto again; 7229c2daa00SOllivier Robert } 723c0b746e5SOllivier Robert 724ea906c41SOllivier Robert if (res != 0) 725c0b746e5SOllivier Robert return; 726c0b746e5SOllivier Robert 727c0b746e5SOllivier Robert if (!checkitems(items, fp)) 728c0b746e5SOllivier Robert return; 729c0b746e5SOllivier Robert 7309c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_peer)) && 7319c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_peer))) 732c0b746e5SOllivier Robert return; 733c0b746e5SOllivier Robert 734c0b746e5SOllivier Robert while (items-- > 0) { 735c0b746e5SOllivier Robert printpeer(pp, fp); 736c0b746e5SOllivier Robert if (items > 0) 7372b15cb3dSCy Schubert fprintf(fp, "\n"); 738c0b746e5SOllivier Robert pp++; 739c0b746e5SOllivier Robert } 740c0b746e5SOllivier Robert } 741c0b746e5SOllivier Robert 742c0b746e5SOllivier Robert 743c0b746e5SOllivier Robert /* 744c0b746e5SOllivier Robert * peerstats - return statistics for a peer 745c0b746e5SOllivier Robert */ 746c0b746e5SOllivier Robert static void 747c0b746e5SOllivier Robert peerstats( 748c0b746e5SOllivier Robert struct parse *pcmd, 749c0b746e5SOllivier Robert FILE *fp 750c0b746e5SOllivier Robert ) 751c0b746e5SOllivier Robert { 752c0b746e5SOllivier Robert struct info_peer_stats *pp; 753c0b746e5SOllivier Robert /* 4 is the maximum number of peers which will fit in a packet */ 7549c2daa00SOllivier Robert struct info_peer_list *pl, plist[min(MAXARGS, 4)]; 7552b15cb3dSCy Schubert sockaddr_u src, dst; 7563311ff84SXin LI size_t qitemlim; 7573311ff84SXin LI size_t qitems; 7583311ff84SXin LI size_t items; 7593311ff84SXin LI size_t itemsize; 760c0b746e5SOllivier Robert int res; 7613311ff84SXin LI size_t sendsize; 762c0b746e5SOllivier Robert 7639c2daa00SOllivier Robert again: 7649c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 7659c2daa00SOllivier Robert sendsize = sizeof(struct info_peer_list); 7669c2daa00SOllivier Robert else 7679c2daa00SOllivier Robert sendsize = v4sizeof(struct info_peer_list); 7689c2daa00SOllivier Robert 7692b15cb3dSCy Schubert ZERO(plist); 7702b15cb3dSCy Schubert 7712b15cb3dSCy Schubert qitemlim = min(pcmd->nargs, COUNTOF(plist)); 7722b15cb3dSCy Schubert for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) { 7732b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[qitems].netnum)) { 7742b15cb3dSCy Schubert pl->addr = NSRCADR(&pcmd->argval[qitems].netnum); 7759c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 7769c2daa00SOllivier Robert pl->v6_flag = 0; 7779c2daa00SOllivier Robert } else { 7789c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 7799c2daa00SOllivier Robert fprintf(stderr, 7809c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 7819c2daa00SOllivier Robert return; 7829c2daa00SOllivier Robert } 7832b15cb3dSCy Schubert pl->addr6 = SOCK_ADDR6(&pcmd->argval[qitems].netnum); 7849c2daa00SOllivier Robert pl->v6_flag = 1; 7859c2daa00SOllivier Robert } 7869c2daa00SOllivier Robert pl->port = (u_short)s_port; 7879c2daa00SOllivier Robert pl->hmode = plist[qitems].flags = 0; 7882b15cb3dSCy Schubert pl = (void *)((char *)pl + sendsize); 789c0b746e5SOllivier Robert } 790c0b746e5SOllivier Robert 7919c2daa00SOllivier Robert res = doquery(impl_ver, REQ_PEER_STATS, 0, qitems, 7929c2daa00SOllivier Robert sendsize, (char *)plist, &items, 7939c2daa00SOllivier Robert &itemsize, (void *)&pp, 0, 7949c2daa00SOllivier Robert sizeof(struct info_peer_stats)); 7959c2daa00SOllivier Robert 7969c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 7979c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 7989c2daa00SOllivier Robert goto again; 7999c2daa00SOllivier Robert } 800c0b746e5SOllivier Robert 801ea906c41SOllivier Robert if (res != 0) 802c0b746e5SOllivier Robert return; 803c0b746e5SOllivier Robert 804c0b746e5SOllivier Robert if (!checkitems(items, fp)) 805c0b746e5SOllivier Robert return; 806c0b746e5SOllivier Robert 8079c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_peer_stats)) && 8089c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_peer_stats))) 809c0b746e5SOllivier Robert return; 810c0b746e5SOllivier Robert 811c0b746e5SOllivier Robert while (items-- > 0) { 8122b15cb3dSCy Schubert ZERO_SOCK(&dst); 8132b15cb3dSCy Schubert ZERO_SOCK(&src); 8149c2daa00SOllivier Robert if (pp->v6_flag != 0) { 8152b15cb3dSCy Schubert AF(&dst) = AF_INET6; 8162b15cb3dSCy Schubert AF(&src) = AF_INET6; 8172b15cb3dSCy Schubert SOCK_ADDR6(&dst) = pp->dstadr6; 8182b15cb3dSCy Schubert SOCK_ADDR6(&src) = pp->srcadr6; 8199c2daa00SOllivier Robert } else { 8202b15cb3dSCy Schubert AF(&dst) = AF_INET; 8212b15cb3dSCy Schubert AF(&src) = AF_INET; 8222b15cb3dSCy Schubert NSRCADR(&dst) = pp->dstadr; 8232b15cb3dSCy Schubert NSRCADR(&src) = pp->srcadr; 8249c2daa00SOllivier Robert } 8252b15cb3dSCy Schubert #ifdef ISC_PLATFORM_HAVESALEN 8262b15cb3dSCy Schubert src.sa.sa_len = SOCKLEN(&src); 8272b15cb3dSCy Schubert dst.sa.sa_len = SOCKLEN(&dst); 8289c2daa00SOllivier Robert #endif 8292b15cb3dSCy Schubert fprintf(fp, "remote host: %s\n", 8309c2daa00SOllivier Robert nntohost(&src)); 8312b15cb3dSCy Schubert fprintf(fp, "local interface: %s\n", 8329c2daa00SOllivier Robert stoa(&dst)); 8332b15cb3dSCy Schubert fprintf(fp, "time last received: %lus\n", 8342b15cb3dSCy Schubert (u_long)ntohl(pp->timereceived)); 8352b15cb3dSCy Schubert fprintf(fp, "time until next send: %lus\n", 8362b15cb3dSCy Schubert (u_long)ntohl(pp->timetosend)); 8372b15cb3dSCy Schubert fprintf(fp, "reachability change: %lus\n", 8382b15cb3dSCy Schubert (u_long)ntohl(pp->timereachable)); 8392b15cb3dSCy Schubert fprintf(fp, "packets sent: %lu\n", 8402b15cb3dSCy Schubert (u_long)ntohl(pp->sent)); 8412b15cb3dSCy Schubert fprintf(fp, "packets received: %lu\n", 8422b15cb3dSCy Schubert (u_long)ntohl(pp->processed)); 8432b15cb3dSCy Schubert fprintf(fp, "bad authentication: %lu\n", 8442b15cb3dSCy Schubert (u_long)ntohl(pp->badauth)); 8452b15cb3dSCy Schubert fprintf(fp, "bogus origin: %lu\n", 8462b15cb3dSCy Schubert (u_long)ntohl(pp->bogusorg)); 8472b15cb3dSCy Schubert fprintf(fp, "duplicate: %lu\n", 8482b15cb3dSCy Schubert (u_long)ntohl(pp->oldpkt)); 8492b15cb3dSCy Schubert fprintf(fp, "bad dispersion: %lu\n", 8502b15cb3dSCy Schubert (u_long)ntohl(pp->seldisp)); 8512b15cb3dSCy Schubert fprintf(fp, "bad reference time: %lu\n", 8522b15cb3dSCy Schubert (u_long)ntohl(pp->selbroken)); 8532b15cb3dSCy Schubert fprintf(fp, "candidate order: %u\n", 8542b15cb3dSCy Schubert pp->candidate); 855c0b746e5SOllivier Robert if (items > 0) 8562b15cb3dSCy Schubert fprintf(fp, "\n"); 8572b15cb3dSCy Schubert fprintf(fp, "flags: "); 858ea906c41SOllivier Robert print_pflag(fp, ntohs(pp->flags)); 859c0b746e5SOllivier Robert pp++; 860c0b746e5SOllivier Robert } 861c0b746e5SOllivier Robert } 862c0b746e5SOllivier Robert 863c0b746e5SOllivier Robert 864c0b746e5SOllivier Robert /* 865c0b746e5SOllivier Robert * loopinfo - show loop filter information 866c0b746e5SOllivier Robert */ 867c0b746e5SOllivier Robert static void 868c0b746e5SOllivier Robert loopinfo( 869c0b746e5SOllivier Robert struct parse *pcmd, 870c0b746e5SOllivier Robert FILE *fp 871c0b746e5SOllivier Robert ) 872c0b746e5SOllivier Robert { 873c0b746e5SOllivier Robert struct info_loop *il; 8743311ff84SXin LI size_t items; 8753311ff84SXin LI size_t itemsize; 876c0b746e5SOllivier Robert int oneline = 0; 877c0b746e5SOllivier Robert int res; 878c0b746e5SOllivier Robert l_fp tempts; 879c0b746e5SOllivier Robert 880c0b746e5SOllivier Robert if (pcmd->nargs > 0) { 881c0b746e5SOllivier Robert if (STREQ(pcmd->argval[0].string, "oneline")) 882c0b746e5SOllivier Robert oneline = 1; 883c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[0].string, "multiline")) 884c0b746e5SOllivier Robert oneline = 0; 885c0b746e5SOllivier Robert else { 886c0b746e5SOllivier Robert (void) fprintf(stderr, "How many lines?\n"); 887c0b746e5SOllivier Robert return; 888c0b746e5SOllivier Robert } 889c0b746e5SOllivier Robert } 890c0b746e5SOllivier Robert 8919c2daa00SOllivier Robert again: 8929c2daa00SOllivier Robert res = doquery(impl_ver, REQ_LOOP_INFO, 0, 0, 0, (char *)NULL, 8939c2daa00SOllivier Robert &items, &itemsize, (void *)&il, 0, 8949c2daa00SOllivier Robert sizeof(struct info_loop)); 8959c2daa00SOllivier Robert 8969c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 8979c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 8989c2daa00SOllivier Robert goto again; 8999c2daa00SOllivier Robert } 900c0b746e5SOllivier Robert 901ea906c41SOllivier Robert if (res != 0) 902c0b746e5SOllivier Robert return; 903c0b746e5SOllivier Robert 904c0b746e5SOllivier Robert if (!check1item(items, fp)) 905c0b746e5SOllivier Robert return; 906c0b746e5SOllivier Robert 907c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_loop))) 908c0b746e5SOllivier Robert return; 909c0b746e5SOllivier Robert 910c0b746e5SOllivier Robert if (oneline) { 911c0b746e5SOllivier Robert l_fp temp2ts; 912c0b746e5SOllivier Robert 913c0b746e5SOllivier Robert NTOHL_FP(&il->last_offset, &tempts); 914c0b746e5SOllivier Robert NTOHL_FP(&il->drift_comp, &temp2ts); 915c0b746e5SOllivier Robert 916c0b746e5SOllivier Robert (void) fprintf(fp, 917c0b746e5SOllivier Robert "offset %s, frequency %s, time_const %ld, watchdog %ld\n", 918c0b746e5SOllivier Robert lfptoa(&tempts, 6), 919c0b746e5SOllivier Robert lfptoa(&temp2ts, 3), 9202b15cb3dSCy Schubert (long)(int32)ntohl((u_long)il->compliance), 921ea906c41SOllivier Robert (u_long)ntohl((u_long)il->watchdog_timer)); 922c0b746e5SOllivier Robert } else { 923c0b746e5SOllivier Robert NTOHL_FP(&il->last_offset, &tempts); 924c0b746e5SOllivier Robert (void) fprintf(fp, "offset: %s s\n", 925c0b746e5SOllivier Robert lfptoa(&tempts, 6)); 926c0b746e5SOllivier Robert NTOHL_FP(&il->drift_comp, &tempts); 927c0b746e5SOllivier Robert (void) fprintf(fp, "frequency: %s ppm\n", 928c0b746e5SOllivier Robert lfptoa(&tempts, 3)); 929c0b746e5SOllivier Robert (void) fprintf(fp, "poll adjust: %ld\n", 9302b15cb3dSCy Schubert (long)(int32)ntohl(il->compliance)); 931c0b746e5SOllivier Robert (void) fprintf(fp, "watchdog timer: %ld s\n", 932c0b746e5SOllivier Robert (u_long)ntohl(il->watchdog_timer)); 933c0b746e5SOllivier Robert } 934c0b746e5SOllivier Robert } 935c0b746e5SOllivier Robert 936c0b746e5SOllivier Robert 937c0b746e5SOllivier Robert /* 938c0b746e5SOllivier Robert * sysinfo - show current system state 939c0b746e5SOllivier Robert */ 940c0b746e5SOllivier Robert /*ARGSUSED*/ 941c0b746e5SOllivier Robert static void 942c0b746e5SOllivier Robert sysinfo( 943c0b746e5SOllivier Robert struct parse *pcmd, 944c0b746e5SOllivier Robert FILE *fp 945c0b746e5SOllivier Robert ) 946c0b746e5SOllivier Robert { 947c0b746e5SOllivier Robert struct info_sys *is; 9482b15cb3dSCy Schubert sockaddr_u peeraddr; 9493311ff84SXin LI size_t items; 9503311ff84SXin LI size_t itemsize; 951c0b746e5SOllivier Robert int res; 952c0b746e5SOllivier Robert l_fp tempts; 953c0b746e5SOllivier Robert 9549c2daa00SOllivier Robert again: 9559c2daa00SOllivier Robert res = doquery(impl_ver, REQ_SYS_INFO, 0, 0, 0, (char *)NULL, 9569c2daa00SOllivier Robert &items, &itemsize, (void *)&is, 0, 9579c2daa00SOllivier Robert sizeof(struct info_sys)); 9589c2daa00SOllivier Robert 9599c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 9609c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 9619c2daa00SOllivier Robert goto again; 9629c2daa00SOllivier Robert } 963c0b746e5SOllivier Robert 964ea906c41SOllivier Robert if (res != 0) 965c0b746e5SOllivier Robert return; 966c0b746e5SOllivier Robert 967c0b746e5SOllivier Robert if (!check1item(items, fp)) 968c0b746e5SOllivier Robert return; 969c0b746e5SOllivier Robert 9709c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_sys)) && 9719c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_sys))) 972c0b746e5SOllivier Robert return; 973c0b746e5SOllivier Robert 9742b15cb3dSCy Schubert SET_ADDR(peeraddr, is->v6_flag, is->peer, is->peer6); 9752b15cb3dSCy Schubert 9769c2daa00SOllivier Robert (void) fprintf(fp, "system peer: %s\n", nntohost(&peeraddr)); 977c0b746e5SOllivier Robert (void) fprintf(fp, "system peer mode: %s\n", modetoa(is->peer_mode)); 978c0b746e5SOllivier Robert (void) fprintf(fp, "leap indicator: %c%c\n", 979c0b746e5SOllivier Robert is->leap & 0x2 ? '1' : '0', 980c0b746e5SOllivier Robert is->leap & 0x1 ? '1' : '0'); 981c0b746e5SOllivier Robert (void) fprintf(fp, "stratum: %d\n", (int)is->stratum); 982c0b746e5SOllivier Robert (void) fprintf(fp, "precision: %d\n", (int)is->precision); 983c0b746e5SOllivier Robert (void) fprintf(fp, "root distance: %s s\n", 984c0b746e5SOllivier Robert fptoa(NTOHS_FP(is->rootdelay), 5)); 985c0b746e5SOllivier Robert (void) fprintf(fp, "root dispersion: %s s\n", 986c0b746e5SOllivier Robert ufptoa(NTOHS_FP(is->rootdispersion), 5)); 987c0b746e5SOllivier Robert (void) fprintf(fp, "reference ID: [%s]\n", 988c0b746e5SOllivier Robert refid_string(is->refid, is->stratum)); 989c0b746e5SOllivier Robert NTOHL_FP(&is->reftime, &tempts); 990c0b746e5SOllivier Robert (void) fprintf(fp, "reference time: %s\n", prettydate(&tempts)); 991c0b746e5SOllivier Robert 992c0b746e5SOllivier Robert (void) fprintf(fp, "system flags: "); 993c0b746e5SOllivier Robert if ((is->flags & (INFO_FLAG_BCLIENT | INFO_FLAG_AUTHENABLE | 994ce265a54SOllivier Robert INFO_FLAG_NTP | INFO_FLAG_KERNEL| INFO_FLAG_CAL | 995c0b746e5SOllivier Robert INFO_FLAG_PPS_SYNC | INFO_FLAG_MONITOR | INFO_FLAG_FILEGEN)) == 0) { 996c0b746e5SOllivier Robert (void) fprintf(fp, "none\n"); 997c0b746e5SOllivier Robert } else { 998c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_BCLIENT) 999c0b746e5SOllivier Robert (void) fprintf(fp, "bclient "); 1000c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_AUTHENTICATE) 1001c0b746e5SOllivier Robert (void) fprintf(fp, "auth "); 1002c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_MONITOR) 1003c0b746e5SOllivier Robert (void) fprintf(fp, "monitor "); 1004c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_NTP) 1005c0b746e5SOllivier Robert (void) fprintf(fp, "ntp "); 1006c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_KERNEL) 1007c0b746e5SOllivier Robert (void) fprintf(fp, "kernel "); 1008c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_FILEGEN) 1009c0b746e5SOllivier Robert (void) fprintf(fp, "stats "); 1010ce265a54SOllivier Robert if (is->flags & INFO_FLAG_CAL) 1011ce265a54SOllivier Robert (void) fprintf(fp, "calibrate "); 1012c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_PPS_SYNC) 1013ce265a54SOllivier Robert (void) fprintf(fp, "pps "); 1014c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 1015c0b746e5SOllivier Robert } 1016c0b746e5SOllivier Robert (void) fprintf(fp, "jitter: %s s\n", 1017c0b746e5SOllivier Robert fptoa(ntohl(is->frequency), 6)); 1018c0b746e5SOllivier Robert (void) fprintf(fp, "stability: %s ppm\n", 1019c0b746e5SOllivier Robert ufptoa(ntohl(is->stability), 3)); 1020c0b746e5SOllivier Robert (void) fprintf(fp, "broadcastdelay: %s s\n", 1021c0b746e5SOllivier Robert fptoa(NTOHS_FP(is->bdelay), 6)); 1022c0b746e5SOllivier Robert NTOHL_FP(&is->authdelay, &tempts); 1023c0b746e5SOllivier Robert (void) fprintf(fp, "authdelay: %s s\n", lfptoa(&tempts, 6)); 1024c0b746e5SOllivier Robert } 1025c0b746e5SOllivier Robert 1026c0b746e5SOllivier Robert 1027c0b746e5SOllivier Robert /* 1028c0b746e5SOllivier Robert * sysstats - print system statistics 1029c0b746e5SOllivier Robert */ 1030c0b746e5SOllivier Robert /*ARGSUSED*/ 1031c0b746e5SOllivier Robert static void 1032c0b746e5SOllivier Robert sysstats( 1033c0b746e5SOllivier Robert struct parse *pcmd, 1034c0b746e5SOllivier Robert FILE *fp 1035c0b746e5SOllivier Robert ) 1036c0b746e5SOllivier Robert { 1037c0b746e5SOllivier Robert struct info_sys_stats *ss; 10383311ff84SXin LI size_t items; 10393311ff84SXin LI size_t itemsize; 1040c0b746e5SOllivier Robert int res; 1041c0b746e5SOllivier Robert 10429c2daa00SOllivier Robert again: 10439c2daa00SOllivier Robert res = doquery(impl_ver, REQ_SYS_STATS, 0, 0, 0, (char *)NULL, 10449c2daa00SOllivier Robert &items, &itemsize, (void *)&ss, 0, 10459c2daa00SOllivier Robert sizeof(struct info_sys_stats)); 10469c2daa00SOllivier Robert 10479c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 10489c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 10499c2daa00SOllivier Robert goto again; 10509c2daa00SOllivier Robert } 1051c0b746e5SOllivier Robert 1052ea906c41SOllivier Robert if (res != 0) 1053c0b746e5SOllivier Robert return; 1054c0b746e5SOllivier Robert 1055c0b746e5SOllivier Robert if (!check1item(items, fp)) 1056c0b746e5SOllivier Robert return; 1057c0b746e5SOllivier Robert 1058c0b746e5SOllivier Robert if (itemsize != sizeof(struct info_sys_stats) && 1059c0b746e5SOllivier Robert itemsize != sizeof(struct old_info_sys_stats)) { 1060c0b746e5SOllivier Robert /* issue warning according to new structure size */ 1061c0b746e5SOllivier Robert checkitemsize(itemsize, sizeof(struct info_sys_stats)); 1062c0b746e5SOllivier Robert return; 1063c0b746e5SOllivier Robert } 10642b15cb3dSCy Schubert fprintf(fp, "time since restart: %lu\n", 1065c0b746e5SOllivier Robert (u_long)ntohl(ss->timeup)); 10662b15cb3dSCy Schubert fprintf(fp, "time since reset: %lu\n", 1067c0b746e5SOllivier Robert (u_long)ntohl(ss->timereset)); 10682b15cb3dSCy Schubert fprintf(fp, "packets received: %lu\n", 10699c2daa00SOllivier Robert (u_long)ntohl(ss->received)); 10702b15cb3dSCy Schubert fprintf(fp, "packets processed: %lu\n", 1071c0b746e5SOllivier Robert (u_long)ntohl(ss->processed)); 10722b15cb3dSCy Schubert fprintf(fp, "current version: %lu\n", 10739c2daa00SOllivier Robert (u_long)ntohl(ss->newversionpkt)); 10742b15cb3dSCy Schubert fprintf(fp, "previous version: %lu\n", 10759c2daa00SOllivier Robert (u_long)ntohl(ss->oldversionpkt)); 10762b15cb3dSCy Schubert fprintf(fp, "declined: %lu\n", 10779c2daa00SOllivier Robert (u_long)ntohl(ss->unknownversion)); 10782b15cb3dSCy Schubert fprintf(fp, "access denied: %lu\n", 10799c2daa00SOllivier Robert (u_long)ntohl(ss->denied)); 10802b15cb3dSCy Schubert fprintf(fp, "bad length or format: %lu\n", 10819c2daa00SOllivier Robert (u_long)ntohl(ss->badlength)); 10822b15cb3dSCy Schubert fprintf(fp, "bad authentication: %lu\n", 1083c0b746e5SOllivier Robert (u_long)ntohl(ss->badauth)); 1084c0b746e5SOllivier Robert if (itemsize != sizeof(struct info_sys_stats)) 1085c0b746e5SOllivier Robert return; 1086c0b746e5SOllivier Robert 10872b15cb3dSCy Schubert fprintf(fp, "rate exceeded: %lu\n", 1088c0b746e5SOllivier Robert (u_long)ntohl(ss->limitrejected)); 1089c0b746e5SOllivier Robert } 1090c0b746e5SOllivier Robert 1091c0b746e5SOllivier Robert 1092c0b746e5SOllivier Robert 1093c0b746e5SOllivier Robert /* 1094c0b746e5SOllivier Robert * iostats - print I/O statistics 1095c0b746e5SOllivier Robert */ 1096c0b746e5SOllivier Robert /*ARGSUSED*/ 1097c0b746e5SOllivier Robert static void 1098c0b746e5SOllivier Robert iostats( 1099c0b746e5SOllivier Robert struct parse *pcmd, 1100c0b746e5SOllivier Robert FILE *fp 1101c0b746e5SOllivier Robert ) 1102c0b746e5SOllivier Robert { 1103c0b746e5SOllivier Robert struct info_io_stats *io; 11043311ff84SXin LI size_t items; 11053311ff84SXin LI size_t itemsize; 1106c0b746e5SOllivier Robert int res; 1107c0b746e5SOllivier Robert 11089c2daa00SOllivier Robert again: 11092b15cb3dSCy Schubert res = doquery(impl_ver, REQ_IO_STATS, 0, 0, 0, NULL, &items, 11102b15cb3dSCy Schubert &itemsize, (void *)&io, 0, sizeof(*io)); 11119c2daa00SOllivier Robert 11129c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 11139c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 11149c2daa00SOllivier Robert goto again; 11159c2daa00SOllivier Robert } 1116c0b746e5SOllivier Robert 1117ea906c41SOllivier Robert if (res != 0) 1118c0b746e5SOllivier Robert return; 1119c0b746e5SOllivier Robert 1120c0b746e5SOllivier Robert if (!check1item(items, fp)) 1121c0b746e5SOllivier Robert return; 1122c0b746e5SOllivier Robert 11232b15cb3dSCy Schubert if (!checkitemsize(itemsize, sizeof(*io))) 1124c0b746e5SOllivier Robert return; 1125c0b746e5SOllivier Robert 11262b15cb3dSCy Schubert fprintf(fp, "time since reset: %lu\n", 1127c0b746e5SOllivier Robert (u_long)ntohl(io->timereset)); 11282b15cb3dSCy Schubert fprintf(fp, "receive buffers: %u\n", 11292b15cb3dSCy Schubert (u_int)ntohs(io->totalrecvbufs)); 11302b15cb3dSCy Schubert fprintf(fp, "free receive buffers: %u\n", 11312b15cb3dSCy Schubert (u_int)ntohs(io->freerecvbufs)); 11322b15cb3dSCy Schubert fprintf(fp, "used receive buffers: %u\n", 11332b15cb3dSCy Schubert (u_int)ntohs(io->fullrecvbufs)); 11342b15cb3dSCy Schubert fprintf(fp, "low water refills: %u\n", 11352b15cb3dSCy Schubert (u_int)ntohs(io->lowwater)); 11362b15cb3dSCy Schubert fprintf(fp, "dropped packets: %lu\n", 1137c0b746e5SOllivier Robert (u_long)ntohl(io->dropped)); 11382b15cb3dSCy Schubert fprintf(fp, "ignored packets: %lu\n", 1139c0b746e5SOllivier Robert (u_long)ntohl(io->ignored)); 11402b15cb3dSCy Schubert fprintf(fp, "received packets: %lu\n", 1141c0b746e5SOllivier Robert (u_long)ntohl(io->received)); 11422b15cb3dSCy Schubert fprintf(fp, "packets sent: %lu\n", 1143c0b746e5SOllivier Robert (u_long)ntohl(io->sent)); 11442b15cb3dSCy Schubert fprintf(fp, "packets not sent: %lu\n", 1145c0b746e5SOllivier Robert (u_long)ntohl(io->notsent)); 11462b15cb3dSCy Schubert fprintf(fp, "interrupts handled: %lu\n", 1147c0b746e5SOllivier Robert (u_long)ntohl(io->interrupts)); 11482b15cb3dSCy Schubert fprintf(fp, "received by int: %lu\n", 1149c0b746e5SOllivier Robert (u_long)ntohl(io->int_received)); 1150c0b746e5SOllivier Robert } 1151c0b746e5SOllivier Robert 1152c0b746e5SOllivier Robert 1153c0b746e5SOllivier Robert /* 1154c0b746e5SOllivier Robert * memstats - print peer memory statistics 1155c0b746e5SOllivier Robert */ 1156c0b746e5SOllivier Robert /*ARGSUSED*/ 1157c0b746e5SOllivier Robert static void 1158c0b746e5SOllivier Robert memstats( 1159c0b746e5SOllivier Robert struct parse *pcmd, 1160c0b746e5SOllivier Robert FILE *fp 1161c0b746e5SOllivier Robert ) 1162c0b746e5SOllivier Robert { 1163c0b746e5SOllivier Robert struct info_mem_stats *mem; 1164c0b746e5SOllivier Robert int i; 11653311ff84SXin LI size_t items; 11663311ff84SXin LI size_t itemsize; 1167c0b746e5SOllivier Robert int res; 1168c0b746e5SOllivier Robert 11699c2daa00SOllivier Robert again: 11702b15cb3dSCy Schubert res = doquery(impl_ver, REQ_MEM_STATS, 0, 0, 0, NULL, &items, 11712b15cb3dSCy Schubert &itemsize, (void *)&mem, 0, sizeof(*mem)); 11729c2daa00SOllivier Robert 11739c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 11749c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 11759c2daa00SOllivier Robert goto again; 11769c2daa00SOllivier Robert } 1177c0b746e5SOllivier Robert 1178ea906c41SOllivier Robert if (res != 0) 1179c0b746e5SOllivier Robert return; 1180c0b746e5SOllivier Robert 1181c0b746e5SOllivier Robert if (!check1item(items, fp)) 1182c0b746e5SOllivier Robert return; 1183c0b746e5SOllivier Robert 11842b15cb3dSCy Schubert if (!checkitemsize(itemsize, sizeof(*mem))) 1185c0b746e5SOllivier Robert return; 1186c0b746e5SOllivier Robert 11872b15cb3dSCy Schubert fprintf(fp, "time since reset: %lu\n", 1188c0b746e5SOllivier Robert (u_long)ntohl(mem->timereset)); 11892b15cb3dSCy Schubert fprintf(fp, "total peer memory: %u\n", 11902b15cb3dSCy Schubert (u_int)ntohs(mem->totalpeermem)); 11912b15cb3dSCy Schubert fprintf(fp, "free peer memory: %u\n", 11922b15cb3dSCy Schubert (u_int)ntohs(mem->freepeermem)); 11932b15cb3dSCy Schubert fprintf(fp, "calls to findpeer: %lu\n", 1194c0b746e5SOllivier Robert (u_long)ntohl(mem->findpeer_calls)); 11952b15cb3dSCy Schubert fprintf(fp, "new peer allocations: %lu\n", 1196c0b746e5SOllivier Robert (u_long)ntohl(mem->allocations)); 11972b15cb3dSCy Schubert fprintf(fp, "peer demobilizations: %lu\n", 1198c0b746e5SOllivier Robert (u_long)ntohl(mem->demobilizations)); 1199c0b746e5SOllivier Robert 12002b15cb3dSCy Schubert fprintf(fp, "hash table counts: "); 1201ea906c41SOllivier Robert for (i = 0; i < NTP_HASH_SIZE; i++) { 12022b15cb3dSCy Schubert fprintf(fp, "%4d", (int)mem->hashcount[i]); 12032b15cb3dSCy Schubert if ((i % 8) == 7 && i != (NTP_HASH_SIZE-1)) 12042b15cb3dSCy Schubert fprintf(fp, "\n "); 1205c0b746e5SOllivier Robert } 12062b15cb3dSCy Schubert fprintf(fp, "\n"); 1207c0b746e5SOllivier Robert } 1208c0b746e5SOllivier Robert 1209c0b746e5SOllivier Robert 1210c0b746e5SOllivier Robert 1211c0b746e5SOllivier Robert /* 1212c0b746e5SOllivier Robert * timerstats - print timer statistics 1213c0b746e5SOllivier Robert */ 1214c0b746e5SOllivier Robert /*ARGSUSED*/ 1215c0b746e5SOllivier Robert static void 1216c0b746e5SOllivier Robert timerstats( 1217c0b746e5SOllivier Robert struct parse *pcmd, 1218c0b746e5SOllivier Robert FILE *fp 1219c0b746e5SOllivier Robert ) 1220c0b746e5SOllivier Robert { 1221c0b746e5SOllivier Robert struct info_timer_stats *tim; 12223311ff84SXin LI size_t items; 12233311ff84SXin LI size_t itemsize; 1224c0b746e5SOllivier Robert int res; 1225c0b746e5SOllivier Robert 12269c2daa00SOllivier Robert again: 12272b15cb3dSCy Schubert res = doquery(impl_ver, REQ_TIMER_STATS, 0, 0, 0, NULL, &items, 12282b15cb3dSCy Schubert &itemsize, (void *)&tim, 0, sizeof(*tim)); 12299c2daa00SOllivier Robert 12309c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 12319c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 12329c2daa00SOllivier Robert goto again; 12339c2daa00SOllivier Robert } 1234c0b746e5SOllivier Robert 1235ea906c41SOllivier Robert if (res != 0) 1236c0b746e5SOllivier Robert return; 1237c0b746e5SOllivier Robert 1238c0b746e5SOllivier Robert if (!check1item(items, fp)) 1239c0b746e5SOllivier Robert return; 1240c0b746e5SOllivier Robert 12412b15cb3dSCy Schubert if (!checkitemsize(itemsize, sizeof(*tim))) 1242c0b746e5SOllivier Robert return; 1243c0b746e5SOllivier Robert 12442b15cb3dSCy Schubert fprintf(fp, "time since reset: %lu\n", 1245c0b746e5SOllivier Robert (u_long)ntohl(tim->timereset)); 12462b15cb3dSCy Schubert fprintf(fp, "alarms handled: %lu\n", 1247c0b746e5SOllivier Robert (u_long)ntohl(tim->alarms)); 12482b15cb3dSCy Schubert fprintf(fp, "alarm overruns: %lu\n", 1249c0b746e5SOllivier Robert (u_long)ntohl(tim->overflows)); 12502b15cb3dSCy Schubert fprintf(fp, "calls to transmit: %lu\n", 1251c0b746e5SOllivier Robert (u_long)ntohl(tim->xmtcalls)); 1252c0b746e5SOllivier Robert } 1253c0b746e5SOllivier Robert 1254c0b746e5SOllivier Robert 1255c0b746e5SOllivier Robert /* 1256c0b746e5SOllivier Robert * addpeer - configure an active mode association 1257c0b746e5SOllivier Robert */ 1258c0b746e5SOllivier Robert static void 1259c0b746e5SOllivier Robert addpeer( 1260c0b746e5SOllivier Robert struct parse *pcmd, 1261c0b746e5SOllivier Robert FILE *fp 1262c0b746e5SOllivier Robert ) 1263c0b746e5SOllivier Robert { 1264c0b746e5SOllivier Robert doconfig(pcmd, fp, MODE_ACTIVE, 0); 1265c0b746e5SOllivier Robert } 1266c0b746e5SOllivier Robert 1267c0b746e5SOllivier Robert 1268c0b746e5SOllivier Robert /* 1269c0b746e5SOllivier Robert * addserver - configure a client mode association 1270c0b746e5SOllivier Robert */ 1271c0b746e5SOllivier Robert static void 1272c0b746e5SOllivier Robert addserver( 1273c0b746e5SOllivier Robert struct parse *pcmd, 1274c0b746e5SOllivier Robert FILE *fp 1275c0b746e5SOllivier Robert ) 1276c0b746e5SOllivier Robert { 1277c0b746e5SOllivier Robert doconfig(pcmd, fp, MODE_CLIENT, 0); 1278c0b746e5SOllivier Robert } 1279c0b746e5SOllivier Robert 1280c0b746e5SOllivier Robert /* 1281c0b746e5SOllivier Robert * addrefclock - configure a reference clock association 1282c0b746e5SOllivier Robert */ 1283c0b746e5SOllivier Robert static void 1284c0b746e5SOllivier Robert addrefclock( 1285c0b746e5SOllivier Robert struct parse *pcmd, 1286c0b746e5SOllivier Robert FILE *fp 1287c0b746e5SOllivier Robert ) 1288c0b746e5SOllivier Robert { 1289c0b746e5SOllivier Robert doconfig(pcmd, fp, MODE_CLIENT, 1); 1290c0b746e5SOllivier Robert } 1291c0b746e5SOllivier Robert 1292c0b746e5SOllivier Robert /* 1293c0b746e5SOllivier Robert * broadcast - configure a broadcast mode association 1294c0b746e5SOllivier Robert */ 1295c0b746e5SOllivier Robert static void 1296c0b746e5SOllivier Robert broadcast( 1297c0b746e5SOllivier Robert struct parse *pcmd, 1298c0b746e5SOllivier Robert FILE *fp 1299c0b746e5SOllivier Robert ) 1300c0b746e5SOllivier Robert { 1301c0b746e5SOllivier Robert doconfig(pcmd, fp, MODE_BROADCAST, 0); 1302c0b746e5SOllivier Robert } 1303c0b746e5SOllivier Robert 1304c0b746e5SOllivier Robert 1305c0b746e5SOllivier Robert /* 1306c0b746e5SOllivier Robert * config - configure a new peer association 1307c0b746e5SOllivier Robert */ 1308c0b746e5SOllivier Robert static void 1309c0b746e5SOllivier Robert doconfig( 1310c0b746e5SOllivier Robert struct parse *pcmd, 1311c0b746e5SOllivier Robert FILE *fp, 1312c0b746e5SOllivier Robert int mode, 1313c0b746e5SOllivier Robert int refc 1314c0b746e5SOllivier Robert ) 1315c0b746e5SOllivier Robert { 1316c0b746e5SOllivier Robert struct conf_peer cpeer; 13173311ff84SXin LI size_t items; 13183311ff84SXin LI size_t itemsize; 13193311ff84SXin LI const char *dummy; 1320c0b746e5SOllivier Robert u_long keyid; 1321c0b746e5SOllivier Robert u_int version; 1322c0b746e5SOllivier Robert u_char minpoll; 1323ea906c41SOllivier Robert u_char maxpoll; 1324c0b746e5SOllivier Robert u_int flags; 1325c0b746e5SOllivier Robert u_char cmode; 1326c0b746e5SOllivier Robert int res; 13279c2daa00SOllivier Robert int sendsize; 1328ea906c41SOllivier Robert int numtyp; 13292b15cb3dSCy Schubert long val; 1330c0b746e5SOllivier Robert 13319c2daa00SOllivier Robert again: 1332c0b746e5SOllivier Robert keyid = 0; 1333ea906c41SOllivier Robert version = 3; 1334c0b746e5SOllivier Robert flags = 0; 13352b15cb3dSCy Schubert res = FALSE; 1336c0b746e5SOllivier Robert cmode = 0; 1337c0b746e5SOllivier Robert minpoll = NTP_MINDPOLL; 1338ea906c41SOllivier Robert maxpoll = NTP_MAXDPOLL; 1339ea906c41SOllivier Robert numtyp = 1; 1340ea906c41SOllivier Robert if (refc) 1341ea906c41SOllivier Robert numtyp = 5; 1342c0b746e5SOllivier Robert 13439c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 13449c2daa00SOllivier Robert sendsize = sizeof(struct conf_peer); 13459c2daa00SOllivier Robert else 13469c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_peer); 13479c2daa00SOllivier Robert 1348ea906c41SOllivier Robert items = 1; 13492b15cb3dSCy Schubert while (pcmd->nargs > (size_t)items) { 1350c0b746e5SOllivier Robert if (STREQ(pcmd->argval[items].string, "prefer")) 1351c0b746e5SOllivier Robert flags |= CONF_FLAG_PREFER; 1352c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "burst")) 1353c0b746e5SOllivier Robert flags |= CONF_FLAG_BURST; 1354ea906c41SOllivier Robert else if (STREQ(pcmd->argval[items].string, "iburst")) 1355ea906c41SOllivier Robert flags |= CONF_FLAG_IBURST; 1356ea906c41SOllivier Robert else if (!refc && STREQ(pcmd->argval[items].string, "keyid")) 1357ea906c41SOllivier Robert numtyp = 1; 1358ea906c41SOllivier Robert else if (!refc && STREQ(pcmd->argval[items].string, "version")) 1359ea906c41SOllivier Robert numtyp = 2; 1360ea906c41SOllivier Robert else if (STREQ(pcmd->argval[items].string, "minpoll")) 1361ea906c41SOllivier Robert numtyp = 3; 1362ea906c41SOllivier Robert else if (STREQ(pcmd->argval[items].string, "maxpoll")) 1363ea906c41SOllivier Robert numtyp = 4; 1364c0b746e5SOllivier Robert else { 1365ea906c41SOllivier Robert if (!atoint(pcmd->argval[items].string, &val)) 1366ea906c41SOllivier Robert numtyp = 0; 1367ea906c41SOllivier Robert switch (numtyp) { 1368ea906c41SOllivier Robert case 1: 1369ea906c41SOllivier Robert keyid = val; 1370ea906c41SOllivier Robert numtyp = 2; 1371ea906c41SOllivier Robert break; 1372ea906c41SOllivier Robert 1373ea906c41SOllivier Robert case 2: 1374ea906c41SOllivier Robert version = (u_int)val; 1375ea906c41SOllivier Robert numtyp = 0; 1376ea906c41SOllivier Robert break; 1377ea906c41SOllivier Robert 1378ea906c41SOllivier Robert case 3: 1379ea906c41SOllivier Robert minpoll = (u_char)val; 1380ea906c41SOllivier Robert numtyp = 0; 1381ea906c41SOllivier Robert break; 1382ea906c41SOllivier Robert 1383ea906c41SOllivier Robert case 4: 1384ea906c41SOllivier Robert maxpoll = (u_char)val; 1385ea906c41SOllivier Robert numtyp = 0; 1386ea906c41SOllivier Robert break; 1387ea906c41SOllivier Robert 1388ea906c41SOllivier Robert case 5: 1389ea906c41SOllivier Robert cmode = (u_char)val; 1390ea906c41SOllivier Robert numtyp = 0; 1391ea906c41SOllivier Robert break; 1392ea906c41SOllivier Robert 1393ea906c41SOllivier Robert default: 13942b15cb3dSCy Schubert fprintf(fp, "*** '%s' not understood\n", 1395c0b746e5SOllivier Robert pcmd->argval[items].string); 13962b15cb3dSCy Schubert res = TRUE; 1397ea906c41SOllivier Robert numtyp = 0; 1398c0b746e5SOllivier Robert } 1399ea906c41SOllivier Robert if (val < 0) { 14002b15cb3dSCy Schubert fprintf(stderr, 1401ea906c41SOllivier Robert "*** Value '%s' should be unsigned\n", 1402ea906c41SOllivier Robert pcmd->argval[items].string); 14032b15cb3dSCy Schubert res = TRUE; 1404c0b746e5SOllivier Robert } 1405c0b746e5SOllivier Robert } 1406c0b746e5SOllivier Robert items++; 1407c0b746e5SOllivier Robert } 1408ea906c41SOllivier Robert if (keyid > 0) 1409ea906c41SOllivier Robert flags |= CONF_FLAG_AUTHENABLE; 14102b15cb3dSCy Schubert if (version > NTP_VERSION || version < NTP_OLDVERSION) { 14112b15cb3dSCy Schubert fprintf(fp, "***invalid version number: %u\n", 1412ea906c41SOllivier Robert version); 14132b15cb3dSCy Schubert res = TRUE; 1414ea906c41SOllivier Robert } 1415ea906c41SOllivier Robert if (minpoll < NTP_MINPOLL || minpoll > NTP_MAXPOLL || 1416ea906c41SOllivier Robert maxpoll < NTP_MINPOLL || maxpoll > NTP_MAXPOLL || 1417ea906c41SOllivier Robert minpoll > maxpoll) { 14182b15cb3dSCy Schubert fprintf(fp, "***min/max-poll must be within %d..%d\n", 1419ea906c41SOllivier Robert NTP_MINPOLL, NTP_MAXPOLL); 14202b15cb3dSCy Schubert res = TRUE; 1421ea906c41SOllivier Robert } 1422c0b746e5SOllivier Robert 1423c0b746e5SOllivier Robert if (res) 1424c0b746e5SOllivier Robert return; 1425c0b746e5SOllivier Robert 14262b15cb3dSCy Schubert ZERO(cpeer); 1427c0b746e5SOllivier Robert 14282b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[0].netnum)) { 14292b15cb3dSCy Schubert cpeer.peeraddr = NSRCADR(&pcmd->argval[0].netnum); 14309c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 14319c2daa00SOllivier Robert cpeer.v6_flag = 0; 14329c2daa00SOllivier Robert } else { 14339c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 14349c2daa00SOllivier Robert fprintf(stderr, 14359c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 14369c2daa00SOllivier Robert return; 14379c2daa00SOllivier Robert } 14382b15cb3dSCy Schubert cpeer.peeraddr6 = SOCK_ADDR6(&pcmd->argval[0].netnum); 14399c2daa00SOllivier Robert cpeer.v6_flag = 1; 14409c2daa00SOllivier Robert } 1441c0b746e5SOllivier Robert cpeer.hmode = (u_char) mode; 1442c0b746e5SOllivier Robert cpeer.keyid = keyid; 1443c0b746e5SOllivier Robert cpeer.version = (u_char) version; 1444c0b746e5SOllivier Robert cpeer.minpoll = minpoll; 1445ea906c41SOllivier Robert cpeer.maxpoll = maxpoll; 1446c0b746e5SOllivier Robert cpeer.flags = (u_char)flags; 1447c0b746e5SOllivier Robert cpeer.ttl = cmode; 1448c0b746e5SOllivier Robert 14499c2daa00SOllivier Robert res = doquery(impl_ver, REQ_CONFIG, 1, 1, 14509c2daa00SOllivier Robert sendsize, (char *)&cpeer, &items, 14519c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_peer)); 14529c2daa00SOllivier Robert 14539c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 14549c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 14559c2daa00SOllivier Robert goto again; 14569c2daa00SOllivier Robert } 1457c0b746e5SOllivier Robert 1458ce265a54SOllivier Robert if (res == INFO_ERR_FMT) { 1459ce265a54SOllivier Robert (void) fprintf(fp, 1460ce265a54SOllivier Robert "***Retrying command with old conf_peer size\n"); 14619c2daa00SOllivier Robert res = doquery(impl_ver, REQ_CONFIG, 1, 1, 1462ce265a54SOllivier Robert sizeof(struct old_conf_peer), (char *)&cpeer, 14639c2daa00SOllivier Robert &items, &itemsize, &dummy, 0, 14649c2daa00SOllivier Robert sizeof(struct conf_peer)); 1465ce265a54SOllivier Robert } 1466c0b746e5SOllivier Robert if (res == 0) 1467c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 1468c0b746e5SOllivier Robert return; 1469c0b746e5SOllivier Robert } 1470c0b746e5SOllivier Robert 1471c0b746e5SOllivier Robert 1472c0b746e5SOllivier Robert /* 1473c0b746e5SOllivier Robert * unconfig - unconfigure some associations 1474c0b746e5SOllivier Robert */ 1475c0b746e5SOllivier Robert static void 1476c0b746e5SOllivier Robert unconfig( 1477c0b746e5SOllivier Robert struct parse *pcmd, 1478c0b746e5SOllivier Robert FILE *fp 1479c0b746e5SOllivier Robert ) 1480c0b746e5SOllivier Robert { 1481c0b746e5SOllivier Robert /* 8 is the maximum number of peers which will fit in a packet */ 14829c2daa00SOllivier Robert struct conf_unpeer *pl, plist[min(MAXARGS, 8)]; 14833311ff84SXin LI size_t qitemlim; 14843311ff84SXin LI size_t qitems; 14853311ff84SXin LI size_t items; 14863311ff84SXin LI size_t itemsize; 14873311ff84SXin LI const char *dummy; 1488c0b746e5SOllivier Robert int res; 14893311ff84SXin LI size_t sendsize; 1490c0b746e5SOllivier Robert 14919c2daa00SOllivier Robert again: 14929c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 14939c2daa00SOllivier Robert sendsize = sizeof(struct conf_unpeer); 14949c2daa00SOllivier Robert else 14959c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_unpeer); 14969c2daa00SOllivier Robert 14972b15cb3dSCy Schubert qitemlim = min(pcmd->nargs, COUNTOF(plist)); 14982b15cb3dSCy Schubert for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) { 14992b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[0].netnum)) { 15002b15cb3dSCy Schubert pl->peeraddr = NSRCADR(&pcmd->argval[qitems].netnum); 15019c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 15029c2daa00SOllivier Robert pl->v6_flag = 0; 15039c2daa00SOllivier Robert } else { 15049c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 15059c2daa00SOllivier Robert fprintf(stderr, 15069c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 15079c2daa00SOllivier Robert return; 15089c2daa00SOllivier Robert } 15099c2daa00SOllivier Robert pl->peeraddr6 = 15102b15cb3dSCy Schubert SOCK_ADDR6(&pcmd->argval[qitems].netnum); 15119c2daa00SOllivier Robert pl->v6_flag = 1; 15129c2daa00SOllivier Robert } 15132b15cb3dSCy Schubert pl = (void *)((char *)pl + sendsize); 1514c0b746e5SOllivier Robert } 1515c0b746e5SOllivier Robert 15169c2daa00SOllivier Robert res = doquery(impl_ver, REQ_UNCONFIG, 1, qitems, 15179c2daa00SOllivier Robert sendsize, (char *)plist, &items, 15189c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_unpeer)); 15199c2daa00SOllivier Robert 15209c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 15219c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 15229c2daa00SOllivier Robert goto again; 15239c2daa00SOllivier Robert } 1524c0b746e5SOllivier Robert 1525c0b746e5SOllivier Robert if (res == 0) 1526c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 1527c0b746e5SOllivier Robert } 1528c0b746e5SOllivier Robert 1529c0b746e5SOllivier Robert 1530c0b746e5SOllivier Robert /* 1531c0b746e5SOllivier Robert * set - set some system flags 1532c0b746e5SOllivier Robert */ 1533c0b746e5SOllivier Robert static void 1534c0b746e5SOllivier Robert set( 1535c0b746e5SOllivier Robert struct parse *pcmd, 1536c0b746e5SOllivier Robert FILE *fp 1537c0b746e5SOllivier Robert ) 1538c0b746e5SOllivier Robert { 1539c0b746e5SOllivier Robert doset(pcmd, fp, REQ_SET_SYS_FLAG); 1540c0b746e5SOllivier Robert } 1541c0b746e5SOllivier Robert 1542c0b746e5SOllivier Robert 1543c0b746e5SOllivier Robert /* 1544c0b746e5SOllivier Robert * clear - clear some system flags 1545c0b746e5SOllivier Robert */ 1546c0b746e5SOllivier Robert static void 1547c0b746e5SOllivier Robert sys_clear( 1548c0b746e5SOllivier Robert struct parse *pcmd, 1549c0b746e5SOllivier Robert FILE *fp 1550c0b746e5SOllivier Robert ) 1551c0b746e5SOllivier Robert { 1552c0b746e5SOllivier Robert doset(pcmd, fp, REQ_CLR_SYS_FLAG); 1553c0b746e5SOllivier Robert } 1554c0b746e5SOllivier Robert 1555c0b746e5SOllivier Robert 1556c0b746e5SOllivier Robert /* 1557c0b746e5SOllivier Robert * doset - set/clear system flags 1558c0b746e5SOllivier Robert */ 1559c0b746e5SOllivier Robert static void 1560c0b746e5SOllivier Robert doset( 1561c0b746e5SOllivier Robert struct parse *pcmd, 1562c0b746e5SOllivier Robert FILE *fp, 1563c0b746e5SOllivier Robert int req 1564c0b746e5SOllivier Robert ) 1565c0b746e5SOllivier Robert { 1566c0b746e5SOllivier Robert struct conf_sys_flags sys; 15673311ff84SXin LI size_t items; 15683311ff84SXin LI size_t itemsize; 15693311ff84SXin LI const char *dummy; 1570c0b746e5SOllivier Robert int res; 1571c0b746e5SOllivier Robert 1572c0b746e5SOllivier Robert sys.flags = 0; 1573c0b746e5SOllivier Robert res = 0; 15742b15cb3dSCy Schubert for (items = 0; (size_t)items < pcmd->nargs; items++) { 1575ce265a54SOllivier Robert if (STREQ(pcmd->argval[items].string, "auth")) 1576ce265a54SOllivier Robert sys.flags |= SYS_FLAG_AUTH; 1577c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "bclient")) 1578c0b746e5SOllivier Robert sys.flags |= SYS_FLAG_BCLIENT; 1579ce265a54SOllivier Robert else if (STREQ(pcmd->argval[items].string, "calibrate")) 1580ce265a54SOllivier Robert sys.flags |= SYS_FLAG_CAL; 1581ce265a54SOllivier Robert else if (STREQ(pcmd->argval[items].string, "kernel")) 1582ce265a54SOllivier Robert sys.flags |= SYS_FLAG_KERNEL; 1583c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "monitor")) 1584c0b746e5SOllivier Robert sys.flags |= SYS_FLAG_MONITOR; 1585c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "ntp")) 1586c0b746e5SOllivier Robert sys.flags |= SYS_FLAG_NTP; 1587ce265a54SOllivier Robert else if (STREQ(pcmd->argval[items].string, "pps")) 1588ce265a54SOllivier Robert sys.flags |= SYS_FLAG_PPS; 1589c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "stats")) 1590c0b746e5SOllivier Robert sys.flags |= SYS_FLAG_FILEGEN; 1591c0b746e5SOllivier Robert else { 1592c0b746e5SOllivier Robert (void) fprintf(fp, "Unknown flag %s\n", 1593c0b746e5SOllivier Robert pcmd->argval[items].string); 1594c0b746e5SOllivier Robert res = 1; 1595c0b746e5SOllivier Robert } 1596c0b746e5SOllivier Robert } 1597c0b746e5SOllivier Robert 1598ea906c41SOllivier Robert sys.flags = htonl(sys.flags); 1599c0b746e5SOllivier Robert if (res || sys.flags == 0) 1600c0b746e5SOllivier Robert return; 1601c0b746e5SOllivier Robert 16029c2daa00SOllivier Robert again: 16039c2daa00SOllivier Robert res = doquery(impl_ver, req, 1, 1, 1604c0b746e5SOllivier Robert sizeof(struct conf_sys_flags), (char *)&sys, &items, 16059c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_sys_flags)); 16069c2daa00SOllivier Robert 16079c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 16089c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 16099c2daa00SOllivier Robert goto again; 16109c2daa00SOllivier Robert } 1611c0b746e5SOllivier Robert 1612c0b746e5SOllivier Robert if (res == 0) 1613c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 1614c0b746e5SOllivier Robert } 1615c0b746e5SOllivier Robert 1616c0b746e5SOllivier Robert 1617c0b746e5SOllivier Robert /* 1618c0b746e5SOllivier Robert * data for printing/interrpreting the restrict flags 1619c0b746e5SOllivier Robert */ 1620c0b746e5SOllivier Robert struct resflags { 1621c0b746e5SOllivier Robert const char *str; 1622c0b746e5SOllivier Robert int bit; 1623c0b746e5SOllivier Robert }; 1624c0b746e5SOllivier Robert 1625ea906c41SOllivier Robert /* XXX: HMS: we apparently don't report set bits we do not recognize. */ 1626ea906c41SOllivier Robert 1627ea906c41SOllivier Robert static struct resflags resflagsV2[] = { 1628ea906c41SOllivier Robert { "ignore", 0x001 }, 1629ea906c41SOllivier Robert { "noserve", 0x002 }, 1630ea906c41SOllivier Robert { "notrust", 0x004 }, 1631ea906c41SOllivier Robert { "noquery", 0x008 }, 1632ea906c41SOllivier Robert { "nomodify", 0x010 }, 1633ea906c41SOllivier Robert { "nopeer", 0x020 }, 1634ea906c41SOllivier Robert { "notrap", 0x040 }, 1635ea906c41SOllivier Robert { "lptrap", 0x080 }, 1636ea906c41SOllivier Robert { "limited", 0x100 }, 1637ea906c41SOllivier Robert { "", 0 } 1638ea906c41SOllivier Robert }; 1639ea906c41SOllivier Robert 1640ea906c41SOllivier Robert static struct resflags resflagsV3[] = { 1641c0b746e5SOllivier Robert { "ignore", RES_IGNORE }, 1642c0b746e5SOllivier Robert { "noserve", RES_DONTSERVE }, 1643c0b746e5SOllivier Robert { "notrust", RES_DONTTRUST }, 1644c0b746e5SOllivier Robert { "noquery", RES_NOQUERY }, 1645c0b746e5SOllivier Robert { "nomodify", RES_NOMODIFY }, 1646c0b746e5SOllivier Robert { "nopeer", RES_NOPEER }, 1647c0b746e5SOllivier Robert { "notrap", RES_NOTRAP }, 1648c0b746e5SOllivier Robert { "lptrap", RES_LPTRAP }, 1649c0b746e5SOllivier Robert { "limited", RES_LIMITED }, 1650224ba2bdSOllivier Robert { "version", RES_VERSION }, 16512b15cb3dSCy Schubert { "kod", RES_KOD }, 16522b15cb3dSCy Schubert { "flake", RES_FLAKE }, 1653224ba2bdSOllivier Robert 1654c0b746e5SOllivier Robert { "", 0 } 1655c0b746e5SOllivier Robert }; 1656c0b746e5SOllivier Robert 1657c0b746e5SOllivier Robert static struct resflags resmflags[] = { 1658c0b746e5SOllivier Robert { "ntpport", RESM_NTPONLY }, 1659c0b746e5SOllivier Robert { "interface", RESM_INTERFACE }, 16602b15cb3dSCy Schubert { "source", RESM_SOURCE }, 1661c0b746e5SOllivier Robert { "", 0 } 1662c0b746e5SOllivier Robert }; 1663c0b746e5SOllivier Robert 1664c0b746e5SOllivier Robert 1665c0b746e5SOllivier Robert /* 1666c0b746e5SOllivier Robert * reslist - obtain and print the server's restrict list 1667c0b746e5SOllivier Robert */ 1668c0b746e5SOllivier Robert /*ARGSUSED*/ 1669c0b746e5SOllivier Robert static void 1670c0b746e5SOllivier Robert reslist( 1671c0b746e5SOllivier Robert struct parse *pcmd, 1672c0b746e5SOllivier Robert FILE *fp 1673c0b746e5SOllivier Robert ) 1674c0b746e5SOllivier Robert { 1675c0b746e5SOllivier Robert struct info_restrict *rl; 16762b15cb3dSCy Schubert sockaddr_u resaddr; 16772b15cb3dSCy Schubert sockaddr_u maskaddr; 16783311ff84SXin LI size_t items; 16793311ff84SXin LI size_t itemsize; 1680c0b746e5SOllivier Robert int res; 16819c2daa00SOllivier Robert int skip; 16822b15cb3dSCy Schubert const char *addr; 16832b15cb3dSCy Schubert const char *mask; 1684c0b746e5SOllivier Robert struct resflags *rf; 1685c0b746e5SOllivier Robert u_int32 count; 168609100258SXin LI u_short rflags; 1687c0b746e5SOllivier Robert u_short mflags; 1688c0b746e5SOllivier Robert char flagstr[300]; 1689c0b746e5SOllivier Robert static const char *comma = ", "; 1690c0b746e5SOllivier Robert 16919c2daa00SOllivier Robert again: 16929c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_RESTRICT, 0, 0, 0, (char *)NULL, 16939c2daa00SOllivier Robert &items, &itemsize, (void *)&rl, 0, 16949c2daa00SOllivier Robert sizeof(struct info_restrict)); 16959c2daa00SOllivier Robert 16969c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 16979c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 16989c2daa00SOllivier Robert goto again; 16999c2daa00SOllivier Robert } 1700c0b746e5SOllivier Robert 1701ea906c41SOllivier Robert if (res != 0) 1702c0b746e5SOllivier Robert return; 1703c0b746e5SOllivier Robert 1704c0b746e5SOllivier Robert if (!checkitems(items, fp)) 1705c0b746e5SOllivier Robert return; 1706c0b746e5SOllivier Robert 17079c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_restrict)) && 17089c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_restrict))) 1709c0b746e5SOllivier Robert return; 1710c0b746e5SOllivier Robert 17112b15cb3dSCy Schubert fprintf(fp, 1712c0b746e5SOllivier Robert " address mask count flags\n"); 17132b15cb3dSCy Schubert fprintf(fp, 1714c0b746e5SOllivier Robert "=====================================================================\n"); 17159c2daa00SOllivier Robert 1716c0b746e5SOllivier Robert while (items > 0) { 17172b15cb3dSCy Schubert SET_ADDRS(resaddr, maskaddr, rl, addr, mask); 17189c2daa00SOllivier Robert if (rl->v6_flag != 0) { 17199c2daa00SOllivier Robert addr = nntohost(&resaddr); 17209c2daa00SOllivier Robert } else { 17212b15cb3dSCy Schubert if (rl->mask == (u_int32)0xffffffff) 17229c2daa00SOllivier Robert addr = nntohost(&resaddr); 1723c0b746e5SOllivier Robert else 17249c2daa00SOllivier Robert addr = stoa(&resaddr); 17259c2daa00SOllivier Robert } 17269c2daa00SOllivier Robert mask = stoa(&maskaddr); 17279c2daa00SOllivier Robert skip = 1; 17289c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 17299c2daa00SOllivier Robert ((pcmd->argval->ival == 6) && (rl->v6_flag != 0)) || 17309c2daa00SOllivier Robert ((pcmd->argval->ival == 4) && (rl->v6_flag == 0))) 17319c2daa00SOllivier Robert skip = 0; 1732c0b746e5SOllivier Robert count = ntohl(rl->count); 173309100258SXin LI rflags = ntohs(rl->rflags); 1734c0b746e5SOllivier Robert mflags = ntohs(rl->mflags); 1735c0b746e5SOllivier Robert flagstr[0] = '\0'; 1736c0b746e5SOllivier Robert 1737c0b746e5SOllivier Robert res = 1; 1738c0b746e5SOllivier Robert rf = &resmflags[0]; 1739c0b746e5SOllivier Robert while (rf->bit != 0) { 1740c0b746e5SOllivier Robert if (mflags & rf->bit) { 1741c0b746e5SOllivier Robert if (!res) 17422b15cb3dSCy Schubert strlcat(flagstr, comma, 17432b15cb3dSCy Schubert sizeof(flagstr)); 1744c0b746e5SOllivier Robert res = 0; 17452b15cb3dSCy Schubert strlcat(flagstr, rf->str, 17462b15cb3dSCy Schubert sizeof(flagstr)); 1747c0b746e5SOllivier Robert } 1748c0b746e5SOllivier Robert rf++; 1749c0b746e5SOllivier Robert } 1750c0b746e5SOllivier Robert 1751ea906c41SOllivier Robert rf = (impl_ver == IMPL_XNTPD_OLD) 1752ea906c41SOllivier Robert ? &resflagsV2[0] 17532b15cb3dSCy Schubert : &resflagsV3[0]; 17542b15cb3dSCy Schubert 1755c0b746e5SOllivier Robert while (rf->bit != 0) { 175609100258SXin LI if (rflags & rf->bit) { 1757c0b746e5SOllivier Robert if (!res) 17582b15cb3dSCy Schubert strlcat(flagstr, comma, 17592b15cb3dSCy Schubert sizeof(flagstr)); 1760c0b746e5SOllivier Robert res = 0; 17612b15cb3dSCy Schubert strlcat(flagstr, rf->str, 17622b15cb3dSCy Schubert sizeof(flagstr)); 1763c0b746e5SOllivier Robert } 1764c0b746e5SOllivier Robert rf++; 1765c0b746e5SOllivier Robert } 1766c0b746e5SOllivier Robert 1767c0b746e5SOllivier Robert if (flagstr[0] == '\0') 17682b15cb3dSCy Schubert strlcpy(flagstr, "none", sizeof(flagstr)); 1769c0b746e5SOllivier Robert 17709c2daa00SOllivier Robert if (!skip) 17712b15cb3dSCy Schubert fprintf(fp, "%-15.15s %-15.15s %9lu %s\n", 1772c0b746e5SOllivier Robert addr, mask, (u_long)count, flagstr); 1773c0b746e5SOllivier Robert rl++; 1774c0b746e5SOllivier Robert items--; 1775c0b746e5SOllivier Robert } 1776c0b746e5SOllivier Robert } 1777c0b746e5SOllivier Robert 1778c0b746e5SOllivier Robert 1779c0b746e5SOllivier Robert 1780c0b746e5SOllivier Robert /* 1781c0b746e5SOllivier Robert * new_restrict - create/add a set of restrictions 1782c0b746e5SOllivier Robert */ 1783c0b746e5SOllivier Robert static void 1784c0b746e5SOllivier Robert new_restrict( 1785c0b746e5SOllivier Robert struct parse *pcmd, 1786c0b746e5SOllivier Robert FILE *fp 1787c0b746e5SOllivier Robert ) 1788c0b746e5SOllivier Robert { 1789c0b746e5SOllivier Robert do_restrict(pcmd, fp, REQ_RESADDFLAGS); 1790c0b746e5SOllivier Robert } 1791c0b746e5SOllivier Robert 1792c0b746e5SOllivier Robert 1793c0b746e5SOllivier Robert /* 1794c0b746e5SOllivier Robert * unrestrict - remove restriction flags from existing entry 1795c0b746e5SOllivier Robert */ 1796c0b746e5SOllivier Robert static void 1797c0b746e5SOllivier Robert unrestrict( 1798c0b746e5SOllivier Robert struct parse *pcmd, 1799c0b746e5SOllivier Robert FILE *fp 1800c0b746e5SOllivier Robert ) 1801c0b746e5SOllivier Robert { 1802c0b746e5SOllivier Robert do_restrict(pcmd, fp, REQ_RESSUBFLAGS); 1803c0b746e5SOllivier Robert } 1804c0b746e5SOllivier Robert 1805c0b746e5SOllivier Robert 1806c0b746e5SOllivier Robert /* 1807c0b746e5SOllivier Robert * delrestrict - delete an existing restriction 1808c0b746e5SOllivier Robert */ 1809c0b746e5SOllivier Robert static void 1810c0b746e5SOllivier Robert delrestrict( 1811c0b746e5SOllivier Robert struct parse *pcmd, 1812c0b746e5SOllivier Robert FILE *fp 1813c0b746e5SOllivier Robert ) 1814c0b746e5SOllivier Robert { 1815c0b746e5SOllivier Robert do_restrict(pcmd, fp, REQ_UNRESTRICT); 1816c0b746e5SOllivier Robert } 1817c0b746e5SOllivier Robert 1818c0b746e5SOllivier Robert 1819c0b746e5SOllivier Robert /* 1820c0b746e5SOllivier Robert * do_restrict - decode commandline restrictions and make the request 1821c0b746e5SOllivier Robert */ 1822c0b746e5SOllivier Robert static void 1823c0b746e5SOllivier Robert do_restrict( 1824c0b746e5SOllivier Robert struct parse *pcmd, 1825c0b746e5SOllivier Robert FILE *fp, 1826c0b746e5SOllivier Robert int req_code 1827c0b746e5SOllivier Robert ) 1828c0b746e5SOllivier Robert { 1829c0b746e5SOllivier Robert struct conf_restrict cres; 18303311ff84SXin LI size_t items; 18313311ff84SXin LI size_t itemsize; 18323311ff84SXin LI const char *dummy; 1833c0b746e5SOllivier Robert u_int32 num; 1834c0b746e5SOllivier Robert u_long bit; 1835c0b746e5SOllivier Robert int i; 18362b15cb3dSCy Schubert size_t res; 1837c0b746e5SOllivier Robert int err; 18389c2daa00SOllivier Robert int sendsize; 1839c0b746e5SOllivier Robert 18409c2daa00SOllivier Robert /* Initialize cres */ 18419c2daa00SOllivier Robert cres.addr = 0; 18429c2daa00SOllivier Robert cres.mask = 0; 18439c2daa00SOllivier Robert cres.flags = 0; 18449c2daa00SOllivier Robert cres.mflags = 0; 18459c2daa00SOllivier Robert cres.v6_flag = 0; 18469c2daa00SOllivier Robert 18479c2daa00SOllivier Robert again: 18489c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 18499c2daa00SOllivier Robert sendsize = sizeof(struct conf_restrict); 18509c2daa00SOllivier Robert else 18519c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_restrict); 18529c2daa00SOllivier Robert 18532b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[0].netnum)) { 18542b15cb3dSCy Schubert cres.addr = NSRCADR(&pcmd->argval[0].netnum); 18552b15cb3dSCy Schubert cres.mask = NSRCADR(&pcmd->argval[1].netnum); 18569c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 18579c2daa00SOllivier Robert cres.v6_flag = 0; 18589c2daa00SOllivier Robert } else { 18599c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 18609c2daa00SOllivier Robert fprintf(stderr, 18619c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 18629c2daa00SOllivier Robert return; 18639c2daa00SOllivier Robert } 18642b15cb3dSCy Schubert cres.addr6 = SOCK_ADDR6(&pcmd->argval[0].netnum); 18659c2daa00SOllivier Robert cres.v6_flag = 1; 18669c2daa00SOllivier Robert } 1867c0b746e5SOllivier Robert cres.flags = 0; 1868c0b746e5SOllivier Robert cres.mflags = 0; 18692b15cb3dSCy Schubert err = FALSE; 1870c0b746e5SOllivier Robert for (res = 2; res < pcmd->nargs; res++) { 1871c0b746e5SOllivier Robert if (STREQ(pcmd->argval[res].string, "ntpport")) { 1872c0b746e5SOllivier Robert cres.mflags |= RESM_NTPONLY; 1873c0b746e5SOllivier Robert } else { 1874ea906c41SOllivier Robert for (i = 0; resflagsV3[i].bit != 0; i++) { 1875c0b746e5SOllivier Robert if (STREQ(pcmd->argval[res].string, 1876ea906c41SOllivier Robert resflagsV3[i].str)) 1877c0b746e5SOllivier Robert break; 1878c0b746e5SOllivier Robert } 1879ea906c41SOllivier Robert if (resflagsV3[i].bit != 0) { 1880ea906c41SOllivier Robert cres.flags |= resflagsV3[i].bit; 1881c0b746e5SOllivier Robert if (req_code == REQ_UNRESTRICT) { 18822b15cb3dSCy Schubert fprintf(fp, 1883c0b746e5SOllivier Robert "Flag %s inappropriate\n", 1884ea906c41SOllivier Robert resflagsV3[i].str); 18852b15cb3dSCy Schubert err = TRUE; 1886c0b746e5SOllivier Robert } 1887c0b746e5SOllivier Robert } else { 18882b15cb3dSCy Schubert fprintf(fp, "Unknown flag %s\n", 1889c0b746e5SOllivier Robert pcmd->argval[res].string); 18902b15cb3dSCy Schubert err = TRUE; 1891c0b746e5SOllivier Robert } 1892c0b746e5SOllivier Robert } 1893c0b746e5SOllivier Robert } 1894ea906c41SOllivier Robert cres.flags = htons(cres.flags); 1895ea906c41SOllivier Robert cres.mflags = htons(cres.mflags); 1896c0b746e5SOllivier Robert 1897c0b746e5SOllivier Robert /* 1898c0b746e5SOllivier Robert * Make sure mask for default address is zero. Otherwise, 1899c0b746e5SOllivier Robert * make sure mask bits are contiguous. 1900c0b746e5SOllivier Robert */ 19012b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[0].netnum)) { 1902c0b746e5SOllivier Robert if (cres.addr == 0) { 1903c0b746e5SOllivier Robert cres.mask = 0; 1904c0b746e5SOllivier Robert } else { 1905c0b746e5SOllivier Robert num = ntohl(cres.mask); 1906c0b746e5SOllivier Robert for (bit = 0x80000000; bit != 0; bit >>= 1) 1907c0b746e5SOllivier Robert if ((num & bit) == 0) 1908c0b746e5SOllivier Robert break; 1909c0b746e5SOllivier Robert for ( ; bit != 0; bit >>= 1) 1910c0b746e5SOllivier Robert if ((num & bit) != 0) 1911c0b746e5SOllivier Robert break; 1912c0b746e5SOllivier Robert if (bit != 0) { 19132b15cb3dSCy Schubert fprintf(fp, "Invalid mask %s\n", 1914c0b746e5SOllivier Robert numtoa(cres.mask)); 19152b15cb3dSCy Schubert err = TRUE; 1916c0b746e5SOllivier Robert } 1917c0b746e5SOllivier Robert } 19189c2daa00SOllivier Robert } else { 19199c2daa00SOllivier Robert /* XXX IPv6 sanity checking stuff */ 19209c2daa00SOllivier Robert } 1921c0b746e5SOllivier Robert 1922c0b746e5SOllivier Robert if (err) 1923c0b746e5SOllivier Robert return; 1924c0b746e5SOllivier Robert 19252b15cb3dSCy Schubert res = doquery(impl_ver, req_code, 1, 1, sendsize, (char *)&cres, 19262b15cb3dSCy Schubert &items, &itemsize, &dummy, 0, sizeof(cres)); 19279c2daa00SOllivier Robert 19289c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 19299c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 19309c2daa00SOllivier Robert goto again; 19319c2daa00SOllivier Robert } 1932c0b746e5SOllivier Robert 1933c0b746e5SOllivier Robert if (res == 0) 1934c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 1935c0b746e5SOllivier Robert return; 1936c0b746e5SOllivier Robert } 1937c0b746e5SOllivier Robert 1938c0b746e5SOllivier Robert 1939c0b746e5SOllivier Robert /* 1940c0b746e5SOllivier Robert * monlist - obtain and print the server's monitor data 1941c0b746e5SOllivier Robert */ 1942c0b746e5SOllivier Robert /*ARGSUSED*/ 1943c0b746e5SOllivier Robert static void 1944c0b746e5SOllivier Robert monlist( 1945c0b746e5SOllivier Robert struct parse *pcmd, 1946c0b746e5SOllivier Robert FILE *fp 1947c0b746e5SOllivier Robert ) 1948c0b746e5SOllivier Robert { 19493311ff84SXin LI const char *struct_star; 19503311ff84SXin LI const struct info_monitor *ml; 19513311ff84SXin LI const struct info_monitor_1 *m1; 19523311ff84SXin LI const struct old_info_monitor *oml; 19532b15cb3dSCy Schubert sockaddr_u addr; 19542b15cb3dSCy Schubert sockaddr_u dstadr; 19553311ff84SXin LI size_t items; 19563311ff84SXin LI size_t itemsize; 1957c0b746e5SOllivier Robert int res; 1958c0b746e5SOllivier Robert int version = -1; 1959c0b746e5SOllivier Robert 19602b15cb3dSCy Schubert if (pcmd->nargs > 0) 1961c0b746e5SOllivier Robert version = pcmd->argval[0].ival; 1962c0b746e5SOllivier Robert 19639c2daa00SOllivier Robert again: 19649c2daa00SOllivier Robert res = doquery(impl_ver, 1965c0b746e5SOllivier Robert (version == 1 || version == -1) ? REQ_MON_GETLIST_1 : 19662b15cb3dSCy Schubert REQ_MON_GETLIST, 0, 0, 0, NULL, 1967c0b746e5SOllivier Robert &items, &itemsize, &struct_star, 19689c2daa00SOllivier Robert (version < 0) ? (1 << INFO_ERR_REQ) : 0, 19699c2daa00SOllivier Robert sizeof(struct info_monitor_1)); 19709c2daa00SOllivier Robert 19719c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 19729c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 19739c2daa00SOllivier Robert goto again; 19749c2daa00SOllivier Robert } 1975c0b746e5SOllivier Robert 1976c0b746e5SOllivier Robert if (res == INFO_ERR_REQ && version < 0) 19772b15cb3dSCy Schubert res = doquery(impl_ver, REQ_MON_GETLIST, 0, 0, 0, NULL, 19789c2daa00SOllivier Robert &items, &itemsize, &struct_star, 0, 19799c2daa00SOllivier Robert sizeof(struct info_monitor)); 1980c0b746e5SOllivier Robert 1981ea906c41SOllivier Robert if (res != 0) 1982c0b746e5SOllivier Robert return; 1983c0b746e5SOllivier Robert 1984c0b746e5SOllivier Robert if (!checkitems(items, fp)) 1985c0b746e5SOllivier Robert return; 1986c0b746e5SOllivier Robert 19879c2daa00SOllivier Robert if (itemsize == sizeof(struct info_monitor_1) || 19889c2daa00SOllivier Robert itemsize == v4sizeof(struct info_monitor_1)) { 1989c0b746e5SOllivier Robert 19903311ff84SXin LI m1 = (const void*)struct_star; 19912b15cb3dSCy Schubert fprintf(fp, 19922b15cb3dSCy Schubert "remote address port local address count m ver rstr avgint lstint\n"); 19932b15cb3dSCy Schubert fprintf(fp, 1994c0b746e5SOllivier Robert "===============================================================================\n"); 1995c0b746e5SOllivier Robert while (items > 0) { 19962b15cb3dSCy Schubert SET_ADDRS(dstadr, addr, m1, daddr, addr); 19979c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 19982b15cb3dSCy Schubert ((pcmd->argval->ival == 6) && (m1->v6_flag != 0)) || 19992b15cb3dSCy Schubert ((pcmd->argval->ival == 4) && (m1->v6_flag == 0))) 20002b15cb3dSCy Schubert fprintf(fp, 20012b15cb3dSCy Schubert "%-22.22s %5d %-15s %8lu %1u %1u %6lx %6lu %7lu\n", 20029c2daa00SOllivier Robert nntohost(&addr), 20032b15cb3dSCy Schubert ntohs(m1->port), 20049c2daa00SOllivier Robert stoa(&dstadr), 20052b15cb3dSCy Schubert (u_long)ntohl(m1->count), 20062b15cb3dSCy Schubert m1->mode, 20072b15cb3dSCy Schubert m1->version, 20082b15cb3dSCy Schubert (u_long)ntohl(m1->restr), 20092b15cb3dSCy Schubert (u_long)ntohl(m1->avg_int), 20102b15cb3dSCy Schubert (u_long)ntohl(m1->last_int)); 20112b15cb3dSCy Schubert m1++; 2012c0b746e5SOllivier Robert items--; 2013c0b746e5SOllivier Robert } 20149c2daa00SOllivier Robert } else if (itemsize == sizeof(struct info_monitor) || 20159c2daa00SOllivier Robert itemsize == v4sizeof(struct info_monitor)) { 2016c0b746e5SOllivier Robert 20173311ff84SXin LI ml = (const void *)struct_star; 20182b15cb3dSCy Schubert fprintf(fp, 20192b15cb3dSCy Schubert " address port count mode ver rstr avgint lstint\n"); 20202b15cb3dSCy Schubert fprintf(fp, 2021c0b746e5SOllivier Robert "===============================================================================\n"); 2022c0b746e5SOllivier Robert while (items > 0) { 20232b15cb3dSCy Schubert SET_ADDR(dstadr, ml->v6_flag, ml->addr, ml->addr6); 20249c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 20259c2daa00SOllivier Robert ((pcmd->argval->ival == 6) && (ml->v6_flag != 0)) || 20269c2daa00SOllivier Robert ((pcmd->argval->ival == 4) && (ml->v6_flag == 0))) 20272b15cb3dSCy Schubert fprintf(fp, 20282b15cb3dSCy Schubert "%-25.25s %5u %9lu %4u %2u %9lx %9lu %9lu\n", 20299c2daa00SOllivier Robert nntohost(&dstadr), 2030c0b746e5SOllivier Robert ntohs(ml->port), 2031c0b746e5SOllivier Robert (u_long)ntohl(ml->count), 2032c0b746e5SOllivier Robert ml->mode, 2033c0b746e5SOllivier Robert ml->version, 20342b15cb3dSCy Schubert (u_long)ntohl(ml->restr), 20352b15cb3dSCy Schubert (u_long)ntohl(ml->avg_int), 20362b15cb3dSCy Schubert (u_long)ntohl(ml->last_int)); 2037c0b746e5SOllivier Robert ml++; 2038c0b746e5SOllivier Robert items--; 2039c0b746e5SOllivier Robert } 2040c0b746e5SOllivier Robert } else if (itemsize == sizeof(struct old_info_monitor)) { 20412b15cb3dSCy Schubert 20423311ff84SXin LI oml = (const void *)struct_star; 20432b15cb3dSCy Schubert fprintf(fp, 2044c0b746e5SOllivier Robert " address port count mode version lasttime firsttime\n"); 20452b15cb3dSCy Schubert fprintf(fp, 2046c0b746e5SOllivier Robert "======================================================================\n"); 2047c0b746e5SOllivier Robert while (items > 0) { 20482b15cb3dSCy Schubert SET_ADDR(dstadr, oml->v6_flag, oml->addr, oml->addr6); 20492b15cb3dSCy Schubert fprintf(fp, "%-20.20s %5u %9lu %4u %3u %9lu %9lu\n", 20509c2daa00SOllivier Robert nntohost(&dstadr), 2051c0b746e5SOllivier Robert ntohs(oml->port), 2052c0b746e5SOllivier Robert (u_long)ntohl(oml->count), 2053c0b746e5SOllivier Robert oml->mode, 2054c0b746e5SOllivier Robert oml->version, 2055c0b746e5SOllivier Robert (u_long)ntohl(oml->lasttime), 2056c0b746e5SOllivier Robert (u_long)ntohl(oml->firsttime)); 2057c0b746e5SOllivier Robert oml++; 2058c0b746e5SOllivier Robert items--; 2059c0b746e5SOllivier Robert } 2060c0b746e5SOllivier Robert } else { 2061c0b746e5SOllivier Robert /* issue warning according to new info_monitor size */ 2062c0b746e5SOllivier Robert checkitemsize(itemsize, sizeof(struct info_monitor)); 2063c0b746e5SOllivier Robert } 2064c0b746e5SOllivier Robert } 2065c0b746e5SOllivier Robert 2066c0b746e5SOllivier Robert 2067c0b746e5SOllivier Robert /* 2068c0b746e5SOllivier Robert * Mapping between command line strings and stat reset flags 2069c0b746e5SOllivier Robert */ 2070c0b746e5SOllivier Robert struct statreset { 20712b15cb3dSCy Schubert const char * const str; 20722b15cb3dSCy Schubert const int flag; 2073c0b746e5SOllivier Robert } sreset[] = { 20742b15cb3dSCy Schubert { "allpeers", RESET_FLAG_ALLPEERS }, 2075c0b746e5SOllivier Robert { "io", RESET_FLAG_IO }, 2076c0b746e5SOllivier Robert { "sys", RESET_FLAG_SYS }, 2077c0b746e5SOllivier Robert { "mem", RESET_FLAG_MEM }, 2078c0b746e5SOllivier Robert { "timer", RESET_FLAG_TIMER }, 2079c0b746e5SOllivier Robert { "auth", RESET_FLAG_AUTH }, 20802b15cb3dSCy Schubert { "ctl", RESET_FLAG_CTL }, 2081c0b746e5SOllivier Robert { "", 0 } 2082c0b746e5SOllivier Robert }; 2083c0b746e5SOllivier Robert 2084c0b746e5SOllivier Robert /* 2085c0b746e5SOllivier Robert * reset - reset statistic counters 2086c0b746e5SOllivier Robert */ 2087c0b746e5SOllivier Robert static void 2088c0b746e5SOllivier Robert reset( 2089c0b746e5SOllivier Robert struct parse *pcmd, 2090c0b746e5SOllivier Robert FILE *fp 2091c0b746e5SOllivier Robert ) 2092c0b746e5SOllivier Robert { 2093c0b746e5SOllivier Robert struct reset_flags rflags; 20943311ff84SXin LI size_t items; 20953311ff84SXin LI size_t itemsize; 20963311ff84SXin LI const char *dummy; 2097c0b746e5SOllivier Robert int i; 20982b15cb3dSCy Schubert size_t res; 2099c0b746e5SOllivier Robert int err; 2100c0b746e5SOllivier Robert 2101c0b746e5SOllivier Robert err = 0; 2102c0b746e5SOllivier Robert rflags.flags = 0; 2103c0b746e5SOllivier Robert for (res = 0; res < pcmd->nargs; res++) { 2104c0b746e5SOllivier Robert for (i = 0; sreset[i].flag != 0; i++) { 2105c0b746e5SOllivier Robert if (STREQ(pcmd->argval[res].string, sreset[i].str)) 2106c0b746e5SOllivier Robert break; 2107c0b746e5SOllivier Robert } 2108c0b746e5SOllivier Robert if (sreset[i].flag == 0) { 21092b15cb3dSCy Schubert fprintf(fp, "Flag %s unknown\n", 2110c0b746e5SOllivier Robert pcmd->argval[res].string); 2111f0574f5cSXin LI err = 1; 2112c0b746e5SOllivier Robert } else { 2113c0b746e5SOllivier Robert rflags.flags |= sreset[i].flag; 2114c0b746e5SOllivier Robert } 2115c0b746e5SOllivier Robert } 2116ea906c41SOllivier Robert rflags.flags = htonl(rflags.flags); 2117c0b746e5SOllivier Robert 2118c0b746e5SOllivier Robert if (err) { 2119c0b746e5SOllivier Robert (void) fprintf(fp, "Not done due to errors\n"); 2120c0b746e5SOllivier Robert return; 2121c0b746e5SOllivier Robert } 2122c0b746e5SOllivier Robert 21239c2daa00SOllivier Robert again: 21249c2daa00SOllivier Robert res = doquery(impl_ver, REQ_RESET_STATS, 1, 1, 2125c0b746e5SOllivier Robert sizeof(struct reset_flags), (char *)&rflags, &items, 21269c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct reset_flags)); 21279c2daa00SOllivier Robert 21289c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 21299c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 21309c2daa00SOllivier Robert goto again; 21319c2daa00SOllivier Robert } 2132c0b746e5SOllivier Robert 2133c0b746e5SOllivier Robert if (res == 0) 2134c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2135c0b746e5SOllivier Robert return; 2136c0b746e5SOllivier Robert } 2137c0b746e5SOllivier Robert 2138c0b746e5SOllivier Robert 2139c0b746e5SOllivier Robert 2140c0b746e5SOllivier Robert /* 2141c0b746e5SOllivier Robert * preset - reset stat counters for particular peers 2142c0b746e5SOllivier Robert */ 2143c0b746e5SOllivier Robert static void 2144c0b746e5SOllivier Robert preset( 2145c0b746e5SOllivier Robert struct parse *pcmd, 2146c0b746e5SOllivier Robert FILE *fp 2147c0b746e5SOllivier Robert ) 2148c0b746e5SOllivier Robert { 2149c0b746e5SOllivier Robert /* 8 is the maximum number of peers which will fit in a packet */ 21509c2daa00SOllivier Robert struct conf_unpeer *pl, plist[min(MAXARGS, 8)]; 21513311ff84SXin LI size_t qitemlim; 21523311ff84SXin LI size_t qitems; 21533311ff84SXin LI size_t items; 21543311ff84SXin LI size_t itemsize; 21553311ff84SXin LI const char *dummy; 2156c0b746e5SOllivier Robert int res; 21573311ff84SXin LI size_t sendsize; 2158c0b746e5SOllivier Robert 21599c2daa00SOllivier Robert again: 21609c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 21619c2daa00SOllivier Robert sendsize = sizeof(struct conf_unpeer); 21629c2daa00SOllivier Robert else 21639c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_unpeer); 21649c2daa00SOllivier Robert 21652b15cb3dSCy Schubert qitemlim = min(pcmd->nargs, COUNTOF(plist)); 21662b15cb3dSCy Schubert for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) { 21672b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[qitems].netnum)) { 21682b15cb3dSCy Schubert pl->peeraddr = NSRCADR(&pcmd->argval[qitems].netnum); 21699c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 21709c2daa00SOllivier Robert pl->v6_flag = 0; 21719c2daa00SOllivier Robert } else { 21729c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 21739c2daa00SOllivier Robert fprintf(stderr, 21749c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 21759c2daa00SOllivier Robert return; 21769c2daa00SOllivier Robert } 21779c2daa00SOllivier Robert pl->peeraddr6 = 21782b15cb3dSCy Schubert SOCK_ADDR6(&pcmd->argval[qitems].netnum); 21799c2daa00SOllivier Robert pl->v6_flag = 1; 21809c2daa00SOllivier Robert } 21812b15cb3dSCy Schubert pl = (void *)((char *)pl + sendsize); 2182c0b746e5SOllivier Robert } 2183c0b746e5SOllivier Robert 21849c2daa00SOllivier Robert res = doquery(impl_ver, REQ_RESET_PEER, 1, qitems, 21859c2daa00SOllivier Robert sendsize, (char *)plist, &items, 21869c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_unpeer)); 21879c2daa00SOllivier Robert 21889c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 21899c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 21909c2daa00SOllivier Robert goto again; 21919c2daa00SOllivier Robert } 2192c0b746e5SOllivier Robert 2193c0b746e5SOllivier Robert if (res == 0) 2194c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2195c0b746e5SOllivier Robert } 2196c0b746e5SOllivier Robert 2197c0b746e5SOllivier Robert 2198c0b746e5SOllivier Robert /* 2199c0b746e5SOllivier Robert * readkeys - request the server to reread the keys file 2200c0b746e5SOllivier Robert */ 2201c0b746e5SOllivier Robert /*ARGSUSED*/ 2202c0b746e5SOllivier Robert static void 2203c0b746e5SOllivier Robert readkeys( 2204c0b746e5SOllivier Robert struct parse *pcmd, 2205c0b746e5SOllivier Robert FILE *fp 2206c0b746e5SOllivier Robert ) 2207c0b746e5SOllivier Robert { 22083311ff84SXin LI size_t items; 22093311ff84SXin LI size_t itemsize; 22103311ff84SXin LI const char *dummy; 2211c0b746e5SOllivier Robert int res; 2212c0b746e5SOllivier Robert 22139c2daa00SOllivier Robert again: 22149c2daa00SOllivier Robert res = doquery(impl_ver, REQ_REREAD_KEYS, 1, 0, 0, (char *)0, 22159c2daa00SOllivier Robert &items, &itemsize, &dummy, 0, sizeof(dummy)); 22169c2daa00SOllivier Robert 22179c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 22189c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 22199c2daa00SOllivier Robert goto again; 22209c2daa00SOllivier Robert } 2221c0b746e5SOllivier Robert 2222c0b746e5SOllivier Robert if (res == 0) 2223c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2224c0b746e5SOllivier Robert return; 2225c0b746e5SOllivier Robert } 2226c0b746e5SOllivier Robert 2227c0b746e5SOllivier Robert 2228c0b746e5SOllivier Robert /* 2229c0b746e5SOllivier Robert * trustkey - add some keys to the trusted key list 2230c0b746e5SOllivier Robert */ 2231c0b746e5SOllivier Robert static void 2232c0b746e5SOllivier Robert trustkey( 2233c0b746e5SOllivier Robert struct parse *pcmd, 2234c0b746e5SOllivier Robert FILE *fp 2235c0b746e5SOllivier Robert ) 2236c0b746e5SOllivier Robert { 2237c0b746e5SOllivier Robert do_trustkey(pcmd, fp, REQ_TRUSTKEY); 2238c0b746e5SOllivier Robert } 2239c0b746e5SOllivier Robert 2240c0b746e5SOllivier Robert 2241c0b746e5SOllivier Robert /* 2242c0b746e5SOllivier Robert * untrustkey - remove some keys from the trusted key list 2243c0b746e5SOllivier Robert */ 2244c0b746e5SOllivier Robert static void 2245c0b746e5SOllivier Robert untrustkey( 2246c0b746e5SOllivier Robert struct parse *pcmd, 2247c0b746e5SOllivier Robert FILE *fp 2248c0b746e5SOllivier Robert ) 2249c0b746e5SOllivier Robert { 2250c0b746e5SOllivier Robert do_trustkey(pcmd, fp, REQ_UNTRUSTKEY); 2251c0b746e5SOllivier Robert } 2252c0b746e5SOllivier Robert 2253c0b746e5SOllivier Robert 2254c0b746e5SOllivier Robert /* 2255c0b746e5SOllivier Robert * do_trustkey - do grunge work of adding/deleting keys 2256c0b746e5SOllivier Robert */ 2257c0b746e5SOllivier Robert static void 2258c0b746e5SOllivier Robert do_trustkey( 2259c0b746e5SOllivier Robert struct parse *pcmd, 2260c0b746e5SOllivier Robert FILE *fp, 2261c0b746e5SOllivier Robert int req 2262c0b746e5SOllivier Robert ) 2263c0b746e5SOllivier Robert { 2264c0b746e5SOllivier Robert u_long keyids[MAXARGS]; 22652b15cb3dSCy Schubert size_t i; 22663311ff84SXin LI size_t items; 22673311ff84SXin LI size_t itemsize; 22683311ff84SXin LI const char *dummy; 2269c0b746e5SOllivier Robert int ritems; 2270c0b746e5SOllivier Robert int res; 2271c0b746e5SOllivier Robert 2272c0b746e5SOllivier Robert ritems = 0; 2273c0b746e5SOllivier Robert for (i = 0; i < pcmd->nargs; i++) { 2274c0b746e5SOllivier Robert keyids[ritems++] = pcmd->argval[i].uval; 2275c0b746e5SOllivier Robert } 2276c0b746e5SOllivier Robert 22779c2daa00SOllivier Robert again: 22789c2daa00SOllivier Robert res = doquery(impl_ver, req, 1, ritems, sizeof(u_long), 22799c2daa00SOllivier Robert (char *)keyids, &items, &itemsize, &dummy, 0, 22809c2daa00SOllivier Robert sizeof(dummy)); 22819c2daa00SOllivier Robert 22829c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 22839c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 22849c2daa00SOllivier Robert goto again; 22859c2daa00SOllivier Robert } 2286c0b746e5SOllivier Robert 2287c0b746e5SOllivier Robert if (res == 0) 2288c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2289c0b746e5SOllivier Robert return; 2290c0b746e5SOllivier Robert } 2291c0b746e5SOllivier Robert 2292c0b746e5SOllivier Robert 2293c0b746e5SOllivier Robert 2294c0b746e5SOllivier Robert /* 2295c0b746e5SOllivier Robert * authinfo - obtain and print info about authentication 2296c0b746e5SOllivier Robert */ 2297c0b746e5SOllivier Robert /*ARGSUSED*/ 2298c0b746e5SOllivier Robert static void 2299c0b746e5SOllivier Robert authinfo( 2300c0b746e5SOllivier Robert struct parse *pcmd, 2301c0b746e5SOllivier Robert FILE *fp 2302c0b746e5SOllivier Robert ) 2303c0b746e5SOllivier Robert { 2304c0b746e5SOllivier Robert struct info_auth *ia; 23053311ff84SXin LI size_t items; 23063311ff84SXin LI size_t itemsize; 2307c0b746e5SOllivier Robert int res; 2308c0b746e5SOllivier Robert 23099c2daa00SOllivier Robert again: 23102b15cb3dSCy Schubert res = doquery(impl_ver, REQ_AUTHINFO, 0, 0, 0, NULL, &items, 23112b15cb3dSCy Schubert &itemsize, (void *)&ia, 0, sizeof(*ia)); 23129c2daa00SOllivier Robert 23139c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 23149c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 23159c2daa00SOllivier Robert goto again; 23169c2daa00SOllivier Robert } 2317c0b746e5SOllivier Robert 2318ea906c41SOllivier Robert if (res != 0) 2319c0b746e5SOllivier Robert return; 2320c0b746e5SOllivier Robert 2321c0b746e5SOllivier Robert if (!check1item(items, fp)) 2322c0b746e5SOllivier Robert return; 2323c0b746e5SOllivier Robert 23242b15cb3dSCy Schubert if (!checkitemsize(itemsize, sizeof(*ia))) 2325c0b746e5SOllivier Robert return; 2326c0b746e5SOllivier Robert 23272b15cb3dSCy Schubert fprintf(fp, "time since reset: %lu\n", 2328c0b746e5SOllivier Robert (u_long)ntohl(ia->timereset)); 23292b15cb3dSCy Schubert fprintf(fp, "stored keys: %lu\n", 2330c0b746e5SOllivier Robert (u_long)ntohl(ia->numkeys)); 23312b15cb3dSCy Schubert fprintf(fp, "free keys: %lu\n", 2332c0b746e5SOllivier Robert (u_long)ntohl(ia->numfreekeys)); 23332b15cb3dSCy Schubert fprintf(fp, "key lookups: %lu\n", 2334c0b746e5SOllivier Robert (u_long)ntohl(ia->keylookups)); 23352b15cb3dSCy Schubert fprintf(fp, "keys not found: %lu\n", 2336c0b746e5SOllivier Robert (u_long)ntohl(ia->keynotfound)); 23372b15cb3dSCy Schubert fprintf(fp, "uncached keys: %lu\n", 2338c0b746e5SOllivier Robert (u_long)ntohl(ia->keyuncached)); 23392b15cb3dSCy Schubert fprintf(fp, "encryptions: %lu\n", 2340c0b746e5SOllivier Robert (u_long)ntohl(ia->encryptions)); 23412b15cb3dSCy Schubert fprintf(fp, "decryptions: %lu\n", 2342c0b746e5SOllivier Robert (u_long)ntohl(ia->decryptions)); 23432b15cb3dSCy Schubert fprintf(fp, "expired keys: %lu\n", 2344c0b746e5SOllivier Robert (u_long)ntohl(ia->expired)); 2345c0b746e5SOllivier Robert } 2346c0b746e5SOllivier Robert 2347c0b746e5SOllivier Robert 2348c0b746e5SOllivier Robert 2349c0b746e5SOllivier Robert /* 2350c0b746e5SOllivier Robert * traps - obtain and print a list of traps 2351c0b746e5SOllivier Robert */ 2352c0b746e5SOllivier Robert /*ARGSUSED*/ 2353c0b746e5SOllivier Robert static void 2354c0b746e5SOllivier Robert traps( 2355c0b746e5SOllivier Robert struct parse *pcmd, 2356c0b746e5SOllivier Robert FILE *fp 2357c0b746e5SOllivier Robert ) 2358c0b746e5SOllivier Robert { 23593311ff84SXin LI size_t i; 2360c0b746e5SOllivier Robert struct info_trap *it; 23612b15cb3dSCy Schubert sockaddr_u trap_addr, local_addr; 23623311ff84SXin LI size_t items; 23633311ff84SXin LI size_t itemsize; 2364c0b746e5SOllivier Robert int res; 2365c0b746e5SOllivier Robert 23669c2daa00SOllivier Robert again: 23672b15cb3dSCy Schubert res = doquery(impl_ver, REQ_TRAPS, 0, 0, 0, NULL, &items, 23682b15cb3dSCy Schubert &itemsize, (void *)&it, 0, sizeof(*it)); 23699c2daa00SOllivier Robert 23709c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 23719c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 23729c2daa00SOllivier Robert goto again; 23739c2daa00SOllivier Robert } 2374c0b746e5SOllivier Robert 2375ea906c41SOllivier Robert if (res != 0) 2376c0b746e5SOllivier Robert return; 2377c0b746e5SOllivier Robert 2378c0b746e5SOllivier Robert if (!checkitems(items, fp)) 2379c0b746e5SOllivier Robert return; 2380c0b746e5SOllivier Robert 23819c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_trap)) && 23829c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_trap))) 2383c0b746e5SOllivier Robert return; 2384c0b746e5SOllivier Robert 2385c0b746e5SOllivier Robert for (i = 0; i < items; i++ ) { 23862b15cb3dSCy Schubert SET_ADDRS(trap_addr, local_addr, it, trap_address, local_address); 23872b15cb3dSCy Schubert fprintf(fp, "%saddress %s, port %d\n", 23882b15cb3dSCy Schubert (0 == i) 23892b15cb3dSCy Schubert ? "" 23902b15cb3dSCy Schubert : "\n", 23912b15cb3dSCy Schubert stoa(&trap_addr), ntohs(it->trap_port)); 23922b15cb3dSCy Schubert fprintf(fp, "interface: %s, ", 23932b15cb3dSCy Schubert (0 == it->local_address) 2394c0b746e5SOllivier Robert ? "wildcard" 23959c2daa00SOllivier Robert : stoa(&local_addr)); 2396c0b746e5SOllivier Robert if (ntohl(it->flags) & TRAP_CONFIGURED) 23972b15cb3dSCy Schubert fprintf(fp, "configured\n"); 2398c0b746e5SOllivier Robert else if (ntohl(it->flags) & TRAP_NONPRIO) 23992b15cb3dSCy Schubert fprintf(fp, "low priority\n"); 2400c0b746e5SOllivier Robert else 24012b15cb3dSCy Schubert fprintf(fp, "normal priority\n"); 2402c0b746e5SOllivier Robert 24032b15cb3dSCy Schubert fprintf(fp, "set for %ld secs, last set %ld secs ago\n", 2404c0b746e5SOllivier Robert (long)ntohl(it->origtime), 2405c0b746e5SOllivier Robert (long)ntohl(it->settime)); 24062b15cb3dSCy Schubert fprintf(fp, "sequence %d, number of resets %ld\n", 24072b15cb3dSCy Schubert ntohs(it->sequence), (long)ntohl(it->resets)); 2408c0b746e5SOllivier Robert } 2409c0b746e5SOllivier Robert } 2410c0b746e5SOllivier Robert 2411c0b746e5SOllivier Robert 2412c0b746e5SOllivier Robert /* 2413c0b746e5SOllivier Robert * addtrap - configure a trap 2414c0b746e5SOllivier Robert */ 2415c0b746e5SOllivier Robert static void 2416c0b746e5SOllivier Robert addtrap( 2417c0b746e5SOllivier Robert struct parse *pcmd, 2418c0b746e5SOllivier Robert FILE *fp 2419c0b746e5SOllivier Robert ) 2420c0b746e5SOllivier Robert { 2421c0b746e5SOllivier Robert do_addclr_trap(pcmd, fp, REQ_ADD_TRAP); 2422c0b746e5SOllivier Robert } 2423c0b746e5SOllivier Robert 2424c0b746e5SOllivier Robert 2425c0b746e5SOllivier Robert /* 2426c0b746e5SOllivier Robert * clrtrap - clear a trap from the server 2427c0b746e5SOllivier Robert */ 2428c0b746e5SOllivier Robert static void 2429c0b746e5SOllivier Robert clrtrap( 2430c0b746e5SOllivier Robert struct parse *pcmd, 2431c0b746e5SOllivier Robert FILE *fp 2432c0b746e5SOllivier Robert ) 2433c0b746e5SOllivier Robert { 2434c0b746e5SOllivier Robert do_addclr_trap(pcmd, fp, REQ_CLR_TRAP); 2435c0b746e5SOllivier Robert } 2436c0b746e5SOllivier Robert 2437c0b746e5SOllivier Robert 2438c0b746e5SOllivier Robert /* 2439c0b746e5SOllivier Robert * do_addclr_trap - do grunge work of adding/deleting traps 2440c0b746e5SOllivier Robert */ 2441c0b746e5SOllivier Robert static void 2442c0b746e5SOllivier Robert do_addclr_trap( 2443c0b746e5SOllivier Robert struct parse *pcmd, 2444c0b746e5SOllivier Robert FILE *fp, 2445c0b746e5SOllivier Robert int req 2446c0b746e5SOllivier Robert ) 2447c0b746e5SOllivier Robert { 2448c0b746e5SOllivier Robert struct conf_trap ctrap; 24493311ff84SXin LI size_t items; 24503311ff84SXin LI size_t itemsize; 24513311ff84SXin LI const char *dummy; 2452c0b746e5SOllivier Robert int res; 24539c2daa00SOllivier Robert int sendsize; 2454c0b746e5SOllivier Robert 24559c2daa00SOllivier Robert again: 24569c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 24579c2daa00SOllivier Robert sendsize = sizeof(struct conf_trap); 24589c2daa00SOllivier Robert else 24599c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_trap); 24609c2daa00SOllivier Robert 24612b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[0].netnum)) { 24622b15cb3dSCy Schubert ctrap.trap_address = NSRCADR(&pcmd->argval[0].netnum); 24639c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 24649c2daa00SOllivier Robert ctrap.v6_flag = 0; 24659c2daa00SOllivier Robert } else { 24669c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 24679c2daa00SOllivier Robert fprintf(stderr, 24689c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 24699c2daa00SOllivier Robert return; 24709c2daa00SOllivier Robert } 24712b15cb3dSCy Schubert ctrap.trap_address6 = SOCK_ADDR6(&pcmd->argval[0].netnum); 24729c2daa00SOllivier Robert ctrap.v6_flag = 1; 24739c2daa00SOllivier Robert } 2474c0b746e5SOllivier Robert ctrap.local_address = 0; 2475c0b746e5SOllivier Robert ctrap.trap_port = htons(TRAPPORT); 2476c0b746e5SOllivier Robert ctrap.unused = 0; 2477c0b746e5SOllivier Robert 2478c0b746e5SOllivier Robert if (pcmd->nargs > 1) { 24792b15cb3dSCy Schubert ctrap.trap_port = htons((u_short)pcmd->argval[1].uval); 24809c2daa00SOllivier Robert if (pcmd->nargs > 2) { 24812b15cb3dSCy Schubert if (AF(&pcmd->argval[2].netnum) != 24822b15cb3dSCy Schubert AF(&pcmd->argval[0].netnum)) { 24839c2daa00SOllivier Robert fprintf(stderr, 24849c2daa00SOllivier Robert "***Cannot mix IPv4 and IPv6 addresses\n"); 24859c2daa00SOllivier Robert return; 24869c2daa00SOllivier Robert } 24872b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[2].netnum)) 24882b15cb3dSCy Schubert ctrap.local_address = NSRCADR(&pcmd->argval[2].netnum); 24899c2daa00SOllivier Robert else 24902b15cb3dSCy Schubert ctrap.local_address6 = SOCK_ADDR6(&pcmd->argval[2].netnum); 24919c2daa00SOllivier Robert } 2492c0b746e5SOllivier Robert } 2493c0b746e5SOllivier Robert 24949c2daa00SOllivier Robert res = doquery(impl_ver, req, 1, 1, sendsize, 24959c2daa00SOllivier Robert (char *)&ctrap, &items, &itemsize, &dummy, 0, 24969c2daa00SOllivier Robert sizeof(struct conf_trap)); 24979c2daa00SOllivier Robert 24989c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 24999c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 25009c2daa00SOllivier Robert goto again; 25019c2daa00SOllivier Robert } 2502c0b746e5SOllivier Robert 2503c0b746e5SOllivier Robert if (res == 0) 2504c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2505c0b746e5SOllivier Robert return; 2506c0b746e5SOllivier Robert } 2507c0b746e5SOllivier Robert 2508c0b746e5SOllivier Robert 2509c0b746e5SOllivier Robert 2510c0b746e5SOllivier Robert /* 2511c0b746e5SOllivier Robert * requestkey - change the server's request key (a dangerous request) 2512c0b746e5SOllivier Robert */ 2513c0b746e5SOllivier Robert static void 2514c0b746e5SOllivier Robert requestkey( 2515c0b746e5SOllivier Robert struct parse *pcmd, 2516c0b746e5SOllivier Robert FILE *fp 2517c0b746e5SOllivier Robert ) 2518c0b746e5SOllivier Robert { 2519c0b746e5SOllivier Robert do_changekey(pcmd, fp, REQ_REQUEST_KEY); 2520c0b746e5SOllivier Robert } 2521c0b746e5SOllivier Robert 2522c0b746e5SOllivier Robert 2523c0b746e5SOllivier Robert /* 2524c0b746e5SOllivier Robert * controlkey - change the server's control key 2525c0b746e5SOllivier Robert */ 2526c0b746e5SOllivier Robert static void 2527c0b746e5SOllivier Robert controlkey( 2528c0b746e5SOllivier Robert struct parse *pcmd, 2529c0b746e5SOllivier Robert FILE *fp 2530c0b746e5SOllivier Robert ) 2531c0b746e5SOllivier Robert { 2532c0b746e5SOllivier Robert do_changekey(pcmd, fp, REQ_CONTROL_KEY); 2533c0b746e5SOllivier Robert } 2534c0b746e5SOllivier Robert 2535c0b746e5SOllivier Robert 2536c0b746e5SOllivier Robert 2537c0b746e5SOllivier Robert /* 2538c0b746e5SOllivier Robert * do_changekey - do grunge work of changing keys 2539c0b746e5SOllivier Robert */ 2540c0b746e5SOllivier Robert static void 2541c0b746e5SOllivier Robert do_changekey( 2542c0b746e5SOllivier Robert struct parse *pcmd, 2543c0b746e5SOllivier Robert FILE *fp, 2544c0b746e5SOllivier Robert int req 2545c0b746e5SOllivier Robert ) 2546c0b746e5SOllivier Robert { 2547c0b746e5SOllivier Robert u_long key; 25483311ff84SXin LI size_t items; 25493311ff84SXin LI size_t itemsize; 25503311ff84SXin LI const char *dummy; 2551c0b746e5SOllivier Robert int res; 2552c0b746e5SOllivier Robert 2553c0b746e5SOllivier Robert 2554c0b746e5SOllivier Robert key = htonl((u_int32)pcmd->argval[0].uval); 2555c0b746e5SOllivier Robert 25569c2daa00SOllivier Robert again: 25579c2daa00SOllivier Robert res = doquery(impl_ver, req, 1, 1, sizeof(u_int32), 25589c2daa00SOllivier Robert (char *)&key, &items, &itemsize, &dummy, 0, 25599c2daa00SOllivier Robert sizeof(dummy)); 25609c2daa00SOllivier Robert 25619c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 25629c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 25639c2daa00SOllivier Robert goto again; 25649c2daa00SOllivier Robert } 2565c0b746e5SOllivier Robert 2566c0b746e5SOllivier Robert if (res == 0) 2567c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2568c0b746e5SOllivier Robert return; 2569c0b746e5SOllivier Robert } 2570c0b746e5SOllivier Robert 2571c0b746e5SOllivier Robert 2572c0b746e5SOllivier Robert 2573c0b746e5SOllivier Robert /* 2574c0b746e5SOllivier Robert * ctlstats - obtain and print info about authentication 2575c0b746e5SOllivier Robert */ 2576c0b746e5SOllivier Robert /*ARGSUSED*/ 2577c0b746e5SOllivier Robert static void 2578c0b746e5SOllivier Robert ctlstats( 2579c0b746e5SOllivier Robert struct parse *pcmd, 2580c0b746e5SOllivier Robert FILE *fp 2581c0b746e5SOllivier Robert ) 2582c0b746e5SOllivier Robert { 2583c0b746e5SOllivier Robert struct info_control *ic; 25843311ff84SXin LI size_t items; 25853311ff84SXin LI size_t itemsize; 2586c0b746e5SOllivier Robert int res; 2587c0b746e5SOllivier Robert 25889c2daa00SOllivier Robert again: 25892b15cb3dSCy Schubert res = doquery(impl_ver, REQ_GET_CTLSTATS, 0, 0, 0, NULL, &items, 25902b15cb3dSCy Schubert &itemsize, (void *)&ic, 0, sizeof(*ic)); 25919c2daa00SOllivier Robert 25929c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 25939c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 25949c2daa00SOllivier Robert goto again; 25959c2daa00SOllivier Robert } 2596c0b746e5SOllivier Robert 2597ea906c41SOllivier Robert if (res != 0) 2598c0b746e5SOllivier Robert return; 2599c0b746e5SOllivier Robert 2600c0b746e5SOllivier Robert if (!check1item(items, fp)) 2601c0b746e5SOllivier Robert return; 2602c0b746e5SOllivier Robert 26032b15cb3dSCy Schubert if (!checkitemsize(itemsize, sizeof(*ic))) 2604c0b746e5SOllivier Robert return; 2605c0b746e5SOllivier Robert 26062b15cb3dSCy Schubert fprintf(fp, "time since reset: %lu\n", 2607c0b746e5SOllivier Robert (u_long)ntohl(ic->ctltimereset)); 26082b15cb3dSCy Schubert fprintf(fp, "requests received: %lu\n", 2609c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlreq)); 26102b15cb3dSCy Schubert fprintf(fp, "responses sent: %lu\n", 2611c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlresponses)); 26122b15cb3dSCy Schubert fprintf(fp, "fragments sent: %lu\n", 2613c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlfrags)); 26142b15cb3dSCy Schubert fprintf(fp, "async messages sent: %lu\n", 2615c0b746e5SOllivier Robert (u_long)ntohl(ic->numasyncmsgs)); 26162b15cb3dSCy Schubert fprintf(fp, "error msgs sent: %lu\n", 2617c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlerrors)); 26182b15cb3dSCy Schubert fprintf(fp, "total bad pkts: %lu\n", 2619c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlbadpkts)); 26202b15cb3dSCy Schubert fprintf(fp, "packet too short: %lu\n", 2621c0b746e5SOllivier Robert (u_long)ntohl(ic->numctltooshort)); 26222b15cb3dSCy Schubert fprintf(fp, "response on input: %lu\n", 2623c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlinputresp)); 26242b15cb3dSCy Schubert fprintf(fp, "fragment on input: %lu\n", 2625c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlinputfrag)); 26262b15cb3dSCy Schubert fprintf(fp, "error set on input: %lu\n", 2627c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlinputerr)); 26282b15cb3dSCy Schubert fprintf(fp, "bad offset on input: %lu\n", 2629c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlbadoffset)); 26302b15cb3dSCy Schubert fprintf(fp, "bad version packets: %lu\n", 2631c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlbadversion)); 26322b15cb3dSCy Schubert fprintf(fp, "data in pkt too short: %lu\n", 2633c0b746e5SOllivier Robert (u_long)ntohl(ic->numctldatatooshort)); 26342b15cb3dSCy Schubert fprintf(fp, "unknown op codes: %lu\n", 2635c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlbadop)); 2636c0b746e5SOllivier Robert } 2637c0b746e5SOllivier Robert 2638c0b746e5SOllivier Robert 2639c0b746e5SOllivier Robert /* 2640c0b746e5SOllivier Robert * clockstat - get and print clock status information 2641c0b746e5SOllivier Robert */ 2642c0b746e5SOllivier Robert static void 2643c0b746e5SOllivier Robert clockstat( 2644c0b746e5SOllivier Robert struct parse *pcmd, 2645c0b746e5SOllivier Robert FILE *fp 2646c0b746e5SOllivier Robert ) 2647c0b746e5SOllivier Robert { 2648c0b746e5SOllivier Robert struct info_clock *cl; 2649c0b746e5SOllivier Robert /* 8 is the maximum number of clocks which will fit in a packet */ 2650c0b746e5SOllivier Robert u_long clist[min(MAXARGS, 8)]; 26513311ff84SXin LI size_t qitemlim; 26523311ff84SXin LI size_t qitems; 26533311ff84SXin LI size_t items; 26543311ff84SXin LI size_t itemsize; 2655c0b746e5SOllivier Robert int res; 2656c0b746e5SOllivier Robert l_fp ts; 2657c0b746e5SOllivier Robert struct clktype *clk; 2658c0b746e5SOllivier Robert 26592b15cb3dSCy Schubert qitemlim = min(pcmd->nargs, COUNTOF(clist)); 26602b15cb3dSCy Schubert for (qitems = 0; qitems < qitemlim; qitems++) 26612b15cb3dSCy Schubert clist[qitems] = NSRCADR(&pcmd->argval[qitems].netnum); 2662c0b746e5SOllivier Robert 26639c2daa00SOllivier Robert again: 26649c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_CLOCKINFO, 0, qitems, 2665c0b746e5SOllivier Robert sizeof(u_int32), (char *)clist, &items, 26669c2daa00SOllivier Robert &itemsize, (void *)&cl, 0, sizeof(struct info_clock)); 26679c2daa00SOllivier Robert 26689c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 26699c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 26709c2daa00SOllivier Robert goto again; 26719c2daa00SOllivier Robert } 2672c0b746e5SOllivier Robert 2673ea906c41SOllivier Robert if (res != 0) 2674c0b746e5SOllivier Robert return; 2675c0b746e5SOllivier Robert 2676c0b746e5SOllivier Robert if (!checkitems(items, fp)) 2677c0b746e5SOllivier Robert return; 2678c0b746e5SOllivier Robert 2679c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_clock))) 2680c0b746e5SOllivier Robert return; 2681c0b746e5SOllivier Robert 2682c0b746e5SOllivier Robert while (items-- > 0) { 2683c0b746e5SOllivier Robert (void) fprintf(fp, "clock address: %s\n", 2684c0b746e5SOllivier Robert numtoa(cl->clockadr)); 2685c0b746e5SOllivier Robert for (clk = clktypes; clk->code >= 0; clk++) 2686c0b746e5SOllivier Robert if (clk->code == cl->type) 2687c0b746e5SOllivier Robert break; 2688c0b746e5SOllivier Robert if (clk->code >= 0) 2689c0b746e5SOllivier Robert (void) fprintf(fp, "clock type: %s\n", 2690c0b746e5SOllivier Robert clk->clocktype); 2691c0b746e5SOllivier Robert else 2692c0b746e5SOllivier Robert (void) fprintf(fp, "clock type: unknown type (%d)\n", 2693c0b746e5SOllivier Robert cl->type); 2694c0b746e5SOllivier Robert (void) fprintf(fp, "last event: %d\n", 2695c0b746e5SOllivier Robert cl->lastevent); 2696c0b746e5SOllivier Robert (void) fprintf(fp, "current status: %d\n", 2697c0b746e5SOllivier Robert cl->currentstatus); 2698c0b746e5SOllivier Robert (void) fprintf(fp, "number of polls: %lu\n", 2699c0b746e5SOllivier Robert (u_long)ntohl(cl->polls)); 2700c0b746e5SOllivier Robert (void) fprintf(fp, "no response to poll: %lu\n", 2701c0b746e5SOllivier Robert (u_long)ntohl(cl->noresponse)); 2702c0b746e5SOllivier Robert (void) fprintf(fp, "bad format responses: %lu\n", 2703c0b746e5SOllivier Robert (u_long)ntohl(cl->badformat)); 2704c0b746e5SOllivier Robert (void) fprintf(fp, "bad data responses: %lu\n", 2705c0b746e5SOllivier Robert (u_long)ntohl(cl->baddata)); 2706c0b746e5SOllivier Robert (void) fprintf(fp, "running time: %lu\n", 2707c0b746e5SOllivier Robert (u_long)ntohl(cl->timestarted)); 2708c0b746e5SOllivier Robert NTOHL_FP(&cl->fudgetime1, &ts); 2709c0b746e5SOllivier Robert (void) fprintf(fp, "fudge time 1: %s\n", 2710c0b746e5SOllivier Robert lfptoa(&ts, 6)); 2711c0b746e5SOllivier Robert NTOHL_FP(&cl->fudgetime2, &ts); 2712c0b746e5SOllivier Robert (void) fprintf(fp, "fudge time 2: %s\n", 2713c0b746e5SOllivier Robert lfptoa(&ts, 6)); 2714c0b746e5SOllivier Robert (void) fprintf(fp, "stratum: %ld\n", 2715c0b746e5SOllivier Robert (u_long)ntohl(cl->fudgeval1)); 2716*052d159aSCy Schubert /* [Bug3527] Backward Incompatible: cl->fudgeval2 is 2717*052d159aSCy Schubert * a string, instantiated via memcpy() so there is no 2718*052d159aSCy Schubert * endian issue to correct. 2719*052d159aSCy Schubert */ 2720*052d159aSCy Schubert #ifdef DISABLE_BUG3527_FIX 2721c0b746e5SOllivier Robert (void) fprintf(fp, "reference ID: %s\n", 2722ea906c41SOllivier Robert refid_string(ntohl(cl->fudgeval2), 0)); 2723*052d159aSCy Schubert #else 2724*052d159aSCy Schubert (void) fprintf(fp, "reference ID: %s\n", 2725*052d159aSCy Schubert refid_string(cl->fudgeval2, 0)); 2726*052d159aSCy Schubert #endif 2727c0b746e5SOllivier Robert (void) fprintf(fp, "fudge flags: 0x%x\n", 2728c0b746e5SOllivier Robert cl->flags); 2729c0b746e5SOllivier Robert 2730c0b746e5SOllivier Robert if (items > 0) 2731c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2732c0b746e5SOllivier Robert cl++; 2733c0b746e5SOllivier Robert } 2734c0b746e5SOllivier Robert } 2735c0b746e5SOllivier Robert 2736c0b746e5SOllivier Robert 2737c0b746e5SOllivier Robert /* 2738c0b746e5SOllivier Robert * fudge - set clock fudge factors 2739c0b746e5SOllivier Robert */ 2740c0b746e5SOllivier Robert static void 2741c0b746e5SOllivier Robert fudge( 2742c0b746e5SOllivier Robert struct parse *pcmd, 2743c0b746e5SOllivier Robert FILE *fp 2744c0b746e5SOllivier Robert ) 2745c0b746e5SOllivier Robert { 2746c0b746e5SOllivier Robert struct conf_fudge fudgedata; 27473311ff84SXin LI size_t items; 27483311ff84SXin LI size_t itemsize; 27493311ff84SXin LI const char *dummy; 2750c0b746e5SOllivier Robert l_fp ts; 2751c0b746e5SOllivier Robert int res; 2752c0b746e5SOllivier Robert long val; 2753c0b746e5SOllivier Robert u_long u_val; 2754c0b746e5SOllivier Robert int err; 2755c0b746e5SOllivier Robert 2756c0b746e5SOllivier Robert 2757c0b746e5SOllivier Robert err = 0; 27582b15cb3dSCy Schubert ZERO(fudgedata); 27592b15cb3dSCy Schubert fudgedata.clockadr = NSRCADR(&pcmd->argval[0].netnum); 2760c0b746e5SOllivier Robert 2761c0b746e5SOllivier Robert if (STREQ(pcmd->argval[1].string, "time1")) { 2762c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_TIME1); 2763c0b746e5SOllivier Robert if (!atolfp(pcmd->argval[2].string, &ts)) 2764c0b746e5SOllivier Robert err = 1; 2765c0b746e5SOllivier Robert else 2766c0b746e5SOllivier Robert NTOHL_FP(&ts, &fudgedata.fudgetime); 2767c0b746e5SOllivier Robert } else if (STREQ(pcmd->argval[1].string, "time2")) { 2768c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_TIME2); 2769c0b746e5SOllivier Robert if (!atolfp(pcmd->argval[2].string, &ts)) 2770c0b746e5SOllivier Robert err = 1; 2771c0b746e5SOllivier Robert else 2772c0b746e5SOllivier Robert NTOHL_FP(&ts, &fudgedata.fudgetime); 2773c0b746e5SOllivier Robert } else if (STREQ(pcmd->argval[1].string, "val1")) { 2774c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_VAL1); 2775c0b746e5SOllivier Robert if (!atoint(pcmd->argval[2].string, &val)) 2776c0b746e5SOllivier Robert err = 1; 2777c0b746e5SOllivier Robert else 2778c0b746e5SOllivier Robert fudgedata.fudgeval_flags = htonl(val); 2779c0b746e5SOllivier Robert } else if (STREQ(pcmd->argval[1].string, "val2")) { 2780c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_VAL2); 2781c0b746e5SOllivier Robert if (!atoint(pcmd->argval[2].string, &val)) 2782c0b746e5SOllivier Robert err = 1; 2783c0b746e5SOllivier Robert else 2784c0b746e5SOllivier Robert fudgedata.fudgeval_flags = htonl((u_int32)val); 2785c0b746e5SOllivier Robert } else if (STREQ(pcmd->argval[1].string, "flags")) { 2786c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_FLAGS); 2787c0b746e5SOllivier Robert if (!hextoint(pcmd->argval[2].string, &u_val)) 2788c0b746e5SOllivier Robert err = 1; 2789c0b746e5SOllivier Robert else 2790c0b746e5SOllivier Robert fudgedata.fudgeval_flags = htonl((u_int32)(u_val & 0xf)); 2791c0b746e5SOllivier Robert } else { 2792c0b746e5SOllivier Robert (void) fprintf(stderr, "What fudge is %s?\n", 2793c0b746e5SOllivier Robert pcmd->argval[1].string); 2794c0b746e5SOllivier Robert return; 2795c0b746e5SOllivier Robert } 2796c0b746e5SOllivier Robert 2797c0b746e5SOllivier Robert if (err) { 2798c0b746e5SOllivier Robert (void) fprintf(stderr, "Unknown fudge parameter %s\n", 2799c0b746e5SOllivier Robert pcmd->argval[2].string); 2800c0b746e5SOllivier Robert return; 2801c0b746e5SOllivier Robert } 2802c0b746e5SOllivier Robert 28039c2daa00SOllivier Robert again: 28049c2daa00SOllivier Robert res = doquery(impl_ver, REQ_SET_CLKFUDGE, 1, 1, 2805c0b746e5SOllivier Robert sizeof(struct conf_fudge), (char *)&fudgedata, &items, 28069c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(dummy)); 28079c2daa00SOllivier Robert 28089c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 28099c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 28109c2daa00SOllivier Robert goto again; 28119c2daa00SOllivier Robert } 2812c0b746e5SOllivier Robert 2813c0b746e5SOllivier Robert if (res == 0) 2814c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2815c0b746e5SOllivier Robert return; 2816c0b746e5SOllivier Robert } 2817c0b746e5SOllivier Robert 2818c0b746e5SOllivier Robert /* 2819c0b746e5SOllivier Robert * clkbug - get and print clock debugging information 2820c0b746e5SOllivier Robert */ 2821c0b746e5SOllivier Robert static void 2822c0b746e5SOllivier Robert clkbug( 2823c0b746e5SOllivier Robert struct parse *pcmd, 2824c0b746e5SOllivier Robert FILE *fp 2825c0b746e5SOllivier Robert ) 2826c0b746e5SOllivier Robert { 2827c0b746e5SOllivier Robert register int i; 2828c0b746e5SOllivier Robert register int n; 2829c0b746e5SOllivier Robert register u_int32 s; 2830c0b746e5SOllivier Robert struct info_clkbug *cl; 2831c0b746e5SOllivier Robert /* 8 is the maximum number of clocks which will fit in a packet */ 2832c0b746e5SOllivier Robert u_long clist[min(MAXARGS, 8)]; 2833c0b746e5SOllivier Robert u_int32 ltemp; 28343311ff84SXin LI size_t qitemlim; 28353311ff84SXin LI size_t qitems; 28363311ff84SXin LI size_t items; 28373311ff84SXin LI size_t itemsize; 2838c0b746e5SOllivier Robert int res; 2839c0b746e5SOllivier Robert int needsp; 2840c0b746e5SOllivier Robert l_fp ts; 2841c0b746e5SOllivier Robert 28422b15cb3dSCy Schubert qitemlim = min(pcmd->nargs, COUNTOF(clist)); 28432b15cb3dSCy Schubert for (qitems = 0; qitems < qitemlim; qitems++) 28442b15cb3dSCy Schubert clist[qitems] = NSRCADR(&pcmd->argval[qitems].netnum); 2845c0b746e5SOllivier Robert 28469c2daa00SOllivier Robert again: 28479c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_CLKBUGINFO, 0, qitems, 2848c0b746e5SOllivier Robert sizeof(u_int32), (char *)clist, &items, 28499c2daa00SOllivier Robert &itemsize, (void *)&cl, 0, sizeof(struct info_clkbug)); 28509c2daa00SOllivier Robert 28519c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 28529c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 28539c2daa00SOllivier Robert goto again; 28549c2daa00SOllivier Robert } 2855c0b746e5SOllivier Robert 2856ea906c41SOllivier Robert if (res != 0) 2857c0b746e5SOllivier Robert return; 2858c0b746e5SOllivier Robert 2859c0b746e5SOllivier Robert if (!checkitems(items, fp)) 2860c0b746e5SOllivier Robert return; 2861c0b746e5SOllivier Robert 2862c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_clkbug))) 2863c0b746e5SOllivier Robert return; 2864c0b746e5SOllivier Robert 2865c0b746e5SOllivier Robert while (items-- > 0) { 2866c0b746e5SOllivier Robert (void) fprintf(fp, "clock address: %s\n", 2867c0b746e5SOllivier Robert numtoa(cl->clockadr)); 2868c0b746e5SOllivier Robert n = (int)cl->nvalues; 2869c0b746e5SOllivier Robert (void) fprintf(fp, "values: %d", n); 2870c0b746e5SOllivier Robert s = ntohs(cl->svalues); 2871c0b746e5SOllivier Robert if (n > NUMCBUGVALUES) 2872c0b746e5SOllivier Robert n = NUMCBUGVALUES; 2873c0b746e5SOllivier Robert for (i = 0; i < n; i++) { 2874c0b746e5SOllivier Robert ltemp = ntohl(cl->values[i]); 2875c0b746e5SOllivier Robert ltemp &= 0xffffffff; /* HMS: This does nothing now */ 2876c0b746e5SOllivier Robert if ((i & 0x3) == 0) 2877c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2878c0b746e5SOllivier Robert if (s & (1 << i)) 2879c0b746e5SOllivier Robert (void) fprintf(fp, "%12ld", (u_long)ltemp); 2880c0b746e5SOllivier Robert else 2881c0b746e5SOllivier Robert (void) fprintf(fp, "%12lu", (u_long)ltemp); 2882c0b746e5SOllivier Robert } 2883c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2884c0b746e5SOllivier Robert 2885c0b746e5SOllivier Robert n = (int)cl->ntimes; 2886c0b746e5SOllivier Robert (void) fprintf(fp, "times: %d", n); 2887c0b746e5SOllivier Robert s = ntohl(cl->stimes); 2888c0b746e5SOllivier Robert if (n > NUMCBUGTIMES) 2889c0b746e5SOllivier Robert n = NUMCBUGTIMES; 2890c0b746e5SOllivier Robert needsp = 0; 2891c0b746e5SOllivier Robert for (i = 0; i < n; i++) { 2892c0b746e5SOllivier Robert if ((i & 0x1) == 0) { 2893c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2894c0b746e5SOllivier Robert } else { 2895c0b746e5SOllivier Robert for (;needsp > 0; needsp--) 2896c0b746e5SOllivier Robert putc(' ', fp); 2897c0b746e5SOllivier Robert } 2898c0b746e5SOllivier Robert NTOHL_FP(&cl->times[i], &ts); 2899c0b746e5SOllivier Robert if (s & (1 << i)) { 2900c0b746e5SOllivier Robert (void) fprintf(fp, "%17s", 2901c0b746e5SOllivier Robert lfptoa(&ts, 6)); 2902c0b746e5SOllivier Robert needsp = 22; 2903c0b746e5SOllivier Robert } else { 2904c0b746e5SOllivier Robert (void) fprintf(fp, "%37s", 2905c0b746e5SOllivier Robert uglydate(&ts)); 2906c0b746e5SOllivier Robert needsp = 2; 2907c0b746e5SOllivier Robert } 2908c0b746e5SOllivier Robert } 2909c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2910c0b746e5SOllivier Robert if (items > 0) { 2911c0b746e5SOllivier Robert cl++; 2912c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2913c0b746e5SOllivier Robert } 2914c0b746e5SOllivier Robert } 2915c0b746e5SOllivier Robert } 2916c0b746e5SOllivier Robert 2917c0b746e5SOllivier Robert 2918c0b746e5SOllivier Robert /* 2919c0b746e5SOllivier Robert * kerninfo - display the kernel pll/pps variables 2920c0b746e5SOllivier Robert */ 2921c0b746e5SOllivier Robert static void 2922c0b746e5SOllivier Robert kerninfo( 2923c0b746e5SOllivier Robert struct parse *pcmd, 2924c0b746e5SOllivier Robert FILE *fp 2925c0b746e5SOllivier Robert ) 2926c0b746e5SOllivier Robert { 2927c0b746e5SOllivier Robert struct info_kernel *ik; 29283311ff84SXin LI size_t items; 29293311ff84SXin LI size_t itemsize; 2930c0b746e5SOllivier Robert int res; 2931c0b746e5SOllivier Robert unsigned status; 2932*052d159aSCy Schubert double tscale_usec = 1e-6, tscale_unano = 1e-6; 2933c0b746e5SOllivier Robert 29349c2daa00SOllivier Robert again: 29359c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_KERNEL, 0, 0, 0, (char *)NULL, 29369c2daa00SOllivier Robert &items, &itemsize, (void *)&ik, 0, 29379c2daa00SOllivier Robert sizeof(struct info_kernel)); 29389c2daa00SOllivier Robert 29399c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 29409c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 29419c2daa00SOllivier Robert goto again; 29429c2daa00SOllivier Robert } 29439c2daa00SOllivier Robert 2944ea906c41SOllivier Robert if (res != 0) 2945c0b746e5SOllivier Robert return; 2946c0b746e5SOllivier Robert if (!check1item(items, fp)) 2947c0b746e5SOllivier Robert return; 2948c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_kernel))) 2949c0b746e5SOllivier Robert return; 2950c0b746e5SOllivier Robert 2951c0b746e5SOllivier Robert status = ntohs(ik->status) & 0xffff; 2952c0b746e5SOllivier Robert /* 2953c0b746e5SOllivier Robert * pll variables. We know more than we should about the NANO bit. 2954c0b746e5SOllivier Robert */ 2955c0b746e5SOllivier Robert #ifdef STA_NANO 2956c0b746e5SOllivier Robert if (status & STA_NANO) 2957*052d159aSCy Schubert tscale_unano = 1e-9; 2958c0b746e5SOllivier Robert #endif 2959c0b746e5SOllivier Robert (void)fprintf(fp, "pll offset: %g s\n", 2960*052d159aSCy Schubert (int32)ntohl(ik->offset) * tscale_unano); 2961c0b746e5SOllivier Robert (void)fprintf(fp, "pll frequency: %s ppm\n", 2962c0b746e5SOllivier Robert fptoa((s_fp)ntohl(ik->freq), 3)); 2963c0b746e5SOllivier Robert (void)fprintf(fp, "maximum error: %g s\n", 2964*052d159aSCy Schubert (u_long)ntohl(ik->maxerror) * tscale_usec); 2965c0b746e5SOllivier Robert (void)fprintf(fp, "estimated error: %g s\n", 2966*052d159aSCy Schubert (u_long)ntohl(ik->esterror) * tscale_usec); 2967c0b746e5SOllivier Robert (void)fprintf(fp, "status: %04x ", status); 2968c0b746e5SOllivier Robert #ifdef STA_PLL 2969c0b746e5SOllivier Robert if (status & STA_PLL) (void)fprintf(fp, " pll"); 2970c0b746e5SOllivier Robert #endif 2971c0b746e5SOllivier Robert #ifdef STA_PPSFREQ 2972c0b746e5SOllivier Robert if (status & STA_PPSFREQ) (void)fprintf(fp, " ppsfreq"); 2973c0b746e5SOllivier Robert #endif 2974c0b746e5SOllivier Robert #ifdef STA_PPSTIME 2975c0b746e5SOllivier Robert if (status & STA_PPSTIME) (void)fprintf(fp, " ppstime"); 2976c0b746e5SOllivier Robert #endif 2977c0b746e5SOllivier Robert #ifdef STA_FLL 2978c0b746e5SOllivier Robert if (status & STA_FLL) (void)fprintf(fp, " fll"); 2979c0b746e5SOllivier Robert #endif 2980c0b746e5SOllivier Robert #ifdef STA_INS 2981c0b746e5SOllivier Robert if (status & STA_INS) (void)fprintf(fp, " ins"); 2982c0b746e5SOllivier Robert #endif 2983c0b746e5SOllivier Robert #ifdef STA_DEL 2984c0b746e5SOllivier Robert if (status & STA_DEL) (void)fprintf(fp, " del"); 2985c0b746e5SOllivier Robert #endif 2986c0b746e5SOllivier Robert #ifdef STA_UNSYNC 2987c0b746e5SOllivier Robert if (status & STA_UNSYNC) (void)fprintf(fp, " unsync"); 2988c0b746e5SOllivier Robert #endif 2989c0b746e5SOllivier Robert #ifdef STA_FREQHOLD 2990c0b746e5SOllivier Robert if (status & STA_FREQHOLD) (void)fprintf(fp, " freqhold"); 2991c0b746e5SOllivier Robert #endif 2992c0b746e5SOllivier Robert #ifdef STA_PPSSIGNAL 2993c0b746e5SOllivier Robert if (status & STA_PPSSIGNAL) (void)fprintf(fp, " ppssignal"); 2994c0b746e5SOllivier Robert #endif 2995c0b746e5SOllivier Robert #ifdef STA_PPSJITTER 2996c0b746e5SOllivier Robert if (status & STA_PPSJITTER) (void)fprintf(fp, " ppsjitter"); 2997c0b746e5SOllivier Robert #endif 2998c0b746e5SOllivier Robert #ifdef STA_PPSWANDER 2999c0b746e5SOllivier Robert if (status & STA_PPSWANDER) (void)fprintf(fp, " ppswander"); 3000c0b746e5SOllivier Robert #endif 3001c0b746e5SOllivier Robert #ifdef STA_PPSERROR 3002c0b746e5SOllivier Robert if (status & STA_PPSERROR) (void)fprintf(fp, " ppserror"); 3003c0b746e5SOllivier Robert #endif 3004c0b746e5SOllivier Robert #ifdef STA_CLOCKERR 3005c0b746e5SOllivier Robert if (status & STA_CLOCKERR) (void)fprintf(fp, " clockerr"); 3006c0b746e5SOllivier Robert #endif 3007c0b746e5SOllivier Robert #ifdef STA_NANO 3008c0b746e5SOllivier Robert if (status & STA_NANO) (void)fprintf(fp, " nano"); 3009c0b746e5SOllivier Robert #endif 3010c0b746e5SOllivier Robert #ifdef STA_MODE 3011c0b746e5SOllivier Robert if (status & STA_MODE) (void)fprintf(fp, " mode=fll"); 3012c0b746e5SOllivier Robert #endif 3013c0b746e5SOllivier Robert #ifdef STA_CLK 3014c0b746e5SOllivier Robert if (status & STA_CLK) (void)fprintf(fp, " src=B"); 3015c0b746e5SOllivier Robert #endif 3016c0b746e5SOllivier Robert (void)fprintf(fp, "\n"); 3017c0b746e5SOllivier Robert (void)fprintf(fp, "pll time constant: %ld\n", 3018c0b746e5SOllivier Robert (u_long)ntohl(ik->constant)); 3019c0b746e5SOllivier Robert (void)fprintf(fp, "precision: %g s\n", 3020*052d159aSCy Schubert (u_long)ntohl(ik->precision) * tscale_usec); 3021c0b746e5SOllivier Robert (void)fprintf(fp, "frequency tolerance: %s ppm\n", 3022c0b746e5SOllivier Robert fptoa((s_fp)ntohl(ik->tolerance), 0)); 3023c0b746e5SOllivier Robert 3024c0b746e5SOllivier Robert /* 3025c0b746e5SOllivier Robert * For backwards compatibility (ugh), we find the pps variables 3026c0b746e5SOllivier Robert * only if the shift member is nonzero. 3027c0b746e5SOllivier Robert */ 3028c0b746e5SOllivier Robert if (!ik->shift) 3029c0b746e5SOllivier Robert return; 3030c0b746e5SOllivier Robert 3031c0b746e5SOllivier Robert /* 3032c0b746e5SOllivier Robert * pps variables 3033c0b746e5SOllivier Robert */ 3034c0b746e5SOllivier Robert (void)fprintf(fp, "pps frequency: %s ppm\n", 3035c0b746e5SOllivier Robert fptoa((s_fp)ntohl(ik->ppsfreq), 3)); 3036c0b746e5SOllivier Robert (void)fprintf(fp, "pps stability: %s ppm\n", 3037c0b746e5SOllivier Robert fptoa((s_fp)ntohl(ik->stabil), 3)); 3038c0b746e5SOllivier Robert (void)fprintf(fp, "pps jitter: %g s\n", 3039*052d159aSCy Schubert (u_long)ntohl(ik->jitter) * tscale_unano); 3040c0b746e5SOllivier Robert (void)fprintf(fp, "calibration interval: %d s\n", 3041c0b746e5SOllivier Robert 1 << ntohs(ik->shift)); 3042c0b746e5SOllivier Robert (void)fprintf(fp, "calibration cycles: %ld\n", 3043c0b746e5SOllivier Robert (u_long)ntohl(ik->calcnt)); 3044c0b746e5SOllivier Robert (void)fprintf(fp, "jitter exceeded: %ld\n", 3045c0b746e5SOllivier Robert (u_long)ntohl(ik->jitcnt)); 3046c0b746e5SOllivier Robert (void)fprintf(fp, "stability exceeded: %ld\n", 3047c0b746e5SOllivier Robert (u_long)ntohl(ik->stbcnt)); 3048c0b746e5SOllivier Robert (void)fprintf(fp, "calibration errors: %ld\n", 3049c0b746e5SOllivier Robert (u_long)ntohl(ik->errcnt)); 3050c0b746e5SOllivier Robert } 3051ea906c41SOllivier Robert 30522b15cb3dSCy Schubert #define IF_LIST_FMT "%2d %c %48s %c %c %12.12s %03lx %3lu %2lu %5lu %5lu %5lu %2lu %3lu %7lu\n" 30532b15cb3dSCy Schubert #define IF_LIST_FMT_STR "%2s %c %48s %c %c %12.12s %3s %3s %2s %5s %5s %5s %2s %3s %7s\n" 3054ea906c41SOllivier Robert #define IF_LIST_AFMT_STR " %48s %c\n" 30552b15cb3dSCy Schubert #define IF_LIST_LABELS "#", 'A', "Address/Mask/Broadcast", 'T', 'E', "IF name", "Flg", "TL", "#M", "recv", "sent", "drop", "S", "PC", "uptime" 30562b15cb3dSCy Schubert #define IF_LIST_LINE "==================================================================================================================\n" 3057ea906c41SOllivier Robert 3058ea906c41SOllivier Robert static void 3059ea906c41SOllivier Robert iflist( 3060ea906c41SOllivier Robert FILE *fp, 3061ea906c41SOllivier Robert struct info_if_stats *ifs, 30623311ff84SXin LI size_t items, 30633311ff84SXin LI size_t itemsize, 3064ea906c41SOllivier Robert int res 3065ea906c41SOllivier Robert ) 3066ea906c41SOllivier Robert { 30672b15cb3dSCy Schubert static const char *actions = "?.+-"; 30682b15cb3dSCy Schubert sockaddr_u saddr; 3069ea906c41SOllivier Robert 3070ea906c41SOllivier Robert if (res != 0) 3071ea906c41SOllivier Robert return; 3072ea906c41SOllivier Robert 3073ea906c41SOllivier Robert if (!checkitems(items, fp)) 3074ea906c41SOllivier Robert return; 3075ea906c41SOllivier Robert 3076ea906c41SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_if_stats))) 3077ea906c41SOllivier Robert return; 3078ea906c41SOllivier Robert 3079ea906c41SOllivier Robert fprintf(fp, IF_LIST_FMT_STR, IF_LIST_LABELS); 3080ea906c41SOllivier Robert fprintf(fp, IF_LIST_LINE); 3081ea906c41SOllivier Robert 3082ea906c41SOllivier Robert while (items > 0) { 30832b15cb3dSCy Schubert SET_ADDR(saddr, ntohl(ifs->v6_flag), 30842b15cb3dSCy Schubert ifs->unaddr.addr.s_addr, ifs->unaddr.addr6); 3085ea906c41SOllivier Robert fprintf(fp, IF_LIST_FMT, 3086ea906c41SOllivier Robert ntohl(ifs->ifnum), 3087ea906c41SOllivier Robert actions[(ifs->action >= 1 && ifs->action < 4) ? ifs->action : 0], 3088ea906c41SOllivier Robert stoa((&saddr)), 'A', 3089ea906c41SOllivier Robert ifs->ignore_packets ? 'D' : 'E', 3090ea906c41SOllivier Robert ifs->name, 30912b15cb3dSCy Schubert (u_long)ntohl(ifs->flags), 30922b15cb3dSCy Schubert (u_long)ntohl(ifs->last_ttl), 30932b15cb3dSCy Schubert (u_long)ntohl(ifs->num_mcast), 30942b15cb3dSCy Schubert (u_long)ntohl(ifs->received), 30952b15cb3dSCy Schubert (u_long)ntohl(ifs->sent), 30962b15cb3dSCy Schubert (u_long)ntohl(ifs->notsent), 30972b15cb3dSCy Schubert (u_long)ntohl(ifs->scopeid), 30982b15cb3dSCy Schubert (u_long)ntohl(ifs->peercnt), 30992b15cb3dSCy Schubert (u_long)ntohl(ifs->uptime)); 3100ea906c41SOllivier Robert 31012b15cb3dSCy Schubert SET_ADDR(saddr, ntohl(ifs->v6_flag), 31022b15cb3dSCy Schubert ifs->unmask.addr.s_addr, ifs->unmask.addr6); 3103ea906c41SOllivier Robert fprintf(fp, IF_LIST_AFMT_STR, stoa(&saddr), 'M'); 3104ea906c41SOllivier Robert 3105ea906c41SOllivier Robert if (!ntohl(ifs->v6_flag) && ntohl(ifs->flags) & (INT_BCASTOPEN)) { 31062b15cb3dSCy Schubert SET_ADDR(saddr, ntohl(ifs->v6_flag), 31072b15cb3dSCy Schubert ifs->unbcast.addr.s_addr, ifs->unbcast.addr6); 3108ea906c41SOllivier Robert fprintf(fp, IF_LIST_AFMT_STR, stoa(&saddr), 'B'); 3109ea906c41SOllivier Robert 3110ea906c41SOllivier Robert } 3111ea906c41SOllivier Robert 3112ea906c41SOllivier Robert ifs++; 3113ea906c41SOllivier Robert items--; 3114ea906c41SOllivier Robert } 3115ea906c41SOllivier Robert } 3116ea906c41SOllivier Robert 3117ea906c41SOllivier Robert /*ARGSUSED*/ 3118ea906c41SOllivier Robert static void 3119ea906c41SOllivier Robert get_if_stats( 3120ea906c41SOllivier Robert struct parse *pcmd, 3121ea906c41SOllivier Robert FILE *fp 3122ea906c41SOllivier Robert ) 3123ea906c41SOllivier Robert { 3124ea906c41SOllivier Robert struct info_if_stats *ifs; 31253311ff84SXin LI size_t items; 31263311ff84SXin LI size_t itemsize; 3127ea906c41SOllivier Robert int res; 3128ea906c41SOllivier Robert 3129ea906c41SOllivier Robert res = doquery(impl_ver, REQ_IF_STATS, 1, 0, 0, (char *)NULL, &items, 3130ea906c41SOllivier Robert &itemsize, (void *)&ifs, 0, 3131ea906c41SOllivier Robert sizeof(struct info_if_stats)); 3132ea906c41SOllivier Robert iflist(fp, ifs, items, itemsize, res); 3133ea906c41SOllivier Robert } 3134ea906c41SOllivier Robert 3135ea906c41SOllivier Robert /*ARGSUSED*/ 3136ea906c41SOllivier Robert static void 3137ea906c41SOllivier Robert do_if_reload( 3138ea906c41SOllivier Robert struct parse *pcmd, 3139ea906c41SOllivier Robert FILE *fp 3140ea906c41SOllivier Robert ) 3141ea906c41SOllivier Robert { 3142ea906c41SOllivier Robert struct info_if_stats *ifs; 31433311ff84SXin LI size_t items; 31443311ff84SXin LI size_t itemsize; 3145ea906c41SOllivier Robert int res; 3146ea906c41SOllivier Robert 3147ea906c41SOllivier Robert res = doquery(impl_ver, REQ_IF_RELOAD, 1, 0, 0, (char *)NULL, &items, 3148ea906c41SOllivier Robert &itemsize, (void *)&ifs, 0, 3149ea906c41SOllivier Robert sizeof(struct info_if_stats)); 3150ea906c41SOllivier Robert iflist(fp, ifs, items, itemsize, res); 3151ea906c41SOllivier Robert } 3152