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))) 385*2d4e511cSCy Schubert { 386*2d4e511cSCy Schubert const char *strhost = nntohost(&paddr); 387*2d4e511cSCy Schubert const char *straddr = stoa(&paddr); 388*2d4e511cSCy Schubert (void) fprintf(fp, "%-12s %s", 389*2d4e511cSCy Schubert modetoa(plist->hmode), strhost); 390*2d4e511cSCy Schubert if (strcmp(strhost,straddr)) 391*2d4e511cSCy Schubert (void) fprintf(fp, " (%s)\n", straddr); 392*2d4e511cSCy Schubert else 393*2d4e511cSCy Schubert (void) fprintf(fp, "\n"); 394*2d4e511cSCy Schubert } 395c0b746e5SOllivier Robert plist++; 396c0b746e5SOllivier Robert items--; 397c0b746e5SOllivier Robert } 398c0b746e5SOllivier Robert } 399c0b746e5SOllivier Robert 400c0b746e5SOllivier Robert 401c0b746e5SOllivier Robert /* 402c0b746e5SOllivier Robert * peers - show peer summary 403c0b746e5SOllivier Robert */ 404c0b746e5SOllivier Robert static void 405c0b746e5SOllivier Robert peers( 406c0b746e5SOllivier Robert struct parse *pcmd, 407c0b746e5SOllivier Robert FILE *fp 408c0b746e5SOllivier Robert ) 409c0b746e5SOllivier Robert { 410c0b746e5SOllivier Robert dopeers(pcmd, fp, 0); 411c0b746e5SOllivier Robert } 412c0b746e5SOllivier Robert 413c0b746e5SOllivier Robert /* 414c0b746e5SOllivier Robert * dmpeers - show peer summary, Dave Mills style 415c0b746e5SOllivier Robert */ 416c0b746e5SOllivier Robert static void 417c0b746e5SOllivier Robert dmpeers( 418c0b746e5SOllivier Robert struct parse *pcmd, 419c0b746e5SOllivier Robert FILE *fp 420c0b746e5SOllivier Robert ) 421c0b746e5SOllivier Robert { 422c0b746e5SOllivier Robert dopeers(pcmd, fp, 1); 423c0b746e5SOllivier Robert } 424c0b746e5SOllivier Robert 425c0b746e5SOllivier Robert 426c0b746e5SOllivier Robert /* 427c0b746e5SOllivier Robert * peers - show peer summary 428c0b746e5SOllivier Robert */ 429c0b746e5SOllivier Robert /*ARGSUSED*/ 430c0b746e5SOllivier Robert static void 431c0b746e5SOllivier Robert dopeers( 432c0b746e5SOllivier Robert struct parse *pcmd, 433c0b746e5SOllivier Robert FILE *fp, 434c0b746e5SOllivier Robert int dmstyle 435c0b746e5SOllivier Robert ) 436c0b746e5SOllivier Robert { 437c0b746e5SOllivier Robert struct info_peer_summary *plist; 4382b15cb3dSCy Schubert sockaddr_u dstadr; 4392b15cb3dSCy Schubert sockaddr_u srcadr; 4403311ff84SXin LI size_t items; 4413311ff84SXin LI size_t itemsize; 442c0b746e5SOllivier Robert int ntp_poll; 443c0b746e5SOllivier Robert int res; 444c0b746e5SOllivier Robert int c; 445c0b746e5SOllivier Robert l_fp tempts; 446c0b746e5SOllivier Robert 4479c2daa00SOllivier Robert again: 4489c2daa00SOllivier Robert res = doquery(impl_ver, REQ_PEER_LIST_SUM, 0, 0, 0, (char *)NULL, 4499c2daa00SOllivier Robert &items, &itemsize, (void *)&plist, 0, 4509c2daa00SOllivier Robert sizeof(struct info_peer_summary)); 4519c2daa00SOllivier Robert 4529c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 4539c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 4549c2daa00SOllivier Robert goto again; 4559c2daa00SOllivier Robert } 456c0b746e5SOllivier Robert 457ea906c41SOllivier Robert if (res != 0) 458c0b746e5SOllivier Robert return; 459c0b746e5SOllivier Robert 460c0b746e5SOllivier Robert if (!checkitems(items, fp)) 461c0b746e5SOllivier Robert return; 462c0b746e5SOllivier Robert 4639c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_peer_summary)) && 4649c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_peer_summary))) 465c0b746e5SOllivier Robert return; 466c0b746e5SOllivier Robert 467c0b746e5SOllivier Robert (void) fprintf(fp, 468c0b746e5SOllivier Robert " remote local st poll reach delay offset disp\n"); 469c0b746e5SOllivier Robert (void) fprintf(fp, 470c0b746e5SOllivier Robert "=======================================================================\n"); 471c0b746e5SOllivier Robert while (items > 0) { 472c0b746e5SOllivier Robert if (!dmstyle) { 473c0b746e5SOllivier Robert if (plist->flags & INFO_FLAG_SYSPEER) 474c0b746e5SOllivier Robert c = '*'; 475c0b746e5SOllivier Robert else if (plist->hmode == MODE_ACTIVE) 476c0b746e5SOllivier Robert c = '+'; 477c0b746e5SOllivier Robert else if (plist->hmode == MODE_PASSIVE) 478c0b746e5SOllivier Robert c = '-'; 479c0b746e5SOllivier Robert else if (plist->hmode == MODE_CLIENT) 480c0b746e5SOllivier Robert c = '='; 481c0b746e5SOllivier Robert else if (plist->hmode == MODE_BROADCAST) 482c0b746e5SOllivier Robert c = '^'; 483c0b746e5SOllivier Robert else if (plist->hmode == MODE_BCLIENT) 484c0b746e5SOllivier Robert c = '~'; 485c0b746e5SOllivier Robert else 486c0b746e5SOllivier Robert c = ' '; 487c0b746e5SOllivier Robert } else { 488c0b746e5SOllivier Robert if (plist->flags & INFO_FLAG_SYSPEER) 489c0b746e5SOllivier Robert c = '*'; 490c0b746e5SOllivier Robert else if (plist->flags & INFO_FLAG_SHORTLIST) 491c0b746e5SOllivier Robert c = '+'; 492c0b746e5SOllivier Robert else if (plist->flags & INFO_FLAG_SEL_CANDIDATE) 493c0b746e5SOllivier Robert c = '.'; 494c0b746e5SOllivier Robert else 495c0b746e5SOllivier Robert c = ' '; 496c0b746e5SOllivier Robert } 497c0b746e5SOllivier Robert NTOHL_FP(&(plist->offset), &tempts); 498c0b746e5SOllivier Robert ntp_poll = 1<<max(min3(plist->ppoll, plist->hpoll, NTP_MAXPOLL), 499c0b746e5SOllivier Robert NTP_MINPOLL); 5002b15cb3dSCy Schubert SET_ADDRS(dstadr, srcadr, plist, dstadr, srcadr); 5019c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 5029c2daa00SOllivier Robert ((pcmd->argval->ival == 6) && (plist->v6_flag != 0)) || 5039c2daa00SOllivier Robert ((pcmd->argval->ival == 4) && (plist->v6_flag == 0))) 504c0b746e5SOllivier Robert (void) fprintf(fp, 5052b15cb3dSCy Schubert "%c%-15.15s %-15.15s %2u %4d %3o %7.7s %9.9s %7.7s\n", 5069c2daa00SOllivier Robert c, nntohost(&srcadr), stoa(&dstadr), 507c0b746e5SOllivier Robert plist->stratum, ntp_poll, plist->reach, 508c0b746e5SOllivier Robert fptoa(NTOHS_FP(plist->delay), 5), 509c0b746e5SOllivier Robert lfptoa(&tempts, 6), 510c0b746e5SOllivier Robert ufptoa(NTOHS_FP(plist->dispersion), 5)); 511c0b746e5SOllivier Robert plist++; 512c0b746e5SOllivier Robert items--; 513c0b746e5SOllivier Robert } 514c0b746e5SOllivier Robert } 515c0b746e5SOllivier Robert 516c0b746e5SOllivier Robert /* Convert a refid & stratum (in host order) to a string */ 517c0b746e5SOllivier Robert static char * 518c0b746e5SOllivier Robert refid_string( 519c0b746e5SOllivier Robert u_int32 refid, 520c0b746e5SOllivier Robert int stratum 521c0b746e5SOllivier Robert ) 522c0b746e5SOllivier Robert { 523c0b746e5SOllivier Robert if (stratum <= 1) { 524c0b746e5SOllivier Robert static char junk[5]; 525c0b746e5SOllivier Robert junk[4] = 0; 5262b15cb3dSCy Schubert memcpy(junk, &refid, 4); 527c0b746e5SOllivier Robert return junk; 528c0b746e5SOllivier Robert } 529c0b746e5SOllivier Robert 530c0b746e5SOllivier Robert return numtoa(refid); 531c0b746e5SOllivier Robert } 532c0b746e5SOllivier Robert 533ea906c41SOllivier Robert static void 534ea906c41SOllivier Robert print_pflag( 535ea906c41SOllivier Robert FILE * fp, 536ea906c41SOllivier Robert u_int32 flags 537ea906c41SOllivier Robert ) 538ea906c41SOllivier Robert { 5392b15cb3dSCy Schubert static const char none[] = ""; 5402b15cb3dSCy Schubert static const char comma[] = ","; 5412b15cb3dSCy Schubert const char *dlim; 542ea906c41SOllivier Robert 5432b15cb3dSCy Schubert if (0 == flags) { 5442b15cb3dSCy Schubert fprintf(fp, " none\n"); 5452b15cb3dSCy Schubert return; 5462b15cb3dSCy Schubert } 5472b15cb3dSCy Schubert dlim = none; 548ea906c41SOllivier Robert if (flags & INFO_FLAG_SYSPEER) { 5492b15cb3dSCy Schubert fprintf(fp, " system_peer"); 5502b15cb3dSCy Schubert dlim = comma; 551ea906c41SOllivier Robert } 552ea906c41SOllivier Robert if (flags & INFO_FLAG_CONFIG) { 5532b15cb3dSCy Schubert fprintf(fp, "%s config", dlim); 5542b15cb3dSCy Schubert dlim = comma; 555ea906c41SOllivier Robert } 556ea906c41SOllivier Robert if (flags & INFO_FLAG_REFCLOCK) { 5572b15cb3dSCy Schubert fprintf(fp, "%s refclock", dlim); 5582b15cb3dSCy Schubert dlim = comma; 559ea906c41SOllivier Robert } 560ea906c41SOllivier Robert if (flags & INFO_FLAG_AUTHENABLE) { 5612b15cb3dSCy Schubert fprintf(fp, "%s auth", dlim); 5622b15cb3dSCy Schubert dlim = comma; 563ea906c41SOllivier Robert } 564ea906c41SOllivier Robert if (flags & INFO_FLAG_PREFER) { 5652b15cb3dSCy Schubert fprintf(fp, "%s prefer", dlim); 5662b15cb3dSCy Schubert dlim = comma; 567ea906c41SOllivier Robert } 568ea906c41SOllivier Robert if (flags & INFO_FLAG_IBURST) { 5692b15cb3dSCy Schubert fprintf(fp, "%s iburst", dlim); 5702b15cb3dSCy Schubert dlim = comma; 571ea906c41SOllivier Robert } 572ea906c41SOllivier Robert if (flags & INFO_FLAG_BURST) { 5732b15cb3dSCy Schubert fprintf(fp, "%s burst", dlim); 5742b15cb3dSCy Schubert dlim = comma; 575ea906c41SOllivier Robert } 5762b15cb3dSCy Schubert if (flags & INFO_FLAG_SEL_CANDIDATE) { 5772b15cb3dSCy Schubert fprintf(fp, "%s candidate", dlim); 5782b15cb3dSCy Schubert dlim = comma; 579ea906c41SOllivier Robert } 5802b15cb3dSCy Schubert if (flags & INFO_FLAG_SHORTLIST) { 5812b15cb3dSCy Schubert fprintf(fp, "%s shortlist", dlim); 5822b15cb3dSCy Schubert dlim = comma; 5832b15cb3dSCy Schubert } 5842b15cb3dSCy Schubert fprintf(fp, "\n"); 585ea906c41SOllivier Robert } 586c0b746e5SOllivier Robert /* 587c0b746e5SOllivier Robert * printpeer - print detail information for a peer 588c0b746e5SOllivier Robert */ 589c0b746e5SOllivier Robert static void 590c0b746e5SOllivier Robert printpeer( 591c0b746e5SOllivier Robert register struct info_peer *pp, 592c0b746e5SOllivier Robert FILE *fp 593c0b746e5SOllivier Robert ) 594c0b746e5SOllivier Robert { 595c0b746e5SOllivier Robert register int i; 596c0b746e5SOllivier Robert l_fp tempts; 5972b15cb3dSCy Schubert sockaddr_u srcadr, dstadr; 598c0b746e5SOllivier Robert 5992b15cb3dSCy Schubert SET_ADDRS(dstadr, srcadr, pp, dstadr, srcadr); 6002b15cb3dSCy Schubert 601c0b746e5SOllivier Robert (void) fprintf(fp, "remote %s, local %s\n", 6029c2daa00SOllivier Robert stoa(&srcadr), stoa(&dstadr)); 603c0b746e5SOllivier Robert (void) fprintf(fp, "hmode %s, pmode %s, stratum %d, precision %d\n", 604c0b746e5SOllivier Robert modetoa(pp->hmode), modetoa(pp->pmode), 605c0b746e5SOllivier Robert pp->stratum, pp->precision); 606c0b746e5SOllivier Robert 607c0b746e5SOllivier Robert (void) fprintf(fp, 608c0b746e5SOllivier Robert "leap %c%c, refid [%s], rootdistance %s, rootdispersion %s\n", 609c0b746e5SOllivier Robert pp->leap & 0x2 ? '1' : '0', 610c0b746e5SOllivier Robert pp->leap & 0x1 ? '1' : '0', 611*2d4e511cSCy Schubert refid_string(pp->refid, 612*2d4e511cSCy Schubert (pp->flags & INFO_FLAG_REFCLOCK ? 0 : pp->stratum)), 613*2d4e511cSCy Schubert fptoa(NTOHS_FP(pp->rootdelay), 5), 614c0b746e5SOllivier Robert ufptoa(NTOHS_FP(pp->rootdispersion), 5)); 615c0b746e5SOllivier Robert 616c0b746e5SOllivier Robert (void) fprintf(fp, 617c0b746e5SOllivier Robert "ppoll %d, hpoll %d, keyid %lu, version %d, association %u\n", 618c0b746e5SOllivier Robert pp->ppoll, pp->hpoll, (u_long)pp->keyid, pp->version, ntohs(pp->associd)); 619c0b746e5SOllivier Robert 620c0b746e5SOllivier Robert (void) fprintf(fp, 621224ba2bdSOllivier Robert "reach %03o, unreach %d, flash 0x%04x, ", 622224ba2bdSOllivier Robert pp->reach, pp->unreach, pp->flash2); 623c0b746e5SOllivier Robert 624c0b746e5SOllivier Robert (void) fprintf(fp, "boffset %s, ttl/mode %d\n", 625c0b746e5SOllivier Robert fptoa(NTOHS_FP(pp->estbdelay), 5), pp->ttl); 626c0b746e5SOllivier Robert 627c0b746e5SOllivier Robert (void) fprintf(fp, "timer %lds, flags", (long)ntohl(pp->timer)); 628ea906c41SOllivier Robert print_pflag(fp, pp->flags); 629c0b746e5SOllivier Robert 630c0b746e5SOllivier Robert NTOHL_FP(&pp->reftime, &tempts); 631c0b746e5SOllivier Robert (void) fprintf(fp, "reference time: %s\n", 632c0b746e5SOllivier Robert prettydate(&tempts)); 633c0b746e5SOllivier Robert NTOHL_FP(&pp->org, &tempts); 634c0b746e5SOllivier Robert (void) fprintf(fp, "originate timestamp: %s\n", 635c0b746e5SOllivier Robert prettydate(&tempts)); 636c0b746e5SOllivier Robert NTOHL_FP(&pp->rec, &tempts); 637c0b746e5SOllivier Robert (void) fprintf(fp, "receive timestamp: %s\n", 638c0b746e5SOllivier Robert prettydate(&tempts)); 639c0b746e5SOllivier Robert NTOHL_FP(&pp->xmt, &tempts); 640c0b746e5SOllivier Robert (void) fprintf(fp, "transmit timestamp: %s\n", 641c0b746e5SOllivier Robert prettydate(&tempts)); 642c0b746e5SOllivier Robert 643c0b746e5SOllivier Robert (void) fprintf(fp, "filter delay: "); 644c0b746e5SOllivier Robert for (i = 0; i < NTP_SHIFT; i++) { 645c0b746e5SOllivier Robert (void) fprintf(fp, " %-8.8s", 646c0b746e5SOllivier Robert fptoa(NTOHS_FP(pp->filtdelay[i]), 5)); 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 offset:"); 653c0b746e5SOllivier Robert for (i = 0; i < NTP_SHIFT; i++) { 654c0b746e5SOllivier Robert NTOHL_FP(&pp->filtoffset[i], &tempts); 655c0b746e5SOllivier Robert (void) fprintf(fp, " %-8.8s", lfptoa(&tempts, 6)); 656c0b746e5SOllivier Robert if (i == (NTP_SHIFT>>1)-1) 657c0b746e5SOllivier Robert (void) fprintf(fp, "\n "); 658c0b746e5SOllivier Robert } 659c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 660c0b746e5SOllivier Robert 661c0b746e5SOllivier Robert (void) fprintf(fp, "filter order: "); 662c0b746e5SOllivier Robert for (i = 0; i < NTP_SHIFT; i++) { 663c0b746e5SOllivier Robert (void) fprintf(fp, " %-8d", pp->order[i]); 664c0b746e5SOllivier Robert if (i == (NTP_SHIFT>>1)-1) 665c0b746e5SOllivier Robert (void) fprintf(fp, "\n "); 666c0b746e5SOllivier Robert } 667c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 668c0b746e5SOllivier Robert 669c0b746e5SOllivier Robert 670c0b746e5SOllivier Robert NTOHL_FP(&pp->offset, &tempts); 671c0b746e5SOllivier Robert (void) fprintf(fp, 672c0b746e5SOllivier Robert "offset %s, delay %s, error bound %s, filter error %s\n", 673c0b746e5SOllivier Robert lfptoa(&tempts, 6), fptoa(NTOHS_FP(pp->delay), 5), 674c0b746e5SOllivier Robert ufptoa(NTOHS_FP(pp->dispersion), 5), 675c0b746e5SOllivier Robert ufptoa(NTOHS_FP(pp->selectdisp), 5)); 676c0b746e5SOllivier Robert } 677c0b746e5SOllivier Robert 678c0b746e5SOllivier Robert 679c0b746e5SOllivier Robert /* 680c0b746e5SOllivier Robert * showpeer - show detailed information for a peer 681c0b746e5SOllivier Robert */ 682c0b746e5SOllivier Robert static void 683c0b746e5SOllivier Robert showpeer( 684c0b746e5SOllivier Robert struct parse *pcmd, 685c0b746e5SOllivier Robert FILE *fp 686c0b746e5SOllivier Robert ) 687c0b746e5SOllivier Robert { 688c0b746e5SOllivier Robert struct info_peer *pp; 689c0b746e5SOllivier Robert /* 4 is the maximum number of peers which will fit in a packet */ 6909c2daa00SOllivier Robert struct info_peer_list *pl, plist[min(MAXARGS, 4)]; 6913311ff84SXin LI size_t qitemlim; 6923311ff84SXin LI size_t qitems; 6933311ff84SXin LI size_t items; 6943311ff84SXin LI size_t itemsize; 695c0b746e5SOllivier Robert int res; 6969c2daa00SOllivier Robert int sendsize; 697c0b746e5SOllivier Robert 6989c2daa00SOllivier Robert again: 6999c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 7009c2daa00SOllivier Robert sendsize = sizeof(struct info_peer_list); 7019c2daa00SOllivier Robert else 7029c2daa00SOllivier Robert sendsize = v4sizeof(struct info_peer_list); 7039c2daa00SOllivier Robert 7042b15cb3dSCy Schubert qitemlim = min(pcmd->nargs, COUNTOF(plist)); 7052b15cb3dSCy Schubert for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) { 7062b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[qitems].netnum)) { 7072b15cb3dSCy Schubert pl->addr = NSRCADR(&pcmd->argval[qitems].netnum); 7089c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 7099c2daa00SOllivier Robert pl->v6_flag = 0; 7109c2daa00SOllivier Robert } else { 7119c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 7129c2daa00SOllivier Robert fprintf(stderr, 7139c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 7149c2daa00SOllivier Robert return; 7159c2daa00SOllivier Robert } 7162b15cb3dSCy Schubert pl->addr6 = SOCK_ADDR6(&pcmd->argval[qitems].netnum); 7179c2daa00SOllivier Robert pl->v6_flag = 1; 7189c2daa00SOllivier Robert } 7199c2daa00SOllivier Robert pl->port = (u_short)s_port; 7209c2daa00SOllivier Robert pl->hmode = pl->flags = 0; 7212b15cb3dSCy Schubert pl = (void *)((char *)pl + sendsize); 722c0b746e5SOllivier Robert } 723c0b746e5SOllivier Robert 7249c2daa00SOllivier Robert res = doquery(impl_ver, REQ_PEER_INFO, 0, qitems, 7259c2daa00SOllivier Robert sendsize, (char *)plist, &items, 7269c2daa00SOllivier Robert &itemsize, (void *)&pp, 0, sizeof(struct info_peer)); 7279c2daa00SOllivier Robert 7289c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 7299c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 7309c2daa00SOllivier Robert goto again; 7319c2daa00SOllivier Robert } 732c0b746e5SOllivier Robert 733ea906c41SOllivier Robert if (res != 0) 734c0b746e5SOllivier Robert return; 735c0b746e5SOllivier Robert 736c0b746e5SOllivier Robert if (!checkitems(items, fp)) 737c0b746e5SOllivier Robert return; 738c0b746e5SOllivier Robert 7399c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_peer)) && 7409c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_peer))) 741c0b746e5SOllivier Robert return; 742c0b746e5SOllivier Robert 743c0b746e5SOllivier Robert while (items-- > 0) { 744c0b746e5SOllivier Robert printpeer(pp, fp); 745c0b746e5SOllivier Robert if (items > 0) 7462b15cb3dSCy Schubert fprintf(fp, "\n"); 747c0b746e5SOllivier Robert pp++; 748c0b746e5SOllivier Robert } 749c0b746e5SOllivier Robert } 750c0b746e5SOllivier Robert 751c0b746e5SOllivier Robert 752c0b746e5SOllivier Robert /* 753c0b746e5SOllivier Robert * peerstats - return statistics for a peer 754c0b746e5SOllivier Robert */ 755c0b746e5SOllivier Robert static void 756c0b746e5SOllivier Robert peerstats( 757c0b746e5SOllivier Robert struct parse *pcmd, 758c0b746e5SOllivier Robert FILE *fp 759c0b746e5SOllivier Robert ) 760c0b746e5SOllivier Robert { 761c0b746e5SOllivier Robert struct info_peer_stats *pp; 762c0b746e5SOllivier Robert /* 4 is the maximum number of peers which will fit in a packet */ 7639c2daa00SOllivier Robert struct info_peer_list *pl, plist[min(MAXARGS, 4)]; 7642b15cb3dSCy Schubert sockaddr_u src, dst; 7653311ff84SXin LI size_t qitemlim; 7663311ff84SXin LI size_t qitems; 7673311ff84SXin LI size_t items; 7683311ff84SXin LI size_t itemsize; 769c0b746e5SOllivier Robert int res; 7703311ff84SXin LI size_t sendsize; 771c0b746e5SOllivier Robert 7729c2daa00SOllivier Robert again: 7739c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 7749c2daa00SOllivier Robert sendsize = sizeof(struct info_peer_list); 7759c2daa00SOllivier Robert else 7769c2daa00SOllivier Robert sendsize = v4sizeof(struct info_peer_list); 7779c2daa00SOllivier Robert 7782b15cb3dSCy Schubert ZERO(plist); 7792b15cb3dSCy Schubert 7802b15cb3dSCy Schubert qitemlim = min(pcmd->nargs, COUNTOF(plist)); 7812b15cb3dSCy Schubert for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) { 7822b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[qitems].netnum)) { 7832b15cb3dSCy Schubert pl->addr = NSRCADR(&pcmd->argval[qitems].netnum); 7849c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 7859c2daa00SOllivier Robert pl->v6_flag = 0; 7869c2daa00SOllivier Robert } else { 7879c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 7889c2daa00SOllivier Robert fprintf(stderr, 7899c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 7909c2daa00SOllivier Robert return; 7919c2daa00SOllivier Robert } 7922b15cb3dSCy Schubert pl->addr6 = SOCK_ADDR6(&pcmd->argval[qitems].netnum); 7939c2daa00SOllivier Robert pl->v6_flag = 1; 7949c2daa00SOllivier Robert } 7959c2daa00SOllivier Robert pl->port = (u_short)s_port; 7969c2daa00SOllivier Robert pl->hmode = plist[qitems].flags = 0; 7972b15cb3dSCy Schubert pl = (void *)((char *)pl + sendsize); 798c0b746e5SOllivier Robert } 799c0b746e5SOllivier Robert 8009c2daa00SOllivier Robert res = doquery(impl_ver, REQ_PEER_STATS, 0, qitems, 8019c2daa00SOllivier Robert sendsize, (char *)plist, &items, 8029c2daa00SOllivier Robert &itemsize, (void *)&pp, 0, 8039c2daa00SOllivier Robert sizeof(struct info_peer_stats)); 8049c2daa00SOllivier Robert 8059c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 8069c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 8079c2daa00SOllivier Robert goto again; 8089c2daa00SOllivier Robert } 809c0b746e5SOllivier Robert 810ea906c41SOllivier Robert if (res != 0) 811c0b746e5SOllivier Robert return; 812c0b746e5SOllivier Robert 813c0b746e5SOllivier Robert if (!checkitems(items, fp)) 814c0b746e5SOllivier Robert return; 815c0b746e5SOllivier Robert 8169c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_peer_stats)) && 8179c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_peer_stats))) 818c0b746e5SOllivier Robert return; 819c0b746e5SOllivier Robert 820c0b746e5SOllivier Robert while (items-- > 0) { 8212b15cb3dSCy Schubert ZERO_SOCK(&dst); 8222b15cb3dSCy Schubert ZERO_SOCK(&src); 8239c2daa00SOllivier Robert if (pp->v6_flag != 0) { 8242b15cb3dSCy Schubert AF(&dst) = AF_INET6; 8252b15cb3dSCy Schubert AF(&src) = AF_INET6; 8262b15cb3dSCy Schubert SOCK_ADDR6(&dst) = pp->dstadr6; 8272b15cb3dSCy Schubert SOCK_ADDR6(&src) = pp->srcadr6; 8289c2daa00SOllivier Robert } else { 8292b15cb3dSCy Schubert AF(&dst) = AF_INET; 8302b15cb3dSCy Schubert AF(&src) = AF_INET; 8312b15cb3dSCy Schubert NSRCADR(&dst) = pp->dstadr; 8322b15cb3dSCy Schubert NSRCADR(&src) = pp->srcadr; 8339c2daa00SOllivier Robert } 8342b15cb3dSCy Schubert #ifdef ISC_PLATFORM_HAVESALEN 8352b15cb3dSCy Schubert src.sa.sa_len = SOCKLEN(&src); 8362b15cb3dSCy Schubert dst.sa.sa_len = SOCKLEN(&dst); 8379c2daa00SOllivier Robert #endif 8382b15cb3dSCy Schubert fprintf(fp, "remote host: %s\n", 8399c2daa00SOllivier Robert nntohost(&src)); 8402b15cb3dSCy Schubert fprintf(fp, "local interface: %s\n", 8419c2daa00SOllivier Robert stoa(&dst)); 8422b15cb3dSCy Schubert fprintf(fp, "time last received: %lus\n", 8432b15cb3dSCy Schubert (u_long)ntohl(pp->timereceived)); 8442b15cb3dSCy Schubert fprintf(fp, "time until next send: %lus\n", 8452b15cb3dSCy Schubert (u_long)ntohl(pp->timetosend)); 8462b15cb3dSCy Schubert fprintf(fp, "reachability change: %lus\n", 8472b15cb3dSCy Schubert (u_long)ntohl(pp->timereachable)); 8482b15cb3dSCy Schubert fprintf(fp, "packets sent: %lu\n", 8492b15cb3dSCy Schubert (u_long)ntohl(pp->sent)); 8502b15cb3dSCy Schubert fprintf(fp, "packets received: %lu\n", 8512b15cb3dSCy Schubert (u_long)ntohl(pp->processed)); 8522b15cb3dSCy Schubert fprintf(fp, "bad authentication: %lu\n", 8532b15cb3dSCy Schubert (u_long)ntohl(pp->badauth)); 8542b15cb3dSCy Schubert fprintf(fp, "bogus origin: %lu\n", 8552b15cb3dSCy Schubert (u_long)ntohl(pp->bogusorg)); 8562b15cb3dSCy Schubert fprintf(fp, "duplicate: %lu\n", 8572b15cb3dSCy Schubert (u_long)ntohl(pp->oldpkt)); 8582b15cb3dSCy Schubert fprintf(fp, "bad dispersion: %lu\n", 8592b15cb3dSCy Schubert (u_long)ntohl(pp->seldisp)); 8602b15cb3dSCy Schubert fprintf(fp, "bad reference time: %lu\n", 8612b15cb3dSCy Schubert (u_long)ntohl(pp->selbroken)); 8622b15cb3dSCy Schubert fprintf(fp, "candidate order: %u\n", 8632b15cb3dSCy Schubert pp->candidate); 864c0b746e5SOllivier Robert if (items > 0) 8652b15cb3dSCy Schubert fprintf(fp, "\n"); 8662b15cb3dSCy Schubert fprintf(fp, "flags: "); 867ea906c41SOllivier Robert print_pflag(fp, ntohs(pp->flags)); 868c0b746e5SOllivier Robert pp++; 869c0b746e5SOllivier Robert } 870c0b746e5SOllivier Robert } 871c0b746e5SOllivier Robert 872c0b746e5SOllivier Robert 873c0b746e5SOllivier Robert /* 874c0b746e5SOllivier Robert * loopinfo - show loop filter information 875c0b746e5SOllivier Robert */ 876c0b746e5SOllivier Robert static void 877c0b746e5SOllivier Robert loopinfo( 878c0b746e5SOllivier Robert struct parse *pcmd, 879c0b746e5SOllivier Robert FILE *fp 880c0b746e5SOllivier Robert ) 881c0b746e5SOllivier Robert { 882c0b746e5SOllivier Robert struct info_loop *il; 8833311ff84SXin LI size_t items; 8843311ff84SXin LI size_t itemsize; 885c0b746e5SOllivier Robert int oneline = 0; 886c0b746e5SOllivier Robert int res; 887c0b746e5SOllivier Robert l_fp tempts; 888c0b746e5SOllivier Robert 889c0b746e5SOllivier Robert if (pcmd->nargs > 0) { 890c0b746e5SOllivier Robert if (STREQ(pcmd->argval[0].string, "oneline")) 891c0b746e5SOllivier Robert oneline = 1; 892c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[0].string, "multiline")) 893c0b746e5SOllivier Robert oneline = 0; 894c0b746e5SOllivier Robert else { 895c0b746e5SOllivier Robert (void) fprintf(stderr, "How many lines?\n"); 896c0b746e5SOllivier Robert return; 897c0b746e5SOllivier Robert } 898c0b746e5SOllivier Robert } 899c0b746e5SOllivier Robert 9009c2daa00SOllivier Robert again: 9019c2daa00SOllivier Robert res = doquery(impl_ver, REQ_LOOP_INFO, 0, 0, 0, (char *)NULL, 9029c2daa00SOllivier Robert &items, &itemsize, (void *)&il, 0, 9039c2daa00SOllivier Robert sizeof(struct info_loop)); 9049c2daa00SOllivier Robert 9059c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 9069c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 9079c2daa00SOllivier Robert goto again; 9089c2daa00SOllivier Robert } 909c0b746e5SOllivier Robert 910ea906c41SOllivier Robert if (res != 0) 911c0b746e5SOllivier Robert return; 912c0b746e5SOllivier Robert 913c0b746e5SOllivier Robert if (!check1item(items, fp)) 914c0b746e5SOllivier Robert return; 915c0b746e5SOllivier Robert 916c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_loop))) 917c0b746e5SOllivier Robert return; 918c0b746e5SOllivier Robert 919c0b746e5SOllivier Robert if (oneline) { 920c0b746e5SOllivier Robert l_fp temp2ts; 921c0b746e5SOllivier Robert 922c0b746e5SOllivier Robert NTOHL_FP(&il->last_offset, &tempts); 923c0b746e5SOllivier Robert NTOHL_FP(&il->drift_comp, &temp2ts); 924c0b746e5SOllivier Robert 925c0b746e5SOllivier Robert (void) fprintf(fp, 926c0b746e5SOllivier Robert "offset %s, frequency %s, time_const %ld, watchdog %ld\n", 927c0b746e5SOllivier Robert lfptoa(&tempts, 6), 928c0b746e5SOllivier Robert lfptoa(&temp2ts, 3), 9292b15cb3dSCy Schubert (long)(int32)ntohl((u_long)il->compliance), 930ea906c41SOllivier Robert (u_long)ntohl((u_long)il->watchdog_timer)); 931c0b746e5SOllivier Robert } else { 932c0b746e5SOllivier Robert NTOHL_FP(&il->last_offset, &tempts); 933c0b746e5SOllivier Robert (void) fprintf(fp, "offset: %s s\n", 934c0b746e5SOllivier Robert lfptoa(&tempts, 6)); 935c0b746e5SOllivier Robert NTOHL_FP(&il->drift_comp, &tempts); 936c0b746e5SOllivier Robert (void) fprintf(fp, "frequency: %s ppm\n", 937c0b746e5SOllivier Robert lfptoa(&tempts, 3)); 938c0b746e5SOllivier Robert (void) fprintf(fp, "poll adjust: %ld\n", 9392b15cb3dSCy Schubert (long)(int32)ntohl(il->compliance)); 940c0b746e5SOllivier Robert (void) fprintf(fp, "watchdog timer: %ld s\n", 941c0b746e5SOllivier Robert (u_long)ntohl(il->watchdog_timer)); 942c0b746e5SOllivier Robert } 943c0b746e5SOllivier Robert } 944c0b746e5SOllivier Robert 945c0b746e5SOllivier Robert 946c0b746e5SOllivier Robert /* 947c0b746e5SOllivier Robert * sysinfo - show current system state 948c0b746e5SOllivier Robert */ 949c0b746e5SOllivier Robert /*ARGSUSED*/ 950c0b746e5SOllivier Robert static void 951c0b746e5SOllivier Robert sysinfo( 952c0b746e5SOllivier Robert struct parse *pcmd, 953c0b746e5SOllivier Robert FILE *fp 954c0b746e5SOllivier Robert ) 955c0b746e5SOllivier Robert { 956c0b746e5SOllivier Robert struct info_sys *is; 9572b15cb3dSCy Schubert sockaddr_u peeraddr; 9583311ff84SXin LI size_t items; 9593311ff84SXin LI size_t itemsize; 960c0b746e5SOllivier Robert int res; 961c0b746e5SOllivier Robert l_fp tempts; 962c0b746e5SOllivier Robert 9639c2daa00SOllivier Robert again: 9649c2daa00SOllivier Robert res = doquery(impl_ver, REQ_SYS_INFO, 0, 0, 0, (char *)NULL, 9659c2daa00SOllivier Robert &items, &itemsize, (void *)&is, 0, 9669c2daa00SOllivier Robert sizeof(struct info_sys)); 9679c2daa00SOllivier Robert 9689c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 9699c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 9709c2daa00SOllivier Robert goto again; 9719c2daa00SOllivier Robert } 972c0b746e5SOllivier Robert 973ea906c41SOllivier Robert if (res != 0) 974c0b746e5SOllivier Robert return; 975c0b746e5SOllivier Robert 976c0b746e5SOllivier Robert if (!check1item(items, fp)) 977c0b746e5SOllivier Robert return; 978c0b746e5SOllivier Robert 9799c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_sys)) && 9809c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_sys))) 981c0b746e5SOllivier Robert return; 982c0b746e5SOllivier Robert 9832b15cb3dSCy Schubert SET_ADDR(peeraddr, is->v6_flag, is->peer, is->peer6); 9842b15cb3dSCy Schubert 9859c2daa00SOllivier Robert (void) fprintf(fp, "system peer: %s\n", nntohost(&peeraddr)); 986c0b746e5SOllivier Robert (void) fprintf(fp, "system peer mode: %s\n", modetoa(is->peer_mode)); 987c0b746e5SOllivier Robert (void) fprintf(fp, "leap indicator: %c%c\n", 988c0b746e5SOllivier Robert is->leap & 0x2 ? '1' : '0', 989c0b746e5SOllivier Robert is->leap & 0x1 ? '1' : '0'); 990c0b746e5SOllivier Robert (void) fprintf(fp, "stratum: %d\n", (int)is->stratum); 991c0b746e5SOllivier Robert (void) fprintf(fp, "precision: %d\n", (int)is->precision); 992c0b746e5SOllivier Robert (void) fprintf(fp, "root distance: %s s\n", 993c0b746e5SOllivier Robert fptoa(NTOHS_FP(is->rootdelay), 5)); 994c0b746e5SOllivier Robert (void) fprintf(fp, "root dispersion: %s s\n", 995c0b746e5SOllivier Robert ufptoa(NTOHS_FP(is->rootdispersion), 5)); 996c0b746e5SOllivier Robert (void) fprintf(fp, "reference ID: [%s]\n", 997c0b746e5SOllivier Robert refid_string(is->refid, is->stratum)); 998c0b746e5SOllivier Robert NTOHL_FP(&is->reftime, &tempts); 999c0b746e5SOllivier Robert (void) fprintf(fp, "reference time: %s\n", prettydate(&tempts)); 1000c0b746e5SOllivier Robert 1001c0b746e5SOllivier Robert (void) fprintf(fp, "system flags: "); 1002c0b746e5SOllivier Robert if ((is->flags & (INFO_FLAG_BCLIENT | INFO_FLAG_AUTHENABLE | 1003ce265a54SOllivier Robert INFO_FLAG_NTP | INFO_FLAG_KERNEL| INFO_FLAG_CAL | 1004c0b746e5SOllivier Robert INFO_FLAG_PPS_SYNC | INFO_FLAG_MONITOR | INFO_FLAG_FILEGEN)) == 0) { 1005c0b746e5SOllivier Robert (void) fprintf(fp, "none\n"); 1006c0b746e5SOllivier Robert } else { 1007c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_BCLIENT) 1008c0b746e5SOllivier Robert (void) fprintf(fp, "bclient "); 1009c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_AUTHENTICATE) 1010c0b746e5SOllivier Robert (void) fprintf(fp, "auth "); 1011c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_MONITOR) 1012c0b746e5SOllivier Robert (void) fprintf(fp, "monitor "); 1013c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_NTP) 1014c0b746e5SOllivier Robert (void) fprintf(fp, "ntp "); 1015c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_KERNEL) 1016c0b746e5SOllivier Robert (void) fprintf(fp, "kernel "); 1017c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_FILEGEN) 1018c0b746e5SOllivier Robert (void) fprintf(fp, "stats "); 1019ce265a54SOllivier Robert if (is->flags & INFO_FLAG_CAL) 1020ce265a54SOllivier Robert (void) fprintf(fp, "calibrate "); 1021c0b746e5SOllivier Robert if (is->flags & INFO_FLAG_PPS_SYNC) 1022ce265a54SOllivier Robert (void) fprintf(fp, "pps "); 1023c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 1024c0b746e5SOllivier Robert } 1025c0b746e5SOllivier Robert (void) fprintf(fp, "jitter: %s s\n", 1026c0b746e5SOllivier Robert fptoa(ntohl(is->frequency), 6)); 1027c0b746e5SOllivier Robert (void) fprintf(fp, "stability: %s ppm\n", 1028c0b746e5SOllivier Robert ufptoa(ntohl(is->stability), 3)); 1029c0b746e5SOllivier Robert (void) fprintf(fp, "broadcastdelay: %s s\n", 1030c0b746e5SOllivier Robert fptoa(NTOHS_FP(is->bdelay), 6)); 1031c0b746e5SOllivier Robert NTOHL_FP(&is->authdelay, &tempts); 1032c0b746e5SOllivier Robert (void) fprintf(fp, "authdelay: %s s\n", lfptoa(&tempts, 6)); 1033c0b746e5SOllivier Robert } 1034c0b746e5SOllivier Robert 1035c0b746e5SOllivier Robert 1036c0b746e5SOllivier Robert /* 1037c0b746e5SOllivier Robert * sysstats - print system statistics 1038c0b746e5SOllivier Robert */ 1039c0b746e5SOllivier Robert /*ARGSUSED*/ 1040c0b746e5SOllivier Robert static void 1041c0b746e5SOllivier Robert sysstats( 1042c0b746e5SOllivier Robert struct parse *pcmd, 1043c0b746e5SOllivier Robert FILE *fp 1044c0b746e5SOllivier Robert ) 1045c0b746e5SOllivier Robert { 1046c0b746e5SOllivier Robert struct info_sys_stats *ss; 10473311ff84SXin LI size_t items; 10483311ff84SXin LI size_t itemsize; 1049c0b746e5SOllivier Robert int res; 1050c0b746e5SOllivier Robert 10519c2daa00SOllivier Robert again: 10529c2daa00SOllivier Robert res = doquery(impl_ver, REQ_SYS_STATS, 0, 0, 0, (char *)NULL, 10539c2daa00SOllivier Robert &items, &itemsize, (void *)&ss, 0, 10549c2daa00SOllivier Robert sizeof(struct info_sys_stats)); 10559c2daa00SOllivier Robert 10569c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 10579c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 10589c2daa00SOllivier Robert goto again; 10599c2daa00SOllivier Robert } 1060c0b746e5SOllivier Robert 1061ea906c41SOllivier Robert if (res != 0) 1062c0b746e5SOllivier Robert return; 1063c0b746e5SOllivier Robert 1064c0b746e5SOllivier Robert if (!check1item(items, fp)) 1065c0b746e5SOllivier Robert return; 1066c0b746e5SOllivier Robert 1067c0b746e5SOllivier Robert if (itemsize != sizeof(struct info_sys_stats) && 1068c0b746e5SOllivier Robert itemsize != sizeof(struct old_info_sys_stats)) { 1069c0b746e5SOllivier Robert /* issue warning according to new structure size */ 1070c0b746e5SOllivier Robert checkitemsize(itemsize, sizeof(struct info_sys_stats)); 1071c0b746e5SOllivier Robert return; 1072c0b746e5SOllivier Robert } 10732b15cb3dSCy Schubert fprintf(fp, "time since restart: %lu\n", 1074c0b746e5SOllivier Robert (u_long)ntohl(ss->timeup)); 10752b15cb3dSCy Schubert fprintf(fp, "time since reset: %lu\n", 1076c0b746e5SOllivier Robert (u_long)ntohl(ss->timereset)); 10772b15cb3dSCy Schubert fprintf(fp, "packets received: %lu\n", 10789c2daa00SOllivier Robert (u_long)ntohl(ss->received)); 10792b15cb3dSCy Schubert fprintf(fp, "packets processed: %lu\n", 1080c0b746e5SOllivier Robert (u_long)ntohl(ss->processed)); 10812b15cb3dSCy Schubert fprintf(fp, "current version: %lu\n", 10829c2daa00SOllivier Robert (u_long)ntohl(ss->newversionpkt)); 10832b15cb3dSCy Schubert fprintf(fp, "previous version: %lu\n", 10849c2daa00SOllivier Robert (u_long)ntohl(ss->oldversionpkt)); 10852b15cb3dSCy Schubert fprintf(fp, "declined: %lu\n", 10869c2daa00SOllivier Robert (u_long)ntohl(ss->unknownversion)); 10872b15cb3dSCy Schubert fprintf(fp, "access denied: %lu\n", 10889c2daa00SOllivier Robert (u_long)ntohl(ss->denied)); 10892b15cb3dSCy Schubert fprintf(fp, "bad length or format: %lu\n", 10909c2daa00SOllivier Robert (u_long)ntohl(ss->badlength)); 10912b15cb3dSCy Schubert fprintf(fp, "bad authentication: %lu\n", 1092c0b746e5SOllivier Robert (u_long)ntohl(ss->badauth)); 1093c0b746e5SOllivier Robert if (itemsize != sizeof(struct info_sys_stats)) 1094c0b746e5SOllivier Robert return; 1095c0b746e5SOllivier Robert 10962b15cb3dSCy Schubert fprintf(fp, "rate exceeded: %lu\n", 1097c0b746e5SOllivier Robert (u_long)ntohl(ss->limitrejected)); 1098c0b746e5SOllivier Robert } 1099c0b746e5SOllivier Robert 1100c0b746e5SOllivier Robert 1101c0b746e5SOllivier Robert 1102c0b746e5SOllivier Robert /* 1103c0b746e5SOllivier Robert * iostats - print I/O statistics 1104c0b746e5SOllivier Robert */ 1105c0b746e5SOllivier Robert /*ARGSUSED*/ 1106c0b746e5SOllivier Robert static void 1107c0b746e5SOllivier Robert iostats( 1108c0b746e5SOllivier Robert struct parse *pcmd, 1109c0b746e5SOllivier Robert FILE *fp 1110c0b746e5SOllivier Robert ) 1111c0b746e5SOllivier Robert { 1112c0b746e5SOllivier Robert struct info_io_stats *io; 11133311ff84SXin LI size_t items; 11143311ff84SXin LI size_t itemsize; 1115c0b746e5SOllivier Robert int res; 1116c0b746e5SOllivier Robert 11179c2daa00SOllivier Robert again: 11182b15cb3dSCy Schubert res = doquery(impl_ver, REQ_IO_STATS, 0, 0, 0, NULL, &items, 11192b15cb3dSCy Schubert &itemsize, (void *)&io, 0, sizeof(*io)); 11209c2daa00SOllivier Robert 11219c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 11229c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 11239c2daa00SOllivier Robert goto again; 11249c2daa00SOllivier Robert } 1125c0b746e5SOllivier Robert 1126ea906c41SOllivier Robert if (res != 0) 1127c0b746e5SOllivier Robert return; 1128c0b746e5SOllivier Robert 1129c0b746e5SOllivier Robert if (!check1item(items, fp)) 1130c0b746e5SOllivier Robert return; 1131c0b746e5SOllivier Robert 11322b15cb3dSCy Schubert if (!checkitemsize(itemsize, sizeof(*io))) 1133c0b746e5SOllivier Robert return; 1134c0b746e5SOllivier Robert 11352b15cb3dSCy Schubert fprintf(fp, "time since reset: %lu\n", 1136c0b746e5SOllivier Robert (u_long)ntohl(io->timereset)); 11372b15cb3dSCy Schubert fprintf(fp, "receive buffers: %u\n", 11382b15cb3dSCy Schubert (u_int)ntohs(io->totalrecvbufs)); 11392b15cb3dSCy Schubert fprintf(fp, "free receive buffers: %u\n", 11402b15cb3dSCy Schubert (u_int)ntohs(io->freerecvbufs)); 11412b15cb3dSCy Schubert fprintf(fp, "used receive buffers: %u\n", 11422b15cb3dSCy Schubert (u_int)ntohs(io->fullrecvbufs)); 11432b15cb3dSCy Schubert fprintf(fp, "low water refills: %u\n", 11442b15cb3dSCy Schubert (u_int)ntohs(io->lowwater)); 11452b15cb3dSCy Schubert fprintf(fp, "dropped packets: %lu\n", 1146c0b746e5SOllivier Robert (u_long)ntohl(io->dropped)); 11472b15cb3dSCy Schubert fprintf(fp, "ignored packets: %lu\n", 1148c0b746e5SOllivier Robert (u_long)ntohl(io->ignored)); 11492b15cb3dSCy Schubert fprintf(fp, "received packets: %lu\n", 1150c0b746e5SOllivier Robert (u_long)ntohl(io->received)); 11512b15cb3dSCy Schubert fprintf(fp, "packets sent: %lu\n", 1152c0b746e5SOllivier Robert (u_long)ntohl(io->sent)); 11532b15cb3dSCy Schubert fprintf(fp, "packets not sent: %lu\n", 1154c0b746e5SOllivier Robert (u_long)ntohl(io->notsent)); 11552b15cb3dSCy Schubert fprintf(fp, "interrupts handled: %lu\n", 1156c0b746e5SOllivier Robert (u_long)ntohl(io->interrupts)); 11572b15cb3dSCy Schubert fprintf(fp, "received by int: %lu\n", 1158c0b746e5SOllivier Robert (u_long)ntohl(io->int_received)); 1159c0b746e5SOllivier Robert } 1160c0b746e5SOllivier Robert 1161c0b746e5SOllivier Robert 1162c0b746e5SOllivier Robert /* 1163c0b746e5SOllivier Robert * memstats - print peer memory statistics 1164c0b746e5SOllivier Robert */ 1165c0b746e5SOllivier Robert /*ARGSUSED*/ 1166c0b746e5SOllivier Robert static void 1167c0b746e5SOllivier Robert memstats( 1168c0b746e5SOllivier Robert struct parse *pcmd, 1169c0b746e5SOllivier Robert FILE *fp 1170c0b746e5SOllivier Robert ) 1171c0b746e5SOllivier Robert { 1172c0b746e5SOllivier Robert struct info_mem_stats *mem; 1173c0b746e5SOllivier Robert int i; 11743311ff84SXin LI size_t items; 11753311ff84SXin LI size_t itemsize; 1176c0b746e5SOllivier Robert int res; 1177c0b746e5SOllivier Robert 11789c2daa00SOllivier Robert again: 11792b15cb3dSCy Schubert res = doquery(impl_ver, REQ_MEM_STATS, 0, 0, 0, NULL, &items, 11802b15cb3dSCy Schubert &itemsize, (void *)&mem, 0, sizeof(*mem)); 11819c2daa00SOllivier Robert 11829c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 11839c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 11849c2daa00SOllivier Robert goto again; 11859c2daa00SOllivier Robert } 1186c0b746e5SOllivier Robert 1187ea906c41SOllivier Robert if (res != 0) 1188c0b746e5SOllivier Robert return; 1189c0b746e5SOllivier Robert 1190c0b746e5SOllivier Robert if (!check1item(items, fp)) 1191c0b746e5SOllivier Robert return; 1192c0b746e5SOllivier Robert 11932b15cb3dSCy Schubert if (!checkitemsize(itemsize, sizeof(*mem))) 1194c0b746e5SOllivier Robert return; 1195c0b746e5SOllivier Robert 11962b15cb3dSCy Schubert fprintf(fp, "time since reset: %lu\n", 1197c0b746e5SOllivier Robert (u_long)ntohl(mem->timereset)); 11982b15cb3dSCy Schubert fprintf(fp, "total peer memory: %u\n", 11992b15cb3dSCy Schubert (u_int)ntohs(mem->totalpeermem)); 12002b15cb3dSCy Schubert fprintf(fp, "free peer memory: %u\n", 12012b15cb3dSCy Schubert (u_int)ntohs(mem->freepeermem)); 12022b15cb3dSCy Schubert fprintf(fp, "calls to findpeer: %lu\n", 1203c0b746e5SOllivier Robert (u_long)ntohl(mem->findpeer_calls)); 12042b15cb3dSCy Schubert fprintf(fp, "new peer allocations: %lu\n", 1205c0b746e5SOllivier Robert (u_long)ntohl(mem->allocations)); 12062b15cb3dSCy Schubert fprintf(fp, "peer demobilizations: %lu\n", 1207c0b746e5SOllivier Robert (u_long)ntohl(mem->demobilizations)); 1208c0b746e5SOllivier Robert 12092b15cb3dSCy Schubert fprintf(fp, "hash table counts: "); 1210ea906c41SOllivier Robert for (i = 0; i < NTP_HASH_SIZE; i++) { 12112b15cb3dSCy Schubert fprintf(fp, "%4d", (int)mem->hashcount[i]); 12122b15cb3dSCy Schubert if ((i % 8) == 7 && i != (NTP_HASH_SIZE-1)) 12132b15cb3dSCy Schubert fprintf(fp, "\n "); 1214c0b746e5SOllivier Robert } 12152b15cb3dSCy Schubert fprintf(fp, "\n"); 1216c0b746e5SOllivier Robert } 1217c0b746e5SOllivier Robert 1218c0b746e5SOllivier Robert 1219c0b746e5SOllivier Robert 1220c0b746e5SOllivier Robert /* 1221c0b746e5SOllivier Robert * timerstats - print timer statistics 1222c0b746e5SOllivier Robert */ 1223c0b746e5SOllivier Robert /*ARGSUSED*/ 1224c0b746e5SOllivier Robert static void 1225c0b746e5SOllivier Robert timerstats( 1226c0b746e5SOllivier Robert struct parse *pcmd, 1227c0b746e5SOllivier Robert FILE *fp 1228c0b746e5SOllivier Robert ) 1229c0b746e5SOllivier Robert { 1230c0b746e5SOllivier Robert struct info_timer_stats *tim; 12313311ff84SXin LI size_t items; 12323311ff84SXin LI size_t itemsize; 1233c0b746e5SOllivier Robert int res; 1234c0b746e5SOllivier Robert 12359c2daa00SOllivier Robert again: 12362b15cb3dSCy Schubert res = doquery(impl_ver, REQ_TIMER_STATS, 0, 0, 0, NULL, &items, 12372b15cb3dSCy Schubert &itemsize, (void *)&tim, 0, sizeof(*tim)); 12389c2daa00SOllivier Robert 12399c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 12409c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 12419c2daa00SOllivier Robert goto again; 12429c2daa00SOllivier Robert } 1243c0b746e5SOllivier Robert 1244ea906c41SOllivier Robert if (res != 0) 1245c0b746e5SOllivier Robert return; 1246c0b746e5SOllivier Robert 1247c0b746e5SOllivier Robert if (!check1item(items, fp)) 1248c0b746e5SOllivier Robert return; 1249c0b746e5SOllivier Robert 12502b15cb3dSCy Schubert if (!checkitemsize(itemsize, sizeof(*tim))) 1251c0b746e5SOllivier Robert return; 1252c0b746e5SOllivier Robert 12532b15cb3dSCy Schubert fprintf(fp, "time since reset: %lu\n", 1254c0b746e5SOllivier Robert (u_long)ntohl(tim->timereset)); 12552b15cb3dSCy Schubert fprintf(fp, "alarms handled: %lu\n", 1256c0b746e5SOllivier Robert (u_long)ntohl(tim->alarms)); 12572b15cb3dSCy Schubert fprintf(fp, "alarm overruns: %lu\n", 1258c0b746e5SOllivier Robert (u_long)ntohl(tim->overflows)); 12592b15cb3dSCy Schubert fprintf(fp, "calls to transmit: %lu\n", 1260c0b746e5SOllivier Robert (u_long)ntohl(tim->xmtcalls)); 1261c0b746e5SOllivier Robert } 1262c0b746e5SOllivier Robert 1263c0b746e5SOllivier Robert 1264c0b746e5SOllivier Robert /* 1265c0b746e5SOllivier Robert * addpeer - configure an active mode association 1266c0b746e5SOllivier Robert */ 1267c0b746e5SOllivier Robert static void 1268c0b746e5SOllivier Robert addpeer( 1269c0b746e5SOllivier Robert struct parse *pcmd, 1270c0b746e5SOllivier Robert FILE *fp 1271c0b746e5SOllivier Robert ) 1272c0b746e5SOllivier Robert { 1273c0b746e5SOllivier Robert doconfig(pcmd, fp, MODE_ACTIVE, 0); 1274c0b746e5SOllivier Robert } 1275c0b746e5SOllivier Robert 1276c0b746e5SOllivier Robert 1277c0b746e5SOllivier Robert /* 1278c0b746e5SOllivier Robert * addserver - configure a client mode association 1279c0b746e5SOllivier Robert */ 1280c0b746e5SOllivier Robert static void 1281c0b746e5SOllivier Robert addserver( 1282c0b746e5SOllivier Robert struct parse *pcmd, 1283c0b746e5SOllivier Robert FILE *fp 1284c0b746e5SOllivier Robert ) 1285c0b746e5SOllivier Robert { 1286c0b746e5SOllivier Robert doconfig(pcmd, fp, MODE_CLIENT, 0); 1287c0b746e5SOllivier Robert } 1288c0b746e5SOllivier Robert 1289c0b746e5SOllivier Robert /* 1290c0b746e5SOllivier Robert * addrefclock - configure a reference clock association 1291c0b746e5SOllivier Robert */ 1292c0b746e5SOllivier Robert static void 1293c0b746e5SOllivier Robert addrefclock( 1294c0b746e5SOllivier Robert struct parse *pcmd, 1295c0b746e5SOllivier Robert FILE *fp 1296c0b746e5SOllivier Robert ) 1297c0b746e5SOllivier Robert { 1298c0b746e5SOllivier Robert doconfig(pcmd, fp, MODE_CLIENT, 1); 1299c0b746e5SOllivier Robert } 1300c0b746e5SOllivier Robert 1301c0b746e5SOllivier Robert /* 1302c0b746e5SOllivier Robert * broadcast - configure a broadcast mode association 1303c0b746e5SOllivier Robert */ 1304c0b746e5SOllivier Robert static void 1305c0b746e5SOllivier Robert broadcast( 1306c0b746e5SOllivier Robert struct parse *pcmd, 1307c0b746e5SOllivier Robert FILE *fp 1308c0b746e5SOllivier Robert ) 1309c0b746e5SOllivier Robert { 1310c0b746e5SOllivier Robert doconfig(pcmd, fp, MODE_BROADCAST, 0); 1311c0b746e5SOllivier Robert } 1312c0b746e5SOllivier Robert 1313c0b746e5SOllivier Robert 1314c0b746e5SOllivier Robert /* 1315c0b746e5SOllivier Robert * config - configure a new peer association 1316c0b746e5SOllivier Robert */ 1317c0b746e5SOllivier Robert static void 1318c0b746e5SOllivier Robert doconfig( 1319c0b746e5SOllivier Robert struct parse *pcmd, 1320c0b746e5SOllivier Robert FILE *fp, 1321c0b746e5SOllivier Robert int mode, 1322c0b746e5SOllivier Robert int refc 1323c0b746e5SOllivier Robert ) 1324c0b746e5SOllivier Robert { 1325c0b746e5SOllivier Robert struct conf_peer cpeer; 13263311ff84SXin LI size_t items; 13273311ff84SXin LI size_t itemsize; 13283311ff84SXin LI const char *dummy; 1329c0b746e5SOllivier Robert u_long keyid; 1330c0b746e5SOllivier Robert u_int version; 1331c0b746e5SOllivier Robert u_char minpoll; 1332ea906c41SOllivier Robert u_char maxpoll; 1333c0b746e5SOllivier Robert u_int flags; 1334c0b746e5SOllivier Robert u_char cmode; 1335c0b746e5SOllivier Robert int res; 13369c2daa00SOllivier Robert int sendsize; 1337ea906c41SOllivier Robert int numtyp; 13382b15cb3dSCy Schubert long val; 1339c0b746e5SOllivier Robert 13409c2daa00SOllivier Robert again: 1341c0b746e5SOllivier Robert keyid = 0; 1342ea906c41SOllivier Robert version = 3; 1343c0b746e5SOllivier Robert flags = 0; 13442b15cb3dSCy Schubert res = FALSE; 1345c0b746e5SOllivier Robert cmode = 0; 1346c0b746e5SOllivier Robert minpoll = NTP_MINDPOLL; 1347ea906c41SOllivier Robert maxpoll = NTP_MAXDPOLL; 1348ea906c41SOllivier Robert numtyp = 1; 1349ea906c41SOllivier Robert if (refc) 1350ea906c41SOllivier Robert numtyp = 5; 1351c0b746e5SOllivier Robert 13529c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 13539c2daa00SOllivier Robert sendsize = sizeof(struct conf_peer); 13549c2daa00SOllivier Robert else 13559c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_peer); 13569c2daa00SOllivier Robert 1357ea906c41SOllivier Robert items = 1; 13582b15cb3dSCy Schubert while (pcmd->nargs > (size_t)items) { 1359c0b746e5SOllivier Robert if (STREQ(pcmd->argval[items].string, "prefer")) 1360c0b746e5SOllivier Robert flags |= CONF_FLAG_PREFER; 1361c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "burst")) 1362c0b746e5SOllivier Robert flags |= CONF_FLAG_BURST; 1363ea906c41SOllivier Robert else if (STREQ(pcmd->argval[items].string, "iburst")) 1364ea906c41SOllivier Robert flags |= CONF_FLAG_IBURST; 1365ea906c41SOllivier Robert else if (!refc && STREQ(pcmd->argval[items].string, "keyid")) 1366ea906c41SOllivier Robert numtyp = 1; 1367ea906c41SOllivier Robert else if (!refc && STREQ(pcmd->argval[items].string, "version")) 1368ea906c41SOllivier Robert numtyp = 2; 1369ea906c41SOllivier Robert else if (STREQ(pcmd->argval[items].string, "minpoll")) 1370ea906c41SOllivier Robert numtyp = 3; 1371ea906c41SOllivier Robert else if (STREQ(pcmd->argval[items].string, "maxpoll")) 1372ea906c41SOllivier Robert numtyp = 4; 1373c0b746e5SOllivier Robert else { 1374ea906c41SOllivier Robert if (!atoint(pcmd->argval[items].string, &val)) 1375ea906c41SOllivier Robert numtyp = 0; 1376ea906c41SOllivier Robert switch (numtyp) { 1377ea906c41SOllivier Robert case 1: 1378ea906c41SOllivier Robert keyid = val; 1379ea906c41SOllivier Robert numtyp = 2; 1380ea906c41SOllivier Robert break; 1381ea906c41SOllivier Robert 1382ea906c41SOllivier Robert case 2: 1383ea906c41SOllivier Robert version = (u_int)val; 1384ea906c41SOllivier Robert numtyp = 0; 1385ea906c41SOllivier Robert break; 1386ea906c41SOllivier Robert 1387ea906c41SOllivier Robert case 3: 1388ea906c41SOllivier Robert minpoll = (u_char)val; 1389ea906c41SOllivier Robert numtyp = 0; 1390ea906c41SOllivier Robert break; 1391ea906c41SOllivier Robert 1392ea906c41SOllivier Robert case 4: 1393ea906c41SOllivier Robert maxpoll = (u_char)val; 1394ea906c41SOllivier Robert numtyp = 0; 1395ea906c41SOllivier Robert break; 1396ea906c41SOllivier Robert 1397ea906c41SOllivier Robert case 5: 1398ea906c41SOllivier Robert cmode = (u_char)val; 1399ea906c41SOllivier Robert numtyp = 0; 1400ea906c41SOllivier Robert break; 1401ea906c41SOllivier Robert 1402ea906c41SOllivier Robert default: 14032b15cb3dSCy Schubert fprintf(fp, "*** '%s' not understood\n", 1404c0b746e5SOllivier Robert pcmd->argval[items].string); 14052b15cb3dSCy Schubert res = TRUE; 1406ea906c41SOllivier Robert numtyp = 0; 1407c0b746e5SOllivier Robert } 1408ea906c41SOllivier Robert if (val < 0) { 14092b15cb3dSCy Schubert fprintf(stderr, 1410ea906c41SOllivier Robert "*** Value '%s' should be unsigned\n", 1411ea906c41SOllivier Robert pcmd->argval[items].string); 14122b15cb3dSCy Schubert res = TRUE; 1413c0b746e5SOllivier Robert } 1414c0b746e5SOllivier Robert } 1415c0b746e5SOllivier Robert items++; 1416c0b746e5SOllivier Robert } 1417ea906c41SOllivier Robert if (keyid > 0) 1418ea906c41SOllivier Robert flags |= CONF_FLAG_AUTHENABLE; 14192b15cb3dSCy Schubert if (version > NTP_VERSION || version < NTP_OLDVERSION) { 14202b15cb3dSCy Schubert fprintf(fp, "***invalid version number: %u\n", 1421ea906c41SOllivier Robert version); 14222b15cb3dSCy Schubert res = TRUE; 1423ea906c41SOllivier Robert } 1424ea906c41SOllivier Robert if (minpoll < NTP_MINPOLL || minpoll > NTP_MAXPOLL || 1425ea906c41SOllivier Robert maxpoll < NTP_MINPOLL || maxpoll > NTP_MAXPOLL || 1426ea906c41SOllivier Robert minpoll > maxpoll) { 14272b15cb3dSCy Schubert fprintf(fp, "***min/max-poll must be within %d..%d\n", 1428ea906c41SOllivier Robert NTP_MINPOLL, NTP_MAXPOLL); 14292b15cb3dSCy Schubert res = TRUE; 1430ea906c41SOllivier Robert } 1431c0b746e5SOllivier Robert 1432c0b746e5SOllivier Robert if (res) 1433c0b746e5SOllivier Robert return; 1434c0b746e5SOllivier Robert 14352b15cb3dSCy Schubert ZERO(cpeer); 1436c0b746e5SOllivier Robert 14372b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[0].netnum)) { 14382b15cb3dSCy Schubert cpeer.peeraddr = NSRCADR(&pcmd->argval[0].netnum); 14399c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 14409c2daa00SOllivier Robert cpeer.v6_flag = 0; 14419c2daa00SOllivier Robert } else { 14429c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 14439c2daa00SOllivier Robert fprintf(stderr, 14449c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 14459c2daa00SOllivier Robert return; 14469c2daa00SOllivier Robert } 14472b15cb3dSCy Schubert cpeer.peeraddr6 = SOCK_ADDR6(&pcmd->argval[0].netnum); 14489c2daa00SOllivier Robert cpeer.v6_flag = 1; 14499c2daa00SOllivier Robert } 1450c0b746e5SOllivier Robert cpeer.hmode = (u_char) mode; 1451c0b746e5SOllivier Robert cpeer.keyid = keyid; 1452c0b746e5SOllivier Robert cpeer.version = (u_char) version; 1453c0b746e5SOllivier Robert cpeer.minpoll = minpoll; 1454ea906c41SOllivier Robert cpeer.maxpoll = maxpoll; 1455c0b746e5SOllivier Robert cpeer.flags = (u_char)flags; 1456c0b746e5SOllivier Robert cpeer.ttl = cmode; 1457c0b746e5SOllivier Robert 14589c2daa00SOllivier Robert res = doquery(impl_ver, REQ_CONFIG, 1, 1, 14599c2daa00SOllivier Robert sendsize, (char *)&cpeer, &items, 14609c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_peer)); 14619c2daa00SOllivier Robert 14629c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 14639c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 14649c2daa00SOllivier Robert goto again; 14659c2daa00SOllivier Robert } 1466c0b746e5SOllivier Robert 1467ce265a54SOllivier Robert if (res == INFO_ERR_FMT) { 1468ce265a54SOllivier Robert (void) fprintf(fp, 1469ce265a54SOllivier Robert "***Retrying command with old conf_peer size\n"); 14709c2daa00SOllivier Robert res = doquery(impl_ver, REQ_CONFIG, 1, 1, 1471ce265a54SOllivier Robert sizeof(struct old_conf_peer), (char *)&cpeer, 14729c2daa00SOllivier Robert &items, &itemsize, &dummy, 0, 14739c2daa00SOllivier Robert sizeof(struct conf_peer)); 1474ce265a54SOllivier Robert } 1475c0b746e5SOllivier Robert if (res == 0) 1476c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 1477c0b746e5SOllivier Robert return; 1478c0b746e5SOllivier Robert } 1479c0b746e5SOllivier Robert 1480c0b746e5SOllivier Robert 1481c0b746e5SOllivier Robert /* 1482c0b746e5SOllivier Robert * unconfig - unconfigure some associations 1483c0b746e5SOllivier Robert */ 1484c0b746e5SOllivier Robert static void 1485c0b746e5SOllivier Robert unconfig( 1486c0b746e5SOllivier Robert struct parse *pcmd, 1487c0b746e5SOllivier Robert FILE *fp 1488c0b746e5SOllivier Robert ) 1489c0b746e5SOllivier Robert { 1490c0b746e5SOllivier Robert /* 8 is the maximum number of peers which will fit in a packet */ 14919c2daa00SOllivier Robert struct conf_unpeer *pl, plist[min(MAXARGS, 8)]; 14923311ff84SXin LI size_t qitemlim; 14933311ff84SXin LI size_t qitems; 14943311ff84SXin LI size_t items; 14953311ff84SXin LI size_t itemsize; 14963311ff84SXin LI const char *dummy; 1497c0b746e5SOllivier Robert int res; 14983311ff84SXin LI size_t sendsize; 1499c0b746e5SOllivier Robert 15009c2daa00SOllivier Robert again: 15019c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 15029c2daa00SOllivier Robert sendsize = sizeof(struct conf_unpeer); 15039c2daa00SOllivier Robert else 15049c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_unpeer); 15059c2daa00SOllivier Robert 15062b15cb3dSCy Schubert qitemlim = min(pcmd->nargs, COUNTOF(plist)); 15072b15cb3dSCy Schubert for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) { 15082b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[0].netnum)) { 15092b15cb3dSCy Schubert pl->peeraddr = NSRCADR(&pcmd->argval[qitems].netnum); 15109c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 15119c2daa00SOllivier Robert pl->v6_flag = 0; 15129c2daa00SOllivier Robert } else { 15139c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 15149c2daa00SOllivier Robert fprintf(stderr, 15159c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 15169c2daa00SOllivier Robert return; 15179c2daa00SOllivier Robert } 15189c2daa00SOllivier Robert pl->peeraddr6 = 15192b15cb3dSCy Schubert SOCK_ADDR6(&pcmd->argval[qitems].netnum); 15209c2daa00SOllivier Robert pl->v6_flag = 1; 15219c2daa00SOllivier Robert } 15222b15cb3dSCy Schubert pl = (void *)((char *)pl + sendsize); 1523c0b746e5SOllivier Robert } 1524c0b746e5SOllivier Robert 15259c2daa00SOllivier Robert res = doquery(impl_ver, REQ_UNCONFIG, 1, qitems, 15269c2daa00SOllivier Robert sendsize, (char *)plist, &items, 15279c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_unpeer)); 15289c2daa00SOllivier Robert 15299c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 15309c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 15319c2daa00SOllivier Robert goto again; 15329c2daa00SOllivier Robert } 1533c0b746e5SOllivier Robert 1534c0b746e5SOllivier Robert if (res == 0) 1535c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 1536c0b746e5SOllivier Robert } 1537c0b746e5SOllivier Robert 1538c0b746e5SOllivier Robert 1539c0b746e5SOllivier Robert /* 1540c0b746e5SOllivier Robert * set - set some system flags 1541c0b746e5SOllivier Robert */ 1542c0b746e5SOllivier Robert static void 1543c0b746e5SOllivier Robert set( 1544c0b746e5SOllivier Robert struct parse *pcmd, 1545c0b746e5SOllivier Robert FILE *fp 1546c0b746e5SOllivier Robert ) 1547c0b746e5SOllivier Robert { 1548c0b746e5SOllivier Robert doset(pcmd, fp, REQ_SET_SYS_FLAG); 1549c0b746e5SOllivier Robert } 1550c0b746e5SOllivier Robert 1551c0b746e5SOllivier Robert 1552c0b746e5SOllivier Robert /* 1553c0b746e5SOllivier Robert * clear - clear some system flags 1554c0b746e5SOllivier Robert */ 1555c0b746e5SOllivier Robert static void 1556c0b746e5SOllivier Robert sys_clear( 1557c0b746e5SOllivier Robert struct parse *pcmd, 1558c0b746e5SOllivier Robert FILE *fp 1559c0b746e5SOllivier Robert ) 1560c0b746e5SOllivier Robert { 1561c0b746e5SOllivier Robert doset(pcmd, fp, REQ_CLR_SYS_FLAG); 1562c0b746e5SOllivier Robert } 1563c0b746e5SOllivier Robert 1564c0b746e5SOllivier Robert 1565c0b746e5SOllivier Robert /* 1566c0b746e5SOllivier Robert * doset - set/clear system flags 1567c0b746e5SOllivier Robert */ 1568c0b746e5SOllivier Robert static void 1569c0b746e5SOllivier Robert doset( 1570c0b746e5SOllivier Robert struct parse *pcmd, 1571c0b746e5SOllivier Robert FILE *fp, 1572c0b746e5SOllivier Robert int req 1573c0b746e5SOllivier Robert ) 1574c0b746e5SOllivier Robert { 1575c0b746e5SOllivier Robert struct conf_sys_flags sys; 15763311ff84SXin LI size_t items; 15773311ff84SXin LI size_t itemsize; 15783311ff84SXin LI const char *dummy; 1579c0b746e5SOllivier Robert int res; 1580c0b746e5SOllivier Robert 1581c0b746e5SOllivier Robert sys.flags = 0; 1582c0b746e5SOllivier Robert res = 0; 15832b15cb3dSCy Schubert for (items = 0; (size_t)items < pcmd->nargs; items++) { 1584ce265a54SOllivier Robert if (STREQ(pcmd->argval[items].string, "auth")) 1585ce265a54SOllivier Robert sys.flags |= SYS_FLAG_AUTH; 1586c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "bclient")) 1587c0b746e5SOllivier Robert sys.flags |= SYS_FLAG_BCLIENT; 1588ce265a54SOllivier Robert else if (STREQ(pcmd->argval[items].string, "calibrate")) 1589ce265a54SOllivier Robert sys.flags |= SYS_FLAG_CAL; 1590ce265a54SOllivier Robert else if (STREQ(pcmd->argval[items].string, "kernel")) 1591ce265a54SOllivier Robert sys.flags |= SYS_FLAG_KERNEL; 1592c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "monitor")) 1593c0b746e5SOllivier Robert sys.flags |= SYS_FLAG_MONITOR; 1594c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "ntp")) 1595c0b746e5SOllivier Robert sys.flags |= SYS_FLAG_NTP; 1596ce265a54SOllivier Robert else if (STREQ(pcmd->argval[items].string, "pps")) 1597ce265a54SOllivier Robert sys.flags |= SYS_FLAG_PPS; 1598c0b746e5SOllivier Robert else if (STREQ(pcmd->argval[items].string, "stats")) 1599c0b746e5SOllivier Robert sys.flags |= SYS_FLAG_FILEGEN; 1600c0b746e5SOllivier Robert else { 1601c0b746e5SOllivier Robert (void) fprintf(fp, "Unknown flag %s\n", 1602c0b746e5SOllivier Robert pcmd->argval[items].string); 1603c0b746e5SOllivier Robert res = 1; 1604c0b746e5SOllivier Robert } 1605c0b746e5SOllivier Robert } 1606c0b746e5SOllivier Robert 1607ea906c41SOllivier Robert sys.flags = htonl(sys.flags); 1608c0b746e5SOllivier Robert if (res || sys.flags == 0) 1609c0b746e5SOllivier Robert return; 1610c0b746e5SOllivier Robert 16119c2daa00SOllivier Robert again: 16129c2daa00SOllivier Robert res = doquery(impl_ver, req, 1, 1, 1613c0b746e5SOllivier Robert sizeof(struct conf_sys_flags), (char *)&sys, &items, 16149c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_sys_flags)); 16159c2daa00SOllivier Robert 16169c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 16179c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 16189c2daa00SOllivier Robert goto again; 16199c2daa00SOllivier Robert } 1620c0b746e5SOllivier Robert 1621c0b746e5SOllivier Robert if (res == 0) 1622c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 1623c0b746e5SOllivier Robert } 1624c0b746e5SOllivier Robert 1625c0b746e5SOllivier Robert 1626c0b746e5SOllivier Robert /* 1627c0b746e5SOllivier Robert * data for printing/interrpreting the restrict flags 1628c0b746e5SOllivier Robert */ 1629c0b746e5SOllivier Robert struct resflags { 1630c0b746e5SOllivier Robert const char *str; 1631c0b746e5SOllivier Robert int bit; 1632c0b746e5SOllivier Robert }; 1633c0b746e5SOllivier Robert 1634ea906c41SOllivier Robert /* XXX: HMS: we apparently don't report set bits we do not recognize. */ 1635ea906c41SOllivier Robert 1636ea906c41SOllivier Robert static struct resflags resflagsV2[] = { 1637ea906c41SOllivier Robert { "ignore", 0x001 }, 1638ea906c41SOllivier Robert { "noserve", 0x002 }, 1639ea906c41SOllivier Robert { "notrust", 0x004 }, 1640ea906c41SOllivier Robert { "noquery", 0x008 }, 1641ea906c41SOllivier Robert { "nomodify", 0x010 }, 1642ea906c41SOllivier Robert { "nopeer", 0x020 }, 1643ea906c41SOllivier Robert { "notrap", 0x040 }, 1644ea906c41SOllivier Robert { "lptrap", 0x080 }, 1645ea906c41SOllivier Robert { "limited", 0x100 }, 1646ea906c41SOllivier Robert { "", 0 } 1647ea906c41SOllivier Robert }; 1648ea906c41SOllivier Robert 1649ea906c41SOllivier Robert static struct resflags resflagsV3[] = { 1650c0b746e5SOllivier Robert { "ignore", RES_IGNORE }, 1651c0b746e5SOllivier Robert { "noserve", RES_DONTSERVE }, 1652c0b746e5SOllivier Robert { "notrust", RES_DONTTRUST }, 1653c0b746e5SOllivier Robert { "noquery", RES_NOQUERY }, 1654c0b746e5SOllivier Robert { "nomodify", RES_NOMODIFY }, 1655c0b746e5SOllivier Robert { "nopeer", RES_NOPEER }, 1656c0b746e5SOllivier Robert { "notrap", RES_NOTRAP }, 1657c0b746e5SOllivier Robert { "lptrap", RES_LPTRAP }, 1658c0b746e5SOllivier Robert { "limited", RES_LIMITED }, 1659224ba2bdSOllivier Robert { "version", RES_VERSION }, 16602b15cb3dSCy Schubert { "kod", RES_KOD }, 16612b15cb3dSCy Schubert { "flake", RES_FLAKE }, 1662224ba2bdSOllivier Robert 1663c0b746e5SOllivier Robert { "", 0 } 1664c0b746e5SOllivier Robert }; 1665c0b746e5SOllivier Robert 1666c0b746e5SOllivier Robert static struct resflags resmflags[] = { 1667c0b746e5SOllivier Robert { "ntpport", RESM_NTPONLY }, 1668c0b746e5SOllivier Robert { "interface", RESM_INTERFACE }, 16692b15cb3dSCy Schubert { "source", RESM_SOURCE }, 1670c0b746e5SOllivier Robert { "", 0 } 1671c0b746e5SOllivier Robert }; 1672c0b746e5SOllivier Robert 1673c0b746e5SOllivier Robert 1674c0b746e5SOllivier Robert /* 1675c0b746e5SOllivier Robert * reslist - obtain and print the server's restrict list 1676c0b746e5SOllivier Robert */ 1677c0b746e5SOllivier Robert /*ARGSUSED*/ 1678c0b746e5SOllivier Robert static void 1679c0b746e5SOllivier Robert reslist( 1680c0b746e5SOllivier Robert struct parse *pcmd, 1681c0b746e5SOllivier Robert FILE *fp 1682c0b746e5SOllivier Robert ) 1683c0b746e5SOllivier Robert { 1684c0b746e5SOllivier Robert struct info_restrict *rl; 16852b15cb3dSCy Schubert sockaddr_u resaddr; 16862b15cb3dSCy Schubert sockaddr_u maskaddr; 16873311ff84SXin LI size_t items; 16883311ff84SXin LI size_t itemsize; 1689c0b746e5SOllivier Robert int res; 16909c2daa00SOllivier Robert int skip; 16912b15cb3dSCy Schubert const char *addr; 16922b15cb3dSCy Schubert const char *mask; 1693c0b746e5SOllivier Robert struct resflags *rf; 1694c0b746e5SOllivier Robert u_int32 count; 169509100258SXin LI u_short rflags; 1696c0b746e5SOllivier Robert u_short mflags; 1697c0b746e5SOllivier Robert char flagstr[300]; 1698c0b746e5SOllivier Robert static const char *comma = ", "; 1699c0b746e5SOllivier Robert 17009c2daa00SOllivier Robert again: 17019c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_RESTRICT, 0, 0, 0, (char *)NULL, 17029c2daa00SOllivier Robert &items, &itemsize, (void *)&rl, 0, 17039c2daa00SOllivier Robert sizeof(struct info_restrict)); 17049c2daa00SOllivier Robert 17059c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 17069c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 17079c2daa00SOllivier Robert goto again; 17089c2daa00SOllivier Robert } 1709c0b746e5SOllivier Robert 1710ea906c41SOllivier Robert if (res != 0) 1711c0b746e5SOllivier Robert return; 1712c0b746e5SOllivier Robert 1713c0b746e5SOllivier Robert if (!checkitems(items, fp)) 1714c0b746e5SOllivier Robert return; 1715c0b746e5SOllivier Robert 17169c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_restrict)) && 17179c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_restrict))) 1718c0b746e5SOllivier Robert return; 1719c0b746e5SOllivier Robert 17202b15cb3dSCy Schubert fprintf(fp, 1721c0b746e5SOllivier Robert " address mask count flags\n"); 17222b15cb3dSCy Schubert fprintf(fp, 1723c0b746e5SOllivier Robert "=====================================================================\n"); 17249c2daa00SOllivier Robert 1725c0b746e5SOllivier Robert while (items > 0) { 17262b15cb3dSCy Schubert SET_ADDRS(resaddr, maskaddr, rl, addr, mask); 17279c2daa00SOllivier Robert if (rl->v6_flag != 0) { 17289c2daa00SOllivier Robert addr = nntohost(&resaddr); 17299c2daa00SOllivier Robert } else { 17302b15cb3dSCy Schubert if (rl->mask == (u_int32)0xffffffff) 17319c2daa00SOllivier Robert addr = nntohost(&resaddr); 1732c0b746e5SOllivier Robert else 17339c2daa00SOllivier Robert addr = stoa(&resaddr); 17349c2daa00SOllivier Robert } 17359c2daa00SOllivier Robert mask = stoa(&maskaddr); 17369c2daa00SOllivier Robert skip = 1; 17379c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 17389c2daa00SOllivier Robert ((pcmd->argval->ival == 6) && (rl->v6_flag != 0)) || 17399c2daa00SOllivier Robert ((pcmd->argval->ival == 4) && (rl->v6_flag == 0))) 17409c2daa00SOllivier Robert skip = 0; 1741c0b746e5SOllivier Robert count = ntohl(rl->count); 174209100258SXin LI rflags = ntohs(rl->rflags); 1743c0b746e5SOllivier Robert mflags = ntohs(rl->mflags); 1744c0b746e5SOllivier Robert flagstr[0] = '\0'; 1745c0b746e5SOllivier Robert 1746c0b746e5SOllivier Robert res = 1; 1747c0b746e5SOllivier Robert rf = &resmflags[0]; 1748c0b746e5SOllivier Robert while (rf->bit != 0) { 1749c0b746e5SOllivier Robert if (mflags & rf->bit) { 1750c0b746e5SOllivier Robert if (!res) 17512b15cb3dSCy Schubert strlcat(flagstr, comma, 17522b15cb3dSCy Schubert sizeof(flagstr)); 1753c0b746e5SOllivier Robert res = 0; 17542b15cb3dSCy Schubert strlcat(flagstr, rf->str, 17552b15cb3dSCy Schubert sizeof(flagstr)); 1756c0b746e5SOllivier Robert } 1757c0b746e5SOllivier Robert rf++; 1758c0b746e5SOllivier Robert } 1759c0b746e5SOllivier Robert 1760ea906c41SOllivier Robert rf = (impl_ver == IMPL_XNTPD_OLD) 1761ea906c41SOllivier Robert ? &resflagsV2[0] 17622b15cb3dSCy Schubert : &resflagsV3[0]; 17632b15cb3dSCy Schubert 1764c0b746e5SOllivier Robert while (rf->bit != 0) { 176509100258SXin LI if (rflags & rf->bit) { 1766c0b746e5SOllivier Robert if (!res) 17672b15cb3dSCy Schubert strlcat(flagstr, comma, 17682b15cb3dSCy Schubert sizeof(flagstr)); 1769c0b746e5SOllivier Robert res = 0; 17702b15cb3dSCy Schubert strlcat(flagstr, rf->str, 17712b15cb3dSCy Schubert sizeof(flagstr)); 1772c0b746e5SOllivier Robert } 1773c0b746e5SOllivier Robert rf++; 1774c0b746e5SOllivier Robert } 1775c0b746e5SOllivier Robert 1776c0b746e5SOllivier Robert if (flagstr[0] == '\0') 17772b15cb3dSCy Schubert strlcpy(flagstr, "none", sizeof(flagstr)); 1778c0b746e5SOllivier Robert 17799c2daa00SOllivier Robert if (!skip) 17802b15cb3dSCy Schubert fprintf(fp, "%-15.15s %-15.15s %9lu %s\n", 1781c0b746e5SOllivier Robert addr, mask, (u_long)count, flagstr); 1782c0b746e5SOllivier Robert rl++; 1783c0b746e5SOllivier Robert items--; 1784c0b746e5SOllivier Robert } 1785c0b746e5SOllivier Robert } 1786c0b746e5SOllivier Robert 1787c0b746e5SOllivier Robert 1788c0b746e5SOllivier Robert 1789c0b746e5SOllivier Robert /* 1790c0b746e5SOllivier Robert * new_restrict - create/add a set of restrictions 1791c0b746e5SOllivier Robert */ 1792c0b746e5SOllivier Robert static void 1793c0b746e5SOllivier Robert new_restrict( 1794c0b746e5SOllivier Robert struct parse *pcmd, 1795c0b746e5SOllivier Robert FILE *fp 1796c0b746e5SOllivier Robert ) 1797c0b746e5SOllivier Robert { 1798c0b746e5SOllivier Robert do_restrict(pcmd, fp, REQ_RESADDFLAGS); 1799c0b746e5SOllivier Robert } 1800c0b746e5SOllivier Robert 1801c0b746e5SOllivier Robert 1802c0b746e5SOllivier Robert /* 1803c0b746e5SOllivier Robert * unrestrict - remove restriction flags from existing entry 1804c0b746e5SOllivier Robert */ 1805c0b746e5SOllivier Robert static void 1806c0b746e5SOllivier Robert unrestrict( 1807c0b746e5SOllivier Robert struct parse *pcmd, 1808c0b746e5SOllivier Robert FILE *fp 1809c0b746e5SOllivier Robert ) 1810c0b746e5SOllivier Robert { 1811c0b746e5SOllivier Robert do_restrict(pcmd, fp, REQ_RESSUBFLAGS); 1812c0b746e5SOllivier Robert } 1813c0b746e5SOllivier Robert 1814c0b746e5SOllivier Robert 1815c0b746e5SOllivier Robert /* 1816c0b746e5SOllivier Robert * delrestrict - delete an existing restriction 1817c0b746e5SOllivier Robert */ 1818c0b746e5SOllivier Robert static void 1819c0b746e5SOllivier Robert delrestrict( 1820c0b746e5SOllivier Robert struct parse *pcmd, 1821c0b746e5SOllivier Robert FILE *fp 1822c0b746e5SOllivier Robert ) 1823c0b746e5SOllivier Robert { 1824c0b746e5SOllivier Robert do_restrict(pcmd, fp, REQ_UNRESTRICT); 1825c0b746e5SOllivier Robert } 1826c0b746e5SOllivier Robert 1827c0b746e5SOllivier Robert 1828c0b746e5SOllivier Robert /* 1829c0b746e5SOllivier Robert * do_restrict - decode commandline restrictions and make the request 1830c0b746e5SOllivier Robert */ 1831c0b746e5SOllivier Robert static void 1832c0b746e5SOllivier Robert do_restrict( 1833c0b746e5SOllivier Robert struct parse *pcmd, 1834c0b746e5SOllivier Robert FILE *fp, 1835c0b746e5SOllivier Robert int req_code 1836c0b746e5SOllivier Robert ) 1837c0b746e5SOllivier Robert { 1838c0b746e5SOllivier Robert struct conf_restrict cres; 18393311ff84SXin LI size_t items; 18403311ff84SXin LI size_t itemsize; 18413311ff84SXin LI const char *dummy; 1842c0b746e5SOllivier Robert u_int32 num; 1843c0b746e5SOllivier Robert u_long bit; 1844c0b746e5SOllivier Robert int i; 18452b15cb3dSCy Schubert size_t res; 1846c0b746e5SOllivier Robert int err; 18479c2daa00SOllivier Robert int sendsize; 1848c0b746e5SOllivier Robert 18499c2daa00SOllivier Robert /* Initialize cres */ 18509c2daa00SOllivier Robert cres.addr = 0; 18519c2daa00SOllivier Robert cres.mask = 0; 18529c2daa00SOllivier Robert cres.flags = 0; 18539c2daa00SOllivier Robert cres.mflags = 0; 18549c2daa00SOllivier Robert cres.v6_flag = 0; 18559c2daa00SOllivier Robert 18569c2daa00SOllivier Robert again: 18579c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 18589c2daa00SOllivier Robert sendsize = sizeof(struct conf_restrict); 18599c2daa00SOllivier Robert else 18609c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_restrict); 18619c2daa00SOllivier Robert 18622b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[0].netnum)) { 18632b15cb3dSCy Schubert cres.addr = NSRCADR(&pcmd->argval[0].netnum); 18642b15cb3dSCy Schubert cres.mask = NSRCADR(&pcmd->argval[1].netnum); 18659c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 18669c2daa00SOllivier Robert cres.v6_flag = 0; 18679c2daa00SOllivier Robert } else { 18689c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 18699c2daa00SOllivier Robert fprintf(stderr, 18709c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 18719c2daa00SOllivier Robert return; 18729c2daa00SOllivier Robert } 18732b15cb3dSCy Schubert cres.addr6 = SOCK_ADDR6(&pcmd->argval[0].netnum); 18749c2daa00SOllivier Robert cres.v6_flag = 1; 18759c2daa00SOllivier Robert } 1876c0b746e5SOllivier Robert cres.flags = 0; 1877c0b746e5SOllivier Robert cres.mflags = 0; 18782b15cb3dSCy Schubert err = FALSE; 1879c0b746e5SOllivier Robert for (res = 2; res < pcmd->nargs; res++) { 1880c0b746e5SOllivier Robert if (STREQ(pcmd->argval[res].string, "ntpport")) { 1881c0b746e5SOllivier Robert cres.mflags |= RESM_NTPONLY; 1882c0b746e5SOllivier Robert } else { 1883ea906c41SOllivier Robert for (i = 0; resflagsV3[i].bit != 0; i++) { 1884c0b746e5SOllivier Robert if (STREQ(pcmd->argval[res].string, 1885ea906c41SOllivier Robert resflagsV3[i].str)) 1886c0b746e5SOllivier Robert break; 1887c0b746e5SOllivier Robert } 1888ea906c41SOllivier Robert if (resflagsV3[i].bit != 0) { 1889ea906c41SOllivier Robert cres.flags |= resflagsV3[i].bit; 1890c0b746e5SOllivier Robert if (req_code == REQ_UNRESTRICT) { 18912b15cb3dSCy Schubert fprintf(fp, 1892c0b746e5SOllivier Robert "Flag %s inappropriate\n", 1893ea906c41SOllivier Robert resflagsV3[i].str); 18942b15cb3dSCy Schubert err = TRUE; 1895c0b746e5SOllivier Robert } 1896c0b746e5SOllivier Robert } else { 18972b15cb3dSCy Schubert fprintf(fp, "Unknown flag %s\n", 1898c0b746e5SOllivier Robert pcmd->argval[res].string); 18992b15cb3dSCy Schubert err = TRUE; 1900c0b746e5SOllivier Robert } 1901c0b746e5SOllivier Robert } 1902c0b746e5SOllivier Robert } 1903ea906c41SOllivier Robert cres.flags = htons(cres.flags); 1904ea906c41SOllivier Robert cres.mflags = htons(cres.mflags); 1905c0b746e5SOllivier Robert 1906c0b746e5SOllivier Robert /* 1907c0b746e5SOllivier Robert * Make sure mask for default address is zero. Otherwise, 1908c0b746e5SOllivier Robert * make sure mask bits are contiguous. 1909c0b746e5SOllivier Robert */ 19102b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[0].netnum)) { 1911c0b746e5SOllivier Robert if (cres.addr == 0) { 1912c0b746e5SOllivier Robert cres.mask = 0; 1913c0b746e5SOllivier Robert } else { 1914c0b746e5SOllivier Robert num = ntohl(cres.mask); 1915c0b746e5SOllivier Robert for (bit = 0x80000000; bit != 0; bit >>= 1) 1916c0b746e5SOllivier Robert if ((num & bit) == 0) 1917c0b746e5SOllivier Robert break; 1918c0b746e5SOllivier Robert for ( ; bit != 0; bit >>= 1) 1919c0b746e5SOllivier Robert if ((num & bit) != 0) 1920c0b746e5SOllivier Robert break; 1921c0b746e5SOllivier Robert if (bit != 0) { 19222b15cb3dSCy Schubert fprintf(fp, "Invalid mask %s\n", 1923c0b746e5SOllivier Robert numtoa(cres.mask)); 19242b15cb3dSCy Schubert err = TRUE; 1925c0b746e5SOllivier Robert } 1926c0b746e5SOllivier Robert } 19279c2daa00SOllivier Robert } else { 19289c2daa00SOllivier Robert /* XXX IPv6 sanity checking stuff */ 19299c2daa00SOllivier Robert } 1930c0b746e5SOllivier Robert 1931c0b746e5SOllivier Robert if (err) 1932c0b746e5SOllivier Robert return; 1933c0b746e5SOllivier Robert 19342b15cb3dSCy Schubert res = doquery(impl_ver, req_code, 1, 1, sendsize, (char *)&cres, 19352b15cb3dSCy Schubert &items, &itemsize, &dummy, 0, sizeof(cres)); 19369c2daa00SOllivier Robert 19379c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 19389c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 19399c2daa00SOllivier Robert goto again; 19409c2daa00SOllivier Robert } 1941c0b746e5SOllivier Robert 1942c0b746e5SOllivier Robert if (res == 0) 1943c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 1944c0b746e5SOllivier Robert return; 1945c0b746e5SOllivier Robert } 1946c0b746e5SOllivier Robert 1947c0b746e5SOllivier Robert 1948c0b746e5SOllivier Robert /* 1949c0b746e5SOllivier Robert * monlist - obtain and print the server's monitor data 1950c0b746e5SOllivier Robert */ 1951c0b746e5SOllivier Robert /*ARGSUSED*/ 1952c0b746e5SOllivier Robert static void 1953c0b746e5SOllivier Robert monlist( 1954c0b746e5SOllivier Robert struct parse *pcmd, 1955c0b746e5SOllivier Robert FILE *fp 1956c0b746e5SOllivier Robert ) 1957c0b746e5SOllivier Robert { 19583311ff84SXin LI const char *struct_star; 19593311ff84SXin LI const struct info_monitor *ml; 19603311ff84SXin LI const struct info_monitor_1 *m1; 19613311ff84SXin LI const struct old_info_monitor *oml; 19622b15cb3dSCy Schubert sockaddr_u addr; 19632b15cb3dSCy Schubert sockaddr_u dstadr; 19643311ff84SXin LI size_t items; 19653311ff84SXin LI size_t itemsize; 1966c0b746e5SOllivier Robert int res; 1967c0b746e5SOllivier Robert int version = -1; 1968c0b746e5SOllivier Robert 19692b15cb3dSCy Schubert if (pcmd->nargs > 0) 1970c0b746e5SOllivier Robert version = pcmd->argval[0].ival; 1971c0b746e5SOllivier Robert 19729c2daa00SOllivier Robert again: 19739c2daa00SOllivier Robert res = doquery(impl_ver, 1974c0b746e5SOllivier Robert (version == 1 || version == -1) ? REQ_MON_GETLIST_1 : 19752b15cb3dSCy Schubert REQ_MON_GETLIST, 0, 0, 0, NULL, 1976c0b746e5SOllivier Robert &items, &itemsize, &struct_star, 19779c2daa00SOllivier Robert (version < 0) ? (1 << INFO_ERR_REQ) : 0, 19789c2daa00SOllivier Robert sizeof(struct info_monitor_1)); 19799c2daa00SOllivier Robert 19809c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 19819c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 19829c2daa00SOllivier Robert goto again; 19839c2daa00SOllivier Robert } 1984c0b746e5SOllivier Robert 1985c0b746e5SOllivier Robert if (res == INFO_ERR_REQ && version < 0) 19862b15cb3dSCy Schubert res = doquery(impl_ver, REQ_MON_GETLIST, 0, 0, 0, NULL, 19879c2daa00SOllivier Robert &items, &itemsize, &struct_star, 0, 19889c2daa00SOllivier Robert sizeof(struct info_monitor)); 1989c0b746e5SOllivier Robert 1990ea906c41SOllivier Robert if (res != 0) 1991c0b746e5SOllivier Robert return; 1992c0b746e5SOllivier Robert 1993c0b746e5SOllivier Robert if (!checkitems(items, fp)) 1994c0b746e5SOllivier Robert return; 1995c0b746e5SOllivier Robert 19969c2daa00SOllivier Robert if (itemsize == sizeof(struct info_monitor_1) || 19979c2daa00SOllivier Robert itemsize == v4sizeof(struct info_monitor_1)) { 1998c0b746e5SOllivier Robert 19993311ff84SXin LI m1 = (const void*)struct_star; 20002b15cb3dSCy Schubert fprintf(fp, 20012b15cb3dSCy Schubert "remote address port local address count m ver rstr avgint lstint\n"); 20022b15cb3dSCy Schubert fprintf(fp, 2003c0b746e5SOllivier Robert "===============================================================================\n"); 2004c0b746e5SOllivier Robert while (items > 0) { 20052b15cb3dSCy Schubert SET_ADDRS(dstadr, addr, m1, daddr, addr); 20069c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 20072b15cb3dSCy Schubert ((pcmd->argval->ival == 6) && (m1->v6_flag != 0)) || 20082b15cb3dSCy Schubert ((pcmd->argval->ival == 4) && (m1->v6_flag == 0))) 20092b15cb3dSCy Schubert fprintf(fp, 20102b15cb3dSCy Schubert "%-22.22s %5d %-15s %8lu %1u %1u %6lx %6lu %7lu\n", 20119c2daa00SOllivier Robert nntohost(&addr), 20122b15cb3dSCy Schubert ntohs(m1->port), 20139c2daa00SOllivier Robert stoa(&dstadr), 20142b15cb3dSCy Schubert (u_long)ntohl(m1->count), 20152b15cb3dSCy Schubert m1->mode, 20162b15cb3dSCy Schubert m1->version, 20172b15cb3dSCy Schubert (u_long)ntohl(m1->restr), 20182b15cb3dSCy Schubert (u_long)ntohl(m1->avg_int), 20192b15cb3dSCy Schubert (u_long)ntohl(m1->last_int)); 20202b15cb3dSCy Schubert m1++; 2021c0b746e5SOllivier Robert items--; 2022c0b746e5SOllivier Robert } 20239c2daa00SOllivier Robert } else if (itemsize == sizeof(struct info_monitor) || 20249c2daa00SOllivier Robert itemsize == v4sizeof(struct info_monitor)) { 2025c0b746e5SOllivier Robert 20263311ff84SXin LI ml = (const void *)struct_star; 20272b15cb3dSCy Schubert fprintf(fp, 20282b15cb3dSCy Schubert " address port count mode ver rstr avgint lstint\n"); 20292b15cb3dSCy Schubert fprintf(fp, 2030c0b746e5SOllivier Robert "===============================================================================\n"); 2031c0b746e5SOllivier Robert while (items > 0) { 20322b15cb3dSCy Schubert SET_ADDR(dstadr, ml->v6_flag, ml->addr, ml->addr6); 20339c2daa00SOllivier Robert if ((pcmd->nargs == 0) || 20349c2daa00SOllivier Robert ((pcmd->argval->ival == 6) && (ml->v6_flag != 0)) || 20359c2daa00SOllivier Robert ((pcmd->argval->ival == 4) && (ml->v6_flag == 0))) 20362b15cb3dSCy Schubert fprintf(fp, 20372b15cb3dSCy Schubert "%-25.25s %5u %9lu %4u %2u %9lx %9lu %9lu\n", 20389c2daa00SOllivier Robert nntohost(&dstadr), 2039c0b746e5SOllivier Robert ntohs(ml->port), 2040c0b746e5SOllivier Robert (u_long)ntohl(ml->count), 2041c0b746e5SOllivier Robert ml->mode, 2042c0b746e5SOllivier Robert ml->version, 20432b15cb3dSCy Schubert (u_long)ntohl(ml->restr), 20442b15cb3dSCy Schubert (u_long)ntohl(ml->avg_int), 20452b15cb3dSCy Schubert (u_long)ntohl(ml->last_int)); 2046c0b746e5SOllivier Robert ml++; 2047c0b746e5SOllivier Robert items--; 2048c0b746e5SOllivier Robert } 2049c0b746e5SOllivier Robert } else if (itemsize == sizeof(struct old_info_monitor)) { 20502b15cb3dSCy Schubert 20513311ff84SXin LI oml = (const void *)struct_star; 20522b15cb3dSCy Schubert fprintf(fp, 2053c0b746e5SOllivier Robert " address port count mode version lasttime firsttime\n"); 20542b15cb3dSCy Schubert fprintf(fp, 2055c0b746e5SOllivier Robert "======================================================================\n"); 2056c0b746e5SOllivier Robert while (items > 0) { 20572b15cb3dSCy Schubert SET_ADDR(dstadr, oml->v6_flag, oml->addr, oml->addr6); 20582b15cb3dSCy Schubert fprintf(fp, "%-20.20s %5u %9lu %4u %3u %9lu %9lu\n", 20599c2daa00SOllivier Robert nntohost(&dstadr), 2060c0b746e5SOllivier Robert ntohs(oml->port), 2061c0b746e5SOllivier Robert (u_long)ntohl(oml->count), 2062c0b746e5SOllivier Robert oml->mode, 2063c0b746e5SOllivier Robert oml->version, 2064c0b746e5SOllivier Robert (u_long)ntohl(oml->lasttime), 2065c0b746e5SOllivier Robert (u_long)ntohl(oml->firsttime)); 2066c0b746e5SOllivier Robert oml++; 2067c0b746e5SOllivier Robert items--; 2068c0b746e5SOllivier Robert } 2069c0b746e5SOllivier Robert } else { 2070c0b746e5SOllivier Robert /* issue warning according to new info_monitor size */ 2071c0b746e5SOllivier Robert checkitemsize(itemsize, sizeof(struct info_monitor)); 2072c0b746e5SOllivier Robert } 2073c0b746e5SOllivier Robert } 2074c0b746e5SOllivier Robert 2075c0b746e5SOllivier Robert 2076c0b746e5SOllivier Robert /* 2077c0b746e5SOllivier Robert * Mapping between command line strings and stat reset flags 2078c0b746e5SOllivier Robert */ 2079c0b746e5SOllivier Robert struct statreset { 20802b15cb3dSCy Schubert const char * const str; 20812b15cb3dSCy Schubert const int flag; 2082c0b746e5SOllivier Robert } sreset[] = { 20832b15cb3dSCy Schubert { "allpeers", RESET_FLAG_ALLPEERS }, 2084c0b746e5SOllivier Robert { "io", RESET_FLAG_IO }, 2085c0b746e5SOllivier Robert { "sys", RESET_FLAG_SYS }, 2086c0b746e5SOllivier Robert { "mem", RESET_FLAG_MEM }, 2087c0b746e5SOllivier Robert { "timer", RESET_FLAG_TIMER }, 2088c0b746e5SOllivier Robert { "auth", RESET_FLAG_AUTH }, 20892b15cb3dSCy Schubert { "ctl", RESET_FLAG_CTL }, 2090c0b746e5SOllivier Robert { "", 0 } 2091c0b746e5SOllivier Robert }; 2092c0b746e5SOllivier Robert 2093c0b746e5SOllivier Robert /* 2094c0b746e5SOllivier Robert * reset - reset statistic counters 2095c0b746e5SOllivier Robert */ 2096c0b746e5SOllivier Robert static void 2097c0b746e5SOllivier Robert reset( 2098c0b746e5SOllivier Robert struct parse *pcmd, 2099c0b746e5SOllivier Robert FILE *fp 2100c0b746e5SOllivier Robert ) 2101c0b746e5SOllivier Robert { 2102c0b746e5SOllivier Robert struct reset_flags rflags; 21033311ff84SXin LI size_t items; 21043311ff84SXin LI size_t itemsize; 21053311ff84SXin LI const char *dummy; 2106c0b746e5SOllivier Robert int i; 21072b15cb3dSCy Schubert size_t res; 2108c0b746e5SOllivier Robert int err; 2109c0b746e5SOllivier Robert 2110c0b746e5SOllivier Robert err = 0; 2111c0b746e5SOllivier Robert rflags.flags = 0; 2112c0b746e5SOllivier Robert for (res = 0; res < pcmd->nargs; res++) { 2113c0b746e5SOllivier Robert for (i = 0; sreset[i].flag != 0; i++) { 2114c0b746e5SOllivier Robert if (STREQ(pcmd->argval[res].string, sreset[i].str)) 2115c0b746e5SOllivier Robert break; 2116c0b746e5SOllivier Robert } 2117c0b746e5SOllivier Robert if (sreset[i].flag == 0) { 21182b15cb3dSCy Schubert fprintf(fp, "Flag %s unknown\n", 2119c0b746e5SOllivier Robert pcmd->argval[res].string); 2120f0574f5cSXin LI err = 1; 2121c0b746e5SOllivier Robert } else { 2122c0b746e5SOllivier Robert rflags.flags |= sreset[i].flag; 2123c0b746e5SOllivier Robert } 2124c0b746e5SOllivier Robert } 2125ea906c41SOllivier Robert rflags.flags = htonl(rflags.flags); 2126c0b746e5SOllivier Robert 2127c0b746e5SOllivier Robert if (err) { 2128c0b746e5SOllivier Robert (void) fprintf(fp, "Not done due to errors\n"); 2129c0b746e5SOllivier Robert return; 2130c0b746e5SOllivier Robert } 2131c0b746e5SOllivier Robert 21329c2daa00SOllivier Robert again: 21339c2daa00SOllivier Robert res = doquery(impl_ver, REQ_RESET_STATS, 1, 1, 2134c0b746e5SOllivier Robert sizeof(struct reset_flags), (char *)&rflags, &items, 21359c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct reset_flags)); 21369c2daa00SOllivier Robert 21379c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 21389c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 21399c2daa00SOllivier Robert goto again; 21409c2daa00SOllivier Robert } 2141c0b746e5SOllivier Robert 2142c0b746e5SOllivier Robert if (res == 0) 2143c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2144c0b746e5SOllivier Robert return; 2145c0b746e5SOllivier Robert } 2146c0b746e5SOllivier Robert 2147c0b746e5SOllivier Robert 2148c0b746e5SOllivier Robert 2149c0b746e5SOllivier Robert /* 2150c0b746e5SOllivier Robert * preset - reset stat counters for particular peers 2151c0b746e5SOllivier Robert */ 2152c0b746e5SOllivier Robert static void 2153c0b746e5SOllivier Robert preset( 2154c0b746e5SOllivier Robert struct parse *pcmd, 2155c0b746e5SOllivier Robert FILE *fp 2156c0b746e5SOllivier Robert ) 2157c0b746e5SOllivier Robert { 2158c0b746e5SOllivier Robert /* 8 is the maximum number of peers which will fit in a packet */ 21599c2daa00SOllivier Robert struct conf_unpeer *pl, plist[min(MAXARGS, 8)]; 21603311ff84SXin LI size_t qitemlim; 21613311ff84SXin LI size_t qitems; 21623311ff84SXin LI size_t items; 21633311ff84SXin LI size_t itemsize; 21643311ff84SXin LI const char *dummy; 2165c0b746e5SOllivier Robert int res; 21663311ff84SXin LI size_t sendsize; 2167c0b746e5SOllivier Robert 21689c2daa00SOllivier Robert again: 21699c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 21709c2daa00SOllivier Robert sendsize = sizeof(struct conf_unpeer); 21719c2daa00SOllivier Robert else 21729c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_unpeer); 21739c2daa00SOllivier Robert 21742b15cb3dSCy Schubert qitemlim = min(pcmd->nargs, COUNTOF(plist)); 21752b15cb3dSCy Schubert for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) { 21762b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[qitems].netnum)) { 21772b15cb3dSCy Schubert pl->peeraddr = NSRCADR(&pcmd->argval[qitems].netnum); 21789c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 21799c2daa00SOllivier Robert pl->v6_flag = 0; 21809c2daa00SOllivier Robert } else { 21819c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 21829c2daa00SOllivier Robert fprintf(stderr, 21839c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 21849c2daa00SOllivier Robert return; 21859c2daa00SOllivier Robert } 21869c2daa00SOllivier Robert pl->peeraddr6 = 21872b15cb3dSCy Schubert SOCK_ADDR6(&pcmd->argval[qitems].netnum); 21889c2daa00SOllivier Robert pl->v6_flag = 1; 21899c2daa00SOllivier Robert } 21902b15cb3dSCy Schubert pl = (void *)((char *)pl + sendsize); 2191c0b746e5SOllivier Robert } 2192c0b746e5SOllivier Robert 21939c2daa00SOllivier Robert res = doquery(impl_ver, REQ_RESET_PEER, 1, qitems, 21949c2daa00SOllivier Robert sendsize, (char *)plist, &items, 21959c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(struct conf_unpeer)); 21969c2daa00SOllivier Robert 21979c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 21989c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 21999c2daa00SOllivier Robert goto again; 22009c2daa00SOllivier Robert } 2201c0b746e5SOllivier Robert 2202c0b746e5SOllivier Robert if (res == 0) 2203c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2204c0b746e5SOllivier Robert } 2205c0b746e5SOllivier Robert 2206c0b746e5SOllivier Robert 2207c0b746e5SOllivier Robert /* 2208c0b746e5SOllivier Robert * readkeys - request the server to reread the keys file 2209c0b746e5SOllivier Robert */ 2210c0b746e5SOllivier Robert /*ARGSUSED*/ 2211c0b746e5SOllivier Robert static void 2212c0b746e5SOllivier Robert readkeys( 2213c0b746e5SOllivier Robert struct parse *pcmd, 2214c0b746e5SOllivier Robert FILE *fp 2215c0b746e5SOllivier Robert ) 2216c0b746e5SOllivier Robert { 22173311ff84SXin LI size_t items; 22183311ff84SXin LI size_t itemsize; 22193311ff84SXin LI const char *dummy; 2220c0b746e5SOllivier Robert int res; 2221c0b746e5SOllivier Robert 22229c2daa00SOllivier Robert again: 22239c2daa00SOllivier Robert res = doquery(impl_ver, REQ_REREAD_KEYS, 1, 0, 0, (char *)0, 22249c2daa00SOllivier Robert &items, &itemsize, &dummy, 0, sizeof(dummy)); 22259c2daa00SOllivier Robert 22269c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 22279c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 22289c2daa00SOllivier Robert goto again; 22299c2daa00SOllivier Robert } 2230c0b746e5SOllivier Robert 2231c0b746e5SOllivier Robert if (res == 0) 2232c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2233c0b746e5SOllivier Robert return; 2234c0b746e5SOllivier Robert } 2235c0b746e5SOllivier Robert 2236c0b746e5SOllivier Robert 2237c0b746e5SOllivier Robert /* 2238c0b746e5SOllivier Robert * trustkey - add some keys to the trusted key list 2239c0b746e5SOllivier Robert */ 2240c0b746e5SOllivier Robert static void 2241c0b746e5SOllivier Robert trustkey( 2242c0b746e5SOllivier Robert struct parse *pcmd, 2243c0b746e5SOllivier Robert FILE *fp 2244c0b746e5SOllivier Robert ) 2245c0b746e5SOllivier Robert { 2246c0b746e5SOllivier Robert do_trustkey(pcmd, fp, REQ_TRUSTKEY); 2247c0b746e5SOllivier Robert } 2248c0b746e5SOllivier Robert 2249c0b746e5SOllivier Robert 2250c0b746e5SOllivier Robert /* 2251c0b746e5SOllivier Robert * untrustkey - remove some keys from the trusted key list 2252c0b746e5SOllivier Robert */ 2253c0b746e5SOllivier Robert static void 2254c0b746e5SOllivier Robert untrustkey( 2255c0b746e5SOllivier Robert struct parse *pcmd, 2256c0b746e5SOllivier Robert FILE *fp 2257c0b746e5SOllivier Robert ) 2258c0b746e5SOllivier Robert { 2259c0b746e5SOllivier Robert do_trustkey(pcmd, fp, REQ_UNTRUSTKEY); 2260c0b746e5SOllivier Robert } 2261c0b746e5SOllivier Robert 2262c0b746e5SOllivier Robert 2263c0b746e5SOllivier Robert /* 2264c0b746e5SOllivier Robert * do_trustkey - do grunge work of adding/deleting keys 2265c0b746e5SOllivier Robert */ 2266c0b746e5SOllivier Robert static void 2267c0b746e5SOllivier Robert do_trustkey( 2268c0b746e5SOllivier Robert struct parse *pcmd, 2269c0b746e5SOllivier Robert FILE *fp, 2270c0b746e5SOllivier Robert int req 2271c0b746e5SOllivier Robert ) 2272c0b746e5SOllivier Robert { 2273c0b746e5SOllivier Robert u_long keyids[MAXARGS]; 22742b15cb3dSCy Schubert size_t i; 22753311ff84SXin LI size_t items; 22763311ff84SXin LI size_t itemsize; 22773311ff84SXin LI const char *dummy; 2278c0b746e5SOllivier Robert int ritems; 2279c0b746e5SOllivier Robert int res; 2280c0b746e5SOllivier Robert 2281c0b746e5SOllivier Robert ritems = 0; 2282c0b746e5SOllivier Robert for (i = 0; i < pcmd->nargs; i++) { 2283c0b746e5SOllivier Robert keyids[ritems++] = pcmd->argval[i].uval; 2284c0b746e5SOllivier Robert } 2285c0b746e5SOllivier Robert 22869c2daa00SOllivier Robert again: 22879c2daa00SOllivier Robert res = doquery(impl_ver, req, 1, ritems, sizeof(u_long), 22889c2daa00SOllivier Robert (char *)keyids, &items, &itemsize, &dummy, 0, 22899c2daa00SOllivier Robert sizeof(dummy)); 22909c2daa00SOllivier Robert 22919c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 22929c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 22939c2daa00SOllivier Robert goto again; 22949c2daa00SOllivier Robert } 2295c0b746e5SOllivier Robert 2296c0b746e5SOllivier Robert if (res == 0) 2297c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2298c0b746e5SOllivier Robert return; 2299c0b746e5SOllivier Robert } 2300c0b746e5SOllivier Robert 2301c0b746e5SOllivier Robert 2302c0b746e5SOllivier Robert 2303c0b746e5SOllivier Robert /* 2304c0b746e5SOllivier Robert * authinfo - obtain and print info about authentication 2305c0b746e5SOllivier Robert */ 2306c0b746e5SOllivier Robert /*ARGSUSED*/ 2307c0b746e5SOllivier Robert static void 2308c0b746e5SOllivier Robert authinfo( 2309c0b746e5SOllivier Robert struct parse *pcmd, 2310c0b746e5SOllivier Robert FILE *fp 2311c0b746e5SOllivier Robert ) 2312c0b746e5SOllivier Robert { 2313c0b746e5SOllivier Robert struct info_auth *ia; 23143311ff84SXin LI size_t items; 23153311ff84SXin LI size_t itemsize; 2316c0b746e5SOllivier Robert int res; 2317c0b746e5SOllivier Robert 23189c2daa00SOllivier Robert again: 23192b15cb3dSCy Schubert res = doquery(impl_ver, REQ_AUTHINFO, 0, 0, 0, NULL, &items, 23202b15cb3dSCy Schubert &itemsize, (void *)&ia, 0, sizeof(*ia)); 23219c2daa00SOllivier Robert 23229c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 23239c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 23249c2daa00SOllivier Robert goto again; 23259c2daa00SOllivier Robert } 2326c0b746e5SOllivier Robert 2327ea906c41SOllivier Robert if (res != 0) 2328c0b746e5SOllivier Robert return; 2329c0b746e5SOllivier Robert 2330c0b746e5SOllivier Robert if (!check1item(items, fp)) 2331c0b746e5SOllivier Robert return; 2332c0b746e5SOllivier Robert 23332b15cb3dSCy Schubert if (!checkitemsize(itemsize, sizeof(*ia))) 2334c0b746e5SOllivier Robert return; 2335c0b746e5SOllivier Robert 23362b15cb3dSCy Schubert fprintf(fp, "time since reset: %lu\n", 2337c0b746e5SOllivier Robert (u_long)ntohl(ia->timereset)); 23382b15cb3dSCy Schubert fprintf(fp, "stored keys: %lu\n", 2339c0b746e5SOllivier Robert (u_long)ntohl(ia->numkeys)); 23402b15cb3dSCy Schubert fprintf(fp, "free keys: %lu\n", 2341c0b746e5SOllivier Robert (u_long)ntohl(ia->numfreekeys)); 23422b15cb3dSCy Schubert fprintf(fp, "key lookups: %lu\n", 2343c0b746e5SOllivier Robert (u_long)ntohl(ia->keylookups)); 23442b15cb3dSCy Schubert fprintf(fp, "keys not found: %lu\n", 2345c0b746e5SOllivier Robert (u_long)ntohl(ia->keynotfound)); 23462b15cb3dSCy Schubert fprintf(fp, "uncached keys: %lu\n", 2347c0b746e5SOllivier Robert (u_long)ntohl(ia->keyuncached)); 23482b15cb3dSCy Schubert fprintf(fp, "encryptions: %lu\n", 2349c0b746e5SOllivier Robert (u_long)ntohl(ia->encryptions)); 23502b15cb3dSCy Schubert fprintf(fp, "decryptions: %lu\n", 2351c0b746e5SOllivier Robert (u_long)ntohl(ia->decryptions)); 23522b15cb3dSCy Schubert fprintf(fp, "expired keys: %lu\n", 2353c0b746e5SOllivier Robert (u_long)ntohl(ia->expired)); 2354c0b746e5SOllivier Robert } 2355c0b746e5SOllivier Robert 2356c0b746e5SOllivier Robert 2357c0b746e5SOllivier Robert 2358c0b746e5SOllivier Robert /* 2359c0b746e5SOllivier Robert * traps - obtain and print a list of traps 2360c0b746e5SOllivier Robert */ 2361c0b746e5SOllivier Robert /*ARGSUSED*/ 2362c0b746e5SOllivier Robert static void 2363c0b746e5SOllivier Robert traps( 2364c0b746e5SOllivier Robert struct parse *pcmd, 2365c0b746e5SOllivier Robert FILE *fp 2366c0b746e5SOllivier Robert ) 2367c0b746e5SOllivier Robert { 23683311ff84SXin LI size_t i; 2369c0b746e5SOllivier Robert struct info_trap *it; 23702b15cb3dSCy Schubert sockaddr_u trap_addr, local_addr; 23713311ff84SXin LI size_t items; 23723311ff84SXin LI size_t itemsize; 2373c0b746e5SOllivier Robert int res; 2374c0b746e5SOllivier Robert 23759c2daa00SOllivier Robert again: 23762b15cb3dSCy Schubert res = doquery(impl_ver, REQ_TRAPS, 0, 0, 0, NULL, &items, 23772b15cb3dSCy Schubert &itemsize, (void *)&it, 0, sizeof(*it)); 23789c2daa00SOllivier Robert 23799c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 23809c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 23819c2daa00SOllivier Robert goto again; 23829c2daa00SOllivier Robert } 2383c0b746e5SOllivier Robert 2384ea906c41SOllivier Robert if (res != 0) 2385c0b746e5SOllivier Robert return; 2386c0b746e5SOllivier Robert 2387c0b746e5SOllivier Robert if (!checkitems(items, fp)) 2388c0b746e5SOllivier Robert return; 2389c0b746e5SOllivier Robert 23909c2daa00SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_trap)) && 23919c2daa00SOllivier Robert !checkitemsize(itemsize, v4sizeof(struct info_trap))) 2392c0b746e5SOllivier Robert return; 2393c0b746e5SOllivier Robert 2394c0b746e5SOllivier Robert for (i = 0; i < items; i++ ) { 23952b15cb3dSCy Schubert SET_ADDRS(trap_addr, local_addr, it, trap_address, local_address); 23962b15cb3dSCy Schubert fprintf(fp, "%saddress %s, port %d\n", 23972b15cb3dSCy Schubert (0 == i) 23982b15cb3dSCy Schubert ? "" 23992b15cb3dSCy Schubert : "\n", 24002b15cb3dSCy Schubert stoa(&trap_addr), ntohs(it->trap_port)); 24012b15cb3dSCy Schubert fprintf(fp, "interface: %s, ", 24022b15cb3dSCy Schubert (0 == it->local_address) 2403c0b746e5SOllivier Robert ? "wildcard" 24049c2daa00SOllivier Robert : stoa(&local_addr)); 2405c0b746e5SOllivier Robert if (ntohl(it->flags) & TRAP_CONFIGURED) 24062b15cb3dSCy Schubert fprintf(fp, "configured\n"); 2407c0b746e5SOllivier Robert else if (ntohl(it->flags) & TRAP_NONPRIO) 24082b15cb3dSCy Schubert fprintf(fp, "low priority\n"); 2409c0b746e5SOllivier Robert else 24102b15cb3dSCy Schubert fprintf(fp, "normal priority\n"); 2411c0b746e5SOllivier Robert 24122b15cb3dSCy Schubert fprintf(fp, "set for %ld secs, last set %ld secs ago\n", 2413c0b746e5SOllivier Robert (long)ntohl(it->origtime), 2414c0b746e5SOllivier Robert (long)ntohl(it->settime)); 24152b15cb3dSCy Schubert fprintf(fp, "sequence %d, number of resets %ld\n", 24162b15cb3dSCy Schubert ntohs(it->sequence), (long)ntohl(it->resets)); 2417c0b746e5SOllivier Robert } 2418c0b746e5SOllivier Robert } 2419c0b746e5SOllivier Robert 2420c0b746e5SOllivier Robert 2421c0b746e5SOllivier Robert /* 2422c0b746e5SOllivier Robert * addtrap - configure a trap 2423c0b746e5SOllivier Robert */ 2424c0b746e5SOllivier Robert static void 2425c0b746e5SOllivier Robert addtrap( 2426c0b746e5SOllivier Robert struct parse *pcmd, 2427c0b746e5SOllivier Robert FILE *fp 2428c0b746e5SOllivier Robert ) 2429c0b746e5SOllivier Robert { 2430c0b746e5SOllivier Robert do_addclr_trap(pcmd, fp, REQ_ADD_TRAP); 2431c0b746e5SOllivier Robert } 2432c0b746e5SOllivier Robert 2433c0b746e5SOllivier Robert 2434c0b746e5SOllivier Robert /* 2435c0b746e5SOllivier Robert * clrtrap - clear a trap from the server 2436c0b746e5SOllivier Robert */ 2437c0b746e5SOllivier Robert static void 2438c0b746e5SOllivier Robert clrtrap( 2439c0b746e5SOllivier Robert struct parse *pcmd, 2440c0b746e5SOllivier Robert FILE *fp 2441c0b746e5SOllivier Robert ) 2442c0b746e5SOllivier Robert { 2443c0b746e5SOllivier Robert do_addclr_trap(pcmd, fp, REQ_CLR_TRAP); 2444c0b746e5SOllivier Robert } 2445c0b746e5SOllivier Robert 2446c0b746e5SOllivier Robert 2447c0b746e5SOllivier Robert /* 2448c0b746e5SOllivier Robert * do_addclr_trap - do grunge work of adding/deleting traps 2449c0b746e5SOllivier Robert */ 2450c0b746e5SOllivier Robert static void 2451c0b746e5SOllivier Robert do_addclr_trap( 2452c0b746e5SOllivier Robert struct parse *pcmd, 2453c0b746e5SOllivier Robert FILE *fp, 2454c0b746e5SOllivier Robert int req 2455c0b746e5SOllivier Robert ) 2456c0b746e5SOllivier Robert { 2457c0b746e5SOllivier Robert struct conf_trap ctrap; 24583311ff84SXin LI size_t items; 24593311ff84SXin LI size_t itemsize; 24603311ff84SXin LI const char *dummy; 2461c0b746e5SOllivier Robert int res; 24629c2daa00SOllivier Robert int sendsize; 2463c0b746e5SOllivier Robert 24649c2daa00SOllivier Robert again: 24659c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 24669c2daa00SOllivier Robert sendsize = sizeof(struct conf_trap); 24679c2daa00SOllivier Robert else 24689c2daa00SOllivier Robert sendsize = v4sizeof(struct conf_trap); 24699c2daa00SOllivier Robert 24702b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[0].netnum)) { 24712b15cb3dSCy Schubert ctrap.trap_address = NSRCADR(&pcmd->argval[0].netnum); 24729c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD) 24739c2daa00SOllivier Robert ctrap.v6_flag = 0; 24749c2daa00SOllivier Robert } else { 24759c2daa00SOllivier Robert if (impl_ver == IMPL_XNTPD_OLD) { 24769c2daa00SOllivier Robert fprintf(stderr, 24779c2daa00SOllivier Robert "***Server doesn't understand IPv6 addresses\n"); 24789c2daa00SOllivier Robert return; 24799c2daa00SOllivier Robert } 24802b15cb3dSCy Schubert ctrap.trap_address6 = SOCK_ADDR6(&pcmd->argval[0].netnum); 24819c2daa00SOllivier Robert ctrap.v6_flag = 1; 24829c2daa00SOllivier Robert } 2483c0b746e5SOllivier Robert ctrap.local_address = 0; 2484c0b746e5SOllivier Robert ctrap.trap_port = htons(TRAPPORT); 2485c0b746e5SOllivier Robert ctrap.unused = 0; 2486c0b746e5SOllivier Robert 2487c0b746e5SOllivier Robert if (pcmd->nargs > 1) { 24882b15cb3dSCy Schubert ctrap.trap_port = htons((u_short)pcmd->argval[1].uval); 24899c2daa00SOllivier Robert if (pcmd->nargs > 2) { 24902b15cb3dSCy Schubert if (AF(&pcmd->argval[2].netnum) != 24912b15cb3dSCy Schubert AF(&pcmd->argval[0].netnum)) { 24929c2daa00SOllivier Robert fprintf(stderr, 24939c2daa00SOllivier Robert "***Cannot mix IPv4 and IPv6 addresses\n"); 24949c2daa00SOllivier Robert return; 24959c2daa00SOllivier Robert } 24962b15cb3dSCy Schubert if (IS_IPV4(&pcmd->argval[2].netnum)) 24972b15cb3dSCy Schubert ctrap.local_address = NSRCADR(&pcmd->argval[2].netnum); 24989c2daa00SOllivier Robert else 24992b15cb3dSCy Schubert ctrap.local_address6 = SOCK_ADDR6(&pcmd->argval[2].netnum); 25009c2daa00SOllivier Robert } 2501c0b746e5SOllivier Robert } 2502c0b746e5SOllivier Robert 25039c2daa00SOllivier Robert res = doquery(impl_ver, req, 1, 1, sendsize, 25049c2daa00SOllivier Robert (char *)&ctrap, &items, &itemsize, &dummy, 0, 25059c2daa00SOllivier Robert sizeof(struct conf_trap)); 25069c2daa00SOllivier Robert 25079c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 25089c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 25099c2daa00SOllivier Robert goto again; 25109c2daa00SOllivier Robert } 2511c0b746e5SOllivier Robert 2512c0b746e5SOllivier Robert if (res == 0) 2513c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2514c0b746e5SOllivier Robert return; 2515c0b746e5SOllivier Robert } 2516c0b746e5SOllivier Robert 2517c0b746e5SOllivier Robert 2518c0b746e5SOllivier Robert 2519c0b746e5SOllivier Robert /* 2520c0b746e5SOllivier Robert * requestkey - change the server's request key (a dangerous request) 2521c0b746e5SOllivier Robert */ 2522c0b746e5SOllivier Robert static void 2523c0b746e5SOllivier Robert requestkey( 2524c0b746e5SOllivier Robert struct parse *pcmd, 2525c0b746e5SOllivier Robert FILE *fp 2526c0b746e5SOllivier Robert ) 2527c0b746e5SOllivier Robert { 2528c0b746e5SOllivier Robert do_changekey(pcmd, fp, REQ_REQUEST_KEY); 2529c0b746e5SOllivier Robert } 2530c0b746e5SOllivier Robert 2531c0b746e5SOllivier Robert 2532c0b746e5SOllivier Robert /* 2533c0b746e5SOllivier Robert * controlkey - change the server's control key 2534c0b746e5SOllivier Robert */ 2535c0b746e5SOllivier Robert static void 2536c0b746e5SOllivier Robert controlkey( 2537c0b746e5SOllivier Robert struct parse *pcmd, 2538c0b746e5SOllivier Robert FILE *fp 2539c0b746e5SOllivier Robert ) 2540c0b746e5SOllivier Robert { 2541c0b746e5SOllivier Robert do_changekey(pcmd, fp, REQ_CONTROL_KEY); 2542c0b746e5SOllivier Robert } 2543c0b746e5SOllivier Robert 2544c0b746e5SOllivier Robert 2545c0b746e5SOllivier Robert 2546c0b746e5SOllivier Robert /* 2547c0b746e5SOllivier Robert * do_changekey - do grunge work of changing keys 2548c0b746e5SOllivier Robert */ 2549c0b746e5SOllivier Robert static void 2550c0b746e5SOllivier Robert do_changekey( 2551c0b746e5SOllivier Robert struct parse *pcmd, 2552c0b746e5SOllivier Robert FILE *fp, 2553c0b746e5SOllivier Robert int req 2554c0b746e5SOllivier Robert ) 2555c0b746e5SOllivier Robert { 2556c0b746e5SOllivier Robert u_long key; 25573311ff84SXin LI size_t items; 25583311ff84SXin LI size_t itemsize; 25593311ff84SXin LI const char *dummy; 2560c0b746e5SOllivier Robert int res; 2561c0b746e5SOllivier Robert 2562c0b746e5SOllivier Robert 2563c0b746e5SOllivier Robert key = htonl((u_int32)pcmd->argval[0].uval); 2564c0b746e5SOllivier Robert 25659c2daa00SOllivier Robert again: 25669c2daa00SOllivier Robert res = doquery(impl_ver, req, 1, 1, sizeof(u_int32), 25679c2daa00SOllivier Robert (char *)&key, &items, &itemsize, &dummy, 0, 25689c2daa00SOllivier Robert sizeof(dummy)); 25699c2daa00SOllivier Robert 25709c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 25719c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 25729c2daa00SOllivier Robert goto again; 25739c2daa00SOllivier Robert } 2574c0b746e5SOllivier Robert 2575c0b746e5SOllivier Robert if (res == 0) 2576c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2577c0b746e5SOllivier Robert return; 2578c0b746e5SOllivier Robert } 2579c0b746e5SOllivier Robert 2580c0b746e5SOllivier Robert 2581c0b746e5SOllivier Robert 2582c0b746e5SOllivier Robert /* 2583c0b746e5SOllivier Robert * ctlstats - obtain and print info about authentication 2584c0b746e5SOllivier Robert */ 2585c0b746e5SOllivier Robert /*ARGSUSED*/ 2586c0b746e5SOllivier Robert static void 2587c0b746e5SOllivier Robert ctlstats( 2588c0b746e5SOllivier Robert struct parse *pcmd, 2589c0b746e5SOllivier Robert FILE *fp 2590c0b746e5SOllivier Robert ) 2591c0b746e5SOllivier Robert { 2592c0b746e5SOllivier Robert struct info_control *ic; 25933311ff84SXin LI size_t items; 25943311ff84SXin LI size_t itemsize; 2595c0b746e5SOllivier Robert int res; 2596c0b746e5SOllivier Robert 25979c2daa00SOllivier Robert again: 25982b15cb3dSCy Schubert res = doquery(impl_ver, REQ_GET_CTLSTATS, 0, 0, 0, NULL, &items, 25992b15cb3dSCy Schubert &itemsize, (void *)&ic, 0, sizeof(*ic)); 26009c2daa00SOllivier Robert 26019c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 26029c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 26039c2daa00SOllivier Robert goto again; 26049c2daa00SOllivier Robert } 2605c0b746e5SOllivier Robert 2606ea906c41SOllivier Robert if (res != 0) 2607c0b746e5SOllivier Robert return; 2608c0b746e5SOllivier Robert 2609c0b746e5SOllivier Robert if (!check1item(items, fp)) 2610c0b746e5SOllivier Robert return; 2611c0b746e5SOllivier Robert 26122b15cb3dSCy Schubert if (!checkitemsize(itemsize, sizeof(*ic))) 2613c0b746e5SOllivier Robert return; 2614c0b746e5SOllivier Robert 26152b15cb3dSCy Schubert fprintf(fp, "time since reset: %lu\n", 2616c0b746e5SOllivier Robert (u_long)ntohl(ic->ctltimereset)); 26172b15cb3dSCy Schubert fprintf(fp, "requests received: %lu\n", 2618c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlreq)); 26192b15cb3dSCy Schubert fprintf(fp, "responses sent: %lu\n", 2620c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlresponses)); 26212b15cb3dSCy Schubert fprintf(fp, "fragments sent: %lu\n", 2622c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlfrags)); 26232b15cb3dSCy Schubert fprintf(fp, "async messages sent: %lu\n", 2624c0b746e5SOllivier Robert (u_long)ntohl(ic->numasyncmsgs)); 26252b15cb3dSCy Schubert fprintf(fp, "error msgs sent: %lu\n", 2626c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlerrors)); 26272b15cb3dSCy Schubert fprintf(fp, "total bad pkts: %lu\n", 2628c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlbadpkts)); 26292b15cb3dSCy Schubert fprintf(fp, "packet too short: %lu\n", 2630c0b746e5SOllivier Robert (u_long)ntohl(ic->numctltooshort)); 26312b15cb3dSCy Schubert fprintf(fp, "response on input: %lu\n", 2632c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlinputresp)); 26332b15cb3dSCy Schubert fprintf(fp, "fragment on input: %lu\n", 2634c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlinputfrag)); 26352b15cb3dSCy Schubert fprintf(fp, "error set on input: %lu\n", 2636c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlinputerr)); 26372b15cb3dSCy Schubert fprintf(fp, "bad offset on input: %lu\n", 2638c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlbadoffset)); 26392b15cb3dSCy Schubert fprintf(fp, "bad version packets: %lu\n", 2640c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlbadversion)); 26412b15cb3dSCy Schubert fprintf(fp, "data in pkt too short: %lu\n", 2642c0b746e5SOllivier Robert (u_long)ntohl(ic->numctldatatooshort)); 26432b15cb3dSCy Schubert fprintf(fp, "unknown op codes: %lu\n", 2644c0b746e5SOllivier Robert (u_long)ntohl(ic->numctlbadop)); 2645c0b746e5SOllivier Robert } 2646c0b746e5SOllivier Robert 2647c0b746e5SOllivier Robert 2648c0b746e5SOllivier Robert /* 2649c0b746e5SOllivier Robert * clockstat - get and print clock status information 2650c0b746e5SOllivier Robert */ 2651c0b746e5SOllivier Robert static void 2652c0b746e5SOllivier Robert clockstat( 2653c0b746e5SOllivier Robert struct parse *pcmd, 2654c0b746e5SOllivier Robert FILE *fp 2655c0b746e5SOllivier Robert ) 2656c0b746e5SOllivier Robert { 2657c0b746e5SOllivier Robert struct info_clock *cl; 2658c0b746e5SOllivier Robert /* 8 is the maximum number of clocks which will fit in a packet */ 2659c0b746e5SOllivier Robert u_long clist[min(MAXARGS, 8)]; 26603311ff84SXin LI size_t qitemlim; 26613311ff84SXin LI size_t qitems; 26623311ff84SXin LI size_t items; 26633311ff84SXin LI size_t itemsize; 2664c0b746e5SOllivier Robert int res; 2665c0b746e5SOllivier Robert l_fp ts; 2666c0b746e5SOllivier Robert struct clktype *clk; 2667c0b746e5SOllivier Robert 26682b15cb3dSCy Schubert qitemlim = min(pcmd->nargs, COUNTOF(clist)); 26692b15cb3dSCy Schubert for (qitems = 0; qitems < qitemlim; qitems++) 26702b15cb3dSCy Schubert clist[qitems] = NSRCADR(&pcmd->argval[qitems].netnum); 2671c0b746e5SOllivier Robert 26729c2daa00SOllivier Robert again: 26739c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_CLOCKINFO, 0, qitems, 2674c0b746e5SOllivier Robert sizeof(u_int32), (char *)clist, &items, 26759c2daa00SOllivier Robert &itemsize, (void *)&cl, 0, sizeof(struct info_clock)); 26769c2daa00SOllivier Robert 26779c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 26789c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 26799c2daa00SOllivier Robert goto again; 26809c2daa00SOllivier Robert } 2681c0b746e5SOllivier Robert 2682ea906c41SOllivier Robert if (res != 0) 2683c0b746e5SOllivier Robert return; 2684c0b746e5SOllivier Robert 2685c0b746e5SOllivier Robert if (!checkitems(items, fp)) 2686c0b746e5SOllivier Robert return; 2687c0b746e5SOllivier Robert 2688c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_clock))) 2689c0b746e5SOllivier Robert return; 2690c0b746e5SOllivier Robert 2691c0b746e5SOllivier Robert while (items-- > 0) { 2692c0b746e5SOllivier Robert (void) fprintf(fp, "clock address: %s\n", 2693c0b746e5SOllivier Robert numtoa(cl->clockadr)); 2694c0b746e5SOllivier Robert for (clk = clktypes; clk->code >= 0; clk++) 2695c0b746e5SOllivier Robert if (clk->code == cl->type) 2696c0b746e5SOllivier Robert break; 2697c0b746e5SOllivier Robert if (clk->code >= 0) 2698c0b746e5SOllivier Robert (void) fprintf(fp, "clock type: %s\n", 2699c0b746e5SOllivier Robert clk->clocktype); 2700c0b746e5SOllivier Robert else 2701c0b746e5SOllivier Robert (void) fprintf(fp, "clock type: unknown type (%d)\n", 2702c0b746e5SOllivier Robert cl->type); 2703c0b746e5SOllivier Robert (void) fprintf(fp, "last event: %d\n", 2704c0b746e5SOllivier Robert cl->lastevent); 2705c0b746e5SOllivier Robert (void) fprintf(fp, "current status: %d\n", 2706c0b746e5SOllivier Robert cl->currentstatus); 2707c0b746e5SOllivier Robert (void) fprintf(fp, "number of polls: %lu\n", 2708c0b746e5SOllivier Robert (u_long)ntohl(cl->polls)); 2709c0b746e5SOllivier Robert (void) fprintf(fp, "no response to poll: %lu\n", 2710c0b746e5SOllivier Robert (u_long)ntohl(cl->noresponse)); 2711c0b746e5SOllivier Robert (void) fprintf(fp, "bad format responses: %lu\n", 2712c0b746e5SOllivier Robert (u_long)ntohl(cl->badformat)); 2713c0b746e5SOllivier Robert (void) fprintf(fp, "bad data responses: %lu\n", 2714c0b746e5SOllivier Robert (u_long)ntohl(cl->baddata)); 2715c0b746e5SOllivier Robert (void) fprintf(fp, "running time: %lu\n", 2716c0b746e5SOllivier Robert (u_long)ntohl(cl->timestarted)); 2717c0b746e5SOllivier Robert NTOHL_FP(&cl->fudgetime1, &ts); 2718c0b746e5SOllivier Robert (void) fprintf(fp, "fudge time 1: %s\n", 2719c0b746e5SOllivier Robert lfptoa(&ts, 6)); 2720c0b746e5SOllivier Robert NTOHL_FP(&cl->fudgetime2, &ts); 2721c0b746e5SOllivier Robert (void) fprintf(fp, "fudge time 2: %s\n", 2722c0b746e5SOllivier Robert lfptoa(&ts, 6)); 2723c0b746e5SOllivier Robert (void) fprintf(fp, "stratum: %ld\n", 2724c0b746e5SOllivier Robert (u_long)ntohl(cl->fudgeval1)); 2725052d159aSCy Schubert /* [Bug3527] Backward Incompatible: cl->fudgeval2 is 2726052d159aSCy Schubert * a string, instantiated via memcpy() so there is no 2727052d159aSCy Schubert * endian issue to correct. 2728052d159aSCy Schubert */ 2729052d159aSCy Schubert #ifdef DISABLE_BUG3527_FIX 2730c0b746e5SOllivier Robert (void) fprintf(fp, "reference ID: %s\n", 2731ea906c41SOllivier Robert refid_string(ntohl(cl->fudgeval2), 0)); 2732052d159aSCy Schubert #else 2733052d159aSCy Schubert (void) fprintf(fp, "reference ID: %s\n", 2734052d159aSCy Schubert refid_string(cl->fudgeval2, 0)); 2735052d159aSCy Schubert #endif 2736c0b746e5SOllivier Robert (void) fprintf(fp, "fudge flags: 0x%x\n", 2737c0b746e5SOllivier Robert cl->flags); 2738c0b746e5SOllivier Robert 2739c0b746e5SOllivier Robert if (items > 0) 2740c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2741c0b746e5SOllivier Robert cl++; 2742c0b746e5SOllivier Robert } 2743c0b746e5SOllivier Robert } 2744c0b746e5SOllivier Robert 2745c0b746e5SOllivier Robert 2746c0b746e5SOllivier Robert /* 2747c0b746e5SOllivier Robert * fudge - set clock fudge factors 2748c0b746e5SOllivier Robert */ 2749c0b746e5SOllivier Robert static void 2750c0b746e5SOllivier Robert fudge( 2751c0b746e5SOllivier Robert struct parse *pcmd, 2752c0b746e5SOllivier Robert FILE *fp 2753c0b746e5SOllivier Robert ) 2754c0b746e5SOllivier Robert { 2755c0b746e5SOllivier Robert struct conf_fudge fudgedata; 27563311ff84SXin LI size_t items; 27573311ff84SXin LI size_t itemsize; 27583311ff84SXin LI const char *dummy; 2759c0b746e5SOllivier Robert l_fp ts; 2760c0b746e5SOllivier Robert int res; 2761c0b746e5SOllivier Robert long val; 2762c0b746e5SOllivier Robert u_long u_val; 2763c0b746e5SOllivier Robert int err; 2764c0b746e5SOllivier Robert 2765c0b746e5SOllivier Robert 2766c0b746e5SOllivier Robert err = 0; 27672b15cb3dSCy Schubert ZERO(fudgedata); 27682b15cb3dSCy Schubert fudgedata.clockadr = NSRCADR(&pcmd->argval[0].netnum); 2769c0b746e5SOllivier Robert 2770c0b746e5SOllivier Robert if (STREQ(pcmd->argval[1].string, "time1")) { 2771c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_TIME1); 2772c0b746e5SOllivier Robert if (!atolfp(pcmd->argval[2].string, &ts)) 2773c0b746e5SOllivier Robert err = 1; 2774c0b746e5SOllivier Robert else 2775c0b746e5SOllivier Robert NTOHL_FP(&ts, &fudgedata.fudgetime); 2776c0b746e5SOllivier Robert } else if (STREQ(pcmd->argval[1].string, "time2")) { 2777c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_TIME2); 2778c0b746e5SOllivier Robert if (!atolfp(pcmd->argval[2].string, &ts)) 2779c0b746e5SOllivier Robert err = 1; 2780c0b746e5SOllivier Robert else 2781c0b746e5SOllivier Robert NTOHL_FP(&ts, &fudgedata.fudgetime); 2782c0b746e5SOllivier Robert } else if (STREQ(pcmd->argval[1].string, "val1")) { 2783c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_VAL1); 2784c0b746e5SOllivier Robert if (!atoint(pcmd->argval[2].string, &val)) 2785c0b746e5SOllivier Robert err = 1; 2786c0b746e5SOllivier Robert else 2787c0b746e5SOllivier Robert fudgedata.fudgeval_flags = htonl(val); 2788c0b746e5SOllivier Robert } else if (STREQ(pcmd->argval[1].string, "val2")) { 2789c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_VAL2); 2790c0b746e5SOllivier Robert if (!atoint(pcmd->argval[2].string, &val)) 2791c0b746e5SOllivier Robert err = 1; 2792c0b746e5SOllivier Robert else 2793c0b746e5SOllivier Robert fudgedata.fudgeval_flags = htonl((u_int32)val); 2794c0b746e5SOllivier Robert } else if (STREQ(pcmd->argval[1].string, "flags")) { 2795c0b746e5SOllivier Robert fudgedata.which = htonl(FUDGE_FLAGS); 2796c0b746e5SOllivier Robert if (!hextoint(pcmd->argval[2].string, &u_val)) 2797c0b746e5SOllivier Robert err = 1; 2798c0b746e5SOllivier Robert else 2799c0b746e5SOllivier Robert fudgedata.fudgeval_flags = htonl((u_int32)(u_val & 0xf)); 2800c0b746e5SOllivier Robert } else { 2801c0b746e5SOllivier Robert (void) fprintf(stderr, "What fudge is %s?\n", 2802c0b746e5SOllivier Robert pcmd->argval[1].string); 2803c0b746e5SOllivier Robert return; 2804c0b746e5SOllivier Robert } 2805c0b746e5SOllivier Robert 2806c0b746e5SOllivier Robert if (err) { 2807c0b746e5SOllivier Robert (void) fprintf(stderr, "Unknown fudge parameter %s\n", 2808c0b746e5SOllivier Robert pcmd->argval[2].string); 2809c0b746e5SOllivier Robert return; 2810c0b746e5SOllivier Robert } 2811c0b746e5SOllivier Robert 28129c2daa00SOllivier Robert again: 28139c2daa00SOllivier Robert res = doquery(impl_ver, REQ_SET_CLKFUDGE, 1, 1, 2814c0b746e5SOllivier Robert sizeof(struct conf_fudge), (char *)&fudgedata, &items, 28159c2daa00SOllivier Robert &itemsize, &dummy, 0, sizeof(dummy)); 28169c2daa00SOllivier Robert 28179c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 28189c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 28199c2daa00SOllivier Robert goto again; 28209c2daa00SOllivier Robert } 2821c0b746e5SOllivier Robert 2822c0b746e5SOllivier Robert if (res == 0) 2823c0b746e5SOllivier Robert (void) fprintf(fp, "done!\n"); 2824c0b746e5SOllivier Robert return; 2825c0b746e5SOllivier Robert } 2826c0b746e5SOllivier Robert 2827c0b746e5SOllivier Robert /* 2828c0b746e5SOllivier Robert * clkbug - get and print clock debugging information 2829c0b746e5SOllivier Robert */ 2830c0b746e5SOllivier Robert static void 2831c0b746e5SOllivier Robert clkbug( 2832c0b746e5SOllivier Robert struct parse *pcmd, 2833c0b746e5SOllivier Robert FILE *fp 2834c0b746e5SOllivier Robert ) 2835c0b746e5SOllivier Robert { 2836c0b746e5SOllivier Robert register int i; 2837c0b746e5SOllivier Robert register int n; 2838c0b746e5SOllivier Robert register u_int32 s; 2839c0b746e5SOllivier Robert struct info_clkbug *cl; 2840c0b746e5SOllivier Robert /* 8 is the maximum number of clocks which will fit in a packet */ 2841c0b746e5SOllivier Robert u_long clist[min(MAXARGS, 8)]; 2842c0b746e5SOllivier Robert u_int32 ltemp; 28433311ff84SXin LI size_t qitemlim; 28443311ff84SXin LI size_t qitems; 28453311ff84SXin LI size_t items; 28463311ff84SXin LI size_t itemsize; 2847c0b746e5SOllivier Robert int res; 2848c0b746e5SOllivier Robert int needsp; 2849c0b746e5SOllivier Robert l_fp ts; 2850c0b746e5SOllivier Robert 28512b15cb3dSCy Schubert qitemlim = min(pcmd->nargs, COUNTOF(clist)); 28522b15cb3dSCy Schubert for (qitems = 0; qitems < qitemlim; qitems++) 28532b15cb3dSCy Schubert clist[qitems] = NSRCADR(&pcmd->argval[qitems].netnum); 2854c0b746e5SOllivier Robert 28559c2daa00SOllivier Robert again: 28569c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_CLKBUGINFO, 0, qitems, 2857c0b746e5SOllivier Robert sizeof(u_int32), (char *)clist, &items, 28589c2daa00SOllivier Robert &itemsize, (void *)&cl, 0, sizeof(struct info_clkbug)); 28599c2daa00SOllivier Robert 28609c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 28619c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 28629c2daa00SOllivier Robert goto again; 28639c2daa00SOllivier Robert } 2864c0b746e5SOllivier Robert 2865ea906c41SOllivier Robert if (res != 0) 2866c0b746e5SOllivier Robert return; 2867c0b746e5SOllivier Robert 2868c0b746e5SOllivier Robert if (!checkitems(items, fp)) 2869c0b746e5SOllivier Robert return; 2870c0b746e5SOllivier Robert 2871c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_clkbug))) 2872c0b746e5SOllivier Robert return; 2873c0b746e5SOllivier Robert 2874c0b746e5SOllivier Robert while (items-- > 0) { 2875c0b746e5SOllivier Robert (void) fprintf(fp, "clock address: %s\n", 2876c0b746e5SOllivier Robert numtoa(cl->clockadr)); 2877c0b746e5SOllivier Robert n = (int)cl->nvalues; 2878c0b746e5SOllivier Robert (void) fprintf(fp, "values: %d", n); 2879c0b746e5SOllivier Robert s = ntohs(cl->svalues); 2880c0b746e5SOllivier Robert if (n > NUMCBUGVALUES) 2881c0b746e5SOllivier Robert n = NUMCBUGVALUES; 2882c0b746e5SOllivier Robert for (i = 0; i < n; i++) { 2883c0b746e5SOllivier Robert ltemp = ntohl(cl->values[i]); 2884c0b746e5SOllivier Robert ltemp &= 0xffffffff; /* HMS: This does nothing now */ 2885c0b746e5SOllivier Robert if ((i & 0x3) == 0) 2886c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2887c0b746e5SOllivier Robert if (s & (1 << i)) 2888c0b746e5SOllivier Robert (void) fprintf(fp, "%12ld", (u_long)ltemp); 2889c0b746e5SOllivier Robert else 2890c0b746e5SOllivier Robert (void) fprintf(fp, "%12lu", (u_long)ltemp); 2891c0b746e5SOllivier Robert } 2892c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2893c0b746e5SOllivier Robert 2894c0b746e5SOllivier Robert n = (int)cl->ntimes; 2895c0b746e5SOllivier Robert (void) fprintf(fp, "times: %d", n); 2896c0b746e5SOllivier Robert s = ntohl(cl->stimes); 2897c0b746e5SOllivier Robert if (n > NUMCBUGTIMES) 2898c0b746e5SOllivier Robert n = NUMCBUGTIMES; 2899c0b746e5SOllivier Robert needsp = 0; 2900c0b746e5SOllivier Robert for (i = 0; i < n; i++) { 2901c0b746e5SOllivier Robert if ((i & 0x1) == 0) { 2902c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2903c0b746e5SOllivier Robert } else { 2904c0b746e5SOllivier Robert for (;needsp > 0; needsp--) 2905c0b746e5SOllivier Robert putc(' ', fp); 2906c0b746e5SOllivier Robert } 2907c0b746e5SOllivier Robert NTOHL_FP(&cl->times[i], &ts); 2908c0b746e5SOllivier Robert if (s & (1 << i)) { 2909c0b746e5SOllivier Robert (void) fprintf(fp, "%17s", 2910c0b746e5SOllivier Robert lfptoa(&ts, 6)); 2911c0b746e5SOllivier Robert needsp = 22; 2912c0b746e5SOllivier Robert } else { 2913c0b746e5SOllivier Robert (void) fprintf(fp, "%37s", 2914c0b746e5SOllivier Robert uglydate(&ts)); 2915c0b746e5SOllivier Robert needsp = 2; 2916c0b746e5SOllivier Robert } 2917c0b746e5SOllivier Robert } 2918c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2919c0b746e5SOllivier Robert if (items > 0) { 2920c0b746e5SOllivier Robert cl++; 2921c0b746e5SOllivier Robert (void) fprintf(fp, "\n"); 2922c0b746e5SOllivier Robert } 2923c0b746e5SOllivier Robert } 2924c0b746e5SOllivier Robert } 2925c0b746e5SOllivier Robert 2926c0b746e5SOllivier Robert 2927c0b746e5SOllivier Robert /* 2928c0b746e5SOllivier Robert * kerninfo - display the kernel pll/pps variables 2929c0b746e5SOllivier Robert */ 2930c0b746e5SOllivier Robert static void 2931c0b746e5SOllivier Robert kerninfo( 2932c0b746e5SOllivier Robert struct parse *pcmd, 2933c0b746e5SOllivier Robert FILE *fp 2934c0b746e5SOllivier Robert ) 2935c0b746e5SOllivier Robert { 2936c0b746e5SOllivier Robert struct info_kernel *ik; 29373311ff84SXin LI size_t items; 29383311ff84SXin LI size_t itemsize; 2939c0b746e5SOllivier Robert int res; 2940c0b746e5SOllivier Robert unsigned status; 2941052d159aSCy Schubert double tscale_usec = 1e-6, tscale_unano = 1e-6; 2942c0b746e5SOllivier Robert 29439c2daa00SOllivier Robert again: 29449c2daa00SOllivier Robert res = doquery(impl_ver, REQ_GET_KERNEL, 0, 0, 0, (char *)NULL, 29459c2daa00SOllivier Robert &items, &itemsize, (void *)&ik, 0, 29469c2daa00SOllivier Robert sizeof(struct info_kernel)); 29479c2daa00SOllivier Robert 29489c2daa00SOllivier Robert if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) { 29499c2daa00SOllivier Robert impl_ver = IMPL_XNTPD_OLD; 29509c2daa00SOllivier Robert goto again; 29519c2daa00SOllivier Robert } 29529c2daa00SOllivier Robert 2953ea906c41SOllivier Robert if (res != 0) 2954c0b746e5SOllivier Robert return; 2955c0b746e5SOllivier Robert if (!check1item(items, fp)) 2956c0b746e5SOllivier Robert return; 2957c0b746e5SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_kernel))) 2958c0b746e5SOllivier Robert return; 2959c0b746e5SOllivier Robert 2960c0b746e5SOllivier Robert status = ntohs(ik->status) & 0xffff; 2961c0b746e5SOllivier Robert /* 2962c0b746e5SOllivier Robert * pll variables. We know more than we should about the NANO bit. 2963c0b746e5SOllivier Robert */ 2964c0b746e5SOllivier Robert #ifdef STA_NANO 2965c0b746e5SOllivier Robert if (status & STA_NANO) 2966052d159aSCy Schubert tscale_unano = 1e-9; 2967c0b746e5SOllivier Robert #endif 2968c0b746e5SOllivier Robert (void)fprintf(fp, "pll offset: %g s\n", 2969052d159aSCy Schubert (int32)ntohl(ik->offset) * tscale_unano); 2970c0b746e5SOllivier Robert (void)fprintf(fp, "pll frequency: %s ppm\n", 2971c0b746e5SOllivier Robert fptoa((s_fp)ntohl(ik->freq), 3)); 2972c0b746e5SOllivier Robert (void)fprintf(fp, "maximum error: %g s\n", 2973052d159aSCy Schubert (u_long)ntohl(ik->maxerror) * tscale_usec); 2974c0b746e5SOllivier Robert (void)fprintf(fp, "estimated error: %g s\n", 2975052d159aSCy Schubert (u_long)ntohl(ik->esterror) * tscale_usec); 2976c0b746e5SOllivier Robert (void)fprintf(fp, "status: %04x ", status); 2977c0b746e5SOllivier Robert #ifdef STA_PLL 2978c0b746e5SOllivier Robert if (status & STA_PLL) (void)fprintf(fp, " pll"); 2979c0b746e5SOllivier Robert #endif 2980c0b746e5SOllivier Robert #ifdef STA_PPSFREQ 2981c0b746e5SOllivier Robert if (status & STA_PPSFREQ) (void)fprintf(fp, " ppsfreq"); 2982c0b746e5SOllivier Robert #endif 2983c0b746e5SOllivier Robert #ifdef STA_PPSTIME 2984c0b746e5SOllivier Robert if (status & STA_PPSTIME) (void)fprintf(fp, " ppstime"); 2985c0b746e5SOllivier Robert #endif 2986c0b746e5SOllivier Robert #ifdef STA_FLL 2987c0b746e5SOllivier Robert if (status & STA_FLL) (void)fprintf(fp, " fll"); 2988c0b746e5SOllivier Robert #endif 2989c0b746e5SOllivier Robert #ifdef STA_INS 2990c0b746e5SOllivier Robert if (status & STA_INS) (void)fprintf(fp, " ins"); 2991c0b746e5SOllivier Robert #endif 2992c0b746e5SOllivier Robert #ifdef STA_DEL 2993c0b746e5SOllivier Robert if (status & STA_DEL) (void)fprintf(fp, " del"); 2994c0b746e5SOllivier Robert #endif 2995c0b746e5SOllivier Robert #ifdef STA_UNSYNC 2996c0b746e5SOllivier Robert if (status & STA_UNSYNC) (void)fprintf(fp, " unsync"); 2997c0b746e5SOllivier Robert #endif 2998c0b746e5SOllivier Robert #ifdef STA_FREQHOLD 2999c0b746e5SOllivier Robert if (status & STA_FREQHOLD) (void)fprintf(fp, " freqhold"); 3000c0b746e5SOllivier Robert #endif 3001c0b746e5SOllivier Robert #ifdef STA_PPSSIGNAL 3002c0b746e5SOllivier Robert if (status & STA_PPSSIGNAL) (void)fprintf(fp, " ppssignal"); 3003c0b746e5SOllivier Robert #endif 3004c0b746e5SOllivier Robert #ifdef STA_PPSJITTER 3005c0b746e5SOllivier Robert if (status & STA_PPSJITTER) (void)fprintf(fp, " ppsjitter"); 3006c0b746e5SOllivier Robert #endif 3007c0b746e5SOllivier Robert #ifdef STA_PPSWANDER 3008c0b746e5SOllivier Robert if (status & STA_PPSWANDER) (void)fprintf(fp, " ppswander"); 3009c0b746e5SOllivier Robert #endif 3010c0b746e5SOllivier Robert #ifdef STA_PPSERROR 3011c0b746e5SOllivier Robert if (status & STA_PPSERROR) (void)fprintf(fp, " ppserror"); 3012c0b746e5SOllivier Robert #endif 3013c0b746e5SOllivier Robert #ifdef STA_CLOCKERR 3014c0b746e5SOllivier Robert if (status & STA_CLOCKERR) (void)fprintf(fp, " clockerr"); 3015c0b746e5SOllivier Robert #endif 3016c0b746e5SOllivier Robert #ifdef STA_NANO 3017c0b746e5SOllivier Robert if (status & STA_NANO) (void)fprintf(fp, " nano"); 3018c0b746e5SOllivier Robert #endif 3019c0b746e5SOllivier Robert #ifdef STA_MODE 3020c0b746e5SOllivier Robert if (status & STA_MODE) (void)fprintf(fp, " mode=fll"); 3021c0b746e5SOllivier Robert #endif 3022c0b746e5SOllivier Robert #ifdef STA_CLK 3023c0b746e5SOllivier Robert if (status & STA_CLK) (void)fprintf(fp, " src=B"); 3024c0b746e5SOllivier Robert #endif 3025c0b746e5SOllivier Robert (void)fprintf(fp, "\n"); 3026c0b746e5SOllivier Robert (void)fprintf(fp, "pll time constant: %ld\n", 3027c0b746e5SOllivier Robert (u_long)ntohl(ik->constant)); 3028c0b746e5SOllivier Robert (void)fprintf(fp, "precision: %g s\n", 3029052d159aSCy Schubert (u_long)ntohl(ik->precision) * tscale_usec); 3030c0b746e5SOllivier Robert (void)fprintf(fp, "frequency tolerance: %s ppm\n", 3031c0b746e5SOllivier Robert fptoa((s_fp)ntohl(ik->tolerance), 0)); 3032c0b746e5SOllivier Robert 3033c0b746e5SOllivier Robert /* 3034c0b746e5SOllivier Robert * For backwards compatibility (ugh), we find the pps variables 3035c0b746e5SOllivier Robert * only if the shift member is nonzero. 3036c0b746e5SOllivier Robert */ 3037c0b746e5SOllivier Robert if (!ik->shift) 3038c0b746e5SOllivier Robert return; 3039c0b746e5SOllivier Robert 3040c0b746e5SOllivier Robert /* 3041c0b746e5SOllivier Robert * pps variables 3042c0b746e5SOllivier Robert */ 3043c0b746e5SOllivier Robert (void)fprintf(fp, "pps frequency: %s ppm\n", 3044c0b746e5SOllivier Robert fptoa((s_fp)ntohl(ik->ppsfreq), 3)); 3045c0b746e5SOllivier Robert (void)fprintf(fp, "pps stability: %s ppm\n", 3046c0b746e5SOllivier Robert fptoa((s_fp)ntohl(ik->stabil), 3)); 3047c0b746e5SOllivier Robert (void)fprintf(fp, "pps jitter: %g s\n", 3048052d159aSCy Schubert (u_long)ntohl(ik->jitter) * tscale_unano); 3049c0b746e5SOllivier Robert (void)fprintf(fp, "calibration interval: %d s\n", 3050c0b746e5SOllivier Robert 1 << ntohs(ik->shift)); 3051c0b746e5SOllivier Robert (void)fprintf(fp, "calibration cycles: %ld\n", 3052c0b746e5SOllivier Robert (u_long)ntohl(ik->calcnt)); 3053c0b746e5SOllivier Robert (void)fprintf(fp, "jitter exceeded: %ld\n", 3054c0b746e5SOllivier Robert (u_long)ntohl(ik->jitcnt)); 3055c0b746e5SOllivier Robert (void)fprintf(fp, "stability exceeded: %ld\n", 3056c0b746e5SOllivier Robert (u_long)ntohl(ik->stbcnt)); 3057c0b746e5SOllivier Robert (void)fprintf(fp, "calibration errors: %ld\n", 3058c0b746e5SOllivier Robert (u_long)ntohl(ik->errcnt)); 3059c0b746e5SOllivier Robert } 3060ea906c41SOllivier Robert 30612b15cb3dSCy Schubert #define IF_LIST_FMT "%2d %c %48s %c %c %12.12s %03lx %3lu %2lu %5lu %5lu %5lu %2lu %3lu %7lu\n" 30622b15cb3dSCy Schubert #define IF_LIST_FMT_STR "%2s %c %48s %c %c %12.12s %3s %3s %2s %5s %5s %5s %2s %3s %7s\n" 3063ea906c41SOllivier Robert #define IF_LIST_AFMT_STR " %48s %c\n" 30642b15cb3dSCy Schubert #define IF_LIST_LABELS "#", 'A', "Address/Mask/Broadcast", 'T', 'E', "IF name", "Flg", "TL", "#M", "recv", "sent", "drop", "S", "PC", "uptime" 30652b15cb3dSCy Schubert #define IF_LIST_LINE "==================================================================================================================\n" 3066ea906c41SOllivier Robert 3067ea906c41SOllivier Robert static void 3068ea906c41SOllivier Robert iflist( 3069ea906c41SOllivier Robert FILE *fp, 3070ea906c41SOllivier Robert struct info_if_stats *ifs, 30713311ff84SXin LI size_t items, 30723311ff84SXin LI size_t itemsize, 3073ea906c41SOllivier Robert int res 3074ea906c41SOllivier Robert ) 3075ea906c41SOllivier Robert { 30762b15cb3dSCy Schubert static const char *actions = "?.+-"; 30772b15cb3dSCy Schubert sockaddr_u saddr; 3078ea906c41SOllivier Robert 3079ea906c41SOllivier Robert if (res != 0) 3080ea906c41SOllivier Robert return; 3081ea906c41SOllivier Robert 3082ea906c41SOllivier Robert if (!checkitems(items, fp)) 3083ea906c41SOllivier Robert return; 3084ea906c41SOllivier Robert 3085ea906c41SOllivier Robert if (!checkitemsize(itemsize, sizeof(struct info_if_stats))) 3086ea906c41SOllivier Robert return; 3087ea906c41SOllivier Robert 3088ea906c41SOllivier Robert fprintf(fp, IF_LIST_FMT_STR, IF_LIST_LABELS); 3089ea906c41SOllivier Robert fprintf(fp, IF_LIST_LINE); 3090ea906c41SOllivier Robert 3091ea906c41SOllivier Robert while (items > 0) { 30922b15cb3dSCy Schubert SET_ADDR(saddr, ntohl(ifs->v6_flag), 30932b15cb3dSCy Schubert ifs->unaddr.addr.s_addr, ifs->unaddr.addr6); 3094ea906c41SOllivier Robert fprintf(fp, IF_LIST_FMT, 3095ea906c41SOllivier Robert ntohl(ifs->ifnum), 3096ea906c41SOllivier Robert actions[(ifs->action >= 1 && ifs->action < 4) ? ifs->action : 0], 3097ea906c41SOllivier Robert stoa((&saddr)), 'A', 3098ea906c41SOllivier Robert ifs->ignore_packets ? 'D' : 'E', 3099ea906c41SOllivier Robert ifs->name, 31002b15cb3dSCy Schubert (u_long)ntohl(ifs->flags), 31012b15cb3dSCy Schubert (u_long)ntohl(ifs->last_ttl), 31022b15cb3dSCy Schubert (u_long)ntohl(ifs->num_mcast), 31032b15cb3dSCy Schubert (u_long)ntohl(ifs->received), 31042b15cb3dSCy Schubert (u_long)ntohl(ifs->sent), 31052b15cb3dSCy Schubert (u_long)ntohl(ifs->notsent), 31062b15cb3dSCy Schubert (u_long)ntohl(ifs->scopeid), 31072b15cb3dSCy Schubert (u_long)ntohl(ifs->peercnt), 31082b15cb3dSCy Schubert (u_long)ntohl(ifs->uptime)); 3109ea906c41SOllivier Robert 31102b15cb3dSCy Schubert SET_ADDR(saddr, ntohl(ifs->v6_flag), 31112b15cb3dSCy Schubert ifs->unmask.addr.s_addr, ifs->unmask.addr6); 3112ea906c41SOllivier Robert fprintf(fp, IF_LIST_AFMT_STR, stoa(&saddr), 'M'); 3113ea906c41SOllivier Robert 3114ea906c41SOllivier Robert if (!ntohl(ifs->v6_flag) && ntohl(ifs->flags) & (INT_BCASTOPEN)) { 31152b15cb3dSCy Schubert SET_ADDR(saddr, ntohl(ifs->v6_flag), 31162b15cb3dSCy Schubert ifs->unbcast.addr.s_addr, ifs->unbcast.addr6); 3117ea906c41SOllivier Robert fprintf(fp, IF_LIST_AFMT_STR, stoa(&saddr), 'B'); 3118ea906c41SOllivier Robert 3119ea906c41SOllivier Robert } 3120ea906c41SOllivier Robert 3121ea906c41SOllivier Robert ifs++; 3122ea906c41SOllivier Robert items--; 3123ea906c41SOllivier Robert } 3124ea906c41SOllivier Robert } 3125ea906c41SOllivier Robert 3126ea906c41SOllivier Robert /*ARGSUSED*/ 3127ea906c41SOllivier Robert static void 3128ea906c41SOllivier Robert get_if_stats( 3129ea906c41SOllivier Robert struct parse *pcmd, 3130ea906c41SOllivier Robert FILE *fp 3131ea906c41SOllivier Robert ) 3132ea906c41SOllivier Robert { 3133ea906c41SOllivier Robert struct info_if_stats *ifs; 31343311ff84SXin LI size_t items; 31353311ff84SXin LI size_t itemsize; 3136ea906c41SOllivier Robert int res; 3137ea906c41SOllivier Robert 3138ea906c41SOllivier Robert res = doquery(impl_ver, REQ_IF_STATS, 1, 0, 0, (char *)NULL, &items, 3139ea906c41SOllivier Robert &itemsize, (void *)&ifs, 0, 3140ea906c41SOllivier Robert sizeof(struct info_if_stats)); 3141ea906c41SOllivier Robert iflist(fp, ifs, items, itemsize, res); 3142ea906c41SOllivier Robert } 3143ea906c41SOllivier Robert 3144ea906c41SOllivier Robert /*ARGSUSED*/ 3145ea906c41SOllivier Robert static void 3146ea906c41SOllivier Robert do_if_reload( 3147ea906c41SOllivier Robert struct parse *pcmd, 3148ea906c41SOllivier Robert FILE *fp 3149ea906c41SOllivier Robert ) 3150ea906c41SOllivier Robert { 3151ea906c41SOllivier Robert struct info_if_stats *ifs; 31523311ff84SXin LI size_t items; 31533311ff84SXin LI size_t itemsize; 3154ea906c41SOllivier Robert int res; 3155ea906c41SOllivier Robert 3156ea906c41SOllivier Robert res = doquery(impl_ver, REQ_IF_RELOAD, 1, 0, 0, (char *)NULL, &items, 3157ea906c41SOllivier Robert &itemsize, (void *)&ifs, 0, 3158ea906c41SOllivier Robert sizeof(struct info_if_stats)); 3159ea906c41SOllivier Robert iflist(fp, ifs, items, itemsize, res); 3160ea906c41SOllivier Robert } 3161